@passgage/sdk-react-native 1.0.1 → 1.0.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.mjs CHANGED
@@ -1,15 +1,1161 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __export = (target, all) => {
3
+ for (var name in all)
4
+ __defProp(target, name, { get: all[name], enumerable: true });
5
+ };
6
+
7
+ // src/api/client.ts
8
+ import axios from "axios";
9
+ var ApiClient = class {
10
+ constructor(config) {
11
+ this.isRefreshing = false;
12
+ this.refreshQueue = [];
13
+ this.config = {
14
+ timeout: 3e4,
15
+ apiVersion: "v2",
16
+ ...config
17
+ };
18
+ this.axiosInstance = axios.create({
19
+ baseURL: `${this.config.baseURL}/api/${this.config.apiVersion}`,
20
+ timeout: this.config.timeout,
21
+ headers: {
22
+ "Content-Type": "application/json",
23
+ Accept: "application/json",
24
+ ...this.config.headers
25
+ }
26
+ });
27
+ this.setupInterceptors();
28
+ }
29
+ /**
30
+ * Setup request and response interceptors
31
+ */
32
+ setupInterceptors() {
33
+ this.axiosInstance.interceptors.request.use(
34
+ (config) => {
35
+ const skipAuth = config.skipAuth;
36
+ if (this.config.token && !skipAuth) {
37
+ config.headers.Authorization = `Bearer ${this.config.token}`;
38
+ }
39
+ return config;
40
+ },
41
+ (error) => {
42
+ return Promise.reject(this.handleError(error));
43
+ }
44
+ );
45
+ this.axiosInstance.interceptors.response.use(
46
+ (response) => response,
47
+ async (error) => {
48
+ const originalRequest = error.config;
49
+ if (error.response?.status === 401 && originalRequest && !originalRequest._retry) {
50
+ const skipAuth = originalRequest.skipAuth;
51
+ if (skipAuth) {
52
+ return Promise.reject(this.handleError(error));
53
+ }
54
+ if (this.config.onTokenRefreshNeeded) {
55
+ originalRequest._retry = true;
56
+ const retryOriginalRequest = new Promise((resolve, reject) => {
57
+ this.refreshQueue.push({
58
+ config: originalRequest,
59
+ resolve,
60
+ reject
61
+ });
62
+ });
63
+ if (!this.isRefreshing) {
64
+ this.isRefreshing = true;
65
+ try {
66
+ const newToken = await this.config.onTokenRefreshNeeded();
67
+ if (newToken) {
68
+ this.setToken(newToken);
69
+ this.refreshQueue.forEach(({ config, resolve, reject }) => {
70
+ if (config.headers) {
71
+ config.headers.Authorization = `Bearer ${newToken}`;
72
+ }
73
+ this.axiosInstance.request(config).then(resolve).catch(reject);
74
+ });
75
+ this.refreshQueue = [];
76
+ } else {
77
+ this.refreshQueue.forEach(({ reject }) => {
78
+ reject(new Error("Token refresh failed"));
79
+ });
80
+ this.refreshQueue = [];
81
+ if (this.config.onUnauthorized) {
82
+ this.config.onUnauthorized();
83
+ }
84
+ }
85
+ } catch (refreshError) {
86
+ this.refreshQueue.forEach(({ reject }) => {
87
+ reject(refreshError);
88
+ });
89
+ this.refreshQueue = [];
90
+ if (this.config.onUnauthorized) {
91
+ this.config.onUnauthorized();
92
+ }
93
+ } finally {
94
+ this.isRefreshing = false;
95
+ }
96
+ }
97
+ return retryOriginalRequest;
98
+ } else {
99
+ if (this.config.onUnauthorized) {
100
+ this.config.onUnauthorized();
101
+ }
102
+ }
103
+ }
104
+ const apiError = this.handleError(error);
105
+ if (this.config.onError) {
106
+ this.config.onError(apiError);
107
+ }
108
+ return Promise.reject(apiError);
109
+ }
110
+ );
111
+ }
112
+ /**
113
+ * Handle API errors
114
+ */
115
+ handleError(error) {
116
+ const responseData = error.response?.data;
117
+ const apiError = new Error(
118
+ responseData?.message || error.message || "An unknown error occurred"
119
+ );
120
+ apiError.code = error.code;
121
+ apiError.status = error.response?.status;
122
+ apiError.response = responseData;
123
+ return apiError;
124
+ }
125
+ /**
126
+ * Update authorization token
127
+ */
128
+ setToken(token) {
129
+ this.config.token = token || void 0;
130
+ }
131
+ /**
132
+ * Remove authorization token
133
+ */
134
+ clearToken() {
135
+ this.config.token = void 0;
136
+ }
137
+ /**
138
+ * Generic GET request
139
+ */
140
+ async get(options) {
141
+ const response = await this.axiosInstance.get(options.endpoint, {
142
+ params: options.params,
143
+ headers: options.headers,
144
+ ...options.config,
145
+ skipAuth: options.skipAuth
146
+ });
147
+ return response.data;
148
+ }
149
+ /**
150
+ * Generic POST request
151
+ */
152
+ async post(options) {
153
+ const response = await this.axiosInstance.post(
154
+ options.endpoint,
155
+ options.data,
156
+ {
157
+ params: options.params,
158
+ headers: options.headers,
159
+ ...options.config,
160
+ skipAuth: options.skipAuth
161
+ }
162
+ );
163
+ return response.data;
164
+ }
165
+ /**
166
+ * Generic PUT request
167
+ */
168
+ async put(options) {
169
+ const response = await this.axiosInstance.put(
170
+ options.endpoint,
171
+ options.data,
172
+ {
173
+ params: options.params,
174
+ headers: options.headers,
175
+ ...options.config,
176
+ skipAuth: options.skipAuth
177
+ }
178
+ );
179
+ return response.data;
180
+ }
181
+ /**
182
+ * Generic PATCH request
183
+ */
184
+ async patch(options) {
185
+ const response = await this.axiosInstance.patch(
186
+ options.endpoint,
187
+ options.data,
188
+ {
189
+ params: options.params,
190
+ headers: options.headers,
191
+ ...options.config,
192
+ skipAuth: options.skipAuth
193
+ }
194
+ );
195
+ return response.data;
196
+ }
197
+ /**
198
+ * Generic DELETE request
199
+ */
200
+ async delete(options) {
201
+ const response = await this.axiosInstance.delete(options.endpoint, {
202
+ params: options.params,
203
+ headers: options.headers,
204
+ ...options.config,
205
+ skipAuth: options.skipAuth
206
+ });
207
+ return response.data;
208
+ }
209
+ };
210
+ function createApiClient(config) {
211
+ return new ApiClient(config);
212
+ }
213
+
214
+ // src/api/endpoints.ts
215
+ var endpoints_exports = {};
216
+ __export(endpoints_exports, {
217
+ EP_BRANCHES: () => EP_BRANCHES,
218
+ EP_CREATE_QR: () => EP_CREATE_QR,
219
+ EP_DEVICES: () => EP_DEVICES,
220
+ EP_ENTRANCES: () => EP_ENTRANCES,
221
+ EP_LOCATION_VERIFICATION: () => EP_LOCATION_VERIFICATION,
222
+ EP_LOGIN: () => EP_LOGIN,
223
+ EP_ME: () => EP_ME,
224
+ EP_NFC_CHECK: () => EP_NFC_CHECK,
225
+ EP_QR_ACCESS: () => EP_QR_ACCESS,
226
+ EP_QR_CHECK: () => EP_QR_CHECK,
227
+ EP_QR_DEVICES: () => EP_QR_DEVICES,
228
+ EP_TOKEN: () => EP_TOKEN,
229
+ EP_TRIGGER_IOT: () => EP_TRIGGER_IOT,
230
+ EP_USERS: () => EP_USERS
231
+ });
232
+ var EP_LOGIN = "users/sign_in";
233
+ var EP_TOKEN = "token";
234
+ var EP_DEVICES = "devices";
235
+ var EP_QR_DEVICES = "devices/qr_devices";
236
+ var EP_QR_ACCESS = "qr_access/accessible_qrs";
237
+ var EP_QR_CHECK = "qr_check";
238
+ var EP_NFC_CHECK = "nfc_check";
239
+ var EP_ENTRANCES = "entrances";
240
+ var EP_CREATE_QR = "entrances/create_from_qr";
241
+ var EP_BRANCHES = "branches";
242
+ var EP_LOCATION_VERIFICATION = "location_verification_logs";
243
+ var EP_TRIGGER_IOT = "iot/trigger";
244
+ var EP_USERS = "users";
245
+ var EP_ME = "users/lite_me";
246
+
247
+ // src/models/common.ts
248
+ var EntranceType = /* @__PURE__ */ ((EntranceType2) => {
249
+ EntranceType2[EntranceType2["ENTRY"] = 0] = "ENTRY";
250
+ EntranceType2[EntranceType2["EXIT"] = 1] = "EXIT";
251
+ return EntranceType2;
252
+ })(EntranceType || {});
253
+ var DeviceUsage = /* @__PURE__ */ ((DeviceUsage2) => {
254
+ DeviceUsage2["PDKS"] = "pdks";
255
+ DeviceUsage2["MEETING_ROOM"] = "meeting_room";
256
+ DeviceUsage2["FOOD"] = "food";
257
+ return DeviceUsage2;
258
+ })(DeviceUsage || {});
259
+ var DeviceDirection = /* @__PURE__ */ ((DeviceDirection2) => {
260
+ DeviceDirection2[DeviceDirection2["ENTRY"] = 0] = "ENTRY";
261
+ DeviceDirection2[DeviceDirection2["EXIT"] = 1] = "EXIT";
262
+ DeviceDirection2[DeviceDirection2["BIDIRECTIONAL"] = 2] = "BIDIRECTIONAL";
263
+ return DeviceDirection2;
264
+ })(DeviceDirection || {});
265
+
266
+ // src/services/AuthService.ts
267
+ var AuthService = class {
268
+ constructor(apiClient) {
269
+ this.apiClient = apiClient;
270
+ }
271
+ /**
272
+ * Set token storage implementation
273
+ * This is used by platform-specific implementations (React Native, Android, iOS)
274
+ */
275
+ setTokenStorage(storage) {
276
+ this.tokenStorage = storage;
277
+ }
278
+ /**
279
+ * Login with credentials
280
+ *
281
+ * @param credentials - User login credentials (email/phone and password)
282
+ * @returns Login result with tokens on success
283
+ *
284
+ * @example
285
+ * ```typescript
286
+ * const result = await authService.login({
287
+ * login: 'user@example.com',
288
+ * password: 'password123'
289
+ * });
290
+ *
291
+ * if (result.success) {
292
+ * console.log('Access token:', result.tokens.access.token);
293
+ * } else {
294
+ * console.error('Login failed:', result.error);
295
+ * }
296
+ * ```
297
+ */
298
+ async login(credentials) {
299
+ try {
300
+ const requestBody = {
301
+ user: {
302
+ login: credentials.login,
303
+ password: credentials.password
304
+ }
305
+ };
306
+ const response = await this.apiClient.post({
307
+ endpoint: "/api/v2/users/sign_in",
308
+ data: requestBody,
309
+ skipAuth: true
310
+ // Don't send auth header for login
311
+ });
312
+ if (!response.success || !response.data?.tokens) {
313
+ return {
314
+ success: false,
315
+ error: response.message || "Login failed",
316
+ code: "LOGIN_FAILED"
317
+ };
318
+ }
319
+ const tokens = response.data.tokens;
320
+ if (this.tokenStorage) {
321
+ await this.tokenStorage.saveTokens(tokens);
322
+ }
323
+ this.apiClient.setToken(tokens.access.token);
324
+ let user;
325
+ try {
326
+ const userResult = await this.getCurrentUser();
327
+ if (userResult.success) {
328
+ user = userResult.user;
329
+ if (this.tokenStorage) {
330
+ await this.tokenStorage.saveUser(user);
331
+ }
332
+ }
333
+ } catch (error) {
334
+ console.warn("Failed to fetch user info after login:", error);
335
+ }
336
+ return {
337
+ success: true,
338
+ tokens,
339
+ user
340
+ };
341
+ } catch (error) {
342
+ return {
343
+ success: false,
344
+ error: error.message || "An error occurred during login",
345
+ code: error.code || "NETWORK_ERROR"
346
+ };
347
+ }
348
+ }
349
+ /**
350
+ * Refresh access token using refresh token
351
+ *
352
+ * @param refreshToken - The refresh token
353
+ * @returns Refresh result with new tokens on success
354
+ *
355
+ * @example
356
+ * ```typescript
357
+ * const result = await authService.refreshToken('refresh_token_here');
358
+ *
359
+ * if (result.success) {
360
+ * console.log('New access token:', result.tokens.access.token);
361
+ * }
362
+ * ```
363
+ */
364
+ async refreshToken(refreshToken) {
365
+ try {
366
+ const requestBody = {
367
+ refresh_token: refreshToken
368
+ };
369
+ const response = await this.apiClient.post({
370
+ endpoint: "/token",
371
+ data: requestBody,
372
+ skipAuth: true
373
+ });
374
+ if (!response.success || !response.data?.token || !response.data?.refresh_token) {
375
+ return {
376
+ success: false,
377
+ error: response.message || "Token refresh failed",
378
+ code: "REFRESH_FAILED"
379
+ };
380
+ }
381
+ const tokens = {
382
+ access: {
383
+ token: response.data.token,
384
+ expiresIn: "30 days"
385
+ },
386
+ refresh: {
387
+ token: response.data.refresh_token,
388
+ expiresIn: "30 days"
389
+ }
390
+ };
391
+ if (this.tokenStorage) {
392
+ await this.tokenStorage.saveTokens(tokens);
393
+ }
394
+ this.apiClient.setToken(tokens.access.token);
395
+ return {
396
+ success: true,
397
+ tokens
398
+ };
399
+ } catch (error) {
400
+ return {
401
+ success: false,
402
+ error: error.message || "An error occurred during token refresh",
403
+ code: error.code || "NETWORK_ERROR"
404
+ };
405
+ }
406
+ }
407
+ /**
408
+ * Get current user information
409
+ *
410
+ * @returns Result with user information
411
+ *
412
+ * @example
413
+ * ```typescript
414
+ * const result = await authService.getCurrentUser();
415
+ *
416
+ * if (result.success) {
417
+ * console.log('User name:', result.user.fullName);
418
+ * }
419
+ * ```
420
+ */
421
+ async getCurrentUser() {
422
+ try {
423
+ const response = await this.apiClient.get({
424
+ endpoint: "/api/v2/users/me"
425
+ });
426
+ if (!response.success || !response.data) {
427
+ return {
428
+ success: false,
429
+ error: response.message || "Failed to fetch user information"
430
+ };
431
+ }
432
+ const userData = response.data;
433
+ const user = {
434
+ id: userData.id,
435
+ email: userData.email,
436
+ firstName: userData.first_name,
437
+ lastName: userData.last_name,
438
+ company: {
439
+ id: userData.company.id,
440
+ name: userData.company.name
441
+ },
442
+ fullName: userData.full_name || `${userData.first_name} ${userData.last_name}`,
443
+ gsm: userData.gsm,
444
+ avatar: userData.avatar?.url,
445
+ jobTitle: userData.job_title,
446
+ birthDate: userData.birth_date,
447
+ cardNo: userData.card_no
448
+ };
449
+ return {
450
+ success: true,
451
+ user
452
+ };
453
+ } catch (error) {
454
+ return {
455
+ success: false,
456
+ error: error.message || "Failed to fetch user information"
457
+ };
458
+ }
459
+ }
460
+ /**
461
+ * Logout current user
462
+ * Clears tokens from storage and API client
463
+ *
464
+ * @example
465
+ * ```typescript
466
+ * await authService.logout();
467
+ * console.log('User logged out');
468
+ * ```
469
+ */
470
+ async logout() {
471
+ if (this.tokenStorage) {
472
+ await this.tokenStorage.clearTokens();
473
+ await this.tokenStorage.clearUser();
474
+ }
475
+ this.apiClient.setToken(null);
476
+ }
477
+ /**
478
+ * Check if user is authenticated
479
+ *
480
+ * @returns True if user has valid tokens
481
+ */
482
+ async isAuthenticated() {
483
+ if (!this.tokenStorage) {
484
+ return false;
485
+ }
486
+ const tokens = await this.tokenStorage.getTokens();
487
+ return tokens !== null && tokens.access.token.length > 0;
488
+ }
489
+ /**
490
+ * Get stored tokens
491
+ *
492
+ * @returns Stored tokens or null
493
+ */
494
+ async getStoredTokens() {
495
+ if (!this.tokenStorage) {
496
+ return null;
497
+ }
498
+ return await this.tokenStorage.getTokens();
499
+ }
500
+ /**
501
+ * Get stored user
502
+ *
503
+ * @returns Stored user or null
504
+ */
505
+ async getStoredUser() {
506
+ if (!this.tokenStorage) {
507
+ return null;
508
+ }
509
+ return await this.tokenStorage.getUser();
510
+ }
511
+ };
512
+
513
+ // src/utils/location.ts
514
+ function calculateDistance(lat1, lon1, lat2, lon2) {
515
+ const R = 6371e3;
516
+ const \u03C61 = lat1 * Math.PI / 180;
517
+ const \u03C62 = lat2 * Math.PI / 180;
518
+ const \u0394\u03C6 = (lat2 - lat1) * Math.PI / 180;
519
+ const \u0394\u03BB = (lon2 - lon1) * Math.PI / 180;
520
+ const a = Math.sin(\u0394\u03C6 / 2) * Math.sin(\u0394\u03C6 / 2) + Math.cos(\u03C61) * Math.cos(\u03C62) * Math.sin(\u0394\u03BB / 2) * Math.sin(\u0394\u03BB / 2);
521
+ const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
522
+ return R * c;
523
+ }
524
+ function checkOnLocation(targetLat, targetLon, allowedRange, userPosition) {
525
+ if (!userPosition) {
526
+ return { ok: false };
527
+ }
528
+ const distance = calculateDistance(
529
+ targetLat,
530
+ targetLon,
531
+ userPosition.latitude,
532
+ userPosition.longitude
533
+ );
534
+ return {
535
+ ok: distance <= allowedRange,
536
+ distance
537
+ };
538
+ }
539
+ function validateCoordinates(coords) {
540
+ if (!coords) {
541
+ return false;
542
+ }
543
+ const { latitude, longitude } = coords;
544
+ return typeof latitude === "number" && typeof longitude === "number" && latitude >= -90 && latitude <= 90 && longitude >= -180 && longitude <= 180;
545
+ }
546
+
547
+ // src/utils/validation.ts
548
+ var READ_TIMEOUT = 15e3;
549
+ var readRecords = [];
550
+ function checkRepetitiveRead(code) {
551
+ const now = Date.now();
552
+ readRecords = readRecords.filter((record) => now - record.timestamp < READ_TIMEOUT);
553
+ const recentRead = readRecords.find(
554
+ (record) => record.code === code && now - record.timestamp < READ_TIMEOUT
555
+ );
556
+ if (recentRead) {
557
+ return false;
558
+ }
559
+ readRecords.push({ code, timestamp: now });
560
+ return true;
561
+ }
562
+ function clearReadRecords() {
563
+ readRecords = [];
564
+ }
565
+ function validateQRCode(code) {
566
+ return typeof code === "string" && code.length > 0;
567
+ }
568
+ function validateNFCCode(code) {
569
+ return typeof code === "string" && code.length > 0;
570
+ }
571
+ function validateDeviceId(id) {
572
+ const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
573
+ return uuidRegex.test(id);
574
+ }
575
+
576
+ // src/utils/date.ts
577
+ function formatISO(date = /* @__PURE__ */ new Date()) {
578
+ return date.toISOString();
579
+ }
580
+ function formatDate(date = /* @__PURE__ */ new Date()) {
581
+ const year = date.getFullYear();
582
+ const month = String(date.getMonth() + 1).padStart(2, "0");
583
+ const day = String(date.getDate()).padStart(2, "0");
584
+ return `${year}-${month}-${day}`;
585
+ }
586
+ function formatTime(date = /* @__PURE__ */ new Date()) {
587
+ const hours = String(date.getHours()).padStart(2, "0");
588
+ const minutes = String(date.getMinutes()).padStart(2, "0");
589
+ return `${hours}:${minutes}`;
590
+ }
591
+ function formatDateTime(date = /* @__PURE__ */ new Date()) {
592
+ const dateStr = formatDate(date);
593
+ const timeStr = formatTime(date);
594
+ const seconds = String(date.getSeconds()).padStart(2, "0");
595
+ return `${dateStr} ${timeStr}:${seconds}`;
596
+ }
597
+ function parseISO(isoString) {
598
+ return new Date(isoString);
599
+ }
600
+
601
+ // src/services/QRAccessService.ts
602
+ var QRAccessService = class {
603
+ constructor(apiClient) {
604
+ this.apiClient = apiClient;
605
+ }
606
+ /**
607
+ * Validate QR code format
608
+ */
609
+ validateQRFormat(code) {
610
+ return validateQRCode(code);
611
+ }
612
+ /**
613
+ * Check if location validation is required
614
+ */
615
+ shouldValidateLocation(device) {
616
+ return device.range_matter === "1" && !!device.latitude && !!device.longitude;
617
+ }
618
+ /**
619
+ * Validate user location against device location
620
+ */
621
+ validateLocation(device, userLocation) {
622
+ if (!this.shouldValidateLocation(device)) {
623
+ return { valid: true };
624
+ }
625
+ if (!userLocation) {
626
+ return { valid: false };
627
+ }
628
+ const locationCheck = checkOnLocation(
629
+ device.latitude,
630
+ device.longitude,
631
+ device.range || 100,
632
+ userLocation
633
+ );
634
+ return {
635
+ valid: locationCheck.ok,
636
+ distance: locationCheck.distance
637
+ };
638
+ }
639
+ /**
640
+ * Validate QR code with full checks
641
+ */
642
+ async validateQR(options) {
643
+ const { qrCode, device, userLocation, skipLocationCheck, skipRepetitiveCheck } = options;
644
+ if (!this.validateQRFormat(qrCode)) {
645
+ return {
646
+ success: false,
647
+ message: "Invalid QR code format",
648
+ error: { code: "INVALID_QR_FORMAT" }
649
+ };
650
+ }
651
+ if (!skipRepetitiveCheck && !checkRepetitiveRead(qrCode)) {
652
+ return {
653
+ success: false,
654
+ message: "QR code was recently scanned. Please wait before scanning again.",
655
+ error: { code: "REPETITIVE_READ" }
656
+ };
657
+ }
658
+ if (!skipLocationCheck) {
659
+ const locationValidation = this.validateLocation(device, userLocation);
660
+ if (!locationValidation.valid) {
661
+ return {
662
+ success: false,
663
+ message: "You are not within the allowed range of this device",
664
+ error: {
665
+ code: "LOCATION_OUT_OF_RANGE",
666
+ details: locationValidation.distance ? `Distance: ${locationValidation.distance.toFixed(2)}m` : void 0
667
+ }
668
+ };
669
+ }
670
+ }
671
+ try {
672
+ const response = await this.apiClient.post({
673
+ endpoint: EP_QR_CHECK,
674
+ data: { qr_code: qrCode }
675
+ });
676
+ if (!response.success) {
677
+ return {
678
+ success: false,
679
+ message: response.message || "QR validation failed",
680
+ error: { code: "API_ERROR" }
681
+ };
682
+ }
683
+ return {
684
+ success: true,
685
+ message: "QR code validated successfully",
686
+ entrance: response.data
687
+ };
688
+ } catch (error) {
689
+ return {
690
+ success: false,
691
+ message: error.message || "Failed to validate QR code",
692
+ error: { code: "NETWORK_ERROR" }
693
+ };
694
+ }
695
+ }
696
+ /**
697
+ * Create entrance from QR code
698
+ */
699
+ async createEntranceFromQR(request) {
700
+ return this.apiClient.post({
701
+ endpoint: EP_CREATE_QR,
702
+ data: request
703
+ });
704
+ }
705
+ /**
706
+ * Trigger IoT device
707
+ */
708
+ async triggerIoTDevice(deviceId) {
709
+ return this.apiClient.post({
710
+ endpoint: `${EP_TRIGGER_IOT}/${deviceId}`
711
+ });
712
+ }
713
+ };
714
+
715
+ // src/services/NFCAccessService.ts
716
+ var NFCAccessService = class {
717
+ constructor(apiClient) {
718
+ this.apiClient = apiClient;
719
+ }
720
+ /**
721
+ * Validate NFC code format
722
+ */
723
+ validateNFCFormat(code) {
724
+ return validateNFCCode(code);
725
+ }
726
+ /**
727
+ * Check if location validation is required
728
+ */
729
+ shouldValidateLocation(device) {
730
+ return device.nfc_range_matter === "1" && !!device.latitude && !!device.longitude;
731
+ }
732
+ /**
733
+ * Validate user location against device location
734
+ */
735
+ validateLocation(device, userLocation) {
736
+ if (!this.shouldValidateLocation(device)) {
737
+ return { valid: true };
738
+ }
739
+ if (!userLocation) {
740
+ return { valid: false };
741
+ }
742
+ const locationCheck = checkOnLocation(
743
+ device.latitude,
744
+ device.longitude,
745
+ device.nfc_range || 100,
746
+ userLocation
747
+ );
748
+ return {
749
+ valid: locationCheck.ok,
750
+ distance: locationCheck.distance
751
+ };
752
+ }
753
+ /**
754
+ * Validate NFC code with full checks
755
+ */
756
+ async validateNFC(options) {
757
+ const { nfcCode, device, userLocation, skipLocationCheck, skipRepetitiveCheck } = options;
758
+ if (!this.validateNFCFormat(nfcCode)) {
759
+ return {
760
+ success: false,
761
+ message: "Invalid NFC code format",
762
+ error: { code: "INVALID_NFC_FORMAT" }
763
+ };
764
+ }
765
+ if (!skipRepetitiveCheck && !checkRepetitiveRead(nfcCode)) {
766
+ return {
767
+ success: false,
768
+ message: "NFC card was recently scanned. Please wait before scanning again.",
769
+ error: { code: "REPETITIVE_READ" }
770
+ };
771
+ }
772
+ if (!skipLocationCheck) {
773
+ const locationValidation = this.validateLocation(device, userLocation);
774
+ if (!locationValidation.valid) {
775
+ return {
776
+ success: false,
777
+ message: "You are not within the allowed range of this device",
778
+ error: {
779
+ code: "LOCATION_OUT_OF_RANGE",
780
+ details: locationValidation.distance ? `Distance: ${locationValidation.distance.toFixed(2)}m` : void 0
781
+ }
782
+ };
783
+ }
784
+ }
785
+ try {
786
+ const response = await this.apiClient.post({
787
+ endpoint: EP_NFC_CHECK,
788
+ data: { nfc_code: nfcCode }
789
+ });
790
+ if (!response.success) {
791
+ return {
792
+ success: false,
793
+ message: response.message || "NFC validation failed",
794
+ error: { code: "API_ERROR" }
795
+ };
796
+ }
797
+ return {
798
+ success: true,
799
+ message: "NFC card validated successfully",
800
+ entrance: response.data
801
+ };
802
+ } catch (error) {
803
+ return {
804
+ success: false,
805
+ message: error.message || "Failed to validate NFC card",
806
+ error: { code: "NETWORK_ERROR" }
807
+ };
808
+ }
809
+ }
810
+ };
811
+
812
+ // src/services/CheckInService.ts
813
+ var CheckInService = class {
814
+ constructor(apiClient) {
815
+ this.apiClient = apiClient;
816
+ }
817
+ /**
818
+ * Get nearby branches based on user location
819
+ */
820
+ async getNearbyBranches(request) {
821
+ const { latitude, longitude, radius } = request;
822
+ if (!validateCoordinates({ latitude, longitude })) {
823
+ throw new Error("Invalid coordinates provided");
824
+ }
825
+ return this.apiClient.get({
826
+ endpoint: EP_BRANCHES,
827
+ params: {
828
+ latitude,
829
+ longitude,
830
+ ...radius && { radius }
831
+ }
832
+ });
833
+ }
834
+ /**
835
+ * Check in to a branch
836
+ */
837
+ async checkIn(options) {
838
+ const { branchId, entranceType, userId, userLocation: _userLocation } = options;
839
+ try {
840
+ const entranceRequest = {
841
+ user_id: userId,
842
+ branch_id: branchId,
843
+ entrance_type: entranceType,
844
+ is_manual_recording: false
845
+ };
846
+ const response = await this.apiClient.post({
847
+ endpoint: EP_ENTRANCES,
848
+ data: entranceRequest
849
+ });
850
+ if (!response.success) {
851
+ return {
852
+ success: false,
853
+ message: response.message || "Check-in failed",
854
+ error: { code: "API_ERROR" }
855
+ };
856
+ }
857
+ return {
858
+ success: true,
859
+ message: "Check-in successful",
860
+ entrance: response.data
861
+ };
862
+ } catch (error) {
863
+ return {
864
+ success: false,
865
+ message: error.message || "Failed to check-in",
866
+ error: { code: "NETWORK_ERROR" }
867
+ };
868
+ }
869
+ }
870
+ /**
871
+ * Get branch by ID
872
+ */
873
+ async getBranchById(branchId) {
874
+ return this.apiClient.get({
875
+ endpoint: `${EP_BRANCHES}/${branchId}`
876
+ });
877
+ }
878
+ /**
879
+ * Get all branches (with pagination)
880
+ */
881
+ async getAllBranches(params) {
882
+ return this.apiClient.get({
883
+ endpoint: EP_BRANCHES,
884
+ params
885
+ });
886
+ }
887
+ };
888
+
889
+ // src/services/RemoteWorkService.ts
890
+ var RemoteWorkService = class {
891
+ constructor(apiClient) {
892
+ this.apiClient = apiClient;
893
+ }
894
+ /**
895
+ * Log remote work entry or exit
896
+ */
897
+ async logRemoteWork(options) {
898
+ const { userId, entranceType, timestamp, description } = options;
899
+ try {
900
+ const createdAt = timestamp ? typeof timestamp === "string" ? timestamp : formatISO(timestamp) : formatISO();
901
+ const entranceRequest = {
902
+ user_id: userId,
903
+ entrance_type: entranceType,
904
+ is_manual_recording: true,
905
+ is_remote_work: true,
906
+ created_at: createdAt,
907
+ description
908
+ };
909
+ const response = await this.apiClient.post({
910
+ endpoint: EP_ENTRANCES,
911
+ data: { entrance: entranceRequest }
912
+ });
913
+ if (!response.success) {
914
+ return {
915
+ success: false,
916
+ message: response.message || "Failed to log remote work",
917
+ error: { code: "API_ERROR" }
918
+ };
919
+ }
920
+ return {
921
+ success: true,
922
+ message: "Remote work logged successfully",
923
+ entrance: response.data
924
+ };
925
+ } catch (error) {
926
+ return {
927
+ success: false,
928
+ message: error.message || "Failed to log remote work",
929
+ error: { code: "NETWORK_ERROR" }
930
+ };
931
+ }
932
+ }
933
+ /**
934
+ * Log remote work entry
935
+ */
936
+ async logEntry(options) {
937
+ return this.logRemoteWork({
938
+ ...options,
939
+ entranceType: 0 /* ENTRY */
940
+ });
941
+ }
942
+ /**
943
+ * Log remote work exit
944
+ */
945
+ async logExit(options) {
946
+ return this.logRemoteWork({
947
+ ...options,
948
+ entranceType: 1 /* EXIT */
949
+ });
950
+ }
951
+ };
952
+
953
+ // src/services/DeviceAccessService.ts
954
+ var DeviceAccessService = class {
955
+ constructor(apiClient) {
956
+ this.apiClient = apiClient;
957
+ }
958
+ /**
959
+ * Get all devices
960
+ */
961
+ async getDevices(params) {
962
+ return this.apiClient.get({
963
+ endpoint: EP_DEVICES,
964
+ params: params || { per_page: 100 }
965
+ });
966
+ }
967
+ /**
968
+ * Get all QR devices
969
+ */
970
+ async getQRDevices(params) {
971
+ return this.apiClient.get({
972
+ endpoint: EP_QR_DEVICES,
973
+ params: params || { per_page: 100 }
974
+ });
975
+ }
976
+ /**
977
+ * Get all QR devices with pagination support
978
+ */
979
+ async getAllQRDevices() {
980
+ const perPage = 50;
981
+ let currentPage = 1;
982
+ let allData = [];
983
+ while (true) {
984
+ const response = await this.getQRDevices({
985
+ page: currentPage,
986
+ per_page: perPage
987
+ });
988
+ if (!response.success || !response.data) {
989
+ break;
990
+ }
991
+ allData = [...allData, ...response.data];
992
+ if (!response.meta || !response.meta.total_pages) {
993
+ break;
994
+ }
995
+ if (currentPage >= response.meta.total_pages) {
996
+ break;
997
+ }
998
+ currentPage++;
999
+ }
1000
+ return allData;
1001
+ }
1002
+ /**
1003
+ * Get accessible QR codes for current user
1004
+ */
1005
+ async getAccessibleQRs() {
1006
+ return this.apiClient.get({
1007
+ endpoint: EP_QR_ACCESS
1008
+ });
1009
+ }
1010
+ /**
1011
+ * Get user devices
1012
+ */
1013
+ async getUserDevices(request) {
1014
+ const { userId, page, per_page } = request;
1015
+ return this.apiClient.get({
1016
+ endpoint: `${EP_USERS}/${userId}/devices`,
1017
+ params: {
1018
+ ...page && { page },
1019
+ ...per_page && { per_page }
1020
+ }
1021
+ });
1022
+ }
1023
+ /**
1024
+ * Get device by ID
1025
+ */
1026
+ async getDeviceById(deviceId) {
1027
+ return this.apiClient.get({
1028
+ endpoint: `${EP_DEVICES}/${deviceId}`
1029
+ });
1030
+ }
1031
+ /**
1032
+ * Check if user has access to a device
1033
+ */
1034
+ async checkDeviceAccess(deviceId) {
1035
+ try {
1036
+ const response = await this.getAccessibleQRs();
1037
+ if (!response.success || !response.data) {
1038
+ return false;
1039
+ }
1040
+ return response.data.qr_ids.includes(deviceId);
1041
+ } catch {
1042
+ return false;
1043
+ }
1044
+ }
1045
+ /**
1046
+ * Find QR device by QR code ID
1047
+ */
1048
+ async findDeviceByQRCode(qrCodeId) {
1049
+ try {
1050
+ const devices = await this.getAllQRDevices();
1051
+ return devices.find((device) => device.qr_code_id === qrCodeId);
1052
+ } catch {
1053
+ return void 0;
1054
+ }
1055
+ }
1056
+ /**
1057
+ * Find QR device by NFC code
1058
+ */
1059
+ async findDeviceByNFCCode(nfcCode) {
1060
+ try {
1061
+ const devices = await this.getAllQRDevices();
1062
+ return devices.find((device) => device.nfc_code === nfcCode);
1063
+ } catch {
1064
+ return void 0;
1065
+ }
1066
+ }
1067
+ };
1068
+
1069
+ // src/services/LocationService.ts
1070
+ var LocationService = class {
1071
+ constructor(apiClient) {
1072
+ this.apiClient = apiClient;
1073
+ }
1074
+ /**
1075
+ * Log location verification
1076
+ */
1077
+ async logLocationVerification(log) {
1078
+ return this.apiClient.post({
1079
+ endpoint: EP_LOCATION_VERIFICATION,
1080
+ data: { log }
1081
+ });
1082
+ }
1083
+ /**
1084
+ * Create location verification log for QR scan
1085
+ */
1086
+ async logQRScan(params) {
1087
+ const log = {
1088
+ mobileLatitude: params.mobileLocation.latitude,
1089
+ mobileLongitude: params.mobileLocation.longitude,
1090
+ accuracy: params.mobileLocation.accuracy,
1091
+ altitude: params.mobileLocation.altitude,
1092
+ qrLatitude: params.qrLocation?.latitude ?? -1,
1093
+ qrLongitude: params.qrLocation?.longitude ?? -1,
1094
+ currentScreen: params.currentScreen,
1095
+ qr: params.qrCode,
1096
+ errorCode: params.errorCode,
1097
+ message: params.message,
1098
+ navigation_step: "qr_scan_location",
1099
+ isGps: true,
1100
+ deviceRange: params.deviceRange || 0,
1101
+ distance: params.distance,
1102
+ additionalInfo: params.additionalInfo || "",
1103
+ customData: params.customData
1104
+ };
1105
+ return this.logLocationVerification(log);
1106
+ }
1107
+ /**
1108
+ * Create location verification log for NFC scan
1109
+ */
1110
+ async logNFCScan(params) {
1111
+ const log = {
1112
+ mobileLatitude: params.mobileLocation.latitude,
1113
+ mobileLongitude: params.mobileLocation.longitude,
1114
+ accuracy: params.mobileLocation.accuracy,
1115
+ altitude: params.mobileLocation.altitude,
1116
+ qrLatitude: params.nfcLocation?.latitude ?? -1,
1117
+ qrLongitude: params.nfcLocation?.longitude ?? -1,
1118
+ currentScreen: params.currentScreen,
1119
+ qr: params.nfcCode,
1120
+ errorCode: params.errorCode,
1121
+ message: params.message,
1122
+ navigation_step: "nfc_scan_location",
1123
+ isGps: true,
1124
+ deviceRange: params.deviceRange || 0,
1125
+ distance: params.distance,
1126
+ additionalInfo: params.additionalInfo || "",
1127
+ customData: params.customData
1128
+ };
1129
+ return this.logLocationVerification(log);
1130
+ }
1131
+ /**
1132
+ * Create location verification log for check-in
1133
+ */
1134
+ async logCheckIn(params) {
1135
+ const log = {
1136
+ mobileLatitude: params.mobileLocation.latitude,
1137
+ mobileLongitude: params.mobileLocation.longitude,
1138
+ accuracy: params.mobileLocation.accuracy,
1139
+ altitude: params.mobileLocation.altitude,
1140
+ qrLatitude: params.branchLocation?.latitude ?? -1,
1141
+ qrLongitude: params.branchLocation?.longitude ?? -1,
1142
+ currentScreen: params.currentScreen,
1143
+ qr: "-",
1144
+ errorCode: params.errorCode,
1145
+ message: params.message,
1146
+ navigation_step: "check_in",
1147
+ isGps: true,
1148
+ deviceRange: 0,
1149
+ distance: params.distance,
1150
+ additionalInfo: params.additionalInfo || "buraday\u0131m",
1151
+ customData: params.customData
1152
+ };
1153
+ return this.logLocationVerification(log);
1154
+ }
1155
+ };
1156
+
1
1157
  // src/providers/PassgageAccessProvider.tsx
