@classytic/revenue 0.2.3 → 1.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 (111) hide show
  1. package/README.md +498 -499
  2. package/dist/actions-CwG-b7fR.d.ts +519 -0
  3. package/dist/core/index.d.ts +884 -0
  4. package/dist/core/index.js +2941 -0
  5. package/dist/core/index.js.map +1 -0
  6. package/dist/enums/index.d.ts +130 -0
  7. package/dist/enums/index.js +167 -0
  8. package/dist/enums/index.js.map +1 -0
  9. package/dist/index-BnJWVXuw.d.ts +378 -0
  10. package/dist/index-ChVD3P9k.d.ts +504 -0
  11. package/dist/index.d.ts +42 -0
  12. package/dist/index.js +4353 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/providers/index.d.ts +132 -0
  15. package/dist/providers/index.js +122 -0
  16. package/dist/providers/index.js.map +1 -0
  17. package/dist/retry-80lBCmSe.d.ts +234 -0
  18. package/dist/schemas/index.d.ts +894 -0
  19. package/dist/schemas/index.js +524 -0
  20. package/dist/schemas/index.js.map +1 -0
  21. package/dist/schemas/validation.d.ts +309 -0
  22. package/dist/schemas/validation.js +249 -0
  23. package/dist/schemas/validation.js.map +1 -0
  24. package/dist/services/index.d.ts +3 -0
  25. package/dist/services/index.js +1632 -0
  26. package/dist/services/index.js.map +1 -0
  27. package/dist/split.enums-DHdM1YAV.d.ts +255 -0
  28. package/dist/split.schema-BPdFZMbU.d.ts +958 -0
  29. package/dist/utils/index.d.ts +24 -0
  30. package/dist/utils/index.js +1067 -0
  31. package/dist/utils/index.js.map +1 -0
  32. package/package.json +48 -32
  33. package/core/builder.js +0 -219
  34. package/core/container.js +0 -119
  35. package/core/errors.js +0 -262
  36. package/dist/types/core/builder.d.ts +0 -97
  37. package/dist/types/core/container.d.ts +0 -57
  38. package/dist/types/core/errors.d.ts +0 -122
  39. package/dist/types/enums/escrow.enums.d.ts +0 -24
  40. package/dist/types/enums/index.d.ts +0 -69
  41. package/dist/types/enums/monetization.enums.d.ts +0 -6
  42. package/dist/types/enums/payment.enums.d.ts +0 -16
  43. package/dist/types/enums/split.enums.d.ts +0 -25
  44. package/dist/types/enums/subscription.enums.d.ts +0 -15
  45. package/dist/types/enums/transaction.enums.d.ts +0 -24
  46. package/dist/types/index.d.ts +0 -22
  47. package/dist/types/providers/base.d.ts +0 -126
  48. package/dist/types/schemas/escrow/hold.schema.d.ts +0 -54
  49. package/dist/types/schemas/escrow/index.d.ts +0 -6
  50. package/dist/types/schemas/index.d.ts +0 -506
  51. package/dist/types/schemas/split/index.d.ts +0 -8
  52. package/dist/types/schemas/split/split.schema.d.ts +0 -142
  53. package/dist/types/schemas/subscription/index.d.ts +0 -152
  54. package/dist/types/schemas/subscription/info.schema.d.ts +0 -128
  55. package/dist/types/schemas/subscription/plan.schema.d.ts +0 -39
  56. package/dist/types/schemas/transaction/common.schema.d.ts +0 -12
  57. package/dist/types/schemas/transaction/gateway.schema.d.ts +0 -86
  58. package/dist/types/schemas/transaction/index.d.ts +0 -202
  59. package/dist/types/schemas/transaction/payment.schema.d.ts +0 -145
  60. package/dist/types/services/escrow.service.d.ts +0 -51
  61. package/dist/types/services/monetization.service.d.ts +0 -193
  62. package/dist/types/services/payment.service.d.ts +0 -112
  63. package/dist/types/services/transaction.service.d.ts +0 -40
  64. package/dist/types/utils/category-resolver.d.ts +0 -46
  65. package/dist/types/utils/commission-split.d.ts +0 -56
  66. package/dist/types/utils/commission.d.ts +0 -29
  67. package/dist/types/utils/hooks.d.ts +0 -17
  68. package/dist/types/utils/index.d.ts +0 -6
  69. package/dist/types/utils/logger.d.ts +0 -12
  70. package/dist/types/utils/subscription/actions.d.ts +0 -28
  71. package/dist/types/utils/subscription/index.d.ts +0 -2
  72. package/dist/types/utils/subscription/period.d.ts +0 -47
  73. package/dist/types/utils/transaction-type.d.ts +0 -102
  74. package/enums/escrow.enums.js +0 -36
  75. package/enums/index.d.ts +0 -116
  76. package/enums/index.js +0 -110
  77. package/enums/monetization.enums.js +0 -15
  78. package/enums/payment.enums.js +0 -64
  79. package/enums/split.enums.js +0 -37
  80. package/enums/subscription.enums.js +0 -33
  81. package/enums/transaction.enums.js +0 -69
  82. package/index.js +0 -76
  83. package/providers/base.js +0 -162
  84. package/schemas/escrow/hold.schema.js +0 -62
  85. package/schemas/escrow/index.js +0 -15
  86. package/schemas/index.d.ts +0 -33
  87. package/schemas/index.js +0 -27
  88. package/schemas/split/index.js +0 -16
  89. package/schemas/split/split.schema.js +0 -86
  90. package/schemas/subscription/index.js +0 -17
  91. package/schemas/subscription/info.schema.js +0 -115
  92. package/schemas/subscription/plan.schema.js +0 -48
  93. package/schemas/transaction/common.schema.js +0 -22
  94. package/schemas/transaction/gateway.schema.js +0 -69
  95. package/schemas/transaction/index.js +0 -20
  96. package/schemas/transaction/payment.schema.js +0 -110
  97. package/services/escrow.service.js +0 -353
  98. package/services/monetization.service.js +0 -671
  99. package/services/payment.service.js +0 -517
  100. package/services/transaction.service.js +0 -142
  101. package/utils/category-resolver.js +0 -74
  102. package/utils/commission-split.js +0 -180
  103. package/utils/commission.js +0 -83
  104. package/utils/hooks.js +0 -44
  105. package/utils/index.d.ts +0 -164
  106. package/utils/index.js +0 -16
  107. package/utils/logger.js +0 -36
  108. package/utils/subscription/actions.js +0 -68
  109. package/utils/subscription/index.js +0 -20
  110. package/utils/subscription/period.js +0 -123
  111. package/utils/transaction-type.js +0 -254
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/money.ts","../../src/core/result.ts","../../src/utils/retry.ts","../../src/utils/idempotency.ts","../../src/utils/transaction-type.ts","../../src/utils/logger.ts","../../src/utils/hooks.ts","../../src/utils/commission.ts","../../src/enums/split.enums.ts","../../src/utils/commission-split.ts","../../src/enums/transaction.enums.ts","../../src/utils/category-resolver.ts","../../src/utils/subscription/period.ts","../../src/enums/subscription.enums.ts","../../src/utils/subscription/actions.ts"],"names":["logger"],"mappings":"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","file":"index.js","sourcesContent":["/**\r\n * Money Utility - Integer-safe currency handling\r\n * @classytic/revenue\r\n *\r\n * Never use floating point for money!\r\n * All amounts stored as smallest unit (cents, paisa, etc.)\r\n * \r\n * Inspired by: Stripe, Dinero.js, tc39/proposal-decimal\r\n */\r\n\r\nexport interface MoneyValue {\r\n /** Amount in smallest currency unit (cents, paisa, etc.) */\r\n readonly amount: number;\r\n /** ISO 4217 currency code */\r\n readonly currency: string;\r\n}\r\n\r\n/** Currency configuration */\r\ninterface CurrencyConfig {\r\n code: string;\r\n decimals: number;\r\n symbol: string;\r\n name: string;\r\n}\r\n\r\n/** Supported currencies with their decimal places */\r\nconst CURRENCIES: Record<string, CurrencyConfig> = {\r\n USD: { code: 'USD', decimals: 2, symbol: '$', name: 'US Dollar' },\r\n EUR: { code: 'EUR', decimals: 2, symbol: '€', name: 'Euro' },\r\n GBP: { code: 'GBP', decimals: 2, symbol: '£', name: 'British Pound' },\r\n BDT: { code: 'BDT', decimals: 2, symbol: '৳', name: 'Bangladeshi Taka' },\r\n INR: { code: 'INR', decimals: 2, symbol: '₹', name: 'Indian Rupee' },\r\n JPY: { code: 'JPY', decimals: 0, symbol: '¥', name: 'Japanese Yen' },\r\n CNY: { code: 'CNY', decimals: 2, symbol: '¥', name: 'Chinese Yuan' },\r\n AED: { code: 'AED', decimals: 2, symbol: 'د.إ', name: 'UAE Dirham' },\r\n SAR: { code: 'SAR', decimals: 2, symbol: '﷼', name: 'Saudi Riyal' },\r\n SGD: { code: 'SGD', decimals: 2, symbol: 'S$', name: 'Singapore Dollar' },\r\n AUD: { code: 'AUD', decimals: 2, symbol: 'A$', name: 'Australian Dollar' },\r\n CAD: { code: 'CAD', decimals: 2, symbol: 'C$', name: 'Canadian Dollar' },\r\n};\r\n\r\n/**\r\n * Money class - immutable money representation\r\n */\r\nexport class Money implements MoneyValue {\r\n readonly amount: number;\r\n readonly currency: string;\r\n\r\n private constructor(amount: number, currency: string) {\r\n if (!Number.isInteger(amount)) {\r\n throw new Error(`Money amount must be integer (smallest unit). Got: ${amount}`);\r\n }\r\n this.amount = amount;\r\n this.currency = currency.toUpperCase();\r\n }\r\n\r\n // ============ FACTORY METHODS ============\r\n\r\n /**\r\n * Create money from smallest unit (cents, paisa)\r\n * @example Money.cents(1999, 'USD') // $19.99\r\n */\r\n static cents(amount: number, currency = 'USD'): Money {\r\n return new Money(Math.round(amount), currency);\r\n }\r\n\r\n /**\r\n * Create money from major unit (dollars, taka)\r\n * @example Money.of(19.99, 'USD') // $19.99 (stored as 1999 cents)\r\n */\r\n static of(amount: number, currency = 'USD'): Money {\r\n const config = CURRENCIES[currency.toUpperCase()] ?? { decimals: 2 };\r\n const multiplier = Math.pow(10, config.decimals);\r\n return new Money(Math.round(amount * multiplier), currency);\r\n }\r\n\r\n /**\r\n * Create zero money\r\n */\r\n static zero(currency = 'USD'): Money {\r\n return new Money(0, currency);\r\n }\r\n\r\n // ============ SHORTHAND FACTORIES ============\r\n\r\n static usd(cents: number): Money { return Money.cents(cents, 'USD'); }\r\n static eur(cents: number): Money { return Money.cents(cents, 'EUR'); }\r\n static gbp(pence: number): Money { return Money.cents(pence, 'GBP'); }\r\n static bdt(paisa: number): Money { return Money.cents(paisa, 'BDT'); }\r\n static inr(paisa: number): Money { return Money.cents(paisa, 'INR'); }\r\n static jpy(yen: number): Money { return Money.cents(yen, 'JPY'); }\r\n\r\n // ============ ARITHMETIC ============\r\n\r\n /**\r\n * Add two money values (must be same currency)\r\n */\r\n add(other: Money): Money {\r\n this.assertSameCurrency(other);\r\n return new Money(this.amount + other.amount, this.currency);\r\n }\r\n\r\n /**\r\n * Subtract money (must be same currency)\r\n */\r\n subtract(other: Money): Money {\r\n this.assertSameCurrency(other);\r\n return new Money(this.amount - other.amount, this.currency);\r\n }\r\n\r\n /**\r\n * Multiply by a factor (rounds to nearest integer)\r\n */\r\n multiply(factor: number): Money {\r\n return new Money(Math.round(this.amount * factor), this.currency);\r\n }\r\n\r\n /**\r\n * Divide by a divisor (rounds to nearest integer)\r\n */\r\n divide(divisor: number): Money {\r\n if (divisor === 0) throw new Error('Cannot divide by zero');\r\n return new Money(Math.round(this.amount / divisor), this.currency);\r\n }\r\n\r\n /**\r\n * Calculate percentage\r\n * @example money.percentage(10) // 10% of money\r\n */\r\n percentage(percent: number): Money {\r\n return this.multiply(percent / 100);\r\n }\r\n\r\n /**\r\n * Allocate money among recipients (handles rounding)\r\n * @example Money.usd(100).allocate([1, 1, 1]) // [34, 33, 33] cents\r\n */\r\n allocate(ratios: number[]): Money[] {\r\n const total = ratios.reduce((a, b) => a + b, 0);\r\n if (total === 0) throw new Error('Ratios must sum to more than 0');\r\n\r\n let remainder = this.amount;\r\n const results: Money[] = [];\r\n\r\n for (let i = 0; i < ratios.length; i++) {\r\n const share = Math.floor((this.amount * ratios[i]) / total);\r\n results.push(new Money(share, this.currency));\r\n remainder -= share;\r\n }\r\n\r\n // Distribute remainder (largest remainder method)\r\n for (let i = 0; i < remainder; i++) {\r\n results[i] = new Money(results[i].amount + 1, this.currency);\r\n }\r\n\r\n return results;\r\n }\r\n\r\n /**\r\n * Split equally among n recipients\r\n */\r\n split(parts: number): Money[] {\r\n return this.allocate(Array(parts).fill(1));\r\n }\r\n\r\n // ============ COMPARISON ============\r\n\r\n isZero(): boolean { return this.amount === 0; }\r\n isPositive(): boolean { return this.amount > 0; }\r\n isNegative(): boolean { return this.amount < 0; }\r\n \r\n equals(other: Money): boolean {\r\n return this.amount === other.amount && this.currency === other.currency;\r\n }\r\n\r\n greaterThan(other: Money): boolean {\r\n this.assertSameCurrency(other);\r\n return this.amount > other.amount;\r\n }\r\n\r\n lessThan(other: Money): boolean {\r\n this.assertSameCurrency(other);\r\n return this.amount < other.amount;\r\n }\r\n\r\n greaterThanOrEqual(other: Money): boolean {\r\n return this.greaterThan(other) || this.equals(other);\r\n }\r\n\r\n lessThanOrEqual(other: Money): boolean {\r\n return this.lessThan(other) || this.equals(other);\r\n }\r\n\r\n // ============ FORMATTING ============\r\n\r\n /**\r\n * Get amount in major unit (dollars, taka)\r\n */\r\n toUnit(): number {\r\n const config = CURRENCIES[this.currency] ?? { decimals: 2 };\r\n return this.amount / Math.pow(10, config.decimals);\r\n }\r\n\r\n /**\r\n * Format for display\r\n * @example Money.usd(1999).format() // \"$19.99\"\r\n */\r\n format(locale = 'en-US'): string {\r\n return new Intl.NumberFormat(locale, {\r\n style: 'currency',\r\n currency: this.currency,\r\n }).format(this.toUnit());\r\n }\r\n\r\n /**\r\n * Format without currency symbol\r\n */\r\n formatAmount(locale = 'en-US'): string {\r\n const config = CURRENCIES[this.currency] ?? { decimals: 2 };\r\n return new Intl.NumberFormat(locale, {\r\n minimumFractionDigits: config.decimals,\r\n maximumFractionDigits: config.decimals,\r\n }).format(this.toUnit());\r\n }\r\n\r\n /**\r\n * Convert to JSON-serializable object\r\n */\r\n toJSON(): MoneyValue {\r\n return { amount: this.amount, currency: this.currency };\r\n }\r\n\r\n /**\r\n * Create from JSON\r\n */\r\n static fromJSON(json: MoneyValue): Money {\r\n return new Money(json.amount, json.currency);\r\n }\r\n\r\n toString(): string {\r\n return `${this.currency} ${this.amount}`;\r\n }\r\n\r\n // ============ HELPERS ============\r\n\r\n private assertSameCurrency(other: Money): void {\r\n if (this.currency !== other.currency) {\r\n throw new Error(\r\n `Currency mismatch: ${this.currency} vs ${other.currency}. Convert first.`\r\n );\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Helper functions for legacy compatibility\r\n */\r\nexport function toSmallestUnit(amount: number, currency = 'USD'): number {\r\n return Money.of(amount, currency).amount;\r\n}\r\n\r\nexport function fromSmallestUnit(amount: number, currency = 'USD'): number {\r\n return Money.cents(amount, currency).toUnit();\r\n}\r\n\r\nexport default Money;\r\n\r\n","/**\r\n * Result Type - Rust-inspired error handling\r\n * @classytic/revenue\r\n *\r\n * No more try/catch - explicit, type-safe error handling\r\n * Inspired by: Rust Result<T, E>, neverthrow, Effect-TS\r\n */\r\n\r\n/**\r\n * Success result\r\n */\r\nexport interface Ok<T> {\r\n readonly ok: true;\r\n readonly value: T;\r\n readonly error?: never;\r\n}\r\n\r\n/**\r\n * Error result\r\n */\r\nexport interface Err<E> {\r\n readonly ok: false;\r\n readonly error: E;\r\n readonly value?: never;\r\n}\r\n\r\n/**\r\n * Result type - either Ok<T> or Err<E>\r\n */\r\nexport type Result<T, E = Error> = Ok<T> | Err<E>;\r\n\r\n/**\r\n * Create a success result\r\n */\r\nexport function ok<T>(value: T): Ok<T> {\r\n return { ok: true, value };\r\n}\r\n\r\n/**\r\n * Create an error result\r\n */\r\nexport function err<E>(error: E): Err<E> {\r\n return { ok: false, error };\r\n}\r\n\r\n/**\r\n * Check if result is Ok\r\n */\r\nexport function isOk<T, E>(result: Result<T, E>): result is Ok<T> {\r\n return result.ok === true;\r\n}\r\n\r\n/**\r\n * Check if result is Err\r\n */\r\nexport function isErr<T, E>(result: Result<T, E>): result is Err<E> {\r\n return result.ok === false;\r\n}\r\n\r\n/**\r\n * Unwrap a result, throwing if it's an error\r\n * Use sparingly - prefer pattern matching\r\n */\r\nexport function unwrap<T, E>(result: Result<T, E>): T {\r\n if (result.ok) return result.value;\r\n throw result.error;\r\n}\r\n\r\n/**\r\n * Unwrap a result with a default value\r\n */\r\nexport function unwrapOr<T, E>(result: Result<T, E>, defaultValue: T): T {\r\n return result.ok ? result.value : defaultValue;\r\n}\r\n\r\n/**\r\n * Map over a successful result\r\n */\r\nexport function map<T, U, E>(\r\n result: Result<T, E>,\r\n fn: (value: T) => U\r\n): Result<U, E> {\r\n return result.ok ? ok(fn(result.value)) : result;\r\n}\r\n\r\n/**\r\n * Map over an error result\r\n */\r\nexport function mapErr<T, E, F>(\r\n result: Result<T, E>,\r\n fn: (error: E) => F\r\n): Result<T, F> {\r\n return result.ok ? result : err(fn(result.error));\r\n}\r\n\r\n/**\r\n * Flat map (chain) results\r\n */\r\nexport function flatMap<T, U, E>(\r\n result: Result<T, E>,\r\n fn: (value: T) => Result<U, E>\r\n): Result<U, E> {\r\n return result.ok ? fn(result.value) : result;\r\n}\r\n\r\n/**\r\n * Try-catch wrapper that returns Result\r\n */\r\nexport async function tryCatch<T, E = Error>(\r\n fn: () => Promise<T>,\r\n mapError?: (e: unknown) => E\r\n): Promise<Result<T, E>> {\r\n try {\r\n const value = await fn();\r\n return ok(value);\r\n } catch (e) {\r\n const error = mapError ? mapError(e) : (e as E);\r\n return err(error);\r\n }\r\n}\r\n\r\n/**\r\n * Synchronous try-catch wrapper\r\n */\r\nexport function tryCatchSync<T, E = Error>(\r\n fn: () => T,\r\n mapError?: (e: unknown) => E\r\n): Result<T, E> {\r\n try {\r\n const value = fn();\r\n return ok(value);\r\n } catch (e) {\r\n const error = mapError ? mapError(e) : (e as E);\r\n return err(error);\r\n }\r\n}\r\n\r\n/**\r\n * Combine multiple results - all must succeed\r\n */\r\nexport function all<T extends readonly Result<unknown, unknown>[]>(\r\n results: T\r\n): Result<\r\n { [K in keyof T]: T[K] extends Result<infer U, unknown> ? U : never },\r\n T[number] extends Result<unknown, infer E> ? E : never\r\n> {\r\n const values: unknown[] = [];\r\n for (const result of results) {\r\n if (!result.ok) return result as any;\r\n values.push(result.value);\r\n }\r\n return ok(values as any);\r\n}\r\n\r\n/**\r\n * Pattern match on result\r\n */\r\nexport function match<T, E, U>(\r\n result: Result<T, E>,\r\n handlers: {\r\n ok: (value: T) => U;\r\n err: (error: E) => U;\r\n }\r\n): U {\r\n return result.ok ? handlers.ok(result.value) : handlers.err(result.error);\r\n}\r\n\r\nexport const Result = {\r\n ok,\r\n err,\r\n isOk,\r\n isErr,\r\n unwrap,\r\n unwrapOr,\r\n map,\r\n mapErr,\r\n flatMap,\r\n tryCatch,\r\n tryCatchSync,\r\n all,\r\n match,\r\n} as const;\r\n\r\nexport default Result;\r\n\r\n","/**\r\n * Retry Utilities\r\n * @classytic/revenue\r\n *\r\n * Exponential backoff with jitter for resilient operations\r\n * Inspired by: AWS SDK retry, Netflix Hystrix, resilience4j\r\n */\r\n\r\nimport { Result, ok, err } from '../core/result.js';\r\n\r\n// ============ TYPES ============\r\n\r\nexport interface RetryConfig {\r\n /** Maximum number of retry attempts (default: 3) */\r\n maxAttempts: number;\r\n /** Base delay in milliseconds (default: 1000) */\r\n baseDelay: number;\r\n /** Maximum delay in milliseconds (default: 30000) */\r\n maxDelay: number;\r\n /** Backoff multiplier (default: 2) */\r\n backoffMultiplier: number;\r\n /** Jitter factor 0-1 (default: 0.1) */\r\n jitter: number;\r\n /** Which errors are retryable */\r\n retryIf?: (error: unknown) => boolean;\r\n /** Callback on each retry */\r\n onRetry?: (error: unknown, attempt: number, delay: number) => void;\r\n}\r\n\r\nexport interface RetryState {\r\n attempt: number;\r\n totalDelay: number;\r\n errors: Error[];\r\n}\r\n\r\n// ============ DEFAULT CONFIG ============\r\n\r\nconst DEFAULT_CONFIG: RetryConfig = {\r\n maxAttempts: 3,\r\n baseDelay: 1000,\r\n maxDelay: 30000,\r\n backoffMultiplier: 2,\r\n jitter: 0.1,\r\n retryIf: isRetryableError,\r\n};\r\n\r\n// ============ RETRY LOGIC ============\r\n\r\n/**\r\n * Calculate delay with exponential backoff and jitter\r\n */\r\nexport function calculateDelay(\r\n attempt: number,\r\n config: RetryConfig\r\n): number {\r\n // Exponential backoff: baseDelay * multiplier^attempt\r\n const exponentialDelay = config.baseDelay * Math.pow(config.backoffMultiplier, attempt);\r\n \r\n // Cap at maxDelay\r\n const cappedDelay = Math.min(exponentialDelay, config.maxDelay);\r\n \r\n // Add jitter (random variance)\r\n const jitterRange = cappedDelay * config.jitter;\r\n const jitter = Math.random() * jitterRange * 2 - jitterRange;\r\n \r\n return Math.round(Math.max(0, cappedDelay + jitter));\r\n}\r\n\r\n/**\r\n * Sleep for specified milliseconds\r\n */\r\nexport function sleep(ms: number): Promise<void> {\r\n return new Promise(resolve => setTimeout(resolve, ms));\r\n}\r\n\r\n/**\r\n * Check if error is retryable by default\r\n */\r\nexport function isRetryableError(error: unknown): boolean {\r\n if (!(error instanceof Error)) return false;\r\n\r\n // Network errors\r\n if (error.message.includes('ECONNREFUSED')) return true;\r\n if (error.message.includes('ETIMEDOUT')) return true;\r\n if (error.message.includes('ENOTFOUND')) return true;\r\n if (error.message.includes('network')) return true;\r\n if (error.message.includes('timeout')) return true;\r\n\r\n // Rate limiting\r\n if (error.message.includes('429')) return true;\r\n if (error.message.includes('rate limit')) return true;\r\n\r\n // Server errors (5xx)\r\n if (error.message.includes('500')) return true;\r\n if (error.message.includes('502')) return true;\r\n if (error.message.includes('503')) return true;\r\n if (error.message.includes('504')) return true;\r\n\r\n // Check for retryable property\r\n if ('retryable' in error && (error as any).retryable === true) return true;\r\n\r\n return false;\r\n}\r\n\r\n/**\r\n * Execute operation with retry logic\r\n */\r\nexport async function retry<T>(\r\n operation: () => Promise<T>,\r\n config: Partial<RetryConfig> = {}\r\n): Promise<T> {\r\n const fullConfig: RetryConfig = { ...DEFAULT_CONFIG, ...config };\r\n const state: RetryState = {\r\n attempt: 0,\r\n totalDelay: 0,\r\n errors: [],\r\n };\r\n\r\n while (state.attempt < fullConfig.maxAttempts) {\r\n try {\r\n return await operation();\r\n } catch (error) {\r\n state.errors.push(error instanceof Error ? error : new Error(String(error)));\r\n state.attempt++;\r\n\r\n // Check if we should retry\r\n const shouldRetry = fullConfig.retryIf?.(error) ?? isRetryableError(error);\r\n \r\n if (!shouldRetry || state.attempt >= fullConfig.maxAttempts) {\r\n throw new RetryExhaustedError(\r\n `Operation failed after ${state.attempt} attempts`,\r\n state.errors\r\n );\r\n }\r\n\r\n // Calculate delay\r\n const delay = calculateDelay(state.attempt - 1, fullConfig);\r\n state.totalDelay += delay;\r\n\r\n // Callback\r\n fullConfig.onRetry?.(error, state.attempt, delay);\r\n\r\n // Wait before retry\r\n await sleep(delay);\r\n }\r\n }\r\n\r\n // Should never reach here, but TypeScript needs it\r\n throw new RetryExhaustedError(\r\n `Operation failed after ${state.attempt} attempts`,\r\n state.errors\r\n );\r\n}\r\n\r\n/**\r\n * Execute operation with retry, returning Result instead of throwing\r\n */\r\nexport async function retryWithResult<T>(\r\n operation: () => Promise<T>,\r\n config: Partial<RetryConfig> = {}\r\n): Promise<Result<T, RetryExhaustedError>> {\r\n try {\r\n const result = await retry(operation, config);\r\n return ok(result);\r\n } catch (error) {\r\n if (error instanceof RetryExhaustedError) {\r\n return err(error);\r\n }\r\n return err(new RetryExhaustedError('Operation failed', [\r\n error instanceof Error ? error : new Error(String(error))\r\n ]));\r\n }\r\n}\r\n\r\n// ============ ERROR CLASSES ============\r\n\r\n/**\r\n * Error thrown when all retries are exhausted\r\n */\r\nexport class RetryExhaustedError extends Error {\r\n public readonly attempts: number;\r\n public readonly errors: Error[];\r\n\r\n constructor(message: string, errors: Error[]) {\r\n super(message);\r\n this.name = 'RetryExhaustedError';\r\n this.attempts = errors.length;\r\n this.errors = errors;\r\n }\r\n\r\n /**\r\n * Get the last error\r\n */\r\n get lastError(): Error | undefined {\r\n return this.errors[this.errors.length - 1];\r\n }\r\n\r\n /**\r\n * Get the first error\r\n */\r\n get firstError(): Error | undefined {\r\n return this.errors[0];\r\n }\r\n}\r\n\r\n// ============ CIRCUIT BREAKER ============\r\n\r\nexport type CircuitState = 'closed' | 'open' | 'half-open';\r\n\r\nexport interface CircuitBreakerConfig {\r\n /** Number of failures before opening circuit */\r\n failureThreshold: number;\r\n /** Time in ms to wait before half-opening */\r\n resetTimeout: number;\r\n /** Number of successes in half-open to close circuit */\r\n successThreshold: number;\r\n /** Monitor window in ms */\r\n monitorWindow: number;\r\n}\r\n\r\nconst DEFAULT_CIRCUIT_CONFIG: CircuitBreakerConfig = {\r\n failureThreshold: 5,\r\n resetTimeout: 30000,\r\n successThreshold: 3,\r\n monitorWindow: 60000,\r\n};\r\n\r\n/**\r\n * Circuit breaker for preventing cascade failures\r\n * Inspired by: Netflix Hystrix, resilience4j\r\n */\r\nexport class CircuitBreaker {\r\n private state: CircuitState = 'closed';\r\n private failures: Date[] = [];\r\n private successes = 0;\r\n private lastFailure?: Date;\r\n private config: CircuitBreakerConfig;\r\n\r\n constructor(config: Partial<CircuitBreakerConfig> = {}) {\r\n this.config = { ...DEFAULT_CIRCUIT_CONFIG, ...config };\r\n }\r\n\r\n /**\r\n * Execute operation through circuit breaker\r\n */\r\n async execute<T>(operation: () => Promise<T>): Promise<T> {\r\n // Check circuit state\r\n if (this.state === 'open') {\r\n if (this.shouldAttemptReset()) {\r\n this.state = 'half-open';\r\n } else {\r\n throw new CircuitOpenError('Circuit is open, request rejected');\r\n }\r\n }\r\n\r\n try {\r\n const result = await operation();\r\n this.onSuccess();\r\n return result;\r\n } catch (error) {\r\n this.onFailure();\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Execute with Result type\r\n */\r\n async executeWithResult<T>(\r\n operation: () => Promise<T>\r\n ): Promise<Result<T, CircuitOpenError | Error>> {\r\n try {\r\n const result = await this.execute(operation);\r\n return ok(result);\r\n } catch (error) {\r\n return err(error as Error);\r\n }\r\n }\r\n\r\n private onSuccess(): void {\r\n if (this.state === 'half-open') {\r\n this.successes++;\r\n if (this.successes >= this.config.successThreshold) {\r\n this.reset();\r\n }\r\n }\r\n // Clean old failures outside monitor window\r\n this.cleanOldFailures();\r\n }\r\n\r\n private onFailure(): void {\r\n this.failures.push(new Date());\r\n this.lastFailure = new Date();\r\n this.successes = 0;\r\n\r\n // Clean old failures\r\n this.cleanOldFailures();\r\n\r\n // Check if we should open circuit\r\n if (this.failures.length >= this.config.failureThreshold) {\r\n this.state = 'open';\r\n }\r\n }\r\n\r\n private shouldAttemptReset(): boolean {\r\n if (!this.lastFailure) return true;\r\n return Date.now() - this.lastFailure.getTime() >= this.config.resetTimeout;\r\n }\r\n\r\n private cleanOldFailures(): void {\r\n const cutoff = Date.now() - this.config.monitorWindow;\r\n this.failures = this.failures.filter(f => f.getTime() > cutoff);\r\n }\r\n\r\n private reset(): void {\r\n this.state = 'closed';\r\n this.failures = [];\r\n this.successes = 0;\r\n }\r\n\r\n /**\r\n * Get current circuit state\r\n */\r\n getState(): CircuitState {\r\n return this.state;\r\n }\r\n\r\n /**\r\n * Manually reset circuit\r\n */\r\n forceReset(): void {\r\n this.reset();\r\n }\r\n\r\n /**\r\n * Get circuit statistics\r\n */\r\n getStats(): {\r\n state: CircuitState;\r\n failures: number;\r\n successes: number;\r\n lastFailure?: Date;\r\n } {\r\n return {\r\n state: this.state,\r\n failures: this.failures.length,\r\n successes: this.successes,\r\n lastFailure: this.lastFailure,\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Error thrown when circuit is open\r\n */\r\nexport class CircuitOpenError extends Error {\r\n constructor(message: string) {\r\n super(message);\r\n this.name = 'CircuitOpenError';\r\n }\r\n}\r\n\r\n/**\r\n * Create a circuit breaker\r\n */\r\nexport function createCircuitBreaker(\r\n config?: Partial<CircuitBreakerConfig>\r\n): CircuitBreaker {\r\n return new CircuitBreaker(config);\r\n}\r\n\r\n// ============ COMBINED RETRY WITH CIRCUIT BREAKER ============\r\n\r\n/**\r\n * Execute with both retry and circuit breaker\r\n */\r\nexport async function resilientExecute<T>(\r\n operation: () => Promise<T>,\r\n options: {\r\n retry?: Partial<RetryConfig>;\r\n circuitBreaker?: CircuitBreaker;\r\n } = {}\r\n): Promise<T> {\r\n const { retry: retryConfig, circuitBreaker } = options;\r\n\r\n const wrappedOperation = async () => {\r\n if (circuitBreaker) {\r\n return circuitBreaker.execute(operation);\r\n }\r\n return operation();\r\n };\r\n\r\n if (retryConfig) {\r\n return retry(wrappedOperation, retryConfig);\r\n }\r\n\r\n return wrappedOperation();\r\n}\r\n\r\nexport default retry;\r\n\r\n","/**\r\n * Idempotency Utilities\r\n * @classytic/revenue\r\n *\r\n * Prevent duplicate operations with idempotency keys\r\n * Inspired by: Stripe, Amazon SQS deduplication\r\n */\r\n\r\nimport { nanoid } from 'nanoid';\r\nimport { Result, ok, err } from '../core/result.js';\r\n\r\n// ============ TYPES ============\r\n\r\nexport interface IdempotencyRecord<T = unknown> {\r\n /** Idempotency key */\r\n key: string;\r\n /** Operation result (if completed) */\r\n result?: T;\r\n /** Operation status */\r\n status: 'pending' | 'completed' | 'failed';\r\n /** Creation timestamp */\r\n createdAt: Date;\r\n /** Completion timestamp */\r\n completedAt?: Date;\r\n /** Request hash for validation */\r\n requestHash: string;\r\n /** TTL - when record expires */\r\n expiresAt: Date;\r\n}\r\n\r\nexport interface IdempotencyStore {\r\n /** Get record by key */\r\n get<T>(key: string): Promise<IdempotencyRecord<T> | null>;\r\n /** Set or update record */\r\n set<T>(key: string, record: IdempotencyRecord<T>): Promise<void>;\r\n /** Delete record */\r\n delete(key: string): Promise<void>;\r\n /** Check if key exists */\r\n exists(key: string): Promise<boolean>;\r\n}\r\n\r\nexport interface IdempotencyConfig {\r\n /** TTL in milliseconds (default: 24 hours) */\r\n ttl?: number;\r\n /** Custom store implementation */\r\n store?: IdempotencyStore;\r\n /** Key prefix */\r\n prefix?: string;\r\n}\r\n\r\n// ============ IN-MEMORY STORE ============\r\n\r\n/**\r\n * Simple in-memory idempotency store\r\n * Use Redis/database store in production\r\n */\r\nexport class MemoryIdempotencyStore implements IdempotencyStore {\r\n private records = new Map<string, IdempotencyRecord>();\r\n private cleanupInterval: NodeJS.Timeout | null = null;\r\n\r\n constructor(cleanupIntervalMs = 60000) {\r\n // Periodic cleanup of expired records\r\n this.cleanupInterval = setInterval(() => {\r\n this.cleanup();\r\n }, cleanupIntervalMs);\r\n }\r\n\r\n async get<T>(key: string): Promise<IdempotencyRecord<T> | null> {\r\n const record = this.records.get(key);\r\n if (!record) return null;\r\n \r\n // Check if expired\r\n if (record.expiresAt < new Date()) {\r\n this.records.delete(key);\r\n return null;\r\n }\r\n \r\n return record as IdempotencyRecord<T>;\r\n }\r\n\r\n async set<T>(key: string, record: IdempotencyRecord<T>): Promise<void> {\r\n this.records.set(key, record);\r\n }\r\n\r\n async delete(key: string): Promise<void> {\r\n this.records.delete(key);\r\n }\r\n\r\n async exists(key: string): Promise<boolean> {\r\n const record = await this.get(key);\r\n return record !== null;\r\n }\r\n\r\n private cleanup(): void {\r\n const now = new Date();\r\n for (const [key, record] of this.records) {\r\n if (record.expiresAt < now) {\r\n this.records.delete(key);\r\n }\r\n }\r\n }\r\n\r\n destroy(): void {\r\n if (this.cleanupInterval) {\r\n clearInterval(this.cleanupInterval);\r\n this.cleanupInterval = null;\r\n }\r\n this.records.clear();\r\n }\r\n}\r\n\r\n// ============ IDEMPOTENCY MANAGER ============\r\n\r\nexport class IdempotencyError extends Error {\r\n constructor(\r\n message: string,\r\n public readonly code: 'DUPLICATE_REQUEST' | 'REQUEST_IN_PROGRESS' | 'REQUEST_MISMATCH'\r\n ) {\r\n super(message);\r\n this.name = 'IdempotencyError';\r\n }\r\n}\r\n\r\n/**\r\n * Idempotency manager\r\n */\r\nexport class IdempotencyManager {\r\n private store: IdempotencyStore;\r\n private ttl: number;\r\n private prefix: string;\r\n\r\n constructor(config: IdempotencyConfig = {}) {\r\n this.store = config.store ?? new MemoryIdempotencyStore();\r\n this.ttl = config.ttl ?? 24 * 60 * 60 * 1000; // 24 hours\r\n this.prefix = config.prefix ?? 'idem:';\r\n }\r\n\r\n /**\r\n * Generate a unique idempotency key\r\n */\r\n generateKey(): string {\r\n return `${this.prefix}${nanoid(21)}`;\r\n }\r\n\r\n /**\r\n * Hash request parameters for validation\r\n */\r\n private hashRequest(params: unknown): string {\r\n // Simple JSON hash - in production, use a proper hash function\r\n const json = JSON.stringify(params, Object.keys(params as object).sort());\r\n let hash = 0;\r\n for (let i = 0; i < json.length; i++) {\r\n const char = json.charCodeAt(i);\r\n hash = ((hash << 5) - hash) + char;\r\n hash = hash & hash;\r\n }\r\n return hash.toString(36);\r\n }\r\n\r\n /**\r\n * Execute operation with idempotency protection\r\n */\r\n async execute<T>(\r\n key: string,\r\n params: unknown,\r\n operation: () => Promise<T>\r\n ): Promise<Result<T, IdempotencyError>> {\r\n const fullKey = key.startsWith(this.prefix) ? key : `${this.prefix}${key}`;\r\n const requestHash = this.hashRequest(params);\r\n\r\n // Check for existing record\r\n const existing = await this.store.get<T>(fullKey);\r\n\r\n if (existing) {\r\n // Validate request hash matches\r\n if (existing.requestHash !== requestHash) {\r\n return err(new IdempotencyError(\r\n 'Idempotency key used with different request parameters',\r\n 'REQUEST_MISMATCH'\r\n ));\r\n }\r\n\r\n // If already completed, return cached result\r\n if (existing.status === 'completed' && existing.result !== undefined) {\r\n return ok(existing.result);\r\n }\r\n\r\n // If in progress, reject\r\n if (existing.status === 'pending') {\r\n return err(new IdempotencyError(\r\n 'Request with this idempotency key is already in progress',\r\n 'REQUEST_IN_PROGRESS'\r\n ));\r\n }\r\n\r\n // If failed, allow retry\r\n if (existing.status === 'failed') {\r\n await this.store.delete(fullKey);\r\n }\r\n }\r\n\r\n // Create pending record\r\n const record: IdempotencyRecord<T> = {\r\n key: fullKey,\r\n status: 'pending',\r\n createdAt: new Date(),\r\n requestHash,\r\n expiresAt: new Date(Date.now() + this.ttl),\r\n };\r\n\r\n await this.store.set(fullKey, record);\r\n\r\n try {\r\n // Execute operation\r\n const result = await operation();\r\n\r\n // Update record with result\r\n record.status = 'completed';\r\n record.result = result;\r\n record.completedAt = new Date();\r\n await this.store.set(fullKey, record);\r\n\r\n return ok(result);\r\n } catch (error) {\r\n // Mark as failed\r\n record.status = 'failed';\r\n await this.store.set(fullKey, record);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Check if operation with key was already completed\r\n */\r\n async wasCompleted(key: string): Promise<boolean> {\r\n const fullKey = key.startsWith(this.prefix) ? key : `${this.prefix}${key}`;\r\n const record = await this.store.get(fullKey);\r\n return record?.status === 'completed';\r\n }\r\n\r\n /**\r\n * Get cached result for key\r\n */\r\n async getCached<T>(key: string): Promise<T | null> {\r\n const fullKey = key.startsWith(this.prefix) ? key : `${this.prefix}${key}`;\r\n const record = await this.store.get<T>(fullKey);\r\n return record?.status === 'completed' ? (record.result ?? null) : null;\r\n }\r\n\r\n /**\r\n * Invalidate a key (force re-execution on next call)\r\n */\r\n async invalidate(key: string): Promise<void> {\r\n const fullKey = key.startsWith(this.prefix) ? key : `${this.prefix}${key}`;\r\n await this.store.delete(fullKey);\r\n }\r\n}\r\n\r\n/**\r\n * Create idempotency manager\r\n */\r\nexport function createIdempotencyManager(\r\n config?: IdempotencyConfig\r\n): IdempotencyManager {\r\n return new IdempotencyManager(config);\r\n}\r\n\r\n/**\r\n * Decorator for idempotent operations\r\n * @example\r\n * class PaymentService {\r\n * @withIdempotency(manager, (p) => p.idempotencyKey)\r\n * async createPayment(params) { ... }\r\n * }\r\n */\r\nexport function withIdempotency(\r\n manager: IdempotencyManager,\r\n getKey: (params: unknown) => string | undefined\r\n) {\r\n return function(\r\n _target: unknown,\r\n _propertyKey: string,\r\n descriptor: PropertyDescriptor\r\n ) {\r\n const original = descriptor.value;\r\n\r\n descriptor.value = async function(this: unknown, params: unknown) {\r\n const key = getKey(params);\r\n \r\n if (!key) {\r\n // No idempotency key provided, execute normally\r\n return original.call(this, params);\r\n }\r\n\r\n const result = await manager.execute(key, params, () => \r\n original.call(this, params)\r\n );\r\n\r\n if (result.ok) {\r\n return result.value;\r\n }\r\n\r\n throw result.error;\r\n };\r\n\r\n return descriptor;\r\n };\r\n}\r\n\r\nexport default IdempotencyManager;\r\n\r\n","/**\r\n * Transaction Type Detection & Classification\r\n *\r\n * Distinguishes between:\r\n * - Monetization-managed transactions (library-controlled, strict rules)\r\n * - Manual admin transactions (flexible, admin-controlled)\r\n *\r\n * @module @classytic/revenue/utils/transaction-type\r\n */\r\n\r\nimport type {\r\n TransactionDocument,\r\n TransactionTypeOptions,\r\n FieldUpdateValidationResult,\r\n} from '../types/index.js';\r\n\r\n/**\r\n * Transaction types with different protection rules\r\n */\r\nexport const TRANSACTION_MANAGEMENT_TYPE = {\r\n MONETIZATION: 'monetization', // Library-managed (subscriptions, purchases)\r\n MANUAL: 'manual', // Admin-managed (expenses, income, adjustments)\r\n} as const;\r\n\r\nexport type TransactionManagementType = typeof TRANSACTION_MANAGEMENT_TYPE[keyof typeof TRANSACTION_MANAGEMENT_TYPE];\r\n\r\n/**\r\n * Default monetization categories\r\n * Users can extend this via config.categoryMappings\r\n */\r\nconst DEFAULT_MONETIZATION_CATEGORIES = [\r\n 'subscription',\r\n 'purchase',\r\n];\r\n\r\n/**\r\n * Check if category is monetization-related\r\n * @param category - Transaction category\r\n * @param additionalCategories - Additional categories from user config\r\n */\r\nfunction isMonetizationCategory(\r\n category: string,\r\n additionalCategories: string[] = []\r\n): boolean {\r\n const allCategories = [...DEFAULT_MONETIZATION_CATEGORIES, ...additionalCategories];\r\n return allCategories.includes(category);\r\n}\r\n\r\n/**\r\n * Check if transaction is monetization-managed\r\n *\r\n * Monetization-managed means:\r\n * - Created through subscription/purchase flows via the library\r\n * - Status controlled by payment webhooks/verification\r\n * - Amount/commission calculated by library\r\n * - Protected fields: status, amount, commission, gateway, verifiedAt, verifiedBy\r\n *\r\n * @param transaction - Transaction document or data\r\n * @param options - Options\r\n */\r\nexport function isMonetizationTransaction(\r\n transaction: Partial<TransactionDocument>,\r\n options: TransactionTypeOptions = {}\r\n): boolean {\r\n const {\r\n targetModels = ['Subscription', 'Membership'],\r\n additionalCategories = [],\r\n } = options;\r\n\r\n // Check 1: Has referenceModel from registered models\r\n if (transaction.referenceModel && targetModels.includes(transaction.referenceModel)) {\r\n return true;\r\n }\r\n\r\n // Check 2: Category is monetization-related\r\n if (transaction.category) {\r\n return isMonetizationCategory(transaction.category, additionalCategories);\r\n }\r\n\r\n return false;\r\n}\r\n\r\n/**\r\n * Check if transaction is manual admin transaction\r\n *\r\n * Manual transactions:\r\n * - Created directly by admins for operational expenses/income\r\n * - Can be self-verified by admins\r\n * - More flexible updates allowed\r\n * - No commission/gateway complexity\r\n *\r\n * @param transaction - Transaction document or data\r\n * @param options - Options (same as isMonetizationTransaction)\r\n */\r\nexport function isManualTransaction(\r\n transaction: Partial<TransactionDocument>,\r\n options: TransactionTypeOptions = {}\r\n): boolean {\r\n return !isMonetizationTransaction(transaction, options);\r\n}\r\n\r\n/**\r\n * Get transaction type\r\n *\r\n * @param transaction - Transaction document or data\r\n * @param options - Options (same as isMonetizationTransaction)\r\n */\r\nexport function getTransactionType(\r\n transaction: Partial<TransactionDocument>,\r\n options: TransactionTypeOptions = {}\r\n): TransactionManagementType {\r\n return isMonetizationTransaction(transaction, options)\r\n ? TRANSACTION_MANAGEMENT_TYPE.MONETIZATION\r\n : TRANSACTION_MANAGEMENT_TYPE.MANUAL;\r\n}\r\n\r\n/**\r\n * Protected fields for monetization transactions\r\n * These fields cannot be updated directly by admins\r\n */\r\nexport const PROTECTED_MONETIZATION_FIELDS = [\r\n 'status',\r\n 'amount',\r\n 'platformCommission',\r\n 'netAmount',\r\n 'verifiedAt',\r\n 'verifiedBy',\r\n 'gateway',\r\n 'webhook',\r\n 'metadata.commission',\r\n 'metadata.gateway',\r\n 'type',\r\n 'category',\r\n 'referenceModel',\r\n 'referenceId',\r\n] as const;\r\n\r\n/**\r\n * Editable fields for monetization transactions (before verification)\r\n * These fields can be updated by frontend/customer before payment is verified\r\n */\r\nexport const EDITABLE_MONETIZATION_FIELDS_PRE_VERIFICATION = [\r\n 'reference',\r\n 'paymentDetails',\r\n 'notes',\r\n] as const;\r\n\r\n/**\r\n * Allowed fields for manual transaction creation\r\n */\r\nexport const MANUAL_TRANSACTION_CREATE_FIELDS = [\r\n 'organizationId',\r\n 'type',\r\n 'category',\r\n 'amount',\r\n 'method',\r\n 'reference',\r\n 'paymentDetails',\r\n 'notes',\r\n 'date', // Transaction date (can be backdated)\r\n 'description',\r\n] as const;\r\n\r\n/**\r\n * Allowed fields for manual transaction updates\r\n */\r\nexport const MANUAL_TRANSACTION_UPDATE_FIELDS = [\r\n 'amount',\r\n 'method',\r\n 'reference',\r\n 'paymentDetails',\r\n 'notes',\r\n 'date',\r\n 'description',\r\n] as const;\r\n\r\n/**\r\n * Get allowed update fields based on transaction type and status\r\n *\r\n * @param transaction - Transaction document\r\n * @param options - Options for transaction type detection\r\n */\r\nexport function getAllowedUpdateFields(\r\n transaction: Partial<TransactionDocument>,\r\n options: TransactionTypeOptions = {}\r\n): readonly string[] {\r\n const type = getTransactionType(transaction, options);\r\n\r\n if (type === TRANSACTION_MANAGEMENT_TYPE.MONETIZATION) {\r\n // Monetization transactions: only allow pre-verification edits\r\n if (transaction.status === 'pending') {\r\n return EDITABLE_MONETIZATION_FIELDS_PRE_VERIFICATION;\r\n }\r\n // After verification, no direct updates allowed\r\n return [];\r\n }\r\n\r\n // Manual transactions: more flexible\r\n if (transaction.status === 'verified' || transaction.status === 'completed') {\r\n // Once verified/completed, only notes can be updated\r\n return ['notes'];\r\n }\r\n\r\n // Pending manual transactions can be fully edited\r\n return MANUAL_TRANSACTION_UPDATE_FIELDS;\r\n}\r\n\r\n/**\r\n * Validate if field update is allowed\r\n *\r\n * @param transaction - Transaction document\r\n * @param fieldName - Field being updated\r\n * @param options - Options for transaction type detection\r\n */\r\nexport function validateFieldUpdate(\r\n transaction: Partial<TransactionDocument>,\r\n fieldName: string,\r\n options: TransactionTypeOptions = {}\r\n): FieldUpdateValidationResult {\r\n const allowedFields = getAllowedUpdateFields(transaction, options);\r\n\r\n if (allowedFields.includes(fieldName)) {\r\n return { allowed: true };\r\n }\r\n\r\n const type = getTransactionType(transaction, options);\r\n\r\n if (type === TRANSACTION_MANAGEMENT_TYPE.MONETIZATION) {\r\n if ((PROTECTED_MONETIZATION_FIELDS as readonly string[]).includes(fieldName)) {\r\n return {\r\n allowed: false,\r\n reason: `Field \"${fieldName}\" is protected for monetization transactions. Updates must go through payment flow.`,\r\n };\r\n }\r\n }\r\n\r\n return {\r\n allowed: false,\r\n reason: `Field \"${fieldName}\" cannot be updated for ${transaction.status} transactions.`,\r\n };\r\n}\r\n\r\n/**\r\n * Check if transaction can be self-verified by admin\r\n *\r\n * @param transaction - Transaction document\r\n * @param options - Options for transaction type detection\r\n */\r\nexport function canSelfVerify(\r\n transaction: Partial<TransactionDocument>,\r\n options: TransactionTypeOptions = {}\r\n): boolean {\r\n const type = getTransactionType(transaction, options);\r\n\r\n // Only manual transactions can be self-verified\r\n if (type === TRANSACTION_MANAGEMENT_TYPE.MANUAL) {\r\n return transaction.status === 'pending';\r\n }\r\n\r\n return false;\r\n}\r\n\r\nexport default {\r\n TRANSACTION_MANAGEMENT_TYPE,\r\n isMonetizationTransaction,\r\n isManualTransaction,\r\n getTransactionType,\r\n PROTECTED_MONETIZATION_FIELDS,\r\n EDITABLE_MONETIZATION_FIELDS_PRE_VERIFICATION,\r\n MANUAL_TRANSACTION_CREATE_FIELDS,\r\n MANUAL_TRANSACTION_UPDATE_FIELDS,\r\n getAllowedUpdateFields,\r\n validateFieldUpdate,\r\n canSelfVerify,\r\n};\r\n\r\n","/**\r\n * Logger Abstraction for Monetization Library\r\n *\r\n * Defaults to console for standalone usage\r\n * Can be overridden with custom logger (pino, winston, etc)\r\n *\r\n * Usage:\r\n * ```typescript\r\n * import { setLogger } from '@classytic/revenue';\r\n *\r\n * // Optional: Use your own logger\r\n * setLogger(myPinoLogger);\r\n * ```\r\n */\r\n\r\nimport type { Logger } from '../types/index.js';\r\n\r\nlet _logger: Logger = console;\r\n\r\n/**\r\n * Set custom logger implementation\r\n * @param customLogger - Logger instance with info, warn, error, debug methods\r\n */\r\nexport function setLogger(customLogger: Logger): void {\r\n _logger = customLogger;\r\n}\r\n\r\n/**\r\n * Logger proxy - delegates to current logger implementation\r\n */\r\nexport const logger: Logger = {\r\n info: (...args: unknown[]): void => {\r\n (_logger.info ?? _logger.log)?.call(_logger, ...args);\r\n },\r\n warn: (...args: unknown[]): void => {\r\n (_logger.warn ?? _logger.log)?.call(_logger, 'WARN:', ...args);\r\n },\r\n error: (...args: unknown[]): void => {\r\n (_logger.error ?? _logger.log)?.call(_logger, 'ERROR:', ...args);\r\n },\r\n debug: (...args: unknown[]): void => {\r\n (_logger.debug ?? _logger.log)?.call(_logger, 'DEBUG:', ...args);\r\n },\r\n};\r\n\r\nexport default logger;\r\n\r\n","/**\r\n * Hook Utilities\r\n * @classytic/revenue\r\n *\r\n * Fire-and-forget hook execution - never blocks main flow\r\n */\r\n\r\nimport type { Logger, HooksRegistry } from '../types/index.js';\r\n\r\n/**\r\n * Trigger hooks asynchronously without waiting\r\n * Errors are logged but never thrown\r\n *\r\n * @param hooks - Hooks object\r\n * @param event - Event name\r\n * @param data - Event data\r\n * @param logger - Logger instance\r\n */\r\nexport function triggerHook(\r\n hooks: HooksRegistry,\r\n event: string,\r\n data: unknown,\r\n logger: Logger\r\n): void {\r\n const handlers = hooks[event] ?? [];\r\n\r\n if (handlers.length === 0) {\r\n return; // No handlers, return immediately\r\n }\r\n\r\n // Fire-and-forget: Don't await, don't block\r\n Promise.all(\r\n handlers.map((handler) =>\r\n Promise.resolve(handler(data)).catch((error: Error) => {\r\n logger.error(`Hook \"${event}\" failed:`, {\r\n error: error.message,\r\n stack: error.stack,\r\n event,\r\n // Don't log full data (could be huge)\r\n dataKeys: Object.keys(data as object),\r\n });\r\n })\r\n )\r\n ).catch(() => {\r\n // Swallow any Promise.all errors (already logged individually)\r\n });\r\n\r\n // Return immediately - hooks run in background\r\n}\r\n\r\nexport default triggerHook;\r\n\r\n","/**\r\n * Commission Calculation Utility\r\n * @classytic/revenue\r\n *\r\n * Handles platform commission calculation with gateway fee deduction\r\n */\r\n\r\nimport type { CommissionInfo } from '../types/index.js';\r\n\r\n/**\r\n * Build commission object for transaction\r\n *\r\n * @param amount - Transaction amount\r\n * @param commissionRate - Commission rate (0 to 1, e.g., 0.10 for 10%)\r\n * @param gatewayFeeRate - Gateway fee rate (0 to 1, e.g., 0.018 for 1.8%)\r\n * @returns Commission object or null\r\n */\r\nexport function calculateCommission(\r\n amount: number,\r\n commissionRate: number,\r\n gatewayFeeRate: number = 0\r\n): CommissionInfo | null {\r\n // No commission if rate is 0 or negative\r\n if (!commissionRate || commissionRate <= 0) {\r\n return null;\r\n }\r\n\r\n // Validate inputs\r\n if (amount < 0) {\r\n throw new Error('Transaction amount cannot be negative');\r\n }\r\n\r\n if (commissionRate < 0 || commissionRate > 1) {\r\n throw new Error('Commission rate must be between 0 and 1');\r\n }\r\n\r\n if (gatewayFeeRate < 0 || gatewayFeeRate > 1) {\r\n throw new Error('Gateway fee rate must be between 0 and 1');\r\n }\r\n\r\n // Calculate commission\r\n const grossAmount = Math.round(amount * commissionRate * 100) / 100; // Round to 2 decimals\r\n const gatewayFeeAmount = Math.round(amount * gatewayFeeRate * 100) / 100;\r\n const netAmount = Math.max(0, Math.round((grossAmount - gatewayFeeAmount) * 100) / 100);\r\n\r\n return {\r\n rate: commissionRate,\r\n grossAmount,\r\n gatewayFeeRate,\r\n gatewayFeeAmount,\r\n netAmount,\r\n status: 'pending',\r\n };\r\n}\r\n\r\n/**\r\n * Reverse commission on refund (proportional)\r\n *\r\n * @param originalCommission - Original commission object\r\n * @param originalAmount - Original transaction amount\r\n * @param refundAmount - Amount being refunded\r\n * @returns Reversed commission or null\r\n */\r\nexport function reverseCommission(\r\n originalCommission: CommissionInfo | null | undefined,\r\n originalAmount: number,\r\n refundAmount: number\r\n): CommissionInfo | null {\r\n if (!originalCommission?.netAmount) {\r\n return null;\r\n }\r\n\r\n // Calculate proportional refund\r\n const refundRatio = refundAmount / originalAmount;\r\n const reversedNetAmount = Math.round(originalCommission.netAmount * refundRatio * 100) / 100;\r\n const reversedGrossAmount = Math.round(originalCommission.grossAmount * refundRatio * 100) / 100;\r\n const reversedGatewayFee = Math.round(originalCommission.gatewayFeeAmount * refundRatio * 100) / 100;\r\n\r\n return {\r\n rate: originalCommission.rate,\r\n grossAmount: reversedGrossAmount,\r\n gatewayFeeRate: originalCommission.gatewayFeeRate,\r\n gatewayFeeAmount: reversedGatewayFee,\r\n netAmount: reversedNetAmount,\r\n status: 'waived', // Commission waived due to refund\r\n };\r\n}\r\n\r\nexport default {\r\n calculateCommission,\r\n reverseCommission,\r\n};\r\n\r\n","/**\r\n * Split Payment Enums\r\n * @classytic/revenue\r\n *\r\n * Enums for multi-party commission splits\r\n */\r\n\r\nexport const SPLIT_TYPE = {\r\n PLATFORM_COMMISSION: 'platform_commission',\r\n AFFILIATE_COMMISSION: 'affiliate_commission',\r\n REFERRAL_COMMISSION: 'referral_commission',\r\n PARTNER_COMMISSION: 'partner_commission',\r\n CUSTOM: 'custom',\r\n} as const;\r\n\r\nexport type SplitType = typeof SPLIT_TYPE;\r\nexport type SplitTypeValue = SplitType[keyof SplitType];\r\nexport const SPLIT_TYPE_VALUES = Object.values(SPLIT_TYPE);\r\n\r\nexport const SPLIT_STATUS = {\r\n PENDING: 'pending',\r\n DUE: 'due',\r\n PAID: 'paid',\r\n WAIVED: 'waived',\r\n CANCELLED: 'cancelled',\r\n} as const;\r\n\r\nexport type SplitStatus = typeof SPLIT_STATUS;\r\nexport type SplitStatusValue = SplitStatus[keyof SplitStatus];\r\nexport const SPLIT_STATUS_VALUES = Object.values(SPLIT_STATUS);\r\n\r\nexport const PAYOUT_METHOD = {\r\n BANK_TRANSFER: 'bank_transfer',\r\n MOBILE_WALLET: 'mobile_wallet',\r\n PLATFORM_BALANCE: 'platform_balance',\r\n CRYPTO: 'crypto',\r\n CHECK: 'check',\r\n MANUAL: 'manual',\r\n} as const;\r\n\r\nexport type PayoutMethod = typeof PAYOUT_METHOD;\r\nexport type PayoutMethodValue = PayoutMethod[keyof PayoutMethod];\r\nexport const PAYOUT_METHOD_VALUES = Object.values(PAYOUT_METHOD);\r\n\r\n","/**\r\n * Commission Split Utilities\r\n * @classytic/revenue\r\n *\r\n * Multi-party commission split calculation for affiliate/referral systems\r\n */\r\n\r\nimport { SPLIT_TYPE, SPLIT_STATUS } from '../enums/split.enums.js';\r\nimport type {\r\n SplitRule,\r\n SplitInfo,\r\n CommissionInfo,\r\n CommissionWithSplitsOptions,\r\n} from '../types/index.js';\r\n\r\n/**\r\n * Calculate multi-party commission splits\r\n *\r\n * @param amount - Transaction amount\r\n * @param splitRules - Split configuration\r\n * @param gatewayFeeRate - Gateway fee rate (optional)\r\n * @returns Split objects\r\n *\r\n * @example\r\n * calculateSplits(1000, [\r\n * { type: 'platform_commission', recipientId: 'platform', recipientType: 'platform', rate: 0.10 },\r\n * { type: 'affiliate_commission', recipientId: 'affiliate-123', recipientType: 'user', rate: 0.02 },\r\n * ], 0.018);\r\n *\r\n * Returns:\r\n * [\r\n * { type: 'platform_commission', recipientId: 'platform', grossAmount: 100, gatewayFeeAmount: 18, netAmount: 82, ... },\r\n * { type: 'affiliate_commission', recipientId: 'affiliate-123', grossAmount: 20, gatewayFeeAmount: 0, netAmount: 20, ... },\r\n * ]\r\n */\r\nexport function calculateSplits(\r\n amount: number,\r\n splitRules: SplitRule[] = [],\r\n gatewayFeeRate: number = 0\r\n): SplitInfo[] {\r\n if (!splitRules || splitRules.length === 0) {\r\n return [];\r\n }\r\n\r\n if (amount < 0) {\r\n throw new Error('Transaction amount cannot be negative');\r\n }\r\n\r\n if (gatewayFeeRate < 0 || gatewayFeeRate > 1) {\r\n throw new Error('Gateway fee rate must be between 0 and 1');\r\n }\r\n\r\n const totalRate = splitRules.reduce((sum, rule) => sum + rule.rate, 0);\r\n if (totalRate > 1) {\r\n throw new Error(`Total split rate (${totalRate}) cannot exceed 1.0`);\r\n }\r\n\r\n return splitRules.map((rule, index) => {\r\n if (rule.rate < 0 || rule.rate > 1) {\r\n throw new Error(`Split rate must be between 0 and 1 for split ${index}`);\r\n }\r\n\r\n const grossAmount = Math.round(amount * rule.rate * 100) / 100;\r\n\r\n const gatewayFeeAmount = index === 0 && gatewayFeeRate > 0\r\n ? Math.round(amount * gatewayFeeRate * 100) / 100\r\n : 0;\r\n\r\n const netAmount = Math.max(0, Math.round((grossAmount - gatewayFeeAmount) * 100) / 100);\r\n\r\n return {\r\n type: rule.type ?? SPLIT_TYPE.CUSTOM,\r\n recipientId: rule.recipientId,\r\n recipientType: rule.recipientType,\r\n rate: rule.rate,\r\n grossAmount,\r\n gatewayFeeRate: gatewayFeeAmount > 0 ? gatewayFeeRate : 0,\r\n gatewayFeeAmount,\r\n netAmount,\r\n status: SPLIT_STATUS.PENDING,\r\n dueDate: rule.dueDate ?? null,\r\n metadata: rule.metadata ?? {},\r\n };\r\n });\r\n}\r\n\r\n/**\r\n * Calculate organization payout after splits\r\n *\r\n * @param amount - Total transaction amount\r\n * @param splits - Calculated splits\r\n * @returns Amount organization receives\r\n */\r\nexport function calculateOrganizationPayout(\r\n amount: number,\r\n splits: SplitInfo[] = []\r\n): number {\r\n const totalSplitAmount = splits.reduce((sum, split) => sum + split.grossAmount, 0);\r\n return Math.max(0, Math.round((amount - totalSplitAmount) * 100) / 100);\r\n}\r\n\r\n/**\r\n * Reverse splits proportionally on refund\r\n *\r\n * @param originalSplits - Original split objects\r\n * @param originalAmount - Original transaction amount\r\n * @param refundAmount - Amount being refunded\r\n * @returns Reversed splits\r\n */\r\nexport function reverseSplits(\r\n originalSplits: SplitInfo[] | undefined | null,\r\n originalAmount: number,\r\n refundAmount: number\r\n): SplitInfo[] {\r\n if (!originalSplits || originalSplits.length === 0) {\r\n return [];\r\n }\r\n\r\n const refundRatio = refundAmount / originalAmount;\r\n\r\n return originalSplits.map((split) => ({\r\n ...split,\r\n grossAmount: Math.round(split.grossAmount * refundRatio * 100) / 100,\r\n gatewayFeeAmount: Math.round(split.gatewayFeeAmount * refundRatio * 100) / 100,\r\n netAmount: Math.round(split.netAmount * refundRatio * 100) / 100,\r\n status: SPLIT_STATUS.WAIVED,\r\n }));\r\n}\r\n\r\n/**\r\n * Build commission object with splits support\r\n * Backward compatible with existing calculateCommission\r\n *\r\n * @param amount - Transaction amount\r\n * @param commissionRate - Platform commission rate\r\n * @param gatewayFeeRate - Gateway fee rate\r\n * @param options - Additional options\r\n * @returns Commission with optional splits\r\n */\r\nexport function calculateCommissionWithSplits(\r\n amount: number,\r\n commissionRate: number,\r\n gatewayFeeRate: number = 0,\r\n options: CommissionWithSplitsOptions = {}\r\n): CommissionInfo | null {\r\n const { affiliateRate = 0, affiliateId = null, affiliateType = 'user' } = options;\r\n\r\n if (commissionRate <= 0 && affiliateRate <= 0) {\r\n return null;\r\n }\r\n\r\n const splitRules: SplitRule[] = [];\r\n\r\n if (commissionRate > 0) {\r\n splitRules.push({\r\n type: SPLIT_TYPE.PLATFORM_COMMISSION,\r\n recipientId: 'platform',\r\n recipientType: 'platform',\r\n rate: commissionRate,\r\n });\r\n }\r\n\r\n if (affiliateRate > 0 && affiliateId) {\r\n splitRules.push({\r\n type: SPLIT_TYPE.AFFILIATE_COMMISSION,\r\n recipientId: affiliateId,\r\n recipientType: affiliateType,\r\n rate: affiliateRate,\r\n });\r\n }\r\n\r\n const splits = calculateSplits(amount, splitRules, gatewayFeeRate);\r\n\r\n const platformSplit = splits.find((s) => s.type === SPLIT_TYPE.PLATFORM_COMMISSION);\r\n const affiliateSplit = splits.find((s) => s.type === SPLIT_TYPE.AFFILIATE_COMMISSION);\r\n\r\n return {\r\n rate: commissionRate,\r\n grossAmount: platformSplit?.grossAmount ?? 0,\r\n gatewayFeeRate: platformSplit?.gatewayFeeRate ?? 0,\r\n gatewayFeeAmount: platformSplit?.gatewayFeeAmount ?? 0,\r\n netAmount: platformSplit?.netAmount ?? 0,\r\n status: 'pending',\r\n ...(splits.length > 0 && { splits }),\r\n ...(affiliateSplit && {\r\n affiliate: {\r\n recipientId: affiliateSplit.recipientId,\r\n recipientType: affiliateSplit.recipientType,\r\n rate: affiliateSplit.rate,\r\n grossAmount: affiliateSplit.grossAmount,\r\n netAmount: affiliateSplit.netAmount,\r\n },\r\n }),\r\n };\r\n}\r\n\r\nexport default {\r\n calculateSplits,\r\n calculateOrganizationPayout,\r\n reverseSplits,\r\n calculateCommissionWithSplits,\r\n};\r\n\r\n","/**\r\n * Transaction Enums\r\n * @classytic/revenue\r\n *\r\n * Library-managed transaction enums only.\r\n * Users should define their own categories and merge with these.\r\n */\r\n\r\n// ============ TRANSACTION TYPE ============\r\n/**\r\n * Transaction Type - Income vs Expense\r\n *\r\n * INCOME: Money coming in (payments, subscriptions, purchases)\r\n * EXPENSE: Money going out (refunds, payouts)\r\n *\r\n * Users can map these in their config via transactionTypeMapping\r\n */\r\nexport const TRANSACTION_TYPE = {\r\n INCOME: 'income',\r\n EXPENSE: 'expense',\r\n} as const;\r\n\r\nexport type TransactionType = typeof TRANSACTION_TYPE;\r\nexport type TransactionTypeValue = TransactionType[keyof TransactionType];\r\nexport const TRANSACTION_TYPE_VALUES = Object.values(TRANSACTION_TYPE);\r\n\r\n// ============ TRANSACTION STATUS ============\r\n/**\r\n * Transaction Status - Library-managed states\r\n */\r\nexport const TRANSACTION_STATUS = {\r\n PENDING: 'pending',\r\n PAYMENT_INITIATED: 'payment_initiated',\r\n PROCESSING: 'processing',\r\n REQUIRES_ACTION: 'requires_action',\r\n VERIFIED: 'verified',\r\n COMPLETED: 'completed',\r\n FAILED: 'failed',\r\n CANCELLED: 'cancelled',\r\n EXPIRED: 'expired',\r\n REFUNDED: 'refunded',\r\n PARTIALLY_REFUNDED: 'partially_refunded',\r\n} as const;\r\n\r\nexport type TransactionStatus = typeof TRANSACTION_STATUS;\r\nexport type TransactionStatusValue = TransactionStatus[keyof TransactionStatus];\r\nexport const TRANSACTION_STATUS_VALUES = Object.values(TRANSACTION_STATUS);\r\n\r\n// ============ LIBRARY CATEGORIES ============\r\n/**\r\n * Categories managed by this library\r\n *\r\n * SUBSCRIPTION: Recurring subscription payments\r\n * PURCHASE: One-time purchases\r\n *\r\n * Users should spread these into their own category enums:\r\n *\r\n * @example\r\n * import { LIBRARY_CATEGORIES } from '@classytic/revenue';\r\n *\r\n * export const MY_CATEGORIES = {\r\n * ...LIBRARY_CATEGORIES,\r\n * SALARY: 'salary',\r\n * RENT: 'rent',\r\n * EQUIPMENT: 'equipment',\r\n * } as const;\r\n */\r\nexport const LIBRARY_CATEGORIES = {\r\n SUBSCRIPTION: 'subscription',\r\n PURCHASE: 'purchase',\r\n} as const;\r\n\r\nexport type LibraryCategories = typeof LIBRARY_CATEGORIES;\r\nexport type LibraryCategoryValue = LibraryCategories[keyof LibraryCategories];\r\nexport const LIBRARY_CATEGORY_VALUES = Object.values(LIBRARY_CATEGORIES);\r\n\r\n","/**\r\n * Category Resolver Utility\r\n * @classytic/revenue\r\n *\r\n * Resolves transaction category based on referenceModel and categoryMappings\r\n */\r\n\r\nimport { LIBRARY_CATEGORIES } from '../enums/transaction.enums.js';\r\nimport type { MonetizationTypeValue } from '../types/index.js';\r\n\r\n/**\r\n * Resolve category for a transaction based on entity and monetizationType\r\n *\r\n * Resolution Logic:\r\n * 1. If categoryMappings[entity] exists → use it\r\n * 2. Otherwise → fall back to default library category\r\n *\r\n * @param entity - The logical entity/identifier (e.g., 'Order', 'PlatformSubscription', 'Membership')\r\n * NOTE: This is NOT a database model name - it's just a logical identifier\r\n * @param monetizationType - The monetization type ('subscription', 'purchase', 'free')\r\n * @param categoryMappings - User-defined category mappings from config\r\n * @returns Category name for the transaction\r\n *\r\n * @example\r\n * // With mapping defined\r\n * resolveCategory('Order', 'subscription', { Order: 'order_subscription' })\r\n * // Returns: 'order_subscription'\r\n *\r\n * @example\r\n * // Without mapping, falls back to library default\r\n * resolveCategory('Order', 'subscription', {})\r\n * // Returns: 'subscription'\r\n *\r\n * @example\r\n * // Different entities with different mappings\r\n * const mappings = {\r\n * Order: 'order_subscription',\r\n * PlatformSubscription: 'platform_subscription',\r\n * TenantUpgrade: 'tenant_upgrade',\r\n * Membership: 'gym_membership',\r\n * Enrollment: 'course_enrollment',\r\n * };\r\n * resolveCategory('PlatformSubscription', 'subscription', mappings)\r\n * // Returns: 'platform_subscription'\r\n */\r\nexport function resolveCategory(\r\n entity: string | null | undefined,\r\n monetizationType: MonetizationTypeValue,\r\n categoryMappings: Record<string, string> = {}\r\n): string {\r\n // If user has defined a custom mapping for this entity, use it\r\n if (entity && categoryMappings[entity]) {\r\n return categoryMappings[entity];\r\n }\r\n\r\n // Otherwise, fall back to library default based on monetization type\r\n switch (monetizationType) {\r\n case 'subscription':\r\n return LIBRARY_CATEGORIES.SUBSCRIPTION; // 'subscription'\r\n case 'purchase':\r\n return LIBRARY_CATEGORIES.PURCHASE; // 'purchase'\r\n default:\r\n return LIBRARY_CATEGORIES.SUBSCRIPTION; // Default to subscription\r\n }\r\n}\r\n\r\n/**\r\n * Validate that a category is defined in user's Transaction model enum\r\n * This is informational - actual validation happens at Mongoose schema level\r\n *\r\n * @param category - Category to validate\r\n * @param allowedCategories - List of allowed categories\r\n * @returns Whether category is valid\r\n */\r\nexport function isCategoryValid(\r\n category: string,\r\n allowedCategories: string[] = []\r\n): boolean {\r\n return allowedCategories.includes(category);\r\n}\r\n\r\nexport default resolveCategory;\r\n\r\n","/**\r\n * Subscription Period Utilities\r\n * @classytic/revenue/utils/subscription\r\n *\r\n * Universal period calculation, proration, and date utilities\r\n */\r\n\r\nimport type {\r\n PeriodRangeParams,\r\n PeriodRangeResult,\r\n ProratedAmountParams,\r\n DurationResult,\r\n} from '../../types/index.js';\r\n\r\nexport type DurationUnit = 'days' | 'day' | 'weeks' | 'week' | 'months' | 'month' | 'years' | 'year';\r\n\r\n/**\r\n * Add duration to date\r\n */\r\nexport function addDuration(\r\n startDate: Date,\r\n duration: number,\r\n unit: DurationUnit = 'days'\r\n): Date {\r\n const date = new Date(startDate);\r\n\r\n switch (unit) {\r\n case 'months':\r\n case 'month':\r\n date.setMonth(date.getMonth() + duration);\r\n return date;\r\n case 'years':\r\n case 'year':\r\n date.setFullYear(date.getFullYear() + duration);\r\n return date;\r\n case 'weeks':\r\n case 'week':\r\n date.setDate(date.getDate() + (duration * 7));\r\n return date;\r\n case 'days':\r\n case 'day':\r\n default:\r\n date.setDate(date.getDate() + duration);\r\n return date;\r\n }\r\n}\r\n\r\n/**\r\n * Calculate subscription period start/end dates\r\n */\r\nexport function calculatePeriodRange(params: PeriodRangeParams): PeriodRangeResult {\r\n const {\r\n currentEndDate = null,\r\n startDate = null,\r\n duration,\r\n unit = 'days',\r\n now = new Date(),\r\n } = params;\r\n\r\n let periodStart: Date;\r\n\r\n if (startDate) {\r\n periodStart = new Date(startDate);\r\n } else if (currentEndDate) {\r\n const end = new Date(currentEndDate);\r\n periodStart = end > now ? end : now;\r\n } else {\r\n periodStart = now;\r\n }\r\n\r\n const periodEnd = addDuration(periodStart, duration, unit as DurationUnit);\r\n\r\n return { startDate: periodStart, endDate: periodEnd };\r\n}\r\n\r\n/**\r\n * Calculate prorated refund amount for unused period\r\n */\r\nexport function calculateProratedAmount(params: ProratedAmountParams): number {\r\n const {\r\n amountPaid,\r\n startDate,\r\n endDate,\r\n asOfDate = new Date(),\r\n precision = 2,\r\n } = params;\r\n\r\n if (!amountPaid || amountPaid <= 0) return 0;\r\n\r\n const start = new Date(startDate);\r\n const end = new Date(endDate);\r\n const asOf = new Date(asOfDate);\r\n\r\n const totalMs = end.getTime() - start.getTime();\r\n if (totalMs <= 0) return 0;\r\n\r\n const remainingMs = Math.max(0, end.getTime() - asOf.getTime());\r\n if (remainingMs <= 0) return 0;\r\n\r\n const ratio = remainingMs / totalMs;\r\n const amount = amountPaid * ratio;\r\n\r\n const factor = 10 ** precision;\r\n return Math.round(amount * factor) / factor;\r\n}\r\n\r\n/**\r\n * Convert interval + count to duration/unit\r\n */\r\nexport function resolveIntervalToDuration(\r\n interval: string = 'month',\r\n intervalCount: number = 1\r\n): DurationResult {\r\n const normalized = (interval || 'month').toLowerCase();\r\n const count = Number(intervalCount) > 0 ? Number(intervalCount) : 1;\r\n\r\n switch (normalized) {\r\n case 'year':\r\n case 'years':\r\n return { duration: count, unit: 'years' };\r\n case 'week':\r\n case 'weeks':\r\n return { duration: count, unit: 'weeks' };\r\n case 'quarter':\r\n case 'quarters':\r\n return { duration: count * 3, unit: 'months' };\r\n case 'day':\r\n case 'days':\r\n return { duration: count, unit: 'days' };\r\n case 'month':\r\n case 'months':\r\n default:\r\n return { duration: count, unit: 'months' };\r\n }\r\n}\r\n\r\nexport default {\r\n addDuration,\r\n calculatePeriodRange,\r\n calculateProratedAmount,\r\n resolveIntervalToDuration,\r\n};\r\n\r\n","/**\r\n * Subscription Enums\r\n * @classytic/revenue\r\n *\r\n * All subscription-related enums and constants\r\n */\r\n\r\n// ============ SUBSCRIPTION STATUS ============\r\n/**\r\n * Subscription Status\r\n */\r\nexport const SUBSCRIPTION_STATUS = {\r\n ACTIVE: 'active',\r\n PAUSED: 'paused',\r\n CANCELLED: 'cancelled',\r\n EXPIRED: 'expired',\r\n PENDING: 'pending',\r\n INACTIVE: 'inactive',\r\n} as const;\r\n\r\nexport type SubscriptionStatus = typeof SUBSCRIPTION_STATUS;\r\nexport type SubscriptionStatusValue = SubscriptionStatus[keyof SubscriptionStatus];\r\nexport const SUBSCRIPTION_STATUS_VALUES = Object.values(SUBSCRIPTION_STATUS);\r\n\r\n// ============ PLAN KEYS ============\r\n/**\r\n * Supported plan intervals\r\n */\r\nexport const PLAN_KEYS = {\r\n MONTHLY: 'monthly',\r\n QUARTERLY: 'quarterly',\r\n YEARLY: 'yearly',\r\n} as const;\r\n\r\nexport type PlanKeys = typeof PLAN_KEYS;\r\nexport type PlanKeyValue = PlanKeys[keyof PlanKeys];\r\nexport const PLAN_KEY_VALUES = Object.values(PLAN_KEYS);\r\n\r\n","/**\r\n * Subscription Action Utilities\r\n * @classytic/revenue/utils/subscription\r\n *\r\n * Eligibility checks for subscription actions\r\n */\r\n\r\nimport { SUBSCRIPTION_STATUS } from '../../enums/subscription.enums.js';\r\nimport type { SubscriptionEntity, SubscriptionDocument } from '../../types/index.js';\r\n\r\n/**\r\n * Check if subscription is active\r\n */\r\nexport function isSubscriptionActive(\r\n subscription: Partial<SubscriptionDocument> | null | undefined\r\n): boolean {\r\n if (!subscription) return false;\r\n if (!subscription.isActive) return false;\r\n\r\n if (subscription.endDate) {\r\n const now = new Date();\r\n const endDate = new Date(subscription.endDate);\r\n if (endDate < now) return false;\r\n }\r\n\r\n return true;\r\n}\r\n\r\n/**\r\n * Check if can renew\r\n */\r\nexport function canRenewSubscription(entity: SubscriptionEntity | null | undefined): boolean {\r\n if (!entity?.subscription) return false;\r\n return isSubscriptionActive(entity.subscription as Partial<SubscriptionDocument>);\r\n}\r\n\r\n/**\r\n * Check if can cancel\r\n */\r\nexport function canCancelSubscription(entity: SubscriptionEntity | null | undefined): boolean {\r\n if (!entity?.subscription) return false;\r\n if (!isSubscriptionActive(entity.subscription as Partial<SubscriptionDocument>)) return false;\r\n return !entity.subscription.canceledAt;\r\n}\r\n\r\n/**\r\n * Check if can pause\r\n */\r\nexport function canPauseSubscription(entity: SubscriptionEntity | null | undefined): boolean {\r\n if (!entity?.subscription) return false;\r\n if (entity.status === SUBSCRIPTION_STATUS.PAUSED) return false;\r\n if (entity.status === SUBSCRIPTION_STATUS.CANCELLED) return false;\r\n return isSubscriptionActive(entity.subscription as Partial<SubscriptionDocument>);\r\n}\r\n\r\n/**\r\n * Check if can resume\r\n */\r\nexport function canResumeSubscription(entity: SubscriptionEntity | null | undefined): boolean {\r\n if (!entity?.subscription) return false;\r\n return entity.status === SUBSCRIPTION_STATUS.PAUSED;\r\n}\r\n\r\nexport default {\r\n isSubscriptionActive,\r\n canRenewSubscription,\r\n canCancelSubscription,\r\n canPauseSubscription,\r\n canResumeSubscription,\r\n};\r\n\r\n"]}
package/package.json CHANGED
@@ -1,9 +1,11 @@
1
1
  {
2
2
  "name": "@classytic/revenue",
3
- "version": "0.2.3",
4
- "description": "Enterprise revenue management system with subscriptions, purchases, proration, payment processing, escrow, and multi-party splits",
5
- "main": "index.js",
3
+ "version": "1.0.0",
4
+ "description": "Enterprise revenue management system with subscriptions, payments, escrow, splits - Modern, Type-safe, Resilient",
6
5
  "type": "module",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
7
9
  "keywords": [
8
10
  "revenue",
9
11
  "monetization",
@@ -26,7 +28,8 @@
26
28
  "split",
27
29
  "affiliate",
28
30
  "commission",
29
- "marketplace"
31
+ "marketplace",
32
+ "typescript"
30
33
  ],
31
34
  "author": "Sadman Chowdhury",
32
35
  "license": "MIT",
@@ -39,53 +42,66 @@
39
42
  },
40
43
  "homepage": "https://github.com/classytic/revenue#readme",
41
44
  "scripts": {
42
- "types": "tsc -p tsconfig.types.json",
43
- "build": "npm run types",
44
- "prepublishOnly": "npm run build",
45
+ "build": "tsup",
46
+ "build:watch": "tsup --watch",
47
+ "typecheck": "tsc --noEmit",
48
+ "clean": "rimraf dist",
49
+ "prepublishOnly": "npm run clean && npm run build",
45
50
  "test": "node ../tests/run-all.js"
46
51
  },
47
- "peerDependencies": {
48
- "mongoose": "^8.0.0 || ^9.0.0"
49
- },
50
- "engines": {
51
- "node": ">=18.0.0"
52
- },
53
52
  "exports": {
54
53
  ".": {
55
- "types": "./dist/types/index.d.ts",
56
- "default": "./index.js"
54
+ "types": "./dist/index.d.ts",
55
+ "import": "./dist/index.js"
56
+ },
57
+ "./core": {
58
+ "types": "./dist/core/index.d.ts",
59
+ "import": "./dist/core/index.js"
57
60
  },
58
61
  "./enums": {
59
- "types": "./dist/types/enums/index.d.ts",
60
- "default": "./enums/index.js"
62
+ "types": "./dist/enums/index.d.ts",
63
+ "import": "./dist/enums/index.js"
61
64
  },
62
65
  "./schemas": {
63
- "types": "./dist/types/schemas/index.d.ts",
64
- "default": "./schemas/index.js"
66
+ "types": "./dist/schemas/index.d.ts",
67
+ "import": "./dist/schemas/index.js"
68
+ },
69
+ "./schemas/validation": {
70
+ "types": "./dist/schemas/validation.d.ts",
71
+ "import": "./dist/schemas/validation.js"
65
72
  },
66
73
  "./utils": {
67
- "types": "./dist/types/utils/index.d.ts",
68
- "default": "./utils/index.js"
74
+ "types": "./dist/utils/index.d.ts",
75
+ "import": "./dist/utils/index.js"
76
+ },
77
+ "./providers": {
78
+ "types": "./dist/providers/index.d.ts",
79
+ "import": "./dist/providers/index.js"
80
+ },
81
+ "./services": {
82
+ "types": "./dist/services/index.d.ts",
83
+ "import": "./dist/services/index.js"
69
84
  }
70
85
  },
71
- "types": "./dist/types/index.d.ts",
72
86
  "files": [
73
- "index.js",
74
- "LICENSE",
87
+ "dist",
75
88
  "README.md",
76
- "core/",
77
- "providers/",
78
- "services/",
79
- "enums/",
80
- "schemas/",
81
- "utils/",
82
- "dist/types/"
89
+ "LICENSE"
83
90
  ],
91
+ "peerDependencies": {
92
+ "mongoose": "^8.0.0 || ^9.0.0"
93
+ },
94
+ "engines": {
95
+ "node": ">=18.0.0"
96
+ },
84
97
  "devDependencies": {
85
98
  "@types/node": "^22.8.7",
99
+ "rimraf": "^6.0.0",
100
+ "tsup": "^8.3.0",
86
101
  "typescript": "^5.6.3"
87
102
  },
88
103
  "dependencies": {
89
- "nanoid": "^5.1.6"
104
+ "nanoid": "^5.1.6",
105
+ "zod": "^4.1.13"
90
106
  }
91
107
  }
