@ankhorage/expo-runtime 0.0.0 → 0.0.3

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 (53) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/README.md +3 -0
  3. package/dist/ExpoBarcodeScannerAdapter.d.ts +4 -0
  4. package/dist/ExpoBarcodeScannerAdapter.d.ts.map +1 -0
  5. package/dist/ExpoBarcodeScannerAdapter.js +49 -0
  6. package/dist/ExpoBarcodeScannerAdapter.js.map +1 -0
  7. package/dist/ExpoRuntimeProviders.d.ts +8 -0
  8. package/dist/ExpoRuntimeProviders.d.ts.map +1 -0
  9. package/dist/ExpoRuntimeProviders.js +11 -0
  10. package/dist/ExpoRuntimeProviders.js.map +1 -0
  11. package/dist/barcodeScanRuntime.d.ts +15 -0
  12. package/dist/barcodeScanRuntime.d.ts.map +1 -0
  13. package/dist/barcodeScanRuntime.js +48 -0
  14. package/dist/barcodeScanRuntime.js.map +1 -0
  15. package/dist/componentRegistry.d.ts +4 -0
  16. package/dist/componentRegistry.d.ts.map +1 -0
  17. package/dist/componentRegistry.js +6 -0
  18. package/dist/componentRegistry.js.map +1 -0
  19. package/dist/createExpoRuntimeRegistry.d.ts +3 -0
  20. package/dist/createExpoRuntimeRegistry.d.ts.map +1 -0
  21. package/dist/createExpoRuntimeRegistry.js +14 -0
  22. package/dist/createExpoRuntimeRegistry.js.map +1 -0
  23. package/dist/index.d.ts +8 -0
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +6 -2
  26. package/dist/index.js.map +1 -1
  27. package/dist/permissionRuntime.d.ts +3 -0
  28. package/dist/permissionRuntime.d.ts.map +1 -0
  29. package/dist/permissionRuntime.js +3 -0
  30. package/dist/permissionRuntime.js.map +1 -0
  31. package/dist/planning.d.ts +3 -0
  32. package/dist/planning.d.ts.map +1 -0
  33. package/dist/planning.js +2 -0
  34. package/dist/planning.js.map +1 -0
  35. package/dist/resolveExpoRuntimePlan.d.ts +53 -0
  36. package/dist/resolveExpoRuntimePlan.d.ts.map +1 -0
  37. package/dist/resolveExpoRuntimePlan.js +215 -0
  38. package/dist/resolveExpoRuntimePlan.js.map +1 -0
  39. package/package.json +26 -4
  40. package/src/ExpoBarcodeScannerAdapter.test.tsx +75 -0
  41. package/src/ExpoBarcodeScannerAdapter.tsx +84 -0
  42. package/src/ExpoRuntimeProviders.test.tsx +61 -0
  43. package/src/ExpoRuntimeProviders.tsx +21 -0
  44. package/src/barcodeScanRuntime.ts +78 -0
  45. package/src/componentRegistry.ts +11 -0
  46. package/src/createExpoRuntimeRegistry.test.tsx +31 -0
  47. package/src/createExpoRuntimeRegistry.tsx +17 -0
  48. package/src/index.ts +20 -1
  49. package/src/permissionRuntime.ts +2 -0
  50. package/src/planning.test.ts +9 -0
  51. package/src/planning.ts +6 -0
  52. package/src/resolveExpoRuntimePlan.test.ts +212 -0
  53. package/src/resolveExpoRuntimePlan.ts +337 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,21 @@
1
+ # @ankhorage/expo-runtime
2
+
3
+ ## 0.0.3
4
+
5
+ ### Patch Changes
6
+
7
+ - 1919ae8: Add a public planning entrypoint for Expo runtime resolution.
8
+
9
+ ## 0.0.2
10
+
11
+ ### Patch Changes
12
+
13
+ - ba20014: Release trigger
14
+
15
+ ## 0.0.1
16
+
17
+ ### Patch Changes
18
+
19
+ - 1f9a5dc: Add the Expo runtime plan resolver, provider wrapper, scanner adapter, and
20
+ component registry factory so generated apps and Studio preview can share the
21
+ same Expo runtime implementation path.
package/README.md CHANGED
@@ -15,3 +15,6 @@ Declarative runtime integration for Expo apps: maps app capabilities to permissi
15
15
  - [Architecture overview](././paradox/diagrams/architecture-overview.mmd)
16
16
  - [Module relationships](././paradox/diagrams/module-relationships.mmd)
17
17
  - [Export graph](././paradox/diagrams/export-graph.mmd)
