@classytic/revenue 1.1.4 → 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 +33 -37
  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-rRdOqnWx.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-BhdS7nXh.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-DnNSFpGd.d.mts +0 -344
  74. package/dist/settlement.service-DjzAjezU.d.mts +0 -594
  75. package/dist/settlement.service-DmdKv0Zu.mjs +0 -2511
  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
@@ -0,0 +1,3 @@
1
+ import { $ as WebhookProcessedPayload, A as SettlementCreated, B as SubscriptionCancelled, C as PurchaseCreated, D as RevenueEventSchema, E as RevenueEventPayloadOf, F as SettlementProcessingPayload, G as SubscriptionPausedPayload, H as SubscriptionCreated, I as SettlementScheduled, J as SubscriptionResumed, K as SubscriptionRenewed, L as SettlementScheduledPayload, M as SettlementFailed, N as SettlementFailedPayload, O as SettlementCompleted, P as SettlementProcessing, Q as WebhookProcessed, R as SubscriptionActivated, S as PaymentVerifiedPayload, T as RevenueEventDefinition, U as SubscriptionCreatedPayload, V as SubscriptionCancelledPayload, W as SubscriptionPaused, X as TransactionUpdated, Y as SubscriptionResumedPayload, Z as TransactionUpdatedPayload, _ as PaymentRefunded, a as EscrowReleased, at as InProcessRevenueBusOptions, b as PaymentRequiresActionPayload, c as EscrowSplitPayload, d as MonetizationCreated, et as revenueEventDefinitions, f as MonetizationCreatedPayload, g as PaymentProcessingPayload, h as PaymentProcessing, i as EscrowHeldPayload, it as InProcessRevenueBus, j as SettlementCreatedPayload, k as SettlementCompletedPayload, l as FreeCreated, m as PaymentFailedPayload, n as EscrowCancelledPayload, nt as RevenueEventName, o as EscrowReleasedPayload, p as PaymentFailed, q as SubscriptionRenewedPayload, r as EscrowHeld, rt as createEvent, s as EscrowSplit, t as EscrowCancelled, tt as REVENUE_EVENTS, u as FreeCreatedPayload, v as PaymentRefundedPayload, w as PurchaseCreatedPayload, x as PaymentVerified, y as PaymentRequiresAction, z as SubscriptionActivatedPayload } from "../revenue-event-catalog-BX3g7RUi.mjs";
2
+ import { DomainEvent, EventHandler, EventTransport } from "@classytic/primitives/events";
3
+ export { type DomainEvent, EscrowCancelled, type EscrowCancelledPayload, EscrowHeld, type EscrowHeldPayload, EscrowReleased, type EscrowReleasedPayload, EscrowSplit, type EscrowSplitPayload, type EventHandler, type EventTransport, FreeCreated, type FreeCreatedPayload, InProcessRevenueBus, type InProcessRevenueBusOptions, MonetizationCreated, type MonetizationCreatedPayload, PaymentFailed, type PaymentFailedPayload, PaymentProcessing, type PaymentProcessingPayload, PaymentRefunded, type PaymentRefundedPayload, PaymentRequiresAction, type PaymentRequiresActionPayload, PaymentVerified, type PaymentVerifiedPayload, PurchaseCreated, type PurchaseCreatedPayload, REVENUE_EVENTS, type RevenueEventDefinition, type RevenueEventName, type RevenueEventPayloadOf, type RevenueEventSchema, SettlementCompleted, type SettlementCompletedPayload, SettlementCreated, type SettlementCreatedPayload, SettlementFailed, type SettlementFailedPayload, SettlementProcessing, type SettlementProcessingPayload, SettlementScheduled, type SettlementScheduledPayload, SubscriptionActivated, type SubscriptionActivatedPayload, SubscriptionCancelled, type SubscriptionCancelledPayload, SubscriptionCreated, type SubscriptionCreatedPayload, SubscriptionPaused, type SubscriptionPausedPayload, SubscriptionRenewed, type SubscriptionRenewedPayload, SubscriptionResumed, type SubscriptionResumedPayload, TransactionUpdated, type TransactionUpdatedPayload, WebhookProcessed, type WebhookProcessedPayload, createEvent, revenueEventDefinitions };
@@ -0,0 +1,4 @@
1
+ import { n as createEvent, t as REVENUE_EVENTS } from "../event-constants-CEMitnIV.mjs";
2
+ import { C as SubscriptionResumed, D as InProcessRevenueBus, E as revenueEventDefinitions, S as SubscriptionRenewed, T as WebhookProcessed, _ as SettlementScheduled, a as FreeCreated, b as SubscriptionCreated, c as PaymentProcessing, d as PaymentVerified, f as PurchaseCreated, g as SettlementProcessing, h as SettlementFailed, i as EscrowSplit, l as PaymentRefunded, m as SettlementCreated, n as EscrowHeld, o as MonetizationCreated, p as SettlementCompleted, r as EscrowReleased, s as PaymentFailed, t as EscrowCancelled, u as PaymentRequiresAction, v as SubscriptionActivated, w as TransactionUpdated, x as SubscriptionPaused, y as SubscriptionCancelled } from "../revenue-event-catalog-LqxPnsU_.mjs";
3
+
4
+ export { EscrowCancelled, EscrowHeld, EscrowReleased, EscrowSplit, FreeCreated, InProcessRevenueBus, MonetizationCreated, PaymentFailed, PaymentProcessing, PaymentRefunded, PaymentRequiresAction, PaymentVerified, PurchaseCreated, REVENUE_EVENTS, SettlementCompleted, SettlementCreated, SettlementFailed, SettlementProcessing, SettlementScheduled, SubscriptionActivated, SubscriptionCancelled, SubscriptionCreated, SubscriptionPaused, SubscriptionRenewed, SubscriptionResumed, TransactionUpdated, WebhookProcessed, createEvent, revenueEventDefinitions };
package/dist/index.d.mts CHANGED
@@ -1,9 +1,77 @@
1
- import "./settlement.service-DjzAjezU.mjs";
2
- import { K as ITransaction, q as ITransactionCreateInput } from "./index-Dsp7H5Wb.mjs";
3
- import "./settlement.schema-DnNSFpGd.mjs";
4
- import { a as WebhookEvent, i as RefundResult, n as PaymentProvider, r as PaymentResult, t as PaymentIntent } from "./base-CsTlVQJe.mjs";
5
- import "./plugin-BbK0OVHy.mjs";
6
- import { S as unwrapOr, c as Ok, d as err, l as Result, m as isOk, p as isErr, s as Err, v as ok, x as unwrap } from "./retry-HHCOXYdn.mjs";
7
- import { A as SUBSCRIPTION_STATE_MACHINE, B as Revenue, C as TransactionNotFoundError, D as HOLD_STATE_MACHINE, E as isRevenueError, F as filterAuditTrail, H as RevenueOptions, I as getAuditTrail, L as getLastStateChange, M as StateMachine, N as StateChangeEvent, O as SETTLEMENT_STATE_MACHINE, P as appendAuditEvent, R as ModelsConfig, S as SubscriptionNotFoundError, T as isRetryable, U as createRevenue, V as RevenueBuilder, _ as RefundNotSupportedError, a as InvalidAmountError, b as StateError, c as ModelNotRegisteredError, d as PaymentIntentCreationError, f as PaymentVerificationError, g as RefundError, h as ProviderNotFoundError, i as ErrorCode, j as TRANSACTION_STATE_MACHINE, k as SPLIT_STATE_MACHINE, l as NotFoundError, m as ProviderError, n as ConfigurationError, o as InvalidStateTransitionError, p as ProviderCapabilityError, r as ERROR_CODES, s as MissingRequiredFieldError, t as AlreadyVerifiedError, u as OperationError, v as RevenueError, w as ValidationError, x as SubscriptionNotActiveError, y as RevenueErrorOptions, z as ProvidersConfig } from "./errors-rRdOqnWx.mjs";
8
- import { i as toSmallestUnit, n as MoneyValue, r as fromSmallestUnit, t as Money } from "./money-DPG8AtJ8.mjs";
9
- export { AlreadyVerifiedError, ConfigurationError, ERROR_CODES, type Err, ErrorCode, HOLD_STATE_MACHINE, type ITransaction, type ITransactionCreateInput, InvalidAmountError, InvalidStateTransitionError, MissingRequiredFieldError, ModelNotRegisteredError, type ModelsConfig, Money, type MoneyValue, NotFoundError, type Ok, OperationError, PaymentIntent, PaymentIntentCreationError, PaymentProvider, PaymentResult, PaymentVerificationError, ProviderCapabilityError, ProviderError, ProviderNotFoundError, type ProvidersConfig, RefundError, RefundNotSupportedError, RefundResult, Result, Revenue, RevenueBuilder, RevenueError, RevenueErrorOptions, type RevenueOptions, SETTLEMENT_STATE_MACHINE, SPLIT_STATE_MACHINE, SUBSCRIPTION_STATE_MACHINE, type StateChangeEvent, StateError, StateMachine, SubscriptionNotActiveError, SubscriptionNotFoundError, TRANSACTION_STATE_MACHINE, TransactionNotFoundError, ValidationError, WebhookEvent, appendAuditEvent, createRevenue, err, filterAuditTrail, fromSmallestUnit, getAuditTrail, getLastStateChange, isErr, isOk, isRetryable, isRevenueError, ok, toSmallestUnit, unwrap, unwrapOr };
1
+ import { t as RevenueContext } from "./context-DRqSeTPM.mjs";
2
+ import { a as CurrencyBridge, c as LedgerBridge, i as CustomerBridge, o as NotificationBridge, r as AnalyticsBridge, s as TaxBridge, t as RevenueBridges } from "./revenue-bridges-sdlrR85c.mjs";
3
+ import { $ as LibraryCategories, A as isReleaseReason, B as isSettlementType, C as HoldStatusValue, D as ReleaseReasonValue, E as ReleaseReason, F as SettlementStatus, G as SUBSCRIPTION_STATUS, H as PLAN_KEY_VALUES, I as SettlementStatusValue, J as SubscriptionStatusValue, K as SUBSCRIPTION_STATUS_VALUES, L as SettlementType, M as SETTLEMENT_STATUS_VALUES, N as SETTLEMENT_TYPE, O as isHoldReason, P as SETTLEMENT_TYPE_VALUES, Q as LIBRARY_CATEGORY_VALUES, R as SettlementTypeValue, S as HoldStatus, T as RELEASE_REASON_VALUES, U as PlanKeyValue, V as PLAN_KEYS, W as PlanKeys, X as isSubscriptionStatus, Y as isPlanKey, Z as LIBRARY_CATEGORIES, _ as HOLD_REASON_VALUES, a as SPLIT_STATUS, at as TransactionFlow, b as HoldReason, c as SPLIT_TYPE_VALUES, ct as TransactionStatusValue, d as SplitType, dt as isTransactionStatus, et as LibraryCategoryValue, f as SplitTypeValue, g as HOLD_REASON, h as isSplitType, i as PayoutMethodValue, it as TRANSACTION_STATUS_VALUES, j as SETTLEMENT_STATUS, k as isHoldStatus, l as SplitStatus, lt as isLibraryCategory, m as isSplitStatus, n as PAYOUT_METHOD_VALUES, nt as TRANSACTION_FLOW_VALUES, o as SPLIT_STATUS_VALUES, ot as TransactionFlowValue, p as isPayoutMethod, q as SubscriptionStatus, r as PayoutMethod, rt as TRANSACTION_STATUS, s as SPLIT_TYPE, st as TransactionStatus, t as PAYOUT_METHOD, tt as TRANSACTION_FLOW, u as SplitStatusValue, ut as isTransactionFlow, v as HOLD_STATUS, w as RELEASE_REASON, x as HoldReasonValue, y as HOLD_STATUS_VALUES, z as isSettlementStatus } from "./split.enums-Dw4zCrcZ.mjs";
4
+ import { HOLD_STATE_MACHINE, SETTLEMENT_STATE_MACHINE, SPLIT_STATE_MACHINE, SUBSCRIPTION_STATE_MACHINE, StateChangeEvent, StateMachine, TRANSACTION_STATE_MACHINE } from "./core/state-machines.mjs";
5
+ import { a as isMonetizationType, c as PAYMENT_STATUS, d as PaymentGatewayTypeValue, f as PaymentStatus, h as isPaymentStatus, i as MonetizationTypes, l as PAYMENT_STATUS_VALUES, m as isPaymentGatewayType, n as MONETIZATION_TYPE_VALUES, o as PAYMENT_GATEWAY_TYPE, p as PaymentStatusValue, r as MonetizationTypeValue, s as PAYMENT_GATEWAY_TYPE_VALUES, t as MONETIZATION_TYPES, u as PaymentGatewayType } from "./monetization.enums-D2xbxXJM.mjs";
6
+ import { D as RevenueEventSchema, E as RevenueEventPayloadOf, T as RevenueEventDefinition, at as InProcessRevenueBusOptions, et as revenueEventDefinitions, it as InProcessRevenueBus, nt as RevenueEventName, rt as createEvent, tt as REVENUE_EVENTS } from "./revenue-event-catalog-BX3g7RUi.mjs";
7
+ import { a as PaymentIntentData, c as PaymentResultData, d as RefundResultData, f as WebhookEvent, i as PaymentIntent, l as ProviderCapabilities, n as createProviderRegistry, o as PaymentProvider, p as WebhookEventData, r as CreateIntentParams, s as PaymentResult, t as ProviderRegistry, u as RefundResult } from "./registry-SvIGPAx_.mjs";
8
+ import { a as SettlementRepository, c as RevenueModels, d as SubscriptionDocument, f as TransactionDocument, i as RevenueEngine, l as RevenueSchemaOptions, n as RetryConfig, o as SubscriptionRepository, r as RevenueConfig, s as TransactionRepository, t as CommissionConfig, u as SettlementDocument } from "./engine-types-CcjIb4Fy.mjs";
9
+ import { RepositoryPluginBundle, RevenueRepositories } from "./repositories/create-repositories.mjs";
10
+ import { A as transactionBaseSchema, C as subscriptionBaseSchema, D as TransactionCreateInput, E as subscriptionUpdateSchema, M as transactionListFilterSchema, N as transactionUpdateSchema, O as TransactionListFilter, S as SubscriptionUpdateInput, T as subscriptionListFilterSchema, _ as settlementCreateSchema, a as escrowReleaseSchema, b as SubscriptionCreateInput, c as PaymentVerifyInput, d as paymentVerifySchema, f as refundSchema, g as settlementBaseSchema, h as SettlementUpdateInput, i as escrowHoldSchema, j as transactionCreateSchema, k as TransactionUpdateInput, l as RefundInput, m as SettlementListFilter, n as EscrowReleaseInput, o as splitRuleSchema, p as SettlementCreateInput, r as SplitRuleInput, s as PaymentIntentInput, t as EscrowHoldInput, u as paymentIntentSchema, v as settlementListFilterSchema, w as subscriptionCreateSchema, x as SubscriptionListFilter, y as settlementUpdateSchema } from "./escrow.schema-CC8XuD46.mjs";
11
+ import { A as SplitInfo, B as validateTaxCalculation, C as multiplyMoney, D as toCurrencyCode, E as sumMoney, F as TaxConfig, H as calculateCommission, I as TaxType, L as calculateTax, M as calculateOrganizationPayout, N as calculateSplits, O as toMajor, P as TaxCalculation, R as getTaxType, S as money, T as subtractMoney, U as reverseCommission, V as CommissionInfo, _ as isMoney, a as CurrencyCode, b as isZeroMoney, c as Money, d as addMoney, f as compareMoney, g as isCurrencyCode, h as fromSmallestUnit, i as CURRENCIES, j as SplitRule, k as toSmallestUnit, l as MoneyValue, m as fromMajor, n as getAuditTrail, o as CurrencyMismatchError, p as equalsMoney, r as getLastStateChange, s as MINOR_UNIT_FACTOR, t as appendAuditEvent, u as absMoney, v as isNegativeMoney, w as negateMoney, x as minorUnitFactor, y as isPositiveMoney, z as reverseTax } from "./audit-DZ0eTr9g.mjs";
12
+ import { HookHandler, PluginContext, PluginManager, RevenuePluginDefinition } from "./plugins/plugin.interface.mjs";
13
+ import { DomainEvent, EventHandler, EventTransport } from "@classytic/primitives/events";
14
+ import { InvalidOutboxEventError, OutboxAcknowledgeOptions, OutboxClaimOptions, OutboxErrorInfo, OutboxFailOptions, OutboxFailureContext, OutboxFailureDecision, OutboxFailurePolicy, OutboxOwnershipError, OutboxStore, OutboxWriteOptions } from "@classytic/primitives/outbox";
15
+ import { Result, err, isErr, isOk, ok } from "@classytic/primitives/result";
16
+
17
+ //#region src/engine/create-revenue.d.ts
18
+ /**
19
+ * createRevenue — factory for the revenue engine.
20
+ *
21
+ * Accepts an optional arc-compatible `EventTransport`. When the host
22
+ * doesn't pass one, we instantiate `InProcessRevenueBus` — a ~50-line
23
+ * structural match of arc's `MemoryEventTransport` that ships with the
24
+ * package so `createRevenue` always returns a working engine even without
25
+ * arc installed. Hosts that already use arc can pass
26
+ * `new RedisEventTransport(...)` (or any arc transport) straight in.
27
+ *
28
+ * Domain verbs publish via `this.deps.events.publish(createEvent(...))` and
29
+ * hosts subscribe via `revenue.events.subscribe('revenue:payment.*', ...)`.
30
+ * See PACKAGE_RULES §13–§14.
31
+ */
32
+ declare function createRevenue(config: RevenueConfig): Promise<RevenueEngine>;
33
+ //#endregion
34
+ //#region src/core/errors.d.ts
35
+ declare class RevenueError extends Error {
36
+ readonly code: string;
37
+ readonly details?: Record<string, unknown> | undefined;
38
+ constructor(message: string, code: string, details?: Record<string, unknown> | undefined);
39
+ }
40
+ declare class ValidationError extends RevenueError {
41
+ constructor(message: string, details?: Record<string, unknown>);
42
+ }
43
+ declare class ConfigurationError extends RevenueError {
44
+ constructor(message: string, details?: Record<string, unknown>);
45
+ }
46
+ declare class ProviderNotFoundError extends RevenueError {
47
+ constructor(providerName: string);
48
+ }
49
+ declare class TransactionNotFoundError extends RevenueError {
50
+ constructor(transactionId: string);
51
+ }
52
+ declare class SubscriptionNotFoundError extends RevenueError {
53
+ constructor(subscriptionId: string);
54
+ }
55
+ declare class SettlementNotFoundError extends RevenueError {
56
+ constructor(settlementId: string);
57
+ }
58
+ declare class PaymentIntentCreationError extends RevenueError {
59
+ constructor(message: string, details?: Record<string, unknown>);
60
+ }
61
+ declare class ProviderCapabilityError extends RevenueError {
62
+ constructor(provider: string, capability: string);
63
+ }
64
+ declare class InvalidStateTransitionError extends RevenueError {
65
+ constructor(resourceType: string, resourceId: string, from: string, to: string);
66
+ }
67
+ declare class AlreadyVerifiedError extends RevenueError {
68
+ constructor(transactionId: string);
69
+ }
70
+ declare class RefundNotSupportedError extends RevenueError {
71
+ constructor(provider: string);
72
+ }
73
+ declare class PaymentVerificationError extends RevenueError {
74
+ constructor(message: string, details?: Record<string, unknown>);
75
+ }
76
+ //#endregion
77
+ export { AlreadyVerifiedError, type AnalyticsBridge, CURRENCIES, type CommissionConfig, type CommissionInfo, ConfigurationError, type CreateIntentParams, type CurrencyBridge, type CurrencyCode, CurrencyMismatchError, type CustomerBridge, type DomainEvent, EscrowHoldInput, EscrowReleaseInput, type EventHandler, type EventTransport, HOLD_REASON, HOLD_REASON_VALUES, HOLD_STATE_MACHINE, HOLD_STATUS, HOLD_STATUS_VALUES, HoldReason, HoldReasonValue, HoldStatus, HoldStatusValue, type HookHandler, InProcessRevenueBus, type InProcessRevenueBusOptions, InvalidOutboxEventError, InvalidStateTransitionError, LIBRARY_CATEGORIES, LIBRARY_CATEGORY_VALUES, type LedgerBridge, LibraryCategories, LibraryCategoryValue, MINOR_UNIT_FACTOR, MONETIZATION_TYPES, MONETIZATION_TYPE_VALUES, MonetizationTypeValue, MonetizationTypes, type Money, type MoneyValue, type NotificationBridge, type OutboxAcknowledgeOptions, type OutboxClaimOptions, type OutboxErrorInfo, type OutboxFailOptions, type OutboxFailureContext, type OutboxFailureDecision, type OutboxFailurePolicy, OutboxOwnershipError, type OutboxStore, type OutboxWriteOptions, PAYMENT_GATEWAY_TYPE, PAYMENT_GATEWAY_TYPE_VALUES, PAYMENT_STATUS, PAYMENT_STATUS_VALUES, PAYOUT_METHOD, PAYOUT_METHOD_VALUES, PLAN_KEYS, PLAN_KEY_VALUES, PaymentGatewayType, PaymentGatewayTypeValue, PaymentIntent, PaymentIntentCreationError, type PaymentIntentData, PaymentIntentInput, PaymentProvider, PaymentResult, type PaymentResultData, PaymentStatus, PaymentStatusValue, PaymentVerificationError, PaymentVerifyInput, PayoutMethod, PayoutMethodValue, PlanKeyValue, PlanKeys, type PluginContext, PluginManager, type ProviderCapabilities, ProviderCapabilityError, ProviderNotFoundError, ProviderRegistry, RELEASE_REASON, RELEASE_REASON_VALUES, REVENUE_EVENTS, RefundInput, RefundNotSupportedError, RefundResult, type RefundResultData, ReleaseReason, ReleaseReasonValue, type RepositoryPluginBundle, type Result, type RetryConfig, type RevenueBridges, type RevenueConfig, type RevenueContext, type RevenueEngine, RevenueError, type RevenueEventDefinition, type RevenueEventName, type RevenueEventPayloadOf, type RevenueEventSchema, type RevenueModels, type RevenuePluginDefinition, type RevenueRepositories, type RevenueSchemaOptions, SETTLEMENT_STATE_MACHINE, SETTLEMENT_STATUS, SETTLEMENT_STATUS_VALUES, SETTLEMENT_TYPE, SETTLEMENT_TYPE_VALUES, SPLIT_STATE_MACHINE, SPLIT_STATUS, SPLIT_STATUS_VALUES, SPLIT_TYPE, SPLIT_TYPE_VALUES, SUBSCRIPTION_STATE_MACHINE, SUBSCRIPTION_STATUS, SUBSCRIPTION_STATUS_VALUES, SettlementCreateInput, type SettlementDocument, SettlementListFilter, SettlementNotFoundError, SettlementRepository, SettlementStatus, SettlementStatusValue, SettlementType, SettlementTypeValue, SettlementUpdateInput, type SplitInfo, type SplitRule, SplitRuleInput, SplitStatus, SplitStatusValue, SplitType, SplitTypeValue, type StateChangeEvent, StateMachine, SubscriptionCreateInput, type SubscriptionDocument, SubscriptionListFilter, SubscriptionNotFoundError, SubscriptionRepository, SubscriptionStatus, SubscriptionStatusValue, SubscriptionUpdateInput, TRANSACTION_FLOW, TRANSACTION_FLOW_VALUES, TRANSACTION_STATE_MACHINE, TRANSACTION_STATUS, TRANSACTION_STATUS_VALUES, type TaxBridge, type TaxCalculation, type TaxConfig, type TaxType, TransactionCreateInput, type TransactionDocument, TransactionFlow, TransactionFlowValue, TransactionListFilter, TransactionNotFoundError, TransactionRepository, TransactionStatus, TransactionStatusValue, TransactionUpdateInput, ValidationError, WebhookEvent, type WebhookEventData, absMoney, addMoney, appendAuditEvent, calculateCommission, calculateOrganizationPayout, calculateSplits, calculateTax, compareMoney, createEvent, createProviderRegistry, createRevenue, equalsMoney, err, escrowHoldSchema, escrowReleaseSchema, fromMajor, fromSmallestUnit, getAuditTrail, getLastStateChange, getTaxType, isCurrencyCode, isErr, isHoldReason, isHoldStatus, isLibraryCategory, isMonetizationType, isMoney, isNegativeMoney, isOk, isPaymentGatewayType, isPaymentStatus, isPayoutMethod, isPlanKey, isPositiveMoney, isReleaseReason, isSettlementStatus, isSettlementType, isSplitStatus, isSplitType, isSubscriptionStatus, isTransactionFlow, isTransactionStatus, isZeroMoney, minorUnitFactor, money, multiplyMoney, negateMoney, ok, paymentIntentSchema, paymentVerifySchema, refundSchema, revenueEventDefinitions, reverseCommission, reverseTax, settlementBaseSchema, settlementCreateSchema, settlementListFilterSchema, settlementUpdateSchema, splitRuleSchema, subscriptionBaseSchema, subscriptionCreateSchema, subscriptionListFilterSchema, subscriptionUpdateSchema, subtractMoney, sumMoney, toCurrencyCode, toMajor, toSmallestUnit, transactionBaseSchema, transactionCreateSchema, transactionListFilterSchema, transactionUpdateSchema, validateTaxCalculation };
package/dist/index.mjs CHANGED
@@ -1,38 +1,474 @@
1
- import { n as RevenueBuilder, r as createRevenue, t as Revenue } from "./revenue-BhdS7nXh.mjs";
2
- import { S as unwrapOr, d as err, l as Result, m as isOk, p as isErr, v as ok, x as unwrap } from "./commission-split-BzB8cd39.mjs";
3
- import { C as ValidationError, S as TransactionNotFoundError, T as isRevenueError, _ as RefundNotSupportedError, a as InvalidAmountError, b as SubscriptionNotActiveError, c as ModelNotRegisteredError, d as PaymentIntentCreationError, f as PaymentVerificationError, g as RefundError, h as ProviderNotFoundError, i as ERROR_CODES, l as NotFoundError, m as ProviderError, n as AlreadyVerifiedError, o as InvalidStateTransitionError, p as ProviderCapabilityError, r as ConfigurationError, s as MissingRequiredFieldError, u as OperationError, v as RevenueError, w as isRetryable, x as SubscriptionNotFoundError, y as StateError } from "./category-resolver-DV83N8ok.mjs";
4
- import { c as getAuditTrail, d as SETTLEMENT_STATE_MACHINE, f as SPLIT_STATE_MACHINE, h as StateMachine, l as getLastStateChange, m as TRANSACTION_STATE_MACHINE, o as appendAuditEvent, p as SUBSCRIPTION_STATE_MACHINE, s as filterAuditTrail, u as HOLD_STATE_MACHINE } from "./settlement.service-DmdKv0Zu.mjs";
5
- import { a as WebhookEvent, i as RefundResult, n as PaymentProvider, r as PaymentResult, t as PaymentIntent } from "./base-DCoyIUj6.mjs";
6
- import { n as fromSmallestUnit, r as toSmallestUnit, t as Money } from "./money-CvrDOijQ.mjs";
1
+ import { n as createEvent, t as REVENUE_EVENTS } from "./event-constants-CEMitnIV.mjs";
2
+ import { A as isReleaseReason, C as HOLD_REASON_VALUES, D as RELEASE_REASON_VALUES, E as RELEASE_REASON, F as TRANSACTION_STATUS, I as TRANSACTION_STATUS_VALUES, L as isLibraryCategory, M as LIBRARY_CATEGORY_VALUES, N as TRANSACTION_FLOW, O as isHoldReason, P as TRANSACTION_FLOW_VALUES, R as isTransactionFlow, S as HOLD_REASON, T as HOLD_STATUS_VALUES, _ as PLAN_KEY_VALUES, a as SPLIT_TYPE, b as isPlanKey, c as isSplitStatus, d as SETTLEMENT_STATUS_VALUES, f as SETTLEMENT_TYPE, g as PLAN_KEYS, h as isSettlementType, i as SPLIT_STATUS_VALUES, j as LIBRARY_CATEGORIES, k as isHoldStatus, l as isSplitType, m as isSettlementStatus, n as PAYOUT_METHOD_VALUES, o as SPLIT_TYPE_VALUES, p as SETTLEMENT_TYPE_VALUES, r as SPLIT_STATUS, s as isPayoutMethod, t as PAYOUT_METHOD, u as SETTLEMENT_STATUS, v as SUBSCRIPTION_STATUS, w as HOLD_STATUS, x as isSubscriptionStatus, y as SUBSCRIPTION_STATUS_VALUES, z as isTransactionStatus } from "./split.enums-CQE3ekH1.mjs";
3
+ import { a as PaymentVerificationError, c as RefundNotSupportedError, d as SubscriptionNotFoundError, f as TransactionNotFoundError, i as PaymentIntentCreationError, l as RevenueError, n as ConfigurationError, o as ProviderCapabilityError, p as ValidationError, r as InvalidStateTransitionError, s as ProviderNotFoundError, t as AlreadyVerifiedError, u as SettlementNotFoundError } from "./errors-DHa8JVQ-.mjs";
4
+ import { HOLD_STATE_MACHINE, SETTLEMENT_STATE_MACHINE, SPLIT_STATE_MACHINE, SUBSCRIPTION_STATE_MACHINE, StateMachine, TRANSACTION_STATE_MACHINE } from "./core/state-machines.mjs";
5
+ import { a as reverseTax, c as reverseCommission, i as getTaxType, n as calculateSplits, o as validateTaxCalculation, r as calculateTax, s as calculateCommission, t as calculateOrganizationPayout } from "./splits-BAfY-a9P.mjs";
6
+ import { n as SubscriptionRepository, r as TransactionRepository, t as SettlementRepository } from "./settlement.repository-Cy3mMWGH.mjs";
7
+ import { createRevenueRepositories } from "./repositories/create-repositories.mjs";
8
+ import { a as PaymentResult, i as PaymentProvider, n as createProviderRegistry, o as RefundResult, r as PaymentIntent, s as WebhookEvent, t as ProviderRegistry } from "./registry-DhFMsSn5.mjs";
9
+ import { D as InProcessRevenueBus, E as revenueEventDefinitions } from "./revenue-event-catalog-LqxPnsU_.mjs";
10
+ import { a as PAYMENT_GATEWAY_TYPE_VALUES, c as isPaymentGatewayType, i as PAYMENT_GATEWAY_TYPE, l as isPaymentStatus, n as MONETIZATION_TYPE_VALUES, o as PAYMENT_STATUS, r as isMonetizationType, s as PAYMENT_STATUS_VALUES, t as MONETIZATION_TYPES } from "./monetization.enums-BtiU3t8o.mjs";
11
+ import { _ as transactionListFilterSchema, a as paymentVerifySchema, c as settlementCreateSchema, d as subscriptionBaseSchema, f as subscriptionCreateSchema, g as transactionCreateSchema, h as transactionBaseSchema, i as paymentIntentSchema, l as settlementListFilterSchema, m as subscriptionUpdateSchema, n as escrowReleaseSchema, o as refundSchema, p as subscriptionListFilterSchema, r as splitRuleSchema, s as settlementBaseSchema, t as escrowHoldSchema, u as settlementUpdateSchema, v as transactionUpdateSchema } from "./escrow.schema-BBv9oVEW.mjs";
12
+ import { C as sumMoney, E as toSmallestUnit, S as subtractMoney, T as toMajor, _ as isZeroMoney, a as CurrencyMismatchError, b as multiplyMoney, c as addMoney, d as fromMajor, f as fromSmallestUnit, g as isPositiveMoney, h as isNegativeMoney, i as CURRENCIES, l as compareMoney, m as isMoney, n as getAuditTrail, o as MINOR_UNIT_FACTOR, p as isCurrencyCode, r as getLastStateChange, s as absMoney, t as appendAuditEvent, u as equalsMoney, v as minorUnitFactor, w as toCurrencyCode, x as negateMoney, y as money } from "./audit-B39B0Sdq.mjs";
13
+ import { PluginManager } from "./plugins/plugin.interface.mjs";
14
+ import { customIdPlugin, multiTenantPlugin, prefixedId, softDeletePlugin } from "@classytic/mongokit";
15
+ import { resolveTenantConfig } from "@classytic/primitives/tenant";
16
+ import mongoose, { Schema } from "mongoose";
17
+ import { InvalidOutboxEventError, OutboxOwnershipError } from "@classytic/primitives/outbox";
18
+ import { err, isErr, isOk, ok } from "@classytic/primitives/result";
7
19
 
