@billingos/sdk 0.1.0 → 0.1.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.mjs CHANGED
@@ -3,12 +3,12 @@ var Ot = Object.defineProperty;
3
3
  var jt = (e, r, n) => r in e ? Ot(e, r, { enumerable: !0, configurable: !0, writable: !0, value: n }) : e[r] = n;
4
4
  var ie = (e, r, n) => jt(e, typeof r != "symbol" ? r + "" : r, n);
5
5
  import * as u from "react";
6
- import Te, { useState as O, useRef as Re, useCallback as ve, useEffect as K, createContext as qt, useMemo as ze, useContext as $t, forwardRef as nt } from "react";
6
+ import Te, { useState as O, useRef as Re, useCallback as ve, useEffect as W, createContext as qt, useMemo as ze, useContext as $t, forwardRef as nt } from "react";
7
7
  import { QueryClient as zt, QueryClientProvider as Ht, useQuery as ee, useQueryClient as G, useMutation as te } from "@tanstack/react-query";
8
8
  import { useQueryClient as ma } from "@tanstack/react-query";
9
9
  import { jsx as t, jsxs as s, Fragment as se } from "react/jsx-runtime";
10
- import { createRoot as Kt } from "react-dom/client";
11
- import { clsx as Wt } from "clsx";
10
+ import { createRoot as Wt } from "react-dom/client";
11
+ import { clsx as Kt } from "clsx";
12
12
  import { twMerge as Vt } from "tailwind-merge";
13
13
  import { cva as _e } from "class-variance-authority";
14
14
  import { loadStripe as st } from "@stripe/stripe-js";
@@ -581,7 +581,7 @@ function rr(e = {}) {
581
581
  w.current && v(!1);
582
582
  }
583
583
  }, [r, l, o]);
584
- K(() => {
584
+ W(() => {
585
585
  if (!i || !m || !r) return;
586
586
  y.current && clearTimeout(y.current);
587
587
  const b = Date.now(), T = m.getTime() - b, P = T - a * 1e3;
@@ -590,11 +590,11 @@ function rr(e = {}) {
590
590
  }, P) : T > 0 && N(), () => {
591
591
  y.current && clearTimeout(y.current);
592
592
  };
593
- }, [m, i, a, r, N]), K(() => {
593
+ }, [m, i, a, r, N]), W(() => {
594
594
  r && !n && N();
595
- }, [r, n, N]), K(() => {
595
+ }, [r, n, N]), W(() => {
596
596
  n && (d(n), h(null));
597
- }, [n]), K(() => () => {
597
+ }, [n]), W(() => () => {
598
598
  w.current = !1, y.current && clearTimeout(y.current);
599
599
  }, []);
600
600
  const C = !!(c && (!m || m.getTime() > Date.now()));
@@ -772,7 +772,7 @@ function lr(e) {
772
772
  });
773
773
  }
774
774
  function f(...e) {
775
- return Vt(Wt(e));
775
+ return Vt(Kt(e));
776
776
  }
777
777
  const dt = u.createContext(null);
778
778
  function je() {
@@ -996,9 +996,9 @@ function cr({
996
996
  }
997
997
  }
998
998
  };
