@odla-ai/chapter 0.47.5 → 0.47.7

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
@@ -13,6 +13,10 @@ interface ChapterTier {
13
13
  name: string;
14
14
  /** Price in minor units. `0` is free and needs no Stripe price. */
15
15
  priceCents: number;
16
+ /** ISO currency inherited from the group for legacy rows. */
17
+ currency?: string;
18
+ /** Recurring interval inherited from the group for legacy rows. */
19
+ interval?: "year" | "month";
16
20
  /** Stripe price to subscribe. Required only when `priceCents > 0`. */
17
21
  stripePriceId?: string | null;
18
22
  /** Short description shown beside the tier on the join page. */
@@ -32,6 +36,8 @@ interface ChapterTierConfig {
32
36
  id: string;
33
37
  name: string;
34
38
  priceCents: number;
39
+ currency?: string;
40
+ interval?: "year" | "month";
35
41
  stripePriceId?: string;
36
42
  blurb?: string;
37
43
  /** Defaults to declaration order when omitted. */
@@ -49,6 +55,8 @@ interface TierGroup {
49
55
  stripePriceId?: string | null;
50
56
  standardPriceCents?: number;
51
57
  foundingDiscountCents?: number;
58
+ currency?: string;
59
+ interval?: "year" | "month";
52
60
  }
53
61
  /**
54
62
  * Whether this tier costs nothing. A free tier never touches Stripe.
@@ -96,11 +104,16 @@ interface JoinConfigTier {
96
104
  id: string;
97
105
  name: string;
98
106
  priceCents: number;
107
+ currency: string;
108
+ interval: "year" | "month";
99
109
  blurb: string;
100
110
  free: boolean;
101
111
  }
102
112
  /** Project tiers for the public join config, dropping provider identifiers. */
103
- declare function joinConfigTiers(tiers: readonly ChapterTier[]): JoinConfigTier[];
113
+ declare function joinConfigTiers(tiers: readonly ChapterTier[], defaults?: {
114
+ currency?: string;
115
+ interval?: "year" | "month";
116
+ }): JoinConfigTier[];
104
117
 
105
118
  type TextFields$1<Key extends string> = {
106
119
  [Field in Key]: string;
@@ -2027,6 +2040,8 @@ interface JoinConfigGroup {
2027
2040
  name: string;
2028
2041
  standardPriceCents?: number;
2029
2042
  foundingDiscountCents?: number;
2043
+ currency?: string;
2044
+ interval?: "year" | "month";
2030
2045
  disclaimerText?: string;
2031
2046
  refundPolicyText?: string;
2032
2047
  merchantDisclosureText?: string;
@@ -3014,6 +3029,10 @@ interface SignupControlTier {
3014
3029
  available: boolean;
3015
3030
  sortOrder: number;
3016
3031
  priceCents: number;
3032
+ /** ISO currency; omitted only by pre-field schema-v1 documents. */
3033
+ currency?: string;
3034
+ /** Recurring interval; omitted only by pre-field schema-v1 documents. */
3035
+ interval?: "year" | "month";
3017
3036
  stripePriceId?: string;
3018
3037
  blurb?: string;
3019
3038
  }
package/dist/index.d.ts CHANGED
@@ -13,6 +13,10 @@ interface ChapterTier {
13
13
  name: string;
14
14
  /** Price in minor units. `0` is free and needs no Stripe price. */
15
15
  priceCents: number;
16
+ /** ISO currency inherited from the group for legacy rows. */
17
+ currency?: string;
18
+ /** Recurring interval inherited from the group for legacy rows. */
19
+ interval?: "year" | "month";
16
20
  /** Stripe price to subscribe. Required only when `priceCents > 0`. */
17
21
  stripePriceId?: string | null;
18
22
  /** Short description shown beside the tier on the join page. */
@@ -32,6 +36,8 @@ interface ChapterTierConfig {
32
36
  id: string;
33
37
  name: string;
34
38
  priceCents: number;
39
+ currency?: string;
40
+ interval?: "year" | "month";
35
41
  stripePriceId?: string;
36
42
  blurb?: string;
37
43
  /** Defaults to declaration order when omitted. */
@@ -49,6 +55,8 @@ interface TierGroup {
49
55
  stripePriceId?: string | null;
50
56
  standardPriceCents?: number;
51
57
  foundingDiscountCents?: number;
58
+ currency?: string;
59
+ interval?: "year" | "month";
52
60
  }
53
61
  /**
54
62
  * Whether this tier costs nothing. A free tier never touches Stripe.
@@ -96,11 +104,16 @@ interface JoinConfigTier {
96
104
  id: string;
97
105
  name: string;
98
106
  priceCents: number;
107
+ currency: string;
108
+ interval: "year" | "month";
99
109
  blurb: string;
100
110
  free: boolean;
101
111
  }
102
112
  /** Project tiers for the public join config, dropping provider identifiers. */
103
- declare function joinConfigTiers(tiers: readonly ChapterTier[]): JoinConfigTier[];
113
+ declare function joinConfigTiers(tiers: readonly ChapterTier[], defaults?: {
114
+ currency?: string;
115
+ interval?: "year" | "month";
116
+ }): JoinConfigTier[];
104
117
 
105
118
  type TextFields$1<Key extends string> = {
106
119
  [Field in Key]: string;
@@ -2027,6 +2040,8 @@ interface JoinConfigGroup {
2027
2040
  name: string;
2028
2041
  standardPriceCents?: number;
2029
2042
  foundingDiscountCents?: number;
2043
+ currency?: string;
2044
+ interval?: "year" | "month";
2030
2045
  disclaimerText?: string;
2031
2046
  refundPolicyText?: string;
2032
2047
  merchantDisclosureText?: string;
@@ -3014,6 +3029,10 @@ interface SignupControlTier {
3014
3029
  available: boolean;
3015
3030
  sortOrder: number;
3016
3031
  priceCents: number;
3032
+ /** ISO currency; omitted only by pre-field schema-v1 documents. */
3033
+ currency?: string;
3034
+ /** Recurring interval; omitted only by pre-field schema-v1 documents. */
3035
+ interval?: "year" | "month";
3017
3036
  stripePriceId?: string;
3018
3037
  blurb?: string;
3019
3038
  }
package/dist/index.js CHANGED
@@ -160,6 +160,8 @@ function joinConfig(group, paymentsReady2, tiers2 = [], conditions = {}) {
160
160
  name: group.name,
161
161
  standardPriceCents: group.standardPriceCents ?? 0,
162
162
  foundingDiscountCents: group.foundingDiscountCents ?? 0,
163
+ currency: group.currency ?? "usd",
164
+ interval: group.interval ?? "year",
163
165
  tiers: [...tiers2],
164
166
  // The browser evaluates the same conditions the server enforces.
165
167
  conditions,
@@ -716,6 +718,8 @@ var groups = {
716
718
  name: attr5("string"),
717
719
  standardPriceCents: attr5("number"),
718
720
  foundingDiscountCents: attr5("number"),
721
+ currency: attr5("string", { optional: true }),
722
+ interval: attr5("string", { optional: true }),
719
723
  stripePriceId: attr5("string", { optional: true }),
720
724
  stripePublishableKey: attr5("string", { optional: true }),
721
725
  notificationEmail: attr5("string"),
@@ -739,6 +743,8 @@ var tiers = {
739
743
  groupId: attr5("string", { indexed: true }),
740
744
  name: attr5("string"),
741
745
  priceCents: attr5("number"),
746
+ currency: attr5("string", { optional: true }),
747
+ interval: attr5("string", { optional: true }),
742
748
  stripePriceId: attr5("string", { optional: true }),
743
749
  blurb: attr5("string", { optional: true }),
744
750
  sortOrder: attr5("number", { indexed: true }),
@@ -956,6 +962,8 @@ function buildGroupSeed(config) {
956
962
  name: config.name,
957
963
  standardPriceCents: prices?.standardCents ?? 0,
958
964
  foundingDiscountCents: prices?.foundingDiscountCents ?? 0,
965
+ currency: prices?.currency ?? "usd",
966
+ interval: prices?.interval ?? "year",
959
967
  notificationEmail: emails?.notificationEmail ?? "",
960
968
  replyTo: emails?.replyTo ?? emails?.notificationEmail ?? "",
961
969
  disclaimerText: policy.disclaimerText ?? "",
@@ -2696,6 +2704,8 @@ function buildTierSeeds(groupId, configured = [], now = 0) {
2696
2704
  groupId,
2697
2705
  name: tier.name,
2698
2706
  priceCents: tier.priceCents,
2707
+ ...tier.currency ? { currency: tier.currency } : {},
2708
+ ...tier.interval ? { interval: tier.interval } : {},
2699
2709
  ...tier.stripePriceId ? { stripePriceId: tier.stripePriceId } : {},
2700
2710
  ...tier.blurb ? { blurb: tier.blurb } : {},
2701
2711
  sortOrder: tier.sortOrder ?? index2,
@@ -2721,6 +2731,8 @@ function resolveTiers(group, rows3 = []) {
2721
2731
  groupId: String(group.id ?? ""),
2722
2732
  name: "Membership",
2723
2733
  priceCents: group.standardPriceCents ?? 0,
2734
+ currency: group.currency ?? "usd",
2735
+ interval: group.interval ?? "year",
2724
2736
  ...group.stripePriceId ? { stripePriceId: group.stripePriceId } : {},
2725
2737
  sortOrder: 0,
2726
2738
  active: true
@@ -2733,11 +2745,13 @@ function findTier(tiers2, tierId) {
2733
2745
  if (!tierId) return tiers2.length === 1 ? tiers2[0] : null;
2734
2746
  return tiers2.find((tier) => tier.id === tierId) ?? null;
2735
2747
  }
2736
- function joinConfigTiers(tiers2) {
2748
+ function joinConfigTiers(tiers2, defaults = {}) {
2737
2749
  return tiers2.map((tier) => ({
2738
2750
  id: tier.id,
2739
2751
  name: tier.name,
2740
2752
  priceCents: tier.priceCents,
2753
+ currency: tier.currency ?? defaults.currency ?? "usd",
2754
+ interval: tier.interval ?? defaults.interval ?? "year",
2741
2755
  blurb: tier.blurb ?? "",
2742
2756
  free: tierIsFree(tier)
2743
2757
  }));
@@ -4753,6 +4767,8 @@ function rowToTier(row, groupId) {
4753
4767
  groupId: String(row.groupId ?? groupId),
4754
4768
  name: String(row.name ?? ""),
4755
4769
  priceCents: typeof row.priceCents === "number" ? row.priceCents : 0,
4770
+ ...typeof row.currency === "string" && row.currency ? { currency: row.currency } : {},
4771
+ ...row.interval === "year" || row.interval === "month" ? { interval: row.interval } : {},
4756
4772
  ...typeof row.stripePriceId === "string" && row.stripePriceId ? { stripePriceId: row.stripePriceId } : {},
4757
4773
  ...typeof row.blurb === "string" ? { blurb: row.blurb } : {},
4758
4774
  sortOrder: typeof row.sortOrder === "number" ? row.sortOrder : 0,
@@ -4969,7 +4985,7 @@ var ROOT_KEYS4 = /* @__PURE__ */ new Set([
4969
4985
  "theme",
4970
4986
  "giftOffers"
4971
4987
  ]);
4972
- var TIER_KEYS2 = /* @__PURE__ */ new Set(["id", "name", "available", "sortOrder", "priceCents", "stripePriceId", "blurb"]);
4988
+ var TIER_KEYS2 = /* @__PURE__ */ new Set(["id", "name", "available", "sortOrder", "priceCents", "currency", "interval", "stripePriceId", "blurb"]);
4973
4989
  var recordOf = (value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
4974
4990
  function unknownKeys3(value, allowed2, path, errors) {
4975
4991
  for (const key of Object.keys(value)) if (!allowed2.has(key)) errors.push(`${path}.${key} is not supported`);
@@ -5013,6 +5029,12 @@ function tiersOf(value, errors) {
5013
5029
  if (item.available === true && Number(item.priceCents) > 0 && !item.stripePriceId) {
5014
5030
  errors.push(`${path}.stripePriceId is required for an available paid tier`);
5015
5031
  }
5032
+ if (item.currency !== void 0 && (typeof item.currency !== "string" || !/^[a-z]{3}$/.test(item.currency))) {
5033
+ errors.push(`${path}.currency must be a lowercase ISO currency code`);
5034
+ }
5035
+ if (item.interval !== void 0 && item.interval !== "year" && item.interval !== "month") {
5036
+ errors.push(`${path}.interval must be year or month`);
5037
+ }
5016
5038
  const blurb = item.blurb === void 0 ? void 0 : text5(item.blurb, `${path}.blurb`, errors, 4e3);
5017
5039
  return [{
5018
5040
  id: id6,
@@ -5020,6 +5042,8 @@ function tiersOf(value, errors) {
5020
5042
  available: item.available === true,
5021
5043
  sortOrder: Number(item.sortOrder) || 0,
5022
5044
  priceCents: Number(item.priceCents) || 0,
5045
+ ...typeof item.currency === "string" ? { currency: item.currency } : {},
5046
+ ...item.interval === "year" || item.interval === "month" ? { interval: item.interval } : {},
5023
5047
  ...typeof item.stripePriceId === "string" ? { stripePriceId: item.stripePriceId } : {},
5024
5048
  ...blurb ? { blurb } : {}
5025
5049
  }];