@wayq/beekon-rn 0.0.9 → 0.1.2
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/BeekonRn.podspec +2 -2
- package/CHANGELOG.md +70 -7
- package/LICENSE.txt +3 -3
- package/README.md +111 -326
- package/android/build.gradle +2 -2
- package/android/src/main/AndroidManifest.xml +10 -0
- package/android/src/main/java/in/wayq/beekonrn/BeekonRnModule.kt +132 -1
- package/ios/BeekonRn.mm +5 -0
- package/ios/BeekonRn.swift +96 -10
- package/ios/Frameworks/BeekonKit.xcframework/LICENSE.txt +3 -3
- package/ios/Frameworks/BeekonKit.xcframework/ios-arm64/BeekonKit.framework/BeekonKit +0 -0
- package/ios/Frameworks/BeekonKit.xcframework/ios-arm64/BeekonKit.framework/Info.plist +0 -0
- package/ios/Frameworks/BeekonKit.xcframework/ios-arm64/BeekonKit.framework/Modules/BeekonKit.swiftmodule/arm64-apple-ios.abi.json +6218 -3034
- package/ios/Frameworks/BeekonKit.xcframework/ios-arm64/BeekonKit.framework/Modules/BeekonKit.swiftmodule/arm64-apple-ios.swiftdoc +0 -0
- package/ios/Frameworks/BeekonKit.xcframework/ios-arm64/BeekonKit.framework/Modules/BeekonKit.swiftmodule/arm64-apple-ios.swiftinterface +89 -5
- package/ios/Frameworks/BeekonKit.xcframework/ios-arm64_x86_64-simulator/BeekonKit.framework/BeekonKit +0 -0
- package/ios/Frameworks/BeekonKit.xcframework/ios-arm64_x86_64-simulator/BeekonKit.framework/Info.plist +0 -0
- package/ios/Frameworks/BeekonKit.xcframework/ios-arm64_x86_64-simulator/BeekonKit.framework/Modules/BeekonKit.swiftmodule/arm64-apple-ios-simulator.abi.json +6218 -3034
- package/ios/Frameworks/BeekonKit.xcframework/ios-arm64_x86_64-simulator/BeekonKit.framework/Modules/BeekonKit.swiftmodule/arm64-apple-ios-simulator.swiftdoc +0 -0
- package/ios/Frameworks/BeekonKit.xcframework/ios-arm64_x86_64-simulator/BeekonKit.framework/Modules/BeekonKit.swiftmodule/arm64-apple-ios-simulator.swiftinterface +89 -5
- package/ios/Frameworks/BeekonKit.xcframework/ios-arm64_x86_64-simulator/BeekonKit.framework/Modules/BeekonKit.swiftmodule/x86_64-apple-ios-simulator.abi.json +6218 -3034
- package/ios/Frameworks/BeekonKit.xcframework/ios-arm64_x86_64-simulator/BeekonKit.framework/Modules/BeekonKit.swiftmodule/x86_64-apple-ios-simulator.swiftdoc +0 -0
- package/ios/Frameworks/BeekonKit.xcframework/ios-arm64_x86_64-simulator/BeekonKit.framework/Modules/BeekonKit.swiftmodule/x86_64-apple-ios-simulator.swiftinterface +89 -5
- package/ios/Frameworks/BeekonKit.xcframework/ios-arm64_x86_64-simulator/BeekonKit.framework/_CodeSignature/CodeResources +1 -1
- package/lib/module/NativeBeekonRn.js +14 -0
- package/lib/module/NativeBeekonRn.js.map +1 -1
- package/lib/module/beekon.js +26 -1
- package/lib/module/beekon.js.map +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/internal/mappers.js +95 -2
- package/lib/module/internal/mappers.js.map +1 -1
- package/lib/module/types/permission.js +2 -0
- package/lib/module/types/permission.js.map +1 -0
- package/lib/typescript/src/NativeBeekonRn.d.ts +39 -0
- package/lib/typescript/src/NativeBeekonRn.d.ts.map +1 -1
- package/lib/typescript/src/beekon.d.ts +20 -0
- package/lib/typescript/src/beekon.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +2 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/internal/mappers.d.ts +4 -1
- package/lib/typescript/src/internal/mappers.d.ts.map +1 -1
- package/lib/typescript/src/types/geofence.d.ts +37 -0
- package/lib/typescript/src/types/geofence.d.ts.map +1 -1
- package/lib/typescript/src/types/permission.d.ts +78 -0
- package/lib/typescript/src/types/permission.d.ts.map +1 -0
- package/package.json +5 -5
- package/scripts/fetch-beekonkit.sh +6 -6
- package/src/NativeBeekonRn.ts +45 -0
- package/src/beekon.ts +33 -0
- package/src/index.tsx +12 -0
- package/src/internal/mappers.ts +140 -0
- package/src/types/geofence.ts +41 -0
- package/src/types/permission.ts +91 -0
|
@@ -5,8 +5,9 @@ export type { AccuracyMode, StationaryMode, LocationTrigger, LocationQuality, Mo
|
|
|
5
5
|
export type { LogEntry } from './types/log';
|
|
6
6
|
export type { AuthConfig, AuthResponseMapping, AuthTokens } from './types/auth';
|
|
7
7
|
export type { Location } from './types/location';
|
|
8
|
-
export type { BeekonGeofence, GeofenceEvent, Transition, } from './types/geofence';
|
|
8
|
+
export type { BeekonGeofence, GeofenceEvent, GeofenceNotification, NotificationContent, NotificationDelivery, NotificationImportance, Transition, } from './types/geofence';
|
|
9
9
|
export type { BeekonState, StopReason } from './types/state';
|
|
10
|
+
export type { PermissionStatus, PermissionLevel, PermissionAccuracy, BeekonPermission, PermissionImportance, PermissionRequirement, } from './types/permission';
|
|
10
11
|
export type { SyncStatus, SyncFailure } from './types/sync';
|
|
11
12
|
export type { LicenseStatus, LicenseInvalidReason } from './types/license';
|
|
12
13
|
export { BeekonError, type BeekonErrorKind } from './types/error';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAIlC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,YAAY,EACV,WAAW,EACX,iBAAiB,EACjB,UAAU,EACV,kBAAkB,GACnB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EACV,YAAY,EACZ,cAAc,EACd,eAAe,EACf,eAAe,EACf,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,QAAQ,GACT,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,YAAY,EAAE,UAAU,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAChF,YAAY,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACjD,YAAY,EACV,cAAc,EACd,aAAa,EACb,UAAU,GACX,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC7D,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC5D,YAAY,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAC3E,OAAO,EAAE,WAAW,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAIlC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,YAAY,EACV,WAAW,EACX,iBAAiB,EACjB,UAAU,EACV,kBAAkB,GACnB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EACV,YAAY,EACZ,cAAc,EACd,eAAe,EACf,eAAe,EACf,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,QAAQ,GACT,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,YAAY,EAAE,UAAU,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAChF,YAAY,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACjD,YAAY,EACV,cAAc,EACd,aAAa,EACb,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EACpB,sBAAsB,EACtB,UAAU,GACX,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC7D,YAAY,EACV,gBAAgB,EAChB,eAAe,EACf,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC5D,YAAY,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAC3E,OAAO,EAAE,WAAW,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -4,9 +4,10 @@ import type { LogEntry } from '../types/log';
|
|
|
4
4
|
import type { BeekonGeofence, GeofenceEvent } from '../types/geofence';
|
|
5
5
|
import type { LicenseStatus } from '../types/license';
|
|
6
6
|
import type { Location } from '../types/location';
|
|
7
|
+
import type { PermissionRequirement, PermissionStatus } from '../types/permission';
|
|
7
8
|
import type { BeekonState } from '../types/state';
|
|
8
9
|
import type { SyncStatus } from '../types/sync';
|
|
9
|
-
import type { WireAuthConfig, WireAuthTokens, WireConfig, WireGeofence, WireGeofenceEvent, WireKeyValue, WireLicenseStatus, WireLocation, WireLogEntry, WireState, WireSyncStatus } from '../NativeBeekonRn';
|
|
10
|
+
import type { WireAuthConfig, WireAuthTokens, WireConfig, WireGeofence, WireGeofenceEvent, WireKeyValue, WireLicenseStatus, WireLocation, WireLogEntry, WirePermissionRequirement, WirePermissionStatus, WireState, WireSyncStatus } from '../NativeBeekonRn';
|
|
10
11
|
export declare function recordToEntries(record: Record<string, string> | undefined): WireKeyValue[];
|
|
11
12
|
export declare function configToWire(config: BeekonConfig): WireConfig;
|
|
12
13
|
export declare function geofenceToWire(g: BeekonGeofence): WireGeofence;
|
|
@@ -16,6 +17,8 @@ export declare function wireToGeofence(w: WireGeofence): BeekonGeofence;
|
|
|
16
17
|
export declare function wireToGeofenceEvent(w: WireGeofenceEvent): GeofenceEvent;
|
|
17
18
|
export declare function wireToLogEntry(w: WireLogEntry): LogEntry;
|
|
18
19
|
export declare function wireToState(w: WireState): BeekonState;
|
|
20
|
+
export declare function wireToPermissionStatus(w: WirePermissionStatus): PermissionStatus;
|
|
21
|
+
export declare function wireToPermissionRequirement(w: WirePermissionRequirement): PermissionRequirement;
|
|
19
22
|
export declare function wireToSyncStatus(w: WireSyncStatus): SyncStatus;
|
|
20
23
|
/** `expiresAtMs` (epoch millis) becomes a `Date`; `null` propagates faithfully. */
|
|
21
24
|
export declare function wireToAuthTokens(w: WireAuthTokens): AuthTokens;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mappers.d.ts","sourceRoot":"","sources":["../../../../src/internal/mappers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAYpD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,KAAK,EACV,cAAc,EACd,aAAa,
|
|
1
|
+
{"version":3,"file":"mappers.d.ts","sourceRoot":"","sources":["../../../../src/internal/mappers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAYpD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,KAAK,EACV,cAAc,EACd,aAAa,EAMd,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAwB,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC5E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,KAAK,EAKV,qBAAqB,EACrB,gBAAgB,EACjB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,WAAW,EAAc,MAAM,gBAAgB,CAAC;AAC9D,OAAO,KAAK,EAAe,UAAU,EAAE,MAAM,eAAe,CAAC;AAE7D,OAAO,KAAK,EACV,cAAc,EACd,cAAc,EACd,UAAU,EACV,YAAY,EACZ,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,EACjB,YAAY,EACZ,YAAY,EACZ,yBAAyB,EACzB,oBAAoB,EACpB,SAAS,EACT,cAAc,EACf,MAAM,mBAAmB,CAAC;AA0B3B,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,GACzC,YAAY,EAAE,CAGhB;AAiBD,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,UAAU,CA4D7D;AAED,wBAAgB,cAAc,CAAC,CAAC,EAAE,cAAc,GAAG,YAAY,CAU9D;AAoFD,wBAAgB,UAAU,CAAC,CAAC,EAAE,UAAU,GAAG,cAAc,CAqBxD;AAID,wBAAgB,cAAc,CAAC,CAAC,EAAE,YAAY,GAAG,QAAQ,CA0CxD;AAED,wBAAgB,cAAc,CAAC,CAAC,EAAE,YAAY,GAAG,cAAc,CAU9D;AAED,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,iBAAiB,GAAG,aAAa,CAOvE;AAED,wBAAgB,cAAc,CAAC,CAAC,EAAE,YAAY,GAAG,QAAQ,CAYxD;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,SAAS,GAAG,WAAW,CAYrD;AAED,wBAAgB,sBAAsB,CACpC,CAAC,EAAE,oBAAoB,GACtB,gBAAgB,CAgBlB;AAED,wBAAgB,2BAA2B,CACzC,CAAC,EAAE,yBAAyB,GAC3B,qBAAqB,CAoBvB;AAED,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,cAAc,GAAG,UAAU,CAW9D;AAED,mFAAmF;AACnF,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,cAAc,GAAG,UAAU,CAO9D;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,iBAAiB,GAAG,aAAa,CAqCvE;AAqCD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,OAAO,GAAG,KAAK,CAQtD"}
|
|
@@ -16,6 +16,43 @@ export type BeekonGeofence = {
|
|
|
16
16
|
notifyOnEntry?: boolean;
|
|
17
17
|
/** Emit an event on exit. Default: `true`. */
|
|
18
18
|
notifyOnExit?: boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Optional per-geofence notification the SDK renders natively at crossing time —
|
|
21
|
+
* offline and even when the app is killed. Omit it to handle crossings yourself
|
|
22
|
+
* via `Beekon.onGeofenceEvent`. `onEnter` requires `notifyOnEntry`; `onExit`
|
|
23
|
+
* requires `notifyOnExit`; in self-managed mode `delivery` must be `'local'`.
|
|
24
|
+
*/
|
|
25
|
+
notification?: GeofenceNotification;
|
|
26
|
+
};
|
|
27
|
+
/** Where a geofence-crossing notification is delivered. Mirrors `NotificationDelivery` on the natives. */
|
|
28
|
+
export type NotificationDelivery = 'local' | 'cloud';
|
|
29
|
+
/** Relative prominence of a geofence notification. Mirrors `NotificationImportance`. */
|
|
30
|
+
export type NotificationImportance = 'high' | 'default';
|
|
31
|
+
/** Per-direction content the SDK renders natively for a geofence crossing. */
|
|
32
|
+
export type NotificationContent = {
|
|
33
|
+
/** Notification title. */
|
|
34
|
+
title: string;
|
|
35
|
+
/** Notification body. */
|
|
36
|
+
body: string;
|
|
37
|
+
/** Relative prominence. Default `'high'`. */
|
|
38
|
+
importance?: NotificationImportance;
|
|
39
|
+
/** Optional deep-link URI delivered in the notification for the host to route on tap. */
|
|
40
|
+
deepLink?: string;
|
|
41
|
+
/** Optional flat string payload delivered in the notification for routing on tap. */
|
|
42
|
+
data?: Record<string, string>;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* An optional per-geofence notification rendered natively at crossing time.
|
|
46
|
+
* Mirrors `GeofenceNotification` on both native SDKs. The presence of `onEnter` /
|
|
47
|
+
* `onExit` selects which directions notify.
|
|
48
|
+
*/
|
|
49
|
+
export type GeofenceNotification = {
|
|
50
|
+
/** Delivery channel. `'local'` (offline, device-rendered) is the default and only implemented mode. */
|
|
51
|
+
delivery: NotificationDelivery;
|
|
52
|
+
/** Content rendered on entry. Requires `notifyOnEntry`. */
|
|
53
|
+
onEnter?: NotificationContent;
|
|
54
|
+
/** Content rendered on exit. Requires `notifyOnExit`. */
|
|
55
|
+
onExit?: NotificationContent;
|
|
19
56
|
};
|
|
20
57
|
/** Whether a {@link GeofenceEvent} marks entering or exiting a geofence. */
|
|
21
58
|
export type Transition = 'enter' | 'exit';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"geofence.d.ts","sourceRoot":"","sources":["../../../../src/types/geofence.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,yEAAyE;IACzE,EAAE,EAAE,MAAM,CAAC;IACX,0CAA0C;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,2CAA2C;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,gFAAgF;IAChF,YAAY,EAAE,MAAM,CAAC;IACrB,+CAA+C;IAC/C,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,8CAA8C;IAC9C,YAAY,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"geofence.d.ts","sourceRoot":"","sources":["../../../../src/types/geofence.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,yEAAyE;IACzE,EAAE,EAAE,MAAM,CAAC;IACX,0CAA0C;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,2CAA2C;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,gFAAgF;IAChF,YAAY,EAAE,MAAM,CAAC;IACrB,+CAA+C;IAC/C,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,8CAA8C;IAC9C,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,oBAAoB,CAAC;CACrC,CAAC;AAEF,0GAA0G;AAC1G,MAAM,MAAM,oBAAoB,GAAG,OAAO,GAAG,OAAO,CAAC;AAErD,wFAAwF;AACxF,MAAM,MAAM,sBAAsB,GAAG,MAAM,GAAG,SAAS,CAAC;AAExD,8EAA8E;AAC9E,MAAM,MAAM,mBAAmB,GAAG;IAChC,0BAA0B;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,yBAAyB;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,6CAA6C;IAC7C,UAAU,CAAC,EAAE,sBAAsB,CAAC;IACpC,yFAAyF;IACzF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qFAAqF;IACrF,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/B,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,uGAAuG;IACvG,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,2DAA2D;IAC3D,OAAO,CAAC,EAAE,mBAAmB,CAAC;IAC9B,yDAAyD;IACzD,MAAM,CAAC,EAAE,mBAAmB,CAAC;CAC9B,CAAC;AAEF,4EAA4E;AAC5E,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,MAAM,CAAC;AAE1C;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,wDAAwD;IACxD,EAAE,EAAE,MAAM,CAAC;IACX,sDAAsD;IACtD,UAAU,EAAE,MAAM,CAAC;IACnB,4CAA4C;IAC5C,IAAI,EAAE,UAAU,CAAC;IACjB,kCAAkC;IAClC,SAAS,EAAE,IAAI,CAAC;CACjB,CAAC"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How far the host app's location grant reaches. Mirrors the native
|
|
3
|
+
* `PermissionStatus` level on both platforms.
|
|
4
|
+
*
|
|
5
|
+
* Normalized — not platform permission constants. `'restricted'` is **iOS-only**
|
|
6
|
+
* (MDM / Screen Time); on Android "not yet asked" and "denied" cannot be told
|
|
7
|
+
* apart without an `Activity`, so both report `'notDetermined'`.
|
|
8
|
+
*
|
|
9
|
+
* - `'notDetermined'` — not yet decided; request to proceed.
|
|
10
|
+
* - `'denied'` — the user denied access (iOS). User-fixable in Settings.
|
|
11
|
+
* - `'restricted'` — blocked by an unchangeable policy (iOS-only).
|
|
12
|
+
* - `'foreground'` — granted while in use; foreground tracking only.
|
|
13
|
+
* - `'background'` — granted at all times; background tracking works.
|
|
14
|
+
*/
|
|
15
|
+
export type PermissionLevel = 'notDetermined' | 'denied' | 'restricted' | 'foreground' | 'background';
|
|
16
|
+
/**
|
|
17
|
+
* Precision of a granted location authorization. `null` unless granted.
|
|
18
|
+
*
|
|
19
|
+
* - `'full'` — precise location.
|
|
20
|
+
* - `'reduced'` — approximate only (iOS 14 / Android 12 "approximate").
|
|
21
|
+
*/
|
|
22
|
+
export type PermissionAccuracy = 'full' | 'reduced';
|
|
23
|
+
/**
|
|
24
|
+
* A point-in-time snapshot of the location-permission grant, returned by
|
|
25
|
+
* `Beekon.getPermissionStatus()`. Mirrors the native `PermissionStatus`.
|
|
26
|
+
*
|
|
27
|
+
* Beekon never *requests* permission — the app owns that. This is a read-only
|
|
28
|
+
* query for pre-start checks; it never prompts. It is a snapshot, not an
|
|
29
|
+
* observer: once tracking is running, permission loss surfaces on the `onState`
|
|
30
|
+
* stream as `{ kind: 'stopped', reason: 'permissionDenied' }`.
|
|
31
|
+
*/
|
|
32
|
+
export type PermissionStatus = {
|
|
33
|
+
/** How far the grant reaches. */
|
|
34
|
+
level: PermissionLevel;
|
|
35
|
+
/** Precision of the grant, or `null` when not authorized. */
|
|
36
|
+
accuracy: PermissionAccuracy | null;
|
|
37
|
+
/** `true` when authorized at all — foreground or background. */
|
|
38
|
+
isAuthorized: boolean;
|
|
39
|
+
/** `true` when background tracking is authorized. */
|
|
40
|
+
canTrackInBackground: boolean;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* A permission Beekon may require, normalized across platforms. Mirrors the
|
|
44
|
+
* native `BeekonPermission`.
|
|
45
|
+
*
|
|
46
|
+
* - `'location'` — foreground location; required for all tracking.
|
|
47
|
+
* - `'backgroundLocation'` — background revival, geofences, stationary resume.
|
|
48
|
+
* - `'activityRecognition'` — motion-based stationary detection.
|
|
49
|
+
* - `'notifications'` — the foreground-service notification (**Android only**).
|
|
50
|
+
*/
|
|
51
|
+
export type BeekonPermission = 'location' | 'backgroundLocation' | 'activityRecognition' | 'notifications';
|
|
52
|
+
/**
|
|
53
|
+
* How badly a {@link PermissionRequirement} is needed.
|
|
54
|
+
*
|
|
55
|
+
* - `'required'` — tracking cannot start, or an explicitly-enabled feature is dead, without it.
|
|
56
|
+
* - `'recommended'` — an active feature silently degrades without it; tracking still runs.
|
|
57
|
+
*/
|
|
58
|
+
export type PermissionImportance = 'required' | 'recommended';
|
|
59
|
+
/**
|
|
60
|
+
* One permission Beekon needs **for the current configuration**, each marked
|
|
61
|
+
* satisfied against the live grant — returned by `Beekon.getRequiredPermissions()`.
|
|
62
|
+
* Mirrors the native `PermissionRequirement`.
|
|
63
|
+
*
|
|
64
|
+
* Beekon never *requests* permission — the app owns that. This is the
|
|
65
|
+
* config-aware "doctor" companion to {@link PermissionStatus}: it reports
|
|
66
|
+
* activity-recognition (and, on Android, notifications) too.
|
|
67
|
+
*/
|
|
68
|
+
export type PermissionRequirement = {
|
|
69
|
+
/** The normalized permission. */
|
|
70
|
+
permission: BeekonPermission;
|
|
71
|
+
/** Whether tracking/a feature breaks (`'required'`) or merely degrades (`'recommended'`) when absent. */
|
|
72
|
+
importance: PermissionImportance;
|
|
73
|
+
/** Whether the live OS grant covers it right now. */
|
|
74
|
+
satisfied: boolean;
|
|
75
|
+
/** Human-readable explanation of why Beekon needs it / what degrades without it. */
|
|
76
|
+
rationale: string;
|
|
77
|
+
};
|
|
78
|
+
//# sourceMappingURL=permission.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permission.d.ts","sourceRoot":"","sources":["../../../../src/types/permission.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,eAAe,GACvB,eAAe,GACf,QAAQ,GACR,YAAY,GACZ,YAAY,GACZ,YAAY,CAAC;AAEjB;;;;;GAKG;AACH,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,SAAS,CAAC;AAEpD;;;;;;;;GAQG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,iCAAiC;IACjC,KAAK,EAAE,eAAe,CAAC;IACvB,6DAA6D;IAC7D,QAAQ,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACpC,gEAAgE;IAChE,YAAY,EAAE,OAAO,CAAC;IACtB,qDAAqD;IACrD,oBAAoB,EAAE,OAAO,CAAC;CAC/B,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,gBAAgB,GACxB,UAAU,GACV,oBAAoB,GACpB,qBAAqB,GACrB,eAAe,CAAC;AAEpB;;;;;GAKG;AACH,MAAM,MAAM,oBAAoB,GAAG,UAAU,GAAG,aAAa,CAAC;AAE9D;;;;;;;;GAQG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC,iCAAiC;IACjC,UAAU,EAAE,gBAAgB,CAAC;IAC7B,yGAAyG;IACzG,UAAU,EAAE,oBAAoB,CAAC;IACjC,qDAAqD;IACrD,SAAS,EAAE,OAAO,CAAC;IACnB,oFAAoF;IACpF,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wayq/beekon-rn",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "React Native binding for the Beekon location SDK (Android + iOS).",
|
|
5
5
|
"main": "./lib/module/index.js",
|
|
6
6
|
"types": "./lib/typescript/src/index.d.ts",
|
|
@@ -58,14 +58,14 @@
|
|
|
58
58
|
],
|
|
59
59
|
"repository": {
|
|
60
60
|
"type": "git",
|
|
61
|
-
"url": "git+https://github.com/
|
|
61
|
+
"url": "git+https://github.com/beekonlabs/beekon-rn.git"
|
|
62
62
|
},
|
|
63
|
-
"author": "
|
|
63
|
+
"author": "beekonlabs <beekonlabs@users.noreply.github.com> (https://github.com/beekonlabs)",
|
|
64
64
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
65
65
|
"bugs": {
|
|
66
|
-
"url": "https://github.com/
|
|
66
|
+
"url": "https://github.com/beekonlabs/beekon-rn/issues"
|
|
67
67
|
},
|
|
68
|
-
"homepage": "https://github.com/
|
|
68
|
+
"homepage": "https://github.com/beekonlabs/beekon-rn#readme",
|
|
69
69
|
"publishConfig": {
|
|
70
70
|
"registry": "https://registry.npmjs.org/",
|
|
71
71
|
"access": "public"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# Fetches BeekonKit.xcframework from
|
|
2
|
+
# Fetches BeekonKit.xcframework from beekonlabs/beekon-ios-binary's GitHub
|
|
3
3
|
# Release at the pinned version, verifies SHA256, and extracts it into
|
|
4
4
|
# ios/Frameworks/. Idempotent: skips if the framework is already present.
|
|
5
5
|
#
|
|
@@ -13,12 +13,12 @@
|
|
|
13
13
|
|
|
14
14
|
set -euo pipefail
|
|
15
15
|
|
|
16
|
-
VERSION="0.
|
|
17
|
-
URL="https://github.com/
|
|
18
|
-
# SHA256 of the v0.
|
|
19
|
-
# `binaryTarget` checksum in beekon-ios-binary's Package.swift at tag v0.
|
|
16
|
+
VERSION="0.1.2"
|
|
17
|
+
URL="https://github.com/beekonlabs/beekon-ios-binary/releases/download/v${VERSION}/BeekonKit.xcframework.zip"
|
|
18
|
+
# SHA256 of the v0.1.2 BeekonKit.xcframework.zip. Matches the SwiftPM
|
|
19
|
+
# `binaryTarget` checksum in beekon-ios-binary's Package.swift at tag v0.1.2
|
|
20
20
|
# (SwiftPM's compute-checksum is the SHA256 of the zip).
|
|
21
|
-
EXPECTED_SHA="
|
|
21
|
+
EXPECTED_SHA="43b1f959699654020f32d3e8e4e1de6aacba8e32628c69a7477c1b2ba084a4a4"
|
|
22
22
|
|
|
23
23
|
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
24
24
|
DEST_DIR="${ROOT}/ios/Frameworks"
|
package/src/NativeBeekonRn.ts
CHANGED
|
@@ -156,6 +156,9 @@ export type WireGeofence = {
|
|
|
156
156
|
radiusMeters: number;
|
|
157
157
|
notifyOnEntry: boolean;
|
|
158
158
|
notifyOnExit: boolean;
|
|
159
|
+
// Optional notification as a canonical JSON string (rendering is native-only).
|
|
160
|
+
// Flat string keeps Codegen happy and lets the payload schema grow without re-running codegen.
|
|
161
|
+
notificationJson?: string;
|
|
159
162
|
};
|
|
160
163
|
|
|
161
164
|
export type WireGeofenceEvent = {
|
|
@@ -218,6 +221,35 @@ export type WireLicenseStatus = {
|
|
|
218
221
|
reason: string | null;
|
|
219
222
|
};
|
|
220
223
|
|
|
224
|
+
/**
|
|
225
|
+
* Flat wire form of the current location-permission grant (read-only). `level`
|
|
226
|
+
* is the wire-stable identifier; `accuracy` is `''` (not null — Codegen has no
|
|
227
|
+
* portable nullable-enum) when location is not granted, else 'full' | 'reduced'.
|
|
228
|
+
*/
|
|
229
|
+
export type WirePermissionStatus = {
|
|
230
|
+
/**
|
|
231
|
+
* One of: 'notDetermined' | 'denied' | 'restricted' | 'foreground' |
|
|
232
|
+
* 'background'.
|
|
233
|
+
*/
|
|
234
|
+
level: string;
|
|
235
|
+
/** 'full' | 'reduced', or '' when not granted. */
|
|
236
|
+
accuracy: string;
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Flat wire form of one `PermissionRequirement` (read-only). `permission` is one
|
|
241
|
+
* of 'location' | 'backgroundLocation' | 'activityRecognition' | 'notifications'
|
|
242
|
+
* ('notifications' Android-only); `importance` is 'required' | 'recommended'.
|
|
243
|
+
* The mappers translate to the public string-literal unions with a defensive
|
|
244
|
+
* fallback.
|
|
245
|
+
*/
|
|
246
|
+
export type WirePermissionRequirement = {
|
|
247
|
+
permission: string;
|
|
248
|
+
importance: string;
|
|
249
|
+
satisfied: boolean;
|
|
250
|
+
rationale: string;
|
|
251
|
+
};
|
|
252
|
+
|
|
221
253
|
export interface Spec extends TurboModule {
|
|
222
254
|
/**
|
|
223
255
|
* The config crosses as an untyped object (`ReadableMap` on Android,
|
|
@@ -267,6 +299,19 @@ export interface Spec extends TurboModule {
|
|
|
267
299
|
*/
|
|
268
300
|
licenseStatus(): Promise<WireLicenseStatus>;
|
|
269
301
|
|
|
302
|
+
/**
|
|
303
|
+
* The current location-permission grant (read-only; never prompts). For
|
|
304
|
+
* pre-start checks — during tracking, permission loss surfaces on `onState`.
|
|
305
|
+
*/
|
|
306
|
+
getPermissionStatus(): Promise<WirePermissionStatus>;
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* The permissions Beekon needs for the active configuration, each marked
|
|
310
|
+
* satisfied against the live grant (read-only; never prompts). The config-aware
|
|
311
|
+
* companion to `getPermissionStatus`. Call after `configure`.
|
|
312
|
+
*/
|
|
313
|
+
getRequiredPermissions(): Promise<WirePermissionRequirement[]>;
|
|
314
|
+
|
|
270
315
|
/** Persisted diagnostic log entries in `[fromMs, toMs]`, oldest first. */
|
|
271
316
|
getLog(fromMs: number, toMs: number): Promise<WireLogEntry[]>;
|
|
272
317
|
/** Serialize the whole log buffer to an NDJSON file; resolves its path. */
|
package/src/beekon.ts
CHANGED
|
@@ -7,6 +7,10 @@ import type { BeekonGeofence, GeofenceEvent } from './types/geofence';
|
|
|
7
7
|
import type { LicenseStatus } from './types/license';
|
|
8
8
|
import type { Location } from './types/location';
|
|
9
9
|
import type { LogEntry } from './types/log';
|
|
10
|
+
import type {
|
|
11
|
+
PermissionRequirement,
|
|
12
|
+
PermissionStatus,
|
|
13
|
+
} from './types/permission';
|
|
10
14
|
import type { BeekonState } from './types/state';
|
|
11
15
|
import type { SyncStatus } from './types/sync';
|
|
12
16
|
import {
|
|
@@ -20,6 +24,8 @@ import {
|
|
|
20
24
|
wireToLicenseStatus,
|
|
21
25
|
wireToLocation,
|
|
22
26
|
wireToLogEntry,
|
|
27
|
+
wireToPermissionRequirement,
|
|
28
|
+
wireToPermissionStatus,
|
|
23
29
|
wireToState,
|
|
24
30
|
wireToSyncStatus,
|
|
25
31
|
} from './internal/mappers';
|
|
@@ -354,6 +360,33 @@ class BeekonImpl {
|
|
|
354
360
|
return wireToLicenseStatus(await NativeBeekon.licenseStatus());
|
|
355
361
|
}
|
|
356
362
|
|
|
363
|
+
/**
|
|
364
|
+
* The current location-permission grant — a point-in-time read for
|
|
365
|
+
* **pre-start** checks, returned without ever prompting. Beekon never requests
|
|
366
|
+
* permission; the app owns that. A snapshot, not an observer: once tracking is
|
|
367
|
+
* running, permission loss surfaces on `onState` as
|
|
368
|
+
* `{ kind: 'stopped', reason: 'permissionDenied' }`. On Android, "not yet
|
|
369
|
+
* asked" and "denied" both report `'notDetermined'`; `'restricted'` is iOS-only.
|
|
370
|
+
*/
|
|
371
|
+
async getPermissionStatus(): Promise<PermissionStatus> {
|
|
372
|
+
return wireToPermissionStatus(await NativeBeekon.getPermissionStatus());
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* The permissions Beekon needs **for the current configuration**, each marked
|
|
377
|
+
* `satisfied` against the live grant — the config-aware "doctor" companion to
|
|
378
|
+
* `getPermissionStatus()`. Unlike that location-only snapshot, this reports
|
|
379
|
+
* activity-recognition (and, on Android, notifications) too, derived from the
|
|
380
|
+
* active mode and tracking config. Read-only; never prompts. Call after
|
|
381
|
+
* `configure()`; in cloud mode (server-owned config) it returns the
|
|
382
|
+
* conservative list.
|
|
383
|
+
*/
|
|
384
|
+
async getRequiredPermissions(): Promise<PermissionRequirement[]> {
|
|
385
|
+
return (await NativeBeekon.getRequiredPermissions()).map(
|
|
386
|
+
wireToPermissionRequirement
|
|
387
|
+
);
|
|
388
|
+
}
|
|
389
|
+
|
|
357
390
|
/**
|
|
358
391
|
* Read persisted diagnostic log entries in the inclusive range `[from, to]`,
|
|
359
392
|
* oldest first. Entries survive process death, so this recovers what the SDK
|
package/src/index.tsx
CHANGED
|
@@ -26,9 +26,21 @@ export type { Location } from './types/location';
|
|
|
26
26
|
export type {
|
|
27
27
|
BeekonGeofence,
|
|
28
28
|
GeofenceEvent,
|
|
29
|
+
GeofenceNotification,
|
|
30
|
+
NotificationContent,
|
|
31
|
+
NotificationDelivery,
|
|
32
|
+
NotificationImportance,
|
|
29
33
|
Transition,
|
|
30
34
|
} from './types/geofence';
|
|
31
35
|
export type { BeekonState, StopReason } from './types/state';
|
|
36
|
+
export type {
|
|
37
|
+
PermissionStatus,
|
|
38
|
+
PermissionLevel,
|
|
39
|
+
PermissionAccuracy,
|
|
40
|
+
BeekonPermission,
|
|
41
|
+
PermissionImportance,
|
|
42
|
+
PermissionRequirement,
|
|
43
|
+
} from './types/permission';
|
|
32
44
|
export type { SyncStatus, SyncFailure } from './types/sync';
|
|
33
45
|
export type { LicenseStatus, LicenseInvalidReason } from './types/license';
|
|
34
46
|
export { BeekonError, type BeekonErrorKind } from './types/error';
|
package/src/internal/mappers.ts
CHANGED
|
@@ -15,10 +15,22 @@ import type { LogEntry } from '../types/log';
|
|
|
15
15
|
import type {
|
|
16
16
|
BeekonGeofence,
|
|
17
17
|
GeofenceEvent,
|
|
18
|
+
GeofenceNotification,
|
|
19
|
+
NotificationContent,
|
|
20
|
+
NotificationDelivery,
|
|
21
|
+
NotificationImportance,
|
|
18
22
|
Transition,
|
|
19
23
|
} from '../types/geofence';
|
|
20
24
|
import type { LicenseInvalidReason, LicenseStatus } from '../types/license';
|
|
21
25
|
import type { Location } from '../types/location';
|
|
26
|
+
import type {
|
|
27
|
+
BeekonPermission,
|
|
28
|
+
PermissionAccuracy,
|
|
29
|
+
PermissionImportance,
|
|
30
|
+
PermissionLevel,
|
|
31
|
+
PermissionRequirement,
|
|
32
|
+
PermissionStatus,
|
|
33
|
+
} from '../types/permission';
|
|
22
34
|
import type { BeekonState, StopReason } from '../types/state';
|
|
23
35
|
import type { SyncFailure, SyncStatus } from '../types/sync';
|
|
24
36
|
import { BeekonError, type BeekonErrorKind } from '../types/error';
|
|
@@ -32,6 +44,8 @@ import type {
|
|
|
32
44
|
WireLicenseStatus,
|
|
33
45
|
WireLocation,
|
|
34
46
|
WireLogEntry,
|
|
47
|
+
WirePermissionRequirement,
|
|
48
|
+
WirePermissionStatus,
|
|
35
49
|
WireState,
|
|
36
50
|
WireSyncStatus,
|
|
37
51
|
} from '../NativeBeekonRn';
|
|
@@ -152,7 +166,88 @@ export function geofenceToWire(g: BeekonGeofence): WireGeofence {
|
|
|
152
166
|
radiusMeters: g.radiusMeters,
|
|
153
167
|
notifyOnEntry: g.notifyOnEntry ?? true,
|
|
154
168
|
notifyOnExit: g.notifyOnExit ?? true,
|
|
169
|
+
notificationJson: notificationToJson(g.notification),
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Serialize a notification to the canonical JSON string the native SDKs understand
|
|
174
|
+
// (rendering is native-only). Optional keys are omitted; undefined ⇒ undefined.
|
|
175
|
+
function notificationToJson(
|
|
176
|
+
n: GeofenceNotification | undefined
|
|
177
|
+
): string | undefined {
|
|
178
|
+
if (!n) return undefined;
|
|
179
|
+
const obj: Record<string, unknown> = {
|
|
180
|
+
delivery: n.delivery === 'cloud' ? 'cloud' : 'local',
|
|
181
|
+
};
|
|
182
|
+
if (n.onEnter) obj.onEnter = contentToObj(n.onEnter);
|
|
183
|
+
if (n.onExit) obj.onExit = contentToObj(n.onExit);
|
|
184
|
+
return JSON.stringify(obj);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
function contentToObj(c: NotificationContent): Record<string, unknown> {
|
|
188
|
+
const obj: Record<string, unknown> = {
|
|
189
|
+
title: c.title,
|
|
190
|
+
body: c.body,
|
|
191
|
+
importance: c.importance === 'default' ? 'default' : 'high',
|
|
192
|
+
};
|
|
193
|
+
if (c.deepLink != null) obj.deepLink = c.deepLink;
|
|
194
|
+
if (c.data && Object.keys(c.data).length > 0) obj.data = c.data;
|
|
195
|
+
return obj;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Parse a canonical notification JSON string. Tolerant: malformed input, an unknown
|
|
199
|
+
// enum, or content missing title/body degrades to undefined/defaults.
|
|
200
|
+
function notificationFromJson(
|
|
201
|
+
json: string | undefined
|
|
202
|
+
): GeofenceNotification | undefined {
|
|
203
|
+
if (!json) return undefined;
|
|
204
|
+
let parsed: unknown;
|
|
205
|
+
try {
|
|
206
|
+
parsed = JSON.parse(json);
|
|
207
|
+
} catch {
|
|
208
|
+
return undefined;
|
|
209
|
+
}
|
|
210
|
+
if (typeof parsed !== 'object' || parsed === null) return undefined;
|
|
211
|
+
const obj = parsed as Record<string, unknown>;
|
|
212
|
+
const onEnter = contentFromObj(obj.onEnter);
|
|
213
|
+
const onExit = contentFromObj(obj.onExit);
|
|
214
|
+
if (!onEnter && !onExit) return undefined;
|
|
215
|
+
const delivery: NotificationDelivery =
|
|
216
|
+
obj.delivery === 'cloud' ? 'cloud' : 'local';
|
|
217
|
+
return {
|
|
218
|
+
delivery,
|
|
219
|
+
...(onEnter ? { onEnter } : {}),
|
|
220
|
+
...(onExit ? { onExit } : {}),
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
function contentFromObj(raw: unknown): NotificationContent | undefined {
|
|
225
|
+
if (typeof raw !== 'object' || raw === null) return undefined;
|
|
226
|
+
const r = raw as Record<string, unknown>;
|
|
227
|
+
if (
|
|
228
|
+
typeof r.title !== 'string' ||
|
|
229
|
+
typeof r.body !== 'string' ||
|
|
230
|
+
!r.title ||
|
|
231
|
+
!r.body
|
|
232
|
+
) {
|
|
233
|
+
return undefined;
|
|
234
|
+
}
|
|
235
|
+
const importance: NotificationImportance =
|
|
236
|
+
r.importance === 'default' ? 'default' : 'high';
|
|
237
|
+
const data: Record<string, string> = {};
|
|
238
|
+
if (typeof r.data === 'object' && r.data !== null) {
|
|
239
|
+
for (const [k, v] of Object.entries(r.data as Record<string, unknown>)) {
|
|
240
|
+
if (typeof v === 'string') data[k] = v;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
const content: NotificationContent = {
|
|
244
|
+
title: r.title,
|
|
245
|
+
body: r.body,
|
|
246
|
+
importance,
|
|
155
247
|
};
|
|
248
|
+
if (typeof r.deepLink === 'string') content.deepLink = r.deepLink;
|
|
249
|
+
if (Object.keys(data).length > 0) content.data = data;
|
|
250
|
+
return content;
|
|
156
251
|
}
|
|
157
252
|
|
|
158
253
|
// `expiresAt` (a `Date`) becomes epoch millis on the wire; the native side
|
|
@@ -234,6 +329,7 @@ export function wireToGeofence(w: WireGeofence): BeekonGeofence {
|
|
|
234
329
|
radiusMeters: w.radiusMeters,
|
|
235
330
|
notifyOnEntry: w.notifyOnEntry,
|
|
236
331
|
notifyOnExit: w.notifyOnExit,
|
|
332
|
+
notification: notificationFromJson(w.notificationJson),
|
|
237
333
|
};
|
|
238
334
|
}
|
|
239
335
|
|
|
@@ -274,6 +370,50 @@ export function wireToState(w: WireState): BeekonState {
|
|
|
274
370
|
}
|
|
275
371
|
}
|
|
276
372
|
|
|
373
|
+
export function wireToPermissionStatus(
|
|
374
|
+
w: WirePermissionStatus
|
|
375
|
+
): PermissionStatus {
|
|
376
|
+
const level = oneOf<PermissionLevel>(
|
|
377
|
+
w.level,
|
|
378
|
+
['notDetermined', 'denied', 'restricted', 'foreground', 'background'],
|
|
379
|
+
'notDetermined'
|
|
380
|
+
);
|
|
381
|
+
// '' is the wire encoding of null (not granted); an unknown non-empty value
|
|
382
|
+
// degrades to null rather than guessing a precision.
|
|
383
|
+
const accuracy: PermissionAccuracy | null =
|
|
384
|
+
w.accuracy === 'full' || w.accuracy === 'reduced' ? w.accuracy : null;
|
|
385
|
+
return {
|
|
386
|
+
level,
|
|
387
|
+
accuracy,
|
|
388
|
+
isAuthorized: level === 'foreground' || level === 'background',
|
|
389
|
+
canTrackInBackground: level === 'background',
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
export function wireToPermissionRequirement(
|
|
394
|
+
w: WirePermissionRequirement
|
|
395
|
+
): PermissionRequirement {
|
|
396
|
+
return {
|
|
397
|
+
permission: oneOf<BeekonPermission>(
|
|
398
|
+
w.permission,
|
|
399
|
+
[
|
|
400
|
+
'location',
|
|
401
|
+
'backgroundLocation',
|
|
402
|
+
'activityRecognition',
|
|
403
|
+
'notifications',
|
|
404
|
+
],
|
|
405
|
+
'location'
|
|
406
|
+
),
|
|
407
|
+
importance: oneOf<PermissionImportance>(
|
|
408
|
+
w.importance,
|
|
409
|
+
['required', 'recommended'],
|
|
410
|
+
'recommended'
|
|
411
|
+
),
|
|
412
|
+
satisfied: w.satisfied,
|
|
413
|
+
rationale: w.rationale,
|
|
414
|
+
};
|
|
415
|
+
}
|
|
416
|
+
|
|
277
417
|
export function wireToSyncStatus(w: WireSyncStatus): SyncStatus {
|
|
278
418
|
switch (w.type) {
|
|
279
419
|
case 'idle':
|
package/src/types/geofence.ts
CHANGED
|
@@ -16,6 +16,47 @@ export type BeekonGeofence = {
|
|
|
16
16
|
notifyOnEntry?: boolean;
|
|
17
17
|
/** Emit an event on exit. Default: `true`. */
|
|
18
18
|
notifyOnExit?: boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Optional per-geofence notification the SDK renders natively at crossing time —
|
|
21
|
+
* offline and even when the app is killed. Omit it to handle crossings yourself
|
|
22
|
+
* via `Beekon.onGeofenceEvent`. `onEnter` requires `notifyOnEntry`; `onExit`
|
|
23
|
+
* requires `notifyOnExit`; in self-managed mode `delivery` must be `'local'`.
|
|
24
|
+
*/
|
|
25
|
+
notification?: GeofenceNotification;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/** Where a geofence-crossing notification is delivered. Mirrors `NotificationDelivery` on the natives. */
|
|
29
|
+
export type NotificationDelivery = 'local' | 'cloud';
|
|
30
|
+
|
|
31
|
+
/** Relative prominence of a geofence notification. Mirrors `NotificationImportance`. */
|
|
32
|
+
export type NotificationImportance = 'high' | 'default';
|
|
33
|
+
|
|
34
|
+
/** Per-direction content the SDK renders natively for a geofence crossing. */
|
|
35
|
+
export type NotificationContent = {
|
|
36
|
+
/** Notification title. */
|
|
37
|
+
title: string;
|
|
38
|
+
/** Notification body. */
|
|
39
|
+
body: string;
|
|
40
|
+
/** Relative prominence. Default `'high'`. */
|
|
41
|
+
importance?: NotificationImportance;
|
|
42
|
+
/** Optional deep-link URI delivered in the notification for the host to route on tap. */
|
|
43
|
+
deepLink?: string;
|
|
44
|
+
/** Optional flat string payload delivered in the notification for routing on tap. */
|
|
45
|
+
data?: Record<string, string>;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* An optional per-geofence notification rendered natively at crossing time.
|
|
50
|
+
* Mirrors `GeofenceNotification` on both native SDKs. The presence of `onEnter` /
|
|
51
|
+
* `onExit` selects which directions notify.
|
|
52
|
+
*/
|
|
53
|
+
export type GeofenceNotification = {
|
|
54
|
+
/** Delivery channel. `'local'` (offline, device-rendered) is the default and only implemented mode. */
|
|
55
|
+
delivery: NotificationDelivery;
|
|
56
|
+
/** Content rendered on entry. Requires `notifyOnEntry`. */
|
|
57
|
+
onEnter?: NotificationContent;
|
|
58
|
+
/** Content rendered on exit. Requires `notifyOnExit`. */
|
|
59
|
+
onExit?: NotificationContent;
|
|
19
60
|
};
|
|
20
61
|
|
|
21
62
|
/** Whether a {@link GeofenceEvent} marks entering or exiting a geofence. */
|