anzar 1.2.10 → 1.3.5

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
@@ -61,9 +61,11 @@ Anzar provides authentication support for email and password.
61
61
  ### Sign Up
62
62
  To sign up a user you need to call the method register with the user's information.
63
63
  ```typescript
64
+ import type { AuthResult } from "anzar/types";
65
+
64
66
  try {
65
- const response = await anzar.Auth.register({ username, email, password });
66
- const data: AuthResponse = response.data;
67
+ const data: AuthResult = await anzar.Auth.register({ username, email, password });
68
+ console.log(data);
67
69
  } catch (e) {
68
70
  const message = e.response?.data?.message ?? "An unknown error occurred";
69
71
  console.log(message);
@@ -76,9 +78,11 @@ try {
76
78
  ### Sign In
77
79
  To sign in a user you need to call the method login.
78
80
  ```typescript
81
+ import type { AuthResult } from "anzar/types";
82
+
79
83
  try {
80
- const response = await anzar.Auth.login({ email, password });
81
- const data: AuthResponse = response.data;
84
+ const data: AuthResult = await anzar.Auth.login({ email, password });
85
+ console.log(data);
82
86
  } catch (e) {
83
87
  const message = e.response?.data?.message ?? "An unknown error occurred";
84
88
  console.log(message);
@@ -1,4 +1,4 @@
1
- import { B as BaseStorage, S as SessionTokens } from '../base_storage-CQKHFbrb.cjs';
1
+ import { B as BaseStorage, S as SessionTokens } from '../base_storage-BnHsA4fU.cjs';
2
2
 
3
3
  declare class LocalStorage implements BaseStorage {
4
4
  getToken(): string | null;
@@ -1,4 +1,4 @@
1
- import { B as BaseStorage, S as SessionTokens } from '../base_storage-CQKHFbrb.js';
1
+ import { B as BaseStorage, S as SessionTokens } from '../base_storage-BnHsA4fU.js';
2
2
 
3
3
  declare class LocalStorage implements BaseStorage {
4
4
  getToken(): string | null;
@@ -9,9 +9,14 @@
9
9
  * https://openapi-generator.tech
10
10
  * Do not edit the class manually.
11
11
  */
12
+ /**
13
+ * SessionTokens model
14
+ */
12
15
  interface SessionTokens {
13
16
  'access': string;
17
+ 'expires_in': number;
14
18
  'refresh': string;
19
+ 'token_type': string;
15
20
  }
16
21
 
17
22
  interface BaseStorage {
@@ -9,9 +9,14 @@
9
9
  * https://openapi-generator.tech
10
10
  * Do not edit the class manually.
11
11
  */
12
+ /**
13
+ * SessionTokens model
14
+ */
12
15
  interface SessionTokens {
13
16
  'access': string;
17
+ 'expires_in': number;
14
18
  'refresh': string;
19
+ 'token_type': string;
15
20
  }
16
21
 
17
22
  interface BaseStorage {
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Anzar Software API
3
+ * REST API for the Anzar platform. All protected routes require a Bearer token.
4
+ *
5
+ * The version of the OpenAPI document: 0.6.2
6
+ * Contact: dev@anzar.io
7
+ *
8
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
9
+ * https://openapi-generator.tech
10
+ * Do not edit the class manually.
11
+ */
12
+ declare const Role: {
13
+ readonly User: "User";
14
+ readonly Admin: "Admin";
15
+ };
16
+ type Role = typeof Role[keyof typeof Role];
17
+
18
+ /**
19
+ * Anzar Software API
20
+ * REST API for the Anzar platform. All protected routes require a Bearer token.
21
+ *
22
+ * The version of the OpenAPI document: 0.6.2
23
+ * Contact: dev@anzar.io
24
+ *
25
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
26
+ * https://openapi-generator.tech
27
+ * Do not edit the class manually.
28
+ */
29
+
30
+ interface User {
31
+ '_id'?: string | null;
32
+ 'createdAt': string;
33
+ 'email': string;
34
+ 'role': Role;
35
+ 'username': string;
36
+ 'verified': boolean;
37
+ }
38
+
39
+ /**
40
+ * Anzar Software API
41
+ * REST API for the Anzar platform. All protected routes require a Bearer token.
42
+ *
43
+ * The version of the OpenAPI document: 0.6.2
44
+ * Contact: dev@anzar.io
45
+ *
46
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
47
+ * https://openapi-generator.tech
48
+ * Do not edit the class manually.
49
+ */
50
+ /**
51
+ * Verification model
52
+ */
53
+ interface Verification {
54
+ 'link': string;
55
+ 'token': string;
56
+ }
57
+
58
+ interface AuthResult {
59
+ user: User;
60
+ verification?: Verification | null;
61
+ }
62
+
63
+ export type { AuthResult as A, User as U, Verification as V };
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Anzar Software API
3
+ * REST API for the Anzar platform. All protected routes require a Bearer token.
4
+ *
5
+ * The version of the OpenAPI document: 0.6.2
6
+ * Contact: dev@anzar.io
7
+ *
8
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
9
+ * https://openapi-generator.tech
10
+ * Do not edit the class manually.
11
+ */
12
+ declare const Role: {
13
+ readonly User: "User";
14
+ readonly Admin: "Admin";
15
+ };
16
+ type Role = typeof Role[keyof typeof Role];
17
+
18
+ /**
19
+ * Anzar Software API
20
+ * REST API for the Anzar platform. All protected routes require a Bearer token.
21
+ *
22
+ * The version of the OpenAPI document: 0.6.2
23
+ * Contact: dev@anzar.io
24
+ *
25
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
26
+ * https://openapi-generator.tech
27
+ * Do not edit the class manually.
28
+ */
29
+
30
+ interface User {
31
+ '_id'?: string | null;
32
+ 'createdAt': string;
33
+ 'email': string;
34
+ 'role': Role;
35
+ 'username': string;
36
+ 'verified': boolean;
37
+ }
38
+
39
+ /**
40
+ * Anzar Software API
41
+ * REST API for the Anzar platform. All protected routes require a Bearer token.
42
+ *
43
+ * The version of the OpenAPI document: 0.6.2
44
+ * Contact: dev@anzar.io
45
+ *
46
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
47
+ * https://openapi-generator.tech
48
+ * Do not edit the class manually.
49
+ */
50
+ /**
51
+ * Verification model
52
+ */
53
+ interface Verification {
54
+ 'link': string;
55
+ 'token': string;
56
+ }
57
+
58
+ interface AuthResult {
59
+ user: User;
60
+ verification?: Verification | null;
61
+ }
62
+
63
+ export type { AuthResult as A, User as U, Verification as V };
package/dist/index.cjs CHANGED
@@ -68,14 +68,31 @@ var AuthModule = class {
68
68
  this.strategy = strategy;
69
69
  this.options = options;
70
70
  }
71
- login(body) {
72
- return this.authApi.login(body);
71
+ async login(body) {
72
+ const response = await this.authApi.login(body);
73
+ const auth_response = response.data;
74
+ if (auth_response.tokens) {
75
+ this.options?.storage.onTokenRefresh?.(auth_response.tokens);
76
+ }
77
+ return {
78
+ user: auth_response.user,
79
+ verification: auth_response.verification
80
+ };
73
81
  }
74
- register(body) {
75
- return this.authApi.register(body);
82
+ async register(body) {
83
+ const response = await this.authApi.register(body);
84
+ const auth_response = response.data;
85
+ if (auth_response.tokens) {
86
+ this.options?.storage.onTokenRefresh?.(auth_response.tokens);
87
+ }
88
+ return {
89
+ user: auth_response.user,
90
+ verification: auth_response.verification
91
+ };
76
92
  }
77
93
  async logout() {
78
- await this.authApi.logout();
94
+ const refreshToken = this.options?.storage.getRefreshToken();
95
+ await this.authApi.logout({ refresh_token: refreshToken ?? "" });
79
96
  this.options?.storage.onLogout?.();
80
97
  }
81
98
  resetPassword(body) {
@@ -92,16 +109,27 @@ var AuthModule = class {
92
109
  throw false;
93
110
  }
94
111
  }
95
- session() {
112
+ async session() {
96
113
  if (this.strategy !== "Session" /* Session */) {
97
114
  throw new Error("session() is only available with Session auth strategy");
98
115
  }
99
- return this.authApi.getSession();
116
+ const response = await this.authApi.getSession();
117
+ return response.data;
100
118
  }
101
119
  };
102
120
 
103
121
  // src/api/interceptor.ts
104
122
  var JwtInterceptor = class {
123
+ isRefreshing = false;
124
+ waitingQueue = [];
125
+ drainQueue(token) {
126
+ this.waitingQueue.forEach(({ resolve }) => resolve(token));
127
+ this.waitingQueue = [];
128
+ }
129
+ rejectQueue(error) {
130
+ this.waitingQueue.forEach(({ reject }) => reject(error));
131
+ this.waitingQueue = [];
132
+ }
105
133
  apply(axiosInstance, options) {
106
134
  const REFRESH_URI = "/auth/refresh-token";
107
135
  axiosInstance.interceptors.request.use(
@@ -113,7 +141,6 @@ var JwtInterceptor = class {
113
141
  return config;
114
142
  },
115
143
  (error) => {
116
- console.error("Request error:", error);
117
144
  return Promise.reject(error);
118
145
  }
119
146
  );
@@ -121,27 +148,39 @@ var JwtInterceptor = class {
121
148
  (response) => response,
122
149
  async (error) => {
123
150
  const originalRequest = error.config;
124
- if (error.response?.status === 401 && !originalRequest._retry && !originalRequest.url?.includes(REFRESH_URI)) {
125
- originalRequest._retry = true;
126
- try {
127
- const refreshToken = options?.storage.getRefreshToken();
128
- const response = await axiosInstance.post(
129
- REFRESH_URI,
130
- {},
131
- { headers: { "x-refresh-token": `Bearer ${refreshToken}` } }
132
- );
133
- const auth_response = response.data;
134
- if (auth_response.tokens) {
135
- options?.storage.onTokenRefresh?.(auth_response.tokens);
136
- }
137
- originalRequest.headers.Authorization = `Bearer ${auth_response.tokens?.access}`;
151
+ if (error.response?.status !== 401 || originalRequest._retry || originalRequest.url?.includes(REFRESH_URI)) {
152
+ return Promise.reject(error);
153
+ }
154
+ if (this.isRefreshing) {
155
+ return new Promise((resolve, reject) => {
156
+ this.waitingQueue.push({ resolve, reject });
157
+ }).then((newToken) => {
158
+ originalRequest.headers.Authorization = `Bearer ${newToken}`;
138
159
  return axiosInstance(originalRequest);
139
- } catch (e) {
140
- options?.storage.onSessionExpired?.();
141
- return Promise.reject(e);
160
+ });
161
+ }
162
+ originalRequest._retry = true;
163
+ this.isRefreshing = true;
164
+ try {
165
+ const refreshToken = options?.storage.getRefreshToken();
166
+ if (!refreshToken) return Promise.reject(error);
167
+ const response = await axiosInstance.post(REFRESH_URI, {
168
+ refresh_token: refreshToken
169
+ });
170
+ const auth_response = response.data;
171
+ if (auth_response.tokens) {
172
+ options?.storage.onTokenRefresh?.(auth_response.tokens);
142
173
  }
174
+ this.drainQueue(auth_response.tokens?.access);
175
+ originalRequest.headers.Authorization = `Bearer ${auth_response.tokens?.access}`;
176
+ return axiosInstance(originalRequest);
177
+ } catch (e) {
178
+ this.rejectQueue(e);
179
+ options?.storage.onSessionExpired?.();
180
+ return Promise.reject(e);
181
+ } finally {
182
+ this.isRefreshing = false;
143
183
  }
144
- return Promise.reject(error);
145
184
  }
146
185
  );
147
186
  }
@@ -292,10 +331,12 @@ var AuthApiAxiosParamCreator = function(configuration) {
292
331
  /**
293
332
  * Invalidates the current session and refresh token. The client should discard stored tokens.
294
333
  * @summary Logout
334
+ * @param {RefreshTokenRequest} refreshTokenRequest
295
335
  * @param {*} [options] Override http request option.
296
336
  * @throws {RequiredError}
297
337
  */
298
- logout: async (options = {}) => {
338
+ logout: async (refreshTokenRequest, options = {}) => {
339
+ assertParamExists("logout", "refreshTokenRequest", refreshTokenRequest);
299
340
  const localVarPath = `/auth/logout`;
300
341
  const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
301
342
  let baseOptions;
@@ -306,10 +347,12 @@ var AuthApiAxiosParamCreator = function(configuration) {
306
347
  const localVarHeaderParameter = {};
307
348
  const localVarQueryParameter = {};
308
349
  await setBearerAuthToObject(localVarHeaderParameter, configuration);
350
+ localVarHeaderParameter["Content-Type"] = "application/json";
309
351
  localVarHeaderParameter["Accept"] = "application/json";
310
352
  setSearchParams(localVarUrlObj, localVarQueryParameter);
311
353
  let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
312
354
  localVarRequestOptions.headers = { ...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers };
355
+ localVarRequestOptions.data = serializeDataIfNeeded(refreshTokenRequest, localVarRequestOptions, configuration);
313
356
  return {
314
357
  url: toPathString(localVarUrlObj),
315
358
  options: localVarRequestOptions
@@ -318,10 +361,12 @@ var AuthApiAxiosParamCreator = function(configuration) {
318
361
  /**
319
362
  * Issues a new access token using a valid refresh token. Rotate refresh tokens on each call.
320
363
  * @summary Refresh access token
364
+ * @param {RefreshTokenRequest} refreshTokenRequest
321
365
  * @param {*} [options] Override http request option.
322
366
  * @throws {RequiredError}
323
367
  */
324
- refreshToken: async (options = {}) => {
368
+ refreshToken: async (refreshTokenRequest, options = {}) => {
369
+ assertParamExists("refreshToken", "refreshTokenRequest", refreshTokenRequest);
325
370
  const localVarPath = `/auth/refresh-token`;
326
371
  const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
327
372
  let baseOptions;
@@ -332,10 +377,12 @@ var AuthApiAxiosParamCreator = function(configuration) {
332
377
  const localVarHeaderParameter = {};
333
378
  const localVarQueryParameter = {};
334
379
  await setBearerAuthToObject(localVarHeaderParameter, configuration);
380
+ localVarHeaderParameter["Content-Type"] = "application/json";
335
381
  localVarHeaderParameter["Accept"] = "application/json";
336
382
  setSearchParams(localVarUrlObj, localVarQueryParameter);
337
383
  let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
338
384
  localVarRequestOptions.headers = { ...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers };
385
+ localVarRequestOptions.data = serializeDataIfNeeded(refreshTokenRequest, localVarRequestOptions, configuration);
339
386
  return {
340
387
  url: toPathString(localVarUrlObj),
341
388
  options: localVarRequestOptions
@@ -493,11 +540,12 @@ var AuthApiFp = function(configuration) {
493
540
  /**
494
541
  * Invalidates the current session and refresh token. The client should discard stored tokens.
495
542
  * @summary Logout
543
+ * @param {RefreshTokenRequest} refreshTokenRequest
496
544
  * @param {*} [options] Override http request option.
497
545
  * @throws {RequiredError}
498
546
  */
499
- async logout(options) {
500
- const localVarAxiosArgs = await localVarAxiosParamCreator.logout(options);
547
+ async logout(refreshTokenRequest, options) {
548
+ const localVarAxiosArgs = await localVarAxiosParamCreator.logout(refreshTokenRequest, options);
501
549
  const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
502
550
  const localVarOperationServerBasePath = operationServerMap["AuthApi.logout"]?.[localVarOperationServerIndex]?.url;
503
551
  return (axios3, basePath) => createRequestFunction(localVarAxiosArgs, import_axios3.default, BASE_PATH, configuration)(axios3, localVarOperationServerBasePath || basePath);
@@ -505,11 +553,12 @@ var AuthApiFp = function(configuration) {
505
553
  /**
506
554
  * Issues a new access token using a valid refresh token. Rotate refresh tokens on each call.
507
555
  * @summary Refresh access token
556
+ * @param {RefreshTokenRequest} refreshTokenRequest
508
557
  * @param {*} [options] Override http request option.
509
558
  * @throws {RequiredError}
510
559
  */
511
- async refreshToken(options) {
512
- const localVarAxiosArgs = await localVarAxiosParamCreator.refreshToken(options);
560
+ async refreshToken(refreshTokenRequest, options) {
561
+ const localVarAxiosArgs = await localVarAxiosParamCreator.refreshToken(refreshTokenRequest, options);
513
562
  const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
514
563
  const localVarOperationServerBasePath = operationServerMap["AuthApi.refreshToken"]?.[localVarOperationServerIndex]?.url;
515
564
  return (axios3, basePath) => createRequestFunction(localVarAxiosArgs, import_axios3.default, BASE_PATH, configuration)(axios3, localVarOperationServerBasePath || basePath);
@@ -591,20 +640,22 @@ var AuthApi = class extends BaseAPI {
591
640
  /**
592
641
  * Invalidates the current session and refresh token. The client should discard stored tokens.
593
642
  * @summary Logout
643
+ * @param {RefreshTokenRequest} refreshTokenRequest
594
644
  * @param {*} [options] Override http request option.
595
645
  * @throws {RequiredError}
596
646
  */
597
- logout(options) {
598
- return AuthApiFp(this.configuration).logout(options).then((request) => request(this.axios, this.basePath));
647
+ logout(refreshTokenRequest, options) {
648
+ return AuthApiFp(this.configuration).logout(refreshTokenRequest, options).then((request) => request(this.axios, this.basePath));
599
649
  }
600
650
  /**
601
651
  * Issues a new access token using a valid refresh token. Rotate refresh tokens on each call.
602
652
  * @summary Refresh access token
653
+ * @param {RefreshTokenRequest} refreshTokenRequest
603
654
  * @param {*} [options] Override http request option.
604
655
  * @throws {RequiredError}
605
656
  */
606
- refreshToken(options) {
607
- return AuthApiFp(this.configuration).refreshToken(options).then((request) => request(this.axios, this.basePath));
657
+ refreshToken(refreshTokenRequest, options) {
658
+ return AuthApiFp(this.configuration).refreshToken(refreshTokenRequest, options).then((request) => request(this.axios, this.basePath));
608
659
  }
609
660
  /**
610
661
  * Creates a new user account. Sends a verification email upon successful registration.
package/dist/index.d.cts CHANGED
@@ -1,6 +1,7 @@
1
1
  import * as axios from 'axios';
2
- import { AxiosInstance, RawAxiosRequestConfig, AxiosResponse } from 'axios';
3
- import { S as SessionTokens, B as BaseStorage } from './base_storage-CQKHFbrb.cjs';
2
+ import { AxiosInstance, RawAxiosRequestConfig } from 'axios';
3
+ import { S as SessionTokens, B as BaseStorage } from './base_storage-BnHsA4fU.cjs';
4
+ import { U as User, V as Verification, A as AuthResult } from './index-BZFSacf5.cjs';
4
5
 
5
6
  /**
6
7
  * Anzar Software API
@@ -119,23 +120,6 @@ declare class BaseAPI {
119
120
  constructor(configuration?: Configuration, basePath?: string, axios?: AxiosInstance);
120
121
  }
121
122
 
122
- /**
123
- * Anzar Software API
124
- * REST API for the Anzar platform. All protected routes require a Bearer token.
125
- *
126
- * The version of the OpenAPI document: 0.6.2
127
- * Contact: dev@anzar.io
128
- *
129
- * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
130
- * https://openapi-generator.tech
131
- * Do not edit the class manually.
132
- */
133
- declare const Role: {
134
- readonly User: "User";
135
- readonly Admin: "Admin";
136
- };
137
- type Role = typeof Role[keyof typeof Role];
138
-
139
123
  /**
140
124
  * Anzar Software API
141
125
  * REST API for the Anzar platform. All protected routes require a Bearer token.
@@ -148,32 +132,10 @@ type Role = typeof Role[keyof typeof Role];
148
132
  * Do not edit the class manually.
149
133
  */
150
134
 
151
- interface User {
152
- '_id'?: string | null;
153
- 'createdAt': string;
154
- 'email': string;
155
- 'role': Role;
156
- 'username': string;
157
- 'verified': boolean;
158
- }
159
-
160
- /**
161
- * Anzar Software API
162
- * REST API for the Anzar platform. All protected routes require a Bearer token.
163
- *
164
- * The version of the OpenAPI document: 0.6.2
165
- * Contact: dev@anzar.io
166
- *
167
- * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
168
- * https://openapi-generator.tech
169
- * Do not edit the class manually.
170
- */
171
- /**
172
- * Verification model
173
- */
174
- interface Verification {
175
- 'link': string;
176
- 'token': string;
135
+ interface AuthResponse {
136
+ 'tokens'?: SessionTokens | null;
137
+ 'user': User;
138
+ 'verification'?: Verification | null;
177
139
  }
178
140
 
179
141
  /**
@@ -187,11 +149,8 @@ interface Verification {
187
149
  * https://openapi-generator.tech
188
150
  * Do not edit the class manually.
189
151
  */
190
-
191
- interface AuthResponse {
192
- 'tokens'?: SessionTokens | null;
193
- 'user': User;
194
- 'verification'?: Verification | null;
152
+ interface EmailRequest {
153
+ 'email': string;
195
154
  }
196
155
 
197
156
  /**
@@ -205,8 +164,9 @@ interface AuthResponse {
205
164
  * https://openapi-generator.tech
206
165
  * Do not edit the class manually.
207
166
  */
208
- interface EmailRequest {
167
+ interface LoginRequest {
209
168
  'email': string;
169
+ 'password': string;
210
170
  }
211
171
 
212
172
  /**
@@ -220,9 +180,8 @@ interface EmailRequest {
220
180
  * https://openapi-generator.tech
221
181
  * Do not edit the class manually.
222
182
  */
223
- interface LoginRequest {
224
- 'email': string;
225
- 'password': string;
183
+ interface RefreshTokenRequest {
184
+ 'refresh_token': string;
226
185
  }
227
186
 
228
187
  /**
@@ -332,17 +291,19 @@ declare class AuthApi extends BaseAPI {
332
291
  /**
333
292
  * Invalidates the current session and refresh token. The client should discard stored tokens.
334
293
  * @summary Logout
294
+ * @param {RefreshTokenRequest} refreshTokenRequest
335
295
  * @param {*} [options] Override http request option.
336
296
  * @throws {RequiredError}
337
297
  */
338
- logout(options?: RawAxiosRequestConfig): Promise<axios.AxiosResponse<void, any, {}>>;
298
+ logout(refreshTokenRequest: RefreshTokenRequest, options?: RawAxiosRequestConfig): Promise<axios.AxiosResponse<void, any, {}>>;
339
299
  /**
340
300
  * Issues a new access token using a valid refresh token. Rotate refresh tokens on each call.
341
301
  * @summary Refresh access token
302
+ * @param {RefreshTokenRequest} refreshTokenRequest
342
303
  * @param {*} [options] Override http request option.
343
304
  * @throws {RequiredError}
344
305
  */
345
- refreshToken(options?: RawAxiosRequestConfig): Promise<axios.AxiosResponse<AuthResponse, any, {}>>;
306
+ refreshToken(refreshTokenRequest: RefreshTokenRequest, options?: RawAxiosRequestConfig): Promise<axios.AxiosResponse<AuthResponse, any, {}>>;
346
307
  /**
347
308
  * Creates a new user account. Sends a verification email upon successful registration.
348
309
  * @summary Register a new user
@@ -484,12 +445,12 @@ declare class AuthModule {
484
445
  private readonly strategy;
485
446
  private readonly options?;
486
447
  constructor(authApi: AuthApi, userApi: UsersApi, strategy: AuthStrategy, options?: SdkOptions | undefined);
487
- login(body: LoginRequest): Promise<AxiosResponse<AuthResponse, any, {}>>;
488
- register(body: RegisterRequest): Promise<AxiosResponse<AuthResponse, any, {}>>;
448
+ login(body: LoginRequest): Promise<AuthResult>;
449
+ register(body: RegisterRequest): Promise<AuthResult>;
489
450
  logout(): Promise<void>;
490
451
  resetPassword(body: EmailRequest): void;
491
452
  isAuthenticated(): Promise<boolean>;
492
- session(): Promise<AxiosResponse<Session, any, {}>>;
453
+ session(): Promise<Session>;
493
454
  }
494
455
 
495
456
  declare class Anzar {
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import * as axios from 'axios';
2
- import { AxiosInstance, RawAxiosRequestConfig, AxiosResponse } from 'axios';
3
- import { S as SessionTokens, B as BaseStorage } from './base_storage-CQKHFbrb.js';
2
+ import { AxiosInstance, RawAxiosRequestConfig } from 'axios';
3
+ import { S as SessionTokens, B as BaseStorage } from './base_storage-BnHsA4fU.js';
4
+ import { U as User, V as Verification, A as AuthResult } from './index-BZFSacf5.js';
4
5
 
5
6
  /**
6
7
  * Anzar Software API
@@ -119,23 +120,6 @@ declare class BaseAPI {
119
120
  constructor(configuration?: Configuration, basePath?: string, axios?: AxiosInstance);
120
121
  }
121
122
 
122
- /**
123
- * Anzar Software API
124
- * REST API for the Anzar platform. All protected routes require a Bearer token.
125
- *
126
- * The version of the OpenAPI document: 0.6.2
127
- * Contact: dev@anzar.io
128
- *
129
- * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
130
- * https://openapi-generator.tech
131
- * Do not edit the class manually.
132
- */
133
- declare const Role: {
134
- readonly User: "User";
135
- readonly Admin: "Admin";
136
- };
137
- type Role = typeof Role[keyof typeof Role];
138
-
139
123
  /**
140
124
  * Anzar Software API
141
125
  * REST API for the Anzar platform. All protected routes require a Bearer token.
@@ -148,32 +132,10 @@ type Role = typeof Role[keyof typeof Role];
148
132
  * Do not edit the class manually.
149
133
  */
150
134
 
151
- interface User {
152
- '_id'?: string | null;
153
- 'createdAt': string;
154
- 'email': string;
155
- 'role': Role;
156
- 'username': string;
157
- 'verified': boolean;
158
- }
159
-
160
- /**
161
- * Anzar Software API
162
- * REST API for the Anzar platform. All protected routes require a Bearer token.
163
- *
164
- * The version of the OpenAPI document: 0.6.2
165
- * Contact: dev@anzar.io
166
- *
167
- * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
168
- * https://openapi-generator.tech
169
- * Do not edit the class manually.
170
- */
171
- /**
172
- * Verification model
173
- */
174
- interface Verification {
175
- 'link': string;
176
- 'token': string;
135
+ interface AuthResponse {
136
+ 'tokens'?: SessionTokens | null;
137
+ 'user': User;
138
+ 'verification'?: Verification | null;
177
139
  }
178
140
 
179
141
  /**
@@ -187,11 +149,8 @@ interface Verification {
187
149
  * https://openapi-generator.tech
188
150
  * Do not edit the class manually.
189
151
  */
190
-
191
- interface AuthResponse {
192
- 'tokens'?: SessionTokens | null;
193
- 'user': User;
194
- 'verification'?: Verification | null;
152
+ interface EmailRequest {
153
+ 'email': string;
195
154
  }
196
155
 
197
156
  /**
@@ -205,8 +164,9 @@ interface AuthResponse {
205
164
  * https://openapi-generator.tech
206
165
  * Do not edit the class manually.
207
166
  */
208
- interface EmailRequest {
167
+ interface LoginRequest {
209
168
  'email': string;
169
+ 'password': string;
210
170
  }
211
171
 
212
172
  /**
@@ -220,9 +180,8 @@ interface EmailRequest {
220
180
  * https://openapi-generator.tech
221
181
  * Do not edit the class manually.
222
182
  */
223
- interface LoginRequest {
224
- 'email': string;
225
- 'password': string;
183
+ interface RefreshTokenRequest {
184
+ 'refresh_token': string;
226
185
  }
227
186
 
228
187
  /**
@@ -332,17 +291,19 @@ declare class AuthApi extends BaseAPI {
332
291
  /**
333
292
  * Invalidates the current session and refresh token. The client should discard stored tokens.
334
293
  * @summary Logout
294
+ * @param {RefreshTokenRequest} refreshTokenRequest
335
295
  * @param {*} [options] Override http request option.
336
296
  * @throws {RequiredError}
337
297
  */
338
- logout(options?: RawAxiosRequestConfig): Promise<axios.AxiosResponse<void, any, {}>>;
298
+ logout(refreshTokenRequest: RefreshTokenRequest, options?: RawAxiosRequestConfig): Promise<axios.AxiosResponse<void, any, {}>>;
339
299
  /**
340
300
  * Issues a new access token using a valid refresh token. Rotate refresh tokens on each call.
341
301
  * @summary Refresh access token
302
+ * @param {RefreshTokenRequest} refreshTokenRequest
342
303
  * @param {*} [options] Override http request option.
343
304
  * @throws {RequiredError}
344
305
  */
345
- refreshToken(options?: RawAxiosRequestConfig): Promise<axios.AxiosResponse<AuthResponse, any, {}>>;
306
+ refreshToken(refreshTokenRequest: RefreshTokenRequest, options?: RawAxiosRequestConfig): Promise<axios.AxiosResponse<AuthResponse, any, {}>>;
346
307
  /**
347
308
  * Creates a new user account. Sends a verification email upon successful registration.
348
309
  * @summary Register a new user
@@ -484,12 +445,12 @@ declare class AuthModule {
484
445
  private readonly strategy;
485
446
  private readonly options?;
486
447
  constructor(authApi: AuthApi, userApi: UsersApi, strategy: AuthStrategy, options?: SdkOptions | undefined);
487
- login(body: LoginRequest): Promise<AxiosResponse<AuthResponse, any, {}>>;
488
- register(body: RegisterRequest): Promise<AxiosResponse<AuthResponse, any, {}>>;
448
+ login(body: LoginRequest): Promise<AuthResult>;
449
+ register(body: RegisterRequest): Promise<AuthResult>;
489
450
  logout(): Promise<void>;
490
451
  resetPassword(body: EmailRequest): void;
491
452
  isAuthenticated(): Promise<boolean>;
492
- session(): Promise<AxiosResponse<Session, any, {}>>;
453
+ session(): Promise<Session>;
493
454
  }
494
455
 
495
456
  declare class Anzar {
package/dist/index.js CHANGED
@@ -14,14 +14,31 @@ var AuthModule = class {
14
14
  this.strategy = strategy;
15
15
  this.options = options;
16
16
  }
17
- login(body) {
18
- return this.authApi.login(body);
17
+ async login(body) {
18
+ const response = await this.authApi.login(body);
19
+ const auth_response = response.data;
20
+ if (auth_response.tokens) {
21
+ this.options?.storage.onTokenRefresh?.(auth_response.tokens);
22
+ }
23
+ return {
24
+ user: auth_response.user,
25
+ verification: auth_response.verification
26
+ };
19
27
  }
20
- register(body) {
21
- return this.authApi.register(body);
28
+ async register(body) {
29
+ const response = await this.authApi.register(body);
30
+ const auth_response = response.data;
31
+ if (auth_response.tokens) {
32
+ this.options?.storage.onTokenRefresh?.(auth_response.tokens);
33
+ }
34
+ return {
35
+ user: auth_response.user,
36
+ verification: auth_response.verification
37
+ };
22
38
  }
23
39
  async logout() {
24
- await this.authApi.logout();
40
+ const refreshToken = this.options?.storage.getRefreshToken();
41
+ await this.authApi.logout({ refresh_token: refreshToken ?? "" });
25
42
  this.options?.storage.onLogout?.();
26
43
  }
27
44
  resetPassword(body) {
@@ -38,16 +55,27 @@ var AuthModule = class {
38
55
  throw false;
39
56
  }
40
57
  }
41
- session() {
58
+ async session() {
42
59
  if (this.strategy !== "Session" /* Session */) {
43
60
  throw new Error("session() is only available with Session auth strategy");
44
61
  }
45
- return this.authApi.getSession();
62
+ const response = await this.authApi.getSession();
63
+ return response.data;
46
64
  }
47
65
  };
48
66
 
49
67
  // src/api/interceptor.ts
50
68
  var JwtInterceptor = class {
69
+ isRefreshing = false;
70
+ waitingQueue = [];
71
+ drainQueue(token) {
72
+ this.waitingQueue.forEach(({ resolve }) => resolve(token));
73
+ this.waitingQueue = [];
74
+ }
75
+ rejectQueue(error) {
76
+ this.waitingQueue.forEach(({ reject }) => reject(error));
77
+ this.waitingQueue = [];
78
+ }
51
79
  apply(axiosInstance, options) {
52
80
  const REFRESH_URI = "/auth/refresh-token";
53
81
  axiosInstance.interceptors.request.use(
@@ -59,7 +87,6 @@ var JwtInterceptor = class {
59
87
  return config;
60
88
  },
61
89
  (error) => {
62
- console.error("Request error:", error);
63
90
  return Promise.reject(error);
64
91
  }
65
92
  );
@@ -67,27 +94,39 @@ var JwtInterceptor = class {
67
94
  (response) => response,
68
95
  async (error) => {
69
96
  const originalRequest = error.config;
70
- if (error.response?.status === 401 && !originalRequest._retry && !originalRequest.url?.includes(REFRESH_URI)) {
71
- originalRequest._retry = true;
72
- try {
73
- const refreshToken = options?.storage.getRefreshToken();
74
- const response = await axiosInstance.post(
75
- REFRESH_URI,
76
- {},
77
- { headers: { "x-refresh-token": `Bearer ${refreshToken}` } }
78
- );
79
- const auth_response = response.data;
80
- if (auth_response.tokens) {
81
- options?.storage.onTokenRefresh?.(auth_response.tokens);
82
- }
83
- originalRequest.headers.Authorization = `Bearer ${auth_response.tokens?.access}`;
97
+ if (error.response?.status !== 401 || originalRequest._retry || originalRequest.url?.includes(REFRESH_URI)) {
98
+ return Promise.reject(error);
99
+ }
100
+ if (this.isRefreshing) {
101
+ return new Promise((resolve, reject) => {
102
+ this.waitingQueue.push({ resolve, reject });
103
+ }).then((newToken) => {
104
+ originalRequest.headers.Authorization = `Bearer ${newToken}`;
84
105
  return axiosInstance(originalRequest);
85
- } catch (e) {
86
- options?.storage.onSessionExpired?.();
87
- return Promise.reject(e);
106
+ });
107
+ }
108
+ originalRequest._retry = true;
109
+ this.isRefreshing = true;
110
+ try {
111
+ const refreshToken = options?.storage.getRefreshToken();
112
+ if (!refreshToken) return Promise.reject(error);
113
+ const response = await axiosInstance.post(REFRESH_URI, {
114
+ refresh_token: refreshToken
115
+ });
116
+ const auth_response = response.data;
117
+ if (auth_response.tokens) {
118
+ options?.storage.onTokenRefresh?.(auth_response.tokens);
88
119
  }
120
+ this.drainQueue(auth_response.tokens?.access);
121
+ originalRequest.headers.Authorization = `Bearer ${auth_response.tokens?.access}`;
122
+ return axiosInstance(originalRequest);
123
+ } catch (e) {
124
+ this.rejectQueue(e);
125
+ options?.storage.onSessionExpired?.();
126
+ return Promise.reject(e);
127
+ } finally {
128
+ this.isRefreshing = false;
89
129
  }
90
- return Promise.reject(error);
91
130
  }
92
131
  );
93
132
  }
@@ -238,10 +277,12 @@ var AuthApiAxiosParamCreator = function(configuration) {
238
277
  /**
239
278
  * Invalidates the current session and refresh token. The client should discard stored tokens.
240
279
  * @summary Logout
280
+ * @param {RefreshTokenRequest} refreshTokenRequest
241
281
  * @param {*} [options] Override http request option.
242
282
  * @throws {RequiredError}
243
283
  */
244
- logout: async (options = {}) => {
284
+ logout: async (refreshTokenRequest, options = {}) => {
285
+ assertParamExists("logout", "refreshTokenRequest", refreshTokenRequest);
245
286
  const localVarPath = `/auth/logout`;
246
287
  const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
247
288
  let baseOptions;
@@ -252,10 +293,12 @@ var AuthApiAxiosParamCreator = function(configuration) {
252
293
  const localVarHeaderParameter = {};
253
294
  const localVarQueryParameter = {};
254
295
  await setBearerAuthToObject(localVarHeaderParameter, configuration);
296
+ localVarHeaderParameter["Content-Type"] = "application/json";
255
297
  localVarHeaderParameter["Accept"] = "application/json";
256
298
  setSearchParams(localVarUrlObj, localVarQueryParameter);
257
299
  let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
258
300
  localVarRequestOptions.headers = { ...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers };
301
+ localVarRequestOptions.data = serializeDataIfNeeded(refreshTokenRequest, localVarRequestOptions, configuration);
259
302
  return {
260
303
  url: toPathString(localVarUrlObj),
261
304
  options: localVarRequestOptions
@@ -264,10 +307,12 @@ var AuthApiAxiosParamCreator = function(configuration) {
264
307
  /**
265
308
  * Issues a new access token using a valid refresh token. Rotate refresh tokens on each call.
266
309
  * @summary Refresh access token
310
+ * @param {RefreshTokenRequest} refreshTokenRequest
267
311
  * @param {*} [options] Override http request option.
268
312
  * @throws {RequiredError}
269
313
  */
270
- refreshToken: async (options = {}) => {
314
+ refreshToken: async (refreshTokenRequest, options = {}) => {
315
+ assertParamExists("refreshToken", "refreshTokenRequest", refreshTokenRequest);
271
316
  const localVarPath = `/auth/refresh-token`;
272
317
  const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
273
318
  let baseOptions;
@@ -278,10 +323,12 @@ var AuthApiAxiosParamCreator = function(configuration) {
278
323
  const localVarHeaderParameter = {};
279
324
  const localVarQueryParameter = {};
280
325
  await setBearerAuthToObject(localVarHeaderParameter, configuration);
326
+ localVarHeaderParameter["Content-Type"] = "application/json";
281
327
  localVarHeaderParameter["Accept"] = "application/json";
282
328
  setSearchParams(localVarUrlObj, localVarQueryParameter);
283
329
  let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
284
330
  localVarRequestOptions.headers = { ...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers };
331
+ localVarRequestOptions.data = serializeDataIfNeeded(refreshTokenRequest, localVarRequestOptions, configuration);
285
332
  return {
286
333
  url: toPathString(localVarUrlObj),
287
334
  options: localVarRequestOptions
@@ -439,11 +486,12 @@ var AuthApiFp = function(configuration) {
439
486
  /**
440
487
  * Invalidates the current session and refresh token. The client should discard stored tokens.
441
488
  * @summary Logout
489
+ * @param {RefreshTokenRequest} refreshTokenRequest
442
490
  * @param {*} [options] Override http request option.
443
491
  * @throws {RequiredError}
444
492
  */
445
- async logout(options) {
446
- const localVarAxiosArgs = await localVarAxiosParamCreator.logout(options);
493
+ async logout(refreshTokenRequest, options) {
494
+ const localVarAxiosArgs = await localVarAxiosParamCreator.logout(refreshTokenRequest, options);
447
495
  const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
448
496
  const localVarOperationServerBasePath = operationServerMap["AuthApi.logout"]?.[localVarOperationServerIndex]?.url;
449
497
  return (axios3, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios2, BASE_PATH, configuration)(axios3, localVarOperationServerBasePath || basePath);
@@ -451,11 +499,12 @@ var AuthApiFp = function(configuration) {
451
499
  /**
452
500
  * Issues a new access token using a valid refresh token. Rotate refresh tokens on each call.
453
501
  * @summary Refresh access token
502
+ * @param {RefreshTokenRequest} refreshTokenRequest
454
503
  * @param {*} [options] Override http request option.
455
504
  * @throws {RequiredError}
456
505
  */
457
- async refreshToken(options) {
458
- const localVarAxiosArgs = await localVarAxiosParamCreator.refreshToken(options);
506
+ async refreshToken(refreshTokenRequest, options) {
507
+ const localVarAxiosArgs = await localVarAxiosParamCreator.refreshToken(refreshTokenRequest, options);
459
508
  const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
460
509
  const localVarOperationServerBasePath = operationServerMap["AuthApi.refreshToken"]?.[localVarOperationServerIndex]?.url;
461
510
  return (axios3, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios2, BASE_PATH, configuration)(axios3, localVarOperationServerBasePath || basePath);
@@ -537,20 +586,22 @@ var AuthApi = class extends BaseAPI {
537
586
  /**
538
587
  * Invalidates the current session and refresh token. The client should discard stored tokens.
539
588
  * @summary Logout
589
+ * @param {RefreshTokenRequest} refreshTokenRequest
540
590
  * @param {*} [options] Override http request option.
541
591
  * @throws {RequiredError}
542
592
  */
543
- logout(options) {
544
- return AuthApiFp(this.configuration).logout(options).then((request) => request(this.axios, this.basePath));
593
+ logout(refreshTokenRequest, options) {
594
+ return AuthApiFp(this.configuration).logout(refreshTokenRequest, options).then((request) => request(this.axios, this.basePath));
545
595
  }
546
596
  /**
547
597
  * Issues a new access token using a valid refresh token. Rotate refresh tokens on each call.
548
598
  * @summary Refresh access token
599
+ * @param {RefreshTokenRequest} refreshTokenRequest
549
600
  * @param {*} [options] Override http request option.
550
601
  * @throws {RequiredError}
551
602
  */
552
- refreshToken(options) {
553
- return AuthApiFp(this.configuration).refreshToken(options).then((request) => request(this.axios, this.basePath));
603
+ refreshToken(refreshTokenRequest, options) {
604
+ return AuthApiFp(this.configuration).refreshToken(refreshTokenRequest, options).then((request) => request(this.axios, this.basePath));
554
605
  }
555
606
  /**
556
607
  * Creates a new user account. Sends a verification email upon successful registration.
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __copyProps = (to, from, except, desc) => {
7
+ if (from && typeof from === "object" || typeof from === "function") {
8
+ for (let key of __getOwnPropNames(from))
9
+ if (!__hasOwnProp.call(to, key) && key !== except)
10
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
+ }
12
+ return to;
13
+ };
14
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
15
+
16
+ // src/types/index.ts
17
+ var types_exports = {};
18
+ module.exports = __toCommonJS(types_exports);
@@ -0,0 +1 @@
1
+ export { A as AuthResult, U as User } from '../index-BZFSacf5.cjs';
@@ -0,0 +1 @@
1
+ export { A as AuthResult, U as User } from '../index-BZFSacf5.js';
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "anzar",
3
- "version": "1.2.10",
3
+ "version": "1.3.5",
4
4
  "description": "Anzar SDK",
5
5
  "type": "module",
6
6
  "module": "./dist/index.js",
@@ -16,6 +16,11 @@
16
16
  "types": "./dist/adapters/index.d.ts",
17
17
  "import": "./dist/adapters/index.js",
18
18
  "require": "./dist/adapters/index.cjs"
19
+ },
20
+ "./types": {
21
+ "types": "./dist/types/index.d.ts",
22
+ "import": "./dist/types/index.js",
23
+ "require": "./dist/types/index.cjs"
19
24
  }
20
25
  },
21
26
  "files": [
@@ -24,7 +29,8 @@
24
29
  "LICENSE"
25
30
  ],
26
31
  "scripts": {
27
- "test": "echo \"Error: no test specified\" && exit 1",
32
+ "test": "node --import tsx/esm --test",
33
+ "coverage": "node --import tsx/esm --experimental-test-coverage --test-coverage-lines=80 --test-coverage-branches=80 --test-coverage-functions=70 --test",
28
34
  "build": "tsup",
29
35
  "prepublishOnly": "npm run build"
30
36
  },
@@ -46,7 +52,9 @@
46
52
  },
47
53
  "devDependencies": {
48
54
  "@openapitools/openapi-generator-cli": "^2.29.0",
55
+ "axios-mock-adapter": "^2.1.0",
49
56
  "tsup": "^8.5.1",
57
+ "tsx": "^4.21.0",
50
58
  "typescript": "^5.9.3"
51
59
  }
52
60
  }