@ankhorage/permissions 0.1.1 → 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.
Files changed (70) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +97 -21
  3. package/dist/client/types.d.ts +2 -8
  4. package/dist/client/types.d.ts.map +1 -1
  5. package/dist/client/types.js.map +1 -1
  6. package/dist/expo/adapters/camera.d.ts +3 -0
  7. package/dist/expo/adapters/camera.d.ts.map +1 -0
  8. package/dist/expo/adapters/camera.js +30 -0
  9. package/dist/expo/adapters/camera.js.map +1 -0
  10. package/dist/expo/adapters/location.d.ts +3 -0
  11. package/dist/expo/adapters/location.d.ts.map +1 -0
  12. package/dist/expo/adapters/location.js +31 -0
  13. package/dist/expo/adapters/location.js.map +1 -0
  14. package/dist/expo/adapters/mediaLibrary.d.ts +3 -0
  15. package/dist/expo/adapters/mediaLibrary.d.ts.map +1 -0
  16. package/dist/expo/adapters/mediaLibrary.js +28 -0
  17. package/dist/expo/adapters/mediaLibrary.js.map +1 -0
  18. package/dist/expo/adapters/microphone.d.ts +3 -0
  19. package/dist/expo/adapters/microphone.d.ts.map +1 -0
  20. package/dist/expo/adapters/microphone.js +30 -0
  21. package/dist/expo/adapters/microphone.js.map +1 -0
  22. package/dist/expo/adapters/notifications.d.ts +3 -0
  23. package/dist/expo/adapters/notifications.d.ts.map +1 -0
  24. package/dist/expo/adapters/notifications.js +24 -0
  25. package/dist/expo/adapters/notifications.js.map +1 -0
  26. package/dist/expo/client.d.ts +9 -0
  27. package/dist/expo/client.d.ts.map +1 -0
  28. package/dist/expo/client.js +63 -0
  29. package/dist/expo/client.js.map +1 -0
  30. package/dist/expo/index.d.ts +3 -0
  31. package/dist/expo/index.d.ts.map +1 -0
  32. package/dist/expo/index.js +3 -0
  33. package/dist/expo/index.js.map +1 -0
  34. package/dist/expo/manifest.d.ts +9 -0
  35. package/dist/expo/manifest.d.ts.map +1 -0
  36. package/dist/expo/manifest.js +44 -0
  37. package/dist/expo/manifest.js.map +1 -0
  38. package/dist/expo/permissionResponse.d.ts +11 -0
  39. package/dist/expo/permissionResponse.d.ts.map +1 -0
  40. package/dist/expo/permissionResponse.js +47 -0
  41. package/dist/expo/permissionResponse.js.map +1 -0
  42. package/dist/manager/createPermissionManager.d.ts +4 -15
  43. package/dist/manager/createPermissionManager.d.ts.map +1 -1
  44. package/dist/manager/createPermissionManager.js +3 -14
  45. package/dist/manager/createPermissionManager.js.map +1 -1
  46. package/dist/react/index.d.ts +0 -14
  47. package/dist/react/index.d.ts.map +1 -1
  48. package/dist/react/index.js +0 -14
  49. package/dist/react/index.js.map +1 -1
  50. package/dist/testing/index.d.ts +0 -8
  51. package/dist/testing/index.d.ts.map +1 -1
  52. package/dist/testing/index.js +0 -8
  53. package/dist/testing/index.js.map +1 -1
  54. package/package.json +13 -1
  55. package/src/client/types.ts +2 -8
  56. package/src/expo/adapters/camera.ts +52 -0
  57. package/src/expo/adapters/location.ts +34 -0
  58. package/src/expo/adapters/mediaLibrary.ts +33 -0
  59. package/src/expo/adapters/microphone.ts +52 -0
  60. package/src/expo/adapters/notifications.ts +28 -0
  61. package/src/expo/client.test.ts +372 -0
  62. package/src/expo/client.ts +79 -0
  63. package/src/expo/index.ts +3 -0
  64. package/src/expo/manifest.test.ts +65 -0
  65. package/src/expo/manifest.ts +57 -0
  66. package/src/expo/modules.d.ts +53 -0
  67. package/src/expo/permissionResponse.ts +84 -0
  68. package/src/manager/createPermissionManager.ts +4 -15
  69. package/src/react/index.tsx +0 -14
  70. package/src/testing/index.ts +0 -8
