@doorstepai/dropoff-sdk-capacitor 1.0.1 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/android/build.gradle +1 -1
  2. package/android/src/main/java/ai/doorstep/dropoffsdk/capacitor/DoorstepAIDropoffSDKPlugin.kt +140 -2
  3. package/dist/docs.json +282 -1
  4. package/dist/esm/definitions.d.ts +82 -8
  5. package/dist/esm/index.js.map +1 -1
  6. package/dist/esm/web.d.ts +13 -1
  7. package/dist/esm/web.js +15 -0
  8. package/dist/esm/web.js.map +1 -1
  9. package/dist/plugin.cjs.js +15 -2
  10. package/dist/plugin.cjs.js.map +1 -1
  11. package/dist/plugin.js +15 -2
  12. package/dist/plugin.js.map +1 -1
  13. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64/DoorstepDropoffSDK.framework/DoorstepDropoffSDK +0 -0
  14. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64/DoorstepDropoffSDK.framework/Info.plist +0 -0
  15. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64/DoorstepDropoffSDK.framework/Modules/DoorstepDropoffSDK.swiftmodule/arm64-apple-ios.abi.json +5365 -1558
  16. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64/DoorstepDropoffSDK.framework/Modules/DoorstepDropoffSDK.swiftmodule/arm64-apple-ios.private.swiftinterface +82 -9
  17. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64/DoorstepDropoffSDK.framework/Modules/DoorstepDropoffSDK.swiftmodule/arm64-apple-ios.swiftdoc +0 -0
  18. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64/DoorstepDropoffSDK.framework/Modules/DoorstepDropoffSDK.swiftmodule/arm64-apple-ios.swiftinterface +82 -9
  19. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64/DoorstepDropoffSDK.framework/_CodeSignature/CodeResources +11 -11
  20. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64/dSYMs/DoorstepDropoffSDK.framework.dSYM/Contents/Resources/DWARF/DoorstepDropoffSDK +0 -0
  21. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64/dSYMs/DoorstepDropoffSDK.framework.dSYM/Contents/Resources/Relocations/aarch64/DoorstepDropoffSDK.yml +2630 -2113
  22. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/DoorstepDropoffSDK.framework/DoorstepDropoffSDK +0 -0
  23. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/DoorstepDropoffSDK.framework/Info.plist +0 -0
  24. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/DoorstepDropoffSDK.framework/Modules/DoorstepDropoffSDK.swiftmodule/arm64-apple-ios-simulator.abi.json +5365 -1558
  25. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/DoorstepDropoffSDK.framework/Modules/DoorstepDropoffSDK.swiftmodule/arm64-apple-ios-simulator.private.swiftinterface +82 -9
  26. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/DoorstepDropoffSDK.framework/Modules/DoorstepDropoffSDK.swiftmodule/arm64-apple-ios-simulator.swiftdoc +0 -0
  27. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/DoorstepDropoffSDK.framework/Modules/DoorstepDropoffSDK.swiftmodule/arm64-apple-ios-simulator.swiftinterface +82 -9
  28. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/DoorstepDropoffSDK.framework/Modules/DoorstepDropoffSDK.swiftmodule/x86_64-apple-ios-simulator.abi.json +5365 -1558
  29. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/DoorstepDropoffSDK.framework/Modules/DoorstepDropoffSDK.swiftmodule/x86_64-apple-ios-simulator.private.swiftinterface +82 -9
  30. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/DoorstepDropoffSDK.framework/Modules/DoorstepDropoffSDK.swiftmodule/x86_64-apple-ios-simulator.swiftdoc +0 -0
  31. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/DoorstepDropoffSDK.framework/Modules/DoorstepDropoffSDK.swiftmodule/x86_64-apple-ios-simulator.swiftinterface +82 -9
  32. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/DoorstepDropoffSDK.framework/_CodeSignature/CodeResources +21 -21
  33. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/dSYMs/DoorstepDropoffSDK.framework.dSYM/Contents/Resources/DWARF/DoorstepDropoffSDK +0 -0
  34. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/dSYMs/DoorstepDropoffSDK.framework.dSYM/Contents/Resources/Relocations/aarch64/DoorstepDropoffSDK.yml +2630 -2113
  35. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/dSYMs/DoorstepDropoffSDK.framework.dSYM/Contents/Resources/Relocations/x86_64/DoorstepDropoffSDK.yml +2616 -2102
  36. package/ios/Plugin/DoorstepAIDropoffSDKPlugin.m +5 -0
  37. package/ios/Plugin/DoorstepAIDropoffSDKPlugin.swift +132 -1
  38. package/package.json +1 -1
