@ankhorage/expo-runtime 2.6.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/README.md +1 -2
- package/dist/ExpoBarcodeScannerAdapter.d.ts.map +1 -1
- package/dist/ExpoBarcodeScannerAdapter.js +4 -16
- package/dist/ExpoBarcodeScannerAdapter.js.map +1 -1
- package/dist/barcodeScanRuntime.d.ts +4 -1
- package/dist/barcodeScanRuntime.d.ts.map +1 -1
- package/dist/barcodeScanRuntime.js +15 -1
- package/dist/barcodeScanRuntime.js.map +1 -1
- package/dist/expoRuntimePlanningMetadata.d.ts +59 -0
- package/dist/expoRuntimePlanningMetadata.d.ts.map +1 -0
- package/dist/expoRuntimePlanningMetadata.js +133 -0
- package/dist/expoRuntimePlanningMetadata.js.map +1 -0
- package/dist/mediaPicker/documentPicker.d.ts +1 -2
- package/dist/mediaPicker/documentPicker.d.ts.map +1 -1
- package/dist/mediaPicker/documentPicker.js +1 -1
- package/dist/mediaPicker/documentPicker.js.map +1 -1
- package/dist/mediaPicker/photoLibraryPicker.d.ts +1 -2
- package/dist/mediaPicker/photoLibraryPicker.d.ts.map +1 -1
- package/dist/mediaPicker/photoLibraryPicker.js +1 -1
- package/dist/mediaPicker/photoLibraryPicker.js.map +1 -1
- package/dist/mediaPicker/readSelectedBytes.d.ts +1 -4
- package/dist/mediaPicker/readSelectedBytes.d.ts.map +1 -1
- package/dist/mediaPicker/readSelectedBytes.js +7 -1
- package/dist/mediaPicker/readSelectedBytes.js.map +1 -1
- package/dist/platform.d.ts +83 -0
- package/dist/platform.d.ts.map +1 -0
- package/dist/platform.js +81 -0
- package/dist/platform.js.map +1 -0
- package/dist/resolveExpoRuntimePlan.d.ts +3 -23
- package/dist/resolveExpoRuntimePlan.d.ts.map +1 -1
- package/dist/resolveExpoRuntimePlan.js +155 -187
- package/dist/resolveExpoRuntimePlan.js.map +1 -1
- package/package.json +74 -29
- package/src/ExpoBarcodeScannerAdapter.test.tsx +47 -4
- package/src/ExpoBarcodeScannerAdapter.tsx +10 -19
- package/src/barcodeScanRuntime.ts +27 -2
- package/src/expoRuntimePlanningMetadata.ts +190 -0
- package/src/generatedAppOutput.test.ts +29 -7
- package/src/mediaPicker/documentPicker.ts +1 -6
- package/src/mediaPicker/photoLibraryPicker.ts +1 -6
- package/src/mediaPicker/readSelectedBytes.ts +12 -3
- package/src/oauthBrowserRuntime.test.ts +1 -1
- package/src/platform.test.ts +34 -0
- package/src/platform.ts +88 -0
- package/src/resolveExpoRuntimePlan.test.ts +130 -6
- package/src/resolveExpoRuntimePlan.ts +214 -244
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @ankhorage/expo-runtime
|
|
2
2
|
|
|
3
|
+
## 3.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- 8621e2b: Align the root Expo 57 runtime with released ZORA 3 and Surface 3, and make package-wide application peers optional at install time so the public `platform` subpath remains independently consumable by headless planners. Root and feature entrypoints still require consumers to install the peers they execute.
|
|
8
|
+
|
|
9
|
+
## 2.7.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- b3f74f3: Add the canonical Expo 57 platform contract, migrate runtime planning and adapters to the SDK 57 baseline, and validate the declared package set with Expo CLI and Expo Doctor.
|
|
14
|
+
|
|
3
15
|
## 2.6.0
|
|
4
16
|
|
|
5
17
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
# EXPO-RUNTIME
|
|
5
5
|
|
|
6
|
-
         
