@usethrottle/auth 0.7.0 → 0.8.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.
package/dist/index.d.cts CHANGED
@@ -180,6 +180,21 @@ interface Subscription {
180
180
  totalPayments: number | null;
181
181
  paymentsMade: number;
182
182
  completedAt: string | null;
183
+ /** Installment plans only: every payment in order; dueAt is an estimate. */
184
+ paymentSchedule?: Array<{
185
+ index: number;
186
+ amount: number;
187
+ discount: number;
188
+ net: number;
189
+ intervalUnit: string | null;
190
+ intervalCount: number | null;
191
+ status: 'paid' | 'due' | 'upcoming';
192
+ dueAt: string | null;
193
+ }> | null;
194
+ /** Installment plans only: the sum of every payment's net amount. */
195
+ scheduleTotal?: number | null;
196
+ /** Installment plans only: what the next payment will charge; null once complete. */
197
+ nextPaymentAmount?: number | null;
183
198
  amount: number;
184
199
  quantity: number;
185
200
  currency: string;
package/dist/index.d.ts CHANGED
@@ -180,6 +180,21 @@ interface Subscription {
180
180
  totalPayments: number | null;
181
181
  paymentsMade: number;
182
182
  completedAt: string | null;
183
+ /** Installment plans only: every payment in order; dueAt is an estimate. */
184
+ paymentSchedule?: Array<{
185
+ index: number;
186
+ amount: number;
187
+ discount: number;
188
+ net: number;
189
+ intervalUnit: string | null;
190
+ intervalCount: number | null;
191
+ status: 'paid' | 'due' | 'upcoming';
192
+ dueAt: string | null;
193
+ }> | null;
194
+ /** Installment plans only: the sum of every payment's net amount. */
195
+ scheduleTotal?: number | null;
196
+ /** Installment plans only: what the next payment will charge; null once complete. */
197
+ nextPaymentAmount?: number | null;
183
198
  amount: number;
184
199
  quantity: number;
185
200
  currency: string;
@@ -1228,6 +1228,11 @@ var enUS = {
1228
1228
  cancelledOn: "Cancelled on",
1229
1229
  trialEnds: "Trial ends",
1230
1230
  installmentProgress: "Payment {paid} of {total}",
1231
+ installmentTotal: "{amount} total",
1232
+ installmentNext: "Next {amount} on {date}",
1233
+ /** Spec §5: a varied schedule's dated list; dates are estimates, hence "~". */
1234
+ upcomingPayments: "Upcoming payments",
1235
+ upcomingPayment: "{amount} \xB7 ~{date}",
1231
1236
  cancelButton: "Cancel",
1232
1237
  cancelAtPeriodEnd: "Cancel at period end",
1233
1238
  cancelNow: "Cancel immediately",
@@ -4414,6 +4419,18 @@ function isIntervalUnit(value) {
4414
4419
  return typeof value === "string" && INTERVAL_UNITS.includes(value);
4415
4420
  }
4416
4421
 
4422
+ // ../core-cadence/src/schedule.ts
4423
+ function isVariedSchedule(rows) {
4424
+ if (!rows || rows.length === 0) return false;
4425
+ return rows.some(
4426
+ (r, i) => r.discount !== 0 || r.amount !== rows[0].amount || i > 1 && (r.intervalUnit !== rows[1].intervalUnit || r.intervalCount !== rows[1].intervalCount)
4427
+ );
4428
+ }
4429
+ function upcomingSchedulePayments(rows) {
4430
+ if (!rows || !isVariedSchedule(rows)) return [];
4431
+ return rows.filter((r) => r.status !== "paid" && r.dueAt != null);
4432
+ }
4433
+
4417
4434
  // ../core-cadence/src/labels.ts
4418
4435
  var NAMED_NOUN = {
4419
4436
  weekly: "week",
@@ -4429,6 +4446,10 @@ function cadenceNoun(cadence) {
4429
4446
  }
4430
4447
  return cadence.interval;
4431
4448
  }
4449
+ function scheduleDeal(sub) {
4450
+ if (!sub.paymentSchedule || sub.scheduleTotal == null || !isVariedSchedule(sub.paymentSchedule)) return null;
4451
+ return { total: sub.scheduleTotal, payments: sub.paymentSchedule.length };
4452
+ }
4432
4453
 
4433
4454
  // src/react/components/account/SubscriptionsPanel.tsx
4434
4455
  var import_jsx_runtime43 = require("react/jsx-runtime");
@@ -4455,7 +4476,20 @@ function SubscriptionsPanel(props) {
4455
4476
  await run(fn);
4456
4477
  })();
4457
4478
  };
4458
- const priceLabel = (sub) => `${formatMoney(sub.amount, sub.currency, locale)} / ${cadenceNoun(sub)}${sub.quantity > 1 ? ` \xD7 ${sub.quantity}` : ""}`;
4479
+ const priceLabel = (sub) => {
4480
+ const deal = scheduleDeal(sub);
4481
+ return deal ? t.subscriptions.installmentTotal.replace("{amount}", formatMoney(deal.total, sub.currency, locale)) : `${formatMoney(sub.amount, sub.currency, locale)} / ${cadenceNoun(sub)}${sub.quantity > 1 ? ` \xD7 ${sub.quantity}` : ""}`;
4482
+ };
4483
+ const nextPaymentLabel = (sub) => {
4484
+ if (!isVariedSchedule(sub.paymentSchedule) || !sub.paymentSchedule || sub.nextPaymentAmount == null) return null;
4485
+ const upcoming = sub.paymentSchedule.find((r) => r.status !== "paid");
4486
+ return t.subscriptions.installmentNext.replace("{amount}", formatMoney(sub.nextPaymentAmount, sub.currency, locale)).replace("{date}", formatDate(upcoming?.dueAt ?? sub.currentPeriodEnd, locale));
4487
+ };
4488
+ const upcomingList = (sub) => {
4489
+ const upcoming = upcomingSchedulePayments(sub.paymentSchedule);
4490
+ if (upcoming.length === 0) return null;
4491
+ return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("ul", { className: "throttle-muted", "aria-label": t.subscriptions.upcomingPayments, children: upcoming.map((r) => /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("li", { children: t.subscriptions.upcomingPayment.replace("{amount}", formatMoney(r.net, sub.currency, locale)).replace("{date}", formatDate(r.dueAt, locale)) }, r.dueAt)) });
4492
+ };
4459
4493
  const renewsLabel = (sub) => formatDate(
4460
4494
  sub.status === "completed" ? sub.completedAt ?? sub.currentPeriodEnd : sub.status === "cancelled" ? sub.cancelledAt ?? sub.currentPeriodEnd : sub.currentPeriodEnd,
4461
4495
  locale
@@ -4537,7 +4571,9 @@ function SubscriptionsPanel(props) {
4537
4571
  columns: [
4538
4572
  { key: "plan", label: t.subscriptions.columnPlan, render: (sub) => /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(import_jsx_runtime43.Fragment, { children: [
4539
4573
  sub.planName ?? sub.planReference,
4540
- sub.totalPayments != null ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: "throttle-muted", children: t.subscriptions.installmentProgress.replace("{paid}", String(Math.min(sub.paymentsMade ?? 0, sub.totalPayments))).replace("{total}", String(sub.totalPayments)) }) : null
4574
+ sub.totalPayments != null ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: "throttle-muted", children: t.subscriptions.installmentProgress.replace("{paid}", String(Math.min(sub.paymentsMade ?? 0, sub.totalPayments))).replace("{total}", String(sub.totalPayments)) }) : null,
4575
+ nextPaymentLabel(sub) ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: "throttle-muted", children: nextPaymentLabel(sub) }) : null,
4576
+ upcomingList(sub)
4541
4577
  ] }) },
