react-native-permission-handler 0.1.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.
Files changed (41) hide show
  1. package/README.md +212 -53
  2. package/dist/chunk-EU3KPRTI.mjs +81 -0
  3. package/dist/chunk-EU3KPRTI.mjs.map +1 -0
  4. package/dist/chunk-NFEGQTCC.mjs +27 -0
  5. package/dist/chunk-NFEGQTCC.mjs.map +1 -0
  6. package/dist/engines/expo.d.mts +18 -0
  7. package/dist/engines/expo.d.ts +18 -0
  8. package/dist/engines/expo.js +58 -0
  9. package/dist/engines/expo.js.map +1 -0
  10. package/dist/engines/expo.mjs +35 -0
  11. package/dist/engines/expo.mjs.map +1 -0
  12. package/dist/engines/rnp.d.mts +22 -0
  13. package/dist/engines/rnp.d.ts +22 -0
  14. package/dist/engines/rnp.js +83 -0
  15. package/dist/engines/rnp.js.map +1 -0
  16. package/dist/engines/rnp.mjs +12 -0
  17. package/dist/engines/rnp.mjs.map +1 -0
  18. package/dist/index.d.mts +7 -107
  19. package/dist/index.d.ts +7 -107
  20. package/dist/index.js +175 -76
  21. package/dist/index.js.map +1 -1
  22. package/dist/index.mjs +98 -70
  23. package/dist/index.mjs.map +1 -1
  24. package/dist/types-QXyq8VnD.d.mts +122 -0
  25. package/dist/types-QXyq8VnD.d.ts +122 -0
  26. package/package.json +27 -2
  27. package/src/components/permission-gate.tsx +10 -3
  28. package/src/engines/expo.test.ts +122 -0
  29. package/src/engines/expo.ts +45 -0
  30. package/src/engines/resolve.test.ts +85 -0
  31. package/src/engines/resolve.ts +11 -0
  32. package/src/engines/rnp-fallback.ts +23 -0
  33. package/src/engines/rnp.test.ts +122 -0
  34. package/src/engines/rnp.ts +68 -0
  35. package/src/engines/use-engine.ts +10 -0
  36. package/src/hooks/use-multiple-permissions.test.ts +94 -54
  37. package/src/hooks/use-multiple-permissions.ts +52 -39
  38. package/src/hooks/use-permission-handler.test.ts +59 -49
  39. package/src/hooks/use-permission-handler.ts +11 -40
  40. package/src/index.ts +3 -0
  41. package/src/types.ts +20 -3
@@ -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
- let status: PermissionStatus;
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
- let status: PermissionStatus;
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
- let status: PermissionStatus;
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
- import type { Permission, PermissionStatus } from "react-native-permissions";
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: Permission | "notifications";
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: Permission | "notifications";
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