@li-nk.me/react-native-sdk 0.2.5 → 0.2.8
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/lib/index.d.ts +2 -0
- package/lib/index.js +62 -2
- package/package.json +1 -1
- package/src/index.ts +66 -2
package/lib/index.d.ts
CHANGED
package/lib/index.js
CHANGED
|
@@ -9,6 +9,34 @@ try {
|
|
|
9
9
|
catch {
|
|
10
10
|
// expo-clipboard not installed - pasteboard will be skipped
|
|
11
11
|
}
|
|
12
|
+
const UTM_KEYS = new Set([
|
|
13
|
+
'utm_source',
|
|
14
|
+
'utm_medium',
|
|
15
|
+
'utm_campaign',
|
|
16
|
+
'utm_term',
|
|
17
|
+
'utm_content',
|
|
18
|
+
'utm_id',
|
|
19
|
+
'utm_source_platform',
|
|
20
|
+
'utm_creative_format',
|
|
21
|
+
'utm_marketing_tactic',
|
|
22
|
+
'tags',
|
|
23
|
+
]);
|
|
24
|
+
function splitSearchParams(searchParams) {
|
|
25
|
+
const params = {};
|
|
26
|
+
const utm = {};
|
|
27
|
+
for (const [key, value] of searchParams.entries()) {
|
|
28
|
+
if (UTM_KEYS.has(key)) {
|
|
29
|
+
utm[key] = value;
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
params[key] = value;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return {
|
|
36
|
+
params: Object.keys(params).length ? params : undefined,
|
|
37
|
+
utm: Object.keys(utm).length ? utm : undefined,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
12
40
|
class LinkMeController {
|
|
13
41
|
constructor(deps) {
|
|
14
42
|
var _a, _b;
|
|
@@ -430,6 +458,13 @@ class LinkMeController {
|
|
|
430
458
|
body: JSON.stringify(body),
|
|
431
459
|
});
|
|
432
460
|
if (!res.ok) {
|
|
461
|
+
const errorCode = await this.readErrorCode(res);
|
|
462
|
+
if (errorCode === 'domain_not_found') {
|
|
463
|
+
const parsed = this.parseUrl(url);
|
|
464
|
+
if (parsed) {
|
|
465
|
+
return this.buildBasicUniversalPayload(parsed);
|
|
466
|
+
}
|
|
467
|
+
}
|
|
433
468
|
return null;
|
|
434
469
|
}
|
|
435
470
|
return await this.parsePayload(res);
|
|
@@ -482,16 +517,41 @@ class LinkMeController {
|
|
|
482
517
|
device.consent = consent;
|
|
483
518
|
return device;
|
|
484
519
|
}
|
|
485
|
-
async parsePayload(res) {
|
|
520
|
+
async parsePayload(res, assumeLinkMe = true) {
|
|
486
521
|
try {
|
|
487
522
|
const json = (await res.json());
|
|
488
|
-
|
|
523
|
+
if (!json) {
|
|
524
|
+
return null;
|
|
525
|
+
}
|
|
526
|
+
if (assumeLinkMe && json.isLinkMe === undefined) {
|
|
527
|
+
json.isLinkMe = true;
|
|
528
|
+
}
|
|
529
|
+
return json;
|
|
489
530
|
}
|
|
490
531
|
catch (err) {
|
|
491
532
|
this.logDebug('payload.parse_error', { message: err instanceof Error ? err.message : String(err) });
|
|
492
533
|
return null;
|
|
493
534
|
}
|
|
494
535
|
}
|
|
536
|
+
async readErrorCode(res) {
|
|
537
|
+
try {
|
|
538
|
+
const data = (await res.json());
|
|
539
|
+
return typeof (data === null || data === void 0 ? void 0 : data.error) === 'string' ? data.error : undefined;
|
|
540
|
+
}
|
|
541
|
+
catch {
|
|
542
|
+
return undefined;
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
buildBasicUniversalPayload(parsed) {
|
|
546
|
+
const { params, utm } = splitSearchParams(parsed.searchParams);
|
|
547
|
+
return {
|
|
548
|
+
path: parsed.pathname || '/',
|
|
549
|
+
params,
|
|
550
|
+
utm,
|
|
551
|
+
url: parsed.toString(),
|
|
552
|
+
isLinkMe: false,
|
|
553
|
+
};
|
|
554
|
+
}
|
|
495
555
|
emit(payload) {
|
|
496
556
|
this.lastPayload = payload;
|
|
497
557
|
for (const listener of this.listeners) {
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -17,6 +17,8 @@ export type LinkMePayload = {
|
|
|
17
17
|
params?: Record<string, string>;
|
|
18
18
|
utm?: Record<string, string>;
|
|
19
19
|
custom?: Record<string, string>;
|
|
20
|
+
url?: string;
|
|
21
|
+
isLinkMe?: boolean;
|
|
20
22
|
};
|
|
21
23
|
|
|
22
24
|
export type LinkMeConfig = {
|
|
@@ -51,6 +53,35 @@ type ControllerDeps = {
|
|
|
51
53
|
linking?: LinkingLike;
|
|
52
54
|
};
|
|
53
55
|
|
|
56
|
+
const UTM_KEYS = new Set([
|
|
57
|
+
'utm_source',
|
|
58
|
+
'utm_medium',
|
|
59
|
+
'utm_campaign',
|
|
60
|
+
'utm_term',
|
|
61
|
+
'utm_content',
|
|
62
|
+
'utm_id',
|
|
63
|
+
'utm_source_platform',
|
|
64
|
+
'utm_creative_format',
|
|
65
|
+
'utm_marketing_tactic',
|
|
66
|
+
'tags',
|
|
67
|
+
]);
|
|
68
|
+
|
|
69
|
+
function splitSearchParams(searchParams: URLSearchParams): { params?: Record<string, string>; utm?: Record<string, string> } {
|
|
70
|
+
const params: Record<string, string> = {};
|
|
71
|
+
const utm: Record<string, string> = {};
|
|
72
|
+
for (const [key, value] of searchParams.entries()) {
|
|
73
|
+
if (UTM_KEYS.has(key)) {
|
|
74
|
+
utm[key] = value;
|
|
75
|
+
} else {
|
|
76
|
+
params[key] = value;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return {
|
|
80
|
+
params: Object.keys(params).length ? params : undefined,
|
|
81
|
+
utm: Object.keys(utm).length ? utm : undefined,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
54
85
|
class LinkMeController {
|
|
55
86
|
private config: NormalizedConfig | undefined;
|
|
56
87
|
private ready = false;
|
|
@@ -485,6 +516,13 @@ class LinkMeController {
|
|
|
485
516
|
body: JSON.stringify(body),
|
|
486
517
|
});
|
|
487
518
|
if (!res.ok) {
|
|
519
|
+
const errorCode = await this.readErrorCode(res);
|
|
520
|
+
if (errorCode === 'domain_not_found') {
|
|
521
|
+
const parsed = this.parseUrl(url);
|
|
522
|
+
if (parsed) {
|
|
523
|
+
return this.buildBasicUniversalPayload(parsed);
|
|
524
|
+
}
|
|
525
|
+
}
|
|
488
526
|
return null;
|
|
489
527
|
}
|
|
490
528
|
return await this.parsePayload(res);
|
|
@@ -538,16 +576,42 @@ class LinkMeController {
|
|
|
538
576
|
return device;
|
|
539
577
|
}
|
|
540
578
|
|
|
541
|
-
private async parsePayload(res: Response): Promise<LinkMePayload | null> {
|
|
579
|
+
private async parsePayload(res: Response, assumeLinkMe = true): Promise<LinkMePayload | null> {
|
|
542
580
|
try {
|
|
543
581
|
const json = (await res.json()) as LinkMePayload;
|
|
544
|
-
|
|
582
|
+
if (!json) {
|
|
583
|
+
return null;
|
|
584
|
+
}
|
|
585
|
+
if (assumeLinkMe && json.isLinkMe === undefined) {
|
|
586
|
+
json.isLinkMe = true;
|
|
587
|
+
}
|
|
588
|
+
return json;
|
|
545
589
|
} catch (err) {
|
|
546
590
|
this.logDebug('payload.parse_error', { message: err instanceof Error ? err.message : String(err) });
|
|
547
591
|
return null;
|
|
548
592
|
}
|
|
549
593
|
}
|
|
550
594
|
|
|
595
|
+
private async readErrorCode(res: Response): Promise<string | undefined> {
|
|
596
|
+
try {
|
|
597
|
+
const data = (await res.json()) as { error?: unknown } | null;
|
|
598
|
+
return typeof data?.error === 'string' ? data.error : undefined;
|
|
599
|
+
} catch {
|
|
600
|
+
return undefined;
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
private buildBasicUniversalPayload(parsed: URL): LinkMePayload {
|
|
605
|
+
const { params, utm } = splitSearchParams(parsed.searchParams);
|
|
606
|
+
return {
|
|
607
|
+
path: parsed.pathname || '/',
|
|
608
|
+
params,
|
|
609
|
+
utm,
|
|
610
|
+
url: parsed.toString(),
|
|
611
|
+
isLinkMe: false,
|
|
612
|
+
};
|
|
613
|
+
}
|
|
614
|
+
|
|
551
615
|
private emit(payload: LinkMePayload): void {
|
|
552
616
|
this.lastPayload = payload;
|
|
553
617
|
for (const listener of this.listeners) {
|