@classytic/revenue 1.1.3 → 2.0.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.
Files changed (82) hide show
  1. package/CHANGELOG.md +90 -0
  2. package/README.md +638 -632
  3. package/dist/audit-B39B0Sdq.mjs +53 -0
  4. package/dist/audit-DZ0eTr9g.d.mts +89 -0
  5. package/dist/bridges/index.d.mts +2 -0
  6. package/dist/bridges/index.mjs +1 -0
  7. package/dist/context-DRqSeTPM.d.mts +35 -0
  8. package/dist/core/state-machines.d.mts +35 -0
  9. package/dist/core/state-machines.mjs +134 -0
  10. package/dist/engine-types-CcjIb4Fy.d.mts +611 -0
  11. package/dist/enums/index.d.mts +3 -157
  12. package/dist/enums/index.mjs +3 -55
  13. package/dist/errors-DHa8JVQ-.mjs +92 -0
  14. package/dist/escrow.schema-BBv9oVEW.mjs +322 -0
  15. package/dist/escrow.schema-CC8XuD46.d.mts +629 -0
  16. package/dist/event-constants-CEMitnIV.mjs +53 -0
  17. package/dist/events/index.d.mts +3 -0
  18. package/dist/events/index.mjs +4 -0
  19. package/dist/index.d.mts +77 -9
  20. package/dist/index.mjs +465 -29
  21. package/dist/monetization.enums-BtiU3t8o.mjs +39 -0
  22. package/dist/monetization.enums-D2xbxXJM.d.mts +34 -0
  23. package/dist/plugins/plugin.interface.d.mts +28 -0
  24. package/dist/plugins/plugin.interface.mjs +26 -0
  25. package/dist/providers/index.d.mts +2 -3
  26. package/dist/providers/index.mjs +2 -2
  27. package/dist/{base-DCoyIUj6.mjs → registry-DhFMsSn5.mjs} +34 -36
  28. package/dist/{base-CsTlVQJe.d.mts → registry-SvIGPAx_.d.mts} +73 -66
  29. package/dist/repositories/create-repositories.d.mts +21 -0
  30. package/dist/repositories/create-repositories.mjs +12 -0
  31. package/dist/revenue-bridges-sdlrR85c.d.mts +145 -0
  32. package/dist/revenue-event-catalog-BX3g7RUi.d.mts +823 -0
  33. package/dist/revenue-event-catalog-LqxPnsU_.mjs +388 -0
  34. package/dist/settlement.repository-Cy3mMWGH.mjs +771 -0
  35. package/dist/shared/index.d.mts +2 -0
  36. package/dist/shared/index.mjs +4 -0
  37. package/dist/split.enums-CQE3ekH1.mjs +172 -0
  38. package/dist/split.enums-Dw4zCrcZ.d.mts +154 -0
  39. package/dist/splits-BAfY-a9P.mjs +123 -0
  40. package/dist/validators/index.d.mts +2 -0
  41. package/dist/validators/index.mjs +3 -0
  42. package/package.json +32 -36
  43. package/dist/application/services/index.d.mts +0 -4
  44. package/dist/application/services/index.mjs +0 -3
  45. package/dist/category-resolver-DV83N8ok.mjs +0 -284
  46. package/dist/commission-split-BzB8cd39.mjs +0 -485
  47. package/dist/core/events.d.mts +0 -294
  48. package/dist/core/events.mjs +0 -100
  49. package/dist/core/index.d.mts +0 -9
  50. package/dist/core/index.mjs +0 -8
  51. package/dist/errors-CorrWz7A.d.mts +0 -787
  52. package/dist/escrow.enums-CZGrrdg7.mjs +0 -101
  53. package/dist/escrow.enums-DwdLuuve.d.mts +0 -78
  54. package/dist/idempotency-DaYcUGY1.mjs +0 -172
  55. package/dist/index-Dsp7H5Wb.d.mts +0 -471
  56. package/dist/infrastructure/plugins/index.d.mts +0 -239
  57. package/dist/infrastructure/plugins/index.mjs +0 -345
  58. package/dist/money-CvrDOijQ.mjs +0 -271
  59. package/dist/money-DPG8AtJ8.d.mts +0 -112
  60. package/dist/payment.enums-HAuAS9Pp.d.mts +0 -70
  61. package/dist/payment.enums-tEFVa-Xp.mjs +0 -69
  62. package/dist/plugin-BbK0OVHy.d.mts +0 -327
  63. package/dist/plugin-Cd_V04Em.mjs +0 -210
  64. package/dist/reconciliation/index.d.mts +0 -193
  65. package/dist/reconciliation/index.mjs +0 -192
  66. package/dist/retry-HHCOXYdn.d.mts +0 -186
  67. package/dist/revenue-9scqKSef.mjs +0 -553
  68. package/dist/schemas/index.d.mts +0 -2665
  69. package/dist/schemas/index.mjs +0 -717
  70. package/dist/schemas/validation.d.mts +0 -375
  71. package/dist/schemas/validation.mjs +0 -325
  72. package/dist/settlement.enums-DFhkqZEY.d.mts +0 -132
  73. package/dist/settlement.schema-D5uWB5tP.d.mts +0 -344
  74. package/dist/settlement.service-BxuiHpNC.d.mts +0 -594
  75. package/dist/settlement.service-CUxbUTzT.mjs +0 -2510
  76. package/dist/split.enums-BrjabxIX.mjs +0 -86
  77. package/dist/split.enums-DmskfLOM.d.mts +0 -43
  78. package/dist/tax-BoCt5cEd.d.mts +0 -61
  79. package/dist/tax-EQ15DO81.mjs +0 -162
  80. package/dist/transaction.enums-pCyMFT4Z.mjs +0 -96
  81. package/dist/utils/index.d.mts +0 -428
  82. package/dist/utils/index.mjs +0 -346
