@hexclave/shared 1.0.45 → 1.0.46

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 (109) hide show
  1. package/dist/{admin-interface-B-UjGQ0i.d.ts → admin-interface-DQcggLpw.d.ts} +11 -11
  2. package/dist/{admin-interface-B-UjGQ0i.d.ts.map → admin-interface-DQcggLpw.d.ts.map} +1 -1
  3. package/dist/{admin-metrics-1yiWGq9z.d.ts → admin-metrics-bsOkw4YQ.d.ts} +15 -15
  4. package/dist/{admin-metrics-1yiWGq9z.d.ts.map → admin-metrics-bsOkw4YQ.d.ts.map} +1 -1
  5. package/dist/{client-interface-DjVtlQix.d.ts → client-interface-BQz4jNAC.d.ts} +10 -10
  6. package/dist/{client-interface-DjVtlQix.d.ts.map → client-interface-BQz4jNAC.d.ts.map} +1 -1
  7. package/dist/config/schema.d.ts +1 -1
  8. package/dist/config-authoring.d.ts +1 -1
  9. package/dist/{current-user-BCkMYzHx.d.ts → current-user-BBoN3hsn.d.ts} +17 -17
  10. package/dist/{current-user-BCkMYzHx.d.ts.map → current-user-BBoN3hsn.d.ts.map} +1 -1
  11. package/dist/dates-BRAvSk6L.d.ts +40 -0
  12. package/dist/{dates-B6ne9iOR.d.ts.map → dates-BRAvSk6L.d.ts.map} +1 -1
  13. package/dist/{email-outbox-BRZiK0ZG.d.ts → email-outbox-CYmVerum.d.ts} +225 -225
  14. package/dist/{email-outbox-BRZiK0ZG.d.ts.map → email-outbox-CYmVerum.d.ts.map} +1 -1
  15. package/dist/esm/config/schema.d.ts +116 -116
  16. package/dist/esm/interface/admin-metrics.d.ts +14 -14
  17. package/dist/esm/interface/conversations.d.ts +37 -37
  18. package/dist/esm/interface/crud/current-user.d.ts +16 -16
  19. package/dist/esm/interface/crud/email-outbox.d.ts +224 -224
  20. package/dist/esm/interface/crud/invoices.d.ts +2 -2
  21. package/dist/esm/interface/crud/products.d.ts +21 -21
  22. package/dist/esm/interface/crud/project-api-keys.d.ts +4 -4
  23. package/dist/esm/interface/crud/projects.d.ts +59 -59
  24. package/dist/esm/interface/crud/team-member-profiles.d.ts +32 -32
  25. package/dist/esm/interface/crud/transactions.d.ts +17 -17
  26. package/dist/esm/interface/crud/transactions.d.ts.map +1 -1
  27. package/dist/esm/interface/crud/users.d.ts +22 -22
  28. package/dist/esm/interface/plan-usage.d.ts +1 -1
  29. package/dist/esm/interface/webhooks.d.ts +4 -4
  30. package/dist/esm/known-errors.d.ts +3 -3
  31. package/dist/esm/schema-fields.d.ts +12 -12
  32. package/dist/esm/schema-fields.d.ts.map +1 -1
  33. package/dist/esm/schema-fields.js +2 -2
  34. package/dist/esm/schema-fields.js.map +1 -1
  35. package/dist/esm/sessions.d.ts +9 -9
  36. package/dist/esm/utils/currencies.d.ts +16 -1
  37. package/dist/esm/utils/currencies.d.ts.map +1 -1
  38. package/dist/esm/utils/currencies.js +24 -1
  39. package/dist/esm/utils/currencies.js.map +1 -1
  40. package/dist/esm/utils/dates.d.ts +18 -1
  41. package/dist/esm/utils/dates.d.ts.map +1 -1
  42. package/dist/esm/utils/dates.js +36 -15
  43. package/dist/esm/utils/dates.js.map +1 -1
  44. package/dist/helpers/password.d.ts +1 -1
  45. package/dist/helpers/production-mode.d.ts +1 -1
  46. package/dist/index.d.ts +4 -4
  47. package/dist/interface/admin-interface.d.ts +2 -2
  48. package/dist/interface/admin-metrics.d.ts +1 -1
  49. package/dist/interface/client-interface.d.ts +1 -1
  50. package/dist/interface/conversations.d.ts +37 -37
  51. package/dist/interface/crud/current-user.d.ts +1 -1
  52. package/dist/interface/crud/email-outbox.d.ts +1 -1
  53. package/dist/interface/crud/invoices.d.ts +1 -1
  54. package/dist/interface/crud/products.d.ts +1 -1
  55. package/dist/interface/crud/project-api-keys.d.ts +1 -1
  56. package/dist/interface/crud/projects.d.ts +1 -1
  57. package/dist/interface/crud/team-member-profiles.d.ts +1 -1
  58. package/dist/interface/crud/transactions.d.ts +1 -1
  59. package/dist/interface/crud/users.d.ts +1 -1
  60. package/dist/interface/plan-usage.d.ts +1 -1
  61. package/dist/interface/server-interface.d.ts +1 -1
  62. package/dist/interface/webhooks.d.ts +1 -1
  63. package/dist/{invoices-BGLLnTlR.d.ts → invoices-CHo9YKbI.d.ts} +3 -3
  64. package/dist/{invoices-BGLLnTlR.d.ts.map → invoices-CHo9YKbI.d.ts.map} +1 -1
  65. package/dist/{known-errors-g7JC8z58.d.ts → known-errors-Bm4a61wL.d.ts} +4 -4
  66. package/dist/{known-errors-g7JC8z58.d.ts.map → known-errors-Bm4a61wL.d.ts.map} +1 -1
  67. package/dist/known-errors.d.ts +1 -1
  68. package/dist/{plan-usage-BigvGIcT.d.ts → plan-usage-ChUZqQWw.d.ts} +2 -2
  69. package/dist/{plan-usage-BigvGIcT.d.ts.map → plan-usage-ChUZqQWw.d.ts.map} +1 -1
  70. package/dist/{products-D_fcxfR0.d.ts → products-D4o8A2W0.d.ts} +23 -23
  71. package/dist/{products-D_fcxfR0.d.ts.map → products-D4o8A2W0.d.ts.map} +1 -1
  72. package/dist/{project-api-keys-OQqmKtMS.d.ts → project-api-keys--7V5X_UW.d.ts} +5 -5
  73. package/dist/{project-api-keys-OQqmKtMS.d.ts.map → project-api-keys--7V5X_UW.d.ts.map} +1 -1
  74. package/dist/{projects-C42SVFvm.d.ts → projects-CFTNXRfG.d.ts} +60 -60
  75. package/dist/{projects-C42SVFvm.d.ts.map → projects-CFTNXRfG.d.ts.map} +1 -1
  76. package/dist/{schema-Bgy-GC70.d.ts → schema-Daq0b_sf.d.ts} +118 -118
  77. package/dist/{schema-Bgy-GC70.d.ts.map → schema-Daq0b_sf.d.ts.map} +1 -1
  78. package/dist/{schema-fields-BljhsWsa.d.ts → schema-fields-DZtDQEEO.d.ts} +14 -14
  79. package/dist/schema-fields-DZtDQEEO.d.ts.map +1 -0
  80. package/dist/schema-fields.d.ts +1 -1
  81. package/dist/schema-fields.js +2 -2
  82. package/dist/schema-fields.js.map +1 -1
  83. package/dist/{server-interface-C1W1tZ_y.d.ts → server-interface-BjY-eS4Q.d.ts} +8 -8
  84. package/dist/{server-interface-C1W1tZ_y.d.ts.map → server-interface-BjY-eS4Q.d.ts.map} +1 -1
  85. package/dist/{sessions-C0nM8bE_.d.ts → sessions-CI-0TBQb.d.ts} +11 -11
  86. package/dist/{sessions-C0nM8bE_.d.ts.map → sessions-CI-0TBQb.d.ts.map} +1 -1
  87. package/dist/sessions.d.ts +1 -1
  88. package/dist/{team-member-profiles-CgYXR-Rx.d.ts → team-member-profiles-BoDEqx-0.d.ts} +33 -33
  89. package/dist/{team-member-profiles-CgYXR-Rx.d.ts.map → team-member-profiles-BoDEqx-0.d.ts.map} +1 -1
  90. package/dist/{transactions-BomBBiph.d.ts → transactions-CHNUJ42J.d.ts} +19 -19
  91. package/dist/transactions-CHNUJ42J.d.ts.map +1 -0
  92. package/dist/{users-7MKfEyyq.d.ts → users-DHNRwoSz.d.ts} +24 -24
  93. package/dist/{users-7MKfEyyq.d.ts.map → users-DHNRwoSz.d.ts.map} +1 -1
  94. package/dist/utils/currencies.d.ts +16 -1
  95. package/dist/utils/currencies.d.ts.map +1 -1
  96. package/dist/utils/currencies.js +24 -0
  97. package/dist/utils/currencies.js.map +1 -1
  98. package/dist/utils/dates.d.ts +2 -2
  99. package/dist/utils/dates.js +36 -14
  100. package/dist/utils/dates.js.map +1 -1
  101. package/dist/{webhooks-C5gG85Ce.d.ts → webhooks-8Ts1Clcb.d.ts} +5 -5
  102. package/dist/{webhooks-C5gG85Ce.d.ts.map → webhooks-8Ts1Clcb.d.ts.map} +1 -1
  103. package/package.json +1 -1
  104. package/src/schema-fields.ts +13 -2
  105. package/src/utils/currencies.tsx +69 -0
  106. package/src/utils/dates.tsx +104 -15
  107. package/dist/dates-B6ne9iOR.d.ts +0 -23
  108. package/dist/schema-fields-BljhsWsa.d.ts.map +0 -1
  109. package/dist/transactions-BomBBiph.d.ts.map +0 -1
