@classytic/revenue 2.0.1 → 2.1.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.
- package/dist/bank-feed-DJtLvz_7.mjs +133 -0
- package/dist/bank-feed.enums-BadqNJTC.d.mts +118 -0
- package/dist/bank-feed.enums-kYTLTTbe.mjs +165 -0
- package/dist/bridges/index.d.mts +1 -1
- package/dist/core/state-machines.d.mts +25 -2
- package/dist/core/state-machines.mjs +43 -3
- package/dist/{engine-types-CcjIb4Fy.d.mts → engine-types-txFXOiQS.d.mts} +451 -14
- package/dist/enums/index.d.mts +4 -3
- package/dist/enums/index.mjs +4 -3
- package/dist/{errors-DHa8JVQ-.mjs → errors-Dt46UZL_.mjs} +23 -1
- package/dist/{escrow.schema-D5X32LwX.d.mts → escrow.schema-9yh4Q-aQ.d.mts} +23 -23
- package/dist/{event-constants-CEMitnIV.mjs → event-constants-CTiDNWzc.mjs} +6 -0
- package/dist/events/index.d.mts +2 -2
- package/dist/events/index.mjs +3 -3
- package/dist/index.d.mts +21 -11
- package/dist/index.mjs +120 -19
- package/dist/providers/index.d.mts +2 -2
- package/dist/providers/index.mjs +2 -2
- package/dist/registry-h8sasoLh.d.mts +145 -0
- package/dist/repositories/create-repositories.d.mts +1 -1
- package/dist/repositories/create-repositories.mjs +1 -1
- package/dist/{revenue-bridges-sdlrR85c.d.mts → revenue-bridges-BtkWFsJu.d.mts} +107 -1
- package/dist/{revenue-event-catalog-LqxPnsU_.mjs → revenue-event-catalog-CgZ57M-f.mjs} +77 -3
- package/dist/{revenue-event-catalog-BX3g7RUi.d.mts → revenue-event-catalog-JpJcyK1E.d.mts} +198 -2
- package/dist/{settlement.repository-DHIPx5S4.mjs → settlement.repository-Ba2U17zY.mjs} +559 -17
- package/dist/shared/index.d.mts +1 -1
- package/dist/shared/index.mjs +2 -2
- package/dist/{subscription.enums-tfoAgsTv.mjs → subscription.enums-DoIr56O6.mjs} +1 -40
- package/dist/{transaction.enums-u4MshXcL.d.mts → subscription.enums-k24kLpF7.d.mts} +1 -36
- package/dist/validators/index.d.mts +158 -2
- package/dist/validators/index.mjs +95 -2
- package/package.json +7 -7
- package/dist/registry-DhFMsSn5.mjs +0 -150
- package/dist/registry-SvIGPAx_.d.mts +0 -143
- /package/dist/{audit-B39B0Sdq.mjs → audit-Ba2XB2C4.mjs} +0 -0
- /package/dist/{audit-DZ0eTr9g.d.mts → audit-DRKuLBFO.d.mts} +0 -0
- /package/dist/{context-DRqSeTPM.d.mts → context-pjP1QeE3.d.mts} +0 -0
- /package/dist/{escrow.schema-BBv9oVEW.mjs → escrow.schema-C-b41z_G.mjs} +0 -0
- /package/dist/{monetization.enums-BtiU3t8o.mjs → monetization.enums-B9HBOecd.mjs} +0 -0
- /package/dist/{monetization.enums-D2xbxXJM.d.mts → monetization.enums-DzAI4sT7.d.mts} +0 -0
- /package/dist/{splits-BAfY-a9P.mjs → splits-D8XkNWgX.mjs} +0 -0
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { l as ProviderNotFoundError } from "./errors-Dt46UZL_.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/providers/base.ts
|
|
4
|
+
/**
|
|
5
|
+
* Abstract `PaymentProvider` — the contract revenue's repositories
|
|
6
|
+
* consume. Provider implementations may extend this for the default
|
|
7
|
+
* config plumbing, or just satisfy the structural shape.
|
|
8
|
+
*/
|
|
9
|
+
var PaymentProvider = class {
|
|
10
|
+
config;
|
|
11
|
+
name;
|
|
12
|
+
_defaultCurrency = "USD";
|
|
13
|
+
constructor(config = {}) {
|
|
14
|
+
this.config = config;
|
|
15
|
+
this.name = "base";
|
|
16
|
+
if (config.defaultCurrency && typeof config.defaultCurrency === "string") this._defaultCurrency = config.defaultCurrency;
|
|
17
|
+
}
|
|
18
|
+
get defaultCurrency() {
|
|
19
|
+
return this._defaultCurrency;
|
|
20
|
+
}
|
|
21
|
+
setDefaultCurrency(currency) {
|
|
22
|
+
this._defaultCurrency = currency;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Default: accept all signatures (manual / dev provider). Real
|
|
26
|
+
* gateways MUST override with HMAC / timing-safe verification.
|
|
27
|
+
*/
|
|
28
|
+
verifyWebhookSignature(_payload, _signature) {
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
getCapabilities() {
|
|
32
|
+
return {
|
|
33
|
+
supportsWebhooks: false,
|
|
34
|
+
supportsRefunds: false,
|
|
35
|
+
supportsPartialRefunds: false,
|
|
36
|
+
requiresManualVerification: true
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
//#endregion
|
|
42
|
+
//#region src/providers/registry.ts
|
|
43
|
+
var ProviderRegistry = class {
|
|
44
|
+
providers = /* @__PURE__ */ new Map();
|
|
45
|
+
register(name, provider) {
|
|
46
|
+
this.providers.set(name, provider);
|
|
47
|
+
}
|
|
48
|
+
get(name) {
|
|
49
|
+
const provider = this.providers.get(name);
|
|
50
|
+
if (!provider) throw new ProviderNotFoundError(name);
|
|
51
|
+
return provider;
|
|
52
|
+
}
|
|
53
|
+
has(name) {
|
|
54
|
+
return this.providers.has(name);
|
|
55
|
+
}
|
|
56
|
+
list() {
|
|
57
|
+
return Array.from(this.providers.keys());
|
|
58
|
+
}
|
|
59
|
+
setDefaultCurrency(currency) {
|
|
60
|
+
for (const provider of this.providers.values()) provider.setDefaultCurrency(currency);
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
function createProviderRegistry(providers = {}, defaultCurrency) {
|
|
64
|
+
const registry = new ProviderRegistry();
|
|
65
|
+
for (const [name, provider] of Object.entries(providers)) {
|
|
66
|
+
if (defaultCurrency) provider.setDefaultCurrency(defaultCurrency);
|
|
67
|
+
registry.register(name, provider);
|
|
68
|
+
}
|
|
69
|
+
return registry;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
//#endregion
|
|
73
|
+
//#region src/providers/bank-feed.ts
|
|
74
|
+
/**
|
|
75
|
+
* Bank-feed provider — implement one method or both depending on the
|
|
76
|
+
* upstream's capabilities. Mirrors the optional-method pattern that
|
|
77
|
+
* works well across PaymentProvider's gateway plurality.
|
|
78
|
+
*/
|
|
79
|
+
var BankFeedProvider = class {
|
|
80
|
+
config;
|
|
81
|
+
name;
|
|
82
|
+
constructor(name, config = {}) {
|
|
83
|
+
this.name = name;
|
|
84
|
+
this.config = config;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Async drain — yields one batch per call until the upstream is
|
|
88
|
+
* caught up. Default implementation pulls `fetchTransactions` in a
|
|
89
|
+
* loop; providers can override for more efficient pagination
|
|
90
|
+
* (e.g. SSE / long-poll) or to interleave `removed[]` correctly.
|
|
91
|
+
*/
|
|
92
|
+
async *drain(params = {}) {
|
|
93
|
+
if (!this.fetchTransactions) throw new Error(`Provider ${this.name} does not support fetchTransactions()`);
|
|
94
|
+
let cursor = params.cursor;
|
|
95
|
+
const MAX_PAGES = 1e4;
|
|
96
|
+
for (let i = 0; i < MAX_PAGES; i++) {
|
|
97
|
+
const result = await this.fetchTransactions({
|
|
98
|
+
...params,
|
|
99
|
+
cursor
|
|
100
|
+
});
|
|
101
|
+
yield result;
|
|
102
|
+
const tooLittle = result.transactions.length === 0 && (result.removed?.length ?? 0) === 0;
|
|
103
|
+
if (result.hasMore === false || tooLittle) return;
|
|
104
|
+
if (!result.nextCursor || result.nextCursor === cursor) return;
|
|
105
|
+
cursor = result.nextCursor;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
var BankFeedProviderRegistry = class {
|
|
110
|
+
providers = /* @__PURE__ */ new Map();
|
|
111
|
+
register(name, provider) {
|
|
112
|
+
this.providers.set(name, provider);
|
|
113
|
+
}
|
|
114
|
+
get(name) {
|
|
115
|
+
const provider = this.providers.get(name);
|
|
116
|
+
if (!provider) throw new ProviderNotFoundError(name);
|
|
117
|
+
return provider;
|
|
118
|
+
}
|
|
119
|
+
has(name) {
|
|
120
|
+
return this.providers.has(name);
|
|
121
|
+
}
|
|
122
|
+
list() {
|
|
123
|
+
return Array.from(this.providers.keys());
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
function createBankFeedProviderRegistry(providers = {}) {
|
|
127
|
+
const registry = new BankFeedProviderRegistry();
|
|
128
|
+
for (const [name, provider] of Object.entries(providers)) registry.register(name, provider);
|
|
129
|
+
return registry;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
//#endregion
|
|
133
|
+
export { createProviderRegistry as a, ProviderRegistry as i, BankFeedProviderRegistry as n, PaymentProvider as o, createBankFeedProviderRegistry as r, BankFeedProvider as t };
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
//#region src/enums/transaction.enums.d.ts
|
|
2
|
+
declare const TRANSACTION_FLOW: {
|
|
3
|
+
readonly INFLOW: "inflow";
|
|
4
|
+
readonly OUTFLOW: "outflow";
|
|
5
|
+
};
|
|
6
|
+
type TransactionFlow = typeof TRANSACTION_FLOW;
|
|
7
|
+
type TransactionFlowValue = TransactionFlow[keyof TransactionFlow];
|
|
8
|
+
declare const TRANSACTION_FLOW_VALUES: TransactionFlowValue[];
|
|
9
|
+
declare const TRANSACTION_STATUS: {
|
|
10
|
+
readonly PENDING: "pending";
|
|
11
|
+
readonly PAYMENT_INITIATED: "payment_initiated";
|
|
12
|
+
readonly PROCESSING: "processing";
|
|
13
|
+
readonly REQUIRES_ACTION: "requires_action";
|
|
14
|
+
readonly VERIFIED: "verified";
|
|
15
|
+
readonly COMPLETED: "completed";
|
|
16
|
+
readonly FAILED: "failed";
|
|
17
|
+
readonly CANCELLED: "cancelled";
|
|
18
|
+
readonly EXPIRED: "expired";
|
|
19
|
+
readonly REFUNDED: "refunded";
|
|
20
|
+
readonly PARTIALLY_REFUNDED: "partially_refunded";
|
|
21
|
+
readonly IMPORTED: "imported";
|
|
22
|
+
readonly MATCHED: "matched";
|
|
23
|
+
readonly JOURNALIZED: "journalized";
|
|
24
|
+
readonly REJECTED: "rejected";
|
|
25
|
+
};
|
|
26
|
+
type TransactionStatus = typeof TRANSACTION_STATUS;
|
|
27
|
+
type TransactionStatusValue = TransactionStatus[keyof TransactionStatus];
|
|
28
|
+
declare const TRANSACTION_STATUS_VALUES: TransactionStatusValue[];
|
|
29
|
+
declare const LIBRARY_CATEGORIES: {
|
|
30
|
+
readonly SUBSCRIPTION: "subscription";
|
|
31
|
+
readonly PURCHASE: "purchase";
|
|
32
|
+
};
|
|
33
|
+
type LibraryCategories = typeof LIBRARY_CATEGORIES;
|
|
34
|
+
type LibraryCategoryValue = LibraryCategories[keyof LibraryCategories];
|
|
35
|
+
declare const LIBRARY_CATEGORY_VALUES: LibraryCategoryValue[];
|
|
36
|
+
declare function isLibraryCategory(value: unknown): value is LibraryCategoryValue;
|
|
37
|
+
declare function isTransactionFlow(value: unknown): value is TransactionFlowValue;
|
|
38
|
+
declare function isTransactionStatus(value: unknown): value is TransactionStatusValue;
|
|
39
|
+
//#endregion
|
|
40
|
+
//#region src/enums/bank-feed.enums.d.ts
|
|
41
|
+
declare const TRANSACTION_KIND: {
|
|
42
|
+
/**
|
|
43
|
+
* Payment-gateway flow — the original revenue lifecycle. Stripe / SSL /
|
|
44
|
+
* Bkash / manual all share this graph.
|
|
45
|
+
* pending → payment_initiated → processing → requires_action → verified
|
|
46
|
+
* → completed → refunded | partially_refunded
|
|
47
|
+
*/
|
|
48
|
+
readonly PAYMENT_FLOW: "payment_flow";
|
|
49
|
+
/**
|
|
50
|
+
* Bank / accounting feed — OFX upload, Plaid sync, QBO/Xero CDC.
|
|
51
|
+
* imported → matched → journalized (happy path)
|
|
52
|
+
* imported → rejected (operator skip)
|
|
53
|
+
* matched → imported (un-match)
|
|
54
|
+
*/
|
|
55
|
+
readonly BANK_FEED: "bank_feed";
|
|
56
|
+
/**
|
|
57
|
+
* Hand-keyed entry — treasurer logs a cash deposit, owner injects
|
|
58
|
+
* capital. Cleaner two-step lifecycle than payment_flow.
|
|
59
|
+
* pending → matched → journalized | rejected
|
|
60
|
+
*/
|
|
61
|
+
readonly MANUAL: "manual";
|
|
62
|
+
};
|
|
63
|
+
type TransactionKind = typeof TRANSACTION_KIND;
|
|
64
|
+
type TransactionKindValue = TransactionKind[keyof TransactionKind];
|
|
65
|
+
declare const TRANSACTION_KIND_VALUES: TransactionKindValue[];
|
|
66
|
+
declare function isTransactionKind(value: unknown): value is TransactionKindValue;
|
|
67
|
+
declare const BANK_FEED_STATUS: {
|
|
68
|
+
readonly IMPORTED: "imported";
|
|
69
|
+
readonly MATCHED: "matched";
|
|
70
|
+
readonly JOURNALIZED: "journalized";
|
|
71
|
+
readonly REJECTED: "rejected";
|
|
72
|
+
};
|
|
73
|
+
type BankFeedStatusValue = (typeof BANK_FEED_STATUS)[keyof typeof BANK_FEED_STATUS];
|
|
74
|
+
declare const BANK_FEED_STATUS_VALUES: BankFeedStatusValue[];
|
|
75
|
+
declare function isBankFeedStatus(value: unknown): value is BankFeedStatusValue;
|
|
76
|
+
declare const BANK_FEED_SOURCE: {
|
|
77
|
+
readonly OFX: "ofx";
|
|
78
|
+
readonly CAMT053: "camt.053";
|
|
79
|
+
readonly MT940: "mt940";
|
|
80
|
+
readonly CSV: "csv";
|
|
81
|
+
readonly IIF: "iif";
|
|
82
|
+
readonly QBO: "qbo";
|
|
83
|
+
readonly XERO: "xero";
|
|
84
|
+
readonly PLAID: "plaid";
|
|
85
|
+
readonly MANUAL: "manual";
|
|
86
|
+
};
|
|
87
|
+
type BankFeedSourceValue = (typeof BANK_FEED_SOURCE)[keyof typeof BANK_FEED_SOURCE];
|
|
88
|
+
declare const BANK_FEED_SOURCE_VALUES: BankFeedSourceValue[];
|
|
89
|
+
declare function isBankFeedSource(value: unknown): value is BankFeedSourceValue;
|
|
90
|
+
/**
|
|
91
|
+
* Initial status for a freshly created row of a given kind. Centralized so
|
|
92
|
+
* the schema, repo verbs, and validators agree.
|
|
93
|
+
*
|
|
94
|
+
* - `payment_flow` → `pending` — provider may flip to verified instantly
|
|
95
|
+
* for zero-amount rows (see `createPaymentIntent`).
|
|
96
|
+
* - `bank_feed` → `imported` — bulk upsert from a feed/upload.
|
|
97
|
+
* - `manual` → `pending` — treasurer reviews then `match()`es.
|
|
98
|
+
*/
|
|
99
|
+
declare function initialStatusFor(kind: TransactionKindValue): TransactionStatusValue;
|
|
100
|
+
/**
|
|
101
|
+
* True iff `status` is a legal value for a transaction of the given
|
|
102
|
+
* `kind`. Use at API boundaries (admin status filters, list-page query
|
|
103
|
+
* params, JSON imports) to reject `?kind=payment_flow&status=imported`
|
|
104
|
+
* before it reaches the repository.
|
|
105
|
+
*
|
|
106
|
+
* @example
|
|
107
|
+
* if (!isStatusValidForKind(req.query.status, req.query.kind)) {
|
|
108
|
+
* throw new ValidationError('status invalid for kind');
|
|
109
|
+
* }
|
|
110
|
+
*/
|
|
111
|
+
declare function isStatusValidForKind(status: unknown, kind: TransactionKindValue): boolean;
|
|
112
|
+
/**
|
|
113
|
+
* The set of status values legal for a given kind. Useful for building
|
|
114
|
+
* dropdown options or `$in` filters at the API layer.
|
|
115
|
+
*/
|
|
116
|
+
declare function statusesForKind(kind: TransactionKindValue): readonly string[];
|
|
117
|
+
//#endregion
|
|
118
|
+
export { isTransactionFlow as A, TRANSACTION_STATUS as C, TransactionStatus as D, TransactionFlowValue as E, TransactionStatusValue as O, TRANSACTION_FLOW_VALUES as S, TransactionFlow as T, LIBRARY_CATEGORIES as _, BankFeedSourceValue as a, LibraryCategoryValue as b, TRANSACTION_KIND_VALUES as c, initialStatusFor as d, isBankFeedSource as f, statusesForKind as g, isTransactionKind as h, BANK_FEED_STATUS_VALUES as i, isTransactionStatus as j, isLibraryCategory as k, TransactionKind as l, isStatusValidForKind as m, BANK_FEED_SOURCE_VALUES as n, BankFeedStatusValue as o, isBankFeedStatus as p, BANK_FEED_STATUS as r, TRANSACTION_KIND as s, BANK_FEED_SOURCE as t, TransactionKindValue as u, LIBRARY_CATEGORY_VALUES as v, TRANSACTION_STATUS_VALUES as w, TRANSACTION_FLOW as x, LibraryCategories as y };
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
//#region src/enums/transaction.enums.ts
|
|
2
|
+
const TRANSACTION_FLOW = {
|
|
3
|
+
INFLOW: "inflow",
|
|
4
|
+
OUTFLOW: "outflow"
|
|
5
|
+
};
|
|
6
|
+
const TRANSACTION_FLOW_VALUES = Object.values(TRANSACTION_FLOW);
|
|
7
|
+
const TRANSACTION_STATUS = {
|
|
8
|
+
PENDING: "pending",
|
|
9
|
+
PAYMENT_INITIATED: "payment_initiated",
|
|
10
|
+
PROCESSING: "processing",
|
|
11
|
+
REQUIRES_ACTION: "requires_action",
|
|
12
|
+
VERIFIED: "verified",
|
|
13
|
+
COMPLETED: "completed",
|
|
14
|
+
FAILED: "failed",
|
|
15
|
+
CANCELLED: "cancelled",
|
|
16
|
+
EXPIRED: "expired",
|
|
17
|
+
REFUNDED: "refunded",
|
|
18
|
+
PARTIALLY_REFUNDED: "partially_refunded",
|
|
19
|
+
IMPORTED: "imported",
|
|
20
|
+
MATCHED: "matched",
|
|
21
|
+
JOURNALIZED: "journalized",
|
|
22
|
+
REJECTED: "rejected"
|
|
23
|
+
};
|
|
24
|
+
const TRANSACTION_STATUS_VALUES = Object.values(TRANSACTION_STATUS);
|
|
25
|
+
const LIBRARY_CATEGORIES = {
|
|
26
|
+
SUBSCRIPTION: "subscription",
|
|
27
|
+
PURCHASE: "purchase"
|
|
28
|
+
};
|
|
29
|
+
const LIBRARY_CATEGORY_VALUES = Object.values(LIBRARY_CATEGORIES);
|
|
30
|
+
const transactionFlowSet = new Set(TRANSACTION_FLOW_VALUES);
|
|
31
|
+
const transactionStatusSet = new Set(TRANSACTION_STATUS_VALUES);
|
|
32
|
+
const libraryCategorySet = new Set(LIBRARY_CATEGORY_VALUES);
|
|
33
|
+
function isLibraryCategory(value) {
|
|
34
|
+
return typeof value === "string" && libraryCategorySet.has(value);
|
|
35
|
+
}
|
|
36
|
+
function isTransactionFlow(value) {
|
|
37
|
+
return typeof value === "string" && transactionFlowSet.has(value);
|
|
38
|
+
}
|
|
39
|
+
function isTransactionStatus(value) {
|
|
40
|
+
return typeof value === "string" && transactionStatusSet.has(value);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
//#endregion
|
|
44
|
+
//#region src/enums/bank-feed.enums.ts
|
|
45
|
+
/**
|
|
46
|
+
* Bank-feed lifecycle enums.
|
|
47
|
+
*
|
|
48
|
+
* Revenue 3.0 generalizes the Transaction model from "payment-gateway-only"
|
|
49
|
+
* to a unified cashflow ledger. The `kind` discriminator selects which
|
|
50
|
+
* state machine governs the row (see `core/state-machines.ts`); these
|
|
51
|
+
* enums own the bank-feed and manual lifecycles plus the canonical
|
|
52
|
+
* `TransactionKind` literals every consumer should branch on.
|
|
53
|
+
*
|
|
54
|
+
* Why a discriminator instead of a separate model — same collection wins
|
|
55
|
+
* the unified-audit-ledger query ("everything that touched cash this
|
|
56
|
+
* quarter"), keeps soft-delete + retention policies single-sourced, and
|
|
57
|
+
* lets `relatedTransactionId` cross-link a Stripe charge to its Plaid
|
|
58
|
+
* deposit without a polymorphic ref. See PACKAGE_RULES §30 / §35.
|
|
59
|
+
*/
|
|
60
|
+
const TRANSACTION_KIND = {
|
|
61
|
+
PAYMENT_FLOW: "payment_flow",
|
|
62
|
+
BANK_FEED: "bank_feed",
|
|
63
|
+
MANUAL: "manual"
|
|
64
|
+
};
|
|
65
|
+
const TRANSACTION_KIND_VALUES = Object.values(TRANSACTION_KIND);
|
|
66
|
+
const transactionKindSet = new Set(TRANSACTION_KIND_VALUES);
|
|
67
|
+
function isTransactionKind(value) {
|
|
68
|
+
return typeof value === "string" && transactionKindSet.has(value);
|
|
69
|
+
}
|
|
70
|
+
const BANK_FEED_STATUS = {
|
|
71
|
+
IMPORTED: "imported",
|
|
72
|
+
MATCHED: "matched",
|
|
73
|
+
JOURNALIZED: "journalized",
|
|
74
|
+
REJECTED: "rejected"
|
|
75
|
+
};
|
|
76
|
+
const BANK_FEED_STATUS_VALUES = Object.values(BANK_FEED_STATUS);
|
|
77
|
+
const bankFeedStatusSet = new Set(BANK_FEED_STATUS_VALUES);
|
|
78
|
+
function isBankFeedStatus(value) {
|
|
79
|
+
return typeof value === "string" && bankFeedStatusSet.has(value);
|
|
80
|
+
}
|
|
81
|
+
const BANK_FEED_SOURCE = {
|
|
82
|
+
OFX: "ofx",
|
|
83
|
+
CAMT053: "camt.053",
|
|
84
|
+
MT940: "mt940",
|
|
85
|
+
CSV: "csv",
|
|
86
|
+
IIF: "iif",
|
|
87
|
+
QBO: "qbo",
|
|
88
|
+
XERO: "xero",
|
|
89
|
+
PLAID: "plaid",
|
|
90
|
+
MANUAL: "manual"
|
|
91
|
+
};
|
|
92
|
+
const BANK_FEED_SOURCE_VALUES = Object.values(BANK_FEED_SOURCE);
|
|
93
|
+
const bankFeedSourceSet = new Set(BANK_FEED_SOURCE_VALUES);
|
|
94
|
+
function isBankFeedSource(value) {
|
|
95
|
+
return typeof value === "string" && bankFeedSourceSet.has(value);
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Initial status for a freshly created row of a given kind. Centralized so
|
|
99
|
+
* the schema, repo verbs, and validators agree.
|
|
100
|
+
*
|
|
101
|
+
* - `payment_flow` → `pending` — provider may flip to verified instantly
|
|
102
|
+
* for zero-amount rows (see `createPaymentIntent`).
|
|
103
|
+
* - `bank_feed` → `imported` — bulk upsert from a feed/upload.
|
|
104
|
+
* - `manual` → `pending` — treasurer reviews then `match()`es.
|
|
105
|
+
*/
|
|
106
|
+
function initialStatusFor(kind) {
|
|
107
|
+
switch (kind) {
|
|
108
|
+
case TRANSACTION_KIND.BANK_FEED: return BANK_FEED_STATUS.IMPORTED;
|
|
109
|
+
case TRANSACTION_KIND.MANUAL: return TRANSACTION_STATUS.PENDING;
|
|
110
|
+
case TRANSACTION_KIND.PAYMENT_FLOW:
|
|
111
|
+
default: return TRANSACTION_STATUS.PENDING;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
const STATUSES_BY_KIND = {
|
|
115
|
+
[TRANSACTION_KIND.PAYMENT_FLOW]: new Set([
|
|
116
|
+
TRANSACTION_STATUS.PENDING,
|
|
117
|
+
TRANSACTION_STATUS.PAYMENT_INITIATED,
|
|
118
|
+
TRANSACTION_STATUS.PROCESSING,
|
|
119
|
+
TRANSACTION_STATUS.REQUIRES_ACTION,
|
|
120
|
+
TRANSACTION_STATUS.VERIFIED,
|
|
121
|
+
TRANSACTION_STATUS.COMPLETED,
|
|
122
|
+
TRANSACTION_STATUS.FAILED,
|
|
123
|
+
TRANSACTION_STATUS.CANCELLED,
|
|
124
|
+
TRANSACTION_STATUS.EXPIRED,
|
|
125
|
+
TRANSACTION_STATUS.REFUNDED,
|
|
126
|
+
TRANSACTION_STATUS.PARTIALLY_REFUNDED
|
|
127
|
+
]),
|
|
128
|
+
[TRANSACTION_KIND.BANK_FEED]: new Set([
|
|
129
|
+
TRANSACTION_STATUS.IMPORTED,
|
|
130
|
+
TRANSACTION_STATUS.MATCHED,
|
|
131
|
+
TRANSACTION_STATUS.JOURNALIZED,
|
|
132
|
+
TRANSACTION_STATUS.REJECTED
|
|
133
|
+
]),
|
|
134
|
+
[TRANSACTION_KIND.MANUAL]: new Set([
|
|
135
|
+
TRANSACTION_STATUS.PENDING,
|
|
136
|
+
TRANSACTION_STATUS.MATCHED,
|
|
137
|
+
TRANSACTION_STATUS.JOURNALIZED,
|
|
138
|
+
TRANSACTION_STATUS.REJECTED
|
|
139
|
+
])
|
|
140
|
+
};
|
|
141
|
+
/**
|
|
142
|
+
* True iff `status` is a legal value for a transaction of the given
|
|
143
|
+
* `kind`. Use at API boundaries (admin status filters, list-page query
|
|
144
|
+
* params, JSON imports) to reject `?kind=payment_flow&status=imported`
|
|
145
|
+
* before it reaches the repository.
|
|
146
|
+
*
|
|
147
|
+
* @example
|
|
148
|
+
* if (!isStatusValidForKind(req.query.status, req.query.kind)) {
|
|
149
|
+
* throw new ValidationError('status invalid for kind');
|
|
150
|
+
* }
|
|
151
|
+
*/
|
|
152
|
+
function isStatusValidForKind(status, kind) {
|
|
153
|
+
if (typeof status !== "string") return false;
|
|
154
|
+
return STATUSES_BY_KIND[kind].has(status);
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* The set of status values legal for a given kind. Useful for building
|
|
158
|
+
* dropdown options or `$in` filters at the API layer.
|
|
159
|
+
*/
|
|
160
|
+
function statusesForKind(kind) {
|
|
161
|
+
return [...STATUSES_BY_KIND[kind]];
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
//#endregion
|
|
165
|
+
export { TRANSACTION_STATUS as _, TRANSACTION_KIND as a, isTransactionFlow as b, isBankFeedSource as c, isTransactionKind as d, statusesForKind as f, TRANSACTION_FLOW_VALUES as g, TRANSACTION_FLOW as h, BANK_FEED_STATUS_VALUES as i, isBankFeedStatus as l, LIBRARY_CATEGORY_VALUES as m, BANK_FEED_SOURCE_VALUES as n, TRANSACTION_KIND_VALUES as o, LIBRARY_CATEGORIES as p, BANK_FEED_STATUS as r, initialStatusFor as s, BANK_FEED_SOURCE as t, isStatusValidForKind as u, TRANSACTION_STATUS_VALUES as v, isTransactionStatus as x, isLibraryCategory as y };
|
package/dist/bridges/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as CurrencyBridge, c as LedgerBridge, i as CustomerBridge, n as SourceBridge, o as NotificationBridge, r as AnalyticsBridge, s as TaxBridge, t as RevenueBridges } from "../revenue-bridges-
|
|
1
|
+
import { a as CurrencyBridge, c as LedgerBridge, i as CustomerBridge, n as SourceBridge, o as NotificationBridge, r as AnalyticsBridge, s as TaxBridge, t as RevenueBridges } from "../revenue-bridges-BtkWFsJu.mjs";
|
|
2
2
|
export { type AnalyticsBridge, type CurrencyBridge, type CustomerBridge, type LedgerBridge, type NotificationBridge, type RevenueBridges, type SourceBridge, type TaxBridge };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { U as HoldStatusValue, b as SplitStatusValue, c as SubscriptionStatusValue, j as SettlementStatusValue } from "../subscription.enums-k24kLpF7.mjs";
|
|
2
|
+
import { O as TransactionStatusValue, u as TransactionKindValue } from "../bank-feed.enums-BadqNJTC.mjs";
|
|
2
3
|
|
|
3
4
|
//#region src/core/state-machines.d.ts
|
|
4
5
|
/**
|
|
@@ -49,5 +50,27 @@ declare const SUBSCRIPTION_STATE_MACHINE: StateMachine<SubscriptionStatusValue>;
|
|
|
49
50
|
declare const SETTLEMENT_STATE_MACHINE: StateMachine<SettlementStatusValue>;
|
|
50
51
|
declare const HOLD_STATE_MACHINE: StateMachine<HoldStatusValue>;
|
|
51
52
|
declare const SPLIT_STATE_MACHINE: StateMachine<SplitStatusValue>;
|
|
53
|
+
declare const PAYMENT_FLOW_STATE_MACHINE: StateMachine<TransactionStatusValue>;
|
|
54
|
+
declare const BANK_FEED_STATE_MACHINE: StateMachine<TransactionStatusValue>;
|
|
55
|
+
declare const MANUAL_STATE_MACHINE: StateMachine<TransactionStatusValue>;
|
|
56
|
+
/**
|
|
57
|
+
* Select the state machine that governs a transaction row, given its
|
|
58
|
+
* `kind`. Repo verbs call this at the start of every state transition
|
|
59
|
+
* so the same `from → to` rules apply on both the in-memory check
|
|
60
|
+
* (state machine) and the atomic CAS (mongokit `claim()` with the
|
|
61
|
+
* `where: { kind }` predicate).
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```ts
|
|
65
|
+
* const machine = smFor(transaction.kind);
|
|
66
|
+
* machine.validate(transaction.status, 'matched', String(transaction._id));
|
|
67
|
+
* await this.claim(id, {
|
|
68
|
+
* from: ['imported', 'matched'],
|
|
69
|
+
* to: 'matched',
|
|
70
|
+
* where: { kind: transaction.kind },
|
|
71
|
+
* }, patch, opts);
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
declare function smFor(kind: TransactionKindValue): StateMachine<TransactionStatusValue>;
|
|
52
75
|
//#endregion
|
|
53
|
-
export { HOLD_STATE_MACHINE, SETTLEMENT_STATE_MACHINE, SPLIT_STATE_MACHINE, SUBSCRIPTION_STATE_MACHINE, StateChangeEvent, StateMachine, TRANSACTION_STATE_MACHINE };
|
|
76
|
+
export { BANK_FEED_STATE_MACHINE, HOLD_STATE_MACHINE, MANUAL_STATE_MACHINE, PAYMENT_FLOW_STATE_MACHINE, SETTLEMENT_STATE_MACHINE, SPLIT_STATE_MACHINE, SUBSCRIPTION_STATE_MACHINE, StateChangeEvent, StateMachine, TRANSACTION_STATE_MACHINE, smFor };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { r as
|
|
1
|
+
import { _ as TRANSACTION_STATUS, a as TRANSACTION_KIND } from "../bank-feed.enums-kYTLTTbe.mjs";
|
|
2
|
+
import { g as SETTLEMENT_STATUS, l as SPLIT_STATUS, r as SUBSCRIPTION_STATUS, w as HOLD_STATUS } from "../subscription.enums-DoIr56O6.mjs";
|
|
3
|
+
import { a as InvalidStateTransitionError } from "../errors-Dt46UZL_.mjs";
|
|
3
4
|
import { defineStateMachine } from "@classytic/primitives/state-machine";
|
|
4
5
|
|
|
5
6
|
//#region src/core/state-machines.ts
|
|
@@ -148,6 +149,45 @@ const SPLIT_STATE_MACHINE = new StateMachine(new Map([
|
|
|
148
149
|
[SPLIT_STATUS.WAIVED, /* @__PURE__ */ new Set([])],
|
|
149
150
|
[SPLIT_STATUS.CANCELLED, /* @__PURE__ */ new Set([])]
|
|
150
151
|
]), "split");
|
|
152
|
+
const PAYMENT_FLOW_STATE_MACHINE = TRANSACTION_STATE_MACHINE;
|
|
153
|
+
const BANK_FEED_STATE_MACHINE = new StateMachine(new Map([
|
|
154
|
+
[TRANSACTION_STATUS.IMPORTED, new Set([TRANSACTION_STATUS.MATCHED, TRANSACTION_STATUS.REJECTED])],
|
|
155
|
+
[TRANSACTION_STATUS.MATCHED, new Set([TRANSACTION_STATUS.IMPORTED, TRANSACTION_STATUS.JOURNALIZED])],
|
|
156
|
+
[TRANSACTION_STATUS.JOURNALIZED, /* @__PURE__ */ new Set([])],
|
|
157
|
+
[TRANSACTION_STATUS.REJECTED, /* @__PURE__ */ new Set([])]
|
|
158
|
+
]), "transaction.bank_feed");
|
|
159
|
+
const MANUAL_STATE_MACHINE = new StateMachine(new Map([
|
|
160
|
+
[TRANSACTION_STATUS.PENDING, new Set([TRANSACTION_STATUS.MATCHED, TRANSACTION_STATUS.REJECTED])],
|
|
161
|
+
[TRANSACTION_STATUS.MATCHED, new Set([TRANSACTION_STATUS.JOURNALIZED])],
|
|
162
|
+
[TRANSACTION_STATUS.JOURNALIZED, /* @__PURE__ */ new Set([])],
|
|
163
|
+
[TRANSACTION_STATUS.REJECTED, /* @__PURE__ */ new Set([])]
|
|
164
|
+
]), "transaction.manual");
|
|
165
|
+
/**
|
|
166
|
+
* Select the state machine that governs a transaction row, given its
|
|
167
|
+
* `kind`. Repo verbs call this at the start of every state transition
|
|
168
|
+
* so the same `from → to` rules apply on both the in-memory check
|
|
169
|
+
* (state machine) and the atomic CAS (mongokit `claim()` with the
|
|
170
|
+
* `where: { kind }` predicate).
|
|
171
|
+
*
|
|
172
|
+
* @example
|
|
173
|
+
* ```ts
|
|
174
|
+
* const machine = smFor(transaction.kind);
|
|
175
|
+
* machine.validate(transaction.status, 'matched', String(transaction._id));
|
|
176
|
+
* await this.claim(id, {
|
|
177
|
+
* from: ['imported', 'matched'],
|
|
178
|
+
* to: 'matched',
|
|
179
|
+
* where: { kind: transaction.kind },
|
|
180
|
+
* }, patch, opts);
|
|
181
|
+
* ```
|
|
182
|
+
*/
|
|
183
|
+
function smFor(kind) {
|
|
184
|
+
switch (kind) {
|
|
185
|
+
case TRANSACTION_KIND.BANK_FEED: return BANK_FEED_STATE_MACHINE;
|
|
186
|
+
case TRANSACTION_KIND.MANUAL: return MANUAL_STATE_MACHINE;
|
|
187
|
+
case TRANSACTION_KIND.PAYMENT_FLOW:
|
|
188
|
+
default: return PAYMENT_FLOW_STATE_MACHINE;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
151
191
|
|
|
152
192
|
//#endregion
|
|
153
|
-
export { HOLD_STATE_MACHINE, SETTLEMENT_STATE_MACHINE, SPLIT_STATE_MACHINE, SUBSCRIPTION_STATE_MACHINE, StateMachine, TRANSACTION_STATE_MACHINE };
|
|
193
|
+
export { BANK_FEED_STATE_MACHINE, HOLD_STATE_MACHINE, MANUAL_STATE_MACHINE, PAYMENT_FLOW_STATE_MACHINE, SETTLEMENT_STATE_MACHINE, SPLIT_STATE_MACHINE, SUBSCRIPTION_STATE_MACHINE, StateMachine, TRANSACTION_STATE_MACHINE, smFor };
|