@churnkey/react 0.7.0 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-SWEPUHIN.cjs → chunk-ER6YITYC.cjs} +12 -2
- package/dist/chunk-ER6YITYC.cjs.map +1 -0
- package/dist/{chunk-4ZAJYXG2.cjs → chunk-FK4AJOX6.cjs} +6 -6
- package/dist/{chunk-4ZAJYXG2.cjs.map → chunk-FK4AJOX6.cjs.map} +1 -1
- package/dist/{chunk-KS3RWFRH.js → chunk-GNRS7V7H.js} +3 -3
- package/dist/{chunk-KS3RWFRH.js.map → chunk-GNRS7V7H.js.map} +1 -1
- package/dist/{chunk-BODEVZ3K.js → chunk-RFKW3LWM.js} +12 -2
- package/dist/chunk-RFKW3LWM.js.map +1 -0
- package/dist/core.cjs +14 -14
- package/dist/core.d.cts +2 -2
- package/dist/core.d.ts +2 -2
- package/dist/core.js +1 -1
- package/dist/headless.cjs +3 -3
- package/dist/headless.d.cts +1 -1
- package/dist/headless.d.ts +1 -1
- package/dist/headless.js +2 -2
- package/dist/index.cjs +124 -123
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +20 -19
- package/dist/index.js.map +1 -1
- package/dist/{step-graph-s1L1wV-P.d.cts → step-graph-C7JC8Umv.d.cts} +18 -0
- package/dist/{step-graph-s1L1wV-P.d.ts → step-graph-C7JC8Umv.d.ts} +18 -0
- package/package.json +1 -1
- package/dist/chunk-BODEVZ3K.js.map +0 -1
- package/dist/chunk-SWEPUHIN.cjs.map +0 -1
|
@@ -64,6 +64,16 @@ var defaultMessages = {
|
|
|
64
64
|
newEndDateLabel: "New end date",
|
|
65
65
|
currentPlanBadge: "Current",
|
|
66
66
|
switchToCta: "Switch to {planName}",
|
|
67
|
+
acceptCta: {
|
|
68
|
+
discount: "",
|
|
69
|
+
pause: "",
|
|
70
|
+
trial_extension: "",
|
|
71
|
+
plan_change: "",
|
|
72
|
+
contact: "",
|
|
73
|
+
redirect: "",
|
|
74
|
+
rebate: ""
|
|
75
|
+
},
|
|
76
|
+
declineCta: "",
|
|
67
77
|
rebate: {
|
|
68
78
|
paidLabel: "You paid this period",
|
|
69
79
|
moneyBackLabel: "Money back",
|
|
@@ -1400,5 +1410,5 @@ exports.defaultMessages = defaultMessages;
|
|
|
1400
1410
|
exports.defaultTitles = defaultTitles;
|
|
1401
1411
|
exports.formatMessage = formatMessage;
|
|
1402
1412
|
exports.selectTiming = selectTiming;
|
|
1403
|
-
//# sourceMappingURL=chunk-
|
|
1404
|
-
//# sourceMappingURL=chunk-
|
|
1413
|
+
//# sourceMappingURL=chunk-ER6YITYC.cjs.map
|
|
1414
|
+
//# sourceMappingURL=chunk-ER6YITYC.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/messages.ts","../src/core/utils.ts","../src/core/api.ts","../src/core/merge-fields.ts","../src/core/step-graph.ts","../src/core/transform.ts","../src/core/machine.ts","../src/core/types.ts","../src/core/token.ts"],"names":["defaultOfferCopy"],"mappings":"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","file":"chunk-ER6YITYC.cjs","sourcesContent":["// Message catalog for every string the SDK renders that isn't flow content.\n// Flow content (step titles, offer copy) is authored per-org in the dashboard\n// and arrives resolved in token mode; this catalog covers the chrome around\n// it. Overrides layer lowest-to-highest: built-in defaults, then each entry\n// in the locale fallback chain of `i18n.messages`, and per-step props\n// (confirmLabel, savedTitle, …) win over everything at the render site.\n\n/** Both timing variants of a message. Which one renders is decided by the\n * flow's effective cancel timing (`FlowState.cancelAtPeriodEnd`). */\nexport interface TimingVariants {\n immediate: string\n atPeriodEnd: string\n}\n\n/**\n * A message that may differ by cancellation timing. Plain strings render\n * as-is in both cases; pass the object form when the wording should change\n * (e.g. \"Cancel\" vs \"Turn off auto-renew\").\n */\nexport type TimingAware = string | TimingVariants\n\n/** Success-screen copy for one accepted offer type. */\nexport interface SavedOfferCopy {\n title: string\n description: string\n}\n\nexport interface CancelFlowMessages {\n common: {\n continue: string\n back: string\n close: string\n done: string\n processing: string\n tryAgain: string\n loading: string\n loadError: string\n error: string\n day: string\n days: string\n month: string\n months: string\n }\n survey: {\n title: string\n followupPlaceholder: string\n followupAriaLabel: string\n }\n feedback: {\n title: string\n placeholder: string\n /** Used instead of `placeholder` when the step sets `minLength`. Supports `{minLength}`. */\n placeholderWithMin: string\n }\n confirm: {\n title: string\n lossesLabel: string\n cta: TimingAware\n goBack: string\n /** Shown between the description and the confirm button. Supports\n * `{periodEnd}`. The default immediate variant is empty, which\n * suppresses the notice for immediate timing; empty OVERRIDE values are\n * dropped like any blank override, so to remove the notice entirely\n * replace the `Confirm` component or hide it via\n * `classNames.periodEndNotice`. */\n periodEndNotice: TimingAware\n }\n success: {\n saved: {\n /** Generic fallback — used for offer types without their own entry\n * (contact, redirect, custom types). */\n title: string\n description: string\n discount: SavedOfferCopy\n pause: SavedOfferCopy & {\n /** Used instead of `description` when the resume date is known\n * (the built-in pause UI always supplies it). Supports `{resumeDate}`. */\n resumeDescription: string\n }\n trial_extension: SavedOfferCopy\n plan_change: SavedOfferCopy\n rebate: SavedOfferCopy\n }\n cancelled: {\n title: TimingAware\n description: TimingAware\n }\n }\n offer: {\n limitedTimeEyebrow: string\n pauseEyebrow: string\n newEndDateLabel: string\n currentPlanBadge: string\n /** CTA when a plan is selected in a plan-change offer. Supports `{planName}`. */\n switchToCta: string\n /**\n * Accept-button override per offer type. Defaults are empty: an unset\n * key falls through to the offer's own `copy.cta` (today a\n * server-synthesized default like \"Accept refund\"; authored per-offer\n * copy, when it exists, keeps winning over an unset key).\n */\n acceptCta: {\n discount: string\n pause: string\n trial_extension: string\n plan_change: string\n contact: string\n redirect: string\n rebate: string\n }\n /** Decline-link override for every offer type. Empty default falls\n * through to the offer's own `copy.declineCta`. */\n declineCta: string\n rebate: {\n paidLabel: string\n moneyBackLabel: string\n /** Tax parenthetical after the money-back label. Supports `{amount}`. */\n inclTax: string\n netLabel: string\n }\n }\n}\n\n/**\n * Recursive partial of the catalog for overrides. Timing-aware fields also\n * accept a plain string (applies to both timings) or a partial variant pair\n * (the missing variant keeps the base value).\n */\nexport type MessagesPatch<T = CancelFlowMessages> = {\n [K in keyof T]?: T[K] extends string\n ? string\n : T[K] extends TimingAware\n ? string | Partial<TimingVariants>\n : MessagesPatch<T[K]>\n}\n\nexport interface I18nConfig {\n /** UI language. Defaults to the browser language, falling back to `'en'`. */\n locale?: string\n /** Per-locale message overrides, e.g. `{ en: { confirm: { cta: 'Turn off auto-renew' } } }`. */\n messages?: Record<string, MessagesPatch>\n}\n\nexport const defaultMessages: CancelFlowMessages = {\n common: {\n continue: 'Continue',\n back: 'Back',\n close: 'Close',\n done: 'Done',\n processing: 'Processing...',\n tryAgain: 'Try again',\n loading: 'Loading your options...',\n loadError: \"We couldn't load your cancellation options. Please try again.\",\n error: 'Something went wrong. Please try again.',\n day: 'day',\n days: 'days',\n month: 'month',\n months: 'months',\n },\n survey: {\n title: 'Why are you cancelling?',\n followupPlaceholder: 'Tell us more (optional)',\n followupAriaLabel: 'Additional detail',\n },\n feedback: {\n title: 'Any other feedback?',\n placeholder: 'Type your thoughts…',\n placeholderWithMin: 'At least {minLength} characters…',\n },\n confirm: {\n title: 'Confirm cancellation',\n lossesLabel: \"You'll lose access to:\",\n cta: 'Cancel subscription',\n goBack: 'Go back',\n periodEndNotice: {\n immediate: '',\n atPeriodEnd: 'Your access continues until {periodEnd}.',\n },\n },\n success: {\n // Per-offer defaults mirror the embed's *Applied keys so the two\n // surfaces confirm the same outcome with the same words.\n saved: {\n title: 'Welcome back!',\n description: 'Your offer has been applied.',\n discount: { title: 'Discount applied.', description: \"We're so happy you're still here.\" },\n pause: {\n title: 'Subscription paused.',\n description: \"You won't be billed until your subscription resumes.\",\n resumeDescription: \"You won't be billed again until {resumeDate}.\",\n },\n trial_extension: { title: 'Trial extended.', description: 'Your trial has been extended successfully.' },\n plan_change: { title: 'Plan changed.', description: 'Your new plan is now in effect.' },\n rebate: { title: 'Refund issued.', description: \"Your money's on its way back.\" },\n },\n cancelled: {\n title: 'Subscription cancelled',\n description: \"We're sorry to see you go.\",\n },\n },\n offer: {\n limitedTimeEyebrow: 'Limited-time offer',\n pauseEyebrow: \"We'll see you back on\",\n newEndDateLabel: 'New end date',\n currentPlanBadge: 'Current',\n switchToCta: 'Switch to {planName}',\n acceptCta: {\n discount: '',\n pause: '',\n trial_extension: '',\n plan_change: '',\n contact: '',\n redirect: '',\n rebate: '',\n },\n declineCta: '',\n rebate: {\n paidLabel: 'You paid this period',\n moneyBackLabel: 'Money back',\n inclTax: '(incl. {amount} tax)',\n netLabel: 'Your net for this period',\n },\n },\n}\n\nfunction isTimingVariants(value: unknown): value is Partial<TimingVariants> {\n return (\n typeof value === 'object' &&\n value !== null &&\n ('immediate' in value || 'atPeriodEnd' in value) &&\n !Array.isArray(value)\n )\n}\n\n/**\n * Pick the string for the flow's effective cancel timing. `null` (timing\n * unknown — local mode) behaves like period-end, matching the default the\n * cancel action itself uses.\n */\nexport function selectTiming(value: TimingAware, cancelAtPeriodEnd: boolean | null): string {\n if (typeof value === 'string') return value\n return (cancelAtPeriodEnd ?? true) ? value.atPeriodEnd : value.immediate\n}\n\n/** Replace `{name}` tokens. Unknown tokens are left in place. */\nexport function formatMessage(template: string, vars: Record<string, string | number>): string {\n return template.replace(/\\{(\\w+)\\}/g, (match, name) => {\n const value = vars[name]\n return value == null ? match : String(value)\n })\n}\n\n// Leaves that accept an { immediate, atPeriodEnd } pair, by dot-path. The\n// base value alone can't identify them — most default to a plain string —\n// and pair patches must be rejected everywhere else: a pair landing on a\n// plain leaf would reach the renderer as an object child and throw.\nconst TIMING_AWARE_PATHS: ReadonlySet<string> = new Set([\n 'confirm.cta',\n 'confirm.periodEndNotice',\n 'success.cancelled.title',\n 'success.cancelled.description',\n])\n\n// The base (catalog) drives the merge, not the patch: org overrides arrive\n// unvalidated over the wire, so a patch shaped wrong for its slot is dropped\n// rather than trusted, and keys the catalog doesn't declare are ignored —\n// the catalog is closed. Empty-string overrides are also dropped (a blank\n// dashboard field must not clobber a real string — same rule as the embed),\n// which is why defaults may legitimately hold '' but patches never land one.\nfunction mergeValue(base: unknown, patch: unknown, path: string): unknown {\n if (typeof base === 'string' || isTimingVariants(base)) {\n if (typeof patch === 'string') return patch === '' ? base : patch\n if (isTimingVariants(patch) && TIMING_AWARE_PATHS.has(path)) {\n const result: TimingVariants =\n typeof base === 'string'\n ? { immediate: base, atPeriodEnd: base }\n : { immediate: '', atPeriodEnd: '', ...(base as Partial<TimingVariants>) }\n let applied = false\n if (typeof patch.immediate === 'string' && patch.immediate) {\n result.immediate = patch.immediate\n applied = true\n }\n if (typeof patch.atPeriodEnd === 'string' && patch.atPeriodEnd) {\n result.atPeriodEnd = patch.atPeriodEnd\n applied = true\n }\n return applied ? result : base\n }\n return base\n }\n if (\n typeof base === 'object' &&\n base !== null &&\n typeof patch === 'object' &&\n patch !== null &&\n !Array.isArray(patch) &&\n !isTimingVariants(patch)\n ) {\n const merged: Record<string, unknown> = { ...(base as Record<string, unknown>) }\n for (const [key, value] of Object.entries(patch)) {\n if (value == null || !(key in merged)) continue\n merged[key] = mergeValue(merged[key], value, path ? `${path}.${key}` : key)\n }\n return merged\n }\n return base\n}\n\nexport function mergeMessages(base: CancelFlowMessages, patch: MessagesPatch | undefined): CancelFlowMessages {\n if (!patch) return base\n return mergeValue(base, patch, '') as CancelFlowMessages\n}\n\nexport function resolveLocale(explicit?: string): string {\n if (explicit) return explicit\n if (typeof navigator !== 'undefined' && navigator.language) return navigator.language\n return 'en'\n}\n\n// Fallback chain, least to most specific: 'en' first so an English override\n// still shows through a partial regional catalog, then the base language,\n// then the exact tag. Keys are matched case-insensitively ('pt-BR' ≡ 'pt-br').\nfunction localeChain(locale: string): string[] {\n const exact = locale.toLowerCase()\n const base = exact.split('-')[0]\n const chain = ['en']\n if (base !== 'en') chain.push(base)\n if (exact !== base) chain.push(exact)\n return chain\n}\n\nfunction applyLocaleLayer(\n base: CancelFlowMessages,\n byLang: Record<string, MessagesPatch> | undefined,\n chain: string[],\n): CancelFlowMessages {\n if (!byLang) return base\n const byLowerKey = new Map(Object.entries(byLang).map(([k, v]) => [k.toLowerCase(), v]))\n let resolved = base\n for (const lang of chain) {\n resolved = mergeMessages(resolved, byLowerKey.get(lang))\n }\n return resolved\n}\n\n/**\n * Resolve the full catalog for a locale. Layers, lowest to highest: built-in\n * defaults, then `orgMessages` (dashboard-configured overrides delivered on\n * the token-mode config), then the config's own per-locale messages — the\n * developer's overrides always end up on top. Both per-language layers run\n * through the same locale fallback chain.\n */\nexport function buildMessages(i18n?: I18nConfig, orgMessages?: Record<string, MessagesPatch>): CancelFlowMessages {\n const chain = localeChain(resolveLocale(i18n?.locale))\n return applyLocaleLayer(applyLocaleLayer(defaultMessages, orgMessages, chain), i18n?.messages, chain)\n}\n","import type { CSSProperties } from 'react'\nimport { defaultMessages } from './messages'\nimport type { Appearance, AppearanceVariables } from './types'\n\nexport const BUILT_IN_STEP_TYPES: readonly string[] = ['survey', 'offer', 'feedback', 'confirm', 'success']\nexport const BUILT_IN_OFFER_TYPES: readonly string[] = [\n 'discount',\n 'pause',\n 'trial_extension',\n 'plan_change',\n 'contact',\n 'redirect',\n 'rebate',\n]\n\nexport function cn(...classes: (string | undefined | null | false)[]): string {\n return classes.filter(Boolean).join(' ')\n}\n\n// Maps the typed `appearance.variables` field names to the underlying\n// CSS custom properties. Light/dark variants live in CSS — these\n// overrides apply on top of whichever scheme is active.\nconst VAR_MAP: Record<string, keyof AppearanceVariables> = {\n // Surfaces\n '--ck-color-bg': 'colorBackground',\n '--ck-color-surface': 'colorSurface',\n '--ck-color-surface-muted': 'colorSurfaceMuted',\n\n // Borders\n '--ck-color-border': 'colorBorder',\n '--ck-color-border-strong': 'colorBorderStrong',\n\n // Text\n '--ck-color-text': 'colorText',\n '--ck-color-text-secondary': 'colorTextSecondary',\n '--ck-color-text-muted': 'colorTextMuted',\n\n // Primary\n '--ck-color-primary': 'colorPrimary',\n '--ck-color-primary-hover': 'colorPrimaryHover',\n '--ck-color-primary-soft': 'colorPrimarySoft',\n\n // Semantic\n '--ck-color-success': 'colorSuccess',\n '--ck-color-success-soft': 'colorSuccessSoft',\n '--ck-color-danger': 'colorDanger',\n '--ck-color-danger-hover': 'colorDangerHover',\n '--ck-color-danger-soft': 'colorDangerSoft',\n\n // Typography\n '--ck-font-family': 'fontFamily',\n '--ck-font-mono': 'fontFamilyMono',\n '--ck-font-display': 'fontFamilyDisplay',\n '--ck-font-size': 'fontSize',\n '--ck-step-title-weight': 'fontWeightDisplay',\n '--ck-step-title-letter-spacing': 'letterSpacingDisplay',\n\n // Geometry\n '--ck-border-radius': 'borderRadius',\n '--ck-radius-sm': 'radiusSm',\n '--ck-radius-md': 'radiusMd',\n '--ck-radius-lg': 'radiusLg',\n '--ck-radius-xl': 'radiusXl',\n\n // Elevation\n '--ck-shadow-modal': 'shadowModal',\n '--ck-shadow-card': 'shadowCard',\n\n // Overlay\n '--ck-overlay-color': 'overlayColor',\n}\n\nexport function appearanceToStyle(appearance?: Appearance): CSSProperties | undefined {\n const variables = appearance?.variables\n if (!variables) return undefined\n\n const style: Record<string, string> = {}\n for (const [cssProp, varKey] of Object.entries(VAR_MAP)) {\n const value = variables[varKey]\n if (value) style[cssProp] = value\n }\n\n return Object.keys(style).length > 0 ? (style as CSSProperties) : undefined\n}\n\n// Step-level fallback titles when neither token-mode config nor local\n// step config provide one. Offer and Success are absent — Offer falls back\n// to `offer.copy.headline`, Success branches on outcome. Kept for backwards\n// compatibility; the renderer now reads titles from the message catalog,\n// which these mirror.\nexport const defaultTitles = {\n survey: defaultMessages.survey.title,\n feedback: defaultMessages.feedback.title,\n confirm: defaultMessages.confirm.title,\n} as const\n","import type { SdkConfig } from './api-types'\nimport type { SessionCredentials } from './token'\nimport type { DirectCustomer, DirectSubscription, Mode } from './types'\n\nconst DEFAULT_BASE_URL = 'https://api.churnkey.co/v1'\n\n// Wire enums accepted by the API. Literal unions so payload builders fail\n// at compile time if they emit a value outside the accepted set.\nexport type ApiStepType = 'OFFER' | 'SURVEY' | 'CONFIRM' | 'FREEFORM' | 'CUSTOM'\nexport type ApiOfferType =\n | 'DISCOUNT'\n | 'PAUSE'\n | 'PLAN_CHANGE'\n | 'TRIAL_EXTENSION'\n | 'CONTACT'\n | 'REDIRECT'\n | 'REBATE'\n | 'CUSTOM'\nexport type ApiPauseInterval = 'MONTH' | 'WEEK'\nexport type ApiCouponType = 'PERCENT' | 'AMOUNT'\nexport type ApiBillingInterval = 'DAY' | 'WEEK' | 'MONTH' | 'YEAR'\nexport type ApiMode = 'LIVE' | 'TEST' | 'SANDBOX'\n\n// Exhaustive switch so a new Mode member without a wire mapping fails to compile.\nexport function toApiMode(mode: Mode): ApiMode {\n switch (mode) {\n case 'live':\n return 'LIVE'\n case 'test':\n return 'TEST'\n case 'sandbox':\n return 'SANDBOX'\n }\n}\n\nexport interface StepViewed {\n stepType: ApiStepType\n // Populated iff stepType === 'CUSTOM' — holds the SDK step name.\n customStepType?: string\n guid?: string\n numChoices?: number\n start: string\n end?: string\n duration?: number\n}\n\nexport interface PresentedOffer {\n guid?: string\n offerType?: ApiOfferType\n // Populated iff offerType === 'CUSTOM' — holds the SDK offer name.\n customOfferType?: string\n accepted: boolean\n presentedAt: string\n acceptedAt?: string\n declinedAt?: string\n [key: string]: unknown\n}\n\nexport interface AcceptedOfferPayload {\n guid?: string\n offerType: ApiOfferType\n // Populated iff offerType === 'CUSTOM' — holds the SDK offer name.\n customOfferType?: string\n // Populated iff offerType === 'CUSTOM' — the result arg passed to\n // `onAccept(result)` from the custom offer component.\n customOfferResult?: Record<string, unknown>\n couponId?: string\n couponType?: ApiCouponType\n couponAmount?: number\n couponDuration?: number\n pauseDuration?: number\n pauseInterval?: ApiPauseInterval\n newPlanId?: string\n newPlanPrice?: number\n trialExtensionDays?: number\n redirectUrl?: string\n rebateAmount?: number\n}\n\nexport interface SessionCustomer {\n id: string\n email?: string\n subscriptionId?: string\n planId?: string\n planPrice?: number\n currency?: string\n billingInterval?: ApiBillingInterval\n created?: string\n onTrial?: boolean\n customAttributes?: Record<string, unknown>\n}\n\nexport interface SessionPayload {\n blueprintId?: string\n surveyId?: string\n customer?: SessionCustomer\n canceled?: boolean\n aborted?: boolean\n surveyChoiceId?: string\n surveyChoiceValue?: string\n /** Free-text from a `freeform: true` reason. The reason's static `label` still travels on `surveyChoiceValue`. */\n followupResponse?: string\n feedback?: string\n acceptedOffer?: AcceptedOfferPayload\n presentedOffers?: PresentedOffer[]\n stepsViewed?: StepViewed[]\n customStepResults?: Record<string, unknown>\n mode: ApiMode\n provider?: string\n embedVersion?: string\n // Token-mode session-record fields. Populated automatically when the SDK\n // is configured with a session token; ignored in local/analytics mode.\n clickToCancelEnabled?: boolean\n strictFTCComplianceEnabled?: boolean\n usedClickToCancel?: boolean\n autoOptimizationUsed?: boolean\n autoOptimizationKey?: string\n discountCooldown?: number\n pauseCooldown?: number\n discountCooldownApplied?: boolean\n pauseCooldownApplied?: boolean\n}\n\nexport class ChurnkeyApi {\n private creds: SessionCredentials\n private baseUrl: string\n\n constructor(creds: SessionCredentials, baseUrl?: string) {\n this.creds = creds\n this.baseUrl = baseUrl ?? DEFAULT_BASE_URL\n }\n\n private get headers(): Record<string, string> {\n const h: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'x-ck-app': this.creds.appId,\n 'x-ck-customer': this.creds.customerId,\n 'x-ck-authorization': this.creds.authHash,\n 'x-ck-mode': this.creds.mode,\n }\n if (this.creds.subscriptionId) {\n h['x-ck-subscription'] = this.creds.subscriptionId\n }\n return h\n }\n\n private orgUrl(path: string): string {\n return `${this.baseUrl}/api/orgs/${this.creds.appId}/${path}`\n }\n\n // Action methods discard the response body, so don't parse JSON here —\n // a server returning an empty 201 would otherwise blow up res.json() and\n // surface as an error even though the action committed.\n private async request(url: string, body?: unknown): Promise<Response> {\n const res = await fetch(url, {\n method: 'POST',\n headers: this.headers,\n body: body ? JSON.stringify(body) : undefined,\n })\n if (!res.ok) {\n const text = await res.text().catch(() => '')\n throw new Error(`Churnkey API error (${res.status}): ${text}`)\n }\n return res\n }\n\n // customAttributes feed server-side segment matching when the blueprint is\n // picked. The body must not also carry a Direct `customer` — that tells the\n // server to skip the provider lookup, and segments should match against the\n // real provider customer plus this attribute layer.\n async fetchConfig(customAttributes?: Record<string, unknown>): Promise<SdkConfig> {\n const res = await this.request(\n this.orgUrl('cancel-flow/config'),\n customAttributes ? { customAttributes } : undefined,\n )\n return (await res.json()) as SdkConfig\n }\n\n async applyDiscount(couponId: string, blueprintId?: string): Promise<void> {\n await this.request(this.orgUrl('cancel-flow/actions/discount'), {\n coupon: couponId,\n blueprintId,\n })\n }\n\n async pause(params: { duration: number; interval: string }): Promise<void> {\n await this.request(this.orgUrl('cancel-flow/actions/pause'), {\n duration: params.duration,\n interval: params.interval,\n })\n }\n\n async cancelSubscription(cancelAtPeriodEnd = true, blueprintId?: string): Promise<void> {\n await this.request(this.orgUrl('cancel-flow/actions/cancel'), {\n cancelAtPeriodEnd,\n ...(blueprintId && { blueprintId }),\n })\n }\n\n async changePlan(planId: string): Promise<void> {\n await this.request(this.orgUrl('cancel-flow/actions/change-plan'), { planId })\n }\n\n async extendTrial(days: number, blueprintId?: string): Promise<void> {\n await this.request(this.orgUrl('cancel-flow/actions/extend-trial'), { days, blueprintId })\n }\n\n async applyRebate(blueprintId?: string, offerGuid?: string): Promise<void> {\n await this.request(this.orgUrl('cancel-flow/actions/rebate'), { blueprintId, offerGuid })\n }\n\n async createSession(payload: SessionPayload): Promise<void> {\n await this.request(`${this.baseUrl}/api/sessions/sdk`, payload)\n }\n}\n\nexport class AnalyticsClient {\n private appId: string\n private baseUrl: string\n\n constructor(appId: string, baseUrl?: string) {\n this.appId = appId\n this.baseUrl = baseUrl ?? DEFAULT_BASE_URL\n }\n\n // Fire-and-forget. Non-2xx responses are ignored — analytics failures\n // should never surface into the host app's flow.\n async createSession(payload: SessionPayload): Promise<void> {\n await fetch(`${this.baseUrl}/api/sessions/sdk`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-ck-app': this.appId,\n },\n body: JSON.stringify(payload),\n })\n }\n}\n\nfunction toIsoString(value: Date | string | undefined): string | undefined {\n if (value == null) return undefined\n return value instanceof Date ? value.toISOString() : String(value)\n}\n\nfunction toApiBillingInterval(interval: 'day' | 'week' | 'month' | 'year' | undefined): ApiBillingInterval | undefined {\n if (!interval) return undefined\n return interval.toUpperCase() as ApiBillingInterval\n}\n\nexport function directDataToSessionCustomer(\n customer: DirectCustomer,\n subscriptions?: DirectSubscription[],\n): SessionPayload['customer'] {\n const sub = subscriptions?.[0]\n const price = sub?.items[0]?.price\n\n return {\n id: customer.id,\n email: customer.email,\n subscriptionId: sub?.id,\n planId: price?.id,\n planPrice: price?.amount.value,\n currency: price?.amount.currency ?? customer.currency,\n billingInterval: toApiBillingInterval(price?.duration?.interval),\n created: toIsoString(sub?.start),\n onTrial: sub ? sub.status.name === 'trial' : undefined,\n customAttributes: customer.metadata,\n }\n}\n","// Merge field substitution for dashboard-authored copy. Placeholders look\n// like `{{CUSTOMER_NAME.FIRST|Jane}}` — field name, optional fallback after\n// the pipe. Copy can also arrive wrapped in `<merge-field>` tags (the\n// dashboard editor uses them for its own UI); browsers render unknown tags\n// as their text content, so the wrapper is transparent and only the inner\n// `{{…}}` needs substitution.\n\nimport type {\n DirectCustomer,\n FeedbackStep,\n OfferConfig,\n OfferDecision,\n OfferStep,\n ReasonConfig,\n Step,\n SurveyStep,\n} from './types'\n\nexport type MergeAttrs = Record<string, string>\n\nconst MERGE_FIELD_PATTERN = /{{([a-zA-Z0-9_.]+)\\|([^}]*)}}/g\n\n/**\n * Build the attribute map merge fields are resolved against. Sourced from\n * Direct.Customer fields: name (with `.FIRST`/`.LAST` variants), email, and\n * metadata, then the consumer's `customerAttributes` layer, which wins key\n * conflicts (same precedence as the embed). Values that aren't strings are\n * coerced — dashboards emit merge fields into HTML, and HTML only speaks\n * strings.\n */\nexport function buildMergeAttrs(\n customer: DirectCustomer | null | undefined,\n customerAttributes?: Record<string, unknown> | null,\n): MergeAttrs {\n const attrs: MergeAttrs = {}\n\n if (customer) {\n // Build full name from Direct.Customer's separate first/last name fields.\n const first = customer.name\n const last = customer.lastName\n const fullName = [first, last].filter(Boolean).join(' ') || undefined\n if (fullName) attrs.CUSTOMER_NAME = fullName\n if (first) attrs['CUSTOMER_NAME.FIRST'] = first\n if (last) attrs['CUSTOMER_NAME.LAST'] = last\n\n if (customer.email) attrs.CUSTOMER_EMAIL = customer.email\n\n for (const [key, value] of Object.entries(customer.metadata ?? {})) {\n if (value != null) attrs[key] = String(value)\n }\n }\n\n for (const [key, value] of Object.entries(customerAttributes ?? {})) {\n if (value != null) attrs[key] = String(value)\n }\n\n return attrs\n}\n\n/**\n * Replace `{{FIELD|fallback}}` placeholders in `text` with values from `attrs`.\n * Missing keys fall back to the `|…}}` segment (which may be empty). The\n * enclosing `<merge-field>` wrapper, if any, is left as-is — browsers ignore\n * unknown tags and render their children, so the visible output is correct.\n */\nexport function applyMergeFields(text: string, attrs: MergeAttrs): string {\n if (!text?.includes('{{')) return text\n return text.replace(MERGE_FIELD_PATTERN, (_match, field: string, fallback: string) => attrs[field] ?? fallback)\n}\n\n/**\n * Substitute merge fields across a Step[] tree. Called once at machine init\n * so the runtime carries already-resolved copy — components stay unaware of\n * merge fields entirely.\n */\nexport function applyMergeFieldsToSteps(\n steps: Step[],\n customer: DirectCustomer | null | undefined,\n customerAttributes?: Record<string, unknown> | null,\n): Step[] {\n const attrs = buildMergeAttrs(customer, customerAttributes)\n return steps.map((step) => mergeStep(step, attrs))\n}\n\nfunction mergeStep(step: Step, attrs: MergeAttrs): Step {\n // CustomStepConfig.type is `string`, so a literal-string switch doesn't\n // narrow it out of the union — each branch needs an explicit cast.\n switch (step.type) {\n case 'survey': {\n const s = step as SurveyStep\n return {\n ...s,\n title: maybeMerge(s.title, attrs),\n description: maybeMerge(s.description, attrs),\n reasons: s.reasons.map((r) => mergeReason(r, attrs)),\n }\n }\n case 'offer': {\n const s = step as OfferStep\n return {\n ...s,\n title: maybeMerge(s.title, attrs),\n description: maybeMerge(s.description, attrs),\n offer: s.offer ? mergeOffer(s.offer, attrs) : undefined,\n }\n }\n case 'feedback': {\n const s = step as FeedbackStep\n return {\n ...s,\n title: maybeMerge(s.title, attrs),\n description: maybeMerge(s.description, attrs),\n placeholder: maybeMerge(s.placeholder, attrs),\n }\n }\n case 'success':\n // savedTitle/cancelledTitle/etc. are picked at render time based on the\n // outcome; merge substitution can be added there if it's ever needed.\n return step\n default: {\n const s = step as { title?: string; description?: string }\n return { ...step, title: maybeMerge(s.title, attrs), description: maybeMerge(s.description, attrs) }\n }\n }\n}\n\nfunction mergeReason(r: ReasonConfig, attrs: MergeAttrs): ReasonConfig {\n return { ...r, label: applyMergeFields(r.label, attrs) }\n}\n\n// Standalone OfferSteps may arrive without copy (the step graph synthesizes\n// defaults later); merging copy is a no-op when there's nothing to merge.\nfunction mergeOffer(o: OfferConfig | OfferDecision, attrs: MergeAttrs): OfferConfig | OfferDecision {\n if (!('copy' in o)) return o\n return {\n ...o,\n copy: {\n headline: applyMergeFields(o.copy.headline, attrs),\n body: applyMergeFields(o.copy.body, attrs),\n cta: applyMergeFields(o.copy.cta, attrs),\n declineCta: applyMergeFields(o.copy.declineCta, attrs),\n },\n }\n}\n\nfunction maybeMerge(text: string | undefined, attrs: MergeAttrs): string | undefined {\n return text ? applyMergeFields(text, attrs) : text\n}\n","// Steps are a graph, not an array. Each step has a guid and two pointer\n// fields — defaultNextStep, defaultPreviousStep — set once at build and\n// never mutated. Survey steps additionally carry offersAttached, a\n// reasonId → synthetic-offer-step-guid map.\n//\n// Survey-choice offers are their own steps rather than a mutable slot, so\n// the current offer is always readable as stepMap[currentStepId].offer —\n// one source of truth for what's on screen.\n//\n// The graph is immutable after build. Local mode builds in the machine\n// constructor; token mode defers until the server config has loaded.\n\nimport type {\n ConfirmStep,\n CustomStepConfig,\n FeedbackStep,\n OfferConfig,\n OfferDecision,\n OfferStep,\n ReasonConfig,\n Step,\n SuccessStep,\n SurveyStep,\n} from './types'\n\nexport interface ResolvedStep {\n guid: string\n type: string\n defaultNextStep?: string\n defaultPreviousStep?: string\n title?: string\n description?: string\n\n // survey\n reasons?: ReasonConfig[]\n offersAttached?: Record<string, string>\n numChoices?: number\n\n // offer\n offer?: OfferDecision\n /** True if this step was synthesized from a survey choice. Used by stepIndex so synthetic offers share the survey's progress slot. */\n surveyOffer?: boolean\n\n // feedback\n placeholder?: string\n required?: boolean\n minLength?: number\n\n // confirm\n losses?: string[]\n lossesLabel?: string\n\n // success\n savedTitle?: string\n savedDescription?: string\n cancelledTitle?: string\n cancelledDescription?: string\n\n // custom\n data?: Record<string, unknown>\n\n classNames?: unknown\n}\n\nexport interface StepGraph {\n stepMap: Record<string, ResolvedStep>\n /** Entry point. */\n firstStepId: string\n /** Developer-declared steps in declaration order. Synthetic offer steps are NOT included — they live in stepMap only. Drives progress UI. */\n orderedStepIds: string[]\n /** Cached for O(1) lookup. Undefined if the flow has no survey step. */\n surveyStepId?: string\n}\n\nconst EMPTY_GRAPH: StepGraph = { stepMap: {}, firstStepId: '', orderedStepIds: [] }\n\nexport function buildStepGraph(\n steps: Step[],\n defaultOfferCopy: (offer: OfferConfig) => OfferDecision['copy'],\n): StepGraph {\n if (steps.length === 0) return EMPTY_GRAPH\n\n const resolved = steps.map((step, i) => normalizeStep(step, i, defaultOfferCopy))\n linkNeighbors(resolved)\n\n const stepMap: Record<string, ResolvedStep> = {}\n for (const step of resolved) stepMap[step.guid] = step\n\n // Only the first survey in the declared order gets its choice offers wired.\n // Multiple surveys per flow is legal but unusual; the second+ behave as\n // plain steps. If this becomes a real pattern, wire them all.\n const surveyStep = resolved.find((s) => s.type === 'survey')\n if (surveyStep?.reasons) {\n surveyStep.offersAttached = {}\n for (const reason of surveyStep.reasons) {\n if (!reason.offer) continue\n const offerGuid = `${surveyStep.guid}:offer:${reason.id}`\n stepMap[offerGuid] = {\n guid: offerGuid,\n type: 'offer',\n surveyOffer: true,\n offer: toDecision(reason.offer, defaultOfferCopy),\n // Decline/next from the synthetic offer skips the survey entirely;\n // back returns to the survey so the user can pick a different reason.\n defaultNextStep: surveyStep.defaultNextStep,\n defaultPreviousStep: surveyStep.guid,\n }\n surveyStep.offersAttached[reason.id] = offerGuid\n }\n }\n\n return {\n stepMap,\n firstStepId: resolved[0].guid,\n orderedStepIds: resolved.map((s) => s.guid),\n surveyStepId: surveyStep?.guid,\n }\n}\n\nfunction normalizeStep(\n step: Step,\n index: number,\n defaultOfferCopy: (offer: OfferConfig) => OfferDecision['copy'],\n): ResolvedStep {\n // Prefer the caller-provided guid; otherwise generate a stable slug. Stable\n // ids matter for analytics and React keys.\n const guid = (step as { guid?: string }).guid ?? `step-${index}-${step.type}`\n const base: ResolvedStep = { guid, type: step.type }\n\n switch (step.type) {\n case 'survey': {\n const s = step as SurveyStep\n return {\n ...base,\n title: s.title,\n description: s.description,\n reasons: s.reasons,\n numChoices: s.reasons.length,\n classNames: s.classNames,\n }\n }\n case 'offer': {\n const s = step as OfferStep\n return {\n ...base,\n title: s.title,\n description: s.description,\n // Standalone offers may arrive without `copy` — toDecision fills it\n // in from defaultOfferCopy. Token-mode offers already carry copy\n // from the server, so toDecision passes them through unchanged.\n offer: s.offer ? toDecision(s.offer, defaultOfferCopy) : undefined,\n classNames: s.classNames,\n }\n }\n case 'feedback': {\n const s = step as FeedbackStep\n return {\n ...base,\n title: s.title,\n description: s.description,\n placeholder: s.placeholder,\n required: s.required,\n minLength: s.minLength,\n classNames: s.classNames,\n }\n }\n case 'confirm': {\n const s = step as ConfirmStep\n return {\n ...base,\n title: s.title,\n description: s.description,\n losses: s.losses,\n lossesLabel: s.lossesLabel,\n classNames: s.classNames,\n }\n }\n case 'success': {\n const s = step as SuccessStep\n return {\n ...base,\n savedTitle: s.savedTitle,\n savedDescription: s.savedDescription,\n cancelledTitle: s.cancelledTitle,\n cancelledDescription: s.cancelledDescription,\n classNames: s.classNames,\n }\n }\n default: {\n const s = step as CustomStepConfig\n return {\n ...base,\n title: s.title,\n description: s.description,\n data: s.data,\n }\n }\n }\n}\n\nfunction linkNeighbors(steps: ResolvedStep[]): void {\n for (let i = 0; i < steps.length; i++) {\n if (i < steps.length - 1) steps[i].defaultNextStep = steps[i + 1].guid\n if (i > 0) steps[i].defaultPreviousStep = steps[i - 1].guid\n }\n}\n\nfunction toDecision(offer: OfferConfig, defaultCopy: (o: OfferConfig) => OfferDecision['copy']): OfferDecision {\n return 'copy' in offer ? (offer as OfferDecision) : { ...offer, copy: defaultCopy(offer) }\n}\n","// Translate the SdkConfig response (token mode) into the runtime Step shape\n// the rest of the SDK works with. Token-mode flows arrive with offers fully\n// resolved — coupon ids hydrated to amounts and durations, plan ids inlined\n// as DirectPrice[], so this layer is a pure shape projection.\n\nimport type { SdkConfig, SdkCustomOffer, SdkDiscountOffer, SdkOffer, SdkReason, SdkStep } from './api-types'\nimport type { BuiltInOfferConfig, OfferConfig, OfferCopy, OfferDecision, ReasonConfig, Step } from './types'\nimport { BUILT_IN_OFFER_TYPES } from './utils'\n\nexport interface TransformResult {\n steps: Step[]\n blueprintId: string\n metadata: {\n autoOptimizationKey?: string\n }\n}\n\nexport function transformSdkConfig(config: SdkConfig): TransformResult {\n return {\n steps: config.steps.map(transformStep),\n blueprintId: config.blueprintId,\n metadata: {\n autoOptimizationKey: config.autoOptimizationKey,\n },\n }\n}\n\nfunction transformStep(step: SdkStep): Step {\n switch (step.type) {\n case 'survey':\n return {\n type: 'survey',\n guid: step.guid,\n title: step.title,\n description: step.description,\n reasons: step.reasons.map(transformReason),\n }\n case 'offer':\n return {\n type: 'offer',\n guid: step.guid,\n title: step.title,\n description: step.description,\n offer: transformOfferDecision(step.offer),\n }\n case 'feedback':\n return {\n type: 'feedback',\n guid: step.guid,\n title: step.title,\n description: step.description,\n placeholder: step.placeholder,\n required: step.required,\n minLength: step.minLength,\n }\n case 'confirm':\n return {\n type: 'confirm',\n guid: step.guid,\n title: step.title,\n description: step.description,\n }\n }\n}\n\nfunction transformReason(r: SdkReason): ReasonConfig {\n const out: ReasonConfig = {\n id: r.id,\n label: r.label,\n }\n if (r.freeform) out.freeform = true\n if (r.offer) out.offer = transformOfferConfig(r.offer)\n return out\n}\n\nfunction transformOfferDecision(o: SdkOffer): OfferDecision {\n return { ...transformOfferConfig(o), copy: o.copy, decisionId: o.decisionId }\n}\n\nfunction transformOfferConfig(o: SdkOffer): OfferConfig {\n // Merchant-defined offers: `type` is the registered key and `data` the\n // builder's config. Pass both through untouched so the renderer can match\n // customComponents[type].\n if (!BUILT_IN_OFFER_TYPES.includes(o.type)) {\n const custom = o as unknown as SdkCustomOffer\n return custom.data !== undefined ? { type: custom.type, data: custom.data } : { type: custom.type }\n }\n switch (o.type) {\n case 'discount': {\n const d: SdkDiscountOffer = o\n return {\n type: 'discount',\n couponId: d.couponId,\n percentOff: d.percentOff,\n amountOff: d.amountOff,\n currency: d.currency,\n durationInMonths: d.durationInMonths,\n }\n }\n case 'pause':\n return {\n type: 'pause',\n months: o.months,\n interval: o.interval,\n }\n case 'plan_change':\n return {\n type: 'plan_change',\n plans: o.plans,\n }\n case 'trial_extension':\n return {\n type: 'trial_extension',\n days: o.days,\n }\n case 'redirect':\n return {\n type: 'redirect',\n url: o.url,\n label: o.label ?? '',\n }\n case 'contact':\n return {\n type: 'contact',\n url: o.url,\n label: o.label,\n }\n case 'rebate':\n return {\n type: 'rebate',\n amountMinor: o.amountMinor,\n currency: o.currency,\n amountPaidMinor: o.amountPaidMinor,\n netAfterRebateMinor: o.netAfterRebateMinor,\n paymentMethodBrand: o.paymentMethodBrand,\n paymentMethodLast4: o.paymentMethodLast4,\n }\n }\n}\n\n/**\n * Default offer copy used by step-graph.ts when a local-mode offer doesn't\n * include explicit copy. Token-mode offers come with copy already filled in\n * by the server, so this only fires for local mode.\n */\nexport function defaultOfferCopy(offer: OfferConfig): OfferCopy {\n const o = offer as BuiltInOfferConfig\n switch (o.type) {\n case 'discount':\n return {\n headline: o.percentOff != null ? `How about ${o.percentOff}% off?` : 'Special offer',\n body: discountBody(o),\n cta: 'Accept offer',\n declineCta: 'No thanks',\n }\n case 'pause':\n return {\n headline: 'Take a break instead?',\n body: `Pause your subscription for up to ${o.months} month${o.months === 1 ? '' : 's'}.`,\n cta: 'Pause subscription',\n declineCta: 'No thanks',\n }\n case 'plan_change':\n return {\n headline: 'Switch to a different plan?',\n body: 'We have other plans that might be a better fit.',\n cta: 'Switch plan',\n declineCta: 'No thanks',\n }\n case 'trial_extension':\n return {\n headline: 'Need more time?',\n body: `We'll extend your trial by ${o.days} day${o.days === 1 ? '' : 's'}.`,\n cta: 'Extend trial',\n declineCta: 'No thanks',\n }\n case 'contact':\n return {\n headline: 'Talk to us first?',\n body: 'Our team would love to help resolve any issues.',\n cta: o.label ?? 'Contact support',\n declineCta: 'No thanks',\n }\n case 'redirect':\n return {\n headline: 'Before you go...',\n body: 'Check this out — it might change your mind.',\n cta: o.label,\n declineCta: 'No thanks',\n }\n case 'rebate':\n return {\n headline: 'Get money back',\n body: \"Stay subscribed and we'll refund part of your most recent payment.\",\n cta: 'Accept refund',\n declineCta: 'No thanks',\n }\n default:\n return {\n headline: 'Before you go...',\n body: \"We'd like to offer you something.\",\n cta: 'Accept',\n declineCta: 'No thanks',\n }\n }\n}\n\nfunction discountBody(o: { percentOff?: number; durationInMonths?: number }): string {\n if (o.percentOff == null) return \"We'd like to offer you a discount.\"\n const months = o.durationInMonths ?? 1\n return `We'd like to offer you ${o.percentOff}% off for ${months} month${months === 1 ? '' : 's'}.`\n}\n","import type {\n AcceptedOfferPayload,\n ApiOfferType,\n ApiPauseInterval,\n ApiStepType,\n ChurnkeyApi,\n PresentedOffer,\n SessionPayload,\n StepViewed,\n} from './api'\nimport { AnalyticsClient, directDataToSessionCustomer, toApiMode } from './api'\nimport type { SdkConfig } from './api-types'\nimport { applyMergeFieldsToSteps } from './merge-fields'\nimport { buildMessages, type CancelFlowMessages, type I18nConfig } from './messages'\nimport { buildStepGraph, type ResolvedStep, type StepGraph } from './step-graph'\nimport type { SessionCredentials } from './token'\nimport { defaultOfferCopy, transformSdkConfig } from './transform'\nimport type {\n AcceptedOffer,\n BuiltInOfferConfig,\n BuiltInStepType,\n DirectCustomer,\n DirectSubscription,\n FlowCallbacks,\n FlowConfig,\n FlowState,\n Mode,\n OfferDecision,\n ReasonConfig,\n Step,\n} from './types'\n\ntype OfferCallback = (offer: AcceptedOffer, customer: DirectCustomer | null) => Promise<void> | void\n\nfunction handlerFor(offerType: string, cb: FlowCallbacks): OfferCallback | undefined {\n switch (offerType) {\n case 'discount':\n return cb.handleDiscount\n case 'pause':\n return cb.handlePause\n case 'plan_change':\n return cb.handlePlanChange\n case 'trial_extension':\n return cb.handleTrialExtension\n case 'rebate':\n return cb.handleRebate\n default:\n return undefined\n }\n}\n\nfunction listenerFor(offerType: string, cb: FlowCallbacks): OfferCallback | undefined {\n switch (offerType) {\n case 'discount':\n return cb.onDiscount\n case 'pause':\n return cb.onPause\n case 'plan_change':\n return cb.onPlanChange\n case 'trial_extension':\n return cb.onTrialExtension\n case 'rebate':\n return cb.onRebate\n default:\n return undefined\n }\n}\n\n// Listener errors are swallowed — they're side effects, not part of the\n// success path, and shouldn't flip the flow into an error state.\nfunction runListener(listener: OfferCallback, offer: AcceptedOffer, customer: DirectCustomer | null): Promise<void> {\n return Promise.resolve(listener(offer, customer)).catch((e) => {\n console.error('Error in offer listener:', e)\n })\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n if (!value || typeof value !== 'object') return false\n const proto = Object.getPrototypeOf(value)\n return proto === null || proto === Object.prototype\n}\n\n// --- Wire translation ---\n//\n// SDK types use lowercase identifiers; the API expects uppercase enums.\n// Both maps are typed as exhaustive Records so adding a new built-in step\n// or offer type fails the build until its wire mapping is set.\nconst STEP_TYPE_API_MAP: Record<Exclude<BuiltInStepType, 'success'>, Exclude<ApiStepType, 'CUSTOM'>> = {\n survey: 'SURVEY',\n offer: 'OFFER',\n feedback: 'FREEFORM',\n confirm: 'CONFIRM',\n}\n\nconst OFFER_TYPE_API_MAP: Record<BuiltInOfferConfig['type'], Exclude<ApiOfferType, 'CUSTOM'>> = {\n discount: 'DISCOUNT',\n pause: 'PAUSE',\n plan_change: 'PLAN_CHANGE',\n trial_extension: 'TRIAL_EXTENSION',\n contact: 'CONTACT',\n redirect: 'REDIRECT',\n rebate: 'REBATE',\n}\n\n// 'success' isn't a stepsViewed entry — the session's outcome/canceled/\n// acceptedOffer already captures the terminal state, and recording it\n// separately would double-count the funnel's last hop.\nfunction toApiStepType(step: string): { stepType: ApiStepType; customStepType?: string } | null {\n if (step === 'success') return null\n const builtIn = STEP_TYPE_API_MAP[step as Exclude<BuiltInStepType, 'success'>]\n if (builtIn) return { stepType: builtIn }\n return { stepType: 'CUSTOM', customStepType: step }\n}\n\nfunction toApiOfferType(type: string): { offerType: ApiOfferType; customOfferType?: string } {\n const builtIn = OFFER_TYPE_API_MAP[type as BuiltInOfferConfig['type']]\n if (builtIn) return { offerType: builtIn }\n return { offerType: 'CUSTOM', customOfferType: type }\n}\n\nfunction toApiPauseInterval(interval: 'month' | 'week' | undefined): ApiPauseInterval {\n return interval === 'week' ? 'WEEK' : 'MONTH'\n}\n\n// --- Offer shape builders ---\n//\n// Sessions record offers two ways: presentedOffers keeps the nested config\n// shape (discountConfig, pauseConfig, …); acceptedOffer flattens the fields.\n// Two builders, one source of truth.\n\nfunction toPresentedOfferConfig(rec: OfferDecision): Partial<PresentedOffer> {\n const base = toApiOfferType(rec.type)\n if (base.offerType === 'CUSTOM') return base\n const o = rec as BuiltInOfferConfig\n switch (o.type) {\n case 'discount':\n return {\n ...base,\n discountConfig: { couponId: o.couponId, customAmount: o.percentOff },\n }\n case 'pause':\n return {\n ...base,\n pauseConfig: {\n maxPauseLength: o.months,\n pauseInterval: toApiPauseInterval(o.interval),\n },\n }\n case 'plan_change':\n return { ...base, planChangeConfig: {} }\n case 'trial_extension':\n return { ...base, trialExtensionConfig: { trialExtensionDays: o.days } }\n case 'redirect':\n return {\n ...base,\n redirectConfig: { redirectUrl: o.url, redirectLabel: o.label },\n }\n case 'contact':\n return { ...base, contactConfig: {} }\n default:\n return base\n }\n}\n\nfunction toAcceptedOfferPayload(rec: OfferDecision, result?: Record<string, unknown>): AcceptedOfferPayload {\n const base: AcceptedOfferPayload = { guid: rec.decisionId, ...toApiOfferType(rec.type) }\n if (base.offerType === 'CUSTOM') {\n return result ? { ...base, customOfferResult: result } : base\n }\n const o = rec as BuiltInOfferConfig\n switch (o.type) {\n case 'discount':\n return {\n ...base,\n couponId: o.couponId,\n couponAmount: o.percentOff,\n couponType: 'PERCENT',\n couponDuration: o.durationInMonths,\n }\n case 'pause':\n return {\n ...base,\n pauseDuration: o.months,\n pauseInterval: toApiPauseInterval(o.interval),\n }\n case 'plan_change':\n return {\n ...base,\n newPlanId: o.plans?.[0]?.id,\n newPlanPrice: o.plans?.[0]?.amount.value,\n }\n case 'trial_extension':\n return { ...base, trialExtensionDays: o.days }\n case 'redirect':\n return { ...base, redirectUrl: o.url }\n case 'rebate':\n return { ...base, rebateAmount: o.amountMinor }\n default:\n return base\n }\n}\n\n// --- Machine ---\n\nexport class CancelFlowMachine {\n private state: FlowState\n private cachedSnapshot: FlowState\n private callbacks: FlowCallbacks\n private graph: StepGraph = { stepMap: {}, firstStepId: '', orderedStepIds: [] }\n private listeners: Set<() => void> = new Set()\n\n private apiClient: ChurnkeyApi | null = null\n private analyticsClient: AnalyticsClient | null = null\n private directCustomer: DirectCustomer | null = null\n private directSubscriptions: DirectSubscription[] | null = null\n private customerAttributes: Record<string, unknown> | null = null\n private creds: SessionCredentials | null = null\n private config: SdkConfig | null = null\n private blueprintId: string | null = null\n private localSteps: Step[] | null = null\n private stepsViewed: StepViewed[] = []\n private presentedOffers: PresentedOffer[] = []\n private customStepResults: Record<string, unknown> = {}\n private configMode: Mode = 'live'\n private i18nConfig: I18nConfig | undefined\n private localCancelAtPeriodEnd: boolean | null = null\n private resolvedMessages: CancelFlowMessages\n private stepEnteredAt: number = Date.now()\n private aborted = false\n // Visited-step stack. `back` pops this so it lands on the actually-seen\n // previous step (including synthetic offers a survey choice spawned),\n // not the previous step in declared graph order.\n private history: string[] = []\n\n constructor(config: FlowConfig) {\n // FlowConfig extends FlowCallbacks; storing the whole config covers\n // every callback by name without a separate copy.\n this.callbacks = config\n this.i18nConfig = config.i18n\n this.resolvedMessages = buildMessages(config.i18n)\n // Local mode only — in token mode the server-resolved value is\n // authoritative, and when the server omits it the timing must stay\n // unknown rather than silently adopting the local claim. `null` copy\n // reads as period-end, matching the token cancel action's fallback, so\n // display and execution stay consistent either way.\n if (!config.session && typeof config.cancelAtPeriodEnd === 'boolean') {\n this.localCancelAtPeriodEnd = config.cancelAtPeriodEnd\n }\n if (config.mode) this.configMode = config.mode\n if (config.customerAttributes) this.customerAttributes = config.customerAttributes\n if (config.appId && config.customer) {\n this.analyticsClient = new AnalyticsClient(config.appId, config.apiBaseUrl)\n this.directCustomer = config.customer\n this.directSubscriptions = config.subscriptions ?? null\n }\n\n // Token mode defers graph construction until initializeFromConfig runs\n // with the server-supplied steps; stash any locally-declared steps for\n // merging then.\n if (config.session) {\n if (config.steps) this.localSteps = config.steps\n } else if (config.steps) {\n const merged = applyMergeFieldsToSteps(config.steps, this.directCustomer, this.customerAttributes)\n this.graph = buildStepGraph(merged, defaultOfferCopy)\n }\n\n // Seed state from local props for open-source and analytics modes. Token\n // mode overwrites both fields once initializeFromConfig settles, so these\n // values only matter for the pre-fetch render.\n this.state = this.buildInitialState(this.directCustomer, this.directSubscriptions ?? [])\n this.cachedSnapshot = { ...this.state }\n\n // Defer entry tracking in token mode — firing trackStepEnter before the\n // graph is built would record a stale (empty) guid.\n const first = this.firstStep()\n if (!config.session && first) this.trackStepEnter(first)\n }\n\n // Public methods are arrow-bound so consumers can pass them directly\n // (`<button onClick={flow.next}>`) and so useSyncExternalStore sees\n // stable references between renders.\n\n subscribe = (listener: () => void): (() => void) => {\n this.listeners.add(listener)\n return () => {\n this.listeners.delete(listener)\n }\n }\n\n getSnapshot = (): FlowState => {\n return this.cachedSnapshot\n }\n\n get reasons(): ReasonConfig[] {\n return this.surveyStep()?.reasons ?? []\n }\n\n get currentStep(): ResolvedStep | undefined {\n return this.graph.stepMap[this.state.currentStepId]\n }\n\n /** The offer on the current step, or null. Always derived — no separate slot to drift. */\n get currentOffer(): OfferDecision | null {\n return this.currentStep?.offer ?? null\n }\n\n /**\n * The fully resolved message catalog (defaults layered with the config's\n * `i18n` overrides). Timing-aware values are still unresolved — pick a\n * variant with `selectTiming(value, state.cancelAtPeriodEnd)`.\n */\n get messages(): CancelFlowMessages {\n return this.resolvedMessages\n }\n\n /** Whether `back()` would move anywhere — false on the first step and on success. */\n get canGoBack(): boolean {\n if (this.state.step === 'success') return false\n return this.history.length > 0 || Boolean(this.currentStep?.defaultPreviousStep)\n }\n\n /**\n * First step of a given type. Fine for the common \"one step per type\" case;\n * flows with multiple of a type should key on currentStepId instead.\n */\n getStepConfig(stepType: string): ResolvedStep | undefined {\n return Object.values(this.graph.stepMap).find((s) => s.type === stepType)\n }\n\n /** Progress indicator index. Synthetic offers share their survey's slot. */\n get stepIndex(): number {\n const current = this.currentStep\n if (!current) return 0\n if (current.surveyOffer) {\n const surveyId = current.defaultPreviousStep\n return surveyId ? this.graph.orderedStepIds.indexOf(surveyId) : 0\n }\n return Math.max(0, this.graph.orderedStepIds.indexOf(current.guid))\n }\n\n get totalSteps(): number {\n return this.graph.orderedStepIds.length\n }\n\n selectReason = (id: string): void => {\n if (!this.reasons.find((r) => r.id === id)) return\n // Clear follow-up text on reason change so it doesn't carry across selections.\n this.setState({ selectedReason: id, followupResponse: '' })\n }\n\n setFollowupResponse = (text: string): void => {\n this.setState({ followupResponse: text })\n }\n\n next = (result?: Record<string, unknown>): void => {\n // `onClick={next}` would otherwise pass a SyntheticEvent through as result\n // — has circular refs, breaks JSON.stringify. Only accept plain objects.\n if (isPlainObject(result)) {\n this.customStepResults[this.state.step] = result\n }\n const nextId = this.projectedNextStepId()\n if (!nextId) return\n this.transitionTo(nextId, { recordHistory: true })\n }\n\n back = (): void => {\n const popped = this.history.pop()\n if (popped) {\n this.transitionTo(popped)\n return\n }\n // History is empty when the consumer triggered back without a prior\n // forward navigation (e.g. starting state). Fall back to declared order.\n const prevId = this.currentStep?.defaultPreviousStep\n if (prevId) this.transitionTo(prevId)\n }\n\n accept = async (result?: Record<string, unknown>): Promise<void> => {\n // Capture before any state transition — the 'success' transition may\n // move currentStepId off the offer step, depending on whether a success\n // step is declared in the graph.\n const offer = this.currentOffer\n if (!offer) return\n const safeResult = isPlainObject(result) ? result : undefined\n this.setState({ isProcessing: true, error: null })\n try {\n const acceptedOffer = this.buildAcceptedOffer(offer, safeResult)\n const customer = this.state.customer\n\n // Handler wins over the server-side action. With no handler, token mode\n // hits the server endpoint and local mode is a no-op (relying on\n // onAccept's catch-all if anything).\n const handler = handlerFor(offer.type, this.callbacks)\n if (handler) {\n await handler(acceptedOffer, customer)\n } else if (this.isTokenMode()) {\n await this.executeTokenAction(acceptedOffer, offer.decisionId)\n }\n\n // Listeners fire after the action succeeded, regardless of who ran it.\n // Per-type listener first, then the catch-all onAccept.\n const listener = listenerFor(offer.type, this.callbacks)\n if (listener) await runListener(listener, acceptedOffer, customer)\n await this.callbacks.onAccept?.(acceptedOffer, customer)\n\n this.markCurrentOfferAccepted()\n this.enterSuccessStep('saved', acceptedOffer)\n this.recordOutcome('saved', offer, safeResult)\n } catch (error) {\n this.setState({ isProcessing: false, error: error as Error })\n }\n }\n\n decline = (): void => {\n this.markCurrentOfferDeclined()\n const nextId = this.currentStep?.defaultNextStep\n if (nextId) this.transitionTo(nextId, { recordHistory: true })\n }\n\n setFeedback = (text: string): void => {\n this.setState({ feedback: text })\n }\n\n cancel = async (): Promise<void> => {\n this.setState({ isProcessing: true, error: null })\n try {\n const customer = this.state.customer\n\n if (this.callbacks.handleCancel) {\n await this.callbacks.handleCancel(customer)\n } else if (this.isTokenMode()) {\n await this.apiClient!.cancelSubscription(\n this.config?.settings.cancelAtPeriodEnd ?? true,\n this.blueprintId ?? undefined,\n )\n }\n\n await this.callbacks.onCancel?.(customer)\n this.enterSuccessStep('cancelled')\n this.recordOutcome('cancelled')\n } catch (error) {\n this.setState({ isProcessing: false, error: error as Error })\n }\n }\n\n close = (): void => {\n if (this.state.outcome === null && !this.aborted) {\n this.aborted = true\n this.recordAbort()\n }\n this.callbacks.onClose?.()\n }\n\n destroy(): void {\n this.listeners.clear()\n }\n\n // Callbacks are wired through the constructor; this only takes the\n // server-supplied config so callers can't accidentally clobber them.\n initializeFromConfig(config: SdkConfig, apiClient: ChurnkeyApi, creds: SessionCredentials): void {\n this.apiClient = apiClient\n this.creds = creds\n this.config = config\n\n // Re-resolve with the org's dashboard-configured overrides, which ride\n // along on the config payload. Developer i18n.messages still win.\n if (config.translations) {\n this.resolvedMessages = buildMessages(this.i18nConfig, config.translations)\n }\n\n const result = transformSdkConfig(config)\n this.blueprintId = result.blueprintId\n\n const merged = this.localSteps ? mergeLocalSteps(result.steps, this.localSteps) : result.steps\n const steps = applyMergeFieldsToSteps(merged, config.customer ?? null, this.customerAttributes)\n this.graph = buildStepGraph(steps, defaultOfferCopy)\n\n this.state = this.buildInitialState(config.customer ?? null, config.subscriptions ?? [])\n this.cachedSnapshot = { ...this.state }\n const first = this.firstStep()\n if (first) this.trackStepEnter(first)\n this.notify()\n }\n\n // --- Internal helpers ---\n\n private isTokenMode(): boolean {\n return this.apiClient != null\n }\n\n private firstStep(): ResolvedStep | undefined {\n return this.graph.stepMap[this.graph.firstStepId]\n }\n\n private surveyStep(): ResolvedStep | undefined {\n return this.graph.surveyStepId ? this.graph.stepMap[this.graph.surveyStepId] : undefined\n }\n\n private buildInitialState(customer: DirectCustomer | null, subscriptions: DirectSubscription[]): FlowState {\n const first = this.firstStep()\n return {\n step: first?.type ?? 'survey',\n currentStepId: this.graph.firstStepId,\n selectedReason: null,\n followupResponse: '',\n feedback: '',\n outcome: null,\n isProcessing: false,\n error: null,\n customer,\n subscriptions,\n cancelAtPeriodEnd: this.config?.settings.cancelAtPeriodEnd ?? this.localCancelAtPeriodEnd,\n acceptedOffer: null,\n }\n }\n\n // On a survey step with a selected reason that has an attached offer,\n // jump to that offer's synthetic step; otherwise follow the default\n // forward pointer.\n private projectedNextStepId(): string | undefined {\n const current = this.currentStep\n if (!current) return undefined\n if (current.offersAttached && this.state.selectedReason) {\n const override = current.offersAttached[this.state.selectedReason]\n if (override) return override\n }\n return current.defaultNextStep\n }\n\n // Single entry point for step changes. All navigation flows through here so\n // view-timing and presentation tracking stay in one place. Forward callers\n // pass recordHistory; `back` omits it so popping isn't reversed.\n private transitionTo(stepId: string, opts: { recordHistory?: boolean } = {}): void {\n const step = this.graph.stepMap[stepId]\n if (!step) return\n if (opts.recordHistory && this.state.currentStepId && this.state.currentStepId !== stepId) {\n this.history.push(this.state.currentStepId)\n }\n this.setState({ step: step.type, currentStepId: stepId })\n }\n\n private setState(partial: Partial<FlowState>): void {\n const prevStep = this.state.step\n this.state = { ...this.state, ...partial }\n this.cachedSnapshot = { ...this.state }\n if (partial.step && partial.step !== prevStep) {\n this.finalizeStepView(prevStep)\n // enterSuccessStep can set state.step='success' without moving currentStepId\n // (when no success step is declared). Only feed the new graph node into\n // trackStepEnter when its type actually matches — otherwise the prior\n // step would be re-recorded.\n const step = this.graph.stepMap[this.state.currentStepId]\n if (step?.type === partial.step) this.trackStepEnter(step)\n else this.trackStepView(partial.step)\n this.callbacks.onStepChange?.(partial.step, prevStep)\n }\n this.notify()\n }\n\n private trackStepEnter(step: ResolvedStep): void {\n this.trackStepView(step.type, step.guid, step.numChoices)\n if (step.type === 'offer') this.recordOfferPresented()\n }\n\n private recordOfferPresented(): void {\n const offer = this.currentOffer\n if (!offer) return\n this.presentedOffers.push({\n ...toPresentedOfferConfig(offer),\n guid: offer.decisionId,\n accepted: false,\n presentedAt: new Date().toISOString(),\n })\n }\n\n private markCurrentOfferAccepted(): void {\n const last = this.presentedOffers[this.presentedOffers.length - 1]\n if (!last || last.acceptedAt || last.declinedAt) return\n last.accepted = true\n last.acceptedAt = new Date().toISOString()\n }\n\n private markCurrentOfferDeclined(): void {\n const last = this.presentedOffers[this.presentedOffers.length - 1]\n if (!last || last.acceptedAt || last.declinedAt) return\n last.declinedAt = new Date().toISOString()\n }\n\n private notify(): void {\n for (const listener of this.listeners) {\n listener()\n }\n }\n\n private async executeTokenAction(offer: AcceptedOffer, decisionId?: string): Promise<void> {\n if (!this.apiClient) return\n\n // Only built-in offer types have a server action; custom types route\n // entirely through the consumer's handler/onAccept.\n const o = offer as BuiltInOfferConfig\n switch (o.type) {\n case 'discount':\n if (o.couponId) {\n await this.apiClient.applyDiscount(o.couponId, this.blueprintId ?? undefined)\n }\n break\n case 'pause':\n await this.apiClient.pause({ duration: o.months, interval: o.interval ?? 'month' })\n break\n case 'plan_change':\n await this.apiClient.changePlan(o.plans[0]?.id)\n break\n case 'trial_extension':\n await this.apiClient.extendTrial(o.days, this.blueprintId ?? undefined)\n break\n case 'rebate':\n await this.apiClient.applyRebate(this.blueprintId ?? undefined, decisionId)\n break\n }\n }\n\n private trackStepView(stepType: string, guid?: string, numChoices?: number): void {\n this.stepEnteredAt = Date.now()\n const mapped = toApiStepType(stepType)\n if (!mapped) return\n\n const entry: StepViewed = {\n ...mapped,\n start: new Date().toISOString(),\n }\n if (guid) entry.guid = guid\n if (numChoices != null) entry.numChoices = numChoices\n\n this.stepsViewed.push(entry)\n }\n\n private finalizeStepView(step: string): void {\n const mapped = toApiStepType(step)\n if (!mapped) return\n // Match the most recent entry for this step. Custom steps share\n // stepType='CUSTOM', so disambiguate on customStepType.\n const entry = [...this.stepsViewed]\n .reverse()\n .find((s) => s.stepType === mapped.stepType && s.customStepType === mapped.customStepType)\n if (entry) {\n entry.end = new Date().toISOString()\n entry.duration = Date.now() - this.stepEnteredAt\n }\n }\n\n // Offer passed in so accept() can capture it before enterSuccessStep\n // potentially moves currentStepId off the offer step. copy and decisionId\n // are SDK-internal — strip them from the consumer-facing payload.\n private buildAcceptedOffer(offer: OfferDecision, result?: Record<string, unknown>): AcceptedOffer {\n const { copy: _copy, decisionId: _decisionId, ...offerConfig } = offer\n const accepted: AcceptedOffer = offerConfig\n if (this.state.selectedReason) accepted.reasonId = this.state.selectedReason\n if (result) accepted.result = result\n return accepted\n }\n\n // Terminal transition. Prefer moving currentStepId to a declared success\n // step so the developer's savedTitle / classNames / custom component\n // applies; otherwise stay put and the renderer's defaults cover it.\n // The accepted offer is snapshotted into state here because currentOffer\n // derives from currentStepId, which a declared success step moves off the\n // offer — per-offer success copy needs a stable source.\n private enterSuccessStep(outcome: 'saved' | 'cancelled', acceptedOffer?: AcceptedOffer): void {\n const success = this.getStepConfig('success')\n const partial: Partial<FlowState> = {\n step: 'success',\n outcome,\n isProcessing: false,\n acceptedOffer: acceptedOffer ?? null,\n }\n if (success) partial.currentStepId = success.guid\n this.setState(partial)\n }\n\n private resolveSessionCustomer(): SessionPayload['customer'] {\n const direct = this.directCustomer\n ? directDataToSessionCustomer(this.directCustomer, this.directSubscriptions ?? undefined)\n : undefined\n // The consumer's attribute layer wins key conflicts with customer.metadata,\n // matching merge-field precedence and the embed's session shape.\n const customAttributes = this.customerAttributes\n ? { ...direct?.customAttributes, ...this.customerAttributes }\n : direct?.customAttributes\n // Token identifies the customer authoritatively; direct data fills in\n // extras (email, plan, metadata) but never overrides id/subscriptionId.\n if (this.creds) {\n return { ...direct, customAttributes, id: this.creds.customerId, subscriptionId: this.creds.subscriptionId }\n }\n return direct ? { ...direct, customAttributes } : undefined\n }\n\n private buildBasePayload(): SessionPayload {\n const selectedReason = this.reasons.find((r) => r.id === this.state.selectedReason)\n // surveyChoiceValue is always the static label so dashboard groupings\n // by reason stay stable. Typed text from `freeform: true` reasons\n // travels separately on followupResponse, mirroring the embed payload.\n const followupResponse =\n selectedReason?.freeform && this.state.followupResponse ? this.state.followupResponse : undefined\n const payload: SessionPayload = {\n blueprintId: this.blueprintId ?? undefined,\n customer: this.resolveSessionCustomer(),\n canceled: false,\n surveyChoiceId: this.state.selectedReason ?? undefined,\n surveyChoiceValue: selectedReason?.label,\n followupResponse,\n feedback: this.state.feedback || undefined,\n presentedOffers: this.presentedOffers,\n stepsViewed: this.stepsViewed,\n customStepResults: Object.keys(this.customStepResults).length > 0 ? this.customStepResults : undefined,\n // Token's signed mode wins — the client can't override it.\n mode: toApiMode(this.creds?.mode ?? this.configMode),\n provider: this.isTokenMode() ? undefined : 'sdk-react',\n embedVersion: 'sdk-react',\n }\n\n // Token-mode session-record fields. Required by downstream analytics\n // and compliance reporting on the dashboard.\n if (this.config) {\n const surveyStep = this.config.steps.find((s) => s.type === 'survey')\n payload.surveyId = surveyStep?.guid\n payload.clickToCancelEnabled = this.config.settings.clickToCancelEnabled\n payload.strictFTCComplianceEnabled = this.config.settings.strictFTCComplianceEnabled\n payload.usedClickToCancel = false\n payload.autoOptimizationUsed = !!this.config.autoOptimizationKey\n payload.autoOptimizationKey = this.config.autoOptimizationKey\n payload.discountCooldown = this.config.settings.discountCooldown\n payload.pauseCooldown = this.config.settings.pauseCooldown\n payload.discountCooldownApplied = false\n payload.pauseCooldownApplied = false\n }\n\n return payload\n }\n\n private recordAbort(): void {\n const client = this.apiClient ?? this.analyticsClient\n if (!client) return\n this.finalizeStepView(this.state.step)\n client.createSession({ ...this.buildBasePayload(), aborted: true }).catch(() => {})\n }\n\n // acceptedOffer is a parameter so callers capture it before enterSuccessStep\n // moves currentStepId off the offer step. setState already finalized the\n // step view on the way to 'success', so no extra finalize call here.\n private recordOutcome(\n outcome: 'saved' | 'cancelled',\n acceptedOffer?: OfferDecision,\n result?: Record<string, unknown>,\n ): void {\n const client = this.apiClient ?? this.analyticsClient\n if (!client) return\n\n const payload = this.buildBasePayload()\n payload.canceled = outcome === 'cancelled'\n\n if (outcome === 'saved' && acceptedOffer) {\n payload.acceptedOffer = toAcceptedOfferPayload(acceptedOffer, result)\n }\n\n client.createSession(payload).catch(() => {})\n }\n}\n\n// Local steps override server steps by type. Unmatched local steps append\n// at the end. Server order is preserved so the dashboard stays in charge of\n// flow shape while developers can swap in their own copy / custom steps.\nfunction mergeLocalSteps(serverSteps: Step[], localSteps: Step[]): Step[] {\n const localByType = new Map(localSteps.map((s) => [s.type, s]))\n const merged = serverSteps.map((serverStep) => {\n const local = localByType.get(serverStep.type)\n if (!local) return serverStep\n localByType.delete(serverStep.type)\n return { ...serverStep, ...local } as Step\n })\n for (const [, step] of localByType) merged.push(step)\n return merged\n}\n","import type { ComponentType, ReactElement, ReactNode } from 'react'\nimport type { CancelFlowMessages, I18nConfig } from './messages'\n\n// ─── Direct shape — billing data passed in and out of the SDK ─────────────\n//\n// Used both for consumer-supplied props (customer, subscriptions) and for\n// data the SDK receives in token mode, so there's no translation layer in\n// between. Provider-agnostic and intentionally minimal — only the fields the\n// cancel flow needs to render and record sessions.\n\nexport interface DirectAddress {\n line1?: string\n line2?: string\n city?: string\n state?: string\n postalCode?: string\n /** ISO 3166-1 alpha-2 */\n country?: string\n}\n\nexport interface DirectCustomer {\n id: string\n email?: string\n name?: string\n lastName?: string\n phone?: string\n /** ISO 4217 */\n currency?: string\n addresses?: DirectAddress[]\n metadata?: Record<string, unknown>\n}\n\nexport interface DirectPrice {\n id: string\n type?: 'standalone' | 'product'\n active?: boolean\n productId?: string\n name?: string\n description?: string\n duration?: {\n interval: 'day' | 'week' | 'month' | 'year'\n intervalCount?: number\n }\n amount: {\n model?: 'fixed' | 'tiered'\n /** Smallest currency unit (cents for USD). */\n value: number\n currency?: string\n }\n metadata?: Record<string, unknown>\n}\n\nexport interface DirectCoupon {\n id?: string\n name?: string\n percentOff?: number\n /** Smallest currency unit (cents for USD). */\n amountOff?: number\n currency?: string\n duration?: 'once' | 'repeating' | 'forever'\n durationInMonths?: number\n metadata?: Record<string, unknown>\n}\n\nexport type SubscriptionStatus =\n | { name: 'active'; currentPeriod: { start: Date | string; end: Date | string } }\n | {\n name: 'trial'\n trial: { start: Date | string; end: Date | string }\n currentPeriod?: { start: Date | string; end: Date | string }\n }\n | {\n name: 'paused'\n pause: { start: Date | string; end?: Date | string }\n currentPeriod?: { start: Date | string; end: Date | string }\n }\n | { name: 'canceled'; canceledAt: Date | string }\n | { name: 'unpaid'; currentPeriod?: { start: Date | string; end: Date | string } }\n | { name: 'future'; currentPeriod?: { start: Date | string; end: Date | string } }\n\nexport interface DirectSubscriptionItem {\n id?: string\n price: DirectPrice\n quantity?: number\n}\n\nexport interface DirectSubscription {\n id: string\n customerId?: string\n start: Date | string\n status: SubscriptionStatus\n items: DirectSubscriptionItem[]\n duration?: {\n interval: 'day' | 'week' | 'month' | 'year'\n intervalCount?: number\n }\n end?: Date | string\n discounts?: Array<{\n id?: string\n coupon?: DirectCoupon\n start?: Date | string\n end?: Date | string\n }>\n metadata?: Record<string, unknown>\n}\n\n// ─── Offers ──────────────────────────────────────────────────────────────────\n//\n// Local-mode developers write the same offer shape the SDK receives in\n// token mode, so behavior is consistent across modes.\n\nexport interface DiscountOffer {\n type: 'discount'\n couponId?: string\n percentOff?: number\n /** Smallest currency unit (cents for USD). */\n amountOff?: number\n currency?: string\n durationInMonths?: number\n}\n\nexport interface PauseOffer {\n type: 'pause'\n months: number\n interval?: 'month' | 'week'\n}\n\nexport interface PlanChangeOffer {\n type: 'plan_change'\n plans: PlanOption[]\n}\n\n/**\n * Plan option in a `plan_change` offer — `DirectPrice` plus optional\n * cancel-flow merchandising fields. Marketing fields are presentation-only\n * and live on `PlanOption` rather than `DirectPrice` so `Direct` stays a\n * clean billing-data shape reusable outside the cancel-flow context.\n */\nexport interface PlanOption extends DirectPrice {\n /** Short marketing line (e.g. \"Most popular\"). */\n tagline?: string\n /** Bullet list of plan features shown on the card. */\n features?: string[]\n /** Pre-formatted \"before\" price rendered struck-through (e.g. \"$49/mo\"). */\n msrp?: string\n}\n\nexport interface TrialExtensionOffer {\n type: 'trial_extension'\n days: number\n}\n\nexport interface ContactOffer {\n type: 'contact'\n url?: string\n label?: string\n}\n\nexport interface RedirectOffer {\n type: 'redirect'\n url: string\n label: string\n}\n\nexport interface RebateOffer {\n type: 'rebate'\n /** The rebate amount (pre-tax), smallest currency unit. The card is refunded this plus any tax charged on it. */\n amountMinor: number\n currency: string\n /** Gross paid on the target invoice. Server-resolved in token mode. */\n amountPaidMinor?: number\n /** amountPaidMinor minus the full refund (the rebate plus its tax). Server-resolved in token mode. */\n netAfterRebateMinor?: number\n paymentMethodBrand?: string\n paymentMethodLast4?: string\n}\n\nexport interface CustomOfferConfig {\n type: string\n data?: Record<string, unknown>\n}\n\nexport type BuiltInOfferConfig =\n | DiscountOffer\n | PauseOffer\n | PlanChangeOffer\n | TrialExtensionOffer\n | ContactOffer\n | RedirectOffer\n | RebateOffer\nexport type OfferConfig = BuiltInOfferConfig | CustomOfferConfig\n\nexport type OfferDecision = OfferConfig & { copy: OfferCopy; decisionId?: string }\n\nexport interface OfferCopy {\n headline: string\n /**\n * May contain HTML when the flow was authored in the Churnkey dashboard\n * (the description editor is rich text). Render with the exported\n * `RichText` component — the same renderer the built-in steps use — rather\n * than as a text node, or the markup shows escaped. Pass `as=\"div\"` (built-in\n * steps do) so block content like an embedded video iframe isn't hoisted out\n * of the default `<p>` wrapper.\n */\n body: string\n cta: string\n declineCta: string\n}\n\nexport type AcceptedOffer = OfferConfig & {\n /** Survey reason that routed to this offer. Absent when the offer was\n * declared as a standalone `OfferStep`. */\n reasonId?: string\n /** Payload from custom offers — whatever your component passed to\n * `onAccept(result)`. Built-in offer types do not populate this. */\n result?: Record<string, unknown>\n}\n\n// ─── Reasons ─────────────────────────────────────────────────────────────────\n\nexport interface ReasonConfig {\n id: string\n label: string\n /**\n * When true, picking this reason reveals a text input below the reason list.\n * The typed text lands on the session as `followupResponse`. `surveyChoiceId`\n * still carries the reason's `id` and `surveyChoiceValue` still carries the\n * static `label`, so analytics groupings stay stable.\n */\n freeform?: boolean\n offer?: OfferConfig\n}\n\n// ─── Steps ───────────────────────────────────────────────────────────────────\n//\n// `guid` is optional. Set it for stable identity (React keys, test assertions);\n// otherwise the SDK auto-generates one at graph-build time. In token mode,\n// server-supplied steps already carry guids for analytics correlation.\n\nexport interface SurveyStep {\n type: 'survey'\n guid?: string\n title?: string\n description?: string\n reasons: ReasonConfig[]\n classNames?: SurveyClassNames\n}\n\nexport interface OfferStep {\n type: 'offer'\n guid?: string\n title?: string\n description?: string\n /**\n * Offer attached to this step. Set this to declare a standalone offer\n * step (one that isn't routed from a survey reason). `copy` is optional —\n * the SDK synthesizes default copy from the offer config when none is\n * provided, the same way it does for survey-attached offers.\n */\n offer?: OfferConfig | OfferDecision\n classNames?: OfferClassNames\n}\n\nexport interface FeedbackStep {\n type: 'feedback'\n guid?: string\n title?: string\n description?: string\n placeholder?: string\n required?: boolean\n minLength?: number\n classNames?: FeedbackClassNames\n}\n\nexport interface ConfirmStep {\n type: 'confirm'\n guid?: string\n title?: string\n description?: string\n /** Optional bullet list of what the customer is giving up. Rendered between the description and the period-end notice. */\n losses?: string[]\n /** Heading above the loss list. Defaults to \"You'll lose access to:\". */\n lossesLabel?: string\n confirmLabel?: string\n goBackLabel?: string\n classNames?: ConfirmClassNames\n}\n\nexport interface SuccessStep {\n type: 'success'\n guid?: string\n savedTitle?: string\n savedDescription?: string\n cancelledTitle?: string\n cancelledDescription?: string\n classNames?: SuccessClassNames\n}\n\nexport interface CustomStepConfig {\n type: string\n guid?: string\n title?: string\n description?: string\n data?: Record<string, unknown>\n}\n\nexport type BuiltInStep = SurveyStep | OfferStep | FeedbackStep | ConfirmStep | SuccessStep\nexport type Step = BuiltInStep | CustomStepConfig\n\nexport type BuiltInStepType = 'survey' | 'offer' | 'feedback' | 'confirm' | 'success'\n\n// ─── Per-step classNames ─────────────────────────────────────────────────────\n\nexport interface SurveyClassNames {\n root?: string\n title?: string\n description?: string\n reasonList?: string\n reasonButton?: string\n reasonButtonSelected?: string\n reasonLabel?: string\n followupInput?: string\n continueButton?: string\n}\n\nexport interface OfferClassNames {\n root?: string\n title?: string\n description?: string\n card?: string\n headline?: string\n body?: string\n acceptButton?: string\n declineButton?: string\n discountBadge?: string\n priceComparison?: string\n pauseSlider?: string\n planGrid?: string\n planCard?: string\n planCardSelected?: string\n}\n\nexport interface FeedbackClassNames {\n root?: string\n title?: string\n description?: string\n textarea?: string\n characterCount?: string\n submitButton?: string\n}\n\nexport interface ConfirmClassNames {\n root?: string\n title?: string\n description?: string\n lossList?: string\n lossLabel?: string\n lossItem?: string\n lossBullet?: string\n confirmButton?: string\n goBackButton?: string\n periodEndNotice?: string\n}\n\nexport interface SuccessClassNames {\n root?: string\n icon?: string\n title?: string\n description?: string\n closeButton?: string\n}\n\n// ─── Structural classNames ───────────────────────────────────────────────────\n\nexport interface StructuralClassNames {\n overlay?: string\n modal?: string\n closeButton?: string\n backButton?: string\n}\n\n// ─── Appearance ──────────────────────────────────────────────────────────────\n\n/**\n * Typed surface for `appearance.variables`. Every key maps to a `--ck-*`\n * CSS custom property. Consumers who need a token not in this list can\n * still set the underlying CSS variable directly — these are the ones\n * exposed through the typed JS API.\n */\nexport interface AppearanceVariables {\n // Surfaces\n colorBackground: string\n colorSurface: string\n colorSurfaceMuted: string\n\n // Borders\n colorBorder: string\n colorBorderStrong: string\n\n // Text\n colorText: string\n colorTextSecondary: string\n colorTextMuted: string\n\n // Primary\n colorPrimary: string\n colorPrimaryHover: string\n colorPrimarySoft: string\n\n // Semantic\n colorSuccess: string\n colorSuccessSoft: string\n colorDanger: string\n colorDangerHover: string\n colorDangerSoft: string\n\n // Typography\n fontFamily: string\n fontFamilyMono: string\n /**\n * Display face used by step titles and other visual headlines. Defaults\n * to `fontFamily`. Set this when your brand uses a separate display face\n * (Tiempos, Canela, etc.) for headings.\n */\n fontFamilyDisplay: string\n fontSize: string\n /** Weight applied to the step title. Default `'600'`. */\n fontWeightDisplay: string\n /** Letter spacing applied to the step title. Default `'-0.015em'`. */\n letterSpacingDisplay: string\n\n // Geometry\n borderRadius: string\n radiusSm: string\n radiusMd: string\n radiusLg: string\n radiusXl: string\n\n // Elevation\n shadowModal: string\n shadowCard: string\n\n // Overlay\n /**\n * Color of the dim behind the modal. Defaults to a neutral translucent\n * ink. Set to `color-mix(in srgb, var(--ck-color-primary) 40%, transparent)`\n * to derive the overlay from your primary color, or any CSS color value.\n */\n overlayColor: string\n}\n\nexport interface Appearance {\n /**\n * `'auto'` follows the user's OS preference (`prefers-color-scheme`) and\n * watches for changes. Default: `'light'`.\n */\n colorScheme?: 'auto' | 'light' | 'dark'\n variables?: Partial<AppearanceVariables>\n}\n\nexport interface CustomStepProps {\n step: CustomStepConfig\n customer: DirectCustomer | null\n subscriptions: DirectSubscription[]\n onNext: (result?: Record<string, unknown>) => void\n onBack: () => void\n}\n\nexport interface CustomOfferProps {\n offer: OfferDecision\n customer: DirectCustomer | null\n subscriptions: DirectSubscription[]\n onAccept: (result?: Record<string, unknown>) => Promise<void>\n onDecline: () => void\n isProcessing: boolean\n}\n\n// ─── Component overrides ─────────────────────────────────────────────────────\n\nexport interface ComponentOverrides {\n // Structural\n Modal?: (props: ModalProps) => ReactElement\n CloseButton?: (props: CloseButtonProps) => ReactElement\n BackButton?: (props: BackButtonProps) => ReactElement\n\n // Step-level (replace entire built-in step)\n Survey?: (props: SurveyStepProps) => ReactElement\n Offer?: (props: OfferStepProps) => ReactElement\n Feedback?: (props: FeedbackStepProps) => ReactElement\n Confirm?: (props: ConfirmStepProps) => ReactElement\n Success?: (props: SuccessStepProps) => ReactElement\n\n // Sub-component (replace part of a step)\n ReasonButton?: (props: ReasonButtonProps) => ReactElement\n\n // Per-type offer slots. Each owns its full canvas (title, description,\n // body, buttons) just like the step-level defaults — replacing one\n // gives full control over a single offer type. To take over offer\n // routing entirely, override `Offer` instead.\n DiscountOffer?: (props: OfferStepProps) => ReactElement\n PauseOffer?: (props: OfferStepProps) => ReactElement\n PlanChangeOffer?: (props: OfferStepProps) => ReactElement\n TrialExtensionOffer?: (props: OfferStepProps) => ReactElement\n ContactOffer?: (props: OfferStepProps) => ReactElement\n RedirectOffer?: (props: OfferStepProps) => ReactElement\n RebateOffer?: (props: OfferStepProps) => ReactElement\n}\n\nexport type CustomComponents = Record<string, ComponentType<CustomStepProps> | ComponentType<CustomOfferProps>>\n\n// ─── Structural component props ──────────────────────────────────────────────\n\nexport interface ModalProps {\n open: boolean\n onClose: () => void\n children: ReactNode\n className?: string\n overlayClassName?: string\n}\n\nexport interface CloseButtonProps {\n onClose: () => void\n className?: string\n /** Accessible label. Defaults to \"Close\". */\n label?: string\n}\n\nexport interface BackButtonProps {\n onBack: () => void\n className?: string\n /** Visible label. Defaults to \"Back\". */\n label?: string\n}\n\n// ─── Step component props ────────────────────────────────────────────────────\n\nexport interface SurveyStepProps {\n title: string\n description?: string\n customer: DirectCustomer | null\n subscriptions: DirectSubscription[]\n reasons: ReasonConfig[]\n selectedReason: string | null\n onSelectReason: (id: string) => void\n /** Free-text value when the selected reason has `freeform: true`. Lands on the session as `followupResponse`. */\n followupResponse: string\n /** Set the follow-up response. The SDK forwards the value to the session. */\n onFollowupResponseChange: (text: string) => void\n onNext: () => void\n classNames?: SurveyClassNames\n components?: Partial<ComponentOverrides>\n /** Resolved message catalog. Default components fall back to `defaultMessages` when absent. */\n messages?: CancelFlowMessages\n}\n\nexport interface OfferStepProps {\n title?: string\n description?: string\n customer: DirectCustomer | null\n subscriptions: DirectSubscription[]\n offer: OfferDecision\n /**\n * Accept the offer. The optional `result` is included on the resulting\n * `AcceptedOffer` payload — used by offers that need a user choice (e.g.\n * `plan_change` passes `{ planId }`).\n */\n onAccept: (result?: Record<string, unknown>) => Promise<void>\n onDecline: () => void\n isProcessing: boolean\n classNames?: OfferClassNames\n /**\n * Forwarded to the default `Offer` switcher so it can dispatch to per-type\n * overrides (`DiscountOffer`, `PauseOffer`, etc). Custom `Offer`\n * implementations can ignore this.\n */\n components?: Partial<ComponentOverrides>\n /** Resolved message catalog. Default components fall back to `defaultMessages` when absent. */\n messages?: CancelFlowMessages\n}\n\nexport interface FeedbackStepProps {\n title: string\n description?: string\n customer: DirectCustomer | null\n subscriptions: DirectSubscription[]\n placeholder?: string\n required: boolean\n minLength: number\n value: string\n onChange: (text: string) => void\n onSubmit: () => void\n classNames?: FeedbackClassNames\n /** Resolved message catalog. Default components fall back to `defaultMessages` when absent. */\n messages?: CancelFlowMessages\n}\n\nexport interface ConfirmStepProps {\n title: string\n description?: string\n customer: DirectCustomer | null\n subscriptions: DirectSubscription[]\n losses?: string[]\n lossesLabel?: string\n confirmLabel: string\n goBackLabel: string\n /**\n * Timing-resolved access notice (\"Your access continues until June 14, 2026.\"),\n * rendered between the loss list and the confirm button. Absent when the\n * period end is unknown or the resolved message is empty.\n */\n periodEndNotice?: string\n onConfirm: () => Promise<void>\n onGoBack: () => void\n isProcessing: boolean\n classNames?: ConfirmClassNames\n /** Resolved message catalog. Default components fall back to `defaultMessages` when absent. */\n messages?: CancelFlowMessages\n}\n\nexport interface SuccessStepProps {\n outcome: 'saved' | 'cancelled'\n offer?: OfferDecision\n /** The accepted offer (consumer-facing shape, incl. any accept result).\n * Present when outcome is 'saved'. */\n acceptedOffer?: AcceptedOffer\n title: string\n description?: string\n customer: DirectCustomer | null\n subscriptions: DirectSubscription[]\n onClose: () => void\n classNames?: SuccessClassNames\n /** Resolved message catalog. Default components fall back to `defaultMessages` when absent. */\n messages?: CancelFlowMessages\n}\n\n// ─── Sub-component props ─────────────────────────────────────────────────────\n\nexport interface ReasonButtonProps {\n reason: ReasonConfig\n index: number\n isSelected: boolean\n onSelect: (id: string) => void\n}\n\n// ─── Flow state ──────────────────────────────────────────────────────────────\n\nexport interface FlowState {\n step: string\n currentStepId: string\n selectedReason: string | null\n followupResponse: string\n feedback: string\n outcome: 'saved' | 'cancelled' | null\n /** The offer the customer accepted, set alongside outcome 'saved'. Drives\n * per-offer success copy; `null` until then and for cancellations. */\n acceptedOffer: AcceptedOffer | null\n isProcessing: boolean\n error: Error | null\n customer: DirectCustomer | null\n subscriptions: DirectSubscription[]\n /**\n * Effective cancel timing for this flow: the server-resolved value per\n * blueprint (token mode), else the developer's `cancelAtPeriodEnd`\n * declaration (local mode), else `null` — unknown. Drives timing-aware\n * messages; `null` reads as period-end, matching the default the cancel\n * action uses.\n */\n cancelAtPeriodEnd: boolean | null\n}\n\n// ─── Flow config ─────────────────────────────────────────────────────────────\n\nexport const MODES = ['live', 'test', 'sandbox'] as const\n\n/**\n * Environment a session runs against. `'test'` and `'sandbox'` both keep\n * sessions out of live analytics; `'sandbox'` additionally routes server-side\n * billing actions to the org's Stripe Sandbox credentials, which live under a\n * separate Stripe account ID from live/test mode.\n */\nexport type Mode = (typeof MODES)[number]\n\nexport interface FlowConfig extends FlowCallbacks {\n appId?: string\n customer?: DirectCustomer\n subscriptions?: DirectSubscription[]\n /**\n * Client-side attribute layer on top of provider data, e.g. usage counts\n * or entitlements only the host app knows (`{ videosCreated: 28 }`). In token mode\n * they're sent with the config request so segments can match on them when\n * picking the blueprint. In every mode they resolve as merge fields and\n * are recorded on the session, taking precedence over `customer.metadata`\n * keys. Same role as the embed's `customerAttributes`.\n */\n customerAttributes?: Record<string, unknown>\n session?: string\n apiBaseUrl?: string\n steps?: Step[]\n /**\n * Tags the session as live, test, or sandbox. Use `'test'` from staging so\n * your dashboard can filter out non-production traffic, or `'sandbox'` when\n * the org is connected to a Stripe Sandbox. Defaults to `'live'`.\n * In token mode the mode is encoded in the signed token and overrides\n * this field.\n */\n mode?: Mode\n /**\n * Locale and message overrides for the SDK's own strings (buttons, loading\n * and confirmation chrome). Flow content — step titles, offer copy — is\n * authored in the dashboard and localized server-side; override it there or\n * via `steps`. Read once at mount, like `steps`.\n */\n i18n?: I18nConfig\n /**\n * Local-mode declaration of your billing behavior: does cancellation take\n * effect at the end of the billing period (`true`) or immediately\n * (`false`)? Drives timing-aware messages and the confirm step's\n * access-until notice. In token mode this is ignored: the server-resolved\n * value is authoritative, and if the server omits it the timing is treated\n * as unknown rather than falling back to this declaration.\n */\n cancelAtPeriodEnd?: boolean\n}\n\ntype OfferCallback = (offer: AcceptedOffer, customer: DirectCustomer | null) => Promise<void> | void\ntype CancelCallback = (customer: DirectCustomer | null) => Promise<void> | void\n\n/**\n * Two kinds of callbacks, distinguished by name:\n *\n * - `handle<Type>` runs the action. When defined, it replaces whatever\n * Churnkey would do on the server — the consumer takes responsibility.\n * In local mode (no token), handlers are the only path that does anything.\n * - `on<Type>` is a listener that fires after the action. Side effects only —\n * refetch state, log analytics, show a toast. Errors thrown here are\n * swallowed; listeners can't flip the flow into an error state.\n *\n * `onAccept` is a catch-all that fires alongside the per-type listener.\n */\nexport interface FlowCallbacks {\n handleDiscount?: OfferCallback\n handlePause?: OfferCallback\n handlePlanChange?: OfferCallback\n handleTrialExtension?: OfferCallback\n handleRebate?: OfferCallback\n handleCancel?: CancelCallback\n\n onAccept?: OfferCallback\n onDiscount?: OfferCallback\n onPause?: OfferCallback\n onPlanChange?: OfferCallback\n onTrialExtension?: OfferCallback\n onRebate?: OfferCallback\n onCancel?: CancelCallback\n onClose?: () => void\n onStepChange?: (step: string, prevStep: string) => void\n}\n\n// ─── CancelFlow props ────────────────────────────────────────────────────────\n\nexport interface CancelFlowProps extends FlowCallbacks {\n appId?: string\n customer?: DirectCustomer\n subscriptions?: DirectSubscription[]\n /** See FlowConfig.customerAttributes. */\n customerAttributes?: Record<string, unknown>\n session?: string\n steps?: Step[]\n apiBaseUrl?: string\n /** See FlowConfig.mode. Ignored in token mode (the token is authoritative). */\n mode?: Mode\n /** See FlowConfig.i18n. */\n i18n?: I18nConfig\n /** See FlowConfig.cancelAtPeriodEnd. Local mode only; the token config wins. */\n cancelAtPeriodEnd?: boolean\n appearance?: Appearance\n classNames?: StructuralClassNames\n components?: Partial<ComponentOverrides>\n customComponents?: CustomComponents\n}\n","import { MODES, type Mode } from './types'\n\nexport interface SessionCredentials {\n appId: string\n customerId: string\n subscriptionId?: string\n authHash: string\n mode: Mode\n issuedAt: number\n}\n\nfunction isMode(value: unknown): value is Mode {\n return MODES.includes(value as Mode)\n}\n\n/** Decode a session token created by `@churnkey/node`. */\nexport function decodeSessionToken(token: string): SessionCredentials {\n if (!token.startsWith('ck_')) {\n throw new Error('Invalid token: must start with \"ck_\"')\n }\n\n const encoded = token.slice(3)\n\n let json: string\n try {\n // base64url decode: replace URL-safe chars, add padding\n const base64 = encoded.replace(/-/g, '+').replace(/_/g, '/')\n const padded = base64 + '='.repeat((4 - (base64.length % 4)) % 4)\n json = atob(padded)\n } catch {\n throw new Error('Invalid token: malformed base64')\n }\n\n let payload: Record<string, unknown>\n try {\n payload = JSON.parse(json)\n } catch {\n throw new Error('Invalid token: malformed JSON')\n }\n\n if (typeof payload.a !== 'string' || !payload.a) {\n throw new Error('Invalid token: missing appId')\n }\n if (typeof payload.c !== 'string' || !payload.c) {\n throw new Error('Invalid token: missing customerId')\n }\n if (typeof payload.h !== 'string' || !payload.h) {\n throw new Error('Invalid token: missing authHash')\n }\n // `m` is optional and defaults to 'live'. An unrecognized value is rejected\n // rather than coerced — coercing would point test or sandbox traffic at\n // live billing data.\n const mode = payload.m === undefined ? 'live' : payload.m\n if (!isMode(mode)) {\n throw new Error(`Invalid token: unknown mode \"${String(payload.m)}\"`)\n }\n\n return {\n appId: payload.a,\n customerId: payload.c,\n subscriptionId: typeof payload.s === 'string' ? payload.s : undefined,\n authHash: payload.h,\n mode,\n issuedAt: typeof payload.t === 'number' ? payload.t : 0,\n }\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkER6YITYC_cjs = require('./chunk-ER6YITYC.cjs');
|
|
4
4
|
var react = require('react');
|
|
5
5
|
|
|
6
6
|
function useCancelFlowMachine(config) {
|
|
@@ -25,7 +25,7 @@ function useCancelFlowMachine(config) {
|
|
|
25
25
|
onClose: () => cb.current.onClose?.(),
|
|
26
26
|
onStepChange: (step, prevStep) => cb.current.onStepChange?.(step, prevStep)
|
|
27
27
|
};
|
|
28
|
-
return new
|
|
28
|
+
return new chunkER6YITYC_cjs.CancelFlowMachine({ ...config, ...dispatch });
|
|
29
29
|
});
|
|
30
30
|
const [state, setState] = react.useState(() => machine.getSnapshot());
|
|
31
31
|
const [isLoading, setIsLoading] = react.useState(!!config.session);
|
|
@@ -39,8 +39,8 @@ function useCancelFlowMachine(config) {
|
|
|
39
39
|
setLoadError(null);
|
|
40
40
|
setIsLoading(true);
|
|
41
41
|
let cancelled = false;
|
|
42
|
-
const creds =
|
|
43
|
-
const api = new
|
|
42
|
+
const creds = chunkER6YITYC_cjs.decodeSessionToken(config.session);
|
|
43
|
+
const api = new chunkER6YITYC_cjs.ChurnkeyApi(creds, config.apiBaseUrl);
|
|
44
44
|
api.fetchConfig(callbacksRef.current.customerAttributes).then((sdkConfig) => {
|
|
45
45
|
if (cancelled) return;
|
|
46
46
|
machine.initializeFromConfig(sdkConfig, api, creds);
|
|
@@ -89,5 +89,5 @@ function useCancelFlow(config) {
|
|
|
89
89
|
|
|
90
90
|
exports.useCancelFlow = useCancelFlow;
|
|
91
91
|
exports.useCancelFlowMachine = useCancelFlowMachine;
|
|
92
|
-
//# sourceMappingURL=chunk-
|
|
93
|
-
//# sourceMappingURL=chunk-
|
|
92
|
+
//# sourceMappingURL=chunk-FK4AJOX6.cjs.map
|
|
93
|
+
//# sourceMappingURL=chunk-FK4AJOX6.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/headless/use-cancel-flow-machine.ts","../src/headless/use-cancel-flow.ts"],"names":["useRef","useState","CancelFlowMachine","useEffect","useCallback","decodeSessionToken","ChurnkeyApi"],"mappings":"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","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/headless/use-cancel-flow-machine.ts","../src/headless/use-cancel-flow.ts"],"names":["useRef","useState","CancelFlowMachine","useEffect","useCallback","decodeSessionToken","ChurnkeyApi"],"mappings":"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","file":"chunk-FK4AJOX6.cjs","sourcesContent":["// Internal — shared by `useCancelFlow` (headless) and the `CancelFlow`\n// component. Lives under headless/ since it's the headless layer of the\n// SDK; the component imports it because there's no separate public/private\n// split worth maintaining for one shared file.\n\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport { ChurnkeyApi } from '../core/api'\nimport { CancelFlowMachine } from '../core/machine'\nimport { decodeSessionToken } from '../core/token'\nimport type { FlowCallbacks, FlowConfig, FlowState } from '../core/types'\n\nexport interface CancelFlowMachineHandle {\n machine: CancelFlowMachine\n state: FlowState\n isLoading: boolean\n loadError: Error | null\n /** Re-fetch the flow config (token mode only). No-op without a session. */\n retry: () => void\n}\n\n/**\n * Wires a CancelFlowMachine to React lifecycle. Used internally by both the\n * `CancelFlow` component and the `useCancelFlow` hook — not part of the\n * public API.\n *\n * Callbacks reach the machine via thunks that dereference a ref updated each\n * render. This buys two things: the consumer's latest closure always runs,\n * and the fetch effect's dep list stays stable so inline-arrow handlers\n * don't trigger a re-fetch and reset the flow to step 1.\n */\nexport function useCancelFlowMachine(config: FlowConfig): CancelFlowMachineHandle {\n // FlowConfig extends FlowCallbacks, so storing the whole config gives us\n // access to every callback by name without a separate copy.\n const callbacksRef = useRef(config)\n callbacksRef.current = config\n\n const [machine] = useState(() => {\n const cb = callbacksRef\n const dispatch: FlowCallbacks = {\n handleDiscount: (o, c) => cb.current.handleDiscount?.(o, c),\n handlePause: (o, c) => cb.current.handlePause?.(o, c),\n handlePlanChange: (o, c) => cb.current.handlePlanChange?.(o, c),\n handleTrialExtension: (o, c) => cb.current.handleTrialExtension?.(o, c),\n handleRebate: (o, c) => cb.current.handleRebate?.(o, c),\n handleCancel: (c) => cb.current.handleCancel?.(c),\n onAccept: (o, c) => cb.current.onAccept?.(o, c),\n onDiscount: (o, c) => cb.current.onDiscount?.(o, c),\n onPause: (o, c) => cb.current.onPause?.(o, c),\n onPlanChange: (o, c) => cb.current.onPlanChange?.(o, c),\n onTrialExtension: (o, c) => cb.current.onTrialExtension?.(o, c),\n onRebate: (o, c) => cb.current.onRebate?.(o, c),\n onCancel: (c) => cb.current.onCancel?.(c),\n onClose: () => cb.current.onClose?.(),\n onStepChange: (step, prevStep) => cb.current.onStepChange?.(step, prevStep),\n }\n return new CancelFlowMachine({ ...config, ...dispatch })\n })\n\n const [state, setState] = useState<FlowState>(() => machine.getSnapshot())\n const [isLoading, setIsLoading] = useState(!!config.session)\n const [loadError, setLoadError] = useState<Error | null>(null)\n\n useEffect(() => {\n setState(machine.getSnapshot())\n return machine.subscribe(() => setState(machine.getSnapshot()))\n }, [machine])\n\n const loadConfig = useCallback(() => {\n if (!config.session) return\n setLoadError(null)\n setIsLoading(true)\n let cancelled = false\n const creds = decodeSessionToken(config.session)\n const api = new ChurnkeyApi(creds, config.apiBaseUrl)\n api\n // Read through the ref, not the closure: an inline `customerAttributes`\n // object literal would otherwise join the dep list and re-fetch (and\n // reset the flow) on every render.\n .fetchConfig(callbacksRef.current.customerAttributes)\n .then((sdkConfig) => {\n if (cancelled) return\n machine.initializeFromConfig(sdkConfig, api, creds)\n setIsLoading(false)\n })\n .catch((err) => {\n if (cancelled) return\n setLoadError(err instanceof Error ? err : new Error(String(err)))\n setIsLoading(false)\n })\n return () => {\n cancelled = true\n }\n }, [config.session, config.apiBaseUrl, machine])\n\n useEffect(() => {\n if (!config.session) return\n return loadConfig()\n }, [config.session, loadConfig])\n\n return { machine, state, isLoading, loadError, retry: loadConfig }\n}\n","import type { FlowConfig } from '../core/types'\nimport { useCancelFlowMachine } from './use-cancel-flow-machine'\n\nexport function useCancelFlow(config: FlowConfig) {\n const { machine, state, isLoading, loadError, retry } = useCancelFlowMachine(config)\n\n return {\n ...state,\n isLoading,\n loadError,\n retry,\n messages: machine.messages,\n reasons: machine.reasons,\n currentStep: machine.currentStep,\n currentOffer: machine.currentOffer,\n stepIndex: machine.stepIndex,\n totalSteps: machine.totalSteps,\n selectReason: machine.selectReason,\n setFollowupResponse: machine.setFollowupResponse,\n setFeedback: machine.setFeedback,\n accept: machine.accept,\n decline: machine.decline,\n cancel: machine.cancel,\n next: machine.next,\n back: machine.back,\n close: machine.close,\n }\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CancelFlowMachine, decodeSessionToken, ChurnkeyApi } from './chunk-
|
|
1
|
+
import { CancelFlowMachine, decodeSessionToken, ChurnkeyApi } from './chunk-RFKW3LWM.js';
|
|
2
2
|
import { useRef, useState, useEffect, useCallback } from 'react';
|
|
3
3
|
|
|
4
4
|
function useCancelFlowMachine(config) {
|
|
@@ -86,5 +86,5 @@ function useCancelFlow(config) {
|
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
export { useCancelFlow, useCancelFlowMachine };
|
|
89
|
-
//# sourceMappingURL=chunk-
|
|
90
|
-
//# sourceMappingURL=chunk-
|
|
89
|
+
//# sourceMappingURL=chunk-GNRS7V7H.js.map
|
|
90
|
+
//# sourceMappingURL=chunk-GNRS7V7H.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/headless/use-cancel-flow-machine.ts","../src/headless/use-cancel-flow.ts"],"names":[],"mappings":"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","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/headless/use-cancel-flow-machine.ts","../src/headless/use-cancel-flow.ts"],"names":[],"mappings":";;;AA8BO,SAAS,qBAAqB,MAAA,EAA6C;AAGhF,EAAA,MAAM,YAAA,GAAe,OAAO,MAAM,CAAA;AAClC,EAAA,YAAA,CAAa,OAAA,GAAU,MAAA;AAEvB,EAAA,MAAM,CAAC,OAAO,CAAA,GAAI,QAAA,CAAS,MAAM;AAC/B,IAAA,MAAM,EAAA,GAAK,YAAA;AACX,IAAA,MAAM,QAAA,GAA0B;AAAA,MAC9B,cAAA,EAAgB,CAAC,CAAA,EAAG,CAAA,KAAM,GAAG,OAAA,CAAQ,cAAA,GAAiB,GAAG,CAAC,CAAA;AAAA,MAC1D,WAAA,EAAa,CAAC,CAAA,EAAG,CAAA,KAAM,GAAG,OAAA,CAAQ,WAAA,GAAc,GAAG,CAAC,CAAA;AAAA,MACpD,gBAAA,EAAkB,CAAC,CAAA,EAAG,CAAA,KAAM,GAAG,OAAA,CAAQ,gBAAA,GAAmB,GAAG,CAAC,CAAA;AAAA,MAC9D,oBAAA,EAAsB,CAAC,CAAA,EAAG,CAAA,KAAM,GAAG,OAAA,CAAQ,oBAAA,GAAuB,GAAG,CAAC,CAAA;AAAA,MACtE,YAAA,EAAc,CAAC,CAAA,EAAG,CAAA,KAAM,GAAG,OAAA,CAAQ,YAAA,GAAe,GAAG,CAAC,CAAA;AAAA,MACtD,cAAc,CAAC,CAAA,KAAM,EAAA,CAAG,OAAA,CAAQ,eAAe,CAAC,CAAA;AAAA,MAChD,QAAA,EAAU,CAAC,CAAA,EAAG,CAAA,KAAM,GAAG,OAAA,CAAQ,QAAA,GAAW,GAAG,CAAC,CAAA;AAAA,MAC9C,UAAA,EAAY,CAAC,CAAA,EAAG,CAAA,KAAM,GAAG,OAAA,CAAQ,UAAA,GAAa,GAAG,CAAC,CAAA;AAAA,MAClD,OAAA,EAAS,CAAC,CAAA,EAAG,CAAA,KAAM,GAAG,OAAA,CAAQ,OAAA,GAAU,GAAG,CAAC,CAAA;AAAA,MAC5C,YAAA,EAAc,CAAC,CAAA,EAAG,CAAA,KAAM,GAAG,OAAA,CAAQ,YAAA,GAAe,GAAG,CAAC,CAAA;AAAA,MACtD,gBAAA,EAAkB,CAAC,CAAA,EAAG,CAAA,KAAM,GAAG,OAAA,CAAQ,gBAAA,GAAmB,GAAG,CAAC,CAAA;AAAA,MAC9D,QAAA,EAAU,CAAC,CAAA,EAAG,CAAA,KAAM,GAAG,OAAA,CAAQ,QAAA,GAAW,GAAG,CAAC,CAAA;AAAA,MAC9C,UAAU,CAAC,CAAA,KAAM,EAAA,CAAG,OAAA,CAAQ,WAAW,CAAC,CAAA;AAAA,MACxC,OAAA,EAAS,MAAM,EAAA,CAAG,OAAA,CAAQ,OAAA,IAAU;AAAA,MACpC,YAAA,EAAc,CAAC,IAAA,EAAM,QAAA,KAAa,GAAG,OAAA,CAAQ,YAAA,GAAe,MAAM,QAAQ;AAAA,KAC5E;AACA,IAAA,OAAO,IAAI,iBAAA,CAAkB,EAAE,GAAG,MAAA,EAAQ,GAAG,UAAU,CAAA;AAAA,EACzD,CAAC,CAAA;AAED,EAAA,MAAM,CAAC,OAAO,QAAQ,CAAA,GAAI,SAAoB,MAAM,OAAA,CAAQ,aAAa,CAAA;AACzE,EAAA,MAAM,CAAC,WAAW,YAAY,CAAA,GAAI,SAAS,CAAC,CAAC,OAAO,OAAO,CAAA;AAC3D,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAI,SAAuB,IAAI,CAAA;AAE7D,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,QAAA,CAAS,OAAA,CAAQ,aAAa,CAAA;AAC9B,IAAA,OAAO,QAAQ,SAAA,CAAU,MAAM,SAAS,OAAA,CAAQ,WAAA,EAAa,CAAC,CAAA;AAAA,EAChE,CAAA,EAAG,CAAC,OAAO,CAAC,CAAA;AAEZ,EAAA,MAAM,UAAA,GAAa,YAAY,MAAM;AACnC,IAAA,IAAI,CAAC,OAAO,OAAA,EAAS;AACrB,IAAA,YAAA,CAAa,IAAI,CAAA;AACjB,IAAA,YAAA,CAAa,IAAI,CAAA;AACjB,IAAA,IAAI,SAAA,GAAY,KAAA;AAChB,IAAA,MAAM,KAAA,GAAQ,kBAAA,CAAmB,MAAA,CAAO,OAAO,CAAA;AAC/C,IAAA,MAAM,GAAA,GAAM,IAAI,WAAA,CAAY,KAAA,EAAO,OAAO,UAAU,CAAA;AACpD,IAAA,GAAA,CAIG,YAAY,YAAA,CAAa,OAAA,CAAQ,kBAAkB,CAAA,CACnD,IAAA,CAAK,CAAC,SAAA,KAAc;AACnB,MAAA,IAAI,SAAA,EAAW;AACf,MAAA,OAAA,CAAQ,oBAAA,CAAqB,SAAA,EAAW,GAAA,EAAK,KAAK,CAAA;AAClD,MAAA,YAAA,CAAa,KAAK,CAAA;AAAA,IACpB,CAAC,CAAA,CACA,KAAA,CAAM,CAAC,GAAA,KAAQ;AACd,MAAA,IAAI,SAAA,EAAW;AACf,MAAA,YAAA,CAAa,GAAA,YAAe,QAAQ,GAAA,GAAM,IAAI,MAAM,MAAA,CAAO,GAAG,CAAC,CAAC,CAAA;AAChE,MAAA,YAAA,CAAa,KAAK,CAAA;AAAA,IACpB,CAAC,CAAA;AACH,IAAA,OAAO,MAAM;AACX,MAAA,SAAA,GAAY,IAAA;AAAA,IACd,CAAA;AAAA,EACF,GAAG,CAAC,MAAA,CAAO,SAAS,MAAA,CAAO,UAAA,EAAY,OAAO,CAAC,CAAA;AAE/C,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,OAAO,OAAA,EAAS;AACrB,IAAA,OAAO,UAAA,EAAW;AAAA,EACpB,CAAA,EAAG,CAAC,MAAA,CAAO,OAAA,EAAS,UAAU,CAAC,CAAA;AAE/B,EAAA,OAAO,EAAE,OAAA,EAAS,KAAA,EAAO,SAAA,EAAW,SAAA,EAAW,OAAO,UAAA,EAAW;AACnE;;;ACjGO,SAAS,cAAc,MAAA,EAAoB;AAChD,EAAA,MAAM,EAAE,SAAS,KAAA,EAAO,SAAA,EAAW,WAAW,KAAA,EAAM,GAAI,qBAAqB,MAAM,CAAA;AAEnF,EAAA,OAAO;AAAA,IACL,GAAG,KAAA;AAAA,IACH,SAAA;AAAA,IACA,SAAA;AAAA,IACA,KAAA;AAAA,IACA,UAAU,OAAA,CAAQ,QAAA;AAAA,IAClB,SAAS,OAAA,CAAQ,OAAA;AAAA,IACjB,aAAa,OAAA,CAAQ,WAAA;AAAA,IACrB,cAAc,OAAA,CAAQ,YAAA;AAAA,IACtB,WAAW,OAAA,CAAQ,SAAA;AAAA,IACnB,YAAY,OAAA,CAAQ,UAAA;AAAA,IACpB,cAAc,OAAA,CAAQ,YAAA;AAAA,IACtB,qBAAqB,OAAA,CAAQ,mBAAA;AAAA,IAC7B,aAAa,OAAA,CAAQ,WAAA;AAAA,IACrB,QAAQ,OAAA,CAAQ,MAAA;AAAA,IAChB,SAAS,OAAA,CAAQ,OAAA;AAAA,IACjB,QAAQ,OAAA,CAAQ,MAAA;AAAA,IAChB,MAAM,OAAA,CAAQ,IAAA;AAAA,IACd,MAAM,OAAA,CAAQ,IAAA;AAAA,IACd,OAAO,OAAA,CAAQ;AAAA,GACjB;AACF","file":"chunk-GNRS7V7H.js","sourcesContent":["// Internal — shared by `useCancelFlow` (headless) and the `CancelFlow`\n// component. Lives under headless/ since it's the headless layer of the\n// SDK; the component imports it because there's no separate public/private\n// split worth maintaining for one shared file.\n\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport { ChurnkeyApi } from '../core/api'\nimport { CancelFlowMachine } from '../core/machine'\nimport { decodeSessionToken } from '../core/token'\nimport type { FlowCallbacks, FlowConfig, FlowState } from '../core/types'\n\nexport interface CancelFlowMachineHandle {\n machine: CancelFlowMachine\n state: FlowState\n isLoading: boolean\n loadError: Error | null\n /** Re-fetch the flow config (token mode only). No-op without a session. */\n retry: () => void\n}\n\n/**\n * Wires a CancelFlowMachine to React lifecycle. Used internally by both the\n * `CancelFlow` component and the `useCancelFlow` hook — not part of the\n * public API.\n *\n * Callbacks reach the machine via thunks that dereference a ref updated each\n * render. This buys two things: the consumer's latest closure always runs,\n * and the fetch effect's dep list stays stable so inline-arrow handlers\n * don't trigger a re-fetch and reset the flow to step 1.\n */\nexport function useCancelFlowMachine(config: FlowConfig): CancelFlowMachineHandle {\n // FlowConfig extends FlowCallbacks, so storing the whole config gives us\n // access to every callback by name without a separate copy.\n const callbacksRef = useRef(config)\n callbacksRef.current = config\n\n const [machine] = useState(() => {\n const cb = callbacksRef\n const dispatch: FlowCallbacks = {\n handleDiscount: (o, c) => cb.current.handleDiscount?.(o, c),\n handlePause: (o, c) => cb.current.handlePause?.(o, c),\n handlePlanChange: (o, c) => cb.current.handlePlanChange?.(o, c),\n handleTrialExtension: (o, c) => cb.current.handleTrialExtension?.(o, c),\n handleRebate: (o, c) => cb.current.handleRebate?.(o, c),\n handleCancel: (c) => cb.current.handleCancel?.(c),\n onAccept: (o, c) => cb.current.onAccept?.(o, c),\n onDiscount: (o, c) => cb.current.onDiscount?.(o, c),\n onPause: (o, c) => cb.current.onPause?.(o, c),\n onPlanChange: (o, c) => cb.current.onPlanChange?.(o, c),\n onTrialExtension: (o, c) => cb.current.onTrialExtension?.(o, c),\n onRebate: (o, c) => cb.current.onRebate?.(o, c),\n onCancel: (c) => cb.current.onCancel?.(c),\n onClose: () => cb.current.onClose?.(),\n onStepChange: (step, prevStep) => cb.current.onStepChange?.(step, prevStep),\n }\n return new CancelFlowMachine({ ...config, ...dispatch })\n })\n\n const [state, setState] = useState<FlowState>(() => machine.getSnapshot())\n const [isLoading, setIsLoading] = useState(!!config.session)\n const [loadError, setLoadError] = useState<Error | null>(null)\n\n useEffect(() => {\n setState(machine.getSnapshot())\n return machine.subscribe(() => setState(machine.getSnapshot()))\n }, [machine])\n\n const loadConfig = useCallback(() => {\n if (!config.session) return\n setLoadError(null)\n setIsLoading(true)\n let cancelled = false\n const creds = decodeSessionToken(config.session)\n const api = new ChurnkeyApi(creds, config.apiBaseUrl)\n api\n // Read through the ref, not the closure: an inline `customerAttributes`\n // object literal would otherwise join the dep list and re-fetch (and\n // reset the flow) on every render.\n .fetchConfig(callbacksRef.current.customerAttributes)\n .then((sdkConfig) => {\n if (cancelled) return\n machine.initializeFromConfig(sdkConfig, api, creds)\n setIsLoading(false)\n })\n .catch((err) => {\n if (cancelled) return\n setLoadError(err instanceof Error ? err : new Error(String(err)))\n setIsLoading(false)\n })\n return () => {\n cancelled = true\n }\n }, [config.session, config.apiBaseUrl, machine])\n\n useEffect(() => {\n if (!config.session) return\n return loadConfig()\n }, [config.session, loadConfig])\n\n return { machine, state, isLoading, loadError, retry: loadConfig }\n}\n","import type { FlowConfig } from '../core/types'\nimport { useCancelFlowMachine } from './use-cancel-flow-machine'\n\nexport function useCancelFlow(config: FlowConfig) {\n const { machine, state, isLoading, loadError, retry } = useCancelFlowMachine(config)\n\n return {\n ...state,\n isLoading,\n loadError,\n retry,\n messages: machine.messages,\n reasons: machine.reasons,\n currentStep: machine.currentStep,\n currentOffer: machine.currentOffer,\n stepIndex: machine.stepIndex,\n totalSteps: machine.totalSteps,\n selectReason: machine.selectReason,\n setFollowupResponse: machine.setFollowupResponse,\n setFeedback: machine.setFeedback,\n accept: machine.accept,\n decline: machine.decline,\n cancel: machine.cancel,\n next: machine.next,\n back: machine.back,\n close: machine.close,\n }\n}\n"]}
|
|
@@ -62,6 +62,16 @@ var defaultMessages = {
|
|
|
62
62
|
newEndDateLabel: "New end date",
|
|
63
63
|
currentPlanBadge: "Current",
|
|
64
64
|
switchToCta: "Switch to {planName}",
|
|
65
|
+
acceptCta: {
|
|
66
|
+
discount: "",
|
|
67
|
+
pause: "",
|
|
68
|
+
trial_extension: "",
|
|
69
|
+
plan_change: "",
|
|
70
|
+
contact: "",
|
|
71
|
+
redirect: "",
|
|
72
|
+
rebate: ""
|
|
73
|
+
},
|
|
74
|
+
declineCta: "",
|
|
65
75
|
rebate: {
|
|
66
76
|
paidLabel: "You paid this period",
|
|
67
77
|
moneyBackLabel: "Money back",
|
|
@@ -1386,5 +1396,5 @@ function decodeSessionToken(token) {
|
|
|
1386
1396
|
}
|
|
1387
1397
|
|
|
1388
1398
|
export { AnalyticsClient, BUILT_IN_OFFER_TYPES, BUILT_IN_STEP_TYPES, CancelFlowMachine, ChurnkeyApi, appearanceToStyle, buildMessages, cn, decodeSessionToken, defaultMessages, defaultTitles, formatMessage, selectTiming };
|
|
1389
|
-
//# sourceMappingURL=chunk-
|
|
1390
|
-
//# sourceMappingURL=chunk-
|
|
1399
|
+
//# sourceMappingURL=chunk-RFKW3LWM.js.map
|
|
1400
|
+
//# sourceMappingURL=chunk-RFKW3LWM.js.map
|