@shware/purchase 7.6.0 → 8.0.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.
Files changed (58) hide show
  1. package/README.md +25 -14
  2. package/dist/app-store/config.cjs +24 -3
  3. package/dist/app-store/config.cjs.map +1 -1
  4. package/dist/app-store/config.d.cts +14 -2
  5. package/dist/app-store/config.d.cts.map +1 -1
  6. package/dist/app-store/config.d.mts +14 -2
  7. package/dist/app-store/config.d.mts.map +1 -1
  8. package/dist/app-store/config.mjs +24 -4
  9. package/dist/app-store/config.mjs.map +1 -1
  10. package/dist/app-store/index.cjs +1 -0
  11. package/dist/app-store/index.d.cts +2 -2
  12. package/dist/app-store/index.d.mts +2 -2
  13. package/dist/app-store/index.mjs +2 -2
  14. package/dist/catalog.cjs +22 -0
  15. package/dist/catalog.cjs.map +1 -0
  16. package/dist/catalog.d.cts +21 -0
  17. package/dist/catalog.d.cts.map +1 -0
  18. package/dist/catalog.d.mts +21 -0
  19. package/dist/catalog.d.mts.map +1 -0
  20. package/dist/catalog.mjs +19 -0
  21. package/dist/catalog.mjs.map +1 -0
  22. package/dist/google-play/config.cjs +23 -3
  23. package/dist/google-play/config.cjs.map +1 -1
  24. package/dist/google-play/config.d.cts +14 -2
  25. package/dist/google-play/config.d.cts.map +1 -1
  26. package/dist/google-play/config.d.mts +14 -2
  27. package/dist/google-play/config.d.mts.map +1 -1
  28. package/dist/google-play/config.mjs +23 -4
  29. package/dist/google-play/config.mjs.map +1 -1
  30. package/dist/google-play/index.cjs +1 -0
  31. package/dist/google-play/index.d.cts +2 -2
  32. package/dist/google-play/index.d.mts +2 -2
  33. package/dist/google-play/index.mjs +2 -2
  34. package/dist/index.cjs +3 -0
  35. package/dist/index.d.cts +4 -4
  36. package/dist/index.d.mts +4 -4
  37. package/dist/index.mjs +4 -4
  38. package/dist/stripe/config.cjs +41 -4
  39. package/dist/stripe/config.cjs.map +1 -1
  40. package/dist/stripe/config.d.cts +30 -2
  41. package/dist/stripe/config.d.cts.map +1 -1
  42. package/dist/stripe/config.d.mts +30 -2
  43. package/dist/stripe/config.d.mts.map +1 -1
  44. package/dist/stripe/config.mjs +41 -5
  45. package/dist/stripe/config.mjs.map +1 -1
  46. package/dist/stripe/index.cjs +5 -0
  47. package/dist/stripe/index.d.cts +3 -2
  48. package/dist/stripe/index.d.mts +3 -2
  49. package/dist/stripe/index.mjs +3 -2
  50. package/dist/stripe/plan-change.cjs +400 -0
  51. package/dist/stripe/plan-change.cjs.map +1 -0
  52. package/dist/stripe/plan-change.d.cts +142 -0
  53. package/dist/stripe/plan-change.d.cts.map +1 -0
  54. package/dist/stripe/plan-change.d.mts +142 -0
  55. package/dist/stripe/plan-change.d.mts.map +1 -0
  56. package/dist/stripe/plan-change.mjs +397 -0
  57. package/dist/stripe/plan-change.mjs.map +1 -0
  58. package/package.json +2 -2
@@ -1,3 +1,4 @@
1
+ import { Catalog } from "../catalog.cjs";
1
2
  import { Metadata } from "../types.cjs";
2
3
  //#region src/stripe/config.d.ts
3
4
  export type PriceId = `price_${string}`;
@@ -9,6 +10,8 @@ export type PriceId = `price_${string}`;
9
10
  */
10
11
  export type StripeMode = 'live' | 'test';
11
12
  declare const addMethod: unique symbol;
13
+ /** The private constructor's one door, for this module's `define` function only. */
14
+ declare const construct: unique symbol;
12
15
  declare class Product<NS extends Lowercase<string> = Lowercase<string>, PE extends string = string, BP extends string = string, PL extends string = never, PI extends string = never, I extends PriceId = never> {
13
16
  readonly id: string;
14
17
  readonly config: StripeConfig<NS, PE, BP, PL, PI>;
@@ -35,7 +38,8 @@ declare class Product<NS extends Lowercase<string> = Lowercase<string>, PE exten
35
38
  test: PriceId;
36
39
  }) => StripeConfig<NS, PE, BP, PL, PI>;
37
40
  }