18
+ - [createExpoRuntimeRegistry sequence](././paradox/diagrams/sequences/create-expo-runtime-registry.mmd)
19
+ - [ExpoBarcodeScannerAdapter sequence](././paradox/diagrams/sequences/expo-barcode-scanner-adapter.mmd)
20
+ - [resolveExpoRuntimePlan sequence](././paradox/diagrams/sequences/resolve-expo-runtime-plan.mmd)
@@ -0,0 +1,4 @@
1
+ import { type BarcodeScannerViewProps } from '@ankhorage/zora';
2
+ import React from 'react';
3
+ export declare function ExpoBarcodeScannerAdapter(props: BarcodeScannerViewProps): React.JSX.Element;
4
+ //# sourceMappingURL=ExpoBarcodeScannerAdapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExpoBarcodeScannerAdapter.d.ts","sourceRoot":"","sources":["../src/ExpoBarcodeScannerAdapter.tsx"],"names":[],"mappings":"AACA,OAAO,EAAsB,KAAK,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAEnF,OAAO,KAAK,MAAM,OAAO,CAAC;AAa1B,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,uBAAuB,qBA6DvE"}
@@ -0,0 +1,49 @@
1
+ import { Permission, usePermission } from '@ankhorage/permissions';
2
+ import { BarcodeScannerView } from '@ankhorage/zora';
3
+ import { CameraView } from 'expo-camera';
4
+ import React from 'react';
5
+ import { StyleSheet } from 'react-native';
6
+ import { BARCODE_SCANNER_TYPES, mapPermissionStatusToCameraPermissionStatus, normalizeExpoBarcodeScanResult, shouldIgnoreBarcodeScan, } from './barcodeScanRuntime';
7
+ const CAMERA_BARCODE_TYPES = [...BARCODE_SCANNER_TYPES];
8
+ export function ExpoBarcodeScannerAdapter(props) {
9
+ const { onBarcodeScanned, onRequestPermission, ...viewProps } = props;
10
+ const cameraPermission = usePermission(Permission.Camera);
11
+ const [isRequestingPermission, setIsRequestingPermission] = React.useState(false);
12
+ const lastScanRef = React.useRef(null);
13
+ const permissionStatus = mapPermissionStatusToCameraPermissionStatus(cameraPermission.status, isRequestingPermission);
14
+ const handleRequestPermission = React.useCallback(async () => {
15
+ setIsRequestingPermission(true);
16
+ try {
17
+ await cameraPermission.request();
18
+ await onRequestPermission?.();
19
+ }
20
+ finally {
21
+ setIsRequestingPermission(false);
22
+ }
23
+ }, [cameraPermission, onRequestPermission]);
24
+ const handleBarcodeScanned = React.useCallback((result) => {
25
+ void (async () => {
26
+ const normalizedResult = normalizeExpoBarcodeScanResult(result);
27
+ if (normalizedResult === null) {
28
+ return;
29
+ }
30
+ const now = Date.now();
31
+ if (shouldIgnoreBarcodeScan(lastScanRef.current, normalizedResult, now)) {
32
+ return;
33
+ }
34
+ lastScanRef.current = {
35
+ ...normalizedResult,
36
+ timestamp: now,
37
+ };
38
+ await onBarcodeScanned?.(normalizedResult);
39
+ })();
40
+ }, [onBarcodeScanned]);
41
+ const camera = permissionStatus === 'granted' ? (<CameraView barcodeScannerSettings={{ barcodeTypes: CAMERA_BARCODE_TYPES }} onBarcodeScanned={handleBarcodeScanned} style={styles.camera}/>) : undefined;
42
+ return (<BarcodeScannerView {...viewProps} camera={camera} onRequestPermission={handleRequestPermission} permissionStatus={permissionStatus}/>);
43
+ }
44
+ const styles = StyleSheet.create({
45
+ camera: {
46
+ flex: 1,
47
+ },
48
+ });
49
+ //# sourceMappingURL=ExpoBarcodeScannerAdapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExpoBarcodeScannerAdapter.js","sourceRoot":"","sources":["../src/ExpoBarcodeScannerAdapter.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Permission, usePermission } from '@ankhorage/permissions';\nimport { BarcodeScannerView, type BarcodeScannerViewProps } from '@ankhorage/zora';\nimport { type BarcodeScanningResult, type BarcodeType, CameraView } from 'expo-camera';\nimport React from 'react';\nimport { StyleSheet } from 'react-native';\n\nimport {\n BARCODE_SCANNER_TYPES,\n type BarcodeScanRecord,\n mapPermissionStatusToCameraPermissionStatus,\n normalizeExpoBarcodeScanResult,\n shouldIgnoreBarcodeScan,\n} from './barcodeScanRuntime';\n\nconst CAMERA_BARCODE_TYPES: BarcodeType[] = [...BARCODE_SCANNER_TYPES];\n\nexport function ExpoBarcodeScannerAdapter(props: BarcodeScannerViewProps) {\n const { onBarcodeScanned, onRequestPermission, ...viewProps } = props;\n const cameraPermission = usePermission(Permission.Camera);\n const [isRequestingPermission, setIsRequestingPermission] = React.useState(false);\n const lastScanRef = React.useRef<BarcodeScanRecord | null>(null);\n\n const permissionStatus = mapPermissionStatusToCameraPermissionStatus(\n cameraPermission.status,\n isRequestingPermission,\n );\n\n const handleRequestPermission = React.useCallback(async () => {\n setIsRequestingPermission(true);\n try {\n await cameraPermission.request();\n await onRequestPermission?.();\n } finally {\n setIsRequestingPermission(false);\n }\n }, [cameraPermission, onRequestPermission]);\n\n const handleBarcodeScanned = React.useCallback(\n (result: BarcodeScanningResult) => {\n void (async () => {\n const normalizedResult = normalizeExpoBarcodeScanResult(result);\n if (normalizedResult === null) {\n return;\n }\n\n const now = Date.now();\n if (shouldIgnoreBarcodeScan(lastScanRef.current, normalizedResult, now)) {\n return;\n }\n\n lastScanRef.current = {\n ...normalizedResult,\n timestamp: now,\n };\n await onBarcodeScanned?.(normalizedResult);\n })();\n },\n [onBarcodeScanned],\n );\n\n const camera =\n permissionStatus === 'granted' ? (\n <CameraView\n barcodeScannerSettings={{ barcodeTypes: CAMERA_BARCODE_TYPES }}\n onBarcodeScanned={handleBarcodeScanned}\n style={styles.camera}\n />\n ) : undefined;\n\n return (\n <BarcodeScannerView\n {...viewProps}\n camera={camera}\n onRequestPermission={handleRequestPermission}\n permissionStatus={permissionStatus}\n />\n );\n}\n\nconst styles = StyleSheet.create({\n camera: {\n flex: 1,\n },\n});\n"]}
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ import type { ExpoRuntimeProviderId } from './resolveExpoRuntimePlan';
3
+ export interface ExpoRuntimeProvidersProps {
4
+ readonly children: React.ReactNode;
5
+ readonly providers?: readonly ExpoRuntimeProviderId[];
6
+ }
7
+ export declare function ExpoRuntimeProviders(props: ExpoRuntimeProvidersProps): React.JSX.Element;
8
+ //# sourceMappingURL=ExpoRuntimeProviders.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExpoRuntimeProviders.d.ts","sourceRoot":"","sources":["../src/ExpoRuntimeProviders.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAItE,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IACnC,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,qBAAqB,EAAE,CAAC;CACvD;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,yBAAyB,qBAQpE"}
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ import { createPermissionClient, PermissionsProvider } from './permissionRuntime';
3
+ const permissionClient = createPermissionClient();
4
+ export function ExpoRuntimeProviders(props) {
5
+ const { children, providers = [] } = props;
6
+ if (providers.includes('permissions')) {
7
+ return <PermissionsProvider client={permissionClient}>{children}</PermissionsProvider>;
8
+ }
9
+ return <>{children}</>;
10
+ }
11
+ //# sourceMappingURL=ExpoRuntimeProviders.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExpoRuntimeProviders.js","sourceRoot":"","sources":["../src/ExpoRuntimeProviders.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAGlF,MAAM,gBAAgB,GAAG,sBAAsB,EAAE,CAAC;AAOlD,MAAM,UAAU,oBAAoB,CAAC,KAAgC;IACnE,MAAM,EAAE,QAAQ,EAAE,SAAS,GAAG,EAAE,EAAE,GAAG,KAAK,CAAC;IAE3C,IAAI,SAAS,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;QACtC,OAAO,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,mBAAmB,CAAC,CAAC;IACzF,CAAC;IAED,OAAO,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC;AACzB,CAAC","sourcesContent":["import React from 'react';\n\nimport { createPermissionClient, PermissionsProvider } from './permissionRuntime';\nimport type { ExpoRuntimeProviderId } from './resolveExpoRuntimePlan';\n\nconst permissionClient = createPermissionClient();\n\nexport interface ExpoRuntimeProvidersProps {\n readonly children: React.ReactNode;\n readonly providers?: readonly ExpoRuntimeProviderId[];\n}\n\nexport function ExpoRuntimeProviders(props: ExpoRuntimeProvidersProps) {\n const { children, providers = [] } = props;\n\n if (providers.includes('permissions')) {\n return <PermissionsProvider client={permissionClient}>{children}</PermissionsProvider>;\n }\n\n return <>{children}</>;\n}\n"]}
@@ -0,0 +1,15 @@
1
+ import type { PermissionStatus } from '@ankhorage/permissions';
2
+ import type { BarcodeScanResult, CameraPermissionStatus } from '@ankhorage/zora';
3
+ export declare const BARCODE_SCAN_DEDUPE_WINDOW_MS = 1500;
4
+ export declare const BARCODE_SCANNER_TYPES: readonly ["aztec", "code128", "code39", "code93", "datamatrix", "ean13", "ean8", "itf14", "pdf417", "qr", "upc_a", "upc_e"];
5
+ export interface BarcodeScanRecord extends BarcodeScanResult {
6
+ readonly timestamp: number;
7
+ }
8
+ export interface ExpoBarcodeScanResultLike {
9
+ readonly data: string;
10
+ readonly type?: string;
11
+ }
12
+ export declare function mapPermissionStatusToCameraPermissionStatus(status: PermissionStatus, isRequestingPermission: boolean): CameraPermissionStatus;
13
+ export declare function normalizeExpoBarcodeScanResult(result: ExpoBarcodeScanResultLike): BarcodeScanResult | null;
14
+ export declare function shouldIgnoreBarcodeScan(previous: BarcodeScanRecord | null, next: BarcodeScanResult, now: number): boolean;
15
+ //# sourceMappingURL=barcodeScanRuntime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"barcodeScanRuntime.d.ts","sourceRoot":"","sources":["../src/barcodeScanRuntime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,KAAK,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAEjF,eAAO,MAAM,6BAA6B,OAAO,CAAC;AAElD,eAAO,MAAM,qBAAqB,6HAaxB,CAAC;AAEX,MAAM,WAAW,iBAAkB,SAAQ,iBAAiB;IAC1D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,wBAAgB,2CAA2C,CACzD,MAAM,EAAE,gBAAgB,EACxB,sBAAsB,EAAE,OAAO,GAC9B,sBAAsB,CAaxB;AAED,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,yBAAyB,GAChC,iBAAiB,GAAG,IAAI,CAY1B;AAED,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,iBAAiB,GAAG,IAAI,EAClC,IAAI,EAAE,iBAAiB,EACvB,GAAG,EAAE,MAAM,GACV,OAAO,CAUT"}
@@ -0,0 +1,48 @@
1
+ export const BARCODE_SCAN_DEDUPE_WINDOW_MS = 1500;
2
+ export const BARCODE_SCANNER_TYPES = [
3
+ 'aztec',
4
+ 'code128',
5
+ 'code39',
6
+ 'code93',
7
+ 'datamatrix',
8
+ 'ean13',
9
+ 'ean8',
10
+ 'itf14',
11
+ 'pdf417',
12
+ 'qr',
13
+ 'upc_a',
14
+ 'upc_e',
15
+ ];
16
+ export function mapPermissionStatusToCameraPermissionStatus(status, isRequestingPermission) {
17
+ if (isRequestingPermission) {
18
+ return 'requesting';
19
+ }
20
+ switch (status) {
21
+ case 'granted':
22
+ return 'granted';
23
+ case 'unknown':
24
+ return 'unknown';
25
+ default:
26
+ return 'denied';
27
+ }
28
+ }
29
+ export function normalizeExpoBarcodeScanResult(result) {
30
+ const value = result.data.trim();
31
+ if (value.length === 0) {
32
+ return null;
33
+ }
34
+ const type = typeof result.type === 'string' && result.type.length > 0 ? result.type : undefined;
35
+ return {
36
+ value,
37
+ type,
38
+ };
39
+ }
40
+ export function shouldIgnoreBarcodeScan(previous, next, now) {
41
+ if (previous === null) {
42
+ return false;
43
+ }
44
+ return (previous.value === next.value &&
45
+ previous.type === next.type &&
46
+ now - previous.timestamp < BARCODE_SCAN_DEDUPE_WINDOW_MS);
47
+ }
48
+ //# sourceMappingURL=barcodeScanRuntime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"barcodeScanRuntime.js","sourceRoot":"","sources":["../src/barcodeScanRuntime.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,MAAM,6BAA6B,GAAG,IAAI,CAAC;AAElD,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,OAAO;IACP,SAAS;IACT,QAAQ;IACR,QAAQ;IACR,YAAY;IACZ,OAAO;IACP,MAAM;IACN,OAAO;IACP,QAAQ;IACR,IAAI;IACJ,OAAO;IACP,OAAO;CACC,CAAC;AAWX,MAAM,UAAU,2CAA2C,CACzD,MAAwB,EACxB,sBAA+B;IAE/B,IAAI,sBAAsB,EAAE,CAAC;QAC3B,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,SAAS;YACZ,OAAO,SAAS,CAAC;QACnB,KAAK,SAAS;YACZ,OAAO,SAAS,CAAC;QACnB;YACE,OAAO,QAAQ,CAAC;IACpB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,8BAA8B,CAC5C,MAAiC;IAEjC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IACjC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,IAAI,GAAG,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;IAEjG,OAAO;QACL,KAAK;QACL,IAAI;KACL,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,uBAAuB,CACrC,QAAkC,EAClC,IAAuB,EACvB,GAAW;IAEX,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACtB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,CACL,QAAQ,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK;QAC7B,QAAQ,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI;QAC3B,GAAG,GAAG,QAAQ,CAAC,SAAS,GAAG,6BAA6B,CACzD,CAAC;AACJ,CAAC","sourcesContent":["import type { PermissionStatus } from '@ankhorage/permissions';\nimport type { BarcodeScanResult, CameraPermissionStatus } from '@ankhorage/zora';\n\nexport const BARCODE_SCAN_DEDUPE_WINDOW_MS = 1500;\n\nexport const BARCODE_SCANNER_TYPES = [\n 'aztec',\n 'code128',\n 'code39',\n 'code93',\n 'datamatrix',\n 'ean13',\n 'ean8',\n 'itf14',\n 'pdf417',\n 'qr',\n 'upc_a',\n 'upc_e',\n] as const;\n\nexport interface BarcodeScanRecord extends BarcodeScanResult {\n readonly timestamp: number;\n}\n\nexport interface ExpoBarcodeScanResultLike {\n readonly data: string;\n readonly type?: string;\n}\n\nexport function mapPermissionStatusToCameraPermissionStatus(\n status: PermissionStatus,\n isRequestingPermission: boolean,\n): CameraPermissionStatus {\n if (isRequestingPermission) {\n return 'requesting';\n }\n\n switch (status) {\n case 'granted':\n return 'granted';\n case 'unknown':\n return 'unknown';\n default:\n return 'denied';\n }\n}\n\nexport function normalizeExpoBarcodeScanResult(\n result: ExpoBarcodeScanResultLike,\n): BarcodeScanResult | null {\n const value = result.data.trim();\n if (value.length === 0) {\n return null;\n }\n\n const type = typeof result.type === 'string' && result.type.length > 0 ? result.type : undefined;\n\n return {\n value,\n type,\n };\n}\n\nexport function shouldIgnoreBarcodeScan(\n previous: BarcodeScanRecord | null,\n next: BarcodeScanResult,\n now: number,\n): boolean {\n if (previous === null) {\n return false;\n }\n\n return (\n previous.value === next.value &&\n previous.type === next.type &&\n now - previous.timestamp < BARCODE_SCAN_DEDUPE_WINDOW_MS\n );\n}\n"]}
@@ -0,0 +1,4 @@
1
+ import type React from 'react';
2
+ export type ComponentRegistry = Record<string, React.ElementType>;
3
+ export declare function createComponentRegistry(...registries: readonly ComponentRegistry[]): ComponentRegistry;
4
+ //# sourceMappingURL=componentRegistry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"componentRegistry.d.ts","sourceRoot":"","sources":["../src/componentRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,MAAM,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;AAElE,wBAAgB,uBAAuB,CACrC,GAAG,UAAU,EAAE,SAAS,iBAAiB,EAAE,GAC1C,iBAAiB,CAInB"}
@@ -0,0 +1,6 @@
1
+ export function createComponentRegistry(...registries) {
2
+ return registries.reduce((mergedRegistry, registry) => {
3
+ return { ...mergedRegistry, ...registry };
4
+ }, {});
5
+ }
6
+ //# sourceMappingURL=componentRegistry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"componentRegistry.js","sourceRoot":"","sources":["../src/componentRegistry.ts"],"names":[],"mappings":"AAIA,MAAM,UAAU,uBAAuB,CACrC,GAAG,UAAwC;IAE3C,OAAO,UAAU,CAAC,MAAM,CAAoB,CAAC,cAAc,EAAE,QAAQ,EAAE,EAAE;QACvE,OAAO,EAAE,GAAG,cAAc,EAAE,GAAG,QAAQ,EAAE,CAAC;IAC5C,CAAC,EAAE,EAAE,CAAC,CAAC;AACT,CAAC","sourcesContent":["import type React from 'react';\n\nexport type ComponentRegistry = Record<string, React.ElementType>;\n\nexport function createComponentRegistry(\n ...registries: readonly ComponentRegistry[]\n): ComponentRegistry {\n return registries.reduce<ComponentRegistry>((mergedRegistry, registry) => {\n return { ...mergedRegistry, ...registry };\n }, {});\n}\n"]}
@@ -0,0 +1,3 @@
1
+ import { type ComponentRegistry } from './componentRegistry';
2
+ export declare function createExpoRuntimeRegistry(baseRegistry: ComponentRegistry): ComponentRegistry;
3
+ //# sourceMappingURL=createExpoRuntimeRegistry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createExpoRuntimeRegistry.d.ts","sourceRoot":"","sources":["../src/createExpoRuntimeRegistry.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,iBAAiB,EAA2B,MAAM,qBAAqB,CAAC;AAOtF,wBAAgB,yBAAyB,CAAC,YAAY,EAAE,iBAAiB,GAAG,iBAAiB,CAE5F"}
@@ -0,0 +1,14 @@
1
+ import {} from '@ankhorage/zora';
2
+ import React from 'react';
3
+ import { createComponentRegistry } from './componentRegistry';
4
+ import { ExpoBarcodeScannerAdapter } from './ExpoBarcodeScannerAdapter';
5
+ const EXPO_RUNTIME_OVERRIDES = {
6
+ BarcodeScannerView: ExpoBarcodeScannerView,
7
+ };
8
+ export function createExpoRuntimeRegistry(baseRegistry) {
9
+ return createComponentRegistry(baseRegistry, EXPO_RUNTIME_OVERRIDES);
10
+ }
11
+ function ExpoBarcodeScannerView(props) {
12
+ return <ExpoBarcodeScannerAdapter {...props}/>;
13
+ }
14
+ //# sourceMappingURL=createExpoRuntimeRegistry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createExpoRuntimeRegistry.js","sourceRoot":"","sources":["../src/createExpoRuntimeRegistry.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAgC,MAAM,iBAAiB,CAAC;AAC/D,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAA0B,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AACtF,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AAExE,MAAM,sBAAsB,GAAsB;IAChD,kBAAkB,EAAE,sBAAsB;CAC3C,CAAC;AAEF,MAAM,UAAU,yBAAyB,CAAC,YAA+B;IACvE,OAAO,uBAAuB,CAAC,YAAY,EAAE,sBAAsB,CAAC,CAAC;AACvE,CAAC;AAED,SAAS,sBAAsB,CAAC,KAA8B;IAC5D,OAAO,CAAC,yBAAyB,CAAC,IAAI,KAAK,CAAC,EAAG,CAAC;AAClD,CAAC","sourcesContent":["import { type BarcodeScannerViewProps } from '@ankhorage/zora';\nimport React from 'react';\n\nimport { type ComponentRegistry, createComponentRegistry } from './componentRegistry';\nimport { ExpoBarcodeScannerAdapter } from './ExpoBarcodeScannerAdapter';\n\nconst EXPO_RUNTIME_OVERRIDES: ComponentRegistry = {\n BarcodeScannerView: ExpoBarcodeScannerView,\n};\n\nexport function createExpoRuntimeRegistry(baseRegistry: ComponentRegistry): ComponentRegistry {\n return createComponentRegistry(baseRegistry, EXPO_RUNTIME_OVERRIDES);\n}\n\nfunction ExpoBarcodeScannerView(props: BarcodeScannerViewProps) {\n return <ExpoBarcodeScannerAdapter {...props} />;\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -1 +1,9 @@
1
+ export { BARCODE_SCAN_DEDUPE_WINDOW_MS, BARCODE_SCANNER_TYPES, type BarcodeScanRecord, type ExpoBarcodeScanResultLike, mapPermissionStatusToCameraPermissionStatus, normalizeExpoBarcodeScanResult, shouldIgnoreBarcodeScan, } from './barcodeScanRuntime';
2
+ export type { ComponentRegistry } from './componentRegistry';
3
+ export { createComponentRegistry } from './componentRegistry';
4
+ export { createExpoRuntimeRegistry } from './createExpoRuntimeRegistry';
5
+ export { ExpoBarcodeScannerAdapter } from './ExpoBarcodeScannerAdapter';
6
+ export { ExpoRuntimeProviders, type ExpoRuntimeProvidersProps } from './ExpoRuntimeProviders';
7
+ export type { ExpoRuntimeAdapterId, ExpoRuntimePlan, ExpoRuntimeProviderId, } from './resolveExpoRuntimePlan';
8
+ export { resolveExpoRuntimePlan } from './resolveExpoRuntimePlan';
1
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,6BAA6B,EAC7B,qBAAqB,EACrB,KAAK,iBAAiB,EACtB,KAAK,yBAAyB,EAC9B,2CAA2C,EAC3C,8BAA8B,EAC9B,uBAAuB,GACxB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,EAAE,oBAAoB,EAAE,KAAK,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AAC9F,YAAY,EACV,oBAAoB,EACpB,eAAe,EACf,qBAAqB,GACtB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC"}
package/dist/index.js CHANGED
@@ -1,3 +1,7 @@
1
- "use strict";
2
- /* todo */
1
+ export { BARCODE_SCAN_DEDUPE_WINDOW_MS, BARCODE_SCANNER_TYPES, mapPermissionStatusToCameraPermissionStatus, normalizeExpoBarcodeScanResult, shouldIgnoreBarcodeScan, } from './barcodeScanRuntime';
2
+ export { createComponentRegistry } from './componentRegistry';
3
+ export { createExpoRuntimeRegistry } from './createExpoRuntimeRegistry';
4
+ export { ExpoBarcodeScannerAdapter } from './ExpoBarcodeScannerAdapter';
5
+ export { ExpoRuntimeProviders } from './ExpoRuntimeProviders';
6
+ export { resolveExpoRuntimePlan } from './resolveExpoRuntimePlan';
3
7
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,UAAU","sourcesContent":["/* todo */\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,6BAA6B,EAC7B,qBAAqB,EAGrB,2CAA2C,EAC3C,8BAA8B,EAC9B,uBAAuB,GACxB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,EAAE,oBAAoB,EAAkC,MAAM,wBAAwB,CAAC;AAM9F,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC","sourcesContent":["export {\n BARCODE_SCAN_DEDUPE_WINDOW_MS,\n BARCODE_SCANNER_TYPES,\n type BarcodeScanRecord,\n type ExpoBarcodeScanResultLike,\n mapPermissionStatusToCameraPermissionStatus,\n normalizeExpoBarcodeScanResult,\n shouldIgnoreBarcodeScan,\n} from './barcodeScanRuntime';\nexport type { ComponentRegistry } from './componentRegistry';\nexport { createComponentRegistry } from './componentRegistry';\nexport { createExpoRuntimeRegistry } from './createExpoRuntimeRegistry';\nexport { ExpoBarcodeScannerAdapter } from './ExpoBarcodeScannerAdapter';\nexport { ExpoRuntimeProviders, type ExpoRuntimeProvidersProps } from './ExpoRuntimeProviders';\nexport type {\n ExpoRuntimeAdapterId,\n ExpoRuntimePlan,\n ExpoRuntimeProviderId,\n} from './resolveExpoRuntimePlan';\nexport { resolveExpoRuntimePlan } from './resolveExpoRuntimePlan';\n"]}
@@ -0,0 +1,3 @@
1
+ export { PermissionsProvider } from '@ankhorage/permissions';
2
+ export { createPermissionClient } from '@ankhorage/permissions/expo';
3
+ //# sourceMappingURL=permissionRuntime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permissionRuntime.d.ts","sourceRoot":"","sources":["../src/permissionRuntime.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { PermissionsProvider } from '@ankhorage/permissions';
2
+ export { createPermissionClient } from '@ankhorage/permissions/expo';
3
+ //# sourceMappingURL=permissionRuntime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permissionRuntime.js","sourceRoot":"","sources":["../src/permissionRuntime.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC","sourcesContent":["export { PermissionsProvider } from '@ankhorage/permissions';\nexport { createPermissionClient } from '@ankhorage/permissions/expo';\n"]}
@@ -0,0 +1,3 @@
1
+ export type { ExpoRuntimeAdapterId, ExpoRuntimePlan, ExpoRuntimeProviderId, } from './resolveExpoRuntimePlan';
2
+ export { resolveExpoRuntimePlan } from './resolveExpoRuntimePlan';
3
+ //# sourceMappingURL=planning.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"planning.d.ts","sourceRoot":"","sources":["../src/planning.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,oBAAoB,EACpB,eAAe,EACf,qBAAqB,GACtB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { resolveExpoRuntimePlan } from './resolveExpoRuntimePlan';
2
+ //# sourceMappingURL=planning.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"planning.js","sourceRoot":"","sources":["../src/planning.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC","sourcesContent":["export type {\n ExpoRuntimeAdapterId,\n ExpoRuntimePlan,\n ExpoRuntimeProviderId,\n} from './resolveExpoRuntimePlan';\nexport { resolveExpoRuntimePlan } from './resolveExpoRuntimePlan';\n"]}
@@ -0,0 +1,53 @@
1
+ import type { AnkhorageCapabilityName, AppManifest, ScreenCapabilityRequirement, ScreenPermissionRequirement } from '@ankhorage/contracts';
2
+ import type { Permission } from '@ankhorage/permissions';
3
+ import { type ExpoPermissionMetadata, type PermissionSupport } from '@ankhorage/permissions/expo/manifest';
4
+ interface ExpoRuntimeDependency {
5
+ readonly name: string;
6
+ readonly version: string;
7
+ readonly reasons: readonly string[];
8
+ }
9
+ interface ExpoRuntimeConfigPlugin {
10
+ readonly name: string;
11
+ readonly options?: Readonly<Record<string, boolean | string>>;
12
+ }
13
+ export type ExpoRuntimeProviderId = 'permissions';
14
+ export type ExpoRuntimeAdapterId = 'ExpoBarcodeScannerAdapter';
15
+ interface ExpoRuntimeDiagnostic {
16
+ readonly severity: 'error' | 'warning';
17
+ readonly requirementType: 'capability' | 'configHint' | 'package' | 'permission';
18
+ readonly requirement: string;
19
+ readonly message: string;
20
+ readonly support?: PermissionSupport;
21
+ }
22
+ export interface ExpoRuntimePlan {
23
+ readonly permissions: readonly ScreenPermissionRequirement[];
24
+ readonly capabilities: readonly ScreenCapabilityRequirement[];
25
+ readonly impliedPermissions: readonly ScreenPermissionRequirement[];
26
+ readonly dependencies: readonly ExpoRuntimeDependency[];
27
+ readonly nativeConfig: {
28
+ readonly androidPermissions: readonly string[];
29
+ readonly configHints: readonly string[];
30
+ readonly plugins: readonly ExpoRuntimeConfigPlugin[];
31
+ };
32
+ readonly providers: readonly ExpoRuntimeProviderId[];
33
+ readonly runtimeAdapters: readonly ExpoRuntimeAdapterId[];
34
+ readonly usesExpoRuntimeRegistry: boolean;
35
+ readonly needsPermissionsProvider: boolean;
36
+ readonly diagnostics: readonly ExpoRuntimeDiagnostic[];
37
+ }
38
+ interface ExpoRuntimeCapabilityMetadata {
39
+ readonly impliedPermissions?: readonly ScreenPermissionRequirement[];
40
+ readonly requiredPackages?: readonly string[];
41
+ readonly providers?: readonly ExpoRuntimeProviderId[];
42
+ readonly runtimeAdapters?: readonly ExpoRuntimeAdapterId[];
43
+ readonly androidPermissions?: readonly string[];
44
+ readonly plugins?: readonly ExpoRuntimeConfigPlugin[];
45
+ }
46
+ interface ResolveExpoRuntimePlanOptions {
47
+ readonly capabilityRegistry?: Readonly<Partial<Record<AnkhorageCapabilityName, ExpoRuntimeCapabilityMetadata>>>;
48
+ readonly dependencyVersions?: Readonly<Record<string, string>>;
49
+ readonly permissionSupport?: Readonly<Record<Permission, ExpoPermissionMetadata>>;
50
+ }
51
+ export declare function resolveExpoRuntimePlan(manifest: AppManifest, options?: ResolveExpoRuntimePlanOptions): ExpoRuntimePlan;
52
+ export {};
53
+ //# sourceMappingURL=resolveExpoRuntimePlan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolveExpoRuntimePlan.d.ts","sourceRoot":"","sources":["../src/resolveExpoRuntimePlan.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,215 @@
1
+ import { isPermission } from '@ankhorage/permissions';
2
+ import { EXPO_PERMISSION_SUPPORT, } from '@ankhorage/permissions/expo/manifest';
3
+ const CAMERA_ANDROID_PERMISSION = 'android.permission.CAMERA';
4
+ const EXPO_RUNTIME_PACKAGE_NAME = '@ankhorage/expo-runtime';
5
+ const GENERATED_EXPO_DEPENDENCY_VERSIONS = {
6
+ '@ankhorage/permissions': '^0.2.0',
7
+ '@ankhorage/expo-runtime': 'latest',
8
+ 'expo-camera': '~17.0.10',
9
+ };
10
+ const EXPO_RUNTIME_PROVIDER_PACKAGES = {
11
+ permissions: '@ankhorage/permissions',
12
+ };
13
+ const EXPO_RUNTIME_CONFIG_HINTS = {
14
+ cameraPermission: {
15
+ androidPermissions: [CAMERA_ANDROID_PERMISSION],
16
+ plugin: {
17
+ name: 'expo-camera',
18
+ options: {
19
+ cameraPermission: 'Allow camera access.',
20
+ },
21
+ },
22
+ },
23
+ };
24
+ const EXPO_CAPABILITY_RUNTIME_REGISTRY = {
25
+ barcodeScanner: {
26
+ impliedPermissions: [{ permission: 'camera' }],
27
+ requiredPackages: ['expo-camera'],
28
+ providers: ['permissions'],
29
+ runtimeAdapters: ['ExpoBarcodeScannerAdapter'],
30
+ androidPermissions: [CAMERA_ANDROID_PERMISSION],
31
+ plugins: [
32
+ {
33
+ name: 'expo-camera',
34
+ options: {
35
+ cameraPermission: 'Allow camera access to scan barcodes.',
36
+ },
37
+ },
38
+ ],
39
+ },
40
+ };
41
+ export function resolveExpoRuntimePlan(manifest, options = {}) {
42
+ const permissionsByName = new Map();
43
+ const impliedPermissionsByName = new Map();
44
+ const capabilitiesByName = new Map();
45
+ for (const screen of Object.values(manifest.screens)) {
46
+ screen.requires?.permissions?.forEach((requirement) => {
47
+ permissionsByName.set(requirement.permission, requirement);
48
+ });
49
+ screen.requires?.capabilities?.forEach((requirement) => {
50
+ capabilitiesByName.set(requirement.capability, requirement);
51
+ });
52
+ }
53
+ const capabilityRegistry = options.capabilityRegistry ?? EXPO_CAPABILITY_RUNTIME_REGISTRY;
54
+ for (const capabilityRequirement of capabilitiesByName.values()) {
55
+ capabilityRegistry[capabilityRequirement.capability]?.impliedPermissions?.forEach((permissionRequirement) => {
56
+ if (!permissionsByName.has(permissionRequirement.permission)) {
57
+ permissionsByName.set(permissionRequirement.permission, permissionRequirement);
58
+ impliedPermissionsByName.set(permissionRequirement.permission, permissionRequirement);
59
+ }
60
+ });
61
+ }
62
+ const diagnostics = [];
63
+ const dependencies = new Map();
64
+ const pluginOptions = new Map();
65
+ const configHints = new Set();
66
+ const androidPermissions = new Set();
67
+ const providers = new Set();
68
+ const runtimeAdapters = new Set();
69
+ const dependencyVersions = options.dependencyVersions ?? GENERATED_EXPO_DEPENDENCY_VERSIONS;
70
+ const permissionSupport = options.permissionSupport ?? EXPO_PERMISSION_SUPPORT;
71
+ const configHintRegistry = EXPO_RUNTIME_CONFIG_HINTS;
72
+ const addDependency = (name, reason) => {
73
+ const version = dependencyVersions[name];
74
+ if (version === undefined) {
75
+ diagnostics.push({
76
+ severity: 'warning',
77
+ requirementType: 'package',
78
+ requirement: name,
79
+ message: `No generated-app dependency version is registered for '${name}'.`,
80
+ });
81
+ return;
82
+ }
83
+ const existing = dependencies.get(name);
84
+ if (existing) {
85
+ dependencies.set(name, {
86
+ ...existing,
87
+ reasons: Array.from(new Set([...existing.reasons, reason])),
88
+ });
89
+ return;
90
+ }
91
+ dependencies.set(name, {
92
+ name,
93
+ version,
94
+ reasons: [reason],
95
+ });
96
+ };
97
+ const addProvider = (provider, reason) => {
98
+ providers.add(provider);
99
+ addDependency(EXPO_RUNTIME_PROVIDER_PACKAGES[provider], reason);
100
+ };
101
+ const addPlugin = (plugin) => {
102
+ const existingOptions = pluginOptions.get(plugin.name) ?? {};
103
+ pluginOptions.set(plugin.name, {
104
+ ...existingOptions,
105
+ ...(plugin.options ?? {}),
106
+ });
107
+ };
108
+ for (const permissionRequirement of permissionsByName.values()) {
109
+ if (!isPermission(permissionRequirement.permission)) {
110
+ diagnostics.push({
111
+ severity: 'error',
112
+ requirementType: 'permission',
113
+ requirement: permissionRequirement.permission,
114
+ message: `Unknown permission '${permissionRequirement.permission}' cannot be resolved for Expo runtime generation.`,
115
+ });
116
+ continue;
117
+ }
118
+ const supportMetadata = permissionSupport[permissionRequirement.permission];
119
+ if (supportMetadata.support === 'unsupported' ||
120
+ supportMetadata.support === 'notImplemented' ||
121
+ supportMetadata.support === 'limited') {
122
+ diagnostics.push({
123
+ severity: supportMetadata.support === 'limited' ? 'warning' : 'error',
124
+ requirementType: 'permission',
125
+ requirement: permissionRequirement.permission,
126
+ message: `Expo runtime support for '${permissionRequirement.permission}' is '${supportMetadata.support}'.`,
127
+ support: supportMetadata.support,
128
+ });
129
+ continue;
130
+ }
131
+ if (supportMetadata.support === 'notRequired') {
132
+ continue;
133
+ }
134
+ addProvider('permissions', `permission:${permissionRequirement.permission}`);
135
+ supportMetadata.requiredPackages.forEach((packageName) => {
136
+ addDependency(packageName, `permission:${permissionRequirement.permission}`);
137
+ });
138
+ supportMetadata.configHints.forEach((configHint) => {
139
+ configHints.add(configHint);
140
+ const configHintMetadata = configHintRegistry[configHint];
141
+ if (!configHintMetadata) {
142
+ diagnostics.push({
143
+ severity: 'warning',
144
+ requirementType: 'configHint',
145
+ requirement: configHint,
146
+ message: `Config hint '${configHint}' is not translated into generated Expo config yet.`,
147
+ });
148
+ return;
149
+ }
150
+ configHintMetadata.androidPermissions?.forEach((permissionName) => {
151
+ androidPermissions.add(permissionName);
152
+ });
153
+ if (configHintMetadata.plugin) {
154
+ addPlugin(configHintMetadata.plugin);
155
+ }
156
+ });
157
+ }
158
+ for (const capabilityRequirement of capabilitiesByName.values()) {
159
+ const capabilityMetadata = capabilityRegistry[capabilityRequirement.capability];
160
+ if (!capabilityMetadata) {
161
+ diagnostics.push({
162
+ severity: 'warning',
163
+ requirementType: 'capability',
164
+ requirement: capabilityRequirement.capability,
165
+ message: `No Expo runtime metadata is registered for capability '${capabilityRequirement.capability}'.`,
166
+ });
167
+ continue;
168
+ }
169
+ capabilityMetadata.requiredPackages?.forEach((packageName) => {
170
+ addDependency(packageName, `capability:${capabilityRequirement.capability}`);
171
+ });
172
+ capabilityMetadata.providers?.forEach((provider) => {
173
+ addProvider(provider, `capability:${capabilityRequirement.capability}`);
174
+ });
175
+ capabilityMetadata.runtimeAdapters?.forEach((runtimeAdapter) => {
176
+ runtimeAdapters.add(runtimeAdapter);
177
+ });
178
+ capabilityMetadata.androidPermissions?.forEach((permissionName) => {
179
+ androidPermissions.add(permissionName);
180
+ });
181
+ capabilityMetadata.plugins?.forEach(addPlugin);
182
+ }
183
+ if (providers.size > 0 || runtimeAdapters.size > 0) {
184
+ addDependency(EXPO_RUNTIME_PACKAGE_NAME, 'runtime:expo');
185
+ }
186
+ const plugins = Array.from(pluginOptions.entries())
187
+ .map(([name, options]) => ({
188
+ name,
189
+ options: Object.keys(options).length > 0 ? options : undefined,
190
+ }))
191
+ .sort((left, right) => left.name.localeCompare(right.name));
192
+ return {
193
+ permissions: Array.from(permissionsByName.values()).sort(comparePermissionRequirements),
194
+ capabilities: Array.from(capabilitiesByName.values()).sort(compareCapabilityRequirements),
195
+ impliedPermissions: Array.from(impliedPermissionsByName.values()).sort(comparePermissionRequirements),
196
+ dependencies: Array.from(dependencies.values()).sort((left, right) => left.name.localeCompare(right.name)),
197
+ nativeConfig: {
198
+ androidPermissions: Array.from(androidPermissions).sort(),
199
+ configHints: Array.from(configHints).sort(),
200
+ plugins,
201
+ },
202
+ providers: Array.from(providers).sort(),
203
+ runtimeAdapters: Array.from(runtimeAdapters).sort(),
204
+ usesExpoRuntimeRegistry: runtimeAdapters.size > 0,
205
+ needsPermissionsProvider: providers.has('permissions'),
206
+ diagnostics,
207
+ };
208
+ }
209
+ function compareCapabilityRequirements(left, right) {
210
+ return left.capability.localeCompare(right.capability);
211
+ }
212
+ function comparePermissionRequirements(left, right) {
213
+ return left.permission.localeCompare(right.permission);
214
+ }
215
+ //# sourceMappingURL=resolveExpoRuntimePlan.js.map