skikrumb-api 2.1.1 → 2.1.3
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.js +89 -121
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -20,7 +20,9 @@ class SkiKrumbRealtimeClient {
|
|
|
20
20
|
return Promise.resolve();
|
|
21
21
|
}
|
|
22
22
|
// Additional guard: check if we're already connecting or connected
|
|
23
|
-
if (this.websocket &&
|
|
23
|
+
if (this.websocket &&
|
|
24
|
+
(this.websocket.readyState === WebSocket.CONNECTING ||
|
|
25
|
+
this.websocket.readyState === WebSocket.OPEN)) {
|
|
24
26
|
return Promise.resolve();
|
|
25
27
|
}
|
|
26
28
|
// Clean up any stale websocket before creating new one
|
|
@@ -39,7 +41,8 @@ class SkiKrumbRealtimeClient {
|
|
|
39
41
|
connectToWebSocket() {
|
|
40
42
|
return new Promise((resolve, reject) => {
|
|
41
43
|
try {
|
|
42
|
-
const baseWsUrl = this.url.replace(/^https/, 'wss').replace(/^http/, 'ws') +
|
|
44
|
+
const baseWsUrl = this.url.replace(/^https/, 'wss').replace(/^http/, 'ws') +
|
|
45
|
+
'/realtime';
|
|
43
46
|
let wsUrl = `${baseWsUrl}?token=${encodeURIComponent(this.sessionToken)}`;
|
|
44
47
|
if (this.supabaseToken) {
|
|
45
48
|
wsUrl += `&supabaseToken=${encodeURIComponent(this.supabaseToken)}`;
|
|
@@ -59,8 +62,8 @@ class SkiKrumbRealtimeClient {
|
|
|
59
62
|
this.emit('connected', message);
|
|
60
63
|
resolve();
|
|
61
64
|
}
|
|
62
|
-
else if (message.type === 'auth_error' ||
|
|
63
|
-
|
|
65
|
+
else if (message.type === 'auth_error' ||
|
|
66
|
+
message.type === 'error') {
|
|
64
67
|
(_a = this.websocket) === null || _a === void 0 ? void 0 : _a.close();
|
|
65
68
|
reject(new Error(`Connection failed: ${message.message || message.error}`));
|
|
66
69
|
}
|
|
@@ -77,12 +80,18 @@ class SkiKrumbRealtimeClient {
|
|
|
77
80
|
// Transform device data to match expected React Native format
|
|
78
81
|
const deviceData = {
|
|
79
82
|
...message.data,
|
|
80
|
-
device_id: ((_b = message.data.deveui) === null || _b === void 0 ? void 0 : _b.replace(/'/g, '')) ||
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
83
|
+
device_id: ((_b = message.data.deveui) === null || _b === void 0 ? void 0 : _b.replace(/'/g, '')) ||
|
|
84
|
+
message.data.device_id,
|
|
85
|
+
serial_number: ((_c = message.data.serial_number) === null || _c === void 0 ? void 0 : _c.replace(/'/g, '')) ||
|
|
86
|
+
message.data.serial_number,
|
|
87
|
+
gps_fix: ((_d = message.data.gps_fix) === null || _d === void 0 ? void 0 : _d.replace(/'/g, '')) ||
|
|
88
|
+
message.data.gps_fix,
|
|
89
|
+
gateway_id: ((_e = message.data.gateway_uuid) === null || _e === void 0 ? void 0 : _e.replace(/'/g, '')) ||
|
|
90
|
+
message.data.gateway_id,
|
|
91
|
+
created_at: ((_f = message.data.recorded_at) === null || _f === void 0 ? void 0 : _f.replace(/'/g, '')) ||
|
|
92
|
+
message.data.created_at ||
|
|
93
|
+
message.timestamp,
|
|
94
|
+
timestamp: message.timestamp,
|
|
86
95
|
};
|
|
87
96
|
this.emit('device_data', deviceData);
|
|
88
97
|
}
|
|
@@ -98,12 +107,10 @@ class SkiKrumbRealtimeClient {
|
|
|
98
107
|
}
|
|
99
108
|
}
|
|
100
109
|
catch (error) {
|
|
101
|
-
console.error('❌ Error parsing realtime message:', error);
|
|
102
110
|
this.emit('error', error);
|
|
103
111
|
}
|
|
104
112
|
};
|
|
105
113
|
this.websocket.onerror = (error) => {
|
|
106
|
-
console.error('❌ Realtime connection error:', error);
|
|
107
114
|
this.isConnecting = false;
|
|
108
115
|
this.emit('error', error);
|
|
109
116
|
reject(error);
|
|
@@ -143,9 +150,7 @@ class SkiKrumbRealtimeClient {
|
|
|
143
150
|
const delay = this.reconnectDelay * Math.pow(2, this.reconnectAttempts - 1);
|
|
144
151
|
setTimeout(() => {
|
|
145
152
|
this.connect().catch((error) => {
|
|
146
|
-
console.error('❌ Reconnect failed:', error);
|
|
147
153
|
if (this.reconnectAttempts >= this.maxReconnectAttempts) {
|
|
148
|
-
console.error('❌ Max reconnect attempts reached');
|
|
149
154
|
this.emit('max_reconnect_attempts_reached');
|
|
150
155
|
}
|
|
151
156
|
});
|
|
@@ -161,7 +166,8 @@ class SkiKrumbRealtimeClient {
|
|
|
161
166
|
this.websocket.onerror = null;
|
|
162
167
|
this.websocket.onclose = null;
|
|
163
168
|
// Close the connection if it's still open
|
|
164
|
-
if (this.websocket.readyState === WebSocket.OPEN ||
|
|
169
|
+
if (this.websocket.readyState === WebSocket.OPEN ||
|
|
170
|
+
this.websocket.readyState === WebSocket.CONNECTING) {
|
|
165
171
|
this.websocket.close(1000, 'Manual disconnect');
|
|
166
172
|
}
|
|
167
173
|
this.websocket = null;
|
|
@@ -174,7 +180,10 @@ class SkiKrumbRealtimeClient {
|
|
|
174
180
|
}
|
|
175
181
|
requestRefresh() {
|
|
176
182
|
if (this.websocket && this.websocket.readyState === WebSocket.OPEN) {
|
|
177
|
-
this.websocket.send(JSON.stringify({
|
|
183
|
+
this.websocket.send(JSON.stringify({
|
|
184
|
+
type: 'request_refresh',
|
|
185
|
+
timestamp: new Date().toISOString(),
|
|
186
|
+
}));
|
|
178
187
|
}
|
|
179
188
|
}
|
|
180
189
|
on(event, callback) {
|
|
@@ -199,9 +208,7 @@ class SkiKrumbRealtimeClient {
|
|
|
199
208
|
try {
|
|
200
209
|
callback(data);
|
|
201
210
|
}
|
|
202
|
-
catch (error) {
|
|
203
|
-
console.error(`❌ Error in realtime event listener for '${event}':`, error);
|
|
204
|
-
}
|
|
211
|
+
catch (error) { }
|
|
205
212
|
});
|
|
206
213
|
}
|
|
207
214
|
isConnected() {
|
|
@@ -305,118 +312,79 @@ export const skiKrumb = (options = {
|
|
|
305
312
|
}
|
|
306
313
|
};
|
|
307
314
|
const sendMobileLocation = async (payload) => {
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
return response;
|
|
313
|
-
}
|
|
314
|
-
catch (error) {
|
|
315
|
-
console.error('❌ Send Mobile Location Error:', error);
|
|
316
|
-
throw error;
|
|
317
|
-
}
|
|
315
|
+
const response = await request
|
|
316
|
+
.post('devices/location/mobile', { json: payload })
|
|
317
|
+
.json();
|
|
318
|
+
return response;
|
|
318
319
|
};
|
|
319
320
|
const authenticateExternalUser = async (userData) => {
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
return response;
|
|
325
|
-
}
|
|
326
|
-
catch (error) {
|
|
327
|
-
console.error('❌ External User Authentication Error:', error);
|
|
328
|
-
throw error;
|
|
329
|
-
}
|
|
321
|
+
const response = await request
|
|
322
|
+
.post('auth/external', { json: userData })
|
|
323
|
+
.json();
|
|
324
|
+
return response;
|
|
330
325
|
};
|
|
331
326
|
const refreshSessionToken = async (currentToken) => {
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
serialsCount: response.serialsCount,
|
|
350
|
-
timestamp: response.timestamp,
|
|
351
|
-
};
|
|
352
|
-
}
|
|
353
|
-
catch (error) {
|
|
354
|
-
console.error('❌ Token Refresh Error:', error);
|
|
355
|
-
throw error;
|
|
356
|
-
}
|
|
327
|
+
// Create temporary request with current token
|
|
328
|
+
const refreshRequest = ky.create({
|
|
329
|
+
prefixUrl: options.url,
|
|
330
|
+
headers: {
|
|
331
|
+
'Content-Type': 'application/json',
|
|
332
|
+
Authorization: `Bearer ${currentToken}`,
|
|
333
|
+
'x-client': options.requestedWith,
|
|
334
|
+
},
|
|
335
|
+
});
|
|
336
|
+
const response = await refreshRequest.post('auth/external/refresh').json();
|
|
337
|
+
return {
|
|
338
|
+
success: response.success,
|
|
339
|
+
sessionToken: response.sessionToken,
|
|
340
|
+
accessibleSerials: response.accessibleSerials,
|
|
341
|
+
serialsCount: response.serialsCount,
|
|
342
|
+
timestamp: response.timestamp,
|
|
343
|
+
};
|
|
357
344
|
};
|
|
358
|
-
// Sharing API endpoints
|
|
359
345
|
const createSharingLink = async (shareRequest) => {
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
return response;
|
|
374
|
-
}
|
|
375
|
-
catch (error) {
|
|
376
|
-
console.error('❌ Create Sharing Link Error:', error);
|
|
377
|
-
throw error;
|
|
378
|
-
}
|
|
346
|
+
const requestWithAuth = ky.create({
|
|
347
|
+
prefixUrl: options.url,
|
|
348
|
+
headers: {
|
|
349
|
+
'Content-Type': 'application/json',
|
|
350
|
+
Authorization: `Bearer ${options.apiKey}`,
|
|
351
|
+
'supabase-auth-token': options.supabaseToken || '',
|
|
352
|
+
'x-client': options.requestedWith,
|
|
353
|
+
},
|
|
354
|
+
});
|
|
355
|
+
const response = await requestWithAuth
|
|
356
|
+
.post('sharing/create', { json: shareRequest })
|
|
357
|
+
.json();
|
|
358
|
+
return response;
|
|
379
359
|
};
|
|
380
360
|
const previewSharingLink = async (token) => {
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
return response;
|
|
394
|
-
}
|
|
395
|
-
catch (error) {
|
|
396
|
-
console.error('❌ Preview Sharing Link Error:', error);
|
|
397
|
-
throw error;
|
|
398
|
-
}
|
|
361
|
+
const requestWithAuth = ky.create({
|
|
362
|
+
prefixUrl: options.url,
|
|
363
|
+
headers: {
|
|
364
|
+
Authorization: `Bearer ${options.apiKey}`,
|
|
365
|
+
'supabase-auth-token': options.supabaseToken || '',
|
|
366
|
+
'x-client': options.requestedWith,
|
|
367
|
+
},
|
|
368
|
+
});
|
|
369
|
+
const response = await requestWithAuth
|
|
370
|
+
.get(`sharing/accept/${token}`)
|
|
371
|
+
.json();
|
|
372
|
+
return response;
|
|
399
373
|
};
|
|
400
374
|
const acceptSharingLink = async (token, acceptRequest) => {
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
return response;
|
|
415
|
-
}
|
|
416
|
-
catch (error) {
|
|
417
|
-
console.error('❌ Accept Sharing Link Error:', error);
|
|
418
|
-
throw error;
|
|
419
|
-
}
|
|
375
|
+
const requestWithAuth = ky.create({
|
|
376
|
+
prefixUrl: options.url,
|
|
377
|
+
headers: {
|
|
378
|
+
'Content-Type': 'application/json',
|
|
379
|
+
Authorization: `Bearer ${options.apiKey}`,
|
|
380
|
+
'supabase-auth-token': options.supabaseToken || '',
|
|
381
|
+
'x-client': options.requestedWith,
|
|
382
|
+
},
|
|
383
|
+
});
|
|
384
|
+
const response = await requestWithAuth
|
|
385
|
+
.post(`sharing/accept/${token}`, { json: acceptRequest })
|
|
386
|
+
.json();
|
|
387
|
+
return response;
|
|
420
388
|
};
|
|
421
389
|
return {
|
|
422
390
|
createDevice,
|