react-native-permission-handler 0.2.0 → 0.2.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 +29 -6
- package/dist/chunk-EU3KPRTI.mjs +81 -0
- package/dist/chunk-EU3KPRTI.mjs.map +1 -0
- package/dist/engines/rnp.d.mts +18 -1
- package/dist/engines/rnp.d.ts +18 -1
- package/dist/engines/rnp.js +31 -0
- package/dist/engines/rnp.js.map +1 -1
- package/dist/engines/rnp.mjs +3 -1
- package/dist/index.js +49 -19
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
- package/src/engines/rnp.test.ts +27 -1
- package/src/engines/rnp.ts +35 -0
- package/dist/chunk-WZJOIVOM.mjs +0 -49
- package/dist/chunk-WZJOIVOM.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -26,11 +26,11 @@ npm install react-native-permissions
|
|
|
26
26
|
|
|
27
27
|
```tsx
|
|
28
28
|
import { usePermissionHandler } from "react-native-permission-handler";
|
|
29
|
-
import {
|
|
29
|
+
import { Permissions } from "react-native-permission-handler/rnp";
|
|
30
30
|
|
|
31
31
|
function QRScannerScreen() {
|
|
32
32
|
const camera = usePermissionHandler({
|
|
33
|
-
permission:
|
|
33
|
+
permission: Permissions.CAMERA,
|
|
34
34
|
prePrompt: {
|
|
35
35
|
title: "Camera Access",
|
|
36
36
|
message: "We need your camera to scan QR codes.",
|
|
@@ -239,7 +239,7 @@ The main hook. Manages the full permission lifecycle.
|
|
|
239
239
|
```tsx
|
|
240
240
|
function CameraScreen() {
|
|
241
241
|
const camera = usePermissionHandler({
|
|
242
|
-
permission:
|
|
242
|
+
permission: Permissions.CAMERA,
|
|
243
243
|
prePrompt: {
|
|
244
244
|
title: "Camera Access",
|
|
245
245
|
message: "We need your camera to scan QR codes.",
|
|
@@ -323,12 +323,12 @@ function VideoCallScreen() {
|
|
|
323
323
|
const perms = useMultiplePermissions({
|
|
324
324
|
permissions: [
|
|
325
325
|
{
|
|
326
|
-
permission:
|
|
326
|
+
permission: Permissions.CAMERA,
|
|
327
327
|
prePrompt: { title: "Camera", message: "Needed for video." },
|
|
328
328
|
blockedPrompt: { title: "Camera Blocked", message: "Enable in Settings." },
|
|
329
329
|
},
|
|
330
330
|
{
|
|
331
|
-
permission:
|
|
331
|
+
permission: Permissions.MICROPHONE,
|
|
332
332
|
prePrompt: { title: "Microphone", message: "Needed for audio." },
|
|
333
333
|
blockedPrompt: { title: "Mic Blocked", message: "Enable in Settings." },
|
|
334
334
|
},
|
|
@@ -381,7 +381,7 @@ Declarative component that renders children only when permission is granted.
|
|
|
381
381
|
|
|
382
382
|
```tsx
|
|
383
383
|
<PermissionGate
|
|
384
|
-
permission={
|
|
384
|
+
permission={Permissions.CAMERA}
|
|
385
385
|
prePrompt={{ title: "Camera", message: "We need camera access." }}
|
|
386
386
|
blockedPrompt={{ title: "Blocked", message: "Enable in Settings." }}
|
|
387
387
|
fallback={<LoadingSpinner />}
|
|
@@ -464,6 +464,29 @@ You don't need to call this explicitly if `react-native-permissions` is installe
|
|
|
464
464
|
|
|
465
465
|
---
|
|
466
466
|
|
|
467
|
+
### `Permissions` (cross-platform constants)
|
|
468
|
+
|
|
469
|
+
The RNP entry point also exports cross-platform permission constants that resolve to the correct platform-specific string via `Platform.select`:
|
|
470
|
+
|
|
471
|
+
```typescript
|
|
472
|
+
import { Permissions } from "react-native-permission-handler/rnp";
|
|
473
|
+
|
|
474
|
+
Permissions.CAMERA // ios: "ios.permission.CAMERA", android: "android.permission.CAMERA"
|
|
475
|
+
Permissions.MICROPHONE // ios: "ios.permission.MICROPHONE", android: "android.permission.RECORD_AUDIO"
|
|
476
|
+
Permissions.CONTACTS // ios: "ios.permission.CONTACTS", android: "android.permission.READ_CONTACTS"
|
|
477
|
+
Permissions.CALENDARS // ios: "ios.permission.CALENDARS", android: "android.permission.READ_CALENDAR"
|
|
478
|
+
Permissions.LOCATION_WHEN_IN_USE
|
|
479
|
+
Permissions.LOCATION_ALWAYS
|
|
480
|
+
Permissions.PHOTO_LIBRARY
|
|
481
|
+
Permissions.PHOTO_LIBRARY_ADD_ONLY
|
|
482
|
+
Permissions.BLUETOOTH
|
|
483
|
+
Permissions.NOTIFICATIONS // "notifications" (routed to notification-specific APIs by the engine)
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
For platform-specific permissions not in this map, pass the raw string directly (e.g., `"ios.permission.FACE_ID"`).
|
|
487
|
+
|
|
488
|
+
---
|
|
489
|
+
|
|
467
490
|
### `createExpoEngine(config)`
|
|
468
491
|
|
|
469
492
|
Create an engine adapter for Expo permission modules. Pass a map of permission keys to Expo modules.
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__esm,
|
|
3
|
+
__export
|
|
4
|
+
} from "./chunk-NFEGQTCC.mjs";
|
|
5
|
+
|
|
6
|
+
// src/engines/rnp.ts
|
|
7
|
+
var rnp_exports = {};
|
|
8
|
+
__export(rnp_exports, {
|
|
9
|
+
Permissions: () => Permissions,
|
|
10
|
+
createRNPEngine: () => createRNPEngine
|
|
11
|
+
});
|
|
12
|
+
import { Platform } from "react-native";
|
|
13
|
+
import {
|
|
14
|
+
check,
|
|
15
|
+
checkNotifications,
|
|
16
|
+
openSettings,
|
|
17
|
+
request,
|
|
18
|
+
requestNotifications
|
|
19
|
+
} from "react-native-permissions";
|
|
20
|
+
function p(ios, android) {
|
|
21
|
+
return Platform.select({ ios, android, default: ios }) ?? ios;
|
|
22
|
+
}
|
|
23
|
+
function createRNPEngine() {
|
|
24
|
+
return {
|
|
25
|
+
async check(permission) {
|
|
26
|
+
if (permission === "notifications") {
|
|
27
|
+
const result = await checkNotifications();
|
|
28
|
+
return result.status;
|
|
29
|
+
}
|
|
30
|
+
return await check(permission);
|
|
31
|
+
},
|
|
32
|
+
async request(permission) {
|
|
33
|
+
if (permission === "notifications") {
|
|
34
|
+
const result = await requestNotifications(["alert", "badge", "sound"]);
|
|
35
|
+
return result.status;
|
|
36
|
+
}
|
|
37
|
+
return await request(permission);
|
|
38
|
+
},
|
|
39
|
+
async openSettings() {
|
|
40
|
+
await openSettings();
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
var Permissions;
|
|
45
|
+
var init_rnp = __esm({
|
|
46
|
+
"src/engines/rnp.ts"() {
|
|
47
|
+
Permissions = {
|
|
48
|
+
CAMERA: p("ios.permission.CAMERA", "android.permission.CAMERA"),
|
|
49
|
+
MICROPHONE: p("ios.permission.MICROPHONE", "android.permission.RECORD_AUDIO"),
|
|
50
|
+
CONTACTS: p("ios.permission.CONTACTS", "android.permission.READ_CONTACTS"),
|
|
51
|
+
CALENDARS: p("ios.permission.CALENDARS", "android.permission.READ_CALENDAR"),
|
|
52
|
+
CALENDARS_WRITE_ONLY: p(
|
|
53
|
+
"ios.permission.CALENDARS_WRITE_ONLY",
|
|
54
|
+
"android.permission.WRITE_CALENDAR"
|
|
55
|
+
),
|
|
56
|
+
LOCATION_WHEN_IN_USE: p(
|
|
57
|
+
"ios.permission.LOCATION_WHEN_IN_USE",
|
|
58
|
+
"android.permission.ACCESS_FINE_LOCATION"
|
|
59
|
+
),
|
|
60
|
+
LOCATION_ALWAYS: p(
|
|
61
|
+
"ios.permission.LOCATION_ALWAYS",
|
|
62
|
+
"android.permission.ACCESS_BACKGROUND_LOCATION"
|
|
63
|
+
),
|
|
64
|
+
PHOTO_LIBRARY: p("ios.permission.PHOTO_LIBRARY", "android.permission.READ_MEDIA_IMAGES"),
|
|
65
|
+
PHOTO_LIBRARY_ADD_ONLY: p(
|
|
66
|
+
"ios.permission.PHOTO_LIBRARY_ADD_ONLY",
|
|
67
|
+
"android.permission.WRITE_EXTERNAL_STORAGE"
|
|
68
|
+
),
|
|
69
|
+
BLUETOOTH: p("ios.permission.BLUETOOTH", "android.permission.BLUETOOTH_CONNECT"),
|
|
70
|
+
NOTIFICATIONS: "notifications"
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
export {
|
|
76
|
+
Permissions,
|
|
77
|
+
createRNPEngine,
|
|
78
|
+
rnp_exports,
|
|
79
|
+
init_rnp
|
|
80
|
+
};
|
|
81
|
+
//# sourceMappingURL=chunk-EU3KPRTI.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/engines/rnp.ts"],"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"],"mappings":";;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,SAAS,gBAAgB;AACzB;AAAA,EAEE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGP,SAAS,EAAE,KAAa,SAAyB;AAC/C,SAAO,SAAS,OAAO,EAAE,KAAK,SAAS,SAAS,IAAI,CAAC,KAAK;AAC5D;AAgCO,SAAS,kBAAoC;AAClD,SAAO;AAAA,IACL,MAAM,MAAM,YAA+C;AACzD,UAAI,eAAe,iBAAiB;AAClC,cAAM,SAAS,MAAM,mBAAmB;AACxC,eAAO,OAAO;AAAA,MAChB;AACA,aAAQ,MAAM,MAAM,UAAwB;AAAA,IAC9C;AAAA,IAEA,MAAM,QAAQ,YAA+C;AAC3D,UAAI,eAAe,iBAAiB;AAClC,cAAM,SAAS,MAAM,qBAAqB,CAAC,SAAS,SAAS,OAAO,CAAC;AACrE,eAAO,OAAO;AAAA,MAChB;AACA,aAAQ,MAAM,QAAQ,UAAwB;AAAA,IAChD;AAAA,IAEA,MAAM,eAA8B;AAClC,YAAM,aAAa;AAAA,IACrB;AAAA,EACF;AACF;AAnEA,IAmBa;AAnBb;AAAA;AAmBO,IAAM,cAAc;AAAA,MACzB,QAAQ,EAAE,yBAAyB,2BAA2B;AAAA,MAC9D,YAAY,EAAE,6BAA6B,iCAAiC;AAAA,MAC5E,UAAU,EAAE,2BAA2B,kCAAkC;AAAA,MACzE,WAAW,EAAE,4BAA4B,kCAAkC;AAAA,MAC3E,sBAAsB;AAAA,QACpB;AAAA,QACA;AAAA,MACF;AAAA,MACA,sBAAsB;AAAA,QACpB;AAAA,QACA;AAAA,MACF;AAAA,MACA,iBAAiB;AAAA,QACf;AAAA,QACA;AAAA,MACF;AAAA,MACA,eAAe,EAAE,gCAAgC,sCAAsC;AAAA,MACvF,wBAAwB;AAAA,QACtB;AAAA,QACA;AAAA,MACF;AAAA,MACA,WAAW,EAAE,4BAA4B,sCAAsC;AAAA,MAC/E,eAAe;AAAA,IACjB;AAAA;AAAA;","names":[]}
|
package/dist/engines/rnp.d.mts
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
import { P as PermissionEngine } from '../types-QXyq8VnD.mjs';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Cross-platform permission constants for use with the RNP engine.
|
|
5
|
+
* Each resolves to the correct platform-specific string at runtime.
|
|
6
|
+
*/
|
|
7
|
+
declare const Permissions: {
|
|
8
|
+
readonly CAMERA: string;
|
|
9
|
+
readonly MICROPHONE: string;
|
|
10
|
+
readonly CONTACTS: string;
|
|
11
|
+
readonly CALENDARS: string;
|
|
12
|
+
readonly CALENDARS_WRITE_ONLY: string;
|
|
13
|
+
readonly LOCATION_WHEN_IN_USE: string;
|
|
14
|
+
readonly LOCATION_ALWAYS: string;
|
|
15
|
+
readonly PHOTO_LIBRARY: string;
|
|
16
|
+
readonly PHOTO_LIBRARY_ADD_ONLY: string;
|
|
17
|
+
readonly BLUETOOTH: string;
|
|
18
|
+
readonly NOTIFICATIONS: "notifications";
|
|
19
|
+
};
|
|
3
20
|
declare function createRNPEngine(): PermissionEngine;
|
|
4
21
|
|
|
5
|
-
export { createRNPEngine };
|
|
22
|
+
export { Permissions, createRNPEngine };
|
package/dist/engines/rnp.d.ts
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
import { P as PermissionEngine } from '../types-QXyq8VnD.js';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Cross-platform permission constants for use with the RNP engine.
|
|
5
|
+
* Each resolves to the correct platform-specific string at runtime.
|
|
6
|
+
*/
|
|
7
|
+
declare const Permissions: {
|
|
8
|
+
readonly CAMERA: string;
|
|
9
|
+
readonly MICROPHONE: string;
|
|
10
|
+
readonly CONTACTS: string;
|
|
11
|
+
readonly CALENDARS: string;
|
|
12
|
+
readonly CALENDARS_WRITE_ONLY: string;
|
|
13
|
+
readonly LOCATION_WHEN_IN_USE: string;
|
|
14
|
+
readonly LOCATION_ALWAYS: string;
|
|
15
|
+
readonly PHOTO_LIBRARY: string;
|
|
16
|
+
readonly PHOTO_LIBRARY_ADD_ONLY: string;
|
|
17
|
+
readonly BLUETOOTH: string;
|
|
18
|
+
readonly NOTIFICATIONS: "notifications";
|
|
19
|
+
};
|
|
3
20
|
declare function createRNPEngine(): PermissionEngine;
|
|
4
21
|
|
|
5
|
-
export { createRNPEngine };
|
|
22
|
+
export { Permissions, createRNPEngine };
|
package/dist/engines/rnp.js
CHANGED
|
@@ -20,10 +20,40 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/engines/rnp.ts
|
|
21
21
|
var rnp_exports = {};
|
|
22
22
|
__export(rnp_exports, {
|
|
23
|
+
Permissions: () => Permissions,
|
|
23
24
|
createRNPEngine: () => createRNPEngine
|
|
24
25
|
});
|
|
25
26
|
module.exports = __toCommonJS(rnp_exports);
|
|
27
|
+
var import_react_native = require("react-native");
|
|
26
28
|
var import_react_native_permissions = require("react-native-permissions");
|
|
29
|
+
function p(ios, android) {
|
|
30
|
+
return import_react_native.Platform.select({ ios, android, default: ios }) ?? ios;
|
|
31
|
+
}
|
|
32
|
+
var Permissions = {
|
|
33
|
+
CAMERA: p("ios.permission.CAMERA", "android.permission.CAMERA"),
|
|
34
|
+
MICROPHONE: p("ios.permission.MICROPHONE", "android.permission.RECORD_AUDIO"),
|
|
35
|
+
CONTACTS: p("ios.permission.CONTACTS", "android.permission.READ_CONTACTS"),
|
|
36
|
+
CALENDARS: p("ios.permission.CALENDARS", "android.permission.READ_CALENDAR"),
|
|
37
|
+
CALENDARS_WRITE_ONLY: p(
|
|
38
|
+
"ios.permission.CALENDARS_WRITE_ONLY",
|
|
39
|
+
"android.permission.WRITE_CALENDAR"
|
|
40
|
+
),
|
|
41
|
+
LOCATION_WHEN_IN_USE: p(
|
|
42
|
+
"ios.permission.LOCATION_WHEN_IN_USE",
|
|
43
|
+
"android.permission.ACCESS_FINE_LOCATION"
|
|
44
|
+
),
|
|
45
|
+
LOCATION_ALWAYS: p(
|
|
46
|
+
"ios.permission.LOCATION_ALWAYS",
|
|
47
|
+
"android.permission.ACCESS_BACKGROUND_LOCATION"
|
|
48
|
+
),
|
|
49
|
+
PHOTO_LIBRARY: p("ios.permission.PHOTO_LIBRARY", "android.permission.READ_MEDIA_IMAGES"),
|
|
50
|
+
PHOTO_LIBRARY_ADD_ONLY: p(
|
|
51
|
+
"ios.permission.PHOTO_LIBRARY_ADD_ONLY",
|
|
52
|
+
"android.permission.WRITE_EXTERNAL_STORAGE"
|
|
53
|
+
),
|
|
54
|
+
BLUETOOTH: p("ios.permission.BLUETOOTH", "android.permission.BLUETOOTH_CONNECT"),
|
|
55
|
+
NOTIFICATIONS: "notifications"
|
|
56
|
+
};
|
|
27
57
|
function createRNPEngine() {
|
|
28
58
|
return {
|
|
29
59
|
async check(permission) {
|
|
@@ -47,6 +77,7 @@ function createRNPEngine() {
|
|
|
47
77
|
}
|
|
48
78
|
// Annotate the CommonJS export names for ESM import in node:
|
|
49
79
|
0 && (module.exports = {
|
|
80
|
+
Permissions,
|
|
50
81
|
createRNPEngine
|
|
51
82
|
});
|
|
52
83
|
//# sourceMappingURL=rnp.js.map
|
package/dist/engines/rnp.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/engines/rnp.ts"],"sourcesContent":["import {\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\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"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sCAOO;
|
|
1
|
+
{"version":3,"sources":["../../src/engines/rnp.ts"],"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"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BAAyB;AACzB,sCAOO;AAGP,SAAS,EAAE,KAAa,SAAyB;AAC/C,SAAO,6BAAS,OAAO,EAAE,KAAK,SAAS,SAAS,IAAI,CAAC,KAAK;AAC5D;AAMO,IAAM,cAAc;AAAA,EACzB,QAAQ,EAAE,yBAAyB,2BAA2B;AAAA,EAC9D,YAAY,EAAE,6BAA6B,iCAAiC;AAAA,EAC5E,UAAU,EAAE,2BAA2B,kCAAkC;AAAA,EACzE,WAAW,EAAE,4BAA4B,kCAAkC;AAAA,EAC3E,sBAAsB;AAAA,IACpB;AAAA,IACA;AAAA,EACF;AAAA,EACA,sBAAsB;AAAA,IACpB;AAAA,IACA;AAAA,EACF;AAAA,EACA,iBAAiB;AAAA,IACf;AAAA,IACA;AAAA,EACF;AAAA,EACA,eAAe,EAAE,gCAAgC,sCAAsC;AAAA,EACvF,wBAAwB;AAAA,IACtB;AAAA,IACA;AAAA,EACF;AAAA,EACA,WAAW,EAAE,4BAA4B,sCAAsC;AAAA,EAC/E,eAAe;AACjB;AAEO,SAAS,kBAAoC;AAClD,SAAO;AAAA,IACL,MAAM,MAAM,YAA+C;AACzD,UAAI,eAAe,iBAAiB;AAClC,cAAM,SAAS,UAAM,oDAAmB;AACxC,eAAO,OAAO;AAAA,MAChB;AACA,aAAQ,UAAM,uCAAM,UAAwB;AAAA,IAC9C;AAAA,IAEA,MAAM,QAAQ,YAA+C;AAC3D,UAAI,eAAe,iBAAiB;AAClC,cAAM,SAAS,UAAM,sDAAqB,CAAC,SAAS,SAAS,OAAO,CAAC;AACrE,eAAO,OAAO;AAAA,MAChB;AACA,aAAQ,UAAM,yCAAQ,UAAwB;AAAA,IAChD;AAAA,IAEA,MAAM,eAA8B;AAClC,gBAAM,8CAAa;AAAA,IACrB;AAAA,EACF;AACF;","names":[]}
|
package/dist/engines/rnp.mjs
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
|
+
Permissions,
|
|
2
3
|
createRNPEngine,
|
|
3
4
|
init_rnp
|
|
4
|
-
} from "../chunk-
|
|
5
|
+
} from "../chunk-EU3KPRTI.mjs";
|
|
5
6
|
import "../chunk-NFEGQTCC.mjs";
|
|
6
7
|
init_rnp();
|
|
7
8
|
export {
|
|
9
|
+
Permissions,
|
|
8
10
|
createRNPEngine
|
|
9
11
|
};
|
|
10
12
|
//# sourceMappingURL=rnp.mjs.map
|
package/dist/index.js
CHANGED
|
@@ -23,8 +23,12 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
23
23
|
// src/engines/rnp.ts
|
|
24
24
|
var rnp_exports = {};
|
|
25
25
|
__export(rnp_exports, {
|
|
26
|
+
Permissions: () => Permissions,
|
|
26
27
|
createRNPEngine: () => createRNPEngine
|
|
27
28
|
});
|
|
29
|
+
function p(ios, android) {
|
|
30
|
+
return import_react_native.Platform.select({ ios, android, default: ios }) ?? ios;
|
|
31
|
+
}
|
|
28
32
|
function createRNPEngine() {
|
|
29
33
|
return {
|
|
30
34
|
async check(permission) {
|
|
@@ -46,11 +50,37 @@ function createRNPEngine() {
|
|
|
46
50
|
}
|
|
47
51
|
};
|
|
48
52
|
}
|
|
49
|
-
var import_react_native_permissions;
|
|
53
|
+
var import_react_native, import_react_native_permissions, Permissions;
|
|
50
54
|
var init_rnp = __esm({
|
|
51
55
|
"src/engines/rnp.ts"() {
|
|
52
56
|
"use strict";
|
|
57
|
+
import_react_native = require("react-native");
|
|
53
58
|
import_react_native_permissions = require("react-native-permissions");
|
|
59
|
+
Permissions = {
|
|
60
|
+
CAMERA: p("ios.permission.CAMERA", "android.permission.CAMERA"),
|
|
61
|
+
MICROPHONE: p("ios.permission.MICROPHONE", "android.permission.RECORD_AUDIO"),
|
|
62
|
+
CONTACTS: p("ios.permission.CONTACTS", "android.permission.READ_CONTACTS"),
|
|
63
|
+
CALENDARS: p("ios.permission.CALENDARS", "android.permission.READ_CALENDAR"),
|
|
64
|
+
CALENDARS_WRITE_ONLY: p(
|
|
65
|
+
"ios.permission.CALENDARS_WRITE_ONLY",
|
|
66
|
+
"android.permission.WRITE_CALENDAR"
|
|
67
|
+
),
|
|
68
|
+
LOCATION_WHEN_IN_USE: p(
|
|
69
|
+
"ios.permission.LOCATION_WHEN_IN_USE",
|
|
70
|
+
"android.permission.ACCESS_FINE_LOCATION"
|
|
71
|
+
),
|
|
72
|
+
LOCATION_ALWAYS: p(
|
|
73
|
+
"ios.permission.LOCATION_ALWAYS",
|
|
74
|
+
"android.permission.ACCESS_BACKGROUND_LOCATION"
|
|
75
|
+
),
|
|
76
|
+
PHOTO_LIBRARY: p("ios.permission.PHOTO_LIBRARY", "android.permission.READ_MEDIA_IMAGES"),
|
|
77
|
+
PHOTO_LIBRARY_ADD_ONLY: p(
|
|
78
|
+
"ios.permission.PHOTO_LIBRARY_ADD_ONLY",
|
|
79
|
+
"android.permission.WRITE_EXTERNAL_STORAGE"
|
|
80
|
+
),
|
|
81
|
+
BLUETOOTH: p("ios.permission.BLUETOOTH", "android.permission.BLUETOOTH_CONNECT"),
|
|
82
|
+
NOTIFICATIONS: "notifications"
|
|
83
|
+
};
|
|
54
84
|
}
|
|
55
85
|
});
|
|
56
86
|
|
|
@@ -153,7 +183,7 @@ function transition(state, event) {
|
|
|
153
183
|
|
|
154
184
|
// src/hooks/use-permission-handler.ts
|
|
155
185
|
var import_react = require("react");
|
|
156
|
-
var
|
|
186
|
+
var import_react_native2 = require("react-native");
|
|
157
187
|
|
|
158
188
|
// src/engines/rnp-fallback.ts
|
|
159
189
|
var cachedFallback = null;
|
|
@@ -186,7 +216,7 @@ function usePermissionHandler(config) {
|
|
|
186
216
|
const [nativeStatus, setNativeStatus] = (0, import_react.useState)(null);
|
|
187
217
|
const isRequesting = (0, import_react.useRef)(false);
|
|
188
218
|
const waitingForSettings = (0, import_react.useRef)(false);
|
|
189
|
-
const appStateRef = (0, import_react.useRef)(
|
|
219
|
+
const appStateRef = (0, import_react.useRef)(import_react_native2.AppState.currentState);
|
|
190
220
|
const { permission, autoCheck = true, onGrant, onDeny, onBlock, onSettingsReturn } = config;
|
|
191
221
|
const checkPermission = (0, import_react.useCallback)(async () => {
|
|
192
222
|
setFlowState((s) => transition(s, { type: "CHECK" }));
|
|
@@ -257,7 +287,7 @@ function usePermissionHandler(config) {
|
|
|
257
287
|
}
|
|
258
288
|
}, []);
|
|
259
289
|
(0, import_react.useEffect)(() => {
|
|
260
|
-
const subscription =
|
|
290
|
+
const subscription = import_react_native2.AppState.addEventListener("change", (nextAppState) => {
|
|
261
291
|
if (appStateRef.current.match(/inactive|background/) && nextAppState === "active" && waitingForSettings.current) {
|
|
262
292
|
waitingForSettings.current = false;
|
|
263
293
|
recheckAfterSettings();
|
|
@@ -442,7 +472,7 @@ async function runParallel(permissions, engine, updateStatus) {
|
|
|
442
472
|
}
|
|
443
473
|
|
|
444
474
|
// src/components/default-blocked-prompt.tsx
|
|
445
|
-
var
|
|
475
|
+
var import_react_native3 = require("react-native");
|
|
446
476
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
447
477
|
function DefaultBlockedPrompt({
|
|
448
478
|
visible,
|
|
@@ -451,21 +481,21 @@ function DefaultBlockedPrompt({
|
|
|
451
481
|
settingsLabel = "Open Settings",
|
|
452
482
|
onOpenSettings
|
|
453
483
|
}) {
|
|
454
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
455
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
456
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
484
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native3.Modal, { visible, transparent: true, animationType: "fade", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native3.View, { style: styles.overlay, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native3.View, { style: styles.modal, children: [
|
|
485
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native3.Text, { style: styles.title, children: title }),
|
|
486
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native3.Text, { style: styles.message, children: message }),
|
|
457
487
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
458
|
-
|
|
488
|
+
import_react_native3.TouchableOpacity,
|
|
459
489
|
{
|
|
460
490
|
style: styles.settingsButton,
|
|
461
491
|
onPress: onOpenSettings,
|
|
462
492
|
accessibilityRole: "button",
|
|
463
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
493
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native3.Text, { style: styles.settingsText, children: settingsLabel })
|
|
464
494
|
}
|
|
465
495
|
)
|
|
466
496
|
] }) }) });
|
|
467
497
|
}
|
|
468
|
-
var styles =
|
|
498
|
+
var styles = import_react_native3.StyleSheet.create({
|
|
469
499
|
overlay: {
|
|
470
500
|
flex: 1,
|
|
471
501
|
backgroundColor: "rgba(0,0,0,0.5)",
|
|
@@ -508,7 +538,7 @@ var styles = import_react_native2.StyleSheet.create({
|
|
|
508
538
|
});
|
|
509
539
|
|
|
510
540
|
// src/components/default-pre-prompt.tsx
|
|
511
|
-
var
|
|
541
|
+
var import_react_native4 = require("react-native");
|
|
512
542
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
513
543
|
function DefaultPrePrompt({
|
|
514
544
|
visible,
|
|
@@ -519,22 +549,22 @@ function DefaultPrePrompt({
|
|
|
519
549
|
onConfirm,
|
|
520
550
|
onCancel
|
|
521
551
|
}) {
|
|
522
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
523
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
524
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
552
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Modal, { visible, transparent: true, animationType: "fade", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.View, { style: styles2.overlay, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native4.View, { style: styles2.modal, children: [
|
|
553
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: styles2.title, children: title }),
|
|
554
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: styles2.message, children: message }),
|
|
525
555
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
526
|
-
|
|
556
|
+
import_react_native4.TouchableOpacity,
|
|
527
557
|
{
|
|
528
558
|
style: styles2.confirmButton,
|
|
529
559
|
onPress: onConfirm,
|
|
530
560
|
accessibilityRole: "button",
|
|
531
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
561
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: styles2.confirmText, children: confirmLabel })
|
|
532
562
|
}
|
|
533
563
|
),
|
|
534
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
564
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.TouchableOpacity, { onPress: onCancel, accessibilityRole: "button", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: styles2.cancelText, children: cancelLabel }) })
|
|
535
565
|
] }) }) });
|
|
536
566
|
}
|
|
537
|
-
var styles2 =
|
|
567
|
+
var styles2 = import_react_native4.StyleSheet.create({
|
|
538
568
|
overlay: {
|
|
539
569
|
flex: 1,
|
|
540
570
|
backgroundColor: "rgba(0,0,0,0.5)",
|
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 {\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\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":["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/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"]}
|
package/dist/index.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-permission-handler",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Smart permission UX flows for React Native — pre-prompts, blocked handling, settings redirect & foreground re-check. Pluggable engine: works with react-native-permissions, Expo, or your own.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
package/src/engines/rnp.test.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
2
|
|
|
3
|
+
vi.mock("react-native", () => ({
|
|
4
|
+
Platform: { select: (opts: Record<string, string>) => opts.ios ?? opts.default },
|
|
5
|
+
}));
|
|
6
|
+
|
|
3
7
|
vi.mock("react-native-permissions", () => ({
|
|
4
8
|
check: vi.fn(),
|
|
5
9
|
request: vi.fn(),
|
|
@@ -15,7 +19,7 @@ import {
|
|
|
15
19
|
request,
|
|
16
20
|
requestNotifications,
|
|
17
21
|
} from "react-native-permissions";
|
|
18
|
-
import { createRNPEngine } from "./rnp";
|
|
22
|
+
import { Permissions, createRNPEngine } from "./rnp";
|
|
19
23
|
|
|
20
24
|
describe("createRNPEngine", () => {
|
|
21
25
|
beforeEach(() => {
|
|
@@ -94,3 +98,25 @@ describe("createRNPEngine", () => {
|
|
|
94
98
|
});
|
|
95
99
|
});
|
|
96
100
|
});
|
|
101
|
+
|
|
102
|
+
describe("Permissions constants", () => {
|
|
103
|
+
it("resolves to iOS strings (mocked platform)", () => {
|
|
104
|
+
expect(Permissions.CAMERA).toBe("ios.permission.CAMERA");
|
|
105
|
+
expect(Permissions.MICROPHONE).toBe("ios.permission.MICROPHONE");
|
|
106
|
+
expect(Permissions.LOCATION_WHEN_IN_USE).toBe("ios.permission.LOCATION_WHEN_IN_USE");
|
|
107
|
+
expect(Permissions.NOTIFICATIONS).toBe("notifications");
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it("includes all expected cross-platform permissions", () => {
|
|
111
|
+
const keys = Object.keys(Permissions);
|
|
112
|
+
expect(keys).toContain("CAMERA");
|
|
113
|
+
expect(keys).toContain("MICROPHONE");
|
|
114
|
+
expect(keys).toContain("CONTACTS");
|
|
115
|
+
expect(keys).toContain("CALENDARS");
|
|
116
|
+
expect(keys).toContain("LOCATION_WHEN_IN_USE");
|
|
117
|
+
expect(keys).toContain("LOCATION_ALWAYS");
|
|
118
|
+
expect(keys).toContain("PHOTO_LIBRARY");
|
|
119
|
+
expect(keys).toContain("BLUETOOTH");
|
|
120
|
+
expect(keys).toContain("NOTIFICATIONS");
|
|
121
|
+
});
|
|
122
|
+
});
|
package/src/engines/rnp.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Platform } from "react-native";
|
|
1
2
|
import {
|
|
2
3
|
type Permission,
|
|
3
4
|
check,
|
|
@@ -8,6 +9,40 @@ import {
|
|
|
8
9
|
} from "react-native-permissions";
|
|
9
10
|
import type { PermissionEngine, PermissionStatus } from "../types";
|
|
10
11
|
|
|
12
|
+
function p(ios: string, android: string): string {
|
|
13
|
+
return Platform.select({ ios, android, default: ios }) ?? ios;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Cross-platform permission constants for use with the RNP engine.
|
|
18
|
+
* Each resolves to the correct platform-specific string at runtime.
|
|
19
|
+
*/
|
|
20
|
+
export const Permissions = {
|
|
21
|
+
CAMERA: p("ios.permission.CAMERA", "android.permission.CAMERA"),
|
|
22
|
+
MICROPHONE: p("ios.permission.MICROPHONE", "android.permission.RECORD_AUDIO"),
|
|
23
|
+
CONTACTS: p("ios.permission.CONTACTS", "android.permission.READ_CONTACTS"),
|
|
24
|
+
CALENDARS: p("ios.permission.CALENDARS", "android.permission.READ_CALENDAR"),
|
|
25
|
+
CALENDARS_WRITE_ONLY: p(
|
|
26
|
+
"ios.permission.CALENDARS_WRITE_ONLY",
|
|
27
|
+
"android.permission.WRITE_CALENDAR",
|
|
28
|
+
),
|
|
29
|
+
LOCATION_WHEN_IN_USE: p(
|
|
30
|
+
"ios.permission.LOCATION_WHEN_IN_USE",
|
|
31
|
+
"android.permission.ACCESS_FINE_LOCATION",
|
|
32
|
+
),
|
|
33
|
+
LOCATION_ALWAYS: p(
|
|
34
|
+
"ios.permission.LOCATION_ALWAYS",
|
|
35
|
+
"android.permission.ACCESS_BACKGROUND_LOCATION",
|
|
36
|
+
),
|
|
37
|
+
PHOTO_LIBRARY: p("ios.permission.PHOTO_LIBRARY", "android.permission.READ_MEDIA_IMAGES"),
|
|
38
|
+
PHOTO_LIBRARY_ADD_ONLY: p(
|
|
39
|
+
"ios.permission.PHOTO_LIBRARY_ADD_ONLY",
|
|
40
|
+
"android.permission.WRITE_EXTERNAL_STORAGE",
|
|
41
|
+
),
|
|
42
|
+
BLUETOOTH: p("ios.permission.BLUETOOTH", "android.permission.BLUETOOTH_CONNECT"),
|
|
43
|
+
NOTIFICATIONS: "notifications",
|
|
44
|
+
} as const;
|
|
45
|
+
|
|
11
46
|
export function createRNPEngine(): PermissionEngine {
|
|
12
47
|
return {
|
|
13
48
|
async check(permission: string): Promise<PermissionStatus> {
|
package/dist/chunk-WZJOIVOM.mjs
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
__esm,
|
|
3
|
-
__export
|
|
4
|
-
} from "./chunk-NFEGQTCC.mjs";
|
|
5
|
-
|
|
6
|
-
// src/engines/rnp.ts
|
|
7
|
-
var rnp_exports = {};
|
|
8
|
-
__export(rnp_exports, {
|
|
9
|
-
createRNPEngine: () => createRNPEngine
|
|
10
|
-
});
|
|
11
|
-
import {
|
|
12
|
-
check,
|
|
13
|
-
checkNotifications,
|
|
14
|
-
openSettings,
|
|
15
|
-
request,
|
|
16
|
-
requestNotifications
|
|
17
|
-
} from "react-native-permissions";
|
|
18
|
-
function createRNPEngine() {
|
|
19
|
-
return {
|
|
20
|
-
async check(permission) {
|
|
21
|
-
if (permission === "notifications") {
|
|
22
|
-
const result = await checkNotifications();
|
|
23
|
-
return result.status;
|
|
24
|
-
}
|
|
25
|
-
return await check(permission);
|
|
26
|
-
},
|
|
27
|
-
async request(permission) {
|
|
28
|
-
if (permission === "notifications") {
|
|
29
|
-
const result = await requestNotifications(["alert", "badge", "sound"]);
|
|
30
|
-
return result.status;
|
|
31
|
-
}
|
|
32
|
-
return await request(permission);
|
|
33
|
-
},
|
|
34
|
-
async openSettings() {
|
|
35
|
-
await openSettings();
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
var init_rnp = __esm({
|
|
40
|
-
"src/engines/rnp.ts"() {
|
|
41
|
-
}
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
export {
|
|
45
|
-
createRNPEngine,
|
|
46
|
-
rnp_exports,
|
|
47
|
-
init_rnp
|
|
48
|
-
};
|
|
49
|
-
//# sourceMappingURL=chunk-WZJOIVOM.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/engines/rnp.ts"],"sourcesContent":["import {\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\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"],"mappings":";;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAEE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGA,SAAS,kBAAoC;AAClD,SAAO;AAAA,IACL,MAAM,MAAM,YAA+C;AACzD,UAAI,eAAe,iBAAiB;AAClC,cAAM,SAAS,MAAM,mBAAmB;AACxC,eAAO,OAAO;AAAA,MAChB;AACA,aAAQ,MAAM,MAAM,UAAwB;AAAA,IAC9C;AAAA,IAEA,MAAM,QAAQ,YAA+C;AAC3D,UAAI,eAAe,iBAAiB;AAClC,cAAM,SAAS,MAAM,qBAAqB,CAAC,SAAS,SAAS,OAAO,CAAC;AACrE,eAAO,OAAO;AAAA,MAChB;AACA,aAAQ,MAAM,QAAQ,UAAwB;AAAA,IAChD;AAAA,IAEA,MAAM,eAA8B;AAClC,YAAM,aAAa;AAAA,IACrB;AAAA,EACF;AACF;AAhCA;AAAA;AAAA;AAAA;","names":[]}
|