@@ -1,345 +0,0 @@
1
- import { r as definePlugin } from "../../plugin-Cd_V04Em.mjs";
2
- import { t as resolveCategory } from "../../category-resolver-DV83N8ok.mjs";
3
- import { n as getTaxType, t as calculateTax } from "../../tax-EQ15DO81.mjs";
4
-
5
- //#region src/infrastructure/plugins/business/logging.plugin.ts
6
- /**
7
- * Logging Plugin
8
- * @classytic/revenue
9
- *
10
- * Logs all revenue operations at specified log level
11
- */
12
- /**
13
- * Logging plugin - logs all operations
14
- *
15
- * Logs payment creation, verification, and refund operations
16
- *
17
- * @param options - Plugin options
18
- * @returns Logging plugin
19
- *
20
- * @example
21
- * ```typescript
22
- * import { Revenue } from '@classytic/revenue';
23
- * import { loggingPlugin } from '@classytic/revenue/plugins';
24
- *
25
- * const revenue = Revenue
26
- * .create()
27
- * .withPlugin(loggingPlugin({ level: 'debug' }))
28
- * .build();
29
- * ```
30
- */
31
- function loggingPlugin(options = {}) {
32
- const level = options.level ?? "info";
33
- return definePlugin({
34
- name: "logging",
35
- version: "1.0.0",
36
- description: "Logs all revenue operations",
37
- hooks: {
38
- "payment.create.after": async (ctx, input, next) => {
39
- ctx.logger[level]("Creating payment", {
40
- amount: input.amount,
41
- currency: input.currency
42
- });
43
- const result = await next();
44
- ctx.logger[level]("Payment created", { paymentIntentId: result?.paymentIntentId });
45
- return result;
46
- },
47
- "payment.verify.after": async (ctx, input, next) => {
48
- ctx.logger[level]("Verifying payment", { id: input.id });
49
- const result = await next();
50
- ctx.logger[level]("Payment verified", { verified: result?.verified });
51
- return result;
52
- },
53
- "payment.refund.after": async (ctx, input, next) => {
54
- ctx.logger[level]("Processing refund", {
55
- transactionId: input.transactionId,
56
- amount: input.amount
57
- });
58
- const result = await next();
59
- ctx.logger[level]("Refund processed", { refundId: result?.refundId });
60
- return result;
61
- }
62
- }
63
- });
64
- }
65
-
66
- //#endregion
67
- //#region src/infrastructure/plugins/business/audit.plugin.ts
68
- /**
69
- * Audit Plugin
70
- * @classytic/revenue
71
- *
72
- * Records all operations for compliance and audit trails
73
- */
74
- /**
75
- * Sanitize input by removing sensitive fields
76
- * @private
77
- */
78
- function sanitizeInput(input) {
79
- if (typeof input !== "object" || !input) return {};
80
- const sanitized = { ...input };
81
- delete sanitized.apiKey;
82
- delete sanitized.secretKey;
83
- delete sanitized.password;
84
- return sanitized;
85
- }
86
- /**
87
- * Sanitize output
88
- * @private
89
- */
90
- function sanitizeOutput(output) {
91
- if (typeof output !== "object" || !output) return {};
92
- return { ...output };
93
- }
94
- /**
95
- * Audit plugin - records all operations for compliance
96
- *
97
- * Records payment creation, refunds, and other operations with sanitized data
98
- *
99
- * @param options - Plugin options
100
- * @returns Audit plugin
101
- *
102
- * @example
103
- * ```typescript
104
- * import { Revenue } from '@classytic/revenue';
105
- * import { auditPlugin } from '@classytic/revenue/plugins';
106
- *
107
- * const revenue = Revenue
108
- * .create()
109
- * .withPlugin(auditPlugin({
110
- * store: async (entry) => {
111
- * await AuditLog.create(entry);
112
- * }
113
- * }))
114
- * .build();
115
- * ```
116
- */
117
- function auditPlugin(options = {}) {
118
- const entries = [];
119
- const store = options.store ?? (async (entry) => {
120
- entries.push(entry);
121
- });
122
- return definePlugin({
123
- name: "audit",
124
- version: "1.0.0",
125
- description: "Audit trail for all operations",
126
- hooks: {
127
- "payment.create.after": async (ctx, input, next) => {
128
- const result = await next();
129
- await store({
130
- action: "payment.create",
131
- requestId: ctx.meta.requestId,
132
- timestamp: ctx.meta.timestamp,
133
- input: sanitizeInput(input),
134
- output: sanitizeOutput(result),
135
- idempotencyKey: ctx.meta.idempotencyKey
136
- });
137
- return result;
138
- },
139
- "payment.refund.after": async (ctx, input, next) => {
140
- const result = await next();
141
- await store({
142
- action: "payment.refund",
143
- requestId: ctx.meta.requestId,
144
- timestamp: ctx.meta.timestamp,
145
- input: sanitizeInput(input),
146
- output: sanitizeOutput(result),
147
- idempotencyKey: ctx.meta.idempotencyKey
148
- });
149
- return result;
150
- }
151
- }
152
- });
153
- }
154
-
155
- //#endregion
156
- //#region src/infrastructure/plugins/business/metrics.plugin.ts
157
- /**
158
- * Metrics Plugin
159
- * @classytic/revenue
160
- *
161
- * Collects operation metrics (duration, success/failure)
162
- */
163
- /**
164
- * Metrics plugin - collects operation metrics
165
- *
166
- * Tracks duration and success/failure of operations
167
- *
168
- * @param options - Plugin options
169
- * @returns Metrics plugin
170
- *
171
- * @example
172
- * ```typescript
173
- * import { Revenue } from '@classytic/revenue';
174
- * import { metricsPlugin } from '@classytic/revenue/plugins';
175
- *
176
- * const revenue = Revenue
177
- * .create()
178
- * .withPlugin(metricsPlugin({
179
- * onMetric: (metric) => {
180
- * // Send to Datadog, Prometheus, etc.
181
- * statsd.timing(metric.name, metric.duration);
182
- * if (!metric.success) {
183
- * statsd.increment(`${metric.name}.error`);
184
- * }
185
- * }
186
- * }))
187
- * .build();
188
- * ```
189
- */
190
- function metricsPlugin(options = {}) {
191
- const metrics = [];
192
- const record = options.onMetric ?? ((metric) => {
193
- metrics.push(metric);
194
- });
195
- return definePlugin({
196
- name: "metrics",
197
- version: "1.0.0",
198
- description: "Collects operation metrics",
199
- hooks: { "payment.create.before": async (_ctx, input, next) => {
200
- const start = Date.now();
201
- try {
202
- const result = await next();
203
- record({
204
- name: "payment.create",
205
- duration: Date.now() - start,
206
- success: true,
207
- amount: input.amount,
208
- currency: input.currency
209
- });
210
- return result;
211
- } catch (error) {
212
- record({
213
- name: "payment.create",
214
- duration: Date.now() - start,
215
- success: false,
216
- error: error.message
217
- });
218
- throw error;
219
- }
220
- } }
221
- });
222
- }
223
-
224
- //#endregion
225
- //#region src/infrastructure/plugins/business/tax.plugin.ts
226
- /**
227
- * Tax Plugin
228
- * @classytic/revenue
229
- *
230
- * Automatic tax calculation for transactions
231
- * Integrates with monetization.create.before hook
232
- */
233
- /**
234
- * Create Tax Plugin
235
- *
236
- * Automatically calculates and applies tax to transactions during monetization.create()
237
- *
238
- * @param options - Plugin options
239
- * @returns Tax plugin
240
- *
241
- * @example
242
- * ```typescript
243
- * import { Revenue } from '@classytic/revenue';
244
- * import { createTaxPlugin } from '@classytic/revenue/plugins';
245
- *
246
- * const revenue = Revenue
247
- * .create({ defaultCurrency: 'USD' })
248
- * .withModels({ Transaction, Subscription })
249
- * .withProvider('stripe', stripeProvider)
250
- * .withPlugin(createTaxPlugin({
251
- * getTaxConfig: async (orgId) => {
252
- * const org = await Organization.findById(orgId);
253
- * return {
254
- * isRegistered: true,
255
- * defaultRate: 0.15, // 15% tax
256
- * pricesIncludeTax: false,
257
- * exemptCategories: ['education'],
258
- * };
259
- * },
260
- * categoryMappings: {
261
- * Order: 'order_subscription',
262
- * Membership: 'gym_membership',
263
- * },
264
- * }))
265
- * .build();
266
- *
267
- * // Tax is now automatically calculated
268
- * await revenue.monetization.create({
269
- * data: { organizationId: 'org_123', customerId: 'cust_456' },
270
- * planKey: 'monthly',
271
- * amount: 10000, // $100
272
- * entity: 'Order',
273
- * monetizationType: 'subscription',
274
- * });
275
- * // → Creates transaction with tax: {
276
- * // isApplicable: true,
277
- * // rate: 0.15,
278
- * // baseAmount: 10000,
279
- * // taxAmount: 1500,
280
- * // totalAmount: 11500,
281
- * // type: 'collected'
282
- * // }
283
- * ```
284
- */
285
- function createTaxPlugin(options) {
286
- const { getTaxConfig, categoryMappings = {}, incomeCategories = [
287
- "subscription",
288
- "purchase",
289
- "course_enrollment",
290
- "product_order"
291
- ] } = options;
292
- return definePlugin({
293
- name: "tax",
294
- version: "1.0.0",
295
- description: "Automatic tax calculation for transactions",
296
- hooks: { "monetization.create.before": async (ctx, input, next) => {
297
- const orgId = input.data.organizationId;
298
- if (!orgId) {
299
- ctx.logger.debug("Tax plugin: No organizationId in input.data, skipping tax calculation");
300
- return next();
301
- }
302
- try {
303
- const config = await getTaxConfig(orgId);
304
- if (!config) {
305
- ctx.logger.debug("Tax plugin: No tax config for org", { orgId });
306
- return next();
307
- }
308
- const category = resolveCategory(input.entity, input.monetizationType || "subscription", categoryMappings);
309
- const transactionFlow = incomeCategories.includes(category) ? "inflow" : "outflow";
310
- const taxCalc = calculateTax(input.amount, category, config);
311
- const taxType = getTaxType(transactionFlow, category, config.exemptCategories);
312
- input.tax = {
313
- ...taxCalc,
314
- type: taxType
315
- };
316
- ctx.logger.debug("Tax plugin: Tax calculated", {
317
- orgId,
318
- category,
319
- entity: input.entity,
320
- monetizationType: input.monetizationType,
321
- taxAmount: taxCalc.taxAmount,
322
- type: taxType
323
- });
324
- } catch (error) {
325
- ctx.logger.error("Tax plugin: Failed to calculate tax", {
326
- orgId,
327
- error: error.message
328
- });
329
- }
330
- return next();
331
- } }
332
- });
333
- }
334
-
335
- //#endregion
336
- //#region src/infrastructure/plugins/index.ts
337
- var plugins_default = {
338
- loggingPlugin,
339
- auditPlugin,
340
- metricsPlugin,
341
- createTaxPlugin
342
- };
343
-
344
- //#endregion
345
- export { auditPlugin, createTaxPlugin, plugins_default as default, definePlugin, loggingPlugin, metricsPlugin };
@@ -1,271 +0,0 @@
1
- //#region src/shared/utils/formatters/money.ts
2
- /** Supported currencies with their decimal places */
3
- const CURRENCIES = {
4
- USD: {
5
- code: "USD",
6
- decimals: 2,
7
- symbol: "$",
8
- name: "US Dollar"
9
- },
10
- EUR: {
11
- code: "EUR",
12
- decimals: 2,
13
- symbol: "€",
14
- name: "Euro"
15
- },
16
- GBP: {
17
- code: "GBP",
18
- decimals: 2,
19
- symbol: "£",
20
- name: "British Pound"
21
- },
22
- BDT: {
23
- code: "BDT",
24
- decimals: 2,
25
- symbol: "৳",
26
- name: "Bangladeshi Taka"
27
- },
28
- INR: {
29
- code: "INR",
30
- decimals: 2,
31
- symbol: "₹",
32
- name: "Indian Rupee"
33
- },
34
- JPY: {
35
- code: "JPY",
36
- decimals: 0,
37
- symbol: "¥",
38
- name: "Japanese Yen"
39
- },
40
- CNY: {
41
- code: "CNY",
42
- decimals: 2,
43
- symbol: "¥",
44
- name: "Chinese Yuan"
45
- },
46
- AED: {
47
- code: "AED",
48
- decimals: 2,
49
- symbol: "د.إ",
50
- name: "UAE Dirham"
51
- },
52
- SAR: {
53
- code: "SAR",
54
- decimals: 2,
55
- symbol: "﷼",
56
- name: "Saudi Riyal"
57
- },
58
- SGD: {
59
- code: "SGD",
60
- decimals: 2,
61
- symbol: "S$",
62
- name: "Singapore Dollar"
63
- },
64
- AUD: {
65
- code: "AUD",
66
- decimals: 2,
67
- symbol: "A$",
68
- name: "Australian Dollar"
69
- },
70
- CAD: {
71
- code: "CAD",
72
- decimals: 2,
73
- symbol: "C$",
74
- name: "Canadian Dollar"
75
- }
76
- };
77
- /**
78
- * Money class - immutable money representation
79
- */
80
- var Money = class Money {
81
- amount;
82
- currency;
83
- constructor(amount, currency) {
84
- if (!Number.isInteger(amount)) throw new Error(`Money amount must be integer (smallest unit). Got: ${amount}`);
85
- this.amount = amount;
86
- this.currency = currency.toUpperCase();
87
- }
88
- /**
89
- * Create money from smallest unit (cents, paisa)
90
- * @example Money.cents(1999, 'USD') // $19.99
91
- */
92
- static cents(amount, currency = "USD") {
93
- return new Money(Math.round(amount), currency);
94
- }
95
- /**
96
- * Create money from major unit (dollars, taka)
97
- * @example Money.of(19.99, 'USD') // $19.99 (stored as 1999 cents)
98
- */
99
- static of(amount, currency = "USD") {
100
- const config = CURRENCIES[currency.toUpperCase()] ?? { decimals: 2 };
101
- const multiplier = Math.pow(10, config.decimals);
102
- return new Money(Math.round(amount * multiplier), currency);
103
- }
104
- /**
105
- * Create zero money
106
- */
107
- static zero(currency = "USD") {
108
- return new Money(0, currency);
109
- }
110
- static usd(cents) {
111
- return Money.cents(cents, "USD");
112
- }
113
- static eur(cents) {
114
- return Money.cents(cents, "EUR");
115
- }
116
- static gbp(pence) {
117
- return Money.cents(pence, "GBP");
118
- }
119
- static bdt(paisa) {
120
- return Money.cents(paisa, "BDT");
121
- }
122
- static inr(paisa) {
123
- return Money.cents(paisa, "INR");
124
- }
125
- static jpy(yen) {
126
- return Money.cents(yen, "JPY");
127
- }
128
- /**
129
- * Add two money values (must be same currency)
130
- */
131
- add(other) {
132
- this.assertSameCurrency(other);
133
- return new Money(this.amount + other.amount, this.currency);
134
- }
135
- /**
136
- * Subtract money (must be same currency)
137
- */
138
- subtract(other) {
139
- this.assertSameCurrency(other);
140
- return new Money(this.amount - other.amount, this.currency);
141
- }
142
- /**
143
- * Multiply by a factor (rounds to nearest integer)
144
- */
145
- multiply(factor) {
146
- return new Money(Math.round(this.amount * factor), this.currency);
147
- }
148
- /**
149
- * Divide by a divisor (rounds to nearest integer)
150
- */
151
- divide(divisor) {
152
- if (divisor === 0) throw new Error("Cannot divide by zero");
153
- return new Money(Math.round(this.amount / divisor), this.currency);
154
- }
155
- /**
156
- * Calculate percentage
157
- * @example money.percentage(10) // 10% of money
158
- */
159
- percentage(percent) {
160
- return this.multiply(percent / 100);
161
- }
162
- /**
163
- * Allocate money among recipients (handles rounding)
164
- * @example Money.usd(100).allocate([1, 1, 1]) // [34, 33, 33] cents
165
- */
166
- allocate(ratios) {
167
- const total = ratios.reduce((a, b) => a + b, 0);
168
- if (total === 0) throw new Error("Ratios must sum to more than 0");
169
- let remainder = this.amount;
170
- const results = [];
171
- for (let i = 0; i < ratios.length; i++) {
172
- const share = Math.floor(this.amount * ratios[i] / total);
173
- results.push(new Money(share, this.currency));
174
- remainder -= share;
175
- }
176
- for (let i = 0; i < remainder; i++) results[i] = new Money(results[i].amount + 1, this.currency);
177
- return results;
178
- }
179
- /**
180
- * Split equally among n recipients
181
- */
182
- split(parts) {
183
- return this.allocate(Array(parts).fill(1));
184
- }
185
- isZero() {
186
- return this.amount === 0;
187
- }
188
- isPositive() {
189
- return this.amount > 0;
190
- }
191
- isNegative() {
192
- return this.amount < 0;
193
- }
194
- equals(other) {
195
- return this.amount === other.amount && this.currency === other.currency;
196
- }
197
- greaterThan(other) {
198
- this.assertSameCurrency(other);
199
- return this.amount > other.amount;
200
- }
201
- lessThan(other) {
202
- this.assertSameCurrency(other);
203
- return this.amount < other.amount;
204
- }
205
- greaterThanOrEqual(other) {
206
- return this.greaterThan(other) || this.equals(other);
207
- }
208
- lessThanOrEqual(other) {
209
- return this.lessThan(other) || this.equals(other);
210
- }
211
- /**
212
- * Get amount in major unit (dollars, taka)
213
- */
214
- toUnit() {
215
- const config = CURRENCIES[this.currency] ?? { decimals: 2 };
216
- return this.amount / Math.pow(10, config.decimals);
217
- }
218
- /**
219
- * Format for display
220
- * @example Money.usd(1999).format() // "$19.99"
221
- */
222
- format(locale = "en-US") {
223
- return new Intl.NumberFormat(locale, {
224
- style: "currency",
225
- currency: this.currency
226
- }).format(this.toUnit());
227
- }
228
- /**
229
- * Format without currency symbol
230
- */
231
- formatAmount(locale = "en-US") {
232
- const config = CURRENCIES[this.currency] ?? { decimals: 2 };
233
- return new Intl.NumberFormat(locale, {
234
- minimumFractionDigits: config.decimals,
235
- maximumFractionDigits: config.decimals
236
- }).format(this.toUnit());
237
- }
238
- /**
239
- * Convert to JSON-serializable object
240
- */
241
- toJSON() {
242
- return {
243
- amount: this.amount,
244
- currency: this.currency
245
- };
246
- }
247
- /**
248
- * Create from JSON
249
- */
250
- static fromJSON(json) {
251
- return new Money(json.amount, json.currency);
252
- }
253
- toString() {
254
- return `${this.currency} ${this.amount}`;
255
- }
256
- assertSameCurrency(other) {
257
- if (this.currency !== other.currency) throw new Error(`Currency mismatch: ${this.currency} vs ${other.currency}. Convert first.`);
258
- }
259
- };
260
- /**
261
- * Helper functions for legacy compatibility
262
- */
263
- function toSmallestUnit(amount, currency = "USD") {
264
- return Money.of(amount, currency).amount;
265
- }
266
- function fromSmallestUnit(amount, currency = "USD") {
267
- return Money.cents(amount, currency).toUnit();
268
- }
269
-
270
- //#endregion
271
- export { fromSmallestUnit as n, toSmallestUnit as r, Money as t };
@@ -1,112 +0,0 @@
1
- //#region src/shared/utils/formatters/money.d.ts
2
- /**
3
- * Money Utility - Integer-safe currency handling
4
- * @classytic/revenue
5
- *
6
- * Never use floating point for money!
7
- * All amounts stored as smallest unit (cents, paisa, etc.)
8
- *
9
- * Inspired by: Stripe, Dinero.js, tc39/proposal-decimal
10
- */
11
- interface MoneyValue {
12
- /** Amount in smallest currency unit (cents, paisa, etc.) */
13
- readonly amount: number;
14
- /** ISO 4217 currency code */
15
- readonly currency: string;
16
- }
17
- /**
18
- * Money class - immutable money representation
19
- */
20
- declare class Money implements MoneyValue {
21
- readonly amount: number;
22
- readonly currency: string;
23
- private constructor();
24
- /**
25
- * Create money from smallest unit (cents, paisa)
26
- * @example Money.cents(1999, 'USD') // $19.99
27
- */
28
- static cents(amount: number, currency?: string): Money;
29
- /**
30
- * Create money from major unit (dollars, taka)
31
- * @example Money.of(19.99, 'USD') // $19.99 (stored as 1999 cents)
32
- */
33
- static of(amount: number, currency?: string): Money;
34
- /**
35
- * Create zero money
36
- */
37
- static zero(currency?: string): Money;
38
- static usd(cents: number): Money;
39
- static eur(cents: number): Money;
40
- static gbp(pence: number): Money;
41
- static bdt(paisa: number): Money;
42
- static inr(paisa: number): Money;
43
- static jpy(yen: number): Money;
44
- /**
45
- * Add two money values (must be same currency)
46
- */
47
- add(other: Money): Money;
48
- /**
49
- * Subtract money (must be same currency)
50
- */
51
- subtract(other: Money): Money;
52
- /**
53
- * Multiply by a factor (rounds to nearest integer)
54
- */
55
- multiply(factor: number): Money;
56
- /**
57
- * Divide by a divisor (rounds to nearest integer)
58
- */
59
- divide(divisor: number): Money;
60
- /**
61
- * Calculate percentage
62
- * @example money.percentage(10) // 10% of money
63
- */
64
- percentage(percent: number): Money;
65
- /**
66
- * Allocate money among recipients (handles rounding)
67
- * @example Money.usd(100).allocate([1, 1, 1]) // [34, 33, 33] cents
68
- */
69
- allocate(ratios: number[]): Money[];
70
- /**
71
- * Split equally among n recipients
72
- */
73
- split(parts: number): Money[];
74
- isZero(): boolean;
75
- isPositive(): boolean;
76
- isNegative(): boolean;
77
- equals(other: Money): boolean;
78
- greaterThan(other: Money): boolean;
79
- lessThan(other: Money): boolean;
80
- greaterThanOrEqual(other: Money): boolean;
81
- lessThanOrEqual(other: Money): boolean;
82
- /**
83
- * Get amount in major unit (dollars, taka)
84
- */
85
- toUnit(): number;
86
- /**
87
- * Format for display
88
- * @example Money.usd(1999).format() // "$19.99"
89
- */
90
- format(locale?: string): string;
91
- /**
92
- * Format without currency symbol
93
- */
94
- formatAmount(locale?: string): string;
95
- /**
96
- * Convert to JSON-serializable object
97
- */
98
- toJSON(): MoneyValue;
99
- /**
100
- * Create from JSON
101
- */
102
- static fromJSON(json: MoneyValue): Money;
103
- toString(): string;
104
- private assertSameCurrency;
105
- }
106
- /**
107
- * Helper functions for legacy compatibility
108
- */
109
- declare function toSmallestUnit(amount: number, currency?: string): number;
110
- declare function fromSmallestUnit(amount: number, currency?: string): number;
111
- //#endregion
112
- export { toSmallestUnit as i, MoneyValue as n, fromSmallestUnit as r, Money as t };