@schematichq/schematic-react 1.13.0 → 1.14.0

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.
@@ -68,11 +68,12 @@ __export(index_exports, {
68
68
  useSchematicStrings: () => useSchematicStrings,
69
69
  useSchematicTranslate: () => useSchematicTranslate,
70
70
  useSetupIntent: () => useSetupIntent,
71
+ useUnsubscribe: () => useUnsubscribe,
71
72
  useUpcomingInvoice: () => useUpcomingInvoice
72
73
  });
73
74
  module.exports = __toCommonJS(index_exports);
74
75
 
75
- // node_modules/.pnpm/@schematichq+schematic-js@1.13.0/node_modules/@schematichq/schematic-js/dist/schematic.esm.js
76
+ // node_modules/.pnpm/@schematichq+schematic-js@1.14.0/node_modules/@schematichq/schematic-js/dist/schematic.esm.js
76
77
  var __create2 = Object.create;
77
78
  var __defProp2 = Object.defineProperty;
78
79
  var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
@@ -1400,7 +1401,7 @@ var ContextSignatureManager = class {
1400
1401
  }
1401
1402
  }
1402
1403
  };
1403
- var version = "1.13.0";
1404
+ var version = "1.14.0";
1404
1405
  var SINGLETON = {};
1405
1406
  var models_exports = {};