@@ -19,39 +19,40 @@ declare const teamMemberProfilesCrudServerReadSchema: import("yup").ObjectSchema
19
19
  profile_image_url: string | null;
20
20
  } & {
21
21
  user: {
22
- id: string;
22
+ restricted_reason: {
23
+ type: "anonymous" | "email_not_verified" | "restricted_by_administrator";
24
+ } | null;
25
+ primary_email: string | null;
26
+ display_name: string | null;
23
27
  client_metadata: {} | null;
24
28
  client_read_only_metadata: {} | null;
25
29
  server_metadata: {} | null;
26
- primary_email: string | null;
30
+ id: string;
31
+ selected_team_id: string | null;
32
+ is_anonymous: boolean;
33
+ is_restricted: boolean;
34
+ requires_totp_mfa: boolean;
35
+ country_code: string | null;
36
+ profile_image_url: string | null;
37
+ signed_up_at_millis: number;
38
+ last_active_at_millis: number;
27
39
  primary_email_verified: boolean;
28
40
  primary_email_auth_enabled: boolean;
29
- display_name: string | null;
30
- profile_image_url: string | null;
31
41
  selected_team: {
32
42
  client_metadata?: {} | null | undefined;
33
43
  client_read_only_metadata?: {} | null | undefined;
34
44
  server_metadata?: {} | null | undefined;
35
- id: string;
36
45
  display_name: string;
37
- profile_image_url: string | null;
46
+ id: string;
38
47
  created_at_millis: number;
48
+ profile_image_url: string | null;
39
49
  } | null;
40
- selected_team_id: string | null;
41
- signed_up_at_millis: number;
42
50
  has_password: boolean;
43
51
  otp_auth_enabled: boolean;
44
52
  passkey_auth_enabled: boolean;
45
- last_active_at_millis: number;
46
- is_anonymous: boolean;
47
- is_restricted: boolean;
48
- restricted_reason: {
49
- type: "anonymous" | "email_not_verified" | "restricted_by_administrator";
50
- } | null;
51
53
  restricted_by_admin: boolean;
52
54
  restricted_by_admin_reason: string | null;
53
55
  restricted_by_admin_private_details: string | null;
54
- country_code: string | null;
55
56
  risk_scores: {
56
57
  sign_up: {
57
58
  bot: number;
@@ -64,7 +65,6 @@ declare const teamMemberProfilesCrudServerReadSchema: import("yup").ObjectSchema
64
65
  account_id: string;
65
66
  }[];
66
67
  auth_with_email: boolean;
67
- requires_totp_mfa: boolean;
68
68
  };
69
69
  }, import("yup").AnyObject, {
70
70
  team_id: undefined;
@@ -142,39 +142,40 @@ declare const teamMemberProfilesCrud: CrudSchemaFromOptions<{
142
142
  profile_image_url: string | null;
143
143
  } & {
144
144
  user: {
145
- id: string;
145
+ restricted_reason: {
146
+ type: "anonymous" | "email_not_verified" | "restricted_by_administrator";
147
+ } | null;
148
+ primary_email: string | null;
149
+ display_name: string | null;
146
150
  client_metadata: {} | null;
147
151
  client_read_only_metadata: {} | null;
148
152
  server_metadata: {} | null;
149
- primary_email: string | null;
153
+ id: string;
154
+ selected_team_id: string | null;
155
+ is_anonymous: boolean;
156
+ is_restricted: boolean;
157
+ requires_totp_mfa: boolean;
158
+ country_code: string | null;
159
+ profile_image_url: string | null;
160
+ signed_up_at_millis: number;
161
+ last_active_at_millis: number;
150
162
  primary_email_verified: boolean;
151
163
  primary_email_auth_enabled: boolean;
152
- display_name: string | null;
153
- profile_image_url: string | null;
154
164
  selected_team: {
155
165
  client_metadata?: {} | null | undefined;
156
166
  client_read_only_metadata?: {} | null | undefined;
157
167
  server_metadata?: {} | null | undefined;
158
- id: string;
159
168
  display_name: string;
160
- profile_image_url: string | null;
169
+ id: string;
161
170
  created_at_millis: number;
171
+ profile_image_url: string | null;
162
172
  } | null;
163
- selected_team_id: string | null;
164
- signed_up_at_millis: number;
165
173
  has_password: boolean;
166
174
  otp_auth_enabled: boolean;
167
175
  passkey_auth_enabled: boolean;
168
- last_active_at_millis: number;
169
- is_anonymous: boolean;
170
- is_restricted: boolean;
171
- restricted_reason: {
172
- type: "anonymous" | "email_not_verified" | "restricted_by_administrator";
173
- } | null;
174
176
  restricted_by_admin: boolean;
175
177
  restricted_by_admin_reason: string | null;
176
178
  restricted_by_admin_private_details: string | null;
177
- country_code: string | null;
178
179
  risk_scores: {
179
180
  sign_up: {
180
181
  bot: number;
@@ -187,7 +188,6 @@ declare const teamMemberProfilesCrud: CrudSchemaFromOptions<{
187
188
  account_id: string;
188
189
  }[];
189
190
  auth_with_email: boolean;
190
- requires_totp_mfa: boolean;
191
191
  };
192
192
  }, import("yup").AnyObject, {
193
193
  team_id: undefined;
@@ -282,4 +282,4 @@ declare const teamMemberProfilesCrud: CrudSchemaFromOptions<{
282
282
  type TeamMemberProfilesCrud = CrudTypeOf<typeof teamMemberProfilesCrud>;
283
283
  //#endregion
284
284
  export { teamMemberProfilesCrudServerReadSchema as a, teamMemberProfilesCrudClientUpdateSchema as i, teamMemberProfilesCrud as n, teamMemberProfilesCrudClientReadSchema as r, TeamMemberProfilesCrud as t };
285
- //# sourceMappingURL=team-member-profiles-CgYXR-Rx.d.ts.map
285
+ //# sourceMappingURL=team-member-profiles-BoDEqx-0.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"team-member-profiles-CgYXR-Rx.d.ts","names":[],"sources":["../src/interface/crud/team-member-profiles.ts"],"mappings":";;;cAMa,sCAAA,gBAAsC,YAAA;;;;;;;;;;;cAOtC,sCAAA,gBAAsC,YAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAItC,wCAAA,gBAAwC,YAAA;;;;;;;cAKxC,sBAAA,EAoCX,qBApCiC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAsCvB,sBAAA,GAAyB,UAAU,QAAQ,sBAAA"}
1
+ {"version":3,"file":"team-member-profiles-BoDEqx-0.d.ts","names":[],"sources":["../src/interface/crud/team-member-profiles.ts"],"mappings":";;;cAMa,sCAAA,gBAAsC,YAAA;;;;;;;;;;;cAOtC,sCAAA,gBAAsC,YAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAItC,wCAAA,gBAAwC,YAAA;;;;;;;cAKxC,sBAAA,EAoCX,qBApCiC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAsCvB,sBAAA,GAAyB,UAAU,QAAQ,sBAAA"}
@@ -1,11 +1,11 @@
1
- import { t as DayInterval } from "./dates-B6ne9iOR.js";
1
+ import { t as DayInterval } from "./dates-BRAvSk6L.js";
2
2
  import { InferType } from "yup";
3
3
 
4
4
  //#region src/interface/crud/transactions.d.ts
5
5
  declare const transactionEntrySchema: import("yup").MixedSchema<{
6
6
  type: "money_transfer";
7
7
  customer_id: string;
8
- customer_type: "user" | "team" | "custom";
8
+ customer_type: "team" | "user" | "custom";
9
9
  charged_amount: {
10
10
  USD?: string | undefined;
11
11
  EUR?: string | undefined;
@@ -25,7 +25,7 @@ declare const transactionEntrySchema: import("yup").MixedSchema<{
25
25
  item_id: string;
26
26
  customer_id: string;
27
27
  quantity: number;
28
- customer_type: "user" | "team" | "custom";
28
+ customer_type: "team" | "user" | "custom";
29
29
  adjusted_transaction_id: string | null;
30
30
  adjusted_entry_index: number | null;
31
31
  } | {
@@ -35,18 +35,16 @@ declare const transactionEntrySchema: import("yup").MixedSchema<{
35
35
  customer_id: string;
36
36
  product_id: string | null;
37
37
  quantity: number;
38
- customer_type: "user" | "team" | "custom";
38
+ customer_type: "team" | "user" | "custom";
39
39
  product: {
40
+ free_trial?: DayInterval | undefined;
40
41
  client_metadata?: {} | null | undefined;
41
42
  client_read_only_metadata?: {} | null | undefined;
42
43
  server_metadata?: {} | null | undefined;
43
- free_trial?: DayInterval | undefined;
44
- display_name: string;
45
44
  server_only: boolean;
46
- customer_type: "user" | "team" | "custom";
45
+ customer_type: "team" | "user" | "custom";
47
46
  stackable: boolean;
48
47
  prices: Record<string, {
49
- free_trial?: DayInterval | undefined;
50
48
  USD?: string | undefined;
51
49
  EUR?: string | undefined;
52
50
  GBP?: string | undefined;
@@ -55,10 +53,12 @@ declare const transactionEntrySchema: import("yup").MixedSchema<{
55
53
  AUD?: string | undefined;
56
54
  CAD?: string | undefined;
57
55
  interval?: DayInterval | undefined;
56
+ free_trial?: DayInterval | undefined;
58
57
  }>;
58
+ display_name: string;
59
59
  included_items: Record<string, {
60
- repeat?: "never" | DayInterval | undefined;
61
60
  quantity?: number | undefined;
61
+ repeat?: "never" | DayInterval | undefined;
62
62
  expires?: "never" | "when-purchase-expires" | "when-repeated" | undefined;
63
63
  }>;
64
64
  };
@@ -84,12 +84,12 @@ declare const transactionSchema: import("yup").ObjectSchema<{
84
84
  created_at_millis: number;
85
85
  effective_at_millis: number;
86
86
  type: "purchase" | "subscription-cancellation" | "subscription-renewal" | "manual-item-quantity-change" | "refund" | "chargeback" | "product-change" | null;
87
- customer_type: "user" | "team" | "custom";
87
+ customer_type: "team" | "user" | "custom";
88
88
  customer_id: string;
89
89
  entries: ({
90
90
  type: "money_transfer";
91
91
  customer_id: string;
92
- customer_type: "user" | "team" | "custom";
92
+ customer_type: "team" | "user" | "custom";
93
93
  charged_amount: {
94
94
  USD?: string | undefined;
95
95
  EUR?: string | undefined;
@@ -109,7 +109,7 @@ declare const transactionSchema: import("yup").ObjectSchema<{
109
109
  item_id: string;
110
110
  customer_id: string;
111
111
  quantity: number;
112
- customer_type: "user" | "team" | "custom";
112
+ customer_type: "team" | "user" | "custom";
113
113
  adjusted_transaction_id: string | null;
114
114
  adjusted_entry_index: number | null;
115
115
  } | {
@@ -119,18 +119,16 @@ declare const transactionSchema: import("yup").ObjectSchema<{
119
119
  customer_id: string;
120
120
  product_id: string | null;
121
121
  quantity: number;
122
- customer_type: "user" | "team" | "custom";
122
+ customer_type: "team" | "user" | "custom";
123
123
  product: {
124
+ free_trial?: DayInterval | undefined;
124
125
  client_metadata?: {} | null | undefined;
125
126
  client_read_only_metadata?: {} | null | undefined;
126
127
  server_metadata?: {} | null | undefined;
127
- free_trial?: DayInterval | undefined;
128
- display_name: string;
129
128
  server_only: boolean;
130
- customer_type: "user" | "team" | "custom";
129
+ customer_type: "team" | "user" | "custom";
131
130
  stackable: boolean;
132
131
  prices: Record<string, {
133
- free_trial?: DayInterval | undefined;
134
132
  USD?: string | undefined;
135
133
  EUR?: string | undefined;
136
134
  GBP?: string | undefined;
@@ -139,10 +137,12 @@ declare const transactionSchema: import("yup").ObjectSchema<{
139
137
  AUD?: string | undefined;
140
138
  CAD?: string | undefined;
141
139
  interval?: DayInterval | undefined;
140
+ free_trial?: DayInterval | undefined;
142
141
  }>;
142
+ display_name: string;
143
143
  included_items: Record<string, {
144
- repeat?: "never" | DayInterval | undefined;
145
144
  quantity?: number | undefined;
145
+ repeat?: "never" | DayInterval | undefined;
146
146
  expires?: "never" | "when-purchase-expires" | "when-repeated" | undefined;
147
147
  }>;
148
148
  };
@@ -179,4 +179,4 @@ declare const transactionSchema: import("yup").ObjectSchema<{
179
179
  type Transaction = InferType<typeof transactionSchema>;
180
180
  //#endregion
181
181
  export { transactionEntrySchema as a, TransactionType as i, Transaction as n, transactionSchema as o, TransactionEntry as r, TRANSACTION_TYPES as t };
182
- //# sourceMappingURL=transactions-BomBBiph.d.ts.map
182
+ //# sourceMappingURL=transactions-CHNUJ42J.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transactions-CHNUJ42J.d.ts","names":[],"sources":["../src/interface/crud/transactions.ts"],"mappings":";;;;cAwFa,sBAAA,gBAAsB,WAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAMxB,WAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAEC,gBAAA,GAAmB,SAAS,QAAQ,sBAAA;AAAA,cAEnC,iBAAA;AAAA,KAUD,eAAA,WAA0B,iBAAiB;AAAA,cAE1C,iBAAA,gBAAiB,YAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mBAkBlB,WAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAEA,WAAA,GAAc,SAAS,QAAQ,iBAAA"}
@@ -1,5 +1,5 @@
1
1
  import { c as CrudTypeOf, s as CrudSchemaFromOptions } from "./crud-CqmEW9s6.js";
2
- import { t as WebhookEvent } from "./webhooks-C5gG85Ce.js";
2
+ import { t as WebhookEvent } from "./webhooks-8Ts1Clcb.js";
3
3
  import * as yup$1 from "yup";
4
4
  import { InferType } from "yup";
5
5
 
@@ -80,10 +80,10 @@ declare const usersCrudServerReadSchema: yup$1.ObjectSchema<{
80
80
  client_metadata?: {} | null | undefined;
81
81
  client_read_only_metadata?: {} | null | undefined;
82
82
  server_metadata?: {} | null | undefined;
83
- id: string;
84
83
  display_name: string;
85
- profile_image_url: string | null;
84
+ id: string;
86
85
  created_at_millis: number;
86
+ profile_image_url: string | null;
87
87
  } | null;
88
88
  selected_team_id: string | null;
89
89
  profile_image_url: string | null;
@@ -162,34 +162,34 @@ declare const usersCrudServerReadSchema: yup$1.ObjectSchema<{
162
162
  requires_totp_mfa: undefined;
163
163
  }, "">;
164
164
  declare const usersCrudServerCreateSchema: yup$1.ObjectSchema<{
165
+ primary_email: string | null | undefined;
166
+ display_name: string | null | undefined;
165
167
  client_metadata: {} | null | undefined;
166
168
  client_read_only_metadata: {} | null | undefined;
167
169
  server_metadata: {} | null | undefined;
168
- primary_email: string | null | undefined;
170
+ is_anonymous: boolean | undefined;
171
+ password: string | null | undefined;
172
+ country_code: string | null | undefined;
173
+ profile_image_url: string | null | undefined;
169
174
  primary_email_verified: boolean | undefined;
170
175
  primary_email_auth_enabled: boolean | undefined;
171
- display_name: string | null | undefined;
172
- profile_image_url: string | null | undefined;
173
176
  otp_auth_enabled: boolean | undefined;
174
177
  passkey_auth_enabled: boolean | undefined;
175
- is_anonymous: boolean | undefined;
176
178
  restricted_by_admin: boolean | undefined;
177
179
  restricted_by_admin_reason: string | null | undefined;
178
180
  restricted_by_admin_private_details: string | null | undefined;
179
- country_code: string | null | undefined;
180
181
  risk_scores: {
181
182
  sign_up: {
182
183
  bot: number;
183
184
  free_trial_abuse: number;
184
185
  };
185
186
  } | undefined;
186
- password: string | null | undefined;
187
187
  password_hash: string | undefined;
188
188
  totp_secret_base64: string | null | undefined;
189
189
  } & {
190
190
  oauth_providers: {
191
- id: string;
192
191
  email: string | null;
192
+ id: string;
193
193
  account_id: string;
194
194
  }[] | undefined;
195
195
  is_anonymous: boolean | undefined;
@@ -233,10 +233,10 @@ declare const usersCrud: CrudSchemaFromOptions<{
233
233
  client_metadata?: {} | null | undefined;
234
234
  client_read_only_metadata?: {} | null | undefined;
235
235
  server_metadata?: {} | null | undefined;
236
- id: string;
237
236
  display_name: string;
238
- profile_image_url: string | null;
237
+ id: string;
239
238
  created_at_millis: number;
239
+ profile_image_url: string | null;
240
240
  } | null;
241
241
  selected_team_id: string | null;
242
242
  profile_image_url: string | null;
@@ -368,34 +368,34 @@ declare const usersCrud: CrudSchemaFromOptions<{
368
368
  };
369
369
  }, "">;
370
370
  serverCreateSchema: yup$1.ObjectSchema<{
371
+ primary_email: string | null | undefined;
372
+ display_name: string | null | undefined;
371
373
  client_metadata: {} | null | undefined;
372
374
  client_read_only_metadata: {} | null | undefined;
373
375
  server_metadata: {} | null | undefined;
374
- primary_email: string | null | undefined;
376
+ is_anonymous: boolean | undefined;
377
+ password: string | null | undefined;
378
+ country_code: string | null | undefined;
379
+ profile_image_url: string | null | undefined;
375
380
  primary_email_verified: boolean | undefined;
376
381
  primary_email_auth_enabled: boolean | undefined;
377
- display_name: string | null | undefined;
378
- profile_image_url: string | null | undefined;
379
382
  otp_auth_enabled: boolean | undefined;
380
383
  passkey_auth_enabled: boolean | undefined;
381
- is_anonymous: boolean | undefined;
382
384
  restricted_by_admin: boolean | undefined;
383
385
  restricted_by_admin_reason: string | null | undefined;
384
386
  restricted_by_admin_private_details: string | null | undefined;
385
- country_code: string | null | undefined;
386
387
  risk_scores: {
387
388
  sign_up: {
388
389
  bot: number;
389
390
  free_trial_abuse: number;
390
391
  };
391
392
  } | undefined;
392
- password: string | null | undefined;
393
393
  password_hash: string | undefined;
394
394
  totp_secret_base64: string | null | undefined;
395
395
  } & {
396
396
  oauth_providers: {
397
- id: string;
398
397
  email: string | null;
398
+ id: string;
399
399
  account_id: string;
400
400
  }[] | undefined;
401
401
  is_anonymous: boolean | undefined;
@@ -467,10 +467,10 @@ declare const userCreatedWebhookEvent: WebhookEvent<yup$1.ObjectSchema<{
467
467
  client_metadata?: {} | null | undefined;
468
468
  client_read_only_metadata?: {} | null | undefined;
469
469
  server_metadata?: {} | null | undefined;
470
- id: string;
471
470
  display_name: string;
472
- profile_image_url: string | null;
471
+ id: string;
473
472
  created_at_millis: number;
473
+ profile_image_url: string | null;
474
474
  } | null;
475
475
  selected_team_id: string | null;
476
476
  profile_image_url: string | null;
@@ -558,10 +558,10 @@ declare const userUpdatedWebhookEvent: WebhookEvent<yup$1.ObjectSchema<{
558
558
  client_metadata?: {} | null | undefined;
559
559
  client_read_only_metadata?: {} | null | undefined;
560
560
  server_metadata?: {} | null | undefined;
561
- id: string;
562
561
  display_name: string;
563
- profile_image_url: string | null;
562
+ id: string;
564
563
  created_at_millis: number;
564
+ profile_image_url: string | null;
565
565
  } | null;
566
566
  selected_team_id: string | null;
567
567
  profile_image_url: string | null;
@@ -650,4 +650,4 @@ declare const userDeletedWebhookEvent: WebhookEvent<yup$1.ObjectSchema<{
650
650
  }, "">>;
651
651
  //#endregion
652
652
  export { userCreatedWebhookEvent as a, usersCrud as c, usersCrudServerReadSchema as d, usersCrudServerUpdateSchema as f, signUpRiskScoresSchema as i, usersCrudServerCreateSchema as l, UsersCrud as n, userDeletedWebhookEvent as o, riskScoreFieldSchema as r, userUpdatedWebhookEvent as s, SignUpRiskScoresCrud as t, usersCrudServerDeleteSchema as u };
653
- //# sourceMappingURL=users-7MKfEyyq.d.ts.map
653
+ //# sourceMappingURL=users-DHNRwoSz.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"users-7MKfEyyq.d.ts","names":[],"sources":["../src/interface/crud/users.ts"],"mappings":";;;;;;cAea,oBAAA,EAAoB,KAAA,CAAA,YAAA,SAAA,KAAA,CAAA,SAAA;AAAA,cACpB,sBAAA,EAAsB,KAAA,CAAA,YAAA;;;;;GAKjC,KAAA,CAAA,SAAA;;;;;;KACU,oBAAA,GAAuB,SAAS,QAAQ,sBAAA;AAAA,cAqBvC,2BAAA,EAA2B,KAAA,CAAA,YAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GAyBvC,KAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;cAEY,yBAAA,EAAyB,KAAA,CAAA,YAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CrC,KAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAEY,2BAAA,EAA2B,KAAA,CAAA,YAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAM3B,KAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAEA,2BAAA,EAA2B,KAAA,CAAA,WAAA,iBAAA,KAAA,CAAA,SAAA;AAAA,cAE3B,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAiCD,SAAA,GAAY,UAAU,QAAQ,SAAA;AAAA,cAc7B,uBAAA,EAAuB,YAAA,CAAA,KAAA,CAAA,YAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cACvB,uBAAA,EAAuB,YAAA,CAAA,KAAA,CAAA,YAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAQvB,uBAAA,EAAuB,YAAA,CAAA,KAAA,CAAA,YAAA"}
1
+ {"version":3,"file":"users-DHNRwoSz.d.ts","names":[],"sources":["../src/interface/crud/users.ts"],"mappings":";;;;;;cAea,oBAAA,EAAoB,KAAA,CAAA,YAAA,SAAA,KAAA,CAAA,SAAA;AAAA,cACpB,sBAAA,EAAsB,KAAA,CAAA,YAAA;;;;;GAKjC,KAAA,CAAA,SAAA;;;;;;KACU,oBAAA,GAAuB,SAAS,QAAQ,sBAAA;AAAA,cAqBvC,2BAAA,EAA2B,KAAA,CAAA,YAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GAyBvC,KAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;cAEY,yBAAA,EAAyB,KAAA,CAAA,YAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CrC,KAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAEY,2BAAA,EAA2B,KAAA,CAAA,YAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAM3B,KAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAEA,2BAAA,EAA2B,KAAA,CAAA,WAAA,iBAAA,KAAA,CAAA,SAAA;AAAA,cAE3B,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAiCD,SAAA,GAAY,UAAU,QAAQ,SAAA;AAAA,cAc7B,uBAAA,EAAuB,YAAA,CAAA,KAAA,CAAA,YAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cACvB,uBAAA,EAAuB,YAAA,CAAA,KAAA,CAAA,YAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAQvB,uBAAA,EAAuB,YAAA,CAAA,KAAA,CAAA,YAAA"}
@@ -3,6 +3,21 @@ import { n as MoneyAmount, r as SUPPORTED_CURRENCIES, t as Currency } from "../c
3
3
  //#region src/utils/currencies.d.ts
4
4
  type SupportedCurrency = (typeof SUPPORTED_CURRENCIES)[number];
5
5
  declare function moneyAmountToStripeUnits(amount: MoneyAmount, currency: Currency): number;
6
+ /**
7
+ * Inverse of `moneyAmountToStripeUnits`: formats an integer minor-unit amount
8
+ * (e.g. cents) back into the canonical decimal money string for the currency.
9
+ * E.g. for USD (2 decimals): 5000 → "50.00", 1 → "0.01"; for JPY (0 decimals):
10
+ * 500 → "500".
11
+ *
12
+ * Prefer this over `String(number)` whenever an amount is scaled: money math
13
+ * must happen in integer minor units, because float multiplication like
14
+ * `19.99 * 3` yields `59.97000000000001`, which `moneyAmountSchema` then rejects
15
+ * for having more than the currency's allowed decimals.
16
+ *
17
+ * Money amounts are non-negative (see `MoneyAmount`), so a negative input is a
18
+ * programming error and throws rather than silently dropping the sign.
19
+ */
20
+ declare function stripeUnitsToMoneyAmount(stripeUnits: number, currency: Currency): MoneyAmount;
6
21
  //#endregion
7
- export { SupportedCurrency, moneyAmountToStripeUnits };
22
+ export { SupportedCurrency, moneyAmountToStripeUnits, stripeUnitsToMoneyAmount };
8
23
  //# sourceMappingURL=currencies.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"currencies.d.ts","names":[],"sources":["../../src/utils/currencies.tsx"],"mappings":";;;KAIY,iBAAA,WAA4B,oBAAoB;AAAA,iBAE5C,wBAAA,CAAyB,MAAA,EAAQ,WAAA,EAAa,QAAA,EAAU,QAAQ"}
1
+ {"version":3,"file":"currencies.d.ts","names":[],"sources":["../../src/utils/currencies.tsx"],"mappings":";;;KAIY,iBAAA,WAA4B,oBAAoB;AAAA,iBAE5C,wBAAA,CAAyB,MAAA,EAAQ,WAAA,EAAa,QAAA,EAAU,QAAQ;AAFhF;;;;AAA4D;AAE5D;;;;;;;;;AAFA,iBA8BgB,wBAAA,CAAyB,WAAA,UAAqB,QAAA,EAAU,QAAA,GAAW,WAAW"}
@@ -10,7 +10,31 @@ function moneyAmountToStripeUnits(amount, currency) {
10
10
  const paddedFractional = fractional.padEnd(currency.decimals, "0");
11
11
  return Number.parseInt(whole + paddedFractional, 10);
12
12
  }
13
+ /**
14
+ * Inverse of `moneyAmountToStripeUnits`: formats an integer minor-unit amount
15
+ * (e.g. cents) back into the canonical decimal money string for the currency.
16
+ * E.g. for USD (2 decimals): 5000 → "50.00", 1 → "0.01"; for JPY (0 decimals):
17
+ * 500 → "500".
18
+ *
19
+ * Prefer this over `String(number)` whenever an amount is scaled: money math
20
+ * must happen in integer minor units, because float multiplication like
21
+ * `19.99 * 3` yields `59.97000000000001`, which `moneyAmountSchema` then rejects
22
+ * for having more than the currency's allowed decimals.
23
+ *
24
+ * Money amounts are non-negative (see `MoneyAmount`), so a negative input is a
25
+ * programming error and throws rather than silently dropping the sign.
26
+ */
27
+ function stripeUnitsToMoneyAmount(stripeUnits, currency) {
28
+ if (!Number.isFinite(stripeUnits) || Math.trunc(stripeUnits) !== stripeUnits) throw new __errors_js.HexclaveAssertionError("Stripe units must be an integer", { stripeUnits });
29
+ if (stripeUnits < 0) throw new __errors_js.HexclaveAssertionError("Money amounts are non-negative; cannot represent negative stripe units", { stripeUnits });
30
+ if (currency.stripeDecimals !== currency.decimals) throw new __errors_js.HexclaveAssertionError("unimplemented: TODO support different decimal configurations");
31
+ const decimals = currency.decimals;
32
+ if (decimals === 0) return `${stripeUnits}`;
33
+ const padded = stripeUnits.toString().padStart(decimals + 1, "0");
34
+ return `${padded.slice(0, padded.length - decimals)}.${padded.slice(padded.length - decimals)}`;
35
+ }
13
36
  //#endregion
14
37
  exports.moneyAmountToStripeUnits = moneyAmountToStripeUnits;
38
+ exports.stripeUnitsToMoneyAmount = stripeUnitsToMoneyAmount;
15
39
 
16
40
  //# sourceMappingURL=currencies.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"currencies.js","names":["HexclaveAssertionError"],"sources":["../../src/utils/currencies.tsx"],"sourcesContent":["import { moneyAmountSchema } from \"../schema-fields\";\nimport { SUPPORTED_CURRENCIES, type Currency, type MoneyAmount } from \"./currency-constants\";\nimport { HexclaveAssertionError } from \"./errors\";\n\nexport type SupportedCurrency = (typeof SUPPORTED_CURRENCIES)[number];\n\nexport function moneyAmountToStripeUnits(amount: MoneyAmount, currency: Currency): number {\n const validated = moneyAmountSchema(currency).defined().validateSync(amount);\n if (currency.stripeDecimals !== currency.decimals) {\n throw new HexclaveAssertionError(\"unimplemented: TODO support different decimal configurations\");\n }\n // `moneyAmountSchema` accepts strings with 0..currency.decimals fractional\n // digits, so we must right-pad the fractional part before stripping the dot.\n // A naïve `replace('.', '')` underweights inputs like \"5\" → 5 (should be 500\n // for USD) and \"0.5\" → 5 (should be 50).\n const [whole, fractional = \"\"] = validated.split(\".\");\n const paddedFractional = fractional.padEnd(currency.decimals, \"0\");\n return Number.parseInt(whole + paddedFractional, 10);\n}\n\nimport.meta.vitest?.describe(\"moneyAmountToStripeUnits\", (test) => {\n const USD = SUPPORTED_CURRENCIES.find((c) => c.code === \"USD\")!;\n\n test(\"converts fully-padded USD amounts\", ({ expect }) => {\n expect(moneyAmountToStripeUnits(\"5.00\" as MoneyAmount, USD)).toBe(500);\n expect(moneyAmountToStripeUnits(\"0.01\" as MoneyAmount, USD)).toBe(1);\n expect(moneyAmountToStripeUnits(\"12.34\" as MoneyAmount, USD)).toBe(1234);\n });\n\n test(\"converts whole-number USD amounts (no decimals)\", ({ expect }) => {\n expect(moneyAmountToStripeUnits(\"5\" as MoneyAmount, USD)).toBe(500);\n expect(moneyAmountToStripeUnits(\"10\" as MoneyAmount, USD)).toBe(1000);\n expect(moneyAmountToStripeUnits(\"0\" as MoneyAmount, USD)).toBe(0);\n });\n\n test(\"converts USD amounts with one decimal digit\", ({ expect }) => {\n expect(moneyAmountToStripeUnits(\"5.5\" as MoneyAmount, USD)).toBe(550);\n expect(moneyAmountToStripeUnits(\"0.5\" as MoneyAmount, USD)).toBe(50);\n });\n\n test(\"matches stripeUnitsToMoneyAmount round-trip\", ({ expect }) => {\n for (const cents of [0, 1, 5, 50, 99, 100, 1234, 100000]) {\n const padded = `${Math.floor(cents / 100)}.${(cents % 100).toString().padStart(2, \"0\")}` as MoneyAmount;\n expect(moneyAmountToStripeUnits(padded, USD)).toBe(cents);\n }\n });\n\n test(\"rejects invalid money strings via schema\", ({ expect }) => {\n expect(() => moneyAmountToStripeUnits(\"abc\" as MoneyAmount, USD)).toThrow();\n expect(() => moneyAmountToStripeUnits(\"5.555\" as MoneyAmount, USD)).toThrow();\n expect(() => moneyAmountToStripeUnits(\"05\" as MoneyAmount, USD)).toThrow();\n });\n});\n"],"mappings":";;;;;AAMA,SAAgB,yBAAyB,QAAqB,UAA4B;CACxF,MAAM,aAAA,GAAA,oBAAA,kBAAA,CAA8B,QAAQ,CAAC,CAAC,QAAQ,CAAC,CAAC,aAAa,MAAM;CAC3E,IAAI,SAAS,mBAAmB,SAAS,UACvC,MAAM,IAAIA,YAAAA,uBAAuB,8DAA8D;CAMjG,MAAM,CAAC,OAAO,aAAa,MAAM,UAAU,MAAM,GAAG;CACpD,MAAM,mBAAmB,WAAW,OAAO,SAAS,UAAU,GAAG;CACjE,OAAO,OAAO,SAAS,QAAQ,kBAAkB,EAAE;AACrD"}
1
+ {"version":3,"file":"currencies.js","names":["HexclaveAssertionError"],"sources":["../../src/utils/currencies.tsx"],"sourcesContent":["import { moneyAmountSchema } from \"../schema-fields\";\nimport { SUPPORTED_CURRENCIES, type Currency, type MoneyAmount } from \"./currency-constants\";\nimport { HexclaveAssertionError } from \"./errors\";\n\nexport type SupportedCurrency = (typeof SUPPORTED_CURRENCIES)[number];\n\nexport function moneyAmountToStripeUnits(amount: MoneyAmount, currency: Currency): number {\n const validated = moneyAmountSchema(currency).defined().validateSync(amount);\n if (currency.stripeDecimals !== currency.decimals) {\n throw new HexclaveAssertionError(\"unimplemented: TODO support different decimal configurations\");\n }\n // `moneyAmountSchema` accepts strings with 0..currency.decimals fractional\n // digits, so we must right-pad the fractional part before stripping the dot.\n // A naïve `replace('.', '')` underweights inputs like \"5\" → 5 (should be 500\n // for USD) and \"0.5\" → 5 (should be 50).\n const [whole, fractional = \"\"] = validated.split(\".\");\n const paddedFractional = fractional.padEnd(currency.decimals, \"0\");\n return Number.parseInt(whole + paddedFractional, 10);\n}\n\n/**\n * Inverse of `moneyAmountToStripeUnits`: formats an integer minor-unit amount\n * (e.g. cents) back into the canonical decimal money string for the currency.\n * E.g. for USD (2 decimals): 5000 → \"50.00\", 1 → \"0.01\"; for JPY (0 decimals):\n * 500 → \"500\".\n *\n * Prefer this over `String(number)` whenever an amount is scaled: money math\n * must happen in integer minor units, because float multiplication like\n * `19.99 * 3` yields `59.97000000000001`, which `moneyAmountSchema` then rejects\n * for having more than the currency's allowed decimals.\n *\n * Money amounts are non-negative (see `MoneyAmount`), so a negative input is a\n * programming error and throws rather than silently dropping the sign.\n */\nexport function stripeUnitsToMoneyAmount(stripeUnits: number, currency: Currency): MoneyAmount {\n if (!Number.isFinite(stripeUnits) || Math.trunc(stripeUnits) !== stripeUnits) {\n throw new HexclaveAssertionError(\"Stripe units must be an integer\", { stripeUnits });\n }\n if (stripeUnits < 0) {\n throw new HexclaveAssertionError(\"Money amounts are non-negative; cannot represent negative stripe units\", { stripeUnits });\n }\n if (currency.stripeDecimals !== currency.decimals) {\n throw new HexclaveAssertionError(\"unimplemented: TODO support different decimal configurations\");\n }\n const decimals = currency.decimals;\n if (decimals === 0) return `${stripeUnits}` as MoneyAmount;\n // Pad so there's always at least one integer digit plus `decimals` fractional\n // digits, then split at the dot position.\n const padded = stripeUnits.toString().padStart(decimals + 1, \"0\");\n const integerPart = padded.slice(0, padded.length - decimals);\n const fractionalPart = padded.slice(padded.length - decimals);\n return `${integerPart}.${fractionalPart}` as MoneyAmount;\n}\n\nimport.meta.vitest?.describe(\"moneyAmountToStripeUnits\", (test) => {\n const USD = SUPPORTED_CURRENCIES.find((c) => c.code === \"USD\")!;\n\n test(\"converts fully-padded USD amounts\", ({ expect }) => {\n expect(moneyAmountToStripeUnits(\"5.00\" as MoneyAmount, USD)).toBe(500);\n expect(moneyAmountToStripeUnits(\"0.01\" as MoneyAmount, USD)).toBe(1);\n expect(moneyAmountToStripeUnits(\"12.34\" as MoneyAmount, USD)).toBe(1234);\n });\n\n test(\"converts whole-number USD amounts (no decimals)\", ({ expect }) => {\n expect(moneyAmountToStripeUnits(\"5\" as MoneyAmount, USD)).toBe(500);\n expect(moneyAmountToStripeUnits(\"10\" as MoneyAmount, USD)).toBe(1000);\n expect(moneyAmountToStripeUnits(\"0\" as MoneyAmount, USD)).toBe(0);\n });\n\n test(\"converts USD amounts with one decimal digit\", ({ expect }) => {\n expect(moneyAmountToStripeUnits(\"5.5\" as MoneyAmount, USD)).toBe(550);\n expect(moneyAmountToStripeUnits(\"0.5\" as MoneyAmount, USD)).toBe(50);\n });\n\n test(\"matches stripeUnitsToMoneyAmount round-trip\", ({ expect }) => {\n for (const cents of [0, 1, 5, 50, 99, 100, 1234, 100000]) {\n const padded = `${Math.floor(cents / 100)}.${(cents % 100).toString().padStart(2, \"0\")}` as MoneyAmount;\n expect(moneyAmountToStripeUnits(padded, USD)).toBe(cents);\n }\n });\n\n test(\"rejects invalid money strings via schema\", ({ expect }) => {\n expect(() => moneyAmountToStripeUnits(\"abc\" as MoneyAmount, USD)).toThrow();\n expect(() => moneyAmountToStripeUnits(\"5.555\" as MoneyAmount, USD)).toThrow();\n expect(() => moneyAmountToStripeUnits(\"05\" as MoneyAmount, USD)).toThrow();\n });\n});\n\nimport.meta.vitest?.describe(\"stripeUnitsToMoneyAmount\", (test) => {\n const USD = SUPPORTED_CURRENCIES.find((c) => c.code === \"USD\")!;\n const JPY = SUPPORTED_CURRENCIES.find((c) => c.code === \"JPY\")!;\n\n test(\"formats USD minor units as a 2-decimal string\", ({ expect }) => {\n expect(stripeUnitsToMoneyAmount(5000, USD)).toBe(\"50.00\");\n expect(stripeUnitsToMoneyAmount(1, USD)).toBe(\"0.01\");\n expect(stripeUnitsToMoneyAmount(100, USD)).toBe(\"1.00\");\n expect(stripeUnitsToMoneyAmount(0, USD)).toBe(\"0.00\");\n });\n\n test(\"formats 0-decimal currencies without a dot\", ({ expect }) => {\n expect(stripeUnitsToMoneyAmount(500, JPY)).toBe(\"500\");\n expect(stripeUnitsToMoneyAmount(0, JPY)).toBe(\"0\");\n });\n\n test(\"round-trips with moneyAmountToStripeUnits\", ({ expect }) => {\n for (const cents of [0, 1, 5, 50, 99, 100, 1234, 100000]) {\n expect(moneyAmountToStripeUnits(stripeUnitsToMoneyAmount(cents, USD), USD)).toBe(cents);\n }\n });\n\n test(\"scaling in minor units avoids float artifacts\", ({ expect }) => {\n // 19.99 * 3 in float is 59.97000000000001; via minor units it is exact.\n const scaled = moneyAmountToStripeUnits(\"19.99\" as MoneyAmount, USD) * 3;\n expect(stripeUnitsToMoneyAmount(scaled, USD)).toBe(\"59.97\");\n });\n\n test(\"rejects non-integer and negative inputs\", ({ expect }) => {\n expect(() => stripeUnitsToMoneyAmount(1.5, USD)).toThrow();\n expect(() => stripeUnitsToMoneyAmount(-1, USD)).toThrow();\n expect(() => stripeUnitsToMoneyAmount(Number.NaN, USD)).toThrow();\n });\n});\n"],"mappings":";;;;;AAMA,SAAgB,yBAAyB,QAAqB,UAA4B;CACxF,MAAM,aAAA,GAAA,oBAAA,kBAAA,CAA8B,QAAQ,CAAC,CAAC,QAAQ,CAAC,CAAC,aAAa,MAAM;CAC3E,IAAI,SAAS,mBAAmB,SAAS,UACvC,MAAM,IAAIA,YAAAA,uBAAuB,8DAA8D;CAMjG,MAAM,CAAC,OAAO,aAAa,MAAM,UAAU,MAAM,GAAG;CACpD,MAAM,mBAAmB,WAAW,OAAO,SAAS,UAAU,GAAG;CACjE,OAAO,OAAO,SAAS,QAAQ,kBAAkB,EAAE;AACrD;;;;;;;;;;;;;;;AAgBA,SAAgB,yBAAyB,aAAqB,UAAiC;CAC7F,IAAI,CAAC,OAAO,SAAS,WAAW,KAAK,KAAK,MAAM,WAAW,MAAM,aAC/D,MAAM,IAAIA,YAAAA,uBAAuB,mCAAmC,EAAE,YAAY,CAAC;CAErF,IAAI,cAAc,GAChB,MAAM,IAAIA,YAAAA,uBAAuB,0EAA0E,EAAE,YAAY,CAAC;CAE5H,IAAI,SAAS,mBAAmB,SAAS,UACvC,MAAM,IAAIA,YAAAA,uBAAuB,8DAA8D;CAEjG,MAAM,WAAW,SAAS;CAC1B,IAAI,aAAa,GAAG,OAAO,GAAG;CAG9B,MAAM,SAAS,YAAY,SAAS,CAAC,CAAC,SAAS,WAAW,GAAG,GAAG;CAGhE,OAAO,GAFa,OAAO,MAAM,GAAG,OAAO,SAAS,QAEhC,EAAE,GADC,OAAO,MAAM,OAAO,SAAS,QACd;AACxC"}
@@ -1,2 +1,2 @@
1
- import { a as fromNow, c as getIntervalsElapsed, i as addInterval, l as isWeekend, n as FAR_FUTURE_DATE, o as fromNowDetailed, r as Interval, s as getInputDatetimeLocalString, t as DayInterval, u as subtractInterval } from "../dates-B6ne9iOR.js";
2
- export { DayInterval, FAR_FUTURE_DATE, Interval, addInterval, fromNow, fromNowDetailed, getInputDatetimeLocalString, getIntervalsElapsed, isWeekend, subtractInterval };
1
+ import { a as fromNow, c as getIntervalsElapsed, d as subtractInterval, i as addInterval, l as isWeekend, n as FAR_FUTURE_DATE, o as fromNowDetailed, r as Interval, s as getInputDatetimeLocalString, t as DayInterval, u as nthDayIntervalMillis } from "../dates-BRAvSk6L.js";
2
+ export { DayInterval, FAR_FUTURE_DATE, Interval, addInterval, fromNow, fromNowDetailed, getInputDatetimeLocalString, getIntervalsElapsed, isWeekend, nthDayIntervalMillis, subtractInterval };
@@ -100,24 +100,45 @@ function getMsPerDayIntervalUnit(unit) {
100
100
  }
101
101
  function getIntervalsElapsed(anchor, to, repeat) {
102
102
  const [amount, unit] = repeat;
103
- if (to <= anchor) return 0;
103
+ const toMillis = to.getTime();
104
+ if (toMillis <= anchor.getTime()) return 0;
104
105
  if (unit === "day" || unit === "week") {
105
106
  const msPerUnit = getMsPerDayIntervalUnit(unit);
106
- const diffMs = to.getTime() - anchor.getTime();
107
+ const diffMs = toMillis - anchor.getTime();
107
108
  return Math.floor(diffMs / (msPerUnit * amount));
108
109
  }
109
- if (["month", "year"].includes(unit)) {
110
- let count = 0;
111
- let current = new Date(anchor);
112
- for (;;) {
113
- const next = addInterval(new Date(current), [amount, unit]);
114
- if (next > to) break;
115
- current = next;
116
- count += 1;
117
- }
118
- return count;
119
- }
120
- return 0;
110
+ let count = 0;
111
+ while (nthDayIntervalMillis(anchor.getTime(), repeat, count + 1) <= toMillis) count += 1;
112
+ return count;
113
+ }
114
+ /**
115
+ * The UTC millis of the `occurrence`-th (1-based) repeat of `interval` after `anchorMillis`.
116
+ *
117
+ * Each boundary is computed from the *original* anchor (never by stepping off the previous, possibly
118
+ * clamped, boundary) so the anchor's day-of-month is preserved across resets: a Jan 31 anchor yields
119
+ * Feb 28, Mar 31, Apr 30, ... (matching Stripe's billing-cycle behavior) rather than drifting to
120
+ * Feb 28, Mar 28, ... . Month/year overflow (e.g. Jan 31 -> Feb) is clamped to the target month's
121
+ * last day. Day/week are exact multiples (no calendar involved, so no drift possible).
122
+ *
123
+ * Everything is done in UTC (unlike `addInterval`, which uses local-time Date accessors) so the
124
+ * result is deterministic regardless of the server's timezone — this is relied upon by bulldozer
125
+ * folds, which must be reproducible across machines.
126
+ *
127
+ * `occurrence` 0 returns the anchor itself; `getIntervalsElapsed` counts these same boundaries, so
128
+ * the two are always consistent for a given DayInterval.
129
+ */
130
+ function nthDayIntervalMillis(anchorMillis, interval, occurrence) {
131
+ const [count, unit] = interval;
132
+ const totalUnits = count * occurrence;
133
+ if (unit === "day" || unit === "week") return anchorMillis + totalUnits * getMsPerDayIntervalUnit(unit);
134
+ const anchor = new Date(anchorMillis);
135
+ const monthsToAdd = unit === "year" ? totalUnits * 12 : totalUnits;
136
+ const absoluteMonth = anchor.getUTCFullYear() * 12 + anchor.getUTCMonth() + monthsToAdd;
137
+ const targetYear = Math.floor(absoluteMonth / 12);
138
+ const targetMonth = absoluteMonth - targetYear * 12;
139
+ const daysInTargetMonth = new Date(Date.UTC(targetYear, targetMonth + 1, 0)).getUTCDate();
140
+ const clampedDay = Math.min(anchor.getUTCDate(), daysInTargetMonth);
141
+ return Date.UTC(targetYear, targetMonth, clampedDay, anchor.getUTCHours(), anchor.getUTCMinutes(), anchor.getUTCSeconds(), anchor.getUTCMilliseconds());
121
142
  }
122
143
  //#endregion
123
144
  exports.FAR_FUTURE_DATE = FAR_FUTURE_DATE;
@@ -127,6 +148,7 @@ exports.fromNowDetailed = fromNowDetailed;
127
148
  exports.getInputDatetimeLocalString = getInputDatetimeLocalString;
128
149
  exports.getIntervalsElapsed = getIntervalsElapsed;
129
150
  exports.isWeekend = isWeekend;
151
+ exports.nthDayIntervalMillis = nthDayIntervalMillis;
130
152
  exports.subtractInterval = subtractInterval;
131
153
 
132
154
  //# sourceMappingURL=dates.js.map