@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 CHANGED
@@ -6,6 +6,8 @@ export type LinkMePayload = {
6
6
  params?: Record<string, string>;
7
7
  utm?: Record<string, string>;
8
8
  custom?: Record<string, string>;
9
+ url?: string;
10
+ isLinkMe?: boolean;
9
11
  };
10
12
  export type LinkMeConfig = {
11
13
  baseUrl?: string;
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
- return json !== null && json !== void 0 ? json : null;
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@li-nk.me/react-native-sdk",
3
- "version": "0.2.5",
3
+ "version": "0.2.8",
4
4
  "description": "React Native SDK for LinkMe deep and deferred links.",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
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
- return json ?? null;
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) {