Skip to content

Commit d308652

Browse files
committed
[2026-07-rc] Adding in types for purchaseType and recurringCycleLimit fields
1 parent 0feb6d8 commit d308652

5 files changed

Lines changed: 61 additions & 4 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@shopify/ui-extensions': minor
3+
---
4+
5+
Add purchaseType and recurringCycleLimit subscribable fields to the DiscountsApi for discount function settings extensions.

packages/ui-extensions-tester/src/admin/README.md

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,20 @@ extension.shopify.discounts.updateDiscountClasses =
6464
.mockReturnValue(
6565
createResult('updateDiscountClasses'),
6666
);
67+
68+
extension.shopify.discounts.updatePurchaseType =
69+
vi
70+
.fn()
71+
.mockReturnValue(
72+
createResult('updatePurchaseType'),
73+
);
74+
75+
extension.shopify.discounts.updateRecurringCycleLimit =
76+
vi
77+
.fn()
78+
.mockReturnValue(
79+
createResult('updateRecurringCycleLimit'),
80+
);
6781
```
6882

6983
## 📂 Example
@@ -82,7 +96,9 @@ Creates a typed mock result for an admin mutation API.
8296

8397
Supported mutations:
8498

85-
| Mutation | Default |
86-
| ------------------------- | ---------------------------- |
87-
| `'applyMetafieldChange'` | `{type: 'success'}` |
88-
| `'updateDiscountClasses'` | `{success: true, value: []}` |
99+
| Mutation | Default |
100+
| ----------------------------- | --------------------------------------------- |
101+
| `'applyMetafieldChange'` | `{type: 'success'}` |
102+
| `'updateDiscountClasses'` | `{success: true, value: []}` |
103+
| `'updatePurchaseType'` | `{success: true, value: 'one_time_purchase'}` |
104+
| `'updateRecurringCycleLimit'` | `{success: true, value: null}` |

packages/ui-extensions-tester/src/admin/factories.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,11 @@ function createDiscountFunctionSettingsMock<T extends ExtensionTarget>(
260260
discountClasses: createReadonlySignalLike([]),
261261
updateDiscountClasses: () => createResult('updateDiscountClasses'),
262262
discountMethod: createReadonlySignalLike('automatic' as const),
263+
purchaseType: createReadonlySignalLike('one_time_purchase' as const),
264+
updatePurchaseType: () => createResult('updatePurchaseType'),
265+
recurringCycleLimit: createReadonlySignalLike(null),
266+
updateRecurringCycleLimit: () =>
267+
createResult('updateRecurringCycleLimit'),
263268
},
264269
};
265270
}

packages/ui-extensions-tester/src/admin/index.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,22 @@ export interface AdminMutationResults {
5858
| Awaited<ReturnType<ValidationApplyMetafieldChange>>
5959
| Awaited<ReturnType<DiscountApplyMetafieldChange>>;
6060
updateDiscountClasses: ReturnType<DiscountsApi['updateDiscountClasses']>;
61+
updatePurchaseType: ReturnType<DiscountsApi['updatePurchaseType']>;
62+
updateRecurringCycleLimit: ReturnType<
63+
DiscountsApi['updateRecurringCycleLimit']
64+
>;
6165
}
6266

6367
const adminMutationDefaults: {
6468
[K in keyof AdminMutationResults]: () => AdminMutationResults[K];
6569
} = {
6670
applyMetafieldChange: () => ({type: 'success'}),
6771
updateDiscountClasses: () => ({success: true as const, value: []}),
72+
updatePurchaseType: () => ({
73+
success: true as const,
74+
value: 'one_time_purchase' as const,
75+
}),
76+
updateRecurringCycleLimit: () => ({success: true as const, value: null}),
6877
};
6978

7079
/**

packages/ui-extensions/src/surfaces/admin/api/discount-function-settings/launch-options.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@ export type DiscountClass = 'product' | 'order' | 'shipping';
3434
*/
3535
export type DiscountMethod = 'automatic' | 'code';
3636

37+
/**
38+
* The purchase type that determines which purchases the discount applies to. Use `'one_time_purchase'` for one-time purchases only, `'subscription'` for subscription purchases only, or `'both'` for both.
39+
* @publicDocs
40+
*/
41+
export type PurchaseType = 'one_time_purchase' | 'subscription' | 'both';
42+
3743
/**
3844
* The `data` object exposed to discount function settings extensions in the `admin.discount-details.function-settings.render` target. Use this to access the current discount configuration and populate your settings interface with existing values.
3945
* @publicDocs
@@ -62,4 +68,20 @@ export interface DiscountsApi {
6268
* A signal that contains the discount method (`'automatic'` or `'code'`). Read this to determine whether the discount applies automatically at checkout or requires a customer-entered code.
6369
*/
6470
discountMethod: ReadonlySignalLike<DiscountMethod>;
71+
/**
72+
* A signal that contains the purchase type. Read this to determine whether the discount applies to one-time purchases, subscriptions, or both.
73+
*/
74+
purchaseType: ReadonlySignalLike<PurchaseType>;
75+
/**
76+
* A function that updates the purchase type to change which types of purchases the discount applies to. Call this with a `PurchaseType` value (`'one_time_purchase'`, `'subscription'`, or `'both'`).
77+
*/
78+
updatePurchaseType: UpdateSignalFunction<PurchaseType>;
79+
/**
80+
* A signal that contains the recurring cycle limit for subscription purchases. A positive integer limits how many billing cycles the discount applies for. Both `0` and `null` mean unlimited (no limit). `null` is the default when no value has been explicitly set.
81+
*/
82+
recurringCycleLimit: ReadonlySignalLike<number | null>;
83+
/**
84+
* A function that updates the recurring cycle limit for subscription purchases. Pass a positive integer to limit the number of billing cycles, `0` or `null` to remove the limit.
85+
*/
86+
updateRecurringCycleLimit: UpdateSignalFunction<number | null>;
6587
}

0 commit comments

Comments
 (0)