1406
1407
  __export2(models_exports, {
@@ -1450,6 +1451,10 @@ __export2(models_exports, {
1450
1451
  CatalogPriceTierResponseDataFromJSONTyped: () => CatalogPriceTierResponseDataFromJSONTyped,
1451
1452
  CatalogPriceTierResponseDataToJSON: () => CatalogPriceTierResponseDataToJSON,
1452
1453
  CatalogPriceTierResponseDataToJSONTyped: () => CatalogPriceTierResponseDataToJSONTyped,
1454
+ CheckoutUnsubscribeResponseFromJSON: () => CheckoutUnsubscribeResponseFromJSON,
1455
+ CheckoutUnsubscribeResponseFromJSONTyped: () => CheckoutUnsubscribeResponseFromJSONTyped,
1456
+ CheckoutUnsubscribeResponseToJSON: () => CheckoutUnsubscribeResponseToJSON,
1457
+ CheckoutUnsubscribeResponseToJSONTyped: () => CheckoutUnsubscribeResponseToJSONTyped,
1453
1458
  CompanyContextCustomPlanBillingResponseDataFromJSON: () => CompanyContextCustomPlanBillingResponseDataFromJSON,
1454
1459
  CompanyContextCustomPlanBillingResponseDataFromJSONTyped: () => CompanyContextCustomPlanBillingResponseDataFromJSONTyped,
1455
1460
  CompanyContextCustomPlanBillingResponseDataToJSON: () => CompanyContextCustomPlanBillingResponseDataToJSON,
@@ -1670,6 +1675,7 @@ __export2(models_exports, {
1670
1675
  instanceOfCatalogCreditGrantResponseData: () => instanceOfCatalogCreditGrantResponseData,
1671
1676
  instanceOfCatalogPriceResponseData: () => instanceOfCatalogPriceResponseData,
1672
1677
  instanceOfCatalogPriceTierResponseData: () => instanceOfCatalogPriceTierResponseData,
1678
+ instanceOfCheckoutUnsubscribeResponse: () => instanceOfCheckoutUnsubscribeResponse,
1673
1679
  instanceOfCompanyContextCustomPlanBillingResponseData: () => instanceOfCompanyContextCustomPlanBillingResponseData,
1674
1680
  instanceOfCompanyContextPlanResponseData: () => instanceOfCompanyContextPlanResponseData,
1675
1681
  instanceOfCompanyContextResponseData: () => instanceOfCompanyContextResponseData,
@@ -2255,6 +2261,60 @@ function CatalogPriceResponseDataToJSONTyped(value, ignoreDiscriminator = false)
2255
2261
  tiers_mode: BillingTiersModeToJSON2(value["tiersMode"])
2256
2262
  };
2257
2263
  }
2264
+ function instanceOfDeleteResponse(value) {
2265
+ return true;
2266
+ }
2267
+ function DeleteResponseFromJSON(json) {
2268
+ return DeleteResponseFromJSONTyped(json, false);
2269
+ }
2270
+ function DeleteResponseFromJSONTyped(json, ignoreDiscriminator) {
2271
+ if (json == null) {
2272
+ return json;
2273
+ }
2274
+ return {
2275
+ deleted: json["deleted"] == null ? void 0 : json["deleted"]
2276
+ };
2277
+ }
2278
+ function DeleteResponseToJSON(json) {
2279
+ return DeleteResponseToJSONTyped(json, false);
2280
+ }
2281
+ function DeleteResponseToJSONTyped(value, ignoreDiscriminator = false) {
2282
+ if (value == null) {
2283
+ return value;
2284
+ }
2285
+ return {
2286
+ deleted: value["deleted"]
2287
+ };
2288
+ }
2289
+ function instanceOfCheckoutUnsubscribeResponse(value) {
2290
+ if (!("data" in value) || value["data"] === void 0) return false;
2291
+ if (!("params" in value) || value["params"] === void 0) return false;
2292
+ return true;
2293
+ }
2294
+ function CheckoutUnsubscribeResponseFromJSON(json) {
2295
+ return CheckoutUnsubscribeResponseFromJSONTyped(json, false);
2296
+ }
2297
+ function CheckoutUnsubscribeResponseFromJSONTyped(json, ignoreDiscriminator) {
2298
+ if (json == null) {
2299
+ return json;
2300
+ }
2301
+ return {
2302
+ data: DeleteResponseFromJSON(json["data"]),
2303
+ params: json["params"]
2304
+ };
2305
+ }
2306
+ function CheckoutUnsubscribeResponseToJSON(json) {
2307
+ return CheckoutUnsubscribeResponseToJSONTyped(json, false);
2308
+ }
2309
+ function CheckoutUnsubscribeResponseToJSONTyped(value, ignoreDiscriminator = false) {
2310
+ if (value == null) {
2311
+ return value;
2312
+ }
2313
+ return {
2314
+ data: DeleteResponseToJSON(value["data"]),
2315
+ params: value["params"]
2316
+ };
2317
+ }
2258
2318
  var CustomPlanActivationStrategy = {
2259
2319
  Payment: "on_payment",
2260
2320
  Publish: "on_publish"
@@ -3557,31 +3617,6 @@ function CreateSetupIntentResponseToJSONTyped(value, ignoreDiscriminator = false
3557
3617
  params: value["params"]
3558
3618
  };
3559
3619
  }
3560
- function instanceOfDeleteResponse(value) {
3561
- return true;
3562
- }
3563
- function DeleteResponseFromJSON(json) {
3564
- return DeleteResponseFromJSONTyped(json, false);
3565
- }
3566
- function DeleteResponseFromJSONTyped(json, ignoreDiscriminator) {
3567
- if (json == null) {
3568
- return json;
3569
- }
3570
- return {
3571
- deleted: json["deleted"] == null ? void 0 : json["deleted"]
3572
- };
3573
- }
3574
- function DeleteResponseToJSON(json) {
3575
- return DeleteResponseToJSONTyped(json, false);
3576
- }
3577
- function DeleteResponseToJSONTyped(value, ignoreDiscriminator = false) {
3578
- if (value == null) {
3579
- return value;
3580
- }
3581
- return {
3582
- deleted: value["deleted"]
3583
- };
3584
- }
3585
3620
  function instanceOfDeletePaymentMethodResponse(value) {
3586
3621
  if (!("data" in value) || value["data"] === void 0) return false;
3587
3622
  if (!("params" in value) || value["params"] === void 0) return false;
@@ -4411,6 +4446,9 @@ var SchematicBillingClient = class {
4411
4446
  method: "DELETE"
4412
4447
  }).then(() => void 0);
4413
4448
  }
4449
+ cancelSubscription() {
4450
+ return this.session.request("/checkout/unsubscribe", { method: "DELETE" }).then(() => void 0);
4451
+ }
4414
4452
  fetchFeatureUsage() {
4415
4453
  const path = "/company/usage";
4416
4454
  return this.session.request(path).then((body) => {
@@ -6978,6 +7016,19 @@ var BillingStore = class {
6978
7016
  await this._client.deletePaymentMethod(id);
6979
7017
  await this._reloadPaymentMethods();
6980
7018
  }
7019
+ /**
7020
+ * Cancels the subscription at period end, then reloads what that changes:
7021
+ * the company, its next bill and its credits' renewals. Rejects as
7022
+ * `setDefaultPaymentMethod` does.
7023
+ */
7024
+ async unsubscribe() {
7025
+ await this._client.cancelSubscription();
7026
+ await Promise.all([
7027
+ this._reload(this.company),
7028
+ this._reload(this.creditBalances),
7029
+ this._reload(this.upcomingInvoice)
7030
+ ]);
7031
+ }
6981
7032
  /**
6982
7033
  * Mints a setup intent for adding a payment method. Nothing in the store
6983
7034
  * changes until the provider confirms it and the host reloads the list,
@@ -6989,16 +7040,19 @@ var BillingStore = class {
6989
7040
  dispose() {
6990
7041
  this._unsubscribe?.();
6991
7042
  }
7043
+ _reloadPaymentMethods() {
7044
+ return this._reload(this.paymentMethods);
7045
+ }
6992
7046
  /**
6993
- * After a write. A list nobody has read is left alone: it loads fresh
7047
+ * After a write. A resource nobody has read is left alone: it loads fresh
6994
7048
  * when someone does. One that is loaded, or subscribed and waiting on a
6995
7049
  * failed load, is fetched again; `refetch` never rejects.
6996
7050
  */
6997
- async _reloadPaymentMethods() {
6998
- if (!this.paymentMethods.has(SINGLETON)) {
7051
+ async _reload(keyed) {
7052
+ if (!keyed.has(SINGLETON)) {
6999
7053
  return;
7000
7054
  }
7001
- const resource = this.paymentMethods.get(SINGLETON);
7055
+ const resource = keyed.get(SINGLETON);
7002
7056
  if (resource.snapshot.data !== void 0 || resource.subscriberCount > 0) {
7003
7057
  await resource.refetch();
7004
7058
  }
@@ -7100,7 +7154,8 @@ var BILLING_ACTION_UNAVAILABLE_MESSAGE = (name) => `Schematic billing action ${n
7100
7154
  var ACTION_NAMES = [
7101
7155
  "setDefaultPaymentMethod",
7102
7156
  "removePaymentMethod",
7103
- "createSetupIntent"
7157
+ "createSetupIntent",
7158
+ "unsubscribe"
7104
7159
  ];
7105
7160
  function rejectingActions(reason, given = {}) {
7106
7161
  const actions = {};
@@ -7360,6 +7415,29 @@ function useCreditUserUsage(creditId) {
7360
7415
  function useInvalidateBillingData() {
7361
7416
  return useBillingDataSource().invalidateAll;
7362
7417
  }
7418
+ function useUnsubscribe() {
7419
+ const source = useBillingDataSource();
7420
+ const [mutation, setMutation] = (0, import_react3.useState)(IDLE);
7421
+ const unsubscribe = (0, import_react3.useCallback)(async () => {
7422
+ setMutation((m) => ({ inflight: m.inflight + 1, error: void 0 }));
7423
+ try {
7424
+ await actionsOf(source).unsubscribe();
7425
+ } catch (cause) {
7426
+ const error = cause instanceof Error ? cause : new Error(String(cause));
7427
+ setMutation((m) => ({ inflight: m.inflight - 1, error }));
7428
+ throw error;
7429
+ }
7430
+ setMutation((m) => ({ inflight: m.inflight - 1, error: void 0 }));
7431
+ }, [source]);
7432
+ return (0, import_react3.useMemo)(
7433
+ () => ({
7434
+ unsubscribe,
7435
+ isMutating: mutation.inflight > 0,
7436
+ mutationError: mutation.error
7437
+ }),
7438
+ [mutation, unsubscribe]
7439
+ );
7440
+ }
7363
7441
 
7364
7442
  // src/billing/provider.tsx
7365
7443
  var import_react4 = require("react");
@@ -7441,7 +7519,8 @@ function BillingProvider({
7441
7519
  actions: {
7442
7520
  setDefaultPaymentMethod: (externalId) => store.setDefaultPaymentMethod(externalId),
7443
7521
  removePaymentMethod: (id) => store.removePaymentMethod(id),
7444
- createSetupIntent: () => store.createSetupIntent()
7522
+ createSetupIntent: () => store.createSetupIntent(),
7523
+ unsubscribe: () => store.unsubscribe()
7445
7524
  }
7446
7525
  };
7447
7526
  }, [store]);
@@ -7508,7 +7587,7 @@ function staticSource(data) {
7508
7587
  }
7509
7588
 
7510
7589
  // src/version.ts
7511
- var version2 = "1.13.0";
7590
+ var version2 = "1.14.0";
7512
7591
 
7513
7592
  // src/context/schematic.tsx
7514
7593
  var import_jsx_runtime4 = require("react/jsx-runtime");
@@ -57,6 +57,8 @@ export declare interface BillingActions {
57
57
  removePaymentMethod(id: string): Promise<void>;
58
58
  /** Mints a new setup intent every call; nothing is cached. */
59
59
  createSetupIntent(): Promise<SetupIntent>;
60
+ /** Cancels the subscription at period end and reloads what that changes. */
61
+ unsubscribe(): Promise<void>;
60
62
  }
61
63
 
62
64
  declare namespace billingApi {
@@ -121,6 +123,12 @@ declare namespace billingApi {
121
123
  CatalogPriceTierResponseDataToJSON,
122
124
  CatalogPriceTierResponseDataToJSONTyped,
123
125
  CatalogPriceTierResponseData,
126
+ instanceOfCheckoutUnsubscribeResponse,
127
+ CheckoutUnsubscribeResponseFromJSON,
128
+ CheckoutUnsubscribeResponseFromJSONTyped,
129
+ CheckoutUnsubscribeResponseToJSON,
130
+ CheckoutUnsubscribeResponseToJSONTyped,
131
+ CheckoutUnsubscribeResponse,
124
132
  instanceOfCompanyContextCustomPlanBillingResponseData,
125
133
  CompanyContextCustomPlanBillingResponseDataFromJSON,
126
134
  CompanyContextCustomPlanBillingResponseDataFromJSONTyped,
@@ -442,6 +450,12 @@ declare interface BillingClient {
442
450
  updatePaymentMethod(externalId: string): Promise<void>;
443
451
  /** Removes the method, by Schematic's id (`id`). */
444
452
  deletePaymentMethod(id: string): Promise<void>;
453
+ /**
454
+ * Cancels the company's subscription at the end of its billing period.
455
+ * Rejects when it has no single active subscription, or that one is
456
+ * already set to cancel.
457
+ */
458
+ cancelSubscription(): Promise<void>;
445
459
  /** Empty when the company is entitled to nothing. */
446
460
  fetchFeatureUsage(): Promise<FeatureUsage[]>;
447
461
  /** One event-based feature's usage by user over its metric period. */
@@ -626,7 +640,7 @@ export declare function BillingProvider({ billingClient, children, initialData,
626
640
  * much. Named apart from schematic-js's `BillingClient`, which is the whole
627
641
  * interface; this is the part the hooks here call.
628
642
  */
629
- export declare type BillingProviderClient = Pick<BillingClient, "sessionStatus" | "sessionKey" | "setSession" | "onSessionChange" | "fetchInvoices" | "fetchUpcomingInvoice" | "fetchPaymentMethods" | "createSetupIntent" | "updatePaymentMethod" | "deletePaymentMethod" | "fetchFeatureUsage" | "fetchFeatureUserUsage" | "fetchCreditBalances" | "fetchCreditUserUsage" | "fetchCompany">;
643
+ export declare type BillingProviderClient = Pick<BillingClient, "sessionStatus" | "sessionKey" | "setSession" | "onSessionChange" | "fetchInvoices" | "fetchUpcomingInvoice" | "fetchPaymentMethods" | "createSetupIntent" | "updatePaymentMethod" | "deletePaymentMethod" | "fetchFeatureUsage" | "fetchFeatureUserUsage" | "fetchCreditBalances" | "fetchCreditUserUsage" | "fetchCompany" | "cancelSubscription">;
630
644
 
631
645
  declare interface BillingProviderDataProps {
632
646
  /**
@@ -3766,6 +3780,7 @@ declare class SchematicBillingClient implements BillingClient {
3766
3780
  createSetupIntent(): Promise<SetupIntent>;
3767
3781
  updatePaymentMethod(externalId: string): Promise<void>;
3768
3782
  deletePaymentMethod(id: string): Promise<void>;
3783
+ cancelSubscription(): Promise<void>;
3769
3784
  fetchFeatureUsage(): Promise<FeatureUsage[]>;
3770
3785
  fetchCompany(): Promise<Company>;
3771
3786
  fetchCreditBalances(): Promise<CreditBalanceEntry[]>;
@@ -4252,6 +4267,19 @@ export declare const TrialStatus: {
4252
4267
 
4253
4268
  export declare type TrialStatus = (typeof TrialStatus)[keyof typeof TrialStatus];
4254
4269
 
4270
+ export declare interface UnsubscribeHandle {
4271
+ /**
4272
+ * Cancels the subscription at period end; the company, its next bill and
4273
+ * its credits reload once it lands. Rejects with the failure and records
4274
+ * it on `mutationError`.
4275
+ */
4276
+ unsubscribe: () => Promise<void>;
4277
+ /** The cancellation is in flight. */
4278
+ isMutating: boolean;
4279
+ /** The last attempt's failure; cleared when the next one starts. */
4280
+ mutationError: Error | undefined;
4281
+ }
4282
+
4255
4283
  export declare type UpcomingInvoice = CompanyUpcomingInvoiceResponseData;
4256
4284
 
4257
4285
  export declare enum UsagePeriod {
@@ -4385,6 +4413,12 @@ export declare function useSchematicTranslate(): Translate | undefined;
4385
4413
  */
4386
4414
  export declare function useSetupIntent(): SetupIntentHandle;
4387
4415
 
4416
+ /**
4417
+ * Cancels the company's subscription. Subscribes to no resource: read the
4418
+ * subscription's state from `useCompany`, which reloads once this lands.
4419
+ */
4420
+ export declare function useUnsubscribe(): UnsubscribeHandle;
4421
+
4388
4422
  /**
4389
4423
  * The company's next bill. `data` is `null` when there is nothing to bill —
4390
4424
  * no subscription, which the endpoint reports as a 204 — so an element can
@@ -1,4 +1,4 @@
1
- // node_modules/.pnpm/@schematichq+schematic-js@1.13.0/node_modules/@schematichq/schematic-js/dist/schematic.esm.js
1
+ // node_modules/.pnpm/@schematichq+schematic-js@1.14.0/node_modules/@schematichq/schematic-js/dist/schematic.esm.js
2
2
  var __create = Object.create;
3
3
  var __defProp = Object.defineProperty;
4
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -1326,7 +1326,7 @@ var ContextSignatureManager = class {
1326
1326
  }
1327
1327
  }
1328
1328
  };
1329
- var version = "1.13.0";
1329
+ var version = "1.14.0";
1330
1330
  var SINGLETON = {};
1331
1331
  var models_exports = {};
1332
1332
  __export(models_exports, {
@@ -1376,6 +1376,10 @@ __export(models_exports, {
1376
1376
  CatalogPriceTierResponseDataFromJSONTyped: () => CatalogPriceTierResponseDataFromJSONTyped,
1377
1377
  CatalogPriceTierResponseDataToJSON: () => CatalogPriceTierResponseDataToJSON,
1378
1378
  CatalogPriceTierResponseDataToJSONTyped: () => CatalogPriceTierResponseDataToJSONTyped,
1379
+ CheckoutUnsubscribeResponseFromJSON: () => CheckoutUnsubscribeResponseFromJSON,
1380
+ CheckoutUnsubscribeResponseFromJSONTyped: () => CheckoutUnsubscribeResponseFromJSONTyped,
1381
+ CheckoutUnsubscribeResponseToJSON: () => CheckoutUnsubscribeResponseToJSON,
1382
+ CheckoutUnsubscribeResponseToJSONTyped: () => CheckoutUnsubscribeResponseToJSONTyped,
1379
1383
  CompanyContextCustomPlanBillingResponseDataFromJSON: () => CompanyContextCustomPlanBillingResponseDataFromJSON,
1380
1384
  CompanyContextCustomPlanBillingResponseDataFromJSONTyped: () => CompanyContextCustomPlanBillingResponseDataFromJSONTyped,
1381
1385
  CompanyContextCustomPlanBillingResponseDataToJSON: () => CompanyContextCustomPlanBillingResponseDataToJSON,
@@ -1596,6 +1600,7 @@ __export(models_exports, {
1596
1600
  instanceOfCatalogCreditGrantResponseData: () => instanceOfCatalogCreditGrantResponseData,
1597
1601
  instanceOfCatalogPriceResponseData: () => instanceOfCatalogPriceResponseData,
1598
1602
  instanceOfCatalogPriceTierResponseData: () => instanceOfCatalogPriceTierResponseData,
1603
+ instanceOfCheckoutUnsubscribeResponse: () => instanceOfCheckoutUnsubscribeResponse,
1599
1604
  instanceOfCompanyContextCustomPlanBillingResponseData: () => instanceOfCompanyContextCustomPlanBillingResponseData,
1600
1605
  instanceOfCompanyContextPlanResponseData: () => instanceOfCompanyContextPlanResponseData,
1601
1606
  instanceOfCompanyContextResponseData: () => instanceOfCompanyContextResponseData,
@@ -2181,6 +2186,60 @@ function CatalogPriceResponseDataToJSONTyped(value, ignoreDiscriminator = false)
2181
2186
  tiers_mode: BillingTiersModeToJSON2(value["tiersMode"])
2182
2187
  };
2183
2188
  }
2189
+ function instanceOfDeleteResponse(value) {
2190
+ return true;
2191
+ }
2192
+ function DeleteResponseFromJSON(json) {
2193
+ return DeleteResponseFromJSONTyped(json, false);
2194
+ }
2195
+ function DeleteResponseFromJSONTyped(json, ignoreDiscriminator) {
2196
+ if (json == null) {
2197
+ return json;
2198
+ }
2199
+ return {
2200
+ deleted: json["deleted"] == null ? void 0 : json["deleted"]
2201
+ };
2202
+ }
2203
+ function DeleteResponseToJSON(json) {
2204
+ return DeleteResponseToJSONTyped(json, false);
2205
+ }
2206
+ function DeleteResponseToJSONTyped(value, ignoreDiscriminator = false) {
2207
+ if (value == null) {
2208
+ return value;
2209
+ }
2210
+ return {
2211
+ deleted: value["deleted"]
2212
+ };
2213
+ }
2214
+ function instanceOfCheckoutUnsubscribeResponse(value) {
2215
+ if (!("data" in value) || value["data"] === void 0) return false;
2216
+ if (!("params" in value) || value["params"] === void 0) return false;
2217
+ return true;
2218
+ }
2219
+ function CheckoutUnsubscribeResponseFromJSON(json) {
2220
+ return CheckoutUnsubscribeResponseFromJSONTyped(json, false);
2221
+ }
2222
+ function CheckoutUnsubscribeResponseFromJSONTyped(json, ignoreDiscriminator) {
2223
+ if (json == null) {
2224
+ return json;
2225
+ }
2226
+ return {
2227
+ data: DeleteResponseFromJSON(json["data"]),
2228
+ params: json["params"]
2229
+ };
2230
+ }
2231
+ function CheckoutUnsubscribeResponseToJSON(json) {
2232
+ return CheckoutUnsubscribeResponseToJSONTyped(json, false);
2233
+ }
2234
+ function CheckoutUnsubscribeResponseToJSONTyped(value, ignoreDiscriminator = false) {
2235
+ if (value == null) {
2236
+ return value;
2237
+ }
2238
+ return {
2239
+ data: DeleteResponseToJSON(value["data"]),
2240
+ params: value["params"]
2241
+ };
2242
+ }
2184
2243
  var CustomPlanActivationStrategy = {
2185
2244
  Payment: "on_payment",
2186
2245
  Publish: "on_publish"
@@ -3483,31 +3542,6 @@ function CreateSetupIntentResponseToJSONTyped(value, ignoreDiscriminator = false
3483
3542
  params: value["params"]
3484
3543
  };
3485
3544
  }
3486
- function instanceOfDeleteResponse(value) {
3487
- return true;
3488
- }
3489
- function DeleteResponseFromJSON(json) {
3490
- return DeleteResponseFromJSONTyped(json, false);
3491
- }
3492
- function DeleteResponseFromJSONTyped(json, ignoreDiscriminator) {
3493
- if (json == null) {
3494
- return json;
3495
- }
3496
- return {
3497
- deleted: json["deleted"] == null ? void 0 : json["deleted"]
3498
- };
3499
- }
3500
- function DeleteResponseToJSON(json) {
3501
- return DeleteResponseToJSONTyped(json, false);
3502
- }
3503
- function DeleteResponseToJSONTyped(value, ignoreDiscriminator = false) {
3504
- if (value == null) {
3505
- return value;
3506
- }
3507
- return {
3508
- deleted: value["deleted"]
3509
- };
3510
- }
3511
3545
  function instanceOfDeletePaymentMethodResponse(value) {
3512
3546
  if (!("data" in value) || value["data"] === void 0) return false;
3513
3547
  if (!("params" in value) || value["params"] === void 0) return false;
@@ -4337,6 +4371,9 @@ var SchematicBillingClient = class {
4337
4371
  method: "DELETE"
4338
4372
  }).then(() => void 0);
4339
4373
  }
4374
+ cancelSubscription() {
4375
+ return this.session.request("/checkout/unsubscribe", { method: "DELETE" }).then(() => void 0);
4376
+ }
4340
4377
  fetchFeatureUsage() {
4341
4378
  const path = "/company/usage";
4342
4379
  return this.session.request(path).then((body) => {
@@ -6904,6 +6941,19 @@ var BillingStore = class {
6904
6941
  await this._client.deletePaymentMethod(id);
6905
6942
  await this._reloadPaymentMethods();
6906
6943
  }
6944
+ /**
6945
+ * Cancels the subscription at period end, then reloads what that changes:
6946
+ * the company, its next bill and its credits' renewals. Rejects as
6947
+ * `setDefaultPaymentMethod` does.
6948
+ */
6949
+ async unsubscribe() {
6950
+ await this._client.cancelSubscription();
6951
+ await Promise.all([
6952
+ this._reload(this.company),
6953
+ this._reload(this.creditBalances),
6954
+ this._reload(this.upcomingInvoice)
6955
+ ]);
6956
+ }
6907
6957
  /**
6908
6958
  * Mints a setup intent for adding a payment method. Nothing in the store
6909
6959
  * changes until the provider confirms it and the host reloads the list,
@@ -6915,16 +6965,19 @@ var BillingStore = class {
6915
6965
  dispose() {
6916
6966
  this._unsubscribe?.();
6917
6967
  }
6968
+ _reloadPaymentMethods() {
6969
+ return this._reload(this.paymentMethods);
6970
+ }
6918
6971
  /**
6919
- * After a write. A list nobody has read is left alone: it loads fresh
6972
+ * After a write. A resource nobody has read is left alone: it loads fresh
6920
6973
  * when someone does. One that is loaded, or subscribed and waiting on a
6921
6974
  * failed load, is fetched again; `refetch` never rejects.
6922
6975
  */
6923
- async _reloadPaymentMethods() {
6924
- if (!this.paymentMethods.has(SINGLETON)) {
6976
+ async _reload(keyed) {
6977
+ if (!keyed.has(SINGLETON)) {
6925
6978
  return;
6926
6979
  }
6927
- const resource = this.paymentMethods.get(SINGLETON);
6980
+ const resource = keyed.get(SINGLETON);
6928
6981
  if (resource.snapshot.data !== void 0 || resource.subscriberCount > 0) {
6929
6982
  await resource.refetch();
6930
6983
  }
@@ -7026,7 +7079,8 @@ var BILLING_ACTION_UNAVAILABLE_MESSAGE = (name) => `Schematic billing action ${n
7026
7079
  var ACTION_NAMES = [
7027
7080
  "setDefaultPaymentMethod",
7028
7081
  "removePaymentMethod",
7029
- "createSetupIntent"
7082
+ "createSetupIntent",
7083
+ "unsubscribe"
7030
7084
  ];
7031
7085
  function rejectingActions(reason, given = {}) {
7032
7086
  const actions = {};
@@ -7292,6 +7346,29 @@ function useCreditUserUsage(creditId) {
7292
7346
  function useInvalidateBillingData() {
7293
7347
  return useBillingDataSource().invalidateAll;
7294
7348
  }
7349
+ function useUnsubscribe() {
7350
+ const source = useBillingDataSource();
7351
+ const [mutation, setMutation] = useState(IDLE);
7352
+ const unsubscribe = useCallback(async () => {
7353
+ setMutation((m) => ({ inflight: m.inflight + 1, error: void 0 }));
7354
+ try {
7355
+ await actionsOf(source).unsubscribe();
7356
+ } catch (cause) {
7357
+ const error = cause instanceof Error ? cause : new Error(String(cause));
7358
+ setMutation((m) => ({ inflight: m.inflight - 1, error }));
7359
+ throw error;
7360
+ }
7361
+ setMutation((m) => ({ inflight: m.inflight - 1, error: void 0 }));
7362
+ }, [source]);
7363
+ return useMemo3(
7364
+ () => ({
7365
+ unsubscribe,
7366
+ isMutating: mutation.inflight > 0,
7367
+ mutationError: mutation.error
7368
+ }),
7369
+ [mutation, unsubscribe]
7370
+ );
7371
+ }
7295
7372
 
7296
7373
  // src/billing/provider.tsx
7297
7374
  import { useEffect, useMemo as useMemo4, useRef as useRef2 } from "react";
@@ -7373,7 +7450,8 @@ function BillingProvider({
7373
7450
  actions: {
7374
7451
  setDefaultPaymentMethod: (externalId) => store.setDefaultPaymentMethod(externalId),
7375
7452
  removePaymentMethod: (id) => store.removePaymentMethod(id),
7376
- createSetupIntent: () => store.createSetupIntent()
7453
+ createSetupIntent: () => store.createSetupIntent(),
7454
+ unsubscribe: () => store.unsubscribe()
7377
7455
  }
7378
7456
  };
7379
7457
  }, [store]);
@@ -7440,7 +7518,7 @@ function staticSource(data) {
7440
7518
  }
7441
7519
 
7442
7520
  // src/version.ts
7443
- var version2 = "1.13.0";
7521
+ var version2 = "1.14.0";
7444
7522
 
7445
7523
  // src/context/schematic.tsx
7446
7524
  import { jsx as jsx4 } from "react/jsx-runtime";
@@ -7725,6 +7803,7 @@ export {
7725
7803
  useSchematicStrings,
7726
7804
  useSchematicTranslate,
7727
7805
  useSetupIntent,
7806
+ useUnsubscribe,
7728
7807
  useUpcomingInvoice
7729
7808
  };
7730
7809
  /*! Bundled license information:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@schematichq/schematic-react",
3
- "version": "1.13.0",
3
+ "version": "1.14.0",
4
4
  "main": "dist/schematic-react.cjs.js",
5
5
  "module": "dist/schematic-react.esm.js",
6
6
  "types": "dist/schematic-react.d.ts",
@@ -34,7 +34,7 @@
34
34
  "devDependencies": {
35
35
  "@eslint/js": "^10.0.1",
36
36
  "@microsoft/api-extractor": "^7.59.4",
37
- "@schematichq/schematic-js": "^1.13.0",
37
+ "@schematichq/schematic-js": "^1.14.0",
38
38
  "@testing-library/dom": "^10.4.2",
39
39
  "@testing-library/jest-dom": "^7.0.1",
40
40
  "@testing-library/react": "^16.3.3",
@@ -46,7 +46,7 @@
46
46
  "eslint-plugin-react": "^7.37.5",
47
47
  "eslint-plugin-react-hooks": "^7.1.1",
48
48
  "globals": "^17.13.0",
49
- "happy-dom": "^20.14.5",
49
+ "happy-dom": "^20.14.6",
50
50
  "husky": "^9.1.7",
51
51
  "jsdom": "^30.1.2",
52
52
  "prettier": "^3.9.9",