38
- type Options = {
41
+ /** `plans` and `billingPeriods` are the order {@link StripeConfig.comparePlans} reads. */
42
+ type Options<NS extends Lowercase<string>, PE extends string, BP extends string> = Catalog<NS, PE, BP> & {
39
43
  mode: StripeMode;
40
44
  returnUrl: string;
41
45
  cancelUrl: string;
@@ -43,6 +47,15 @@ type Options = {
43
47
  cancellationCouponId: string;
44
48
  allowPromotionCodes: boolean;
45
49
  };
50
+ /**
51
+ * How a switch between two subscription products relates them, by plan level first and billing
52
+ * period second:
53
+ * - `upgrade` / `downgrade`: a higher or lower plan, whatever the periods.
54
+ * - `longer` / `shorter`: the same plan billed over a longer or shorter period (monthly → yearly
55
+ * is `longer`). Apple calls these crossgrades.
56
+ * - `same`: the same plan and period.
57
+ */
58
+ export type PlanComparison = 'upgrade' | 'downgrade' | 'longer' | 'shorter' | 'same';
46
59
  export declare class StripeConfig<NS extends Lowercase<string> = Lowercase<string>, PE extends string = string, BP extends string = string, PL extends string = never, PI extends string = never> {
47
60
  private readonly products;
48
61
  readonly mode: StripeMode;
@@ -51,10 +64,13 @@ export declare class StripeConfig<NS extends Lowercase<string> = Lowercase<strin
51
64
  successUrl: `${string}session_id={CHECKOUT_SESSION_ID}${string}`;
52
65
  cancellationCouponId: string;
53
66
  allowPromotionCodes: boolean;
67
+ readonly namespace: NS;
68
+ readonly plans: readonly PE[];
69
+ readonly billingPeriods: readonly BP[];
54
70
  get productIds(): string[];
55
71
  [addMethod]: (product: Product<NS, PE, BP, PL, PI>) => this;
56
72
  private constructor();
57
- static create: <NS_1 extends Lowercase<string>, PE_1 extends string, BP_1 extends string = string>(options: Options) => StripeConfig<NS_1, PE_1, BP_1, never, never>;
73
+ static [construct]: <NS_1 extends Lowercase<string>, PE_1 extends string, BP_1 extends string>(options: Options<NS_1, PE_1, BP_1>) => StripeConfig<NS_1, PE_1, BP_1, never, never>;
58
74
  /**
59
75
  * One-time products take no extra args; subscriptions require both plan and billingPeriod.
60
76
  * A plan+period pair may be declared on only one product — version its prices in that chain.
@@ -81,10 +97,22 @@ export declare class StripeConfig<NS extends Lowercase<string> = Lowercase<strin
81
97
  * metadata that may already name the next plan, is what an invoice should be credited by.
82
98
  */
83
99
  getProductId: (priceId: string) => string | null;
100
+ /**
101
+ * How switching from one subscription product to another relates them (see
102
+ * {@link PlanComparison}), by the order `plans` and `billingPeriods` were declared in. Throws for
103
+ * a product that is not a subscription.
104
+ */
105
+ comparePlans: (fromProductId: string, toProductId: string) => PlanComparison;
84
106
  getCreditAmount: (productId: string, priceId?: string) => number;
85
107
  private readonly getCreditExpiresIn;
86
108
  getCreditExpiresAt: (productId: string, priceId?: string) => string;
87
109
  }
110
+ /**
111
+ * Declare the Stripe product catalog. Every type parameter is inferred from the options:
112
+ * the namespace from `namespace`, the plans and billing periods from `plans` and `billingPeriods`
113
+ * (`const`, so a literal array needs no `as const`). Products are then added with the fluent chain.
114
+ */
115
+ export declare function defineStripeConfig<const NS extends Lowercase<string>, const PE extends string, const BP extends string>(options: Options<NS, PE, BP>): StripeConfig<NS, PE, BP>;
88
116
  //#endregion
89
117
  export {};
90
118
  //# sourceMappingURL=config.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.cts","names":[],"sources":["../../src/stripe/config.ts"],"mappings":";;YAIY;;;;;;;YAQA;cAEN;cAEA,QACJ,WAAW,oBAAoB,mBAC/B,4BACA,4BACA,2BACA,2BACA,UAAU;WAED;WACA,QAAQ,aAAa,IAAI,IAAI,IAAI,IAAI;WACrC,MAAM;WACN,eAAe;WACf,QAAQ,IAAI,SAAS;EAE9B,gBAAgB;EAEhB,YACE,QAAQ,aAAa,IAAI,IAAI,IAAI,IAAI,KACrC,YACA,OAAM,WACN,gBAAe;;;;;;EAejB,QAAS,UAAU,SAAO,SACf,UAAU,YAAY,GAAC,WACtB,aACT,QAAQ,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI;;;;;;;;;EAcnC,UAAO,gBAAoB,GAAC;IAAW,MAAM;QAAS,aAAA,IAAA,IAAA,IAAA,IAAA;;KAgBnD;EACH,MAAM;EACN;EACA;EACA;EACA;EACA;;qBAGW,aACX,WAAW,oBAAoB,mBAC/B,4BACA,4BACA,2BACA;mBAEiB;WAED,MAAM;EACf;EACA;EACA;EACA;EACA;MAEH;GAMH,aAAU,SAAa,QAAQ,IAAI,IAAI,IAAI,IAAI;UAoBzC;SASA,SAAU,aAAW,mBAAmB,qBAAmB,8BAA0B,SACjF,YAAO,aAAA,MAAA,MAAA;;;;;EASlB;KACG,aAAa,MAAM,qBAClB,WAAW,UAAU,aAAa,IACjC,QAAQ,IAAI,IAAI,IAAI,IAAI,IAAI;KAC9B,aAAa,MAAM,qBAAqB,UAAU,IAAI,UAAU,IAC/D,WAAW,UAAU,aAAa,GAClC,MAAM,GACN,kBAAkB,KAAK,YAAY,aAAa,IAC/C,QAAQ,IAAI,IAAI,OAAO,KAAK,MAAM,IAAI,IAAI;;EAK/C,UAAO,sBAAwB;EAO/B,mBAAgB,sBAAwB;EAOxC,UAAO;;;;;;EAWP,iBAAc;;EAMd,aAAU,sBAAwB;;;;;;;EAalC,eAAY;EAOZ,kBAAe,mBAAqB;mBAanB;EAajB,qBAAkB,mBAAqB"}
1
+ {"version":3,"file":"config.d.cts","names":[],"sources":["../../src/stripe/config.ts"],"mappings":";;;YAKY;;;;;;;YAQA;cAEN;;cAEA;cAEA,QACJ,WAAW,oBAAoB,mBAC/B,4BACA,4BACA,2BACA,2BACA,UAAU;WAED;WACA,QAAQ,aAAa,IAAI,IAAI,IAAI,IAAI;WACrC,MAAM;WACN,eAAe;WACf,QAAQ,IAAI,SAAS;EAE9B,gBAAgB;EAEhB,YACE,QAAQ,aAAa,IAAI,IAAI,IAAI,IAAI,KACrC,YACA,OAAM,WACN,gBAAe;;;;;;EAejB,QAAS,UAAU,SAAO,SACf,UAAU,YAAY,GAAC,WACtB,aACT,QAAQ,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI;;;;;;;;;EAcnC,UAAO,gBAAoB,GAAC;IAAW,MAAM;QAAS,aAAA,IAAA,IAAA,IAAA,IAAA;;;KAiBnD,QAAQ,WAAW,mBAAmB,mBAAmB,qBAAqB,QACjF,IACA,IACA;EAEA,MAAM;EACN;EACA;EACA;EACA;EACA;;;;;;;;;;YAWU;qBAEC,aACX,WAAW,oBAAoB,mBAC/B,4BACA,4BACA,2BACA;mBAEiB;WAED,MAAM;EACf;EACA;EACA;EACA;EACA;WACS,WAAW;WACX,gBAAgB;WAChB,yBAAyB;MAErC;GAMH,aAAU,SAAa,QAAQ,IAAI,IAAI,IAAI,IAAI;UAoBzC;UAaC,aAAc,aAAW,mBAAmB,qBAAmB,qBAAiB,SAC7E,QAAQ,MAAI,MAAI,UAAG,aAAA,MAAA,MAAA;;;;;EAO9B;KACG,aAAa,MAAM,qBAClB,WAAW,UAAU,aAAa,IACjC,QAAQ,IAAI,IAAI,IAAI,IAAI,IAAI;KAC9B,aAAa,MAAM,qBAAqB,UAAU,IAAI,UAAU,IAC/D,WAAW,UAAU,aAAa,GAClC,MAAM,GACN,kBAAkB,KAAK,YAAY,aAAa,IAC/C,QAAQ,IAAI,IAAI,OAAO,KAAK,MAAM,IAAI,IAAI;;EAQ/C,UAAO,sBAAwB;EAO/B,mBAAgB,sBAAwB;EAOxC,UAAO;;;;;;EAWP,iBAAc;;EAMd,aAAU,sBAAwB;;;;;;;EAalC,eAAY;;;;;;EAYZ,eAAY,uBAAyB,wBAAwB;EAY7D,kBAAe,mBAAqB;mBAanB;EAajB,qBAAkB,mBAAqB;;;;;;;wBAWzB,yBACR,WAAW,yBACX,yBACA,mBACN,SAAS,QAAQ,IAAI,IAAI,MAAM,aAAa,IAAI,IAAI"}
@@ -1,3 +1,4 @@
1
+ import { Catalog } from "../catalog.mjs";
1
2
  import { Metadata } from "../types.mjs";
2
3
  //#region src/stripe/config.d.ts
3
4
  export type PriceId = `price_${string}`;
@@ -9,6 +10,8 @@ export type PriceId = `price_${string}`;
9
10
  */
10
11
  export type StripeMode = 'live' | 'test';
11
12
  declare const addMethod: unique symbol;
13
+ /** The private constructor's one door, for this module's `define` function only. */
14
+ declare const construct: unique symbol;
12
15
  declare class Product<NS extends Lowercase<string> = Lowercase<string>, PE extends string = string, BP extends string = string, PL extends string = never, PI extends string = never, I extends PriceId = never> {
13
16
  readonly id: string;
14
17
  readonly config: StripeConfig<NS, PE, BP, PL, PI>;
@@ -35,7 +38,8 @@ declare class Product<NS extends Lowercase<string> = Lowercase<string>, PE exten
35
38
  test: PriceId;
36
39
  }) => StripeConfig<NS, PE, BP, PL, PI>;
37
40
  }
