@ateam-ai-mobile/expo 0.1.7 → 0.1.9
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/bootstrap.js +841 -323
- package/dist/bootstrap.js.map +1 -1
- package/dist/bootstrap.mjs +9 -7
- package/dist/bootstrap.mjs.map +1 -1
- package/dist/chunk-7FWYEHN5.mjs +203 -0
- package/dist/chunk-7FWYEHN5.mjs.map +1 -0
- package/dist/{chunk-4XYXJYN5.mjs → chunk-C7M5WAHA.mjs} +583 -298
- package/dist/chunk-C7M5WAHA.mjs.map +1 -0
- package/dist/{chunk-5HM6UA2K.mjs → chunk-GF2MPTAB.mjs} +83 -7
- package/dist/chunk-GF2MPTAB.mjs.map +1 -0
- package/dist/chunk-J6XRNX7P.mjs +19 -0
- package/dist/chunk-J6XRNX7P.mjs.map +1 -0
- package/dist/{chunk-TZXWVYYR.mjs → chunk-PCAEUX2N.mjs} +1 -1
- package/dist/chunk-PCAEUX2N.mjs.map +1 -0
- package/dist/{chunk-VQJPSLHP.mjs → chunk-Z5AI2SXX.mjs} +13 -4
- package/dist/chunk-Z5AI2SXX.mjs.map +1 -0
- package/dist/createBridge.js +41 -10
- package/dist/createBridge.js.map +1 -1
- package/dist/createBridge.mjs +5 -1
- package/dist/createBridge.mjs.map +1 -1
- package/dist/device/createDeviceProvider.js +278 -17
- package/dist/device/createDeviceProvider.js.map +1 -1
- package/dist/device/createDeviceProvider.mjs +5 -3
- package/dist/device-bridge/index.d.mts +13 -1
- package/dist/device-bridge/index.d.ts +13 -1
- package/dist/device-bridge/index.js +49 -12
- package/dist/device-bridge/index.js.map +1 -1
- package/dist/device-bridge/index.mjs +3 -1
- package/dist/index.d.mts +19 -3
- package/dist/index.d.ts +19 -3
- package/dist/index.js +594 -297
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -1
- package/dist/maps/index.d.mts +56 -0
- package/dist/maps/index.d.ts +56 -0
- package/dist/maps/index.js +95 -0
- package/dist/maps/index.js.map +1 -0
- package/dist/maps/index.mjs +17 -0
- package/dist/maps/index.mjs.map +1 -0
- package/dist/vision/index.d.mts +4 -2
- package/dist/vision/index.d.ts +4 -2
- package/dist/vision/index.js.map +1 -1
- package/dist/vision/index.mjs +1 -1
- package/expo-module.config.json +1 -1
- package/ios/AdaMaps/AdaMapsModule.swift +180 -0
- package/ios/AdaMaps.podspec +25 -0
- package/ios/AdaVision.podspec +4 -0
- package/ios/AdaVisionModule.swift +63 -9
- package/package.json +10 -4
- package/src/args.ts +56 -0
- package/src/createBridge.ts +3 -1
- package/src/device/createDeviceProvider.ts +88 -3
- package/src/device-bridge/collectors/location.ts +21 -9
- package/src/device-state/collectors.ts +5 -1
- package/src/device-state/domains/deviceContext.ts +5 -3
- package/src/device-state/domains/interaction.ts +2 -1
- package/src/device-state/domains/spatial.ts +200 -116
- package/src/device-state/domains/visual.ts +34 -13
- package/src/device-state/events.ts +49 -0
- package/src/device-state/headingSource.ts +43 -8
- package/src/device-state/index.ts +3 -2
- package/src/device-state/replay.ts +76 -11
- package/src/device-state/spatialEvents.ts +300 -0
- package/src/geo.ts +23 -0
- package/src/maps/index.ts +81 -0
- package/src/maps/normalize.ts +225 -0
- package/src/vision/index.ts +4 -2
- package/dist/chunk-4XYXJYN5.mjs.map +0 -1
- package/dist/chunk-5HM6UA2K.mjs.map +0 -1
- package/dist/chunk-TZXWVYYR.mjs.map +0 -1
- package/dist/chunk-VQJPSLHP.mjs.map +0 -1
package/dist/createBridge.js
CHANGED
|
@@ -36,13 +36,44 @@ module.exports = __toCommonJS(createBridge_exports);
|
|
|
36
36
|
var import_async_storage = __toESM(require("@react-native-async-storage/async-storage"));
|
|
37
37
|
var ExpoCalendar = __toESM(require("expo-calendar"));
|
|
38
38
|
var ExpoContacts = __toESM(require("expo-contacts"));
|
|
39
|
-
var
|
|
39
|
+
var ExpoLocation2 = __toESM(require("expo-location"));
|
|
40
40
|
var ExpoBattery = __toESM(require("expo-battery"));
|
|
41
41
|
var ExpoNetwork = __toESM(require("expo-network"));
|
|
42
42
|
var ExpoNotifications = __toESM(require("expo-notifications"));
|
|
43
43
|
var ExpoSMS = __toESM(require("expo-sms"));
|
|
44
44
|
var ExpoLinking = __toESM(require("expo-linking"));
|
|
45
|
+
var import_react_native2 = require("react-native");
|
|
46
|
+
|
|
47
|
+
// src/maps/index.ts
|
|
45
48
|
var import_react_native = require("react-native");
|
|
49
|
+
var import_expo_modules_core = require("expo-modules-core");
|
|
50
|
+
var ExpoLocation = __toESM(require("expo-location"));
|
|
51
|
+
|
|
52
|
+
// src/maps/normalize.ts
|
|
53
|
+
var text = (v) => typeof v === "string" && v.trim() !== "" ? v : null;
|
|
54
|
+
function toMapsAddress(raw) {
|
|
55
|
+
const r = raw ?? {};
|
|
56
|
+
return {
|
|
57
|
+
name: text(r.name),
|
|
58
|
+
street: text(r.street),
|
|
59
|
+
streetNumber: text(r.streetNumber),
|
|
60
|
+
district: text(r.district),
|
|
61
|
+
city: text(r.city),
|
|
62
|
+
region: text(r.region),
|
|
63
|
+
postalCode: text(r.postalCode),
|
|
64
|
+
country: text(r.country),
|
|
65
|
+
isoCountryCode: text(r.isoCountryCode)
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// src/maps/index.ts
|
|
70
|
+
var native = (0, import_expo_modules_core.requireOptionalNativeModule)("AdaMaps");
|
|
71
|
+
async function reverseGeocode(at) {
|
|
72
|
+
const [first] = await ExpoLocation.reverseGeocodeAsync({ latitude: at.latitude, longitude: at.longitude });
|
|
73
|
+
return first ? toMapsAddress(first) : null;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// src/createBridge.ts
|
|
46
77
|
function createBridge(connectorId, deviceId) {
|
|
47
78
|
const storagePrefix = `connector:${connectorId}:`;
|
|
48
79
|
const log = {
|
|
@@ -331,10 +362,10 @@ function createBridge(connectorId, deviceId) {
|
|
|
331
362
|
location: {
|
|
332
363
|
async getCurrent() {
|
|
333
364
|
try {
|
|
334
|
-
const location = await
|
|
335
|
-
accuracy:
|
|
365
|
+
const location = await ExpoLocation2.getCurrentPositionAsync({
|
|
366
|
+
accuracy: ExpoLocation2.Accuracy.Balanced
|
|
336
367
|
});
|
|
337
|
-
const
|
|
368
|
+
const geo = await reverseGeocode({
|
|
338
369
|
latitude: location.coords.latitude,
|
|
339
370
|
longitude: location.coords.longitude
|
|
340
371
|
});
|
|
@@ -432,7 +463,7 @@ function createBridge(connectorId, deviceId) {
|
|
|
432
463
|
async navigate(destination, mode = "driving") {
|
|
433
464
|
try {
|
|
434
465
|
const encoded = encodeURIComponent(destination);
|
|
435
|
-
const url =
|
|
466
|
+
const url = import_react_native2.Platform.OS === "ios" ? `maps://maps.apple.com/?daddr=${encoded}&dirflg=${mode[0]}` : `google.navigation:q=${encoded}&mode=${mode}`;
|
|
436
467
|
const canOpen = await ExpoLinking.canOpenURL(url);
|
|
437
468
|
if (!canOpen) {
|
|
438
469
|
const fallbackUrl = `https://www.google.com/maps/search/${encoded}`;
|
|
@@ -566,7 +597,7 @@ function createBridge(connectorId, deviceId) {
|
|
|
566
597
|
const con = await ExpoContacts.getPermissionsAsync();
|
|
567
598
|
return con.status === "granted" ? "granted" : con.status === "denied" ? "denied" : "not_requested";
|
|
568
599
|
case "location":
|
|
569
|
-
const loc = await
|
|
600
|
+
const loc = await ExpoLocation2.getForegroundPermissionsAsync();
|
|
570
601
|
return loc.status === "granted" ? "granted" : loc.status === "denied" ? "denied" : "not_requested";
|
|
571
602
|
case "notifications":
|
|
572
603
|
const notif = await ExpoNotifications.getPermissionsAsync();
|
|
@@ -589,7 +620,7 @@ function createBridge(connectorId, deviceId) {
|
|
|
589
620
|
const con = await ExpoContacts.requestPermissionsAsync();
|
|
590
621
|
return con.status === "granted";
|
|
591
622
|
case "location":
|
|
592
|
-
const loc = await
|
|
623
|
+
const loc = await ExpoLocation2.requestForegroundPermissionsAsync();
|
|
593
624
|
return loc.status === "granted";
|
|
594
625
|
case "notifications":
|
|
595
626
|
const notif = await ExpoNotifications.requestPermissionsAsync();
|
|
@@ -607,7 +638,7 @@ function createBridge(connectorId, deviceId) {
|
|
|
607
638
|
const [cal, con, loc, notif] = await Promise.allSettled([
|
|
608
639
|
ExpoCalendar.getCalendarPermissionsAsync(),
|
|
609
640
|
ExpoContacts.getPermissionsAsync(),
|
|
610
|
-
|
|
641
|
+
ExpoLocation2.getForegroundPermissionsAsync(),
|
|
611
642
|
ExpoNotifications.getPermissionsAsync()
|
|
612
643
|
]);
|
|
613
644
|
return {
|
|
@@ -628,8 +659,8 @@ function createBridge(connectorId, deviceId) {
|
|
|
628
659
|
},
|
|
629
660
|
getPlatform() {
|
|
630
661
|
return {
|
|
631
|
-
os:
|
|
632
|
-
version:
|
|
662
|
+
os: import_react_native2.Platform.OS,
|
|
663
|
+
version: import_react_native2.Platform.Version ? String(import_react_native2.Platform.Version) : "unknown"
|
|
633
664
|
};
|
|
634
665
|
}
|
|
635
666
|
},
|
package/dist/createBridge.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/createBridge.ts"],"sourcesContent":["/**\n * Native Bridge Factory\n *\n * Creates a Bridge instance that wraps Expo native modules.\n * Each bridge is scoped to a specific connector ID for storage isolation.\n */\n\nimport AsyncStorage from '@react-native-async-storage/async-storage';\nimport * as ExpoCalendar from 'expo-calendar';\nimport * as ExpoContacts from 'expo-contacts';\nimport * as ExpoLocation from 'expo-location';\nimport * as ExpoBattery from 'expo-battery';\nimport * as ExpoNetwork from 'expo-network';\nimport * as ExpoNotifications from 'expo-notifications';\nimport * as ExpoSMS from 'expo-sms';\nimport * as ExpoLinking from 'expo-linking';\nimport { Platform } from 'react-native';\nimport * as Device from 'expo-device';\n\nimport type { Bridge } from '@ateam-ai-mobile/plugin-runtime';\n\nexport function createBridge(connectorId: string, deviceId: string): Bridge {\n const storagePrefix = `connector:${connectorId}:`;\n\n const log = {\n info: (msg: string, data?: any) => {\n console.log(`[${connectorId}] ${msg}`, data || '');\n },\n warn: (msg: string, data?: any) => {\n console.warn(`[${connectorId}] ${msg}`, data || '');\n },\n error: (msg: string, data?: any) => {\n console.error(`[${connectorId}] ${msg}`, data || '');\n },\n };\n\n // ─────────────────────────────────────────────────────────────────────\n // Helper functions\n // ─────────────────────────────────────────────────────────────────────\n\n const parseDateTime = (dateStr: string, timeStr: string): Date => {\n const [year, month, day] = dateStr.split('-').map(Number);\n const [hours, minutes] = timeStr.split(':').map(Number);\n return new Date(year, month - 1, day, hours, minutes);\n };\n\n const formatDate = (date: Date): string => {\n return date.toISOString().split('T')[0];\n };\n\n const getDayOfWeek = (date: Date): string => {\n const days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];\n return days[date.getDay()];\n };\n\n const addDays = (date: Date, days: number): Date => {\n const result = new Date(date);\n result.setDate(result.getDate() + days);\n return result;\n };\n\n const startOfDay = (date: Date): Date => {\n const result = new Date(date);\n result.setHours(0, 0, 0, 0);\n return result;\n };\n\n const endOfDay = (date: Date): Date => {\n const result = new Date(date);\n result.setHours(23, 59, 59, 999);\n return result;\n };\n\n const getCalendarIds = async (): Promise<string[]> => {\n try {\n const calendars = await ExpoCalendar.getCalendarsAsync(ExpoCalendar.EntityTypes.EVENT);\n return calendars.map(c => c.id);\n } catch (err) {\n log.warn('Failed to get calendar IDs', err);\n return [];\n }\n };\n\n const getDefaultCalendarId = async (): Promise<string> => {\n try {\n const calendars = await ExpoCalendar.getCalendarsAsync(ExpoCalendar.EntityTypes.EVENT);\n return calendars.length > 0 ? calendars[0].id : '';\n } catch (err) {\n log.warn('Failed to get default calendar', err);\n return '';\n }\n };\n\n const formatCalendarEvent = (event: any): any => {\n return {\n id: event.id,\n title: event.title,\n date: event.startDate ? formatDate(new Date(event.startDate)) : '',\n start: event.startDate ? new Date(event.startDate).toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' }) : '',\n end: event.endDate ? new Date(event.endDate).toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' }) : '',\n location: event.location || '',\n attendees: event.attendees ? event.attendees.map((a: any) => a.email || a.name) : [],\n notes: event.notes || '',\n };\n };\n\n const formatContact = (contact: any): any => {\n const phone = contact.phoneNumbers?.[0]?.number || null;\n const email = contact.emails?.[0]?.email || null;\n const birthday = contact.birthday\n ? `${contact.birthday.year}-${String(contact.birthday.month).padStart(2, '0')}-${String(contact.birthday.day).padStart(2, '0')}`\n : null;\n\n return {\n id: contact.id,\n name: contact.name,\n phone,\n email,\n relationship: contact.relationships?.[0]?.relationship || contact.contactType || 'contact',\n birthday,\n notes: contact.note || '',\n };\n };\n\n const classifyLocation = (geo: any): string => {\n const name = geo.name?.toLowerCase() || '';\n if (name.includes('home')) return 'home';\n if (name.includes('work') || name.includes('office')) return 'work';\n if (name.includes('school') || name.includes('university')) return 'school';\n if (name.includes('gym') || name.includes('fitness')) return 'fitness';\n if (name.includes('hospital') || name.includes('clinic') || name.includes('medical')) return 'medical';\n return 'other';\n };\n\n const formatPlace = (geo: any): string => {\n if (!geo) return 'Unknown Location';\n const name = geo.name || '';\n const street = geo.street ? `${geo.street}` : '';\n return name ? `${name} — ${street}` : street;\n };\n\n const formatAddress = (geo: any): string => {\n if (!geo) return '';\n const parts = [geo.street, geo.city, geo.region, geo.postalCode].filter(Boolean);\n return parts.join(', ');\n };\n\n const formatNotification = (notif: any): any => {\n return {\n id: notif.request?.identifier || String(Math.random()),\n app: notif.request?.content?.title || 'Unknown',\n title: notif.request?.content?.title || '',\n body: notif.request?.content?.body || '',\n timestamp: new Date().toISOString(),\n sender: null,\n priority: 'medium',\n read: false,\n };\n };\n\n const mapBatteryState = (state: number): 'charging' | 'full' | 'unplugged' => {\n if (state === ExpoBattery.BatteryState.CHARGING) return 'charging';\n if (state === ExpoBattery.BatteryState.FULL) return 'full';\n return 'unplugged';\n };\n\n // ─────────────────────────────────────────────────────────────────────\n // BRIDGE IMPLEMENTATION\n // ─────────────────────────────────────────────────────────────────────\n\n const bridge: Bridge = {\n calendar: {\n async getToday() {\n try {\n const start = startOfDay(new Date());\n const end = endOfDay(new Date());\n const calendarIds = await getCalendarIds();\n const events = await ExpoCalendar.getEventsAsync(calendarIds, start, end);\n return {\n date: formatDate(new Date()),\n day_of_week: getDayOfWeek(new Date()),\n events: events.map(formatCalendarEvent),\n count: events.length,\n };\n } catch (err) {\n log.error('Failed to get today\\'s calendar events', err);\n return { date: formatDate(new Date()), day_of_week: getDayOfWeek(new Date()), events: [], count: 0 };\n }\n },\n\n async getUpcoming(days = 7) {\n try {\n const start = new Date();\n const end = addDays(start, Math.min(days, 14));\n const calendarIds = await getCalendarIds();\n const events = await ExpoCalendar.getEventsAsync(calendarIds, start, end);\n return {\n from: formatDate(start),\n days_ahead: days,\n events: events.map(formatCalendarEvent),\n count: events.length,\n };\n } catch (err) {\n log.error('Failed to get upcoming calendar events', err);\n return { from: formatDate(new Date()), days_ahead: days, events: [], count: 0 };\n }\n },\n\n async create(event) {\n try {\n const calendarId = await getDefaultCalendarId();\n if (!calendarId) throw new Error('No default calendar found');\n\n const eventId = await ExpoCalendar.createEventAsync(calendarId, {\n title: event.title,\n startDate: parseDateTime(event.date, event.start_time),\n endDate: parseDateTime(event.date, event.end_time || event.start_time),\n location: event.location,\n notes: event.notes,\n });\n\n return { event_id: eventId };\n } catch (err) {\n log.error('Failed to create calendar event', err);\n throw err;\n }\n },\n\n async reschedule(params) {\n try {\n const updates: any = {};\n if (params.new_date && params.new_start_time) {\n updates.startDate = parseDateTime(params.new_date, params.new_start_time);\n }\n if (params.new_date && params.new_end_time) {\n updates.endDate = parseDateTime(params.new_date, params.new_end_time);\n }\n await ExpoCalendar.updateEventAsync(params.event_id, updates);\n return { ok: true };\n } catch (err) {\n log.error('Failed to reschedule event', err);\n throw err;\n }\n },\n\n async cancel(event_id) {\n try {\n await ExpoCalendar.deleteEventAsync(event_id);\n return { ok: true };\n } catch (err) {\n log.error('Failed to cancel event', err);\n throw err;\n }\n },\n },\n\n contacts: {\n async search(query) {\n try {\n const { data } = await ExpoContacts.getContactsAsync({\n fields: [\n ExpoContacts.Fields.PhoneNumbers,\n ExpoContacts.Fields.Emails,\n ExpoContacts.Fields.Birthday,\n ExpoContacts.Fields.Note,\n ExpoContacts.Fields.Relationships,\n ],\n });\n\n const q = query.toLowerCase();\n const filtered = data.filter(\n c => c.name?.toLowerCase().includes(q) || c.note?.toLowerCase().includes(q)\n );\n\n return { contacts: filtered.map(formatContact), count: filtered.length };\n } catch (err) {\n log.error('Failed to search contacts', err);\n return { contacts: [], count: 0 };\n }\n },\n\n async get(idOrName) {\n try {\n const { data } = await ExpoContacts.getContactsAsync({\n fields: [\n ExpoContacts.Fields.PhoneNumbers,\n ExpoContacts.Fields.Emails,\n ExpoContacts.Fields.Birthday,\n ExpoContacts.Fields.Note,\n ],\n });\n\n const contact = data.find(c => c.id === idOrName || c.name === idOrName);\n return contact ? formatContact(contact) : null;\n } catch (err) {\n log.error('Failed to get contact', err);\n return null;\n }\n },\n\n async getAll() {\n try {\n const { data } = await ExpoContacts.getContactsAsync({\n fields: [\n ExpoContacts.Fields.PhoneNumbers,\n ExpoContacts.Fields.Emails,\n ExpoContacts.Fields.Birthday,\n ExpoContacts.Fields.Note,\n ExpoContacts.Fields.Relationships,\n ],\n sort: ExpoContacts.SortTypes.LastName,\n });\n\n return { contacts: data.map(formatContact), count: data.length };\n } catch (err) {\n log.error('Failed to get all contacts', err);\n return { contacts: [], count: 0 };\n }\n },\n\n async birthdays(days = 30) {\n try {\n const { data } = await ExpoContacts.getContactsAsync({\n fields: [ExpoContacts.Fields.Birthday],\n });\n\n const today = new Date();\n const futureDate = addDays(today, days);\n\n const birthdays = data\n .filter(c => c.birthday)\n .map(c => {\n const birthday = c.birthday!;\n const thisYearBday = new Date(today.getFullYear(), birthday.month - 1, birthday.day);\n if (thisYearBday < today) {\n thisYearBday.setFullYear(today.getFullYear() + 1);\n }\n\n return {\n name: c.name,\n relationship: c.relationships?.[0]?.relationship || 'contact',\n birthday: `${birthday.year || '????'}-${String(birthday.month).padStart(2, '0')}-${String(birthday.day).padStart(2, '0')}`,\n days_until: Math.floor((thisYearBday.getTime() - today.getTime()) / (1000 * 60 * 60 * 24)),\n is_today: thisYearBday.toDateString() === today.toDateString(),\n };\n })\n .filter(b => b.days_until >= 0 && b.days_until <= days);\n\n return { birthdays, count: birthdays.length };\n } catch (err) {\n log.error('Failed to get birthdays', err);\n return { birthdays: [], count: 0 };\n }\n },\n },\n\n location: {\n async getCurrent() {\n try {\n const location = await ExpoLocation.getCurrentPositionAsync({\n accuracy: ExpoLocation.Accuracy.Balanced,\n });\n\n const [geo] = await ExpoLocation.reverseGeocodeAsync({\n latitude: location.coords.latitude,\n longitude: location.coords.longitude,\n });\n\n return {\n lat: location.coords.latitude,\n lng: location.coords.longitude,\n place: formatPlace(geo),\n address: formatAddress(geo),\n type: classifyLocation(geo),\n timestamp: new Date().toISOString(),\n };\n } catch (err) {\n log.error('Failed to get current location', err);\n throw err;\n }\n },\n },\n\n battery: {\n async getStatus() {\n try {\n const [level, state, lowPower] = await Promise.all([\n ExpoBattery.getBatteryLevelAsync(),\n ExpoBattery.getBatteryStateAsync(),\n ExpoBattery.isLowPowerModeEnabledAsync(),\n ]);\n\n return {\n ok: true as const,\n timestamp: new Date().toISOString(),\n battery: {\n level: Math.round(level * 100),\n state: mapBatteryState(state),\n low_power_mode: lowPower,\n },\n };\n } catch (err) {\n log.error('Failed to get battery status', err);\n throw err;\n }\n },\n },\n\n network: {\n async getStatus() {\n try {\n const state = await ExpoNetwork.getNetworkStateAsync();\n return {\n type: state.type === ExpoNetwork.NetworkStateType.WIFI\n ? 'wifi'\n : state.type === ExpoNetwork.NetworkStateType.CELLULAR\n ? 'cellular'\n : 'none',\n is_connected: state.isConnected ?? false,\n timestamp: new Date().toISOString(),\n };\n } catch (err) {\n log.error('Failed to get network status', err);\n throw err;\n }\n },\n },\n\n notifications: {\n async list() {\n try {\n const presented = await ExpoNotifications.getPresentedNotificationsAsync();\n const notifications = presented.map(formatNotification);\n return {\n notifications,\n total: notifications.length,\n unread: notifications.filter(n => !n.read).length,\n };\n } catch (err) {\n log.error('Failed to get notifications', err);\n return { notifications: [], total: 0, unread: 0 };\n }\n },\n },\n\n sms: {\n async isAvailable() {\n try {\n return await ExpoSMS.isAvailableAsync();\n } catch (err) {\n log.error('Failed to check SMS availability', err);\n return false;\n }\n },\n\n async send(phone, message) {\n try {\n const { result } = await ExpoSMS.sendSMSAsync([phone], message);\n return {\n ok: result === 'sent' || result === 'unknown',\n status: result as 'sent' | 'unknown' | 'cancelled',\n };\n } catch (err) {\n log.error('Failed to send SMS', err);\n throw err;\n }\n },\n },\n\n maps: {\n async navigate(destination, mode = 'driving') {\n try {\n const encoded = encodeURIComponent(destination);\n const url = Platform.OS === 'ios'\n ? `maps://maps.apple.com/?daddr=${encoded}&dirflg=${mode[0]}`\n : `google.navigation:q=${encoded}&mode=${mode}`;\n\n const canOpen = await ExpoLinking.canOpenURL(url);\n if (!canOpen) {\n // Fallback to web\n const fallbackUrl = `https://www.google.com/maps/search/${encoded}`;\n await ExpoLinking.openURL(fallbackUrl);\n } else {\n await ExpoLinking.openURL(url);\n }\n\n return { ok: true, status: 'navigating' };\n } catch (err) {\n log.error('Failed to navigate', err);\n return { ok: false, status: 'error' };\n }\n },\n },\n\n http: {\n async get(url, headers = {}) {\n try {\n const res = await fetch(url, { headers });\n const data = await res.json();\n return {\n ok: res.ok,\n status: res.status,\n data,\n headers: Object.fromEntries(res.headers.entries()),\n };\n } catch (err) {\n log.error('HTTP GET failed', err);\n throw err;\n }\n },\n\n async post(url, body, headers = {}) {\n try {\n const res = await fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...headers },\n body: JSON.stringify(body),\n });\n const data = await res.json();\n return {\n ok: res.ok,\n status: res.status,\n data,\n headers: Object.fromEntries(res.headers.entries()),\n };\n } catch (err) {\n log.error('HTTP POST failed', err);\n throw err;\n }\n },\n\n async put(url, body, headers = {}) {\n try {\n const res = await fetch(url, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json', ...headers },\n body: JSON.stringify(body),\n });\n const data = await res.json();\n return {\n ok: res.ok,\n status: res.status,\n data,\n headers: Object.fromEntries(res.headers.entries()),\n };\n } catch (err) {\n log.error('HTTP PUT failed', err);\n throw err;\n }\n },\n\n async delete(url, body, headers = {}) {\n try {\n const opts: any = {\n method: 'DELETE',\n headers: { 'Content-Type': 'application/json', ...headers },\n };\n if (body) opts.body = JSON.stringify(body);\n\n const res = await fetch(url, opts);\n const data = await res.json();\n return {\n ok: res.ok,\n status: res.status,\n data,\n headers: Object.fromEntries(res.headers.entries()),\n };\n } catch (err) {\n log.error('HTTP DELETE failed', err);\n throw err;\n }\n },\n },\n\n storage: {\n async get(key) {\n try {\n return await AsyncStorage.getItem(storagePrefix + key);\n } catch (err) {\n log.error(`Failed to get storage key: ${key}`, err);\n return null;\n }\n },\n\n async set(key, value) {\n try {\n await AsyncStorage.setItem(storagePrefix + key, value);\n } catch (err) {\n log.error(`Failed to set storage key: ${key}`, err);\n }\n },\n\n async delete(key) {\n try {\n await AsyncStorage.removeItem(storagePrefix + key);\n } catch (err) {\n log.error(`Failed to delete storage key: ${key}`, err);\n }\n },\n\n async keys() {\n try {\n const allKeys = await AsyncStorage.getAllKeys();\n return allKeys\n .filter(k => k.startsWith(storagePrefix))\n .map(k => k.slice(storagePrefix.length));\n } catch (err) {\n log.error('Failed to list storage keys', err);\n return [];\n }\n },\n },\n\n permissions: {\n async check(capability) {\n try {\n // Map capability to Expo permission API\n switch (capability) {\n case 'calendar':\n const cal = await ExpoCalendar.getCalendarPermissionsAsync();\n return cal.status === 'granted' ? 'granted' : cal.status === 'denied' ? 'denied' : 'not_requested';\n case 'contacts':\n const con = await ExpoContacts.getPermissionsAsync();\n return con.status === 'granted' ? 'granted' : con.status === 'denied' ? 'denied' : 'not_requested';\n case 'location':\n const loc = await ExpoLocation.getForegroundPermissionsAsync();\n return loc.status === 'granted' ? 'granted' : loc.status === 'denied' ? 'denied' : 'not_requested';\n case 'notifications':\n const notif = await ExpoNotifications.getPermissionsAsync();\n return notif.granted ? 'granted' : notif.canAskAgain ? 'not_requested' : 'denied';\n default:\n return 'not_requested';\n }\n } catch (err) {\n log.error(`Failed to check permission: ${capability}`, err);\n return 'denied';\n }\n },\n\n async request(capability) {\n try {\n switch (capability) {\n case 'calendar':\n const cal = await ExpoCalendar.requestCalendarPermissionsAsync();\n return cal.status === 'granted';\n case 'contacts':\n const con = await ExpoContacts.requestPermissionsAsync();\n return con.status === 'granted';\n case 'location':\n const loc = await ExpoLocation.requestForegroundPermissionsAsync();\n return loc.status === 'granted';\n case 'notifications':\n const notif = await ExpoNotifications.requestPermissionsAsync();\n return notif.granted;\n default:\n return false;\n }\n } catch (err) {\n log.error(`Failed to request permission: ${capability}`, err);\n return false;\n }\n },\n\n async getAll() {\n try {\n const [cal, con, loc, notif] = await Promise.allSettled([\n ExpoCalendar.getCalendarPermissionsAsync(),\n ExpoContacts.getPermissionsAsync(),\n ExpoLocation.getForegroundPermissionsAsync(),\n ExpoNotifications.getPermissionsAsync(),\n ]);\n\n return {\n calendar: cal.status === 'fulfilled' ? (cal.value.status === 'granted' ? 'granted' : cal.value.status === 'denied' ? 'denied' : 'not_requested') : 'denied',\n contacts: con.status === 'fulfilled' ? (con.value.status === 'granted' ? 'granted' : con.value.status === 'denied' ? 'denied' : 'not_requested') : 'denied',\n location: loc.status === 'fulfilled' ? (loc.value.status === 'granted' ? 'granted' : loc.value.status === 'denied' ? 'denied' : 'not_requested') : 'denied',\n notifications: notif.status === 'fulfilled' ? (notif.value.granted ? 'granted' : notif.value.canAskAgain ? 'not_requested' : 'denied') : 'denied',\n };\n } catch (err) {\n log.error('Failed to get all permissions', err);\n return { calendar: 'denied', contacts: 'denied', location: 'denied', notifications: 'denied' };\n }\n },\n },\n\n device: {\n getDeviceId() {\n return deviceId;\n },\n\n getPlatform() {\n return {\n os: Platform.OS as 'ios' | 'android',\n version: Platform.Version ? String(Platform.Version) : 'unknown',\n };\n },\n },\n\n log,\n };\n\n return bridge;\n}\n"],"mappings":"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","names":["AsyncStorage"]}
|
|
1
|
+
{"version":3,"sources":["../src/createBridge.ts","../src/maps/index.ts","../src/maps/normalize.ts"],"sourcesContent":["/**\n * Native Bridge Factory\n *\n * Creates a Bridge instance that wraps Expo native modules.\n * Each bridge is scoped to a specific connector ID for storage isolation.\n */\n\nimport AsyncStorage from '@react-native-async-storage/async-storage';\nimport * as ExpoCalendar from 'expo-calendar';\nimport * as ExpoContacts from 'expo-contacts';\nimport * as ExpoLocation from 'expo-location';\nimport * as ExpoBattery from 'expo-battery';\nimport * as ExpoNetwork from 'expo-network';\nimport * as ExpoNotifications from 'expo-notifications';\nimport * as ExpoSMS from 'expo-sms';\nimport * as ExpoLinking from 'expo-linking';\nimport { Platform } from 'react-native';\nimport * as Device from 'expo-device';\n// The SDK's one reverse geocode — the same call native.maps.reverseGeocode makes.\nimport { reverseGeocode } from './maps';\n\nimport type { Bridge } from '@ateam-ai-mobile/plugin-runtime';\n\nexport function createBridge(connectorId: string, deviceId: string): Bridge {\n const storagePrefix = `connector:${connectorId}:`;\n\n const log = {\n info: (msg: string, data?: any) => {\n console.log(`[${connectorId}] ${msg}`, data || '');\n },\n warn: (msg: string, data?: any) => {\n console.warn(`[${connectorId}] ${msg}`, data || '');\n },\n error: (msg: string, data?: any) => {\n console.error(`[${connectorId}] ${msg}`, data || '');\n },\n };\n\n // ─────────────────────────────────────────────────────────────────────\n // Helper functions\n // ─────────────────────────────────────────────────────────────────────\n\n const parseDateTime = (dateStr: string, timeStr: string): Date => {\n const [year, month, day] = dateStr.split('-').map(Number);\n const [hours, minutes] = timeStr.split(':').map(Number);\n return new Date(year, month - 1, day, hours, minutes);\n };\n\n const formatDate = (date: Date): string => {\n return date.toISOString().split('T')[0];\n };\n\n const getDayOfWeek = (date: Date): string => {\n const days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];\n return days[date.getDay()];\n };\n\n const addDays = (date: Date, days: number): Date => {\n const result = new Date(date);\n result.setDate(result.getDate() + days);\n return result;\n };\n\n const startOfDay = (date: Date): Date => {\n const result = new Date(date);\n result.setHours(0, 0, 0, 0);\n return result;\n };\n\n const endOfDay = (date: Date): Date => {\n const result = new Date(date);\n result.setHours(23, 59, 59, 999);\n return result;\n };\n\n const getCalendarIds = async (): Promise<string[]> => {\n try {\n const calendars = await ExpoCalendar.getCalendarsAsync(ExpoCalendar.EntityTypes.EVENT);\n return calendars.map(c => c.id);\n } catch (err) {\n log.warn('Failed to get calendar IDs', err);\n return [];\n }\n };\n\n const getDefaultCalendarId = async (): Promise<string> => {\n try {\n const calendars = await ExpoCalendar.getCalendarsAsync(ExpoCalendar.EntityTypes.EVENT);\n return calendars.length > 0 ? calendars[0].id : '';\n } catch (err) {\n log.warn('Failed to get default calendar', err);\n return '';\n }\n };\n\n const formatCalendarEvent = (event: any): any => {\n return {\n id: event.id,\n title: event.title,\n date: event.startDate ? formatDate(new Date(event.startDate)) : '',\n start: event.startDate ? new Date(event.startDate).toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' }) : '',\n end: event.endDate ? new Date(event.endDate).toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' }) : '',\n location: event.location || '',\n attendees: event.attendees ? event.attendees.map((a: any) => a.email || a.name) : [],\n notes: event.notes || '',\n };\n };\n\n const formatContact = (contact: any): any => {\n const phone = contact.phoneNumbers?.[0]?.number || null;\n const email = contact.emails?.[0]?.email || null;\n const birthday = contact.birthday\n ? `${contact.birthday.year}-${String(contact.birthday.month).padStart(2, '0')}-${String(contact.birthday.day).padStart(2, '0')}`\n : null;\n\n return {\n id: contact.id,\n name: contact.name,\n phone,\n email,\n relationship: contact.relationships?.[0]?.relationship || contact.contactType || 'contact',\n birthday,\n notes: contact.note || '',\n };\n };\n\n const classifyLocation = (geo: any): string => {\n const name = geo.name?.toLowerCase() || '';\n if (name.includes('home')) return 'home';\n if (name.includes('work') || name.includes('office')) return 'work';\n if (name.includes('school') || name.includes('university')) return 'school';\n if (name.includes('gym') || name.includes('fitness')) return 'fitness';\n if (name.includes('hospital') || name.includes('clinic') || name.includes('medical')) return 'medical';\n return 'other';\n };\n\n const formatPlace = (geo: any): string => {\n if (!geo) return 'Unknown Location';\n const name = geo.name || '';\n const street = geo.street ? `${geo.street}` : '';\n return name ? `${name} — ${street}` : street;\n };\n\n const formatAddress = (geo: any): string => {\n if (!geo) return '';\n const parts = [geo.street, geo.city, geo.region, geo.postalCode].filter(Boolean);\n return parts.join(', ');\n };\n\n const formatNotification = (notif: any): any => {\n return {\n id: notif.request?.identifier || String(Math.random()),\n app: notif.request?.content?.title || 'Unknown',\n title: notif.request?.content?.title || '',\n body: notif.request?.content?.body || '',\n timestamp: new Date().toISOString(),\n sender: null,\n priority: 'medium',\n read: false,\n };\n };\n\n const mapBatteryState = (state: number): 'charging' | 'full' | 'unplugged' => {\n if (state === ExpoBattery.BatteryState.CHARGING) return 'charging';\n if (state === ExpoBattery.BatteryState.FULL) return 'full';\n return 'unplugged';\n };\n\n // ─────────────────────────────────────────────────────────────────────\n // BRIDGE IMPLEMENTATION\n // ─────────────────────────────────────────────────────────────────────\n\n const bridge: Bridge = {\n calendar: {\n async getToday() {\n try {\n const start = startOfDay(new Date());\n const end = endOfDay(new Date());\n const calendarIds = await getCalendarIds();\n const events = await ExpoCalendar.getEventsAsync(calendarIds, start, end);\n return {\n date: formatDate(new Date()),\n day_of_week: getDayOfWeek(new Date()),\n events: events.map(formatCalendarEvent),\n count: events.length,\n };\n } catch (err) {\n log.error('Failed to get today\\'s calendar events', err);\n return { date: formatDate(new Date()), day_of_week: getDayOfWeek(new Date()), events: [], count: 0 };\n }\n },\n\n async getUpcoming(days = 7) {\n try {\n const start = new Date();\n const end = addDays(start, Math.min(days, 14));\n const calendarIds = await getCalendarIds();\n const events = await ExpoCalendar.getEventsAsync(calendarIds, start, end);\n return {\n from: formatDate(start),\n days_ahead: days,\n events: events.map(formatCalendarEvent),\n count: events.length,\n };\n } catch (err) {\n log.error('Failed to get upcoming calendar events', err);\n return { from: formatDate(new Date()), days_ahead: days, events: [], count: 0 };\n }\n },\n\n async create(event) {\n try {\n const calendarId = await getDefaultCalendarId();\n if (!calendarId) throw new Error('No default calendar found');\n\n const eventId = await ExpoCalendar.createEventAsync(calendarId, {\n title: event.title,\n startDate: parseDateTime(event.date, event.start_time),\n endDate: parseDateTime(event.date, event.end_time || event.start_time),\n location: event.location,\n notes: event.notes,\n });\n\n return { event_id: eventId };\n } catch (err) {\n log.error('Failed to create calendar event', err);\n throw err;\n }\n },\n\n async reschedule(params) {\n try {\n const updates: any = {};\n if (params.new_date && params.new_start_time) {\n updates.startDate = parseDateTime(params.new_date, params.new_start_time);\n }\n if (params.new_date && params.new_end_time) {\n updates.endDate = parseDateTime(params.new_date, params.new_end_time);\n }\n await ExpoCalendar.updateEventAsync(params.event_id, updates);\n return { ok: true };\n } catch (err) {\n log.error('Failed to reschedule event', err);\n throw err;\n }\n },\n\n async cancel(event_id) {\n try {\n await ExpoCalendar.deleteEventAsync(event_id);\n return { ok: true };\n } catch (err) {\n log.error('Failed to cancel event', err);\n throw err;\n }\n },\n },\n\n contacts: {\n async search(query) {\n try {\n const { data } = await ExpoContacts.getContactsAsync({\n fields: [\n ExpoContacts.Fields.PhoneNumbers,\n ExpoContacts.Fields.Emails,\n ExpoContacts.Fields.Birthday,\n ExpoContacts.Fields.Note,\n ExpoContacts.Fields.Relationships,\n ],\n });\n\n const q = query.toLowerCase();\n const filtered = data.filter(\n c => c.name?.toLowerCase().includes(q) || c.note?.toLowerCase().includes(q)\n );\n\n return { contacts: filtered.map(formatContact), count: filtered.length };\n } catch (err) {\n log.error('Failed to search contacts', err);\n return { contacts: [], count: 0 };\n }\n },\n\n async get(idOrName) {\n try {\n const { data } = await ExpoContacts.getContactsAsync({\n fields: [\n ExpoContacts.Fields.PhoneNumbers,\n ExpoContacts.Fields.Emails,\n ExpoContacts.Fields.Birthday,\n ExpoContacts.Fields.Note,\n ],\n });\n\n const contact = data.find(c => c.id === idOrName || c.name === idOrName);\n return contact ? formatContact(contact) : null;\n } catch (err) {\n log.error('Failed to get contact', err);\n return null;\n }\n },\n\n async getAll() {\n try {\n const { data } = await ExpoContacts.getContactsAsync({\n fields: [\n ExpoContacts.Fields.PhoneNumbers,\n ExpoContacts.Fields.Emails,\n ExpoContacts.Fields.Birthday,\n ExpoContacts.Fields.Note,\n ExpoContacts.Fields.Relationships,\n ],\n sort: ExpoContacts.SortTypes.LastName,\n });\n\n return { contacts: data.map(formatContact), count: data.length };\n } catch (err) {\n log.error('Failed to get all contacts', err);\n return { contacts: [], count: 0 };\n }\n },\n\n async birthdays(days = 30) {\n try {\n const { data } = await ExpoContacts.getContactsAsync({\n fields: [ExpoContacts.Fields.Birthday],\n });\n\n const today = new Date();\n const futureDate = addDays(today, days);\n\n const birthdays = data\n .filter(c => c.birthday)\n .map(c => {\n const birthday = c.birthday!;\n const thisYearBday = new Date(today.getFullYear(), birthday.month - 1, birthday.day);\n if (thisYearBday < today) {\n thisYearBday.setFullYear(today.getFullYear() + 1);\n }\n\n return {\n name: c.name,\n relationship: c.relationships?.[0]?.relationship || 'contact',\n birthday: `${birthday.year || '????'}-${String(birthday.month).padStart(2, '0')}-${String(birthday.day).padStart(2, '0')}`,\n days_until: Math.floor((thisYearBday.getTime() - today.getTime()) / (1000 * 60 * 60 * 24)),\n is_today: thisYearBday.toDateString() === today.toDateString(),\n };\n })\n .filter(b => b.days_until >= 0 && b.days_until <= days);\n\n return { birthdays, count: birthdays.length };\n } catch (err) {\n log.error('Failed to get birthdays', err);\n return { birthdays: [], count: 0 };\n }\n },\n },\n\n location: {\n async getCurrent() {\n try {\n const location = await ExpoLocation.getCurrentPositionAsync({\n accuracy: ExpoLocation.Accuracy.Balanced,\n });\n\n const geo = await reverseGeocode({\n latitude: location.coords.latitude,\n longitude: location.coords.longitude,\n });\n\n return {\n lat: location.coords.latitude,\n lng: location.coords.longitude,\n place: formatPlace(geo),\n address: formatAddress(geo),\n type: classifyLocation(geo),\n timestamp: new Date().toISOString(),\n };\n } catch (err) {\n log.error('Failed to get current location', err);\n throw err;\n }\n },\n },\n\n battery: {\n async getStatus() {\n try {\n const [level, state, lowPower] = await Promise.all([\n ExpoBattery.getBatteryLevelAsync(),\n ExpoBattery.getBatteryStateAsync(),\n ExpoBattery.isLowPowerModeEnabledAsync(),\n ]);\n\n return {\n ok: true as const,\n timestamp: new Date().toISOString(),\n battery: {\n level: Math.round(level * 100),\n state: mapBatteryState(state),\n low_power_mode: lowPower,\n },\n };\n } catch (err) {\n log.error('Failed to get battery status', err);\n throw err;\n }\n },\n },\n\n network: {\n async getStatus() {\n try {\n const state = await ExpoNetwork.getNetworkStateAsync();\n return {\n type: state.type === ExpoNetwork.NetworkStateType.WIFI\n ? 'wifi'\n : state.type === ExpoNetwork.NetworkStateType.CELLULAR\n ? 'cellular'\n : 'none',\n is_connected: state.isConnected ?? false,\n timestamp: new Date().toISOString(),\n };\n } catch (err) {\n log.error('Failed to get network status', err);\n throw err;\n }\n },\n },\n\n notifications: {\n async list() {\n try {\n const presented = await ExpoNotifications.getPresentedNotificationsAsync();\n const notifications = presented.map(formatNotification);\n return {\n notifications,\n total: notifications.length,\n unread: notifications.filter(n => !n.read).length,\n };\n } catch (err) {\n log.error('Failed to get notifications', err);\n return { notifications: [], total: 0, unread: 0 };\n }\n },\n },\n\n sms: {\n async isAvailable() {\n try {\n return await ExpoSMS.isAvailableAsync();\n } catch (err) {\n log.error('Failed to check SMS availability', err);\n return false;\n }\n },\n\n async send(phone, message) {\n try {\n const { result } = await ExpoSMS.sendSMSAsync([phone], message);\n return {\n ok: result === 'sent' || result === 'unknown',\n status: result as 'sent' | 'unknown' | 'cancelled',\n };\n } catch (err) {\n log.error('Failed to send SMS', err);\n throw err;\n }\n },\n },\n\n maps: {\n async navigate(destination, mode = 'driving') {\n try {\n const encoded = encodeURIComponent(destination);\n const url = Platform.OS === 'ios'\n ? `maps://maps.apple.com/?daddr=${encoded}&dirflg=${mode[0]}`\n : `google.navigation:q=${encoded}&mode=${mode}`;\n\n const canOpen = await ExpoLinking.canOpenURL(url);\n if (!canOpen) {\n // Fallback to web\n const fallbackUrl = `https://www.google.com/maps/search/${encoded}`;\n await ExpoLinking.openURL(fallbackUrl);\n } else {\n await ExpoLinking.openURL(url);\n }\n\n return { ok: true, status: 'navigating' };\n } catch (err) {\n log.error('Failed to navigate', err);\n return { ok: false, status: 'error' };\n }\n },\n },\n\n http: {\n async get(url, headers = {}) {\n try {\n const res = await fetch(url, { headers });\n const data = await res.json();\n return {\n ok: res.ok,\n status: res.status,\n data,\n headers: Object.fromEntries(res.headers.entries()),\n };\n } catch (err) {\n log.error('HTTP GET failed', err);\n throw err;\n }\n },\n\n async post(url, body, headers = {}) {\n try {\n const res = await fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...headers },\n body: JSON.stringify(body),\n });\n const data = await res.json();\n return {\n ok: res.ok,\n status: res.status,\n data,\n headers: Object.fromEntries(res.headers.entries()),\n };\n } catch (err) {\n log.error('HTTP POST failed', err);\n throw err;\n }\n },\n\n async put(url, body, headers = {}) {\n try {\n const res = await fetch(url, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json', ...headers },\n body: JSON.stringify(body),\n });\n const data = await res.json();\n return {\n ok: res.ok,\n status: res.status,\n data,\n headers: Object.fromEntries(res.headers.entries()),\n };\n } catch (err) {\n log.error('HTTP PUT failed', err);\n throw err;\n }\n },\n\n async delete(url, body, headers = {}) {\n try {\n const opts: any = {\n method: 'DELETE',\n headers: { 'Content-Type': 'application/json', ...headers },\n };\n if (body) opts.body = JSON.stringify(body);\n\n const res = await fetch(url, opts);\n const data = await res.json();\n return {\n ok: res.ok,\n status: res.status,\n data,\n headers: Object.fromEntries(res.headers.entries()),\n };\n } catch (err) {\n log.error('HTTP DELETE failed', err);\n throw err;\n }\n },\n },\n\n storage: {\n async get(key) {\n try {\n return await AsyncStorage.getItem(storagePrefix + key);\n } catch (err) {\n log.error(`Failed to get storage key: ${key}`, err);\n return null;\n }\n },\n\n async set(key, value) {\n try {\n await AsyncStorage.setItem(storagePrefix + key, value);\n } catch (err) {\n log.error(`Failed to set storage key: ${key}`, err);\n }\n },\n\n async delete(key) {\n try {\n await AsyncStorage.removeItem(storagePrefix + key);\n } catch (err) {\n log.error(`Failed to delete storage key: ${key}`, err);\n }\n },\n\n async keys() {\n try {\n const allKeys = await AsyncStorage.getAllKeys();\n return allKeys\n .filter(k => k.startsWith(storagePrefix))\n .map(k => k.slice(storagePrefix.length));\n } catch (err) {\n log.error('Failed to list storage keys', err);\n return [];\n }\n },\n },\n\n permissions: {\n async check(capability) {\n try {\n // Map capability to Expo permission API\n switch (capability) {\n case 'calendar':\n const cal = await ExpoCalendar.getCalendarPermissionsAsync();\n return cal.status === 'granted' ? 'granted' : cal.status === 'denied' ? 'denied' : 'not_requested';\n case 'contacts':\n const con = await ExpoContacts.getPermissionsAsync();\n return con.status === 'granted' ? 'granted' : con.status === 'denied' ? 'denied' : 'not_requested';\n case 'location':\n const loc = await ExpoLocation.getForegroundPermissionsAsync();\n return loc.status === 'granted' ? 'granted' : loc.status === 'denied' ? 'denied' : 'not_requested';\n case 'notifications':\n const notif = await ExpoNotifications.getPermissionsAsync();\n return notif.granted ? 'granted' : notif.canAskAgain ? 'not_requested' : 'denied';\n default:\n return 'not_requested';\n }\n } catch (err) {\n log.error(`Failed to check permission: ${capability}`, err);\n return 'denied';\n }\n },\n\n async request(capability) {\n try {\n switch (capability) {\n case 'calendar':\n const cal = await ExpoCalendar.requestCalendarPermissionsAsync();\n return cal.status === 'granted';\n case 'contacts':\n const con = await ExpoContacts.requestPermissionsAsync();\n return con.status === 'granted';\n case 'location':\n const loc = await ExpoLocation.requestForegroundPermissionsAsync();\n return loc.status === 'granted';\n case 'notifications':\n const notif = await ExpoNotifications.requestPermissionsAsync();\n return notif.granted;\n default:\n return false;\n }\n } catch (err) {\n log.error(`Failed to request permission: ${capability}`, err);\n return false;\n }\n },\n\n async getAll() {\n try {\n const [cal, con, loc, notif] = await Promise.allSettled([\n ExpoCalendar.getCalendarPermissionsAsync(),\n ExpoContacts.getPermissionsAsync(),\n ExpoLocation.getForegroundPermissionsAsync(),\n ExpoNotifications.getPermissionsAsync(),\n ]);\n\n return {\n calendar: cal.status === 'fulfilled' ? (cal.value.status === 'granted' ? 'granted' : cal.value.status === 'denied' ? 'denied' : 'not_requested') : 'denied',\n contacts: con.status === 'fulfilled' ? (con.value.status === 'granted' ? 'granted' : con.value.status === 'denied' ? 'denied' : 'not_requested') : 'denied',\n location: loc.status === 'fulfilled' ? (loc.value.status === 'granted' ? 'granted' : loc.value.status === 'denied' ? 'denied' : 'not_requested') : 'denied',\n notifications: notif.status === 'fulfilled' ? (notif.value.granted ? 'granted' : notif.value.canAskAgain ? 'not_requested' : 'denied') : 'denied',\n };\n } catch (err) {\n log.error('Failed to get all permissions', err);\n return { calendar: 'denied', contacts: 'denied', location: 'denied', notifications: 'denied' };\n }\n },\n },\n\n device: {\n getDeviceId() {\n return deviceId;\n },\n\n getPlatform() {\n return {\n os: Platform.OS as 'ios' | 'android',\n version: Platform.Version ? String(Platform.Version) : 'unknown',\n };\n },\n },\n\n log,\n };\n\n return bridge;\n}\n","// ada-maps — place search + walking directions (Apple MapKit), our own native\n// code, plus the SDK's one reverse geocode.\n//\n// NOT on-device — the opposite of ada-vision. Every call sends the query and the\n// coordinates it is given to a map service over the network. None of it reads\n// the device's location: the caller supplies every coordinate.\n//\n// search(...) — MKLocalSearch (AdaMaps module, iOS only)\n// route(...) — MKDirections (AdaMaps module, iOS only)\n// reverseGeocode(at) — expo-location's reverseGeocodeAsync, which IS CLGeocoder\n// on iOS and the platform Geocoder on Android. No Swift for\n// it, and the ONLY reverse geocode in the SDK: the location\n// collector and the connector bridge call this too.\n//\n// requireOptionalNativeModule: on a binary WITHOUT the module the import is null,\n// isSupported() is false, and search/route refuse cleanly (no crash). Android has\n// no AdaMaps at all, so it refuses by name the same way.\n\nimport { Platform } from 'react-native';\nimport { requireOptionalNativeModule } from 'expo-modules-core';\nimport * as ExpoLocation from 'expo-location';\nimport type { MapsAddress, MapsCoordinate } from '@ateam-ai-mobile/plugin-runtime';\nimport { toMapsAddress } from './normalize';\nimport type { RawMapsPlace, RawMapsRoute } from './normalize';\n\ninterface AdaMapsNative {\n isSupported(): boolean;\n search(query: string, lat: number, lng: number, hasNear: boolean, radiusM: number, limit: number): Promise<RawMapsPlace[]>;\n route(fromLat: number, fromLng: number, toLat: number, toLng: number): Promise<RawMapsRoute | null>;\n}\n\nconst native = requireOptionalNativeModule<AdaMapsNative>('AdaMaps');\n\n/** What search/route are missing in THIS build, as the clause after \"needs\" —\n * or null when they can run. A voice assistant reads it out, so it names the\n * missing thing rather than giving a code. */\nexport function missingReason(): string | null {\n if (Platform.OS !== 'ios') return `iOS (Apple MapKit) — ${Platform.OS} has no implementation yet`;\n if (!native) return 'the app build with the AdaMaps module (this build predates it — a native rebuild is needed)';\n return null;\n}\n\n/** Is the native maps module present in this binary (and on a platform it runs on)? */\nexport function isSupported(): boolean {\n try { return missingReason() === null && (native?.isSupported() ?? false); } catch { return false; }\n}\n\n// search/route hand their arguments to native AS GIVEN: a NaN or Infinity\n// `limit` traps Swift's Int conversion and kills the app. createMapsAPI checks\n// every argument first (searchArgs / coordinateArg in ./normalize); a host\n// calling these directly must pass what those checks would accept.\n\n/** MKLocalSearch around `near` (when given). [] = looked, found nothing; throws =\n * couldn't look, with a string code OFFLINE / THROTTLED / UNAVAILABLE. */\nexport async function search(\n query: string,\n near: MapsCoordinate | null,\n radiusM: number,\n limit: number,\n): Promise<RawMapsPlace[]> {\n if (!native) throw new Error('ada-maps native module not present in this build');\n // Without `near`, hasNear is false and Swift never reads lat/lng — the zeros\n // are placeholders for a primitive argument, not a place.\n return near\n ? native.search(query, near.latitude, near.longitude, true, radiusM, limit)\n : native.search(query, 0, 0, false, radiusM, limit);\n}\n\n/** MKDirections, walking, between two caller-supplied points. null = no route. */\nexport async function route(from: MapsCoordinate, to: MapsCoordinate): Promise<RawMapsRoute | null> {\n if (!native) throw new Error('ada-maps native module not present in this build');\n return native.route(from.latitude, from.longitude, to.latitude, to.longitude);\n}\n\n/** The address at a coordinate, or null when the geocoder has nothing there.\n * Throws when it could not look (network, rate limit, Android without location\n * permission) — callers decide whether that is fatal. */\nexport async function reverseGeocode(at: MapsCoordinate): Promise<MapsAddress | null> {\n const [first] = await ExpoLocation.reverseGeocodeAsync({ latitude: at.latitude, longitude: at.longitude });\n return first ? toMapsAddress(first) : null;\n}\n","// Pure shaping for native.maps — no Expo, no React Native, so it runs under\n// plain `node --test` (tests/adaMapsNormalize.test.mjs pins it).\n//\n// The native side hands back loose dictionaries — AdaMaps (MapKit) for search\n// and route, expo-location's geocoder for reverse geocoding. This turns them\n// into the typed MapsAPI shapes, and one set of failure codes. Unknown is\n// `null`, never '' or 0: an empty street reads as a street with no name, and a\n// 0 m route reads as \"you have arrived\".\n//\n// It also checks what a caller sends BEFORE it crosses the bridge (searchArgs,\n// coordinateArg). A remote bundle is plain JS at runtime, so the types promise\n// nothing: a NaN or Infinity `limit` traps Swift's Int conversion and kills the\n// app, and a `{ lat, lng }` near would search around 0,0 and answer \"found\n// nothing\" with confidence.\n\nimport type {\n MapsAddress,\n MapsCoordinate,\n MapsPlace,\n MapsRoute,\n MapsRouteStep,\n} from '@ateam-ai-mobile/plugin-runtime';\nimport { distanceOf } from '../geo';\nimport { countArg, refuseArgument as refuse, shown, type ArgumentError } from '../args';\n\n/** An address as the native geocoders spell it. AdaMaps sends exactly these\n * keys; expo-location sends these plus `subregion`/`timezone`/\n * `formattedAddress`, which MapsAddress does not carry. */\nexport interface RawMapsAddress {\n name?: string | null;\n street?: string | null;\n streetNumber?: string | null;\n district?: string | null;\n city?: string | null;\n region?: string | null;\n postalCode?: string | null;\n country?: string | null;\n isoCountryCode?: string | null;\n}\n\n/** One AdaMaps search hit (AdaMapsModule.place). */\nexport interface RawMapsPlace {\n name: string | null;\n latitude: number;\n longitude: number;\n /** MKPointOfInterestCategory raw value, e.g. \"MKPOICategoryPharmacy\". */\n category: string | null;\n address: RawMapsAddress;\n}\n\n/** An AdaMaps walking route (AdaMapsModule.route) — distances in metres,\n * expectedTravelTime in SECONDS, as MapKit reports them. */\nexport interface RawMapsRoute {\n distance: number;\n expectedTravelTime: number;\n steps: Array<{ instructions: string | null; distance: number; notice: string | null; polyline: MapsCoordinate[] }>;\n polyline: MapsCoordinate[];\n}\n\n/** The three ways a maps call can fail to look — see MapsAPI. */\nexport type MapsFailureCode = 'UNAVAILABLE' | 'OFFLINE' | 'THROTTLED';\n\n/** A malformed call, refused before anything is sent. Not a fourth way to fail\n * to look: retrying will not help, fixing the call will. */\nexport type MapsArgumentError = ArgumentError;\n\nconst SEARCH_RADIUS_DEFAULT_M = 3000;\n/** Keeps the region MapKit is handed a small, valid one. A \"near\" search wider\n * than this is a different question. */\nconst SEARCH_RADIUS_MAX_M = 100_000;\nconst SEARCH_LIMIT_DEFAULT = 8;\nconst SEARCH_LIMIT_MAX = 25;\n\nconst text = (v: unknown): string | null =>\n typeof v === 'string' && v.trim() !== '' ? v : null;\n\nconst refuseArgument = (verb: string, problem: string, nothing: string): MapsArgumentError =>\n refuse('maps', verb, problem, nothing);\n\n/** A caller's coordinate, checked and copied to exactly `{ latitude, longitude }`.\n * Anything else — `{ lat, lng }`, strings, NaN, out of range — refuses BY NAME\n * rather than being sent as 0,0 or NaN. */\nexport function coordinateArg(verb: string, name: string, value: unknown, nothing: string): MapsCoordinate {\n const c = value as { latitude?: unknown; longitude?: unknown } | null | undefined;\n const latitude = c?.latitude, longitude = c?.longitude;\n if (\n typeof latitude === 'number' && Number.isFinite(latitude) && Math.abs(latitude) <= 90 &&\n typeof longitude === 'number' && Number.isFinite(longitude) && Math.abs(longitude) <= 180\n ) {\n return { latitude, longitude };\n }\n throw refuseArgument(\n verb,\n `${name} must be { latitude, longitude } numbers (latitude -90..90, longitude -180..180), not ${shown(value)}`,\n nothing,\n );\n}\n\n/** search's arguments, checked and defaulted (radiusM 3000, limit 8). `limit`\n * is floored and capped at 25; everything else out of range refuses. */\nexport function searchArgs(\n query: unknown,\n opts: { near?: unknown; radiusM?: unknown; limit?: unknown } | null | undefined,\n): { query: string; near: MapsCoordinate | null; radiusM: number; limit: number } {\n const nothing = 'nothing was searched';\n if (typeof query !== 'string' || query.trim() === '') {\n throw refuseArgument('search', `query must be a non-empty string, not ${shown(query)}`, nothing);\n }\n const near = opts?.near == null ? null : coordinateArg('search', 'near', opts.near, nothing);\n const radiusM = opts?.radiusM ?? SEARCH_RADIUS_DEFAULT_M;\n if (typeof radiusM !== 'number' || !(radiusM > 0 && radiusM <= SEARCH_RADIUS_MAX_M)) {\n throw refuseArgument(\n 'search', `radiusM must be metres above 0 and at most ${SEARCH_RADIUS_MAX_M}, not ${shown(radiusM)}`, nothing);\n }\n const limit = countArg('maps', 'search', 'limit', opts?.limit, SEARCH_LIMIT_DEFAULT, SEARCH_LIMIT_MAX, nothing);\n return { query, near, radiusM, limit };\n}\n\nconst point = (c: MapsCoordinate): MapsCoordinate => ({\n latitude: Number(c.latitude),\n longitude: Number(c.longitude),\n});\n\nexport function toMapsAddress(raw: RawMapsAddress | null | undefined): MapsAddress {\n const r = raw ?? {};\n return {\n name: text(r.name),\n street: text(r.street),\n streetNumber: text(r.streetNumber),\n district: text(r.district),\n city: text(r.city),\n region: text(r.region),\n postalCode: text(r.postalCode),\n country: text(r.country),\n isoCountryCode: text(r.isoCountryCode),\n };\n}\n\n/** \"MKPOICategoryPharmacy\" → \"Pharmacy\": the vocabulary term, without the\n * framework's prefix. */\nexport function toMapsCategory(raw: unknown): string | null {\n const c = text(raw);\n return c ? c.replace(/^MKPOICategory/, '') || null : null;\n}\n\n/** Search hits → places. `distanceM` is straight-line from `near`, and only\n * when the caller gave one — a distance from nowhere would be invented. */\nexport function toMapsPlaces(raw: RawMapsPlace[] | null | undefined, near: MapsCoordinate | null): MapsPlace[] {\n return (raw ?? []).map(r => {\n const coordinate = point(r);\n return {\n name: text(r.name),\n coordinate,\n address: toMapsAddress(r.address),\n category: toMapsCategory(r.category),\n distanceM: near ? distanceOf([near, coordinate]) : null,\n };\n });\n}\n\n/** A reverse-geocoded address → a place AT the point asked about. The platform\n * geocoder returns an address, not a snapped point or a category. */\nexport function toReverseGeocodedPlace(at: MapsCoordinate, address: MapsAddress): MapsPlace {\n return {\n name: address.name,\n coordinate: point(at),\n address,\n category: null,\n distanceM: null,\n };\n}\n\n/** A MapKit route → MapsRoute. Seconds become ms; every step is kept, including\n * Apple's empty-instruction origin step, so indexes match Apple's. */\nexport function toMapsRoute(raw: RawMapsRoute): MapsRoute {\n const steps: MapsRouteStep[] = (raw.steps ?? []).map(s => ({\n instructions: typeof s.instructions === 'string' ? s.instructions : '',\n distanceM: Number(s.distance),\n notice: text(s.notice),\n polyline: (s.polyline ?? []).map(point),\n }));\n return {\n mode: 'walking',\n distanceM: Number(raw.distance),\n expectedTravelTimeMs: Math.round(Number(raw.expectedTravelTime) * 1000),\n steps,\n polyline: (raw.polyline ?? []).map(point),\n };\n}\n\n/**\n * A native rejection → an Error whose `code` is one of MapsAPI's three.\n *\n * AdaMaps already rejects with OFFLINE / THROTTLED / UNAVAILABLE. expo-location\n * (reverseGeocode) has its own codes: on iOS a CLError.network becomes\n * ERR_GEOCODING_NETWORK, which Apple uses for BOTH a lost connection and a rate\n * limit — so it maps to OFFLINE and the message says it may be either. Anything\n * else is UNAVAILABLE, with the platform's own words kept beside ours.\n */\nexport function mapsFailure(verb: string, err: unknown): Error & { code: MapsFailureCode } {\n const nativeCode = String((err as any)?.code ?? '');\n const detail = String((err as any)?.message ?? err ?? '').trim();\n let code: MapsFailureCode;\n let why: string;\n if (nativeCode === 'THROTTLED') {\n code = 'THROTTLED';\n why = 'Apple is rate-limiting map requests from this app — wait before retrying';\n } else if (nativeCode === 'OFFLINE') {\n code = 'OFFLINE';\n why = 'the map service could not be reached — the phone may be offline';\n } else if (nativeCode === 'ERR_GEOCODING_NETWORK') {\n code = 'OFFLINE';\n why = 'the geocoder could not be reached — the phone may be offline, or Apple is ' +\n 'rate-limiting requests (iOS reports both the same way)';\n } else {\n code = 'UNAVAILABLE';\n why = 'the map service failed';\n }\n const failure = new Error(\n `maps.${verb} could not look: ${why}. This is not \"found nothing\".` +\n (detail ? ` (${nativeCode ? nativeCode + ': ' : ''}${detail})` : ''),\n ) as Error & { code: MapsFailureCode };\n failure.code = code;\n return failure;\n}\n"],"mappings":"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","names":["ExpoLocation","import_react_native","AsyncStorage"]}
|
package/dist/createBridge.mjs
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import {
|
|
2
|
+
reverseGeocode
|
|
3
|
+
} from "./chunk-7FWYEHN5.mjs";
|
|
4
|
+
import "./chunk-J6XRNX7P.mjs";
|
|
1
5
|
import "./chunk-WMJKH4XE.mjs";
|
|
2
6
|
|
|
3
7
|
// src/createBridge.ts
|
|
@@ -302,7 +306,7 @@ function createBridge(connectorId, deviceId) {
|
|
|
302
306
|
const location = await ExpoLocation.getCurrentPositionAsync({
|
|
303
307
|
accuracy: ExpoLocation.Accuracy.Balanced
|
|
304
308
|
});
|
|
305
|
-
const
|
|
309
|
+
const geo = await reverseGeocode({
|
|
306
310
|
latitude: location.coords.latitude,
|
|
307
311
|
longitude: location.coords.longitude
|
|
308
312
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/createBridge.ts"],"sourcesContent":["/**\n * Native Bridge Factory\n *\n * Creates a Bridge instance that wraps Expo native modules.\n * Each bridge is scoped to a specific connector ID for storage isolation.\n */\n\nimport AsyncStorage from '@react-native-async-storage/async-storage';\nimport * as ExpoCalendar from 'expo-calendar';\nimport * as ExpoContacts from 'expo-contacts';\nimport * as ExpoLocation from 'expo-location';\nimport * as ExpoBattery from 'expo-battery';\nimport * as ExpoNetwork from 'expo-network';\nimport * as ExpoNotifications from 'expo-notifications';\nimport * as ExpoSMS from 'expo-sms';\nimport * as ExpoLinking from 'expo-linking';\nimport { Platform } from 'react-native';\nimport * as Device from 'expo-device';\n\nimport type { Bridge } from '@ateam-ai-mobile/plugin-runtime';\n\nexport function createBridge(connectorId: string, deviceId: string): Bridge {\n const storagePrefix = `connector:${connectorId}:`;\n\n const log = {\n info: (msg: string, data?: any) => {\n console.log(`[${connectorId}] ${msg}`, data || '');\n },\n warn: (msg: string, data?: any) => {\n console.warn(`[${connectorId}] ${msg}`, data || '');\n },\n error: (msg: string, data?: any) => {\n console.error(`[${connectorId}] ${msg}`, data || '');\n },\n };\n\n // ─────────────────────────────────────────────────────────────────────\n // Helper functions\n // ─────────────────────────────────────────────────────────────────────\n\n const parseDateTime = (dateStr: string, timeStr: string): Date => {\n const [year, month, day] = dateStr.split('-').map(Number);\n const [hours, minutes] = timeStr.split(':').map(Number);\n return new Date(year, month - 1, day, hours, minutes);\n };\n\n const formatDate = (date: Date): string => {\n return date.toISOString().split('T')[0];\n };\n\n const getDayOfWeek = (date: Date): string => {\n const days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];\n return days[date.getDay()];\n };\n\n const addDays = (date: Date, days: number): Date => {\n const result = new Date(date);\n result.setDate(result.getDate() + days);\n return result;\n };\n\n const startOfDay = (date: Date): Date => {\n const result = new Date(date);\n result.setHours(0, 0, 0, 0);\n return result;\n };\n\n const endOfDay = (date: Date): Date => {\n const result = new Date(date);\n result.setHours(23, 59, 59, 999);\n return result;\n };\n\n const getCalendarIds = async (): Promise<string[]> => {\n try {\n const calendars = await ExpoCalendar.getCalendarsAsync(ExpoCalendar.EntityTypes.EVENT);\n return calendars.map(c => c.id);\n } catch (err) {\n log.warn('Failed to get calendar IDs', err);\n return [];\n }\n };\n\n const getDefaultCalendarId = async (): Promise<string> => {\n try {\n const calendars = await ExpoCalendar.getCalendarsAsync(ExpoCalendar.EntityTypes.EVENT);\n return calendars.length > 0 ? calendars[0].id : '';\n } catch (err) {\n log.warn('Failed to get default calendar', err);\n return '';\n }\n };\n\n const formatCalendarEvent = (event: any): any => {\n return {\n id: event.id,\n title: event.title,\n date: event.startDate ? formatDate(new Date(event.startDate)) : '',\n start: event.startDate ? new Date(event.startDate).toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' }) : '',\n end: event.endDate ? new Date(event.endDate).toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' }) : '',\n location: event.location || '',\n attendees: event.attendees ? event.attendees.map((a: any) => a.email || a.name) : [],\n notes: event.notes || '',\n };\n };\n\n const formatContact = (contact: any): any => {\n const phone = contact.phoneNumbers?.[0]?.number || null;\n const email = contact.emails?.[0]?.email || null;\n const birthday = contact.birthday\n ? `${contact.birthday.year}-${String(contact.birthday.month).padStart(2, '0')}-${String(contact.birthday.day).padStart(2, '0')}`\n : null;\n\n return {\n id: contact.id,\n name: contact.name,\n phone,\n email,\n relationship: contact.relationships?.[0]?.relationship || contact.contactType || 'contact',\n birthday,\n notes: contact.note || '',\n };\n };\n\n const classifyLocation = (geo: any): string => {\n const name = geo.name?.toLowerCase() || '';\n if (name.includes('home')) return 'home';\n if (name.includes('work') || name.includes('office')) return 'work';\n if (name.includes('school') || name.includes('university')) return 'school';\n if (name.includes('gym') || name.includes('fitness')) return 'fitness';\n if (name.includes('hospital') || name.includes('clinic') || name.includes('medical')) return 'medical';\n return 'other';\n };\n\n const formatPlace = (geo: any): string => {\n if (!geo) return 'Unknown Location';\n const name = geo.name || '';\n const street = geo.street ? `${geo.street}` : '';\n return name ? `${name} — ${street}` : street;\n };\n\n const formatAddress = (geo: any): string => {\n if (!geo) return '';\n const parts = [geo.street, geo.city, geo.region, geo.postalCode].filter(Boolean);\n return parts.join(', ');\n };\n\n const formatNotification = (notif: any): any => {\n return {\n id: notif.request?.identifier || String(Math.random()),\n app: notif.request?.content?.title || 'Unknown',\n title: notif.request?.content?.title || '',\n body: notif.request?.content?.body || '',\n timestamp: new Date().toISOString(),\n sender: null,\n priority: 'medium',\n read: false,\n };\n };\n\n const mapBatteryState = (state: number): 'charging' | 'full' | 'unplugged' => {\n if (state === ExpoBattery.BatteryState.CHARGING) return 'charging';\n if (state === ExpoBattery.BatteryState.FULL) return 'full';\n return 'unplugged';\n };\n\n // ─────────────────────────────────────────────────────────────────────\n // BRIDGE IMPLEMENTATION\n // ─────────────────────────────────────────────────────────────────────\n\n const bridge: Bridge = {\n calendar: {\n async getToday() {\n try {\n const start = startOfDay(new Date());\n const end = endOfDay(new Date());\n const calendarIds = await getCalendarIds();\n const events = await ExpoCalendar.getEventsAsync(calendarIds, start, end);\n return {\n date: formatDate(new Date()),\n day_of_week: getDayOfWeek(new Date()),\n events: events.map(formatCalendarEvent),\n count: events.length,\n };\n } catch (err) {\n log.error('Failed to get today\\'s calendar events', err);\n return { date: formatDate(new Date()), day_of_week: getDayOfWeek(new Date()), events: [], count: 0 };\n }\n },\n\n async getUpcoming(days = 7) {\n try {\n const start = new Date();\n const end = addDays(start, Math.min(days, 14));\n const calendarIds = await getCalendarIds();\n const events = await ExpoCalendar.getEventsAsync(calendarIds, start, end);\n return {\n from: formatDate(start),\n days_ahead: days,\n events: events.map(formatCalendarEvent),\n count: events.length,\n };\n } catch (err) {\n log.error('Failed to get upcoming calendar events', err);\n return { from: formatDate(new Date()), days_ahead: days, events: [], count: 0 };\n }\n },\n\n async create(event) {\n try {\n const calendarId = await getDefaultCalendarId();\n if (!calendarId) throw new Error('No default calendar found');\n\n const eventId = await ExpoCalendar.createEventAsync(calendarId, {\n title: event.title,\n startDate: parseDateTime(event.date, event.start_time),\n endDate: parseDateTime(event.date, event.end_time || event.start_time),\n location: event.location,\n notes: event.notes,\n });\n\n return { event_id: eventId };\n } catch (err) {\n log.error('Failed to create calendar event', err);\n throw err;\n }\n },\n\n async reschedule(params) {\n try {\n const updates: any = {};\n if (params.new_date && params.new_start_time) {\n updates.startDate = parseDateTime(params.new_date, params.new_start_time);\n }\n if (params.new_date && params.new_end_time) {\n updates.endDate = parseDateTime(params.new_date, params.new_end_time);\n }\n await ExpoCalendar.updateEventAsync(params.event_id, updates);\n return { ok: true };\n } catch (err) {\n log.error('Failed to reschedule event', err);\n throw err;\n }\n },\n\n async cancel(event_id) {\n try {\n await ExpoCalendar.deleteEventAsync(event_id);\n return { ok: true };\n } catch (err) {\n log.error('Failed to cancel event', err);\n throw err;\n }\n },\n },\n\n contacts: {\n async search(query) {\n try {\n const { data } = await ExpoContacts.getContactsAsync({\n fields: [\n ExpoContacts.Fields.PhoneNumbers,\n ExpoContacts.Fields.Emails,\n ExpoContacts.Fields.Birthday,\n ExpoContacts.Fields.Note,\n ExpoContacts.Fields.Relationships,\n ],\n });\n\n const q = query.toLowerCase();\n const filtered = data.filter(\n c => c.name?.toLowerCase().includes(q) || c.note?.toLowerCase().includes(q)\n );\n\n return { contacts: filtered.map(formatContact), count: filtered.length };\n } catch (err) {\n log.error('Failed to search contacts', err);\n return { contacts: [], count: 0 };\n }\n },\n\n async get(idOrName) {\n try {\n const { data } = await ExpoContacts.getContactsAsync({\n fields: [\n ExpoContacts.Fields.PhoneNumbers,\n ExpoContacts.Fields.Emails,\n ExpoContacts.Fields.Birthday,\n ExpoContacts.Fields.Note,\n ],\n });\n\n const contact = data.find(c => c.id === idOrName || c.name === idOrName);\n return contact ? formatContact(contact) : null;\n } catch (err) {\n log.error('Failed to get contact', err);\n return null;\n }\n },\n\n async getAll() {\n try {\n const { data } = await ExpoContacts.getContactsAsync({\n fields: [\n ExpoContacts.Fields.PhoneNumbers,\n ExpoContacts.Fields.Emails,\n ExpoContacts.Fields.Birthday,\n ExpoContacts.Fields.Note,\n ExpoContacts.Fields.Relationships,\n ],\n sort: ExpoContacts.SortTypes.LastName,\n });\n\n return { contacts: data.map(formatContact), count: data.length };\n } catch (err) {\n log.error('Failed to get all contacts', err);\n return { contacts: [], count: 0 };\n }\n },\n\n async birthdays(days = 30) {\n try {\n const { data } = await ExpoContacts.getContactsAsync({\n fields: [ExpoContacts.Fields.Birthday],\n });\n\n const today = new Date();\n const futureDate = addDays(today, days);\n\n const birthdays = data\n .filter(c => c.birthday)\n .map(c => {\n const birthday = c.birthday!;\n const thisYearBday = new Date(today.getFullYear(), birthday.month - 1, birthday.day);\n if (thisYearBday < today) {\n thisYearBday.setFullYear(today.getFullYear() + 1);\n }\n\n return {\n name: c.name,\n relationship: c.relationships?.[0]?.relationship || 'contact',\n birthday: `${birthday.year || '????'}-${String(birthday.month).padStart(2, '0')}-${String(birthday.day).padStart(2, '0')}`,\n days_until: Math.floor((thisYearBday.getTime() - today.getTime()) / (1000 * 60 * 60 * 24)),\n is_today: thisYearBday.toDateString() === today.toDateString(),\n };\n })\n .filter(b => b.days_until >= 0 && b.days_until <= days);\n\n return { birthdays, count: birthdays.length };\n } catch (err) {\n log.error('Failed to get birthdays', err);\n return { birthdays: [], count: 0 };\n }\n },\n },\n\n location: {\n async getCurrent() {\n try {\n const location = await ExpoLocation.getCurrentPositionAsync({\n accuracy: ExpoLocation.Accuracy.Balanced,\n });\n\n const [geo] = await ExpoLocation.reverseGeocodeAsync({\n latitude: location.coords.latitude,\n longitude: location.coords.longitude,\n });\n\n return {\n lat: location.coords.latitude,\n lng: location.coords.longitude,\n place: formatPlace(geo),\n address: formatAddress(geo),\n type: classifyLocation(geo),\n timestamp: new Date().toISOString(),\n };\n } catch (err) {\n log.error('Failed to get current location', err);\n throw err;\n }\n },\n },\n\n battery: {\n async getStatus() {\n try {\n const [level, state, lowPower] = await Promise.all([\n ExpoBattery.getBatteryLevelAsync(),\n ExpoBattery.getBatteryStateAsync(),\n ExpoBattery.isLowPowerModeEnabledAsync(),\n ]);\n\n return {\n ok: true as const,\n timestamp: new Date().toISOString(),\n battery: {\n level: Math.round(level * 100),\n state: mapBatteryState(state),\n low_power_mode: lowPower,\n },\n };\n } catch (err) {\n log.error('Failed to get battery status', err);\n throw err;\n }\n },\n },\n\n network: {\n async getStatus() {\n try {\n const state = await ExpoNetwork.getNetworkStateAsync();\n return {\n type: state.type === ExpoNetwork.NetworkStateType.WIFI\n ? 'wifi'\n : state.type === ExpoNetwork.NetworkStateType.CELLULAR\n ? 'cellular'\n : 'none',\n is_connected: state.isConnected ?? false,\n timestamp: new Date().toISOString(),\n };\n } catch (err) {\n log.error('Failed to get network status', err);\n throw err;\n }\n },\n },\n\n notifications: {\n async list() {\n try {\n const presented = await ExpoNotifications.getPresentedNotificationsAsync();\n const notifications = presented.map(formatNotification);\n return {\n notifications,\n total: notifications.length,\n unread: notifications.filter(n => !n.read).length,\n };\n } catch (err) {\n log.error('Failed to get notifications', err);\n return { notifications: [], total: 0, unread: 0 };\n }\n },\n },\n\n sms: {\n async isAvailable() {\n try {\n return await ExpoSMS.isAvailableAsync();\n } catch (err) {\n log.error('Failed to check SMS availability', err);\n return false;\n }\n },\n\n async send(phone, message) {\n try {\n const { result } = await ExpoSMS.sendSMSAsync([phone], message);\n return {\n ok: result === 'sent' || result === 'unknown',\n status: result as 'sent' | 'unknown' | 'cancelled',\n };\n } catch (err) {\n log.error('Failed to send SMS', err);\n throw err;\n }\n },\n },\n\n maps: {\n async navigate(destination, mode = 'driving') {\n try {\n const encoded = encodeURIComponent(destination);\n const url = Platform.OS === 'ios'\n ? `maps://maps.apple.com/?daddr=${encoded}&dirflg=${mode[0]}`\n : `google.navigation:q=${encoded}&mode=${mode}`;\n\n const canOpen = await ExpoLinking.canOpenURL(url);\n if (!canOpen) {\n // Fallback to web\n const fallbackUrl = `https://www.google.com/maps/search/${encoded}`;\n await ExpoLinking.openURL(fallbackUrl);\n } else {\n await ExpoLinking.openURL(url);\n }\n\n return { ok: true, status: 'navigating' };\n } catch (err) {\n log.error('Failed to navigate', err);\n return { ok: false, status: 'error' };\n }\n },\n },\n\n http: {\n async get(url, headers = {}) {\n try {\n const res = await fetch(url, { headers });\n const data = await res.json();\n return {\n ok: res.ok,\n status: res.status,\n data,\n headers: Object.fromEntries(res.headers.entries()),\n };\n } catch (err) {\n log.error('HTTP GET failed', err);\n throw err;\n }\n },\n\n async post(url, body, headers = {}) {\n try {\n const res = await fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...headers },\n body: JSON.stringify(body),\n });\n const data = await res.json();\n return {\n ok: res.ok,\n status: res.status,\n data,\n headers: Object.fromEntries(res.headers.entries()),\n };\n } catch (err) {\n log.error('HTTP POST failed', err);\n throw err;\n }\n },\n\n async put(url, body, headers = {}) {\n try {\n const res = await fetch(url, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json', ...headers },\n body: JSON.stringify(body),\n });\n const data = await res.json();\n return {\n ok: res.ok,\n status: res.status,\n data,\n headers: Object.fromEntries(res.headers.entries()),\n };\n } catch (err) {\n log.error('HTTP PUT failed', err);\n throw err;\n }\n },\n\n async delete(url, body, headers = {}) {\n try {\n const opts: any = {\n method: 'DELETE',\n headers: { 'Content-Type': 'application/json', ...headers },\n };\n if (body) opts.body = JSON.stringify(body);\n\n const res = await fetch(url, opts);\n const data = await res.json();\n return {\n ok: res.ok,\n status: res.status,\n data,\n headers: Object.fromEntries(res.headers.entries()),\n };\n } catch (err) {\n log.error('HTTP DELETE failed', err);\n throw err;\n }\n },\n },\n\n storage: {\n async get(key) {\n try {\n return await AsyncStorage.getItem(storagePrefix + key);\n } catch (err) {\n log.error(`Failed to get storage key: ${key}`, err);\n return null;\n }\n },\n\n async set(key, value) {\n try {\n await AsyncStorage.setItem(storagePrefix + key, value);\n } catch (err) {\n log.error(`Failed to set storage key: ${key}`, err);\n }\n },\n\n async delete(key) {\n try {\n await AsyncStorage.removeItem(storagePrefix + key);\n } catch (err) {\n log.error(`Failed to delete storage key: ${key}`, err);\n }\n },\n\n async keys() {\n try {\n const allKeys = await AsyncStorage.getAllKeys();\n return allKeys\n .filter(k => k.startsWith(storagePrefix))\n .map(k => k.slice(storagePrefix.length));\n } catch (err) {\n log.error('Failed to list storage keys', err);\n return [];\n }\n },\n },\n\n permissions: {\n async check(capability) {\n try {\n // Map capability to Expo permission API\n switch (capability) {\n case 'calendar':\n const cal = await ExpoCalendar.getCalendarPermissionsAsync();\n return cal.status === 'granted' ? 'granted' : cal.status === 'denied' ? 'denied' : 'not_requested';\n case 'contacts':\n const con = await ExpoContacts.getPermissionsAsync();\n return con.status === 'granted' ? 'granted' : con.status === 'denied' ? 'denied' : 'not_requested';\n case 'location':\n const loc = await ExpoLocation.getForegroundPermissionsAsync();\n return loc.status === 'granted' ? 'granted' : loc.status === 'denied' ? 'denied' : 'not_requested';\n case 'notifications':\n const notif = await ExpoNotifications.getPermissionsAsync();\n return notif.granted ? 'granted' : notif.canAskAgain ? 'not_requested' : 'denied';\n default:\n return 'not_requested';\n }\n } catch (err) {\n log.error(`Failed to check permission: ${capability}`, err);\n return 'denied';\n }\n },\n\n async request(capability) {\n try {\n switch (capability) {\n case 'calendar':\n const cal = await ExpoCalendar.requestCalendarPermissionsAsync();\n return cal.status === 'granted';\n case 'contacts':\n const con = await ExpoContacts.requestPermissionsAsync();\n return con.status === 'granted';\n case 'location':\n const loc = await ExpoLocation.requestForegroundPermissionsAsync();\n return loc.status === 'granted';\n case 'notifications':\n const notif = await ExpoNotifications.requestPermissionsAsync();\n return notif.granted;\n default:\n return false;\n }\n } catch (err) {\n log.error(`Failed to request permission: ${capability}`, err);\n return false;\n }\n },\n\n async getAll() {\n try {\n const [cal, con, loc, notif] = await Promise.allSettled([\n ExpoCalendar.getCalendarPermissionsAsync(),\n ExpoContacts.getPermissionsAsync(),\n ExpoLocation.getForegroundPermissionsAsync(),\n ExpoNotifications.getPermissionsAsync(),\n ]);\n\n return {\n calendar: cal.status === 'fulfilled' ? (cal.value.status === 'granted' ? 'granted' : cal.value.status === 'denied' ? 'denied' : 'not_requested') : 'denied',\n contacts: con.status === 'fulfilled' ? (con.value.status === 'granted' ? 'granted' : con.value.status === 'denied' ? 'denied' : 'not_requested') : 'denied',\n location: loc.status === 'fulfilled' ? (loc.value.status === 'granted' ? 'granted' : loc.value.status === 'denied' ? 'denied' : 'not_requested') : 'denied',\n notifications: notif.status === 'fulfilled' ? (notif.value.granted ? 'granted' : notif.value.canAskAgain ? 'not_requested' : 'denied') : 'denied',\n };\n } catch (err) {\n log.error('Failed to get all permissions', err);\n return { calendar: 'denied', contacts: 'denied', location: 'denied', notifications: 'denied' };\n }\n },\n },\n\n device: {\n getDeviceId() {\n return deviceId;\n },\n\n getPlatform() {\n return {\n os: Platform.OS as 'ios' | 'android',\n version: Platform.Version ? String(Platform.Version) : 'unknown',\n };\n },\n },\n\n log,\n };\n\n return bridge;\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/createBridge.ts"],"sourcesContent":["/**\n * Native Bridge Factory\n *\n * Creates a Bridge instance that wraps Expo native modules.\n * Each bridge is scoped to a specific connector ID for storage isolation.\n */\n\nimport AsyncStorage from '@react-native-async-storage/async-storage';\nimport * as ExpoCalendar from 'expo-calendar';\nimport * as ExpoContacts from 'expo-contacts';\nimport * as ExpoLocation from 'expo-location';\nimport * as ExpoBattery from 'expo-battery';\nimport * as ExpoNetwork from 'expo-network';\nimport * as ExpoNotifications from 'expo-notifications';\nimport * as ExpoSMS from 'expo-sms';\nimport * as ExpoLinking from 'expo-linking';\nimport { Platform } from 'react-native';\nimport * as Device from 'expo-device';\n// The SDK's one reverse geocode — the same call native.maps.reverseGeocode makes.\nimport { reverseGeocode } from './maps';\n\nimport type { Bridge } from '@ateam-ai-mobile/plugin-runtime';\n\nexport function createBridge(connectorId: string, deviceId: string): Bridge {\n const storagePrefix = `connector:${connectorId}:`;\n\n const log = {\n info: (msg: string, data?: any) => {\n console.log(`[${connectorId}] ${msg}`, data || '');\n },\n warn: (msg: string, data?: any) => {\n console.warn(`[${connectorId}] ${msg}`, data || '');\n },\n error: (msg: string, data?: any) => {\n console.error(`[${connectorId}] ${msg}`, data || '');\n },\n };\n\n // ─────────────────────────────────────────────────────────────────────\n // Helper functions\n // ─────────────────────────────────────────────────────────────────────\n\n const parseDateTime = (dateStr: string, timeStr: string): Date => {\n const [year, month, day] = dateStr.split('-').map(Number);\n const [hours, minutes] = timeStr.split(':').map(Number);\n return new Date(year, month - 1, day, hours, minutes);\n };\n\n const formatDate = (date: Date): string => {\n return date.toISOString().split('T')[0];\n };\n\n const getDayOfWeek = (date: Date): string => {\n const days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];\n return days[date.getDay()];\n };\n\n const addDays = (date: Date, days: number): Date => {\n const result = new Date(date);\n result.setDate(result.getDate() + days);\n return result;\n };\n\n const startOfDay = (date: Date): Date => {\n const result = new Date(date);\n result.setHours(0, 0, 0, 0);\n return result;\n };\n\n const endOfDay = (date: Date): Date => {\n const result = new Date(date);\n result.setHours(23, 59, 59, 999);\n return result;\n };\n\n const getCalendarIds = async (): Promise<string[]> => {\n try {\n const calendars = await ExpoCalendar.getCalendarsAsync(ExpoCalendar.EntityTypes.EVENT);\n return calendars.map(c => c.id);\n } catch (err) {\n log.warn('Failed to get calendar IDs', err);\n return [];\n }\n };\n\n const getDefaultCalendarId = async (): Promise<string> => {\n try {\n const calendars = await ExpoCalendar.getCalendarsAsync(ExpoCalendar.EntityTypes.EVENT);\n return calendars.length > 0 ? calendars[0].id : '';\n } catch (err) {\n log.warn('Failed to get default calendar', err);\n return '';\n }\n };\n\n const formatCalendarEvent = (event: any): any => {\n return {\n id: event.id,\n title: event.title,\n date: event.startDate ? formatDate(new Date(event.startDate)) : '',\n start: event.startDate ? new Date(event.startDate).toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' }) : '',\n end: event.endDate ? new Date(event.endDate).toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' }) : '',\n location: event.location || '',\n attendees: event.attendees ? event.attendees.map((a: any) => a.email || a.name) : [],\n notes: event.notes || '',\n };\n };\n\n const formatContact = (contact: any): any => {\n const phone = contact.phoneNumbers?.[0]?.number || null;\n const email = contact.emails?.[0]?.email || null;\n const birthday = contact.birthday\n ? `${contact.birthday.year}-${String(contact.birthday.month).padStart(2, '0')}-${String(contact.birthday.day).padStart(2, '0')}`\n : null;\n\n return {\n id: contact.id,\n name: contact.name,\n phone,\n email,\n relationship: contact.relationships?.[0]?.relationship || contact.contactType || 'contact',\n birthday,\n notes: contact.note || '',\n };\n };\n\n const classifyLocation = (geo: any): string => {\n const name = geo.name?.toLowerCase() || '';\n if (name.includes('home')) return 'home';\n if (name.includes('work') || name.includes('office')) return 'work';\n if (name.includes('school') || name.includes('university')) return 'school';\n if (name.includes('gym') || name.includes('fitness')) return 'fitness';\n if (name.includes('hospital') || name.includes('clinic') || name.includes('medical')) return 'medical';\n return 'other';\n };\n\n const formatPlace = (geo: any): string => {\n if (!geo) return 'Unknown Location';\n const name = geo.name || '';\n const street = geo.street ? `${geo.street}` : '';\n return name ? `${name} — ${street}` : street;\n };\n\n const formatAddress = (geo: any): string => {\n if (!geo) return '';\n const parts = [geo.street, geo.city, geo.region, geo.postalCode].filter(Boolean);\n return parts.join(', ');\n };\n\n const formatNotification = (notif: any): any => {\n return {\n id: notif.request?.identifier || String(Math.random()),\n app: notif.request?.content?.title || 'Unknown',\n title: notif.request?.content?.title || '',\n body: notif.request?.content?.body || '',\n timestamp: new Date().toISOString(),\n sender: null,\n priority: 'medium',\n read: false,\n };\n };\n\n const mapBatteryState = (state: number): 'charging' | 'full' | 'unplugged' => {\n if (state === ExpoBattery.BatteryState.CHARGING) return 'charging';\n if (state === ExpoBattery.BatteryState.FULL) return 'full';\n return 'unplugged';\n };\n\n // ─────────────────────────────────────────────────────────────────────\n // BRIDGE IMPLEMENTATION\n // ─────────────────────────────────────────────────────────────────────\n\n const bridge: Bridge = {\n calendar: {\n async getToday() {\n try {\n const start = startOfDay(new Date());\n const end = endOfDay(new Date());\n const calendarIds = await getCalendarIds();\n const events = await ExpoCalendar.getEventsAsync(calendarIds, start, end);\n return {\n date: formatDate(new Date()),\n day_of_week: getDayOfWeek(new Date()),\n events: events.map(formatCalendarEvent),\n count: events.length,\n };\n } catch (err) {\n log.error('Failed to get today\\'s calendar events', err);\n return { date: formatDate(new Date()), day_of_week: getDayOfWeek(new Date()), events: [], count: 0 };\n }\n },\n\n async getUpcoming(days = 7) {\n try {\n const start = new Date();\n const end = addDays(start, Math.min(days, 14));\n const calendarIds = await getCalendarIds();\n const events = await ExpoCalendar.getEventsAsync(calendarIds, start, end);\n return {\n from: formatDate(start),\n days_ahead: days,\n events: events.map(formatCalendarEvent),\n count: events.length,\n };\n } catch (err) {\n log.error('Failed to get upcoming calendar events', err);\n return { from: formatDate(new Date()), days_ahead: days, events: [], count: 0 };\n }\n },\n\n async create(event) {\n try {\n const calendarId = await getDefaultCalendarId();\n if (!calendarId) throw new Error('No default calendar found');\n\n const eventId = await ExpoCalendar.createEventAsync(calendarId, {\n title: event.title,\n startDate: parseDateTime(event.date, event.start_time),\n endDate: parseDateTime(event.date, event.end_time || event.start_time),\n location: event.location,\n notes: event.notes,\n });\n\n return { event_id: eventId };\n } catch (err) {\n log.error('Failed to create calendar event', err);\n throw err;\n }\n },\n\n async reschedule(params) {\n try {\n const updates: any = {};\n if (params.new_date && params.new_start_time) {\n updates.startDate = parseDateTime(params.new_date, params.new_start_time);\n }\n if (params.new_date && params.new_end_time) {\n updates.endDate = parseDateTime(params.new_date, params.new_end_time);\n }\n await ExpoCalendar.updateEventAsync(params.event_id, updates);\n return { ok: true };\n } catch (err) {\n log.error('Failed to reschedule event', err);\n throw err;\n }\n },\n\n async cancel(event_id) {\n try {\n await ExpoCalendar.deleteEventAsync(event_id);\n return { ok: true };\n } catch (err) {\n log.error('Failed to cancel event', err);\n throw err;\n }\n },\n },\n\n contacts: {\n async search(query) {\n try {\n const { data } = await ExpoContacts.getContactsAsync({\n fields: [\n ExpoContacts.Fields.PhoneNumbers,\n ExpoContacts.Fields.Emails,\n ExpoContacts.Fields.Birthday,\n ExpoContacts.Fields.Note,\n ExpoContacts.Fields.Relationships,\n ],\n });\n\n const q = query.toLowerCase();\n const filtered = data.filter(\n c => c.name?.toLowerCase().includes(q) || c.note?.toLowerCase().includes(q)\n );\n\n return { contacts: filtered.map(formatContact), count: filtered.length };\n } catch (err) {\n log.error('Failed to search contacts', err);\n return { contacts: [], count: 0 };\n }\n },\n\n async get(idOrName) {\n try {\n const { data } = await ExpoContacts.getContactsAsync({\n fields: [\n ExpoContacts.Fields.PhoneNumbers,\n ExpoContacts.Fields.Emails,\n ExpoContacts.Fields.Birthday,\n ExpoContacts.Fields.Note,\n ],\n });\n\n const contact = data.find(c => c.id === idOrName || c.name === idOrName);\n return contact ? formatContact(contact) : null;\n } catch (err) {\n log.error('Failed to get contact', err);\n return null;\n }\n },\n\n async getAll() {\n try {\n const { data } = await ExpoContacts.getContactsAsync({\n fields: [\n ExpoContacts.Fields.PhoneNumbers,\n ExpoContacts.Fields.Emails,\n ExpoContacts.Fields.Birthday,\n ExpoContacts.Fields.Note,\n ExpoContacts.Fields.Relationships,\n ],\n sort: ExpoContacts.SortTypes.LastName,\n });\n\n return { contacts: data.map(formatContact), count: data.length };\n } catch (err) {\n log.error('Failed to get all contacts', err);\n return { contacts: [], count: 0 };\n }\n },\n\n async birthdays(days = 30) {\n try {\n const { data } = await ExpoContacts.getContactsAsync({\n fields: [ExpoContacts.Fields.Birthday],\n });\n\n const today = new Date();\n const futureDate = addDays(today, days);\n\n const birthdays = data\n .filter(c => c.birthday)\n .map(c => {\n const birthday = c.birthday!;\n const thisYearBday = new Date(today.getFullYear(), birthday.month - 1, birthday.day);\n if (thisYearBday < today) {\n thisYearBday.setFullYear(today.getFullYear() + 1);\n }\n\n return {\n name: c.name,\n relationship: c.relationships?.[0]?.relationship || 'contact',\n birthday: `${birthday.year || '????'}-${String(birthday.month).padStart(2, '0')}-${String(birthday.day).padStart(2, '0')}`,\n days_until: Math.floor((thisYearBday.getTime() - today.getTime()) / (1000 * 60 * 60 * 24)),\n is_today: thisYearBday.toDateString() === today.toDateString(),\n };\n })\n .filter(b => b.days_until >= 0 && b.days_until <= days);\n\n return { birthdays, count: birthdays.length };\n } catch (err) {\n log.error('Failed to get birthdays', err);\n return { birthdays: [], count: 0 };\n }\n },\n },\n\n location: {\n async getCurrent() {\n try {\n const location = await ExpoLocation.getCurrentPositionAsync({\n accuracy: ExpoLocation.Accuracy.Balanced,\n });\n\n const geo = await reverseGeocode({\n latitude: location.coords.latitude,\n longitude: location.coords.longitude,\n });\n\n return {\n lat: location.coords.latitude,\n lng: location.coords.longitude,\n place: formatPlace(geo),\n address: formatAddress(geo),\n type: classifyLocation(geo),\n timestamp: new Date().toISOString(),\n };\n } catch (err) {\n log.error('Failed to get current location', err);\n throw err;\n }\n },\n },\n\n battery: {\n async getStatus() {\n try {\n const [level, state, lowPower] = await Promise.all([\n ExpoBattery.getBatteryLevelAsync(),\n ExpoBattery.getBatteryStateAsync(),\n ExpoBattery.isLowPowerModeEnabledAsync(),\n ]);\n\n return {\n ok: true as const,\n timestamp: new Date().toISOString(),\n battery: {\n level: Math.round(level * 100),\n state: mapBatteryState(state),\n low_power_mode: lowPower,\n },\n };\n } catch (err) {\n log.error('Failed to get battery status', err);\n throw err;\n }\n },\n },\n\n network: {\n async getStatus() {\n try {\n const state = await ExpoNetwork.getNetworkStateAsync();\n return {\n type: state.type === ExpoNetwork.NetworkStateType.WIFI\n ? 'wifi'\n : state.type === ExpoNetwork.NetworkStateType.CELLULAR\n ? 'cellular'\n : 'none',\n is_connected: state.isConnected ?? false,\n timestamp: new Date().toISOString(),\n };\n } catch (err) {\n log.error('Failed to get network status', err);\n throw err;\n }\n },\n },\n\n notifications: {\n async list() {\n try {\n const presented = await ExpoNotifications.getPresentedNotificationsAsync();\n const notifications = presented.map(formatNotification);\n return {\n notifications,\n total: notifications.length,\n unread: notifications.filter(n => !n.read).length,\n };\n } catch (err) {\n log.error('Failed to get notifications', err);\n return { notifications: [], total: 0, unread: 0 };\n }\n },\n },\n\n sms: {\n async isAvailable() {\n try {\n return await ExpoSMS.isAvailableAsync();\n } catch (err) {\n log.error('Failed to check SMS availability', err);\n return false;\n }\n },\n\n async send(phone, message) {\n try {\n const { result } = await ExpoSMS.sendSMSAsync([phone], message);\n return {\n ok: result === 'sent' || result === 'unknown',\n status: result as 'sent' | 'unknown' | 'cancelled',\n };\n } catch (err) {\n log.error('Failed to send SMS', err);\n throw err;\n }\n },\n },\n\n maps: {\n async navigate(destination, mode = 'driving') {\n try {\n const encoded = encodeURIComponent(destination);\n const url = Platform.OS === 'ios'\n ? `maps://maps.apple.com/?daddr=${encoded}&dirflg=${mode[0]}`\n : `google.navigation:q=${encoded}&mode=${mode}`;\n\n const canOpen = await ExpoLinking.canOpenURL(url);\n if (!canOpen) {\n // Fallback to web\n const fallbackUrl = `https://www.google.com/maps/search/${encoded}`;\n await ExpoLinking.openURL(fallbackUrl);\n } else {\n await ExpoLinking.openURL(url);\n }\n\n return { ok: true, status: 'navigating' };\n } catch (err) {\n log.error('Failed to navigate', err);\n return { ok: false, status: 'error' };\n }\n },\n },\n\n http: {\n async get(url, headers = {}) {\n try {\n const res = await fetch(url, { headers });\n const data = await res.json();\n return {\n ok: res.ok,\n status: res.status,\n data,\n headers: Object.fromEntries(res.headers.entries()),\n };\n } catch (err) {\n log.error('HTTP GET failed', err);\n throw err;\n }\n },\n\n async post(url, body, headers = {}) {\n try {\n const res = await fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...headers },\n body: JSON.stringify(body),\n });\n const data = await res.json();\n return {\n ok: res.ok,\n status: res.status,\n data,\n headers: Object.fromEntries(res.headers.entries()),\n };\n } catch (err) {\n log.error('HTTP POST failed', err);\n throw err;\n }\n },\n\n async put(url, body, headers = {}) {\n try {\n const res = await fetch(url, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json', ...headers },\n body: JSON.stringify(body),\n });\n const data = await res.json();\n return {\n ok: res.ok,\n status: res.status,\n data,\n headers: Object.fromEntries(res.headers.entries()),\n };\n } catch (err) {\n log.error('HTTP PUT failed', err);\n throw err;\n }\n },\n\n async delete(url, body, headers = {}) {\n try {\n const opts: any = {\n method: 'DELETE',\n headers: { 'Content-Type': 'application/json', ...headers },\n };\n if (body) opts.body = JSON.stringify(body);\n\n const res = await fetch(url, opts);\n const data = await res.json();\n return {\n ok: res.ok,\n status: res.status,\n data,\n headers: Object.fromEntries(res.headers.entries()),\n };\n } catch (err) {\n log.error('HTTP DELETE failed', err);\n throw err;\n }\n },\n },\n\n storage: {\n async get(key) {\n try {\n return await AsyncStorage.getItem(storagePrefix + key);\n } catch (err) {\n log.error(`Failed to get storage key: ${key}`, err);\n return null;\n }\n },\n\n async set(key, value) {\n try {\n await AsyncStorage.setItem(storagePrefix + key, value);\n } catch (err) {\n log.error(`Failed to set storage key: ${key}`, err);\n }\n },\n\n async delete(key) {\n try {\n await AsyncStorage.removeItem(storagePrefix + key);\n } catch (err) {\n log.error(`Failed to delete storage key: ${key}`, err);\n }\n },\n\n async keys() {\n try {\n const allKeys = await AsyncStorage.getAllKeys();\n return allKeys\n .filter(k => k.startsWith(storagePrefix))\n .map(k => k.slice(storagePrefix.length));\n } catch (err) {\n log.error('Failed to list storage keys', err);\n return [];\n }\n },\n },\n\n permissions: {\n async check(capability) {\n try {\n // Map capability to Expo permission API\n switch (capability) {\n case 'calendar':\n const cal = await ExpoCalendar.getCalendarPermissionsAsync();\n return cal.status === 'granted' ? 'granted' : cal.status === 'denied' ? 'denied' : 'not_requested';\n case 'contacts':\n const con = await ExpoContacts.getPermissionsAsync();\n return con.status === 'granted' ? 'granted' : con.status === 'denied' ? 'denied' : 'not_requested';\n case 'location':\n const loc = await ExpoLocation.getForegroundPermissionsAsync();\n return loc.status === 'granted' ? 'granted' : loc.status === 'denied' ? 'denied' : 'not_requested';\n case 'notifications':\n const notif = await ExpoNotifications.getPermissionsAsync();\n return notif.granted ? 'granted' : notif.canAskAgain ? 'not_requested' : 'denied';\n default:\n return 'not_requested';\n }\n } catch (err) {\n log.error(`Failed to check permission: ${capability}`, err);\n return 'denied';\n }\n },\n\n async request(capability) {\n try {\n switch (capability) {\n case 'calendar':\n const cal = await ExpoCalendar.requestCalendarPermissionsAsync();\n return cal.status === 'granted';\n case 'contacts':\n const con = await ExpoContacts.requestPermissionsAsync();\n return con.status === 'granted';\n case 'location':\n const loc = await ExpoLocation.requestForegroundPermissionsAsync();\n return loc.status === 'granted';\n case 'notifications':\n const notif = await ExpoNotifications.requestPermissionsAsync();\n return notif.granted;\n default:\n return false;\n }\n } catch (err) {\n log.error(`Failed to request permission: ${capability}`, err);\n return false;\n }\n },\n\n async getAll() {\n try {\n const [cal, con, loc, notif] = await Promise.allSettled([\n ExpoCalendar.getCalendarPermissionsAsync(),\n ExpoContacts.getPermissionsAsync(),\n ExpoLocation.getForegroundPermissionsAsync(),\n ExpoNotifications.getPermissionsAsync(),\n ]);\n\n return {\n calendar: cal.status === 'fulfilled' ? (cal.value.status === 'granted' ? 'granted' : cal.value.status === 'denied' ? 'denied' : 'not_requested') : 'denied',\n contacts: con.status === 'fulfilled' ? (con.value.status === 'granted' ? 'granted' : con.value.status === 'denied' ? 'denied' : 'not_requested') : 'denied',\n location: loc.status === 'fulfilled' ? (loc.value.status === 'granted' ? 'granted' : loc.value.status === 'denied' ? 'denied' : 'not_requested') : 'denied',\n notifications: notif.status === 'fulfilled' ? (notif.value.granted ? 'granted' : notif.value.canAskAgain ? 'not_requested' : 'denied') : 'denied',\n };\n } catch (err) {\n log.error('Failed to get all permissions', err);\n return { calendar: 'denied', contacts: 'denied', location: 'denied', notifications: 'denied' };\n }\n },\n },\n\n device: {\n getDeviceId() {\n return deviceId;\n },\n\n getPlatform() {\n return {\n os: Platform.OS as 'ios' | 'android',\n version: Platform.Version ? String(Platform.Version) : 'unknown',\n };\n },\n },\n\n log,\n };\n\n return bridge;\n}\n"],"mappings":"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","names":[]}
|