expo-permissions-store 0.1.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 ADDED
@@ -0,0 +1,213 @@
1
+ # expo-permissions-store
2
+
3
+ A Redux Toolkit (RTK Query) store for managing Expo permissions. Provides a centralized, type-safe way to check and request permissions in your React Native / Expo app.
4
+
5
+ ## Features
6
+
7
+ - RTK Query-based state management
8
+ - Detailed permission state (status, canAskAgain, expires)
9
+ - Auto re-check on app foreground
10
+ - Flexible exports: use the built-in store or integrate into your own
11
+ - Full TypeScript support
12
+ - No UI components - just state management
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ npm install expo-permissions-store
18
+ ```
19
+
20
+ ### Peer Dependencies
21
+
22
+ ```bash
23
+ npm install @reduxjs/toolkit react-redux expo-camera expo-media-library expo-location expo-notifications expo-contacts expo-calendar expo-tracking-transparency
24
+ ```
25
+
26
+ > Install only the expo modules you need. Unused permission modules are optional.
27
+
28
+ ## Quick Start
29
+
30
+ ### Option 1: Use the Built-in Store
31
+
32
+ ```tsx
33
+ import { Provider } from "react-redux";
34
+ import {
35
+ store,
36
+ useGetPermissionQuery,
37
+ useRequestPermissionMutation,
38
+ } from "expo-permissions-store";
39
+
40
+ function App() {
41
+ return (
42
+ <Provider store={store}>
43
+ <MyComponent />
44
+ </Provider>
45
+ );
46
+ }
47
+
48
+ function MyComponent() {
49
+ const { data: cameraPermission, isLoading } = useGetPermissionQuery("camera");
50
+ const [requestPermission] = useRequestPermissionMutation();
51
+
52
+ if (isLoading) return <Text>Checking permission...</Text>;
53
+
54
+ if (cameraPermission?.status !== "granted") {
55
+ return (
56
+ <Button
57
+ title="Grant Camera Access"
58
+ onPress={() => requestPermission("camera")}
59
+ />
60
+ );
61
+ }
62
+
63
+ return <CameraView />;
64
+ }
65
+ ```
66
+
67
+ ### Option 2: Integrate into Your Store
68
+
69
+ ```typescript
70
+ import { configureStore } from "@reduxjs/toolkit";
71
+ import { permissionsApi } from "expo-permissions-store";
72
+
73
+ const store = configureStore({
74
+ reducer: {
75
+ // ...your reducers
76
+ [permissionsApi.reducerPath]: permissionsApi.reducer,
77
+ },
78
+ middleware: (getDefaultMiddleware) =>
79
+ getDefaultMiddleware().concat(permissionsApi.middleware),
80
+ });
81
+ ```
82
+
83
+ ### Option 3: Custom Configuration
84
+
85
+ ```typescript
86
+ import { createPermissionsApi } from "expo-permissions-store";
87
+
88
+ const customPermissionsApi = createPermissionsApi({
89
+ // Only include permissions you need
90
+ permissions: ["camera", "microphone", "mediaLibrary"],
91
+
92
+ // Disable foreground re-check
93
+ recheckOnForeground: false,
94
+ });
95
+
96
+ // Use in your store
97
+ const store = configureStore({
98
+ reducer: {
99
+ [customPermissionsApi.reducerPath]: customPermissionsApi.reducer,
100
+ },
101
+ middleware: (getDefaultMiddleware) =>
102
+ getDefaultMiddleware().concat(customPermissionsApi.middleware),
103
+ });
104
+ ```
105
+
106
+ ## API Reference
107
+
108
+ ### Hooks
109
+
110
+ #### `useGetPermissionQuery(permissionType)`
111
+
112
+ Check the current status of a permission.
113
+
114
+ ```typescript
115
+ const { data, isLoading, error, refetch } = useGetPermissionQuery("camera");
116
+ ```
117
+
118
+ Returns:
119
+
120
+ ```typescript
121
+ {
122
+ data: {
123
+ status: 'undetermined' | 'granted' | 'denied' | 'limited';
124
+ canAskAgain: boolean;
125
+ expires: 'never' | number;
126
+ } | undefined;
127
+ isLoading: boolean;
128
+ error: Error | undefined;
129
+ refetch: () => void;
130
+ }
131
+ ```
132
+
133
+ #### `useRequestPermissionMutation()`
134
+
135
+ Request a permission from the user.
136
+
137
+ ```typescript
138
+ const [requestPermission, { isLoading, data, error }] =
139
+ useRequestPermissionMutation();
140
+
141
+ // Trigger request
142
+ await requestPermission("camera");
143
+ ```
144
+
145
+ ### Permission Types
146
+
147
+ ```typescript
148
+ type PermissionType =
149
+ | "camera"
150
+ | "microphone"
151
+ | "mediaLibrary"
152
+ | "locationForeground"
153
+ | "locationBackground"
154
+ | "notifications"
155
+ | "contacts"
156
+ | "calendar"
157
+ | "tracking"; // iOS only
158
+ ```
159
+
160
+ ### Configuration Options
161
+
162
+ ```typescript
163
+ interface PermissionsConfig {
164
+ // Which permissions to include
165
+ // Default: all permissions
166
+ permissions?: PermissionType[];
167
+
168
+ // Re-check permissions when app returns to foreground
169
+ // Default: true
170
+ recheckOnForeground?: boolean;
171
+
172
+ // Automatically check all permissions on store creation
173
+ // Default: false
174
+ autoCheckOnMount?: boolean;
175
+
176
+ // RTK Query cache time in seconds
177
+ // Default: Infinity
178
+ cacheTime?: number;
179
+ }
180
+ ```
181
+
182
+ ## Exports
183
+
184
+ | Export | Description |
185
+ | ------------------------------ | ----------------------------------------- |
186
+ | `store` | Pre-configured Redux store |
187
+ | `permissionsApi` | RTK Query API slice with default config |
188
+ | `createPermissionsApi` | Factory function for custom configuration |
189
+ | `useGetPermissionQuery` | Hook to check permission status |
190
+ | `useRequestPermissionMutation` | Hook to request permission |
191
+ | `PermissionType` | Union type of all permission names |
192
+ | `PermissionState` | Type for permission state object |
193
+ | `PermissionsConfig` | Type for configuration options |
194
+
195
+ ## Permission State
196
+
197
+ Each permission returns a detailed state object:
198
+
199
+ | Property | Type | Description |
200
+ | ------------- | ------------------------------------------------------ | ----------------------------------------- |
201
+ | `status` | `'undetermined' \| 'granted' \| 'denied' \| 'limited'` | Current permission status |
202
+ | `canAskAgain` | `boolean` | Whether the app can prompt the user again |
203
+ | `expires` | `'never' \| number` | When the permission expires |
204
+
205
+ ## Platform Notes
206
+
207
+ - `tracking` permission is iOS 14+ only. On Android, it returns `granted`.
208
+ - `locationBackground` requires `locationForeground` to be granted first.
209
+ - `limited` status is iOS 14+ only (for photos).
210
+
211
+ ## License
212
+
213
+ MIT