-
Notifications
You must be signed in to change notification settings - Fork 402
[WIP] feat(backend, clerk-js): Update the supported API version to 2025-10-01
#7095
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
e783dd0
263b29b
4731af2
38b1d42
52a2409
ed3a125
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| --- | ||
| '@clerk/clerk-js': patch | ||
| '@clerk/backend': patch | ||
| --- | ||
|
|
||
| Update the supported API version to `2025-10-01`. | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -8,8 +8,8 @@ export class BillingPlan extends BaseResource implements BillingPlanResource { | |||||||||||||
| id!: string; | ||||||||||||||
| name!: string; | ||||||||||||||
| fee!: BillingMoneyAmount; | ||||||||||||||
| annualFee!: BillingMoneyAmount; | ||||||||||||||
| annualMonthlyFee!: BillingMoneyAmount; | ||||||||||||||
| annualFee: BillingMoneyAmount | null = null; | ||||||||||||||
| annualMonthlyFee: BillingMoneyAmount | null = null; | ||||||||||||||
| description!: string; | ||||||||||||||
| isDefault!: boolean; | ||||||||||||||
| isRecurring!: boolean; | ||||||||||||||
|
|
@@ -32,11 +32,17 @@ export class BillingPlan extends BaseResource implements BillingPlanResource { | |||||||||||||
| return this; | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| console.log('data', { | ||||||||||||||
| fee: data.fee, | ||||||||||||||
| annual_fee: data.annual_fee, | ||||||||||||||
| annual_monthly_fee: data.annual_monthly_fee, | ||||||||||||||
| }); | ||||||||||||||
|
Comment on lines
+35
to
+39
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove debug console.log before merging. Debug logging should not be committed to production code. This will clutter browser consoles and could expose internal data structures. Apply this diff to remove the debug statement: - console.log('data', {
- fee: data.fee,
- annual_fee: data.annual_fee,
- annual_monthly_fee: data.annual_monthly_fee,
- });
-
this.id = data.id;📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||
|
|
||||||||||||||
| this.id = data.id; | ||||||||||||||
| this.name = data.name; | ||||||||||||||
| this.fee = billingMoneyAmountFromJSON(data.fee); | ||||||||||||||
| this.annualFee = billingMoneyAmountFromJSON(data.annual_fee); | ||||||||||||||
| this.annualMonthlyFee = billingMoneyAmountFromJSON(data.annual_monthly_fee); | ||||||||||||||
| this.annualFee = data.annual_fee ? billingMoneyAmountFromJSON(data.annual_fee) : null; | ||||||||||||||
| this.annualMonthlyFee = data.annual_monthly_fee ? billingMoneyAmountFromJSON(data.annual_monthly_fee) : null; | ||||||||||||||
| this.description = data.description; | ||||||||||||||
| this.isDefault = data.is_default; | ||||||||||||||
| this.isRecurring = data.is_recurring; | ||||||||||||||
|
|
||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -39,7 +39,11 @@ export const CheckoutForm = withCardStateProvider(() => { | |||||||||||||||||||
| const showPastDue = !!totals.pastDue?.amount && totals.pastDue.amount > 0; | ||||||||||||||||||||
| const showDowngradeInfo = !isImmediatePlanChange; | ||||||||||||||||||||
|
|
||||||||||||||||||||
| const fee = planPeriod === 'month' ? plan.fee : plan.annualMonthlyFee; | ||||||||||||||||||||
| const fee = | ||||||||||||||||||||
| planPeriod === 'month' | ||||||||||||||||||||
| ? plan.fee | ||||||||||||||||||||
| : // eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||||||||||||||||||||
| plan.annualMonthlyFee!; | ||||||||||||||||||||
|
Comment on lines
+42
to
+46
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unsafe non-null assertion could cause runtime errors. Same issue as in PaymentAttemptPage: using Apply this safer pattern: - const fee =
- planPeriod === 'month'
- ? plan.fee
- : // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- plan.annualMonthlyFee!;
+ const fee =
+ planPeriod === 'month' || !plan.annualMonthlyFee
+ ? plan.fee
+ : plan.annualMonthlyFee;📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||
|
|
||||||||||||||||||||
| return ( | ||||||||||||||||||||
| <Drawer.Body> | ||||||||||||||||||||
|
|
@@ -166,10 +170,10 @@ const useCheckoutMutations = () => { | |||||||||||||||||||
| e.preventDefault(); | ||||||||||||||||||||
|
|
||||||||||||||||||||
| const data = new FormData(e.currentTarget); | ||||||||||||||||||||
| const paymentSourceId = data.get(HIDDEN_INPUT_NAME) as string; | ||||||||||||||||||||
| const paymentMethodId = data.get(HIDDEN_INPUT_NAME) as string; | ||||||||||||||||||||
|
|
||||||||||||||||||||
| return confirmCheckout({ | ||||||||||||||||||||
| paymentSourceId, | ||||||||||||||||||||
| paymentMethodId, | ||||||||||||||||||||
| }); | ||||||||||||||||||||
| }; | ||||||||||||||||||||
|
|
||||||||||||||||||||
|
|
||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -215,7 +215,10 @@ function PaymentAttemptBody({ subscriptionItem }: { subscriptionItem: BillingSub | |||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| const fee = | ||||||||||||||||||||||
| subscriptionItem.planPeriod === 'month' ? subscriptionItem.plan.fee : subscriptionItem.plan.annualMonthlyFee; | ||||||||||||||||||||||
| subscriptionItem.planPeriod === 'month' | ||||||||||||||||||||||
| ? subscriptionItem.plan.fee | ||||||||||||||||||||||
| : // eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||||||||||||||||||||||
| subscriptionItem.plan.annualMonthlyFee!; | ||||||||||||||||||||||
|
Comment on lines
217
to
+221
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unsafe non-null assertion could cause runtime errors. The code uses a non-null assertion ( Apply this defensive pattern instead: - const fee =
- subscriptionItem.planPeriod === 'month'
- ? subscriptionItem.plan.fee
- : // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- subscriptionItem.plan.annualMonthlyFee!;
+ const fee =
+ subscriptionItem.planPeriod === 'month' || !subscriptionItem.plan.annualMonthlyFee
+ ? subscriptionItem.plan.fee
+ : subscriptionItem.plan.annualMonthlyFee;📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| return ( | ||||||||||||||||||||||
| <Box | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -282,13 +282,17 @@ const CardHeader = React.forwardRef<HTMLDivElement, CardHeaderProps>((props, ref | |
| const { plan, isCompact, planPeriod, setPlanPeriod, badge } = props; | ||
| const { name, annualMonthlyFee } = plan; | ||
|
|
||
| const planSupportsAnnual = annualMonthlyFee.amount > 0; | ||
| const planSupportsAnnual = Boolean(annualMonthlyFee); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chainVerify behavior change: zero-amount annual pricing. The logic changed from checking Run the following script to check if any plans in the codebase have annual pricing with zero amounts: 🏁 Script executed: #!/bin/bash
# Search for test data or fixtures with annual pricing
rg -n -A5 -B5 'annualMonthlyFee|annual_monthly_fee' --type=ts --type=json --type=tsxLength of output: 27 I'll retry with corrected ripgrep syntax and examine the actual file: 🏁 Script executed: #!/bin/bash
# Search for annualMonthlyFee without specifying tsx type
rg -n -A5 -B5 'annualMonthlyFee|annual_monthly_fee'Length of output: 74162 🏁 Script executed: #!/bin/bash
# Also examine the actual file at line 285 with context
cat packages/clerk-js/src/ui/components/PricingTable/PricingTableDefault.tsx | head -300 | tail -50Length of output: 1579 🏁 Script executed: #!/bin/bash
# Search for BillingMoneyAmount type definitions and mock data
rg -n 'BillingMoneyAmount|billingMoneyAmount' -g '*.ts' -g '*.tsx' -g '*.json'Length of output: 7912 🏁 Script executed: #!/bin/bash
# Look for test files or fixtures related to pricing
fd -e test.ts -e test.tsx -e mock.ts -e mock.tsx -e fixture.ts | xargs grep -l 'annualMonthlyFee\|annual' 2>/dev/null || echo "No test files found with pricing patterns"Length of output: 585 🏁 Script executed: #!/bin/bash
# Search for where pricing plans are created/mocked in the codebase
rg -n 'amount.*0|cost.*0|price.*0' packages/clerk-js/src/ui/components/PricingTable/ --type=tsLength of output: 1428 🏁 Script executed: #!/bin/bash
# Look at the imports and structure of the PricingTableDefault file
head -50 packages/clerk-js/src/ui/components/PricingTable/PricingTableDefault.tsxLength of output: 1542 Fix logic to check Line 285 changed to check for object existence instead of positive amount. This breaks plans with zero-cost annual pricing—they will now show the annual toggle when they shouldn't. The test in Note: This pattern also appears in 🤖 Prompt for AI Agents |
||
|
|
||
| const fee = React.useMemo(() => { | ||
| if (!planSupportsAnnual) { | ||
| return plan.fee; | ||
| } | ||
| return planPeriod === 'annual' ? plan.annualMonthlyFee : plan.fee; | ||
|
|
||
| return planPeriod === 'annual' | ||
| ? // eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
| plan.annualMonthlyFee! | ||
|
Comment on lines
+292
to
+294
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unsafe non-null assertion when annual pricing is enabled. Line 294 uses Consider a safer pattern: - return planPeriod === 'annual'
- ? // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- plan.annualMonthlyFee!
- : plan.fee;
+ if (planPeriod === 'annual' && plan.annualMonthlyFee) {
+ return plan.annualMonthlyFee;
+ }
+ return plan.fee;🤖 Prompt for AI Agents |
||
| : plan.fee; | ||
| }, [planSupportsAnnual, planPeriod, plan.fee, plan.annualMonthlyFee]); | ||
|
|
||
| const feeFormatted = React.useMemo(() => { | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -60,7 +60,7 @@ export function PricingTableMatrix({ | |||||||||||
|
|
||||||||||||
| const gridTemplateColumns = React.useMemo(() => `repeat(${plans.length + 1}, minmax(9.375rem,1fr))`, [plans.length]); | ||||||||||||
|
|
||||||||||||
| const renderBillingCycleControls = React.useMemo(() => plans.some(plan => plan.annualMonthlyFee.amount > 0), [plans]); | ||||||||||||
| const renderBillingCycleControls = React.useMemo(() => plans.some(plan => Boolean(plan.annualMonthlyFee)), [plans]); | ||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Critical: Incorrect logic allows zero-cost annual plans to show billing controls. Line 63 changed to check This is inconsistent with test expectations in - const renderBillingCycleControls = React.useMemo(() => plans.some(plan => Boolean(plan.annualMonthlyFee)), [plans]);
+ const renderBillingCycleControls = React.useMemo(
+ () => plans.some(plan => Boolean(plan.annualMonthlyFee && plan.annualMonthlyFee.amount > 0)),
+ [plans]
+ );📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||
|
|
||||||||||||
| const getAllFeatures = React.useMemo(() => { | ||||||||||||
| const featuresSet = new Set<string>(); | ||||||||||||
|
|
@@ -156,12 +156,11 @@ export function PricingTableMatrix({ | |||||||||||
| </Box> | ||||||||||||
| {plans.map(plan => { | ||||||||||||
| const highlight = plan.slug === highlightedPlan; | ||||||||||||
| const planFee = | ||||||||||||
| plan.annualMonthlyFee.amount <= 0 | ||||||||||||
| ? plan.fee | ||||||||||||
| : planPeriod === 'annual' | ||||||||||||
| ? plan.annualMonthlyFee | ||||||||||||
| : plan.fee; | ||||||||||||
| const planFee = !plan.annualMonthlyFee | ||||||||||||
| ? plan.fee | ||||||||||||
| : planPeriod === 'annual' | ||||||||||||
| ? plan.annualMonthlyFee | ||||||||||||
| : plan.fee; | ||||||||||||
|
Comment on lines
+159
to
+163
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion | 🟠 Major Fee calculation should verify amount > 0 for consistency. The fee calculation on lines 159-163 uses presence checks ( - const planFee = !plan.annualMonthlyFee
+ const planFee = !plan.annualMonthlyFee || plan.annualMonthlyFee.amount === 0
? plan.fee
: planPeriod === 'annual'
? plan.annualMonthlyFee
: plan.fee;🤖 Prompt for AI Agents |
||||||||||||
|
|
||||||||||||
| return ( | ||||||||||||
| <Box | ||||||||||||
|
|
@@ -253,7 +252,7 @@ export function PricingTableMatrix({ | |||||||||||
| })} | ||||||||||||
| localizationKey={localizationKeys('billing.month')} | ||||||||||||
| /> | ||||||||||||
| {plan.annualMonthlyFee.amount > 0 ? ( | ||||||||||||
| {plan.annualMonthlyFee ? ( | ||||||||||||
| <Box | ||||||||||||
| elementDescriptor={descriptors.pricingTableMatrixFeePeriodNotice} | ||||||||||||
| sx={[ | ||||||||||||
|
|
||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -374,7 +374,7 @@ const SubscriptionCardActions = ({ subscription }: { subscription: BillingSubscr | |
| const canManageBilling = subscriberType === 'user' || canOrgManageBilling; | ||
|
|
||
| const isSwitchable = | ||
| ((subscription.planPeriod === 'month' && subscription.plan.annualMonthlyFee.amount > 0) || | ||
| ((subscription.planPeriod === 'month' && Boolean(subscription.plan.annualMonthlyFee)) || | ||
| subscription.planPeriod === 'annual') && | ||
| subscription.status !== 'past_due'; | ||
|
Comment on lines
+377
to
379
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Inconsistent annual pricing checks could cause runtime errors. Line 377 checks for Either:
const isSwitchable =
((subscription.planPeriod === 'month' && Boolean(subscription.plan.annualMonthlyFee)) ||
subscription.planPeriod === 'annual') &&
subscription.status !== 'past_due';
+
+ // Verify annualFee exists before building actions that use it
+ if (isSwitchable && subscription.planPeriod === 'month' && !subscription.plan.annualFee) {
+ return [];
+ }
🤖 Prompt for AI Agents |
||
| const isFree = isFreePlan(subscription.plan); | ||
|
|
@@ -409,8 +409,10 @@ const SubscriptionCardActions = ({ subscription }: { subscription: BillingSubscr | |
| label: | ||
| subscription.planPeriod === 'month' | ||
| ? localizationKeys('billing.switchToAnnualWithAnnualPrice', { | ||
| price: normalizeFormatted(subscription.plan.annualFee.amountFormatted), | ||
| currency: subscription.plan.annualFee.currencySymbol, | ||
| // eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
| price: normalizeFormatted(subscription.plan.annualFee!.amountFormatted), | ||
| // eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
| currency: subscription.plan.annualFee!.currencySymbol, | ||
|
Comment on lines
+412
to
+415
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unsafe non-null assertion in localization keys. The non-null assertions for Since this code path only executes when + // Ensure annualFee exists before using it
+ if (!subscription.plan.annualFee) {
+ return null;
+ }
isSwitchable
? {
label:
subscription.planPeriod === 'month'
? localizationKeys('billing.switchToAnnualWithAnnualPrice', {
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- price: normalizeFormatted(subscription.plan.annualFee!.amountFormatted),
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- currency: subscription.plan.annualFee!.currencySymbol,
+ price: normalizeFormatted(subscription.plan.annualFee.amountFormatted),
+ currency: subscription.plan.annualFee.currencySymbol,
})
🤖 Prompt for AI Agents |
||
| }) | ||
| : localizationKeys('billing.switchToMonthlyWithPrice', { | ||
| price: normalizeFormatted(subscription.plan.fee.amountFormatted), | ||
|
|
@@ -480,7 +482,11 @@ const SubscriptionCardActions = ({ subscription }: { subscription: BillingSubscr | |
| const SubscriptionCard = ({ subscription }: { subscription: BillingSubscriptionItemResource }) => { | ||
| const { t } = useLocalizations(); | ||
|
|
||
| const fee = subscription.planPeriod === 'month' ? subscription.plan.fee : subscription.plan.annualFee; | ||
| const fee = | ||
| subscription.planPeriod === 'month' | ||
| ? subscription.plan.fee | ||
| : // eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
| subscription.plan.annualFee!; | ||
|
Comment on lines
+485
to
+489
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unsafe non-null assertion in fee calculation. Using Apply this safer pattern: - const fee =
- subscription.planPeriod === 'month'
- ? subscription.plan.fee
- : // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- subscription.plan.annualFee!;
+ const fee =
+ subscription.planPeriod === 'month' || !subscription.plan.annualFee
+ ? subscription.plan.fee
+ : subscription.plan.annualFee;🤖 Prompt for AI Agents |
||
|
|
||
| return ( | ||
| <Col | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -153,7 +153,8 @@ export function SubscriptionsList({ | |||||||||||
| } | ||||||||||||
|
|
||||||||||||
| function SubscriptionRow({ subscription, length }: { subscription: BillingSubscriptionItemResource; length: number }) { | ||||||||||||
| const fee = subscription.planPeriod === 'annual' ? subscription.plan.annualFee : subscription.plan.fee; | ||||||||||||
| // eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||||||||||||
| const fee = subscription.planPeriod === 'annual' ? subscription.plan.annualFee! : subscription.plan.fee; | ||||||||||||
|
Comment on lines
+156
to
+157
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unsafe non-null assertion for annualFee. Using Apply this safer approach: - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- const fee = subscription.planPeriod === 'annual' ? subscription.plan.annualFee! : subscription.plan.fee;
+ const fee = subscription.planPeriod === 'annual' && subscription.plan.annualFee
+ ? subscription.plan.annualFee
+ : subscription.plan.fee;📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||
| const { captionForSubscription } = usePlansContext(); | ||||||||||||
|
|
||||||||||||
| const feeFormatted = useMemo(() => { | ||||||||||||
|
|
||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -25,15 +25,17 @@ export const billingTotalsFromJSON = <T extends BillingStatementTotalsJSON | Bil | |
| taxTotal: billingMoneyAmountFromJSON(data.tax_total), | ||
| }; | ||
|
|
||
| if ('total_due_now' in data) { | ||
| if ('total_due_now' in data && data.total_due_now) { | ||
| totals.totalDueNow = billingMoneyAmountFromJSON(data.total_due_now); | ||
| } | ||
| if ('credit' in data) { | ||
| if ('credit' in data && data.credit) { | ||
| totals.credit = billingMoneyAmountFromJSON(data.credit); | ||
| } | ||
| if ('past_due' in data) { | ||
| if ('past_due' in data && data.past_due) { | ||
| totals.pastDue = billingMoneyAmountFromJSON(data.past_due); | ||
| } | ||
|
|
||
| // WHY `total_due_after_free_trial` and why `proration` | ||
|
|
||
|
Comment on lines
+38
to
+39
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Clarify the purpose of this comment. The comment suggests uncertainty about 🤖 Prompt for AI Agents |
||
| return totals as T extends { total_due_now: BillingMoneyAmountJSON } ? BillingCheckoutTotals : BillingStatementTotals; | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -131,13 +131,13 @@ export interface BillingPlanResource extends ClerkResource { | |
| */ | ||
| fee: BillingMoneyAmount; | ||
| /** | ||
| * The annual price of the plan. | ||
| * The annual price of the plan or `null` if the plan is not annual. | ||
| */ | ||
| annualFee: BillingMoneyAmount; | ||
| annualFee: BillingMoneyAmount | null; | ||
| /** | ||
| * The effective monthly price when billed annually. | ||
| * The effective monthly price when billed annually or `null` if the plan is not annual. | ||
| */ | ||
| annualMonthlyFee: BillingMoneyAmount; | ||
| annualMonthlyFee: BillingMoneyAmount | null; | ||
|
Comment on lines
+134
to
+140
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chainVerify that consumer code was updated per previous review findings. The nullable type change for Ensure all flagged locations have been fixed before merging:
Based on learnings 🏁 Script executed: #!/bin/bash
# Verify that non-null assertions and unsafe Boolean checks have been addressed
echo "=== Checking for remaining non-null assertions on annual fees ==="
rg -n 'annualFee!' --type=ts -C2
echo ""
echo "=== Checking for remaining non-null assertions on annualMonthlyFee ==="
rg -n 'annualMonthlyFee!' --type=ts -C2
echo ""
echo "=== Checking for unsafe Boolean checks without null guards ==="
rg -nP 'if\s*\([^)]*\.(annualFee|annualMonthlyFee)\)' --type=ts -C2
echo ""
echo "=== Checking for direct property access without null checks ==="
rg -n '\.(annualFee|annualMonthlyFee)\.(amount|amountFormatted|currency)' --type=ts -C3Length of output: 4581 Address unsafe non-null assertions in consumer code to properly handle nullable annual fees. The nullable type changes for
While runtime logic (e.g., 🤖 Prompt for AI Agents |
||
| /** | ||
| * A short description of what the plan offers. | ||
| */ | ||
|
|
@@ -688,10 +688,10 @@ export type CreateCheckoutParams = WithOptionalOrgType<{ | |
| }>; | ||
|
|
||
| /** | ||
| * The `confirm()` method accepts the following parameters. **Only one of `paymentSourceId`, `paymentToken`, or `useTestCard` should be provided.** | ||
| * The `confirm()` method accepts the following parameters. **Only one of `paymentMethodId`, `paymentToken`, or `useTestCard` should be provided.** | ||
| * | ||
| * @unionReturnHeadings | ||
| * ["paymentSourceId", "paymentToken", "useTestCard"] | ||
| * ["paymentMethodId", "paymentToken", "useTestCard"] | ||
| * | ||
| * @experimental This is an experimental API for the Billing feature that is available under a public beta, and the API is subject to change. It is advised to [pin](https://clerk.com/docs/pinning) the SDK version and the clerk-js version to avoid breaking changes. | ||
| */ | ||
|
|
@@ -700,7 +700,7 @@ export type ConfirmCheckoutParams = | |
| /** | ||
| * The ID of a saved payment method to use for this checkout. | ||
| */ | ||
| paymentSourceId?: string; | ||
| paymentMethodId?: string; | ||
| } | ||
| | { | ||
| /** | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.