@sagepilot-ai/react-native-camera-addon 0.3.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/dist/index.js ADDED
@@ -0,0 +1,339 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ createSagepilotCameraXFilePicker: () => createSagepilotCameraXFilePicker,
24
+ getSagepilotNativeCameraCapabilities: () => getSagepilotNativeCameraCapabilities,
25
+ isSagepilotNativeCameraAvailable: () => isSagepilotNativeCameraAvailable,
26
+ pickSagepilotCameraFiles: () => pickSagepilotCameraFiles
27
+ });
28
+ module.exports = __toCommonJS(index_exports);
29
+ var import_react_native2 = require("react-native");
30
+ var import_react_native_sdk2 = require("@sagepilot-ai/react-native-sdk");
31
+
32
+ // src/nativeCamera.ts
33
+ var import_react_native = require("react-native");
34
+ var import_react_native_sdk = require("@sagepilot-ai/react-native-sdk");
35
+ var NATIVE_CAMERA_MODULE_NAME = "SagepilotInAppCamera";
36
+ var NATIVE_CAMERA_DEBUG_EVENT_NAME = "SagepilotInAppCameraDebug";
37
+ var DEBUG_PREFIX = "[SagepilotSDK][InAppCamera]";
38
+ var REQUIRED_NATIVE_CAMERA_CAPABILITIES_VERSION = 2;
39
+ function debugNativeCamera(message, details) {
40
+ console.log(`${DEBUG_PREFIX} ${message}`, details ?? "");
41
+ }
42
+ function readNativeDebugString(event, key) {
43
+ const value = event[key];
44
+ return typeof value === "string" ? value : void 0;
45
+ }
46
+ function readNativeCameraDebugEvent(event) {
47
+ if (!event || typeof event !== "object") return {};
48
+ const record = event;
49
+ return {
50
+ level: readNativeDebugString(record, "level"),
51
+ message: readNativeDebugString(record, "message"),
52
+ error: readNativeDebugString(record, "error")
53
+ };
54
+ }
55
+ function subscribeNativeCameraDebugEvents(nativeCamera) {
56
+ const eventEmitter = new import_react_native.NativeEventEmitter(nativeCamera);
57
+ const subscription = eventEmitter.addListener(
58
+ NATIVE_CAMERA_DEBUG_EVENT_NAME,
59
+ (event) => {
60
+ const debugEvent = readNativeCameraDebugEvent(event);
61
+ debugNativeCamera("native event", {
62
+ level: debugEvent.level,
63
+ message: debugEvent.message,
64
+ error: debugEvent.error
65
+ });
66
+ }
67
+ );
68
+ return () => subscription.remove();
69
+ }
70
+ function getSagepilotNativeCameraModule() {
71
+ const nativeModules = import_react_native.NativeModules;
72
+ const module2 = nativeModules[NATIVE_CAMERA_MODULE_NAME];
73
+ if (!module2 || typeof module2 !== "object") return void 0;
74
+ if (typeof module2.openCamera !== "function") return void 0;
75
+ return module2;
76
+ }
77
+ function isSagepilotNativeCameraAvailable() {
78
+ return Boolean(getSagepilotNativeCameraModule());
79
+ }
80
+ function getSagepilotNativeCameraCapabilities() {
81
+ const nativeCamera = getSagepilotNativeCameraModule();
82
+ const moduleCapabilitiesVersion = typeof nativeCamera?.moduleCapabilitiesVersion === "number" ? nativeCamera.moduleCapabilitiesVersion : 1;
83
+ const supportsImageLibrary = nativeCamera?.supportsImageLibrary === true && typeof nativeCamera?.openImageLibrary === "function";
84
+ const supportsDocumentPicker = nativeCamera?.supportsDocumentPicker === true && typeof nativeCamera?.openDocumentPicker === "function";
85
+ return {
86
+ moduleCapabilitiesVersion,
87
+ requiredModuleCapabilitiesVersion: REQUIRED_NATIVE_CAMERA_CAPABILITIES_VERSION,
88
+ supportsInAppCamera: nativeCamera?.supportsInAppCamera !== false && Boolean(nativeCamera),
89
+ supportsImageLibrary,
90
+ supportsDocumentPicker,
91
+ staleNativeModule: moduleCapabilitiesVersion < REQUIRED_NATIVE_CAMERA_CAPABILITIES_VERSION
92
+ };
93
+ }
94
+ function isSagepilotNativeImageLibraryAvailable() {
95
+ return getSagepilotNativeCameraCapabilities().supportsImageLibrary;
96
+ }
97
+ function isSagepilotNativeDocumentPickerAvailable() {
98
+ return getSagepilotNativeCameraCapabilities().supportsDocumentPicker;
99
+ }
100
+ function normalizeNativeCameraOptions(options = {}) {
101
+ return {
102
+ imageMaxDimension: options.imageMaxDimension ?? import_react_native_sdk.SAGEPILOT_DEFAULT_IMAGE_MAX_DIMENSION,
103
+ imageQuality: options.imageQuality ?? import_react_native_sdk.SAGEPILOT_DEFAULT_IMAGE_QUALITY,
104
+ imageMaxFileSizeBytes: options.imageMaxFileSizeBytes ?? import_react_native_sdk.SAGEPILOT_DEFAULT_IMAGE_MAX_FILE_SIZE_BYTES
105
+ };
106
+ }
107
+ function mapNativeCameraErrorCode(errorCode) {
108
+ switch (errorCode) {
109
+ case "permission":
110
+ case "permission_denied":
111
+ case "E_PERMISSION_DENIED":
112
+ return "permission_denied";
113
+ case "camera_unavailable":
114
+ case "E_CAMERA_UNAVAILABLE":
115
+ return "camera_unavailable";
116
+ case "encode_failed":
117
+ case "E_ENCODE_FAILED":
118
+ return "encode_failed";
119
+ case "file_too_large":
120
+ case "E_FILE_TOO_LARGE":
121
+ return "file_too_large";
122
+ case "read_failed":
123
+ case "E_READ_FAILED":
124
+ return "read_failed";
125
+ default:
126
+ return "unknown";
127
+ }
128
+ }
129
+ function getNativeCameraErrorCode(error) {
130
+ if (!error || typeof error !== "object") return void 0;
131
+ const code = error.code;
132
+ return typeof code === "string" ? code : void 0;
133
+ }
134
+ function getNativeCameraErrorMessage(error) {
135
+ if (error instanceof Error && error.message) return error.message;
136
+ if (!error || typeof error !== "object") return void 0;
137
+ const message = error.message;
138
+ return typeof message === "string" && message.length > 0 ? message : void 0;
139
+ }
140
+ function getDefaultNativeCameraErrorMessage(code) {
141
+ switch (code) {
142
+ case "permission_denied":
143
+ return "Camera permission is required to take a photo.";
144
+ case "camera_unavailable":
145
+ return "The in-app camera is not available in this build.";
146
+ case "encode_failed":
147
+ return "The photo could not be processed. Please try again.";
148
+ case "file_too_large":
149
+ return "Image is too large.";
150
+ case "read_failed":
151
+ return "Could not read the selected file.";
152
+ default:
153
+ return "Could not open the in-app camera.";
154
+ }
155
+ }
156
+ function toSagepilotNativeCameraError(error) {
157
+ if (error instanceof import_react_native_sdk.SagepilotFilePickerError) return error;
158
+ const code = mapNativeCameraErrorCode(getNativeCameraErrorCode(error));
159
+ return new import_react_native_sdk.SagepilotFilePickerError(
160
+ code,
161
+ getNativeCameraErrorMessage(error) ?? getDefaultNativeCameraErrorMessage(code)
162
+ );
163
+ }
164
+ async function openSagepilotCamera(options = {}) {
165
+ const nativeCamera = getSagepilotNativeCameraModule();
166
+ if (!nativeCamera) {
167
+ debugNativeCamera("native module unavailable", {
168
+ moduleName: NATIVE_CAMERA_MODULE_NAME,
169
+ registeredModules: Object.keys(import_react_native.NativeModules).filter(
170
+ (key) => key.toLowerCase().includes("sagepilot")
171
+ )
172
+ });
173
+ throw new import_react_native_sdk.SagepilotFilePickerError("camera_unavailable", "The in-app camera is not available in this build.");
174
+ }
175
+ try {
176
+ const unsubscribeNativeDebugEvents = subscribeNativeCameraDebugEvents(nativeCamera);
177
+ const normalizedOptions = normalizeNativeCameraOptions(options);
178
+ try {
179
+ debugNativeCamera("opening native camera", normalizedOptions);
180
+ const file = await nativeCamera.openCamera(normalizedOptions) ?? null;
181
+ debugNativeCamera("native camera resolved", file ? {
182
+ fileName: file.file_name,
183
+ mimeType: file.mime_type,
184
+ size: file.size,
185
+ base64Length: file.data_base64.length
186
+ } : { cancelled: true });
187
+ return file;
188
+ } finally {
189
+ unsubscribeNativeDebugEvents();
190
+ }
191
+ } catch (error) {
192
+ debugNativeCamera("native camera rejected", {
193
+ code: getNativeCameraErrorCode(error),
194
+ message: getNativeCameraErrorMessage(error)
195
+ });
196
+ throw toSagepilotNativeCameraError(error);
197
+ }
198
+ }
199
+ async function pickSagepilotCameraFiles(options = {}) {
200
+ const file = await openSagepilotCamera(options);
201
+ return file ? [file] : [];
202
+ }
203
+ async function pickSagepilotImageLibraryFiles(options) {
204
+ const nativeCamera = getSagepilotNativeCameraModule();
205
+ if (!nativeCamera?.openImageLibrary) {
206
+ throw new import_react_native_sdk.SagepilotFilePickerError("camera_unavailable", "The image library picker is not available in this build.");
207
+ }
208
+ const unsubscribeNativeDebugEvents = subscribeNativeCameraDebugEvents(nativeCamera);
209
+ try {
210
+ debugNativeCamera("opening native image library", options);
211
+ const files = await nativeCamera.openImageLibrary(options) ?? [];
212
+ debugNativeCamera("native image library resolved", {
213
+ count: files.length,
214
+ files: files.map((file) => ({
215
+ fileName: file.file_name,
216
+ mimeType: file.mime_type,
217
+ size: file.size,
218
+ base64Length: file.data_base64.length
219
+ }))
220
+ });
221
+ return files;
222
+ } catch (error) {
223
+ debugNativeCamera("native image library rejected", {
224
+ code: getNativeCameraErrorCode(error),
225
+ message: getNativeCameraErrorMessage(error)
226
+ });
227
+ throw toSagepilotNativeCameraError(error);
228
+ } finally {
229
+ unsubscribeNativeDebugEvents();
230
+ }
231
+ }
232
+ async function pickSagepilotDocumentFiles(options) {
233
+ const nativeCamera = getSagepilotNativeCameraModule();
234
+ if (!nativeCamera?.openDocumentPicker) {
235
+ throw new import_react_native_sdk.SagepilotFilePickerError("camera_unavailable", "The document picker is not available in this build.");
236
+ }
237
+ const unsubscribeNativeDebugEvents = subscribeNativeCameraDebugEvents(nativeCamera);
238
+ try {
239
+ debugNativeCamera("opening native document picker", options);
240
+ const files = await nativeCamera.openDocumentPicker(options) ?? [];
241
+ debugNativeCamera("native document picker resolved", {
242
+ count: files.length,
243
+ files: files.map((file) => ({
244
+ fileName: file.file_name,
245
+ mimeType: file.mime_type,
246
+ size: file.size,
247
+ base64Length: file.data_base64.length
248
+ }))
249
+ });
250
+ return files;
251
+ } catch (error) {
252
+ debugNativeCamera("native document picker rejected", {
253
+ code: getNativeCameraErrorCode(error),
254
+ message: getNativeCameraErrorMessage(error)
255
+ });
256
+ throw toSagepilotNativeCameraError(error);
257
+ } finally {
258
+ unsubscribeNativeDebugEvents();
259
+ }
260
+ }
261
+
262
+ // src/index.ts
263
+ var DEBUG_PREFIX2 = "[SagepilotSDK][CameraXAddon]";
264
+ var DEFAULT_DOCUMENT_MAX_FILE_SIZE_BYTES = 20 * 1024 * 1024;
265
+ function debugCameraXFilePicker(message, details) {
266
+ console.log(`${DEBUG_PREFIX2} ${message}`, details ?? "");
267
+ }
268
+ function isSourceEnabled(sources, source) {
269
+ return sources.includes(source);
270
+ }
271
+ function rejectUnavailableSource(source) {
272
+ throw new import_react_native_sdk2.SagepilotFilePickerError(
273
+ "camera_unavailable",
274
+ `The ${source} picker is not available in this build.`
275
+ );
276
+ }
277
+ function resolveCameraXFilePickerSources(options) {
278
+ const sources = [];
279
+ if (options.includeCamera !== false && isSagepilotNativeCameraAvailable()) {
280
+ sources.push("camera");
281
+ }
282
+ if (options.includeLibrary !== false && isSagepilotNativeImageLibraryAvailable()) {
283
+ sources.push("library");
284
+ }
285
+ if (options.includeDocuments !== false && isSagepilotNativeDocumentPickerAvailable()) {
286
+ sources.push("documents");
287
+ }
288
+ return sources;
289
+ }
290
+ function createSagepilotCameraXFilePicker(options = {}) {
291
+ if (import_react_native2.Platform.OS !== "android") return void 0;
292
+ const capabilities = getSagepilotNativeCameraCapabilities();
293
+ const sources = resolveCameraXFilePickerSources(options);
294
+ const imageMaxFileSizeBytes = options.imageMaxFileSizeBytes ?? import_react_native_sdk2.SAGEPILOT_DEFAULT_IMAGE_MAX_FILE_SIZE_BYTES;
295
+ const documentMaxFileSizeBytes = options.documentMaxFileSizeBytes ?? DEFAULT_DOCUMENT_MAX_FILE_SIZE_BYTES;
296
+ debugCameraXFilePicker("adapter created", {
297
+ platform: import_react_native2.Platform.OS,
298
+ capabilities,
299
+ sources,
300
+ imageMaxDimension: options.imageMaxDimension,
301
+ imageQuality: options.imageQuality,
302
+ imageMaxFileSizeBytes,
303
+ documentMaxFileSizeBytes
304
+ });
305
+ if (sources.length === 0) return void 0;
306
+ async function pickCamera() {
307
+ if (!isSourceEnabled(sources, "camera")) rejectUnavailableSource("camera");
308
+ await (0, import_react_native_sdk2.ensureSagepilotAndroidCameraPermission)();
309
+ return pickSagepilotCameraFiles({
310
+ imageMaxDimension: options.imageMaxDimension,
311
+ imageQuality: options.imageQuality,
312
+ imageMaxFileSizeBytes
313
+ });
314
+ }
315
+ async function pickLibrary(multiple) {
316
+ if (!isSourceEnabled(sources, "library")) rejectUnavailableSource("library");
317
+ return pickSagepilotImageLibraryFiles({ multiple, imageMaxFileSizeBytes });
318
+ }
319
+ async function pickDocuments(multiple) {
320
+ if (!isSourceEnabled(sources, "documents")) rejectUnavailableSource("documents");
321
+ return pickSagepilotDocumentFiles({ multiple, documentMaxFileSizeBytes });
322
+ }
323
+ return {
324
+ sources,
325
+ async pickFiles(request) {
326
+ debugCameraXFilePicker("pickFiles request", request);
327
+ if (request.source === "camera") return pickCamera();
328
+ if (request.source === "library") return pickLibrary(request.multiple);
329
+ return pickDocuments(request.multiple);
330
+ }
331
+ };
332
+ }
333
+ // Annotate the CommonJS export names for ESM import in node:
334
+ 0 && (module.exports = {
335
+ createSagepilotCameraXFilePicker,
336
+ getSagepilotNativeCameraCapabilities,
337
+ isSagepilotNativeCameraAvailable,
338
+ pickSagepilotCameraFiles
339
+ });
package/dist/index.mjs ADDED
@@ -0,0 +1,320 @@
1
+ // src/index.ts
2
+ import { Platform } from "react-native";
3
+ import {
4
+ ensureSagepilotAndroidCameraPermission,
5
+ SagepilotFilePickerError as SagepilotFilePickerError2,
6
+ SAGEPILOT_DEFAULT_IMAGE_MAX_FILE_SIZE_BYTES as SAGEPILOT_DEFAULT_IMAGE_MAX_FILE_SIZE_BYTES2
7
+ } from "@sagepilot-ai/react-native-sdk";
8
+
9
+ // src/nativeCamera.ts
10
+ import { NativeEventEmitter, NativeModules } from "react-native";
11
+ import {
12
+ SAGEPILOT_DEFAULT_IMAGE_MAX_DIMENSION,
13
+ SAGEPILOT_DEFAULT_IMAGE_MAX_FILE_SIZE_BYTES,
14
+ SAGEPILOT_DEFAULT_IMAGE_QUALITY,
15
+ SagepilotFilePickerError
16
+ } from "@sagepilot-ai/react-native-sdk";
17
+ var NATIVE_CAMERA_MODULE_NAME = "SagepilotInAppCamera";
18
+ var NATIVE_CAMERA_DEBUG_EVENT_NAME = "SagepilotInAppCameraDebug";
19
+ var DEBUG_PREFIX = "[SagepilotSDK][InAppCamera]";
20
+ var REQUIRED_NATIVE_CAMERA_CAPABILITIES_VERSION = 2;
21
+ function debugNativeCamera(message, details) {
22
+ console.log(`${DEBUG_PREFIX} ${message}`, details ?? "");
23
+ }
24
+ function readNativeDebugString(event, key) {
25
+ const value = event[key];
26
+ return typeof value === "string" ? value : void 0;
27
+ }
28
+ function readNativeCameraDebugEvent(event) {
29
+ if (!event || typeof event !== "object") return {};
30
+ const record = event;
31
+ return {
32
+ level: readNativeDebugString(record, "level"),
33
+ message: readNativeDebugString(record, "message"),
34
+ error: readNativeDebugString(record, "error")
35
+ };
36
+ }
37
+ function subscribeNativeCameraDebugEvents(nativeCamera) {
38
+ const eventEmitter = new NativeEventEmitter(nativeCamera);
39
+ const subscription = eventEmitter.addListener(
40
+ NATIVE_CAMERA_DEBUG_EVENT_NAME,
41
+ (event) => {
42
+ const debugEvent = readNativeCameraDebugEvent(event);
43
+ debugNativeCamera("native event", {
44
+ level: debugEvent.level,
45
+ message: debugEvent.message,
46
+ error: debugEvent.error
47
+ });
48
+ }
49
+ );
50
+ return () => subscription.remove();
51
+ }
52
+ function getSagepilotNativeCameraModule() {
53
+ const nativeModules = NativeModules;
54
+ const module = nativeModules[NATIVE_CAMERA_MODULE_NAME];
55
+ if (!module || typeof module !== "object") return void 0;
56
+ if (typeof module.openCamera !== "function") return void 0;
57
+ return module;
58
+ }
59
+ function isSagepilotNativeCameraAvailable() {
60
+ return Boolean(getSagepilotNativeCameraModule());
61
+ }
62
+ function getSagepilotNativeCameraCapabilities() {
63
+ const nativeCamera = getSagepilotNativeCameraModule();
64
+ const moduleCapabilitiesVersion = typeof nativeCamera?.moduleCapabilitiesVersion === "number" ? nativeCamera.moduleCapabilitiesVersion : 1;
65
+ const supportsImageLibrary = nativeCamera?.supportsImageLibrary === true && typeof nativeCamera?.openImageLibrary === "function";
66
+ const supportsDocumentPicker = nativeCamera?.supportsDocumentPicker === true && typeof nativeCamera?.openDocumentPicker === "function";
67
+ return {
68
+ moduleCapabilitiesVersion,
69
+ requiredModuleCapabilitiesVersion: REQUIRED_NATIVE_CAMERA_CAPABILITIES_VERSION,
70
+ supportsInAppCamera: nativeCamera?.supportsInAppCamera !== false && Boolean(nativeCamera),
71
+ supportsImageLibrary,
72
+ supportsDocumentPicker,
73
+ staleNativeModule: moduleCapabilitiesVersion < REQUIRED_NATIVE_CAMERA_CAPABILITIES_VERSION
74
+ };
75
+ }
76
+ function isSagepilotNativeImageLibraryAvailable() {
77
+ return getSagepilotNativeCameraCapabilities().supportsImageLibrary;
78
+ }
79
+ function isSagepilotNativeDocumentPickerAvailable() {
80
+ return getSagepilotNativeCameraCapabilities().supportsDocumentPicker;
81
+ }
82
+ function normalizeNativeCameraOptions(options = {}) {
83
+ return {
84
+ imageMaxDimension: options.imageMaxDimension ?? SAGEPILOT_DEFAULT_IMAGE_MAX_DIMENSION,
85
+ imageQuality: options.imageQuality ?? SAGEPILOT_DEFAULT_IMAGE_QUALITY,
86
+ imageMaxFileSizeBytes: options.imageMaxFileSizeBytes ?? SAGEPILOT_DEFAULT_IMAGE_MAX_FILE_SIZE_BYTES
87
+ };
88
+ }
89
+ function mapNativeCameraErrorCode(errorCode) {
90
+ switch (errorCode) {
91
+ case "permission":
92
+ case "permission_denied":
93
+ case "E_PERMISSION_DENIED":
94
+ return "permission_denied";
95
+ case "camera_unavailable":
96
+ case "E_CAMERA_UNAVAILABLE":
97
+ return "camera_unavailable";
98
+ case "encode_failed":
99
+ case "E_ENCODE_FAILED":
100
+ return "encode_failed";
101
+ case "file_too_large":
102
+ case "E_FILE_TOO_LARGE":
103
+ return "file_too_large";
104
+ case "read_failed":
105
+ case "E_READ_FAILED":
106
+ return "read_failed";
107
+ default:
108
+ return "unknown";
109
+ }
110
+ }
111
+ function getNativeCameraErrorCode(error) {
112
+ if (!error || typeof error !== "object") return void 0;
113
+ const code = error.code;
114
+ return typeof code === "string" ? code : void 0;
115
+ }
116
+ function getNativeCameraErrorMessage(error) {
117
+ if (error instanceof Error && error.message) return error.message;
118
+ if (!error || typeof error !== "object") return void 0;
119
+ const message = error.message;
120
+ return typeof message === "string" && message.length > 0 ? message : void 0;
121
+ }
122
+ function getDefaultNativeCameraErrorMessage(code) {
123
+ switch (code) {
124
+ case "permission_denied":
125
+ return "Camera permission is required to take a photo.";
126
+ case "camera_unavailable":
127
+ return "The in-app camera is not available in this build.";
128
+ case "encode_failed":
129
+ return "The photo could not be processed. Please try again.";
130
+ case "file_too_large":
131
+ return "Image is too large.";
132
+ case "read_failed":
133
+ return "Could not read the selected file.";
134
+ default:
135
+ return "Could not open the in-app camera.";
136
+ }
137
+ }
138
+ function toSagepilotNativeCameraError(error) {
139
+ if (error instanceof SagepilotFilePickerError) return error;
140
+ const code = mapNativeCameraErrorCode(getNativeCameraErrorCode(error));
141
+ return new SagepilotFilePickerError(
142
+ code,
143
+ getNativeCameraErrorMessage(error) ?? getDefaultNativeCameraErrorMessage(code)
144
+ );
145
+ }
146
+ async function openSagepilotCamera(options = {}) {
147
+ const nativeCamera = getSagepilotNativeCameraModule();
148
+ if (!nativeCamera) {
149
+ debugNativeCamera("native module unavailable", {
150
+ moduleName: NATIVE_CAMERA_MODULE_NAME,
151
+ registeredModules: Object.keys(NativeModules).filter(
152
+ (key) => key.toLowerCase().includes("sagepilot")
153
+ )
154
+ });
155
+ throw new SagepilotFilePickerError("camera_unavailable", "The in-app camera is not available in this build.");
156
+ }
157
+ try {
158
+ const unsubscribeNativeDebugEvents = subscribeNativeCameraDebugEvents(nativeCamera);
159
+ const normalizedOptions = normalizeNativeCameraOptions(options);
160
+ try {
161
+ debugNativeCamera("opening native camera", normalizedOptions);
162
+ const file = await nativeCamera.openCamera(normalizedOptions) ?? null;
163
+ debugNativeCamera("native camera resolved", file ? {
164
+ fileName: file.file_name,
165
+ mimeType: file.mime_type,
166
+ size: file.size,
167
+ base64Length: file.data_base64.length
168
+ } : { cancelled: true });
169
+ return file;
170
+ } finally {
171
+ unsubscribeNativeDebugEvents();
172
+ }
173
+ } catch (error) {
174
+ debugNativeCamera("native camera rejected", {
175
+ code: getNativeCameraErrorCode(error),
176
+ message: getNativeCameraErrorMessage(error)
177
+ });
178
+ throw toSagepilotNativeCameraError(error);
179
+ }
180
+ }
181
+ async function pickSagepilotCameraFiles(options = {}) {
182
+ const file = await openSagepilotCamera(options);
183
+ return file ? [file] : [];
184
+ }
185
+ async function pickSagepilotImageLibraryFiles(options) {
186
+ const nativeCamera = getSagepilotNativeCameraModule();
187
+ if (!nativeCamera?.openImageLibrary) {
188
+ throw new SagepilotFilePickerError("camera_unavailable", "The image library picker is not available in this build.");
189
+ }
190
+ const unsubscribeNativeDebugEvents = subscribeNativeCameraDebugEvents(nativeCamera);
191
+ try {
192
+ debugNativeCamera("opening native image library", options);
193
+ const files = await nativeCamera.openImageLibrary(options) ?? [];
194
+ debugNativeCamera("native image library resolved", {
195
+ count: files.length,
196
+ files: files.map((file) => ({
197
+ fileName: file.file_name,
198
+ mimeType: file.mime_type,
199
+ size: file.size,
200
+ base64Length: file.data_base64.length
201
+ }))
202
+ });
203
+ return files;
204
+ } catch (error) {
205
+ debugNativeCamera("native image library rejected", {
206
+ code: getNativeCameraErrorCode(error),
207
+ message: getNativeCameraErrorMessage(error)
208
+ });
209
+ throw toSagepilotNativeCameraError(error);
210
+ } finally {
211
+ unsubscribeNativeDebugEvents();
212
+ }
213
+ }
214
+ async function pickSagepilotDocumentFiles(options) {
215
+ const nativeCamera = getSagepilotNativeCameraModule();
216
+ if (!nativeCamera?.openDocumentPicker) {
217
+ throw new SagepilotFilePickerError("camera_unavailable", "The document picker is not available in this build.");
218
+ }
219
+ const unsubscribeNativeDebugEvents = subscribeNativeCameraDebugEvents(nativeCamera);
220
+ try {
221
+ debugNativeCamera("opening native document picker", options);
222
+ const files = await nativeCamera.openDocumentPicker(options) ?? [];
223
+ debugNativeCamera("native document picker resolved", {
224
+ count: files.length,
225
+ files: files.map((file) => ({
226
+ fileName: file.file_name,
227
+ mimeType: file.mime_type,
228
+ size: file.size,
229
+ base64Length: file.data_base64.length
230
+ }))
231
+ });
232
+ return files;
233
+ } catch (error) {
234
+ debugNativeCamera("native document picker rejected", {
235
+ code: getNativeCameraErrorCode(error),
236
+ message: getNativeCameraErrorMessage(error)
237
+ });
238
+ throw toSagepilotNativeCameraError(error);
239
+ } finally {
240
+ unsubscribeNativeDebugEvents();
241
+ }
242
+ }
243
+
244
+ // src/index.ts
245
+ var DEBUG_PREFIX2 = "[SagepilotSDK][CameraXAddon]";
246
+ var DEFAULT_DOCUMENT_MAX_FILE_SIZE_BYTES = 20 * 1024 * 1024;
247
+ function debugCameraXFilePicker(message, details) {
248
+ console.log(`${DEBUG_PREFIX2} ${message}`, details ?? "");
249
+ }
250
+ function isSourceEnabled(sources, source) {
251
+ return sources.includes(source);
252
+ }
253
+ function rejectUnavailableSource(source) {
254
+ throw new SagepilotFilePickerError2(
255
+ "camera_unavailable",
256
+ `The ${source} picker is not available in this build.`
257
+ );
258
+ }
259
+ function resolveCameraXFilePickerSources(options) {
260
+ const sources = [];
261
+ if (options.includeCamera !== false && isSagepilotNativeCameraAvailable()) {
262
+ sources.push("camera");
263
+ }
264
+ if (options.includeLibrary !== false && isSagepilotNativeImageLibraryAvailable()) {
265
+ sources.push("library");
266
+ }
267
+ if (options.includeDocuments !== false && isSagepilotNativeDocumentPickerAvailable()) {
268
+ sources.push("documents");
269
+ }
270
+ return sources;
271
+ }
272
+ function createSagepilotCameraXFilePicker(options = {}) {
273
+ if (Platform.OS !== "android") return void 0;
274
+ const capabilities = getSagepilotNativeCameraCapabilities();
275
+ const sources = resolveCameraXFilePickerSources(options);
276
+ const imageMaxFileSizeBytes = options.imageMaxFileSizeBytes ?? SAGEPILOT_DEFAULT_IMAGE_MAX_FILE_SIZE_BYTES2;
277
+ const documentMaxFileSizeBytes = options.documentMaxFileSizeBytes ?? DEFAULT_DOCUMENT_MAX_FILE_SIZE_BYTES;
278
+ debugCameraXFilePicker("adapter created", {
279
+ platform: Platform.OS,
280
+ capabilities,
281
+ sources,
282
+ imageMaxDimension: options.imageMaxDimension,
283
+ imageQuality: options.imageQuality,
284
+ imageMaxFileSizeBytes,
285
+ documentMaxFileSizeBytes
286
+ });
287
+ if (sources.length === 0) return void 0;
288
+ async function pickCamera() {
289
+ if (!isSourceEnabled(sources, "camera")) rejectUnavailableSource("camera");
290
+ await ensureSagepilotAndroidCameraPermission();
291
+ return pickSagepilotCameraFiles({
292
+ imageMaxDimension: options.imageMaxDimension,
293
+ imageQuality: options.imageQuality,
294
+ imageMaxFileSizeBytes
295
+ });
296
+ }
297
+ async function pickLibrary(multiple) {
298
+ if (!isSourceEnabled(sources, "library")) rejectUnavailableSource("library");
299
+ return pickSagepilotImageLibraryFiles({ multiple, imageMaxFileSizeBytes });
300
+ }
301
+ async function pickDocuments(multiple) {
302
+ if (!isSourceEnabled(sources, "documents")) rejectUnavailableSource("documents");
303
+ return pickSagepilotDocumentFiles({ multiple, documentMaxFileSizeBytes });
304
+ }
305
+ return {
306
+ sources,
307
+ async pickFiles(request) {
308
+ debugCameraXFilePicker("pickFiles request", request);
309
+ if (request.source === "camera") return pickCamera();
310
+ if (request.source === "library") return pickLibrary(request.multiple);
311
+ return pickDocuments(request.multiple);
312
+ }
313
+ };
314
+ }
315
+ export {
316
+ createSagepilotCameraXFilePicker,
317
+ getSagepilotNativeCameraCapabilities,
318
+ isSagepilotNativeCameraAvailable,
319
+ pickSagepilotCameraFiles
320
+ };