@ansight/react-native 1.4.0-preview.5 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -10
- package/android/build.gradle +2 -2
- package/android/src/main/kotlin/ai/ansight/reactnative/AnsightReactNativeModule.kt +15 -1
- package/expo-plugin.js +2 -2
- package/index.d.ts +9 -2
- package/index.js +8 -0
- package/ios/AnsightReactNative.swift +11 -1
- package/ios/AnsightReactNativeModule.m +4 -0
- package/package.json +5 -3
- package/purchases.d.ts +61 -0
- package/purchases.js +17 -0
package/README.md
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
# @ansight/react-native
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Ansight gives coding agents the runtime evidence to verify their own work in
|
|
4
|
+
React Native and Expo development builds. The SDK captures screenshots, visual trees, touches, logs,
|
|
5
|
+
crashes and unhandled errors, HTTP requests, screen views and navigation, lifecycle events, app events, custom metrics, and sampled memory,
|
|
6
|
+
FPS, frame timing, and battery while the app runs, and exposes app state,
|
|
7
|
+
preferences, secure storage, files, SQLite, artifacts, and your own custom
|
|
8
|
+
tools through guarded remote tools on request. Your agent reads all of it
|
|
9
|
+
through the `ansight` CLI. Nothing leaves your machine unless you export or
|
|
10
|
+
share it. See https://www.ansight.ai and the
|
|
11
|
+
[getting started guide](https://www.ansight.ai/docs/getting-started).
|
|
4
12
|
|
|
5
13
|
The package is intentionally thin: pairing, transport, telemetry, screen
|
|
6
14
|
capture, touch capture, native tool discovery, and native tool execution are
|
|
@@ -80,8 +88,8 @@ bundle; its API requires the native Ansight module.
|
|
|
80
88
|
|
|
81
89
|
This package version expects matching native SDK packages:
|
|
82
90
|
|
|
83
|
-
- CocoaPods: `Ansight`, `AnsightObjC` version `1.
|
|
84
|
-
- Maven: `ai.ansight:ansight-android:1.
|
|
91
|
+
- CocoaPods: `Ansight`, `AnsightObjC` version `1.5.0`
|
|
92
|
+
- Maven: `ai.ansight:ansight-android:1.5.0`
|
|
85
93
|
|
|
86
94
|
## Quickstart
|
|
87
95
|
|
|
@@ -144,9 +152,9 @@ where reconnects should only happen after an explicit app action.
|
|
|
144
152
|
> max-width settings, and disable `sessionJpegCapture` for performance-focused
|
|
145
153
|
> runs unless visual evidence is required.
|
|
146
154
|
|
|
147
|
-
For simulator/emulator sessions,
|
|
155
|
+
For simulator/emulator sessions, host can acknowledge the native
|
|
148
156
|
`device.profile` with host screenshot mode. The native SDK then suspends
|
|
149
|
-
periodic in-app JPEG capture for that session so
|
|
157
|
+
periodic in-app JPEG capture for that session so host can use a host-side
|
|
150
158
|
source such as `simctl` or `adb`.
|
|
151
159
|
|
|
152
160
|
## Options
|
|
@@ -156,7 +164,7 @@ The TypeScript `AnsightOptions` surface mirrors Android `AnsightOptions`, iOS
|
|
|
156
164
|
|
|
157
165
|
| Option | Purpose |
|
|
158
166
|
| --- | --- |
|
|
159
|
-
| `useNativeAllInOneDefaults` | Applies native iOS/Android all-in-one defaults when true. Defaults to false. This enables the native visual-tree/screenshot tools required by
|
|
167
|
+
| `useNativeAllInOneDefaults` | Applies native iOS/Android all-in-one defaults when true. Defaults to false. This enables the native visual-tree/screenshot tools required by host visual tree inspection unless `remoteTools.visualTree` is explicitly false. Configure `toolGuard`, capture options, and `hostConnection` separately. |
|
|
160
168
|
| `clientName` | Default client name for host auto-probe and connections. |
|
|
161
169
|
| `sampleFrequencyMilliseconds` | Built-in telemetry sampling interval. |
|
|
162
170
|
| `retentionPeriodSeconds` | Local metric/event retention window. |
|
|
@@ -273,7 +281,7 @@ app-side policy for inspection or testing.
|
|
|
273
281
|
|
|
274
282
|
## Native Tool Options
|
|
275
283
|
|
|
276
|
-
`remoteTools` configures the native tool suites registered by the bridge. `useNativeAllInOneDefaults: true` enables visual tree tools by default so
|
|
284
|
+
`remoteTools` configures the native tool suites registered by the bridge. `useNativeAllInOneDefaults: true` enables visual tree tools by default so host can pair `ui.get_visual_tree` data with `ui.get_screenshot` frames. Apps that do not use all-in-one defaults can opt in explicitly:
|
|
277
285
|
|
|
278
286
|
```ts
|
|
279
287
|
await Ansight.initializeAndActivate(
|
|
@@ -472,7 +480,7 @@ locale; if the app selects a different language through an i18n library, set
|
|
|
472
480
|
|
|
473
481
|
## JavaScript Tools
|
|
474
482
|
|
|
475
|
-
Custom JavaScript tools can be exposed to Ansight
|
|
483
|
+
Custom JavaScript tools can be exposed to Ansight host:
|
|
476
484
|
|
|
477
485
|
```ts
|
|
478
486
|
const registration = Ansight.registerTool(
|
|
@@ -547,7 +555,7 @@ await reportProvider.ready;
|
|
|
547
555
|
The first provider installs the `read` policy `artifacts.query` and
|
|
548
556
|
`artifacts.request` JavaScript tools in the native registry. A provider can
|
|
549
557
|
return text, base64, byte arrays, `ArrayBuffer`, or `Uint8Array`. Artifact
|
|
550
|
-
requests require a live
|
|
558
|
+
requests require a live host tool call; the bridge forwards the returned
|
|
551
559
|
bytes through the native binary-transfer channel. Call
|
|
552
560
|
`reportProvider.unregister()` during teardown or hot-reload cleanup.
|
|
553
561
|
|
|
@@ -670,5 +678,9 @@ The current-Expo validation app lives in:
|
|
|
670
678
|
|
|
671
679
|
It is pinned to Expo SDK 57 and React Native 0.86 with the New Architecture and
|
|
672
680
|
Hermes enabled. It validates Expo CNG/autolinking, the bundled config plugin,
|
|
673
|
-
Android and iOS native builds, and the same live
|
|
681
|
+
Android and iOS native builds, and the same live host feature surface as the
|
|
674
682
|
baseline harness.
|
|
683
|
+
|
|
684
|
+
## Purchase diagnostics
|
|
685
|
+
|
|
686
|
+
See [purchase observations, adapters, and remote validation](../../docs/purchases.md) for the base SDK purchase suite.
|
package/android/build.gradle
CHANGED
|
@@ -67,6 +67,6 @@ repositories {
|
|
|
67
67
|
dependencies {
|
|
68
68
|
implementation("com.facebook.react:react-android")
|
|
69
69
|
def ansightAndroidVersion =
|
|
70
|
-
findProperty("ansightAndroidVersion") ?: "1.
|
|
71
|
-
implementation("ai.ansight:ansight-android:1.
|
|
70
|
+
findProperty("ansightAndroidVersion") ?: "1.5.0"
|
|
71
|
+
implementation("ai.ansight:ansight-android:1.5.0")
|
|
72
72
|
}
|
|
@@ -48,6 +48,8 @@ import ai.ansight.tools.filesystem.AndroidFileSystemRoot
|
|
|
48
48
|
import ai.ansight.tools.filesystem.AndroidFileSystemToolsOptions
|
|
49
49
|
import ai.ansight.tools.filesystem.withFileSystemTools
|
|
50
50
|
import ai.ansight.tools.preferences.AndroidPreferencesToolsOptions
|
|
51
|
+
import ai.ansight.tools.clipboard.ClipboardToolIds
|
|
52
|
+
import ai.ansight.tools.clipboard.withClipboardTools
|
|
51
53
|
import ai.ansight.tools.preferences.withPreferencesTools
|
|
52
54
|
import ai.ansight.tools.reflection.AndroidReflectionToolsOptions
|
|
53
55
|
import ai.ansight.tools.reflection.withReflectionTools
|
|
@@ -135,6 +137,13 @@ class AnsightReactNativeModule(
|
|
|
135
137
|
|
|
136
138
|
override fun onHostDestroy() = Unit
|
|
137
139
|
|
|
140
|
+
@ReactMethod
|
|
141
|
+
fun purchaseCommand(json: String, promise: Promise) {
|
|
142
|
+
try { promise.resolve(ai.ansight.runtime.purchases.PurchaseDiagnostics.shared.command(json)) }
|
|
143
|
+
catch (error: ai.ansight.runtime.purchases.PurchaseEnvironmentException) { promise.reject(ai.ansight.runtime.purchases.PurchaseEnvironmentException.ERROR_CODE, error.message, error) }
|
|
144
|
+
catch (error: Exception) { promise.reject("purchases_command_failed", "Purchase command failed.", error) }
|
|
145
|
+
}
|
|
146
|
+
|
|
138
147
|
@ReactMethod
|
|
139
148
|
fun addListener(eventName: String) {
|
|
140
149
|
listenerCount.incrementAndGet()
|
|
@@ -894,7 +903,7 @@ class AnsightReactNativeModule(
|
|
|
894
903
|
val crash = map.getMapOrNull("crashCapture")
|
|
895
904
|
AnsightCrashCaptureOptions(
|
|
896
905
|
enabled = crash.booleanValue("enabled", true),
|
|
897
|
-
|
|
906
|
+
hostHandoffEnabled = crash.booleanValue("hostHandoffEnabled", true),
|
|
898
907
|
offlineCaptureAttachmentEnabled = crash.booleanValue("offlineCaptureAttachmentEnabled", true),
|
|
899
908
|
maximumPendingReports = crash.intValue("maximumPendingReports", 8),
|
|
900
909
|
retentionDays = crash.intValue("retentionDays", 7),
|
|
@@ -962,6 +971,11 @@ class AnsightReactNativeModule(
|
|
|
962
971
|
): AnsightOptions {
|
|
963
972
|
val remoteTools = map.getMapOrNull("remoteTools")
|
|
964
973
|
val builder = AnsightOptions.createBuilder(this)
|
|
974
|
+
val clipboardIds = setOf(ClipboardToolIds.GetText, ClipboardToolIds.HasText, ClipboardToolIds.SetText, ClipboardToolIds.Clear)
|
|
975
|
+
builder.withTools(initialTools.filterNot { it.definition.id in clipboardIds })
|
|
976
|
+
if (remoteTools.booleanValue("clipboard", true)) {
|
|
977
|
+
builder.withClipboardTools()
|
|
978
|
+
}
|
|
965
979
|
if (remoteTools.toolSuiteEnabled("visualTree", enableVisualTreeToolsByDefault)) {
|
|
966
980
|
builder.withVisualTreeTools()
|
|
967
981
|
}
|
package/expo-plugin.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
const DEFAULT_CAMERA_PERMISSION =
|
|
4
|
-
"Allow $(PRODUCT_NAME) to use the camera to scan an Ansight
|
|
4
|
+
"Allow $(PRODUCT_NAME) to use the camera to scan an Ansight host enrollment QR code.";
|
|
5
5
|
const DEFAULT_LOCAL_NETWORK_PERMISSION =
|
|
6
|
-
"Allow $(PRODUCT_NAME) to connect to Ansight
|
|
6
|
+
"Allow $(PRODUCT_NAME) to connect to Ansight host on your local network during development.";
|
|
7
7
|
|
|
8
8
|
function withAnsightReactNative(config, options = {}) {
|
|
9
9
|
const { withInfoPlist } = loadExpoConfigPlugins();
|
package/index.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import type { PurchaseDiagnostics } from "./purchases";
|
|
2
|
+
export * from "./purchases";
|
|
3
|
+
export const purchases: PurchaseDiagnostics;
|
|
1
4
|
export type AnsightLifecycleState = "unknown" | "foreground" | "background";
|
|
2
5
|
export type AnsightToolPolicy = "read" | "write" | "critical";
|
|
3
6
|
|
|
@@ -144,6 +147,8 @@ export interface AnsightVisualTreeToolsOptions {
|
|
|
144
147
|
}
|
|
145
148
|
|
|
146
149
|
export interface AnsightRemoteToolsOptions {
|
|
150
|
+
/** Include native clipboard tools; defaults to true. */
|
|
151
|
+
clipboard?: boolean;
|
|
147
152
|
visualTree?: boolean | AnsightVisualTreeToolsOptions;
|
|
148
153
|
fileSystem?: AnsightFileSystemToolsOptions;
|
|
149
154
|
database?: AnsightDatabaseToolsOptions;
|
|
@@ -217,7 +222,7 @@ export interface AnsightOptions {
|
|
|
217
222
|
|
|
218
223
|
export interface AnsightCrashCaptureOptions {
|
|
219
224
|
enabled?: boolean;
|
|
220
|
-
|
|
225
|
+
hostHandoffEnabled?: boolean;
|
|
221
226
|
offlineCaptureAttachmentEnabled?: boolean;
|
|
222
227
|
maximumPendingReports?: number;
|
|
223
228
|
retentionDays?: number;
|
|
@@ -392,6 +397,7 @@ export class AnsightOptionsBuilder {
|
|
|
392
397
|
withoutVisualTreeTools(): this;
|
|
393
398
|
withFileSystemTools(options?: AnsightFileSystemToolsOptions): this;
|
|
394
399
|
withDatabaseTools(options?: AnsightDatabaseToolsOptions): this;
|
|
400
|
+
withClipboardTools(enabled?: boolean): this;
|
|
395
401
|
withPreferencesTools(options?: AnsightPreferencesToolsOptions): this;
|
|
396
402
|
withReflectionTools(options?: AnsightReflectionToolsOptions): this;
|
|
397
403
|
build(): AnsightOptions;
|
|
@@ -617,7 +623,7 @@ export function screenViewed(name: string, details?: Record<string, string>): Pr
|
|
|
617
623
|
export function trackRoute(name: string, details?: Record<string, string>): Promise<AnsightDebugSnapshot>;
|
|
618
624
|
export function setAppLifecycleState(state: AnsightLifecycleState): Promise<AnsightDebugSnapshot>;
|
|
619
625
|
export function connect(pairingPayload?: string | object | null, options?: AnsightConnectOptions): Promise<AnsightHostConnectionResult>;
|
|
620
|
-
/** Scans a one-use
|
|
626
|
+
/** Scans a one-use host invite, registers this installation, and saves automatic reconnect state. */
|
|
621
627
|
export function enrollFromQrCode(options?: AnsightScanPairingOptions): Promise<AnsightHostConnectionResult>;
|
|
622
628
|
export function scanPairingQrCode(options?: AnsightScanPairingOptions): Promise<AnsightHostConnectionResult>;
|
|
623
629
|
export function openSession(pairingPayload: string | object, options?: AnsightOpenSessionOptions): Promise<AnsightHostConnectionResult>;
|
|
@@ -676,6 +682,7 @@ export function installErrorHandlers(options?: { chain?: boolean }): () => void;
|
|
|
676
682
|
export function createReactNavigationTracker(navigationRef: unknown, options?: { recordInitial?: boolean }): ReactNavigationTracker;
|
|
677
683
|
|
|
678
684
|
declare const Ansight: {
|
|
685
|
+
purchases: PurchaseDiagnostics;
|
|
679
686
|
initialize: typeof initialize;
|
|
680
687
|
initializeAndActivate: typeof initializeAndActivate;
|
|
681
688
|
activate: typeof activate;
|
package/index.js
CHANGED
|
@@ -608,6 +608,11 @@ class AnsightOptionsBuilder {
|
|
|
608
608
|
return this;
|
|
609
609
|
}
|
|
610
610
|
|
|
611
|
+
withClipboardTools(enabled = true) {
|
|
612
|
+
this._options.remoteTools = { ...this._options.remoteTools, clipboard: enabled };
|
|
613
|
+
return this;
|
|
614
|
+
}
|
|
615
|
+
|
|
611
616
|
withPreferencesTools(options = {}) {
|
|
612
617
|
this._options.remoteTools = {
|
|
613
618
|
...(this._options.remoteTools || {}),
|
|
@@ -2669,3 +2674,6 @@ module.exports.recordNetworkRequest = recordNetworkRequest;
|
|
|
2669
2674
|
module.exports.installNetworkCapture = installNetworkCapture;
|
|
2670
2675
|
module.exports.uninstallNetworkCapture = uninstallNetworkCapture;
|
|
2671
2676
|
module.exports.sanitizeNetworkRequest = sanitizeNetworkRequest;
|
|
2677
|
+
|
|
2678
|
+
module.exports.purchases = require("./purchases").createPurchaseDiagnostics((json) => nativeModule.purchaseCommand(json));
|
|
2679
|
+
module.exports.createPurchaseDiagnostics = require("./purchases").createPurchaseDiagnostics;
|
|
@@ -4,6 +4,15 @@ import React
|
|
|
4
4
|
|
|
5
5
|
@objc(AnsightReactNative)
|
|
6
6
|
final class AnsightReactNative: RCTEventEmitter {
|
|
7
|
+
@objc(purchaseCommand:resolver:rejecter:)
|
|
8
|
+
func purchaseCommand(_ json: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) {
|
|
9
|
+
Task {
|
|
10
|
+
do { resolve(try await PurchaseDiagnostics.shared.commandAsync(json)) }
|
|
11
|
+
catch PurchaseDiagnosticsError.environmentNotAllowed { reject(PurchaseDiagnosticsError.environmentErrorCode, "Purchase interop is restricted to simulators and emulators.", PurchaseDiagnosticsError.environmentNotAllowed) }
|
|
12
|
+
catch { reject("purchases_command_failed", "Purchase command failed.", error) }
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
7
16
|
private final class PendingToolCall {
|
|
8
17
|
let semaphore = DispatchSemaphore(value: 0)
|
|
9
18
|
var result: AnsightToolExecutionResult?
|
|
@@ -1093,7 +1102,7 @@ final class AnsightReactNative: RCTEventEmitter {
|
|
|
1093
1102
|
} else if let crash = raw as? NSDictionary {
|
|
1094
1103
|
options.crashCapture = AnsightCrashCaptureOptions(
|
|
1095
1104
|
enabled: boolValue(crash, "enabled", defaultValue: true),
|
|
1096
|
-
|
|
1105
|
+
hostHandoffEnabled: boolValue(crash, "hostHandoffEnabled", defaultValue: true),
|
|
1097
1106
|
offlineCaptureAttachmentEnabled: boolValue(crash, "offlineCaptureAttachmentEnabled", defaultValue: true),
|
|
1098
1107
|
maximumPendingReports: intValue(crash, "maximumPendingReports", defaultValue: 8),
|
|
1099
1108
|
retentionDays: intValue(crash, "retentionDays", defaultValue: 7),
|
|
@@ -1153,6 +1162,7 @@ final class AnsightReactNative: RCTEventEmitter {
|
|
|
1153
1162
|
remoteTools?["visualTree"],
|
|
1154
1163
|
defaultValue: useNativeAllInOneDefaults
|
|
1155
1164
|
),
|
|
1165
|
+
clipboard: boolValue(remoteTools, "clipboard", defaultValue: true),
|
|
1156
1166
|
database: databaseToolsOptions(remoteTools?["database"] as? NSDictionary),
|
|
1157
1167
|
fileSystem: fileSystemToolsOptions(remoteTools?["fileSystem"] as? NSDictionary),
|
|
1158
1168
|
preferences: preferencesToolsOptions(remoteTools?["preferences"] as? NSDictionary),
|
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
|
|
4
4
|
@interface RCT_EXTERN_MODULE(AnsightReactNative, RCTEventEmitter)
|
|
5
5
|
|
|
6
|
+
RCT_EXTERN_METHOD(purchaseCommand:(NSString *)json
|
|
7
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
8
|
+
rejecter:(RCTPromiseRejectBlock)reject)
|
|
9
|
+
|
|
6
10
|
RCT_EXTERN_METHOD(initialize:(NSDictionary *)options
|
|
7
11
|
resolver:(RCTPromiseResolveBlock)resolve
|
|
8
12
|
rejecter:(RCTPromiseRejectBlock)reject)
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ansight/react-native",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "React Native bridge for
|
|
3
|
+
"version": "1.5.0",
|
|
4
|
+
"description": "React Native bridge for Ansight: runtime evidence from your app for coding agents. Screenshots, UI trees, logs, network, telemetry, and app state.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
7
7
|
"license": "SEE LICENSE IN LICENSE",
|
|
@@ -34,7 +34,9 @@
|
|
|
34
34
|
"expo-plugin.js",
|
|
35
35
|
"tsconfig.json",
|
|
36
36
|
"AnsightReactNative.podspec",
|
|
37
|
-
"react-native.config.js"
|
|
37
|
+
"react-native.config.js",
|
|
38
|
+
"purchases.js",
|
|
39
|
+
"purchases.d.ts"
|
|
38
40
|
],
|
|
39
41
|
"keywords": [
|
|
40
42
|
"ansight",
|
package/purchases.d.ts
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
export interface PurchaseObservation {
|
|
2
|
+
productId: string;
|
|
3
|
+
source: "store" | "app" | "backend";
|
|
4
|
+
transactionRef?: string | null;
|
|
5
|
+
observedAt?: number;
|
|
6
|
+
state?: "unknown" | "pending" | "purchased" | "cancelled" | "expired" | "revoked" | "failed" | "gracePeriod" | "billingRetry";
|
|
7
|
+
verification?: "unknown" | "verified" | "unverified";
|
|
8
|
+
entitled?: boolean | null;
|
|
9
|
+
deliveryCount?: number | null;
|
|
10
|
+
finished?: boolean | null;
|
|
11
|
+
acknowledged?: boolean | null;
|
|
12
|
+
consumed?: boolean | null;
|
|
13
|
+
expiresAt?: number | null;
|
|
14
|
+
gracePeriodExpiresAt?: number | null;
|
|
15
|
+
environment?: "unknown" | "xcode" | "sandbox" | "production";
|
|
16
|
+
productType?: "unknown" | "consumable" | "nonConsumable" | "subscription" | "nonRenewingSubscription";
|
|
17
|
+
}
|
|
18
|
+
export interface PurchaseProduct {
|
|
19
|
+
productId: string;
|
|
20
|
+
available: boolean;
|
|
21
|
+
observedAt?: number;
|
|
22
|
+
displayPrice?: string | null;
|
|
23
|
+
price?: string | null;
|
|
24
|
+
currencyCode?: string | null;
|
|
25
|
+
productType?: PurchaseObservation["productType"];
|
|
26
|
+
}
|
|
27
|
+
export interface PurchaseExpectations {
|
|
28
|
+
transactionRef?: string;
|
|
29
|
+
productId: string;
|
|
30
|
+
expectedEntitled: boolean;
|
|
31
|
+
requireVerified?: boolean;
|
|
32
|
+
requireBackendVerification?: boolean;
|
|
33
|
+
expectedDeliveryCount?: number;
|
|
34
|
+
maxAgeMilliseconds?: number;
|
|
35
|
+
}
|
|
36
|
+
export interface PurchaseSnapshot {
|
|
37
|
+
schema: "ansight.purchases.v1";
|
|
38
|
+
capturedAt: number;
|
|
39
|
+
droppedEvents: number;
|
|
40
|
+
coverage: "observedOnly";
|
|
41
|
+
observations: PurchaseObservation[];
|
|
42
|
+
products: PurchaseProduct[];
|
|
43
|
+
}
|
|
44
|
+
export interface PurchaseValidationReport extends PurchaseSnapshot {
|
|
45
|
+
status: "pass" | "fail" | "inconclusive";
|
|
46
|
+
checks: { source: string; status: "pass" | "fail" | "inconclusive"; reason: string }[];
|
|
47
|
+
}
|
|
48
|
+
export interface PurchaseDiagnostics {
|
|
49
|
+
createTransactionReference(identifier: string): Promise<{ transactionRef: string }>;
|
|
50
|
+
/** Register read-only remote tools after SDK initialization. */
|
|
51
|
+
register(): Promise<{ success: boolean }>;
|
|
52
|
+
record(observation: PurchaseObservation): Promise<{ success: boolean }>;
|
|
53
|
+
recordProduct(product: PurchaseProduct): Promise<{ success: boolean }>;
|
|
54
|
+
/** Clear evidence on account switch. Does not clear store transactions. */
|
|
55
|
+
clear(): Promise<{ success: boolean }>;
|
|
56
|
+
snapshot(productId?: string): Promise<PurchaseSnapshot>;
|
|
57
|
+
validate(expectations: PurchaseExpectations): Promise<PurchaseValidationReport>;
|
|
58
|
+
/** Apple only. Reads StoreKit 2 using known product IDs. */
|
|
59
|
+
refreshStoreKit(productIds: string[]): Promise<PurchaseSnapshot>;
|
|
60
|
+
}
|
|
61
|
+
export function createPurchaseDiagnostics(send: (json: string) => Promise<string>): PurchaseDiagnostics;
|
package/purchases.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
// All observation retention, validation and tools live in the native base SDK.
|
|
4
|
+
function createPurchaseDiagnostics(send) {
|
|
5
|
+
const command = async (action, fields = {}) => JSON.parse(await send(JSON.stringify({ action, ...fields })));
|
|
6
|
+
return {
|
|
7
|
+
createTransactionReference: (identifier) => command("reference", { identifier }),
|
|
8
|
+
register: () => command("register"),
|
|
9
|
+
record: (observation) => command("record", { observation: { observedAt: Date.now(), ...observation } }),
|
|
10
|
+
recordProduct: (product) => command("recordProduct", { product: { observedAt: Date.now(), productType: "unknown", ...product } }),
|
|
11
|
+
clear: () => command("clear"),
|
|
12
|
+
snapshot: (productId) => command("purchases.get_state", { arguments: productId === undefined ? {} : { productId } }),
|
|
13
|
+
validate: (expectations) => command("purchases.validate", { arguments: expectations }),
|
|
14
|
+
refreshStoreKit: (productIds) => command("refreshStoreKit", { productIds }),
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
module.exports = { createPurchaseDiagnostics };
|