@mitumba/sdk 1.18.0 → 1.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -972,6 +972,14 @@ declare class APIClient {
972
972
  private refreshPromise;
973
973
  constructor(config: MitumbaClientConfig);
974
974
  setToken(token: string, refreshToken?: string): Promise<void>;
975
+ /**
976
+ * Set both tokens explicitly. Requires a valid refresh token.
977
+ * Preferred over setToken() to avoid dropping the refresh token.
978
+ */
979
+ setSession(tokens: {
980
+ access_token: string;
981
+ refresh_token: string;
982
+ }): Promise<void>;
975
983
  getToken(): string | undefined;
976
984
  getBaseUrl(): string;
977
985
  clearToken(): Promise<void>;
@@ -998,13 +1006,13 @@ declare class AuthModule {
998
1006
  constructor(client: APIClient);
999
1007
  /**
1000
1008
  * Register a new account.
1001
- * If using EmailRegisterInput, returns AuthTokens.
1009
+ * If using EmailRegisterInput, returns AuthTokens (auto-persisted).
1002
1010
  * If using PhoneRegisterInput, returns MessageResponse (OTP sent).
1003
1011
  */
1004
1012
  register(input: RegisterInput, options?: RequestOptions): Promise<AuthTokens | MessageResponse>;
1005
1013
  /**
1006
1014
  * Log in to an existing account.
1007
- * If using EmailLoginInput, returns AuthTokens (or TwoFactorRequired if 2FA enabled).
1015
+ * If using EmailLoginInput, returns AuthTokens (auto-persisted) or TwoFactorRequired.
1008
1016
  * If using PhoneLoginInput, returns MessageResponse (OTP sent).
1009
1017
  */
1010
1018
  login(input: LoginInput, options?: RequestOptions): Promise<AuthTokens | MessageResponse | TwoFactorRequired>;
@@ -1013,7 +1021,7 @@ declare class AuthModule {
1013
1021
  */
1014
1022
  sendOtp(input: SendOtpInput, options?: RequestOptions): Promise<MessageResponse>;
1015
1023
  /**
1016
- * Verify an OTP code.
1024
+ * Verify an OTP code. Tokens are auto-persisted.
1017
1025
  */
1018
1026
  verifyOtp(input: VerifyOtpInput, options?: RequestOptions): Promise<AuthTokens>;
1019
1027
  /**
@@ -1023,7 +1031,7 @@ declare class AuthModule {
1023
1031
  refresh_token: string;
1024
1032
  }, options?: RequestOptions): Promise<AuthTokens>;
1025
1033
  /**
1026
- * Revoke the refresh token and log out.
1034
+ * Revoke the refresh token and log out. Clears stored session.
1027
1035
  */
1028
1036
  logout(input: {
1029
1037
  refresh_token: string;
@@ -1032,7 +1040,6 @@ declare class AuthModule {
1032
1040
  }>;
1033
1041
  /**
1034
1042
  * Request a password reset email.
1035
- * Sends a reset link to the provided email address.
1036
1043
  */
1037
1044
  forgotPassword(input: ForgotPasswordInput, options?: RequestOptions): Promise<MessageResponse>;
1038
1045
  /**
@@ -1050,26 +1057,23 @@ declare class AuthModule {
1050
1057
  ok: true;
1051
1058
  }>;
1052
1059
  /**
1053
- * Verify 2FA code during login (when login returns requires_2fa).
1060
+ * Verify 2FA code during login. Tokens are auto-persisted.
1054
1061
  */
1055
1062
  verify2FA(input: Verify2FAInput, options?: RequestOptions): Promise<AuthTokens>;
1056
1063
  /**
1057
1064
  * Send a verification code to the user's email.
1058
- * If unauthenticated, pass the email address.
1059
1065
  */
1060
1066
  sendVerificationCode(email?: string, options?: RequestOptions): Promise<{
1061
1067
  ok: true;
1062
1068
  }>;
1063
1069
  /**
1064
1070
  * Verify the email with the 6-digit code.
1065
- * If unauthenticated, pass the email address.
1066
1071
  */
1067
1072
  verifyEmail(code: string, email?: string, options?: RequestOptions): Promise<{
1068
1073
  ok: true;
1069
1074
  }>;
1070
1075
  /**
1071
1076
  * Upgrade the current user to a seller role.
1072
- * Idempotent — returns success if already a seller.
1073
1077
  */
1074
1078
  becomeSeller(input: BecomeSellerInput, options?: RequestOptions): Promise<{
1075
1079
  ok: true;
@@ -1927,6 +1931,13 @@ declare class MitumbaClient {
1927
1931
  * Optionally pass a refresh token to enable automatic token rotation.
1928
1932
  */
1929
1933
  setToken(token: string, refreshToken?: string): void;
1934
+ /**
1935
+ * Set both tokens explicitly. Preferred — prevents dropping the refresh token.
1936
+ */
1937
+ setSession(tokens: {
1938
+ access_token: string;
1939
+ refresh_token: string;
1940
+ }): Promise<void>;
1930
1941
  /**
1931
1942
  * Get the current access token.
1932
1943
  */
package/dist/index.d.ts CHANGED
@@ -972,6 +972,14 @@ declare class APIClient {
972
972
  private refreshPromise;
973
973
  constructor(config: MitumbaClientConfig);
974
974
  setToken(token: string, refreshToken?: string): Promise<void>;
975
+ /**
976
+ * Set both tokens explicitly. Requires a valid refresh token.
977
+ * Preferred over setToken() to avoid dropping the refresh token.
978
+ */
979
+ setSession(tokens: {
980
+ access_token: string;
981
+ refresh_token: string;
982
+ }): Promise<void>;
975
983
  getToken(): string | undefined;
976
984
  getBaseUrl(): string;
977
985
  clearToken(): Promise<void>;
@@ -998,13 +1006,13 @@ declare class AuthModule {
998
1006
  constructor(client: APIClient);
999
1007
  /**
1000
1008
  * Register a new account.
1001
- * If using EmailRegisterInput, returns AuthTokens.
1009
+ * If using EmailRegisterInput, returns AuthTokens (auto-persisted).
1002
1010
  * If using PhoneRegisterInput, returns MessageResponse (OTP sent).
1003
1011
  */
1004
1012
  register(input: RegisterInput, options?: RequestOptions): Promise<AuthTokens | MessageResponse>;
1005
1013
  /**
1006
1014
  * Log in to an existing account.
1007
- * If using EmailLoginInput, returns AuthTokens (or TwoFactorRequired if 2FA enabled).
1015
+ * If using EmailLoginInput, returns AuthTokens (auto-persisted) or TwoFactorRequired.
1008
1016
  * If using PhoneLoginInput, returns MessageResponse (OTP sent).
1009
1017
  */
1010
1018
  login(input: LoginInput, options?: RequestOptions): Promise<AuthTokens | MessageResponse | TwoFactorRequired>;
@@ -1013,7 +1021,7 @@ declare class AuthModule {
1013
1021
  */
1014
1022
  sendOtp(input: SendOtpInput, options?: RequestOptions): Promise<MessageResponse>;
1015
1023
  /**
1016
- * Verify an OTP code.
1024
+ * Verify an OTP code. Tokens are auto-persisted.
1017
1025
  */
1018
1026
  verifyOtp(input: VerifyOtpInput, options?: RequestOptions): Promise<AuthTokens>;
1019
1027
  /**
@@ -1023,7 +1031,7 @@ declare class AuthModule {
1023
1031
  refresh_token: string;
1024
1032
  }, options?: RequestOptions): Promise<AuthTokens>;
1025
1033
  /**
1026
- * Revoke the refresh token and log out.
1034
+ * Revoke the refresh token and log out. Clears stored session.
1027
1035
  */
1028
1036
  logout(input: {
1029
1037
  refresh_token: string;
@@ -1032,7 +1040,6 @@ declare class AuthModule {
1032
1040
  }>;
1033
1041
  /**
1034
1042
  * Request a password reset email.
1035
- * Sends a reset link to the provided email address.
1036
1043
  */
1037
1044
  forgotPassword(input: ForgotPasswordInput, options?: RequestOptions): Promise<MessageResponse>;
1038
1045
  /**
@@ -1050,26 +1057,23 @@ declare class AuthModule {
1050
1057
  ok: true;
1051
1058
  }>;
1052
1059
  /**
1053
- * Verify 2FA code during login (when login returns requires_2fa).
1060
+ * Verify 2FA code during login. Tokens are auto-persisted.
1054
1061
  */
1055
1062
  verify2FA(input: Verify2FAInput, options?: RequestOptions): Promise<AuthTokens>;
1056
1063
  /**
1057
1064
  * Send a verification code to the user's email.
1058
- * If unauthenticated, pass the email address.
1059
1065
  */
1060
1066
  sendVerificationCode(email?: string, options?: RequestOptions): Promise<{
1061
1067
  ok: true;
1062
1068
  }>;
1063
1069
  /**
1064
1070
  * Verify the email with the 6-digit code.
1065
- * If unauthenticated, pass the email address.
1066
1071
  */
1067
1072
  verifyEmail(code: string, email?: string, options?: RequestOptions): Promise<{
1068
1073
  ok: true;
1069
1074
  }>;
1070
1075
  /**
1071
1076
  * Upgrade the current user to a seller role.
1072
- * Idempotent — returns success if already a seller.
1073
1077
  */
1074
1078
  becomeSeller(input: BecomeSellerInput, options?: RequestOptions): Promise<{
1075
1079
  ok: true;
@@ -1927,6 +1931,13 @@ declare class MitumbaClient {
1927
1931
  * Optionally pass a refresh token to enable automatic token rotation.
1928
1932
  */
1929
1933
  setToken(token: string, refreshToken?: string): void;
1934
+ /**
1935
+ * Set both tokens explicitly. Preferred — prevents dropping the refresh token.
1936
+ */
1937
+ setSession(tokens: {
1938
+ access_token: string;
1939
+ refresh_token: string;
1940
+ }): Promise<void>;
1930
1941
  /**
1931
1942
  * Get the current access token.
1932
1943
  */
package/dist/index.js CHANGED
@@ -110,15 +110,25 @@ var APIClient = class {
110
110
  this.config = config;
111
111
  this.tokenStore = config.tokenStore ?? createTokenStore();
112
112
  if (config.token) {
113
- this.tokenStore.setTokens(config.token, config.refreshToken ?? "");
113
+ this.tokenStore.setTokens(config.token, config.refreshToken || "");
114
114
  }
115
115
  }
116
116
  async setToken(token, refreshToken) {
117
117
  this.config.token = token;
118
- if (refreshToken) {
118
+ if (refreshToken && refreshToken.length > 0) {
119
119
  this.config.refreshToken = refreshToken;
120
120
  }
121
- await this.tokenStore.setTokens(token, refreshToken ?? this.config.refreshToken ?? "");
121
+ const effectiveRefresh = refreshToken && refreshToken.length > 0 ? refreshToken : this.config.refreshToken && this.config.refreshToken.length > 0 ? this.config.refreshToken : "";
122
+ await this.tokenStore.setTokens(token, effectiveRefresh);
123
+ }
124
+ /**
125
+ * Set both tokens explicitly. Requires a valid refresh token.
126
+ * Preferred over setToken() to avoid dropping the refresh token.
127
+ */
128
+ async setSession(tokens) {
129
+ this.config.token = tokens.access_token;
130
+ this.config.refreshToken = tokens.refresh_token;
131
+ await this.tokenStore.setTokens(tokens.access_token, tokens.refresh_token);
122
132
  }
123
133
  getToken() {
124
134
  return this.config.token;
@@ -156,7 +166,7 @@ var APIClient = class {
156
166
  const refresh = await this.tokenStore.getRefreshToken();
157
167
  if (refresh) this.config.refreshToken = refresh;
158
168
  }
159
- if (this.config.token && isExpiringSoon(this.config.token, 60) && this.config.refreshToken) {
169
+ if (this.config.token && isExpiringSoon(this.config.token, 60) && this.config.refreshToken && this.config.refreshToken.length > 0) {
160
170
  await this.handleTokenRefresh();
161
171
  }
162
172
  }
@@ -222,12 +232,20 @@ var APIClient = class {
222
232
  }
223
233
  break;
224
234
  }
225
- if (response.status === 401 && this.config.refreshToken && !path.includes("/auth/refresh")) {
226
- try {
227
- await this.handleTokenRefresh();
228
- headers.set("Authorization", `Bearer ${this.config.token}`);
229
- response = await fetch(url.toString(), { ...init, headers });
230
- } catch {
235
+ if (response.status === 401 && !path.includes("/auth/refresh") && !path.includes("/auth/login") && !path.includes("/auth/register")) {
236
+ const hasRefreshToken = this.config.refreshToken && this.config.refreshToken.length > 0;
237
+ if (hasRefreshToken) {
238
+ try {
239
+ await this.handleTokenRefresh();
240
+ headers.set("Authorization", `Bearer ${this.config.token}`);
241
+ response = await fetch(url.toString(), { ...init, headers });
242
+ } catch {
243
+ if (this.config.onAuthExpired) {
244
+ this.config.onAuthExpired();
245
+ }
246
+ throw new APIError(401, { error: "session_expired", message: "Session expired. Please log in again." });
247
+ }
248
+ } else {
231
249
  if (this.config.onAuthExpired) {
232
250
  this.config.onAuthExpired();
233
251
  }
@@ -299,6 +317,9 @@ var APIClient = class {
299
317
  };
300
318
 
301
319
  // src/modules/auth.ts
320
+ function isAuthTokens(result) {
321
+ return typeof result === "object" && result !== null && "access_token" in result && "refresh_token" in result;
322
+ }
302
323
  var AuthModule = class {
303
324
  constructor(client) {
304
325
  this.client = client;
@@ -306,19 +327,27 @@ var AuthModule = class {
306
327
  client;
307
328
  /**
308
329
  * Register a new account.
309
- * If using EmailRegisterInput, returns AuthTokens.
330
+ * If using EmailRegisterInput, returns AuthTokens (auto-persisted).
310
331
  * If using PhoneRegisterInput, returns MessageResponse (OTP sent).
311
332
  */
312
333
  async register(input, options) {
313
- return this.client.post("/auth/register", input, options);
334
+ const result = await this.client.post("/auth/register", input, options);
335
+ if (isAuthTokens(result)) {
336
+ await this.client.setSession(result);
337
+ }
338
+ return result;
314
339
  }
315
340
  /**
316
341
  * Log in to an existing account.
317
- * If using EmailLoginInput, returns AuthTokens (or TwoFactorRequired if 2FA enabled).
342
+ * If using EmailLoginInput, returns AuthTokens (auto-persisted) or TwoFactorRequired.
318
343
  * If using PhoneLoginInput, returns MessageResponse (OTP sent).
319
344
  */
320
345
  async login(input, options) {
321
- return this.client.post("/auth/login", input, options);
346
+ const result = await this.client.post("/auth/login", input, options);
347
+ if (isAuthTokens(result)) {
348
+ await this.client.setSession(result);
349
+ }
350
+ return result;
322
351
  }
323
352
  /**
324
353
  * Send an OTP code to a phone number.
@@ -327,26 +356,31 @@ var AuthModule = class {
327
356
  return this.client.post("/auth/otp/send", input, options);
328
357
  }
329
358
  /**
330
- * Verify an OTP code.
359
+ * Verify an OTP code. Tokens are auto-persisted.
331
360
  */
332
361
  async verifyOtp(input, options) {
333
- return this.client.post("/auth/otp/verify", input, options);
362
+ const result = await this.client.post("/auth/otp/verify", input, options);
363
+ await this.client.setSession(result);
364
+ return result;
334
365
  }
335
366
  /**
336
367
  * Refresh the access token using a refresh token.
337
368
  */
338
369
  async refresh(input, options) {
339
- return this.client.post("/auth/refresh", input, options);
370
+ const result = await this.client.post("/auth/refresh", input, options);
371
+ await this.client.setSession(result);
372
+ return result;
340
373
  }
341
374
  /**
342
- * Revoke the refresh token and log out.
375
+ * Revoke the refresh token and log out. Clears stored session.
343
376
  */
344
377
  async logout(input, options) {
345
- return this.client.post("/auth/logout", input, options);
378
+ const result = await this.client.post("/auth/logout", input, options);
379
+ await this.client.clearToken();
380
+ return result;
346
381
  }
347
382
  /**
348
383
  * Request a password reset email.
349
- * Sends a reset link to the provided email address.
350
384
  */
351
385
  async forgotPassword(input, options) {
352
386
  return this.client.post("/auth/forgot-password", input, options);
@@ -370,28 +404,27 @@ var AuthModule = class {
370
404
  return this.client.post("/auth/onboarding/complete", input, options);
371
405
  }
372
406
  /**
373
- * Verify 2FA code during login (when login returns requires_2fa).
407
+ * Verify 2FA code during login. Tokens are auto-persisted.
374
408
  */
375
409
  async verify2FA(input, options) {
376
- return this.client.post("/auth/2fa/login", input, options);
410
+ const result = await this.client.post("/auth/2fa/login", input, options);
411
+ await this.client.setSession(result);
412
+ return result;
377
413
  }
378
414
  /**
379
415
  * Send a verification code to the user's email.
380
- * If unauthenticated, pass the email address.
381
416
  */
382
417
  async sendVerificationCode(email, options) {
383
418
  return this.client.post("/auth/verify-email/send", email ? { email } : void 0, options);
384
419
  }
385
420
  /**
386
421
  * Verify the email with the 6-digit code.
387
- * If unauthenticated, pass the email address.
388
422
  */
389
423
  async verifyEmail(code, email, options) {
390
424
  return this.client.post("/auth/verify-email/confirm", email ? { code, email } : { code }, options);
391
425
  }
392
426
  /**
393
427
  * Upgrade the current user to a seller role.
394
- * Idempotent — returns success if already a seller.
395
428
  */
396
429
  async becomeSeller(input, options) {
397
430
  return this.client.post("/auth/become-seller", input, options);
@@ -1364,6 +1397,12 @@ var MitumbaClient = class {
1364
1397
  setToken(token, refreshToken) {
1365
1398
  this.api.setToken(token, refreshToken);
1366
1399
  }
1400
+ /**
1401
+ * Set both tokens explicitly. Preferred — prevents dropping the refresh token.
1402
+ */
1403
+ setSession(tokens) {
1404
+ return this.api.setSession(tokens);
1405
+ }
1367
1406
  /**
1368
1407
  * Get the current access token.
1369
1408
  */