package/core/builder.js DELETED
@@ -1,219 +0,0 @@
1
- /**
2
- * Revenue Builder - Main Entry Point
3
- * @classytic/revenue
4
- *
5
- * Factory function to create revenue instance
6
- * Inspired by: AI SDK, LangChain, Prisma Client
7
- */
8
-
9
- import { Container } from './container.js';
10
- import { MonetizationService } from '../services/monetization.service.js';
11
- import { PaymentService } from '../services/payment.service.js';
12
- import { TransactionService } from '../services/transaction.service.js';
13
- import { EscrowService } from '../services/escrow.service.js';
14
- import { ConfigurationError } from './errors.js';
15
-
16
- /**
17
- * Create revenue instance with dependency injection
18
- *
19
- * @param {Object} options - Configuration options
20
- * @param {Object} options.models - Mongoose models { Transaction, Subscription, etc. }
21
- * @param {Record<string, import('../providers/base.js').PaymentProvider>} options.providers - Payment providers - Register ANY custom gateway by name
22
- * @param {Object} options.hooks - Event hooks
23
- * @param {Object} options.config - Additional configuration
24
- * @param {Object} options.logger - Logger instance
25
- * @returns {Revenue} Revenue instance
26
- *
27
- * @example
28
- * ```javascript
29
- * import { createRevenue } from '@classytic/revenue';
30
- * import { ManualProvider } from '@classytic/revenue-manual';
31
- *
32
- * const revenue = createRevenue({
33
- * models: {
34
- * Transaction: TransactionModel,
35
- * Subscription: SubscriptionModel,
36
- * },
37
- * providers: {
38
- * manual: new ManualProvider(),
39
- * bkash: new BkashProvider(), // Custom gateway
40
- * nagad: new NagadProvider(), // Custom gateway
41
- * stripe: new StripeProvider(), // Custom gateway
42
- * // ... register any gateway you want
43
- * },
44
- * config: {
45
- * targetModels: ['Subscription', 'Membership'],
46
- * categoryMappings: {
47
- * Subscription: 'platform_subscription',
48
- * Membership: 'gym_membership',
49
- * },
50
- * },
51
- * });
52
- *
53
- * // Use any registered gateway by name
54
- * const { transaction } = await revenue.monetization.create({
55
- * gateway: 'bkash', // Use your custom gateway
56
- * monetizationType: 'purchase',
57
- * amount: 1500,
58
- * // ...
59
- * });
60
- * await revenue.payments.verify(transaction._id);
61
- * ```
62
- */
63
- export function createRevenue(options = {}) {
64
- // Validate required options
65
- if (!options.models || !options.models.Transaction) {
66
- throw new Error('createRevenue(): options.models.Transaction is required');
67
- }
68
-
69
- // Create DI container
70
- const container = new Container();
71
-
72
- // Register models
73
- container.singleton('models', options.models);
74
-
75
- // Register providers
76
- const providers = options.providers || {};
77
-
78
- // Validate provider interface in non-production
79
- if (process.env.NODE_ENV !== 'production') {
80
- for (const [name, provider] of Object.entries(providers)) {
81
- validateProvider(name, provider);
82
- }
83
- }
84
-
85
- container.singleton('providers', providers);
86
-
87
- // Register hooks
88
- container.singleton('hooks', options.hooks || {});
89
-
90
- // Register config
91
- const config = {
92
- targetModels: ['Subscription', 'Membership'],
93
- categoryMappings: {},
94
- ...options.config,
95
- };
96
- container.singleton('config', config);
97
-
98
- // Register logger
99
- container.singleton('logger', options.logger || console);
100
-
101
- // Create service instances (lazy-loaded)
102
- const services = {
103
- monetization: null,
104
- payments: null,
105
- transactions: null,
106
- escrow: null,
107
- };
108
-
109
- // Create revenue instance
110
- const revenue = {
111
- /**
112
- * Get container (for advanced usage)
113
- */
114
- container,
115
-
116
- /**
117
- * Registered payment providers
118
- */
119
- providers,
120
-
121
- /**
122
- * Configuration
123
- */
124
- config,
125
-
126
- /**
127
- * Monetization service (handles purchases, subscriptions, free items)
128
- * Lazy-loaded on first access
129
- */
130
- get monetization() {
131
- if (!services.monetization) {
132
- services.monetization = new MonetizationService(container);
133
- }
134
- return services.monetization;
135
- },
136
-
137
- /**
138
- * Payment service
139
- * Lazy-loaded on first access
140
- */
141
- get payments() {
142
- if (!services.payments) {
143
- services.payments = new PaymentService(container);
144
- }
145
- return services.payments;
146
- },
147
-
148
- /**
149
- * Transaction service
150
- * Lazy-loaded on first access
151
- */
152
- get transactions() {
153
- if (!services.transactions) {
154
- services.transactions = new TransactionService(container);
155
- }
156
- return services.transactions;
157
- },
158
-
159
- /**
160
- * Escrow service
161
- * Lazy-loaded on first access
162
- */
163
- get escrow() {
164
- if (!services.escrow) {
165
- services.escrow = new EscrowService(container);
166
- }
167
- return services.escrow;
168
- },
169
-
170
- /**
171
- * Get a specific provider
172
- */
173
- getProvider(name) {
174
- const provider = providers[name];
175
- if (!provider) {
176
- throw new Error(`Provider "${name}" not found. Available: ${Object.keys(providers).join(', ')}`);
177
- }
178
- return provider;
179
- },
180
- };
181
-
182
- // Deeply freeze the revenue object (truly immutable)
183
- Object.freeze(revenue);
184
- Object.freeze(providers);
185
- Object.freeze(config);
186
-
187
- return revenue;
188
- }
189
-
190
- /**
191
- * Validate provider implements required interface
192
- * @private
193
- */
194
- function validateProvider(name, provider) {
195
- const required = ['createIntent', 'verifyPayment', 'getStatus', 'getCapabilities'];
196
- const missing = required.filter(method => typeof provider[method] !== 'function');
197
-
198
- if (missing.length > 0) {
199
- throw new ConfigurationError(
200
- `Provider "${name}" is missing required methods: ${missing.join(', ')}`,
201
- { provider: name, missing }
202
- );
203
- }
204
- }
205
-
206
- /**
207
- * Revenue instance type (for documentation)
208
- * @typedef {Object} Revenue
209
- * @property {Container} container - DI container (readonly)
210
- * @property {Object} providers - Payment providers (readonly, frozen)
211
- * @property {Object} config - Configuration (readonly, frozen)
212
- * @property {MonetizationService} monetization - Monetization service (purchases, subscriptions, free items)
213
- * @property {PaymentService} payments - Payment service
214
- * @property {TransactionService} transactions - Transaction service
215
- * @property {EscrowService} escrow - Escrow service
216
- * @property {Function} getProvider - Get payment provider
217
- */
218
-
219
- export default createRevenue;