@passgage/sdk-react-native 1.0.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/README.md +156 -0
- package/dist/index.d.mts +251 -0
- package/dist/index.d.ts +251 -0
- package/dist/index.js +721 -0
- package/dist/index.mjs +685 -0
- package/package.json +84 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,721 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.tsx
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
PassgageAccessProvider: () => PassgageAccessProvider,
|
|
34
|
+
SDK_VERSION: () => SDK_VERSION,
|
|
35
|
+
useCheckIn: () => useCheckIn,
|
|
36
|
+
useLocation: () => useLocation,
|
|
37
|
+
useNFCScanner: () => useNFCScanner,
|
|
38
|
+
usePassgageAccess: () => usePassgageAccess,
|
|
39
|
+
usePassgageAuth: () => usePassgageAuth,
|
|
40
|
+
useQRScanner: () => useQRScanner,
|
|
41
|
+
useRemoteWork: () => useRemoteWork
|
|
42
|
+
});
|
|
43
|
+
module.exports = __toCommonJS(index_exports);
|
|
44
|
+
|
|
45
|
+
// src/providers/PassgageAccessProvider.tsx
|
|
46
|
+
var import_react = __toESM(require("react"));
|
|
47
|
+
var import_sdk_core = require("@passgage/sdk-core");
|
|
48
|
+
|
|
49
|
+
// src/utils/secureStorage.ts
|
|
50
|
+
var Keychain = __toESM(require("react-native-keychain"));
|
|
51
|
+
var STORAGE_KEYS = {
|
|
52
|
+
TOKENS: "passgage_auth_tokens",
|
|
53
|
+
USER: "passgage_user_info"
|
|
54
|
+
};
|
|
55
|
+
var SecureStorage = class {
|
|
56
|
+
/**
|
|
57
|
+
* Save tokens to secure storage
|
|
58
|
+
*/
|
|
59
|
+
async saveTokens(tokens) {
|
|
60
|
+
try {
|
|
61
|
+
await Keychain.setGenericPassword(
|
|
62
|
+
STORAGE_KEYS.TOKENS,
|
|
63
|
+
JSON.stringify(tokens),
|
|
64
|
+
{
|
|
65
|
+
service: STORAGE_KEYS.TOKENS,
|
|
66
|
+
accessible: Keychain.ACCESSIBLE.WHEN_UNLOCKED
|
|
67
|
+
}
|
|
68
|
+
);
|
|
69
|
+
} catch (error) {
|
|
70
|
+
console.error("Failed to save tokens to secure storage:", error);
|
|
71
|
+
throw new Error("Failed to save tokens");
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Get tokens from secure storage
|
|
76
|
+
*/
|
|
77
|
+
async getTokens() {
|
|
78
|
+
try {
|
|
79
|
+
const credentials = await Keychain.getGenericPassword({
|
|
80
|
+
service: STORAGE_KEYS.TOKENS
|
|
81
|
+
});
|
|
82
|
+
if (!credentials) {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
const tokens = JSON.parse(credentials.password);
|
|
86
|
+
return tokens;
|
|
87
|
+
} catch (error) {
|
|
88
|
+
console.error("Failed to get tokens from secure storage:", error);
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Clear tokens from secure storage
|
|
94
|
+
*/
|
|
95
|
+
async clearTokens() {
|
|
96
|
+
try {
|
|
97
|
+
await Keychain.resetGenericPassword({
|
|
98
|
+
service: STORAGE_KEYS.TOKENS
|
|
99
|
+
});
|
|
100
|
+
} catch (error) {
|
|
101
|
+
console.error("Failed to clear tokens from secure storage:", error);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Save user information
|
|
106
|
+
*/
|
|
107
|
+
async saveUser(user) {
|
|
108
|
+
try {
|
|
109
|
+
await Keychain.setGenericPassword(
|
|
110
|
+
STORAGE_KEYS.USER,
|
|
111
|
+
JSON.stringify(user),
|
|
112
|
+
{
|
|
113
|
+
service: STORAGE_KEYS.USER,
|
|
114
|
+
accessible: Keychain.ACCESSIBLE.WHEN_UNLOCKED
|
|
115
|
+
}
|
|
116
|
+
);
|
|
117
|
+
} catch (error) {
|
|
118
|
+
console.error("Failed to save user to secure storage:", error);
|
|
119
|
+
throw new Error("Failed to save user");
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Get user information
|
|
124
|
+
*/
|
|
125
|
+
async getUser() {
|
|
126
|
+
try {
|
|
127
|
+
const credentials = await Keychain.getGenericPassword({
|
|
128
|
+
service: STORAGE_KEYS.USER
|
|
129
|
+
});
|
|
130
|
+
if (!credentials) {
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
const user = JSON.parse(credentials.password);
|
|
134
|
+
return user;
|
|
135
|
+
} catch (error) {
|
|
136
|
+
console.error("Failed to get user from secure storage:", error);
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Clear user information
|
|
142
|
+
*/
|
|
143
|
+
async clearUser() {
|
|
144
|
+
try {
|
|
145
|
+
await Keychain.resetGenericPassword({
|
|
146
|
+
service: STORAGE_KEYS.USER
|
|
147
|
+
});
|
|
148
|
+
} catch (error) {
|
|
149
|
+
console.error("Failed to clear user from secure storage:", error);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Clear all data (tokens + user)
|
|
154
|
+
*/
|
|
155
|
+
async clearAll() {
|
|
156
|
+
await this.clearTokens();
|
|
157
|
+
await this.clearUser();
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
function createSecureStorage() {
|
|
161
|
+
return new SecureStorage();
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// src/providers/PassgageAccessProvider.tsx
|
|
165
|
+
var PassgageAccessContext = (0, import_react.createContext)(void 0);
|
|
166
|
+
function PassgageAccessProvider({
|
|
167
|
+
children,
|
|
168
|
+
baseURL,
|
|
169
|
+
token,
|
|
170
|
+
apiVersion = "v2",
|
|
171
|
+
timeout = 3e4,
|
|
172
|
+
onUnauthorized,
|
|
173
|
+
onError
|
|
174
|
+
}) {
|
|
175
|
+
const config = {
|
|
176
|
+
baseURL,
|
|
177
|
+
token,
|
|
178
|
+
apiVersion,
|
|
179
|
+
timeout,
|
|
180
|
+
onUnauthorized,
|
|
181
|
+
onError
|
|
182
|
+
};
|
|
183
|
+
const { apiClient, services } = (0, import_react.useMemo)(() => {
|
|
184
|
+
const secureStorage = createSecureStorage();
|
|
185
|
+
let authService;
|
|
186
|
+
const client = (0, import_sdk_core.createApiClient)({
|
|
187
|
+
baseURL: config.baseURL,
|
|
188
|
+
token: config.token,
|
|
189
|
+
apiVersion: config.apiVersion,
|
|
190
|
+
timeout: config.timeout,
|
|
191
|
+
onUnauthorized: config.onUnauthorized,
|
|
192
|
+
onError: config.onError,
|
|
193
|
+
onTokenRefreshNeeded: async () => {
|
|
194
|
+
const storedTokens = await authService.getStoredTokens();
|
|
195
|
+
if (!storedTokens) {
|
|
196
|
+
return null;
|
|
197
|
+
}
|
|
198
|
+
const result = await authService.refreshToken(storedTokens.refresh.token);
|
|
199
|
+
if (result.success) {
|
|
200
|
+
return result.tokens.access.token;
|
|
201
|
+
}
|
|
202
|
+
return null;
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
authService = new import_sdk_core.AuthService(client);
|
|
206
|
+
authService.setTokenStorage(secureStorage);
|
|
207
|
+
const allServices = {
|
|
208
|
+
authService,
|
|
209
|
+
qrAccessService: new import_sdk_core.QRAccessService(client),
|
|
210
|
+
nfcAccessService: new import_sdk_core.NFCAccessService(client),
|
|
211
|
+
checkInService: new import_sdk_core.CheckInService(client),
|
|
212
|
+
remoteWorkService: new import_sdk_core.RemoteWorkService(client),
|
|
213
|
+
deviceAccessService: new import_sdk_core.DeviceAccessService(client),
|
|
214
|
+
locationService: new import_sdk_core.LocationService(client)
|
|
215
|
+
};
|
|
216
|
+
return {
|
|
217
|
+
apiClient: client,
|
|
218
|
+
services: allServices
|
|
219
|
+
};
|
|
220
|
+
}, [config.baseURL, config.token, config.apiVersion, config.timeout, config.onUnauthorized, config.onError]);
|
|
221
|
+
const setToken = (newToken) => {
|
|
222
|
+
apiClient.setToken(newToken);
|
|
223
|
+
};
|
|
224
|
+
const clearToken = () => {
|
|
225
|
+
apiClient.clearToken();
|
|
226
|
+
};
|
|
227
|
+
const contextValue = {
|
|
228
|
+
apiClient,
|
|
229
|
+
...services,
|
|
230
|
+
config,
|
|
231
|
+
setToken,
|
|
232
|
+
clearToken
|
|
233
|
+
};
|
|
234
|
+
return /* @__PURE__ */ import_react.default.createElement(PassgageAccessContext.Provider, { value: contextValue }, children);
|
|
235
|
+
}
|
|
236
|
+
function usePassgageAccess() {
|
|
237
|
+
const context = (0, import_react.useContext)(PassgageAccessContext);
|
|
238
|
+
if (!context) {
|
|
239
|
+
throw new Error(
|
|
240
|
+
"usePassgageAccess must be used within a PassgageAccessProvider"
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
return context;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// src/hooks/usePassgageAuth.ts
|
|
247
|
+
var import_react2 = require("react");
|
|
248
|
+
function usePassgageAuth(options = {}) {
|
|
249
|
+
const {
|
|
250
|
+
onLoginSuccess,
|
|
251
|
+
onLoginError,
|
|
252
|
+
onLogoutSuccess,
|
|
253
|
+
autoRestore = true
|
|
254
|
+
} = options;
|
|
255
|
+
const { authService } = usePassgageAccess();
|
|
256
|
+
const [isAuthenticated, setIsAuthenticated] = (0, import_react2.useState)(false);
|
|
257
|
+
const [user, setUser] = (0, import_react2.useState)(null);
|
|
258
|
+
const [isLoading, setIsLoading] = (0, import_react2.useState)(false);
|
|
259
|
+
const [error, setError] = (0, import_react2.useState)(null);
|
|
260
|
+
(0, import_react2.useEffect)(() => {
|
|
261
|
+
if (!autoRestore) {
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
const restoreAuth = async () => {
|
|
265
|
+
try {
|
|
266
|
+
setIsLoading(true);
|
|
267
|
+
const authenticated = await authService.isAuthenticated();
|
|
268
|
+
if (authenticated) {
|
|
269
|
+
const storedTokens = await authService.getStoredTokens();
|
|
270
|
+
const storedUser = await authService.getStoredUser();
|
|
271
|
+
if (storedTokens && storedUser) {
|
|
272
|
+
authService["apiClient"].setToken(storedTokens.access.token);
|
|
273
|
+
setIsAuthenticated(true);
|
|
274
|
+
setUser(storedUser);
|
|
275
|
+
try {
|
|
276
|
+
const userResult = await authService.getCurrentUser();
|
|
277
|
+
if (userResult.success) {
|
|
278
|
+
setUser(userResult.user);
|
|
279
|
+
}
|
|
280
|
+
} catch (error2) {
|
|
281
|
+
console.warn("Failed to fetch fresh user info:", error2);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
} catch (error2) {
|
|
286
|
+
console.error("Failed to restore authentication:", error2);
|
|
287
|
+
setError(error2.message || "Failed to restore authentication");
|
|
288
|
+
} finally {
|
|
289
|
+
setIsLoading(false);
|
|
290
|
+
}
|
|
291
|
+
};
|
|
292
|
+
restoreAuth();
|
|
293
|
+
}, [authService, autoRestore]);
|
|
294
|
+
const login = (0, import_react2.useCallback)(
|
|
295
|
+
async (credentials) => {
|
|
296
|
+
try {
|
|
297
|
+
setIsLoading(true);
|
|
298
|
+
setError(null);
|
|
299
|
+
const result = await authService.login(credentials);
|
|
300
|
+
if (result.success) {
|
|
301
|
+
setIsAuthenticated(true);
|
|
302
|
+
setUser(result.user || null);
|
|
303
|
+
if (onLoginSuccess) {
|
|
304
|
+
onLoginSuccess(result.user);
|
|
305
|
+
}
|
|
306
|
+
} else {
|
|
307
|
+
setError(result.error);
|
|
308
|
+
if (onLoginError) {
|
|
309
|
+
onLoginError(result.error);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
return result;
|
|
313
|
+
} catch (error2) {
|
|
314
|
+
const errorMessage = error2.message || "An error occurred during login";
|
|
315
|
+
setError(errorMessage);
|
|
316
|
+
if (onLoginError) {
|
|
317
|
+
onLoginError(errorMessage);
|
|
318
|
+
}
|
|
319
|
+
return {
|
|
320
|
+
success: false,
|
|
321
|
+
error: errorMessage,
|
|
322
|
+
code: "UNKNOWN_ERROR"
|
|
323
|
+
};
|
|
324
|
+
} finally {
|
|
325
|
+
setIsLoading(false);
|
|
326
|
+
}
|
|
327
|
+
},
|
|
328
|
+
[authService, onLoginSuccess, onLoginError]
|
|
329
|
+
);
|
|
330
|
+
const logout = (0, import_react2.useCallback)(async () => {
|
|
331
|
+
try {
|
|
332
|
+
setIsLoading(true);
|
|
333
|
+
setError(null);
|
|
334
|
+
await authService.logout();
|
|
335
|
+
setIsAuthenticated(false);
|
|
336
|
+
setUser(null);
|
|
337
|
+
if (onLogoutSuccess) {
|
|
338
|
+
onLogoutSuccess();
|
|
339
|
+
}
|
|
340
|
+
} catch (error2) {
|
|
341
|
+
const errorMessage = error2.message || "An error occurred during logout";
|
|
342
|
+
setError(errorMessage);
|
|
343
|
+
console.error("Logout failed:", error2);
|
|
344
|
+
} finally {
|
|
345
|
+
setIsLoading(false);
|
|
346
|
+
}
|
|
347
|
+
}, [authService, onLogoutSuccess]);
|
|
348
|
+
const refreshToken = (0, import_react2.useCallback)(async () => {
|
|
349
|
+
try {
|
|
350
|
+
const storedTokens = await authService.getStoredTokens();
|
|
351
|
+
if (!storedTokens) {
|
|
352
|
+
return false;
|
|
353
|
+
}
|
|
354
|
+
const result = await authService.refreshToken(storedTokens.refresh.token);
|
|
355
|
+
if (result.success) {
|
|
356
|
+
return true;
|
|
357
|
+
} else {
|
|
358
|
+
await logout();
|
|
359
|
+
return false;
|
|
360
|
+
}
|
|
361
|
+
} catch (error2) {
|
|
362
|
+
console.error("Token refresh failed:", error2);
|
|
363
|
+
await logout();
|
|
364
|
+
return false;
|
|
365
|
+
}
|
|
366
|
+
}, [authService, logout]);
|
|
367
|
+
const clearError = (0, import_react2.useCallback)(() => {
|
|
368
|
+
setError(null);
|
|
369
|
+
}, []);
|
|
370
|
+
return {
|
|
371
|
+
login,
|
|
372
|
+
logout,
|
|
373
|
+
refreshToken,
|
|
374
|
+
isAuthenticated,
|
|
375
|
+
user,
|
|
376
|
+
isLoading,
|
|
377
|
+
error,
|
|
378
|
+
clearError
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
// src/hooks/useQRScanner.ts
|
|
383
|
+
var import_react4 = require("react");
|
|
384
|
+
|
|
385
|
+
// src/hooks/useLocation.ts
|
|
386
|
+
var import_react3 = require("react");
|
|
387
|
+
var import_geolocation = __toESM(require("@react-native-community/geolocation"));
|
|
388
|
+
function useLocation(options = {}) {
|
|
389
|
+
const [location, setLocation] = (0, import_react3.useState)(null);
|
|
390
|
+
const [error, setError] = (0, import_react3.useState)(null);
|
|
391
|
+
const [isLoading, setIsLoading] = (0, import_react3.useState)(true);
|
|
392
|
+
const config = {
|
|
393
|
+
enableHighAccuracy: options.enableHighAccuracy ?? true,
|
|
394
|
+
timeout: options.timeout ?? 15e3,
|
|
395
|
+
maximumAge: options.maximumAge ?? 1e4
|
|
396
|
+
};
|
|
397
|
+
const refreshLocation = (0, import_react3.useCallback)(async () => {
|
|
398
|
+
setIsLoading(true);
|
|
399
|
+
setError(null);
|
|
400
|
+
return new Promise((resolve) => {
|
|
401
|
+
import_geolocation.default.getCurrentPosition(
|
|
402
|
+
(position) => {
|
|
403
|
+
setLocation({
|
|
404
|
+
latitude: position.coords.latitude,
|
|
405
|
+
longitude: position.coords.longitude,
|
|
406
|
+
accuracy: position.coords.accuracy,
|
|
407
|
+
altitude: position.coords.altitude ?? void 0,
|
|
408
|
+
altitudeAccuracy: position.coords.altitudeAccuracy ?? void 0,
|
|
409
|
+
heading: position.coords.heading ?? void 0,
|
|
410
|
+
speed: position.coords.speed ?? void 0
|
|
411
|
+
});
|
|
412
|
+
setIsLoading(false);
|
|
413
|
+
resolve();
|
|
414
|
+
},
|
|
415
|
+
(err) => {
|
|
416
|
+
setError(new Error(err.message));
|
|
417
|
+
setIsLoading(false);
|
|
418
|
+
resolve();
|
|
419
|
+
},
|
|
420
|
+
config
|
|
421
|
+
);
|
|
422
|
+
});
|
|
423
|
+
}, [config.enableHighAccuracy, config.timeout, config.maximumAge]);
|
|
424
|
+
(0, import_react3.useEffect)(() => {
|
|
425
|
+
refreshLocation();
|
|
426
|
+
if (options.watchPosition) {
|
|
427
|
+
const watchId = import_geolocation.default.watchPosition(
|
|
428
|
+
(position) => {
|
|
429
|
+
setLocation({
|
|
430
|
+
latitude: position.coords.latitude,
|
|
431
|
+
longitude: position.coords.longitude,
|
|
432
|
+
accuracy: position.coords.accuracy,
|
|
433
|
+
altitude: position.coords.altitude ?? void 0,
|
|
434
|
+
altitudeAccuracy: position.coords.altitudeAccuracy ?? void 0,
|
|
435
|
+
heading: position.coords.heading ?? void 0,
|
|
436
|
+
speed: position.coords.speed ?? void 0
|
|
437
|
+
});
|
|
438
|
+
},
|
|
439
|
+
(err) => {
|
|
440
|
+
setError(new Error(err.message));
|
|
441
|
+
},
|
|
442
|
+
config
|
|
443
|
+
);
|
|
444
|
+
return () => {
|
|
445
|
+
import_geolocation.default.clearWatch(watchId);
|
|
446
|
+
};
|
|
447
|
+
}
|
|
448
|
+
return void 0;
|
|
449
|
+
}, [options.watchPosition, refreshLocation]);
|
|
450
|
+
return {
|
|
451
|
+
location,
|
|
452
|
+
error,
|
|
453
|
+
isLoading,
|
|
454
|
+
refreshLocation
|
|
455
|
+
};
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
// src/hooks/useQRScanner.ts
|
|
459
|
+
function useQRScanner(options = {}) {
|
|
460
|
+
const { qrAccessService, deviceAccessService } = usePassgageAccess();
|
|
461
|
+
const { location } = useLocation();
|
|
462
|
+
const [isLoading, setIsLoading] = (0, import_react4.useState)(false);
|
|
463
|
+
const [error, setError] = (0, import_react4.useState)(null);
|
|
464
|
+
const scan = (0, import_react4.useCallback)(
|
|
465
|
+
async (qrCode, device) => {
|
|
466
|
+
setIsLoading(true);
|
|
467
|
+
setError(null);
|
|
468
|
+
try {
|
|
469
|
+
let qrDevice = device;
|
|
470
|
+
if (!qrDevice) {
|
|
471
|
+
qrDevice = await deviceAccessService.findDeviceByQRCode(qrCode);
|
|
472
|
+
if (!qrDevice) {
|
|
473
|
+
throw new Error("QR device not found");
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
const result = await qrAccessService.validateQR({
|
|
477
|
+
qrCode,
|
|
478
|
+
device: qrDevice,
|
|
479
|
+
userLocation: location || void 0,
|
|
480
|
+
skipLocationCheck: options.skipLocationCheck,
|
|
481
|
+
skipRepetitiveCheck: options.skipRepetitiveCheck
|
|
482
|
+
});
|
|
483
|
+
if (!result.success) {
|
|
484
|
+
throw new Error(result.message);
|
|
485
|
+
}
|
|
486
|
+
options.onSuccess?.(result.entrance);
|
|
487
|
+
} catch (err) {
|
|
488
|
+
const error2 = err;
|
|
489
|
+
setError(error2);
|
|
490
|
+
options.onError?.(error2);
|
|
491
|
+
} finally {
|
|
492
|
+
setIsLoading(false);
|
|
493
|
+
}
|
|
494
|
+
},
|
|
495
|
+
[qrAccessService, deviceAccessService, location, options]
|
|
496
|
+
);
|
|
497
|
+
return {
|
|
498
|
+
scan,
|
|
499
|
+
isLoading,
|
|
500
|
+
error
|
|
501
|
+
};
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
// src/hooks/useNFCScanner.ts
|
|
505
|
+
var import_react5 = require("react");
|
|
506
|
+
var import_react_native_nfc_manager = __toESM(require("react-native-nfc-manager"));
|
|
507
|
+
function reversedHexToDec(hexString) {
|
|
508
|
+
const hex = hexString.replace(/:/g, "");
|
|
509
|
+
return parseInt(hex, 16).toString();
|
|
510
|
+
}
|
|
511
|
+
function useNFCScanner(options = {}) {
|
|
512
|
+
const { nfcAccessService, deviceAccessService } = usePassgageAccess();
|
|
513
|
+
const { location } = useLocation();
|
|
514
|
+
const [isScanning, setIsScanning] = (0, import_react5.useState)(false);
|
|
515
|
+
const [error, setError] = (0, import_react5.useState)(null);
|
|
516
|
+
const stopScanning = (0, import_react5.useCallback)(async () => {
|
|
517
|
+
try {
|
|
518
|
+
await import_react_native_nfc_manager.default.cancelTechnologyRequest();
|
|
519
|
+
setIsScanning(false);
|
|
520
|
+
} catch {
|
|
521
|
+
}
|
|
522
|
+
}, []);
|
|
523
|
+
const handleNFCTag = (0, import_react5.useCallback)(
|
|
524
|
+
async (tag) => {
|
|
525
|
+
if (!tag.id) {
|
|
526
|
+
return;
|
|
527
|
+
}
|
|
528
|
+
try {
|
|
529
|
+
const nfcCode = reversedHexToDec(tag.id);
|
|
530
|
+
const device = await deviceAccessService.findDeviceByNFCCode(nfcCode);
|
|
531
|
+
if (!device) {
|
|
532
|
+
throw new Error("NFC device not found");
|
|
533
|
+
}
|
|
534
|
+
const result = await nfcAccessService.validateNFC({
|
|
535
|
+
nfcCode,
|
|
536
|
+
device,
|
|
537
|
+
userLocation: location || void 0,
|
|
538
|
+
skipLocationCheck: options.skipLocationCheck,
|
|
539
|
+
skipRepetitiveCheck: options.skipRepetitiveCheck
|
|
540
|
+
});
|
|
541
|
+
if (!result.success) {
|
|
542
|
+
throw new Error(result.message);
|
|
543
|
+
}
|
|
544
|
+
options.onSuccess?.(result.entrance);
|
|
545
|
+
await stopScanning();
|
|
546
|
+
} catch (err) {
|
|
547
|
+
const error2 = err;
|
|
548
|
+
setError(error2);
|
|
549
|
+
options.onError?.(error2);
|
|
550
|
+
await stopScanning();
|
|
551
|
+
}
|
|
552
|
+
},
|
|
553
|
+
[nfcAccessService, deviceAccessService, location, options, stopScanning]
|
|
554
|
+
);
|
|
555
|
+
const startScanning = (0, import_react5.useCallback)(async () => {
|
|
556
|
+
setIsScanning(true);
|
|
557
|
+
setError(null);
|
|
558
|
+
try {
|
|
559
|
+
await import_react_native_nfc_manager.default.requestTechnology(import_react_native_nfc_manager.NfcTech.Ndef, {
|
|
560
|
+
invalidateAfterFirstRead: true
|
|
561
|
+
});
|
|
562
|
+
const tag = await import_react_native_nfc_manager.default.getTag();
|
|
563
|
+
await handleNFCTag(tag || {});
|
|
564
|
+
} catch (err) {
|
|
565
|
+
const error2 = err;
|
|
566
|
+
setError(error2);
|
|
567
|
+
options.onError?.(error2);
|
|
568
|
+
setIsScanning(false);
|
|
569
|
+
}
|
|
570
|
+
}, [handleNFCTag, options]);
|
|
571
|
+
(0, import_react5.useEffect)(() => {
|
|
572
|
+
if (options.autoStart) {
|
|
573
|
+
startScanning();
|
|
574
|
+
}
|
|
575
|
+
return () => {
|
|
576
|
+
stopScanning();
|
|
577
|
+
};
|
|
578
|
+
}, [options.autoStart, startScanning, stopScanning]);
|
|
579
|
+
return {
|
|
580
|
+
startScanning,
|
|
581
|
+
stopScanning,
|
|
582
|
+
isScanning,
|
|
583
|
+
error
|
|
584
|
+
};
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
// src/hooks/useCheckIn.ts
|
|
588
|
+
var import_react6 = require("react");
|
|
589
|
+
function useCheckIn(options = {}) {
|
|
590
|
+
const { checkInService, config: _config } = usePassgageAccess();
|
|
591
|
+
const { location } = useLocation();
|
|
592
|
+
const [nearbyBranches, setNearbyBranches] = (0, import_react6.useState)([]);
|
|
593
|
+
const [isLoading, setIsLoading] = (0, import_react6.useState)(false);
|
|
594
|
+
const [error, setError] = (0, import_react6.useState)(null);
|
|
595
|
+
const fetchNearbyBranches = (0, import_react6.useCallback)(async () => {
|
|
596
|
+
if (!location) {
|
|
597
|
+
return;
|
|
598
|
+
}
|
|
599
|
+
setIsLoading(true);
|
|
600
|
+
setError(null);
|
|
601
|
+
try {
|
|
602
|
+
const response = await checkInService.getNearbyBranches({
|
|
603
|
+
latitude: location.latitude,
|
|
604
|
+
longitude: location.longitude,
|
|
605
|
+
radius: options.radius
|
|
606
|
+
});
|
|
607
|
+
if (response.success && response.data) {
|
|
608
|
+
setNearbyBranches(response.data);
|
|
609
|
+
}
|
|
610
|
+
} catch (err) {
|
|
611
|
+
setError(err);
|
|
612
|
+
} finally {
|
|
613
|
+
setIsLoading(false);
|
|
614
|
+
}
|
|
615
|
+
}, [checkInService, location, options.radius]);
|
|
616
|
+
const checkIn = (0, import_react6.useCallback)(
|
|
617
|
+
async (params) => {
|
|
618
|
+
setIsLoading(true);
|
|
619
|
+
setError(null);
|
|
620
|
+
try {
|
|
621
|
+
const userId = "";
|
|
622
|
+
const result = await checkInService.checkIn({
|
|
623
|
+
...params,
|
|
624
|
+
userId,
|
|
625
|
+
userLocation: location || void 0
|
|
626
|
+
});
|
|
627
|
+
if (!result.success) {
|
|
628
|
+
throw new Error(result.message);
|
|
629
|
+
}
|
|
630
|
+
return result.entrance;
|
|
631
|
+
} catch (err) {
|
|
632
|
+
setError(err);
|
|
633
|
+
throw err;
|
|
634
|
+
} finally {
|
|
635
|
+
setIsLoading(false);
|
|
636
|
+
}
|
|
637
|
+
},
|
|
638
|
+
[checkInService, location]
|
|
639
|
+
);
|
|
640
|
+
(0, import_react6.useEffect)(() => {
|
|
641
|
+
if (options.autoFetch && location) {
|
|
642
|
+
fetchNearbyBranches();
|
|
643
|
+
}
|
|
644
|
+
}, [options.autoFetch, location, fetchNearbyBranches]);
|
|
645
|
+
return {
|
|
646
|
+
nearbyBranches,
|
|
647
|
+
fetchNearbyBranches,
|
|
648
|
+
checkIn,
|
|
649
|
+
isLoading,
|
|
650
|
+
error
|
|
651
|
+
};
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
// src/hooks/useRemoteWork.ts
|
|
655
|
+
var import_react7 = require("react");
|
|
656
|
+
var import_sdk_core2 = require("@passgage/sdk-core");
|
|
657
|
+
function useRemoteWork() {
|
|
658
|
+
const { remoteWorkService } = usePassgageAccess();
|
|
659
|
+
const [isLoading, setIsLoading] = (0, import_react7.useState)(false);
|
|
660
|
+
const [error, setError] = (0, import_react7.useState)(null);
|
|
661
|
+
const logRemoteWork = (0, import_react7.useCallback)(
|
|
662
|
+
async (entranceType, options = {}) => {
|
|
663
|
+
setIsLoading(true);
|
|
664
|
+
setError(null);
|
|
665
|
+
try {
|
|
666
|
+
const userId = "";
|
|
667
|
+
const result = await remoteWorkService.logRemoteWork({
|
|
668
|
+
userId,
|
|
669
|
+
entranceType,
|
|
670
|
+
timestamp: options.timestamp,
|
|
671
|
+
description: options.description
|
|
672
|
+
});
|
|
673
|
+
if (!result.success) {
|
|
674
|
+
throw new Error(result.message);
|
|
675
|
+
}
|
|
676
|
+
return result.entrance;
|
|
677
|
+
} catch (err) {
|
|
678
|
+
const error2 = err;
|
|
679
|
+
setError(error2);
|
|
680
|
+
throw error2;
|
|
681
|
+
} finally {
|
|
682
|
+
setIsLoading(false);
|
|
683
|
+
}
|
|
684
|
+
},
|
|
685
|
+
[remoteWorkService]
|
|
686
|
+
);
|
|
687
|
+
const logEntry = (0, import_react7.useCallback)(
|
|
688
|
+
async (options) => {
|
|
689
|
+
return logRemoteWork(import_sdk_core2.EntranceType.ENTRY, options);
|
|
690
|
+
},
|
|
691
|
+
[logRemoteWork]
|
|
692
|
+
);
|
|
693
|
+
const logExit = (0, import_react7.useCallback)(
|
|
694
|
+
async (options) => {
|
|
695
|
+
return logRemoteWork(import_sdk_core2.EntranceType.EXIT, options);
|
|
696
|
+
},
|
|
697
|
+
[logRemoteWork]
|
|
698
|
+
);
|
|
699
|
+
return {
|
|
700
|
+
logEntry,
|
|
701
|
+
logExit,
|
|
702
|
+
logRemoteWork,
|
|
703
|
+
isLoading,
|
|
704
|
+
error
|
|
705
|
+
};
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
// src/index.tsx
|
|
709
|
+
var SDK_VERSION = "1.0.0";
|
|
710
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
711
|
+
0 && (module.exports = {
|
|
712
|
+
PassgageAccessProvider,
|
|
713
|
+
SDK_VERSION,
|
|
714
|
+
useCheckIn,
|
|
715
|
+
useLocation,
|
|
716
|
+
useNFCScanner,
|
|
717
|
+
usePassgageAccess,
|
|
718
|
+
usePassgageAuth,
|
|
719
|
+
useQRScanner,
|
|
720
|
+
useRemoteWork
|
|
721
|
+
});
|