4542
4578
  { key: "price", label: t.subscriptions.columnPrice, render: (sub) => /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "throttle-table__money", children: priceLabel(sub) }) },
4543
4579
  { key: "renews", label: t.subscriptions.columnRenews, render: (sub) => renewsLabel(sub) },
@@ -4555,12 +4591,9 @@ function SubscriptionsPanel(props) {
4555
4591
  /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(StatusBadge, { status: sub.status, labels: t.subscriptions.statusLabels })
4556
4592
  ] }),
4557
4593
  sub.totalPayments != null ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: "throttle-muted", children: t.subscriptions.installmentProgress.replace("{paid}", String(Math.min(sub.paymentsMade ?? 0, sub.totalPayments))).replace("{total}", String(sub.totalPayments)) }) : null,
4558
- /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("p", { className: "throttle-muted", children: [
4559
- formatMoney(sub.amount, sub.currency, locale),
4560
- " / ",
4561
- cadenceNoun(sub),
4562
- sub.quantity > 1 ? ` \xD7 ${sub.quantity}` : ""
4563
- ] }),
4594
+ nextPaymentLabel(sub) ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: "throttle-muted", children: nextPaymentLabel(sub) }) : null,
4595
+ upcomingList(sub),
4596
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("p", { className: "throttle-muted", children: priceLabel(sub) }),
4564
4597
  sub.status === "completed" ? /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("p", { className: "throttle-muted", children: [
4565
4598
  t.subscriptions.statusLabels.completed,
4566
4599
  " ",