@@ -43,6 +43,6 @@ dependencies {
43
43
  implementation "com.capacitorjs:core:$capacitorAndroidVersion"
44
44
  implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3"
45
45
  implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3"
46
- implementation "ai.doorstep.com:doorstepai-dropoff-sdk:2.0.9"
46
+ implementation "ai.doorstep.com:doorstepai-dropoff-sdk:2.1.0"
47
47
  testImplementation "org.junit.jupiter:junit-jupiter-api:5.10.0"
48
48
  }
@@ -2,6 +2,7 @@ package ai.doorstep.dropoffsdk.capacitor
2
2
 
3
3
  import android.Manifest
4
4
  import android.util.Log
5
+ import com.getcapacitor.JSArray
5
6
  import com.getcapacitor.JSObject
6
7
  import com.getcapacitor.Plugin
7
8
  import com.getcapacitor.PluginCall
@@ -13,13 +14,17 @@ import com.doorstepai.sdks.tracking.AddressType
13
14
  import com.doorstepai.sdks.tracking.DoorstepAI
14
15
  import com.doorstepai.sdks.tracking.DropoffType
15
16
  import com.doorstepai.sdks.tracking.LatLngObject
17
+ import com.doorstepai.sdks.tracking.DeliveryStop
18
+ import com.doorstepai.sdks.tracking.RouteGeofenceOptions
16
19
 
17
20
  import kotlinx.coroutines.CoroutineScope
18
21
  import kotlinx.coroutines.Dispatchers
22
+ import kotlinx.coroutines.Job
19
23
  import kotlinx.coroutines.SupervisorJob
20
24
  import kotlinx.coroutines.cancel
21
25
  import kotlinx.coroutines.launch
22
26
  import kotlinx.coroutines.withContext
27
+ import kotlinx.coroutines.flow.collect
23
28
 
24
29
  @CapacitorPlugin(
25
30
  name = "DoorstepAIDropoffSDK",
@@ -35,15 +40,35 @@ import kotlinx.coroutines.withContext
35
40
  alias = "activity",
36
41
  strings = [Manifest.permission.ACTIVITY_RECOGNITION],
37
42
  ),
43
+ // Bluetooth (BLE) — opt-in; request explicitly via
44
+ // requestPermissions({ permissions: ['bluetooth'] }). BLUETOOTH_SCAN is
45
+ // declared by the SDK manifest (merged). API 31+; a no-op below S.
46
+ Permission(
47
+ alias = "bluetooth",
48
+ strings = [Manifest.permission.BLUETOOTH_SCAN],
49
+ ),
38
50
  ],
39
51
  )