38
- type Options = {
41
+ /** `plans` and `billingPeriods` are the order {@link StripeConfig.comparePlans} reads. */
42
+ type Options<NS extends Lowercase<string>, PE extends string, BP extends string> = Catalog<NS, PE, BP> & {
39
43
  mode: StripeMode;
40
44
  returnUrl: string;
41
45
  cancelUrl: string;
@@ -43,6 +47,15 @@ type Options = {
43
47
  cancellationCouponId: string;
44
48
  allowPromotionCodes: boolean;
45
49
  };
50
+ /**
51
+ * How a switch between two subscription products relates them, by plan level first and billing
52
+ * period second:
53
+ * - `upgrade` / `downgrade`: a higher or lower plan, whatever the periods.
54
+ * - `longer` / `shorter`: the same plan billed over a longer or shorter period (monthly → yearly
55
+ * is `longer`). Apple calls these crossgrades.
56
+ * - `same`: the same plan and period.
57
+ */
58
+ export type PlanComparison = 'upgrade' | 'downgrade' | 'longer' | 'shorter' | 'same';
46
59
  export declare class StripeConfig<NS extends Lowercase<string> = Lowercase<string>, PE extends string = string, BP extends string = string, PL extends string = never, PI extends string = never> {
47
60
  private readonly products;
48
61
  readonly mode: StripeMode;
@@ -51,10 +64,13 @@ export declare class StripeConfig<NS extends Lowercase<string> = Lowercase<strin
51
64
  successUrl: `${string}session_id={CHECKOUT_SESSION_ID}${string}`;
52
65
  cancellationCouponId: string;
53
66
  allowPromotionCodes: boolean;
67
+ readonly namespace: NS;
68
+ readonly plans: readonly PE[];
69
+ readonly billingPeriods: readonly BP[];
54
70
  get productIds(): string[];
55
71
  [addMethod]: (product: Product<NS, PE, BP, PL, PI>) => this;
56
72
  private constructor();
57
- static create: <NS_1 extends Lowercase<string>, PE_1 extends string, BP_1 extends string = string>(options: Options) => StripeConfig<NS_1, PE_1, BP_1, never, never>;
73
+ static [construct]: <NS_1 extends Lowercase<string>, PE_1 extends string, BP_1 extends string>(options: Options<NS_1, PE_1, BP_1>) => StripeConfig<NS_1, PE_1, BP_1, never, never>;
58
74
  /**
59
75
  * One-time products take no extra args; subscriptions require both plan and billingPeriod.
60
76
  * A plan+period pair may be declared on only one product — version its prices in that chain.
@@ -81,10 +97,22 @@ export declare class StripeConfig<NS extends Lowercase<string> = Lowercase<strin
81
97
  * metadata that may already name the next plan, is what an invoice should be credited by.
82
98
  */
83
99
  getProductId: (priceId: string) => string | null;
100
+ /**
101
+ * How switching from one subscription product to another relates them (see
102
+ * {@link PlanComparison}), by the order `plans` and `billingPeriods` were declared in. Throws for
103
+ * a product that is not a subscription.
104
+ */
105
+ comparePlans: (fromProductId: string, toProductId: string) => PlanComparison;
84
106
  getCreditAmount: (productId: string, priceId?: string) => number;
85
107
  private readonly getCreditExpiresIn;
86
108
  getCreditExpiresAt: (productId: string, priceId?: string) => string;
87
109
  }
110
+ /**
111
+ * Declare the Stripe product catalog. Every type parameter is inferred from the options:
112
+ * the namespace from `namespace`, the plans and billing periods from `plans` and `billingPeriods`
113
+ * (`const`, so a literal array needs no `as const`). Products are then added with the fluent chain.
114
+ */
115
+ export declare function defineStripeConfig<const NS extends Lowercase<string>, const PE extends string, const BP extends string>(options: Options<NS, PE, BP>): StripeConfig<NS, PE, BP>;
88
116
  //#endregion
89
117
  export {};
90
118
  //# sourceMappingURL=config.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.mts","names":[],"sources":["../../src/stripe/config.ts"],"mappings":";;YAIY;;;;;;;YAQA;cAEN;cAEA,QACJ,WAAW,oBAAoB,mBAC/B,4BACA,4BACA,2BACA,2BACA,UAAU;WAED;WACA,QAAQ,aAAa,IAAI,IAAI,IAAI,IAAI;WACrC,MAAM;WACN,eAAe;WACf,QAAQ,IAAI,SAAS;EAE9B,gBAAgB;EAEhB,YACE,QAAQ,aAAa,IAAI,IAAI,IAAI,IAAI,KACrC,YACA,OAAM,WACN,gBAAe;;;;;;EAejB,QAAS,UAAU,SAAO,SACf,UAAU,YAAY,GAAC,WACtB,aACT,QAAQ,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI;;;;;;;;;EAcnC,UAAO,gBAAoB,GAAC;IAAW,MAAM;QAAS,aAAA,IAAA,IAAA,IAAA,IAAA;;KAgBnD;EACH,MAAM;EACN;EACA;EACA;EACA;EACA;;qBAGW,aACX,WAAW,oBAAoB,mBAC/B,4BACA,4BACA,2BACA;mBAEiB;WAED,MAAM;EACf;EACA;EACA;EACA;EACA;MAEH;GAMH,aAAU,SAAa,QAAQ,IAAI,IAAI,IAAI,IAAI;UAoBzC;SASA,SAAU,aAAW,mBAAmB,qBAAmB,8BAA0B,SACjF,YAAO,aAAA,MAAA,MAAA;;;;;EASlB;KACG,aAAa,MAAM,qBAClB,WAAW,UAAU,aAAa,IACjC,QAAQ,IAAI,IAAI,IAAI,IAAI,IAAI;KAC9B,aAAa,MAAM,qBAAqB,UAAU,IAAI,UAAU,IAC/D,WAAW,UAAU,aAAa,GAClC,MAAM,GACN,kBAAkB,KAAK,YAAY,aAAa,IAC/C,QAAQ,IAAI,IAAI,OAAO,KAAK,MAAM,IAAI,IAAI;;EAK/C,UAAO,sBAAwB;EAO/B,mBAAgB,sBAAwB;EAOxC,UAAO;;;;;;EAWP,iBAAc;;EAMd,aAAU,sBAAwB;;;;;;;EAalC,eAAY;EAOZ,kBAAe,mBAAqB;mBAanB;EAajB,qBAAkB,mBAAqB"}
1
+ {"version":3,"file":"config.d.mts","names":[],"sources":["../../src/stripe/config.ts"],"mappings":";;;YAKY;;;;;;;YAQA;cAEN;;cAEA;cAEA,QACJ,WAAW,oBAAoB,mBAC/B,4BACA,4BACA,2BACA,2BACA,UAAU;WAED;WACA,QAAQ,aAAa,IAAI,IAAI,IAAI,IAAI;WACrC,MAAM;WACN,eAAe;WACf,QAAQ,IAAI,SAAS;EAE9B,gBAAgB;EAEhB,YACE,QAAQ,aAAa,IAAI,IAAI,IAAI,IAAI,KACrC,YACA,OAAM,WACN,gBAAe;;;;;;EAejB,QAAS,UAAU,SAAO,SACf,UAAU,YAAY,GAAC,WACtB,aACT,QAAQ,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI;;;;;;;;;EAcnC,UAAO,gBAAoB,GAAC;IAAW,MAAM;QAAS,aAAA,IAAA,IAAA,IAAA,IAAA;;;KAiBnD,QAAQ,WAAW,mBAAmB,mBAAmB,qBAAqB,QACjF,IACA,IACA;EAEA,MAAM;EACN;EACA;EACA;EACA;EACA;;;;;;;;;;YAWU;qBAEC,aACX,WAAW,oBAAoB,mBAC/B,4BACA,4BACA,2BACA;mBAEiB;WAED,MAAM;EACf;EACA;EACA;EACA;EACA;WACS,WAAW;WACX,gBAAgB;WAChB,yBAAyB;MAErC;GAMH,aAAU,SAAa,QAAQ,IAAI,IAAI,IAAI,IAAI;UAoBzC;UAaC,aAAc,aAAW,mBAAmB,qBAAmB,qBAAiB,SAC7E,QAAQ,MAAI,MAAI,UAAG,aAAA,MAAA,MAAA;;;;;EAO9B;KACG,aAAa,MAAM,qBAClB,WAAW,UAAU,aAAa,IACjC,QAAQ,IAAI,IAAI,IAAI,IAAI,IAAI;KAC9B,aAAa,MAAM,qBAAqB,UAAU,IAAI,UAAU,IAC/D,WAAW,UAAU,aAAa,GAClC,MAAM,GACN,kBAAkB,KAAK,YAAY,aAAa,IAC/C,QAAQ,IAAI,IAAI,OAAO,KAAK,MAAM,IAAI,IAAI;;EAQ/C,UAAO,sBAAwB;EAO/B,mBAAgB,sBAAwB;EAOxC,UAAO;;;;;;EAWP,iBAAc;;EAMd,aAAU,sBAAwB;;;;;;;EAalC,eAAY;;;;;;EAYZ,eAAY,uBAAyB,wBAAwB;EAY7D,kBAAe,mBAAqB;mBAanB;EAajB,qBAAkB,mBAAqB;;;;;;;wBAWzB,yBACR,WAAW,yBACX,yBACA,mBACN,SAAS,QAAQ,IAAI,IAAI,MAAM,aAAa,IAAI,IAAI"}
@@ -1,7 +1,10 @@
1
+ import { assertCatalog, assertDeclared, assertInNamespace } from "../catalog.mjs";
1
2
  import { invariant } from "@shware/utils";
2
3
  import ms from "ms";
3
4
  //#region src/stripe/config.ts
4
5
  const addMethod = Symbol("addMethod");
6
+ /** The private constructor's one door, for this module's `define` function only. */
7
+ const construct = Symbol("construct");
5
8
  var Product = class {
6
9
  id;
7
10
  config;
@@ -59,6 +62,9 @@ var StripeConfig = class StripeConfig {
59
62
  successUrl;
60
63
  cancellationCouponId;
61
64
  allowPromotionCodes;
65
+ namespace;
66
+ plans;
67
+ billingPeriods;
62
68
  get productIds() {
63
69
  return Array.from(this.products.keys());
64
70
  }
@@ -70,6 +76,10 @@ var StripeConfig = class StripeConfig {
70
76
  return this;
71
77
  };
72
78
  constructor(options) {
79
+ assertCatalog(options);
80
+ this.namespace = options.namespace;
81
+ this.plans = options.plans;
82
+ this.billingPeriods = options.billingPeriods;
73
83
  this.mode = options.mode;
74
84
  this.returnUrl = options.returnUrl;
75
85
  this.cancelUrl = options.cancelUrl;
@@ -77,14 +87,16 @@ var StripeConfig = class StripeConfig {
77
87
  this.cancellationCouponId = options.cancellationCouponId;
78
88
  this.allowPromotionCodes = options.allowPromotionCodes;
79
89
  }
80
- static create = (options) => {
81
- return new StripeConfig(options);
82
- };
90
+ static [construct] = (options) => new StripeConfig(options);
83
91
  /**
84
92
  * One-time products take no extra args; subscriptions require both plan and billingPeriod.
85
93
  * A plan+period pair may be declared on only one product — version its prices in that chain.
86
94
  */
87
- product = (productId, plan = null, billingPeriod = null) => new Product(this, productId, plan, billingPeriod);
95
+ product = (productId, plan = null, billingPeriod = null) => {
96
+ assertInNamespace(this.namespace, productId);
97
+ assertDeclared(this, plan, billingPeriod);
98
+ return new Product(this, productId, plan, billingPeriod);
99
+ };
88
100
  getPlan = (productId) => {
89
101
  const product = this.products.get(productId);
90
102
  invariant(product, `Product not found for ${productId}`);
@@ -128,6 +140,22 @@ var StripeConfig = class StripeConfig {
128
140
  for (const product of this.products.values()) if (product.prices.has(priceId)) return product.id;
129
141
  return null;
130
142
  };
143
+ /**
144
+ * How switching from one subscription product to another relates them (see
145
+ * {@link PlanComparison}), by the order `plans` and `billingPeriods` were declared in. Throws for
146
+ * a product that is not a subscription.
147
+ */
148
+ comparePlans = (fromProductId, toProductId) => {
149
+ const level = (productId) => ({
150
+ plan: this.plans.indexOf(this.getPlan(productId)),
151
+ period: this.billingPeriods.indexOf(this.getBillingPeriod(productId))
152
+ });
153
+ const from = level(fromProductId);
154
+ const to = level(toProductId);
155
+ if (to.plan !== from.plan) return to.plan > from.plan ? "upgrade" : "downgrade";
156
+ if (to.period !== from.period) return to.period > from.period ? "longer" : "shorter";
157
+ return "same";
158
+ };
131
159
  getCreditAmount = (productId, priceId) => {
132
160
  const product = this.products.get(productId);
133
161
  invariant(product, `Product not found for ${productId}`);
@@ -155,7 +183,15 @@ var StripeConfig = class StripeConfig {
155
183
  return new Date(Date.now() + expiresIn).toISOString();
156
184
  };
157
185
  };
186
+ /**
187
+ * Declare the Stripe product catalog. Every type parameter is inferred from the options:
188
+ * the namespace from `namespace`, the plans and billing periods from `plans` and `billingPeriods`
189
+ * (`const`, so a literal array needs no `as const`). Products are then added with the fluent chain.
190
+ */
191
+ function defineStripeConfig(options) {
192
+ return StripeConfig[construct](options);
193
+ }
158
194
  //#endregion
159
- export { StripeConfig };
195
+ export { StripeConfig, defineStripeConfig };
160
196
 
161
197
  //# sourceMappingURL=config.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.mjs","names":[],"sources":["../../src/stripe/config.ts"],"sourcesContent":["import { invariant } from '@shware/utils';\nimport ms from 'ms';\nimport type { Metadata } from '../types';\n\nexport type PriceId = `price_${string}`;\n\n/**\n * Which Stripe object space the config addresses. Test and live prices are\n * disjoint, so a config is built for exactly one of them. Derive it from the\n * secret key (`sk_test_` vs `sk_live_`) rather than from the deployment\n * environment: the key is what actually decides which space API calls hit.\n */\nexport type StripeMode = 'live' | 'test';\n\nconst addMethod = Symbol('addMethod');\n\nclass Product<\n NS extends Lowercase<string> = Lowercase<string>,\n PE extends string = string,\n BP extends string = string,\n PL extends string = never,\n PI extends string = never,\n I extends PriceId = never,\n> {\n readonly id: string;\n readonly config: StripeConfig<NS, PE, BP, PL, PI>;\n readonly plan: PE | null;\n readonly billingPeriod: BP | null;\n readonly prices: Map<PriceId, Metadata>;\n\n defaultPriceId: PriceId | null;\n\n constructor(\n config: StripeConfig<NS, PE, BP, PL, PI>,\n id: string,\n plan: PE | null = null,\n billingPeriod: BP | null = null\n ) {\n this.id = id;\n this.config = config;\n this.plan = plan;\n this.billingPeriod = billingPeriod;\n this.prices = new Map();\n this.defaultPriceId = null;\n }\n\n /**\n * Non-default prices stay declared on purpose: they keep resolving for\n * grandfathered subscribers and serve as price-experiment arms. Never\n * create new checkouts with a legacy price unless that is intentional.\n */\n price = <K extends PriceId>(\n priceId: K extends I ? never : K,\n metadata: Metadata = { credits: 0, expiresIn: '0' }\n ): Product<NS, PE, BP, PL, PI, I | K> => {\n invariant(!this.prices.has(priceId), `Duplicate price ${priceId}`);\n this.prices.set(priceId, metadata);\n return this as Product<NS, PE, BP, PL, PI, I | K>;\n };\n\n /**\n * `test` is the sandbox twin of the default price. In test mode it is what\n * checkouts are created with, and it resolves to the default price's\n * entitlement, so credits are declared once and cannot drift between the\n * two modes. Legacy prices need no twin: a sandbox holds no grandfathered\n * subscribers. Live mode ignores it, so a test price reaching a live config\n * still fails as an unknown price instead of being granted an entitlement.\n */\n default = (defaultPriceId: I, twin?: { test: PriceId }) => {\n const metadata = this.prices.get(defaultPriceId);\n invariant(metadata, `Default price ${defaultPriceId} is not declared`);\n if (this.config.mode === 'test') {\n invariant(twin, `Test price not declared for default ${defaultPriceId} of ${this.id}`);\n invariant(!this.prices.has(twin.test), `Duplicate price ${twin.test}`);\n this.prices.set(twin.test, metadata);\n this.defaultPriceId = twin.test;\n } else {\n this.defaultPriceId = defaultPriceId;\n }\n this.config[addMethod](this);\n return this.config;\n };\n}\n\ntype Options = {\n mode: StripeMode;\n returnUrl: string;\n cancelUrl: string;\n successUrl: `${string}session_id={CHECKOUT_SESSION_ID}${string}`;\n cancellationCouponId: string;\n allowPromotionCodes: boolean;\n};\n\nexport class StripeConfig<\n NS extends Lowercase<string> = Lowercase<string>,\n PE extends string = string,\n BP extends string = string,\n PL extends string = never,\n PI extends string = never,\n> {\n private readonly products: Map<string, Product<NS, PE, BP, PL, PI>> = new Map();\n\n public readonly mode: StripeMode;\n public returnUrl: string;\n public cancelUrl: string;\n public successUrl: `${string}session_id={CHECKOUT_SESSION_ID}${string}`;\n public cancellationCouponId: string;\n public allowPromotionCodes: boolean;\n\n get productIds(): string[] {\n return Array.from(this.products.keys());\n }\n\n // runtime mirror of the type-level guards: generic accumulation only\n // protects a single fluent chain, not statement-style re-entry or casts\n [addMethod] = (product: Product<NS, PE, BP, PL, PI>) => {\n invariant(!this.products.has(product.id), `Duplicate product ${product.id}`);\n // A Stripe price belongs to one Stripe product, and getProductId must have one answer.\n for (const existing of this.products.values()) {\n for (const priceId of product.prices.keys()) {\n invariant(!existing.prices.has(priceId), `Duplicate price ${priceId} on ${existing.id}`);\n }\n }\n if (product.plan !== null) {\n for (const existing of this.products.values()) {\n invariant(\n existing.plan !== product.plan || existing.billingPeriod !== product.billingPeriod,\n `Duplicate plan ${product.plan}:${product.billingPeriod}`\n );\n }\n }\n this.products.set(product.id, product);\n return this;\n };\n\n private constructor(options: Options) {\n this.mode = options.mode;\n this.returnUrl = options.returnUrl;\n this.cancelUrl = options.cancelUrl;\n this.successUrl = options.successUrl;\n this.cancellationCouponId = options.cancellationCouponId;\n this.allowPromotionCodes = options.allowPromotionCodes;\n }\n\n static create = <NS extends Lowercase<string>, PE extends string, BP extends string = string>(\n options: Options\n ) => {\n return new StripeConfig<NS, PE, BP>(options);\n };\n\n /**\n * One-time products take no extra args; subscriptions require both plan and billingPeriod.\n * A plan+period pair may be declared on only one product — version its prices in that chain.\n */\n product: {\n <K extends `${NS}.${Lowercase<string>}`>(\n productId: K extends PI ? never : K\n ): Product<NS, PE, BP, PL, K | PI>;\n <K extends `${NS}.${Lowercase<string>}`, L extends PE, P extends BP>(\n productId: K extends PI ? never : K,\n plan: L,\n billingPeriod: `${L}:${P}` extends PL ? never : P\n ): Product<NS, PE, BP, `${L}:${P}` | PL, K | PI>;\n } = (productId: string, plan: PE | null = null, billingPeriod: BP | null = null) =>\n // oxlint-disable-next-line typescript/no-unnecessary-type-assertion -- widens to the overloads' accumulated generics\n new Product(this, productId, plan, billingPeriod) as never;\n\n getPlan = (productId: string): PE => {\n const product = this.products.get(productId);\n invariant(product, `Product not found for ${productId}`);\n invariant(product.plan, `Product ${productId} is not a subscription`);\n return product.plan;\n };\n\n getBillingPeriod = (productId: string): BP => {\n const product = this.products.get(productId);\n invariant(product, `Product not found for ${productId}`);\n invariant(product.billingPeriod, `Product ${productId} is not a subscription`);\n return product.billingPeriod;\n };\n\n getMode = (productId: string): 'payment' | 'subscription' => {\n const product = this.products.get(productId);\n invariant(product, `Product not found for ${productId}`);\n return product.plan === null ? 'payment' : 'subscription';\n };\n\n /**\n * Whether the config declares `productId` and sells it as a subscription, so `getPlan` and\n * `getBillingPeriod` hold for it. False, not a throw, for an id it does not know: a product that\n * left the config (renamed, retired) or one named by metadata set outside the app.\n */\n isSubscription = (productId: string): boolean => {\n const product = this.products.get(productId);\n return product !== undefined && product.plan !== null;\n };\n\n /** The price new checkouts are created with: the default, or its test twin in test mode. */\n getPriceId = (productId: string): PriceId => {\n const product = this.products.get(productId);\n invariant(product, `Product not found for ${productId}`);\n invariant(product.defaultPriceId, `Default price not found for product ${productId}`);\n return product.defaultPriceId;\n };\n\n /**\n * The product that declares `priceId` (a legacy price or the test twin included), or null for a\n * price this config does not know: one set up by hand in the dashboard, or a test price reaching\n * a live config. Reading the product from the price a Stripe object charged, rather than from\n * metadata that may already name the next plan, is what an invoice should be credited by.\n */\n getProductId = (priceId: string): string | null => {\n for (const product of this.products.values()) {\n if (product.prices.has(priceId as PriceId)) return product.id;\n }\n return null;\n };\n\n getCreditAmount = (productId: string, priceId?: string): number => {\n const product = this.products.get(productId);\n invariant(product, `Product not found for ${productId}`);\n if (priceId) {\n const price = product.prices.get(priceId as PriceId);\n invariant(price, `Price not found for ${priceId}`);\n return price.credits;\n }\n\n invariant(product.defaultPriceId, `Default price not found for product ${productId}`);\n return product.prices.get(product.defaultPriceId)?.credits ?? 0;\n };\n\n private readonly getCreditExpiresIn = (productId: string, priceId?: string): number => {\n const product = this.products.get(productId);\n invariant(product, `Product not found for ${productId}`);\n if (priceId) {\n const price = product.prices.get(priceId as PriceId);\n invariant(price, `Price not found for ${priceId}`);\n return ms(price.expiresIn);\n }\n\n invariant(product.defaultPriceId, `Default price not found for product ${productId}`);\n return ms(product.prices.get(product.defaultPriceId)?.expiresIn ?? '0');\n };\n\n getCreditExpiresAt = (productId: string, priceId?: string): string => {\n const expiresIn = this.getCreditExpiresIn(productId, priceId);\n return new Date(Date.now() + expiresIn).toISOString();\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"config.mjs","names":[],"sources":["../../src/stripe/config.ts"],"sourcesContent":["import { invariant } from '@shware/utils';\nimport ms from 'ms';\nimport { type Catalog, assertCatalog, assertDeclared, assertInNamespace } from '../catalog';\nimport type { Metadata } from '../types';\n\nexport type PriceId = `price_${string}`;\n\n/**\n * Which Stripe object space the config addresses. Test and live prices are\n * disjoint, so a config is built for exactly one of them. Derive it from the\n * secret key (`sk_test_` vs `sk_live_`) rather than from the deployment\n * environment: the key is what actually decides which space API calls hit.\n */\nexport type StripeMode = 'live' | 'test';\n\nconst addMethod = Symbol('addMethod');\n/** The private constructor's one door, for this module's `define` function only. */\nconst construct = Symbol('construct');\n\nclass Product<\n NS extends Lowercase<string> = Lowercase<string>,\n PE extends string = string,\n BP extends string = string,\n PL extends string = never,\n PI extends string = never,\n I extends PriceId = never,\n> {\n readonly id: string;\n readonly config: StripeConfig<NS, PE, BP, PL, PI>;\n readonly plan: PE | null;\n readonly billingPeriod: BP | null;\n readonly prices: Map<PriceId, Metadata>;\n\n defaultPriceId: PriceId | null;\n\n constructor(\n config: StripeConfig<NS, PE, BP, PL, PI>,\n id: string,\n plan: PE | null = null,\n billingPeriod: BP | null = null\n ) {\n this.id = id;\n this.config = config;\n this.plan = plan;\n this.billingPeriod = billingPeriod;\n this.prices = new Map();\n this.defaultPriceId = null;\n }\n\n /**\n * Non-default prices stay declared on purpose: they keep resolving for\n * grandfathered subscribers and serve as price-experiment arms. Never\n * create new checkouts with a legacy price unless that is intentional.\n */\n price = <K extends PriceId>(\n priceId: K extends I ? never : K,\n metadata: Metadata = { credits: 0, expiresIn: '0' }\n ): Product<NS, PE, BP, PL, PI, I | K> => {\n invariant(!this.prices.has(priceId), `Duplicate price ${priceId}`);\n this.prices.set(priceId, metadata);\n return this as Product<NS, PE, BP, PL, PI, I | K>;\n };\n\n /**\n * `test` is the sandbox twin of the default price. In test mode it is what\n * checkouts are created with, and it resolves to the default price's\n * entitlement, so credits are declared once and cannot drift between the\n * two modes. Legacy prices need no twin: a sandbox holds no grandfathered\n * subscribers. Live mode ignores it, so a test price reaching a live config\n * still fails as an unknown price instead of being granted an entitlement.\n */\n default = (defaultPriceId: I, twin?: { test: PriceId }) => {\n const metadata = this.prices.get(defaultPriceId);\n invariant(metadata, `Default price ${defaultPriceId} is not declared`);\n if (this.config.mode === 'test') {\n invariant(twin, `Test price not declared for default ${defaultPriceId} of ${this.id}`);\n invariant(!this.prices.has(twin.test), `Duplicate price ${twin.test}`);\n this.prices.set(twin.test, metadata);\n this.defaultPriceId = twin.test;\n } else {\n this.defaultPriceId = defaultPriceId;\n }\n this.config[addMethod](this);\n return this.config;\n };\n}\n\n/** `plans` and `billingPeriods` are the order {@link StripeConfig.comparePlans} reads. */\ntype Options<NS extends Lowercase<string>, PE extends string, BP extends string> = Catalog<\n NS,\n PE,\n BP\n> & {\n mode: StripeMode;\n returnUrl: string;\n cancelUrl: string;\n successUrl: `${string}session_id={CHECKOUT_SESSION_ID}${string}`;\n cancellationCouponId: string;\n allowPromotionCodes: boolean;\n};\n\n/**\n * How a switch between two subscription products relates them, by plan level first and billing\n * period second:\n * - `upgrade` / `downgrade`: a higher or lower plan, whatever the periods.\n * - `longer` / `shorter`: the same plan billed over a longer or shorter period (monthly → yearly\n * is `longer`). Apple calls these crossgrades.\n * - `same`: the same plan and period.\n */\nexport type PlanComparison = 'upgrade' | 'downgrade' | 'longer' | 'shorter' | 'same';\n\nexport class StripeConfig<\n NS extends Lowercase<string> = Lowercase<string>,\n PE extends string = string,\n BP extends string = string,\n PL extends string = never,\n PI extends string = never,\n> {\n private readonly products: Map<string, Product<NS, PE, BP, PL, PI>> = new Map();\n\n public readonly mode: StripeMode;\n public returnUrl: string;\n public cancelUrl: string;\n public successUrl: `${string}session_id={CHECKOUT_SESSION_ID}${string}`;\n public cancellationCouponId: string;\n public allowPromotionCodes: boolean;\n public readonly namespace: NS;\n public readonly plans: readonly PE[];\n public readonly billingPeriods: readonly BP[];\n\n get productIds(): string[] {\n return Array.from(this.products.keys());\n }\n\n // runtime mirror of the type-level guards: generic accumulation only\n // protects a single fluent chain, not statement-style re-entry or casts\n [addMethod] = (product: Product<NS, PE, BP, PL, PI>) => {\n invariant(!this.products.has(product.id), `Duplicate product ${product.id}`);\n // A Stripe price belongs to one Stripe product, and getProductId must have one answer.\n for (const existing of this.products.values()) {\n for (const priceId of product.prices.keys()) {\n invariant(!existing.prices.has(priceId), `Duplicate price ${priceId} on ${existing.id}`);\n }\n }\n if (product.plan !== null) {\n for (const existing of this.products.values()) {\n invariant(\n existing.plan !== product.plan || existing.billingPeriod !== product.billingPeriod,\n `Duplicate plan ${product.plan}:${product.billingPeriod}`\n );\n }\n }\n this.products.set(product.id, product);\n return this;\n };\n\n private constructor(options: Options<NS, PE, BP>) {\n assertCatalog(options);\n this.namespace = options.namespace;\n this.plans = options.plans;\n this.billingPeriods = options.billingPeriods;\n this.mode = options.mode;\n this.returnUrl = options.returnUrl;\n this.cancelUrl = options.cancelUrl;\n this.successUrl = options.successUrl;\n this.cancellationCouponId = options.cancellationCouponId;\n this.allowPromotionCodes = options.allowPromotionCodes;\n }\n\n static [construct] = <NS extends Lowercase<string>, PE extends string, BP extends string>(\n options: Options<NS, PE, BP>\n ) => new StripeConfig<NS, PE, BP>(options);\n\n /**\n * One-time products take no extra args; subscriptions require both plan and billingPeriod.\n * A plan+period pair may be declared on only one product — version its prices in that chain.\n */\n product: {\n <K extends `${NS}.${Lowercase<string>}`>(\n productId: K extends PI ? never : K\n ): Product<NS, PE, BP, PL, K | PI>;\n <K extends `${NS}.${Lowercase<string>}`, L extends PE, P extends BP>(\n productId: K extends PI ? never : K,\n plan: L,\n billingPeriod: `${L}:${P}` extends PL ? never : P\n ): Product<NS, PE, BP, `${L}:${P}` | PL, K | PI>;\n } = (productId: string, plan: PE | null = null, billingPeriod: BP | null = null) => {\n assertInNamespace(this.namespace, productId);\n assertDeclared(this, plan, billingPeriod);\n // oxlint-disable-next-line typescript/no-unnecessary-type-assertion -- widens to the overloads' accumulated generics\n return new Product(this, productId, plan, billingPeriod) as never;\n };\n\n getPlan = (productId: string): PE => {\n const product = this.products.get(productId);\n invariant(product, `Product not found for ${productId}`);\n invariant(product.plan, `Product ${productId} is not a subscription`);\n return product.plan;\n };\n\n getBillingPeriod = (productId: string): BP => {\n const product = this.products.get(productId);\n invariant(product, `Product not found for ${productId}`);\n invariant(product.billingPeriod, `Product ${productId} is not a subscription`);\n return product.billingPeriod;\n };\n\n getMode = (productId: string): 'payment' | 'subscription' => {\n const product = this.products.get(productId);\n invariant(product, `Product not found for ${productId}`);\n return product.plan === null ? 'payment' : 'subscription';\n };\n\n /**\n * Whether the config declares `productId` and sells it as a subscription, so `getPlan` and\n * `getBillingPeriod` hold for it. False, not a throw, for an id it does not know: a product that\n * left the config (renamed, retired) or one named by metadata set outside the app.\n */\n isSubscription = (productId: string): boolean => {\n const product = this.products.get(productId);\n return product !== undefined && product.plan !== null;\n };\n\n /** The price new checkouts are created with: the default, or its test twin in test mode. */\n getPriceId = (productId: string): PriceId => {\n const product = this.products.get(productId);\n invariant(product, `Product not found for ${productId}`);\n invariant(product.defaultPriceId, `Default price not found for product ${productId}`);\n return product.defaultPriceId;\n };\n\n /**\n * The product that declares `priceId` (a legacy price or the test twin included), or null for a\n * price this config does not know: one set up by hand in the dashboard, or a test price reaching\n * a live config. Reading the product from the price a Stripe object charged, rather than from\n * metadata that may already name the next plan, is what an invoice should be credited by.\n */\n getProductId = (priceId: string): string | null => {\n for (const product of this.products.values()) {\n if (product.prices.has(priceId as PriceId)) return product.id;\n }\n return null;\n };\n\n /**\n * How switching from one subscription product to another relates them (see\n * {@link PlanComparison}), by the order `plans` and `billingPeriods` were declared in. Throws for\n * a product that is not a subscription.\n */\n comparePlans = (fromProductId: string, toProductId: string): PlanComparison => {\n const level = (productId: string) => ({\n plan: this.plans.indexOf(this.getPlan(productId)),\n period: this.billingPeriods.indexOf(this.getBillingPeriod(productId)),\n });\n const from = level(fromProductId);\n const to = level(toProductId);\n if (to.plan !== from.plan) return to.plan > from.plan ? 'upgrade' : 'downgrade';\n if (to.period !== from.period) return to.period > from.period ? 'longer' : 'shorter';\n return 'same';\n };\n\n getCreditAmount = (productId: string, priceId?: string): number => {\n const product = this.products.get(productId);\n invariant(product, `Product not found for ${productId}`);\n if (priceId) {\n const price = product.prices.get(priceId as PriceId);\n invariant(price, `Price not found for ${priceId}`);\n return price.credits;\n }\n\n invariant(product.defaultPriceId, `Default price not found for product ${productId}`);\n return product.prices.get(product.defaultPriceId)?.credits ?? 0;\n };\n\n private readonly getCreditExpiresIn = (productId: string, priceId?: string): number => {\n const product = this.products.get(productId);\n invariant(product, `Product not found for ${productId}`);\n if (priceId) {\n const price = product.prices.get(priceId as PriceId);\n invariant(price, `Price not found for ${priceId}`);\n return ms(price.expiresIn);\n }\n\n invariant(product.defaultPriceId, `Default price not found for product ${productId}`);\n return ms(product.prices.get(product.defaultPriceId)?.expiresIn ?? '0');\n };\n\n getCreditExpiresAt = (productId: string, priceId?: string): string => {\n const expiresIn = this.getCreditExpiresIn(productId, priceId);\n return new Date(Date.now() + expiresIn).toISOString();\n };\n}\n\n/**\n * Declare the Stripe product catalog. Every type parameter is inferred from the options:\n * the namespace from `namespace`, the plans and billing periods from `plans` and `billingPeriods`\n * (`const`, so a literal array needs no `as const`). Products are then added with the fluent chain.\n */\nexport function defineStripeConfig<\n const NS extends Lowercase<string>,\n const PE extends string,\n const BP extends string,\n>(options: Options<NS, PE, BP>): StripeConfig<NS, PE, BP> {\n return StripeConfig[construct](options);\n}\n"],"mappings":"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"}
@@ -9,10 +9,13 @@ const require_stripe_payment_method = require("./payment-method.cjs");
9
9
  const require_stripe_thin_handler = require("./thin-handler.cjs");
10
10
  const require_stripe_schema = require("./schema.cjs");
11
11
  const require_stripe_metadata = require("./metadata.cjs");
12
+ const require_stripe_plan_change = require("./plan-change.cjs");
12
13
  const require_stripe_pending_checkout = require("./pending-checkout.cjs");
13
14
  exports.DECLINE_REASONS = require_stripe_decline.DECLINE_REASONS;
14
15
  exports.DELAYED_NOTIFICATION_PAYMENT_METHOD_TYPES = require_stripe_payment_method.DELAYED_NOTIFICATION_PAYMENT_METHOD_TYPES;
15
16
  exports.METADATA_KEYS = require_stripe_metadata.METADATA_KEYS;
17
+ exports.PLAN_CHANGE_ERROR_REASONS = require_stripe_plan_change.PLAN_CHANGE_ERROR_REASONS;
18
+ exports.PlanChangeError = require_stripe_plan_change.PlanChangeError;
16
19
  exports.StripeConfig = require_stripe_config.StripeConfig;
17
20
  exports.StripeEventHandler = require_stripe_handler.StripeEventHandler;
18
21
  exports.StripeThinEventHandler = require_stripe_thin_handler.StripeThinEventHandler;
@@ -20,6 +23,8 @@ exports.addPendingCheckout = require_stripe_pending_checkout.addPendingCheckout;
20
23
  exports.cancellationComment = require_stripe_mapper.cancellationComment;
21
24
  exports.cancellationDetailsSchema = require_stripe_schema.cancellationDetailsSchema;
22
25
  exports.createCheckoutSessionSchema = require_stripe_schema.createCheckoutSessionSchema;
26
+ exports.createPlanChange = require_stripe_plan_change.createPlanChange;
27
+ exports.defineStripeConfig = require_stripe_config.defineStripeConfig;
23
28
  exports.expanded = require_stripe_expandable.expanded;
24
29
  exports.getBeginCheckoutProperties = require_stripe_mapper.getBeginCheckoutProperties;
25
30
  exports.getPendingCheckouts = require_stripe_pending_checkout.getPendingCheckouts;
@@ -1,5 +1,5 @@
1
1
  import { CancellationDetails } from "../subscription/index.cjs";
2
- import { PriceId, StripeConfig, StripeMode } from "./config.cjs";
2
+ import { PlanComparison, PriceId, StripeConfig, StripeMode, defineStripeConfig } from "./config.cjs";
3
3
  import { CardFailure, DECLINE_REASONS, Decline, DeclineReason, mapDecline } from "./decline.cjs";
4
4
  import { expanded, idOf } from "./expandable.cjs";
5
5
  import { StripeEventHandler } from "./handler.cjs";
@@ -9,6 +9,7 @@ import { DELAYED_NOTIFICATION_PAYMENT_METHOD_TYPES, hasDelayedNotification } fro
9
9
  import { StripeThinEventHandler, StripeThinEventNotificationOf, StripeThinEventType } from "./thin-handler.cjs";
10
10
  import { AllowedOrigins, CreateCheckoutSessionDTO, CreateCheckoutSessionSchemaOptions, cancellationDetailsSchema, createCheckoutSessionSchema, returnUrlSchema } from "./schema.cjs";
11
11
  import { METADATA_KEYS } from "./metadata.cjs";
12
+ import { PLAN_CHANGE_ERROR_REASONS, PlanChange, PlanChangeError, PlanChangeErrorReason, PlanChangeOptions, PlanChangePreview, PlanChangeResult, PlanChangeTiming, PlanSummary, ScheduledPlanChange, createPlanChange } from "./plan-change.cjs";
12
13
  import { addPendingCheckout, getPendingCheckouts, removePendingCheckout } from "./pending-checkout.cjs";
13
14
  import { Stripe } from "stripe";
14
- export { type AllowedOrigins, type BeginCheckoutProperties, type CancellationDetails, type CardFailure, type CheckoutSession, type CreateCheckoutSessionDTO, type CreateCheckoutSessionSchemaOptions, DECLINE_REASONS, DELAYED_NOTIFICATION_PAYMENT_METHOD_TYPES, type Decline, type DeclineReason, type LineItem, METADATA_KEYS, type Money, type PaymentStatus, type Price, type PriceId, type ProductPrice, type PurchaseProperties, type Stripe, StripeConfig, StripeEventHandler, type StripeMode, type StripeSubscriptionState, StripeThinEventHandler, type StripeThinEventNotificationOf, type StripeThinEventType, addPendingCheckout, cancellationComment, cancellationDetailsSchema, createCheckoutSessionSchema, expanded, getBeginCheckoutProperties, getPendingCheckouts, getPurchaseProperties, hasDelayedNotification, idOf, mapCancellationDetails, mapCharge, mapCheckoutSession, mapDecline, mapDisputeStatus, mapInvoice, mapLineItem, mapListPrice, mapPaymentIntent, mapPaymentType, mapPrice, mapRefundStatus, mapSubscription, mapSubscriptionStatus, mapTime, minorUnits, money, price, removePendingCheckout, returnUrlSchema };
15
+ export { type AllowedOrigins, type BeginCheckoutProperties, type CancellationDetails, type CardFailure, type CheckoutSession, type CreateCheckoutSessionDTO, type CreateCheckoutSessionSchemaOptions, DECLINE_REASONS, DELAYED_NOTIFICATION_PAYMENT_METHOD_TYPES, type Decline, type DeclineReason, type LineItem, METADATA_KEYS, type Money, PLAN_CHANGE_ERROR_REASONS, type PaymentStatus, type PlanChange, PlanChangeError, type PlanChangeErrorReason, type PlanChangeOptions, type PlanChangePreview, type PlanChangeResult, type PlanChangeTiming, type PlanComparison, type PlanSummary, type Price, type PriceId, type ProductPrice, type PurchaseProperties, type ScheduledPlanChange, type Stripe, StripeConfig, StripeEventHandler, type StripeMode, type StripeSubscriptionState, StripeThinEventHandler, type StripeThinEventNotificationOf, type StripeThinEventType, addPendingCheckout, cancellationComment, cancellationDetailsSchema, createCheckoutSessionSchema, createPlanChange, defineStripeConfig, expanded, getBeginCheckoutProperties, getPendingCheckouts, getPurchaseProperties, hasDelayedNotification, idOf, mapCancellationDetails, mapCharge, mapCheckoutSession, mapDecline, mapDisputeStatus, mapInvoice, mapLineItem, mapListPrice, mapPaymentIntent, mapPaymentType, mapPrice, mapRefundStatus, mapSubscription, mapSubscriptionStatus, mapTime, minorUnits, money, price, removePendingCheckout, returnUrlSchema };
@@ -1,5 +1,5 @@
1
1
  import { CancellationDetails } from "../subscription/index.mjs";
2
- import { PriceId, StripeConfig, StripeMode } from "./config.mjs";
2
+ import { PlanComparison, PriceId, StripeConfig, StripeMode, defineStripeConfig } from "./config.mjs";
3
3
  import { CardFailure, DECLINE_REASONS, Decline, DeclineReason, mapDecline } from "./decline.mjs";
4
4
  import { expanded, idOf } from "./expandable.mjs";
5
5
  import { StripeEventHandler } from "./handler.mjs";
@@ -9,6 +9,7 @@ import { DELAYED_NOTIFICATION_PAYMENT_METHOD_TYPES, hasDelayedNotification } fro
9
9
  import { StripeThinEventHandler, StripeThinEventNotificationOf, StripeThinEventType } from "./thin-handler.mjs";
10
10
  import { AllowedOrigins, CreateCheckoutSessionDTO, CreateCheckoutSessionSchemaOptions, cancellationDetailsSchema, createCheckoutSessionSchema, returnUrlSchema } from "./schema.mjs";
11
11
  import { METADATA_KEYS } from "./metadata.mjs";
12
+ import { PLAN_CHANGE_ERROR_REASONS, PlanChange, PlanChangeError, PlanChangeErrorReason, PlanChangeOptions, PlanChangePreview, PlanChangeResult, PlanChangeTiming, PlanSummary, ScheduledPlanChange, createPlanChange } from "./plan-change.mjs";
12
13
  import { addPendingCheckout, getPendingCheckouts, removePendingCheckout } from "./pending-checkout.mjs";
13
14
  import { Stripe } from "stripe";
14
- export { type AllowedOrigins, type BeginCheckoutProperties, type CancellationDetails, type CardFailure, type CheckoutSession, type CreateCheckoutSessionDTO, type CreateCheckoutSessionSchemaOptions, DECLINE_REASONS, DELAYED_NOTIFICATION_PAYMENT_METHOD_TYPES, type Decline, type DeclineReason, type LineItem, METADATA_KEYS, type Money, type PaymentStatus, type Price, type PriceId, type ProductPrice, type PurchaseProperties, type Stripe, StripeConfig, StripeEventHandler, type StripeMode, type StripeSubscriptionState, StripeThinEventHandler, type StripeThinEventNotificationOf, type StripeThinEventType, addPendingCheckout, cancellationComment, cancellationDetailsSchema, createCheckoutSessionSchema, expanded, getBeginCheckoutProperties, getPendingCheckouts, getPurchaseProperties, hasDelayedNotification, idOf, mapCancellationDetails, mapCharge, mapCheckoutSession, mapDecline, mapDisputeStatus, mapInvoice, mapLineItem, mapListPrice, mapPaymentIntent, mapPaymentType, mapPrice, mapRefundStatus, mapSubscription, mapSubscriptionStatus, mapTime, minorUnits, money, price, removePendingCheckout, returnUrlSchema };
15
+ export { type AllowedOrigins, type BeginCheckoutProperties, type CancellationDetails, type CardFailure, type CheckoutSession, type CreateCheckoutSessionDTO, type CreateCheckoutSessionSchemaOptions, DECLINE_REASONS, DELAYED_NOTIFICATION_PAYMENT_METHOD_TYPES, type Decline, type DeclineReason, type LineItem, METADATA_KEYS, type Money, PLAN_CHANGE_ERROR_REASONS, type PaymentStatus, type PlanChange, PlanChangeError, type PlanChangeErrorReason, type PlanChangeOptions, type PlanChangePreview, type PlanChangeResult, type PlanChangeTiming, type PlanComparison, type PlanSummary, type Price, type PriceId, type ProductPrice, type PurchaseProperties, type ScheduledPlanChange, type Stripe, StripeConfig, StripeEventHandler, type StripeMode, type StripeSubscriptionState, StripeThinEventHandler, type StripeThinEventNotificationOf, type StripeThinEventType, addPendingCheckout, cancellationComment, cancellationDetailsSchema, createCheckoutSessionSchema, createPlanChange, defineStripeConfig, expanded, getBeginCheckoutProperties, getPendingCheckouts, getPurchaseProperties, hasDelayedNotification, idOf, mapCancellationDetails, mapCharge, mapCheckoutSession, mapDecline, mapDisputeStatus, mapInvoice, mapLineItem, mapListPrice, mapPaymentIntent, mapPaymentType, mapPrice, mapRefundStatus, mapSubscription, mapSubscriptionStatus, mapTime, minorUnits, money, price, removePendingCheckout, returnUrlSchema };
@@ -1,4 +1,4 @@
1
- import { StripeConfig } from "./config.mjs";
1
+ import { StripeConfig, defineStripeConfig } from "./config.mjs";
2
2
  import { DECLINE_REASONS, mapDecline } from "./decline.mjs";
3
3
  import { expanded, idOf } from "./expandable.mjs";
4
4
  import { StripeEventHandler } from "./handler.mjs";
@@ -8,5 +8,6 @@ import { DELAYED_NOTIFICATION_PAYMENT_METHOD_TYPES, hasDelayedNotification } fro
8
8
  import { StripeThinEventHandler } from "./thin-handler.mjs";
9
9
  import { cancellationDetailsSchema, createCheckoutSessionSchema, returnUrlSchema } from "./schema.mjs";
10
10
  import { METADATA_KEYS } from "./metadata.mjs";
11
+ import { PLAN_CHANGE_ERROR_REASONS, PlanChangeError, createPlanChange } from "./plan-change.mjs";
11
12
  import { addPendingCheckout, getPendingCheckouts, removePendingCheckout } from "./pending-checkout.mjs";
12
- export { DECLINE_REASONS, DELAYED_NOTIFICATION_PAYMENT_METHOD_TYPES, METADATA_KEYS, StripeConfig, StripeEventHandler, StripeThinEventHandler, addPendingCheckout, cancellationComment, cancellationDetailsSchema, createCheckoutSessionSchema, expanded, getBeginCheckoutProperties, getPendingCheckouts, getPurchaseProperties, hasDelayedNotification, idOf, mapCancellationDetails, mapCharge, mapCheckoutSession, mapDecline, mapDisputeStatus, mapInvoice, mapLineItem, mapListPrice, mapPaymentIntent, mapPaymentType, mapPrice, mapRefundStatus, mapSubscription, mapSubscriptionStatus, mapTime, minorUnits, money, price, removePendingCheckout, returnUrlSchema };
13
+ export { DECLINE_REASONS, DELAYED_NOTIFICATION_PAYMENT_METHOD_TYPES, METADATA_KEYS, PLAN_CHANGE_ERROR_REASONS, PlanChangeError, StripeConfig, StripeEventHandler, StripeThinEventHandler, addPendingCheckout, cancellationComment, cancellationDetailsSchema, createCheckoutSessionSchema, createPlanChange, defineStripeConfig, expanded, getBeginCheckoutProperties, getPendingCheckouts, getPurchaseProperties, hasDelayedNotification, idOf, mapCancellationDetails, mapCharge, mapCheckoutSession, mapDecline, mapDisputeStatus, mapInvoice, mapLineItem, mapListPrice, mapPaymentIntent, mapPaymentType, mapPrice, mapRefundStatus, mapSubscription, mapSubscriptionStatus, mapTime, minorUnits, money, price, removePendingCheckout, returnUrlSchema };