8
- //#region src/index.ts
20
+ //#region src/models/transaction.schema.ts
21
+ function buildTransactionSchema(config) {
22
+ const fields = {
23
+ publicId: { type: String },
24
+ customerId: {
25
+ type: String,
26
+ default: null
27
+ },
28
+ type: {
29
+ type: String,
30
+ required: true
31
+ },
32
+ flow: {
33
+ type: String,
34
+ enum: ["inflow", "outflow"],
35
+ required: true
36
+ },
37
+ tags: [{ type: String }],
38
+ amount: {
39
+ type: Number,
40
+ required: true
41
+ },
42
+ currency: {
43
+ type: String,
44
+ required: true
45
+ },
46
+ fee: {
47
+ type: Number,
48
+ default: 0
49
+ },
50
+ tax: {
51
+ type: Number,
52
+ default: 0
53
+ },
54
+ net: {
55
+ type: Number,
56
+ default: 0
57
+ },
58
+ taxDetails: { type: Schema.Types.Mixed },
59
+ method: {
60
+ type: String,
61
+ required: true
62
+ },
63
+ status: {
64
+ type: String,
65
+ default: "pending"
66
+ },
67
+ gateway: { type: Schema.Types.Mixed },
68
+ paymentDetails: { type: Schema.Types.Mixed },
69
+ commission: { type: Schema.Types.Mixed },
70
+ splits: [{ type: Schema.Types.Mixed }],
71
+ hold: { type: Schema.Types.Mixed },
72
+ sourceId: { type: String },
73
+ sourceModel: { type: String },
74
+ relatedTransactionId: {
75
+ type: Schema.Types.ObjectId,
76
+ ref: "Transaction"
77
+ },
78
+ refundedAmount: { type: Number },
79
+ refundedAt: { type: Date },
80
+ failureReason: { type: String },
81
+ failedAt: { type: Date },
82
+ verifiedAt: { type: Date },
83
+ verifiedBy: { type: String },
84
+ webhook: { type: Schema.Types.Mixed },
85
+ idempotencyKey: { type: String },
86
+ metadata: { type: Schema.Types.Mixed },
87
+ deletedAt: {
88
+ type: Date,
89
+ default: null
90
+ }
91
+ };
92
+ if (config.extraFields) Object.assign(fields, config.extraFields);
93
+ const schema = new Schema(fields, { timestamps: true });
94
+ schema.index({
95
+ status: 1,
96
+ createdAt: -1
97
+ });
98
+ schema.index({
99
+ customerId: 1,
100
+ createdAt: -1
101
+ });
102
+ schema.index({
103
+ sourceId: 1,
104
+ sourceModel: 1
105
+ });
106
+ if (config.extraIndexes) for (const idx of config.extraIndexes) schema.index(idx.fields, idx.options);
107
+ return schema;
108
+ }
109
+
110
+ //#endregion
111
+ //#region src/models/subscription.schema.ts
112
+ function buildSubscriptionSchema(config) {
113
+ const txnRef = "Transaction";
114
+ const fields = {
115
+ publicId: { type: String },
116
+ customerId: {
117
+ type: String,
118
+ default: null
119
+ },
120
+ planKey: {
121
+ type: String,
122
+ required: true
123
+ },
124
+ amount: {
125
+ type: Number,
126
+ required: true
127
+ },
128
+ currency: { type: String },
129
+ status: {
130
+ type: String,
131
+ default: "pending"
132
+ },
133
+ isActive: {
134
+ type: Boolean,
135
+ default: false
136
+ },
137
+ transactionId: {
138
+ type: Schema.Types.ObjectId,
139
+ ref: txnRef,
140
+ default: null
141
+ },
142
+ paymentIntentId: {
143
+ type: String,
144
+ default: null
145
+ },
146
+ startDate: { type: Date },
147
+ endDate: { type: Date },
148
+ activatedAt: { type: Date },
149
+ pausedAt: { type: Date },
150
+ pauseReason: { type: String },
151
+ canceledAt: { type: Date },
152
+ cancelAt: { type: Date },
153
+ cancellationReason: { type: String },
154
+ renewalTransactionId: {
155
+ type: Schema.Types.ObjectId,
156
+ ref: txnRef
157
+ },
158
+ renewalCount: {
159
+ type: Number,
160
+ default: 0
161
+ },
162
+ metadata: { type: Schema.Types.Mixed },
163
+ deletedAt: {
164
+ type: Date,
165
+ default: null
166
+ }
167
+ };
168
+ if (config.extraFields) Object.assign(fields, config.extraFields);
169
+ const schema = new Schema(fields, { timestamps: true });
170
+ schema.index({
171
+ customerId: 1,
172
+ status: 1
173
+ });
174
+ schema.index({
175
+ status: 1,
176
+ endDate: 1
177
+ });
178
+ schema.index({ publicId: 1 }, {
179
+ unique: true,
180
+ partialFilterExpression: {
181
+ deletedAt: null,
182
+ publicId: { $type: "string" }
183
+ }
184
+ });
185
+ if (config.extraIndexes) for (const idx of config.extraIndexes) schema.index(idx.fields, idx.options);
186
+ return schema;
187
+ }
188
+
189
+ //#endregion
190
+ //#region src/models/settlement.schema.ts
191
+ function buildSettlementSchema(config) {
192
+ const fields = {
193
+ publicId: { type: String },
194
+ recipientId: {
195
+ type: String,
196
+ required: true
197
+ },
198
+ recipientType: {
199
+ type: String,
200
+ required: true
201
+ },
202
+ type: {
203
+ type: String,
204
+ required: true
205
+ },
206
+ status: {
207
+ type: String,
208
+ default: "pending"
209
+ },
210
+ payoutMethod: {
211
+ type: String,
212
+ required: true
213
+ },
214
+ amount: {
215
+ type: Number,
216
+ required: true
217
+ },
218
+ currency: {
219
+ type: String,
220
+ required: true
221
+ },
222
+ sourceTransactionIds: [{
223
+ type: Schema.Types.ObjectId,
224
+ ref: "Transaction"
225
+ }],
226
+ sourceSplitIds: [{ type: String }],
227
+ bankTransferDetails: { type: Schema.Types.Mixed },
228
+ mobileWalletDetails: { type: Schema.Types.Mixed },
229
+ cryptoDetails: { type: Schema.Types.Mixed },
230
+ scheduledAt: {
231
+ type: Date,
232
+ default: () => /* @__PURE__ */ new Date()
233
+ },
234
+ processedAt: { type: Date },
235
+ completedAt: { type: Date },
236
+ failedAt: { type: Date },
237
+ cancelledAt: { type: Date },
238
+ failureReason: { type: String },
239
+ failureCode: { type: String },
240
+ retryCount: {
241
+ type: Number,
242
+ default: 0
243
+ },
244
+ notes: { type: String },
245
+ metadata: { type: Schema.Types.Mixed },
246
+ deletedAt: {
247
+ type: Date,
248
+ default: null
249
+ }
250
+ };
251
+ if (config.extraFields) Object.assign(fields, config.extraFields);
252
+ const schema = new Schema(fields, { timestamps: true });
253
+ schema.index({
254
+ status: 1,
255
+ scheduledAt: 1
256
+ });
257
+ schema.index({
258
+ recipientId: 1,
259
+ status: 1
260
+ });
261
+ schema.index({ publicId: 1 }, {
262
+ unique: true,
263
+ partialFilterExpression: {
264
+ deletedAt: null,
265
+ publicId: { $type: "string" }
266
+ }
267
+ });
268
+ if (config.extraIndexes) for (const idx of config.extraIndexes) schema.index(idx.fields, idx.options);
269
+ return schema;
270
+ }
271
+
272
+ //#endregion
273
+ //#region src/models/inject-tenant.ts
9
274
  /**
10
- * For advanced features, import from submodules:
11
- *
12
- * @example
13
- * ```ts
14
- * // Plugins
15
- * import { loggingPlugin, auditPlugin, createTaxPlugin } from '@classytic/revenue/plugins';
16
- *
17
- * // Enums
18
- * import { TRANSACTION_STATUS, PAYMENT_STATUS } from '@classytic/revenue/enums';
19
- *
20
- * // Events
21
- * import { EventBus, type RevenueEvents } from '@classytic/revenue/events';
275
+ * Inject the tenant field into a schema and (when `enabled`) prepend it
276
+ * to every existing compound index.
22
277
  *
23
- * // Schemas
24
- * import { CreatePaymentSchema, transactionSchema } from '@classytic/revenue/schemas';
278
+ * When `enabled: false` the field is still added (domain verbs reference
279
+ * it in raw queries even without the multi-tenant plugin) — just without
280
+ * `required` and without index prepend.
25
281
  *
26
- * // Utilities
27
- * import { retry, calculateCommission } from '@classytic/revenue/utils';
282
+ * The field storage type follows `scope.fieldType` (`'objectId'` →
283
+ * `Schema.Types.ObjectId` + `ref`, `'string'` `String`). No hardcoding
284
+ * here — callers must pass a `ResolvedTenantConfig` from
285
+ * `@classytic/primitives/tenant` via `resolveTenantConfig(...)`.
286
+ */
287
+ function injectTenantField(schema, scope) {
288
+ schema.add({ [scope.tenantField]: {
289
+ type: scope.fieldType === "objectId" ? mongoose.Schema.Types.ObjectId : String,
290
+ ...scope.required ? { required: true } : {},
291
+ index: true,
292
+ ...scope.fieldType === "objectId" && scope.ref ? { ref: scope.ref } : {}
293
+ } });
294
+ if (!scope.enabled) return;
295
+ const existingIndexes = schema._indexes;
296
+ if (existingIndexes && existingIndexes.length > 0) for (const indexEntry of existingIndexes) {
297
+ const fields = indexEntry[0];
298
+ if (fields[scope.tenantField] !== void 0) continue;
299
+ const newFields = { [scope.tenantField]: 1 };
300
+ for (const [key, val] of Object.entries(fields)) newFields[key] = val;
301
+ indexEntry[0] = newFields;
302
+ }
303
+ }
304
+
305
+ //#endregion
306
+ //#region src/models/create-models.ts
307
+ const REVENUE_MODEL_NAMES = [
308
+ "Transaction",
309
+ "Subscription",
310
+ "Settlement"
311
+ ];
312
+ /**
313
+ * Default physical collection names (see PACKAGE_RULES.md §20.1). Prefixed
314
+ * when `collectionPrefix` is provided; used verbatim when unset.
315
+ */
316
+ const DEFAULT_COLLECTIONS = {
317
+ Transaction: "revenue_transactions",
318
+ Subscription: "revenue_subscriptions",
319
+ Settlement: "revenue_settlements"
320
+ };
321
+ var RevenueModelCollisionError = class extends Error {
322
+ constructor(name) {
323
+ super(`[revenue] Mongoose model "${name}" already exists on this connection. For hot-reload / test fixtures, pass \`forceRecreate: true\` to clobber the existing model. For two revenue engines, use two Mongoose connections (\`mongoose.createConnection(...)\`) — each has its own model registry.`);
324
+ this.name = "RevenueModelCollisionError";
325
+ }
326
+ };
327
+ function createRevenueModels(options) {
328
+ const { connection, scope, schemaOptions = {}, modules = {}, collectionPrefix, forceRecreate } = options;
329
+ const prefix = collectionPrefix ?? "";
330
+ if (forceRecreate) {
331
+ for (const name of REVENUE_MODEL_NAMES) if (connection.models[name]) connection.deleteModel(name);
332
+ } else for (const name of REVENUE_MODEL_NAMES) if (connection.models[name]) throw new RevenueModelCollisionError(name);
333
+ const txnSchema = buildTransactionSchema({
334
+ scoped: scope.enabled,
335
+ extraFields: schemaOptions.transaction?.extraFields,
336
+ extraIndexes: schemaOptions.transaction?.extraIndexes
337
+ });
338
+ injectTenantField(txnSchema, scope);
339
+ txnSchema.index({ "gateway.sessionId": 1 }, { sparse: true });
340
+ txnSchema.index({ "gateway.paymentIntentId": 1 }, { sparse: true });
341
+ txnSchema.index({ idempotencyKey: 1 }, {
342
+ unique: true,
343
+ partialFilterExpression: { idempotencyKey: { $type: "string" } }
344
+ });
345
+ txnSchema.index({ publicId: 1 }, {
346
+ unique: true,
347
+ partialFilterExpression: {
348
+ deletedAt: null,
349
+ publicId: { $type: "string" }
350
+ }
351
+ });
352
+ const models = { Transaction: connection.model("Transaction", txnSchema, prefix + DEFAULT_COLLECTIONS.Transaction) };
353
+ if (modules.subscription !== false) {
354
+ const subSchema = buildSubscriptionSchema({
355
+ scoped: scope.enabled,
356
+ extraFields: schemaOptions.subscription?.extraFields,
357
+ extraIndexes: schemaOptions.subscription?.extraIndexes
358
+ });
359
+ injectTenantField(subSchema, scope);
360
+ models.Subscription = connection.model("Subscription", subSchema, prefix + DEFAULT_COLLECTIONS.Subscription);
361
+ }
362
+ if (modules.settlement) {
363
+ const stlSchema = buildSettlementSchema({
364
+ scoped: scope.enabled,
365
+ extraFields: schemaOptions.settlement?.extraFields,
366
+ extraIndexes: schemaOptions.settlement?.extraIndexes
367
+ });
368
+ injectTenantField(stlSchema, scope);
369
+ models.Settlement = connection.model("Settlement", stlSchema, prefix + DEFAULT_COLLECTIONS.Settlement);
370
+ }
371
+ return models;
372
+ }
373
+
374
+ //#endregion
375
+ //#region src/engine/create-revenue.ts
376
+ /**
377
+ * createRevenue — factory for the revenue engine.
28
378
  *
29
- * // Services (advanced)
30
- * import { MonetizationService } from '@classytic/revenue/services';
379
+ * Accepts an optional arc-compatible `EventTransport`. When the host
380
+ * doesn't pass one, we instantiate `InProcessRevenueBus` — a ~50-line
381
+ * structural match of arc's `MemoryEventTransport` that ships with the
382
+ * package so `createRevenue` always returns a working engine even without
383
+ * arc installed. Hosts that already use arc can pass
384
+ * `new RedisEventTransport(...)` (or any arc transport) straight in.
31
385
  *
32
- * // Reconciliation
33
- * import { reconcileSettlement } from '@classytic/revenue/reconciliation';
34
- * ```
386
+ * Domain verbs publish via `this.deps.events.publish(createEvent(...))` and
387
+ * hosts subscribe via `revenue.events.subscribe('revenue:payment.*', ...)`.
388
+ * See PACKAGE_RULES §13–§14.
35
389
  */