40
52
  class DoorstepAIDropoffSDKPlugin : Plugin() {
41
53
 
42
54
  private val scope = CoroutineScope(SupervisorJob() + Dispatchers.Main.immediate)
55
+ private var geofenceJob: Job? = null
43
56
 
44
57
  override fun load() {
45
58
  super.load()
46
59
  Log.d(TAG, "load(): plugin attached, ready for calls")
60
+ // Stream native geofence-session events onto the "geofenceSessionEvent" listener.
61
+ geofenceJob = scope.launch {
62
+ DoorstepAI.geofenceSessionEvents.collect { ev ->
63
+ notifyListeners(
64
+ "geofenceSessionEvent",
65
+ JSObject()
66
+ .put("deliveryId", ev.deliveryId)
67
+ .put("type", ev.type.name)
68
+ .put("reason", ev.reason)
69
+ )
70
+ }
71
+ }
47
72
  }
48
73
 
49
74
  override fun handleOnDestroy() {
@@ -107,7 +132,8 @@ class DoorstepAIDropoffSDKPlugin : Plugin() {
107
132
  val timeoutSeconds = call.getDouble("timeoutSeconds")
108
133
  val customerId = call.getString("customerId")
109
134
  val autoStopAfterDropoffSeconds = call.getDouble("autoStopAfterDropoffSeconds")
110
- Log.d(TAG, "startDeliveryByPlaceID: placeID=$placeID deliveryId=$deliveryId timeout=$timeoutSeconds customerId=$customerId autoStop=$autoStopAfterDropoffSeconds")
135
+ val manualForeground = call.getBoolean("manualForeground", false) ?: false
136
+ Log.d(TAG, "startDeliveryByPlaceID: placeID=$placeID deliveryId=$deliveryId timeout=$timeoutSeconds customerId=$customerId autoStop=$autoStopAfterDropoffSeconds manualForeground=$manualForeground")
111
137
  if (placeID == null || deliveryId == null) {
112
138
  return call.reject("placeID or deliveryId missing", "BAD_ARGS")
113
139
  }
@@ -118,6 +144,7 @@ class DoorstepAIDropoffSDKPlugin : Plugin() {
118
144
  timeoutSeconds = timeoutSeconds,
119
145
  autoStopAfterDropoffSeconds = autoStopAfterDropoffSeconds,
120
146
  customerId = customerId,
147
+ manualForeground = manualForeground,
121
148
  ) { sdkResult ->
122
149
  sdkResult.onSuccess { call.resolve() }
123
150
  .onFailure { error ->
@@ -169,6 +196,7 @@ class DoorstepAIDropoffSDKPlugin : Plugin() {
169
196
  val timeoutSeconds = call.getDouble("timeoutSeconds")
170
197
  val customerId = call.getString("customerId")
171
198
  val autoStopAfterDropoffSeconds = call.getDouble("autoStopAfterDropoffSeconds")
199
+ val manualForeground = call.getBoolean("manualForeground", false) ?: false
172
200
  val coordinates = parseCoordinates(call.getObject("coordinates"))
173
201
 
174
202
  if (addrObj == null
@@ -198,6 +226,7 @@ class DoorstepAIDropoffSDKPlugin : Plugin() {
198
226
  timeoutSeconds = timeoutSeconds,
199
227
  autoStopAfterDropoffSeconds = autoStopAfterDropoffSeconds,
200
228
  customerId = customerId,
229
+ manualForeground = manualForeground,
201
230
  ) { sdkResult ->
202
231
  sdkResult.onSuccess { call.resolve() }
203
232
  .onFailure { error ->
@@ -216,6 +245,7 @@ class DoorstepAIDropoffSDKPlugin : Plugin() {
216
245
  val timeoutSeconds = call.getDouble("timeoutSeconds")
217
246
  val customerId = call.getString("customerId")
218
247
  val autoStopAfterDropoffSeconds = call.getDouble("autoStopAfterDropoffSeconds")
248
+ val manualForeground = call.getBoolean("manualForeground", false) ?: false
219
249
  val coordinates = parseCoordinates(call.getObject("coordinates"))
220
250
  if (address == null || deliveryId == null) {
221
251
  return call.reject("address or deliveryId missing", "BAD_ARGS")
@@ -228,6 +258,7 @@ class DoorstepAIDropoffSDKPlugin : Plugin() {
228
258
  timeoutSeconds = timeoutSeconds,
229
259
  autoStopAfterDropoffSeconds = autoStopAfterDropoffSeconds,
230
260
  customerId = customerId,
261
+ manualForeground = manualForeground,
231
262
  ) { sdkResult ->
232
263
  sdkResult.onSuccess { call.resolve() }
233
264
  .onFailure { error ->
@@ -301,12 +332,13 @@ class DoorstepAIDropoffSDKPlugin : Plugin() {
301
332
  fun newEvent(call: PluginCall) {
302
333
  val eventName = call.getString("eventName")
303
334
  val deliveryId = call.getString("deliveryId")
335
+ val timestamp = call.getDouble("timestamp")
304
336
  Log.d(TAG, "newEvent: eventName=$eventName deliveryId=$deliveryId")
305
337
  if (eventName == null || deliveryId == null) {
306
338
  return call.reject("eventName or deliveryId missing", "BAD_ARGS")
307
339
  }
308
340
  try {
309
- DoorstepAI.newEvent(eventName, deliveryId) { /* result swallowed in Flutter parity */ }
341
+ DoorstepAI.newEvent(eventName, deliveryId, timestamp) { /* fire-and-forget */ }
310
342
  call.resolve()
311
343
  } catch (e: Exception) {
312
344
  call.reject(e.message ?: "Failed to save event", "EVENT_CREATION_ERROR")
@@ -332,4 +364,110 @@ class DoorstepAIDropoffSDKPlugin : Plugin() {
332
364
  if (lat.isNaN() || lng.isNaN()) return null
333
365
  return LatLngObject(lat = lat, lng = lng)
334
366
  }
367
+
368
+ // ---- Route geofencing ----
369
+
370
+ @PluginMethod
371
+ fun startRouteGeofencing(call: PluginCall) {
372
+ val stops = parseStops(call.getArray("stops"))
373
+ if (stops.isEmpty()) {
374
+ return call.reject("startRouteGeofencing requires at least one valid stop (deliveryId + latitude + longitude)", "ROUTE_GEOFENCING_ERROR")
375
+ }
376
+ try {
377
+ DoorstepAI.startRouteGeofencing(stops, parseRouteOptions(call.getObject("options"))) { r ->
378
+ r.onSuccess { call.resolve() }
379
+ .onFailure { call.reject(it.message ?: "Failed to start route geofencing", "ROUTE_GEOFENCING_ERROR") }
380
+ }
381
+ } catch (e: Exception) {
382
+ call.reject(e.message ?: "Failed to start route geofencing", "ROUTE_GEOFENCING_ERROR")
383
+ }
384
+ }
385
+
386
+ @PluginMethod
387
+ fun updateRouteStops(call: PluginCall) {
388
+ try {
389
+ DoorstepAI.updateRouteStops(parseStops(call.getArray("stops"))) { r ->
390
+ r.onSuccess { call.resolve() }
391
+ .onFailure { call.reject(it.message ?: "Failed to update route stops", "ROUTE_GEOFENCING_ERROR") }
392
+ }
393
+ } catch (e: Exception) {
394
+ call.reject(e.message ?: "Failed to update route stops", "ROUTE_GEOFENCING_ERROR")
395
+ }
396
+ }
397
+
398
+ @PluginMethod
399
+ fun stopRouteGeofencing(call: PluginCall) {
400
+ try {
401
+ DoorstepAI.stopRouteGeofencing()
402
+ call.resolve()
403
+ } catch (e: Exception) {
404
+ call.reject(e.message ?: "Failed to stop route geofencing", "ROUTE_GEOFENCING_ERROR")
405
+ }
406
+ }
407
+
408
+ @PluginMethod
409
+ fun resumeRouteGeofencingIfNeeded(call: PluginCall) {
410
+ try {
411
+ DoorstepAI.resumeRouteGeofencingIfNeeded()
412
+ call.resolve()
413
+ } catch (e: Exception) {
414
+ call.reject(e.message ?: "Failed to resume route geofencing", "ROUTE_GEOFENCING_ERROR")
415
+ }
416
+ }
417
+
418
+ @PluginMethod
419
+ fun getMonitoredStops(call: PluginCall) {
420
+ try {
421
+ val arr = JSArray()
422
+ DoorstepAI.monitoredStops.forEach { arr.put(serializeStop(it)) }
423
+ call.resolve(JSObject().put("stops", arr))
424
+ } catch (e: Exception) {
425
+ call.reject(e.message ?: "Failed to get monitored stops", "ROUTE_GEOFENCING_ERROR")
426
+ }
427
+ }
428
+
429
+ private fun parseStops(arr: JSArray?): List<DeliveryStop> {
430
+ if (arr == null) return emptyList()
431
+ val out = ArrayList<DeliveryStop>()
432
+ for (i in 0 until arr.length()) {
433
+ val m = arr.optJSONObject(i) ?: continue
434
+ val deliveryId = m.optString("deliveryId", "")
435
+ if (deliveryId.isEmpty() || !m.has("latitude") || !m.has("longitude")) continue
436
+ out.add(
437
+ DeliveryStop(
438
+ deliveryId = deliveryId,
439
+ address = m.optString("address", ""),
440
+ latitude = m.optDouble("latitude"),
441
+ longitude = m.optDouble("longitude"),
442
+ radiusMeters = if (m.has("radiusMeters")) m.optDouble("radiusMeters") else null,
443
+ customerId = if (m.has("customerId")) m.optString("customerId") else null,
444
+ driverId = if (m.has("driverId")) m.optString("driverId") else null,
445
+ ),
446
+ )
447
+ }
448
+ return out
449
+ }
450
+
451
+ // Android RouteGeofenceOptions carries manualForeground (unlike iOS).
452
+ private fun parseRouteOptions(o: JSObject?): RouteGeofenceOptions {
453
+ if (o == null) return RouteGeofenceOptions()
454
+ return RouteGeofenceOptions(
455
+ defaultRadiusMeters = if (o.has("defaultRadiusMeters")) o.optDouble("defaultRadiusMeters", 250.0) else 250.0,
456
+ timeoutSeconds = if (o.has("timeoutSeconds")) o.optDouble("timeoutSeconds") else null,
457
+ autoStopAfterDropoffSeconds = if (o.has("autoStopAfterDropoffSeconds")) o.optDouble("autoStopAfterDropoffSeconds") else null,
458
+ manualForeground = o.optBoolean("manualForeground", false),
459
+ )
460
+ }
461
+
462
+ private fun serializeStop(s: DeliveryStop): JSObject {
463
+ val o = JSObject()
464
+ o.put("deliveryId", s.deliveryId)
465
+ o.put("address", s.address)
466
+ o.put("latitude", s.latitude)
467
+ o.put("longitude", s.longitude)
468
+ s.radiusMeters?.let { o.put("radiusMeters", it) }
469
+ s.customerId?.let { o.put("customerId", it) }
470
+ s.driverId?.let { o.put("driverId", it) }
471
+ return o
472
+ }
335
473
  }
package/dist/docs.json CHANGED
@@ -203,6 +203,109 @@
203
203
  ],
204
204
  "slug": "stopdelivery"
205
205
  },
206
+ {
207
+ "name": "startRouteGeofencing",
208
+ "signature": "(options: { stops: DeliveryStop[]; options?: RouteGeofenceOptions; }) => Promise<void>",
209
+ "parameters": [
210
+ {
211
+ "name": "options",
212
+ "docs": "",
213
+ "type": "{ stops: DeliveryStop[]; options?: RouteGeofenceOptions | undefined; }"
214
+ }
215
+ ],
216
+ "returns": "Promise<void>",
217
+ "tags": [],
218
+ "docs": "Start route geofencing. ENTER auto-starts a session; EXIT stops it only if a\ndropoff was marked (else the per-session timeout backstops it). Subscribe to\nsession lifecycle via `addListener('geofenceSessionEvent', ...)`.",
219
+ "complexTypes": [
220
+ "DeliveryStop",
221
+ "RouteGeofenceOptions"
222
+ ],
223
+ "slug": "startroutegeofencing"
224
+ },
225
+ {
226
+ "name": "updateRouteStops",
227
+ "signature": "(options: { stops: DeliveryStop[]; }) => Promise<void>",
228
+ "parameters": [
229
+ {
230
+ "name": "options",
231
+ "docs": "",
232
+ "type": "{ stops: DeliveryStop[]; }"
233
+ }
234
+ ],
235
+ "returns": "Promise<void>",
236
+ "tags": [],
237
+ "docs": "Replace the monitored stops in place without tearing down still-present stops.",
238
+ "complexTypes": [
239
+ "DeliveryStop"
240
+ ],
241
+ "slug": "updateroutestops"
242
+ },
243
+ {
244
+ "name": "stopRouteGeofencing",
245
+ "signature": "() => Promise<void>",
246
+ "parameters": [],
247
+ "returns": "Promise<void>",
248
+ "tags": [],
249
+ "docs": "Stop route geofencing and clear all monitored stops.",
250
+ "complexTypes": [],
251
+ "slug": "stoproutegeofencing"
252
+ },
253
+ {
254
+ "name": "resumeRouteGeofencingIfNeeded",
255
+ "signature": "() => Promise<void>",
256
+ "parameters": [],
257
+ "returns": "Promise<void>",
258
+ "tags": [],
259
+ "docs": "Re-arm route geofencing after a process relaunch if a route was active.",
260
+ "complexTypes": [],
261
+ "slug": "resumeroutegeofencingifneeded"
262
+ },
263
+ {
264
+ "name": "getMonitoredStops",
265
+ "signature": "() => Promise<{ stops: DeliveryStop[]; }>",
266
+ "parameters": [],
267
+ "returns": "Promise<{ stops: DeliveryStop[]; }>",
268
+ "tags": [],
269
+ "docs": "The stops currently registered for route geofencing (empty if none).",
270
+ "complexTypes": [
271
+ "DeliveryStop"
272
+ ],
273
+ "slug": "getmonitoredstops"
274
+ },
275
+ {
276
+ "name": "addListener",
277
+ "signature": "(eventName: 'geofenceSessionEvent', listenerFunc: (event: GeofenceSessionEvent) => void) => Promise<PluginListenerHandle>",
278
+ "parameters": [
279
+ {
280
+ "name": "eventName",
281
+ "docs": "",
282
+ "type": "'geofenceSessionEvent'"
283
+ },
284
+ {
285
+ "name": "listenerFunc",
286
+ "docs": "",
287
+ "type": "(event: GeofenceSessionEvent) => void"
288
+ }
289
+ ],
290
+ "returns": "Promise<PluginListenerHandle>",
291
+ "tags": [],
292
+ "docs": "Subscribe to route-geofence session STARTED/STOPPED events.",
293
+ "complexTypes": [
294
+ "PluginListenerHandle",
295
+ "GeofenceSessionEvent"
296
+ ],
297
+ "slug": "addlistenergeofencesessionevent-"
298
+ },
299
+ {
300
+ "name": "removeAllListeners",
301
+ "signature": "() => Promise<void>",
302
+ "parameters": [],
303
+ "returns": "Promise<void>",
304
+ "tags": [],
305
+ "docs": "Remove all listeners registered for this plugin.",
306
+ "complexTypes": [],
307
+ "slug": "removealllisteners"
308
+ },
206
309
  {
207
310
  "name": "checkPermissions",
208
311
  "signature": "() => Promise<PermissionStatus>",
@@ -615,6 +718,13 @@
615
718
  "docs": "",
616
719
  "complexTypes": [],
617
720
  "type": "string"
721
+ },
722
+ {
723
+ "name": "timestamp",
724
+ "tags": [],
725
+ "docs": "Epoch seconds; if omitted the SDK stamps the current time.",
726
+ "complexTypes": [],
727
+ "type": "number | undefined"
618
728
  }
619
729
  ]
620
730
  },
@@ -634,6 +744,149 @@
634
744
  }
635
745
  ]
636
746
  },
747
+ {
748
+ "name": "DeliveryStop",
749
+ "slug": "deliverystop",
750
+ "docs": "A stop monitored for route geofencing. Mirrors the native `DeliveryStop`.",
751
+ "tags": [],
752
+ "methods": [],
753
+ "properties": [
754
+ {
755
+ "name": "deliveryId",
756
+ "tags": [],
757
+ "docs": "",
758
+ "complexTypes": [],
759
+ "type": "string"
760
+ },
761
+ {
762
+ "name": "address",
763
+ "tags": [],
764
+ "docs": "",
765
+ "complexTypes": [],
766
+ "type": "string"
767
+ },
768
+ {
769
+ "name": "latitude",
770
+ "tags": [],
771
+ "docs": "",
772
+ "complexTypes": [],
773
+ "type": "number"
774
+ },
775
+ {
776
+ "name": "longitude",
777
+ "tags": [],
778
+ "docs": "",
779
+ "complexTypes": [],
780
+ "type": "number"
781
+ },
782
+ {
783
+ "name": "radiusMeters",
784
+ "tags": [],
785
+ "docs": "",
786
+ "complexTypes": [],
787
+ "type": "number | undefined"
788
+ },
789
+ {
790
+ "name": "customerId",
791
+ "tags": [],
792
+ "docs": "",
793
+ "complexTypes": [],
794
+ "type": "string | undefined"
795
+ },
796
+ {
797
+ "name": "driverId",
798
+ "tags": [],
799
+ "docs": "",
800
+ "complexTypes": [],
801
+ "type": "string | undefined"
802
+ }
803
+ ]
804
+ },
805
+ {
806
+ "name": "RouteGeofenceOptions",
807
+ "slug": "routegeofenceoptions",
808
+ "docs": "Options for {@link DoorstepAIDropoffSDKPlugin.startRouteGeofencing}.",
809
+ "tags": [],
810
+ "methods": [],
811
+ "properties": [
812
+ {
813
+ "name": "defaultRadiusMeters",
814
+ "tags": [],
815
+ "docs": "",
816
+ "complexTypes": [],
817
+ "type": "number | undefined"
818
+ },
819
+ {
820
+ "name": "timeoutSeconds",
821
+ "tags": [],
822
+ "docs": "",
823
+ "complexTypes": [],
824
+ "type": "number | undefined"
825
+ },
826
+ {
827
+ "name": "autoStopAfterDropoffSeconds",
828
+ "tags": [],
829
+ "docs": "",
830
+ "complexTypes": [],
831
+ "type": "number | undefined"
832
+ },
833
+ {
834
+ "name": "manualForeground",
835
+ "tags": [],
836
+ "docs": "Android only; ignored on iOS (the OS owns background region monitoring).",
837
+ "complexTypes": [],
838
+ "type": "boolean | undefined"
839
+ }
840
+ ]
841
+ },
842
+ {
843
+ "name": "PluginListenerHandle",
844
+ "slug": "pluginlistenerhandle",
845
+ "docs": "",
846
+ "tags": [],
847
+ "methods": [],
848
+ "properties": [
849
+ {
850
+ "name": "remove",
851
+ "tags": [],
852
+ "docs": "",
853
+ "complexTypes": [],
854
+ "type": "() => Promise<void>"
855
+ }
856
+ ]
857
+ },
858
+ {
859
+ "name": "GeofenceSessionEvent",
860
+ "slug": "geofencesessionevent",
861
+ "docs": "Payload delivered to the `'geofenceSessionEvent'` listener.",
862
+ "tags": [],
863
+ "methods": [],
864
+ "properties": [
865
+ {
866
+ "name": "deliveryId",
867
+ "tags": [],
868
+ "docs": "",
869
+ "complexTypes": [],
870
+ "type": "string"
871
+ },
872
+ {
873
+ "name": "type",
874
+ "tags": [],
875
+ "docs": "",
876
+ "complexTypes": [
877
+ "GeofenceSessionEventType"
878
+ ],
879
+ "type": "GeofenceSessionEventType"
880
+ },
881
+ {
882
+ "name": "reason",
883
+ "tags": [],
884
+ "docs": "",
885
+ "complexTypes": [],
886
+ "type": "string"
887
+ }
888
+ ]
889
+ },
637
890
  {
638
891
  "name": "PermissionStatus",
639
892
  "slug": "permissionstatus",
@@ -658,6 +911,15 @@
658
911
  "PermissionState"
659
912
  ],
660
913
  "type": "PermissionState"
914
+ },
915
+ {
916
+ "name": "bluetooth",
917
+ "tags": [],
918
+ "docs": "Bluetooth, needed only for BLE collection (off unless server-enabled).\nAndroid: `BLUETOOTH_SCAN` (API 31+). iOS: `NSBluetoothAlwaysUsageDescription`.\nOpt-in: NOT requested by a no-argument `requestPermissions()` — pass it\nexplicitly (`requestPermissions({ permissions: ['bluetooth'] })`).",
919
+ "complexTypes": [
920
+ "PermissionState"
921
+ ],
922
+ "type": "PermissionState"
661
923
  }
662
924
  ]
663
925
  },
@@ -671,7 +933,7 @@
671
933
  {
672
934
  "name": "permissions",
673
935
  "tags": [],
674
- "docs": "If omitted, requests all permissions.",
936
+ "docs": "Which permissions to request. If omitted, requests the default set\n(location + activity) — Bluetooth is opt-in and must be listed explicitly.",
675
937
  "complexTypes": [
676
938
  "DoorstepPermissionType"
677
939
  ],
@@ -697,6 +959,21 @@
697
959
  }
698
960
  ]
699
961
  },
962
+ {
963
+ "name": "GeofenceSessionEventType",
964
+ "slug": "geofencesessioneventtype",
965
+ "docs": "",
966
+ "types": [
967
+ {
968
+ "text": "'STARTED'",
969
+ "complexTypes": []
970
+ },
971
+ {
972
+ "text": "'STOPPED'",
973
+ "complexTypes": []
974
+ }
975
+ ]
976
+ },
700
977
  {
701
978
  "name": "PermissionState",
702
979
  "slug": "permissionstate",
@@ -732,6 +1009,10 @@
732
1009
  {
733
1010
  "text": "'activity'",
734
1011
  "complexTypes": []
1012
+ },
1013
+ {
1014
+ "text": "'bluetooth'",
1015
+ "complexTypes": []
735
1016
  }
736
1017
  ]
737
1018
  }