@gymspace/sdk 1.0.3 → 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/dist/index.d.mts +1 -12
- package/dist/index.d.ts +1 -12
- package/dist/index.js +3 -71
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3 -71
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/client.ts +2 -89
- package/src/models/auth.ts +1 -0
- package/src/resources/onboarding.ts +2 -2
- package/src/sdk.ts +0 -6
package/src/client.ts
CHANGED
|
@@ -18,11 +18,6 @@ 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;
|
|
26
21
|
|
|
27
22
|
constructor(config: GymSpaceConfig) {
|
|
28
23
|
this.config = config;
|
|
@@ -48,11 +43,6 @@ export class ApiClient {
|
|
|
48
43
|
config.headers['Authorization'] = `Bearer ${this.config.apiKey}`;
|
|
49
44
|
}
|
|
50
45
|
|
|
51
|
-
// Add refresh token header if available
|
|
52
|
-
if (this.config.refreshToken && config.headers) {
|
|
53
|
-
config.headers['X-Refresh-Token'] = this.config.refreshToken;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
46
|
return config;
|
|
57
47
|
},
|
|
58
48
|
(error) => {
|
|
@@ -60,88 +50,18 @@ export class ApiClient {
|
|
|
60
50
|
},
|
|
61
51
|
);
|
|
62
52
|
|
|
63
|
-
// Response interceptor
|
|
53
|
+
// Response interceptor - simplified without automatic token refresh
|
|
64
54
|
this.axiosInstance.interceptors.response.use(
|
|
65
55
|
(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
56
|
return response;
|
|
77
57
|
},
|
|
78
58
|
async (error: AxiosError) => {
|
|
79
|
-
|
|
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
|
-
|
|
59
|
+
// Simply throw the error - no automatic refresh attempts
|
|
112
60
|
throw this.handleError(error);
|
|
113
61
|
},
|
|
114
62
|
);
|
|
115
63
|
}
|
|
116
64
|
|
|
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
65
|
|
|
146
66
|
private handleError(error: AxiosError): GymSpaceError {
|
|
147
67
|
const requestPath = error.config?.url || 'unknown';
|
|
@@ -248,19 +168,12 @@ export class ApiClient {
|
|
|
248
168
|
this.config.apiKey = token;
|
|
249
169
|
}
|
|
250
170
|
|
|
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;
|
|
255
|
-
}
|
|
256
|
-
|
|
257
171
|
setGymId(gymId: string): void {
|
|
258
172
|
this.axiosInstance.defaults.headers.common['X-Gym-Id'] = gymId;
|
|
259
173
|
}
|
|
260
174
|
|
|
261
175
|
clearAuth(): void {
|
|
262
176
|
delete this.config.apiKey;
|
|
263
|
-
delete this.config.refreshToken;
|
|
264
177
|
delete this.axiosInstance.defaults.headers.common['Authorization'];
|
|
265
178
|
delete this.axiosInstance.defaults.headers.common['X-Gym-Id'];
|
|
266
179
|
}
|
package/src/models/auth.ts
CHANGED
|
@@ -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
|
|
22
|
-
this.client.
|
|
21
|
+
if (response.access_token) {
|
|
22
|
+
this.client.setAuthToken(response.access_token);
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
return response;
|
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
|