@amaster.ai/auth-client 1.1.3 → 1.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -96,7 +96,6 @@ interface AuthClientOptions {
96
96
 
97
97
  ```typescript
98
98
  const authClient = createAuthClient({
99
- baseURL: "https://api.example.com",
100
99
  onTokenExpired: () => (window.location.href = "/login"),
101
100
  onUnauthorized: () => alert("Session expired"),
102
101
  });
@@ -217,40 +216,56 @@ if (window.opener) {
217
216
  }
218
217
  ```
219
218
 
220
- ### WeChat Mini Program Login
219
+ ### Mini Program Login
221
220
 
222
- The SDK automatically detects WeChat Mini Program environment and uses `wx.storage`:
221
+ The SDK exposes a unified Mini Program API for both WeChat and Douyin.
222
+
223
+ - WeChat runtime: auto-detects `wx` and uses WeChat endpoints
224
+ - Douyin Mini Program: auto-detects the `tt` runtime and uses Douyin endpoints
225
+ - Non-runtime or mixed environments: you can explicitly pass `platform`
226
+
227
+ The SDK automatically detects the Mini Program storage runtime and uses WeChat `wx.storage` or Douyin `tt.storage`.
228
+ For most app code, prefer the high-level methods:
229
+
230
+ - `miniLogin()` - automatically calls `Taro.login` / Douyin `tt.login` / WeChat `wx.login`, then completes backend login
231
+ - `miniGetPhone(...)` - accepts a raw code or event object, extracts the phone code, then binds the phone number
223
232
 
224
233
  ```typescript
225
234
  import { createAuthClient } from "@amaster.ai/auth-client";
235
+ import Taro from "@tarojs/taro";
226
236
 
227
- // Zero configuration - auto-detects WeChat environment
228
- const authClient = createAuthClient({
229
- baseURL: "https://api.yourdomain.com",
230
- });
237
+ // Zero configuration - auto-detects mini-program environment
238
+ const authClient = createAuthClient();
231
239
 
232
- // Login with WeChat code
233
- wx.login({
234
- success: async (res) => {
235
- if (res.code) {
236
- const result = await authClient.loginWithMiniProgram(res.code);
237
-
238
- if (result.data) {
239
- console.log("Logged in:", result.data.user);
240
- // Token automatically saved to wx.storage
241
- wx.switchTab({ url: "/pages/index/index" });
242
- } else if (result.error) {
243
- wx.showToast({
244
- title: result.error.message || "Login failed",
245
- icon: "none",
246
- });
247
- }
248
- }
249
- },
250
- fail: (err) => {
251
- console.error("wx.login failed:", err);
252
- },
240
+ const result = await authClient.miniLogin();
241
+
242
+ if (result.data) {
243
+ console.log("Logged in:", result.data.user);
244
+ // Token automatically saved to mini-program storage
245
+ Taro.switchTab({ url: "/pages/index/index" });
246
+ } else if (result.error) {
247
+ Taro.showToast({
248
+ title: result.error.message || "Login failed",
249
+ icon: "none",
250
+ });
251
+ }
252
+ ```
253
+
254
+ **Login with Douyin Mini Program:**
255
+
256
+ ```typescript
257
+ const result = await authClient.miniLogin({
258
+ platform: "douyin",
253
259
  });
260
+
261
+ if (result.data) {
262
+ console.log("Logged in:", result.data.user);
263
+ } else if (result.error) {
264
+ Taro.showToast({
265
+ title: result.error.message || "Login failed",
266
+ icon: "none",
267
+ });
268
+ }
254
269
  ```
255
270
 
256
271
  **Get user phone number (optional):**
@@ -268,25 +283,21 @@ wx.login({
268
283
  ```typescript
269
284
  // JS
270
285
  async onGetPhoneNumber(e) {
271
- const { code } = e.detail;
272
-
273
- if (code) {
274
- const result = await authClient.getMiniProgramPhoneNumber(code);
286
+ const result = await authClient.miniGetPhone(e);
275
287
 
276
- if (result.data) {
277
- console.log("Phone number:", result.data.phone);
278
- console.log("Verified:", result.data.phoneVerified);
288
+ if (result.data) {
289
+ console.log("Phone number:", result.data.phone);
290
+ console.log("Verified:", result.data.phoneVerified);
279
291
 
280
- // Update UI with phone number
281
- this.setData({
282
- phone: result.data.phone
283
- });
284
- } else if (result.error) {
285
- wx.showToast({
286
- title: result.error.message || 'Failed to get phone number',
287
- icon: 'none'
288
- });
289
- }
292
+ // Update UI with phone number
293
+ this.setData({
294
+ phone: result.data.phone
295
+ });
296
+ } else if (result.error) {
297
+ Taro.showToast({
298
+ title: result.error.message || 'Failed to get phone number',
299
+ icon: 'none'
300
+ });
290
301
  } else {
291
302
  // User denied authorization
292
303
  console.log("User cancelled phone number authorization");
@@ -294,15 +305,29 @@ async onGetPhoneNumber(e) {
294
305
  }
295
306
  ```
296
307
 
308
+ **Get Douyin Mini Program phone number:**
309
+
310
+ ```typescript
311
+ async function onGetPhoneNumber(e) {
312
+ const result = await authClient.miniGetPhone({
313
+ ...e,
314
+ platform: "douyin",
315
+ });
316
+
317
+ if (result.data) {
318
+ console.log("Phone number:", result.data.phone);
319
+ }
320
+ }
321
+ ```
322
+
297
323
  **Complete Mini Program example:**
298
324
 
299
325
  ```typescript
300
326
  // pages/login/login.js
301
327
  import { createAuthClient } from "@amaster.ai/auth-client";
328
+ import Taro from "@tarojs/taro";
302
329
 
303
- const authClient = createAuthClient({
304
- baseURL: "https://api.yourdomain.com",
305
- });
330
+ const authClient = createAuthClient();
306
331
 
307
332
  Page({
308
333
  data: {
@@ -317,38 +342,25 @@ Page({
317
342
 
318
343
  // WeChat Mini Program login
319
344
  async handleLogin() {
320
- wx.showLoading({ title: "Logging in..." });
321
-
322
- wx.login({
323
- success: async (res) => {
324
- if (res.code) {
325
- const result = await authClient.loginWithMiniProgram(res.code);
326
-
327
- wx.hideLoading();
328
-
329
- if (result.data) {
330
- this.setData({
331
- userInfo: result.data.user,
332
- });
333
-
334
- // Navigate to home
335
- wx.switchTab({ url: "/pages/index/index" });
336
- } else {
337
- wx.showToast({
338
- title: "Login failed",
339
- icon: "none",
340
- });
341
- }
342
- }
343
- },
344
- fail: () => {
345
- wx.hideLoading();
346
- wx.showToast({
347
- title: "Login failed",
348
- icon: "none",
349
- });
350
- },
351
- });
345
+ Taro.showLoading({ title: "Logging in..." });
346
+
347
+ const result = await authClient.miniLogin();
348
+
349
+ Taro.hideLoading();
350
+
351
+ if (result.data) {
352
+ this.setData({
353
+ userInfo: result.data.user,
354
+ });
355
+
356
+ // Navigate to home
357
+ Taro.switchTab({ url: "/pages/index/index" });
358
+ } else {
359
+ Taro.showToast({
360
+ title: "Login failed",
361
+ icon: "none",
362
+ });
363
+ }
352
364
  },
353
365
 
354
366
  // Get phone number with user authorization
@@ -356,30 +368,30 @@ Page({
356
368
  const { code } = e.detail;
357
369
 
358
370
  if (!code) {
359
- wx.showToast({
371
+ Taro.showToast({
360
372
  title: "Authorization cancelled",
361
373
  icon: "none",
362
374
  });
363
375
  return;
364
376
  }
365
377
 
366
- wx.showLoading({ title: "Getting phone..." });
378
+ Taro.showLoading({ title: "Getting phone..." });
367
379
 
368
- const result = await authClient.getMiniProgramPhoneNumber(code);
380
+ const result = await authClient.miniGetPhone(e);
369
381
 
370
- wx.hideLoading();
382
+ Taro.hideLoading();
371
383
 
372
384
  if (result.data) {
373
385
  this.setData({
374
386
  hasPhone: true,
375
387
  });
376
388
 
377
- wx.showToast({
389
+ Taro.showToast({
378
390
  title: "Phone number obtained",
379
391
  icon: "success",
380
392
  });
381
393
  } else {
382
- wx.showToast({
394
+ Taro.showToast({
383
395
  title: result.error?.message || "Failed to get phone",
384
396
  icon: "none",
385
397
  });
@@ -388,6 +400,13 @@ Page({
388
400
  });
389
401
  ```
390
402
 
403
+ **Low-level compatibility APIs (deprecated, advanced use only):**
404
+
405
+ If your app already has a login `code` or phone `code`, you can still call:
406
+
407
+ - `loginWithMiniProgram(code | { code, platform })`
408
+ - `getMiniProgramPhoneNumber(code | { code, platform })`
409
+
391
410
  ### Logout
392
411
 
393
412
  ```typescript
package/dist/auth.d.cts CHANGED
@@ -14,7 +14,7 @@
14
14
  * ============================================================================
15
15
  */
16
16
  import { HttpClient, ClientResult } from '@amaster.ai/http-client';
17
- import { q as User, i as RegisterParams, e as LoginResponse, L as LoginParams, c as CodeLoginParams, S as SendCodeParams, p as SuccessResponse, b as CaptchaResponse, g as OAuthProvider, M as MiniProgramPhoneResponse, R as RefreshTokenResponse } from './types-Cz0vVJqO.cjs';
17
+ import { w as User, o as RegisterParams, e as LoginResponse, L as LoginParams, c as CodeLoginParams, S as SendCodeParams, v as SuccessResponse, b as CaptchaResponse, m as OAuthProvider, i as MiniProgramLoginParams, h as MiniLoginParams, k as MiniProgramPhoneParams, l as MiniProgramPhoneResponse, g as MiniGetPhoneParams, R as RefreshTokenResponse } from './types-CsCZTBIx.cjs';
18
18
 
19
19
  /**
20
20
  * Authentication Module
@@ -135,50 +135,63 @@ declare function createAuthModule(deps: AuthModuleDeps): {
135
135
  */
136
136
  handleOAuthCallback(): Promise<ClientResult<LoginResponse>>;
137
137
  /**
138
- * Login with WeChat Mini Program code
138
+ * Login with Mini Program code
139
+ *
140
+ * Lower-level API for submitting an already acquired mini-program login code.
141
+ * For most app code, prefer `miniLogin()`.
142
+ *
143
+ * @deprecated Prefer `miniLogin()` unless you already have a resolved mini-program login code.
144
+ *
145
+ * @category Authentication
146
+ */
147
+ loginWithMiniProgram(input: string | MiniProgramLoginParams): Promise<ClientResult<LoginResponse>>;
148
+ /**
149
+ * Unified Mini Program login entry.
150
+ *
151
+ * Automatically calls Taro / WeChat `wx` / Douyin `tt` login APIs to fetch the temporary login code,
152
+ * then submits it to the backend using the correct platform endpoint.
139
153
  *
140
154
  * @category Authentication
141
155
  * @example
142
156
  * ```typescript
143
- * // In WeChat Mini Program
144
- * wx.login({
145
- * success: async (res) => {
146
- * if (res.code) {
147
- * const result = await auth.loginWithMiniProgram(res.code);
148
- * if (result.data) {
149
- * console.log("Logged in:", result.data.user);
150
- * }
151
- * }
152
- * }
157
+ * const result = await auth.miniLogin();
158
+ *
159
+ * const douyinResult = await auth.miniLogin({
160
+ * platform: "douyin",
153
161
  * });
154
162
  * ```
155
163
  */
156
- loginWithMiniProgram(code: string): Promise<ClientResult<LoginResponse>>;
164
+ miniLogin(params?: MiniLoginParams): Promise<ClientResult<LoginResponse>>;
157
165
  /**
158
- * Get WeChat Mini Program user phone number
166
+ * Get Mini Program user phone number
159
167
  * Requires user authorization via getPhoneNumber button
160
168
  *
169
+ * Lower-level API for submitting an already acquired phone code.
170
+ * For most app code, prefer `miniGetPhone(...)`.
171
+ *
172
+ * @deprecated Prefer `miniGetPhone(...)` unless you already have a resolved phone authorization code.
173
+ *
174
+ * @category Authentication
175
+ */
176
+ getMiniProgramPhoneNumber(input: string | MiniProgramPhoneParams): Promise<ClientResult<MiniProgramPhoneResponse>>;
177
+ /**
178
+ * Unified Mini Program phone binding entry.
179
+ *
180
+ * Accepts a raw code, a `{ code, platform }` object, or a Mini Program event object
181
+ * such as the payload received from WeChat `wx`, Douyin `tt`, or Taro `getPhoneNumber`.
182
+ *
161
183
  * @category Authentication
162
184
  * @example
163
185
  * ```typescript
164
- * // WXML
165
- * <button open-type="getPhoneNumber" bindgetphonenumber="onGetPhoneNumber">
166
- * Get Phone Number
167
- * </button>
168
- *
169
- * // JS
170
- * async onGetPhoneNumber(e) {
171
- * const { code } = e.detail;
172
- * if (code) {
173
- * const result = await auth.getMiniProgramPhoneNumber(code);
174
- * if (result.data) {
175
- * console.log("Phone:", result.data.phone);
176
- * }
177
- * }
178
- * }
186
+ * const result = await auth.miniGetPhone(e);
187
+ *
188
+ * const douyinResult = await auth.miniGetPhone({
189
+ * code,
190
+ * platform: "douyin",
191
+ * });
179
192
  * ```
180
193
  */
181
- getMiniProgramPhoneNumber(code: string): Promise<ClientResult<MiniProgramPhoneResponse>>;
194
+ miniGetPhone(input: MiniGetPhoneParams): Promise<ClientResult<MiniProgramPhoneResponse>>;
182
195
  /**
183
196
  * Logout current user
184
197
  *
package/dist/auth.d.ts CHANGED
@@ -14,7 +14,7 @@
14
14
  * ============================================================================
15
15
  */
16
16
  import { HttpClient, ClientResult } from '@amaster.ai/http-client';
17
- import { q as User, i as RegisterParams, e as LoginResponse, L as LoginParams, c as CodeLoginParams, S as SendCodeParams, p as SuccessResponse, b as CaptchaResponse, g as OAuthProvider, M as MiniProgramPhoneResponse, R as RefreshTokenResponse } from './types-Cz0vVJqO.js';
17
+ import { w as User, o as RegisterParams, e as LoginResponse, L as LoginParams, c as CodeLoginParams, S as SendCodeParams, v as SuccessResponse, b as CaptchaResponse, m as OAuthProvider, i as MiniProgramLoginParams, h as MiniLoginParams, k as MiniProgramPhoneParams, l as MiniProgramPhoneResponse, g as MiniGetPhoneParams, R as RefreshTokenResponse } from './types-CsCZTBIx.js';
18
18
 
19
19
  /**
20
20
  * Authentication Module
@@ -135,50 +135,63 @@ declare function createAuthModule(deps: AuthModuleDeps): {
135
135
  */
136
136
  handleOAuthCallback(): Promise<ClientResult<LoginResponse>>;
137
137
  /**
138
- * Login with WeChat Mini Program code
138
+ * Login with Mini Program code
139
+ *
140
+ * Lower-level API for submitting an already acquired mini-program login code.
141
+ * For most app code, prefer `miniLogin()`.
142
+ *
143
+ * @deprecated Prefer `miniLogin()` unless you already have a resolved mini-program login code.
144
+ *
145
+ * @category Authentication
146
+ */
147
+ loginWithMiniProgram(input: string | MiniProgramLoginParams): Promise<ClientResult<LoginResponse>>;
148
+ /**
149
+ * Unified Mini Program login entry.
150
+ *
151
+ * Automatically calls Taro / WeChat `wx` / Douyin `tt` login APIs to fetch the temporary login code,
152
+ * then submits it to the backend using the correct platform endpoint.
139
153
  *
140
154
  * @category Authentication
141
155
  * @example
142
156
  * ```typescript
143
- * // In WeChat Mini Program
144
- * wx.login({
145
- * success: async (res) => {
146
- * if (res.code) {
147
- * const result = await auth.loginWithMiniProgram(res.code);
148
- * if (result.data) {
149
- * console.log("Logged in:", result.data.user);
150
- * }
151
- * }
152
- * }
157
+ * const result = await auth.miniLogin();
158
+ *
159
+ * const douyinResult = await auth.miniLogin({
160
+ * platform: "douyin",
153
161
  * });
154
162
  * ```
155
163
  */
156
- loginWithMiniProgram(code: string): Promise<ClientResult<LoginResponse>>;
164
+ miniLogin(params?: MiniLoginParams): Promise<ClientResult<LoginResponse>>;
157
165
  /**
158
- * Get WeChat Mini Program user phone number
166
+ * Get Mini Program user phone number
159
167
  * Requires user authorization via getPhoneNumber button
160
168
  *
169
+ * Lower-level API for submitting an already acquired phone code.
170
+ * For most app code, prefer `miniGetPhone(...)`.
171
+ *
172
+ * @deprecated Prefer `miniGetPhone(...)` unless you already have a resolved phone authorization code.
173
+ *
174
+ * @category Authentication
175
+ */
176
+ getMiniProgramPhoneNumber(input: string | MiniProgramPhoneParams): Promise<ClientResult<MiniProgramPhoneResponse>>;
177
+ /**
178
+ * Unified Mini Program phone binding entry.
179
+ *
180
+ * Accepts a raw code, a `{ code, platform }` object, or a Mini Program event object
181
+ * such as the payload received from WeChat `wx`, Douyin `tt`, or Taro `getPhoneNumber`.
182
+ *
161
183
  * @category Authentication
162
184
  * @example
163
185
  * ```typescript
164
- * // WXML
165
- * <button open-type="getPhoneNumber" bindgetphonenumber="onGetPhoneNumber">
166
- * Get Phone Number
167
- * </button>
168
- *
169
- * // JS
170
- * async onGetPhoneNumber(e) {
171
- * const { code } = e.detail;
172
- * if (code) {
173
- * const result = await auth.getMiniProgramPhoneNumber(code);
174
- * if (result.data) {
175
- * console.log("Phone:", result.data.phone);
176
- * }
177
- * }
178
- * }
186
+ * const result = await auth.miniGetPhone(e);
187
+ *
188
+ * const douyinResult = await auth.miniGetPhone({
189
+ * code,
190
+ * platform: "douyin",
191
+ * });
179
192
  * ```
180
193
  */
181
- getMiniProgramPhoneNumber(code: string): Promise<ClientResult<MiniProgramPhoneResponse>>;
194
+ miniGetPhone(input: MiniGetPhoneParams): Promise<ClientResult<MiniProgramPhoneResponse>>;
182
195
  /**
183
196
  * Logout current user
184
197
  *
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- 'use strict';var httpClient=require('@amaster.ai/http-client');var S=class{constructor(){this.events={};}on(e,n){this.events[e]||(this.events[e]=[]),this.events[e].push(n);}off(e,n){this.events[e]&&(this.events[e]=this.events[e].filter(r=>r!==n));}emit(e,...n){this.events[e]&&this.events[e].forEach(r=>{try{r(...n);}catch(o){console.error(`[AuthClient] Error in event handler for "${e}":`,o);}});}removeAllListeners(){this.events={};}};var d={ACCESS_TOKEN:"amaster_access_token",REFRESH_TOKEN:"amaster_refresh_token",USER:"amaster_user"};function z(){return typeof wx<"u"&&wx.getStorageSync?"wechat-miniprogram":typeof tt<"u"&&tt.getStorageSync?"douyin-miniprogram":typeof window<"u"&&typeof window.localStorage<"u"?"browser":"node"}function P(){switch(z()){case "wechat-miniprogram":return T(wx,"WeChat");case "douyin-miniprogram":return T(tt,"Douyin");case "browser":return K();case "node":return j()}}function K(){let t=window.localStorage;return {getItem(e){try{return t.getItem(e)}catch(n){return console.error("[AuthClient] Failed to get item from localStorage:",n),null}},setItem(e,n){try{t.setItem(e,n);}catch(r){console.error("[AuthClient] Failed to set item in localStorage:",r);}},removeItem(e){try{t.removeItem(e);}catch(n){console.error("[AuthClient] Failed to remove item from localStorage:",n);}},clear(){try{t.removeItem(d.ACCESS_TOKEN),t.removeItem(d.REFRESH_TOKEN),t.removeItem(d.USER);}catch(e){console.error("[AuthClient] Failed to clear localStorage:",e);}}}}function T(t,e){return {getItem(n){try{return t.getStorageSync(n)||null}catch(r){return console.error(`[AuthClient] Failed to get item from ${e} storage:`,r),null}},setItem(n,r){try{t.setStorageSync(n,r);}catch(o){console.error(`[AuthClient] Failed to set item in ${e} storage:`,o);}},removeItem(n){try{t.removeStorageSync(n);}catch(r){console.error(`[AuthClient] Failed to remove item from ${e} storage:`,r);}},clear(){try{t.removeStorageSync(d.ACCESS_TOKEN),t.removeStorageSync(d.REFRESH_TOKEN),t.removeStorageSync(d.USER);}catch(n){console.error(`[AuthClient] Failed to clear ${e} storage:`,n);}}}}function j(){let t=new Map;return {getItem(e){return t.get(e)??null},setItem(e,n){t.set(e,n);},removeItem(e){t.delete(e);},clear(){t.clear();}}}function D(t){try{let e=t.split(".");if(e.length!==3)return null;let r=(e[1]||"").replace(/-/g,"+").replace(/_/g,"/");if(typeof atob<"u"){let o=decodeURIComponent(atob(r).split("").map(l=>"%"+("00"+l.charCodeAt(0).toString(16)).slice(-2)).join(""));return JSON.parse(o)}if(typeof Buffer<"u"){let o=Buffer.from(r,"base64").toString("utf-8");return JSON.parse(o)}return null}catch(e){return console.error("[AuthClient] Failed to parse JWT token:",e),null}}var v=class{constructor(){this.refreshTimer=null;this.isRefreshing=false;this.refreshCallback=null;}setRefreshCallback(e){this.refreshCallback=e;}scheduleRefresh(e){this.clearSchedule(),!(e<=0)&&(this.refreshTimer=setTimeout(()=>{this.refresh();},e));}scheduleRefreshFromToken(e,n=300){let r=D(e);if(!r||!r.exp){console.warn("[AuthClient] Cannot schedule refresh: invalid token or missing exp claim");return}let o=r.exp*1e3,l=Date.now(),a=o-l-n*1e3;a<=0?(console.warn("[AuthClient] Token already expired or expiring soon, refreshing immediately"),this.refresh()):this.scheduleRefresh(a);}async refresh(){if(!this.isRefreshing){if(!this.refreshCallback){console.error("[AuthClient] No refresh callback set");return}this.isRefreshing=true;try{await this.refreshCallback();}catch(e){console.error("[AuthClient] Token refresh failed:",e);}finally{this.isRefreshing=false;}}}clearSchedule(){this.refreshTimer&&(clearTimeout(this.refreshTimer),this.refreshTimer=null);}isCurrentlyRefreshing(){return this.isRefreshing}destroy(){this.clearSchedule(),this.refreshCallback=null,this.isRefreshing=false;}};function E(t){return t&&typeof t=="object"&&("statusCode"in t||"status"in t)&&"data"in t?t.data:t}var k={transformResponse:E,logErrors:true};function J(t){if(t.email)return "email";if(t.username)return "username";if(t.phone)return "phone"}function W(t){if(t.email)return "email";if(t.phone)return "phone"}function G(t){let e=new URLSearchParams(t);return e.get("access_token")||e.get("accessToken")}function Y(t){return new URLSearchParams(t).get("user")}function Q(){if(typeof window>"u")return null;try{let t=new URLSearchParams(window.location.search).get("redirect");if(!t)return null;let e=new URL(t,window.location.origin);return e.origin!==window.location.origin?(console.warn("[AuthClient] Ignored cross-origin redirect target:",t),null):`${e.pathname}${e.search}${e.hash}`}catch(t){return console.warn("[AuthClient] Failed to resolve redirect target:",t),null}}var V={replace(t){window.location.replace(t);}};function R(t,e){return e.handled?{...t,redirectHandled:true,redirectTarget:e.target}:t}function A(t){if(!t||typeof window>"u"||window.opener)return {handled:false};let e=Q();return e?(V.replace(e),{handled:true,target:e}):{handled:false}}function O(t){let{http:e,onLoginSuccess:n,onLogout:r,autoRedirectAfterLogin:o,storage:l,clearAuth:m}=t;return {async register(a){let s=await e.request({url:"/api/auth/register",method:"post",headers:{"Content-Type":"application/json"},data:a});if(s.data?.user&&s.data?.accessToken){n(s.data.user,s.data.accessToken);let h=A(o);s.data=R(s.data,h);}return s},async login(a){let s=a.loginType||J(a);if(!s)return {data:null,error:{message:"Unable to determine login type. Please provide email, username, or phone.",status:400},status:400};let h={...a,loginType:s},u=await e.request({url:"/api/auth/login",method:"post",headers:{"Content-Type":"application/json"},data:h});if(u.data?.user&&u.data?.accessToken){n(u.data.user,u.data.accessToken);let c=A(o);u.data=R(u.data,c);}return u},async loginWithCode(a){let s=a.loginType||W(a);if(!s)return {data:null,error:{message:"Unable to determine login type. Please provide email or phone.",status:400},status:400};let h={...a,loginType:s},u=await e.request({url:"/api/auth/login-with-code",method:"post",headers:{"Content-Type":"application/json"},data:h});if(u.data?.user&&u.data?.accessToken){n(u.data.user,u.data.accessToken);let c=A(o);u.data=R(u.data,c);}return u},async sendCode(a){return e.request({url:"/api/auth/send-code",method:"post",headers:{"Content-Type":"application/json"},data:a})},async getCaptcha(){return e.request({url:"/api/auth/captcha",method:"get"})},loginWithOAuth(a,s){if(typeof window>"u"){console.error("[AuthClient] OAuth login is only available in browser environment");return}let h=s?`/api/auth/oauth/${a}?redirect_url=${encodeURIComponent(s)}`:`/api/auth/oauth/${a}`;window.location.href=h;},async handleOAuthCallback(){if(typeof window>"u")return {data:null,error:{message:"OAuth callback is only available in browser environment",status:400},status:400};try{let a=window.location.hash.substring(1),s=G(a),h=Y(a);if(!s)return {data:null,error:{message:"OAuth callback failed: missing access token",status:400},status:400};let u;if(h)u=JSON.parse(decodeURIComponent(h));else {l.setItem(d.ACCESS_TOKEN,s);let p=await e.request({url:"/api/auth/me",method:"get",headers:{Authorization:`Bearer ${s}`}});if(!p.data)return {data:null,error:{message:"OAuth callback failed: unable to fetch user info",status:p.status||500},status:p.status||500};u=p.data;}if(n(u,s),window.history&&window.history.replaceState){let p=window.location.pathname+window.location.search;window.history.replaceState(null,"",p);}else window.location.hash="";let c=A(o);return {data:R({user:u,accessToken:s},c),error:null,status:200}}catch(a){return {data:null,error:{message:`OAuth callback failed: ${a instanceof Error?a.message:String(a)}`,status:400},status:400}}},async loginWithMiniProgram(a){let s=await e.request({url:"/api/auth/miniprogram/login",method:"post",headers:{"Content-Type":"application/json"},data:{code:a}});if(s.data?.user&&s.data?.accessToken){n(s.data.user,s.data.accessToken);let h=A(o);s.data=R(s.data,h);}return s},async getMiniProgramPhoneNumber(a){let s=l.getItem("amaster_access_token");return s?e.request({url:"/api/auth/miniprogram/phone",method:"post",headers:{"Content-Type":"application/json",Authorization:`Bearer ${s}`},data:{code:a}}):{data:null,error:{message:"Not authenticated",status:401},status:401}},async logout(){let a=l.getItem("amaster_access_token"),s=await e.request({url:"/api/auth/logout",method:"post",headers:a?{Authorization:`Bearer ${a}`}:void 0});return m(),r(),s},async refreshToken(){let a=await e.request({url:"/api/auth/refresh",method:"post"});return a.data?.accessToken&&l.setItem("amaster_access_token",a.data.accessToken),a}}}function b(t){let{getCurrentUser:e}=t;return {hasRole(n){let r=e();return !r||!r.roles?false:r.roles.includes(n)},hasPermission(n,r){let o=e();if(!o||!o.permissions)return false;let l=`${n}.${r}`;return o.permissions.includes(l)},hasAnyPermission(n){return n.some(({resource:r,action:o})=>this.hasPermission(r,o))},hasAllPermissions(n){return n.every(({resource:r,action:o})=>this.hasPermission(r,o))}}}function M(t){let{http:e,storage:n,onUserUpdate:r}=t;return {async getMe(){let o=n.getItem("amaster_access_token");if(!o)return {data:null,error:{message:"Not authenticated",status:401},status:401};let l=await e.request({url:"/api/auth/me",method:"get",headers:{Authorization:`Bearer ${o}`}});return l.data&&r(l.data),l},async updateMe(o){let l=n.getItem("amaster_access_token");if(!l)return {data:null,error:{message:"Not authenticated",status:401},status:401};let m=await e.request({url:"/api/auth/me",method:"put",headers:{Authorization:`Bearer ${l}`,"Content-Type":"application/json"},data:o});return m.data&&r(m.data),m},async changePassword(o){let l=n.getItem("amaster_access_token");return l?e.request({url:"/api/auth/change-password",method:"post",headers:{Authorization:`Bearer ${l}`,"Content-Type":"application/json"},data:o}):{data:null,error:{message:"Not authenticated",status:401},status:401}}}}function U(t){let{http:e,storage:n}=t;return {async getOAuthBindings(){let r=n.getItem("amaster_access_token");return r?e.request({url:"/api/auth/oauth-bindings",method:"get",headers:{Authorization:`Bearer ${r}`}}):{data:null,error:{message:"Not authenticated",status:401},status:401}},bindOAuth(r){if(typeof window>"u"){console.error("[AuthClient] OAuth binding is only available in browser environment");return}window.location.href=`/api/auth/oauth/${r}/bind`;},async unbindOAuth(r){let o=n.getItem("amaster_access_token");return o?e.request({url:`/api/auth/oauth/${r}/unbind`,method:"delete",headers:{Authorization:`Bearer ${o}`}}):{data:null,error:{message:"Not authenticated",status:401},status:401}}}}function I(t){let{http:e,storage:n}=t;return {async getSession(){let r=n.getItem("amaster_access_token");return r?e.request({url:"/api/auth/sessions/current",method:"get",headers:{Authorization:`Bearer ${r}`}}):{data:null,error:{message:"Not authenticated",status:401},status:401}},async getSessions(){let r=n.getItem("amaster_access_token");return r?e.request({url:"/api/auth/sessions",method:"get",headers:{Authorization:`Bearer ${r}`}}):{data:null,error:{message:"Not authenticated",status:401},status:401}},async revokeSession(r){let o=n.getItem("amaster_access_token");return o?r?e.request({url:`/api/auth/sessions/${r}`,method:"delete",headers:{Authorization:`Bearer ${o}`}}):{data:null,error:{message:"Session ID is required",status:400},status:400}:{data:null,error:{message:"Not authenticated",status:401},status:401}},async revokeAllSessions(){let r=n.getItem("amaster_access_token");return r?e.request({url:"/api/auth/sessions",method:"delete",headers:{Authorization:`Bearer ${r}`}}):{data:null,error:{message:"Not authenticated",status:401},status:401}}}}function Z(t={},e){let {baseURL:n,headers:r,onTokenExpired:o,onUnauthorized:l,autoHandleOAuthCallback:m=true,autoRedirectAfterLogin:a=true}=t,s=e||httpClient.createHttpClient({...k,baseURL:n,headers:r}),u=300,c=P(),p=new S,C=new v,y=null;try{let i=c.getItem(d.USER);i&&(y=JSON.parse(i));}catch(i){console.error("[AuthClient] Failed to load user from storage:",i);}let f;C.setRefreshCallback(async()=>{let i=await f.refreshToken();i.data?(await f.getMe(),p.emit("tokenRefreshed",i.data.accessToken)):(p.emit("tokenExpired"),o?.());});function L(i,g){c.setItem(d.ACCESS_TOKEN,g),c.setItem(d.USER,JSON.stringify(i)),y=i,C.scheduleRefreshFromToken(g,u),p.emit("login",i);}function _(i){y=i,c.setItem(d.USER,JSON.stringify(i));}function x(){p.emit("logout");}function w(){c.clear(),y=null,C.clearSchedule();}function H(){return y}let N=O({http:s,onLoginSuccess:L,onLogout:x,autoRedirectAfterLogin:a,storage:c,clearAuth:w}),$=b({getCurrentUser:H}),q=M({http:s,storage:c,onUserUpdate:_}),B=U({http:s,storage:c}),F=I({http:s,storage:c});if(f={...N,...$,...q,...B,...F,on(i,g){p.on(i,g);},off(i,g){p.off(i,g);},isAuthenticated(){return !!c.getItem(d.ACCESS_TOKEN)},getAccessToken(){return c.getItem(d.ACCESS_TOKEN)},setAccessToken(i){c.setItem(d.ACCESS_TOKEN,i),C.scheduleRefreshFromToken(i,u);},clearAuth:w},f.on("unauthorized",()=>{l?.();}),f.isAuthenticated()&&f.getMe().catch(i=>{console.warn("[AuthClient] Failed to sync user info on init:",i);}),m&&typeof window<"u"){let i=window.location.hash;i&&(i.includes("access_token")||i.includes("accessToken"))&&f.handleOAuthCallback().then(g=>{g.error&&console.error("[AuthClient] Auto OAuth callback failed:",g.error);}).catch(g=>{console.error("[AuthClient] Auto OAuth callback error:",g);});}return f}exports.createAuthClient=Z;exports.defaultHttpClientOptions=k;exports.transformAmasterResponse=E;//# sourceMappingURL=index.cjs.map
1
+ 'use strict';var httpClient=require('@amaster.ai/http-client');var C=class{constructor(){this.events={};}on(e,r){this.events[e]||(this.events[e]=[]),this.events[e].push(r);}off(e,r){this.events[e]&&(this.events[e]=this.events[e].filter(n=>n!==r));}emit(e,...r){this.events[e]&&this.events[e].forEach(n=>{try{n(...r);}catch(i){console.error(`[AuthClient] Error in event handler for "${e}":`,i);}});}removeAllListeners(){this.events={};}};var h={ACCESS_TOKEN:"amaster_access_token",REFRESH_TOKEN:"amaster_refresh_token",USER:"amaster_user"};function J(){return typeof wx<"u"&&wx.getStorageSync?"wechat-miniprogram":typeof tt<"u"&&tt.getStorageSync?"douyin-miniprogram":typeof window<"u"&&typeof window.localStorage<"u"?"browser":"node"}function E(){switch(J()){case "wechat-miniprogram":return M(wx,"WeChat");case "douyin-miniprogram":return M(tt,"Douyin");case "browser":return G();case "node":return W()}}function G(){let t=window.localStorage;return {getItem(e){try{return t.getItem(e)}catch(r){return console.error("[AuthClient] Failed to get item from localStorage:",r),null}},setItem(e,r){try{t.setItem(e,r);}catch(n){console.error("[AuthClient] Failed to set item in localStorage:",n);}},removeItem(e){try{t.removeItem(e);}catch(r){console.error("[AuthClient] Failed to remove item from localStorage:",r);}},clear(){try{t.removeItem(h.ACCESS_TOKEN),t.removeItem(h.REFRESH_TOKEN),t.removeItem(h.USER);}catch(e){console.error("[AuthClient] Failed to clear localStorage:",e);}}}}function M(t,e){return {getItem(r){try{return t.getStorageSync(r)||null}catch(n){return console.error(`[AuthClient] Failed to get item from ${e} storage:`,n),null}},setItem(r,n){try{t.setStorageSync(r,n);}catch(i){console.error(`[AuthClient] Failed to set item in ${e} storage:`,i);}},removeItem(r){try{t.removeStorageSync(r);}catch(n){console.error(`[AuthClient] Failed to remove item from ${e} storage:`,n);}},clear(){try{t.removeStorageSync(h.ACCESS_TOKEN),t.removeStorageSync(h.REFRESH_TOKEN),t.removeStorageSync(h.USER);}catch(r){console.error(`[AuthClient] Failed to clear ${e} storage:`,r);}}}}function W(){let t=new Map;return {getItem(e){return t.get(e)??null},setItem(e,r){t.set(e,r);},removeItem(e){t.delete(e);},clear(){t.clear();}}}function Y(t){try{let e=t.split(".");if(e.length!==3)return null;let n=(e[1]||"").replace(/-/g,"+").replace(/_/g,"/");if(typeof atob<"u"){let i=decodeURIComponent(atob(n).split("").map(u=>"%"+("00"+u.charCodeAt(0).toString(16)).slice(-2)).join(""));return JSON.parse(i)}if(typeof Buffer<"u"){let i=Buffer.from(n,"base64").toString("utf-8");return JSON.parse(i)}return null}catch(e){return console.error("[AuthClient] Failed to parse JWT token:",e),null}}var v=class{constructor(){this.refreshTimer=null;this.isRefreshing=false;this.refreshCallback=null;}setRefreshCallback(e){this.refreshCallback=e;}scheduleRefresh(e){this.clearSchedule(),!(e<=0)&&(this.refreshTimer=setTimeout(()=>{this.refresh();},e));}scheduleRefreshFromToken(e,r=300){let n=Y(e);if(!n||!n.exp){console.warn("[AuthClient] Cannot schedule refresh: invalid token or missing exp claim");return}let i=n.exp*1e3,u=Date.now(),o=i-u-r*1e3;o<=0?(console.warn("[AuthClient] Token already expired or expiring soon, refreshing immediately"),this.refresh()):this.scheduleRefresh(o);}async refresh(){if(!this.isRefreshing){if(!this.refreshCallback){console.error("[AuthClient] No refresh callback set");return}this.isRefreshing=true;try{await this.refreshCallback();}catch(e){console.error("[AuthClient] Token refresh failed:",e);}finally{this.isRefreshing=false;}}}clearSchedule(){this.refreshTimer&&(clearTimeout(this.refreshTimer),this.refreshTimer=null);}isCurrentlyRefreshing(){return this.isRefreshing}destroy(){this.clearSchedule(),this.refreshCallback=null,this.isRefreshing=false;}};function b(t){return t&&typeof t=="object"&&("statusCode"in t||"status"in t)&&"data"in t?t.data:t}var w={transformResponse:b,logErrors:true};function V(t){if(t.email)return "email";if(t.username)return "username";if(t.phone)return "phone"}function Q(t){if(t.email)return "email";if(t.phone)return "phone"}function O(t){return typeof globalThis<"u"&&typeof globalThis[t]<"u"}function S(t){if(t)return t;let e=typeof globalThis<"u"?globalThis.Taro:void 0,r=e?.getEnv?.(),n=e?.ENV_TYPE;return n&&r===n.TT?"douyin":n&&r===n.WEAPP?"wechat":O("tt")?"douyin":("wechat")}function k(t){return typeof t=="string"?{code:t,platform:S()}:{code:t.code,platform:S(t.platform)}}function U(t,e){return e==="douyin"?`/api/auth/miniprogram/douyin/${t}`:`/api/auth/miniprogram/${t}`}async function X(t){let e=S(t),r=typeof globalThis<"u"?globalThis.Taro:void 0;if(typeof r?.login=="function"){let u=await r.login();if(typeof u?.code=="string"&&u.code)return {code:u.code,platform:e};throw new Error("Mini Program login failed: missing code")}let i=typeof globalThis<"u"?globalThis[e==="douyin"?"tt":"wx"]:void 0;if(typeof i?.login!="function")throw new Error(`Mini Program login API is not available for platform '${e}'`);return new Promise((u,m)=>{i.login?.({success:o=>{if(typeof o?.code=="string"&&o.code){u({code:o.code,platform:e});return}m(new Error("Mini Program login failed: missing code"));},fail:o=>{m(new Error(`Mini Program login failed: ${o instanceof Error?o.message:String(o)}`));}});})}function Z(t){if(typeof t=="string")return k(t);let e="detail"in t&&t.detail&&typeof t.detail=="object"?t.detail:null,r=typeof e?.code=="string"&&e.code?e.code:typeof t.code=="string"&&t.code?t.code:void 0;return r?{code:r,platform:S(t.platform)}:null}function ee(t){let e=new URLSearchParams(t);return e.get("access_token")||e.get("accessToken")}function te(t){return new URLSearchParams(t).get("user")}function re(){if(typeof window>"u")return null;try{let t=new URLSearchParams(window.location.search).get("redirect");if(!t)return null;let e=new URL(t,window.location.origin);return e.origin!==window.location.origin?(console.warn("[AuthClient] Ignored cross-origin redirect target:",t),null):`${e.pathname}${e.search}${e.hash}`}catch(t){return console.warn("[AuthClient] Failed to resolve redirect target:",t),null}}var ne={replace(t){window.location.replace(t);}};function P(t,e){return e.handled?{...t,redirectHandled:true,redirectTarget:e.target}:t}function R(t){if(!t||typeof window>"u"||window.opener)return {handled:false};let e=re();return e?(ne.replace(e),{handled:true,target:e}):{handled:false}}function L(t){let{http:e,onLoginSuccess:r,onLogout:n,autoRedirectAfterLogin:i,storage:u,clearAuth:m}=t;return {async register(o){let s=await e.request({url:"/api/auth/register",method:"post",headers:{"Content-Type":"application/json"},data:o});if(s.data?.user&&s.data?.accessToken){r(s.data.user,s.data.accessToken);let d=R(i);s.data=P(s.data,d);}return s},async login(o){let s=o.loginType||V(o);if(!s)return {data:null,error:{message:"Unable to determine login type. Please provide email, username, or phone.",status:400},status:400};let d={...o,loginType:s},a=await e.request({url:"/api/auth/login",method:"post",headers:{"Content-Type":"application/json"},data:d});if(a.data?.user&&a.data?.accessToken){r(a.data.user,a.data.accessToken);let c=R(i);a.data=P(a.data,c);}return a},async loginWithCode(o){let s=o.loginType||Q(o);if(!s)return {data:null,error:{message:"Unable to determine login type. Please provide email or phone.",status:400},status:400};let d={...o,loginType:s},a=await e.request({url:"/api/auth/login-with-code",method:"post",headers:{"Content-Type":"application/json"},data:d});if(a.data?.user&&a.data?.accessToken){r(a.data.user,a.data.accessToken);let c=R(i);a.data=P(a.data,c);}return a},async sendCode(o){return e.request({url:"/api/auth/send-code",method:"post",headers:{"Content-Type":"application/json"},data:o})},async getCaptcha(){return e.request({url:"/api/auth/captcha",method:"get"})},loginWithOAuth(o,s){if(typeof window>"u"){console.error("[AuthClient] OAuth login is only available in browser environment");return}let d=s?`/api/auth/oauth/${o}?redirect_url=${encodeURIComponent(s)}`:`/api/auth/oauth/${o}`;window.location.href=d;},async handleOAuthCallback(){if(typeof window>"u")return {data:null,error:{message:"OAuth callback is only available in browser environment",status:400},status:400};try{let o=window.location.hash.substring(1),s=ee(o),d=te(o);if(!s)return {data:null,error:{message:"OAuth callback failed: missing access token",status:400},status:400};let a;if(d)a=JSON.parse(decodeURIComponent(d));else {u.setItem(h.ACCESS_TOKEN,s);let g=await e.request({url:"/api/auth/me",method:"get",headers:{Authorization:`Bearer ${s}`}});if(!g.data)return {data:null,error:{message:"OAuth callback failed: unable to fetch user info",status:g.status||500},status:g.status||500};a=g.data;}if(r(a,s),window.history&&window.history.replaceState){let g=window.location.pathname+window.location.search;window.history.replaceState(null,"",g);}else window.location.hash="";let c=R(i);return {data:P({user:a,accessToken:s},c),error:null,status:200}}catch(o){return {data:null,error:{message:`OAuth callback failed: ${o instanceof Error?o.message:String(o)}`,status:400},status:400}}},async loginWithMiniProgram(o){let{code:s,platform:d}=k(o),a=await e.request({url:U("login",d),method:"post",headers:{"Content-Type":"application/json"},data:{code:s}});if(a.data?.user&&a.data?.accessToken){r(a.data.user,a.data.accessToken);let c=R(i);a.data=P(a.data,c);}return a},async miniLogin(o={}){try{let s=await X(o.platform);return await this.loginWithMiniProgram(s)}catch(s){return {data:null,error:{message:s instanceof Error?s.message:String(s),status:400},status:400}}},async getMiniProgramPhoneNumber(o){let{code:s,platform:d}=k(o),a=u.getItem(h.ACCESS_TOKEN);return a?e.request({url:U("phone",d),method:"post",headers:{"Content-Type":"application/json",Authorization:`Bearer ${a}`},data:{code:s}}):{data:null,error:{message:"Not authenticated",status:401},status:401}},async miniGetPhone(o){let s=Z(o);return s?this.getMiniProgramPhoneNumber(s):{data:null,error:{message:"Unable to resolve mini-program phone code from input",status:400},status:400}},async logout(){let o=u.getItem("amaster_access_token"),s=await e.request({url:"/api/auth/logout",method:"post",headers:o?{Authorization:`Bearer ${o}`}:void 0});return m(),n(),s},async refreshToken(){let o=await e.request({url:"/api/auth/refresh",method:"post"});return o.data?.accessToken&&u.setItem("amaster_access_token",o.data.accessToken),o}}}function I(t){let{getCurrentUser:e}=t;return {hasRole(r){let n=e();return !n||!n.roles?false:n.roles.includes(r)},hasPermission(r,n){let i=e();if(!i||!i.permissions)return false;let u=`${r}.${n}`;return i.permissions.includes(u)},hasAnyPermission(r){return r.some(({resource:n,action:i})=>this.hasPermission(n,i))},hasAllPermissions(r){return r.every(({resource:n,action:i})=>this.hasPermission(n,i))}}}function _(t){let{http:e,storage:r,onUserUpdate:n}=t;return {async getMe(){let i=r.getItem("amaster_access_token");if(!i)return {data:null,error:{message:"Not authenticated",status:401},status:401};let u=await e.request({url:"/api/auth/me",method:"get",headers:{Authorization:`Bearer ${i}`}});return u.data&&n(u.data),u},async updateMe(i){let u=r.getItem("amaster_access_token");if(!u)return {data:null,error:{message:"Not authenticated",status:401},status:401};let m=await e.request({url:"/api/auth/me",method:"put",headers:{Authorization:`Bearer ${u}`,"Content-Type":"application/json"},data:i});return m.data&&n(m.data),m},async changePassword(i){let u=r.getItem("amaster_access_token");return u?e.request({url:"/api/auth/change-password",method:"post",headers:{Authorization:`Bearer ${u}`,"Content-Type":"application/json"},data:i}):{data:null,error:{message:"Not authenticated",status:401},status:401}}}}function x(t){let{http:e,storage:r}=t;return {async getOAuthBindings(){let n=r.getItem("amaster_access_token");return n?e.request({url:"/api/auth/oauth-bindings",method:"get",headers:{Authorization:`Bearer ${n}`}}):{data:null,error:{message:"Not authenticated",status:401},status:401}},bindOAuth(n){if(typeof window>"u"){console.error("[AuthClient] OAuth binding is only available in browser environment");return}window.location.href=`/api/auth/oauth/${n}/bind`;},async unbindOAuth(n){let i=r.getItem("amaster_access_token");return i?e.request({url:`/api/auth/oauth/${n}/unbind`,method:"delete",headers:{Authorization:`Bearer ${i}`}}):{data:null,error:{message:"Not authenticated",status:401},status:401}}}}function H(t){let{http:e,storage:r}=t;return {async getSession(){let n=r.getItem("amaster_access_token");return n?e.request({url:"/api/auth/sessions/current",method:"get",headers:{Authorization:`Bearer ${n}`}}):{data:null,error:{message:"Not authenticated",status:401},status:401}},async getSessions(){let n=r.getItem("amaster_access_token");return n?e.request({url:"/api/auth/sessions",method:"get",headers:{Authorization:`Bearer ${n}`}}):{data:null,error:{message:"Not authenticated",status:401},status:401}},async revokeSession(n){let i=r.getItem("amaster_access_token");return i?n?e.request({url:`/api/auth/sessions/${n}`,method:"delete",headers:{Authorization:`Bearer ${i}`}}):{data:null,error:{message:"Session ID is required",status:400},status:400}:{data:null,error:{message:"Not authenticated",status:401},status:401}},async revokeAllSessions(){let n=r.getItem("amaster_access_token");return n?e.request({url:"/api/auth/sessions",method:"delete",headers:{Authorization:`Bearer ${n}`}}):{data:null,error:{message:"Not authenticated",status:401},status:401}}}}function se(t={},e){let {baseURL:r,headers:n,onTokenExpired:i,onUnauthorized:u,autoHandleOAuthCallback:m=true,autoRedirectAfterLogin:o=true}=t,s=e||httpClient.createHttpClient({...w,baseURL:r,headers:n}),a=300,c=E(),g=new C,A=new v,y=null;try{let l=c.getItem(h.USER);l&&(y=JSON.parse(l));}catch(l){console.error("[AuthClient] Failed to load user from storage:",l);}let f;A.setRefreshCallback(async()=>{let l=await f.refreshToken();l.data?(await f.getMe(),g.emit("tokenRefreshed",l.data.accessToken)):(g.emit("tokenExpired"),i?.());});function N(l,p){c.setItem(h.ACCESS_TOKEN,p),c.setItem(h.USER,JSON.stringify(l)),y=l,A.scheduleRefreshFromToken(p,a),g.emit("login",l);}function $(l){y=l,c.setItem(h.USER,JSON.stringify(l));}function q(){g.emit("logout");}function T(){c.clear(),y=null,A.clearSchedule();}function B(){return y}let F=L({http:s,onLoginSuccess:N,onLogout:q,autoRedirectAfterLogin:o,storage:c,clearAuth:T}),z=I({getCurrentUser:B}),K=_({http:s,storage:c,onUserUpdate:$}),D=x({http:s,storage:c}),j=H({http:s,storage:c});if(f={...F,...z,...K,...D,...j,on(l,p){g.on(l,p);},off(l,p){g.off(l,p);},isAuthenticated(){return !!c.getItem(h.ACCESS_TOKEN)},getAccessToken(){return c.getItem(h.ACCESS_TOKEN)},setAccessToken(l){c.setItem(h.ACCESS_TOKEN,l),A.scheduleRefreshFromToken(l,a);},clearAuth:T},f.on("unauthorized",()=>{u?.();}),f.isAuthenticated()&&f.getMe().catch(l=>{console.warn("[AuthClient] Failed to sync user info on init:",l);}),m&&typeof window<"u"){let l=window.location.hash;l&&(l.includes("access_token")||l.includes("accessToken"))&&f.handleOAuthCallback().then(p=>{p.error&&console.error("[AuthClient] Auto OAuth callback failed:",p.error);}).catch(p=>{console.error("[AuthClient] Auto OAuth callback error:",p);});}return f}exports.createAuthClient=se;exports.defaultHttpClientOptions=w;exports.transformAmasterResponse=b;//# sourceMappingURL=index.cjs.map
2
2
  //# sourceMappingURL=index.cjs.map