2
1158
  import React, { createContext, useContext, useMemo } from "react";
3
- import {
4
- createApiClient,
5
- AuthService,
6
- QRAccessService,
7
- NFCAccessService,
8
- CheckInService,
9
- RemoteWorkService,
10
- DeviceAccessService,
11
- LocationService
12
- } from "@passgage/sdk-core";
13
1159
 
14
1160
  // src/utils/secureStorage.ts
15
1161
  import * as Keychain from "react-native-keychain";
@@ -344,7 +1490,7 @@ function usePassgageAuth(options = {}) {
344
1490
  };
345
1491
  }
346
1492
 
347
- // src/hooks/useQRScanner.ts
1493
+ // src/hooks/usePassgageQRScanner.ts
348
1494
  import { useState as useState3, useCallback as useCallback3 } from "react";
349
1495
 
350
1496
  // src/hooks/useLocation.ts
@@ -420,8 +1566,8 @@ function useLocation(options = {}) {
420
1566
  };
421
1567
  }
422
1568
 
423
- // src/hooks/useQRScanner.ts
424
- function useQRScanner(options = {}) {
1569
+ // src/hooks/usePassgageQRScanner.ts
1570
+ function usePassgageQRScanner(options = {}) {
425
1571
  const { qrAccessService, deviceAccessService } = usePassgageAccess();
426
1572
  const { location } = useLocation();
427
1573
  const [isLoading, setIsLoading] = useState3(false);
@@ -466,14 +1612,14 @@ function useQRScanner(options = {}) {
466
1612
  };
467
1613
  }
468
1614
 
469
- // src/hooks/useNFCScanner.ts
1615
+ // src/hooks/usePassgageNFCScanner.ts
470
1616
  import { useState as useState4, useCallback as useCallback4, useEffect as useEffect3 } from "react";
471
1617
  import NfcManager, { NfcTech } from "react-native-nfc-manager";
472
1618
  function reversedHexToDec(hexString) {
473
1619
  const hex = hexString.replace(/:/g, "");
474
1620
  return parseInt(hex, 16).toString();
475
1621
  }
476
- function useNFCScanner(options = {}) {
1622
+ function usePassgageNFCScanner(options = {}) {
477
1623
  const { nfcAccessService, deviceAccessService } = usePassgageAccess();
478
1624
  const { location } = useLocation();
479
1625
  const [isScanning, setIsScanning] = useState4(false);
@@ -549,137 +1695,247 @@ function useNFCScanner(options = {}) {
549
1695
  };
550
1696
  }
551
1697
 
552
- // src/hooks/useCheckIn.ts
553
- import { useState as useState5, useEffect as useEffect4, useCallback as useCallback5 } from "react";
554
- function useCheckIn(options = {}) {
555
- const { checkInService, config: _config } = usePassgageAccess();
1698
+ // src/hooks/usePassgageCheckIn.ts
1699
+ import { useState as useState5, useCallback as useCallback5 } from "react";
1700
+ function usePassgageCheckIn(options = {}) {
1701
+ const { checkInService } = usePassgageAccess();
556
1702
  const { location } = useLocation();
557
- const [nearbyBranches, setNearbyBranches] = useState5([]);
558
1703
  const [isLoading, setIsLoading] = useState5(false);
559
1704
  const [error, setError] = useState5(null);
560
- const fetchNearbyBranches = useCallback5(async () => {
561
- if (!location) {
562
- return;
563
- }
564
- setIsLoading(true);
565
- setError(null);
566
- try {
567
- const response = await checkInService.getNearbyBranches({
568
- latitude: location.latitude,
569
- longitude: location.longitude,
570
- radius: options.radius
571
- });
572
- if (response.success && response.data) {
573
- setNearbyBranches(response.data);
1705
+ const getNearbyBranches = useCallback5(
1706
+ async (params) => {
1707
+ if (!location) {
1708
+ return {
1709
+ success: false,
1710
+ error: "Location not available"
1711
+ };
574
1712
  }
575
- } catch (err) {
576
- setError(err);
577
- } finally {
578
- setIsLoading(false);
579
- }
580
- }, [checkInService, location, options.radius]);
581
- const checkIn = useCallback5(
1713
+ setIsLoading(true);
1714
+ setError(null);
1715
+ try {
1716
+ const response = await checkInService.getNearbyBranches({
1717
+ latitude: location.latitude,
1718
+ longitude: location.longitude,
1719
+ radius: params?.radius || options.radius
1720
+ });
1721
+ if (response.success && response.data) {
1722
+ return {
1723
+ success: true,
1724
+ data: response.data
1725
+ };
1726
+ }
1727
+ return {
1728
+ success: false,
1729
+ error: response.message || "Failed to fetch nearby branches"
1730
+ };
1731
+ } catch (err) {
1732
+ const error2 = err;
1733
+ setError(error2);
1734
+ return {
1735
+ success: false,
1736
+ error: error2.message || "Failed to fetch nearby branches"
1737
+ };
1738
+ } finally {
1739
+ setIsLoading(false);
1740
+ }
1741
+ },
1742
+ [checkInService, location, options.radius]
1743
+ );
1744
+ const checkInEntry = useCallback5(
582
1745
  async (params) => {
583
1746
  setIsLoading(true);
584
1747
  setError(null);
585
1748
  try {
586
- const userId = "";
587
1749
  const result = await checkInService.checkIn({
588
- ...params,
589
- userId,
1750
+ branchId: params.branchId,
1751
+ userId: params.userId,
1752
+ entranceType: 0 /* ENTRY */,
590
1753
  userLocation: location || void 0
591
1754
  });
592
- if (!result.success) {
593
- throw new Error(result.message);
1755
+ if (result.success) {
1756
+ return {
1757
+ success: true,
1758
+ data: result.entrance
1759
+ };
594
1760
  }
595
- return result.entrance;
1761
+ return {
1762
+ success: false,
1763
+ error: result.message || "Check-in failed"
1764
+ };
596
1765
  } catch (err) {
597
- setError(err);
598
- throw err;
1766
+ const error2 = err;
1767
+ setError(error2);
1768
+ return {
1769
+ success: false,
1770
+ error: error2.message || "Check-in failed"
1771
+ };
1772
+ } finally {
1773
+ setIsLoading(false);
1774
+ }
1775
+ },
1776
+ [checkInService, location]
1777
+ );
1778
+ const checkInExit = useCallback5(
1779
+ async (params) => {
1780
+ setIsLoading(true);
1781
+ setError(null);
1782
+ try {
1783
+ const result = await checkInService.checkIn({
1784
+ branchId: params.branchId,
1785
+ userId: params.userId,
1786
+ entranceType: 1 /* EXIT */,
1787
+ userLocation: location || void 0
1788
+ });
1789
+ if (result.success) {
1790
+ return {
1791
+ success: true,
1792
+ data: result.entrance
1793
+ };
1794
+ }
1795
+ return {
1796
+ success: false,
1797
+ error: result.message || "Check-out failed"
1798
+ };
1799
+ } catch (err) {
1800
+ const error2 = err;
1801
+ setError(error2);
1802
+ return {
1803
+ success: false,
1804
+ error: error2.message || "Check-out failed"
1805
+ };
599
1806
  } finally {
600
1807
  setIsLoading(false);
601
1808
  }
602
1809
  },
603
1810
  [checkInService, location]
604
1811
  );
605
- useEffect4(() => {
606
- if (options.autoFetch && location) {
607
- fetchNearbyBranches();
608
- }
609
- }, [options.autoFetch, location, fetchNearbyBranches]);
610
1812
  return {
611
- nearbyBranches,
612
- fetchNearbyBranches,
613
- checkIn,
1813
+ getNearbyBranches,
1814
+ checkInEntry,
1815
+ checkInExit,
614
1816
  isLoading,
615
1817
  error
616
1818
  };
617
1819
  }
618
1820
 
619
- // src/hooks/useRemoteWork.ts
1821
+ // src/hooks/usePassgageRemoteWork.ts
620
1822
  import { useState as useState6, useCallback as useCallback6 } from "react";
621
- import { EntranceType } from "@passgage/sdk-core";
622
- function useRemoteWork() {
1823
+ function usePassgageRemoteWork() {
623
1824
  const { remoteWorkService } = usePassgageAccess();
624
1825
  const [isLoading, setIsLoading] = useState6(false);
625
1826
  const [error, setError] = useState6(null);
626
- const logRemoteWork = useCallback6(
627
- async (entranceType, options = {}) => {
1827
+ const logEntry = useCallback6(
1828
+ async (params) => {
628
1829
  setIsLoading(true);
629
1830
  setError(null);
630
1831
  try {
631
- const userId = "";
632
1832
  const result = await remoteWorkService.logRemoteWork({
633
- userId,
634
- entranceType,
635
- timestamp: options.timestamp,
636
- description: options.description
1833
+ userId: params.userId,
1834
+ entranceType: 0 /* ENTRY */,
1835
+ timestamp: params.timestamp,
1836
+ description: params.description
637
1837
  });
638
- if (!result.success) {
639
- throw new Error(result.message);
1838
+ if (result.success) {
1839
+ return {
1840
+ success: true,
1841
+ data: result.entrance
1842
+ };
640
1843
  }
641
- return result.entrance;
1844
+ return {
1845
+ success: false,
1846
+ error: result.message || "Failed to log entry"
1847
+ };
642
1848
  } catch (err) {
643
1849
  const error2 = err;
644
1850
  setError(error2);
645
- throw error2;
1851
+ return {
1852
+ success: false,
1853
+ error: error2.message || "Failed to log entry"
1854
+ };
646
1855
  } finally {
647
1856
  setIsLoading(false);
648
1857
  }
649
1858
  },
650
1859
  [remoteWorkService]
651
1860
  );
652
- const logEntry = useCallback6(
653
- async (options) => {
654
- return logRemoteWork(EntranceType.ENTRY, options);
655
- },
656
- [logRemoteWork]
657
- );
658
1861
  const logExit = useCallback6(
659
- async (options) => {
660
- return logRemoteWork(EntranceType.EXIT, options);
1862
+ async (params) => {
1863
+ setIsLoading(true);
1864
+ setError(null);
1865
+ try {
1866
+ const result = await remoteWorkService.logRemoteWork({
1867
+ userId: params.userId,
1868
+ entranceType: 1 /* EXIT */,
1869
+ timestamp: params.timestamp,
1870
+ description: params.description
1871
+ });
1872
+ if (result.success) {
1873
+ return {
1874
+ success: true,
1875
+ data: result.entrance
1876
+ };
1877
+ }
1878
+ return {
1879
+ success: false,
1880
+ error: result.message || "Failed to log exit"
1881
+ };
1882
+ } catch (err) {
1883
+ const error2 = err;
1884
+ setError(error2);
1885
+ return {
1886
+ success: false,
1887
+ error: error2.message || "Failed to log exit"
1888
+ };
1889
+ } finally {
1890
+ setIsLoading(false);
1891
+ }
661
1892
  },
662
- [logRemoteWork]
1893
+ [remoteWorkService]
663
1894
  );
664
1895
  return {
665
1896
  logEntry,
666
1897
  logExit,
667
- logRemoteWork,
668
1898
  isLoading,
669
1899
  error
670
1900
  };
671
1901
  }
672
1902
 
673
- // src/index.tsx
674
- var SDK_VERSION = "1.0.0";
1903
+ // src/index.ts
1904
+ var SDK_VERSION = "1.0.3";
675
1905
  export {
1906
+ ApiClient,
1907
+ AuthService,
1908
+ CheckInService,
1909
+ DeviceAccessService,
1910
+ DeviceDirection,
1911
+ DeviceUsage,
1912
+ endpoints_exports as Endpoints,
1913
+ EntranceType,
1914
+ LocationService,
1915
+ NFCAccessService,
676
1916
  PassgageAccessProvider,
1917
+ QRAccessService,
1918
+ RemoteWorkService,
677
1919
  SDK_VERSION,
678
- useCheckIn,
1920
+ calculateDistance,
1921
+ checkOnLocation,
1922
+ checkRepetitiveRead,
1923
+ clearReadRecords,
1924
+ createApiClient,
1925
+ formatDate,
1926
+ formatDateTime,
1927
+ formatISO,
1928
+ formatTime,
1929
+ parseISO,
679
1930
  useLocation,
680
- useNFCScanner,
681
1931
  usePassgageAccess,
682
1932
  usePassgageAuth,
683
- useQRScanner,
684
- useRemoteWork
1933
+ usePassgageCheckIn,
1934
+ usePassgageNFCScanner,
1935
+ usePassgageQRScanner,
1936
+ usePassgageRemoteWork,
1937
+ validateCoordinates,
1938
+ validateDeviceId,
1939
+ validateNFCCode,
1940
+ validateQRCode
685
1941
  };