@advenue/react-native 0.6.0 → 0.6.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/dist/index.cjs +827 -0
- package/dist/index.d.cts +346 -0
- package/dist/index.d.ts +4 -4
- package/dist/index.js +149 -12
- package/package.json +8 -4
- package/scripts/check-dist.mjs +31 -0
- package/src/index.ts +4 -0
- package/src/native-require.cjs +23 -0
- package/src/native-require.d.cts +4 -0
- package/src/native.ts +15 -13
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
import { StorageAdapter, SecureStorageAdapter, DeepLink, AdvenueConfig, AdvenueClient, TrackOptions, Consent, DeviceInfo } from '@advenue/sdk-core';
|
|
2
|
+
export { AdvenueConfig, Consent, DeepLink, TrackOptions } from '@advenue/sdk-core';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Minimal structural type for the bits of `react-native-mmkv`'s MMKV instance
|
|
6
|
+
* we use. Declared locally so this package needs no react-native types at
|
|
7
|
+
* compile time — the app injects a real `new MMKV()` instance at runtime.
|
|
8
|
+
*/
|
|
9
|
+
interface MMKVLike {
|
|
10
|
+
set(key: string, value: string): void;
|
|
11
|
+
getString(key: string): string | undefined;
|
|
12
|
+
delete(key: string): void;
|
|
13
|
+
}
|
|
14
|
+
/** Wraps an MMKV instance as an Advenue StorageAdapter (synchronous, fast). */
|
|
15
|
+
declare function createMMKVStorage(mmkv: MMKVLike): StorageAdapter;
|
|
16
|
+
|
|
17
|
+
interface InstallReferrerResult {
|
|
18
|
+
referrer: string;
|
|
19
|
+
/** Device-clock: referrerClickTimestampSeconds. */
|
|
20
|
+
clickTimestamp: number;
|
|
21
|
+
/** Device-clock: installBeginTimestampSeconds. */
|
|
22
|
+
installTimestamp: number;
|
|
23
|
+
/**
|
|
24
|
+
* Server-clock: referrerClickTimestampServerSeconds (G1 fraud trust —
|
|
25
|
+
* referrerTrust:'server'). 0 = unverified; absent on older native builds.
|
|
26
|
+
*/
|
|
27
|
+
clickServerTimestamp?: number;
|
|
28
|
+
/** Server-clock: installBeginTimestampServerSeconds. 0 = unverified. */
|
|
29
|
+
installServerTimestamp?: number;
|
|
30
|
+
googlePlayInstant: boolean;
|
|
31
|
+
}
|
|
32
|
+
interface MetaInstallReferrerResult {
|
|
33
|
+
installReferrer: string;
|
|
34
|
+
isClickThrough: boolean;
|
|
35
|
+
actualTimestamp: number;
|
|
36
|
+
/** Which Meta app served the referrer (e.g. com.facebook.katana). */
|
|
37
|
+
provider: string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Device metadata for Meta CAPI `extinfo` (Task 3n). Structurally mirrors
|
|
41
|
+
* `DeviceInfo` from `@advenue/shared` — kept as a local subset type (rather
|
|
42
|
+
* than importing that package) so this native-module-only package stays
|
|
43
|
+
* dependency-free; the RN facade's `collectDeviceInfo()` merges it into the
|
|
44
|
+
* real `DeviceInfo` shape.
|
|
45
|
+
*/
|
|
46
|
+
interface AdvenueDeviceInfo {
|
|
47
|
+
model?: string;
|
|
48
|
+
locale?: string;
|
|
49
|
+
carrier?: string;
|
|
50
|
+
timezone?: string;
|
|
51
|
+
screenWidth?: number;
|
|
52
|
+
screenHeight?: number;
|
|
53
|
+
screenDensity?: number;
|
|
54
|
+
cpuCores?: number;
|
|
55
|
+
totalStorageGb?: number;
|
|
56
|
+
freeStorageGb?: number;
|
|
57
|
+
}
|
|
58
|
+
interface AdvenueAndroidNativeModule {
|
|
59
|
+
/** Raw Play Install Referrer; parse with @advenue/install-referrer. */
|
|
60
|
+
getInstallReferrer(): Promise<InstallReferrerResult | null>;
|
|
61
|
+
/**
|
|
62
|
+
* Meta install referrer (null when no Facebook/Instagram app is installed);
|
|
63
|
+
* parse with parseMetaInstallReferrer from @advenue/install-referrer.
|
|
64
|
+
*/
|
|
65
|
+
getMetaInstallReferrer(): Promise<MetaInstallReferrerResult | null>;
|
|
66
|
+
/** Google Advertising ID (GAID) + limit-ad-tracking flag; null when unavailable. */
|
|
67
|
+
getAdvertisingId(): Promise<{
|
|
68
|
+
id: string;
|
|
69
|
+
limitAdTracking: boolean;
|
|
70
|
+
} | null>;
|
|
71
|
+
/** App Set ID — non-advertising, developer-scoped fallback id; null when unavailable. */
|
|
72
|
+
getAppSetId(): Promise<string | null>;
|
|
73
|
+
/**
|
|
74
|
+
* Play Integrity Standard API token (G3.1n).
|
|
75
|
+
*
|
|
76
|
+
* `requestHash` MUST be sha256_hex("<appId>:<deviceId>") — lowercase hex SHA-256
|
|
77
|
+
* of the literal string "<appId>:<deviceId>". The server's mapIntegrityVerdict
|
|
78
|
+
* re-derives the same string and compares it byte-for-byte.
|
|
79
|
+
*
|
|
80
|
+
* Rejects when:
|
|
81
|
+
* - ECONFIG: `io.advenue.INTEGRITY_CLOUD_PROJECT_NUMBER` meta-data is absent.
|
|
82
|
+
* - EUNSUPPORTED: Play Services unavailable or provider warming failed.
|
|
83
|
+
* - EINTEGRITY: Play returned an API-level error (network, quota, etc.).
|
|
84
|
+
*
|
|
85
|
+
* The JS bridge treats any rejection as "no attestation" and omits the token
|
|
86
|
+
* from the install event — rejection must never block the install track call.
|
|
87
|
+
*/
|
|
88
|
+
getIntegrityToken(requestHash: string): Promise<string>;
|
|
89
|
+
/**
|
|
90
|
+
* Device metadata (model, locale, screen, cpu, storage, timezone) used to
|
|
91
|
+
* populate Meta CAPI `extinfo` (Task 3n). Synchronous, best-effort — the JS
|
|
92
|
+
* facade (`collectDeviceInfo`) treats a thrown error as "unavailable" and
|
|
93
|
+
* degrades to `{}` rather than blocking anything.
|
|
94
|
+
*/
|
|
95
|
+
getDeviceInfo(): AdvenueDeviceInfo;
|
|
96
|
+
/**
|
|
97
|
+
* Built-in SDK storage (SharedPreferences `io.advenue.sdk`, MODE_PRIVATE) —
|
|
98
|
+
* the durable offline buffer + SDK state, so the app never supplies storage.
|
|
99
|
+
* Optional: absent on native builds predating this capability; the RN facade
|
|
100
|
+
* feature-detects and falls back to in-memory buffering. (No secure variant:
|
|
101
|
+
* Android has no reinstall-durable store — a reinstall legitimately re-fires
|
|
102
|
+
* the install, which the backend per-device window deduplicates.)
|
|
103
|
+
*/
|
|
104
|
+
storageGetItem?(key: string): string | null;
|
|
105
|
+
storageSetItem?(key: string, value: string): void;
|
|
106
|
+
storageRemoveItem?(key: string): void;
|
|
107
|
+
/**
|
|
108
|
+
* Android SSAID (Settings.Secure.ANDROID_ID) — signing-key-scoped, stable
|
|
109
|
+
* across reinstalls. The RN facade reads it ONLY when no usable GAID exists
|
|
110
|
+
* (Adjust-style fallback) and it is used strictly as a first-party
|
|
111
|
+
* fraud/dedup + reinstall-detection signal, never for ad attribution (Play
|
|
112
|
+
* policy). Optional: absent on older native builds; feature-detected.
|
|
113
|
+
*/
|
|
114
|
+
getAndroidId?(): string | null;
|
|
115
|
+
}
|
|
116
|
+
type TrackingAuthorizationStatus = 'notDetermined' | 'restricted' | 'denied' | 'authorized';
|
|
117
|
+
interface AdvenueIosNativeModule {
|
|
118
|
+
registerAppForAttribution(): void;
|
|
119
|
+
/**
|
|
120
|
+
* Conversion value: fine 0–63, coarse 'low'|'medium'|'high'. Updates the
|
|
121
|
+
* SKAN 4.0 postback, and on iOS 17.4+ the AdAttributionKit postback too.
|
|
122
|
+
*/
|
|
123
|
+
updateConversionValue(fineValue: number, coarse: string, lockWindow: boolean): Promise<void>;
|
|
124
|
+
/** Apple Search Ads attribution token (resolve server-side). */
|
|
125
|
+
getAttributionToken(): Promise<string | null>;
|
|
126
|
+
/**
|
|
127
|
+
* Shows the ATT consent prompt; requires NSUserTrackingUsageDescription in
|
|
128
|
+
* the app's Info.plist. Resolves with the resulting status.
|
|
129
|
+
*/
|
|
130
|
+
requestTrackingAuthorization(): Promise<TrackingAuthorizationStatus>;
|
|
131
|
+
getTrackingAuthorizationStatus(): TrackingAuthorizationStatus;
|
|
132
|
+
getAdvertisingId(): Promise<string | null>;
|
|
133
|
+
/** Vendor-scoped device id (IDFV) — available without ATT; a fallback anchor. */
|
|
134
|
+
getIdentifierForVendor(): string | null;
|
|
135
|
+
/** Clipboard match token (advmatch:<id>) for deterministic deferred deep linking; null if absent. */
|
|
136
|
+
getPasteboardMatchToken(): string | null;
|
|
137
|
+
/**
|
|
138
|
+
* G3.2n — App Attest. Generates (or reuses a keychain-cached) DCAppAttest
|
|
139
|
+
* key, computes clientDataHash = SHA-256(challenge), and calls
|
|
140
|
+
* DCAppAttestService.attestKey. Resolves { keyId, attestationObject } where
|
|
141
|
+
* attestationObject is a base64-encoded CBOR attestation for the server.
|
|
142
|
+
* Rejects with code EUNSUPPORTED on simulators (isSupported == false).
|
|
143
|
+
*/
|
|
144
|
+
attestKey(challenge: string): Promise<{
|
|
145
|
+
keyId: string;
|
|
146
|
+
attestationObject: string;
|
|
147
|
+
}>;
|
|
148
|
+
/**
|
|
149
|
+
* G3.3n — DeviceCheck. Calls DCDevice.current.generateToken to obtain the
|
|
150
|
+
* opaque base64 token that identifies this physical device to the Apple
|
|
151
|
+
* DeviceCheck API. The server queries/updates the persistent 2-bit per-device
|
|
152
|
+
* flag to detect reinstall abuse. Rejects with code EUNSUPPORTED on devices
|
|
153
|
+
* where DCDevice.current.isSupported is false (simulator, Catalyst, etc.).
|
|
154
|
+
*/
|
|
155
|
+
getDeviceCheckToken(): Promise<string>;
|
|
156
|
+
/**
|
|
157
|
+
* Device metadata (model, locale, screen, cpu, storage, timezone) used to
|
|
158
|
+
* populate Meta CAPI `extinfo` (Task 3n). Synchronous, best-effort — the JS
|
|
159
|
+
* facade (`collectDeviceInfo`) treats a thrown error as "unavailable" and
|
|
160
|
+
* degrades to `{}` rather than blocking anything.
|
|
161
|
+
*/
|
|
162
|
+
getDeviceInfo(): AdvenueDeviceInfo;
|
|
163
|
+
/**
|
|
164
|
+
* Built-in SDK storage (UserDefaults suite `io.advenue.sdk`) — the durable
|
|
165
|
+
* offline buffer + SDK state, so the app never supplies storage. Optional:
|
|
166
|
+
* absent on native builds predating this capability; the RN facade
|
|
167
|
+
* feature-detects and falls back to in-memory buffering.
|
|
168
|
+
*/
|
|
169
|
+
storageGetItem?(key: string): string | null;
|
|
170
|
+
storageSetItem?(key: string, value: string): void;
|
|
171
|
+
storageRemoveItem?(key: string): void;
|
|
172
|
+
/**
|
|
173
|
+
* Built-in secure storage (Keychain, kSecAttrAccessibleAfterFirstUnlock,
|
|
174
|
+
* ThisDeviceOnly) — survives app reinstall, which is what makes the device
|
|
175
|
+
* identity and the install guard reinstall-resilient (Adjust-style).
|
|
176
|
+
* Optional: absent on older native builds; feature-detected.
|
|
177
|
+
*/
|
|
178
|
+
secureGetItem?(key: string): string | null;
|
|
179
|
+
secureSetItem?(key: string, value: string): void;
|
|
180
|
+
secureRemoveItem?(key: string): void;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Minimal structural type for the bits of `expo-secure-store` we use. Declared
|
|
185
|
+
* locally so this package needs no expo types at compile time — the app passes
|
|
186
|
+
* the module (`import * as SecureStore from 'expo-secure-store'`) at runtime.
|
|
187
|
+
*/
|
|
188
|
+
interface SecureStoreLike {
|
|
189
|
+
getItemAsync(key: string): Promise<string | null>;
|
|
190
|
+
setItemAsync(key: string, value: string): Promise<void>;
|
|
191
|
+
/** Optional — forwarded so GDPR erasure can wipe the durable entries. */
|
|
192
|
+
deleteItemAsync?(key: string): Promise<void>;
|
|
193
|
+
}
|
|
194
|
+
/** Wraps expo-secure-store as an Advenue SecureStorageAdapter (async, durable). */
|
|
195
|
+
declare function createSecureStore(secureStore: SecureStoreLike): SecureStorageAdapter;
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Parses an OS-delivered link (Universal Link, App Link, or custom scheme) into
|
|
199
|
+
* the unified {@link DeepLink} shape. The `deepLinkValue` is a best-effort path
|
|
200
|
+
* (host + path for custom schemes, path for http(s)); the raw `url` is always
|
|
201
|
+
* provided so the host app can parse it itself when needed.
|
|
202
|
+
*/
|
|
203
|
+
declare function parseDirectLink(url: string): DeepLink;
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Lazy access to the native modules that ship inside this package (ios/ and
|
|
207
|
+
* android/, registered via expo-module.config.json). Host-module resolution
|
|
208
|
+
* goes through native-require.cjs so Metro sees literal requires (see the
|
|
209
|
+
* comment there); `requireNativeModule` throws when the native side isn't
|
|
210
|
+
* built (Expo Go, web, missing pods), so calls stay inside try/catch.
|
|
211
|
+
*/
|
|
212
|
+
declare function getIosNative(): AdvenueIosNativeModule | null;
|
|
213
|
+
declare function getAndroidNative(): AdvenueAndroidNativeModule | null;
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Resolves the device advertising id (IDFA on iOS, GAID on Android), gates it
|
|
217
|
+
* on ATT authorization status (iOS) / limitAdTracking flag (Android), and on
|
|
218
|
+
* DMA consent when the user is subject to GDPR. Pushes the result — or an
|
|
219
|
+
* empty object to clear — into the active client via `setAdvertisingId`.
|
|
220
|
+
*
|
|
221
|
+
* Fire-and-forget at call sites; errors are suppressed internally.
|
|
222
|
+
*/
|
|
223
|
+
declare function resolveAdvertisingId(): Promise<void>;
|
|
224
|
+
/**
|
|
225
|
+
* Collects native device metadata (model, locale, screen, cpu, storage, timezone)
|
|
226
|
+
* used to populate Meta CAPI `extinfo`. Reads from the platform-appropriate
|
|
227
|
+
* native module's `getDeviceInfo()`; returns `{}` when the native module or the
|
|
228
|
+
* method is unavailable (bare React Native without the native SDK, web, Expo
|
|
229
|
+
* Go, or an older native build predating this method). Never throws — any
|
|
230
|
+
* native-side error degrades to an empty object so callers can unconditionally
|
|
231
|
+
* pass the result through.
|
|
232
|
+
*/
|
|
233
|
+
declare function collectDeviceInfo(natives: {
|
|
234
|
+
platform: 'ios' | 'android' | string;
|
|
235
|
+
ios?: {
|
|
236
|
+
getDeviceInfo?: () => Partial<DeviceInfo>;
|
|
237
|
+
} | null;
|
|
238
|
+
android?: {
|
|
239
|
+
getDeviceInfo?: () => Partial<DeviceInfo>;
|
|
240
|
+
} | null;
|
|
241
|
+
}): DeviceInfo;
|
|
242
|
+
/**
|
|
243
|
+
* iOS clipboard-match deferred deep linking: reads the `advmatch:<id>` token the
|
|
244
|
+
* link redirector wrote to the pasteboard and exchanges it for the deep link — a
|
|
245
|
+
* DETERMINISTIC match (no IDFA, no fingerprinting). Returns null off iOS, when
|
|
246
|
+
* there's no token, or without consent. (Reading the pasteboard shows the iOS
|
|
247
|
+
* paste banner — the user-visible, privacy-forward deferred path.)
|
|
248
|
+
*/
|
|
249
|
+
declare function resolveClipboardMatch(): Promise<DeepLink | null>;
|
|
250
|
+
interface RNAdvenueConfig extends Omit<AdvenueConfig, 'storage' | 'platform'> {
|
|
251
|
+
/**
|
|
252
|
+
* Auto-detected from React Native's `Platform.OS` — omit it. Pass explicitly
|
|
253
|
+
* only outside a React Native runtime (tests, custom embeddings); `ios` and
|
|
254
|
+
* `android` map verbatim, any other RN target (web, desktop) reports as
|
|
255
|
+
* `web`.
|
|
256
|
+
*/
|
|
257
|
+
platform?: AdvenueConfig['platform'];
|
|
258
|
+
/**
|
|
259
|
+
* @internal Storage override (tests / custom embeddings). The SDK persists
|
|
260
|
+
* via its own native modules (UserDefaults/SharedPreferences) — apps never
|
|
261
|
+
* supply storage. When set, it replaces the built-in native storage.
|
|
262
|
+
*/
|
|
263
|
+
mmkv?: MMKVLike;
|
|
264
|
+
/**
|
|
265
|
+
* G3.1n — Play Integrity (Android) / App Attest (iOS) attestation.
|
|
266
|
+
*
|
|
267
|
+
* Your app's Advenue appId (the UUID in Settings → API Keys). When set on
|
|
268
|
+
* Android, the automatic install obtains a Play Integrity Standard token and
|
|
269
|
+
* attaches it to the install event. The requestHash is computed as
|
|
270
|
+
* `sha256Hex("<appId>:<deviceId>")`, matching the server's verification
|
|
271
|
+
* formula exactly (see `makeDecodeAndroid` in the worker).
|
|
272
|
+
*
|
|
273
|
+
* Omit to run without attestation (the server field stays `unavailable`).
|
|
274
|
+
*/
|
|
275
|
+
appId?: string;
|
|
276
|
+
/**
|
|
277
|
+
* @internal Secure-store override (tests / custom embeddings). The SDK uses
|
|
278
|
+
* its own Keychain-backed native storage on iOS for the reinstall-resilient
|
|
279
|
+
* device identity — apps never supply a secure store. When set, it replaces
|
|
280
|
+
* the built-in Keychain adapter.
|
|
281
|
+
*/
|
|
282
|
+
secureStore?: SecureStoreLike;
|
|
283
|
+
/**
|
|
284
|
+
* Unified deep-link callback (AppsFlyer UDL style). Fires for both direct
|
|
285
|
+
* Universal/App Links (the OS opened the app via a link) and deferred deep
|
|
286
|
+
* links (resolved after an attributed install). The SDK never navigates — the
|
|
287
|
+
* host app reads `link.deepLinkValue` and routes. Inspect `link.isDeferred`
|
|
288
|
+
* to distinguish the two. Omit to disable deep-link handling entirely.
|
|
289
|
+
*/
|
|
290
|
+
onDeepLink?: (link: DeepLink) => void;
|
|
291
|
+
/**
|
|
292
|
+
* @internal Test hook — disables the automatic install fired by
|
|
293
|
+
* `initialize()`. Install tracking is always automatic in production (there
|
|
294
|
+
* is no public `trackInstall`); tests turn it off to exercise the internal
|
|
295
|
+
* install path deterministically.
|
|
296
|
+
*/
|
|
297
|
+
autoTrackInstall?: boolean;
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Maps a React Native AppState status to the client's session lifecycle hooks.
|
|
301
|
+
* Exported for testing. 'inactive' (transient on iOS) is intentionally ignored
|
|
302
|
+
* so brief interruptions (Control Center, incoming call) don't end the session.
|
|
303
|
+
*/
|
|
304
|
+
declare function applyAppState(client: Pick<AdvenueClient, 'notifyAppActive' | 'notifyAppBackground'>, status: string): void;
|
|
305
|
+
/**
|
|
306
|
+
* React Native entry point. Wires MMKV-backed offline buffering automatically
|
|
307
|
+
* and re-exports the same track surface as the core SDK.
|
|
308
|
+
*/
|
|
309
|
+
declare const Advenue: {
|
|
310
|
+
initialize(config: RNAdvenueConfig): Promise<AdvenueClient>;
|
|
311
|
+
track: (name: string, properties?: Record<string, unknown>, opts?: TrackOptions) => void;
|
|
312
|
+
/**
|
|
313
|
+
* Shows the iOS ATT prompt (resolves 'authorized' immediately on Android/web,
|
|
314
|
+
* where ATT doesn't exist) and forwards the result to the consent gate.
|
|
315
|
+
*/
|
|
316
|
+
requestTrackingAuthorization(): Promise<TrackingAuthorizationStatus>;
|
|
317
|
+
setTrackingConsent(granted: boolean): void;
|
|
318
|
+
getTrackingConsent: () => boolean;
|
|
319
|
+
/** GDPR/CCPA erasure: stop tracking and wipe local identifiers/queue. */
|
|
320
|
+
forgetMe(): void;
|
|
321
|
+
setConsentData(consent: Consent): void;
|
|
322
|
+
getConsentData: () => {
|
|
323
|
+
isUserSubjectToGDPR: boolean;
|
|
324
|
+
hasConsentForDataUsage?: boolean | undefined;
|
|
325
|
+
hasConsentForAdsPersonalization?: boolean | undefined;
|
|
326
|
+
hasConsentForAdStorage?: boolean | undefined;
|
|
327
|
+
} | null;
|
|
328
|
+
flush: () => Promise<void>;
|
|
329
|
+
getDeviceId: () => string;
|
|
330
|
+
shutdown(): void;
|
|
331
|
+
};
|
|
332
|
+
/**
|
|
333
|
+
* Tracks the install event enriched with native attribution data: Play + Meta
|
|
334
|
+
* install referrers on Android, SKAdNetwork registration on iOS. Fired
|
|
335
|
+
* automatically by `initialize()` (or its consent deferral); when a
|
|
336
|
+
* `secureStore` is wired it fires at most once per device (reinstall-resilient
|
|
337
|
+
* on iOS via Keychain; Android re-fires after a reinstall, which is
|
|
338
|
+
* unavoidable post-GAID).
|
|
339
|
+
*
|
|
340
|
+
* @internal Exported for tests only — install tracking is automatic and this
|
|
341
|
+
* function is deliberately NOT on the `Advenue` facade. Do not call it from
|
|
342
|
+
* app code.
|
|
343
|
+
*/
|
|
344
|
+
declare function trackInstall(): Promise<void>;
|
|
345
|
+
|
|
346
|
+
export { Advenue, type AdvenueAndroidNativeModule, type AdvenueDeviceInfo, type AdvenueIosNativeModule, type InstallReferrerResult, type MMKVLike, type MetaInstallReferrerResult, type RNAdvenueConfig, type SecureStoreLike, type TrackingAuthorizationStatus, applyAppState, collectDeviceInfo, createMMKVStorage, createSecureStore, getAndroidNative, getIosNative, parseDirectLink, resolveAdvertisingId, resolveClipboardMatch, trackInstall };
|
package/dist/index.d.ts
CHANGED
|
@@ -204,10 +204,10 @@ declare function parseDirectLink(url: string): DeepLink;
|
|
|
204
204
|
|
|
205
205
|
/**
|
|
206
206
|
* Lazy access to the native modules that ship inside this package (ios/ and
|
|
207
|
-
* android/, registered via expo-module.config.json).
|
|
208
|
-
*
|
|
209
|
-
*
|
|
210
|
-
*
|
|
207
|
+
* android/, registered via expo-module.config.json). Host-module resolution
|
|
208
|
+
* goes through native-require.cjs so Metro sees literal requires (see the
|
|
209
|
+
* comment there); `requireNativeModule` throws when the native side isn't
|
|
210
|
+
* built (Expo Go, web, missing pods), so calls stay inside try/catch.
|
|
211
211
|
*/
|
|
212
212
|
declare function getIosNative(): AdvenueIosNativeModule | null;
|
|
213
213
|
declare function getAndroidNative(): AdvenueAndroidNativeModule | null;
|
package/dist/index.js
CHANGED
|
@@ -1,12 +1,69 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
4
7
|
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
5
8
|
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
6
9
|
}) : x)(function(x) {
|
|
7
10
|
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
8
11
|
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
9
12
|
});
|
|
13
|
+
var __commonJS = (cb, mod) => function __require2() {
|
|
14
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
15
|
+
};
|
|
16
|
+
var __copyProps = (to, from, except, desc) => {
|
|
17
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
18
|
+
for (let key of __getOwnPropNames(from))
|
|
19
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
20
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
21
|
+
}
|
|
22
|
+
return to;
|
|
23
|
+
};
|
|
24
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
25
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
26
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
27
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
28
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
29
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
30
|
+
mod
|
|
31
|
+
));
|
|
32
|
+
|
|
33
|
+
// src/native-require.cjs
|
|
34
|
+
var require_native_require = __commonJS({
|
|
35
|
+
"src/native-require.cjs"(exports, module) {
|
|
36
|
+
"use strict";
|
|
37
|
+
module.exports.requireExpoModulesCore = function requireExpoModulesCore2() {
|
|
38
|
+
try {
|
|
39
|
+
return __require("expo-modules-core");
|
|
40
|
+
} catch {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
module.exports.requireReactNative = function requireReactNative2() {
|
|
45
|
+
try {
|
|
46
|
+
return __require("react-native");
|
|
47
|
+
} catch {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
// src/index.ts
|
|
55
|
+
import {
|
|
56
|
+
extractReferrerProperties,
|
|
57
|
+
parseInstallReferrer,
|
|
58
|
+
parseMetaInstallReferrer
|
|
59
|
+
} from "@advenue/install-referrer";
|
|
60
|
+
import {
|
|
61
|
+
AdvenueClient,
|
|
62
|
+
DEFAULT_ENDPOINT,
|
|
63
|
+
DEVICE_ID_KEY,
|
|
64
|
+
MemoryStorage,
|
|
65
|
+
resolveDurableDeviceId
|
|
66
|
+
} from "@advenue/sdk-core";
|
|
10
67
|
|
|
11
68
|
// ../shared/src/match-token.ts
|
|
12
69
|
var MATCH_TOKEN_PREFIX = "advmatch:";
|
|
@@ -165,6 +222,70 @@ function sha256Hex(message) {
|
|
|
165
222
|
return toHex(sha256Bytes(enc.encode(message)));
|
|
166
223
|
}
|
|
167
224
|
|
|
225
|
+
// package.json
|
|
226
|
+
var package_default = {
|
|
227
|
+
name: "@advenue/react-native",
|
|
228
|
+
version: "0.6.2",
|
|
229
|
+
description: "Advenue MMP React Native SDK \u2014 attribution, install tracking, and deep links (bundled iOS/Android Expo native modules)",
|
|
230
|
+
type: "module",
|
|
231
|
+
license: "MIT",
|
|
232
|
+
main: "./dist/index.js",
|
|
233
|
+
types: "./dist/index.d.ts",
|
|
234
|
+
exports: {
|
|
235
|
+
".": {
|
|
236
|
+
types: "./dist/index.d.ts",
|
|
237
|
+
"react-native": "./dist/index.cjs",
|
|
238
|
+
require: "./dist/index.cjs",
|
|
239
|
+
default: "./dist/index.js"
|
|
240
|
+
},
|
|
241
|
+
"./plugin": "./plugin/index.js"
|
|
242
|
+
},
|
|
243
|
+
files: [
|
|
244
|
+
"dist",
|
|
245
|
+
"src",
|
|
246
|
+
"plugin",
|
|
247
|
+
"scripts",
|
|
248
|
+
"ios",
|
|
249
|
+
"android",
|
|
250
|
+
"expo-module.config.json",
|
|
251
|
+
"!**/*.test.ts"
|
|
252
|
+
],
|
|
253
|
+
publishConfig: {
|
|
254
|
+
access: "public"
|
|
255
|
+
},
|
|
256
|
+
scripts: {
|
|
257
|
+
build: "tsup && node scripts/check-dist.mjs",
|
|
258
|
+
typecheck: "tsc --noEmit",
|
|
259
|
+
test: "vitest run"
|
|
260
|
+
},
|
|
261
|
+
dependencies: {
|
|
262
|
+
"@advenue/install-referrer": "workspace:*",
|
|
263
|
+
"@advenue/sdk-core": "workspace:*"
|
|
264
|
+
},
|
|
265
|
+
peerDependencies: {
|
|
266
|
+
"@expo/config-plugins": ">=8",
|
|
267
|
+
react: ">=18.2",
|
|
268
|
+
"react-native": ">=0.74",
|
|
269
|
+
"expo-modules-core": "*"
|
|
270
|
+
},
|
|
271
|
+
peerDependenciesMeta: {
|
|
272
|
+
"@expo/config-plugins": {
|
|
273
|
+
optional: true
|
|
274
|
+
},
|
|
275
|
+
"expo-modules-core": {
|
|
276
|
+
optional: true
|
|
277
|
+
}
|
|
278
|
+
},
|
|
279
|
+
devDependencies: {
|
|
280
|
+
"@advenue/shared": "workspace:*",
|
|
281
|
+
"@advenue/signing": "workspace:*",
|
|
282
|
+
tsup: "^8.5.1",
|
|
283
|
+
typescript: "^5.7.2",
|
|
284
|
+
vitest: "^2.1.8"
|
|
285
|
+
},
|
|
286
|
+
"react-native": "./dist/index.cjs"
|
|
287
|
+
};
|
|
288
|
+
|
|
168
289
|
// src/deep-links.ts
|
|
169
290
|
function parseDirectLink(url) {
|
|
170
291
|
let deepLinkValue = "";
|
|
@@ -215,39 +336,43 @@ function createMMKVStorage(mmkv) {
|
|
|
215
336
|
}
|
|
216
337
|
|
|
217
338
|
// src/native.ts
|
|
339
|
+
var import_native_require = __toESM(require_native_require(), 1);
|
|
218
340
|
function getIosNative() {
|
|
219
341
|
try {
|
|
220
|
-
const core =
|
|
221
|
-
return core.requireNativeModule("AdvenueIos");
|
|
342
|
+
const core = (0, import_native_require.requireExpoModulesCore)();
|
|
343
|
+
return core ? core.requireNativeModule("AdvenueIos") : null;
|
|
222
344
|
} catch {
|
|
223
345
|
return null;
|
|
224
346
|
}
|
|
225
347
|
}
|
|
226
348
|
function getAndroidNative() {
|
|
227
349
|
try {
|
|
228
|
-
const core =
|
|
229
|
-
return core.requireNativeModule("AdvenueAndroid");
|
|
350
|
+
const core = (0, import_native_require.requireExpoModulesCore)();
|
|
351
|
+
return core ? core.requireNativeModule("AdvenueAndroid") : null;
|
|
230
352
|
} catch {
|
|
231
353
|
return null;
|
|
232
354
|
}
|
|
233
355
|
}
|
|
234
356
|
function getPlatformOS() {
|
|
235
357
|
try {
|
|
236
|
-
|
|
358
|
+
const rn = (0, import_native_require.requireReactNative)();
|
|
359
|
+
return rn?.Platform.OS ?? null;
|
|
237
360
|
} catch {
|
|
238
361
|
return null;
|
|
239
362
|
}
|
|
240
363
|
}
|
|
241
364
|
function getAppState() {
|
|
242
365
|
try {
|
|
243
|
-
|
|
366
|
+
const rn = (0, import_native_require.requireReactNative)();
|
|
367
|
+
return rn?.AppState ?? null;
|
|
244
368
|
} catch {
|
|
245
369
|
return null;
|
|
246
370
|
}
|
|
247
371
|
}
|
|
248
372
|
function getLinking() {
|
|
249
373
|
try {
|
|
250
|
-
|
|
374
|
+
const rn = (0, import_native_require.requireReactNative)();
|
|
375
|
+
return rn?.Linking ?? null;
|
|
251
376
|
} catch {
|
|
252
377
|
return null;
|
|
253
378
|
}
|
|
@@ -428,6 +553,7 @@ var Advenue = {
|
|
|
428
553
|
secureStore = secureMod ? createSecureStore(secureMod) : createNativeSecureStore(iosMod);
|
|
429
554
|
const deviceId = rest.deviceId ?? await resolveDurableDeviceId(storage, secureStore ?? void 0);
|
|
430
555
|
instance = new AdvenueClient({ ...rest, platform, deviceId, storage });
|
|
556
|
+
instance.debugLog(`SDK v${package_default.version} \u2014 events -> ${configuredEndpoint}`);
|
|
431
557
|
void resolveAdvertisingId().catch((err) => reportError("enrich.advertisingId", err));
|
|
432
558
|
const deviceInfo = collectDeviceInfo({
|
|
433
559
|
platform,
|
|
@@ -680,5 +806,16 @@ async function trackInstall() {
|
|
|
680
806
|
}
|
|
681
807
|
}
|
|
682
808
|
}
|
|
683
|
-
|
|
684
|
-
|
|
809
|
+
export {
|
|
810
|
+
Advenue,
|
|
811
|
+
applyAppState,
|
|
812
|
+
collectDeviceInfo,
|
|
813
|
+
createMMKVStorage,
|
|
814
|
+
createSecureStore,
|
|
815
|
+
getAndroidNative,
|
|
816
|
+
getIosNative,
|
|
817
|
+
parseDirectLink,
|
|
818
|
+
resolveAdvertisingId,
|
|
819
|
+
resolveClipboardMatch,
|
|
820
|
+
trackInstall
|
|
821
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@advenue/react-native",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.2",
|
|
4
4
|
"description": "Advenue MMP React Native SDK — attribution, install tracking, and deep links (bundled iOS/Android Expo native modules)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
"exports": {
|
|
10
10
|
".": {
|
|
11
11
|
"types": "./dist/index.d.ts",
|
|
12
|
+
"react-native": "./dist/index.cjs",
|
|
13
|
+
"require": "./dist/index.cjs",
|
|
12
14
|
"default": "./dist/index.js"
|
|
13
15
|
},
|
|
14
16
|
"./plugin": "./plugin/index.js"
|
|
@@ -17,6 +19,7 @@
|
|
|
17
19
|
"dist",
|
|
18
20
|
"src",
|
|
19
21
|
"plugin",
|
|
22
|
+
"scripts",
|
|
20
23
|
"ios",
|
|
21
24
|
"android",
|
|
22
25
|
"expo-module.config.json",
|
|
@@ -47,11 +50,12 @@
|
|
|
47
50
|
"tsup": "^8.5.1",
|
|
48
51
|
"typescript": "^5.7.2",
|
|
49
52
|
"vitest": "^2.1.8",
|
|
50
|
-
"@advenue/
|
|
51
|
-
"@advenue/
|
|
53
|
+
"@advenue/signing": "0.0.0",
|
|
54
|
+
"@advenue/shared": "0.1.0"
|
|
52
55
|
},
|
|
56
|
+
"react-native": "./dist/index.cjs",
|
|
53
57
|
"scripts": {
|
|
54
|
-
"build": "tsup",
|
|
58
|
+
"build": "tsup && node scripts/check-dist.mjs",
|
|
55
59
|
"typecheck": "tsc --noEmit",
|
|
56
60
|
"test": "vitest run"
|
|
57
61
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// Publish guard for the Metro __require regression: the CJS build Metro
|
|
2
|
+
// consumes must keep `require("...")` literals (statically analyzable) and
|
|
3
|
+
// must never contain esbuild's `__require` shim. Runs as part of `pnpm build`
|
|
4
|
+
// so a bad dist can never reach npm again.
|
|
5
|
+
import { readFileSync } from 'node:fs';
|
|
6
|
+
import { fileURLToPath } from 'node:url';
|
|
7
|
+
|
|
8
|
+
const cjsPath = fileURLToPath(new URL('../dist/index.cjs', import.meta.url));
|
|
9
|
+
const cjs = readFileSync(cjsPath, 'utf8');
|
|
10
|
+
|
|
11
|
+
const problems = [];
|
|
12
|
+
// Flag __require CALL SITES with a module-string argument (the Metro-invisible
|
|
13
|
+
// shim calls). esbuild's __commonJS helper legitimately names its inner
|
|
14
|
+
// function `__require()` — a definition, not a dynamic require — so a bare
|
|
15
|
+
// name match would false-positive.
|
|
16
|
+
if (/__require\(\s*["']/.test(cjs)) {
|
|
17
|
+
problems.push('dist/index.cjs contains esbuild __require shim calls — Metro cannot resolve them');
|
|
18
|
+
}
|
|
19
|
+
for (const mod of ['expo-modules-core', 'react-native']) {
|
|
20
|
+
// Negative lookbehind: `__require("x")` must NOT satisfy the literal check —
|
|
21
|
+
// that substring trap is exactly how the original regression slipped through.
|
|
22
|
+
if (!new RegExp(String.raw`(?<![\w$])require\((?:"${mod}"|'${mod}')\)`).test(cjs)) {
|
|
23
|
+
problems.push(`dist/index.cjs is missing a genuine literal require("${mod}")`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (problems.length > 0) {
|
|
28
|
+
console.error(`check-dist failed:\n- ${problems.join('\n- ')}`);
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
console.log('check-dist ok: CJS requires are literal, no __require shims');
|
package/src/index.ts
CHANGED
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
} from '@advenue/sdk-core';
|
|
20
20
|
import { parseMatchToken } from '@advenue/shared/match-token';
|
|
21
21
|
import { sha256Hex } from '@advenue/signing';
|
|
22
|
+
import pkg from '../package.json' with { type: 'json' };
|
|
22
23
|
import { type DeepLinkHandle, setupDeepLinks } from './deep-links';
|
|
23
24
|
import { type MMKVLike, createMMKVStorage } from './mmkv-storage';
|
|
24
25
|
import {
|
|
@@ -371,6 +372,9 @@ export const Advenue = {
|
|
|
371
372
|
const deviceId =
|
|
372
373
|
rest.deviceId ?? (await resolveDurableDeviceId(storage, secureStore ?? undefined));
|
|
373
374
|
instance = new AdvenueClient({ ...rest, platform, deviceId, storage });
|
|
375
|
+
// One-line ground truth for "which SDK build talks to which host" — the
|
|
376
|
+
// exact questions a silent integration always raises first.
|
|
377
|
+
instance.debugLog(`SDK v${pkg.version} — events -> ${configuredEndpoint}`);
|
|
374
378
|
// (a) resolve ad-id at init time
|
|
375
379
|
void resolveAdvertisingId().catch((err) => reportError('enrich.advertisingId', err));
|
|
376
380
|
// Collect native device info (Meta CAPI extinfo) once at init time; a
|