@stackframe/react 2.8.78 → 2.8.79

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.
Files changed (96) hide show
  1. package/dist/components-page/account-settings/payments/payments-panel.d.ts.map +1 -1
  2. package/dist/components-page/account-settings/payments/payments-panel.js +3 -2
  3. package/dist/components-page/account-settings/payments/payments-panel.js.map +1 -1
  4. package/dist/components-page/oauth-callback.d.ts.map +1 -1
  5. package/dist/components-page/oauth-callback.js +4 -1
  6. package/dist/components-page/oauth-callback.js.map +1 -1
  7. package/dist/components-page/stack-handler-client.d.ts.map +1 -1
  8. package/dist/components-page/stack-handler-client.js +34 -8
  9. package/dist/components-page/stack-handler-client.js.map +1 -1
  10. package/dist/esm/components-page/account-settings/payments/payments-panel.d.ts.map +1 -1
  11. package/dist/esm/components-page/account-settings/payments/payments-panel.js +3 -2
  12. package/dist/esm/components-page/account-settings/payments/payments-panel.js.map +1 -1
  13. package/dist/esm/components-page/oauth-callback.d.ts.map +1 -1
  14. package/dist/esm/components-page/oauth-callback.js +4 -1
  15. package/dist/esm/components-page/oauth-callback.js.map +1 -1
  16. package/dist/esm/components-page/stack-handler-client.d.ts.map +1 -1
  17. package/dist/esm/components-page/stack-handler-client.js +34 -8
  18. package/dist/esm/components-page/stack-handler-client.js.map +1 -1
  19. package/dist/esm/lib/auth.d.ts.map +1 -1
  20. package/dist/esm/lib/auth.js.map +1 -1
  21. package/dist/esm/lib/env.d.ts +36 -0
  22. package/dist/esm/lib/env.d.ts.map +1 -0
  23. package/dist/esm/lib/env.js +85 -0
  24. package/dist/esm/lib/env.js.map +1 -0
  25. package/dist/esm/lib/stack-app/apps/implementations/admin-app-impl.d.ts +2 -2
  26. package/dist/esm/lib/stack-app/apps/implementations/admin-app-impl.d.ts.map +1 -1
  27. package/dist/esm/lib/stack-app/apps/implementations/client-app-impl.d.ts +19 -4
  28. package/dist/esm/lib/stack-app/apps/implementations/client-app-impl.d.ts.map +1 -1
  29. package/dist/esm/lib/stack-app/apps/implementations/client-app-impl.js +132 -19
  30. package/dist/esm/lib/stack-app/apps/implementations/client-app-impl.js.map +1 -1
  31. package/dist/esm/lib/stack-app/apps/implementations/common.d.ts +9 -7
  32. package/dist/esm/lib/stack-app/apps/implementations/common.d.ts.map +1 -1
  33. package/dist/esm/lib/stack-app/apps/implementations/common.js +17 -36
  34. package/dist/esm/lib/stack-app/apps/implementations/common.js.map +1 -1
  35. package/dist/esm/lib/stack-app/apps/implementations/event-tracker.d.ts.map +1 -1
  36. package/dist/esm/lib/stack-app/apps/implementations/event-tracker.js +30 -13
  37. package/dist/esm/lib/stack-app/apps/implementations/event-tracker.js.map +1 -1
  38. package/dist/esm/lib/stack-app/apps/implementations/redirect-page-urls.d.ts +35 -0
  39. package/dist/esm/lib/stack-app/apps/implementations/redirect-page-urls.d.ts.map +1 -0
  40. package/dist/esm/lib/stack-app/apps/implementations/redirect-page-urls.js +187 -0
  41. package/dist/esm/lib/stack-app/apps/implementations/redirect-page-urls.js.map +1 -0
  42. package/dist/esm/lib/stack-app/apps/interfaces/client-app.d.ts +7 -3
  43. package/dist/esm/lib/stack-app/apps/interfaces/client-app.d.ts.map +1 -1
  44. package/dist/esm/lib/stack-app/apps/interfaces/client-app.js.map +1 -1
  45. package/dist/esm/lib/stack-app/common.d.ts +17 -20
  46. package/dist/esm/lib/stack-app/common.d.ts.map +1 -1
  47. package/dist/esm/lib/stack-app/common.js.map +1 -1
  48. package/dist/esm/lib/stack-app/index.d.ts +2 -2
  49. package/dist/esm/lib/stack-app/url-targets.d.ts +29 -0
  50. package/dist/esm/lib/stack-app/url-targets.d.ts.map +1 -0
  51. package/dist/esm/lib/stack-app/url-targets.js +317 -0
  52. package/dist/esm/lib/stack-app/url-targets.js.map +1 -0
  53. package/dist/esm/lib/stack-app/url-targets.test.d.ts +1 -0
  54. package/dist/esm/lib/stack-app/url-targets.test.js +135 -0
  55. package/dist/esm/lib/stack-app/url-targets.test.js.map +1 -0
  56. package/dist/esm/providers/stack-provider-client.js +1 -1
  57. package/dist/index.d.ts +2 -2
  58. package/dist/lib/auth.d.ts.map +1 -1
  59. package/dist/lib/auth.js.map +1 -1
  60. package/dist/lib/env.d.ts +36 -0
  61. package/dist/lib/env.d.ts.map +1 -0
  62. package/dist/lib/env.js +87 -0
  63. package/dist/lib/env.js.map +1 -0
  64. package/dist/lib/stack-app/apps/implementations/admin-app-impl.d.ts +3 -3
  65. package/dist/lib/stack-app/apps/implementations/admin-app-impl.d.ts.map +1 -1
  66. package/dist/lib/stack-app/apps/implementations/client-app-impl.d.ts +19 -4
  67. package/dist/lib/stack-app/apps/implementations/client-app-impl.d.ts.map +1 -1
  68. package/dist/lib/stack-app/apps/implementations/client-app-impl.js +131 -18
  69. package/dist/lib/stack-app/apps/implementations/client-app-impl.js.map +1 -1
  70. package/dist/lib/stack-app/apps/implementations/common.d.ts +9 -7
  71. package/dist/lib/stack-app/apps/implementations/common.d.ts.map +1 -1
  72. package/dist/lib/stack-app/apps/implementations/common.js +17 -36
  73. package/dist/lib/stack-app/apps/implementations/common.js.map +1 -1
  74. package/dist/lib/stack-app/apps/implementations/event-tracker.d.ts.map +1 -1
  75. package/dist/lib/stack-app/apps/implementations/event-tracker.js +30 -13
  76. package/dist/lib/stack-app/apps/implementations/event-tracker.js.map +1 -1
  77. package/dist/lib/stack-app/apps/implementations/redirect-page-urls.d.ts +35 -0
  78. package/dist/lib/stack-app/apps/implementations/redirect-page-urls.d.ts.map +1 -0
  79. package/dist/lib/stack-app/apps/implementations/redirect-page-urls.js +191 -0
  80. package/dist/lib/stack-app/apps/implementations/redirect-page-urls.js.map +1 -0
  81. package/dist/lib/stack-app/apps/interfaces/client-app.d.ts +7 -3
  82. package/dist/lib/stack-app/apps/interfaces/client-app.d.ts.map +1 -1
  83. package/dist/lib/stack-app/apps/interfaces/client-app.js.map +1 -1
  84. package/dist/lib/stack-app/common.d.ts +17 -20
  85. package/dist/lib/stack-app/common.d.ts.map +1 -1
  86. package/dist/lib/stack-app/common.js.map +1 -1
  87. package/dist/lib/stack-app/index.d.ts +2 -2
  88. package/dist/lib/stack-app/url-targets.d.ts +29 -0
  89. package/dist/lib/stack-app/url-targets.d.ts.map +1 -0
  90. package/dist/lib/stack-app/url-targets.js +324 -0
  91. package/dist/lib/stack-app/url-targets.js.map +1 -0
  92. package/dist/lib/stack-app/url-targets.test.d.ts +1 -0
  93. package/dist/lib/stack-app/url-targets.test.js +135 -0
  94. package/dist/lib/stack-app/url-targets.test.js.map +1 -0
  95. package/dist/providers/stack-provider-client.js +1 -1
  96. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"payments-panel.d.ts","names":[],"sources":["../../../../src/components-page/account-settings/payments/payments-panel.tsx"],"mappings":";;;;KAmBK,oBAAA;EACH,EAAA;EACA,KAAA;EACA,KAAA;EACA,SAAA;EACA,QAAA;AAAA;AAAA,KAsDG,eAAA;EACH,WAAA;EACA,oBAAA,EAAsB,oBAAA;AAAA;AAAA,KAGnB,gCAAA;EACH,YAAA;EACA,eAAA;AAAA;AAAA,KAGG,YAAA;EACH,EAAA;EACA,UAAA,QAAkB,eAAA;EAClB,WAAA,QAAmB,KAAA;IACjB,EAAA;IACA,QAAA;IACA,WAAA;IACA,YAAA;IACA,IAAA;IACA,aAAA,GAAgB,KAAA;MACd,SAAA;MACA,WAAA;MACA,MAAA,EAAQ,MAAA;QAAiB,QAAA;MAAA;IAAA;IAE3B,YAAA;MACE,cAAA;MACA,gBAAA,EAAkB,IAAA;MAClB,iBAAA;MACA,YAAA;IAAA;EAAA;EAGJ,WAAA,GAAc,OAAA,GAAU,2BAAA,KAAgC,oBAAA;EACxD,8BAAA,QAAsC,OAAA,CAAQ,gCAAA;EAC9C,sCAAA,GAAyC,aAAA,aAA0B,OAAA,CAAQ,oBAAA;EAC3E,kBAAA,GAAqB,OAAA;IAAW,aAAA;IAAuB,WAAA;IAAqB,OAAA;IAAkB,QAAA;EAAA,MAAwB,OAAA;AAAA;AAAA,iBAyDxG,aAAA,CAAc,KAAA;EAC5B,KAAA;EACA,QAAA,GAAW,YAAA;EACX,YAAA;EACA,QAAA;AAAA,IACD,kBAAA,CAAA,GAAA,CAAA,OAAA"}
1
+ {"version":3,"file":"payments-panel.d.ts","names":[],"sources":["../../../../src/components-page/account-settings/payments/payments-panel.tsx"],"mappings":";;;;KAoBK,oBAAA;EACH,EAAA;EACA,KAAA;EACA,KAAA;EACA,SAAA;EACA,QAAA;AAAA;AAAA,KAsDG,eAAA;EACH,WAAA;EACA,oBAAA,EAAsB,oBAAA;AAAA;AAAA,KAGnB,gCAAA;EACH,YAAA;EACA,eAAA;AAAA;AAAA,KAGG,YAAA;EACH,EAAA;EACA,UAAA,QAAkB,eAAA;EAClB,WAAA,QAAmB,KAAA;IACjB,EAAA;IACA,QAAA;IACA,WAAA;IACA,YAAA;IACA,IAAA;IACA,aAAA,GAAgB,KAAA;MACd,SAAA;MACA,WAAA;MACA,MAAA,EAAQ,MAAA;QAAiB,QAAA;MAAA;IAAA;IAE3B,YAAA;MACE,cAAA;MACA,gBAAA,EAAkB,IAAA;MAClB,iBAAA;MACA,YAAA;IAAA;EAAA;EAGJ,WAAA,GAAc,OAAA,GAAU,2BAAA,KAAgC,oBAAA;EACxD,8BAAA,QAAsC,OAAA,CAAQ,gCAAA;EAC9C,sCAAA,GAAyC,aAAA,aAA0B,OAAA,CAAQ,oBAAA;EAC3E,kBAAA,GAAqB,OAAA;IAAW,aAAA;IAAuB,WAAA;IAAqB,OAAA;IAAkB,QAAA;EAAA,MAAwB,OAAA;AAAA;AAAA,iBAyDxG,aAAA,CAAc,KAAA;EAC5B,KAAA;EACA,QAAA,GAAW,YAAA;EACX,YAAA;EACA,QAAA;AAAA,IACD,kBAAA,CAAA,GAAA,CAAA,OAAA"}
@@ -13,6 +13,7 @@ let ___section_js = require("../section.js");
13
13
  let _________index_js = require("../../../index.js");
14
14
  let _stripe_react_stripe_js = require("@stripe/react-stripe-js");
15
15
  let _stripe_stripe_js = require("@stripe/stripe-js");
16
+ let _________lib_env_js = require("../../../lib/env.js");
16
17
 
17
18
  //#region src/components-page/account-settings/payments/payments-panel.tsx
18
19
  function formatPaymentMethod(pm) {
@@ -191,7 +192,7 @@ function RealPaymentsPanel(props) {
191
192
  const [switchToProductId, setSwitchToProductId] = (0, react.useState)(null);
192
193
  const stripePromise = (0, react.useMemo)(() => {
193
194
  if (!setupIntentStripeAccountId) return null;
194
- const publishableKey = process.env.NEXT_PUBLIC_STACK_STRIPE_PUBLISHABLE_KEY;
195
+ const publishableKey = _________lib_env_js.envVars.NEXT_PUBLIC_STACK_STRIPE_PUBLISHABLE_KEY;
195
196
  if (!publishableKey) return null;
196
197
  return (0, _stripe_stripe_js.loadStripe)(publishableKey, { stripeAccount: setupIntentStripeAccountId });
197
198
  }, [setupIntentStripeAccountId]);
@@ -204,7 +205,7 @@ function RealPaymentsPanel(props) {
204
205
  });
205
206
  return;
206
207
  }
207
- alert(`An unhandled error occurred. Please ${process.env.NODE_ENV === "development" ? "check the browser console for the full error." : "report this to the developer."}\n\n${error}`);
208
+ alert(`An unhandled error occurred. Please ${_________lib_env_js.envVars.NODE_ENV === "development" ? "check the browser console for the full error." : "report this to the developer."}\n\n${error}`);
208
209
  };