390
+ async function createRevenue(config) {
391
+ const modules = {
392
+ subscription: config.modules?.subscription !== false,
393
+ escrow: config.modules?.escrow ?? false,
394
+ settlement: config.modules?.settlement ?? false
395
+ };
396
+ const scope = resolveTenantConfig(config.scope);
397
+ const events = config.eventTransport ?? new InProcessRevenueBus({ logger: config.logger });
398
+ const models = createRevenueModels({
399
+ connection: config.connection,
400
+ scope,
401
+ schemaOptions: config.schemaOptions,
402
+ modules,
403
+ ...config.collectionPrefix !== void 0 ? { collectionPrefix: config.collectionPrefix } : {},
404
+ ...config.forceRecreate !== void 0 ? { forceRecreate: config.forceRecreate } : {}
405
+ });
406
+ const buildPlugins = (prefix, extraPlugins = []) => {
407
+ const plugins = [customIdPlugin({
408
+ field: "publicId",
409
+ generator: prefixedId({
410
+ prefix,
411
+ separator: "_",
412
+ length: 20
413
+ })
414
+ })];
415
+ if (scope.enabled && scope.strategy === "field") plugins.push(multiTenantPlugin({
416
+ tenantField: scope.tenantField,
417
+ fieldType: scope.fieldType,
418
+ contextKey: scope.contextKey,
419
+ required: scope.required,
420
+ skipWhen: (ctx) => ctx._bypassTenant === true
421
+ }));
422
+ plugins.push(softDeletePlugin({ ttlDays: 365 }));
423
+ plugins.push(...extraPlugins);
424
+ return plugins;
425
+ };
426
+ const repositories = createRevenueRepositories(models, {
427
+ transaction: buildPlugins("txn"),
428
+ subscription: buildPlugins("sub"),
429
+ settlement: buildPlugins("stl")
430
+ }, config.repositoryPlugins);
431
+ const providers = createProviderRegistry(config.providers ?? {}, config.defaultCurrency);
432
+ const commission = typeof config.modules?.commission === "object" ? config.modules.commission : config.commission;
433
+ repositories.transaction.inject({
434
+ events,
435
+ outbox: config.outbox,
436
+ providers,
437
+ bridges: config.bridges ?? {},
438
+ commission,
439
+ defaultCurrency: config.defaultCurrency,
440
+ logger: config.logger
441
+ });
442
+ if (repositories.subscription) repositories.subscription.inject({
443
+ events,
444
+ outbox: config.outbox,
445
+ logger: config.logger
446
+ });
447
+ if (repositories.settlement) repositories.settlement.inject({
448
+ events,
449
+ outbox: config.outbox,
450
+ bridges: config.bridges ?? {},
451
+ logger: config.logger
452
+ });
453
+ if (config.autoIndex !== void 0) for (const [name, model] of Object.entries(models)) {
454
+ if (!model) continue;
455
+ const value = typeof config.autoIndex === "boolean" ? config.autoIndex : config.autoIndex[name] ?? void 0;
456
+ if (value !== void 0) model.schema.set("autoIndex", value);
457
+ }
458
+ return {
459
+ config: Object.freeze({ ...config }),
460
+ models,
461
+ repositories,
462
+ providers,
463
+ events,
464
+ async syncIndexes() {
465
+ await Promise.all(Object.values(models).filter(Boolean).map((m) => m.createIndexes()));
466
+ },
467
+ async destroy() {
468
+ await events.close?.();
469
+ }
470
+ };
471
+ }
36
472
 
