@gymspace/sdk 1.0.3 → 1.1.1

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/src/client.ts CHANGED
@@ -18,11 +18,7 @@ import {
18
18
  export class ApiClient {
19
19
  private axiosInstance: AxiosInstance;
20
20
  private config: GymSpaceConfig;
21
- private refreshPromise: Promise<any> | null = null; // To prevent concurrent refresh attempts
22
-
23
- // Callbacks for token updates and auth errors
24
- public onTokensUpdated?: (accessToken: string, refreshToken: string) => void;
25
- public onAuthError?: (error: any) => void;
21
+ private refreshToken: string | null = null;
26
22
 
27
23
  constructor(config: GymSpaceConfig) {
28
24
  this.config = config;
@@ -48,9 +44,9 @@ export class ApiClient {
48
44
  config.headers['Authorization'] = `Bearer ${this.config.apiKey}`;
49
45
  }
50
46
 
51
- // Add refresh token header if available
52
- if (this.config.refreshToken && config.headers) {
53
- config.headers['X-Refresh-Token'] = this.config.refreshToken;
47
+ // Add refresh token header for current-session endpoint
48
+ if (this.refreshToken && config.url?.includes('current-session') && config.headers) {
49
+ config.headers['X-Refresh-Token'] = this.refreshToken;
54
50
  }
55
51
 
56
52
  return config;
@@ -60,88 +56,18 @@ export class ApiClient {
60
56
  },
61
57
  );
62
58
 
63
- // Response interceptor with automatic token refresh
59
+ // Response interceptor - simplified without automatic token refresh
64
60
  this.axiosInstance.interceptors.response.use(
65
61
  (response) => {
66
- // Check for new tokens in response headers
67
- const newAccessToken = response.headers['x-new-access-token'];
68
- const newRefreshToken = response.headers['x-new-refresh-token'];
69
-
70
- if (newAccessToken && newRefreshToken) {
71
- this.setTokens(newAccessToken, newRefreshToken);
72
- // Emit token update event if needed
73
- this.onTokensUpdated?.(newAccessToken, newRefreshToken);
74
- }
75
-
76
62
  return response;
77
63
  },
78
64
  async (error: AxiosError) => {
79
- const originalRequest = error.config as InternalAxiosRequestConfig & { _retry?: boolean };
80
-
81
- // If it's a 401 error and we haven't retried yet, try to refresh the token
82
- if (error.response?.status === 401 && !originalRequest._retry && this.config.refreshToken) {
83
- originalRequest._retry = true;
84
-
85
- try {
86
- // Prevent concurrent refresh attempts
87
- if (!this.refreshPromise) {
88
- this.refreshPromise = this.refreshAccessToken();
89
- }
90
-
91
- const newTokens = await this.refreshPromise;
92
- this.refreshPromise = null;
93
-
94
- if (newTokens) {
95
- // Update the original request with new token
96
- if (!originalRequest.headers) {
97
- originalRequest.headers = {} as AxiosRequestHeaders;
98
- }
99
- originalRequest.headers['Authorization'] = `Bearer ${newTokens.access_token}`;
100
-
101
- // Retry the original request
102
- return this.axiosInstance(originalRequest);
103
- }
104
- } catch (refreshError) {
105
- this.refreshPromise = null;
106
- // If refresh fails, clear tokens and emit error
107
- this.clearAuth();
108
- this.onAuthError?.(refreshError);
109
- }
110
- }
111
-
65
+ // Simply throw the error - no automatic refresh attempts
112
66
  throw this.handleError(error);
113
67
  },
114
68
  );
115
69
  }
116
70
 
117
- /**
118
- * Refresh the access token using the stored refresh token
119
- */
120
- private async refreshAccessToken(): Promise<any> {
121
- if (!this.config.refreshToken) {
122
- throw new AuthenticationError('No refresh token available');
123
- }
124
-
125
- try {
126
- const response = await axios.post(
127
- `${this.config.baseURL}/auth/refresh`,
128
- { refresh_token: this.config.refreshToken },
129
- {
130
- headers: {
131
- 'Content-Type': 'application/json',
132
- },
133
- timeout: this.config.timeout || 30000,
134
- }
135
- );
136
-
137
- const newTokens = response.data;
138
- this.setTokens(newTokens.access_token, newTokens.refresh_token);
139
-
140
- return newTokens;
141
- } catch (error) {
142
- throw new AuthenticationError('Failed to refresh token');
143
- }
144
- }
145
71
 
146
72
  private handleError(error: AxiosError): GymSpaceError {
147
73
  const requestPath = error.config?.url || 'unknown';
@@ -248,10 +174,12 @@ export class ApiClient {
248
174
  this.config.apiKey = token;
249
175
  }
250
176
 
251
- setTokens(accessToken: string, refreshToken: string): void {
252
- this.config.apiKey = accessToken;
253
- // Store refresh token if needed for token refresh logic
254
- this.config.refreshToken = refreshToken;
177
+ setRefreshToken(token: string | null): void {
178
+ this.refreshToken = token;
179
+ }
180
+
181
+ getRefreshToken(): string | null {
182
+ return this.refreshToken;
255
183
  }
256
184
 
257
185
  setGymId(gymId: string): void {
@@ -260,7 +188,7 @@ export class ApiClient {
260
188
 
261
189
  clearAuth(): void {
262
190
  delete this.config.apiKey;
263
- delete this.config.refreshToken;
191
+ this.refreshToken = null;
264
192
  delete this.axiosInstance.defaults.headers.common['Authorization'];
265
193
  delete this.axiosInstance.defaults.headers.common['X-Gym-Id'];
266
194
  }
@@ -105,6 +105,8 @@ export interface InvitationValidationResponse {
105
105
  }
106
106
 
107
107
  export interface CurrentSessionResponse {
108
+ accessToken: string;
109
+ refreshToken?: string;
108
110
  user: {
109
111
  id: string;
110
112
  email: string;
@@ -43,7 +43,7 @@ export interface Contract {
43
43
  status: ContractStatus;
44
44
  price: number;
45
45
  discountPercentage?: number;
46
- finalPrice: number;
46
+ finalAmount: number;
47
47
  freezeStartDate?: string;
48
48
  freezeEndDate?: string;
49
49
  receiptIds?: string[];
@@ -52,6 +52,12 @@ export interface UpdatePaymentStatusDto {
52
52
  paymentStatus: 'paid' | 'unpaid';
53
53
  }
54
54
 
55
+ export interface PaySaleDto {
56
+ paymentMethodId: string;
57
+ notes?: string;
58
+ fileIds?: string[];
59
+ }
60
+
55
61
  export interface Sale {
56
62
  id: string;
57
63
  gymId: string;
@@ -18,8 +18,8 @@ export class OnboardingResource extends BaseResource {
18
18
  const response = await this.client.post<StartOnboardingResponse>('/onboarding/start', data);
19
19
 
20
20
  // Store tokens after successful onboarding start
21
- if (response.access_token && response.refresh_token) {
22
- this.client.setTokens(response.access_token, response.refresh_token);
21
+ if (response.access_token) {
22
+ this.client.setAuthToken(response.access_token);
23
23
  }
24
24
 
25
25
  return response;
@@ -1,9 +1,10 @@
1
1
  import { BaseResource } from './base';
2
- import {
2
+ import {
3
3
  Sale,
4
- CreateSaleDto,
4
+ CreateSaleDto,
5
5
  UpdateSaleDto,
6
6
  UpdatePaymentStatusDto,
7
+ PaySaleDto,
7
8
  SearchSalesParams,
8
9
  SalesStats,
9
10
  TopSellingProduct,
@@ -45,6 +46,14 @@ export class SalesResource extends BaseResource {
45
46
  return this.client.put<Sale>(`${this.basePath}/${id}/payment-status`, { paymentStatus }, options);
46
47
  }
47
48
 
49
+ async paySale(
50
+ id: string,
51
+ data: PaySaleDto,
52
+ options?: RequestOptions
53
+ ): Promise<Sale> {
54
+ return this.client.post<Sale>(`${this.basePath}/${id}/payment`, data, options);
55
+ }
56
+
48
57
  async deleteSale(id: string, options?: RequestOptions): Promise<void> {
49
58
  return this.client.delete<void>(`${this.basePath}/${id}`, options);
50
59
  }
package/src/sdk.ts CHANGED
@@ -88,10 +88,17 @@ export class GymSpaceSdk {
88
88
  }
89
89
 
90
90
  /**
91
- * Set both access and refresh tokens
91
+ * Set the refresh token
92
92
  */
93
- setTokens(accessToken: string, refreshToken: string): void {
94
- this.client.setTokens(accessToken, refreshToken);
93
+ setRefreshToken(token: string | null): void {
94
+ this.client.setRefreshToken(token);
95
+ }
96
+
97
+ /**
98
+ * Get the current refresh token
99
+ */
100
+ getRefreshToken(): string | null {
101
+ return this.client.getRefreshToken();
95
102
  }
96
103
 
97
104
  /**