209
210
  const openPaymentDialog = () => {
210
211
  (0, _stackframe_stack_shared_dist_utils_promises.runAsynchronously)(async () => {
@@ -1 +1 @@
1
- {"version":3,"file":"payments-panel.js","names":["Typography","CardElement","Button","Section","KnownErrors","ActionDialog","Skeleton","Elements","Result","Select","SelectTrigger","SelectValue","SelectContent","SelectItem","Separator","Table","TableHeader","TableRow","TableHead","TableBody","TableCell"],"sources":["../../../../src/components-page/account-settings/payments/payments-panel.tsx"],"sourcesContent":["'use client';\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY, INSTEAD EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\n\nimport { KnownErrors } from \"@stackframe/stack-shared\";\nimport { runAsynchronously } from \"@stackframe/stack-shared/dist/utils/promises\";\nimport { ActionDialog, Button, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, Separator, Skeleton, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, toast, Typography } from \"@stackframe/stack-ui\";\nimport { CardElement, Elements, useElements, useStripe } from \"@stripe/react-stripe-js\";\nimport { loadStripe } from \"@stripe/stripe-js\";\nimport { useMemo, useState } from \"react\";\nimport { useStackApp } from \"../../..\";\nimport { useTranslation } from \"../../../lib/translations\";\nimport { Section } from \"../section\";\nimport { Result } from \"@stackframe/stack-shared/dist/utils/results\";\nimport type { CustomerInvoiceStatus, CustomerInvoicesList, CustomerInvoicesListOptions } from \"../../../lib/stack-app/customers\";\n\ntype PaymentMethodSummary = {\n id: string,\n brand: string | null,\n last4: string | null,\n exp_month: number | null,\n exp_year: number | null,\n} | null;\n\nfunction formatPaymentMethod(pm: NonNullable<PaymentMethodSummary>) {\n const details = [\n pm.brand ? pm.brand.toUpperCase() : null,\n pm.last4 ? `•••• ${pm.last4}` : null,\n pm.exp_month && pm.exp_year ? `exp ${pm.exp_month}/${pm.exp_year}` : null,\n ].filter(Boolean);\n return details.join(\" · \");\n}\n\nconst formatInvoiceStatus = (status: CustomerInvoiceStatus, t: (value: string) => string) => {\n if (!status) {\n return t(\"Unknown\");\n }\n switch (status) {\n case \"draft\": {\n return t(\"Draft\");\n }\n case \"open\": {\n return t(\"Open\");\n }\n case \"paid\": {\n return t(\"Paid\");\n }\n case \"uncollectible\": {\n return t(\"Uncollectible\");\n }\n case \"void\": {\n return t(\"Void\");\n }\n default: {\n return t(\"Unknown\");\n }\n }\n};\n\nconst formatInvoiceAmount = (amountTotal: number | null | undefined, t: (value: string) => string) => {\n if (typeof amountTotal !== \"number\" || Number.isNaN(amountTotal)) {\n return t(\"Unknown\");\n }\n const normalized = amountTotal / 100;\n const formatted = new Intl.NumberFormat(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 }).format(normalized);\n return `$${formatted}`;\n};\n\nconst formatInvoiceDate = (date: Date | null | undefined, t: (value: string) => string) => {\n if (!date || Number.isNaN(date.getTime())) {\n return t(\"Unknown\");\n }\n return new Intl.DateTimeFormat(undefined, { year: \"numeric\", month: \"short\", day: \"numeric\" }).format(date);\n};\n\ntype CustomerBilling = {\n hasCustomer: boolean,\n defaultPaymentMethod: PaymentMethodSummary,\n};\n\ntype CustomerPaymentMethodSetupIntent = {\n clientSecret: string,\n stripeAccountId: string,\n};\n\ntype CustomerLike = {\n id: string,\n useBilling: () => CustomerBilling,\n useProducts: () => Array<{\n id: string | null,\n quantity: number,\n displayName: string,\n customerType: \"user\" | \"team\" | \"custom\",\n type: \"one_time\" | \"subscription\",\n switchOptions?: Array<{\n productId: string,\n displayName: string,\n prices: Record<string, { interval?: [number, \"day\" | \"week\" | \"month\" | \"year\"] }>,\n }>,\n subscription: null | {\n subscriptionId: string | null,\n currentPeriodEnd: Date | null,\n cancelAtPeriodEnd: boolean,\n isCancelable: boolean,\n },\n }>,\n useInvoices: (options?: CustomerInvoicesListOptions) => CustomerInvoicesList,\n createPaymentMethodSetupIntent: () => Promise<CustomerPaymentMethodSetupIntent>,\n setDefaultPaymentMethodFromSetupIntent: (setupIntentId: string) => Promise<PaymentMethodSummary>,\n switchSubscription: (options: { fromProductId: string, toProductId: string, priceId?: string, quantity?: number }) => Promise<void>,\n};\n\nfunction SetDefaultPaymentMethodForm(props: {\n clientSecret: string,\n onSetupIntentSucceeded: (setupIntentId: string) => Promise<void>,\n}) {\n const stripe = useStripe();\n const elements = useElements();\n const [errorMessage, setErrorMessage] = useState<string | null>(null);\n const darkMode = \"color-scheme\" in document.documentElement.style && document.documentElement.style[\"color-scheme\"] === \"dark\";\n\n return (\n <div className=\"space-y-4\">\n <div className=\"space-y-2\">\n <Typography className=\"font-medium\">Card details</Typography>\n <div className=\"rounded-md border border-input p-3\">\n <CardElement options={{ hidePostalCode: true, style: { base: { color: darkMode ? \"white\" : \"black\" } } }} />\n </div>\n </div>\n {errorMessage && (\n <Typography variant=\"secondary\" type=\"footnote\">\n {errorMessage}\n </Typography>\n )}\n <Button\n onClick={async () => {\n if (!stripe || !elements) {\n setErrorMessage(\"Stripe is still loading. Please try again.\");\n return;\n }\n const card = elements.getElement(CardElement);\n if (!card) {\n setErrorMessage(\"Card element not found.\");\n return;\n }\n\n const result = await stripe.confirmCardSetup(props.clientSecret, {\n payment_method: { card },\n });\n if (result.error) {\n setErrorMessage(result.error.message ?? \"Failed to save payment method.\");\n return;\n }\n if (!result.setupIntent.id) {\n setErrorMessage(\"No setup intent returned from Stripe.\");\n return;\n }\n await props.onSetupIntentSucceeded(result.setupIntent.id);\n }}\n >\n Save payment method\n </Button>\n </div>\n );\n}\n\nexport function PaymentsPanel(props: {\n title?: string,\n customer?: CustomerLike,\n customerType?: \"user\" | \"team\",\n mockMode?: boolean,\n}) {\n if (props.mockMode) {\n return <MockPaymentsPanel title={props.title} />;\n }\n if (!props.customer) {\n return null;\n }\n return <RealPaymentsPanel title={props.title} customer={props.customer} customerType={props.customerType ?? \"user\"} />;\n}\n\nfunction MockPaymentsPanel(props: { title?: string }) {\n const { t } = useTranslation();\n const defaultPaymentMethod: PaymentMethodSummary = {\n id: \"pm_mock\",\n brand: \"visa\",\n last4: \"4242\",\n exp_month: 12,\n exp_year: 2030,\n };\n\n return (\n <div className=\"space-y-4\">\n {props.title && <Typography className=\"font-medium\">{props.title}</Typography>}\n <Section\n title={t(\"Payment method\")}\n description={t(\"Manage the default payment method used for subscriptions and invoices.\")}\n >\n <Typography>{formatPaymentMethod(defaultPaymentMethod)}</Typography>\n <Button disabled>\n {t(\"Update payment method\")}\n </Button>\n </Section>\n\n <Section\n title={t(\"Active plans\")}\n description={t(\"View your active plans and purchases.\")}\n >\n <div className=\"space-y-3\">\n <div className=\"flex items-start justify-between gap-4\">\n <div className=\"min-w-0\">\n <Typography className=\"truncate\">{t(\"Pro\")}</Typography>\n <Typography variant=\"secondary\" type=\"footnote\">{t(\"Renews on\")} Jan 1, 2030</Typography>\n </div>\n <Button disabled variant=\"secondary\" color=\"neutral\">\n {t(\"Cancel subscription\")}\n </Button>\n </div>\n <div className=\"flex items-start justify-between gap-4\">\n <div className=\"min-w-0\">\n <Typography className=\"truncate\">{t(\"Credits pack\")}</Typography>\n <Typography variant=\"secondary\" type=\"footnote\">{t(\"One-time purchase\")}</Typography>\n </div>\n </div>\n </div>\n </Section>\n </div>\n );\n}\n\nfunction RealPaymentsPanel(props: { title?: string, customer: CustomerLike, customerType: \"user\" | \"team\" }) {\n const { t } = useTranslation();\n const stackApp = useStackApp();\n const billing = props.customer.useBilling();\n const defaultPaymentMethod = billing.defaultPaymentMethod;\n const products = props.customer.useProducts();\n const invoices = props.customer.useInvoices({ limit: 10 });\n const productsForCustomerType = products.filter(product => product.customerType === props.customerType);\n\n const [paymentDialogOpen, setPaymentDialogOpen] = useState(false);\n const [setupIntentClientSecret, setSetupIntentClientSecret] = useState<string | null>(null);\n const [setupIntentStripeAccountId, setSetupIntentStripeAccountId] = useState<string | null>(null);\n const [cancelTarget, setCancelTarget] = useState<{ productId: string, subscriptionId?: string } | null>(null);\n const [switchFromProductId, setSwitchFromProductId] = useState<string | null>(null);\n const [switchToProductId, setSwitchToProductId] = useState<string | null>(null);\n\n const stripePromise = useMemo(() => {\n if (!setupIntentStripeAccountId) return null;\n const publishableKey = process.env.NEXT_PUBLIC_STACK_STRIPE_PUBLISHABLE_KEY;\n if (!publishableKey) return null;\n return loadStripe(publishableKey, { stripeAccount: setupIntentStripeAccountId });\n }, [setupIntentStripeAccountId]);\n\n const handleAsyncError = (error: unknown) => {\n if (error instanceof KnownErrors.DefaultPaymentMethodRequired) {\n toast({\n title: t(\"No default payment method\"),\n description: t(\"Add a payment method before switching plans.\"),\n variant: \"destructive\",\n });\n return;\n }\n alert(`An unhandled error occurred. Please ${process.env.NODE_ENV === \"development\" ? \"check the browser console for the full error.\" : \"report this to the developer.\"}\\n\\n${error}`);\n };\n\n const openPaymentDialog = () => {\n runAsynchronously(async () => {\n setPaymentDialogOpen(true);\n const res = await props.customer.createPaymentMethodSetupIntent();\n setSetupIntentClientSecret(res.clientSecret);\n setSetupIntentStripeAccountId(res.stripeAccountId);\n }, { onError: handleAsyncError });\n };\n\n const closePaymentDialog = () => {\n setPaymentDialogOpen(false);\n setSetupIntentClientSecret(null);\n setSetupIntentStripeAccountId(null);\n };\n\n const openSwitchDialog = (productId: string, firstOptionId: string | null) => {\n setSwitchFromProductId(productId);\n setSwitchToProductId(firstOptionId);\n };\n\n const closeSwitchDialog = () => {\n setSwitchFromProductId(null);\n setSwitchToProductId(null);\n };\n\n const switchSourceProduct = switchFromProductId\n ? productsForCustomerType.find((product) => product.id === switchFromProductId) ?? null\n : null;\n const switchOptions = switchSourceProduct?.switchOptions ?? [];\n const selectedSwitchOption = switchOptions.find((option) => option.productId === switchToProductId) ?? null;\n const selectedPriceId = selectedSwitchOption ? (Object.keys(selectedSwitchOption.prices)[0] ?? null) : null;\n\n return (\n <div className=\"space-y-4\">\n {props.title && <Typography className=\"font-medium\">{props.title}</Typography>}\n\n {defaultPaymentMethod && (\n <Section\n title={t(\"Payment method\")}\n description={t(\"Manage the default payment method used for subscriptions and invoices.\")}\n >\n <Typography>{formatPaymentMethod(defaultPaymentMethod)}</Typography>\n\n <Button onClick={openPaymentDialog}>\n {t(\"Update payment method\")}\n </Button>\n\n <ActionDialog\n open={paymentDialogOpen}\n onOpenChange={(open) => {\n if (!open) {\n closePaymentDialog();\n } else {\n setPaymentDialogOpen(true);\n }\n }}\n title={t(\"Update payment method\")}\n >\n {!setupIntentClientSecret || !setupIntentStripeAccountId || !stripePromise ? (\n <Skeleton className=\"h-10 w-full\" />\n ) : (\n <Elements\n stripe={stripePromise}\n options={{\n clientSecret: setupIntentClientSecret,\n }}\n >\n <SetDefaultPaymentMethodForm\n clientSecret={setupIntentClientSecret}\n onSetupIntentSucceeded={async (setupIntentId) => {\n await props.customer.setDefaultPaymentMethodFromSetupIntent(setupIntentId);\n closePaymentDialog();\n }}\n />\n </Elements>\n )}\n </ActionDialog>\n </Section>\n )}\n\n {productsForCustomerType.length > 0 && (\n <Section\n title={t(\"Active plans\")}\n description={t(\"View your active plans and purchases.\")}\n >\n <div className=\"space-y-3\">\n {productsForCustomerType.map((product, index) => {\n const quantitySuffix = product.quantity !== 1 ? ` ×${product.quantity}` : \"\";\n const isSubscription = product.type === \"subscription\";\n const isCancelable = isSubscription && !!product.subscription?.isCancelable;\n const canSwitchPlans = isSubscription && defaultPaymentMethod && !!product.id && (product.switchOptions?.length ?? 0) > 0;\n const renewsAt = isSubscription ? (product.subscription?.currentPeriodEnd ?? null) : null;\n const subtitle =\n product.type === \"one_time\"\n ? t(\"One-time purchase\")\n : renewsAt\n ? `${t(\"Renews on\")} ${new Intl.DateTimeFormat(undefined, { year: \"numeric\", month: \"short\", day: \"numeric\" }).format(renewsAt)}`\n : t(\"Subscription\");\n\n return (\n <div key={product.id ?? `${product.displayName}-${index}`} className=\"flex items-start justify-between gap-4\">\n <div className=\"min-w-0\">\n <Typography className=\"truncate\">{product.displayName}{quantitySuffix}</Typography>\n <Typography variant=\"secondary\" type=\"footnote\">{subtitle}</Typography>\n </div>\n\n <div className=\"flex flex-col items-end gap-2\">\n {canSwitchPlans && (\n <Button\n variant=\"secondary\"\n color=\"neutral\"\n onClick={() => openSwitchDialog(product.id!, product.switchOptions?.[0]?.productId ?? null)}\n >\n {t(\"Change plan\")}\n </Button>\n )}\n {isCancelable && (\n <Button\n variant=\"secondary\"\n color=\"neutral\"\n onClick={() => setCancelTarget({ productId: product.id ?? \"_inline\", subscriptionId: product.subscription?.subscriptionId ?? undefined })}\n >\n {t(\"Cancel subscription\")}\n </Button>\n )}\n </div>\n </div>\n );\n })}\n </div>\n\n <ActionDialog\n open={cancelTarget !== null}\n onOpenChange={(open) => {\n if (!open) setCancelTarget(null);\n }}\n title={t(\"Cancel subscription\")}\n description={t(\"Canceling will stop future renewals for this subscription.\")}\n danger\n cancelButton\n okButton={{\n label: t(\"Cancel subscription\"),\n onClick: async () => {\n if (!cancelTarget) return;\n const { productId, subscriptionId } = cancelTarget;\n if (props.customerType === \"team\") {\n await stackApp.cancelSubscription({ teamId: props.customer.id, productId, subscriptionId });\n } else {\n await stackApp.cancelSubscription({ productId, subscriptionId });\n }\n setCancelTarget(null);\n },\n }}\n />\n\n <ActionDialog\n open={switchFromProductId !== null}\n onOpenChange={(open) => {\n if (!open) closeSwitchDialog();\n }}\n title={t(\"Change plan\")}\n description={t(\"Select a new plan from the same product line.\")}\n cancelButton\n okButton={{\n label: t(\"Switch plan\"),\n onClick: async () => {\n const fromProductId = switchFromProductId;\n const toProductId = switchToProductId;\n if (!fromProductId || !toProductId) return;\n if (!selectedPriceId) return;\n const result = await Result.fromThrowingAsync(() => props.customer.switchSubscription({\n fromProductId,\n toProductId,\n priceId: selectedPriceId,\n }));\n if (result.status === \"error\") {\n handleAsyncError(result.error);\n return \"prevent-close\";\n }\n closeSwitchDialog();\n },\n props: {\n disabled: !switchFromProductId || !switchToProductId || !selectedPriceId,\n },\n }}\n >\n <div className=\"space-y-2\">\n {switchOptions.length === 0 ? (\n <Typography variant=\"secondary\" type=\"footnote\">\n {t(\"No other plans available for this subscription.\")}\n </Typography>\n ) : (\n <>\n <Typography type=\"footnote\">{t(\"Choose a plan\")}</Typography>\n <Select\n value={switchToProductId ?? undefined}\n onValueChange={(value) => setSwitchToProductId(value || null)}\n >\n <SelectTrigger className=\"w-full\">\n <SelectValue placeholder={t(\"Choose a plan\")} />\n </SelectTrigger>\n <SelectContent>\n {switchOptions.map((option: NonNullable<typeof switchOptions>[number]) => (\n <SelectItem key={option.productId} value={option.productId}>\n {option.displayName}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </>\n )}\n </div>\n </ActionDialog>\n </Section>\n )\n }\n {invoices.length > 0 && (\n <>\n <Separator />\n <div className=\"space-y-2\">\n <div className=\"space-y-1\">\n <Typography className=\"font-medium\">{t(\"Invoices\")}</Typography>\n <Typography variant=\"secondary\" type=\"footnote\">{t(\"Review past invoices and receipts.\")}</Typography>\n </div>\n <div className=\"border rounded-md\">\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead className=\"w-[140px]\">{t(\"Date\")}</TableHead>\n <TableHead className=\"w-[120px]\">{t(\"Status\")}</TableHead>\n <TableHead className=\"w-[120px]\">{t(\"Amount\")}</TableHead>\n <TableHead className=\"w-[120px] text-right\">{t(\"Invoice\")}</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {invoices.map((invoice, index) => {\n const createdAtTime = invoice.createdAt.getTime();\n const invoiceKey = Number.isNaN(createdAtTime) ? `invoice-${index}` : `invoice-${createdAtTime}-${index}`;\n return (\n <TableRow key={invoiceKey}>\n <TableCell>\n <Typography>{formatInvoiceDate(invoice.createdAt, t)}</Typography>\n </TableCell>\n <TableCell>\n <Typography>{formatInvoiceStatus(invoice.status, t)}</Typography>\n </TableCell>\n <TableCell>\n <Typography>{formatInvoiceAmount(invoice.amountTotal, t)}</Typography>\n </TableCell>\n <TableCell align=\"right\">\n {invoice.hostedInvoiceUrl ? (\n <Button asChild variant=\"secondary\" color=\"neutral\" size=\"sm\">\n <a href={invoice.hostedInvoiceUrl} target=\"_blank\" rel=\"noreferrer\">\n {t(\"View\")}\n </a>\n </Button>\n ) : (\n <Typography variant=\"secondary\" type=\"footnote\">\n {t(\"Unavailable\")}\n </Typography>\n )}\n </TableCell>\n </TableRow>\n );\n })}\n </TableBody>\n </Table>\n </div>\n </div>\n </>\n )}\n </div >\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AA2BA,SAAS,oBAAoB,IAAuC;AAMlE,QALgB;EACd,GAAG,QAAQ,GAAG,MAAM,aAAa,GAAG;EACpC,GAAG,QAAQ,QAAQ,GAAG,UAAU;EAChC,GAAG,aAAa,GAAG,WAAW,OAAO,GAAG,UAAU,GAAG,GAAG,aAAa;EACtE,CAAC,OAAO,QAAQ,CACF,KAAK,MAAM;;AAG5B,MAAM,uBAAuB,QAA+B,MAAiC;AAC3F,KAAI,CAAC,OACH,QAAO,EAAE,UAAU;AAErB,SAAQ,QAAR;EACE,KAAK,QACH,QAAO,EAAE,QAAQ;EAEnB,KAAK,OACH,QAAO,EAAE,OAAO;EAElB,KAAK,OACH,QAAO,EAAE,OAAO;EAElB,KAAK,gBACH,QAAO,EAAE,gBAAgB;EAE3B,KAAK,OACH,QAAO,EAAE,OAAO;EAElB,QACE,QAAO,EAAE,UAAU;;;AAKzB,MAAM,uBAAuB,aAAwC,MAAiC;AACpG,KAAI,OAAO,gBAAgB,YAAY,OAAO,MAAM,YAAY,CAC9D,QAAO,EAAE,UAAU;CAErB,MAAM,aAAa,cAAc;AAEjC,QAAO,IADW,IAAI,KAAK,aAAa,QAAW;EAAE,uBAAuB;EAAG,uBAAuB;EAAG,CAAC,CAAC,OAAO,WAAW;;AAI/H,MAAM,qBAAqB,MAA+B,MAAiC;AACzF,KAAI,CAAC,QAAQ,OAAO,MAAM,KAAK,SAAS,CAAC,CACvC,QAAO,EAAE,UAAU;AAErB,QAAO,IAAI,KAAK,eAAe,QAAW;EAAE,MAAM;EAAW,OAAO;EAAS,KAAK;EAAW,CAAC,CAAC,OAAO,KAAK;;AAwC7G,SAAS,4BAA4B,OAGlC;CACD,MAAM,iDAAoB;CAC1B,MAAM,qDAAwB;CAC9B,MAAM,CAAC,cAAc,uCAA2C,KAAK;CACrE,MAAM,WAAW,kBAAkB,SAAS,gBAAgB,SAAS,SAAS,gBAAgB,MAAM,oBAAoB;AAExH,QACE,4CAAC;EAAI,WAAU;;GACb,4CAAC;IAAI,WAAU;eACb,2CAACA;KAAW,WAAU;eAAc;MAAyB,EAC7D,2CAAC;KAAI,WAAU;eACb,2CAACC,uCAAY,SAAS;MAAE,gBAAgB;MAAM,OAAO,EAAE,MAAM,EAAE,OAAO,WAAW,UAAU,SAAS,EAAE;MAAE,GAAI;MACxG;KACF;GACL,gBACC,2CAACD;IAAW,SAAQ;IAAY,MAAK;cAClC;KACU;GAEf,2CAACE;IACC,SAAS,YAAY;AACnB,SAAI,CAAC,UAAU,CAAC,UAAU;AACxB,sBAAgB,6CAA6C;AAC7D;;KAEF,MAAM,OAAO,SAAS,WAAWD,oCAAY;AAC7C,SAAI,CAAC,MAAM;AACT,sBAAgB,0BAA0B;AAC1C;;KAGF,MAAM,SAAS,MAAM,OAAO,iBAAiB,MAAM,cAAc,EAC/D,gBAAgB,EAAE,MAAM,EACzB,CAAC;AACF,SAAI,OAAO,OAAO;AAChB,sBAAgB,OAAO,MAAM,WAAW,iCAAiC;AACzE;;AAEF,SAAI,CAAC,OAAO,YAAY,IAAI;AAC1B,sBAAgB,wCAAwC;AACxD;;AAEF,WAAM,MAAM,uBAAuB,OAAO,YAAY,GAAG;;cAE5D;KAEQ;;GACL;;AAIV,SAAgB,cAAc,OAK3B;AACD,KAAI,MAAM,SACR,QAAO,2CAAC,qBAAkB,OAAO,MAAM,QAAS;AAElD,KAAI,CAAC,MAAM,SACT,QAAO;AAET,QAAO,2CAAC;EAAkB,OAAO,MAAM;EAAO,UAAU,MAAM;EAAU,cAAc,MAAM,gBAAgB;GAAU;;AAGxH,SAAS,kBAAkB,OAA2B;CACpD,MAAM,EAAE,wDAAsB;AAS9B,QACE,4CAAC;EAAI,WAAU;;GACZ,MAAM,SAAS,2CAACD;IAAW,WAAU;cAAe,MAAM;KAAmB;GAC9E,4CAACG;IACC,OAAO,EAAE,iBAAiB;IAC1B,aAAa,EAAE,yEAAyE;eAExF,2CAACH,6CAAY,oBAfgC;KACjD,IAAI;KACJ,OAAO;KACP,OAAO;KACP,WAAW;KACX,UAAU;KACX,CAS2D,GAAc,EACpE,2CAACE;KAAO;eACL,EAAE,wBAAwB;MACpB;KACD;GAEV,2CAACC;IACC,OAAO,EAAE,eAAe;IACxB,aAAa,EAAE,wCAAwC;cAEvD,4CAAC;KAAI,WAAU;gBACb,4CAAC;MAAI,WAAU;iBACb,4CAAC;OAAI,WAAU;kBACb,2CAACH;QAAW,WAAU;kBAAY,EAAE,MAAM;SAAc,EACxD,4CAACA;QAAW,SAAQ;QAAY,MAAK;mBAAY,EAAE,YAAY,EAAC;SAAyB;QACrF,EACN,2CAACE;OAAO;OAAS,SAAQ;OAAY,OAAM;iBACxC,EAAE,sBAAsB;QAClB;OACL,EACN,2CAAC;MAAI,WAAU;gBACb,4CAAC;OAAI,WAAU;kBACb,2CAACF;QAAW,WAAU;kBAAY,EAAE,eAAe;SAAc,EACjE,2CAACA;QAAW,SAAQ;QAAY,MAAK;kBAAY,EAAE,oBAAoB;SAAc;QACjF;OACF;MACF;KACE;;GACN;;AAIV,SAAS,kBAAkB,OAAkF;CAC3G,MAAM,EAAE,wDAAsB;CAC9B,MAAM,+CAAwB;CAE9B,MAAM,uBADU,MAAM,SAAS,YAAY,CACN;CACrC,MAAM,WAAW,MAAM,SAAS,aAAa;CAC7C,MAAM,WAAW,MAAM,SAAS,YAAY,EAAE,OAAO,IAAI,CAAC;CAC1D,MAAM,0BAA0B,SAAS,QAAO,YAAW,QAAQ,iBAAiB,MAAM,aAAa;CAEvG,MAAM,CAAC,mBAAmB,4CAAiC,MAAM;CACjE,MAAM,CAAC,yBAAyB,kDAAsD,KAAK;CAC3F,MAAM,CAAC,4BAA4B,qDAAyD,KAAK;CACjG,MAAM,CAAC,cAAc,uCAAmF,KAAK;CAC7G,MAAM,CAAC,qBAAqB,8CAAkD,KAAK;CACnF,MAAM,CAAC,mBAAmB,4CAAgD,KAAK;CAE/E,MAAM,yCAA8B;AAClC,MAAI,CAAC,2BAA4B,QAAO;EACxC,MAAM,iBAAiB,QAAQ,IAAI;AACnC,MAAI,CAAC,eAAgB,QAAO;AAC5B,2CAAkB,gBAAgB,EAAE,eAAe,4BAA4B,CAAC;IAC/E,CAAC,2BAA2B,CAAC;CAEhC,MAAM,oBAAoB,UAAmB;AAC3C,MAAI,iBAAiBI,qCAAY,8BAA8B;AAC7D,mCAAM;IACJ,OAAO,EAAE,4BAA4B;IACrC,aAAa,EAAE,+CAA+C;IAC9D,SAAS;IACV,CAAC;AACF;;AAEF,QAAM,uCAAuC,QAAQ,IAAI,aAAa,gBAAgB,kDAAkD,gCAAgC,MAAM,QAAQ;;CAGxL,MAAM,0BAA0B;AAC9B,sEAAkB,YAAY;AAC5B,wBAAqB,KAAK;GAC1B,MAAM,MAAM,MAAM,MAAM,SAAS,gCAAgC;AACjE,8BAA2B,IAAI,aAAa;AAC5C,iCAA8B,IAAI,gBAAgB;KACjD,EAAE,SAAS,kBAAkB,CAAC;;CAGnC,MAAM,2BAA2B;AAC/B,uBAAqB,MAAM;AAC3B,6BAA2B,KAAK;AAChC,gCAA8B,KAAK;;CAGrC,MAAM,oBAAoB,WAAmB,kBAAiC;AAC5E,yBAAuB,UAAU;AACjC,uBAAqB,cAAc;;CAGrC,MAAM,0BAA0B;AAC9B,yBAAuB,KAAK;AAC5B,uBAAqB,KAAK;;CAM5B,MAAM,iBAHsB,sBACxB,wBAAwB,MAAM,YAAY,QAAQ,OAAO,oBAAoB,IAAI,OACjF,OACuC,iBAAiB,EAAE;CAC9D,MAAM,uBAAuB,cAAc,MAAM,WAAW,OAAO,cAAc,kBAAkB,IAAI;CACvG,MAAM,kBAAkB,uBAAwB,OAAO,KAAK,qBAAqB,OAAO,CAAC,MAAM,OAAQ;AAEvG,QACE,4CAAC;EAAI,WAAU;;GACZ,MAAM,SAAS,2CAACJ;IAAW,WAAU;cAAe,MAAM;KAAmB;GAE7E,wBACC,4CAACG;IACC,OAAO,EAAE,iBAAiB;IAC1B,aAAa,EAAE,yEAAyE;;KAExF,2CAACH,6CAAY,oBAAoB,qBAAqB,GAAc;KAEpE,2CAACE;MAAO,SAAS;gBACd,EAAE,wBAAwB;OACpB;KAET,2CAACG;MACC,MAAM;MACN,eAAe,SAAS;AACtB,WAAI,CAAC,KACH,qBAAoB;WAEpB,sBAAqB,KAAK;;MAG9B,OAAO,EAAE,wBAAwB;gBAEhC,CAAC,2BAA2B,CAAC,8BAA8B,CAAC,gBAC3D,2CAACC,iCAAS,WAAU,gBAAgB,GAEpC,2CAACC;OACC,QAAQ;OACR,SAAS,EACP,cAAc,yBACf;iBAED,2CAAC;QACC,cAAc;QACd,wBAAwB,OAAO,kBAAkB;AAC/C,eAAM,MAAM,SAAS,uCAAuC,cAAc;AAC1E,6BAAoB;;SAEtB;QACO;OAEA;;KACP;GAGX,wBAAwB,SAAS,KAChC,4CAACJ;IACC,OAAO,EAAE,eAAe;IACxB,aAAa,EAAE,wCAAwC;;KAEvD,2CAAC;MAAI,WAAU;gBACZ,wBAAwB,KAAK,SAAS,UAAU;OAC/C,MAAM,iBAAiB,QAAQ,aAAa,IAAI,KAAK,QAAQ,aAAa;OAC1E,MAAM,iBAAiB,QAAQ,SAAS;OACxC,MAAM,eAAe,kBAAkB,CAAC,CAAC,QAAQ,cAAc;OAC/D,MAAM,iBAAiB,kBAAkB,wBAAwB,CAAC,CAAC,QAAQ,OAAO,QAAQ,eAAe,UAAU,KAAK;OACxH,MAAM,WAAW,iBAAkB,QAAQ,cAAc,oBAAoB,OAAQ;OACrF,MAAM,WACJ,QAAQ,SAAS,aACb,EAAE,oBAAoB,GACtB,WACE,GAAG,EAAE,YAAY,CAAC,GAAG,IAAI,KAAK,eAAe,QAAW;QAAE,MAAM;QAAW,OAAO;QAAS,KAAK;QAAW,CAAC,CAAC,OAAO,SAAS,KAC7H,EAAE,eAAe;AAEzB,cACE,4CAAC;QAA0D,WAAU;mBACnE,4CAAC;SAAI,WAAU;oBACb,4CAACH;UAAW,WAAU;qBAAY,QAAQ,aAAa;WAA4B,EACnF,2CAACA;UAAW,SAAQ;UAAY,MAAK;oBAAY;WAAsB;UACnE,EAEN,4CAAC;SAAI,WAAU;oBACZ,kBACC,2CAACE;UACC,SAAQ;UACR,OAAM;UACN,eAAe,iBAAiB,QAAQ,IAAK,QAAQ,gBAAgB,IAAI,aAAa,KAAK;oBAE1F,EAAE,cAAc;WACV,EAEV,gBACC,2CAACA;UACC,SAAQ;UACR,OAAM;UACN,eAAe,gBAAgB;WAAE,WAAW,QAAQ,MAAM;WAAW,gBAAgB,QAAQ,cAAc,kBAAkB;WAAW,CAAC;oBAExI,EAAE,sBAAsB;WAClB;UAEP;UAzBE,QAAQ,MAAM,GAAG,QAAQ,YAAY,GAAG,QA0B5C;QAER;OACE;KAEN,2CAACG;MACC,MAAM,iBAAiB;MACvB,eAAe,SAAS;AACtB,WAAI,CAAC,KAAM,iBAAgB,KAAK;;MAElC,OAAO,EAAE,sBAAsB;MAC/B,aAAa,EAAE,6DAA6D;MAC5E;MACA;MACA,UAAU;OACR,OAAO,EAAE,sBAAsB;OAC/B,SAAS,YAAY;AACnB,YAAI,CAAC,aAAc;QACnB,MAAM,EAAE,WAAW,mBAAmB;AACtC,YAAI,MAAM,iBAAiB,OACzB,OAAM,SAAS,mBAAmB;SAAE,QAAQ,MAAM,SAAS;SAAI;SAAW;SAAgB,CAAC;YAE3F,OAAM,SAAS,mBAAmB;SAAE;SAAW;SAAgB,CAAC;AAElE,wBAAgB,KAAK;;OAExB;OACD;KAEF,2CAACA;MACC,MAAM,wBAAwB;MAC9B,eAAe,SAAS;AACtB,WAAI,CAAC,KAAM,oBAAmB;;MAEhC,OAAO,EAAE,cAAc;MACvB,aAAa,EAAE,gDAAgD;MAC/D;MACA,UAAU;OACR,OAAO,EAAE,cAAc;OACvB,SAAS,YAAY;QACnB,MAAM,gBAAgB;QACtB,MAAM,cAAc;AACpB,YAAI,CAAC,iBAAiB,CAAC,YAAa;AACpC,YAAI,CAAC,gBAAiB;QACtB,MAAM,SAAS,MAAMG,mDAAO,wBAAwB,MAAM,SAAS,mBAAmB;SACpF;SACA;SACA,SAAS;SACV,CAAC,CAAC;AACH,YAAI,OAAO,WAAW,SAAS;AAC7B,0BAAiB,OAAO,MAAM;AAC9B,gBAAO;;AAET,2BAAmB;;OAErB,OAAO,EACL,UAAU,CAAC,uBAAuB,CAAC,qBAAqB,CAAC,iBAC1D;OACF;gBAED,2CAAC;OAAI,WAAU;iBACZ,cAAc,WAAW,IACxB,2CAACR;QAAW,SAAQ;QAAY,MAAK;kBAClC,EAAE,kDAAkD;SAC1C,GAEb,qFACE,2CAACA;QAAW,MAAK;kBAAY,EAAE,gBAAgB;SAAc,EAC7D,4CAACS;QACC,OAAO,qBAAqB;QAC5B,gBAAgB,UAAU,qBAAqB,SAAS,KAAK;mBAE7D,2CAACC;SAAc,WAAU;mBACvB,2CAACC,oCAAY,aAAa,EAAE,gBAAgB,GAAI;UAClC,EAChB,2CAACC,gDACE,cAAc,KAAK,WAClB,2CAACC;SAAkC,OAAO,OAAO;mBAC9C,OAAO;WADO,OAAO,UAEX,CACb,GACY;SACT,IACR;QAED;OACO;;KACP;GAGX,SAAS,SAAS,KACjB,qFACE,2CAACC,mCAAY,EACb,4CAAC;IAAI,WAAU;eACb,4CAAC;KAAI,WAAU;gBACb,2CAACd;MAAW,WAAU;gBAAe,EAAE,WAAW;OAAc,EAChE,2CAACA;MAAW,SAAQ;MAAY,MAAK;gBAAY,EAAE,qCAAqC;OAAc;MAClG,EACN,2CAAC;KAAI,WAAU;eACb,4CAACe,yCACC,2CAACC,8CACC,4CAACC;MACC,2CAACC;OAAU,WAAU;iBAAa,EAAE,OAAO;QAAa;MACxD,2CAACA;OAAU,WAAU;iBAAa,EAAE,SAAS;QAAa;MAC1D,2CAACA;OAAU,WAAU;iBAAa,EAAE,SAAS;QAAa;MAC1D,2CAACA;OAAU,WAAU;iBAAwB,EAAE,UAAU;QAAa;SAC7D,GACC,EACd,2CAACC,4CACE,SAAS,KAAK,SAAS,UAAU;MAChC,MAAM,gBAAgB,QAAQ,UAAU,SAAS;MACjD,MAAM,aAAa,OAAO,MAAM,cAAc,GAAG,WAAW,UAAU,WAAW,cAAc,GAAG;AAClG,aACE,4CAACF;OACC,2CAACG,4CACC,2CAACpB,6CAAY,kBAAkB,QAAQ,WAAW,EAAE,GAAc,GACxD;OACZ,2CAACoB,4CACC,2CAACpB,6CAAY,oBAAoB,QAAQ,QAAQ,EAAE,GAAc,GACvD;OACZ,2CAACoB,4CACC,2CAACpB,6CAAY,oBAAoB,QAAQ,aAAa,EAAE,GAAc,GAC5D;OACZ,2CAACoB;QAAU,OAAM;kBACd,QAAQ,mBACP,2CAAClB;SAAO;SAAQ,SAAQ;SAAY,OAAM;SAAU,MAAK;mBACvD,2CAAC;UAAE,MAAM,QAAQ;UAAkB,QAAO;UAAS,KAAI;oBACpD,EAAE,OAAO;WACR;UACG,GAET,2CAACF;SAAW,SAAQ;SAAY,MAAK;mBAClC,EAAE,cAAc;UACN;SAEL;WAtBC,WAuBJ;OAEb,GACQ,IACN;MACJ;KACF,IACL;;GAEA"}
1
+ {"version":3,"file":"payments-panel.js","names":["Typography","CardElement","Button","Section","envVars","KnownErrors","ActionDialog","Skeleton","Elements","Result","Select","SelectTrigger","SelectValue","SelectContent","SelectItem","Separator","Table","TableHeader","TableRow","TableHead","TableBody","TableCell"],"sources":["../../../../src/components-page/account-settings/payments/payments-panel.tsx"],"sourcesContent":["'use client';\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY, INSTEAD EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\n\nimport { KnownErrors } from \"@stackframe/stack-shared\";\nimport { runAsynchronously } from \"@stackframe/stack-shared/dist/utils/promises\";\nimport { ActionDialog, Button, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, Separator, Skeleton, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, toast, Typography } from \"@stackframe/stack-ui\";\nimport { CardElement, Elements, useElements, useStripe } from \"@stripe/react-stripe-js\";\nimport { loadStripe } from \"@stripe/stripe-js\";\nimport { useMemo, useState } from \"react\";\nimport { useStackApp } from \"../../..\";\nimport { envVars } from \"../../../lib/env\";\nimport { useTranslation } from \"../../../lib/translations\";\nimport { Section } from \"../section\";\nimport { Result } from \"@stackframe/stack-shared/dist/utils/results\";\nimport type { CustomerInvoiceStatus, CustomerInvoicesList, CustomerInvoicesListOptions } from \"../../../lib/stack-app/customers\";\n\ntype PaymentMethodSummary = {\n id: string,\n brand: string | null,\n last4: string | null,\n exp_month: number | null,\n exp_year: number | null,\n} | null;\n\nfunction formatPaymentMethod(pm: NonNullable<PaymentMethodSummary>) {\n const details = [\n pm.brand ? pm.brand.toUpperCase() : null,\n pm.last4 ? `•••• ${pm.last4}` : null,\n pm.exp_month && pm.exp_year ? `exp ${pm.exp_month}/${pm.exp_year}` : null,\n ].filter(Boolean);\n return details.join(\" · \");\n}\n\nconst formatInvoiceStatus = (status: CustomerInvoiceStatus, t: (value: string) => string) => {\n if (!status) {\n return t(\"Unknown\");\n }\n switch (status) {\n case \"draft\": {\n return t(\"Draft\");\n }\n case \"open\": {\n return t(\"Open\");\n }\n case \"paid\": {\n return t(\"Paid\");\n }\n case \"uncollectible\": {\n return t(\"Uncollectible\");\n }\n case \"void\": {\n return t(\"Void\");\n }\n default: {\n return t(\"Unknown\");\n }\n }\n};\n\nconst formatInvoiceAmount = (amountTotal: number | null | undefined, t: (value: string) => string) => {\n if (typeof amountTotal !== \"number\" || Number.isNaN(amountTotal)) {\n return t(\"Unknown\");\n }\n const normalized = amountTotal / 100;\n const formatted = new Intl.NumberFormat(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 }).format(normalized);\n return `$${formatted}`;\n};\n\nconst formatInvoiceDate = (date: Date | null | undefined, t: (value: string) => string) => {\n if (!date || Number.isNaN(date.getTime())) {\n return t(\"Unknown\");\n }\n return new Intl.DateTimeFormat(undefined, { year: \"numeric\", month: \"short\", day: \"numeric\" }).format(date);\n};\n\ntype CustomerBilling = {\n hasCustomer: boolean,\n defaultPaymentMethod: PaymentMethodSummary,\n};\n\ntype CustomerPaymentMethodSetupIntent = {\n clientSecret: string,\n stripeAccountId: string,\n};\n\ntype CustomerLike = {\n id: string,\n useBilling: () => CustomerBilling,\n useProducts: () => Array<{\n id: string | null,\n quantity: number,\n displayName: string,\n customerType: \"user\" | \"team\" | \"custom\",\n type: \"one_time\" | \"subscription\",\n switchOptions?: Array<{\n productId: string,\n displayName: string,\n prices: Record<string, { interval?: [number, \"day\" | \"week\" | \"month\" | \"year\"] }>,\n }>,\n subscription: null | {\n subscriptionId: string | null,\n currentPeriodEnd: Date | null,\n cancelAtPeriodEnd: boolean,\n isCancelable: boolean,\n },\n }>,\n useInvoices: (options?: CustomerInvoicesListOptions) => CustomerInvoicesList,\n createPaymentMethodSetupIntent: () => Promise<CustomerPaymentMethodSetupIntent>,\n setDefaultPaymentMethodFromSetupIntent: (setupIntentId: string) => Promise<PaymentMethodSummary>,\n switchSubscription: (options: { fromProductId: string, toProductId: string, priceId?: string, quantity?: number }) => Promise<void>,\n};\n\nfunction SetDefaultPaymentMethodForm(props: {\n clientSecret: string,\n onSetupIntentSucceeded: (setupIntentId: string) => Promise<void>,\n}) {\n const stripe = useStripe();\n const elements = useElements();\n const [errorMessage, setErrorMessage] = useState<string | null>(null);\n const darkMode = \"color-scheme\" in document.documentElement.style && document.documentElement.style[\"color-scheme\"] === \"dark\";\n\n return (\n <div className=\"space-y-4\">\n <div className=\"space-y-2\">\n <Typography className=\"font-medium\">Card details</Typography>\n <div className=\"rounded-md border border-input p-3\">\n <CardElement options={{ hidePostalCode: true, style: { base: { color: darkMode ? \"white\" : \"black\" } } }} />\n </div>\n </div>\n {errorMessage && (\n <Typography variant=\"secondary\" type=\"footnote\">\n {errorMessage}\n </Typography>\n )}\n <Button\n onClick={async () => {\n if (!stripe || !elements) {\n setErrorMessage(\"Stripe is still loading. Please try again.\");\n return;\n }\n const card = elements.getElement(CardElement);\n if (!card) {\n setErrorMessage(\"Card element not found.\");\n return;\n }\n\n const result = await stripe.confirmCardSetup(props.clientSecret, {\n payment_method: { card },\n });\n if (result.error) {\n setErrorMessage(result.error.message ?? \"Failed to save payment method.\");\n return;\n }\n if (!result.setupIntent.id) {\n setErrorMessage(\"No setup intent returned from Stripe.\");\n return;\n }\n await props.onSetupIntentSucceeded(result.setupIntent.id);\n }}\n >\n Save payment method\n </Button>\n </div>\n );\n}\n\nexport function PaymentsPanel(props: {\n title?: string,\n customer?: CustomerLike,\n customerType?: \"user\" | \"team\",\n mockMode?: boolean,\n}) {\n if (props.mockMode) {\n return <MockPaymentsPanel title={props.title} />;\n }\n if (!props.customer) {\n return null;\n }\n return <RealPaymentsPanel title={props.title} customer={props.customer} customerType={props.customerType ?? \"user\"} />;\n}\n\nfunction MockPaymentsPanel(props: { title?: string }) {\n const { t } = useTranslation();\n const defaultPaymentMethod: PaymentMethodSummary = {\n id: \"pm_mock\",\n brand: \"visa\",\n last4: \"4242\",\n exp_month: 12,\n exp_year: 2030,\n };\n\n return (\n <div className=\"space-y-4\">\n {props.title && <Typography className=\"font-medium\">{props.title}</Typography>}\n <Section\n title={t(\"Payment method\")}\n description={t(\"Manage the default payment method used for subscriptions and invoices.\")}\n >\n <Typography>{formatPaymentMethod(defaultPaymentMethod)}</Typography>\n <Button disabled>\n {t(\"Update payment method\")}\n </Button>\n </Section>\n\n <Section\n title={t(\"Active plans\")}\n description={t(\"View your active plans and purchases.\")}\n >\n <div className=\"space-y-3\">\n <div className=\"flex items-start justify-between gap-4\">\n <div className=\"min-w-0\">\n <Typography className=\"truncate\">{t(\"Pro\")}</Typography>\n <Typography variant=\"secondary\" type=\"footnote\">{t(\"Renews on\")} Jan 1, 2030</Typography>\n </div>\n <Button disabled variant=\"secondary\" color=\"neutral\">\n {t(\"Cancel subscription\")}\n </Button>\n </div>\n <div className=\"flex items-start justify-between gap-4\">\n <div className=\"min-w-0\">\n <Typography className=\"truncate\">{t(\"Credits pack\")}</Typography>\n <Typography variant=\"secondary\" type=\"footnote\">{t(\"One-time purchase\")}</Typography>\n </div>\n </div>\n </div>\n </Section>\n </div>\n );\n}\n\nfunction RealPaymentsPanel(props: { title?: string, customer: CustomerLike, customerType: \"user\" | \"team\" }) {\n const { t } = useTranslation();\n const stackApp = useStackApp();\n const billing = props.customer.useBilling();\n const defaultPaymentMethod = billing.defaultPaymentMethod;\n const products = props.customer.useProducts();\n const invoices = props.customer.useInvoices({ limit: 10 });\n const productsForCustomerType = products.filter(product => product.customerType === props.customerType);\n\n const [paymentDialogOpen, setPaymentDialogOpen] = useState(false);\n const [setupIntentClientSecret, setSetupIntentClientSecret] = useState<string | null>(null);\n const [setupIntentStripeAccountId, setSetupIntentStripeAccountId] = useState<string | null>(null);\n const [cancelTarget, setCancelTarget] = useState<{ productId: string, subscriptionId?: string } | null>(null);\n const [switchFromProductId, setSwitchFromProductId] = useState<string | null>(null);\n const [switchToProductId, setSwitchToProductId] = useState<string | null>(null);\n\n const stripePromise = useMemo(() => {\n if (!setupIntentStripeAccountId) return null;\n const publishableKey = envVars.NEXT_PUBLIC_STACK_STRIPE_PUBLISHABLE_KEY;\n if (!publishableKey) return null;\n return loadStripe(publishableKey, { stripeAccount: setupIntentStripeAccountId });\n }, [setupIntentStripeAccountId]);\n\n const handleAsyncError = (error: unknown) => {\n if (error instanceof KnownErrors.DefaultPaymentMethodRequired) {\n toast({\n title: t(\"No default payment method\"),\n description: t(\"Add a payment method before switching plans.\"),\n variant: \"destructive\",\n });\n return;\n }\n alert(`An unhandled error occurred. Please ${envVars.NODE_ENV === \"development\" ? \"check the browser console for the full error.\" : \"report this to the developer.\"}\\n\\n${error}`);\n };\n\n const openPaymentDialog = () => {\n runAsynchronously(async () => {\n setPaymentDialogOpen(true);\n const res = await props.customer.createPaymentMethodSetupIntent();\n setSetupIntentClientSecret(res.clientSecret);\n setSetupIntentStripeAccountId(res.stripeAccountId);\n }, { onError: handleAsyncError });\n };\n\n const closePaymentDialog = () => {\n setPaymentDialogOpen(false);\n setSetupIntentClientSecret(null);\n setSetupIntentStripeAccountId(null);\n };\n\n const openSwitchDialog = (productId: string, firstOptionId: string | null) => {\n setSwitchFromProductId(productId);\n setSwitchToProductId(firstOptionId);\n };\n\n const closeSwitchDialog = () => {\n setSwitchFromProductId(null);\n setSwitchToProductId(null);\n };\n\n const switchSourceProduct = switchFromProductId\n ? productsForCustomerType.find((product) => product.id === switchFromProductId) ?? null\n : null;\n const switchOptions = switchSourceProduct?.switchOptions ?? [];\n const selectedSwitchOption = switchOptions.find((option) => option.productId === switchToProductId) ?? null;\n const selectedPriceId = selectedSwitchOption ? (Object.keys(selectedSwitchOption.prices)[0] ?? null) : null;\n\n return (\n <div className=\"space-y-4\">\n {props.title && <Typography className=\"font-medium\">{props.title}</Typography>}\n\n {defaultPaymentMethod && (\n <Section\n title={t(\"Payment method\")}\n description={t(\"Manage the default payment method used for subscriptions and invoices.\")}\n >\n <Typography>{formatPaymentMethod(defaultPaymentMethod)}</Typography>\n\n <Button onClick={openPaymentDialog}>\n {t(\"Update payment method\")}\n </Button>\n\n <ActionDialog\n open={paymentDialogOpen}\n onOpenChange={(open) => {\n if (!open) {\n closePaymentDialog();\n } else {\n setPaymentDialogOpen(true);\n }\n }}\n title={t(\"Update payment method\")}\n >\n {!setupIntentClientSecret || !setupIntentStripeAccountId || !stripePromise ? (\n <Skeleton className=\"h-10 w-full\" />\n ) : (\n <Elements\n stripe={stripePromise}\n options={{\n clientSecret: setupIntentClientSecret,\n }}\n >\n <SetDefaultPaymentMethodForm\n clientSecret={setupIntentClientSecret}\n onSetupIntentSucceeded={async (setupIntentId) => {\n await props.customer.setDefaultPaymentMethodFromSetupIntent(setupIntentId);\n closePaymentDialog();\n }}\n />\n </Elements>\n )}\n </ActionDialog>\n </Section>\n )}\n\n {productsForCustomerType.length > 0 && (\n <Section\n title={t(\"Active plans\")}\n description={t(\"View your active plans and purchases.\")}\n >\n <div className=\"space-y-3\">\n {productsForCustomerType.map((product, index) => {\n const quantitySuffix = product.quantity !== 1 ? ` ×${product.quantity}` : \"\";\n const isSubscription = product.type === \"subscription\";\n const isCancelable = isSubscription && !!product.subscription?.isCancelable;\n const canSwitchPlans = isSubscription && defaultPaymentMethod && !!product.id && (product.switchOptions?.length ?? 0) > 0;\n const renewsAt = isSubscription ? (product.subscription?.currentPeriodEnd ?? null) : null;\n const subtitle =\n product.type === \"one_time\"\n ? t(\"One-time purchase\")\n : renewsAt\n ? `${t(\"Renews on\")} ${new Intl.DateTimeFormat(undefined, { year: \"numeric\", month: \"short\", day: \"numeric\" }).format(renewsAt)}`\n : t(\"Subscription\");\n\n return (\n <div key={product.id ?? `${product.displayName}-${index}`} className=\"flex items-start justify-between gap-4\">\n <div className=\"min-w-0\">\n <Typography className=\"truncate\">{product.displayName}{quantitySuffix}</Typography>\n <Typography variant=\"secondary\" type=\"footnote\">{subtitle}</Typography>\n </div>\n\n <div className=\"flex flex-col items-end gap-2\">\n {canSwitchPlans && (\n <Button\n variant=\"secondary\"\n color=\"neutral\"\n onClick={() => openSwitchDialog(product.id!, product.switchOptions?.[0]?.productId ?? null)}\n >\n {t(\"Change plan\")}\n </Button>\n )}\n {isCancelable && (\n <Button\n variant=\"secondary\"\n color=\"neutral\"\n onClick={() => setCancelTarget({ productId: product.id ?? \"_inline\", subscriptionId: product.subscription?.subscriptionId ?? undefined })}\n >\n {t(\"Cancel subscription\")}\n </Button>\n )}\n </div>\n </div>\n );\n })}\n </div>\n\n <ActionDialog\n open={cancelTarget !== null}\n onOpenChange={(open) => {\n if (!open) setCancelTarget(null);\n }}\n title={t(\"Cancel subscription\")}\n description={t(\"Canceling will stop future renewals for this subscription.\")}\n danger\n cancelButton\n okButton={{\n label: t(\"Cancel subscription\"),\n onClick: async () => {\n if (!cancelTarget) return;\n const { productId, subscriptionId } = cancelTarget;\n if (props.customerType === \"team\") {\n await stackApp.cancelSubscription({ teamId: props.customer.id, productId, subscriptionId });\n } else {\n await stackApp.cancelSubscription({ productId, subscriptionId });\n }\n setCancelTarget(null);\n },\n }}\n />\n\n <ActionDialog\n open={switchFromProductId !== null}\n onOpenChange={(open) => {\n if (!open) closeSwitchDialog();\n }}\n title={t(\"Change plan\")}\n description={t(\"Select a new plan from the same product line.\")}\n cancelButton\n okButton={{\n label: t(\"Switch plan\"),\n onClick: async () => {\n const fromProductId = switchFromProductId;\n const toProductId = switchToProductId;\n if (!fromProductId || !toProductId) return;\n if (!selectedPriceId) return;\n const result = await Result.fromThrowingAsync(() => props.customer.switchSubscription({\n fromProductId,\n toProductId,\n priceId: selectedPriceId,\n }));\n if (result.status === \"error\") {\n handleAsyncError(result.error);\n return \"prevent-close\";\n }\n closeSwitchDialog();\n },\n props: {\n disabled: !switchFromProductId || !switchToProductId || !selectedPriceId,\n },\n }}\n >\n <div className=\"space-y-2\">\n {switchOptions.length === 0 ? (\n <Typography variant=\"secondary\" type=\"footnote\">\n {t(\"No other plans available for this subscription.\")}\n </Typography>\n ) : (\n <>\n <Typography type=\"footnote\">{t(\"Choose a plan\")}</Typography>\n <Select\n value={switchToProductId ?? undefined}\n onValueChange={(value) => setSwitchToProductId(value || null)}\n >\n <SelectTrigger className=\"w-full\">\n <SelectValue placeholder={t(\"Choose a plan\")} />\n </SelectTrigger>\n <SelectContent>\n {switchOptions.map((option: NonNullable<typeof switchOptions>[number]) => (\n <SelectItem key={option.productId} value={option.productId}>\n {option.displayName}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </>\n )}\n </div>\n </ActionDialog>\n </Section>\n )\n }\n {invoices.length > 0 && (\n <>\n <Separator />\n <div className=\"space-y-2\">\n <div className=\"space-y-1\">\n <Typography className=\"font-medium\">{t(\"Invoices\")}</Typography>\n <Typography variant=\"secondary\" type=\"footnote\">{t(\"Review past invoices and receipts.\")}</Typography>\n </div>\n <div className=\"border rounded-md\">\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead className=\"w-[140px]\">{t(\"Date\")}</TableHead>\n <TableHead className=\"w-[120px]\">{t(\"Status\")}</TableHead>\n <TableHead className=\"w-[120px]\">{t(\"Amount\")}</TableHead>\n <TableHead className=\"w-[120px] text-right\">{t(\"Invoice\")}</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {invoices.map((invoice, index) => {\n const createdAtTime = invoice.createdAt.getTime();\n const invoiceKey = Number.isNaN(createdAtTime) ? `invoice-${index}` : `invoice-${createdAtTime}-${index}`;\n return (\n <TableRow key={invoiceKey}>\n <TableCell>\n <Typography>{formatInvoiceDate(invoice.createdAt, t)}</Typography>\n </TableCell>\n <TableCell>\n <Typography>{formatInvoiceStatus(invoice.status, t)}</Typography>\n </TableCell>\n <TableCell>\n <Typography>{formatInvoiceAmount(invoice.amountTotal, t)}</Typography>\n </TableCell>\n <TableCell align=\"right\">\n {invoice.hostedInvoiceUrl ? (\n <Button asChild variant=\"secondary\" color=\"neutral\" size=\"sm\">\n <a href={invoice.hostedInvoiceUrl} target=\"_blank\" rel=\"noreferrer\">\n {t(\"View\")}\n </a>\n </Button>\n ) : (\n <Typography variant=\"secondary\" type=\"footnote\">\n {t(\"Unavailable\")}\n </Typography>\n )}\n </TableCell>\n </TableRow>\n );\n })}\n </TableBody>\n </Table>\n </div>\n </div>\n </>\n )}\n </div >\n );\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"oauth-callback.d.ts","names":[],"sources":["../../src/components-page/oauth-callback.tsx"],"mappings":";;;iBAgBgB,aAAA,CAAA;EAAgB;AAAA;EAAc,QAAA;AAAA,IAAoB,kBAAA,CAAA,GAAA,CAAA,OAAA"}
1
+ {"version":3,"file":"oauth-callback.d.ts","names":[],"sources":["../../src/components-page/oauth-callback.tsx"],"mappings":";;;iBAiBgB,aAAA,CAAA;EAAgB;AAAA;EAAc,QAAA;AAAA,IAAoB,kBAAA,CAAA,GAAA,CAAA,OAAA"}
@@ -11,6 +11,7 @@ let ___lib_translations_js = require("../lib/translations.js");
11
11
  let react_jsx_runtime = require("react/jsx-runtime");
12
12
  let ___components_elements_maybe_full_page_js = require("../components/elements/maybe-full-page.js");
13
13
  let ___components_link_js = require("../components/link.js");
14
+ let ___lib_env_js = require("../lib/env.js");
14
15
 
15
16
  //#region src/components-page/oauth-callback.tsx
16
17
  function OAuthCallback({ fullPage }) {
@@ -23,13 +24,15 @@ function OAuthCallback({ fullPage }) {
23
24
  if (called.current) return;
24
25
  called.current = true;
25
26
  let hasRedirected = false;
27
+ let callbackError = null;
26
28
  try {
27
29
  hasRedirected = await app.callOAuthCallback();
28
30
  } catch (e) {
31
+ callbackError = e;
29
32
  (0, _stackframe_stack_shared_dist_utils_errors.captureError)("<OAuthCallback />", e);
30
33
  setError(e);
31
34
  }
32
- if (!hasRedirected && (!error || process.env.NODE_ENV === "production")) await app.redirectToSignIn({ noRedirectBack: true });
35
+ if (!hasRedirected && (callbackError == null || ___lib_env_js.envVars.NODE_ENV === "production")) await app.redirectToSignIn({ noRedirectBack: true });
33
36
  }), []);
34
37
  (0, react.useEffect)(() => {
35
38
  setTimeout(() => setShowRedirectLink(true), 3e3);
@@ -1 +1 @@
1
- {"version":3,"file":"oauth-callback.js","names":["MaybeFullPage","Spinner","StyledLink"],"sources":["../../src/components-page/oauth-callback.tsx"],"sourcesContent":["'use client';\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY, INSTEAD EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\n\nimport { captureError } from \"@stackframe/stack-shared/dist/utils/errors\";\nimport { runAsynchronously } from \"@stackframe/stack-shared/dist/utils/promises\";\nimport { Spinner, cn } from \"@stackframe/stack-ui\";\nimport { useEffect, useRef, useState } from \"react\";\nimport { useStackApp } from \"..\";\nimport { MaybeFullPage } from \"../components/elements/maybe-full-page\";\nimport { StyledLink } from \"../components/link\";\nimport { useTranslation } from \"../lib/translations\";\n\nexport function OAuthCallback({ fullPage }: { fullPage?: boolean }) {\n const { t } = useTranslation();\n const app = useStackApp();\n const called = useRef(false);\n const [error, setError] = useState<unknown>(null);\n const [showRedirectLink, setShowRedirectLink] = useState(false);\n\n useEffect(() => runAsynchronously(async () => {\n if (called.current) return;\n called.current = true;\n let hasRedirected = false;\n try {\n hasRedirected = await app.callOAuthCallback();\n } catch (e) {\n captureError(\"<OAuthCallback />\", e);\n setError(e);\n }\n if (!hasRedirected && (!error || process.env.NODE_ENV === 'production')) {\n await app.redirectToSignIn({ noRedirectBack: true });\n }\n }), []);\n\n useEffect(() => {\n setTimeout(() => setShowRedirectLink(true), 3000);\n }, []);\n\n return (\n <MaybeFullPage\n fullPage={fullPage ?? false}\n containerClassName=\"flex items-center justify-center\"\n >\n <div\n className={cn(\n \"text-center justify-center items-center stack-scope flex flex-col gap-4 max-w-[380px]\",\n fullPage ? \"p-4\" : \"p-0\"\n )}\n >\n <div className=\"flex flex-col justify-center items-center gap-4\">\n <Spinner size={20} />\n </div>\n {showRedirectLink ? <p>{t('If you are not redirected automatically, ')}<StyledLink className=\"whitespace-nowrap\" href={app.urls.home}>{t(\"click here\")}</StyledLink></p> : null}\n {error ? <div>\n <p>{t(\"Something went wrong while processing the OAuth callback:\")}</p>\n <pre>{JSON.stringify(error, null, 2)}</pre>\n <p>{t(\"This is most likely an error in Stack. Please report it.\")}</p>\n </div> : null}\n </div>\n </MaybeFullPage>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;AAgBA,SAAgB,cAAc,EAAE,YAAoC;CAClE,MAAM,EAAE,kDAAsB;CAC9B,MAAM,oCAAmB;CACzB,MAAM,2BAAgB,MAAM;CAC5B,MAAM,CAAC,OAAO,gCAA8B,KAAK;CACjD,MAAM,CAAC,kBAAkB,2CAAgC,MAAM;AAE/D,gGAAkC,YAAY;AAC5C,MAAI,OAAO,QAAS;AACpB,SAAO,UAAU;EACjB,IAAI,gBAAgB;AACpB,MAAI;AACF,mBAAgB,MAAM,IAAI,mBAAmB;WACtC,GAAG;AACV,gEAAa,qBAAqB,EAAE;AACpC,YAAS,EAAE;;AAEb,MAAI,CAAC,kBAAkB,CAAC,SAAS,QAAQ,IAAI,aAAa,cACxD,OAAM,IAAI,iBAAiB,EAAE,gBAAgB,MAAM,CAAC;GAEtD,EAAE,EAAE,CAAC;AAEP,4BAAgB;AACd,mBAAiB,oBAAoB,KAAK,EAAE,IAAK;IAChD,EAAE,CAAC;AAEN,QACE,2CAACA;EACC,UAAU,YAAY;EACtB,oBAAmB;YAEnB,4CAAC;GACC,wCACE,yFACA,WAAW,QAAQ,MACpB;;IAED,2CAAC;KAAI,WAAU;eACb,2CAACC,gCAAQ,MAAM,KAAM;MACjB;IACL,mBAAmB,4CAAC,kBAAG,EAAE,4CAA4C,EAAC,2CAACC;KAAW,WAAU;KAAoB,MAAM,IAAI,KAAK;eAAO,EAAE,aAAa;MAAc,IAAI,GAAG;IAC1K,QAAQ,4CAAC;KACR,2CAAC,iBAAG,EAAE,4DAA4D,GAAK;KACvE,2CAAC,mBAAK,KAAK,UAAU,OAAO,MAAM,EAAE,GAAO;KAC3C,2CAAC,iBAAG,EAAE,2DAA2D,GAAK;QAClE,GAAG;;IACL;GACQ"}
1
+ {"version":3,"file":"oauth-callback.js","names":["envVars","MaybeFullPage","Spinner","StyledLink"],"sources":["../../src/components-page/oauth-callback.tsx"],"sourcesContent":["'use client';\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY, INSTEAD EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\n\nimport { captureError } from \"@stackframe/stack-shared/dist/utils/errors\";\nimport { runAsynchronously } from \"@stackframe/stack-shared/dist/utils/promises\";\nimport { Spinner, cn } from \"@stackframe/stack-ui\";\nimport { useEffect, useRef, useState } from \"react\";\nimport { useStackApp } from \"..\";\nimport { MaybeFullPage } from \"../components/elements/maybe-full-page\";\nimport { StyledLink } from \"../components/link\";\nimport { envVars } from \"../lib/env\";\nimport { useTranslation } from \"../lib/translations\";\n\nexport function OAuthCallback({ fullPage }: { fullPage?: boolean }) {\n const { t } = useTranslation();\n const app = useStackApp();\n const called = useRef(false);\n const [error, setError] = useState<unknown>(null);\n const [showRedirectLink, setShowRedirectLink] = useState(false);\n\n useEffect(() => runAsynchronously(async () => {\n if (called.current) return;\n called.current = true;\n let hasRedirected = false;\n let callbackError: unknown = null;\n try {\n hasRedirected = await app.callOAuthCallback();\n } catch (e) {\n callbackError = e;\n captureError(\"<OAuthCallback />\", e);\n setError(e);\n }\n if (!hasRedirected && (callbackError == null || envVars.NODE_ENV === \"production\")) {\n await app.redirectToSignIn({ noRedirectBack: true });\n }\n }), []);\n\n useEffect(() => {\n setTimeout(() => setShowRedirectLink(true), 3000);\n }, []);\n\n return (\n <MaybeFullPage\n fullPage={fullPage ?? false}\n containerClassName=\"flex items-center justify-center\"\n >\n <div\n className={cn(\n \"text-center justify-center items-center stack-scope flex flex-col gap-4 max-w-[380px]\",\n fullPage ? \"p-4\" : \"p-0\"\n )}\n >\n <div className=\"flex flex-col justify-center items-center gap-4\">\n <Spinner size={20} />\n </div>\n {showRedirectLink ? <p>{t('If you are not redirected automatically, ')}<StyledLink className=\"whitespace-nowrap\" href={app.urls.home}>{t(\"click here\")}</StyledLink></p> : null}\n {error ? <div>\n <p>{t(\"Something went wrong while processing the OAuth callback:\")}</p>\n <pre>{JSON.stringify(error, null, 2)}</pre>\n <p>{t(\"This is most likely an error in Stack. Please report it.\")}</p>\n </div> : null}\n </div>\n </MaybeFullPage>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAiBA,SAAgB,cAAc,EAAE,YAAoC;CAClE,MAAM,EAAE,kDAAsB;CAC9B,MAAM,oCAAmB;CACzB,MAAM,2BAAgB,MAAM;CAC5B,MAAM,CAAC,OAAO,gCAA8B,KAAK;CACjD,MAAM,CAAC,kBAAkB,2CAAgC,MAAM;AAE/D,gGAAkC,YAAY;AAC5C,MAAI,OAAO,QAAS;AACpB,SAAO,UAAU;EACjB,IAAI,gBAAgB;EACpB,IAAI,gBAAyB;AAC7B,MAAI;AACF,mBAAgB,MAAM,IAAI,mBAAmB;WACtC,GAAG;AACV,mBAAgB;AAChB,gEAAa,qBAAqB,EAAE;AACpC,YAAS,EAAE;;AAEb,MAAI,CAAC,kBAAkB,iBAAiB,QAAQA,sBAAQ,aAAa,cACnE,OAAM,IAAI,iBAAiB,EAAE,gBAAgB,MAAM,CAAC;GAEtD,EAAE,EAAE,CAAC;AAEP,4BAAgB;AACd,mBAAiB,oBAAoB,KAAK,EAAE,IAAK;IAChD,EAAE,CAAC;AAEN,QACE,2CAACC;EACC,UAAU,YAAY;EACtB,oBAAmB;YAEnB,4CAAC;GACC,wCACE,yFACA,WAAW,QAAQ,MACpB;;IAED,2CAAC;KAAI,WAAU;eACb,2CAACC,gCAAQ,MAAM,KAAM;MACjB;IACL,mBAAmB,4CAAC,kBAAG,EAAE,4CAA4C,EAAC,2CAACC;KAAW,WAAU;KAAoB,MAAM,IAAI,KAAK;eAAO,EAAE,aAAa;MAAc,IAAI,GAAG;IAC1K,QAAQ,4CAAC;KACR,2CAAC,iBAAG,EAAE,4DAA4D,GAAK;KACvE,2CAAC,mBAAK,KAAK,UAAU,OAAO,MAAM,EAAE,GAAO;KAC3C,2CAAC,iBAAG,EAAE,2DAA2D,GAAK;QAClE,GAAG;;IACL;GACQ"}
@@ -1 +1 @@
1
- {"version":3,"file":"stack-handler-client.d.ts","names":[],"sources":["../../src/components-page/stack-handler-client.tsx"],"mappings":";;;;;;;;;;;;;;;;KA6BK,UAAA;EACH,MAAA,SAAe,MAAA;EACf,MAAA,SAAe,MAAA;EACf,iBAAA,SAA0B,iBAAA;EAC1B,aAAA,SAAsB,aAAA;EACtB,cAAA,SAAuB,cAAA;EACvB,OAAA,SAAgB,OAAA;EAChB,aAAA,SAAsB,aAAA;EACtB,iBAAA,SAA0B,iBAAA;EAC1B,cAAA,SAAuB,cAAA;EACvB,SAAA,SAAkB,SAAA;EAClB,eAAA,SAAwB,eAAA;EACxB,mBAAA,SAA4B,mBAAA;EAC5B,GAAA,SAAY,GAAA;EACZ,UAAA,SAAmB,UAAA;AAAA;AAAA,KAGhB,UAAA;EACH,MAAA,EAAQ,OAAA;IAAU,KAAA;EAAA;IAAwB,KAAA;EAAA;EAC1C,YAAA,EAAc,OAAA,CAAQ,MAAA,oBAA0B,MAAA;AAAA;AAAA,KA2BtC,gBAAA;EACV,QAAA;EACA,cAAA,iBACc,UAAA,IAAc,UAAA,CAAW,UAAA,CAAW,CAAA;AAAA;AAAA,iBAqIpC,kBAAA,CAAmB,KAAA,EAAO,gBAAA,GAAmB,OAAA,CAAQ,UAAA;EAAgB,QAAA;AAAA"}
1
+ {"version":3,"file":"stack-handler-client.d.ts","names":[],"sources":["../../src/components-page/stack-handler-client.tsx"],"mappings":";;;;;;;;;;;;;;;;KA8BK,UAAA;EACH,MAAA,SAAe,MAAA;EACf,MAAA,SAAe,MAAA;EACf,iBAAA,SAA0B,iBAAA;EAC1B,aAAA,SAAsB,aAAA;EACtB,cAAA,SAAuB,cAAA;EACvB,OAAA,SAAgB,OAAA;EAChB,aAAA,SAAsB,aAAA;EACtB,iBAAA,SAA0B,iBAAA;EAC1B,cAAA,SAAuB,cAAA;EACvB,SAAA,SAAkB,SAAA;EAClB,eAAA,SAAwB,eAAA;EACxB,mBAAA,SAA4B,mBAAA;EAC5B,GAAA,SAAY,GAAA;EACZ,UAAA,SAAmB,UAAA;AAAA;AAAA,KAGhB,UAAA;EACH,MAAA,EAAQ,OAAA;IAAU,KAAA;EAAA;IAAwB,KAAA;EAAA;EAC1C,YAAA,EAAc,OAAA,CAAQ,MAAA,oBAA0B,MAAA;AAAA;AAAA,KA6BtC,gBAAA;EACV,QAAA;EACA,cAAA,iBACc,UAAA,IAAc,UAAA,CAAW,UAAA,CAAW,CAAA;AAAA;AAAA,iBA8IpC,kBAAA,CAAmB,KAAA,EAAO,gBAAA,GAAmB,OAAA,CAAQ,UAAA;EAAgB,QAAA;AAAA"}
@@ -10,6 +10,8 @@ let ___lib_hooks_js = require("../lib/hooks.js");
10
10
  let ___components_message_cards_message_card_js = require("../components/message-cards/message-card.js");
11
11
  let _stackframe_stack_shared_dist_utils_objects = require("@stackframe/stack-shared/dist/utils/objects");
12
12
  let _stackframe_stack_shared_dist_utils_urls = require("@stackframe/stack-shared/dist/utils/urls");
13
+ let ___lib_stack_app_index_js = require("../lib/stack-app/index.js");
14
+ let ___lib_stack_app_url_targets_js = require("../lib/stack-app/url-targets.js");
13
15
  let __account_settings_js = require("./account-settings.js");
14
16
  let __cli_auth_confirm_js = require("./cli-auth-confirm.js");
15
17
  let __email_verification_js = require("./email-verification.js");
@@ -40,13 +42,14 @@ const availablePaths = {
40
42
  error: "error",
41
43
  onboarding: "onboarding"
42
44
  };
45
+ const placeholderOrigin = "http://example.com";
43
46
  const pathAliases = {
44
47
  ...Object.fromEntries(Object.entries(availablePaths).map(([key, value]) => [value, value])),
45
48
  "log-in": availablePaths.signIn,
46
49
  "register": availablePaths.signUp
47
50
  };
48
51
  function renderComponent(props) {
49
- const { path, searchParams, fullPage, componentProps, redirectIfNotHandler, onNotFound, app } = props;
52
+ const { path, searchParams, fullPage, componentProps, redirectIfNotHandler, getDefaultUnknownPathUrl, onNotFound, app } = props;
50
53
  switch (path) {
51
54
  case availablePaths.signIn:
52
55
  redirectIfNotHandler?.("signIn");
@@ -133,34 +136,53 @@ function renderComponent(props) {
133
136
  fullPage,
134
137
  ...filterUndefinedINU(componentProps?.Onboarding)
135
138
  });
136
- default:
139
+ default: {
137
140
  if (Object.values(availablePaths).includes(path)) throw new _stackframe_stack_shared_dist_utils_errors.StackAssertionError(`Path alias ${path} not included in switch statement, but in availablePaths?`, { availablePaths });
138
141
  for (const [key, value] of Object.entries(pathAliases)) if (path.toLowerCase().replaceAll("-", "") === key.toLowerCase().replaceAll("-", "")) return { redirect: `${app.urls.handler}/${value}?${new URLSearchParams(searchParams).toString()}` };
142
+ const defaultUnknownPathUrl = getDefaultUnknownPathUrl?.(path);
143
+ if (defaultUnknownPathUrl != null) {
144
+ const defaultUnknownPathUrlObject = new URL(defaultUnknownPathUrl, "http://example.com");
145
+ for (const [key, value] of Object.entries(searchParams)) defaultUnknownPathUrlObject.searchParams.set(key, value);
146
+ return { redirect: toAbsoluteOrRelativeRedirectTarget(defaultUnknownPathUrlObject) };
147
+ }
139
148
  return onNotFound();
149
+ }
140
150
  }
141
151
  }
142
152
  function StackHandlerClient(props) {
143
153
  const stackApp = (0, ___lib_hooks_js.useStackApp)();
144
154
  const currentLocation = props.location ?? window.location.pathname;
145
155
  const searchParamsSource = new URLSearchParams(window.location.search);
146
- const { path, searchParams } = (0, react.useMemo)(() => {
156
+ const { path, searchParams, handlerPath } = (0, react.useMemo)(() => {
147
157
  const handlerPath = new URL(stackApp.urls.handler, "http://example.com").pathname;
148
158
  return {
149
159
  path: currentLocation.startsWith(handlerPath) ? currentLocation.slice(handlerPath.length).replace(/^\/+/, "") : currentLocation.replace(/^\/+/, ""),
150
- searchParams: Object.fromEntries(searchParamsSource.entries())
160
+ searchParams: Object.fromEntries(searchParamsSource.entries()),
161
+ handlerPath
151
162
  };
152
163
  }, [
153
164
  currentLocation,
154
165
  searchParamsSource,
155
166
  stackApp.urls.handler
156
167
  ]);
168
+ const getDefaultUnknownPathUrl = (unknownPath) => {
169
+ return (0, ___lib_stack_app_url_targets_js.resolveUnknownHandlerPathFallbackUrl)({
170
+ defaultTarget: stackApp[___lib_stack_app_index_js.stackAppInternalsSymbol].getConstructorOptions().urls?.default,
171
+ projectId: stackApp.projectId,
172
+ unknownPath
173
+ });
174
+ };
157
175
  const redirectIfNotHandler = (name) => {
158
176
  const url = stackApp.urls[name];
159
- const handlerUrl = stackApp.urls.handler;
160
- if (url !== handlerUrl && url.startsWith(handlerUrl + "/")) return;
161
- const urlObj = new URL(url, "http://example.com");
177
+ if (name === "oauthCallback" && searchParams.stack_cross_domain_auth === "1") return;
178
+ if ((0, ___lib_stack_app_url_targets_js.isLocalHandlerUrlTarget)({
179
+ targetUrl: url,
180
+ handlerPath,
181
+ currentOrigin: typeof window === "undefined" ? void 0 : window.location.origin
182
+ })) return;
183
+ const urlObj = new URL(url, placeholderOrigin);
162
184
  for (const [key, value] of Object.entries(searchParams)) urlObj.searchParams.set(key, value);
163
- window.location.href = (0, _stackframe_stack_shared_dist_utils_urls.getRelativePart)(urlObj);
185
+ window.location.href = toAbsoluteOrRelativeRedirectTarget(urlObj);
164
186
  };
165
187
  const result = renderComponent({
166
188
  path,
@@ -168,6 +190,7 @@ function StackHandlerClient(props) {
168
190
  fullPage: props.fullPage,
169
191
  componentProps: props.componentProps,
170
192
  redirectIfNotHandler,
193
+ getDefaultUnknownPathUrl,
171
194
  onNotFound: () => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(___components_message_cards_message_card_js.MessageCard, {
172
195
  title: "Page does not exist",
173
196
  fullPage: props.fullPage,
@@ -186,6 +209,9 @@ function StackHandlerClient(props) {
186
209
  function filterUndefinedINU(value) {
187
210
  return value === void 0 ? value : (0, _stackframe_stack_shared_dist_utils_objects.filterUndefined)(value);
188
211
  }
212
+ function toAbsoluteOrRelativeRedirectTarget(url) {
213
+ return url.origin === "http://example.com" ? (0, _stackframe_stack_shared_dist_utils_urls.getRelativePart)(url) : url.toString();
214
+ }
189
215
 
190
216
  //#endregion
191
217
  exports.StackHandlerClient = StackHandlerClient;
@@ -1 +1 @@
1
- {"version":3,"file":"stack-handler-client.js","names":["SignIn","SignUp","EmailVerification","PasswordReset","ForgotPassword","SignOut","OAuthCallback","MagicLinkCallback","TeamInvitation","AccountSettings","ErrorPage","CliAuthConfirmation","MFA","Onboarding","StackAssertionError","MessageCard"],"sources":["../../src/components-page/stack-handler-client.tsx"],"sourcesContent":["\"use client\";\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY, INSTEAD EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\n\nimport { StackAssertionError } from \"@stackframe/stack-shared/dist/utils/errors\";\nimport { FilterUndefined, filterUndefined } from \"@stackframe/stack-shared/dist/utils/objects\";\nimport { getRelativePart } from \"@stackframe/stack-shared/dist/utils/urls\";\nimport { useMemo } from 'react';\nimport { SignIn, SignUp, StackServerApp } from \"..\";\nimport { useStackApp } from \"../lib/hooks\";\nimport { HandlerUrls, StackClientApp } from \"../lib/stack-app\";\nimport { AccountSettings } from \"./account-settings\";\nimport { CliAuthConfirmation } from \"./cli-auth-confirm\";\nimport { EmailVerification } from \"./email-verification\";\nimport { ErrorPage } from \"./error-page\";\nimport { ForgotPassword } from \"./forgot-password\";\nimport { MagicLinkCallback } from \"./magic-link-callback\";\nimport { MFA } from \"./mfa\";\nimport { OAuthCallback } from \"./oauth-callback\";\nimport { Onboarding } from \"./onboarding\";\nimport { PasswordReset } from \"./password-reset\";\nimport { SignOut } from \"./sign-out\";\nimport { TeamInvitation } from \"./team-invitation\";\n\nimport { MessageCard } from \"../components/message-cards/message-card\";\n\ntype Components = {\n SignIn: typeof SignIn,\n SignUp: typeof SignUp,\n EmailVerification: typeof EmailVerification,\n PasswordReset: typeof PasswordReset,\n ForgotPassword: typeof ForgotPassword,\n SignOut: typeof SignOut,\n OAuthCallback: typeof OAuthCallback,\n MagicLinkCallback: typeof MagicLinkCallback,\n TeamInvitation: typeof TeamInvitation,\n ErrorPage: typeof ErrorPage,\n AccountSettings: typeof AccountSettings,\n CliAuthConfirmation: typeof CliAuthConfirmation,\n MFA: typeof MFA,\n Onboarding: typeof Onboarding,\n};\n\ntype RouteProps = {\n params: Promise<{ stack?: string[] }> | { stack?: string[] },\n searchParams: Promise<Record<string, string>> | Record<string, string>,\n};\n\nconst availablePaths = {\n signIn: 'sign-in',\n signUp: 'sign-up',\n emailVerification: 'email-verification',\n passwordReset: 'password-reset',\n forgotPassword: 'forgot-password',\n signOut: 'sign-out',\n oauthCallback: 'oauth-callback',\n magicLinkCallback: 'magic-link-callback',\n teamInvitation: 'team-invitation',\n accountSettings: 'account-settings',\n cliAuthConfirm: 'cli-auth-confirm',\n mfa: 'mfa',\n error: 'error',\n onboarding: 'onboarding',\n} as const;\n\nconst pathAliases = {\n // also includes the uppercase and non-dashed versions\n ...Object.fromEntries(Object.entries(availablePaths).map(([key, value]) => [value, value])),\n \"log-in\": availablePaths.signIn,\n \"register\": availablePaths.signUp,\n} as const;\n\nexport type BaseHandlerProps = {\n fullPage: boolean,\n componentProps?: {\n [K in keyof Components]?: Parameters<Components[K]>[0];\n },\n};\n\nfunction renderComponent(props: {\n path: string,\n searchParams: Record<string, string>,\n fullPage: boolean,\n componentProps?: BaseHandlerProps['componentProps'],\n redirectIfNotHandler?: (name: keyof HandlerUrls) => void,\n onNotFound: () => any,\n app: StackClientApp<any> | StackServerApp<any>,\n}) {\n const { path, searchParams, fullPage, componentProps, redirectIfNotHandler, onNotFound, app } = props;\n\n switch (path) {\n case availablePaths.signIn: {\n redirectIfNotHandler?.('signIn');\n return <SignIn\n fullPage={fullPage}\n automaticRedirect\n {...filterUndefinedINU(componentProps?.SignIn)}\n />;\n }\n case availablePaths.signUp: {\n redirectIfNotHandler?.('signUp');\n return <SignUp\n fullPage={fullPage}\n automaticRedirect\n {...filterUndefinedINU(componentProps?.SignUp)}\n />;\n }\n case availablePaths.emailVerification: {\n redirectIfNotHandler?.('emailVerification');\n return <EmailVerification\n searchParams={searchParams}\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.EmailVerification)}\n />;\n }\n case availablePaths.passwordReset: {\n redirectIfNotHandler?.('passwordReset');\n return <PasswordReset\n searchParams={searchParams}\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.PasswordReset)}\n />;\n }\n case availablePaths.forgotPassword: {\n redirectIfNotHandler?.('forgotPassword');\n return <ForgotPassword\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.ForgotPassword)}\n />;\n }\n case availablePaths.signOut: {\n redirectIfNotHandler?.('signOut');\n return <SignOut\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.SignOut)}\n />;\n }\n case availablePaths.oauthCallback: {\n redirectIfNotHandler?.('oauthCallback');\n return <OAuthCallback\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.OAuthCallback)}\n />;\n }\n case availablePaths.magicLinkCallback: {\n redirectIfNotHandler?.('magicLinkCallback');\n return <MagicLinkCallback\n searchParams={searchParams}\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.MagicLinkCallback)}\n />;\n }\n case availablePaths.teamInvitation: {\n redirectIfNotHandler?.('teamInvitation');\n return <TeamInvitation\n searchParams={searchParams}\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.TeamInvitation)}\n />;\n }\n case availablePaths.accountSettings: {\n return <AccountSettings\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.AccountSettings)}\n />;\n }\n case availablePaths.error: {\n return <ErrorPage\n searchParams={searchParams}\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.ErrorPage)}\n />;\n }\n case availablePaths.cliAuthConfirm: {\n return <CliAuthConfirmation\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.CliAuthConfirmation)}\n />;\n }\n case availablePaths.mfa: {\n redirectIfNotHandler?.('mfa');\n return <MFA\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.MFA)}\n />;\n }\n case availablePaths.onboarding: {\n redirectIfNotHandler?.('onboarding');\n return <Onboarding\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.Onboarding)}\n />;\n }\n default: {\n if (Object.values(availablePaths).includes(path as any)) {\n throw new StackAssertionError(`Path alias ${path} not included in switch statement, but in availablePaths?`, { availablePaths });\n }\n for (const [key, value] of Object.entries(pathAliases)) {\n if (path.toLowerCase().replaceAll('-', '') === key.toLowerCase().replaceAll('-', '')) {\n const redirectUrl = `${app.urls.handler}/${value}?${new URLSearchParams(searchParams).toString()}`;\n return { redirect: redirectUrl };\n }\n }\n return onNotFound();\n }\n }\n}\n\nexport function StackHandlerClient(props: BaseHandlerProps & Partial<RouteProps> & { location?: string }) {\n // Use hooks to get app\n const stackApp = useStackApp();\n\n const currentLocation = props.location ?? window.location.pathname;\n const searchParamsSource = new URLSearchParams(window.location.search);\n\n const { path, searchParams } = useMemo(() => {\n const handlerPath = new URL(stackApp.urls.handler, 'http://example.com').pathname;\n const relativePath = currentLocation.startsWith(handlerPath)\n ? currentLocation.slice(handlerPath.length).replace(/^\\/+/, '')\n : currentLocation.replace(/^\\/+/, '');\n\n return {\n path: relativePath,\n searchParams: Object.fromEntries(searchParamsSource.entries())\n };\n }, [currentLocation, searchParamsSource, stackApp.urls.handler]);\n\n const redirectIfNotHandler = (name: keyof HandlerUrls) => {\n const url = stackApp.urls[name];\n const handlerUrl = stackApp.urls.handler;\n\n if (url !== handlerUrl && url.startsWith(handlerUrl + \"/\")) {\n return;\n }\n\n const urlObj = new URL(url, 'http://example.com');\n for (const [key, value] of Object.entries(searchParams)) {\n urlObj.searchParams.set(key, value);\n }\n\n window.location.href = getRelativePart(urlObj);\n };\n\n const result = renderComponent({\n path,\n searchParams,\n fullPage: props.fullPage,\n componentProps: props.componentProps,\n redirectIfNotHandler,\n onNotFound: () =>\n (\n <MessageCard\n title=\"Page does not exist\"\n fullPage={props.fullPage}\n primaryButtonText=\"Go to Home\"\n primaryAction={() => stackApp.redirectToHome()}\n >\n The page you are looking for could not be found. Please check the URL and try again.\n </MessageCard>\n )\n ,\n app: stackApp,\n });\n\n if (result && 'redirect' in result) {\n window.location.href = result.redirect;\n return null;\n }\n\n return result;\n}\n\n// filter undefined values in object. if object itself is undefined, return undefined\nfunction filterUndefinedINU<T extends {}>(value: T | undefined): FilterUndefined<T> | undefined {\n return value === undefined ? value : filterUndefined(value);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"stack-handler-client.js","names":["SignIn","SignUp","EmailVerification","PasswordReset","ForgotPassword","SignOut","OAuthCallback","MagicLinkCallback","TeamInvitation","AccountSettings","ErrorPage","CliAuthConfirmation","MFA","Onboarding","StackAssertionError","stackAppInternalsSymbol","MessageCard"],"sources":["../../src/components-page/stack-handler-client.tsx"],"sourcesContent":["\"use client\";\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY, INSTEAD EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\n\nimport { StackAssertionError } from \"@stackframe/stack-shared/dist/utils/errors\";\nimport { FilterUndefined, filterUndefined } from \"@stackframe/stack-shared/dist/utils/objects\";\nimport { getRelativePart } from \"@stackframe/stack-shared/dist/utils/urls\";\nimport { useMemo } from 'react';\nimport { SignIn, SignUp, StackServerApp } from \"..\";\nimport { useStackApp } from \"../lib/hooks\";\nimport { HandlerUrls, StackClientApp, stackAppInternalsSymbol } from \"../lib/stack-app\";\nimport { isLocalHandlerUrlTarget, resolveUnknownHandlerPathFallbackUrl } from \"../lib/stack-app/url-targets\";\nimport { AccountSettings } from \"./account-settings\";\nimport { CliAuthConfirmation } from \"./cli-auth-confirm\";\nimport { EmailVerification } from \"./email-verification\";\nimport { ErrorPage } from \"./error-page\";\nimport { ForgotPassword } from \"./forgot-password\";\nimport { MagicLinkCallback } from \"./magic-link-callback\";\nimport { MFA } from \"./mfa\";\nimport { OAuthCallback } from \"./oauth-callback\";\nimport { Onboarding } from \"./onboarding\";\nimport { PasswordReset } from \"./password-reset\";\nimport { SignOut } from \"./sign-out\";\nimport { TeamInvitation } from \"./team-invitation\";\n\nimport { MessageCard } from \"../components/message-cards/message-card\";\n\ntype Components = {\n SignIn: typeof SignIn,\n SignUp: typeof SignUp,\n EmailVerification: typeof EmailVerification,\n PasswordReset: typeof PasswordReset,\n ForgotPassword: typeof ForgotPassword,\n SignOut: typeof SignOut,\n OAuthCallback: typeof OAuthCallback,\n MagicLinkCallback: typeof MagicLinkCallback,\n TeamInvitation: typeof TeamInvitation,\n ErrorPage: typeof ErrorPage,\n AccountSettings: typeof AccountSettings,\n CliAuthConfirmation: typeof CliAuthConfirmation,\n MFA: typeof MFA,\n Onboarding: typeof Onboarding,\n};\n\ntype RouteProps = {\n params: Promise<{ stack?: string[] }> | { stack?: string[] },\n searchParams: Promise<Record<string, string>> | Record<string, string>,\n};\n\nconst availablePaths = {\n signIn: 'sign-in',\n signUp: 'sign-up',\n emailVerification: 'email-verification',\n passwordReset: 'password-reset',\n forgotPassword: 'forgot-password',\n signOut: 'sign-out',\n oauthCallback: 'oauth-callback',\n magicLinkCallback: 'magic-link-callback',\n teamInvitation: 'team-invitation',\n accountSettings: 'account-settings',\n cliAuthConfirm: 'cli-auth-confirm',\n mfa: 'mfa',\n error: 'error',\n onboarding: 'onboarding',\n} as const;\n\nconst placeholderOrigin = \"http://example.com\";\n\nconst pathAliases = {\n // also includes the uppercase and non-dashed versions\n ...Object.fromEntries(Object.entries(availablePaths).map(([key, value]) => [value, value])),\n \"log-in\": availablePaths.signIn,\n \"register\": availablePaths.signUp,\n} as const;\n\nexport type BaseHandlerProps = {\n fullPage: boolean,\n componentProps?: {\n [K in keyof Components]?: Parameters<Components[K]>[0];\n },\n};\n\nfunction renderComponent(props: {\n path: string,\n searchParams: Record<string, string>,\n fullPage: boolean,\n componentProps?: BaseHandlerProps['componentProps'],\n redirectIfNotHandler?: (name: keyof HandlerUrls) => void,\n getDefaultUnknownPathUrl?: (path: string) => string | null,\n onNotFound: () => any,\n app: StackClientApp<any> | StackServerApp<any>,\n}) {\n const { path, searchParams, fullPage, componentProps, redirectIfNotHandler, getDefaultUnknownPathUrl, onNotFound, app } = props;\n\n switch (path) {\n case availablePaths.signIn: {\n redirectIfNotHandler?.('signIn');\n return <SignIn\n fullPage={fullPage}\n automaticRedirect\n {...filterUndefinedINU(componentProps?.SignIn)}\n />;\n }\n case availablePaths.signUp: {\n redirectIfNotHandler?.('signUp');\n return <SignUp\n fullPage={fullPage}\n automaticRedirect\n {...filterUndefinedINU(componentProps?.SignUp)}\n />;\n }\n case availablePaths.emailVerification: {\n redirectIfNotHandler?.('emailVerification');\n return <EmailVerification\n searchParams={searchParams}\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.EmailVerification)}\n />;\n }\n case availablePaths.passwordReset: {\n redirectIfNotHandler?.('passwordReset');\n return <PasswordReset\n searchParams={searchParams}\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.PasswordReset)}\n />;\n }\n case availablePaths.forgotPassword: {\n redirectIfNotHandler?.('forgotPassword');\n return <ForgotPassword\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.ForgotPassword)}\n />;\n }\n case availablePaths.signOut: {\n redirectIfNotHandler?.('signOut');\n return <SignOut\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.SignOut)}\n />;\n }\n case availablePaths.oauthCallback: {\n redirectIfNotHandler?.('oauthCallback');\n return <OAuthCallback\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.OAuthCallback)}\n />;\n }\n case availablePaths.magicLinkCallback: {\n redirectIfNotHandler?.('magicLinkCallback');\n return <MagicLinkCallback\n searchParams={searchParams}\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.MagicLinkCallback)}\n />;\n }\n case availablePaths.teamInvitation: {\n redirectIfNotHandler?.('teamInvitation');\n return <TeamInvitation\n searchParams={searchParams}\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.TeamInvitation)}\n />;\n }\n case availablePaths.accountSettings: {\n return <AccountSettings\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.AccountSettings)}\n />;\n }\n case availablePaths.error: {\n return <ErrorPage\n searchParams={searchParams}\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.ErrorPage)}\n />;\n }\n case availablePaths.cliAuthConfirm: {\n return <CliAuthConfirmation\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.CliAuthConfirmation)}\n />;\n }\n case availablePaths.mfa: {\n redirectIfNotHandler?.('mfa');\n return <MFA\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.MFA)}\n />;\n }\n case availablePaths.onboarding: {\n redirectIfNotHandler?.('onboarding');\n return <Onboarding\n fullPage={fullPage}\n {...filterUndefinedINU(componentProps?.Onboarding)}\n />;\n }\n default: {\n if (Object.values(availablePaths).includes(path as any)) {\n throw new StackAssertionError(`Path alias ${path} not included in switch statement, but in availablePaths?`, { availablePaths });\n }\n for (const [key, value] of Object.entries(pathAliases)) {\n if (path.toLowerCase().replaceAll('-', '') === key.toLowerCase().replaceAll('-', '')) {\n const redirectUrl = `${app.urls.handler}/${value}?${new URLSearchParams(searchParams).toString()}`;\n return { redirect: redirectUrl };\n }\n }\n const defaultUnknownPathUrl = getDefaultUnknownPathUrl?.(path);\n if (defaultUnknownPathUrl != null) {\n const defaultUnknownPathUrlObject = new URL(defaultUnknownPathUrl, \"http://example.com\");\n for (const [key, value] of Object.entries(searchParams)) {\n defaultUnknownPathUrlObject.searchParams.set(key, value);\n }\n return { redirect: toAbsoluteOrRelativeRedirectTarget(defaultUnknownPathUrlObject) };\n }\n return onNotFound();\n }\n }\n}\n\nexport function StackHandlerClient(props: BaseHandlerProps & Partial<RouteProps> & { location?: string }) {\n // Use hooks to get app\n const stackApp = useStackApp();\n\n const currentLocation = props.location ?? window.location.pathname;\n const searchParamsSource = new URLSearchParams(window.location.search);\n\n const { path, searchParams, handlerPath } = useMemo(() => {\n const handlerPath = new URL(stackApp.urls.handler, 'http://example.com').pathname;\n const relativePath = currentLocation.startsWith(handlerPath)\n ? currentLocation.slice(handlerPath.length).replace(/^\\/+/, '')\n : currentLocation.replace(/^\\/+/, '');\n\n return {\n path: relativePath,\n searchParams: Object.fromEntries(searchParamsSource.entries()),\n handlerPath,\n };\n }, [currentLocation, searchParamsSource, stackApp.urls.handler]);\n\n const getDefaultUnknownPathUrl = (unknownPath: string): string | null => {\n return resolveUnknownHandlerPathFallbackUrl({\n defaultTarget: stackApp[stackAppInternalsSymbol].getConstructorOptions().urls?.default,\n projectId: stackApp.projectId,\n unknownPath,\n });\n };\n\n const redirectIfNotHandler = (name: keyof HandlerUrls) => {\n const url = stackApp.urls[name];\n const isCrossDomainLocalOauthCallback = name === \"oauthCallback\" && searchParams.stack_cross_domain_auth === \"1\";\n if (isCrossDomainLocalOauthCallback) {\n return;\n }\n const isLocalHandlerTarget = isLocalHandlerUrlTarget({\n targetUrl: url,\n handlerPath,\n currentOrigin: typeof window === \"undefined\" ? undefined : window.location.origin,\n });\n if (isLocalHandlerTarget) {\n return;\n }\n\n const urlObj = new URL(url, placeholderOrigin);\n for (const [key, value] of Object.entries(searchParams)) {\n urlObj.searchParams.set(key, value);\n }\n\n window.location.href = toAbsoluteOrRelativeRedirectTarget(urlObj);\n };\n\n const result = renderComponent({\n path,\n searchParams,\n fullPage: props.fullPage,\n componentProps: props.componentProps,\n redirectIfNotHandler,\n getDefaultUnknownPathUrl,\n onNotFound: () =>\n (\n <MessageCard\n title=\"Page does not exist\"\n fullPage={props.fullPage}\n primaryButtonText=\"Go to Home\"\n primaryAction={() => stackApp.redirectToHome()}\n >\n The page you are looking for could not be found. Please check the URL and try again.\n </MessageCard>\n )\n ,\n app: stackApp,\n });\n\n if (result && 'redirect' in result) {\n window.location.href = result.redirect;\n return null;\n }\n\n return result;\n}\n\n// filter undefined values in object. if object itself is undefined, return undefined\nfunction filterUndefinedINU<T extends {}>(value: T | undefined): FilterUndefined<T> | undefined {\n return value === undefined ? value : filterUndefined(value);\n}\n\nfunction toAbsoluteOrRelativeRedirectTarget(url: URL): string {\n return url.origin === \"http://example.com\" ? getRelativePart(url) : url.toString();\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"payments-panel.d.ts","names":[],"sources":["../../../../../src/components-page/account-settings/payments/payments-panel.tsx"],"mappings":";;;;KAmBK,oBAAA;EACH,EAAA;EACA,KAAA;EACA,KAAA;EACA,SAAA;EACA,QAAA;AAAA;AAAA,KAsDG,eAAA;EACH,WAAA;EACA,oBAAA,EAAsB,oBAAA;AAAA;AAAA,KAGnB,gCAAA;EACH,YAAA;EACA,eAAA;AAAA;AAAA,KAGG,YAAA;EACH,EAAA;EACA,UAAA,QAAkB,eAAA;EAClB,WAAA,QAAmB,KAAA;IACjB,EAAA;IACA,QAAA;IACA,WAAA;IACA,YAAA;IACA,IAAA;IACA,aAAA,GAAgB,KAAA;MACd,SAAA;MACA,WAAA;MACA,MAAA,EAAQ,MAAA;QAAiB,QAAA;MAAA;IAAA;IAE3B,YAAA;MACE,cAAA;MACA,gBAAA,EAAkB,IAAA;MAClB,iBAAA;MACA,YAAA;IAAA;EAAA;EAGJ,WAAA,GAAc,OAAA,GAAU,2BAAA,KAAgC,oBAAA;EACxD,8BAAA,QAAsC,OAAA,CAAQ,gCAAA;EAC9C,sCAAA,GAAyC,aAAA,aAA0B,OAAA,CAAQ,oBAAA;EAC3E,kBAAA,GAAqB,OAAA;IAAW,aAAA;IAAuB,WAAA;IAAqB,OAAA;IAAkB,QAAA;EAAA,MAAwB,OAAA;AAAA;AAAA,iBAyDxG,aAAA,CAAc,KAAA;EAC5B,KAAA;EACA,QAAA,GAAW,YAAA;EACX,YAAA;EACA,QAAA;AAAA,IACD,kBAAA,CAAA,GAAA,CAAA,OAAA"}
1
+ {"version":3,"file":"payments-panel.d.ts","names":[],"sources":["../../../../../src/components-page/account-settings/payments/payments-panel.tsx"],"mappings":";;;;KAoBK,oBAAA;EACH,EAAA;EACA,KAAA;EACA,KAAA;EACA,SAAA;EACA,QAAA;AAAA;AAAA,KAsDG,eAAA;EACH,WAAA;EACA,oBAAA,EAAsB,oBAAA;AAAA;AAAA,KAGnB,gCAAA;EACH,YAAA;EACA,eAAA;AAAA;AAAA,KAGG,YAAA;EACH,EAAA;EACA,UAAA,QAAkB,eAAA;EAClB,WAAA,QAAmB,KAAA;IACjB,EAAA;IACA,QAAA;IACA,WAAA;IACA,YAAA;IACA,IAAA;IACA,aAAA,GAAgB,KAAA;MACd,SAAA;MACA,WAAA;MACA,MAAA,EAAQ,MAAA;QAAiB,QAAA;MAAA;IAAA;IAE3B,YAAA;MACE,cAAA;MACA,gBAAA,EAAkB,IAAA;MAClB,iBAAA;MACA,YAAA;IAAA;EAAA;EAGJ,WAAA,GAAc,OAAA,GAAU,2BAAA,KAAgC,oBAAA;EACxD,8BAAA,QAAsC,OAAA,CAAQ,gCAAA;EAC9C,sCAAA,GAAyC,aAAA,aAA0B,OAAA,CAAQ,oBAAA;EAC3E,kBAAA,GAAqB,OAAA;IAAW,aAAA;IAAuB,WAAA;IAAqB,OAAA;IAAkB,QAAA;EAAA,MAAwB,OAAA;AAAA;AAAA,iBAyDxG,aAAA,CAAc,KAAA;EAC5B,KAAA;EACA,QAAA,GAAW,YAAA;EACX,YAAA;EACA,QAAA;AAAA,IACD,kBAAA,CAAA,GAAA,CAAA,OAAA"}
@@ -11,6 +11,7 @@ import { Section } from "../section.js";
11
11
  import { useStackApp } from "../../../index.js";
12
12
  import { CardElement, Elements, useElements, useStripe } from "@stripe/react-stripe-js";
13
13
  import { loadStripe } from "@stripe/stripe-js";
14
+ import { envVars } from "../../../lib/env.js";
14
15
 
15
16
  //#region src/components-page/account-settings/payments/payments-panel.tsx
16
17
  function formatPaymentMethod(pm) {
@@ -189,7 +190,7 @@ function RealPaymentsPanel(props) {
189
190
  const [switchToProductId, setSwitchToProductId] = useState(null);
190
191
  const stripePromise = useMemo(() => {
191
192
  if (!setupIntentStripeAccountId) return null;
192
- const publishableKey = process.env.NEXT_PUBLIC_STACK_STRIPE_PUBLISHABLE_KEY;
193
+ const publishableKey = envVars.NEXT_PUBLIC_STACK_STRIPE_PUBLISHABLE_KEY;
193
194
  if (!publishableKey) return null;
194
195
  return loadStripe(publishableKey, { stripeAccount: setupIntentStripeAccountId });
195
196
  }, [setupIntentStripeAccountId]);
@@ -202,7 +203,7 @@ function RealPaymentsPanel(props) {
202
203
  });
203
204
  return;
204
205
  }
205
- alert(`An unhandled error occurred. Please ${process.env.NODE_ENV === "development" ? "check the browser console for the full error." : "report this to the developer."}\n\n${error}`);
206
+ alert(`An unhandled error occurred. Please ${envVars.NODE_ENV === "development" ? "check the browser console for the full error." : "report this to the developer."}\n\n${error}`);
206
207
  };
207
208
  const openPaymentDialog = () => {
208
209
  runAsynchronously(async () => {