999
- return K(() => {
999
+ return W(() => {
1000
1000
  e && !c && y();
1001
- }, [e, r]), K(() => () => {
1001
+ }, [e, r]), W(() => () => {
1002
1002
  }, [c]), {
1003
1003
  sessionId: c,
1004
1004
  sessionUrl: m,
@@ -1014,7 +1014,7 @@ function dr() {
1014
1014
  return process.env.NEXT_PUBLIC_APP_URL && e.push(process.env.NEXT_PUBLIC_APP_URL), e.push("https://app.billingos.com"), e.push("https://embed.billingos.com"), process.env.NODE_ENV === "development" && (e.push("http://localhost:3000"), e.push("http://localhost:3001"), e.push("http://127.0.0.1:3000"), e.push("http://127.0.0.1:3001")), e;
1015
1015
  }
1016
1016
  function ur(e) {
1017
- return dr().includes(e);
1017
+ return !!(dr().includes(e) || e.endsWith(".vercel.app") && e.includes("billingos") || e.endsWith(".stripe.com"));
1018
1018
  }
1019
1019
  function mr({
1020
1020
  iframeRef: e,
@@ -1027,7 +1027,7 @@ function mr({
1027
1027
  var d;
1028
1028
  (d = e.current) != null && d.contentWindow ? (a && console.log("[useIframeMessaging] Sending message:", c), e.current.contentWindow.postMessage(c, n)) : console.warn("[useIframeMessaging] Cannot send message - iframe not ready");
1029
1029
  }, [e, n, a]);
1030
- return K(() => {
1030
+ return W(() => {
1031
1031
  const c = (d) => {
1032
1032
  if (!ur(d.origin)) {
1033
1033
  a && console.warn(`[useIframeMessaging] Invalid origin: ${d.origin}`);
@@ -1060,13 +1060,13 @@ function Ye({
1060
1060
  debug: x = !1
1061
1061
  }) {
1062
1062
  const [g, y] = O("loading"), [w, N] = O(null), [C, b] = O(600), S = Re(null);
1063
- K(() => {
1063
+ W(() => {
1064
1064
  console.log(
1065
1065
  "%cšŸš€ BillingOS SDK v1.2.0 loaded with Iframe Checkout",
1066
1066
  "background: linear-gradient(to right, #667eea, #764ba2); color: white; padding: 4px 8px; border-radius: 4px; font-weight: bold;"
1067
1067
  ), console.log("%cšŸ“¦ Using iframe for PCI compliance and security", "color: #10b981; font-weight: 600;"), console.log("%c✨ Customer prefill support enabled", "color: #8b5cf6; font-weight: 600;"), x && console.log("[CheckoutModal] Debug mode enabled");
1068
1068
  }, []);
1069
- const { sessionId: T, sessionUrl: P, loading: z, error: W } = cr({
1069
+ const { sessionId: T, sessionUrl: P, loading: z, error: K } = cr({
1070
1070
  enabled: e,
1071
1071
  priceId: n,
1072
1072
  customer: a,
@@ -1102,7 +1102,7 @@ function Ye({
1102
1102
  onMessage: V,
1103
1103
  debug: x
1104
1104
  });
1105
- K(() => {
1105
+ W(() => {
1106
1106
  T && g === "ready" && Q({
1107
1107
  type: "INIT_CHECKOUT",
1108
1108
  sessionId: T,
@@ -1112,11 +1112,11 @@ function Ye({
1112
1112
  collectBillingAddress: l
1113
1113
  }
1114
1114
  });
1115
- }, [T, g, d, m, l, Q]), K(() => {
1115
+ }, [T, g, d, m, l, Q]), W(() => {
1116
1116
  e || (y("loading"), N(null), b(600));
1117
- }, [e]), K(() => {
1118
- W && (y("error"), N(W), p == null || p(W));
1119
- }, [W, p]);
1117
+ }, [e]), W(() => {
1118
+ K && (y("error"), N(K), p == null || p(K));
1119
+ }, [K, p]);
1120
1120
  const q = z || g === "loading", A = g === "error" && w;
1121
1121
  return /* @__PURE__ */ t(xe, { open: e, onOpenChange: r, children: /* @__PURE__ */ s(
1122
1122
  ye,
@@ -1249,7 +1249,7 @@ class hr {
1249
1249
  onCancel: r.onCancel,
1250
1250
  debug: r.debug
1251
1251
  };
1252
- if (this.root || (this.root = Kt(this.container)), this.client)
1252
+ if (this.root || (this.root = Wt(this.container)), this.client)
1253
1253
  this.root.render(
1254
1254
  Te.createElement(Ye, a)
1255
1255
  );
@@ -1904,7 +1904,7 @@ const Dr = u.forwardRef(
1904
1904
  m(0), p(0);
1905
1905
  return;
1906
1906
  }
1907
- const S = C / N, T = Math.max(S * C, 30), P = N - C, z = P > 0 ? w / P : 0, W = C - T, V = z * W;
1907
+ const S = C / N, T = Math.max(S * C, 30), P = N - C, z = P > 0 ? w / P : 0, K = C - T, V = z * K;
1908
1908
  m(b ? T : 0), p(V);
1909
1909
  }, [a]);
1910
1910
  u.useEffect(() => {
@@ -1926,13 +1926,13 @@ const Dr = u.forwardRef(
1926
1926
  if (b <= 0) return;
1927
1927
  const S = (Q = y.currentTarget.parentElement) == null ? void 0 : Q.parentElement;
1928
1928
  if (!S) return;
1929
- const T = S.getBoundingClientRect(), P = y.clientY, z = w.scrollTop, W = (q) => {
1929
+ const T = S.getBoundingClientRect(), P = y.clientY, z = w.scrollTop, K = (q) => {
1930
1930
  const A = q.clientY - P, Y = T.height, j = A / Y * b, ne = Math.max(0, Math.min(b, z + j));
1931
1931
  w.scrollTop = ne;
1932
1932
  }, V = () => {
1933
- document.removeEventListener("mousemove", W), document.removeEventListener("mouseup", V), document.body.style.userSelect = "", document.body.style.cursor = "";
1933
+ document.removeEventListener("mousemove", K), document.removeEventListener("mouseup", V), document.body.style.userSelect = "", document.body.style.cursor = "";
1934
1934
  };
1935
- document.body.style.userSelect = "none", document.body.style.cursor = "grabbing", document.addEventListener("mousemove", W), document.addEventListener("mouseup", V);
1935
+ document.body.style.userSelect = "none", document.body.style.cursor = "grabbing", document.addEventListener("mousemove", K), document.addEventListener("mouseup", V);
1936
1936
  },
1937
1937
  []
1938
1938
  );
@@ -2377,9 +2377,9 @@ function qr({
2377
2377
  }
2378
2378
  }
2379
2379
  };
2380
- return K(() => {
2380
+ return W(() => {
2381
2381
  e && !i && v();
2382
- }, [e]), K(() => () => {
2382
+ }, [e]), W(() => () => {
2383
2383
  }, [i]), {
2384
2384
  sessionId: i,
2385
2385
  sessionUrl: o,
@@ -2405,7 +2405,7 @@ function $r({
2405
2405
  const o = l.src, c = new URL(o).origin;
2406
2406
  l.contentWindow.postMessage(i, c);
2407
2407
  }, [e, n]);
2408
- return K(() => {
2408
+ return W(() => {
2409
2409
  const i = (l) => {
2410
2410
  if (!l.data || typeof l.data != "object" || !l.data.type)
2411
2411
  return;
@@ -2502,7 +2502,7 @@ const Hr = u.forwardRef(({ className: e, ...r }, n) => /* @__PURE__ */ t(
2502
2502
  }
2503
2503
  ));
2504
2504
  Hr.displayName = "TableCaption";
2505
- function Kr(e = {}) {
2505
+ function Wr(e = {}) {
2506
2506
  const { client: r } = E(), { planIds: n, enabled: a = !0 } = e;
2507
2507
  return ee({
2508
2508
  queryKey: ["products", n],
@@ -2514,7 +2514,7 @@ function Kr(e = {}) {
2514
2514
  // 10 minutes
2515
2515
  });
2516
2516
  }
2517
- class Wr extends u.Component {
2517
+ class Kr extends u.Component {
2518
2518
  constructor(n) {
2519
2519
  super(n);
2520
2520
  ie(this, "reset", () => {
@@ -2932,7 +2932,7 @@ function Gr({
2932
2932
  ] })
2933
2933
  ] });
2934
2934
  }
2935
- const Ke = "pk_test_51SihBODiEfx9xR94hb9APIlKq2CEr3uJqjQ1j98VdO5i30EGWi4HieGFjy1O3lEF3OWangT10RYr2Kae4CxfAvYd00xEVl0Raw";
2935
+ const We = "pk_test_51SihBODiEfx9xR94hb9APIlKq2CEr3uJqjQ1j98VdO5i30EGWi4HieGFjy1O3lEF3OWangT10RYr2Kae4CxfAvYd00xEVl0Raw";
2936
2936
  function Qr(e) {
2937
2937
  return !!((e.startsWith("pk_live_") || e.startsWith("pk_test_")) && e.length > 20);
2938
2938
  }
@@ -2988,16 +2988,16 @@ function Zr({
2988
2988
  }, [b, P, S, r]), u.useEffect(() => {
2989
2989
  var L;
2990
2990
  if (console.log("[PaymentBottomSheet] Stripe initialization effect triggered"), P) {
2991
- const j = Qr(Ke), ne = Xr(P.clientSecret);
2991
+ const j = Qr(We), ne = Xr(P.clientSecret);
2992
2992
  if (console.log("[PaymentBottomSheet] Stripe validation:", {
2993
- publishableKey: Ke,
2993
+ publishableKey: We,
2994
2994
  validKey: j,
2995
2995
  clientSecret: ((L = P.clientSecret) == null ? void 0 : L.substring(0, 20)) + "...",
2996
2996
  validSecret: ne,
2997
2997
  stripeAccountId: P.stripeAccountId
2998
2998
  }), j && ne) {
2999
2999
  console.log("[PaymentBottomSheet] Loading Stripe with valid credentials");
3000
- const oe = st(Ke, {
3000
+ const oe = st(We, {
3001
3001
  stripeAccount: P.stripeAccountId
3002
3002
  });
3003
3003
  h(oe), C(!1);
@@ -3014,7 +3014,7 @@ function Zr({
3014
3014
  v("success"), d.invalidateQueries({ queryKey: ["billingos", "products"] }), console.log("šŸ’« Invalidated products query - PricingTable will auto-refresh"), setTimeout(() => {
3015
3015
  a(L);
3016
3016
  }, 1500);
3017
- }, W = (L) => {
3017
+ }, K = (L) => {
3018
3018
  g(L);
3019
3019
  }, V = () => {
3020
3020
  console.log("[PaymentBottomSheet] handleClose called, isProcessing:", y), !(y && !window.confirm(
@@ -3046,7 +3046,7 @@ function Zr({
3046
3046
  }
3047
3047
  };
3048
3048
  return console.log("[PaymentBottomSheet] Rendering drawer with isOpen:", r, "sheetState:", p), /* @__PURE__ */ t(
3049
- Wr,
3049
+ Kr,
3050
3050
  {
3051
3051
  fallback: (L, j) => /* @__PURE__ */ s("div", { style: { padding: "20px", maxWidth: "400px", margin: "0 auto" }, children: [
3052
3052
  /* @__PURE__ */ t(Z, { variant: "destructive", children: /* @__PURE__ */ s(J, { children: [
@@ -3275,7 +3275,7 @@ function Zr({
3275
3275
  {
3276
3276
  checkoutSession: P,
3277
3277
  onSuccess: z,
3278
- onError: W,
3278
+ onError: K,
3279
3279
  isProcessing: y,
3280
3280
  setIsProcessing: w
3281
3281
  }
@@ -3316,7 +3316,7 @@ function Jr({
3316
3316
  "background: linear-gradient(to right, #10b981, #3b82f6); color: white; padding: 4px 8px; border-radius: 4px; font-weight: bold;"
3317
3317
  ) : console.log("šŸ“¦ Using PaymentBottomSheet (legacy)");
3318
3318
  }, [c]);
3319
- const { data: z, isLoading: W, error: V, refetch: Q } = Kr({ planIds: e }), q = (z == null ? void 0 : z.products) || [], A = (z == null ? void 0 : z.currentSubscription) || null, Y = q.some(
3319
+ const { data: z, isLoading: K, error: V, refetch: Q } = Wr({ planIds: e }), q = (z == null ? void 0 : z.products) || [], A = (z == null ? void 0 : z.currentSubscription) || null, Y = q.some(
3320
3320
  (k) => k.prices.some((M) => M.interval === "year")
3321
3321
  ), L = u.useMemo(() => {
3322
3322
  const k = /* @__PURE__ */ new Map();
@@ -3376,7 +3376,7 @@ function Jr({
3376
3376
  return console.log("[PricingTable] Updated cache data:", R), R;
3377
3377
  })), console.log("[PricingTable] Triggering background refetch..."), await Q(), console.log("%cāœ… Products cache invalidated and refetched", "color: #10b981; font-weight: 600;");
3378
3378
  }, [S, Q, e, d]);
3379
- return W ? /* @__PURE__ */ s("div", { className: f("w-full", i === "dark" && "dark"), children: [
3379
+ return K ? /* @__PURE__ */ s("div", { className: f("w-full", i === "dark" && "dark"), children: [
3380
3380
  l && /* @__PURE__ */ s("div", { className: "text-center mb-8", children: [
3381
3381
  /* @__PURE__ */ t(_, { className: "h-10 w-64 mx-auto mb-2" }),
3382
3382
  o && /* @__PURE__ */ t(_, { className: "h-5 w-96 mx-auto" })
@@ -3735,14 +3735,14 @@ function Fs({
3735
3735
  debug: v = !1
3736
3736
  }) {
3737
3737
  const [x, g] = O("loading"), [y, w] = O(null), [N, C] = O(600), [b, S] = O(!1), [T, P] = O(null), z = Re(null);
3738
- K(() => {
3738
+ W(() => {
3739
3739
  console.log(
3740
3740
  "%cšŸš€ BillingOS SDK v1.2.0 - Iframe Customer Portal with Smart Pricing Table",
3741
3741
  "background: linear-gradient(to right, #667eea, #764ba2); color: white; padding: 4px 8px; border-radius: 4px; font-weight: bold;"
3742
3742
  ), console.log("%cšŸ“¦ Using iframe for instant updates and security", "color: #10b981; font-weight: 600;"), console.log("%cšŸŽØ Supports drawer, modal, and page modes", "color: #8b5cf6; font-weight: 600;"), v && console.log("[CustomerPortal] Debug mode enabled");
3743
3743
  }, []);
3744
- const W = n === "page" || e, { sessionId: V, sessionUrl: Q, loading: q, error: A } = qr({
3745
- enabled: W,
3744
+ const K = n === "page" || e, { sessionId: V, sessionUrl: Q, loading: q, error: A } = qr({
3745
+ enabled: K,
3746
3746
  customerId: o,
3747
3747
  metadata: c
3748
3748
  }), Y = ve((k) => {
@@ -3786,7 +3786,7 @@ function Fs({
3786
3786
  onMessage: Y,
3787
3787
  debug: v
3788
3788
  });
3789
- K(() => {
3789
+ W(() => {
3790
3790
  V && x === "ready" && L({
3791
3791
  type: "INIT_PORTAL",
3792
3792
  sessionId: V,
@@ -3795,9 +3795,9 @@ function Fs({
3795
3795
  defaultTab: a
3796
3796
  }
3797
3797
  });
3798
- }, [V, x, i, a, L]), K(() => {
3799
- W || (g("loading"), w(null), C(600));
3800
- }, [W]), K(() => {
3798
+ }, [V, x, i, a, L]), W(() => {
3799
+ K || (g("loading"), w(null), C(600));
3800
+ }, [K]), W(() => {
3801
3801
  A && (g("error"), w(A));
3802
3802
  }, [A]);
3803
3803
  const j = q || x === "loading", oe = /* @__PURE__ */ s(se, { children: [
@@ -3969,7 +3969,7 @@ function Hs(e) {
3969
3969
  }
3970
3970
  });
3971
3971
  }
3972
- function Ks(e) {
3972
+ function Ws(e) {
3973
3973
  const { client: r } = E(), n = G();
3974
3974
  return te({
3975
3975
  ...e,
@@ -3980,7 +3980,7 @@ function Ks(e) {
3980
3980
  }
3981
3981
  });
3982
3982
  }
3983
- function Ws(e) {
3983
+ function Ks(e) {
3984
3984
  const { client: r } = E(), n = G();
3985
3985
  return te({
3986
3986
  ...e,
@@ -4113,7 +4113,7 @@ function ln(e) {
4113
4113
  return "warning";
4114
4114
  }
4115
4115
  }
4116
- function We({
4116
+ function Ke({
4117
4117
  type: e,
4118
4118
  message: r,
4119
4119
  actionLabel: n,
@@ -4257,7 +4257,7 @@ function Gs({
4257
4257
  ), C = m === "trialing" && v && new Date(v).getTime() - Date.now() < 4320 * 60 * 1e3;
4258
4258
  return /* @__PURE__ */ s("div", { className: f("space-y-6", o), children: [
4259
4259
  m === "past_due" && /* @__PURE__ */ t(
4260
- We,
4260
+ Ke,
4261
4261
  {
4262
4262
  type: "past_due",
4263
4263
  message: "Your last payment was declined. Update your payment method to avoid service interruption.",
@@ -4266,7 +4266,7 @@ function Gs({
4266
4266
  }
4267
4267
  ),
4268
4268
  C && v && /* @__PURE__ */ t(
4269
- We,
4269
+ Ke,
4270
4270
  {
4271
4271
  type: "trial_ending",
4272
4272
  message: `Your trial ends on ${new Date(v).toLocaleDateString()}. Add a payment method to continue.`,
@@ -4275,7 +4275,7 @@ function Gs({
4275
4275
  }
4276
4276
  ),
4277
4277
  p && /* @__PURE__ */ t(
4278
- We,
4278
+ Ke,
4279
4279
  {
4280
4280
  type: "subscription_canceled",
4281
4281
  message: `Your subscription will end on ${w}. You'll have access until then.`,
@@ -5666,7 +5666,7 @@ function Hn({
5666
5666
  }
5667
5667
  ) });
5668
5668
  }
5669
- function Kn(e) {
5669
+ function Wn(e) {
5670
5670
  if (typeof window > "u") return;
5671
5671
  const r = `nudge_dismissed_${e.type}_${e.feature || "general"}`;
5672
5672
  localStorage.setItem(r, Date.now().toString());
@@ -5696,7 +5696,7 @@ function ra({
5696
5696
  return window.addEventListener("keydown", h), () => window.removeEventListener("keydown", h);
5697
5697
  }, [o]);
5698
5698
  const d = () => {
5699
- c(!1), Kn(e), i == null || i();
5699
+ c(!1), Wn(e), i == null || i();
5700
5700
  }, m = () => {
5701
5701
  a == null || a(e.suggestedPlan.priceId);
5702
5702
  };
@@ -5769,12 +5769,12 @@ function sa({
5769
5769
  onAccessDenied: i,
5770
5770
  onQuotaExceeded: l
5771
5771
  });
5772
- return d ? /* @__PURE__ */ t(se, { children: a || /* @__PURE__ */ t(Wn, {}) }) : m || !c ? /* @__PURE__ */ t(se, { children: n || /* @__PURE__ */ t(Vn, { feature: e }) }) : o && p > 0 ? /* @__PURE__ */ s("div", { className: "relative", children: [
5772
+ return d ? /* @__PURE__ */ t(se, { children: a || /* @__PURE__ */ t(Kn, {}) }) : m || !c ? /* @__PURE__ */ t(se, { children: n || /* @__PURE__ */ t(Vn, { feature: e }) }) : o && p > 0 ? /* @__PURE__ */ s("div", { className: "relative", children: [
5773
5773
  r,
5774
5774
  /* @__PURE__ */ t(Yn, { usage: h, limit: p, remaining: v })
5775
5775
  ] }) : /* @__PURE__ */ t(se, { children: r });
5776
5776
  }
5777
- function Wn() {
5777
+ function Kn() {
5778
5778
  return /* @__PURE__ */ t("div", { className: "flex items-center justify-center p-4", children: /* @__PURE__ */ t("div", { className: "animate-pulse text-gray-400", children: "Checking access..." }) });
5779
5779
  }
5780
5780
  function Vn({ feature: e }) {
@@ -6209,7 +6209,7 @@ export {
6209
6209
  tn as UsageBar,
6210
6210
  aa as UsageDisplay,
6211
6211
  Ae as ValidationError,
6212
- We as WarningBanner,
6212
+ Ke as WarningBanner,
6213
6213
  yn as addAmounts,
6214
6214
  br as badgeVariants,
6215
6215
  wr as buttonVariants,
@@ -6261,14 +6261,14 @@ export {
6261
6261
  Rs as useIsApproachingLimit,
6262
6262
  As as usePortalData,
6263
6263
  ir as usePreviewPlanChange,
6264
- Kr as usePricingTableProducts,
6264
+ Wr as usePricingTableProducts,
6265
6265
  vr as useProducts,
6266
6266
  qs as useReactivatePortalSubscription,
6267
6267
  Ss as useReactivateSubscription,
6268
6268
  Hs as useRemovePaymentMethod,
6269
- Ws as useRetryInvoice,
6269
+ Ks as useRetryInvoice,
6270
6270
  rr as useSessionToken,
6271
- Ks as useSetDefaultPaymentMethod,
6271
+ Ws as useSetDefaultPaymentMethod,
6272
6272
  $s as useSetupIntent,
6273
6273
  bs as useSubscription,
6274
6274
  Ps as useSubscriptionPreview,