react-native-permission-handler 0.1.0 → 0.2.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 +183 -47
- package/dist/chunk-NFEGQTCC.mjs +27 -0
- package/dist/chunk-NFEGQTCC.mjs.map +1 -0
- package/dist/chunk-WZJOIVOM.mjs +49 -0
- package/dist/chunk-WZJOIVOM.mjs.map +1 -0
- package/dist/engines/expo.d.mts +18 -0
- package/dist/engines/expo.d.ts +18 -0
- package/dist/engines/expo.js +58 -0
- package/dist/engines/expo.js.map +1 -0
- package/dist/engines/expo.mjs +35 -0
- package/dist/engines/expo.mjs.map +1 -0
- package/dist/engines/rnp.d.mts +5 -0
- package/dist/engines/rnp.d.ts +5 -0
- package/dist/engines/rnp.js +52 -0
- package/dist/engines/rnp.js.map +1 -0
- package/dist/engines/rnp.mjs +10 -0
- package/dist/engines/rnp.mjs.map +1 -0
- package/dist/index.d.mts +7 -107
- package/dist/index.d.ts +7 -107
- package/dist/index.js +127 -58
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +98 -70
- package/dist/index.mjs.map +1 -1
- package/dist/types-QXyq8VnD.d.mts +122 -0
- package/dist/types-QXyq8VnD.d.ts +122 -0
- package/package.json +27 -2
- package/src/components/permission-gate.tsx +10 -3
- package/src/engines/expo.test.ts +122 -0
- package/src/engines/expo.ts +45 -0
- package/src/engines/resolve.test.ts +85 -0
- package/src/engines/resolve.ts +11 -0
- package/src/engines/rnp-fallback.ts +23 -0
- package/src/engines/rnp.test.ts +96 -0
- package/src/engines/rnp.ts +33 -0
- package/src/engines/use-engine.ts +10 -0
- package/src/hooks/use-multiple-permissions.test.ts +94 -54
- package/src/hooks/use-multiple-permissions.ts +52 -39
- package/src/hooks/use-permission-handler.test.ts +59 -49
- package/src/hooks/use-permission-handler.ts +11 -40
- package/src/index.ts +3 -0
- package/src/types.ts +20 -3
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { createElement } from "react";
|
|
2
2
|
import { type ReactTestRenderer, act, create } from "react-test-renderer";
|
|
3
3
|
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
4
|
-
import type { PermissionHandlerConfig, PermissionHandlerResult } from "../types";
|
|
4
|
+
import type { PermissionEngine, PermissionHandlerConfig, PermissionHandlerResult } from "../types";
|
|
5
5
|
|
|
6
|
-
//
|
|
6
|
+
// Mock react-native AppState
|
|
7
7
|
vi.mock("react-native", () => ({
|
|
8
8
|
AppState: {
|
|
9
9
|
currentState: "active",
|
|
@@ -11,17 +11,24 @@ vi.mock("react-native", () => ({
|
|
|
11
11
|
},
|
|
12
12
|
}));
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
requestNotifications: vi.fn(),
|
|
14
|
+
// Mock the RNP fallback so hooks don't try to require react-native-permissions
|
|
15
|
+
vi.mock("../engines/rnp-fallback", () => ({
|
|
16
|
+
getRNPFallbackEngine: vi.fn(() => {
|
|
17
|
+
throw new Error("No engine configured");
|
|
18
|
+
}),
|
|
20
19
|
}));
|
|
21
20
|
|
|
22
|
-
import { check, checkNotifications, request, requestNotifications } from "react-native-permissions";
|
|
23
21
|
import { usePermissionHandler } from "./use-permission-handler";
|
|
24
22
|
|
|
23
|
+
function createMockEngine(overrides?: Partial<PermissionEngine>): PermissionEngine {
|
|
24
|
+
return {
|
|
25
|
+
check: vi.fn().mockResolvedValue("granted"),
|
|
26
|
+
request: vi.fn().mockResolvedValue("granted"),
|
|
27
|
+
openSettings: vi.fn().mockResolvedValue(undefined),
|
|
28
|
+
...overrides,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
25
32
|
// Minimal renderHook using react-test-renderer
|
|
26
33
|
function renderHook(hookFn: () => PermissionHandlerResult) {
|
|
27
34
|
const results: { current: PermissionHandlerResult } = {} as {
|
|
@@ -41,32 +48,36 @@ function renderHook(hookFn: () => PermissionHandlerResult) {
|
|
|
41
48
|
};
|
|
42
49
|
}
|
|
43
50
|
|
|
44
|
-
const baseConfig: PermissionHandlerConfig = {
|
|
45
|
-
permission: "ios.permission.CAMERA" as PermissionHandlerConfig["permission"],
|
|
46
|
-
prePrompt: { title: "Camera", message: "We need camera access" },
|
|
47
|
-
blockedPrompt: { title: "Blocked", message: "Camera is blocked" },
|
|
48
|
-
};
|
|
49
|
-
|
|
50
51
|
describe("usePermissionHandler", () => {
|
|
52
|
+
let engine: PermissionEngine;
|
|
53
|
+
|
|
54
|
+
const baseConfig = (overrides?: Partial<PermissionHandlerConfig>): PermissionHandlerConfig => ({
|
|
55
|
+
permission: "camera",
|
|
56
|
+
engine,
|
|
57
|
+
prePrompt: { title: "Camera", message: "We need camera access" },
|
|
58
|
+
blockedPrompt: { title: "Blocked", message: "Camera is blocked" },
|
|
59
|
+
...overrides,
|
|
60
|
+
});
|
|
61
|
+
|
|
51
62
|
beforeEach(() => {
|
|
52
63
|
vi.clearAllMocks();
|
|
64
|
+
engine = createMockEngine();
|
|
53
65
|
});
|
|
54
66
|
|
|
55
67
|
it("auto-checks on mount and transitions to granted", async () => {
|
|
56
|
-
vi.mocked(check).mockResolvedValue("granted");
|
|
57
|
-
const { result } = renderHook(() => usePermissionHandler(baseConfig));
|
|
68
|
+
vi.mocked(engine.check).mockResolvedValue("granted");
|
|
69
|
+
const { result } = renderHook(() => usePermissionHandler(baseConfig()));
|
|
58
70
|
|
|
59
|
-
// After mount, should be checking
|
|
60
71
|
await act(async () => {});
|
|
61
72
|
|
|
62
73
|
expect(result.current.isGranted).toBe(true);
|
|
63
74
|
expect(result.current.state).toBe("granted");
|
|
64
|
-
expect(check).toHaveBeenCalledWith(
|
|
75
|
+
expect(engine.check).toHaveBeenCalledWith("camera");
|
|
65
76
|
});
|
|
66
77
|
|
|
67
78
|
it("transitions to prePrompt when permission is denied", async () => {
|
|
68
|
-
vi.mocked(check).mockResolvedValue("denied");
|
|
69
|
-
const { result } = renderHook(() => usePermissionHandler(baseConfig));
|
|
79
|
+
vi.mocked(engine.check).mockResolvedValue("denied");
|
|
80
|
+
const { result } = renderHook(() => usePermissionHandler(baseConfig()));
|
|
70
81
|
|
|
71
82
|
await act(async () => {});
|
|
72
83
|
|
|
@@ -74,8 +85,8 @@ describe("usePermissionHandler", () => {
|
|
|
74
85
|
});
|
|
75
86
|
|
|
76
87
|
it("transitions to blockedPrompt when permission is blocked", async () => {
|
|
77
|
-
vi.mocked(check).mockResolvedValue("blocked");
|
|
78
|
-
const { result } = renderHook(() => usePermissionHandler(baseConfig));
|
|
88
|
+
vi.mocked(engine.check).mockResolvedValue("blocked");
|
|
89
|
+
const { result } = renderHook(() => usePermissionHandler(baseConfig()));
|
|
79
90
|
|
|
80
91
|
await act(async () => {});
|
|
81
92
|
|
|
@@ -84,8 +95,8 @@ describe("usePermissionHandler", () => {
|
|
|
84
95
|
});
|
|
85
96
|
|
|
86
97
|
it("transitions to unavailable", async () => {
|
|
87
|
-
vi.mocked(check).mockResolvedValue("unavailable");
|
|
88
|
-
const { result } = renderHook(() => usePermissionHandler(baseConfig));
|
|
98
|
+
vi.mocked(engine.check).mockResolvedValue("unavailable");
|
|
99
|
+
const { result } = renderHook(() => usePermissionHandler(baseConfig()));
|
|
89
100
|
|
|
90
101
|
await act(async () => {});
|
|
91
102
|
|
|
@@ -94,20 +105,20 @@ describe("usePermissionHandler", () => {
|
|
|
94
105
|
});
|
|
95
106
|
|
|
96
107
|
it("skips auto-check when autoCheck is false", async () => {
|
|
97
|
-
const { result } = renderHook(() => usePermissionHandler({
|
|
108
|
+
const { result } = renderHook(() => usePermissionHandler(baseConfig({ autoCheck: false })));
|
|
98
109
|
|
|
99
110
|
await act(async () => {});
|
|
100
111
|
|
|
101
112
|
expect(result.current.state).toBe("idle");
|
|
102
|
-
expect(check).not.toHaveBeenCalled();
|
|
113
|
+
expect(engine.check).not.toHaveBeenCalled();
|
|
103
114
|
});
|
|
104
115
|
|
|
105
116
|
it("requests permission and fires onGrant", async () => {
|
|
106
|
-
vi.mocked(check).mockResolvedValue("denied");
|
|
107
|
-
vi.mocked(request).mockResolvedValue("granted");
|
|
117
|
+
vi.mocked(engine.check).mockResolvedValue("denied");
|
|
118
|
+
vi.mocked(engine.request).mockResolvedValue("granted");
|
|
108
119
|
const onGrant = vi.fn();
|
|
109
120
|
|
|
110
|
-
const { result } = renderHook(() => usePermissionHandler({
|
|
121
|
+
const { result } = renderHook(() => usePermissionHandler(baseConfig({ onGrant })));
|
|
111
122
|
|
|
112
123
|
await act(async () => {});
|
|
113
124
|
expect(result.current.state).toBe("prePrompt");
|
|
@@ -121,11 +132,11 @@ describe("usePermissionHandler", () => {
|
|
|
121
132
|
});
|
|
122
133
|
|
|
123
134
|
it("fires onDeny when request is denied", async () => {
|
|
124
|
-
vi.mocked(check).mockResolvedValue("denied");
|
|
125
|
-
vi.mocked(request).mockResolvedValue("denied");
|
|
135
|
+
vi.mocked(engine.check).mockResolvedValue("denied");
|
|
136
|
+
vi.mocked(engine.request).mockResolvedValue("denied");
|
|
126
137
|
const onDeny = vi.fn();
|
|
127
138
|
|
|
128
|
-
const { result } = renderHook(() => usePermissionHandler({
|
|
139
|
+
const { result } = renderHook(() => usePermissionHandler(baseConfig({ onDeny })));
|
|
129
140
|
|
|
130
141
|
await act(async () => {});
|
|
131
142
|
await act(async () => {
|
|
@@ -137,11 +148,11 @@ describe("usePermissionHandler", () => {
|
|
|
137
148
|
});
|
|
138
149
|
|
|
139
150
|
it("fires onBlock when request results in blocked", async () => {
|
|
140
|
-
vi.mocked(check).mockResolvedValue("denied");
|
|
141
|
-
vi.mocked(request).mockResolvedValue("blocked");
|
|
151
|
+
vi.mocked(engine.check).mockResolvedValue("denied");
|
|
152
|
+
vi.mocked(engine.request).mockResolvedValue("blocked");
|
|
142
153
|
const onBlock = vi.fn();
|
|
143
154
|
|
|
144
|
-
const { result } = renderHook(() => usePermissionHandler({
|
|
155
|
+
const { result } = renderHook(() => usePermissionHandler(baseConfig({ onBlock })));
|
|
145
156
|
|
|
146
157
|
await act(async () => {});
|
|
147
158
|
await act(async () => {
|
|
@@ -152,33 +163,32 @@ describe("usePermissionHandler", () => {
|
|
|
152
163
|
expect(onBlock).toHaveBeenCalled();
|
|
153
164
|
});
|
|
154
165
|
|
|
155
|
-
it("
|
|
156
|
-
vi.mocked(
|
|
157
|
-
vi.mocked(
|
|
166
|
+
it("passes permission string to engine (notification routing is engine's job)", async () => {
|
|
167
|
+
vi.mocked(engine.check).mockResolvedValue("denied");
|
|
168
|
+
vi.mocked(engine.request).mockResolvedValue("granted");
|
|
158
169
|
|
|
159
170
|
const { result } = renderHook(() =>
|
|
160
|
-
usePermissionHandler({
|
|
171
|
+
usePermissionHandler(baseConfig({ permission: "notifications" })),
|
|
161
172
|
);
|
|
162
173
|
|
|
163
174
|
await act(async () => {});
|
|
164
|
-
expect(
|
|
165
|
-
expect(check).not.toHaveBeenCalled();
|
|
175
|
+
expect(engine.check).toHaveBeenCalledWith("notifications");
|
|
166
176
|
|
|
167
177
|
await act(async () => {
|
|
168
178
|
result.current.request();
|
|
169
179
|
});
|
|
170
180
|
|
|
171
|
-
expect(
|
|
181
|
+
expect(engine.request).toHaveBeenCalledWith("notifications");
|
|
172
182
|
expect(result.current.isGranted).toBe(true);
|
|
173
183
|
});
|
|
174
184
|
|
|
175
185
|
it("guards against double-tap race condition", async () => {
|
|
176
|
-
vi.mocked(check).mockResolvedValue("denied");
|
|
177
|
-
vi.mocked(request).mockImplementation(
|
|
186
|
+
vi.mocked(engine.check).mockResolvedValue("denied");
|
|
187
|
+
vi.mocked(engine.request).mockImplementation(
|
|
178
188
|
() => new Promise((resolve) => setTimeout(() => resolve("granted"), 50)),
|
|
179
189
|
);
|
|
180
190
|
|
|
181
|
-
const { result } = renderHook(() => usePermissionHandler(baseConfig));
|
|
191
|
+
const { result } = renderHook(() => usePermissionHandler(baseConfig()));
|
|
182
192
|
|
|
183
193
|
await act(async () => {});
|
|
184
194
|
expect(result.current.state).toBe("prePrompt");
|
|
@@ -188,14 +198,14 @@ describe("usePermissionHandler", () => {
|
|
|
188
198
|
result.current.request(); // double-tap
|
|
189
199
|
});
|
|
190
200
|
|
|
191
|
-
expect(request).toHaveBeenCalledTimes(1);
|
|
201
|
+
expect(engine.request).toHaveBeenCalledTimes(1);
|
|
192
202
|
});
|
|
193
203
|
|
|
194
204
|
it("dismiss fires onDeny and transitions to denied", async () => {
|
|
195
|
-
vi.mocked(check).mockResolvedValue("denied");
|
|
205
|
+
vi.mocked(engine.check).mockResolvedValue("denied");
|
|
196
206
|
const onDeny = vi.fn();
|
|
197
207
|
|
|
198
|
-
const { result } = renderHook(() => usePermissionHandler({
|
|
208
|
+
const { result } = renderHook(() => usePermissionHandler(baseConfig({ onDeny })));
|
|
199
209
|
|
|
200
210
|
await act(async () => {});
|
|
201
211
|
expect(result.current.state).toBe("prePrompt");
|
|
@@ -1,27 +1,16 @@
|
|
|
1
1
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
2
2
|
import { AppState } from "react-native";
|
|
3
|
-
import {
|
|
4
|
-
type PermissionStatus,
|
|
5
|
-
check,
|
|
6
|
-
checkNotifications,
|
|
7
|
-
openSettings,
|
|
8
|
-
request,
|
|
9
|
-
requestNotifications,
|
|
10
|
-
} from "react-native-permissions";
|
|
11
3
|
import { transition } from "../core/state-machine";
|
|
4
|
+
import { resolveEngine } from "../engines/use-engine";
|
|
12
5
|
import type {
|
|
13
6
|
PermissionFlowState,
|
|
14
7
|
PermissionHandlerConfig,
|
|
15
8
|
PermissionHandlerResult,
|
|
9
|
+
PermissionStatus,
|
|
16
10
|
} from "../types";
|
|
17
11
|
|
|
18
|
-
function isNotifications(
|
|
19
|
-
permission: PermissionHandlerConfig["permission"],
|
|
20
|
-
): permission is "notifications" {
|
|
21
|
-
return permission === "notifications";
|
|
22
|
-
}
|
|
23
|
-
|
|
24
12
|
export function usePermissionHandler(config: PermissionHandlerConfig): PermissionHandlerResult {
|
|
13
|
+
const engine = resolveEngine(config.engine);
|
|
25
14
|
const [flowState, setFlowState] = useState<PermissionFlowState>("idle");
|
|
26
15
|
const [nativeStatus, setNativeStatus] = useState<PermissionStatus | null>(null);
|
|
27
16
|
const isRequesting = useRef(false);
|
|
@@ -33,13 +22,7 @@ export function usePermissionHandler(config: PermissionHandlerConfig): Permissio
|
|
|
33
22
|
const checkPermission = useCallback(async () => {
|
|
34
23
|
setFlowState((s) => transition(s, { type: "CHECK" }));
|
|
35
24
|
try {
|
|
36
|
-
|
|
37
|
-
if (isNotifications(permission)) {
|
|
38
|
-
const result = await checkNotifications();
|
|
39
|
-
status = result.status;
|
|
40
|
-
} else {
|
|
41
|
-
status = await check(permission);
|
|
42
|
-
}
|
|
25
|
+
const status = await engine.check(permission);
|
|
43
26
|
setNativeStatus(status);
|
|
44
27
|
setFlowState((s) => {
|
|
45
28
|
const next = transition(s, { type: "CHECK_RESULT", status });
|
|
@@ -49,7 +32,7 @@ export function usePermissionHandler(config: PermissionHandlerConfig): Permissio
|
|
|
49
32
|
} catch {
|
|
50
33
|
setFlowState("idle");
|
|
51
34
|
}
|
|
52
|
-
}, [permission, onGrant]);
|
|
35
|
+
}, [engine, permission, onGrant]);
|
|
53
36
|
|
|
54
37
|
const requestPermission = useCallback(async () => {
|
|
55
38
|
if (isRequesting.current) return;
|
|
@@ -57,13 +40,7 @@ export function usePermissionHandler(config: PermissionHandlerConfig): Permissio
|
|
|
57
40
|
|
|
58
41
|
setFlowState((s) => transition(s, { type: "PRE_PROMPT_CONFIRM" }));
|
|
59
42
|
try {
|
|
60
|
-
|
|
61
|
-
if (isNotifications(permission)) {
|
|
62
|
-
const result = await requestNotifications(["alert", "badge", "sound"]);
|
|
63
|
-
status = result.status;
|
|
64
|
-
} else {
|
|
65
|
-
status = await request(permission);
|
|
66
|
-
}
|
|
43
|
+
const status = await engine.request(permission);
|
|
67
44
|
setNativeStatus(status);
|
|
68
45
|
setFlowState((s) => {
|
|
69
46
|
const next = transition(s, { type: "REQUEST_RESULT", status });
|
|
@@ -77,7 +54,7 @@ export function usePermissionHandler(config: PermissionHandlerConfig): Permissio
|
|
|
77
54
|
} finally {
|
|
78
55
|
isRequesting.current = false;
|
|
79
56
|
}
|
|
80
|
-
}, [permission, onGrant, onDeny, onBlock]);
|
|
57
|
+
}, [engine, permission, onGrant, onDeny, onBlock]);
|
|
81
58
|
|
|
82
59
|
const dismiss = useCallback(() => {
|
|
83
60
|
setFlowState((s) => transition(s, { type: "PRE_PROMPT_DISMISS" }));
|
|
@@ -88,23 +65,17 @@ export function usePermissionHandler(config: PermissionHandlerConfig): Permissio
|
|
|
88
65
|
setFlowState((s) => transition(s, { type: "OPEN_SETTINGS" }));
|
|
89
66
|
waitingForSettings.current = true;
|
|
90
67
|
try {
|
|
91
|
-
await openSettings();
|
|
68
|
+
await engine.openSettings();
|
|
92
69
|
} catch {
|
|
93
70
|
waitingForSettings.current = false;
|
|
94
71
|
setFlowState("blockedPrompt");
|
|
95
72
|
}
|
|
96
|
-
}, []);
|
|
73
|
+
}, [engine]);
|
|
97
74
|
|
|
98
75
|
const recheckAfterSettings = useCallback(async () => {
|
|
99
76
|
setFlowState((s) => transition(s, { type: "SETTINGS_RETURN" }));
|
|
100
77
|
try {
|
|
101
|
-
|
|
102
|
-
if (isNotifications(permission)) {
|
|
103
|
-
const result = await checkNotifications();
|
|
104
|
-
status = result.status;
|
|
105
|
-
} else {
|
|
106
|
-
status = await check(permission);
|
|
107
|
-
}
|
|
78
|
+
const status = await engine.check(permission);
|
|
108
79
|
setNativeStatus(status);
|
|
109
80
|
setFlowState((s) => {
|
|
110
81
|
const next = transition(s, { type: "RECHECK_RESULT", status });
|
|
@@ -115,7 +86,7 @@ export function usePermissionHandler(config: PermissionHandlerConfig): Permissio
|
|
|
115
86
|
} catch {
|
|
116
87
|
setFlowState("blockedPrompt");
|
|
117
88
|
}
|
|
118
|
-
}, [permission, onGrant, onSettingsReturn]);
|
|
89
|
+
}, [engine, permission, onGrant, onSettingsReturn]);
|
|
119
90
|
|
|
120
91
|
// Auto-check on mount
|
|
121
92
|
// biome-ignore lint/correctness/useExhaustiveDependencies: intentional mount-only effect
|
package/src/index.ts
CHANGED
|
@@ -4,13 +4,16 @@ export type {
|
|
|
4
4
|
MultiplePermissionsConfig,
|
|
5
5
|
MultiplePermissionsResult,
|
|
6
6
|
PermissionCallbacks,
|
|
7
|
+
PermissionEngine,
|
|
7
8
|
PermissionFlowEvent,
|
|
8
9
|
PermissionFlowState,
|
|
9
10
|
PermissionHandlerConfig,
|
|
10
11
|
PermissionHandlerResult,
|
|
12
|
+
PermissionStatus,
|
|
11
13
|
PrePromptConfig,
|
|
12
14
|
} from "./types";
|
|
13
15
|
|
|
16
|
+
export { setDefaultEngine } from "./engines/resolve";
|
|
14
17
|
export { transition } from "./core/state-machine";
|
|
15
18
|
export { usePermissionHandler } from "./hooks/use-permission-handler";
|
|
16
19
|
export { useMultiplePermissions } from "./hooks/use-multiple-permissions";
|
package/src/types.ts
CHANGED
|
@@ -1,4 +1,18 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Permission status values owned by this library.
|
|
3
|
+
* Engines must map their native statuses to these values.
|
|
4
|
+
*/
|
|
5
|
+
export type PermissionStatus = "granted" | "denied" | "blocked" | "limited" | "unavailable";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* The pluggable permission engine interface.
|
|
9
|
+
* Implement this to use a custom permissions backend.
|
|
10
|
+
*/
|
|
11
|
+
export interface PermissionEngine {
|
|
12
|
+
check(permission: string): Promise<PermissionStatus>;
|
|
13
|
+
request(permission: string): Promise<PermissionStatus>;
|
|
14
|
+
openSettings(): Promise<void>;
|
|
15
|
+
}
|
|
2
16
|
|
|
3
17
|
/**
|
|
4
18
|
* States of the permission flow state machine.
|
|
@@ -62,7 +76,8 @@ export interface PermissionCallbacks {
|
|
|
62
76
|
* Configuration for usePermissionHandler.
|
|
63
77
|
*/
|
|
64
78
|
export interface PermissionHandlerConfig extends PermissionCallbacks {
|
|
65
|
-
permission:
|
|
79
|
+
permission: string;
|
|
80
|
+
engine?: PermissionEngine;
|
|
66
81
|
prePrompt: PrePromptConfig;
|
|
67
82
|
blockedPrompt: BlockedPromptConfig;
|
|
68
83
|
autoCheck?: boolean;
|
|
@@ -90,7 +105,7 @@ export interface PermissionHandlerResult {
|
|
|
90
105
|
* Configuration for a single permission within useMultiplePermissions.
|
|
91
106
|
*/
|
|
92
107
|
export interface MultiPermissionEntry extends PermissionCallbacks {
|
|
93
|
-
permission:
|
|
108
|
+
permission: string;
|
|
94
109
|
prePrompt: PrePromptConfig;
|
|
95
110
|
blockedPrompt: BlockedPromptConfig;
|
|
96
111
|
}
|
|
@@ -101,6 +116,8 @@ export interface MultiPermissionEntry extends PermissionCallbacks {
|
|
|
101
116
|
export interface MultiplePermissionsConfig {
|
|
102
117
|
permissions: MultiPermissionEntry[];
|
|
103
118
|
strategy: "sequential" | "parallel";
|
|
119
|
+
engine?: PermissionEngine;
|
|
120
|
+
autoCheck?: boolean;
|
|
104
121
|
onAllGranted?: () => void;
|
|
105
122
|
}
|
|
106
123
|
|