@followgate/js 0.9.6 → 0.10.1

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.d.mts CHANGED
@@ -105,8 +105,9 @@ declare class FollowGateClient {
105
105
  show(): Promise<void>;
106
106
  /**
107
107
  * Hide the modal
108
+ * @param cancelled - If true, redirect to cancelUrl if configured
108
109
  */
109
- hide(): void;
110
+ hide(cancelled?: boolean): void;
110
111
  private injectStyles;
111
112
  private createModal;
112
113
  private getContentElement;
@@ -181,6 +182,10 @@ declare class FollowGateClient {
181
182
  private buildLinkedInUrl;
182
183
  private trackEvent;
183
184
  private emit;
185
+ /**
186
+ * Escape HTML to prevent XSS
187
+ */
188
+ private escapeHtml;
184
189
  }
185
190
  declare const FollowGate: FollowGateClient;
186
191
 
package/dist/index.d.ts CHANGED
@@ -105,8 +105,9 @@ declare class FollowGateClient {
105
105
  show(): Promise<void>;
106
106
  /**
107
107
  * Hide the modal
108
+ * @param cancelled - If true, redirect to cancelUrl if configured
108
109
  */
109
- hide(): void;
110
+ hide(cancelled?: boolean): void;
110
111
  private injectStyles;
111
112
  private createModal;
112
113
  private getContentElement;
@@ -181,6 +182,10 @@ declare class FollowGateClient {
181
182
  private buildLinkedInUrl;
182
183
  private trackEvent;
183
184
  private emit;
185
+ /**
186
+ * Escape HTML to prevent XSS
187
+ */
188
+ private escapeHtml;
184
189
  }
185
190
  declare const FollowGate: FollowGateClient;
186
191
 
package/dist/index.js CHANGED
@@ -518,6 +518,8 @@ var FollowGateClient = class {
518
518
  theme: config.theme || "dark",
519
519
  accentColor: config.accentColor || "#6366f1"
520
520
  };
521
+ this.serverConfig = null;
522
+ this.configFetched = false;
521
523
  this.restoreSession();
522
524
  if (config.debug) {
523
525
  console.log("[FollowGate] Initialized with appId:", config.appId);
@@ -585,8 +587,9 @@ var FollowGateClient = class {
585
587
  }
586
588
  /**
587
589
  * Hide the modal
590
+ * @param cancelled - If true, redirect to cancelUrl if configured
588
591
  */
589
- hide() {
592
+ hide(cancelled = false) {
590
593
  if (this.modalElement) {
591
594
  this.modalElement.classList.remove("fg-visible");
592
595
  setTimeout(() => {
@@ -594,6 +597,9 @@ var FollowGateClient = class {
594
597
  this.modalElement = null;
595
598
  }, 300);
596
599
  }
600
+ if (cancelled && this.serverConfig?.cancelUrl) {
601
+ window.location.href = this.serverConfig.cancelUrl;
602
+ }
597
603
  }
598
604
  injectStyles() {
599
605
  if (this.stylesInjected) return;
@@ -646,6 +652,8 @@ var FollowGateClient = class {
646
652
  const handle = this.serverConfig?.targetHandle || this.config?.twitter?.handle;
647
653
  const hasRepost = !!this.config?.twitter?.tweetId;
648
654
  const allowSkip = this.serverConfig?.allowSkip ?? false;
655
+ const welcomeTitle = this.serverConfig?.welcomeTitle || "Unlock Free Access";
656
+ const welcomeMessage = this.serverConfig?.welcomeMessage || "Enter your X username to get started";
649
657
  let explanationText = handle ? `Complete a quick follow${hasRepost ? " & repost" : ""} on X for @${handle} to unlock access.` : `Complete a quick social action to unlock access.`;
650
658
  if (allowSkip) {
651
659
  explanationText += ` You can skip if you prefer, but it helps support the developer.`;
@@ -654,8 +662,8 @@ var FollowGateClient = class {
654
662
  <div class="fg-icon-box">
655
663
  ${ICONS.x}
656
664
  </div>
657
- <h2 class="fg-title">Unlock Free Access</h2>
658
- <p class="fg-subtitle">Enter your X username to get started</p>
665
+ <h2 class="fg-title">${this.escapeHtml(welcomeTitle)}</h2>
666
+ <p class="fg-subtitle">${this.escapeHtml(welcomeMessage)}</p>
659
667
  <div class="fg-info-box" style="margin-bottom: 20px;">
660
668
  <p>${explanationText}</p>
661
669
  </div>
@@ -907,8 +915,11 @@ var FollowGateClient = class {
907
915
  const content = this.getContentElement();
908
916
  if (!content) return;
909
917
  const username = this.currentUser?.username;
918
+ const successTitle = this.serverConfig?.successTitle || "Almost done!";
919
+ const successMessage = this.serverConfig?.successMessage || null;
910
920
  content.innerHTML = `
911
- <h2 class="fg-title">Almost done!</h2>
921
+ <h2 class="fg-title">${this.escapeHtml(successTitle)}</h2>
922
+ ${successMessage ? `<p class="fg-subtitle" style="margin-bottom: 16px;">${this.escapeHtml(successMessage)}</p>` : ""}
912
923
  <div class="fg-verify-box">
913
924
  <div class="fg-verify-box-left">
914
925
  <div class="fg-verify-spinner"></div>
@@ -971,6 +982,9 @@ var FollowGateClient = class {
971
982
  await this.unlock();
972
983
  this.hide();
973
984
  this.config?.onComplete?.();
985
+ if (this.serverConfig?.successUrl) {
986
+ window.location.href = this.serverConfig.successUrl;
987
+ }
974
988
  }
975
989
  renderStepIndicator(currentStep) {
976
990
  return `
@@ -1390,6 +1404,14 @@ var FollowGateClient = class {
1390
1404
  emit(event, data) {
1391
1405
  this.listeners.get(event)?.forEach((callback) => callback(data));
1392
1406
  }
1407
+ /**
1408
+ * Escape HTML to prevent XSS
1409
+ */
1410
+ escapeHtml(text) {
1411
+ const div = document.createElement("div");
1412
+ div.textContent = text;
1413
+ return div.innerHTML;
1414
+ }
1393
1415
  };
1394
1416
  var FollowGate = new FollowGateClient();
1395
1417
  // Annotate the CommonJS export names for ESM import in node:
package/dist/index.mjs CHANGED
@@ -492,6 +492,8 @@ var FollowGateClient = class {
492
492
  theme: config.theme || "dark",
493
493
  accentColor: config.accentColor || "#6366f1"
494
494
  };
495
+ this.serverConfig = null;
496
+ this.configFetched = false;
495
497
  this.restoreSession();
496
498
  if (config.debug) {
497
499
  console.log("[FollowGate] Initialized with appId:", config.appId);
@@ -559,8 +561,9 @@ var FollowGateClient = class {
559
561
  }
560
562
  /**
561
563
  * Hide the modal
564
+ * @param cancelled - If true, redirect to cancelUrl if configured
562
565
  */
563
- hide() {
566
+ hide(cancelled = false) {
564
567
  if (this.modalElement) {
565
568
  this.modalElement.classList.remove("fg-visible");
566
569
  setTimeout(() => {
@@ -568,6 +571,9 @@ var FollowGateClient = class {
568
571
  this.modalElement = null;
569
572
  }, 300);
570
573
  }
574
+ if (cancelled && this.serverConfig?.cancelUrl) {
575
+ window.location.href = this.serverConfig.cancelUrl;
576
+ }
571
577
  }
572
578
  injectStyles() {
573
579
  if (this.stylesInjected) return;
@@ -620,6 +626,8 @@ var FollowGateClient = class {
620
626
  const handle = this.serverConfig?.targetHandle || this.config?.twitter?.handle;
621
627
  const hasRepost = !!this.config?.twitter?.tweetId;
622
628
  const allowSkip = this.serverConfig?.allowSkip ?? false;
629
+ const welcomeTitle = this.serverConfig?.welcomeTitle || "Unlock Free Access";
630
+ const welcomeMessage = this.serverConfig?.welcomeMessage || "Enter your X username to get started";
623
631
  let explanationText = handle ? `Complete a quick follow${hasRepost ? " & repost" : ""} on X for @${handle} to unlock access.` : `Complete a quick social action to unlock access.`;
624
632
  if (allowSkip) {
625
633
  explanationText += ` You can skip if you prefer, but it helps support the developer.`;
@@ -628,8 +636,8 @@ var FollowGateClient = class {
628
636
  <div class="fg-icon-box">
629
637
  ${ICONS.x}
630
638
  </div>
631
- <h2 class="fg-title">Unlock Free Access</h2>
632
- <p class="fg-subtitle">Enter your X username to get started</p>
639
+ <h2 class="fg-title">${this.escapeHtml(welcomeTitle)}</h2>
640
+ <p class="fg-subtitle">${this.escapeHtml(welcomeMessage)}</p>
633
641
  <div class="fg-info-box" style="margin-bottom: 20px;">
634
642
  <p>${explanationText}</p>
635
643
  </div>
@@ -881,8 +889,11 @@ var FollowGateClient = class {
881
889
  const content = this.getContentElement();
882
890
  if (!content) return;
883
891
  const username = this.currentUser?.username;
892
+ const successTitle = this.serverConfig?.successTitle || "Almost done!";
893
+ const successMessage = this.serverConfig?.successMessage || null;
884
894
  content.innerHTML = `
885
- <h2 class="fg-title">Almost done!</h2>
895
+ <h2 class="fg-title">${this.escapeHtml(successTitle)}</h2>
896
+ ${successMessage ? `<p class="fg-subtitle" style="margin-bottom: 16px;">${this.escapeHtml(successMessage)}</p>` : ""}
886
897
  <div class="fg-verify-box">
887
898
  <div class="fg-verify-box-left">
888
899
  <div class="fg-verify-spinner"></div>
@@ -945,6 +956,9 @@ var FollowGateClient = class {
945
956
  await this.unlock();
946
957
  this.hide();
947
958
  this.config?.onComplete?.();
959
+ if (this.serverConfig?.successUrl) {
960
+ window.location.href = this.serverConfig.successUrl;
961
+ }
948
962
  }
949
963
  renderStepIndicator(currentStep) {
950
964
  return `
@@ -1364,6 +1378,14 @@ var FollowGateClient = class {
1364
1378
  emit(event, data) {
1365
1379
  this.listeners.get(event)?.forEach((callback) => callback(data));
1366
1380
  }
1381
+ /**
1382
+ * Escape HTML to prevent XSS
1383
+ */
1384
+ escapeHtml(text) {
1385
+ const div = document.createElement("div");
1386
+ div.textContent = text;
1387
+ return div.innerHTML;
1388
+ }
1367
1389
  };
1368
1390
  var FollowGate = new FollowGateClient();
1369
1391
  export {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@followgate/js",
3
- "version": "0.9.6",
3
+ "version": "0.10.1",
4
4
  "description": "FollowGate SDK - Grow your audience with every download. Require social actions (follow, repost) before users can access your app.",
5
5
  "author": "FollowGate <hello@followgate.app>",
6
6
  "homepage": "https://followgate.app",