|
|
7
7
|
|
|
8
8
|
Declarative runtime integration for Expo apps: maps app capabilities to permissions, packages, config plugins, providers, and adapters
|
|
9
9
|
|
|
@@ -21,4 +21,3 @@ Declarative runtime integration for Expo apps: maps app capabilities to permissi
|
|
|
21
21
|
- [getExpoBundledMediaRegistrySource sequence](././paradox/diagrams/sequences/get-expo-bundled-media-registry-source.mmd)
|
|
22
22
|
- [resolveExpoRuntimeGeneratedAppOutput sequence](././paradox/diagrams/sequences/resolve-expo-runtime-generated-app-output.mmd)
|
|
23
23
|
- [resolveExpoRuntimeNativeOutput sequence](././paradox/diagrams/sequences/resolve-expo-runtime-native-output.mmd)
|
|
24
|
-
- [resolveExpoRuntimePlan sequence](././paradox/diagrams/sequences/resolve-expo-runtime-plan.mmd)
|
|
@@ -1 +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;
|
|
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;AAY1B,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,uBAAuB,qBAqDvE"}
|
|
@@ -3,7 +3,7 @@ import { BarcodeScannerView } from '@ankhorage/zora';
|
|
|
3
3
|
import { CameraView } from 'expo-camera';
|
|
4
4
|
import React from 'react';
|
|
5
5
|
import { StyleSheet } from 'react-native';
|
|
6
|
-
import { BARCODE_SCANNER_TYPES,
|
|
6
|
+
import { BARCODE_SCANNER_TYPES, dispatchExpoBarcodeScan, mapPermissionStatusToCameraPermissionStatus, } from './barcodeScanRuntime';
|
|
7
7
|
const CAMERA_BARCODE_TYPES = [...BARCODE_SCANNER_TYPES];
|
|
8
8
|
export function ExpoBarcodeScannerAdapter(props) {
|
|
9
9
|
const { onBarcodeScanned, onRequestPermission, ...viewProps } = props;
|
|
@@ -22,21 +22,9 @@ export function ExpoBarcodeScannerAdapter(props) {
|
|
|
22
22
|
}
|
|
23
23
|
}, [cameraPermission, onRequestPermission]);
|
|
24
24
|
const handleBarcodeScanned = React.useCallback((result) => {
|
|
25
|
-
void (
|
|
26
|
-
|
|
27
|
-
|
|
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
|
-
})();
|
|
25
|
+
void dispatchExpoBarcodeScan(result, lastScanRef.current, Date.now(), onBarcodeScanned, (record) => {
|
|
26
|
+
lastScanRef.current = record;
|
|
27
|
+
});
|
|
40
28
|
}, [onBarcodeScanned]);
|
|
41
29
|
const camera = permissionStatus === 'granted' ? (<CameraView barcodeScannerSettings={{ barcodeTypes: CAMERA_BARCODE_TYPES }} onBarcodeScanned={handleBarcodeScanned} style={styles.camera}/>) : undefined;
|
|
42
30
|
return (<BarcodeScannerView {...viewProps} camera={camera} onRequestPermission={handleRequestPermission} permissionStatus={permissionStatus}/>);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoBarcodeScannerAdapter.js","sourceRoot":"","sources":["../src/ExpoBarcodeScannerAdapter.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAgC,MAAM,iBAAiB,CAAC;AACnF,OAAO,EAAgD,UAAU,EAAE,MAAM,aAAa,CAAC;AACvF,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,OAAO,EACL,qBAAqB,EAErB,
|
|
1
|
+
{"version":3,"file":"ExpoBarcodeScannerAdapter.js","sourceRoot":"","sources":["../src/ExpoBarcodeScannerAdapter.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAgC,MAAM,iBAAiB,CAAC;AACnF,OAAO,EAAgD,UAAU,EAAE,MAAM,aAAa,CAAC;AACvF,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,OAAO,EACL,qBAAqB,EAErB,uBAAuB,EACvB,2CAA2C,GAC5C,MAAM,sBAAsB,CAAC;AAE9B,MAAM,oBAAoB,GAAkB,CAAC,GAAG,qBAAqB,CAAC,CAAC;AAEvE,MAAM,UAAU,yBAAyB,CAAC,KAA8B;IACtE,MAAM,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,GAAG,SAAS,EAAE,GAAG,KAAK,CAAC;IACtE,MAAM,gBAAgB,GAAG,aAAa,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IAC1D,MAAM,CAAC,sBAAsB,EAAE,yBAAyB,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAClF,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAA2B,IAAI,CAAC,CAAC;IAEjE,MAAM,gBAAgB,GAAG,2CAA2C,CAClE,gBAAgB,CAAC,MAAM,EACvB,sBAAsB,CACvB,CAAC;IAEF,MAAM,uBAAuB,GAAG,KAAK,CAAC,WAAW,CAAC,KAAK,IAAI,EAAE;QAC3D,yBAAyB,CAAC,IAAI,CAAC,CAAC;QAChC,IAAI,CAAC;YACH,MAAM,gBAAgB,CAAC,OAAO,EAAE,CAAC;YACjC,MAAM,mBAAmB,EAAE,EAAE,CAAC;QAChC,CAAC;gBAAS,CAAC;YACT,yBAAyB,CAAC,KAAK,CAAC,CAAC;QACnC,CAAC;IACH,CAAC,EAAE,CAAC,gBAAgB,EAAE,mBAAmB,CAAC,CAAC,CAAC;IAE5C,MAAM,oBAAoB,GAAG,KAAK,CAAC,WAAW,CAC5C,CAAC,MAA6B,EAAE,EAAE;QAChC,KAAK,uBAAuB,CAC1B,MAAM,EACN,WAAW,CAAC,OAAO,EACnB,IAAI,CAAC,GAAG,EAAE,EACV,gBAAgB,EAChB,CAAC,MAAM,EAAE,EAAE;YACT,WAAW,CAAC,OAAO,GAAG,MAAM,CAAC;QAC/B,CAAC,CACF,CAAC;IACJ,CAAC,EACD,CAAC,gBAAgB,CAAC,CACnB,CAAC;IAEF,MAAM,MAAM,GACV,gBAAgB,KAAK,SAAS,CAAC,CAAC,CAAC,CAC/B,CAAC,UAAU,CACT,sBAAsB,CAAC,CAAC,EAAE,YAAY,EAAE,oBAAoB,EAAE,CAAC,CAC/D,gBAAgB,CAAC,CAAC,oBAAoB,CAAC,CACvC,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,EACrB,CACH,CAAC,CAAC,CAAC,SAAS,CAAC;IAEhB,OAAO,CACL,CAAC,kBAAkB,CACjB,IAAI,SAAS,CAAC,CACd,MAAM,CAAC,CAAC,MAAM,CAAC,CACf,mBAAmB,CAAC,CAAC,uBAAuB,CAAC,CAC7C,gBAAgB,CAAC,CAAC,gBAAgB,CAAC,EACnC,CACH,CAAC;AACJ,CAAC;AAED,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC;IAC/B,MAAM,EAAE;QACN,IAAI,EAAE,CAAC;KACR;CACF,CAAC,CAAC","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 dispatchExpoBarcodeScan,\n mapPermissionStatusToCameraPermissionStatus,\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 dispatchExpoBarcodeScan(\n result,\n lastScanRef.current,\n Date.now(),\n onBarcodeScanned,\n (record) => {\n lastScanRef.current = record;\n },\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"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { PermissionStatus } from '@ankhorage/permissions';
|
|
2
2
|
import type { BarcodeScanResult, CameraPermissionStatus } from '@ankhorage/zora';
|
|
3
3
|
export declare const BARCODE_SCAN_DEDUPE_WINDOW_MS = 1500;
|
|
4
|
-
export declare const BARCODE_SCANNER_TYPES: readonly ["aztec", "
|
|
4
|
+
export declare const BARCODE_SCANNER_TYPES: readonly ["aztec", "codabar", "code39", "code93", "code128", "datamatrix", "ean13", "ean8", "itf14", "pdf417", "qr", "upc_a", "upc_e"];
|
|
5
5
|
export interface BarcodeScanRecord extends BarcodeScanResult {
|
|
6
6
|
readonly timestamp: number;
|
|
7
7
|
}
|
|
@@ -9,7 +9,10 @@ export interface ExpoBarcodeScanResultLike {
|
|
|
9
9
|
readonly data: string;
|
|
10
10
|
readonly type?: string;
|
|
11
11
|
}
|
|
12
|
+
type ExpoBarcodeScanCallback = (result: BarcodeScanResult) => Promise<void> | void;
|
|
12
13
|
export declare function mapPermissionStatusToCameraPermissionStatus(status: PermissionStatus, isRequestingPermission: boolean): CameraPermissionStatus;
|
|
13
14
|
export declare function normalizeExpoBarcodeScanResult(result: ExpoBarcodeScanResultLike): BarcodeScanResult | null;
|
|
14
15
|
export declare function shouldIgnoreBarcodeScan(previous: BarcodeScanRecord | null, next: BarcodeScanResult, now: number): boolean;
|
|
16
|
+
export declare function dispatchExpoBarcodeScan(result: ExpoBarcodeScanResultLike, previous: BarcodeScanRecord | null, now: number, onBarcodeScanned: ExpoBarcodeScanCallback | undefined, onAccepted: (record: BarcodeScanRecord) => void): Promise<boolean>;
|
|
17
|
+
export {};
|
|
15
18
|
//# sourceMappingURL=barcodeScanRuntime.d.ts.map
|
|
@@ -1 +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;
|
|
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;AAGjF,eAAO,MAAM,6BAA6B,OAAO,CAAC;AAElD,eAAO,MAAM,qBAAqB,wIAcS,CAAC;AAE5C,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,KAAK,uBAAuB,GAAG,CAAC,MAAM,EAAE,iBAAiB,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAEnF,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;AAED,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,yBAAyB,EACjC,QAAQ,EAAE,iBAAiB,GAAG,IAAI,EAClC,GAAG,EAAE,MAAM,EACX,gBAAgB,EAAE,uBAAuB,GAAG,SAAS,EACrD,UAAU,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,IAAI,GAC9C,OAAO,CAAC,OAAO,CAAC,CAalB"}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
export const BARCODE_SCAN_DEDUPE_WINDOW_MS = 1500;
|
|
2
2
|
export const BARCODE_SCANNER_TYPES = [
|
|
3
3
|
'aztec',
|
|
4
|
-
'
|
|
4
|
+
'codabar',
|
|
5
5
|
'code39',
|
|
6
6
|
'code93',
|
|
7
|
+
'code128',
|
|
7
8
|
'datamatrix',
|
|
8
9
|
'ean13',
|
|
9
10
|
'ean8',
|
|
@@ -45,4 +46,17 @@ export function shouldIgnoreBarcodeScan(previous, next, now) {
|
|
|
45
46
|
previous.type === next.type &&
|
|
46
47
|
now - previous.timestamp < BARCODE_SCAN_DEDUPE_WINDOW_MS);
|
|
47
48
|
}
|
|
49
|
+
export async function dispatchExpoBarcodeScan(result, previous, now, onBarcodeScanned, onAccepted) {
|
|
50
|
+
const normalizedResult = normalizeExpoBarcodeScanResult(result);
|
|
51
|
+
if (normalizedResult === null || shouldIgnoreBarcodeScan(previous, normalizedResult, now)) {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
const record = {
|
|
55
|
+
...normalizedResult,
|
|
56
|
+
timestamp: now,
|
|
57
|
+
};
|
|
58
|
+
onAccepted(record);
|
|
59
|
+
await onBarcodeScanned?.(normalizedResult);
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
48
62
|
//# sourceMappingURL=barcodeScanRuntime.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"barcodeScanRuntime.js","sourceRoot":"","sources":["../src/barcodeScanRuntime.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"barcodeScanRuntime.js","sourceRoot":"","sources":["../src/barcodeScanRuntime.ts"],"names":[],"mappings":"AAIA,MAAM,CAAC,MAAM,6BAA6B,GAAG,IAAI,CAAC;AAElD,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,OAAO;IACP,SAAS;IACT,QAAQ;IACR,QAAQ;IACR,SAAS;IACT,YAAY;IACZ,OAAO;IACP,MAAM;IACN,OAAO;IACP,QAAQ;IACR,IAAI;IACJ,OAAO;IACP,OAAO;CACkC,CAAC;AAa5C,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;AAED,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,MAAiC,EACjC,QAAkC,EAClC,GAAW,EACX,gBAAqD,EACrD,UAA+C;IAE/C,MAAM,gBAAgB,GAAG,8BAA8B,CAAC,MAAM,CAAC,CAAC;IAChE,IAAI,gBAAgB,KAAK,IAAI,IAAI,uBAAuB,CAAC,QAAQ,EAAE,gBAAgB,EAAE,GAAG,CAAC,EAAE,CAAC;QAC1F,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,MAAM,GAAG;QACb,GAAG,gBAAgB;QACnB,SAAS,EAAE,GAAG;KACf,CAAC;IACF,UAAU,CAAC,MAAM,CAAC,CAAC;IACnB,MAAM,gBAAgB,EAAE,CAAC,gBAAgB,CAAC,CAAC;IAC3C,OAAO,IAAI,CAAC;AACd,CAAC","sourcesContent":["import type { PermissionStatus } from '@ankhorage/permissions';\nimport type { BarcodeScanResult, CameraPermissionStatus } from '@ankhorage/zora';\nimport type { BarcodeType } from 'expo-camera';\n\nexport const BARCODE_SCAN_DEDUPE_WINDOW_MS = 1500;\n\nexport const BARCODE_SCANNER_TYPES = [\n 'aztec',\n 'codabar',\n 'code39',\n 'code93',\n 'code128',\n 'datamatrix',\n 'ean13',\n 'ean8',\n 'itf14',\n 'pdf417',\n 'qr',\n 'upc_a',\n 'upc_e',\n] as const satisfies readonly BarcodeType[];\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\ntype ExpoBarcodeScanCallback = (result: BarcodeScanResult) => Promise<void> | void;\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\nexport async function dispatchExpoBarcodeScan(\n result: ExpoBarcodeScanResultLike,\n previous: BarcodeScanRecord | null,\n now: number,\n onBarcodeScanned: ExpoBarcodeScanCallback | undefined,\n onAccepted: (record: BarcodeScanRecord) => void,\n): Promise<boolean> {\n const normalizedResult = normalizeExpoBarcodeScanResult(result);\n if (normalizedResult === null || shouldIgnoreBarcodeScan(previous, normalizedResult, now)) {\n return false;\n }\n\n const record = {\n ...normalizedResult,\n timestamp: now,\n };\n onAccepted(record);\n await onBarcodeScanned?.(normalizedResult);\n return true;\n}\n"]}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { AnkhorageCapabilityName, ScreenCapabilityRequirement, ScreenPermissionRequirement } from '@ankhorage/contracts';
|
|
2
|
+
import type { PermissionSupport } from '@ankhorage/permissions/expo/manifest';
|
|
3
|
+
export interface ExpoRuntimeConfigPlugin {
|
|
4
|
+
readonly name: string;
|
|
5
|
+
readonly options?: Readonly<Record<string, boolean | string>>;
|
|
6
|
+
}
|
|
7
|
+
export type ExpoRuntimeProviderId = 'permissions';
|
|
8
|
+
export type ExpoRuntimeAdapterId = 'ExpoBarcodeScannerAdapter';
|
|
9
|
+
export interface ExpoRuntimeDiagnostic {
|
|
10
|
+
readonly severity: 'error' | 'warning';
|
|
11
|
+
readonly requirementType: 'capability' | 'configHint' | 'package' | 'permission';
|
|
12
|
+
readonly requirement: string;
|
|
13
|
+
readonly message: string;
|
|
14
|
+
readonly support?: PermissionSupport;
|
|
15
|
+
}
|
|
16
|
+
export interface ExpoRuntimeCapabilityMetadata {
|
|
17
|
+
readonly impliedPermissions?: readonly ScreenPermissionRequirement[];
|
|
18
|
+
readonly requiredPackages?: readonly string[];
|
|
19
|
+
readonly providers?: readonly ExpoRuntimeProviderId[];
|
|
20
|
+
readonly runtimeAdapters?: readonly ExpoRuntimeAdapterId[];
|
|
21
|
+
readonly androidPermissions?: readonly string[];
|
|
22
|
+
readonly plugins?: readonly ExpoRuntimeConfigPlugin[];
|
|
23
|
+
}
|
|
24
|
+
export interface ExpoRuntimeHintMetadata {
|
|
25
|
+
readonly androidPermissions?: readonly string[];
|
|
26
|
+
readonly plugin?: ExpoRuntimeConfigPlugin;
|
|
27
|
+
}
|
|
28
|
+
export declare const GENERATED_RUNTIME_DEPENDENCY_VERSIONS: {
|
|
29
|
+
readonly '@ankhorage/permissions': "^0.2.2";
|
|
30
|
+
readonly '@ankhorage/expo-runtime': "^3.0.0";
|
|
31
|
+
};
|
|
32
|
+
export declare const EXPO_RUNTIME_PROVIDER_PACKAGES: {
|
|
33
|
+
readonly permissions: "@ankhorage/permissions";
|
|
34
|
+
};
|
|
35
|
+
export declare const EXPO_CAPABILITY_RUNTIME_REGISTRY: {
|
|
36
|
+
readonly barcodeScanner: {
|
|
37
|
+
readonly impliedPermissions: readonly [{
|
|
38
|
+
readonly permission: "camera";
|
|
39
|
+
}];
|
|
40
|
+
readonly requiredPackages: readonly [string];
|
|
41
|
+
readonly providers: readonly ["permissions"];
|
|
42
|
+
readonly runtimeAdapters: readonly ["ExpoBarcodeScannerAdapter"];
|
|
43
|
+
readonly plugins: readonly [{
|
|
44
|
+
readonly name: string;
|
|
45
|
+
readonly options: {
|
|
46
|
+
readonly cameraPermission: "Allow camera access to scan barcodes.";
|
|
47
|
+
readonly barcodeScannerEnabled: true;
|
|
48
|
+
readonly microphonePermission: false;
|
|
49
|
+
readonly recordAudioAndroid: false;
|
|
50
|
+
};
|
|
51
|
+
}];
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
export declare function findCapabilityMetadata(registry: Readonly<Partial<Record<AnkhorageCapabilityName, ExpoRuntimeCapabilityMetadata>>>, requirement: ScreenCapabilityRequirement): ExpoRuntimeCapabilityMetadata | undefined;
|
|
55
|
+
export declare function findConfigHintMetadata(configHint: string): ExpoRuntimeHintMetadata | undefined;
|
|
56
|
+
export declare function unknownPermissionDiagnostic(permission: string): ExpoRuntimeDiagnostic;
|
|
57
|
+
export declare function unsupportedPermissionDiagnostic(permission: string, support: PermissionSupport): ExpoRuntimeDiagnostic;
|
|
58
|
+
export declare function unknownCapabilityDiagnostic(capability: string): ExpoRuntimeDiagnostic;
|
|
59
|
+
//# sourceMappingURL=expoRuntimePlanningMetadata.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expoRuntimePlanningMetadata.d.ts","sourceRoot":"","sources":["../src/expoRuntimePlanningMetadata.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,uBAAuB,EACvB,2BAA2B,EAC3B,2BAA2B,EAC5B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AAI9E,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC;CAC/D;AAED,MAAM,MAAM,qBAAqB,GAAG,aAAa,CAAC;AAClD,MAAM,MAAM,oBAAoB,GAAG,2BAA2B,CAAC;AAE/D,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,eAAe,EAAE,YAAY,GAAG,YAAY,GAAG,SAAS,GAAG,YAAY,CAAC;IACjF,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,iBAAiB,CAAC;CACtC;AAED,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,kBAAkB,CAAC,EAAE,SAAS,2BAA2B,EAAE,CAAC;IACrE,QAAQ,CAAC,gBAAgB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9C,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,qBAAqB,EAAE,CAAC;IACtD,QAAQ,CAAC,eAAe,CAAC,EAAE,SAAS,oBAAoB,EAAE,CAAC;IAC3D,QAAQ,CAAC,kBAAkB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAChD,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,uBAAuB,EAAE,CAAC;CACvD;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAChD,QAAQ,CAAC,MAAM,CAAC,EAAE,uBAAuB,CAAC;CAC3C;AAcD,eAAO,MAAM,qCAAqC;;;CAGG,CAAC;AAEtD,eAAO,MAAM,8BAA8B;;CAEe,CAAC;AAqE3D,eAAO,MAAM,gCAAgC;;;;;;;;;;;;;;;;;;CAoB5C,CAAC;AAEF,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,uBAAuB,EAAE,6BAA6B,CAAC,CAAC,CAAC,EAC3F,WAAW,EAAE,2BAA2B,GACvC,6BAA6B,GAAG,SAAS,CAE3C;AAED,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,MAAM,GAAG,uBAAuB,GAAG,SAAS,CAE9F;AAED,wBAAgB,2BAA2B,CAAC,UAAU,EAAE,MAAM,GAAG,qBAAqB,CAOrF;AAED,wBAAgB,+BAA+B,CAC7C,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,iBAAiB,GACzB,qBAAqB,CAQvB;AAED,wBAAgB,2BAA2B,CAAC,UAAU,EAAE,MAAM,GAAG,qBAAqB,CAOrF"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { EXPO_PLATFORM } from './platform';
|
|
2
|
+
const GENERATED_ANKHORAGE_DEPENDENCY_VERSIONS = {
|
|
3
|
+
'@ankhorage/permissions': '^0.2.2',
|
|
4
|
+
'@ankhorage/expo-runtime': '^3.0.0',
|
|
5
|
+
};
|
|
6
|
+
const GENERATED_EXPO_DEPENDENCY_VERSIONS = Object.fromEntries(Object.values(EXPO_PLATFORM.packages).map((dependency) => [
|
|
7
|
+
dependency.name,
|
|
8
|
+
dependency.version,
|
|
9
|
+
]));
|
|
10
|
+
export const GENERATED_RUNTIME_DEPENDENCY_VERSIONS = {
|
|
11
|
+
...GENERATED_ANKHORAGE_DEPENDENCY_VERSIONS,
|
|
12
|
+
...GENERATED_EXPO_DEPENDENCY_VERSIONS,
|
|
13
|
+
};
|
|
14
|
+
export const EXPO_RUNTIME_PROVIDER_PACKAGES = {
|
|
15
|
+
permissions: '@ankhorage/permissions',
|
|
16
|
+
};
|
|
17
|
+
const EXPO_RUNTIME_CONFIG_HINTS = {
|
|
18
|
+
cameraPermission: {
|
|
19
|
+
plugin: {
|
|
20
|
+
name: EXPO_PLATFORM.packages.camera.name,
|
|
21
|
+
options: {
|
|
22
|
+
barcodeScannerEnabled: false,
|
|
23
|
+
cameraPermission: 'Allow camera access.',
|
|
24
|
+
microphonePermission: false,
|
|
25
|
+
recordAudioAndroid: false,
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
microphonePermission: {
|
|
30
|
+
plugin: {
|
|
31
|
+
name: EXPO_PLATFORM.packages.audio.name,
|
|
32
|
+
options: {
|
|
33
|
+
enableBackgroundPlayback: false,
|
|
34
|
+
enableBackgroundRecording: false,
|
|
35
|
+
microphonePermission: 'Allow microphone access.',
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
recordAudioAndroid: {
|
|
40
|
+
plugin: {
|
|
41
|
+
name: EXPO_PLATFORM.packages.audio.name,
|
|
42
|
+
options: {
|
|
43
|
+
enableBackgroundPlayback: false,
|
|
44
|
+
enableBackgroundRecording: false,
|
|
45
|
+
recordAudioAndroid: true,
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
mediaLibraryPermission: {
|
|
50
|
+
plugin: {
|
|
51
|
+
name: EXPO_PLATFORM.packages.mediaLibrary.name,
|
|
52
|
+
options: {
|
|
53
|
+
photosPermission: 'Allow photo library access.',
|
|
54
|
+
savePhotosPermission: 'Allow saving to the photo library.',
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
locationWhenInUsePermission: {
|
|
59
|
+
plugin: {
|
|
60
|
+
name: EXPO_PLATFORM.packages.location.name,
|
|
61
|
+
options: {
|
|
62
|
+
locationWhenInUsePermission: 'Allow location access while using the app.',
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
locationAlwaysAndWhenInUsePermission: {
|
|
67
|
+
plugin: {
|
|
68
|
+
name: EXPO_PLATFORM.packages.location.name,
|
|
69
|
+
options: {
|
|
70
|
+
locationAlwaysAndWhenInUsePermission: 'Allow location access.',
|
|
71
|
+
isAndroidBackgroundLocationEnabled: true,
|
|
72
|
+
isAndroidForegroundServiceEnabled: true,
|
|
73
|
+
isIosBackgroundLocationEnabled: true,
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
notificationsPermission: {
|
|
78
|
+
plugin: {
|
|
79
|
+
name: EXPO_PLATFORM.packages.notifications.name,
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
export const EXPO_CAPABILITY_RUNTIME_REGISTRY = {
|
|
84
|
+
barcodeScanner: {
|
|
85
|
+
impliedPermissions: [{ permission: 'camera' }],
|
|
86
|
+
requiredPackages: [EXPO_PLATFORM.packages.camera.name],
|
|
87
|
+
providers: ['permissions'],
|
|
88
|
+
runtimeAdapters: ['ExpoBarcodeScannerAdapter'],
|
|
89
|
+
plugins: [
|
|
90
|
+
{
|
|
91
|
+
name: EXPO_PLATFORM.packages.camera.name,
|
|
92
|
+
options: {
|
|
93
|
+
cameraPermission: 'Allow camera access to scan barcodes.',
|
|
94
|
+
barcodeScannerEnabled: true,
|
|
95
|
+
microphonePermission: false,
|
|
96
|
+
recordAudioAndroid: false,
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
],
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
export function findCapabilityMetadata(registry, requirement) {
|
|
103
|
+
return Object.entries(registry).find(([name]) => name === requirement.capability)?.[1];
|
|
104
|
+
}
|
|
105
|
+
export function findConfigHintMetadata(configHint) {
|
|
106
|
+
return Object.entries(EXPO_RUNTIME_CONFIG_HINTS).find(([name]) => name === configHint)?.[1];
|
|
107
|
+
}
|
|
108
|
+
export function unknownPermissionDiagnostic(permission) {
|
|
109
|
+
return {
|
|
110
|
+
severity: 'error',
|
|
111
|
+
requirementType: 'permission',
|
|
112
|
+
requirement: permission,
|
|
113
|
+
message: `Unknown permission '${permission}' cannot be resolved for Expo runtime generation.`,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
export function unsupportedPermissionDiagnostic(permission, support) {
|
|
117
|
+
return {
|
|
118
|
+
severity: support === 'limited' ? 'warning' : 'error',
|
|
119
|
+
requirementType: 'permission',
|
|
120
|
+
requirement: permission,
|
|
121
|
+
message: `Expo runtime support for '${permission}' is '${support}'.`,
|
|
122
|
+
support,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
export function unknownCapabilityDiagnostic(capability) {
|
|
126
|
+
return {
|
|
127
|
+
severity: 'warning',
|
|
128
|
+
requirementType: 'capability',
|
|
129
|
+
requirement: capability,
|
|
130
|
+
message: `No Expo runtime metadata is registered for capability '${capability}'.`,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=expoRuntimePlanningMetadata.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expoRuntimePlanningMetadata.js","sourceRoot":"","sources":["../src/expoRuntimePlanningMetadata.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AnkhorageCapabilityName,\n ScreenCapabilityRequirement,\n ScreenPermissionRequirement,\n} from '@ankhorage/contracts';\nimport type { PermissionSupport } from '@ankhorage/permissions/expo/manifest';\n\nimport { EXPO_PLATFORM, type ExpoPlatformPackage } from './platform';\n\nexport interface ExpoRuntimeConfigPlugin {\n readonly name: string;\n readonly options?: Readonly<Record<string, boolean | string>>;\n}\n\nexport type ExpoRuntimeProviderId = 'permissions';\nexport type ExpoRuntimeAdapterId = 'ExpoBarcodeScannerAdapter';\n\nexport interface ExpoRuntimeDiagnostic {\n readonly severity: 'error' | 'warning';\n readonly requirementType: 'capability' | 'configHint' | 'package' | 'permission';\n readonly requirement: string;\n readonly message: string;\n readonly support?: PermissionSupport;\n}\n\nexport interface ExpoRuntimeCapabilityMetadata {\n readonly impliedPermissions?: readonly ScreenPermissionRequirement[];\n readonly requiredPackages?: readonly string[];\n readonly providers?: readonly ExpoRuntimeProviderId[];\n readonly runtimeAdapters?: readonly ExpoRuntimeAdapterId[];\n readonly androidPermissions?: readonly string[];\n readonly plugins?: readonly ExpoRuntimeConfigPlugin[];\n}\n\nexport interface ExpoRuntimeHintMetadata {\n readonly androidPermissions?: readonly string[];\n readonly plugin?: ExpoRuntimeConfigPlugin;\n}\n\nconst GENERATED_ANKHORAGE_DEPENDENCY_VERSIONS = {\n '@ankhorage/permissions': '^0.2.2',\n '@ankhorage/expo-runtime': '^3.0.0',\n} as const satisfies Record<string, string>;\n\nconst GENERATED_EXPO_DEPENDENCY_VERSIONS = Object.fromEntries(\n Object.values(EXPO_PLATFORM.packages).map((dependency: ExpoPlatformPackage) => [\n dependency.name,\n dependency.version,\n ]),\n) as Readonly<Record<string, string>>;\n\nexport const GENERATED_RUNTIME_DEPENDENCY_VERSIONS = {\n ...GENERATED_ANKHORAGE_DEPENDENCY_VERSIONS,\n ...GENERATED_EXPO_DEPENDENCY_VERSIONS,\n} as const satisfies Readonly<Record<string, string>>;\n\nexport const EXPO_RUNTIME_PROVIDER_PACKAGES = {\n permissions: '@ankhorage/permissions',\n} as const satisfies Record<ExpoRuntimeProviderId, string>;\n\nconst EXPO_RUNTIME_CONFIG_HINTS = {\n cameraPermission: {\n plugin: {\n name: EXPO_PLATFORM.packages.camera.name,\n options: {\n barcodeScannerEnabled: false,\n cameraPermission: 'Allow camera access.',\n microphonePermission: false,\n recordAudioAndroid: false,\n },\n },\n },\n microphonePermission: {\n plugin: {\n name: EXPO_PLATFORM.packages.audio.name,\n options: {\n enableBackgroundPlayback: false,\n enableBackgroundRecording: false,\n microphonePermission: 'Allow microphone access.',\n },\n },\n },\n recordAudioAndroid: {\n plugin: {\n name: EXPO_PLATFORM.packages.audio.name,\n options: {\n enableBackgroundPlayback: false,\n enableBackgroundRecording: false,\n recordAudioAndroid: true,\n },\n },\n },\n mediaLibraryPermission: {\n plugin: {\n name: EXPO_PLATFORM.packages.mediaLibrary.name,\n options: {\n photosPermission: 'Allow photo library access.',\n savePhotosPermission: 'Allow saving to the photo library.',\n },\n },\n },\n locationWhenInUsePermission: {\n plugin: {\n name: EXPO_PLATFORM.packages.location.name,\n options: {\n locationWhenInUsePermission: 'Allow location access while using the app.',\n },\n },\n },\n locationAlwaysAndWhenInUsePermission: {\n plugin: {\n name: EXPO_PLATFORM.packages.location.name,\n options: {\n locationAlwaysAndWhenInUsePermission: 'Allow location access.',\n isAndroidBackgroundLocationEnabled: true,\n isAndroidForegroundServiceEnabled: true,\n isIosBackgroundLocationEnabled: true,\n },\n },\n },\n notificationsPermission: {\n plugin: {\n name: EXPO_PLATFORM.packages.notifications.name,\n },\n },\n} as const satisfies Readonly<Record<string, ExpoRuntimeHintMetadata>>;\n\nexport const EXPO_CAPABILITY_RUNTIME_REGISTRY = {\n barcodeScanner: {\n impliedPermissions: [{ permission: 'camera' }],\n requiredPackages: [EXPO_PLATFORM.packages.camera.name],\n providers: ['permissions'],\n runtimeAdapters: ['ExpoBarcodeScannerAdapter'],\n plugins: [\n {\n name: EXPO_PLATFORM.packages.camera.name,\n options: {\n cameraPermission: 'Allow camera access to scan barcodes.',\n barcodeScannerEnabled: true,\n microphonePermission: false,\n recordAudioAndroid: false,\n },\n },\n ],\n },\n} as const satisfies Readonly<\n Partial<Record<AnkhorageCapabilityName, ExpoRuntimeCapabilityMetadata>>\n>;\n\nexport function findCapabilityMetadata(\n registry: Readonly<Partial<Record<AnkhorageCapabilityName, ExpoRuntimeCapabilityMetadata>>>,\n requirement: ScreenCapabilityRequirement,\n): ExpoRuntimeCapabilityMetadata | undefined {\n return Object.entries(registry).find(([name]) => name === requirement.capability)?.[1];\n}\n\nexport function findConfigHintMetadata(configHint: string): ExpoRuntimeHintMetadata | undefined {\n return Object.entries(EXPO_RUNTIME_CONFIG_HINTS).find(([name]) => name === configHint)?.[1];\n}\n\nexport function unknownPermissionDiagnostic(permission: string): ExpoRuntimeDiagnostic {\n return {\n severity: 'error',\n requirementType: 'permission',\n requirement: permission,\n message: `Unknown permission '${permission}' cannot be resolved for Expo runtime generation.`,\n };\n}\n\nexport function unsupportedPermissionDiagnostic(\n permission: string,\n support: PermissionSupport,\n): ExpoRuntimeDiagnostic {\n return {\n severity: support === 'limited' ? 'warning' : 'error',\n requirementType: 'permission',\n requirement: permission,\n message: `Expo runtime support for '${permission}' is '${support}'.`,\n support,\n };\n}\n\nexport function unknownCapabilityDiagnostic(capability: string): ExpoRuntimeDiagnostic {\n return {\n severity: 'warning',\n requirementType: 'capability',\n requirement: capability,\n message: `No Expo runtime metadata is registered for capability '${capability}'.`,\n };\n}\n"]}
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import type { MediaAssetKind } from '@ankhorage/contracts';
|
|
2
|
-
import { type
|
|
2
|
+
import { type SelectedMediaByteSource } from './readSelectedBytes';
|
|
3
3
|
import type { ExpoMediaPickerInput, ExpoMediaPickerResult } from './types';
|
|
4
4
|
interface DocumentPickerAssetLike extends SelectedMediaByteSource {
|
|
5
5
|
readonly name: string;
|
|
6
6
|
readonly mimeType?: string;
|
|
7
7
|
readonly size?: number;
|
|
8
|
-
readonly file?: ArrayBufferReadable;
|
|
9
8
|
}
|
|
10
9
|
interface DocumentPickerResultLike {
|
|
11
10
|
readonly canceled: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"documentPicker.d.ts","sourceRoot":"","sources":["../../src/mediaPicker/documentPicker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAO3D,OAAO,
|
|
1
|
+
{"version":3,"file":"documentPicker.d.ts","sourceRoot":"","sources":["../../src/mediaPicker/documentPicker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAO3D,OAAO,EAA0B,KAAK,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAC3F,OAAO,KAAK,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAE3E,UAAU,uBAAwB,SAAQ,uBAAuB;IAC/D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,UAAU,wBAAwB;IAChC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,SAAS,uBAAuB,EAAE,GAAG,IAAI,CAAC;CAC5D;AAED,KAAK,UAAU,GAAG,CAAC,MAAM,EAAE,uBAAuB,KAAK,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;AAElF,wBAAsB,6BAA6B,CACjD,MAAM,EAAE,wBAAwB,EAChC,UAAU,EAAE,SAAS,cAAc,EAAE,GAAG,SAAS,EACjD,SAAS,GAAE,UAAmC,GAC7C,OAAO,CAAC,qBAAqB,CAAC,CAkBhC;AAED,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,oBAAoB,GAC1B,OAAO,CAAC,qBAAqB,CAAC,CAahC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { inferMediaAssetKind, isRequestedMediaKind, resolveDocumentPickerMimeTypes, } from './mediaKinds';
|
|
2
|
-
import { readSelectedMediaBytes
|
|
2
|
+
import { readSelectedMediaBytes } from './readSelectedBytes';
|
|
3
3
|
export async function normalizeDocumentPickerResult(result, mediaKinds, readBytes = readSelectedMediaBytes) {
|
|
4
4
|
if (result.canceled)
|
|
5
5
|
return { ok: false, reason: 'cancelled' };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"documentPicker.js","sourceRoot":"","sources":["../../src/mediaPicker/documentPicker.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,8BAA8B,GAC/B,MAAM,cAAc,CAAC;AACtB,OAAO,
|
|
1
|
+
{"version":3,"file":"documentPicker.js","sourceRoot":"","sources":["../../src/mediaPicker/documentPicker.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,8BAA8B,GAC/B,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,sBAAsB,EAAgC,MAAM,qBAAqB,CAAC;AAgB3F,MAAM,CAAC,KAAK,UAAU,6BAA6B,CACjD,MAAgC,EAChC,UAAiD,EACjD,YAAwB,sBAAsB;IAE9C,IAAI,MAAM,CAAC,QAAQ;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;IAC/D,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;IACjC,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAC5D,MAAM,IAAI,GAAG,mBAAmB,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;IAC7D,IAAI,CAAC,oBAAoB,CAAC,IAAI,EAAE,UAAU,CAAC;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAC9F,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,KAAK,CAAC,CAAC;IACpC,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC;IACvD,OAAO;QACL,EAAE,EAAE,IAAI;QACR,SAAS,EAAE;YACT,IAAI;YACJ,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,IAAI;YACJ,WAAW,EAAE,KAAK,CAAC,QAAQ;YAC3B,SAAS,EAAE,KAAK,CAAC,IAAI,IAAI,IAAI,CAAC,UAAU;SACzC;KACF,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,KAA2B;IAE3B,IAAI,CAAC;QACH,MAAM,cAAc,GAAG,MAAM,MAAM,CAAC,sBAAsB,CAAC,CAAC;QAC5D,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,gBAAgB,CAAC;YACnD,MAAM,EAAE,KAAK;YACb,oBAAoB,EAAE,IAAI;YAC1B,QAAQ,EAAE,KAAK;YACf,IAAI,EAAE,8BAA8B,CAAC,KAAK,CAAC,UAAU,CAAC;SACvD,CAAC,CAAC;QACH,OAAO,MAAM,6BAA6B,CAAC,MAAM,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;IACvE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC;IAChD,CAAC;AACH,CAAC","sourcesContent":["import type { MediaAssetKind } from '@ankhorage/contracts';\n\nimport {\n inferMediaAssetKind,\n isRequestedMediaKind,\n resolveDocumentPickerMimeTypes,\n} from './mediaKinds';\nimport { readSelectedMediaBytes, type SelectedMediaByteSource } from './readSelectedBytes';\nimport type { ExpoMediaPickerInput, ExpoMediaPickerResult } from './types';\n\ninterface DocumentPickerAssetLike extends SelectedMediaByteSource {\n readonly name: string;\n readonly mimeType?: string;\n readonly size?: number;\n}\n\ninterface DocumentPickerResultLike {\n readonly canceled: boolean;\n readonly assets: readonly DocumentPickerAssetLike[] | null;\n}\n\ntype ByteReader = (source: SelectedMediaByteSource) => Promise<Uint8Array | null>;\n\nexport async function normalizeDocumentPickerResult(\n result: DocumentPickerResultLike,\n mediaKinds: readonly MediaAssetKind[] | undefined,\n readBytes: ByteReader = readSelectedMediaBytes,\n): Promise<ExpoMediaPickerResult> {\n if (result.canceled) return { ok: false, reason: 'cancelled' };\n const asset = result.assets?.[0];\n if (!asset) return { ok: false, reason: 'empty-selection' };\n const kind = inferMediaAssetKind(asset.mimeType, asset.name);\n if (!isRequestedMediaKind(kind, mediaKinds)) return { ok: false, reason: 'unsupported-kind' };\n const body = await readBytes(asset);\n if (!body) return { ok: false, reason: 'read-failed' };\n return {\n ok: true,\n selection: {\n kind,\n name: asset.name,\n body,\n contentType: asset.mimeType,\n sizeBytes: asset.size ?? body.byteLength,\n },\n };\n}\n\nexport async function pickDocumentMedia(\n input: ExpoMediaPickerInput,\n): Promise<ExpoMediaPickerResult> {\n try {\n const DocumentPicker = await import('expo-document-picker');\n const result = await DocumentPicker.getDocumentAsync({\n base64: false,\n copyToCacheDirectory: true,\n multiple: false,\n type: resolveDocumentPickerMimeTypes(input.mediaKinds),\n });\n return await normalizeDocumentPickerResult(result, input.mediaKinds);\n } catch {\n return { ok: false, reason: 'picker-failed' };\n }\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { MediaAssetKind } from '@ankhorage/contracts';
|
|
2
|
-
import { type
|
|
2
|
+
import { type SelectedMediaByteSource } from './readSelectedBytes';
|
|
3
3
|
import type { ExpoMediaPickerInput, ExpoMediaPickerResult } from './types';
|
|
4
4
|
export type ExpoPhotoLibraryMediaType = 'images' | 'videos';
|
|
5
5
|
interface PhotoLibraryAssetLike extends SelectedMediaByteSource {
|
|
@@ -10,7 +10,6 @@ interface PhotoLibraryAssetLike extends SelectedMediaByteSource {
|
|
|
10
10
|
readonly height: number;
|
|
11
11
|
readonly duration?: number | null;
|
|
12
12
|
readonly type?: 'image' | 'video' | 'livePhoto' | 'pairedVideo' | null;
|
|
13
|
-
readonly file?: ArrayBufferReadable;
|
|
14
13
|
}
|
|
15
14
|
interface PhotoLibraryResultLike {
|
|
16
15
|
readonly canceled: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"photoLibraryPicker.d.ts","sourceRoot":"","sources":["../../src/mediaPicker/photoLibraryPicker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAG3D,OAAO,
|
|
1
|
+
{"version":3,"file":"photoLibraryPicker.d.ts","sourceRoot":"","sources":["../../src/mediaPicker/photoLibraryPicker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAG3D,OAAO,EAA0B,KAAK,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAC3F,OAAO,KAAK,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAE3E,MAAM,MAAM,yBAAyB,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAE5D,UAAU,qBAAsB,SAAQ,uBAAuB;IAC7D,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,GAAG,WAAW,GAAG,aAAa,GAAG,IAAI,CAAC;CACxE;AAED,UAAU,sBAAsB;IAC9B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,SAAS,qBAAqB,EAAE,GAAG,IAAI,CAAC;CAC1D;AAED,KAAK,UAAU,GAAG,CAAC,MAAM,EAAE,uBAAuB,KAAK,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;AAElF,wBAAgB,6BAA6B,CAC3C,UAAU,CAAC,EAAE,SAAS,cAAc,EAAE,GACrC,yBAAyB,EAAE,GAAG,IAAI,CAMpC;AAED,wBAAsB,2BAA2B,CAC/C,MAAM,EAAE,sBAAsB,EAC9B,UAAU,EAAE,SAAS,cAAc,EAAE,GAAG,SAAS,EACjD,SAAS,GAAE,UAAmC,GAC7C,OAAO,CAAC,qBAAqB,CAAC,CAqBhC;AAED,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,oBAAoB,GAC1B,OAAO,CAAC,qBAAqB,CAAC,CAiBhC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { isRequestedMediaKind } from './mediaKinds';
|
|
2
|
-
import { readSelectedMediaBytes
|
|
2
|
+
import { readSelectedMediaBytes } from './readSelectedBytes';
|
|
3
3
|
export function resolvePhotoLibraryMediaTypes(mediaKinds) {
|
|
4
4
|
if (!mediaKinds?.length)
|
|
5
5
|
return ['images', 'videos'];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"photoLibraryPicker.js","sourceRoot":"","sources":["../../src/mediaPicker/photoLibraryPicker.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,
|
|
1
|
+
{"version":3,"file":"photoLibraryPicker.js","sourceRoot":"","sources":["../../src/mediaPicker/photoLibraryPicker.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,sBAAsB,EAAgC,MAAM,qBAAqB,CAAC;AAsB3F,MAAM,UAAU,6BAA6B,CAC3C,UAAsC;IAEtC,IAAI,CAAC,UAAU,EAAE,MAAM;QAAE,OAAO,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACrD,MAAM,UAAU,GAAgC,EAAE,CAAC;IACnD,IAAI,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC;QAAE,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC5D,IAAI,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC;QAAE,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC5D,OAAO,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC;AACnD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAC/C,MAA8B,EAC9B,UAAiD,EACjD,YAAwB,sBAAsB;IAE9C,IAAI,MAAM,CAAC,QAAQ;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;IAC/D,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;IACjC,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAC5D,MAAM,IAAI,GAAG,4BAA4B,CAAC,KAAK,CAAC,CAAC;IACjD,IAAI,CAAC,oBAAoB,CAAC,IAAI,EAAE,UAAU,CAAC;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAC9F,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,KAAK,CAAC,CAAC;IACpC,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC;IACvD,OAAO;QACL,EAAE,EAAE,IAAI;QACR,SAAS,EAAE;YACT,IAAI;YACJ,IAAI,EAAE,KAAK,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,YAAY,IAAI,EAAE;YAClD,IAAI;YACJ,WAAW,EAAE,KAAK,CAAC,QAAQ,IAAI,SAAS;YACxC,SAAS,EAAE,KAAK,CAAC,QAAQ,IAAI,IAAI,CAAC,UAAU;YAC5C,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,UAAU,EAAE,KAAK,CAAC,QAAQ,IAAI,SAAS;SACxC;KACF,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,KAA2B;IAE3B,MAAM,UAAU,GAAG,6BAA6B,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IACnE,IAAI,CAAC,UAAU;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAClE,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,MAAM,MAAM,CAAC,mBAAmB,CAAC,CAAC;QACtD,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,uBAAuB,CAAC;YACvD,aAAa,EAAE,KAAK;YACpB,uBAAuB,EAAE,KAAK;YAC9B,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,KAAK;YACX,UAAU;YACV,OAAO,EAAE,CAAC;SACX,CAAC,CAAC;QACH,OAAO,MAAM,2BAA2B,CAAC,MAAM,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;IACrE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC;IAChD,CAAC;AACH,CAAC;AAED,SAAS,4BAA4B,CAAC,KAA4B;IAChE,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,KAAK,CAAC,IAAI,KAAK,aAAa;QAAE,OAAO,OAAO,CAAC;IAC3E,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW;QAAE,OAAO,OAAO,CAAC;IACzE,IAAI,KAAK,CAAC,QAAQ,EAAE,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,OAAO,CAAC;IACzD,OAAO,KAAK,CAAC,QAAQ,KAAK,IAAI,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;AACrF,CAAC","sourcesContent":["import type { MediaAssetKind } from '@ankhorage/contracts';\n\nimport { isRequestedMediaKind } from './mediaKinds';\nimport { readSelectedMediaBytes, type SelectedMediaByteSource } from './readSelectedBytes';\nimport type { ExpoMediaPickerInput, ExpoMediaPickerResult } from './types';\n\nexport type ExpoPhotoLibraryMediaType = 'images' | 'videos';\n\ninterface PhotoLibraryAssetLike extends SelectedMediaByteSource {\n readonly fileName?: string | null;\n readonly fileSize?: number;\n readonly mimeType?: string | null;\n readonly width: number;\n readonly height: number;\n readonly duration?: number | null;\n readonly type?: 'image' | 'video' | 'livePhoto' | 'pairedVideo' | null;\n}\n\ninterface PhotoLibraryResultLike {\n readonly canceled: boolean;\n readonly assets: readonly PhotoLibraryAssetLike[] | null;\n}\n\ntype ByteReader = (source: SelectedMediaByteSource) => Promise<Uint8Array | null>;\n\nexport function resolvePhotoLibraryMediaTypes(\n mediaKinds?: readonly MediaAssetKind[],\n): ExpoPhotoLibraryMediaType[] | null {\n if (!mediaKinds?.length) return ['images', 'videos'];\n const mediaTypes: ExpoPhotoLibraryMediaType[] = [];\n if (mediaKinds.includes('image')) mediaTypes.push('images');\n if (mediaKinds.includes('video')) mediaTypes.push('videos');\n return mediaTypes.length > 0 ? mediaTypes : null;\n}\n\nexport async function normalizePhotoLibraryResult(\n result: PhotoLibraryResultLike,\n mediaKinds: readonly MediaAssetKind[] | undefined,\n readBytes: ByteReader = readSelectedMediaBytes,\n): Promise<ExpoMediaPickerResult> {\n if (result.canceled) return { ok: false, reason: 'cancelled' };\n const asset = result.assets?.[0];\n if (!asset) return { ok: false, reason: 'empty-selection' };\n const kind = resolvePhotoLibraryAssetKind(asset);\n if (!isRequestedMediaKind(kind, mediaKinds)) return { ok: false, reason: 'unsupported-kind' };\n const body = await readBytes(asset);\n if (!body) return { ok: false, reason: 'read-failed' };\n return {\n ok: true,\n selection: {\n kind,\n name: asset.fileName?.trim() ?? `selected-${kind}`,\n body,\n contentType: asset.mimeType ?? undefined,\n sizeBytes: asset.fileSize ?? body.byteLength,\n width: asset.width,\n height: asset.height,\n durationMs: asset.duration ?? undefined,\n },\n };\n}\n\nexport async function pickPhotoLibraryMedia(\n input: ExpoMediaPickerInput,\n): Promise<ExpoMediaPickerResult> {\n const mediaTypes = resolvePhotoLibraryMediaTypes(input.mediaKinds);\n if (!mediaTypes) return { ok: false, reason: 'unsupported-kind' };\n try {\n const ImagePicker = await import('expo-image-picker');\n const result = await ImagePicker.launchImageLibraryAsync({\n allowsEditing: false,\n allowsMultipleSelection: false,\n base64: false,\n exif: false,\n mediaTypes,\n quality: 1,\n });\n return await normalizePhotoLibraryResult(result, input.mediaKinds);\n } catch {\n return { ok: false, reason: 'picker-failed' };\n }\n}\n\nfunction resolvePhotoLibraryAssetKind(asset: PhotoLibraryAssetLike): 'image' | 'video' {\n if (asset.type === 'video' || asset.type === 'pairedVideo') return 'video';\n if (asset.type === 'image' || asset.type === 'livePhoto') return 'image';\n if (asset.mimeType?.startsWith('video/')) return 'video';\n return asset.duration !== null && asset.duration !== undefined ? 'video' : 'image';\n}\n"]}
|
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
export interface ArrayBufferReadable {
|
|
2
|
-
arrayBuffer(): Promise<ArrayBuffer>;
|
|
3
|
-
}
|
|
4
1
|
export interface SelectedMediaByteSource {
|
|
5
2
|
readonly uri: string;
|
|
6
|
-
readonly file?:
|
|
3
|
+
readonly file?: unknown;
|
|
7
4
|
}
|
|
8
5
|
export declare function readSelectedMediaBytes(source: SelectedMediaByteSource): Promise<Uint8Array | null>;
|
|
9
6
|
//# sourceMappingURL=readSelectedBytes.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"readSelectedBytes.d.ts","sourceRoot":"","sources":["../../src/mediaPicker/readSelectedBytes.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"readSelectedBytes.d.ts","sourceRoot":"","sources":["../../src/mediaPicker/readSelectedBytes.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,uBAAuB,GAC9B,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAU5B"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export async function readSelectedMediaBytes(source) {
|
|
2
2
|
try {
|
|
3
|
-
if (source.file) {
|
|
3
|
+
if (isArrayBufferReadable(source.file)) {
|
|
4
4
|
return new Uint8Array(await source.file.arrayBuffer());
|
|
5
5
|
}
|
|
6
6
|
const { File } = await import('expo-file-system');
|
|
@@ -10,4 +10,10 @@ export async function readSelectedMediaBytes(source) {
|
|
|
10
10
|
return null;
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
|
+
function isArrayBufferReadable(value) {
|
|
14
|
+
return (typeof value === 'object' &&
|
|
15
|
+
value !== null &&
|
|
16
|
+
'arrayBuffer' in value &&
|
|
17
|
+
typeof value.arrayBuffer === 'function');
|
|
18
|
+
}
|
|
13
19
|
//# sourceMappingURL=readSelectedBytes.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"readSelectedBytes.js","sourceRoot":"","sources":["../../src/mediaPicker/readSelectedBytes.ts"],"names":[],"mappings":"AASA,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,MAA+B;IAE/B,IAAI,CAAC;QACH,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"readSelectedBytes.js","sourceRoot":"","sources":["../../src/mediaPicker/readSelectedBytes.ts"],"names":[],"mappings":"AASA,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,MAA+B;IAE/B,IAAI,CAAC;QACH,IAAI,qBAAqB,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;YACvC,OAAO,IAAI,UAAU,CAAC,MAAM,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;QACzD,CAAC;QACD,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;QAClD,OAAO,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,qBAAqB,CAAC,KAAc;IAC3C,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,aAAa,IAAI,KAAK;QACtB,OAAO,KAAK,CAAC,WAAW,KAAK,UAAU,CACxC,CAAC;AACJ,CAAC","sourcesContent":["interface ArrayBufferReadable {\n arrayBuffer(): Promise<ArrayBuffer>;\n}\n\nexport interface SelectedMediaByteSource {\n readonly uri: string;\n readonly file?: unknown;\n}\n\nexport async function readSelectedMediaBytes(\n source: SelectedMediaByteSource,\n): Promise<Uint8Array | null> {\n try {\n if (isArrayBufferReadable(source.file)) {\n return new Uint8Array(await source.file.arrayBuffer());\n }\n const { File } = await import('expo-file-system');\n return await new File(source.uri).bytes();\n } catch {\n return null;\n }\n}\n\nfunction isArrayBufferReadable(value: unknown): value is ArrayBufferReadable {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'arrayBuffer' in value &&\n typeof value.arrayBuffer === 'function'\n );\n}\n"]}
|