react-native-permission-handler 0.2.1 → 0.3.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/README.md +44 -0
- package/dist/engines/expo.d.mts +1 -1
- package/dist/engines/expo.d.ts +1 -1
- package/dist/engines/rnp.d.mts +1 -1
- package/dist/engines/rnp.d.ts +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +165 -43
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +165 -43
- package/dist/index.mjs.map +1 -1
- package/dist/{types-QXyq8VnD.d.mts → types-DwqbbLGD.d.mts} +6 -0
- package/dist/{types-QXyq8VnD.d.ts → types-DwqbbLGD.d.ts} +6 -0
- package/package.json +1 -1
- package/src/core/debug-logger.test.ts +67 -0
- package/src/core/debug-logger.ts +29 -0
- package/src/core/with-timeout.test.ts +82 -0
- package/src/core/with-timeout.ts +34 -0
- package/src/hooks/use-multiple-permissions.ts +71 -29
- package/src/hooks/use-permission-handler.ts +60 -14
- package/src/types.ts +6 -0
package/README.md
CHANGED
|
@@ -209,6 +209,9 @@ The main hook. Manages the full permission lifecycle.
|
|
|
209
209
|
// Options
|
|
210
210
|
autoCheck?: boolean; // default: true — check on mount
|
|
211
211
|
recheckOnForeground?: boolean; // default: false
|
|
212
|
+
requestTimeout?: number; // timeout for request() in ms (opt-in)
|
|
213
|
+
onTimeout?: () => void; // called if request() times out
|
|
214
|
+
debug?: boolean | ((msg: string) => void); // log state transitions
|
|
212
215
|
}
|
|
213
216
|
```
|
|
214
217
|
|
|
@@ -302,6 +305,9 @@ Orchestrates flows for features needing multiple permissions (e.g., video call =
|
|
|
302
305
|
|
|
303
306
|
engine?: PermissionEngine; // optional — overrides global/fallback
|
|
304
307
|
autoCheck?: boolean; // default: true — check all on mount
|
|
308
|
+
requestTimeout?: number; // timeout for request() in ms (opt-in)
|
|
309
|
+
onTimeout?: () => void; // called if any request() times out
|
|
310
|
+
debug?: boolean | ((msg: string) => void); // log state transitions
|
|
305
311
|
onAllGranted?: () => void;
|
|
306
312
|
}
|
|
307
313
|
```
|
|
@@ -538,6 +544,44 @@ The engine is responsible for:
|
|
|
538
544
|
- Handling special cases like notifications internally
|
|
539
545
|
- Opening the correct settings screen
|
|
540
546
|
|
|
547
|
+
## Debugging & Reliability
|
|
548
|
+
|
|
549
|
+
### Request Timeout
|
|
550
|
+
|
|
551
|
+
On Android 16, `request()` can hang indefinitely when a permission is in `never_ask_again` state ([facebook/react-native#53887](https://github.com/facebook/react-native/issues/53887)). Enable `requestTimeout` to recover:
|
|
552
|
+
|
|
553
|
+
```tsx
|
|
554
|
+
const camera = usePermissionHandler({
|
|
555
|
+
permission: Permissions.CAMERA,
|
|
556
|
+
requestTimeout: 15000, // 15 seconds
|
|
557
|
+
onTimeout: () => console.warn("Permission request timed out"),
|
|
558
|
+
prePrompt: { title: "Camera", message: "..." },
|
|
559
|
+
blockedPrompt: { title: "Blocked", message: "..." },
|
|
560
|
+
});
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
On timeout, the hook transitions to `blockedPrompt` (since the hanging bug only occurs for already-blocked permissions) and fires `onTimeout`.
|
|
564
|
+
|
|
565
|
+
### Debug Logging
|
|
566
|
+
|
|
567
|
+
Enable `debug` to log state transitions — useful for bug reports and support workflows:
|
|
568
|
+
|
|
569
|
+
```tsx
|
|
570
|
+
const camera = usePermissionHandler({
|
|
571
|
+
permission: Permissions.CAMERA,
|
|
572
|
+
debug: true,
|
|
573
|
+
// ...
|
|
574
|
+
});
|
|
575
|
+
// Console: [permission-handler] camera: idle → checking (CHECK)
|
|
576
|
+
// Console: [permission-handler] camera: checking → prePrompt (CHECK_RESULT:denied)
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
Pass a function to route logs to your own logger:
|
|
580
|
+
|
|
581
|
+
```tsx
|
|
582
|
+
debug: (msg) => Sentry.addBreadcrumb({ message: msg, category: "permissions" })
|
|
583
|
+
```
|
|
584
|
+
|
|
541
585
|
## Platform Notes
|
|
542
586
|
|
|
543
587
|
**iOS:**
|
package/dist/engines/expo.d.mts
CHANGED
package/dist/engines/expo.d.ts
CHANGED
package/dist/engines/rnp.d.mts
CHANGED
package/dist/engines/rnp.d.ts
CHANGED
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { P as PermissionEngine, a as PermissionFlowState, b as PermissionFlowEvent, c as PermissionHandlerConfig, d as PermissionHandlerResult, M as MultiplePermissionsConfig, e as MultiplePermissionsResult, f as PermissionCallbacks, g as PrePromptConfig, B as BlockedPromptConfig } from './types-
|
|
2
|
-
export { h as MultiPermissionEntry, i as PermissionStatus } from './types-
|
|
1
|
+
import { P as PermissionEngine, a as PermissionFlowState, b as PermissionFlowEvent, c as PermissionHandlerConfig, d as PermissionHandlerResult, M as MultiplePermissionsConfig, e as MultiplePermissionsResult, f as PermissionCallbacks, g as PrePromptConfig, B as BlockedPromptConfig } from './types-DwqbbLGD.mjs';
|
|
2
|
+
export { h as MultiPermissionEntry, i as PermissionStatus } from './types-DwqbbLGD.mjs';
|
|
3
3
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
4
|
import { ReactNode } from 'react';
|
|
5
5
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { P as PermissionEngine, a as PermissionFlowState, b as PermissionFlowEvent, c as PermissionHandlerConfig, d as PermissionHandlerResult, M as MultiplePermissionsConfig, e as MultiplePermissionsResult, f as PermissionCallbacks, g as PrePromptConfig, B as BlockedPromptConfig } from './types-
|
|
2
|
-
export { h as MultiPermissionEntry, i as PermissionStatus } from './types-
|
|
1
|
+
import { P as PermissionEngine, a as PermissionFlowState, b as PermissionFlowEvent, c as PermissionHandlerConfig, d as PermissionHandlerResult, M as MultiplePermissionsConfig, e as MultiplePermissionsResult, f as PermissionCallbacks, g as PrePromptConfig, B as BlockedPromptConfig } from './types-DwqbbLGD.js';
|
|
2
|
+
export { h as MultiPermissionEntry, i as PermissionStatus } from './types-DwqbbLGD.js';
|
|
3
3
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
4
|
import { ReactNode } from 'react';
|
|
5
5
|
|
package/dist/index.js
CHANGED
|
@@ -185,6 +185,55 @@ function transition(state, event) {
|
|
|
185
185
|
var import_react = require("react");
|
|
186
186
|
var import_react_native2 = require("react-native");
|
|
187
187
|
|
|
188
|
+
// src/core/debug-logger.ts
|
|
189
|
+
var PREFIX = "[permission-handler]";
|
|
190
|
+
var NOOP_LOGGER = {
|
|
191
|
+
transition: () => {
|
|
192
|
+
},
|
|
193
|
+
info: () => {
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
function createDebugLogger(debug, permission) {
|
|
197
|
+
if (!debug) return NOOP_LOGGER;
|
|
198
|
+
const log = typeof debug === "function" ? debug : (msg) => console.log(msg);
|
|
199
|
+
return {
|
|
200
|
+
transition(from, to, event) {
|
|
201
|
+
log(`${PREFIX} ${permission}: ${from} \u2192 ${to}${event ? ` (${event})` : ""}`);
|
|
202
|
+
},
|
|
203
|
+
info(msg) {
|
|
204
|
+
log(`${PREFIX} ${permission}: ${msg}`);
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// src/core/with-timeout.ts
|
|
210
|
+
var PermissionTimeoutError = class extends Error {
|
|
211
|
+
constructor(permission, timeoutMs) {
|
|
212
|
+
super(`Permission request for "${permission}" timed out after ${timeoutMs}ms`);
|
|
213
|
+
this.name = "PermissionTimeoutError";
|
|
214
|
+
this.permission = permission;
|
|
215
|
+
this.timeoutMs = timeoutMs;
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
function withTimeout(promise, timeoutMs, permission) {
|
|
219
|
+
return new Promise((resolve, reject) => {
|
|
220
|
+
const timer = setTimeout(
|
|
221
|
+
() => reject(new PermissionTimeoutError(permission, timeoutMs)),
|
|
222
|
+
timeoutMs
|
|
223
|
+
);
|
|
224
|
+
promise.then(
|
|
225
|
+
(val) => {
|
|
226
|
+
clearTimeout(timer);
|
|
227
|
+
resolve(val);
|
|
228
|
+
},
|
|
229
|
+
(err) => {
|
|
230
|
+
clearTimeout(timer);
|
|
231
|
+
reject(err);
|
|
232
|
+
}
|
|
233
|
+
);
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
|
|
188
237
|
// src/engines/rnp-fallback.ts
|
|
189
238
|
var cachedFallback = null;
|
|
190
239
|
function getRNPFallbackEngine() {
|
|
@@ -217,47 +266,83 @@ function usePermissionHandler(config) {
|
|
|
217
266
|
const isRequesting = (0, import_react.useRef)(false);
|
|
218
267
|
const waitingForSettings = (0, import_react.useRef)(false);
|
|
219
268
|
const appStateRef = (0, import_react.useRef)(import_react_native2.AppState.currentState);
|
|
220
|
-
const {
|
|
269
|
+
const {
|
|
270
|
+
permission,
|
|
271
|
+
autoCheck = true,
|
|
272
|
+
requestTimeout,
|
|
273
|
+
onTimeout,
|
|
274
|
+
debug,
|
|
275
|
+
onGrant,
|
|
276
|
+
onDeny,
|
|
277
|
+
onBlock,
|
|
278
|
+
onSettingsReturn
|
|
279
|
+
} = config;
|
|
280
|
+
const logger = createDebugLogger(debug, permission);
|
|
221
281
|
const checkPermission = (0, import_react.useCallback)(async () => {
|
|
222
|
-
setFlowState((s) =>
|
|
282
|
+
setFlowState((s) => {
|
|
283
|
+
const next = transition(s, { type: "CHECK" });
|
|
284
|
+
logger.transition(s, next, "CHECK");
|
|
285
|
+
return next;
|
|
286
|
+
});
|
|
223
287
|
try {
|
|
224
288
|
const status = await engine.check(permission);
|
|
225
289
|
setNativeStatus(status);
|
|
226
290
|
setFlowState((s) => {
|
|
227
291
|
const next = transition(s, { type: "CHECK_RESULT", status });
|
|
292
|
+
logger.transition(s, next, `CHECK_RESULT:${status}`);
|
|
228
293
|
if (next === "granted" && s !== "granted") onGrant?.();
|
|
229
294
|
return next;
|
|
230
295
|
});
|
|
231
296
|
} catch {
|
|
232
297
|
setFlowState("idle");
|
|
233
298
|
}
|
|
234
|
-
}, [engine, permission, onGrant]);
|
|
299
|
+
}, [engine, permission, logger, onGrant]);
|
|
235
300
|
const requestPermission = (0, import_react.useCallback)(async () => {
|
|
236
301
|
if (isRequesting.current) return;
|
|
237
302
|
isRequesting.current = true;
|
|
238
|
-
setFlowState((s) =>
|
|
303
|
+
setFlowState((s) => {
|
|
304
|
+
const next = transition(s, { type: "PRE_PROMPT_CONFIRM" });
|
|
305
|
+
logger.transition(s, next, "PRE_PROMPT_CONFIRM");
|
|
306
|
+
return next;
|
|
307
|
+
});
|
|
239
308
|
try {
|
|
240
|
-
const
|
|
309
|
+
const requestPromise = engine.request(permission);
|
|
310
|
+
const status = requestTimeout ? await withTimeout(requestPromise, requestTimeout, permission) : await requestPromise;
|
|
241
311
|
setNativeStatus(status);
|
|
242
312
|
setFlowState((s) => {
|
|
243
313
|
const next = transition(s, { type: "REQUEST_RESULT", status });
|
|
314
|
+
logger.transition(s, next, `REQUEST_RESULT:${status}`);
|
|
244
315
|
if (next === "granted") onGrant?.();
|
|
245
316
|
if (next === "denied") onDeny?.();
|
|
246
317
|
if (next === "blockedPrompt") onBlock?.();
|
|
247
318
|
return next;
|
|
248
319
|
});
|
|
249
|
-
} catch {
|
|
250
|
-
|
|
320
|
+
} catch (err) {
|
|
321
|
+
if (err instanceof PermissionTimeoutError) {
|
|
322
|
+
logger.info(`request timed out after ${requestTimeout}ms`);
|
|
323
|
+
onTimeout?.();
|
|
324
|
+
setFlowState("blockedPrompt");
|
|
325
|
+
} else {
|
|
326
|
+
setFlowState("denied");
|
|
327
|
+
}
|
|
251
328
|
} finally {
|
|
252
329
|
isRequesting.current = false;
|
|
253
330
|
}
|
|
254
|
-
}, [engine, permission, onGrant, onDeny, onBlock]);
|
|
331
|
+
}, [engine, permission, requestTimeout, onTimeout, logger, onGrant, onDeny, onBlock]);
|
|
255
332
|
const dismiss = (0, import_react.useCallback)(() => {
|
|
256
|
-
setFlowState((s) =>
|
|
333
|
+
setFlowState((s) => {
|
|
334
|
+
const next = transition(s, { type: "PRE_PROMPT_DISMISS" });
|
|
335
|
+
logger.transition(s, next, "PRE_PROMPT_DISMISS");
|
|
336
|
+
return next;
|
|
337
|
+
});
|
|
257
338
|
onDeny?.();
|
|
258
|
-
}, [onDeny]);
|
|
339
|
+
}, [logger, onDeny]);
|
|
259
340
|
const goToSettings = (0, import_react.useCallback)(async () => {
|
|
260
|
-
setFlowState((s) =>
|
|
341
|
+
setFlowState((s) => {
|
|
342
|
+
const next = transition(s, { type: "OPEN_SETTINGS" });
|
|
343
|
+
logger.transition(s, next, "OPEN_SETTINGS");
|
|
344
|
+
return next;
|
|
345
|
+
});
|
|
261
346
|
waitingForSettings.current = true;
|
|
262
347
|
try {
|
|
263
348
|
await engine.openSettings();
|
|
@@ -265,14 +350,19 @@ function usePermissionHandler(config) {
|
|
|
265
350
|
waitingForSettings.current = false;
|
|
266
351
|
setFlowState("blockedPrompt");
|
|
267
352
|
}
|
|
268
|
-
}, [engine]);
|
|
353
|
+
}, [engine, logger]);
|
|
269
354
|
const recheckAfterSettings = (0, import_react.useCallback)(async () => {
|
|
270
|
-
setFlowState((s) =>
|
|
355
|
+
setFlowState((s) => {
|
|
356
|
+
const next = transition(s, { type: "SETTINGS_RETURN" });
|
|
357
|
+
logger.transition(s, next, "SETTINGS_RETURN");
|
|
358
|
+
return next;
|
|
359
|
+
});
|
|
271
360
|
try {
|
|
272
361
|
const status = await engine.check(permission);
|
|
273
362
|
setNativeStatus(status);
|
|
274
363
|
setFlowState((s) => {
|
|
275
364
|
const next = transition(s, { type: "RECHECK_RESULT", status });
|
|
365
|
+
logger.transition(s, next, `RECHECK_RESULT:${status}`);
|
|
276
366
|
if (next === "granted") onGrant?.();
|
|
277
367
|
onSettingsReturn?.(next === "granted");
|
|
278
368
|
return next;
|
|
@@ -280,7 +370,7 @@ function usePermissionHandler(config) {
|
|
|
280
370
|
} catch {
|
|
281
371
|
setFlowState("blockedPrompt");
|
|
282
372
|
}
|
|
283
|
-
}, [engine, permission, onGrant, onSettingsReturn]);
|
|
373
|
+
}, [engine, permission, logger, onGrant, onSettingsReturn]);
|
|
284
374
|
(0, import_react.useEffect)(() => {
|
|
285
375
|
if (autoCheck) {
|
|
286
376
|
checkPermission();
|
|
@@ -336,7 +426,16 @@ function statusToFlowState(status) {
|
|
|
336
426
|
}
|
|
337
427
|
function useMultiplePermissions(config) {
|
|
338
428
|
const engine = resolveEngine(config.engine);
|
|
339
|
-
const {
|
|
429
|
+
const {
|
|
430
|
+
permissions,
|
|
431
|
+
strategy,
|
|
432
|
+
autoCheck = true,
|
|
433
|
+
requestTimeout,
|
|
434
|
+
onTimeout,
|
|
435
|
+
debug,
|
|
436
|
+
onAllGranted
|
|
437
|
+
} = config;
|
|
438
|
+
const logger = createDebugLogger(debug, "multi");
|
|
340
439
|
const [statuses, setStatuses] = (0, import_react2.useState)(() => {
|
|
341
440
|
const initial = {};
|
|
342
441
|
for (const entry of permissions) {
|
|
@@ -350,13 +449,16 @@ function useMultiplePermissions(config) {
|
|
|
350
449
|
if (isRunning.current) return;
|
|
351
450
|
isRunning.current = true;
|
|
352
451
|
const update = (key, state) => {
|
|
353
|
-
setStatuses((prev) =>
|
|
452
|
+
setStatuses((prev) => {
|
|
453
|
+
logger.transition(prev[key] ?? "idle", state, key);
|
|
454
|
+
return { ...prev, [key]: state };
|
|
455
|
+
});
|
|
354
456
|
};
|
|
355
457
|
try {
|
|
356
458
|
if (strategy === "sequential") {
|
|
357
|
-
await runSequential(permissions, engine, update);
|
|
459
|
+
await runSequential(permissions, engine, update, requestTimeout, onTimeout);
|
|
358
460
|
} else {
|
|
359
|
-
await runParallel(permissions, engine, update);
|
|
461
|
+
await runParallel(permissions, engine, update, requestTimeout, onTimeout);
|
|
360
462
|
}
|
|
361
463
|
let allDone = true;
|
|
362
464
|
for (const entry of permissions) {
|
|
@@ -372,7 +474,7 @@ function useMultiplePermissions(config) {
|
|
|
372
474
|
} finally {
|
|
373
475
|
isRunning.current = false;
|
|
374
476
|
}
|
|
375
|
-
}, [permissions, strategy, engine, onAllGranted]);
|
|
477
|
+
}, [permissions, strategy, engine, requestTimeout, onTimeout, logger, onAllGranted]);
|
|
376
478
|
(0, import_react2.useEffect)(() => {
|
|
377
479
|
if (!autoCheck) return;
|
|
378
480
|
let cancelled = false;
|
|
@@ -395,7 +497,7 @@ function useMultiplePermissions(config) {
|
|
|
395
497
|
request: requestAll
|
|
396
498
|
};
|
|
397
499
|
}
|
|
398
|
-
async function runSequential(permissions, engine, updateStatus) {
|
|
500
|
+
async function runSequential(permissions, engine, updateStatus, requestTimeout, onTimeout) {
|
|
399
501
|
for (const entry of permissions) {
|
|
400
502
|
const key = permissionKey(entry);
|
|
401
503
|
updateStatus(key, "checking");
|
|
@@ -415,22 +517,32 @@ async function runSequential(permissions, engine, updateStatus) {
|
|
|
415
517
|
break;
|
|
416
518
|
}
|
|
417
519
|
updateStatus(key, "requesting");
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
520
|
+
try {
|
|
521
|
+
const requestPromise = engine.request(entry.permission);
|
|
522
|
+
const requestStatus = requestTimeout ? await withTimeout(requestPromise, requestTimeout, entry.permission) : await requestPromise;
|
|
523
|
+
if (isGrantedStatus(requestStatus)) {
|
|
524
|
+
updateStatus(key, "granted");
|
|
525
|
+
entry.onGrant?.();
|
|
526
|
+
} else if (requestStatus === "blocked") {
|
|
527
|
+
updateStatus(key, "blockedPrompt");
|
|
528
|
+
entry.onBlock?.();
|
|
529
|
+
break;
|
|
530
|
+
} else {
|
|
531
|
+
updateStatus(key, "denied");
|
|
532
|
+
entry.onDeny?.();
|
|
533
|
+
break;
|
|
534
|
+
}
|
|
535
|
+
} catch (err) {
|
|
536
|
+
if (err instanceof PermissionTimeoutError) {
|
|
537
|
+
onTimeout?.();
|
|
538
|
+
updateStatus(key, "blockedPrompt");
|
|
539
|
+
break;
|
|
540
|
+
}
|
|
541
|
+
throw err;
|
|
430
542
|
}
|
|
431
543
|
}
|
|
432
544
|
}
|
|
433
|
-
async function runParallel(permissions, engine, updateStatus) {
|
|
545
|
+
async function runParallel(permissions, engine, updateStatus, requestTimeout, onTimeout) {
|
|
434
546
|
const checkResults = await Promise.all(
|
|
435
547
|
permissions.map(async (entry) => {
|
|
436
548
|
const key = permissionKey(entry);
|
|
@@ -457,16 +569,26 @@ async function runParallel(permissions, engine, updateStatus) {
|
|
|
457
569
|
continue;
|
|
458
570
|
}
|
|
459
571
|
updateStatus(key, "requesting");
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
572
|
+
try {
|
|
573
|
+
const requestPromise = engine.request(entry.permission);
|
|
574
|
+
const requestStatus = requestTimeout ? await withTimeout(requestPromise, requestTimeout, entry.permission) : await requestPromise;
|
|
575
|
+
if (isGrantedStatus(requestStatus)) {
|
|
576
|
+
updateStatus(key, "granted");
|
|
577
|
+
entry.onGrant?.();
|
|
578
|
+
} else if (requestStatus === "blocked") {
|
|
579
|
+
updateStatus(key, "blockedPrompt");
|
|
580
|
+
entry.onBlock?.();
|
|
581
|
+
} else {
|
|
582
|
+
updateStatus(key, "denied");
|
|
583
|
+
entry.onDeny?.();
|
|
584
|
+
}
|
|
585
|
+
} catch (err) {
|
|
586
|
+
if (err instanceof PermissionTimeoutError) {
|
|
587
|
+
onTimeout?.();
|
|
588
|
+
updateStatus(key, "blockedPrompt");
|
|
589
|
+
} else {
|
|
590
|
+
throw err;
|
|
591
|
+
}
|
|
470
592
|
}
|
|
471
593
|
}
|
|
472
594
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/engines/rnp.ts","../src/index.ts","../src/engines/resolve.ts","../src/core/state-machine.ts","../src/hooks/use-permission-handler.ts","../src/engines/rnp-fallback.ts","../src/engines/use-engine.ts","../src/hooks/use-multiple-permissions.ts","../src/components/default-blocked-prompt.tsx","../src/components/default-pre-prompt.tsx","../src/components/permission-gate.tsx"],"sourcesContent":["import { Platform } from \"react-native\";\nimport {\n type Permission,\n check,\n checkNotifications,\n openSettings,\n request,\n requestNotifications,\n} from \"react-native-permissions\";\nimport type { PermissionEngine, PermissionStatus } from \"../types\";\n\nfunction p(ios: string, android: string): string {\n return Platform.select({ ios, android, default: ios }) ?? ios;\n}\n\n/**\n * Cross-platform permission constants for use with the RNP engine.\n * Each resolves to the correct platform-specific string at runtime.\n */\nexport const Permissions = {\n CAMERA: p(\"ios.permission.CAMERA\", \"android.permission.CAMERA\"),\n MICROPHONE: p(\"ios.permission.MICROPHONE\", \"android.permission.RECORD_AUDIO\"),\n CONTACTS: p(\"ios.permission.CONTACTS\", \"android.permission.READ_CONTACTS\"),\n CALENDARS: p(\"ios.permission.CALENDARS\", \"android.permission.READ_CALENDAR\"),\n CALENDARS_WRITE_ONLY: p(\n \"ios.permission.CALENDARS_WRITE_ONLY\",\n \"android.permission.WRITE_CALENDAR\",\n ),\n LOCATION_WHEN_IN_USE: p(\n \"ios.permission.LOCATION_WHEN_IN_USE\",\n \"android.permission.ACCESS_FINE_LOCATION\",\n ),\n LOCATION_ALWAYS: p(\n \"ios.permission.LOCATION_ALWAYS\",\n \"android.permission.ACCESS_BACKGROUND_LOCATION\",\n ),\n PHOTO_LIBRARY: p(\"ios.permission.PHOTO_LIBRARY\", \"android.permission.READ_MEDIA_IMAGES\"),\n PHOTO_LIBRARY_ADD_ONLY: p(\n \"ios.permission.PHOTO_LIBRARY_ADD_ONLY\",\n \"android.permission.WRITE_EXTERNAL_STORAGE\",\n ),\n BLUETOOTH: p(\"ios.permission.BLUETOOTH\", \"android.permission.BLUETOOTH_CONNECT\"),\n NOTIFICATIONS: \"notifications\",\n} as const;\n\nexport function createRNPEngine(): PermissionEngine {\n return {\n async check(permission: string): Promise<PermissionStatus> {\n if (permission === \"notifications\") {\n const result = await checkNotifications();\n return result.status as PermissionStatus;\n }\n return (await check(permission as Permission)) as PermissionStatus;\n },\n\n async request(permission: string): Promise<PermissionStatus> {\n if (permission === \"notifications\") {\n const result = await requestNotifications([\"alert\", \"badge\", \"sound\"]);\n return result.status as PermissionStatus;\n }\n return (await request(permission as Permission)) as PermissionStatus;\n },\n\n async openSettings(): Promise<void> {\n await openSettings();\n },\n };\n}\n","export type {\n BlockedPromptConfig,\n MultiPermissionEntry,\n MultiplePermissionsConfig,\n MultiplePermissionsResult,\n PermissionCallbacks,\n PermissionEngine,\n PermissionFlowEvent,\n PermissionFlowState,\n PermissionHandlerConfig,\n PermissionHandlerResult,\n PermissionStatus,\n PrePromptConfig,\n} from \"./types\";\n\nexport { setDefaultEngine } from \"./engines/resolve\";\nexport { transition } from \"./core/state-machine\";\nexport { usePermissionHandler } from \"./hooks/use-permission-handler\";\nexport { useMultiplePermissions } from \"./hooks/use-multiple-permissions\";\nexport { PermissionGate } from \"./components/permission-gate\";\nexport type { PermissionGateProps } from \"./components/permission-gate\";\nexport { DefaultPrePrompt } from \"./components/default-pre-prompt\";\nexport type { DefaultPrePromptProps } from \"./components/default-pre-prompt\";\nexport { DefaultBlockedPrompt } from \"./components/default-blocked-prompt\";\nexport type { DefaultBlockedPromptProps } from \"./components/default-blocked-prompt\";\n","import type { PermissionEngine } from \"../types\";\n\nlet defaultEngine: PermissionEngine | null = null;\n\nexport function setDefaultEngine(engine: PermissionEngine): void {\n defaultEngine = engine;\n}\n\nexport function getDefaultEngine(): PermissionEngine | null {\n return defaultEngine;\n}\n","import type { PermissionFlowEvent, PermissionFlowState } from \"../types\";\n\nexport function transition(\n state: PermissionFlowState,\n event: PermissionFlowEvent,\n): PermissionFlowState {\n switch (state) {\n case \"idle\":\n if (event.type === \"CHECK\") return \"checking\";\n return state;\n\n case \"checking\":\n if (event.type === \"CHECK_RESULT\") {\n switch (event.status) {\n case \"granted\":\n case \"limited\":\n return \"granted\";\n case \"denied\":\n return \"prePrompt\";\n case \"blocked\":\n return \"blockedPrompt\";\n case \"unavailable\":\n return \"unavailable\";\n default:\n return state;\n }\n }\n return state;\n\n case \"prePrompt\":\n if (event.type === \"PRE_PROMPT_CONFIRM\") return \"requesting\";\n if (event.type === \"PRE_PROMPT_DISMISS\") return \"denied\";\n return state;\n\n case \"requesting\":\n if (event.type === \"REQUEST_RESULT\") {\n switch (event.status) {\n case \"granted\":\n case \"limited\":\n return \"granted\";\n case \"denied\":\n return \"denied\";\n case \"blocked\":\n return \"blockedPrompt\";\n default:\n return state;\n }\n }\n return state;\n\n case \"blockedPrompt\":\n if (event.type === \"OPEN_SETTINGS\") return \"openingSettings\";\n return state;\n\n case \"openingSettings\":\n if (event.type === \"SETTINGS_RETURN\") return \"recheckingAfterSettings\";\n return state;\n\n case \"recheckingAfterSettings\":\n if (event.type === \"RECHECK_RESULT\") {\n switch (event.status) {\n case \"granted\":\n case \"limited\":\n return \"granted\";\n case \"blocked\":\n return \"blockedPrompt\";\n case \"denied\":\n return \"blockedPrompt\";\n default:\n return state;\n }\n }\n return state;\n\n case \"granted\":\n case \"denied\":\n case \"unavailable\":\n if (event.type === \"CHECK\") return \"checking\";\n return state;\n\n case \"blocked\":\n return state;\n\n default:\n return state;\n }\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\nimport { AppState } from \"react-native\";\nimport { transition } from \"../core/state-machine\";\nimport { resolveEngine } from \"../engines/use-engine\";\nimport type {\n PermissionFlowState,\n PermissionHandlerConfig,\n PermissionHandlerResult,\n PermissionStatus,\n} from \"../types\";\n\nexport function usePermissionHandler(config: PermissionHandlerConfig): PermissionHandlerResult {\n const engine = resolveEngine(config.engine);\n const [flowState, setFlowState] = useState<PermissionFlowState>(\"idle\");\n const [nativeStatus, setNativeStatus] = useState<PermissionStatus | null>(null);\n const isRequesting = useRef(false);\n const waitingForSettings = useRef(false);\n const appStateRef = useRef(AppState.currentState);\n\n const { permission, autoCheck = true, onGrant, onDeny, onBlock, onSettingsReturn } = config;\n\n const checkPermission = useCallback(async () => {\n setFlowState((s) => transition(s, { type: \"CHECK\" }));\n try {\n const status = await engine.check(permission);\n setNativeStatus(status);\n setFlowState((s) => {\n const next = transition(s, { type: \"CHECK_RESULT\", status });\n if (next === \"granted\" && s !== \"granted\") onGrant?.();\n return next;\n });\n } catch {\n setFlowState(\"idle\");\n }\n }, [engine, permission, onGrant]);\n\n const requestPermission = useCallback(async () => {\n if (isRequesting.current) return;\n isRequesting.current = true;\n\n setFlowState((s) => transition(s, { type: \"PRE_PROMPT_CONFIRM\" }));\n try {\n const status = await engine.request(permission);\n setNativeStatus(status);\n setFlowState((s) => {\n const next = transition(s, { type: \"REQUEST_RESULT\", status });\n if (next === \"granted\") onGrant?.();\n if (next === \"denied\") onDeny?.();\n if (next === \"blockedPrompt\") onBlock?.();\n return next;\n });\n } catch {\n setFlowState(\"denied\");\n } finally {\n isRequesting.current = false;\n }\n }, [engine, permission, onGrant, onDeny, onBlock]);\n\n const dismiss = useCallback(() => {\n setFlowState((s) => transition(s, { type: \"PRE_PROMPT_DISMISS\" }));\n onDeny?.();\n }, [onDeny]);\n\n const goToSettings = useCallback(async () => {\n setFlowState((s) => transition(s, { type: \"OPEN_SETTINGS\" }));\n waitingForSettings.current = true;\n try {\n await engine.openSettings();\n } catch {\n waitingForSettings.current = false;\n setFlowState(\"blockedPrompt\");\n }\n }, [engine]);\n\n const recheckAfterSettings = useCallback(async () => {\n setFlowState((s) => transition(s, { type: \"SETTINGS_RETURN\" }));\n try {\n const status = await engine.check(permission);\n setNativeStatus(status);\n setFlowState((s) => {\n const next = transition(s, { type: \"RECHECK_RESULT\", status });\n if (next === \"granted\") onGrant?.();\n onSettingsReturn?.(next === \"granted\");\n return next;\n });\n } catch {\n setFlowState(\"blockedPrompt\");\n }\n }, [engine, permission, onGrant, onSettingsReturn]);\n\n // Auto-check on mount\n // biome-ignore lint/correctness/useExhaustiveDependencies: intentional mount-only effect\n useEffect(() => {\n if (autoCheck) {\n checkPermission();\n }\n }, []);\n\n // AppState listener for settings return\n useEffect(() => {\n const subscription = AppState.addEventListener(\"change\", (nextAppState) => {\n if (\n appStateRef.current.match(/inactive|background/) &&\n nextAppState === \"active\" &&\n waitingForSettings.current\n ) {\n waitingForSettings.current = false;\n recheckAfterSettings();\n }\n appStateRef.current = nextAppState;\n });\n return () => subscription.remove();\n }, [recheckAfterSettings]);\n\n return {\n state: flowState,\n nativeStatus,\n isGranted: flowState === \"granted\",\n isDenied: flowState === \"denied\",\n isBlocked:\n flowState === \"blocked\" || flowState === \"blockedPrompt\" || flowState === \"openingSettings\",\n isChecking: flowState === \"checking\" || flowState === \"recheckingAfterSettings\",\n isUnavailable: flowState === \"unavailable\",\n request: requestPermission,\n check: checkPermission,\n dismiss,\n openSettings: goToSettings,\n };\n}\n","import type { PermissionEngine } from \"../types\";\n\nlet cachedFallback: PermissionEngine | null = null;\n\nexport function getRNPFallbackEngine(): PermissionEngine {\n if (cachedFallback) return cachedFallback;\n\n try {\n // Dynamic require to avoid hard dependency — only resolves if\n // react-native-permissions is installed by the consumer.\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const mod = require(\"./rnp\") as { createRNPEngine: () => PermissionEngine };\n const { createRNPEngine } = mod;\n cachedFallback = createRNPEngine();\n return cachedFallback;\n } catch {\n throw new Error(\n \"react-native-permission-handler: No permission engine configured. \" +\n \"Either pass an `engine` in your hook config, call setDefaultEngine(), \" +\n \"or install react-native-permissions as a peer dependency.\",\n );\n }\n}\n","import type { PermissionEngine } from \"../types\";\nimport { getDefaultEngine } from \"./resolve\";\nimport { getRNPFallbackEngine } from \"./rnp-fallback\";\n\nexport function resolveEngine(configEngine?: PermissionEngine): PermissionEngine {\n if (configEngine) return configEngine;\n const global = getDefaultEngine();\n if (global) return global;\n return getRNPFallbackEngine();\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\nimport { resolveEngine } from \"../engines/use-engine\";\nimport type {\n MultiPermissionEntry,\n MultiplePermissionsConfig,\n MultiplePermissionsResult,\n PermissionEngine,\n PermissionFlowState,\n PermissionStatus,\n} from \"../types\";\n\nfunction permissionKey(entry: MultiPermissionEntry): string {\n return String(entry.permission);\n}\n\nfunction isGrantedStatus(status: PermissionStatus): boolean {\n return status === \"granted\" || status === \"limited\";\n}\n\nfunction statusToFlowState(status: PermissionStatus): PermissionFlowState {\n switch (status) {\n case \"granted\":\n case \"limited\":\n return \"granted\";\n case \"blocked\":\n return \"blockedPrompt\";\n case \"unavailable\":\n return \"unavailable\";\n case \"denied\":\n return \"prePrompt\";\n default:\n return \"idle\";\n }\n}\n\nexport function useMultiplePermissions(\n config: MultiplePermissionsConfig,\n): MultiplePermissionsResult {\n const engine = resolveEngine(config.engine);\n const { permissions, strategy, autoCheck = true, onAllGranted } = config;\n const [statuses, setStatuses] = useState<Record<string, PermissionFlowState>>(() => {\n const initial: Record<string, PermissionFlowState> = {};\n for (const entry of permissions) {\n initial[permissionKey(entry)] = \"idle\";\n }\n return initial;\n });\n const isRunning = useRef(false);\n\n const allGranted = permissions.every((entry) => statuses[permissionKey(entry)] === \"granted\");\n\n const requestAll = useCallback(async () => {\n if (isRunning.current) return;\n isRunning.current = true;\n\n const update = (key: string, state: PermissionFlowState) => {\n setStatuses((prev) => ({ ...prev, [key]: state }));\n };\n\n try {\n if (strategy === \"sequential\") {\n await runSequential(permissions, engine, update);\n } else {\n await runParallel(permissions, engine, update);\n }\n\n // Final check: are all granted?\n let allDone = true;\n for (const entry of permissions) {\n const finalStatus = await engine.check(entry.permission);\n if (!isGrantedStatus(finalStatus)) {\n allDone = false;\n break;\n }\n }\n if (allDone) {\n onAllGranted?.();\n }\n } finally {\n isRunning.current = false;\n }\n }, [permissions, strategy, engine, onAllGranted]);\n\n // Auto-check on mount\n // biome-ignore lint/correctness/useExhaustiveDependencies: intentional mount-only effect\n useEffect(() => {\n if (!autoCheck) return;\n\n let cancelled = false;\n async function checkAll() {\n for (const entry of permissions) {\n const key = permissionKey(entry);\n const status = await engine.check(entry.permission);\n if (cancelled) return;\n setStatuses((prev) => ({ ...prev, [key]: statusToFlowState(status) }));\n }\n }\n checkAll();\n return () => {\n cancelled = true;\n };\n }, []);\n\n return {\n statuses,\n allGranted,\n request: requestAll,\n };\n}\n\nasync function runSequential(\n permissions: MultiPermissionEntry[],\n engine: PermissionEngine,\n updateStatus: (key: string, state: PermissionFlowState) => void,\n): Promise<void> {\n for (const entry of permissions) {\n const key = permissionKey(entry);\n\n updateStatus(key, \"checking\");\n const checkStatus = await engine.check(entry.permission);\n\n if (isGrantedStatus(checkStatus)) {\n updateStatus(key, \"granted\");\n entry.onGrant?.();\n continue;\n }\n\n if (checkStatus === \"unavailable\") {\n updateStatus(key, \"unavailable\");\n continue;\n }\n\n if (checkStatus === \"blocked\") {\n updateStatus(key, \"blockedPrompt\");\n entry.onBlock?.();\n break;\n }\n\n // Denied — request it\n updateStatus(key, \"requesting\");\n const requestStatus = await engine.request(entry.permission);\n\n if (isGrantedStatus(requestStatus)) {\n updateStatus(key, \"granted\");\n entry.onGrant?.();\n } else if (requestStatus === \"blocked\") {\n updateStatus(key, \"blockedPrompt\");\n entry.onBlock?.();\n break;\n } else {\n updateStatus(key, \"denied\");\n entry.onDeny?.();\n break;\n }\n }\n}\n\nasync function runParallel(\n permissions: MultiPermissionEntry[],\n engine: PermissionEngine,\n updateStatus: (key: string, state: PermissionFlowState) => void,\n): Promise<void> {\n // Check all in parallel\n const checkResults = await Promise.all(\n permissions.map(async (entry) => {\n const key = permissionKey(entry);\n updateStatus(key, \"checking\");\n const status = await engine.check(entry.permission);\n return { entry, key, status };\n }),\n );\n\n // Update granted/unavailable immediately\n for (const { entry, key, status } of checkResults) {\n if (isGrantedStatus(status)) {\n updateStatus(key, \"granted\");\n entry.onGrant?.();\n } else if (status === \"unavailable\") {\n updateStatus(key, \"unavailable\");\n }\n }\n\n // Request denied/blocked ones sequentially (system dialogs are sequential)\n const needsAction = checkResults.filter(\n ({ status }) => status === \"denied\" || status === \"blocked\",\n );\n\n for (const { entry, key, status } of needsAction) {\n if (status === \"blocked\") {\n updateStatus(key, \"blockedPrompt\");\n entry.onBlock?.();\n continue;\n }\n\n updateStatus(key, \"requesting\");\n const requestStatus = await engine.request(entry.permission);\n\n if (isGrantedStatus(requestStatus)) {\n updateStatus(key, \"granted\");\n entry.onGrant?.();\n } else if (requestStatus === \"blocked\") {\n updateStatus(key, \"blockedPrompt\");\n entry.onBlock?.();\n } else {\n updateStatus(key, \"denied\");\n entry.onDeny?.();\n }\n }\n}\n","import React from \"react\";\nimport { Modal, StyleSheet, Text, TouchableOpacity, View } from \"react-native\";\nimport type { BlockedPromptConfig } from \"../types\";\n\nexport interface DefaultBlockedPromptProps extends BlockedPromptConfig {\n visible: boolean;\n onOpenSettings: () => void;\n}\n\nexport function DefaultBlockedPrompt({\n visible,\n title,\n message,\n settingsLabel = \"Open Settings\",\n onOpenSettings,\n}: DefaultBlockedPromptProps) {\n return (\n <Modal visible={visible} transparent animationType=\"fade\">\n <View style={styles.overlay}>\n <View style={styles.modal}>\n <Text style={styles.title}>{title}</Text>\n <Text style={styles.message}>{message}</Text>\n <TouchableOpacity\n style={styles.settingsButton}\n onPress={onOpenSettings}\n accessibilityRole=\"button\"\n >\n <Text style={styles.settingsText}>{settingsLabel}</Text>\n </TouchableOpacity>\n </View>\n </View>\n </Modal>\n );\n}\n\nconst styles = StyleSheet.create({\n overlay: {\n flex: 1,\n backgroundColor: \"rgba(0,0,0,0.5)\",\n justifyContent: \"center\",\n alignItems: \"center\",\n },\n modal: {\n backgroundColor: \"white\",\n borderRadius: 16,\n padding: 24,\n width: \"85%\",\n alignItems: \"center\",\n },\n title: {\n fontSize: 20,\n fontWeight: \"600\",\n marginBottom: 12,\n textAlign: \"center\",\n },\n message: {\n fontSize: 15,\n color: \"#666\",\n textAlign: \"center\",\n marginBottom: 24,\n lineHeight: 22,\n },\n settingsButton: {\n backgroundColor: \"#007AFF\",\n borderRadius: 12,\n paddingVertical: 14,\n paddingHorizontal: 32,\n width: \"100%\",\n alignItems: \"center\",\n },\n settingsText: {\n color: \"white\",\n fontSize: 16,\n fontWeight: \"600\",\n },\n});\n","import React from \"react\";\nimport { Modal, StyleSheet, Text, TouchableOpacity, View } from \"react-native\";\nimport type { PrePromptConfig } from \"../types\";\n\nexport interface DefaultPrePromptProps extends PrePromptConfig {\n visible: boolean;\n onConfirm: () => void;\n onCancel: () => void;\n}\n\nexport function DefaultPrePrompt({\n visible,\n title,\n message,\n confirmLabel = \"Continue\",\n cancelLabel = \"Not Now\",\n onConfirm,\n onCancel,\n}: DefaultPrePromptProps) {\n return (\n <Modal visible={visible} transparent animationType=\"fade\">\n <View style={styles.overlay}>\n <View style={styles.modal}>\n <Text style={styles.title}>{title}</Text>\n <Text style={styles.message}>{message}</Text>\n <TouchableOpacity\n style={styles.confirmButton}\n onPress={onConfirm}\n accessibilityRole=\"button\"\n >\n <Text style={styles.confirmText}>{confirmLabel}</Text>\n </TouchableOpacity>\n <TouchableOpacity onPress={onCancel} accessibilityRole=\"button\">\n <Text style={styles.cancelText}>{cancelLabel}</Text>\n </TouchableOpacity>\n </View>\n </View>\n </Modal>\n );\n}\n\nconst styles = StyleSheet.create({\n overlay: {\n flex: 1,\n backgroundColor: \"rgba(0,0,0,0.5)\",\n justifyContent: \"center\",\n alignItems: \"center\",\n },\n modal: {\n backgroundColor: \"white\",\n borderRadius: 16,\n padding: 24,\n width: \"85%\",\n alignItems: \"center\",\n },\n title: {\n fontSize: 20,\n fontWeight: \"600\",\n marginBottom: 12,\n textAlign: \"center\",\n },\n message: {\n fontSize: 15,\n color: \"#666\",\n textAlign: \"center\",\n marginBottom: 24,\n lineHeight: 22,\n },\n confirmButton: {\n backgroundColor: \"#007AFF\",\n borderRadius: 12,\n paddingVertical: 14,\n paddingHorizontal: 32,\n width: \"100%\",\n alignItems: \"center\",\n marginBottom: 12,\n },\n confirmText: {\n color: \"white\",\n fontSize: 16,\n fontWeight: \"600\",\n },\n cancelText: {\n color: \"#007AFF\",\n fontSize: 15,\n },\n});\n","import React from \"react\";\nimport type { ReactNode } from \"react\";\nimport { usePermissionHandler } from \"../hooks/use-permission-handler\";\nimport type {\n BlockedPromptConfig,\n PermissionCallbacks,\n PermissionEngine,\n PrePromptConfig,\n} from \"../types\";\nimport { DefaultBlockedPrompt } from \"./default-blocked-prompt\";\nimport { DefaultPrePrompt } from \"./default-pre-prompt\";\n\nexport interface PermissionGateProps extends PermissionCallbacks {\n permission: string;\n engine?: PermissionEngine;\n prePrompt: PrePromptConfig;\n blockedPrompt: BlockedPromptConfig;\n children: ReactNode;\n fallback?: ReactNode;\n renderPrePrompt?: (props: {\n config: PrePromptConfig;\n onConfirm: () => void;\n onCancel: () => void;\n }) => ReactNode;\n renderBlockedPrompt?: (props: {\n config: BlockedPromptConfig;\n onOpenSettings: () => void;\n }) => ReactNode;\n}\n\nexport function PermissionGate({\n permission,\n engine,\n prePrompt,\n blockedPrompt,\n children,\n fallback = null,\n renderPrePrompt,\n renderBlockedPrompt,\n onGrant,\n onDeny,\n onBlock,\n onSettingsReturn,\n}: PermissionGateProps) {\n const handler = usePermissionHandler({\n permission,\n engine,\n prePrompt,\n blockedPrompt,\n onGrant,\n onDeny,\n onBlock,\n onSettingsReturn,\n });\n\n if (handler.isGranted) {\n return <>{children}</>;\n }\n\n if (handler.isChecking || handler.isUnavailable) {\n return <>{fallback}</>;\n }\n\n if (handler.state === \"prePrompt\") {\n if (renderPrePrompt) {\n return (\n <>\n {renderPrePrompt({\n config: prePrompt,\n onConfirm: handler.request,\n onCancel: handler.dismiss,\n })}\n </>\n );\n }\n return (\n <DefaultPrePrompt\n visible\n title={prePrompt.title}\n message={prePrompt.message}\n confirmLabel={prePrompt.confirmLabel}\n cancelLabel={prePrompt.cancelLabel}\n onConfirm={handler.request}\n onCancel={handler.dismiss}\n />\n );\n }\n\n if (handler.state === \"blockedPrompt\") {\n if (renderBlockedPrompt) {\n return (\n <>\n {renderBlockedPrompt({\n config: blockedPrompt,\n onOpenSettings: handler.openSettings,\n })}\n </>\n );\n }\n return (\n <DefaultBlockedPrompt\n visible\n title={blockedPrompt.title}\n message={blockedPrompt.message}\n settingsLabel={blockedPrompt.settingsLabel}\n onOpenSettings={handler.openSettings}\n />\n );\n }\n\n return <>{fallback}</>;\n}\n"],"mappings":"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","names":["import_react_native","createRNPEngine","import_react","import_react_native","import_react_native","import_jsx_runtime","styles","import_jsx_runtime"]}
|
|
1
|
+
{"version":3,"sources":["../src/engines/rnp.ts","../src/index.ts","../src/engines/resolve.ts","../src/core/state-machine.ts","../src/hooks/use-permission-handler.ts","../src/core/debug-logger.ts","../src/core/with-timeout.ts","../src/engines/rnp-fallback.ts","../src/engines/use-engine.ts","../src/hooks/use-multiple-permissions.ts","../src/components/default-blocked-prompt.tsx","../src/components/default-pre-prompt.tsx","../src/components/permission-gate.tsx"],"sourcesContent":["import { Platform } from \"react-native\";\nimport {\n type Permission,\n check,\n checkNotifications,\n openSettings,\n request,\n requestNotifications,\n} from \"react-native-permissions\";\nimport type { PermissionEngine, PermissionStatus } from \"../types\";\n\nfunction p(ios: string, android: string): string {\n return Platform.select({ ios, android, default: ios }) ?? ios;\n}\n\n/**\n * Cross-platform permission constants for use with the RNP engine.\n * Each resolves to the correct platform-specific string at runtime.\n */\nexport const Permissions = {\n CAMERA: p(\"ios.permission.CAMERA\", \"android.permission.CAMERA\"),\n MICROPHONE: p(\"ios.permission.MICROPHONE\", \"android.permission.RECORD_AUDIO\"),\n CONTACTS: p(\"ios.permission.CONTACTS\", \"android.permission.READ_CONTACTS\"),\n CALENDARS: p(\"ios.permission.CALENDARS\", \"android.permission.READ_CALENDAR\"),\n CALENDARS_WRITE_ONLY: p(\n \"ios.permission.CALENDARS_WRITE_ONLY\",\n \"android.permission.WRITE_CALENDAR\",\n ),\n LOCATION_WHEN_IN_USE: p(\n \"ios.permission.LOCATION_WHEN_IN_USE\",\n \"android.permission.ACCESS_FINE_LOCATION\",\n ),\n LOCATION_ALWAYS: p(\n \"ios.permission.LOCATION_ALWAYS\",\n \"android.permission.ACCESS_BACKGROUND_LOCATION\",\n ),\n PHOTO_LIBRARY: p(\"ios.permission.PHOTO_LIBRARY\", \"android.permission.READ_MEDIA_IMAGES\"),\n PHOTO_LIBRARY_ADD_ONLY: p(\n \"ios.permission.PHOTO_LIBRARY_ADD_ONLY\",\n \"android.permission.WRITE_EXTERNAL_STORAGE\",\n ),\n BLUETOOTH: p(\"ios.permission.BLUETOOTH\", \"android.permission.BLUETOOTH_CONNECT\"),\n NOTIFICATIONS: \"notifications\",\n} as const;\n\nexport function createRNPEngine(): PermissionEngine {\n return {\n async check(permission: string): Promise<PermissionStatus> {\n if (permission === \"notifications\") {\n const result = await checkNotifications();\n return result.status as PermissionStatus;\n }\n return (await check(permission as Permission)) as PermissionStatus;\n },\n\n async request(permission: string): Promise<PermissionStatus> {\n if (permission === \"notifications\") {\n const result = await requestNotifications([\"alert\", \"badge\", \"sound\"]);\n return result.status as PermissionStatus;\n }\n return (await request(permission as Permission)) as PermissionStatus;\n },\n\n async openSettings(): Promise<void> {\n await openSettings();\n },\n };\n}\n","export type {\n BlockedPromptConfig,\n MultiPermissionEntry,\n MultiplePermissionsConfig,\n MultiplePermissionsResult,\n PermissionCallbacks,\n PermissionEngine,\n PermissionFlowEvent,\n PermissionFlowState,\n PermissionHandlerConfig,\n PermissionHandlerResult,\n PermissionStatus,\n PrePromptConfig,\n} from \"./types\";\n\nexport { setDefaultEngine } from \"./engines/resolve\";\nexport { transition } from \"./core/state-machine\";\nexport { usePermissionHandler } from \"./hooks/use-permission-handler\";\nexport { useMultiplePermissions } from \"./hooks/use-multiple-permissions\";\nexport { PermissionGate } from \"./components/permission-gate\";\nexport type { PermissionGateProps } from \"./components/permission-gate\";\nexport { DefaultPrePrompt } from \"./components/default-pre-prompt\";\nexport type { DefaultPrePromptProps } from \"./components/default-pre-prompt\";\nexport { DefaultBlockedPrompt } from \"./components/default-blocked-prompt\";\nexport type { DefaultBlockedPromptProps } from \"./components/default-blocked-prompt\";\n","import type { PermissionEngine } from \"../types\";\n\nlet defaultEngine: PermissionEngine | null = null;\n\nexport function setDefaultEngine(engine: PermissionEngine): void {\n defaultEngine = engine;\n}\n\nexport function getDefaultEngine(): PermissionEngine | null {\n return defaultEngine;\n}\n","import type { PermissionFlowEvent, PermissionFlowState } from \"../types\";\n\nexport function transition(\n state: PermissionFlowState,\n event: PermissionFlowEvent,\n): PermissionFlowState {\n switch (state) {\n case \"idle\":\n if (event.type === \"CHECK\") return \"checking\";\n return state;\n\n case \"checking\":\n if (event.type === \"CHECK_RESULT\") {\n switch (event.status) {\n case \"granted\":\n case \"limited\":\n return \"granted\";\n case \"denied\":\n return \"prePrompt\";\n case \"blocked\":\n return \"blockedPrompt\";\n case \"unavailable\":\n return \"unavailable\";\n default:\n return state;\n }\n }\n return state;\n\n case \"prePrompt\":\n if (event.type === \"PRE_PROMPT_CONFIRM\") return \"requesting\";\n if (event.type === \"PRE_PROMPT_DISMISS\") return \"denied\";\n return state;\n\n case \"requesting\":\n if (event.type === \"REQUEST_RESULT\") {\n switch (event.status) {\n case \"granted\":\n case \"limited\":\n return \"granted\";\n case \"denied\":\n return \"denied\";\n case \"blocked\":\n return \"blockedPrompt\";\n default:\n return state;\n }\n }\n return state;\n\n case \"blockedPrompt\":\n if (event.type === \"OPEN_SETTINGS\") return \"openingSettings\";\n return state;\n\n case \"openingSettings\":\n if (event.type === \"SETTINGS_RETURN\") return \"recheckingAfterSettings\";\n return state;\n\n case \"recheckingAfterSettings\":\n if (event.type === \"RECHECK_RESULT\") {\n switch (event.status) {\n case \"granted\":\n case \"limited\":\n return \"granted\";\n case \"blocked\":\n return \"blockedPrompt\";\n case \"denied\":\n return \"blockedPrompt\";\n default:\n return state;\n }\n }\n return state;\n\n case \"granted\":\n case \"denied\":\n case \"unavailable\":\n if (event.type === \"CHECK\") return \"checking\";\n return state;\n\n case \"blocked\":\n return state;\n\n default:\n return state;\n }\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\nimport { AppState } from \"react-native\";\nimport { createDebugLogger } from \"../core/debug-logger\";\nimport { transition } from \"../core/state-machine\";\nimport { PermissionTimeoutError, withTimeout } from \"../core/with-timeout\";\nimport { resolveEngine } from \"../engines/use-engine\";\nimport type {\n PermissionFlowState,\n PermissionHandlerConfig,\n PermissionHandlerResult,\n PermissionStatus,\n} from \"../types\";\n\nexport function usePermissionHandler(config: PermissionHandlerConfig): PermissionHandlerResult {\n const engine = resolveEngine(config.engine);\n const [flowState, setFlowState] = useState<PermissionFlowState>(\"idle\");\n const [nativeStatus, setNativeStatus] = useState<PermissionStatus | null>(null);\n const isRequesting = useRef(false);\n const waitingForSettings = useRef(false);\n const appStateRef = useRef(AppState.currentState);\n\n const {\n permission,\n autoCheck = true,\n requestTimeout,\n onTimeout,\n debug,\n onGrant,\n onDeny,\n onBlock,\n onSettingsReturn,\n } = config;\n\n const logger = createDebugLogger(debug, permission);\n\n const checkPermission = useCallback(async () => {\n setFlowState((s) => {\n const next = transition(s, { type: \"CHECK\" });\n logger.transition(s, next, \"CHECK\");\n return next;\n });\n try {\n const status = await engine.check(permission);\n setNativeStatus(status);\n setFlowState((s) => {\n const next = transition(s, { type: \"CHECK_RESULT\", status });\n logger.transition(s, next, `CHECK_RESULT:${status}`);\n if (next === \"granted\" && s !== \"granted\") onGrant?.();\n return next;\n });\n } catch {\n setFlowState(\"idle\");\n }\n }, [engine, permission, logger, onGrant]);\n\n const requestPermission = useCallback(async () => {\n if (isRequesting.current) return;\n isRequesting.current = true;\n\n setFlowState((s) => {\n const next = transition(s, { type: \"PRE_PROMPT_CONFIRM\" });\n logger.transition(s, next, \"PRE_PROMPT_CONFIRM\");\n return next;\n });\n try {\n const requestPromise = engine.request(permission);\n const status = requestTimeout\n ? await withTimeout(requestPromise, requestTimeout, permission)\n : await requestPromise;\n setNativeStatus(status);\n setFlowState((s) => {\n const next = transition(s, { type: \"REQUEST_RESULT\", status });\n logger.transition(s, next, `REQUEST_RESULT:${status}`);\n if (next === \"granted\") onGrant?.();\n if (next === \"denied\") onDeny?.();\n if (next === \"blockedPrompt\") onBlock?.();\n return next;\n });\n } catch (err) {\n if (err instanceof PermissionTimeoutError) {\n logger.info(`request timed out after ${requestTimeout}ms`);\n onTimeout?.();\n setFlowState(\"blockedPrompt\");\n } else {\n setFlowState(\"denied\");\n }\n } finally {\n isRequesting.current = false;\n }\n }, [engine, permission, requestTimeout, onTimeout, logger, onGrant, onDeny, onBlock]);\n\n const dismiss = useCallback(() => {\n setFlowState((s) => {\n const next = transition(s, { type: \"PRE_PROMPT_DISMISS\" });\n logger.transition(s, next, \"PRE_PROMPT_DISMISS\");\n return next;\n });\n onDeny?.();\n }, [logger, onDeny]);\n\n const goToSettings = useCallback(async () => {\n setFlowState((s) => {\n const next = transition(s, { type: \"OPEN_SETTINGS\" });\n logger.transition(s, next, \"OPEN_SETTINGS\");\n return next;\n });\n waitingForSettings.current = true;\n try {\n await engine.openSettings();\n } catch {\n waitingForSettings.current = false;\n setFlowState(\"blockedPrompt\");\n }\n }, [engine, logger]);\n\n const recheckAfterSettings = useCallback(async () => {\n setFlowState((s) => {\n const next = transition(s, { type: \"SETTINGS_RETURN\" });\n logger.transition(s, next, \"SETTINGS_RETURN\");\n return next;\n });\n try {\n const status = await engine.check(permission);\n setNativeStatus(status);\n setFlowState((s) => {\n const next = transition(s, { type: \"RECHECK_RESULT\", status });\n logger.transition(s, next, `RECHECK_RESULT:${status}`);\n if (next === \"granted\") onGrant?.();\n onSettingsReturn?.(next === \"granted\");\n return next;\n });\n } catch {\n setFlowState(\"blockedPrompt\");\n }\n }, [engine, permission, logger, onGrant, onSettingsReturn]);\n\n // Auto-check on mount\n // biome-ignore lint/correctness/useExhaustiveDependencies: intentional mount-only effect\n useEffect(() => {\n if (autoCheck) {\n checkPermission();\n }\n }, []);\n\n // AppState listener for settings return\n useEffect(() => {\n const subscription = AppState.addEventListener(\"change\", (nextAppState) => {\n if (\n appStateRef.current.match(/inactive|background/) &&\n nextAppState === \"active\" &&\n waitingForSettings.current\n ) {\n waitingForSettings.current = false;\n recheckAfterSettings();\n }\n appStateRef.current = nextAppState;\n });\n return () => subscription.remove();\n }, [recheckAfterSettings]);\n\n return {\n state: flowState,\n nativeStatus,\n isGranted: flowState === \"granted\",\n isDenied: flowState === \"denied\",\n isBlocked:\n flowState === \"blocked\" || flowState === \"blockedPrompt\" || flowState === \"openingSettings\",\n isChecking: flowState === \"checking\" || flowState === \"recheckingAfterSettings\",\n isUnavailable: flowState === \"unavailable\",\n request: requestPermission,\n check: checkPermission,\n dismiss,\n openSettings: goToSettings,\n };\n}\n","const PREFIX = \"[permission-handler]\";\n\ninterface DebugLogger {\n transition(from: string, to: string, event?: string): void;\n info(msg: string): void;\n}\n\nconst NOOP_LOGGER: DebugLogger = {\n transition: () => {},\n info: () => {},\n};\n\nexport function createDebugLogger(\n debug: boolean | ((msg: string) => void) | undefined,\n permission: string,\n): DebugLogger {\n if (!debug) return NOOP_LOGGER;\n\n const log = typeof debug === \"function\" ? debug : (msg: string) => console.log(msg);\n\n return {\n transition(from: string, to: string, event?: string) {\n log(`${PREFIX} ${permission}: ${from} → ${to}${event ? ` (${event})` : \"\"}`);\n },\n info(msg: string) {\n log(`${PREFIX} ${permission}: ${msg}`);\n },\n };\n}\n","export class PermissionTimeoutError extends Error {\n readonly permission: string;\n readonly timeoutMs: number;\n\n constructor(permission: string, timeoutMs: number) {\n super(`Permission request for \"${permission}\" timed out after ${timeoutMs}ms`);\n this.name = \"PermissionTimeoutError\";\n this.permission = permission;\n this.timeoutMs = timeoutMs;\n }\n}\n\nexport function withTimeout<T>(\n promise: Promise<T>,\n timeoutMs: number,\n permission: string,\n): Promise<T> {\n return new Promise((resolve, reject) => {\n const timer = setTimeout(\n () => reject(new PermissionTimeoutError(permission, timeoutMs)),\n timeoutMs,\n );\n promise.then(\n (val) => {\n clearTimeout(timer);\n resolve(val);\n },\n (err) => {\n clearTimeout(timer);\n reject(err);\n },\n );\n });\n}\n","import type { PermissionEngine } from \"../types\";\n\nlet cachedFallback: PermissionEngine | null = null;\n\nexport function getRNPFallbackEngine(): PermissionEngine {\n if (cachedFallback) return cachedFallback;\n\n try {\n // Dynamic require to avoid hard dependency — only resolves if\n // react-native-permissions is installed by the consumer.\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const mod = require(\"./rnp\") as { createRNPEngine: () => PermissionEngine };\n const { createRNPEngine } = mod;\n cachedFallback = createRNPEngine();\n return cachedFallback;\n } catch {\n throw new Error(\n \"react-native-permission-handler: No permission engine configured. \" +\n \"Either pass an `engine` in your hook config, call setDefaultEngine(), \" +\n \"or install react-native-permissions as a peer dependency.\",\n );\n }\n}\n","import type { PermissionEngine } from \"../types\";\nimport { getDefaultEngine } from \"./resolve\";\nimport { getRNPFallbackEngine } from \"./rnp-fallback\";\n\nexport function resolveEngine(configEngine?: PermissionEngine): PermissionEngine {\n if (configEngine) return configEngine;\n const global = getDefaultEngine();\n if (global) return global;\n return getRNPFallbackEngine();\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\nimport { createDebugLogger } from \"../core/debug-logger\";\nimport { PermissionTimeoutError, withTimeout } from \"../core/with-timeout\";\nimport { resolveEngine } from \"../engines/use-engine\";\nimport type {\n MultiPermissionEntry,\n MultiplePermissionsConfig,\n MultiplePermissionsResult,\n PermissionEngine,\n PermissionFlowState,\n PermissionStatus,\n} from \"../types\";\n\nfunction permissionKey(entry: MultiPermissionEntry): string {\n return String(entry.permission);\n}\n\nfunction isGrantedStatus(status: PermissionStatus): boolean {\n return status === \"granted\" || status === \"limited\";\n}\n\nfunction statusToFlowState(status: PermissionStatus): PermissionFlowState {\n switch (status) {\n case \"granted\":\n case \"limited\":\n return \"granted\";\n case \"blocked\":\n return \"blockedPrompt\";\n case \"unavailable\":\n return \"unavailable\";\n case \"denied\":\n return \"prePrompt\";\n default:\n return \"idle\";\n }\n}\n\nexport function useMultiplePermissions(\n config: MultiplePermissionsConfig,\n): MultiplePermissionsResult {\n const engine = resolveEngine(config.engine);\n const {\n permissions,\n strategy,\n autoCheck = true,\n requestTimeout,\n onTimeout,\n debug,\n onAllGranted,\n } = config;\n const logger = createDebugLogger(debug, \"multi\");\n const [statuses, setStatuses] = useState<Record<string, PermissionFlowState>>(() => {\n const initial: Record<string, PermissionFlowState> = {};\n for (const entry of permissions) {\n initial[permissionKey(entry)] = \"idle\";\n }\n return initial;\n });\n const isRunning = useRef(false);\n\n const allGranted = permissions.every((entry) => statuses[permissionKey(entry)] === \"granted\");\n\n const requestAll = useCallback(async () => {\n if (isRunning.current) return;\n isRunning.current = true;\n\n const update = (key: string, state: PermissionFlowState) => {\n setStatuses((prev) => {\n logger.transition(prev[key] ?? \"idle\", state, key);\n return { ...prev, [key]: state };\n });\n };\n\n try {\n if (strategy === \"sequential\") {\n await runSequential(permissions, engine, update, requestTimeout, onTimeout);\n } else {\n await runParallel(permissions, engine, update, requestTimeout, onTimeout);\n }\n\n // Final check: are all granted?\n let allDone = true;\n for (const entry of permissions) {\n const finalStatus = await engine.check(entry.permission);\n if (!isGrantedStatus(finalStatus)) {\n allDone = false;\n break;\n }\n }\n if (allDone) {\n onAllGranted?.();\n }\n } finally {\n isRunning.current = false;\n }\n }, [permissions, strategy, engine, requestTimeout, onTimeout, logger, onAllGranted]);\n\n // Auto-check on mount\n // biome-ignore lint/correctness/useExhaustiveDependencies: intentional mount-only effect\n useEffect(() => {\n if (!autoCheck) return;\n\n let cancelled = false;\n async function checkAll() {\n for (const entry of permissions) {\n const key = permissionKey(entry);\n const status = await engine.check(entry.permission);\n if (cancelled) return;\n setStatuses((prev) => ({ ...prev, [key]: statusToFlowState(status) }));\n }\n }\n checkAll();\n return () => {\n cancelled = true;\n };\n }, []);\n\n return {\n statuses,\n allGranted,\n request: requestAll,\n };\n}\n\nasync function runSequential(\n permissions: MultiPermissionEntry[],\n engine: PermissionEngine,\n updateStatus: (key: string, state: PermissionFlowState) => void,\n requestTimeout?: number,\n onTimeout?: () => void,\n): Promise<void> {\n for (const entry of permissions) {\n const key = permissionKey(entry);\n\n updateStatus(key, \"checking\");\n const checkStatus = await engine.check(entry.permission);\n\n if (isGrantedStatus(checkStatus)) {\n updateStatus(key, \"granted\");\n entry.onGrant?.();\n continue;\n }\n\n if (checkStatus === \"unavailable\") {\n updateStatus(key, \"unavailable\");\n continue;\n }\n\n if (checkStatus === \"blocked\") {\n updateStatus(key, \"blockedPrompt\");\n entry.onBlock?.();\n break;\n }\n\n // Denied — request it\n updateStatus(key, \"requesting\");\n try {\n const requestPromise = engine.request(entry.permission);\n const requestStatus = requestTimeout\n ? await withTimeout(requestPromise, requestTimeout, entry.permission)\n : await requestPromise;\n\n if (isGrantedStatus(requestStatus)) {\n updateStatus(key, \"granted\");\n entry.onGrant?.();\n } else if (requestStatus === \"blocked\") {\n updateStatus(key, \"blockedPrompt\");\n entry.onBlock?.();\n break;\n } else {\n updateStatus(key, \"denied\");\n entry.onDeny?.();\n break;\n }\n } catch (err) {\n if (err instanceof PermissionTimeoutError) {\n onTimeout?.();\n updateStatus(key, \"blockedPrompt\");\n break;\n }\n throw err;\n }\n }\n}\n\nasync function runParallel(\n permissions: MultiPermissionEntry[],\n engine: PermissionEngine,\n updateStatus: (key: string, state: PermissionFlowState) => void,\n requestTimeout?: number,\n onTimeout?: () => void,\n): Promise<void> {\n // Check all in parallel\n const checkResults = await Promise.all(\n permissions.map(async (entry) => {\n const key = permissionKey(entry);\n updateStatus(key, \"checking\");\n const status = await engine.check(entry.permission);\n return { entry, key, status };\n }),\n );\n\n // Update granted/unavailable immediately\n for (const { entry, key, status } of checkResults) {\n if (isGrantedStatus(status)) {\n updateStatus(key, \"granted\");\n entry.onGrant?.();\n } else if (status === \"unavailable\") {\n updateStatus(key, \"unavailable\");\n }\n }\n\n // Request denied/blocked ones sequentially (system dialogs are sequential)\n const needsAction = checkResults.filter(\n ({ status }) => status === \"denied\" || status === \"blocked\",\n );\n\n for (const { entry, key, status } of needsAction) {\n if (status === \"blocked\") {\n updateStatus(key, \"blockedPrompt\");\n entry.onBlock?.();\n continue;\n }\n\n updateStatus(key, \"requesting\");\n try {\n const requestPromise = engine.request(entry.permission);\n const requestStatus = requestTimeout\n ? await withTimeout(requestPromise, requestTimeout, entry.permission)\n : await requestPromise;\n\n if (isGrantedStatus(requestStatus)) {\n updateStatus(key, \"granted\");\n entry.onGrant?.();\n } else if (requestStatus === \"blocked\") {\n updateStatus(key, \"blockedPrompt\");\n entry.onBlock?.();\n } else {\n updateStatus(key, \"denied\");\n entry.onDeny?.();\n }\n } catch (err) {\n if (err instanceof PermissionTimeoutError) {\n onTimeout?.();\n updateStatus(key, \"blockedPrompt\");\n } else {\n throw err;\n }\n }\n }\n}\n","import React from \"react\";\nimport { Modal, StyleSheet, Text, TouchableOpacity, View } from \"react-native\";\nimport type { BlockedPromptConfig } from \"../types\";\n\nexport interface DefaultBlockedPromptProps extends BlockedPromptConfig {\n visible: boolean;\n onOpenSettings: () => void;\n}\n\nexport function DefaultBlockedPrompt({\n visible,\n title,\n message,\n settingsLabel = \"Open Settings\",\n onOpenSettings,\n}: DefaultBlockedPromptProps) {\n return (\n <Modal visible={visible} transparent animationType=\"fade\">\n <View style={styles.overlay}>\n <View style={styles.modal}>\n <Text style={styles.title}>{title}</Text>\n <Text style={styles.message}>{message}</Text>\n <TouchableOpacity\n style={styles.settingsButton}\n onPress={onOpenSettings}\n accessibilityRole=\"button\"\n >\n <Text style={styles.settingsText}>{settingsLabel}</Text>\n </TouchableOpacity>\n </View>\n </View>\n </Modal>\n );\n}\n\nconst styles = StyleSheet.create({\n overlay: {\n flex: 1,\n backgroundColor: \"rgba(0,0,0,0.5)\",\n justifyContent: \"center\",\n alignItems: \"center\",\n },\n modal: {\n backgroundColor: \"white\",\n borderRadius: 16,\n padding: 24,\n width: \"85%\",\n alignItems: \"center\",\n },\n title: {\n fontSize: 20,\n fontWeight: \"600\",\n marginBottom: 12,\n textAlign: \"center\",\n },\n message: {\n fontSize: 15,\n color: \"#666\",\n textAlign: \"center\",\n marginBottom: 24,\n lineHeight: 22,\n },\n settingsButton: {\n backgroundColor: \"#007AFF\",\n borderRadius: 12,\n paddingVertical: 14,\n paddingHorizontal: 32,\n width: \"100%\",\n alignItems: \"center\",\n },\n settingsText: {\n color: \"white\",\n fontSize: 16,\n fontWeight: \"600\",\n },\n});\n","import React from \"react\";\nimport { Modal, StyleSheet, Text, TouchableOpacity, View } from \"react-native\";\nimport type { PrePromptConfig } from \"../types\";\n\nexport interface DefaultPrePromptProps extends PrePromptConfig {\n visible: boolean;\n onConfirm: () => void;\n onCancel: () => void;\n}\n\nexport function DefaultPrePrompt({\n visible,\n title,\n message,\n confirmLabel = \"Continue\",\n cancelLabel = \"Not Now\",\n onConfirm,\n onCancel,\n}: DefaultPrePromptProps) {\n return (\n <Modal visible={visible} transparent animationType=\"fade\">\n <View style={styles.overlay}>\n <View style={styles.modal}>\n <Text style={styles.title}>{title}</Text>\n <Text style={styles.message}>{message}</Text>\n <TouchableOpacity\n style={styles.confirmButton}\n onPress={onConfirm}\n accessibilityRole=\"button\"\n >\n <Text style={styles.confirmText}>{confirmLabel}</Text>\n </TouchableOpacity>\n <TouchableOpacity onPress={onCancel} accessibilityRole=\"button\">\n <Text style={styles.cancelText}>{cancelLabel}</Text>\n </TouchableOpacity>\n </View>\n </View>\n </Modal>\n );\n}\n\nconst styles = StyleSheet.create({\n overlay: {\n flex: 1,\n backgroundColor: \"rgba(0,0,0,0.5)\",\n justifyContent: \"center\",\n alignItems: \"center\",\n },\n modal: {\n backgroundColor: \"white\",\n borderRadius: 16,\n padding: 24,\n width: \"85%\",\n alignItems: \"center\",\n },\n title: {\n fontSize: 20,\n fontWeight: \"600\",\n marginBottom: 12,\n textAlign: \"center\",\n },\n message: {\n fontSize: 15,\n color: \"#666\",\n textAlign: \"center\",\n marginBottom: 24,\n lineHeight: 22,\n },\n confirmButton: {\n backgroundColor: \"#007AFF\",\n borderRadius: 12,\n paddingVertical: 14,\n paddingHorizontal: 32,\n width: \"100%\",\n alignItems: \"center\",\n marginBottom: 12,\n },\n confirmText: {\n color: \"white\",\n fontSize: 16,\n fontWeight: \"600\",\n },\n cancelText: {\n color: \"#007AFF\",\n fontSize: 15,\n },\n});\n","import React from \"react\";\nimport type { ReactNode } from \"react\";\nimport { usePermissionHandler } from \"../hooks/use-permission-handler\";\nimport type {\n BlockedPromptConfig,\n PermissionCallbacks,\n PermissionEngine,\n PrePromptConfig,\n} from \"../types\";\nimport { DefaultBlockedPrompt } from \"./default-blocked-prompt\";\nimport { DefaultPrePrompt } from \"./default-pre-prompt\";\n\nexport interface PermissionGateProps extends PermissionCallbacks {\n permission: string;\n engine?: PermissionEngine;\n prePrompt: PrePromptConfig;\n blockedPrompt: BlockedPromptConfig;\n children: ReactNode;\n fallback?: ReactNode;\n renderPrePrompt?: (props: {\n config: PrePromptConfig;\n onConfirm: () => void;\n onCancel: () => void;\n }) => ReactNode;\n renderBlockedPrompt?: (props: {\n config: BlockedPromptConfig;\n onOpenSettings: () => void;\n }) => ReactNode;\n}\n\nexport function PermissionGate({\n permission,\n engine,\n prePrompt,\n blockedPrompt,\n children,\n fallback = null,\n renderPrePrompt,\n renderBlockedPrompt,\n onGrant,\n onDeny,\n onBlock,\n onSettingsReturn,\n}: PermissionGateProps) {\n const handler = usePermissionHandler({\n permission,\n engine,\n prePrompt,\n blockedPrompt,\n onGrant,\n onDeny,\n onBlock,\n onSettingsReturn,\n });\n\n if (handler.isGranted) {\n return <>{children}</>;\n }\n\n if (handler.isChecking || handler.isUnavailable) {\n return <>{fallback}</>;\n }\n\n if (handler.state === \"prePrompt\") {\n if (renderPrePrompt) {\n return (\n <>\n {renderPrePrompt({\n config: prePrompt,\n onConfirm: handler.request,\n onCancel: handler.dismiss,\n })}\n </>\n );\n }\n return (\n <DefaultPrePrompt\n visible\n title={prePrompt.title}\n message={prePrompt.message}\n confirmLabel={prePrompt.confirmLabel}\n cancelLabel={prePrompt.cancelLabel}\n onConfirm={handler.request}\n onCancel={handler.dismiss}\n />\n );\n }\n\n if (handler.state === \"blockedPrompt\") {\n if (renderBlockedPrompt) {\n return (\n <>\n {renderBlockedPrompt({\n config: blockedPrompt,\n onOpenSettings: handler.openSettings,\n })}\n </>\n );\n }\n return (\n <DefaultBlockedPrompt\n visible\n title={blockedPrompt.title}\n message={blockedPrompt.message}\n settingsLabel={blockedPrompt.settingsLabel}\n onOpenSettings={handler.openSettings}\n />\n );\n }\n\n return <>{fallback}</>;\n}\n"],"mappings":"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","names":["import_react_native","createRNPEngine","import_react","import_react_native","import_react_native","import_jsx_runtime","styles","import_jsx_runtime"]}
|