@@ -0,0 +1,84 @@
1
+ import type { Permission } from '../registry/permissions';
2
+ import {
3
+ createPermissionState,
4
+ isPermissionStatus,
5
+ type PermissionState,
6
+ } from '../state/permissionState';
7
+
8
+ export interface ExpoPermissionResponse {
9
+ readonly status: string;
10
+ readonly canAskAgain?: boolean;
11
+ }
12
+
13
+ export type ExpoPermissionMethod = () => Promise<ExpoPermissionResponse>;
14
+
15
+ export function createExpoPermissionState(
16
+ permission: Permission,
17
+ response: ExpoPermissionResponse,
18
+ ): PermissionState {
19
+ const status = isPermissionStatus(response.status) ? response.status : 'unknown';
20
+
21
+ return createPermissionState({
22
+ permission,
23
+ status,
24
+ canAskAgain: response.canAskAgain,
25
+ });
26
+ }
27
+
28
+ export function createExpoUnavailableState(
29
+ permission: Permission,
30
+ error: unknown,
31
+ ): PermissionState {
32
+ return createPermissionState({
33
+ permission,
34
+ status: 'unavailable',
35
+ reason: getExpoPermissionErrorMessage(error),
36
+ });
37
+ }
38
+
39
+ export function findExpoPermissionMethod(
40
+ source: unknown,
41
+ methodName: string,
42
+ containerNames: readonly string[] = [],
43
+ ): ExpoPermissionMethod | undefined {
44
+ if (hasExpoPermissionMethod(source, methodName)) {
45
+ return source[methodName];
46
+ }
47
+
48
+ if (!isRecord(source)) {
49
+ return undefined;
50
+ }
51
+
52
+ for (const containerName of containerNames) {
53
+ const container = source[containerName];
54
+
55
+ if (hasExpoPermissionMethod(container, methodName)) {
56
+ return container[methodName];
57
+ }
58
+ }
59
+
60
+ return undefined;
61
+ }
62
+
63
+ function getExpoPermissionErrorMessage(error: unknown): string {
64
+ if (error instanceof Error && error.message.length > 0) {
65
+ return error.message;
66
+ }
67
+
68
+ if (typeof error === 'string' && error.length > 0) {
69
+ return error;
70
+ }
71
+
72
+ return 'Expo permission operation failed.';
73
+ }
74
+
75
+ function hasExpoPermissionMethod(
76
+ value: unknown,
77
+ methodName: string,
78
+ ): value is Record<string, ExpoPermissionMethod> {
79
+ return isRecord(value) && typeof value[methodName] === 'function';
80
+ }
81
+
82
+ function isRecord(value: unknown): value is Record<string, unknown> {
83
+ return typeof value === 'object' && value !== null;
84
+ }
@@ -3,7 +3,7 @@ import { assertKnownPermission, type Permission } from '../registry/permissions'
3
3
  import { normalizePermissionState, type PermissionState } from '../state/permissionState';
4
4
 
5
5
  /***
6
- * Public manager returned by `createPermissionManager`.
6
+ * Public facade for checking and requesting normalized permission state.
7
7
  */
8
8
  export interface PermissionManager {
9
9
  getStatus(permission: Permission): Promise<PermissionState>;
@@ -12,22 +12,11 @@ export interface PermissionManager {
12
12
  }
13
13
 
14
14
  /***
15
- * Wraps a client with registry validation and normalized results.
15
+ * Creates a permission manager from a runtime-specific client.
16
16
  *
17
17
  * @readme
18
- * Runtime permissions and build-time native configuration are separate concerns.
19
- * This manager checks or requests permissions through a client, but it does not
20
- * generate iOS usage descriptions, Android manifest entries, or Expo config
21
- * plugins.
22
- *
23
- * @usage
24
- * ```ts
25
- * const permissions = createPermissionManager(client);
26
- * const camera = await permissions.getStatus(Permission.Camera);
27
- * const requested = camera.granted
28
- * ? camera
29
- * : await permissions.request(Permission.Camera);
30
- * ```
18
+ * The manager validates permission names and normalizes client results.
19
+ * Native app configuration remains a separate build-time concern.
31
20
  */
32
21
  export function createPermissionManager(client: PermissionClient): PermissionManager {
33
22
  const manager: PermissionManager = {
@@ -99,20 +99,6 @@ export function usePermissions(): PermissionManager {
99
99
 
100
100
  /***
101
101
  * Tracks a single permission and exposes explicit refresh/request actions.
102
- *
103
- * @usage
104
- * ```tsx
105
- * const camera = usePermission(Permission.Camera, { refreshOnMount: true });
106
- *
107
- * return (
108
- * <Button
109
- * disabled={camera.granted}
110
- * onPress={() => {
111
- * void camera.request();
112
- * }}
113
- * />
114
- * );
115
- * ```
116
102
  */
117
103
  export function usePermission(
118
104
  permission: Permission,
@@ -51,14 +51,6 @@ export interface FakePermissionClient extends PermissionClient {
51
51
  * @readme
52
52
  * Fake clients make permission flows testable without native devices, browser
53
53
  * prompts, simulators, or network access.
54
- *
55
- * @usage
56
- * ```ts
57
- * const client = createFakePermissionClient({
58
- * initialStates: [{ permission: Permission.Camera, status: 'denied' }],
59
- * });
60
- * await client.request(Permission.Camera);
61
- * ```
62
54
  */
63
55
  export function createFakePermissionClient(
64
56
  options: FakePermissionClientOptions = {},