37
473
  //#endregion
38
- export { AlreadyVerifiedError, ConfigurationError, ERROR_CODES, HOLD_STATE_MACHINE, InvalidAmountError, InvalidStateTransitionError, MissingRequiredFieldError, ModelNotRegisteredError, Money, NotFoundError, OperationError, PaymentIntent, PaymentIntentCreationError, PaymentProvider, PaymentResult, PaymentVerificationError, ProviderCapabilityError, ProviderError, ProviderNotFoundError, RefundError, RefundNotSupportedError, RefundResult, Result, Revenue, RevenueBuilder, RevenueError, SETTLEMENT_STATE_MACHINE, SPLIT_STATE_MACHINE, SUBSCRIPTION_STATE_MACHINE, StateError, StateMachine, SubscriptionNotActiveError, SubscriptionNotFoundError, TRANSACTION_STATE_MACHINE, TransactionNotFoundError, ValidationError, WebhookEvent, appendAuditEvent, createRevenue, err, filterAuditTrail, fromSmallestUnit, getAuditTrail, getLastStateChange, isErr, isOk, isRetryable, isRevenueError, ok, toSmallestUnit, unwrap, unwrapOr };
474
+ export { AlreadyVerifiedError, CURRENCIES, ConfigurationError, CurrencyMismatchError, HOLD_REASON, HOLD_REASON_VALUES, HOLD_STATE_MACHINE, HOLD_STATUS, HOLD_STATUS_VALUES, InProcessRevenueBus, InvalidOutboxEventError, InvalidStateTransitionError, LIBRARY_CATEGORIES, LIBRARY_CATEGORY_VALUES, MINOR_UNIT_FACTOR, MONETIZATION_TYPES, MONETIZATION_TYPE_VALUES, OutboxOwnershipError, PAYMENT_GATEWAY_TYPE, PAYMENT_GATEWAY_TYPE_VALUES, PAYMENT_STATUS, PAYMENT_STATUS_VALUES, PAYOUT_METHOD, PAYOUT_METHOD_VALUES, PLAN_KEYS, PLAN_KEY_VALUES, PaymentIntent, PaymentIntentCreationError, PaymentProvider, PaymentResult, PaymentVerificationError, PluginManager, ProviderCapabilityError, ProviderNotFoundError, ProviderRegistry, RELEASE_REASON, RELEASE_REASON_VALUES, REVENUE_EVENTS, RefundNotSupportedError, RefundResult, RevenueError, SETTLEMENT_STATE_MACHINE, SETTLEMENT_STATUS, SETTLEMENT_STATUS_VALUES, SETTLEMENT_TYPE, SETTLEMENT_TYPE_VALUES, SPLIT_STATE_MACHINE, SPLIT_STATUS, SPLIT_STATUS_VALUES, SPLIT_TYPE, SPLIT_TYPE_VALUES, SUBSCRIPTION_STATE_MACHINE, SUBSCRIPTION_STATUS, SUBSCRIPTION_STATUS_VALUES, SettlementNotFoundError, SettlementRepository, StateMachine, SubscriptionNotFoundError, SubscriptionRepository, TRANSACTION_FLOW, TRANSACTION_FLOW_VALUES, TRANSACTION_STATE_MACHINE, TRANSACTION_STATUS, TRANSACTION_STATUS_VALUES, TransactionNotFoundError, TransactionRepository, ValidationError, WebhookEvent, absMoney, addMoney, appendAuditEvent, calculateCommission, calculateOrganizationPayout, calculateSplits, calculateTax, compareMoney, createEvent, createProviderRegistry, createRevenue, equalsMoney, err, escrowHoldSchema, escrowReleaseSchema, fromMajor, fromSmallestUnit, getAuditTrail, getLastStateChange, getTaxType, isCurrencyCode, isErr, isHoldReason, isHoldStatus, isLibraryCategory, isMonetizationType, isMoney, isNegativeMoney, isOk, isPaymentGatewayType, isPaymentStatus, isPayoutMethod, isPlanKey, isPositiveMoney, isReleaseReason, isSettlementStatus, isSettlementType, isSplitStatus, isSplitType, isSubscriptionStatus, isTransactionFlow, isTransactionStatus, isZeroMoney, minorUnitFactor, money, multiplyMoney, negateMoney, ok, paymentIntentSchema, paymentVerifySchema, refundSchema, revenueEventDefinitions, reverseCommission, reverseTax, settlementBaseSchema, settlementCreateSchema, settlementListFilterSchema, settlementUpdateSchema, splitRuleSchema, subscriptionBaseSchema, subscriptionCreateSchema, subscriptionListFilterSchema, subscriptionUpdateSchema, subtractMoney, sumMoney, toCurrencyCode, toMajor, toSmallestUnit, transactionBaseSchema, transactionCreateSchema, transactionListFilterSchema, transactionUpdateSchema, validateTaxCalculation };