@shipstatic/types 2.14.0-beta.1 → 2.16.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -102,7 +102,8 @@ import {
102
102
  import type {
103
103
  PlatformLimits, // per-request size limits from /limits (file size, file count, total size)
104
104
  Plan, PlansResponse, // the public plan menu from /plans
105
- BillingInterval, StripeSession,
105
+ BillingInterval, // 'month' | 'year' — Stripe's own recurring interval
106
+ CheckoutSession, BillingPortalSession, // the two hosted Stripe pages
106
107
  ActivityListResponse,
107
108
  PingResponse,
108
109
  } from '@shipstatic/types';
package/dist/index.d.ts CHANGED
@@ -518,11 +518,15 @@ export interface TokenDeleteResponse {
518
518
  * account keeps its tier through suspension and into deletion.
519
519
  *
520
520
  * - **Free** — `free`.
521
- * - **Billed** — `pro`. The one plan a customer can buy; the only plan Stripe
522
- * knows about, and the only one the platform never sets by hand — it is
523
- * derived from the Stripe subscription.
521
+ * - **Billed** — `pro`, `team`. The plans a customer buys; the only plans
522
+ * Stripe knows about, and the only ones the platform never sets by hand —
523
+ * each is derived from the Stripe Subscription, which names its plan on the
524
+ * Price it is on. They form a ladder: a dearer tier is a superset of the one
525
+ * below it, and the API says which is next in {@link Account.upgrade}.
524
526
  * - **Granted** — `scale`, `sponsored`. Paid plans the operator confers by
525
- * hand; no Stripe subscription, no Checkout, no Stripe object at all.
527
+ * hand; no Stripe subscription, no Checkout, no Stripe object at all. These
528
+ * and `free` are the only plans an operator can set; a billed plan is only
529
+ * ever Stripe's to confer.
526
530
  *
527
531
  * The numbers each plan confers — caps, sizes — are POLICY and are delivered
528
532
  * by the API (`GET /plans`, `GET /account`, `GET /limits`), never published
@@ -532,23 +536,31 @@ export interface TokenDeleteResponse {
532
536
  export declare const AccountPlan: {
533
537
  readonly FREE: "free";
534
538
  readonly PRO: "pro";
539
+ readonly TEAM: "team";
535
540
  readonly SCALE: "scale";
536
541
  readonly SPONSORED: "sponsored";
537
542
  };
538
543
  export type AccountPlanType = (typeof AccountPlan)[keyof typeof AccountPlan];
539
544
  /**
540
- * The two things an account ACCUMULATES, and therefore the two things a plan
541
- * caps. One word for the count and for the ceiling: `Account.usage` and
545
+ * The three things an account ACCUMULATES, and therefore the three things a
546
+ * plan caps. One word for the count and for the ceiling: `Account.usage` and
542
547
  * `Account.caps` are the same shape, so a surface renders "2 of 3" by
543
548
  * dividing one by the other and can never divide by a different denominator
544
549
  * than the 403 uses.
545
550
  *
546
- * Both are counts paid plans SELL. A platform subdomain (`x.shipstatic.com`)
547
- * is not among them: the platform owns the name, it costs nothing, and no
548
- * plan bounds how many an account may hold.
551
+ * All three are counts plans SELL, and every plan publishes a number for each.
552
+ * A platform subdomain (`my-app.shipstatic.com`) is among them: the namespace
553
+ * is the platform's, so every plan bounds how many names one account may take
554
+ * from it — which is not the address every deployment gets by construction
555
+ * (`happy-cat-abc1234.shipstatic.com`), one per deployment and bounded by
556
+ * `deployments` already.
549
557
  *
550
558
  * Every cap carries a number on every plan — never `null`, never
551
- * "unlimited" — so no consumer needs an "is it bounded?" branch.
559
+ * "unlimited" — so no consumer needs an "is it bounded?" branch. A cap of `0`
560
+ * means the plan does not have the feature at all; a cap of `N` bounds
561
+ * creation, and what an account already holds above a cap stays until a plan
562
+ * TRANSITION fits it (excess paused, newest first — a domain is the only kind
563
+ * that pauses).
552
564
  *
553
565
  * A count is an aggregate over a collection, so it lives on the summary
554
566
  * resource that owns the collection: `GET /account` for one caller, `GET
@@ -562,6 +574,12 @@ export interface Caps {
562
574
  * different question asked of a different resource.)
563
575
  */
564
576
  readonly deployments: number;
577
+ /**
578
+ * Names the customer chose under the platform's own suffix
579
+ * (`my-app.shipstatic.com`) — every row, paused ones included, by the same
580
+ * rule as custom domains.
581
+ */
582
+ readonly platformDomains: number;
565
583
  /**
566
584
  * Hostnames the customer owns — every row, paused ones included. A paused
567
585
  * domain still occupies its slot, so deleting one is what frees capacity.
@@ -620,6 +638,23 @@ export interface Account {
620
638
  * mirrored on the account row for the operator surface.
621
639
  */
622
640
  readonly pastDue: boolean;
641
+ /**
642
+ * Does Stripe bill this plan — is there a Subscription behind it? True for
643
+ * every billed tier, including one no longer on the menu (a grandfathered
644
+ * row keeps its subscribers), so a console cannot derive it from `/plans`.
645
+ * It is what sends the account to the Customer Portal rather than to
646
+ * Checkout, and what a granted plan (`scale`, `sponsored`) never is.
647
+ */
648
+ readonly billed: boolean;
649
+ /**
650
+ * The next plan up the ladder this account could move to, or `null` when
651
+ * there is none: the top billed tier, every granted plan, and any plan not
652
+ * on the menu answer `null`. One server-side fact so that no surface
653
+ * derives "can this account upgrade, and to what" from the menu — a
654
+ * grandfathered row has no menu price to compare, and a granted account
655
+ * must never be sent to Checkout.
656
+ */
657
+ readonly upgrade: AccountPlanType | null;
623
658
  }
624
659
  /**
625
660
  * Account as returned by `GET /account` — the entity plus how the request
@@ -1748,11 +1783,11 @@ export interface TokenResource {
1748
1783
  delete: (token: string) => Promise<TokenDeleteResponse>;
1749
1784
  }
1750
1785
  /**
1751
- * How often a subscription renews. The platform sells one plan at two
1752
- * intervals, so this is the only thing a buyer chooses at checkout.
1786
+ * How often a subscription renews. Every billed plan is sold at both
1787
+ * intervals, so a buyer chooses a plan and an interval, and nothing else.
1753
1788
  *
1754
1789
  * It never branches business logic — monthly and yearly confer identical
1755
- * caps. It exists to be displayed and to pick a price at checkout.
1790
+ * caps. It exists to be displayed and to pick a Price at checkout.
1756
1791
  */
1757
1792
  export type BillingInterval = 'month' | 'year';
1758
1793
  /**
@@ -1771,13 +1806,20 @@ export interface Plan {
1771
1806
  /** Display name, as the marketing site and the console should print it. */
1772
1807
  readonly name: string;
1773
1808
  /**
1774
- * What it costs. A union rather than a nullable number, so "free" and
1775
- * "talk to us" are two different answers instead of two readings of the
1776
- * same `null`. Amounts are integer CENTS in USD, as the API's plan table
1777
- * states them and as Stripe's Prices are provisioned from it — the wire
1778
- * never carries a formatted price, because formatting is the reader's job.
1809
+ * What it costs, per interval integer CENTS in USD, as the API's plan
1810
+ * table states them and as Stripe's Prices are provisioned from it. The wire
1811
+ * never carries a formatted price: formatting is the reader's job.
1812
+ *
1813
+ * **A free plan costs `{ month: 0, year: 0 }`, not a sentinel.** Free IS
1814
+ * zero, so it is a number like any other and every reader formats it with
1815
+ * the same call; a `'free'` member bought one thing — a branch in each
1816
+ * consumer that mapped it straight back to `$0`.
1817
+ *
1818
+ * `'contact'` stays, and the asymmetry is the point: "not sold at a list
1819
+ * price" is genuinely a different KIND of answer, not a different number, so
1820
+ * it is a different shape. Two shapes, and each earns its own.
1779
1821
  */
1780
- readonly price: 'free' | 'contact' | {
1822
+ readonly price: 'contact' | {
1781
1823
  readonly month: number;
1782
1824
  readonly year: number;
1783
1825
  };
@@ -1800,6 +1842,29 @@ export interface Plan {
1800
1842
  export interface PlansResponse {
1801
1843
  readonly plans: readonly Plan[];
1802
1844
  }
1845
+ /**
1846
+ * The body of `POST /billing/checkout` — which plan, at which interval. Both
1847
+ * required: with more than one billed plan there is no honest default, and
1848
+ * the console always knows which card was clicked. Only a free account
1849
+ * checks out, and only onto a plan the menu sells; a billed account changes
1850
+ * plan through the Portal ({@link BillingPortalRequest}), because Stripe
1851
+ * changes a Subscription in place rather than selling a second one.
1852
+ */
1853
+ export interface CheckoutRequest {
1854
+ readonly plan: AccountPlanType;
1855
+ readonly interval: BillingInterval;
1856
+ }
1857
+ /**
1858
+ * The body of `POST /billing/portal` — optional, and when present a
1859
+ * DESTINATION: the plan and interval the account wants, which opens the
1860
+ * Portal on Stripe's own confirmation page for that Price rather than on its
1861
+ * home page. Absent, the Portal opens where it always did: cards, invoices,
1862
+ * cancellation, and Stripe's own plan picker.
1863
+ */
1864
+ export interface BillingPortalRequest {
1865
+ readonly plan?: AccountPlanType;
1866
+ readonly interval?: BillingInterval;
1867
+ }
1803
1868
  /**
1804
1869
  * The answer of `POST /billing/checkout` — Stripe's `Checkout.Session`,
1805
1870
  * projected to the one field a client needs.
package/dist/index.js CHANGED
@@ -177,11 +177,15 @@ export function validateIdempotencyKey(value) {
177
177
  * account keeps its tier through suspension and into deletion.
178
178
  *
179
179
  * - **Free** — `free`.
180
- * - **Billed** — `pro`. The one plan a customer can buy; the only plan Stripe
181
- * knows about, and the only one the platform never sets by hand — it is
182
- * derived from the Stripe subscription.
180
+ * - **Billed** — `pro`, `team`. The plans a customer buys; the only plans
181
+ * Stripe knows about, and the only ones the platform never sets by hand —
182
+ * each is derived from the Stripe Subscription, which names its plan on the
183
+ * Price it is on. They form a ladder: a dearer tier is a superset of the one
184
+ * below it, and the API says which is next in {@link Account.upgrade}.
183
185
  * - **Granted** — `scale`, `sponsored`. Paid plans the operator confers by
184
- * hand; no Stripe subscription, no Checkout, no Stripe object at all.
186
+ * hand; no Stripe subscription, no Checkout, no Stripe object at all. These
187
+ * and `free` are the only plans an operator can set; a billed plan is only
188
+ * ever Stripe's to confer.
185
189
  *
186
190
  * The numbers each plan confers — caps, sizes — are POLICY and are delivered
187
191
  * by the API (`GET /plans`, `GET /account`, `GET /limits`), never published
@@ -191,6 +195,7 @@ export function validateIdempotencyKey(value) {
191
195
  export const AccountPlan = {
192
196
  FREE: 'free',
193
197
  PRO: 'pro',
198
+ TEAM: 'team',
194
199
  SCALE: 'scale',
195
200
  SPONSORED: 'sponsored',
196
201
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shipstatic/types",
3
- "version": "2.14.0-beta.1",
3
+ "version": "2.16.0-beta.1",
4
4
  "description": "Shared types for ShipStatic platform",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
package/src/index.ts CHANGED
@@ -590,11 +590,15 @@ export interface TokenDeleteResponse {
590
590
  * account keeps its tier through suspension and into deletion.
591
591
  *
592
592
  * - **Free** — `free`.
593
- * - **Billed** — `pro`. The one plan a customer can buy; the only plan Stripe
594
- * knows about, and the only one the platform never sets by hand — it is
595
- * derived from the Stripe subscription.
593
+ * - **Billed** — `pro`, `team`. The plans a customer buys; the only plans
594
+ * Stripe knows about, and the only ones the platform never sets by hand —
595
+ * each is derived from the Stripe Subscription, which names its plan on the
596
+ * Price it is on. They form a ladder: a dearer tier is a superset of the one
597
+ * below it, and the API says which is next in {@link Account.upgrade}.
596
598
  * - **Granted** — `scale`, `sponsored`. Paid plans the operator confers by
597
- * hand; no Stripe subscription, no Checkout, no Stripe object at all.
599
+ * hand; no Stripe subscription, no Checkout, no Stripe object at all. These
600
+ * and `free` are the only plans an operator can set; a billed plan is only
601
+ * ever Stripe's to confer.
598
602
  *
599
603
  * The numbers each plan confers — caps, sizes — are POLICY and are delivered
600
604
  * by the API (`GET /plans`, `GET /account`, `GET /limits`), never published
@@ -604,6 +608,7 @@ export interface TokenDeleteResponse {
604
608
  export const AccountPlan = {
605
609
  FREE: 'free',
606
610
  PRO: 'pro',
611
+ TEAM: 'team',
607
612
  SCALE: 'scale',
608
613
  SPONSORED: 'sponsored',
609
614
  } as const;
@@ -611,18 +616,25 @@ export const AccountPlan = {
611
616
  export type AccountPlanType = (typeof AccountPlan)[keyof typeof AccountPlan];
612
617
 
613
618
  /**
614
- * The two things an account ACCUMULATES, and therefore the two things a plan
615
- * caps. One word for the count and for the ceiling: `Account.usage` and
619
+ * The three things an account ACCUMULATES, and therefore the three things a
620
+ * plan caps. One word for the count and for the ceiling: `Account.usage` and
616
621
  * `Account.caps` are the same shape, so a surface renders "2 of 3" by
617
622
  * dividing one by the other and can never divide by a different denominator
618
623
  * than the 403 uses.
619
624
  *
620
- * Both are counts paid plans SELL. A platform subdomain (`x.shipstatic.com`)
621
- * is not among them: the platform owns the name, it costs nothing, and no
622
- * plan bounds how many an account may hold.
625
+ * All three are counts plans SELL, and every plan publishes a number for each.
626
+ * A platform subdomain (`my-app.shipstatic.com`) is among them: the namespace
627
+ * is the platform's, so every plan bounds how many names one account may take
628
+ * from it — which is not the address every deployment gets by construction
629
+ * (`happy-cat-abc1234.shipstatic.com`), one per deployment and bounded by
630
+ * `deployments` already.
623
631
  *
624
632
  * Every cap carries a number on every plan — never `null`, never
625
- * "unlimited" — so no consumer needs an "is it bounded?" branch.
633
+ * "unlimited" — so no consumer needs an "is it bounded?" branch. A cap of `0`
634
+ * means the plan does not have the feature at all; a cap of `N` bounds
635
+ * creation, and what an account already holds above a cap stays until a plan
636
+ * TRANSITION fits it (excess paused, newest first — a domain is the only kind
637
+ * that pauses).
626
638
  *
627
639
  * A count is an aggregate over a collection, so it lives on the summary
628
640
  * resource that owns the collection: `GET /account` for one caller, `GET
@@ -636,6 +648,12 @@ export interface Caps {
636
648
  * different question asked of a different resource.)
637
649
  */
638
650
  readonly deployments: number;
651
+ /**
652
+ * Names the customer chose under the platform's own suffix
653
+ * (`my-app.shipstatic.com`) — every row, paused ones included, by the same
654
+ * rule as custom domains.
655
+ */
656
+ readonly platformDomains: number;
639
657
  /**
640
658
  * Hostnames the customer owns — every row, paused ones included. A paused
641
659
  * domain still occupies its slot, so deleting one is what frees capacity.
@@ -695,6 +713,23 @@ export interface Account {
695
713
  * mirrored on the account row for the operator surface.
696
714
  */
697
715
  readonly pastDue: boolean;
716
+ /**
717
+ * Does Stripe bill this plan — is there a Subscription behind it? True for
718
+ * every billed tier, including one no longer on the menu (a grandfathered
719
+ * row keeps its subscribers), so a console cannot derive it from `/plans`.
720
+ * It is what sends the account to the Customer Portal rather than to
721
+ * Checkout, and what a granted plan (`scale`, `sponsored`) never is.
722
+ */
723
+ readonly billed: boolean;
724
+ /**
725
+ * The next plan up the ladder this account could move to, or `null` when
726
+ * there is none: the top billed tier, every granted plan, and any plan not
727
+ * on the menu answer `null`. One server-side fact so that no surface
728
+ * derives "can this account upgrade, and to what" from the menu — a
729
+ * grandfathered row has no menu price to compare, and a granted account
730
+ * must never be sent to Checkout.
731
+ */
732
+ readonly upgrade: AccountPlanType | null;
698
733
  }
699
734
 
700
735
  /**
@@ -2611,11 +2646,11 @@ export interface TokenResource {
2611
2646
  // =============================================================================
2612
2647
 
2613
2648
  /**
2614
- * How often a subscription renews. The platform sells one plan at two
2615
- * intervals, so this is the only thing a buyer chooses at checkout.
2649
+ * How often a subscription renews. Every billed plan is sold at both
2650
+ * intervals, so a buyer chooses a plan and an interval, and nothing else.
2616
2651
  *
2617
2652
  * It never branches business logic — monthly and yearly confer identical
2618
- * caps. It exists to be displayed and to pick a price at checkout.
2653
+ * caps. It exists to be displayed and to pick a Price at checkout.
2619
2654
  */
2620
2655
  export type BillingInterval = 'month' | 'year';
2621
2656
 
@@ -2635,13 +2670,20 @@ export interface Plan {
2635
2670
  /** Display name, as the marketing site and the console should print it. */
2636
2671
  readonly name: string;
2637
2672
  /**
2638
- * What it costs. A union rather than a nullable number, so "free" and
2639
- * "talk to us" are two different answers instead of two readings of the
2640
- * same `null`. Amounts are integer CENTS in USD, as the API's plan table
2641
- * states them and as Stripe's Prices are provisioned from it — the wire
2642
- * never carries a formatted price, because formatting is the reader's job.
2673
+ * What it costs, per interval integer CENTS in USD, as the API's plan
2674
+ * table states them and as Stripe's Prices are provisioned from it. The wire
2675
+ * never carries a formatted price: formatting is the reader's job.
2676
+ *
2677
+ * **A free plan costs `{ month: 0, year: 0 }`, not a sentinel.** Free IS
2678
+ * zero, so it is a number like any other and every reader formats it with
2679
+ * the same call; a `'free'` member bought one thing — a branch in each
2680
+ * consumer that mapped it straight back to `$0`.
2681
+ *
2682
+ * `'contact'` stays, and the asymmetry is the point: "not sold at a list
2683
+ * price" is genuinely a different KIND of answer, not a different number, so
2684
+ * it is a different shape. Two shapes, and each earns its own.
2643
2685
  */
2644
- readonly price: 'free' | 'contact' | { readonly month: number; readonly year: number };
2686
+ readonly price: 'contact' | { readonly month: number; readonly year: number };
2645
2687
  /**
2646
2688
  * The caps this plan publishes, or `null` where the menu deliberately says
2647
2689
  * nothing (a plan sold by conversation publishes no numbers).
@@ -2663,6 +2705,31 @@ export interface PlansResponse {
2663
2705
  readonly plans: readonly Plan[];
2664
2706
  }
2665
2707
 
2708
+ /**
2709
+ * The body of `POST /billing/checkout` — which plan, at which interval. Both
2710
+ * required: with more than one billed plan there is no honest default, and
2711
+ * the console always knows which card was clicked. Only a free account
2712
+ * checks out, and only onto a plan the menu sells; a billed account changes
2713
+ * plan through the Portal ({@link BillingPortalRequest}), because Stripe
2714
+ * changes a Subscription in place rather than selling a second one.
2715
+ */
2716
+ export interface CheckoutRequest {
2717
+ readonly plan: AccountPlanType;
2718
+ readonly interval: BillingInterval;
2719
+ }
2720
+
2721
+ /**
2722
+ * The body of `POST /billing/portal` — optional, and when present a
2723
+ * DESTINATION: the plan and interval the account wants, which opens the
2724
+ * Portal on Stripe's own confirmation page for that Price rather than on its
2725
+ * home page. Absent, the Portal opens where it always did: cards, invoices,
2726
+ * cancellation, and Stripe's own plan picker.
2727
+ */
2728
+ export interface BillingPortalRequest {
2729
+ readonly plan?: AccountPlanType;
2730
+ readonly interval?: BillingInterval;
2731
+ }
2732
+
2666
2733
  /**
2667
2734
  * The answer of `POST /billing/checkout` — Stripe's `Checkout.Session`,
2668
2735
  * projected to the one field a client needs.