expo-permissions-store 0.1.0 → 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 tupe12334
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -208,6 +208,10 @@ Each permission returns a detailed state object:
208
208
  - `locationBackground` requires `locationForeground` to be granted first.
209
209
  - `limited` status is iOS 14+ only (for photos).
210
210
 
211
+ ## Contributing
212
+
213
+ Contributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md) and [Code of Conduct](CODE_OF_CONDUCT.md) before submitting a PR.
214
+
211
215
  ## License
212
216
 
213
- MIT
217
+ [MIT](LICENSE)
package/dist/index.cjs CHANGED
@@ -64,9 +64,26 @@ function normalizeResponse(response) {
64
64
  expires: response.expires ?? "never"
65
65
  };
66
66
  }
67
- async function tryImport(moduleName) {
67
+ function safeRequire(id) {
68
68
  try {
69
- return await import(moduleName);
69
+ switch (id) {
70
+ case "expo-camera":
71
+ return require("expo-camera");
72
+ case "expo-media-library":
73
+ return require("expo-media-library");
74
+ case "expo-location":
75
+ return require("expo-location");
76
+ case "expo-notifications":
77
+ return require("expo-notifications");
78
+ case "expo-contacts":
79
+ return require("expo-contacts");
80
+ case "expo-calendar":
81
+ return require("expo-calendar");
82
+ case "expo-tracking-transparency":
83
+ return require("expo-tracking-transparency");
84
+ default:
85
+ return null;
86
+ }
70
87
  } catch {
71
88
  return null;
72
89
  }
@@ -74,60 +91,56 @@ async function tryImport(moduleName) {
74
91
  async function getPermission(type) {
75
92
  switch (type) {
76
93
  case "camera": {
77
- const Camera = await tryImport("expo-camera");
94
+ const Camera = safeRequire("expo-camera");
78
95
  if (!Camera) throw new Error("expo-camera is not installed");
79
96
  const response = await Camera.Camera.getCameraPermissionsAsync();
80
97
  return normalizeResponse(response);
81
98
  }
82
99
  case "microphone": {
83
- const Camera = await tryImport("expo-camera");
100
+ const Camera = safeRequire("expo-camera");
84
101
  if (!Camera) throw new Error("expo-camera is not installed");
85
102
  const response = await Camera.Camera.getMicrophonePermissionsAsync();
86
103
  return normalizeResponse(response);
87
104
  }
88
105
  case "mediaLibrary": {
89
- const MediaLibrary = await tryImport(
90
- "expo-media-library"
91
- );
106
+ const MediaLibrary = safeRequire("expo-media-library");
92
107
  if (!MediaLibrary) throw new Error("expo-media-library is not installed");
93
108
  const response = await MediaLibrary.getPermissionsAsync();
94
109
  return normalizeResponse(response);
95
110
  }
96
111
  case "locationForeground": {
97
- const Location = await tryImport("expo-location");
112
+ const Location = safeRequire("expo-location");
98
113
  if (!Location) throw new Error("expo-location is not installed");
99
114
  const response = await Location.getForegroundPermissionsAsync();
100
115
  return normalizeResponse(response);
101
116
  }
102
117
  case "locationBackground": {
103
- const Location = await tryImport("expo-location");
118
+ const Location = safeRequire("expo-location");
104
119
  if (!Location) throw new Error("expo-location is not installed");
105
120
  const response = await Location.getBackgroundPermissionsAsync();
106
121
  return normalizeResponse(response);
107
122
  }
108
123
  case "notifications": {
109
- const Notifications = await tryImport(
110
- "expo-notifications"
111
- );
124
+ const Notifications = safeRequire("expo-notifications");
112
125
  if (!Notifications)
113
126
  throw new Error("expo-notifications is not installed");
114
127
  const response = await Notifications.getPermissionsAsync();
115
128
  return normalizeResponse(response);
116
129
  }
117
130
  case "contacts": {
118
- const Contacts = await tryImport("expo-contacts");
131
+ const Contacts = safeRequire("expo-contacts");
119
132
  if (!Contacts) throw new Error("expo-contacts is not installed");
120
133
  const response = await Contacts.getPermissionsAsync();
121
134
  return normalizeResponse(response);
122
135
  }
123
136
  case "calendar": {
124
- const Calendar = await tryImport("expo-calendar");
137
+ const Calendar = safeRequire("expo-calendar");
125
138
  if (!Calendar) throw new Error("expo-calendar is not installed");
126
139
  const response = await Calendar.getCalendarPermissionsAsync();
127
140
  return normalizeResponse(response);
128
141
  }
129
142
  case "tracking": {
130
- const Tracking = await tryImport("expo-tracking-transparency");
143
+ const Tracking = safeRequire("expo-tracking-transparency");
131
144
  if (!Tracking)
132
145
  throw new Error("expo-tracking-transparency is not installed");
133
146
  const response = await Tracking.getTrackingPermissionsAsync();
@@ -142,60 +155,56 @@ async function getPermission(type) {
142
155
  async function requestPermission(type) {
143
156
  switch (type) {
144
157
  case "camera": {
145
- const Camera = await tryImport("expo-camera");
158
+ const Camera = safeRequire("expo-camera");
146
159
  if (!Camera) throw new Error("expo-camera is not installed");
147
160
  const response = await Camera.Camera.requestCameraPermissionsAsync();
148
161
  return normalizeResponse(response);
149
162
  }
150
163
  case "microphone": {
151
- const Camera = await tryImport("expo-camera");
164
+ const Camera = safeRequire("expo-camera");
152
165
  if (!Camera) throw new Error("expo-camera is not installed");
153
166
  const response = await Camera.Camera.requestMicrophonePermissionsAsync();
154
167
  return normalizeResponse(response);
155
168
  }
156
169
  case "mediaLibrary": {
157
- const MediaLibrary = await tryImport(
158
- "expo-media-library"
159
- );
170
+ const MediaLibrary = safeRequire("expo-media-library");
160
171
  if (!MediaLibrary) throw new Error("expo-media-library is not installed");
161
172
  const response = await MediaLibrary.requestPermissionsAsync();
162
173
  return normalizeResponse(response);
163
174
  }
164
175
  case "locationForeground": {
165
- const Location = await tryImport("expo-location");
176
+ const Location = safeRequire("expo-location");
166
177
  if (!Location) throw new Error("expo-location is not installed");
167
178
  const response = await Location.requestForegroundPermissionsAsync();
168
179
  return normalizeResponse(response);
169
180
  }
170
181
  case "locationBackground": {
171
- const Location = await tryImport("expo-location");
182
+ const Location = safeRequire("expo-location");
172
183
  if (!Location) throw new Error("expo-location is not installed");
173
184
  const response = await Location.requestBackgroundPermissionsAsync();
174
185
  return normalizeResponse(response);
175
186
  }
176
187
  case "notifications": {
177
- const Notifications = await tryImport(
178
- "expo-notifications"
179
- );
188
+ const Notifications = safeRequire("expo-notifications");
180
189
  if (!Notifications)
181
190
  throw new Error("expo-notifications is not installed");
182
191
  const response = await Notifications.requestPermissionsAsync();
183
192
  return normalizeResponse(response);
184
193
  }
185
194
  case "contacts": {
186
- const Contacts = await tryImport("expo-contacts");
195
+ const Contacts = safeRequire("expo-contacts");
187
196
  if (!Contacts) throw new Error("expo-contacts is not installed");
188
197
  const response = await Contacts.requestPermissionsAsync();
189
198
  return normalizeResponse(response);
190
199
  }
191
200
  case "calendar": {
192
- const Calendar = await tryImport("expo-calendar");
201
+ const Calendar = safeRequire("expo-calendar");
193
202
  if (!Calendar) throw new Error("expo-calendar is not installed");
194
203
  const response = await Calendar.requestCalendarPermissionsAsync();
195
204
  return normalizeResponse(response);
196
205
  }
197
206
  case "tracking": {
198
- const Tracking = await tryImport("expo-tracking-transparency");
207
+ const Tracking = safeRequire("expo-tracking-transparency");
199
208
  if (!Tracking)
200
209
  throw new Error("expo-tracking-transparency is not installed");
201
210
  const response = await Tracking.requestTrackingPermissionsAsync();
package/dist/index.js CHANGED
@@ -1,3 +1,10 @@
1
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
+ }) : x)(function(x) {
4
+ if (typeof require !== "undefined") return require.apply(this, arguments);
5
+ throw Error('Dynamic require of "' + x + '" is not supported');
6
+ });
7
+
1
8
  // src/types.ts
2
9
  var ALL_PERMISSIONS = [
3
10
  "camera",
@@ -29,9 +36,26 @@ function normalizeResponse(response) {
29
36
  expires: response.expires ?? "never"
30
37
  };
31
38
  }
32
- async function tryImport(moduleName) {
39
+ function safeRequire(id) {
33
40
  try {
34
- return await import(moduleName);
41
+ switch (id) {
42
+ case "expo-camera":
43
+ return __require("expo-camera");
44
+ case "expo-media-library":
45
+ return __require("expo-media-library");
46
+ case "expo-location":
47
+ return __require("expo-location");
48
+ case "expo-notifications":
49
+ return __require("expo-notifications");
50
+ case "expo-contacts":
51
+ return __require("expo-contacts");
52
+ case "expo-calendar":
53
+ return __require("expo-calendar");
54
+ case "expo-tracking-transparency":
55
+ return __require("expo-tracking-transparency");
56
+ default:
57
+ return null;
58
+ }
35
59
  } catch {
36
60
  return null;
37
61
  }
@@ -39,60 +63,56 @@ async function tryImport(moduleName) {
39
63
  async function getPermission(type) {
40
64
  switch (type) {
41
65
  case "camera": {
42
- const Camera = await tryImport("expo-camera");
66
+ const Camera = safeRequire("expo-camera");
43
67
  if (!Camera) throw new Error("expo-camera is not installed");
44
68
  const response = await Camera.Camera.getCameraPermissionsAsync();
45
69
  return normalizeResponse(response);
46
70
  }
47
71
  case "microphone": {
48
- const Camera = await tryImport("expo-camera");
72
+ const Camera = safeRequire("expo-camera");
49
73
  if (!Camera) throw new Error("expo-camera is not installed");
50
74
  const response = await Camera.Camera.getMicrophonePermissionsAsync();
51
75
  return normalizeResponse(response);
52
76
  }
53
77
  case "mediaLibrary": {
54
- const MediaLibrary = await tryImport(
55
- "expo-media-library"
56
- );
78
+ const MediaLibrary = safeRequire("expo-media-library");
57
79
  if (!MediaLibrary) throw new Error("expo-media-library is not installed");
58
80
  const response = await MediaLibrary.getPermissionsAsync();
59
81
  return normalizeResponse(response);
60
82
  }
61
83
  case "locationForeground": {
62
- const Location = await tryImport("expo-location");
84
+ const Location = safeRequire("expo-location");
63
85
  if (!Location) throw new Error("expo-location is not installed");
64
86
  const response = await Location.getForegroundPermissionsAsync();
65
87
  return normalizeResponse(response);
66
88
  }
67
89
  case "locationBackground": {
68
- const Location = await tryImport("expo-location");
90
+ const Location = safeRequire("expo-location");
69
91
  if (!Location) throw new Error("expo-location is not installed");
70
92
  const response = await Location.getBackgroundPermissionsAsync();
71
93
  return normalizeResponse(response);
72
94
  }
73
95
  case "notifications": {
74
- const Notifications = await tryImport(
75
- "expo-notifications"
76
- );
96
+ const Notifications = safeRequire("expo-notifications");
77
97
  if (!Notifications)
78
98
  throw new Error("expo-notifications is not installed");
79
99
  const response = await Notifications.getPermissionsAsync();
80
100
  return normalizeResponse(response);
81
101
  }
82
102
  case "contacts": {
83
- const Contacts = await tryImport("expo-contacts");
103
+ const Contacts = safeRequire("expo-contacts");
84
104
  if (!Contacts) throw new Error("expo-contacts is not installed");
85
105
  const response = await Contacts.getPermissionsAsync();
86
106
  return normalizeResponse(response);
87
107
  }
88
108
  case "calendar": {
89
- const Calendar = await tryImport("expo-calendar");
109
+ const Calendar = safeRequire("expo-calendar");
90
110
  if (!Calendar) throw new Error("expo-calendar is not installed");
91
111
  const response = await Calendar.getCalendarPermissionsAsync();
92
112
  return normalizeResponse(response);
93
113
  }
94
114
  case "tracking": {
95
- const Tracking = await tryImport("expo-tracking-transparency");
115
+ const Tracking = safeRequire("expo-tracking-transparency");
96
116
  if (!Tracking)
97
117
  throw new Error("expo-tracking-transparency is not installed");
98
118
  const response = await Tracking.getTrackingPermissionsAsync();
@@ -107,60 +127,56 @@ async function getPermission(type) {
107
127
  async function requestPermission(type) {
108
128
  switch (type) {
109
129
  case "camera": {
110
- const Camera = await tryImport("expo-camera");
130
+ const Camera = safeRequire("expo-camera");
111
131
  if (!Camera) throw new Error("expo-camera is not installed");
112
132
  const response = await Camera.Camera.requestCameraPermissionsAsync();
113
133
  return normalizeResponse(response);
114
134
  }
115
135
  case "microphone": {
116
- const Camera = await tryImport("expo-camera");
136
+ const Camera = safeRequire("expo-camera");
117
137
  if (!Camera) throw new Error("expo-camera is not installed");
118
138
  const response = await Camera.Camera.requestMicrophonePermissionsAsync();
119
139
  return normalizeResponse(response);
120
140
  }
121
141
  case "mediaLibrary": {
122
- const MediaLibrary = await tryImport(
123
- "expo-media-library"
124
- );
142
+ const MediaLibrary = safeRequire("expo-media-library");
125
143
  if (!MediaLibrary) throw new Error("expo-media-library is not installed");
126
144
  const response = await MediaLibrary.requestPermissionsAsync();
127
145
  return normalizeResponse(response);
128
146
  }
129
147
  case "locationForeground": {
130
- const Location = await tryImport("expo-location");
148
+ const Location = safeRequire("expo-location");
131
149
  if (!Location) throw new Error("expo-location is not installed");
132
150
  const response = await Location.requestForegroundPermissionsAsync();
133
151
  return normalizeResponse(response);
134
152
  }
135
153
  case "locationBackground": {
136
- const Location = await tryImport("expo-location");
154
+ const Location = safeRequire("expo-location");
137
155
  if (!Location) throw new Error("expo-location is not installed");
138
156
  const response = await Location.requestBackgroundPermissionsAsync();
139
157
  return normalizeResponse(response);
140
158
  }
141
159
  case "notifications": {
142
- const Notifications = await tryImport(
143
- "expo-notifications"
144
- );
160
+ const Notifications = safeRequire("expo-notifications");
145
161
  if (!Notifications)
146
162
  throw new Error("expo-notifications is not installed");
147
163
  const response = await Notifications.requestPermissionsAsync();
148
164
  return normalizeResponse(response);
149
165
  }
150
166
  case "contacts": {
151
- const Contacts = await tryImport("expo-contacts");
167
+ const Contacts = safeRequire("expo-contacts");
152
168
  if (!Contacts) throw new Error("expo-contacts is not installed");
153
169
  const response = await Contacts.requestPermissionsAsync();
154
170
  return normalizeResponse(response);
155
171
  }
156
172
  case "calendar": {
157
- const Calendar = await tryImport("expo-calendar");
173
+ const Calendar = safeRequire("expo-calendar");
158
174
  if (!Calendar) throw new Error("expo-calendar is not installed");
159
175
  const response = await Calendar.requestCalendarPermissionsAsync();
160
176
  return normalizeResponse(response);
161
177
  }
162
178
  case "tracking": {
163
- const Tracking = await tryImport("expo-tracking-transparency");
179
+ const Tracking = safeRequire("expo-tracking-transparency");
164
180
  if (!Tracking)
165
181
  throw new Error("expo-tracking-transparency is not installed");
166
182
  const response = await Tracking.requestTrackingPermissionsAsync();
@@ -1 +1 @@
1
- {"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../src/permissions/handlers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AA6BhE,wBAAsB,aAAa,CACjC,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,eAAe,CAAC,CAsF1B;AAED,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,eAAe,CAAC,CAsF1B"}
1
+ {"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../src/permissions/handlers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAkDhE,wBAAsB,aAAa,CACjC,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,eAAe,CAAC,CA0F1B;AAED,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,eAAe,CAAC,CA0F1B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-permissions-store",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Redux Toolkit (RTK Query) store for managing Expo permissions",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",
@@ -59,13 +59,15 @@
59
59
  },
60
60
  "devDependencies": {
61
61
  "@commitlint/cli": "^19.0.0",
62
- "@release-it/conventional-changelog": "^10.0.0",
63
62
  "@commitlint/config-conventional": "^19.0.0",
64
63
  "@eslint/js": "^9.0.0",
65
64
  "@reduxjs/toolkit": "^2.0.0",
65
+ "@release-it/conventional-changelog": "^10.0.0",
66
66
  "@types/react": "^18.2.0",
67
+ "@vitest/coverage-v8": "^4.0.18",
67
68
  "cspell": "^8.0.0",
68
69
  "eslint": "^9.0.0",
70
+ "eslint-config-agent": "^1.9.3",
69
71
  "eslint-config-prettier": "^9.0.0",
70
72
  "expo-calendar": "^14.1.4",
71
73
  "expo-camera": "^16.1.11",
@@ -85,7 +87,8 @@
85
87
  "release-it": "^19.0.0",
86
88
  "tsup": "^8.0.0",
87
89
  "typescript": "^5.3.0",
88
- "typescript-eslint": "^8.0.0"
90
+ "typescript-eslint": "^8.0.0",
91
+ "vitest": "^4.0.18"
89
92
  },
90
93
  "scripts": {
91
94
  "build": "tsup && tsc --project tsconfig.build.json",
@@ -97,7 +100,8 @@
97
100
  "typecheck": "tsc --noEmit",
98
101
  "spell": "cspell \"**/*\"",
99
102
  "knip": "knip",
100
- "test": "jest --passWithNoTests",
103
+ "test": "vitest run",
104
+ "test:coverage": "vitest run --coverage",
101
105
  "release": "release-it"
102
106
  }
103
107
  }