@gymspace/sdk 1.0.2 → 1.1.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/src/client.ts CHANGED
@@ -3,6 +3,7 @@ import axios, {
3
3
  AxiosRequestConfig,
4
4
  AxiosError,
5
5
  InternalAxiosRequestConfig,
6
+ AxiosRequestHeaders,
6
7
  } from 'axios';
7
8
  import { GymSpaceConfig, RequestOptions } from './types';
8
9
  import {
@@ -17,11 +18,6 @@ import {
17
18
  export class ApiClient {
18
19
  private axiosInstance: AxiosInstance;
19
20
  private config: GymSpaceConfig;
20
- private refreshPromise: Promise<any> | null = null; // To prevent concurrent refresh attempts
21
-
22
- // Callbacks for token updates and auth errors
23
- public onTokensUpdated?: (accessToken: string, refreshToken: string) => void;
24
- public onAuthError?: (error: any) => void;
25
21
 
26
22
  constructor(config: GymSpaceConfig) {
27
23
  this.config = config;
@@ -47,11 +43,6 @@ export class ApiClient {
47
43
  config.headers['Authorization'] = `Bearer ${this.config.apiKey}`;
48
44
  }
49
45
 
50
- // Add refresh token header if available
51
- if (this.config.refreshToken && config.headers) {
52
- config.headers['X-Refresh-Token'] = this.config.refreshToken;
53
- }
54
-
55
46
  return config;
56
47
  },
57
48
  (error) => {
@@ -59,86 +50,18 @@ export class ApiClient {
59
50
  },
60
51
  );
61
52
 
62
- // Response interceptor with automatic token refresh
53
+ // Response interceptor - simplified without automatic token refresh
63
54
  this.axiosInstance.interceptors.response.use(
64
55
  (response) => {
65
- // Check for new tokens in response headers
66
- const newAccessToken = response.headers['x-new-access-token'];
67
- const newRefreshToken = response.headers['x-new-refresh-token'];
68
-
69
- if (newAccessToken && newRefreshToken) {
70
- this.setTokens(newAccessToken, newRefreshToken);
71
- // Emit token update event if needed
72
- this.onTokensUpdated?.(newAccessToken, newRefreshToken);
73
- }
74
-
75
56
  return response;
76
57
  },
77
58
  async (error: AxiosError) => {
78
- const originalRequest = error.config as InternalAxiosRequestConfig & { _retry?: boolean };
79
-
80
- // If it's a 401 error and we haven't retried yet, try to refresh the token
81
- if (error.response?.status === 401 && !originalRequest._retry && this.config.refreshToken) {
82
- originalRequest._retry = true;
83
-
84
- try {
85
- // Prevent concurrent refresh attempts
86
- if (!this.refreshPromise) {
87
- this.refreshPromise = this.refreshAccessToken();
88
- }
89
-
90
- const newTokens = await this.refreshPromise;
91
- this.refreshPromise = null;
92
-
93
- if (newTokens) {
94
- // Update the original request with new token
95
- originalRequest.headers = originalRequest.headers || {};
96
- originalRequest.headers['Authorization'] = `Bearer ${newTokens.access_token}`;
97
-
98
- // Retry the original request
99
- return this.axiosInstance(originalRequest);
100
- }
101
- } catch (refreshError) {
102
- this.refreshPromise = null;
103
- // If refresh fails, clear tokens and emit error
104
- this.clearAuth();
105
- this.onAuthError?.(refreshError);
106
- }
107
- }
108
-
59
+ // Simply throw the error - no automatic refresh attempts
109
60
  throw this.handleError(error);
110
61
  },
111
62
  );
112
63
  }
113
64
 
114
- /**
115
- * Refresh the access token using the stored refresh token
116
- */
117
- private async refreshAccessToken(): Promise<any> {
118
- if (!this.config.refreshToken) {
119
- throw new AuthenticationError('No refresh token available');
120
- }
121
-
122
- try {
123
- const response = await axios.post(
124
- `${this.config.baseURL}/auth/refresh`,
125
- { refresh_token: this.config.refreshToken },
126
- {
127
- headers: {
128
- 'Content-Type': 'application/json',
129
- },
130
- timeout: this.config.timeout || 30000,
131
- }
132
- );
133
-
134
- const newTokens = response.data;
135
- this.setTokens(newTokens.access_token, newTokens.refresh_token);
136
-
137
- return newTokens;
138
- } catch (error) {
139
- throw new AuthenticationError('Failed to refresh token');
140
- }
141
- }
142
65
 
143
66
  private handleError(error: AxiosError): GymSpaceError {
144
67
  const requestPath = error.config?.url || 'unknown';
@@ -245,19 +168,12 @@ export class ApiClient {
245
168
  this.config.apiKey = token;
246
169
  }
247
170
 
248
- setTokens(accessToken: string, refreshToken: string): void {
249
- this.config.apiKey = accessToken;
250
- // Store refresh token if needed for token refresh logic
251
- this.config.refreshToken = refreshToken;
252
- }
253
-
254
171
  setGymId(gymId: string): void {
255
172
  this.axiosInstance.defaults.headers.common['X-Gym-Id'] = gymId;
256
173
  }
257
174
 
258
175
  clearAuth(): void {
259
176
  delete this.config.apiKey;
260
- delete this.config.refreshToken;
261
177
  delete this.axiosInstance.defaults.headers.common['Authorization'];
262
178
  delete this.axiosInstance.defaults.headers.common['X-Gym-Id'];
263
179
  }
@@ -1,3 +1,5 @@
1
+ import { SubscriptionPlan } from './subscriptions';
2
+
1
3
  export interface RegisterOwnerDto {
2
4
  name: string;
3
5
  email: string;
@@ -79,7 +81,6 @@ export interface ResendResetCodeResponseDto {
79
81
  message: string;
80
82
  }
81
83
 
82
-
83
84
  export interface RegisterCollaboratorDto {
84
85
  invitationToken: string;
85
86
  name: string;
@@ -87,19 +88,6 @@ export interface RegisterCollaboratorDto {
87
88
  password: string;
88
89
  }
89
90
 
90
- export interface SubscriptionPlan {
91
- id: string;
92
- name: string;
93
- price: number;
94
- billingFrequency: string;
95
- maxGyms: number;
96
- maxClientsPerGym: number;
97
- maxUsersPerGym: number;
98
- features: any;
99
- description?: string;
100
- }
101
-
102
-
103
91
  export interface InvitationValidationResponse {
104
92
  valid: boolean;
105
93
  invitation: {
@@ -117,6 +105,7 @@ export interface InvitationValidationResponse {
117
105
  }
118
106
 
119
107
  export interface CurrentSessionResponse {
108
+ accessToken: string;
120
109
  user: {
121
110
  id: string;
122
111
  email: string;
@@ -19,4 +19,20 @@ export interface OrganizationStats {
19
19
  totalContracts: number;
20
20
  activeContracts: number;
21
21
  totalRevenue: number;
22
+ }
23
+
24
+ export interface OrganizationWithDetails {
25
+ id: string;
26
+ name: string;
27
+ owner: {
28
+ id: string;
29
+ email: string;
30
+ fullName: string;
31
+ };
32
+ gyms: Array<{
33
+ id: string;
34
+ name: string;
35
+ address: string;
36
+ }>;
37
+ createdAt: Date;
22
38
  }
@@ -6,7 +6,6 @@ import {
6
6
  RegisterCollaboratorDto,
7
7
  RegisterOwnerDto,
8
8
  ResendVerificationDto,
9
- SubscriptionPlan,
10
9
  VerifyEmailDto,
11
10
  ChangePasswordDto,
12
11
  ChangePasswordResponseDto,
@@ -19,6 +18,7 @@ import {
19
18
  ResendResetCodeDto,
20
19
  ResendResetCodeResponseDto,
21
20
  } from '../models/auth';
21
+ import { SubscriptionPlan } from '../models/subscriptions';
22
22
  import { RequestOptions } from '../types';
23
23
  import { BaseResource } from './base';
24
24
 
@@ -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,5 +1,5 @@
1
1
  import { BaseResource } from './base';
2
- import { Organization, UpdateOrganizationDto, OrganizationStats } from '../models/organizations';
2
+ import { Organization, UpdateOrganizationDto, OrganizationStats, OrganizationWithDetails } from '../models/organizations';
3
3
  import { RequestOptions } from '../types';
4
4
 
5
5
  export class OrganizationsResource extends BaseResource {
@@ -20,4 +20,8 @@ export class OrganizationsResource extends BaseResource {
20
20
  async getOrganizationStats(id: string, options?: RequestOptions): Promise<OrganizationStats> {
21
21
  return this.client.get<OrganizationStats>(`${this.basePath}/${id}/stats`, undefined, options);
22
22
  }
23
+
24
+ async listOrganizations(options?: RequestOptions): Promise<OrganizationWithDetails[]> {
25
+ return this.client.get<OrganizationWithDetails[]>(`${this.basePath}/list`, undefined, options);
26
+ }
23
27
  }
package/src/sdk.ts CHANGED
@@ -87,12 +87,6 @@ export class GymSpaceSdk {
87
87
  this.client.setAuthToken(token);
88
88
  }
89
89
 
90
- /**
91
- * Set both access and refresh tokens
92
- */
93
- setTokens(accessToken: string, refreshToken: string): void {
94
- this.client.setTokens(accessToken, refreshToken);
95
- }
96
90
 
97
91
  /**
98
92
  * Set the current gym context