@ankhorage/permissions 0.2.2 → 0.2.4
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/CHANGELOG.md +13 -0
- package/README.md +27 -3
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +2 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/expo/adapters/mediaLibrary.d.ts.map +1 -1
- package/dist/expo/adapters/mediaLibrary.js +15 -3
- package/dist/expo/adapters/mediaLibrary.js.map +1 -1
- package/dist/expo/adapters/notifications.d.ts.map +1 -1
- package/dist/expo/adapters/notifications.js +32 -3
- package/dist/expo/adapters/notifications.js.map +1 -1
- package/dist/expo/client.d.ts +14 -0
- package/dist/expo/client.d.ts.map +1 -1
- package/dist/expo/client.js +42 -13
- package/dist/expo/client.js.map +1 -1
- package/dist/expo/client.testSupport.d.ts +54 -0
- package/dist/expo/client.testSupport.d.ts.map +1 -0
- package/dist/expo/client.testSupport.js +183 -0
- package/dist/expo/client.testSupport.js.map +1 -0
- package/dist/expo/manifest.d.ts +5 -0
- package/dist/expo/manifest.d.ts.map +1 -1
- package/dist/expo/manifest.js +5 -0
- package/dist/expo/manifest.js.map +1 -1
- package/dist/expo/permissionResponse.d.ts.map +1 -1
- package/dist/expo/permissionResponse.js +16 -9
- package/dist/expo/permissionResponse.js.map +1 -1
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +16 -11
- package/dist/react/index.js.map +1 -1
- package/dist/state/permissionState.d.ts +2 -0
- package/dist/state/permissionState.d.ts.map +1 -1
- package/dist/state/permissionState.js +3 -1
- package/dist/state/permissionState.js.map +1 -1
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +27 -17
- package/dist/testing/index.js.map +1 -1
- package/dist/web/index.d.ts +1 -2
- package/dist/web/index.d.ts.map +1 -1
- package/dist/web/index.js +2 -76
- package/dist/web/index.js.map +1 -1
- package/dist/web/permissionStates.d.ts +10 -0
- package/dist/web/permissionStates.d.ts.map +1 -0
- package/dist/web/permissionStates.js +64 -0
- package/dist/web/permissionStates.js.map +1 -0
- package/package.json +22 -13
- package/src/cli/index.ts +1 -0
- package/src/expo/adapters/mediaLibrary.ts +28 -4
- package/src/expo/adapters/notifications.ts +73 -4
- package/src/expo/client.notifications.test.ts +106 -0
- package/src/expo/client.test.ts +109 -349
- package/src/expo/client.testSupport.ts +188 -0
- package/src/expo/client.ts +45 -13
- package/src/expo/manifest.test.ts +49 -47
- package/src/expo/manifest.ts +7 -5
- package/src/expo/modules.d.ts +18 -4
- package/src/expo/permissionResponse.ts +26 -9
- package/src/manager/createPermissionManager.test.ts +48 -50
- package/src/react/index.tsx +21 -13
- package/src/registry/permissions.test.ts +4 -3
- package/src/state/permissionState.test.ts +8 -1
- package/src/state/permissionState.ts +4 -7
- package/src/testing/index.ts +36 -25
- package/src/web/index.test.ts +149 -151
- package/src/web/index.ts +9 -102
- package/src/web/permissionStates.ts +83 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.testSupport.js","sourceRoot":"","sources":["../../src/expo/client.testSupport.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAYhC,MAAM,UAAU,kBAAkB,CAAC,MAAc,EAAE,WAAW,GAAG,IAAI;IACnE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;AACjC,CAAC;AAED,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,IAAI,EAAE,UAA4B;IAClC,WAAW,EAAE,kBAAkB,CAAC,SAAS,CAAC;IAC1C,eAAe,EAAE,kBAAkB,CAAC,SAAS,CAAC;IAC9C,QAAQ,EAAE,SAA+B;IACzC,YAAY,EAAE,SAA+B;CAC9C,CAAC;AACF,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,IAAI,EAAE,UAA2B;IACjC,WAAW,EAAE,kBAAkB,CAAC,SAAS,CAAC;IAC1C,eAAe,EAAE,kBAAkB,CAAC,SAAS,CAAC;IAC9C,QAAQ,EAAE,SAA+B;IACzC,YAAY,EAAE,SAA+B;CAC9C,CAAC;AACF,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,WAAW,EAAE,kBAAkB,CAAC,SAAS,CAAC;IAC1C,eAAe,EAAE,kBAAkB,CAAC,SAAS,CAAC;IAC9C,QAAQ,EAAE,SAA+B;IACzC,YAAY,EAAE,SAA+B;IAC7C,QAAQ,EAAE,EAAe;IACzB,YAAY,EAAE,EAAe;CAC9B,CAAC;AACF,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,qBAAqB,EAAE,kBAAkB,CAAC,SAAS,CAAC;IACpD,yBAAyB,EAAE,kBAAkB,CAAC,SAAS,CAAC;IACxD,qBAAqB,EAAE,kBAAkB,CAAC,SAAS,CAAC;IACpD,yBAAyB,EAAE,kBAAkB,CAAC,SAAS,CAAC;IACxD,QAAQ,EAAE,EAAc;IACxB,YAAY,EAAE,EAAc;CAC7B,CAAC;AACF,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,WAAW,EAAE,kBAAkB,CAAC,SAAS,CAAC;IAC1C,eAAe,EAAE,kBAAkB,CAAC,SAAS,CAAC;IAC9C,QAAQ,EAAE,SAA+B;IACzC,YAAY,EAAE,SAA+B;CAC9C,CAAC;AACF,MAAM,CAAC,MAAM,WAAW,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,SAA8B,EAAE,CAAC;AAE/E,KAAK,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,GAAG,EAAE,CAAC,CAAC;IACrC,IAAI,yBAAyB;QAC3B,IAAI,UAAU,CAAC,IAAI,KAAK,UAAU;YAAE,OAAO,SAAS,CAAC;QACrD,OAAO,GAAG,EAAE;YACV,IAAI,UAAU,CAAC,QAAQ,KAAK,SAAS;gBAAE,MAAM,IAAI,KAAK,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;YAC5E,OAAO,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;QACjD,CAAC,CAAC;IACJ,CAAC;IACD,IAAI,6BAA6B;QAC/B,IAAI,UAAU,CAAC,IAAI,KAAK,UAAU;YAAE,OAAO,SAAS,CAAC;QACrD,OAAO,GAAG,EAAE;YACV,IAAI,UAAU,CAAC,YAAY,KAAK,SAAS;gBAAE,MAAM,IAAI,KAAK,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;YACpF,OAAO,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;QACrD,CAAC,CAAC;IACJ,CAAC;IACD,IAAI,MAAM;QACR,IAAI,UAAU,CAAC,IAAI,KAAK,iBAAiB;YAAE,OAAO,SAAS,CAAC;QAC5D,OAAO;YACL,yBAAyB,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC;YACxE,6BAA6B,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,eAAe,CAAC;SACjF,CAAC;IACJ,CAAC;CACF,CAAC,CAAC,CAAC;AAEJ,KAAK,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,GAAG,EAAE,CAAC,CAAC;IACpC,IAAI,4BAA4B;QAC9B,IAAI,SAAS,CAAC,IAAI,KAAK,UAAU;YAAE,OAAO,SAAS,CAAC;QACpD,OAAO,GAAG,EAAE;YACV,IAAI,SAAS,CAAC,QAAQ,KAAK,SAAS;gBAAE,MAAM,IAAI,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;YAC1E,OAAO,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QAChD,CAAC,CAAC;IACJ,CAAC;IACD,IAAI,gCAAgC;QAClC,IAAI,SAAS,CAAC,IAAI,KAAK,UAAU;YAAE,OAAO,SAAS,CAAC;QACpD,OAAO,GAAG,EAAE;YACV,IAAI,SAAS,CAAC,YAAY,KAAK,SAAS;gBAAE,MAAM,IAAI,KAAK,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;YAClF,OAAO,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;QACpD,CAAC,CAAC;IACJ,CAAC;IACD,IAAI,WAAW;QACb,IAAI,SAAS,CAAC,IAAI,KAAK,aAAa;YAAE,OAAO,SAAS,CAAC;QACvD,OAAO;YACL,4BAA4B,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,WAAW,CAAC;YAC1E,gCAAgC,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,eAAe,CAAC;SACnF,CAAC;IACJ,CAAC;CACF,CAAC,CAAC,CAAC;AAEJ,KAAK,IAAI,CAAC,MAAM,CAAC,oBAAoB,EAAE,GAAG,EAAE,CAAC,CAAC;IAC5C,mBAAmB,EAAE,CAAC,SAAmB,EAAE,EAAE;QAC3C,gBAAgB,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,KAAK,IAAI,CAAC,CAAC;QACnD,IAAI,gBAAgB,CAAC,QAAQ,KAAK,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;QACxF,OAAO,OAAO,CAAC,OAAO,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC;IACvD,CAAC;IACD,uBAAuB,EAAE,CAAC,SAAmB,EAAE,EAAE;QAC/C,gBAAgB,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,KAAK,IAAI,CAAC,CAAC;QACvD,IAAI,gBAAgB,CAAC,YAAY,KAAK,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC;QAChG,OAAO,OAAO,CAAC,OAAO,CAAC,gBAAgB,CAAC,eAAe,CAAC,CAAC;IAC3D,CAAC;CACF,CAAC,CAAC,CAAC;AAEJ,KAAK,IAAI,CAAC,MAAM,CAAC,eAAe,EAAE,GAAG,EAAE,CAAC,CAAC;IACvC,6BAA6B,EAAE,GAAG,EAAE;QAClC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACzC,OAAO,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,qBAAqB,CAAC,CAAC;IAC7D,CAAC;IACD,iCAAiC,EAAE,GAAG,EAAE;QACtC,YAAY,CAAC,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC7C,OAAO,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,yBAAyB,CAAC,CAAC;IACjE,CAAC;IACD,6BAA6B,EAAE,GAAG,EAAE;QAClC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACzC,OAAO,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,qBAAqB,CAAC,CAAC;IAC7D,CAAC;IACD,iCAAiC,EAAE,GAAG,EAAE;QACtC,YAAY,CAAC,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC7C,OAAO,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,yBAAyB,CAAC,CAAC;IACjE,CAAC;CACF,CAAC,CAAC,CAAC;AAEJ,KAAK,IAAI,CAAC,MAAM,CAAC,oBAAoB,EAAE,GAAG,EAAE,CAAC,CAAC;IAC5C,mBAAmB,EAAE,GAAG,EAAE;QACxB,IAAI,iBAAiB,CAAC,QAAQ,KAAK,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;QAC1F,OAAO,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;IACxD,CAAC;IACD,uBAAuB,EAAE,GAAG,EAAE;QAC5B,IAAI,iBAAiB,CAAC,YAAY,KAAK,SAAS;YAC9C,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,YAAY,CAAC,CAAC;QAClD,OAAO,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,eAAe,CAAC,CAAC;IAC5D,CAAC;CACF,CAAC,CAAC,CAAC;AAEJ,KAAK,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,GAAG,EAAE,CAAC,CAAC;IACtC,YAAY,EAAE,GAAG,EAAE;QACjB,WAAW,CAAC,KAAK,IAAI,CAAC,CAAC;QACvB,IAAI,WAAW,CAAC,KAAK,KAAK,SAAS;YAAE,MAAM,WAAW,CAAC,KAAK,CAAC;QAC7D,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC3B,CAAC;CACF,CAAC,CAAC,CAAC;AAEJ,MAAM,UAAU,cAAc;IAC5B,UAAU,CAAC,IAAI,GAAG,UAAU,CAAC;IAC7B,UAAU,CAAC,WAAW,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;IACvD,UAAU,CAAC,eAAe,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;IAC3D,UAAU,CAAC,QAAQ,GAAG,SAAS,CAAC;IAChC,UAAU,CAAC,YAAY,GAAG,SAAS,CAAC;IACpC,SAAS,CAAC,IAAI,GAAG,UAAU,CAAC;IAC5B,SAAS,CAAC,WAAW,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;IACtD,SAAS,CAAC,eAAe,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;IAC1D,SAAS,CAAC,QAAQ,GAAG,SAAS,CAAC;IAC/B,SAAS,CAAC,YAAY,GAAG,SAAS,CAAC;IACnC,oBAAoB,EAAE,CAAC;IACvB,iBAAiB,CAAC,WAAW,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;IAC9D,iBAAiB,CAAC,eAAe,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;IAClE,iBAAiB,CAAC,QAAQ,GAAG,SAAS,CAAC;IACvC,iBAAiB,CAAC,YAAY,GAAG,SAAS,CAAC;IAC3C,WAAW,CAAC,KAAK,GAAG,CAAC,CAAC;IACtB,WAAW,CAAC,KAAK,GAAG,SAAS,CAAC;AAChC,CAAC;AAED,SAAS,oBAAoB;IAC3B,gBAAgB,CAAC,WAAW,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;IAC7D,gBAAgB,CAAC,eAAe,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;IACjE,gBAAgB,CAAC,QAAQ,GAAG,SAAS,CAAC;IACtC,gBAAgB,CAAC,YAAY,GAAG,SAAS,CAAC;IAC1C,gBAAgB,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;IACrC,gBAAgB,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC;IACzC,YAAY,CAAC,qBAAqB,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;IACnE,YAAY,CAAC,yBAAyB,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;IACvE,YAAY,CAAC,qBAAqB,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;IACnE,YAAY,CAAC,yBAAyB,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;IACvE,YAAY,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;IACjC,YAAY,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC;AACvC,CAAC","sourcesContent":["import { mock } from 'bun:test';\n\nexport interface MockPermissionResponse {\n readonly status: string;\n readonly canAskAgain?: boolean;\n readonly accessPrivileges?: 'all' | 'limited' | 'none';\n readonly ios?: { readonly status?: number };\n}\n\ntype CameraMockMode = 'topLevel' | 'cameraNamespace' | 'missingExports';\ntype AudioMockMode = 'topLevel' | 'audioModule' | 'missingExports';\n\nexport function permissionResponse(status: string, canAskAgain = true): MockPermissionResponse {\n return { status, canAskAgain };\n}\n\nexport const cameraMock = {\n mode: 'topLevel' as CameraMockMode,\n getResponse: permissionResponse('granted'),\n requestResponse: permissionResponse('granted'),\n getError: undefined as string | undefined,\n requestError: undefined as string | undefined,\n};\nexport const audioMock = {\n mode: 'topLevel' as AudioMockMode,\n getResponse: permissionResponse('granted'),\n requestResponse: permissionResponse('granted'),\n getError: undefined as string | undefined,\n requestError: undefined as string | undefined,\n};\nexport const mediaLibraryMock = {\n getResponse: permissionResponse('granted'),\n requestResponse: permissionResponse('granted'),\n getError: undefined as string | undefined,\n requestError: undefined as string | undefined,\n getCalls: [] as boolean[],\n requestCalls: [] as boolean[],\n};\nexport const locationMock = {\n foregroundGetResponse: permissionResponse('granted'),\n foregroundRequestResponse: permissionResponse('granted'),\n backgroundGetResponse: permissionResponse('granted'),\n backgroundRequestResponse: permissionResponse('granted'),\n getCalls: [] as string[],\n requestCalls: [] as string[],\n};\nexport const notificationsMock = {\n getResponse: permissionResponse('granted'),\n requestResponse: permissionResponse('granted'),\n getError: undefined as string | undefined,\n requestError: undefined as string | undefined,\n};\nexport const linkingMock = { calls: 0, error: undefined as Error | undefined };\n\nvoid mock.module('expo-camera', () => ({\n get getCameraPermissionsAsync() {\n if (cameraMock.mode !== 'topLevel') return undefined;\n return () => {\n if (cameraMock.getError !== undefined) throw new Error(cameraMock.getError);\n return Promise.resolve(cameraMock.getResponse);\n };\n },\n get requestCameraPermissionsAsync() {\n if (cameraMock.mode !== 'topLevel') return undefined;\n return () => {\n if (cameraMock.requestError !== undefined) throw new Error(cameraMock.requestError);\n return Promise.resolve(cameraMock.requestResponse);\n };\n },\n get Camera() {\n if (cameraMock.mode !== 'cameraNamespace') return undefined;\n return {\n getCameraPermissionsAsync: () => Promise.resolve(cameraMock.getResponse),\n requestCameraPermissionsAsync: () => Promise.resolve(cameraMock.requestResponse),\n };\n },\n}));\n\nvoid mock.module('expo-audio', () => ({\n get getRecordingPermissionsAsync() {\n if (audioMock.mode !== 'topLevel') return undefined;\n return () => {\n if (audioMock.getError !== undefined) throw new Error(audioMock.getError);\n return Promise.resolve(audioMock.getResponse);\n };\n },\n get requestRecordingPermissionsAsync() {\n if (audioMock.mode !== 'topLevel') return undefined;\n return () => {\n if (audioMock.requestError !== undefined) throw new Error(audioMock.requestError);\n return Promise.resolve(audioMock.requestResponse);\n };\n },\n get AudioModule() {\n if (audioMock.mode !== 'audioModule') return undefined;\n return {\n getRecordingPermissionsAsync: () => Promise.resolve(audioMock.getResponse),\n requestRecordingPermissionsAsync: () => Promise.resolve(audioMock.requestResponse),\n };\n },\n}));\n\nvoid mock.module('expo-media-library', () => ({\n getPermissionsAsync: (writeOnly?: boolean) => {\n mediaLibraryMock.getCalls.push(writeOnly === true);\n if (mediaLibraryMock.getError !== undefined) throw new Error(mediaLibraryMock.getError);\n return Promise.resolve(mediaLibraryMock.getResponse);\n },\n requestPermissionsAsync: (writeOnly?: boolean) => {\n mediaLibraryMock.requestCalls.push(writeOnly === true);\n if (mediaLibraryMock.requestError !== undefined) throw new Error(mediaLibraryMock.requestError);\n return Promise.resolve(mediaLibraryMock.requestResponse);\n },\n}));\n\nvoid mock.module('expo-location', () => ({\n getForegroundPermissionsAsync: () => {\n locationMock.getCalls.push('foreground');\n return Promise.resolve(locationMock.foregroundGetResponse);\n },\n requestForegroundPermissionsAsync: () => {\n locationMock.requestCalls.push('foreground');\n return Promise.resolve(locationMock.foregroundRequestResponse);\n },\n getBackgroundPermissionsAsync: () => {\n locationMock.getCalls.push('background');\n return Promise.resolve(locationMock.backgroundGetResponse);\n },\n requestBackgroundPermissionsAsync: () => {\n locationMock.requestCalls.push('background');\n return Promise.resolve(locationMock.backgroundRequestResponse);\n },\n}));\n\nvoid mock.module('expo-notifications', () => ({\n getPermissionsAsync: () => {\n if (notificationsMock.getError !== undefined) throw new Error(notificationsMock.getError);\n return Promise.resolve(notificationsMock.getResponse);\n },\n requestPermissionsAsync: () => {\n if (notificationsMock.requestError !== undefined)\n throw new Error(notificationsMock.requestError);\n return Promise.resolve(notificationsMock.requestResponse);\n },\n}));\n\nvoid mock.module('expo-linking', () => ({\n openSettings: () => {\n linkingMock.calls += 1;\n if (linkingMock.error !== undefined) throw linkingMock.error;\n return Promise.resolve();\n },\n}));\n\nexport function resetExpoMocks(): void {\n cameraMock.mode = 'topLevel';\n cameraMock.getResponse = permissionResponse('granted');\n cameraMock.requestResponse = permissionResponse('granted');\n cameraMock.getError = undefined;\n cameraMock.requestError = undefined;\n audioMock.mode = 'topLevel';\n audioMock.getResponse = permissionResponse('granted');\n audioMock.requestResponse = permissionResponse('granted');\n audioMock.getError = undefined;\n audioMock.requestError = undefined;\n resetCollectionMocks();\n notificationsMock.getResponse = permissionResponse('granted');\n notificationsMock.requestResponse = permissionResponse('granted');\n notificationsMock.getError = undefined;\n notificationsMock.requestError = undefined;\n linkingMock.calls = 0;\n linkingMock.error = undefined;\n}\n\nfunction resetCollectionMocks(): void {\n mediaLibraryMock.getResponse = permissionResponse('granted');\n mediaLibraryMock.requestResponse = permissionResponse('granted');\n mediaLibraryMock.getError = undefined;\n mediaLibraryMock.requestError = undefined;\n mediaLibraryMock.getCalls.length = 0;\n mediaLibraryMock.requestCalls.length = 0;\n locationMock.foregroundGetResponse = permissionResponse('granted');\n locationMock.foregroundRequestResponse = permissionResponse('granted');\n locationMock.backgroundGetResponse = permissionResponse('granted');\n locationMock.backgroundRequestResponse = permissionResponse('granted');\n locationMock.getCalls.length = 0;\n locationMock.requestCalls.length = 0;\n}\n"]}
|
package/dist/expo/manifest.d.ts
CHANGED
|
@@ -5,5 +5,10 @@ export interface ExpoPermissionMetadata {
|
|
|
5
5
|
readonly requiredPackages: readonly string[];
|
|
6
6
|
readonly configHints: readonly string[];
|
|
7
7
|
}
|
|
8
|
+
/***
|
|
9
|
+
* Expo packages required by the permission client independently of a specific
|
|
10
|
+
* permission capability.
|
|
11
|
+
*/
|
|
12
|
+
export declare const EXPO_PERMISSION_CLIENT_REQUIRED_PACKAGES: readonly ["expo-linking"];
|
|
8
13
|
export declare const EXPO_PERMISSION_SUPPORT: Readonly<Record<Permission, ExpoPermissionMetadata>>;
|
|
9
14
|
//# sourceMappingURL=manifest.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/expo/manifest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAErD,MAAM,MAAM,iBAAiB,
|
|
1
|
+
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/expo/manifest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAErD,MAAM,MAAM,iBAAiB,GAC3B,WAAW,GAAG,aAAa,GAAG,SAAS,GAAG,gBAAgB,GAAG,aAAa,CAAC;AAE7E,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,OAAO,EAAE,iBAAiB,CAAC;IACpC,QAAQ,CAAC,gBAAgB,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7C,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;CACzC;AAED;;;GAGG;AACH,eAAO,MAAM,wCAAwC,2BAA4B,CAAC;AAElF,eAAO,MAAM,uBAAuB,EAAE,QAAQ,CAAC,MAAM,CAAC,UAAU,EAAE,sBAAsB,CAAC,CAyCxF,CAAC"}
|
package/dist/expo/manifest.js
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import { Permission } from '../registry/permissions';
|
|
2
|
+
/***
|
|
3
|
+
* Expo packages required by the permission client independently of a specific
|
|
4
|
+
* permission capability.
|
|
5
|
+
*/
|
|
6
|
+
export const EXPO_PERMISSION_CLIENT_REQUIRED_PACKAGES = ['expo-linking'];
|
|
2
7
|
export const EXPO_PERMISSION_SUPPORT = {
|
|
3
8
|
[Permission.Camera]: {
|
|
4
9
|
support: 'supported',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/expo/manifest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/expo/manifest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAWrD;;;GAGG;AACH,MAAM,CAAC,MAAM,wCAAwC,GAAG,CAAC,cAAc,CAAU,CAAC;AAElF,MAAM,CAAC,MAAM,uBAAuB,GAAyD;IAC3F,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE;QACnB,OAAO,EAAE,WAAW;QACpB,gBAAgB,EAAE,CAAC,aAAa,CAAC;QACjC,WAAW,EAAE,CAAC,kBAAkB,CAAC;KAClC;IACD,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE;QACvB,OAAO,EAAE,WAAW;QACpB,gBAAgB,EAAE,CAAC,YAAY,CAAC;QAChC,WAAW,EAAE,CAAC,sBAAsB,EAAE,oBAAoB,CAAC;KAC5D;IACD,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE;QACzB,OAAO,EAAE,WAAW;QACpB,gBAAgB,EAAE,CAAC,oBAAoB,CAAC;QACxC,WAAW,EAAE,CAAC,wBAAwB,CAAC;KACxC;IACD,CAAC,UAAU,CAAC,iBAAiB,CAAC,EAAE;QAC9B,OAAO,EAAE,WAAW;QACpB,gBAAgB,EAAE,CAAC,oBAAoB,CAAC;QACxC,WAAW,EAAE,CAAC,wBAAwB,CAAC;KACxC;IACD,CAAC,UAAU,CAAC,kBAAkB,CAAC,EAAE;QAC/B,OAAO,EAAE,WAAW;QACpB,gBAAgB,EAAE,CAAC,eAAe,CAAC;QACnC,WAAW,EAAE,CAAC,6BAA6B,CAAC;KAC7C;IACD,CAAC,UAAU,CAAC,kBAAkB,CAAC,EAAE;QAC/B,OAAO,EAAE,WAAW;QACpB,gBAAgB,EAAE,CAAC,eAAe,CAAC;QACnC,WAAW,EAAE,CAAC,sCAAsC,CAAC;KACtD;IACD,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE;QAC1B,OAAO,EAAE,WAAW;QACpB,gBAAgB,EAAE,CAAC,oBAAoB,CAAC;QACxC,WAAW,EAAE,CAAC,yBAAyB,CAAC;KACzC;IACD,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE;QACtB,OAAO,EAAE,aAAa;QACtB,gBAAgB,EAAE,EAAE;QACpB,WAAW,EAAE,EAAE;KAChB;CACF,CAAC","sourcesContent":["import { Permission } from '../registry/permissions';\n\nexport type PermissionSupport =\n 'supported' | 'notRequired' | 'limited' | 'notImplemented' | 'unsupported';\n\nexport interface ExpoPermissionMetadata {\n readonly support: PermissionSupport;\n readonly requiredPackages: readonly string[];\n readonly configHints: readonly string[];\n}\n\n/***\n * Expo packages required by the permission client independently of a specific\n * permission capability.\n */\nexport const EXPO_PERMISSION_CLIENT_REQUIRED_PACKAGES = ['expo-linking'] as const;\n\nexport const EXPO_PERMISSION_SUPPORT: Readonly<Record<Permission, ExpoPermissionMetadata>> = {\n [Permission.Camera]: {\n support: 'supported',\n requiredPackages: ['expo-camera'],\n configHints: ['cameraPermission'],\n },\n [Permission.Microphone]: {\n support: 'supported',\n requiredPackages: ['expo-audio'],\n configHints: ['microphonePermission', 'recordAudioAndroid'],\n },\n [Permission.MediaLibrary]: {\n support: 'supported',\n requiredPackages: ['expo-media-library'],\n configHints: ['mediaLibraryPermission'],\n },\n [Permission.MediaLibraryWrite]: {\n support: 'supported',\n requiredPackages: ['expo-media-library'],\n configHints: ['mediaLibraryPermission'],\n },\n [Permission.LocationForeground]: {\n support: 'supported',\n requiredPackages: ['expo-location'],\n configHints: ['locationWhenInUsePermission'],\n },\n [Permission.LocationBackground]: {\n support: 'supported',\n requiredPackages: ['expo-location'],\n configHints: ['locationAlwaysAndWhenInUsePermission'],\n },\n [Permission.Notifications]: {\n support: 'supported',\n requiredPackages: ['expo-notifications'],\n configHints: ['notificationsPermission'],\n },\n [Permission.Clipboard]: {\n support: 'notRequired',\n requiredPackages: [],\n configHints: [],\n },\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"permissionResponse.d.ts","sourceRoot":"","sources":["../../src/expo/permissionResponse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAGL,KAAK,eAAe,
|
|
1
|
+
{"version":3,"file":"permissionResponse.d.ts","sourceRoot":"","sources":["../../src/expo/permissionResponse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAGL,KAAK,eAAe,EAErB,MAAM,0BAA0B,CAAC;AAElC,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;CAChC;AAED,MAAM,MAAM,oBAAoB,GAAG,MAAM,OAAO,CAAC,sBAAsB,CAAC,CAAC;AAEzE,wBAAgB,yBAAyB,CACvC,UAAU,EAAE,UAAU,EACtB,QAAQ,EAAE,sBAAsB,GAC/B,eAAe,CAIjB;AAED,wBAAgB,0BAA0B,CACxC,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,OAAO,GACb,eAAe,CAMjB;AAED,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,OAAO,EACf,UAAU,EAAE,MAAM,EAClB,cAAc,GAAE,SAAS,MAAM,EAAO,GACrC,oBAAoB,GAAG,SAAS,CAkBlC"}
|
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
import { createPermissionState, isPermissionStatus, } from '../state/permissionState';
|
|
2
2
|
export function createExpoPermissionState(permission, response) {
|
|
3
3
|
const status = isPermissionStatus(response.status) ? response.status : 'unknown';
|
|
4
|
-
return
|
|
5
|
-
permission,
|
|
6
|
-
status,
|
|
7
|
-
canAskAgain: response.canAskAgain,
|
|
8
|
-
});
|
|
4
|
+
return createNormalizedExpoPermissionState(permission, response, status);
|
|
9
5
|
}
|
|
10
6
|
export function createExpoUnavailableState(permission, error) {
|
|
11
7
|
return createPermissionState({
|
|
@@ -16,15 +12,15 @@ export function createExpoUnavailableState(permission, error) {
|
|
|
16
12
|
}
|
|
17
13
|
export function findExpoPermissionMethod(source, methodName, containerNames = []) {
|
|
18
14
|
if (hasExpoPermissionMethod(source, methodName)) {
|
|
19
|
-
return source
|
|
15
|
+
return Reflect.get(source, methodName);
|
|
20
16
|
}
|
|
21
17
|
if (!isRecord(source)) {
|
|
22
18
|
return undefined;
|
|
23
19
|
}
|
|
24
20
|
for (const containerName of containerNames) {
|
|
25
|
-
const container = source
|
|
21
|
+
const container = Reflect.get(source, containerName);
|
|
26
22
|
if (hasExpoPermissionMethod(container, methodName)) {
|
|
27
|
-
return container
|
|
23
|
+
return Reflect.get(container, methodName);
|
|
28
24
|
}
|
|
29
25
|
}
|
|
30
26
|
return undefined;
|
|
@@ -38,8 +34,19 @@ function getExpoPermissionErrorMessage(error) {
|
|
|
38
34
|
}
|
|
39
35
|
return 'Expo permission operation failed.';
|
|
40
36
|
}
|
|
37
|
+
function createNormalizedExpoPermissionState(permission, response, status, reason) {
|
|
38
|
+
const normalizedStatus = status === 'denied' && response.canAskAgain === false ? 'blocked' : status;
|
|
39
|
+
return createPermissionState({
|
|
40
|
+
permission,
|
|
41
|
+
status: normalizedStatus,
|
|
42
|
+
canAskAgain: response.canAskAgain,
|
|
43
|
+
reason: normalizedStatus === 'blocked'
|
|
44
|
+
? 'Permission is blocked. Open system settings to change it.'
|
|
45
|
+
: reason,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
41
48
|
function hasExpoPermissionMethod(value, methodName) {
|
|
42
|
-
return isRecord(value) && typeof value
|
|
49
|
+
return isRecord(value) && typeof Reflect.get(value, methodName) === 'function';
|
|
43
50
|
}
|
|
44
51
|
function isRecord(value) {
|
|
45
52
|
return typeof value === 'object' && value !== null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"permissionResponse.js","sourceRoot":"","sources":["../../src/expo/permissionResponse.ts"],"names":[],"mappings":"AACA,OAAO,EACL,qBAAqB,EACrB,kBAAkB,
|
|
1
|
+
{"version":3,"file":"permissionResponse.js","sourceRoot":"","sources":["../../src/expo/permissionResponse.ts"],"names":[],"mappings":"AACA,OAAO,EACL,qBAAqB,EACrB,kBAAkB,GAGnB,MAAM,0BAA0B,CAAC;AASlC,MAAM,UAAU,yBAAyB,CACvC,UAAsB,EACtB,QAAgC;IAEhC,MAAM,MAAM,GAAG,kBAAkB,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;IAEjF,OAAO,mCAAmC,CAAC,UAAU,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;AAC3E,CAAC;AAED,MAAM,UAAU,0BAA0B,CACxC,UAAsB,EACtB,KAAc;IAEd,OAAO,qBAAqB,CAAC;QAC3B,UAAU;QACV,MAAM,EAAE,aAAa;QACrB,MAAM,EAAE,6BAA6B,CAAC,KAAK,CAAC;KAC7C,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,wBAAwB,CACtC,MAAe,EACf,UAAkB,EAClB,iBAAoC,EAAE;IAEtC,IAAI,uBAAuB,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,CAAC;QAChD,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACzC,CAAC;IAED,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACtB,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,KAAK,MAAM,aAAa,IAAI,cAAc,EAAE,CAAC;QAC3C,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;QAErD,IAAI,uBAAuB,CAAC,SAAS,EAAE,UAAU,CAAC,EAAE,CAAC;YACnD,OAAO,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,6BAA6B,CAAC,KAAc;IACnD,IAAI,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvD,OAAO,KAAK,CAAC,OAAO,CAAC;IACvB,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,mCAAmC,CAAC;AAC7C,CAAC;AAED,SAAS,mCAAmC,CAC1C,UAAsB,EACtB,QAAgC,EAChC,MAAwB,EACxB,MAAe;IAEf,MAAM,gBAAgB,GACpB,MAAM,KAAK,QAAQ,IAAI,QAAQ,CAAC,WAAW,KAAK,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC;IAE7E,OAAO,qBAAqB,CAAC;QAC3B,UAAU;QACV,MAAM,EAAE,gBAAgB;QACxB,WAAW,EAAE,QAAQ,CAAC,WAAW;QACjC,MAAM,EACJ,gBAAgB,KAAK,SAAS;YAC5B,CAAC,CAAC,2DAA2D;YAC7D,CAAC,CAAC,MAAM;KACb,CAAC,CAAC;AACL,CAAC;AAED,SAAS,uBAAuB,CAC9B,KAAc,EACd,UAAkB;IAElB,OAAO,QAAQ,CAAC,KAAK,CAAC,IAAI,OAAO,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,UAAU,CAAC,KAAK,UAAU,CAAC;AACjF,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC;AACrD,CAAC","sourcesContent":["import type { Permission } from '../registry/permissions';\nimport {\n createPermissionState,\n isPermissionStatus,\n type PermissionState,\n type PermissionStatus,\n} from '../state/permissionState';\n\nexport interface ExpoPermissionResponse {\n readonly status: string;\n readonly canAskAgain?: boolean;\n}\n\nexport type ExpoPermissionMethod = () => Promise<ExpoPermissionResponse>;\n\nexport function createExpoPermissionState(\n permission: Permission,\n response: ExpoPermissionResponse,\n): PermissionState {\n const status = isPermissionStatus(response.status) ? response.status : 'unknown';\n\n return createNormalizedExpoPermissionState(permission, response, status);\n}\n\nexport function createExpoUnavailableState(\n permission: Permission,\n error: unknown,\n): PermissionState {\n return createPermissionState({\n permission,\n status: 'unavailable',\n reason: getExpoPermissionErrorMessage(error),\n });\n}\n\nexport function findExpoPermissionMethod(\n source: unknown,\n methodName: string,\n containerNames: readonly string[] = [],\n): ExpoPermissionMethod | undefined {\n if (hasExpoPermissionMethod(source, methodName)) {\n return Reflect.get(source, methodName);\n }\n\n if (!isRecord(source)) {\n return undefined;\n }\n\n for (const containerName of containerNames) {\n const container = Reflect.get(source, containerName);\n\n if (hasExpoPermissionMethod(container, methodName)) {\n return Reflect.get(container, methodName);\n }\n }\n\n return undefined;\n}\n\nfunction getExpoPermissionErrorMessage(error: unknown): string {\n if (error instanceof Error && error.message.length > 0) {\n return error.message;\n }\n\n if (typeof error === 'string' && error.length > 0) {\n return error;\n }\n\n return 'Expo permission operation failed.';\n}\n\nfunction createNormalizedExpoPermissionState(\n permission: Permission,\n response: ExpoPermissionResponse,\n status: PermissionStatus,\n reason?: string,\n): PermissionState {\n const normalizedStatus =\n status === 'denied' && response.canAskAgain === false ? 'blocked' : status;\n\n return createPermissionState({\n permission,\n status: normalizedStatus,\n canAskAgain: response.canAskAgain,\n reason:\n normalizedStatus === 'blocked'\n ? 'Permission is blocked. Open system settings to change it.'\n : reason,\n });\n}\n\nfunction hasExpoPermissionMethod(\n value: unknown,\n methodName: string,\n): value is Record<string, ExpoPermissionMethod> {\n return isRecord(value) && typeof Reflect.get(value, methodName) === 'function';\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,SAAS,EAMf,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAEL,KAAK,iBAAiB,EACvB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAGL,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACtB,MAAM,0BAA0B,CAAC;AAIlC;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC;IAC7B,QAAQ,CAAC,MAAM,CAAC,EAAE,gBAAgB,CAAC;IACnC,QAAQ,CAAC,OAAO,CAAC,EAAE,iBAAiB,CAAC;CACtC;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,YAAY,CAAC,EAAE,eAAe,CAAC;IACxC,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAClC,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,WAAW,CAAC,EAAE,IAAI,CAAC;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAC;IAChC,QAAQ,CAAC,OAAO,EAAE,MAAM,OAAO,CAAC,eAAe,CAAC,CAAC;IACjD,QAAQ,CAAC,OAAO,EAAE,MAAM,OAAO,CAAC,eAAe,CAAC,CAAC;IACjD,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7C;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,QAAQ,EACR,MAAM,EACN,OAAO,GACR,EAAE,wBAAwB,GAAG,SAAS,CActC;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,iBAAiB,CAQlD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC3B,UAAU,EAAE,UAAU,EACtB,OAAO,GAAE,oBAAyB,GACjC,oBAAoB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,SAAS,EAMf,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAEL,KAAK,iBAAiB,EACvB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAGL,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACtB,MAAM,0BAA0B,CAAC;AAIlC;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC;IAC7B,QAAQ,CAAC,MAAM,CAAC,EAAE,gBAAgB,CAAC;IACnC,QAAQ,CAAC,OAAO,CAAC,EAAE,iBAAiB,CAAC;CACtC;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,YAAY,CAAC,EAAE,eAAe,CAAC;IACxC,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAClC,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,WAAW,CAAC,EAAE,IAAI,CAAC;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAC;IAChC,QAAQ,CAAC,OAAO,EAAE,MAAM,OAAO,CAAC,eAAe,CAAC,CAAC;IACjD,QAAQ,CAAC,OAAO,EAAE,MAAM,OAAO,CAAC,eAAe,CAAC,CAAC;IACjD,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7C;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,QAAQ,EACR,MAAM,EACN,OAAO,GACR,EAAE,wBAAwB,GAAG,SAAS,CActC;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,iBAAiB,CAQlD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC3B,UAAU,EAAE,UAAU,EACtB,OAAO,GAAE,oBAAyB,GACjC,oBAAoB,CAgDtB"}
|
package/dist/react/index.js
CHANGED
|
@@ -36,13 +36,7 @@ export function usePermissions() {
|
|
|
36
36
|
*/
|
|
37
37
|
export function usePermission(permission, options = {}) {
|
|
38
38
|
const manager = usePermissions();
|
|
39
|
-
const [state, setState] = useState(() => (options.initialState
|
|
40
|
-
? undefined
|
|
41
|
-
: normalizePermissionState(permission, options.initialState)) ??
|
|
42
|
-
createPermissionState({
|
|
43
|
-
permission,
|
|
44
|
-
status: 'unknown',
|
|
45
|
-
}));
|
|
39
|
+
const [state, setState] = useState(() => createInitialPermissionState(permission, options.initialState));
|
|
46
40
|
const refresh = useCallback(async () => {
|
|
47
41
|
const nextState = await manager.getStatus(permission);
|
|
48
42
|
setState(nextState);
|
|
@@ -54,10 +48,17 @@ export function usePermission(permission, options = {}) {
|
|
|
54
48
|
return nextState;
|
|
55
49
|
}, [manager, permission]);
|
|
56
50
|
useEffect(() => {
|
|
57
|
-
if (options.refreshOnMount
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
51
|
+
if (options.refreshOnMount !== true)
|
|
52
|
+
return;
|
|
53
|
+
let active = true;
|
|
54
|
+
void manager.getStatus(permission).then((nextState) => {
|
|
55
|
+
if (active)
|
|
56
|
+
setState(nextState);
|
|
57
|
+
});
|
|
58
|
+
return () => {
|
|
59
|
+
active = false;
|
|
60
|
+
};
|
|
61
|
+
}, [manager, options.refreshOnMount, permission]);
|
|
61
62
|
const openSettings = manager.openSettings === undefined
|
|
62
63
|
? undefined
|
|
63
64
|
: () => manager.openSettings?.() ?? Promise.resolve();
|
|
@@ -74,4 +75,8 @@ export function usePermission(permission, options = {}) {
|
|
|
74
75
|
openSettings,
|
|
75
76
|
};
|
|
76
77
|
}
|
|
78
|
+
function createInitialPermissionState(permission, initialState) {
|
|
79
|
+
return ((initialState === undefined ? undefined : normalizePermissionState(permission, initialState)) ??
|
|
80
|
+
createPermissionState({ permission, status: 'unknown' }));
|
|
81
|
+
}
|
|
77
82
|
//# sourceMappingURL=index.js.map
|
package/dist/react/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,aAAa,EAEb,WAAW,EACX,UAAU,EACV,SAAS,EACT,OAAO,EACP,QAAQ,GACT,MAAM,OAAO,CAAC;AAGf,OAAO,EACL,uBAAuB,GAExB,MAAM,oCAAoC,CAAC;AAE5C,OAAO,EACL,qBAAqB,EACrB,wBAAwB,GAGzB,MAAM,0BAA0B,CAAC;AAElC,MAAM,kBAAkB,GAAG,aAAa,CAAgC,SAAS,CAAC,CAAC;AAmCnF;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CAAC,EAClC,QAAQ,EACR,MAAM,EACN,OAAO,GACkB;IACzB,MAAM,eAAe,GAAG,OAAO,CAAC,GAAG,EAAE;QACnC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,OAAO,OAAO,CAAC;QACjB,CAAC;QAED,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,OAAO,uBAAuB,CAAC,MAAM,CAAC,CAAC;QACzC,CAAC;QAED,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;IACvE,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAEtB,OAAO,aAAa,CAAC,kBAAkB,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,eAAe,EAAE,EAAE,QAAQ,CAAC,CAAC;AAC1F,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc;IAC5B,MAAM,OAAO,GAAG,UAAU,CAAC,kBAAkB,CAAC,CAAC;IAE/C,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAC;IAC7E,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAC3B,UAAsB,EACtB,UAAgC,EAAE;IAElC,MAAM,OAAO,GAAG,cAAc,EAAE,CAAC;IACjC,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react/index.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n createContext,\n createElement,\n type ReactNode,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n} from 'react';\n\nimport type { PermissionClient } from '../client/types';\nimport {\n createPermissionManager,\n type PermissionManager,\n} from '../manager/createPermissionManager';\nimport type { Permission } from '../registry/permissions';\nimport {\n createPermissionState,\n normalizePermissionState,\n type PermissionState,\n type PermissionStatus,\n} from '../state/permissionState';\n\nconst PermissionsContext = createContext<PermissionManager | undefined>(undefined);\n\n/***\n * Props accepted by `PermissionsProvider`.\n */\nexport interface PermissionsProviderProps {\n readonly children: ReactNode;\n readonly client?: PermissionClient;\n readonly manager?: PermissionManager;\n}\n\n/***\n * Options for `usePermission`.\n */\nexport interface UsePermissionOptions {\n readonly initialState?: PermissionState;\n readonly refreshOnMount?: boolean;\n}\n\n/***\n * Result returned by `usePermission`.\n */\nexport interface PermissionHookResult {\n readonly permission: Permission;\n readonly status: PermissionStatus;\n readonly canAskAgain?: boolean;\n readonly granted: boolean;\n readonly requestedAt?: Date;\n readonly reason?: string;\n readonly state: PermissionState;\n readonly refresh: () => Promise<PermissionState>;\n readonly request: () => Promise<PermissionState>;\n readonly openSettings?: () => Promise<void>;\n}\n\n/***\n * Provides a permission manager to React hooks.\n *\n * @readme\n * React helpers are framework-neutral. They depend on React only and do not\n * import browser, Expo, or React Native permission APIs.\n */\nexport function PermissionsProvider({\n children,\n client,\n manager,\n}: PermissionsProviderProps): ReactNode {\n const resolvedManager = useMemo(() => {\n if (manager !== undefined) {\n return manager;\n }\n\n if (client !== undefined) {\n return createPermissionManager(client);\n }\n\n throw new Error('PermissionsProvider requires a client or manager.');\n }, [client, manager]);\n\n return createElement(PermissionsContext.Provider, { value: resolvedManager }, children);\n}\n\n/***\n * Reads the current permission manager from context.\n */\nexport function usePermissions(): PermissionManager {\n const manager = useContext(PermissionsContext);\n\n if (manager === undefined) {\n throw new Error('usePermissions must be used within PermissionsProvider.');\n }\n\n return manager;\n}\n\n/***\n * Tracks a single permission and exposes explicit refresh/request actions.\n */\nexport function usePermission(\n permission: Permission,\n options: UsePermissionOptions = {},\n): PermissionHookResult {\n const manager = usePermissions();\n const [state, setState] = useState<PermissionState>(() =>\n createInitialPermissionState(permission, options.initialState),\n );\n\n const refresh = useCallback(async () => {\n const nextState = await manager.getStatus(permission);\n setState(nextState);\n\n return nextState;\n }, [manager, permission]);\n\n const request = useCallback(async () => {\n const nextState = await manager.request(permission);\n setState(nextState);\n\n return nextState;\n }, [manager, permission]);\n\n useEffect(() => {\n if (options.refreshOnMount !== true) return;\n let active = true;\n void manager.getStatus(permission).then((nextState) => {\n if (active) setState(nextState);\n });\n return () => {\n active = false;\n };\n }, [manager, options.refreshOnMount, permission]);\n\n const openSettings =\n manager.openSettings === undefined\n ? undefined\n : () => manager.openSettings?.() ?? Promise.resolve();\n\n return {\n permission: state.permission,\n status: state.status,\n canAskAgain: state.canAskAgain,\n granted: state.granted,\n requestedAt: state.requestedAt,\n reason: state.reason,\n state,\n refresh,\n request,\n openSettings,\n };\n}\n\nfunction createInitialPermissionState(\n permission: Permission,\n initialState: PermissionState | undefined,\n): PermissionState {\n return (\n (initialState === undefined ? undefined : normalizePermissionState(permission, initialState)) ??\n createPermissionState({ permission, status: 'unknown' })\n );\n}\n"]}
|
|
@@ -34,6 +34,8 @@ export interface CreatePermissionStateInput {
|
|
|
34
34
|
export declare function isPermissionStatus(value: string): value is PermissionStatus;
|
|
35
35
|
/***
|
|
36
36
|
* Creates a normalized state and derives the `granted` convenience flag.
|
|
37
|
+
* Limited access is usable partial authorization, so both `granted` and
|
|
38
|
+
* `limited` states set `granted` to true.
|
|
37
39
|
*/
|
|
38
40
|
export declare function createPermissionState(input: CreatePermissionStateInput): PermissionState;
|
|
39
41
|
/***
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"permissionState.d.ts","sourceRoot":"","sources":["../../src/state/permissionState.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAE1D;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB,
|
|
1
|
+
{"version":3,"file":"permissionState.d.ts","sourceRoot":"","sources":["../../src/state/permissionState.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAE1D;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB,GAC1B,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,aAAa,CAAC;AAE3E;;GAEG;AACH,eAAO,MAAM,mBAAmB,gFAOgB,CAAC;AAIjD;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAClC,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,WAAW,CAAC,EAAE,IAAI,CAAC;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAClC,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,WAAW,CAAC,EAAE,IAAI,CAAC;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,gBAAgB,CAE3E;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,0BAA0B,GAAG,eAAe,CASxF;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,eAAe,GACrB,eAAe,CAQjB"}
|
|
@@ -18,13 +18,15 @@ export function isPermissionStatus(value) {
|
|
|
18
18
|
}
|
|
19
19
|
/***
|
|
20
20
|
* Creates a normalized state and derives the `granted` convenience flag.
|
|
21
|
+
* Limited access is usable partial authorization, so both `granted` and
|
|
22
|
+
* `limited` states set `granted` to true.
|
|
21
23
|
*/
|
|
22
24
|
export function createPermissionState(input) {
|
|
23
25
|
return {
|
|
24
26
|
permission: input.permission,
|
|
25
27
|
status: input.status,
|
|
26
28
|
canAskAgain: input.canAskAgain,
|
|
27
|
-
granted: input.status === 'granted',
|
|
29
|
+
granted: input.status === 'granted' || input.status === 'limited',
|
|
28
30
|
requestedAt: input.requestedAt,
|
|
29
31
|
reason: input.reason,
|
|
30
32
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"permissionState.js","sourceRoot":"","sources":["../../src/state/permissionState.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"permissionState.js","sourceRoot":"","sources":["../../src/state/permissionState.ts"],"names":[],"mappings":"AAWA;;GAEG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,SAAS;IACT,SAAS;IACT,QAAQ;IACR,SAAS;IACT,SAAS;IACT,aAAa;CACiC,CAAC;AAEjD,MAAM,qBAAqB,GAAG,IAAI,GAAG,CAAS,mBAAmB,CAAC,CAAC;AAsBnE;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAa;IAC9C,OAAO,qBAAqB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AAC1C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAAiC;IACrE,OAAO;QACL,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,OAAO,EAAE,KAAK,CAAC,MAAM,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS;QACjE,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,MAAM,EAAE,KAAK,CAAC,MAAM;KACrB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,wBAAwB,CACtC,UAAsB,EACtB,KAAsB;IAEtB,OAAO,qBAAqB,CAAC;QAC3B,UAAU;QACV,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,MAAM,EAAE,KAAK,CAAC,MAAM;KACrB,CAAC,CAAC;AACL,CAAC","sourcesContent":["import type { Permission } from '../registry/permissions';\n\n/***\n * Normalized permission statuses shared by adapters and UI code.\n *\n * Denial is normal control flow. Unexpected adapter failures may still throw,\n * but user denial should be represented as a permission state.\n */\nexport type PermissionStatus =\n 'unknown' | 'granted' | 'denied' | 'blocked' | 'limited' | 'unavailable';\n\n/***\n * Stable ordered list of normalized statuses.\n */\nexport const PERMISSION_STATUSES = [\n 'unknown',\n 'granted',\n 'denied',\n 'blocked',\n 'limited',\n 'unavailable',\n] as const satisfies readonly PermissionStatus[];\n\nconst PERMISSION_STATUS_SET = new Set<string>(PERMISSION_STATUSES);\n\n/***\n * Normalized result returned by permission clients and managers.\n */\nexport interface PermissionState {\n readonly permission: Permission;\n readonly status: PermissionStatus;\n readonly canAskAgain?: boolean;\n readonly granted: boolean;\n readonly requestedAt?: Date;\n readonly reason?: string;\n}\n\nexport interface CreatePermissionStateInput {\n readonly permission: Permission;\n readonly status: PermissionStatus;\n readonly canAskAgain?: boolean;\n readonly requestedAt?: Date;\n readonly reason?: string;\n}\n\n/***\n * Returns true when a string is one of the normalized statuses.\n */\nexport function isPermissionStatus(value: string): value is PermissionStatus {\n return PERMISSION_STATUS_SET.has(value);\n}\n\n/***\n * Creates a normalized state and derives the `granted` convenience flag.\n * Limited access is usable partial authorization, so both `granted` and\n * `limited` states set `granted` to true.\n */\nexport function createPermissionState(input: CreatePermissionStateInput): PermissionState {\n return {\n permission: input.permission,\n status: input.status,\n canAskAgain: input.canAskAgain,\n granted: input.status === 'granted' || input.status === 'limited',\n requestedAt: input.requestedAt,\n reason: input.reason,\n };\n}\n\n/***\n * Normalizes an adapter result to the requested permission and status shape.\n */\nexport function normalizePermissionState(\n permission: Permission,\n state: PermissionState,\n): PermissionState {\n return createPermissionState({\n permission,\n status: state.status,\n canAskAgain: state.canAskAgain,\n requestedAt: state.requestedAt,\n reason: state.reason,\n });\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAE1D,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACtB,MAAM,0BAA0B,CAAC;AAElC;;GAEG;AACH,MAAM,MAAM,uBAAuB,GAC/B,eAAe,GACf;IACE,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAClC,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEN;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,uBAAuB,EAAE,CAAC;IAC5D,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,uBAAuB,EAAE,CAAC;IAC5D,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7C;AAED;;GAEG;AACH,MAAM,WAAW,oBAAqB,SAAQ,gBAAgB;IAC5D,QAAQ,CAAC,KAAK,EAAE,uBAAuB,GAAG,IAAI,CAAC;IAC/C,SAAS,CACP,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,gBAAgB,EACxB,OAAO,CAAC,EAAE;QACR,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;QAC/B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;KAC1B,GACA,IAAI,CAAC;IACR,WAAW,IAAI,SAAS,eAAe,EAAE,CAAC;CAC3C;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAE1D,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACtB,MAAM,0BAA0B,CAAC;AAElC;;GAEG;AACH,MAAM,MAAM,uBAAuB,GAC/B,eAAe,GACf;IACE,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAClC,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEN;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,uBAAuB,EAAE,CAAC;IAC5D,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,uBAAuB,EAAE,CAAC;IAC5D,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7C;AAED;;GAEG;AACH,MAAM,WAAW,oBAAqB,SAAQ,gBAAgB;IAC5D,QAAQ,CAAC,KAAK,EAAE,uBAAuB,GAAG,IAAI,CAAC;IAC/C,SAAS,CACP,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,gBAAgB,EACxB,OAAO,CAAC,EAAE;QACR,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;QAC/B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;KAC1B,GACA,IAAI,CAAC;IACR,WAAW,IAAI,SAAS,eAAe,EAAE,CAAC;CAC3C;AAQD;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CACxC,OAAO,GAAE,2BAAgC,GACxC,oBAAoB,CAKtB"}
|
package/dist/testing/index.js
CHANGED
|
@@ -8,47 +8,60 @@ import { createPermissionState, } from '../state/permissionState';
|
|
|
8
8
|
* prompts, simulators, or network access.
|
|
9
9
|
*/
|
|
10
10
|
export function createFakePermissionClient(options = {}) {
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
|
|
11
|
+
const context = createFakePermissionContext(options);
|
|
12
|
+
const client = createFakePermissionOperations(context, options.openSettings);
|
|
13
|
+
if (options.openSettings === undefined)
|
|
14
|
+
delete client.openSettings;
|
|
15
|
+
return client;
|
|
16
|
+
}
|
|
17
|
+
function createFakePermissionContext(options) {
|
|
18
|
+
const context = {
|
|
19
|
+
now: options.now ?? (() => new Date()),
|
|
20
|
+
states: new Map(),
|
|
21
|
+
requestStates: new Map(),
|
|
22
|
+
};
|
|
14
23
|
for (const permission of PERMISSIONS) {
|
|
15
|
-
states.set(permission, createPermissionState({
|
|
24
|
+
context.states.set(permission, createPermissionState({
|
|
16
25
|
permission,
|
|
17
26
|
status: 'unknown',
|
|
18
27
|
canAskAgain: true,
|
|
19
28
|
}));
|
|
20
29
|
}
|
|
21
30
|
for (const state of options.initialStates ?? []) {
|
|
22
|
-
states.set(state.permission, normalizeSeed(state));
|
|
31
|
+
context.states.set(state.permission, normalizeSeed(state));
|
|
23
32
|
}
|
|
24
33
|
for (const state of options.requestStates ?? []) {
|
|
25
|
-
requestStates.set(state.permission, normalizeSeed(state));
|
|
34
|
+
context.requestStates.set(state.permission, normalizeSeed(state));
|
|
26
35
|
}
|
|
36
|
+
return context;
|
|
37
|
+
}
|
|
38
|
+
function createFakePermissionOperations(context, openSettings) {
|
|
27
39
|
const client = {
|
|
28
40
|
getStatus(permission) {
|
|
29
|
-
return Promise.resolve(getStoredState(states, assertKnownPermission(permission)));
|
|
41
|
+
return Promise.resolve(getStoredState(context.states, assertKnownPermission(permission)));
|
|
30
42
|
},
|
|
31
43
|
request(permission) {
|
|
32
44
|
const knownPermission = assertKnownPermission(permission);
|
|
33
|
-
const requestState = requestStates.get(knownPermission) ??
|
|
45
|
+
const requestState = context.requestStates.get(knownPermission) ??
|
|
46
|
+
getStoredState(context.states, knownPermission);
|
|
34
47
|
const nextState = createPermissionState({
|
|
35
48
|
permission: knownPermission,
|
|
36
49
|
status: requestState.status,
|
|
37
50
|
canAskAgain: requestState.canAskAgain,
|
|
38
|
-
requestedAt: now(),
|
|
51
|
+
requestedAt: context.now(),
|
|
39
52
|
reason: requestState.reason,
|
|
40
53
|
});
|
|
41
|
-
states.set(knownPermission, nextState);
|
|
54
|
+
context.states.set(knownPermission, nextState);
|
|
42
55
|
return Promise.resolve(nextState);
|
|
43
56
|
},
|
|
44
|
-
openSettings
|
|
57
|
+
openSettings,
|
|
45
58
|
setState(state) {
|
|
46
59
|
const normalizedState = normalizeSeed(state);
|
|
47
|
-
states.set(normalizedState.permission, normalizedState);
|
|
60
|
+
context.states.set(normalizedState.permission, normalizedState);
|
|
48
61
|
},
|
|
49
62
|
setStatus(permission, status, statusOptions = {}) {
|
|
50
63
|
const knownPermission = assertKnownPermission(permission);
|
|
51
|
-
states.set(knownPermission, createPermissionState({
|
|
64
|
+
context.states.set(knownPermission, createPermissionState({
|
|
52
65
|
permission: knownPermission,
|
|
53
66
|
status,
|
|
54
67
|
canAskAgain: statusOptions.canAskAgain,
|
|
@@ -56,12 +69,9 @@ export function createFakePermissionClient(options = {}) {
|
|
|
56
69
|
}));
|
|
57
70
|
},
|
|
58
71
|
getSnapshot() {
|
|
59
|
-
return PERMISSIONS.map((permission) => getStoredState(states, permission));
|
|
72
|
+
return PERMISSIONS.map((permission) => getStoredState(context.states, permission));
|
|
60
73
|
},
|
|
61
74
|
};
|
|
62
|
-
if (options.openSettings === undefined) {
|
|
63
|
-
delete client.openSettings;
|
|
64
|
-
}
|
|
65
75
|
return client;
|
|
66
76
|
}
|
|
67
77
|
function normalizeSeed(seed) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC7E,OAAO,EACL,qBAAqB,GAGtB,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"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","sourcesContent":["import type { PermissionClient } from '../client/types';\nimport type { Permission } from '../registry/permissions';\nimport { assertKnownPermission, PERMISSIONS } from '../registry/permissions';\nimport {\n createPermissionState,\n type PermissionState,\n type PermissionStatus,\n} from '../state/permissionState';\n\n/***\n * Seed format accepted by the fake client.\n */\nexport type FakePermissionStateSeed =\n | PermissionState\n | {\n readonly permission: Permission;\n readonly status: PermissionStatus;\n readonly canAskAgain?: boolean;\n readonly reason?: string;\n };\n\n/***\n * Options for deterministic fake clients.\n */\nexport interface FakePermissionClientOptions {\n readonly initialStates?: readonly FakePermissionStateSeed[];\n readonly requestStates?: readonly FakePermissionStateSeed[];\n readonly now?: () => Date;\n readonly openSettings?: () => Promise<void>;\n}\n\n/***\n * Test client that stores permission states in memory.\n */\nexport interface FakePermissionClient extends PermissionClient {\n setState(state: FakePermissionStateSeed): void;\n setStatus(\n permission: Permission,\n status: PermissionStatus,\n options?: {\n readonly canAskAgain?: boolean;\n readonly reason?: string;\n },\n ): void;\n getSnapshot(): readonly PermissionState[];\n}\n\ninterface FakePermissionContext {\n readonly now: () => Date;\n readonly requestStates: Map<Permission, PermissionState>;\n readonly states: Map<Permission, PermissionState>;\n}\n\n/***\n * Creates a deterministic in-memory client for tests and examples.\n *\n * @readme\n * Fake clients make permission flows testable without native devices, browser\n * prompts, simulators, or network access.\n */\nexport function createFakePermissionClient(\n options: FakePermissionClientOptions = {},\n): FakePermissionClient {\n const context = createFakePermissionContext(options);\n const client = createFakePermissionOperations(context, options.openSettings);\n if (options.openSettings === undefined) delete client.openSettings;\n return client;\n}\n\nfunction createFakePermissionContext(options: FakePermissionClientOptions): FakePermissionContext {\n const context: FakePermissionContext = {\n now: options.now ?? (() => new Date()),\n states: new Map<Permission, PermissionState>(),\n requestStates: new Map<Permission, PermissionState>(),\n };\n\n for (const permission of PERMISSIONS) {\n context.states.set(\n permission,\n createPermissionState({\n permission,\n status: 'unknown',\n canAskAgain: true,\n }),\n );\n }\n\n for (const state of options.initialStates ?? []) {\n context.states.set(state.permission, normalizeSeed(state));\n }\n\n for (const state of options.requestStates ?? []) {\n context.requestStates.set(state.permission, normalizeSeed(state));\n }\n return context;\n}\n\nfunction createFakePermissionOperations(\n context: FakePermissionContext,\n openSettings: (() => Promise<void>) | undefined,\n): FakePermissionClient {\n const client: FakePermissionClient = {\n getStatus(permission) {\n return Promise.resolve(getStoredState(context.states, assertKnownPermission(permission)));\n },\n request(permission) {\n const knownPermission = assertKnownPermission(permission);\n const requestState =\n context.requestStates.get(knownPermission) ??\n getStoredState(context.states, knownPermission);\n const nextState = createPermissionState({\n permission: knownPermission,\n status: requestState.status,\n canAskAgain: requestState.canAskAgain,\n requestedAt: context.now(),\n reason: requestState.reason,\n });\n\n context.states.set(knownPermission, nextState);\n return Promise.resolve(nextState);\n },\n openSettings,\n setState(state) {\n const normalizedState = normalizeSeed(state);\n context.states.set(normalizedState.permission, normalizedState);\n },\n setStatus(permission, status, statusOptions = {}) {\n const knownPermission = assertKnownPermission(permission);\n context.states.set(\n knownPermission,\n createPermissionState({\n permission: knownPermission,\n status,\n canAskAgain: statusOptions.canAskAgain,\n reason: statusOptions.reason,\n }),\n );\n },\n getSnapshot() {\n return PERMISSIONS.map((permission) => getStoredState(context.states, permission));\n },\n };\n return client;\n}\n\nfunction normalizeSeed(seed: FakePermissionStateSeed): PermissionState {\n return createPermissionState({\n permission: assertKnownPermission(seed.permission),\n status: seed.status,\n canAskAgain: seed.canAskAgain,\n requestedAt: 'requestedAt' in seed ? seed.requestedAt : undefined,\n reason: seed.reason,\n });\n}\n\nfunction getStoredState(\n states: ReadonlyMap<Permission, PermissionState>,\n permission: Permission,\n): PermissionState {\n const state = states.get(permission);\n\n if (state === undefined) {\n return createPermissionState({\n permission,\n status: 'unknown',\n canAskAgain: true,\n });\n }\n\n return state;\n}\n"]}
|
package/dist/web/index.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { PermissionClient } from '../client/types';
|
|
2
|
+
import { type BrowserPermissionState, type NotificationPermissionState } from './permissionStates';
|
|
2
3
|
type BrowserPermissionName = 'camera' | 'microphone' | 'geolocation' | 'notifications';
|
|
3
|
-
type BrowserPermissionState = 'granted' | 'denied' | 'prompt';
|
|
4
|
-
type NotificationPermissionState = 'default' | 'denied' | 'granted';
|
|
5
4
|
interface BrowserPermissionStatus {
|
|
6
5
|
readonly state: BrowserPermissionState;
|
|
7
6
|
}
|
package/dist/web/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/web/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/web/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAGxD,OAAO,EACL,KAAK,sBAAsB,EAE3B,KAAK,2BAA2B,EAKjC,MAAM,oBAAoB,CAAC;AAE5B,KAAK,qBAAqB,GAAG,QAAQ,GAAG,YAAY,GAAG,aAAa,GAAG,eAAe,CAAC;AACvF,UAAU,uBAAuB;IAC/B,QAAQ,CAAC,KAAK,EAAE,sBAAsB,CAAC;CACxC;AAED,UAAU,kBAAkB;IAC1B,KAAK,CAAC,UAAU,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,qBAAqB,CAAA;KAAE,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAAC;CAC/F;AAED,UAAU,oBAAoB;IAC5B,IAAI,IAAI,IAAI,CAAC;CACd;AAED,UAAU,eAAe;IACvB,SAAS,IAAI,SAAS,oBAAoB,EAAE,CAAC;CAC9C;AAED,UAAU,gBAAgB;IACxB,YAAY,CAAC,WAAW,EAAE;QACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;QACzB,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;KAC1B,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;CAC9B;AAED,UAAU,eAAe;IACvB,kBAAkB,CAChB,OAAO,EAAE,MAAM,IAAI,EACnB,KAAK,EAAE,MAAM,IAAI,EACjB,OAAO,CAAC,EAAE;QACR,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;QAC7B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;KAC3B,GACA,IAAI,CAAC;CACT;AAED,UAAU,aAAa;IACrB,QAAQ,CAAC,WAAW,CAAC,EAAE,kBAAkB,CAAC;IAC1C,QAAQ,CAAC,YAAY,CAAC,EAAE,gBAAgB,CAAC;IACzC,QAAQ,CAAC,WAAW,CAAC,EAAE,eAAe,CAAC;CACxC;AAED,UAAU,gBAAgB;IACxB,QAAQ,CAAC,UAAU,EAAE,2BAA2B,CAAC;IACjD,iBAAiB,IAAI,OAAO,CAAC,2BAA2B,CAAC,GAAG,2BAA2B,CAAC;CACzF;AAED,UAAU,aAAa;IACrB,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;IACnC,QAAQ,CAAC,SAAS,CAAC,EAAE,aAAa,CAAC;IACnC,QAAQ,CAAC,YAAY,CAAC,EAAE,gBAAgB,CAAC;CAC1C;AAED;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,MAAM,CAAC,EAAE,aAAa,CAAC;CACjC;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,GAAE,0BAA+B,GACvC,gBAAgB,CAiDlB"}
|
package/dist/web/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { assertKnownPermission, Permission } from '../registry/permissions';
|
|
2
|
-
import { createPermissionState
|
|
2
|
+
import { createPermissionState } from '../state/permissionState';
|
|
3
|
+
import { formatErrorName, stateFromBrowserPermission, stateFromMediaError, stateFromNotificationPermission, unavailable, } from './permissionStates';
|
|
3
4
|
/***
|
|
4
5
|
* Creates a browser permission client using guarded structural globals.
|
|
5
6
|
*
|
|
@@ -156,79 +157,4 @@ async function requestMedia(permission, global, constraints) {
|
|
|
156
157
|
return stateFromMediaError(permission, error);
|
|
157
158
|
}
|
|
158
159
|
}
|
|
159
|
-
function stateFromMediaError(permission, error) {
|
|
160
|
-
const errorName = getErrorName(error);
|
|
161
|
-
const unavailableErrorNames = new Set([
|
|
162
|
-
'AbortError',
|
|
163
|
-
'NotFoundError',
|
|
164
|
-
'NotReadableError',
|
|
165
|
-
'OverconstrainedError',
|
|
166
|
-
'SecurityError',
|
|
167
|
-
]);
|
|
168
|
-
if (errorName !== undefined && unavailableErrorNames.has(errorName)) {
|
|
169
|
-
return createPermissionState({
|
|
170
|
-
permission,
|
|
171
|
-
status: 'unavailable',
|
|
172
|
-
canAskAgain: false,
|
|
173
|
-
requestedAt: new Date(),
|
|
174
|
-
reason: `Media permission request failed: ${errorName}.`,
|
|
175
|
-
});
|
|
176
|
-
}
|
|
177
|
-
return createPermissionState({
|
|
178
|
-
permission,
|
|
179
|
-
status: 'denied',
|
|
180
|
-
canAskAgain: false,
|
|
181
|
-
requestedAt: new Date(),
|
|
182
|
-
reason: errorName === undefined
|
|
183
|
-
? 'Media permission request was denied.'
|
|
184
|
-
: `Media permission request was denied: ${errorName}.`,
|
|
185
|
-
});
|
|
186
|
-
}
|
|
187
|
-
function stateFromNotificationPermission(permission, status) {
|
|
188
|
-
if (status === 'granted') {
|
|
189
|
-
return createPermissionState({
|
|
190
|
-
permission,
|
|
191
|
-
status: 'granted',
|
|
192
|
-
canAskAgain: true,
|
|
193
|
-
});
|
|
194
|
-
}
|
|
195
|
-
if (status === 'denied') {
|
|
196
|
-
return createPermissionState({
|
|
197
|
-
permission,
|
|
198
|
-
status: 'denied',
|
|
199
|
-
canAskAgain: false,
|
|
200
|
-
});
|
|
201
|
-
}
|
|
202
|
-
return createPermissionState({
|
|
203
|
-
permission,
|
|
204
|
-
status: 'unknown',
|
|
205
|
-
canAskAgain: true,
|
|
206
|
-
});
|
|
207
|
-
}
|
|
208
|
-
function stateFromBrowserPermission(permission, status) {
|
|
209
|
-
const normalizedStatus = status === 'prompt' ? 'unknown' : status;
|
|
210
|
-
return createPermissionState({
|
|
211
|
-
permission,
|
|
212
|
-
status: normalizedStatus,
|
|
213
|
-
canAskAgain: status === 'prompt' || status === 'granted',
|
|
214
|
-
});
|
|
215
|
-
}
|
|
216
|
-
function unavailable(permission, reason) {
|
|
217
|
-
return createPermissionState({
|
|
218
|
-
permission,
|
|
219
|
-
status: 'unavailable',
|
|
220
|
-
canAskAgain: false,
|
|
221
|
-
reason,
|
|
222
|
-
});
|
|
223
|
-
}
|
|
224
|
-
function formatErrorName(error) {
|
|
225
|
-
const errorName = getErrorName(error);
|
|
226
|
-
return errorName === undefined ? '' : `: ${errorName}`;
|
|
227
|
-
}
|
|
228
|
-
function getErrorName(error) {
|
|
229
|
-
if (typeof error !== 'object' || error === null || !('name' in error)) {
|
|
230
|
-
return undefined;
|
|
231
|
-
}
|
|
232
|
-
return typeof error.name === 'string' && error.name.length > 0 ? error.name : undefined;
|
|
233
|
-
}
|
|
234
160
|
//# sourceMappingURL=index.js.map
|