@classytic/ledger 0.8.0 → 0.9.1
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/README.md +94 -348
- package/dist/bridges/index.d.mts +2 -0
- package/dist/bridges/index.mjs +1 -0
- package/dist/constants/index.d.mts +1 -1
- package/dist/constants/index.mjs +2 -2
- package/dist/country/index.d.mts +1 -1
- package/dist/errors-BI5k4iak.mjs +121 -0
- package/dist/events/index.d.mts +2 -0
- package/dist/events/index.mjs +2 -0
- package/dist/exports/index.d.mts +1 -1
- package/dist/exports/index.mjs +1 -1
- package/dist/{fx-realization.plugin-DDVK-oYO.mjs → fx-realization.plugin-Bxlb8cIx.mjs} +2 -2
- package/dist/{index-RNZsX0Yo.d.mts → index-08IpHhrU.d.mts} +1 -1
- package/dist/{index-BSsvrf3m.d.mts → index-ClLwzNRF.d.mts} +3 -3
- package/dist/index-Dih0lM65.d.mts +169 -0
- package/dist/index.d.mts +233 -65
- package/dist/index.mjs +400 -99
- package/dist/{journals-Dd4A9TN3.d.mts → journals-DUpWwFt1.d.mts} +1 -1
- package/dist/outbox-store-DQbL-KYT.mjs +132 -0
- package/dist/outbox-store-UYC4eZpI.d.mts +249 -0
- package/dist/{partner-ledger-D9H5hegI.mjs → partner-ledger-BoebloHk.mjs} +2 -2
- package/dist/plugins/index.d.mts +1 -1
- package/dist/plugins/index.mjs +1 -1
- package/dist/reports/index.d.mts +1 -1
- package/dist/reports/index.mjs +1 -1
- package/dist/sync/index.d.mts +1 -1
- package/dist/sync/index.mjs +1 -1
- package/dist/{sync-CnuVf441.d.mts → sync-JvchM3FO.d.mts} +1 -1
- package/dist/{trial-balance-DTj-c21f.d.mts → trial-balance-DyNm5bFu.d.mts} +2 -2
- package/package.json +27 -14
- package/dist/errors-CSDQPNyt.mjs +0 -33
- /package/dist/{categories-BkKdv16V.mjs → categories-FJlrvzcl.mjs} +0 -0
- /package/dist/{core-MpgjCqK0.d.mts → core-DwjkrRkJ.d.mts} +0 -0
- /package/dist/{currencies-CsuBGfgs.mjs → currencies-Jo5oaM_4.mjs} +0 -0
- /package/dist/{exports-B3whucXe.mjs → exports-C30yRapf.mjs} +0 -0
- /package/dist/{index-bCEeSzdO.d.mts → index-J-XIbXH-.d.mts} +0 -0
- /package/dist/{opening-balance-DPXmAIzN.mjs → opening-balance-1cixYh6Y.mjs} +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { d as JournalType, f as MainType, h as StatementType, i as CategoryKey, o as Currency, r as Category } from "./core-
|
|
1
|
+
import { d as JournalType, f as MainType, h as StatementType, i as CategoryKey, o as Currency, r as Category } from "./core-DwjkrRkJ.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/constants/categories.d.ts
|
|
4
4
|
/** All valid categories */
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
//#region src/events/event-constants.ts
|
|
3
|
+
/**
|
|
4
|
+
* Ledger domain event names.
|
|
5
|
+
*
|
|
6
|
+
* Convention: `ledger:<resource>.<verb>` — matches the catalog/revenue/flow
|
|
7
|
+
* namespace pattern so hosts can subscribe with a single glob
|
|
8
|
+
* (`ledger:entry.*`, `ledger:*`).
|
|
9
|
+
*/
|
|
10
|
+
const LEDGER_EVENTS = {
|
|
11
|
+
ENTRY_CREATED: "ledger:entry.created",
|
|
12
|
+
ENTRY_POSTED: "ledger:entry.posted",
|
|
13
|
+
ENTRY_UNPOSTED: "ledger:entry.unposted",
|
|
14
|
+
ENTRY_ARCHIVED: "ledger:entry.archived",
|
|
15
|
+
ENTRY_DUPLICATED: "ledger:entry.duplicated",
|
|
16
|
+
ENTRY_REVERSED: "ledger:entry.reversed",
|
|
17
|
+
ACCOUNT_SEEDED: "ledger:account.seeded",
|
|
18
|
+
ACCOUNT_BULK_CREATED: "ledger:account.bulk-created",
|
|
19
|
+
JOURNAL_SEEDED: "ledger:journal.seeded",
|
|
20
|
+
RECONCILIATION_MATCHED: "ledger:reconciliation.matched",
|
|
21
|
+
RECONCILIATION_UNMATCHED: "ledger:reconciliation.unmatched"
|
|
22
|
+
};
|
|
23
|
+
//#endregion
|
|
24
|
+
//#region src/events/helpers.ts
|
|
25
|
+
/**
|
|
26
|
+
* Event creation helper.
|
|
27
|
+
*
|
|
28
|
+
* Builds a well-formed DomainEvent with auto-generated `meta.id` + `meta.timestamp`.
|
|
29
|
+
* Threads optional context fields (userId, organizationId, correlationId) that
|
|
30
|
+
* hosts rely on for audit trails and distributed tracing.
|
|
31
|
+
*/
|
|
32
|
+
function toIdString(value) {
|
|
33
|
+
if (value == null) return void 0;
|
|
34
|
+
if (typeof value === "string") return value;
|
|
35
|
+
if (typeof value === "number" || typeof value === "bigint") return String(value);
|
|
36
|
+
const obj = value;
|
|
37
|
+
if (typeof obj.toHexString === "function") return obj.toHexString();
|
|
38
|
+
if (typeof obj.toString === "function") {
|
|
39
|
+
const s = obj.toString();
|
|
40
|
+
return s === "[object Object]" ? void 0 : s;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function createEvent(type, payload, ctx, meta) {
|
|
44
|
+
return {
|
|
45
|
+
type,
|
|
46
|
+
payload,
|
|
47
|
+
meta: {
|
|
48
|
+
id: randomUUID(),
|
|
49
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
50
|
+
userId: toIdString(ctx?.actorId),
|
|
51
|
+
organizationId: toIdString(ctx?.organizationId),
|
|
52
|
+
correlationId: ctx?.correlationId ?? ctx?.traceId,
|
|
53
|
+
...meta
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
//#endregion
|
|
58
|
+
//#region src/events/in-process-bus.ts
|
|
59
|
+
var InProcessLedgerBus = class {
|
|
60
|
+
name = "in-process-ledger";
|
|
61
|
+
handlers = /* @__PURE__ */ new Map();
|
|
62
|
+
logger;
|
|
63
|
+
constructor(options) {
|
|
64
|
+
this.logger = options?.logger ?? console;
|
|
65
|
+
}
|
|
66
|
+
async publish(event) {
|
|
67
|
+
const exact = this.handlers.get(event.type) ?? /* @__PURE__ */ new Set();
|
|
68
|
+
const wildcard = this.handlers.get("*") ?? /* @__PURE__ */ new Set();
|
|
69
|
+
const pattern = /* @__PURE__ */ new Set();
|
|
70
|
+
for (const [p, handlers] of this.handlers.entries()) if (p.endsWith(".*")) {
|
|
71
|
+
const prefix = p.slice(0, -2);
|
|
72
|
+
if (event.type.startsWith(`${prefix}.`)) for (const h of handlers) pattern.add(h);
|
|
73
|
+
} else if (p.endsWith(":*")) {
|
|
74
|
+
const prefix = p.slice(0, -2);
|
|
75
|
+
if (event.type.startsWith(`${prefix}:`)) for (const h of handlers) pattern.add(h);
|
|
76
|
+
}
|
|
77
|
+
const all = new Set([
|
|
78
|
+
...exact,
|
|
79
|
+
...wildcard,
|
|
80
|
+
...pattern
|
|
81
|
+
]);
|
|
82
|
+
for (const handler of all) try {
|
|
83
|
+
await handler(event);
|
|
84
|
+
} catch (err) {
|
|
85
|
+
this.logger.error(`[InProcessLedgerBus] Handler error for ${event.type}:`, err);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
async publishMany(events) {
|
|
89
|
+
const results = /* @__PURE__ */ new Map();
|
|
90
|
+
for (const event of events) try {
|
|
91
|
+
await this.publish(event);
|
|
92
|
+
results.set(event.meta.id, null);
|
|
93
|
+
} catch (err) {
|
|
94
|
+
results.set(event.meta.id, err instanceof Error ? err : new Error(String(err)));
|
|
95
|
+
}
|
|
96
|
+
return results;
|
|
97
|
+
}
|
|
98
|
+
async subscribe(pattern, handler) {
|
|
99
|
+
if (!this.handlers.has(pattern)) this.handlers.set(pattern, /* @__PURE__ */ new Set());
|
|
100
|
+
this.handlers.get(pattern)?.add(handler);
|
|
101
|
+
return () => {
|
|
102
|
+
const set = this.handlers.get(pattern);
|
|
103
|
+
if (set) {
|
|
104
|
+
set.delete(handler);
|
|
105
|
+
if (set.size === 0) this.handlers.delete(pattern);
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
async close() {
|
|
110
|
+
this.handlers.clear();
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
//#endregion
|
|
114
|
+
//#region src/events/outbox-store.ts
|
|
115
|
+
/**
|
|
116
|
+
* Thrown by a store when `acknowledge` / `fail` is called by a consumer that
|
|
117
|
+
* does not own the event's current lease.
|
|
118
|
+
*/
|
|
119
|
+
var OutboxOwnershipError = class extends Error {
|
|
120
|
+
eventId;
|
|
121
|
+
attemptedBy;
|
|
122
|
+
currentOwner;
|
|
123
|
+
constructor(eventId, attemptedBy, currentOwner) {
|
|
124
|
+
super(`Outbox ownership mismatch for event "${eventId}": attempted by "${attemptedBy}", current owner is "${currentOwner ?? "none"}". The lease may have expired and been reclaimed by another worker.`);
|
|
125
|
+
this.name = "OutboxOwnershipError";
|
|
126
|
+
this.eventId = eventId;
|
|
127
|
+
this.attemptedBy = attemptedBy;
|
|
128
|
+
this.currentOwner = currentOwner;
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
//#endregion
|
|
132
|
+
export { LEDGER_EVENTS as i, InProcessLedgerBus as n, createEvent as r, OutboxOwnershipError as t };
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
//#region src/events/event-constants.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Ledger domain event names.
|
|
4
|
+
*
|
|
5
|
+
* Convention: `ledger:<resource>.<verb>` — matches the catalog/revenue/flow
|
|
6
|
+
* namespace pattern so hosts can subscribe with a single glob
|
|
7
|
+
* (`ledger:entry.*`, `ledger:*`).
|
|
8
|
+
*/
|
|
9
|
+
declare const LEDGER_EVENTS: {
|
|
10
|
+
readonly ENTRY_CREATED: "ledger:entry.created";
|
|
11
|
+
readonly ENTRY_POSTED: "ledger:entry.posted";
|
|
12
|
+
readonly ENTRY_UNPOSTED: "ledger:entry.unposted";
|
|
13
|
+
readonly ENTRY_ARCHIVED: "ledger:entry.archived";
|
|
14
|
+
readonly ENTRY_DUPLICATED: "ledger:entry.duplicated";
|
|
15
|
+
readonly ENTRY_REVERSED: "ledger:entry.reversed";
|
|
16
|
+
readonly ACCOUNT_SEEDED: "ledger:account.seeded";
|
|
17
|
+
readonly ACCOUNT_BULK_CREATED: "ledger:account.bulk-created";
|
|
18
|
+
readonly JOURNAL_SEEDED: "ledger:journal.seeded";
|
|
19
|
+
readonly RECONCILIATION_MATCHED: "ledger:reconciliation.matched";
|
|
20
|
+
readonly RECONCILIATION_UNMATCHED: "ledger:reconciliation.unmatched";
|
|
21
|
+
};
|
|
22
|
+
type LedgerEventName = (typeof LEDGER_EVENTS)[keyof typeof LEDGER_EVENTS];
|
|
23
|
+
//#endregion
|
|
24
|
+
//#region src/events/event-payloads.d.ts
|
|
25
|
+
/**
|
|
26
|
+
* Typed payload definitions for ledger domain events.
|
|
27
|
+
*/
|
|
28
|
+
interface EntryCreatedPayload {
|
|
29
|
+
entryId: unknown;
|
|
30
|
+
journalType?: string;
|
|
31
|
+
state: string;
|
|
32
|
+
referenceNumber?: string;
|
|
33
|
+
idempotencyKey?: string;
|
|
34
|
+
organizationId?: unknown;
|
|
35
|
+
}
|
|
36
|
+
interface EntryPostedPayload {
|
|
37
|
+
entryId: unknown;
|
|
38
|
+
referenceNumber?: string;
|
|
39
|
+
postedBy?: unknown;
|
|
40
|
+
totalDebit: number;
|
|
41
|
+
totalCredit: number;
|
|
42
|
+
organizationId?: unknown;
|
|
43
|
+
}
|
|
44
|
+
interface EntryUnpostedPayload {
|
|
45
|
+
entryId: unknown;
|
|
46
|
+
unpostedBy?: unknown;
|
|
47
|
+
organizationId?: unknown;
|
|
48
|
+
}
|
|
49
|
+
interface EntryArchivedPayload {
|
|
50
|
+
entryId: unknown;
|
|
51
|
+
archivedBy?: unknown;
|
|
52
|
+
organizationId?: unknown;
|
|
53
|
+
}
|
|
54
|
+
interface EntryDuplicatedPayload {
|
|
55
|
+
sourceEntryId: unknown;
|
|
56
|
+
duplicateEntryId: unknown;
|
|
57
|
+
organizationId?: unknown;
|
|
58
|
+
}
|
|
59
|
+
interface EntryReversedPayload {
|
|
60
|
+
originalEntryId: unknown;
|
|
61
|
+
reversalEntryId: unknown;
|
|
62
|
+
reversalDate: Date;
|
|
63
|
+
reversedBy?: unknown;
|
|
64
|
+
organizationId?: unknown;
|
|
65
|
+
}
|
|
66
|
+
interface AccountSeededPayload {
|
|
67
|
+
created: number;
|
|
68
|
+
skipped: number;
|
|
69
|
+
organizationId?: unknown;
|
|
70
|
+
}
|
|
71
|
+
interface AccountBulkCreatedPayload {
|
|
72
|
+
created: number;
|
|
73
|
+
skipped: number;
|
|
74
|
+
errors: number;
|
|
75
|
+
organizationId?: unknown;
|
|
76
|
+
}
|
|
77
|
+
interface JournalSeededPayload {
|
|
78
|
+
created: number;
|
|
79
|
+
skipped: number;
|
|
80
|
+
organizationId?: unknown;
|
|
81
|
+
}
|
|
82
|
+
interface ReconciliationMatchedPayload {
|
|
83
|
+
matchingNumber: string;
|
|
84
|
+
account: unknown;
|
|
85
|
+
itemCount: number;
|
|
86
|
+
debitTotal: number;
|
|
87
|
+
creditTotal: number;
|
|
88
|
+
isFullReconcile: boolean;
|
|
89
|
+
currency: string | null;
|
|
90
|
+
organizationId?: unknown;
|
|
91
|
+
}
|
|
92
|
+
interface ReconciliationUnmatchedPayload {
|
|
93
|
+
matchingNumber: string;
|
|
94
|
+
itemCount: number;
|
|
95
|
+
organizationId?: unknown;
|
|
96
|
+
}
|
|
97
|
+
//#endregion
|
|
98
|
+
//#region src/events/transport.d.ts
|
|
99
|
+
/**
|
|
100
|
+
* EventTransport — structurally identical to @classytic/arc's EventTransport.
|
|
101
|
+
*
|
|
102
|
+
* DO NOT import from @classytic/arc at runtime. TypeScript structural typing
|
|
103
|
+
* means any arc transport (Memory, Redis, BullMQ, Kafka) is assignable to this
|
|
104
|
+
* interface with zero adapter code, as long as the shape matches exactly.
|
|
105
|
+
*
|
|
106
|
+
* See: packages/arc/src/events/EventTransport.ts
|
|
107
|
+
*/
|
|
108
|
+
interface DomainEvent<T = unknown> {
|
|
109
|
+
type: string;
|
|
110
|
+
payload: T;
|
|
111
|
+
meta: {
|
|
112
|
+
id: string;
|
|
113
|
+
timestamp: Date;
|
|
114
|
+
resource?: string;
|
|
115
|
+
resourceId?: string;
|
|
116
|
+
userId?: string;
|
|
117
|
+
organizationId?: string;
|
|
118
|
+
correlationId?: string;
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
type EventHandler<T = unknown> = (event: DomainEvent<T>) => void | Promise<void>;
|
|
122
|
+
/**
|
|
123
|
+
* Per-event outcome returned by `EventTransport.publishMany`.
|
|
124
|
+
* Key is `event.meta.id`; value is `null` for success or `Error` for per-event failure.
|
|
125
|
+
*/
|
|
126
|
+
type PublishManyResult = ReadonlyMap<string, Error | null>;
|
|
127
|
+
interface EventLogger {
|
|
128
|
+
warn(message: string, ...args: unknown[]): void;
|
|
129
|
+
error(message: string, ...args: unknown[]): void;
|
|
130
|
+
}
|
|
131
|
+
interface EventTransport {
|
|
132
|
+
readonly name: string;
|
|
133
|
+
publish(event: DomainEvent): Promise<void>;
|
|
134
|
+
publishMany?(events: readonly DomainEvent[]): Promise<PublishManyResult>;
|
|
135
|
+
subscribe(pattern: string, handler: EventHandler): Promise<() => void>;
|
|
136
|
+
close?(): Promise<void>;
|
|
137
|
+
}
|
|
138
|
+
//#endregion
|
|
139
|
+
//#region src/events/helpers.d.ts
|
|
140
|
+
/** Minimal context shape for event metadata. */
|
|
141
|
+
interface EventContext {
|
|
142
|
+
actorId?: unknown;
|
|
143
|
+
organizationId?: unknown;
|
|
144
|
+
correlationId?: string;
|
|
145
|
+
traceId?: string;
|
|
146
|
+
}
|
|
147
|
+
declare function createEvent<T>(type: string, payload: T, ctx?: EventContext, meta?: Partial<DomainEvent['meta']>): DomainEvent<T>;
|
|
148
|
+
//#endregion
|
|
149
|
+
//#region src/events/in-process-bus.d.ts
|
|
150
|
+
interface InProcessLedgerBusOptions {
|
|
151
|
+
logger?: EventLogger;
|
|
152
|
+
}
|
|
153
|
+
declare class InProcessLedgerBus implements EventTransport {
|
|
154
|
+
readonly name = "in-process-ledger";
|
|
155
|
+
private handlers;
|
|
156
|
+
private logger;
|
|
157
|
+
constructor(options?: InProcessLedgerBusOptions);
|
|
158
|
+
publish(event: DomainEvent): Promise<void>;
|
|
159
|
+
publishMany(events: readonly DomainEvent[]): Promise<PublishManyResult>;
|
|
160
|
+
subscribe(pattern: string, handler: EventHandler): Promise<() => void>;
|
|
161
|
+
close(): Promise<void>;
|
|
162
|
+
}
|
|
163
|
+
//#endregion
|
|
164
|
+
//#region src/events/outbox-store.d.ts
|
|
165
|
+
/** Options passed to `OutboxStore.save` for richer write semantics. */
|
|
166
|
+
interface OutboxWriteOptions {
|
|
167
|
+
/** Host-provided DB session/transaction handle for atomic writes. */
|
|
168
|
+
readonly session?: unknown;
|
|
169
|
+
/** Earliest time the event should be visible to relay workers. */
|
|
170
|
+
readonly visibleAt?: Date;
|
|
171
|
+
/** Idempotency key — stores that support it should dedupe on this. */
|
|
172
|
+
readonly dedupeKey?: string;
|
|
173
|
+
/** Partition/routing key for sharded transports (Kafka, Redis Streams). */
|
|
174
|
+
readonly partitionKey?: string;
|
|
175
|
+
/** Arbitrary headers propagated to the transport layer. */
|
|
176
|
+
readonly headers?: Readonly<Record<string, string>>;
|
|
177
|
+
}
|
|
178
|
+
/** Options for lease-based work claim. */
|
|
179
|
+
interface OutboxClaimOptions {
|
|
180
|
+
readonly limit?: number;
|
|
181
|
+
readonly consumerId?: string;
|
|
182
|
+
readonly leaseMs?: number;
|
|
183
|
+
readonly types?: readonly string[];
|
|
184
|
+
}
|
|
185
|
+
/** Options for `OutboxStore.acknowledge`. */
|
|
186
|
+
interface OutboxAcknowledgeOptions {
|
|
187
|
+
readonly consumerId?: string;
|
|
188
|
+
}
|
|
189
|
+
/** Options for `OutboxStore.fail`. */
|
|
190
|
+
interface OutboxFailOptions {
|
|
191
|
+
readonly consumerId?: string;
|
|
192
|
+
readonly retryAt?: Date;
|
|
193
|
+
readonly deadLetter?: boolean;
|
|
194
|
+
}
|
|
195
|
+
/** Normalized error info passed to `OutboxStore.fail`. */
|
|
196
|
+
interface OutboxErrorInfo {
|
|
197
|
+
readonly message: string;
|
|
198
|
+
readonly code?: string;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Thrown by a store when `acknowledge` / `fail` is called by a consumer that
|
|
202
|
+
* does not own the event's current lease.
|
|
203
|
+
*/
|
|
204
|
+
declare class OutboxOwnershipError extends Error {
|
|
205
|
+
readonly eventId: string;
|
|
206
|
+
readonly attemptedBy: string;
|
|
207
|
+
readonly currentOwner: string | null;
|
|
208
|
+
constructor(eventId: string, attemptedBy: string, currentOwner: string | null);
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Durable storage contract for the transactional outbox pattern.
|
|
212
|
+
*
|
|
213
|
+
* **Required**: `save`, `getPending`, `acknowledge`.
|
|
214
|
+
* **Optional** (stores opt-in): `claimPending`, `fail`, `purge`.
|
|
215
|
+
*
|
|
216
|
+
* Structurally identical to arc's `OutboxStore` — assignable in both
|
|
217
|
+
* directions via TypeScript structural typing.
|
|
218
|
+
*/
|
|
219
|
+
interface OutboxStore {
|
|
220
|
+
/**
|
|
221
|
+
* Save event to outbox (typically inside a business transaction via `options.session`).
|
|
222
|
+
* MUST reject events missing `type` or `meta.id` — throw rather than persist.
|
|
223
|
+
*/
|
|
224
|
+
save(event: DomainEvent, options?: OutboxWriteOptions): Promise<void>;
|
|
225
|
+
/**
|
|
226
|
+
* Get pending (unrelayed) events, FIFO ordered.
|
|
227
|
+
* Multi-worker deployments should prefer `claimPending` if supported.
|
|
228
|
+
*/
|
|
229
|
+
getPending(limit: number): Promise<DomainEvent[]>;
|
|
230
|
+
/**
|
|
231
|
+
* Atomically claim pending events with a lease.
|
|
232
|
+
* Two concurrent callers MUST never receive overlapping events.
|
|
233
|
+
*/
|
|
234
|
+
claimPending?(options?: OutboxClaimOptions): Promise<DomainEvent[]>;
|
|
235
|
+
/**
|
|
236
|
+
* Mark event as successfully relayed. Unknown eventId is a no-op (idempotent).
|
|
237
|
+
* Ownership mismatch MUST throw `OutboxOwnershipError`.
|
|
238
|
+
*/
|
|
239
|
+
acknowledge(eventId: string, options?: OutboxAcknowledgeOptions): Promise<void>;
|
|
240
|
+
/**
|
|
241
|
+
* Record a relay failure. Enables retry scheduling and dead-letter flow.
|
|
242
|
+
* Ownership mismatch MUST throw `OutboxOwnershipError`.
|
|
243
|
+
*/
|
|
244
|
+
fail?(eventId: string, error: OutboxErrorInfo, options?: OutboxFailOptions): Promise<void>;
|
|
245
|
+
/** Purge old delivered events (older than `olderThanMs`). Returns count. */
|
|
246
|
+
purge?(olderThanMs: number): Promise<number>;
|
|
247
|
+
}
|
|
248
|
+
//#endregion
|
|
249
|
+
export { EntryReversedPayload as C, ReconciliationUnmatchedPayload as D, ReconciliationMatchedPayload as E, LEDGER_EVENTS as O, EntryPostedPayload as S, JournalSeededPayload as T, AccountBulkCreatedPayload as _, OutboxOwnershipError as a, EntryCreatedPayload as b, InProcessLedgerBus as c, createEvent as d, DomainEvent as f, PublishManyResult as g, EventTransport as h, OutboxFailOptions as i, LedgerEventName as k, InProcessLedgerBusOptions as l, EventLogger as m, OutboxClaimOptions as n, OutboxStore as o, EventHandler as p, OutboxErrorInfo as r, OutboxWriteOptions as s, OutboxAcknowledgeOptions as t, EventContext as u, AccountSeededPayload as v, EntryUnpostedPayload as w, EntryDuplicatedPayload as x, EntryArchivedPayload as y };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { i as extractMainType } from "./categories-
|
|
1
|
+
import { i as Errors } from "./errors-BI5k4iak.mjs";
|
|
2
|
+
import { i as extractMainType } from "./categories-FJlrvzcl.mjs";
|
|
3
3
|
import mongoose from "mongoose";
|
|
4
4
|
//#region src/utils/tenant-guard.ts
|
|
5
5
|
/**
|
package/dist/plugins/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { S as creditLimitPlugin, _ as FxRealizationPluginOptions, a as dailyLockPlugin, b as doubleEntryPlugin, c as periodResolver, d as LockAccountSelector, f as LockHit, g as idempotencyPlugin, h as IdempotencyPluginOptions, i as FiscalLockPluginOptions, l as createLockPlugin, m as LockResolverContext, n as watermarkResolver, o as fiscalLockPlugin, p as LockResolver, r as DailyLockPluginOptions, s as PeriodResolverOptions, t as WatermarkResolverOptions, u as CreateLockPluginOptions, v as fxRealizationPlugin, x as CreditLimitPluginOptions, y as DoubleEntryPluginOptions } from "../index-
|
|
1
|
+
import { S as creditLimitPlugin, _ as FxRealizationPluginOptions, a as dailyLockPlugin, b as doubleEntryPlugin, c as periodResolver, d as LockAccountSelector, f as LockHit, g as idempotencyPlugin, h as IdempotencyPluginOptions, i as FiscalLockPluginOptions, l as createLockPlugin, m as LockResolverContext, n as watermarkResolver, o as fiscalLockPlugin, p as LockResolver, r as DailyLockPluginOptions, s as PeriodResolverOptions, t as WatermarkResolverOptions, u as CreateLockPluginOptions, v as fxRealizationPlugin, x as CreditLimitPluginOptions, y as DoubleEntryPluginOptions } from "../index-ClLwzNRF.mjs";
|
|
2
2
|
export { type CreateLockPluginOptions, type CreditLimitPluginOptions, type DailyLockPluginOptions, type DoubleEntryPluginOptions, type FiscalLockPluginOptions, type FxRealizationPluginOptions, type IdempotencyPluginOptions, type LockAccountSelector, type LockHit, type LockResolver, type LockResolverContext, type PeriodResolverOptions, type WatermarkResolverOptions, createLockPlugin, creditLimitPlugin, dailyLockPlugin, doubleEntryPlugin, fiscalLockPlugin, fxRealizationPlugin, idempotencyPlugin, periodResolver, watermarkResolver };
|
package/dist/plugins/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as watermarkResolver, c as idempotencyPlugin, i as fiscalLockPlugin, l as doubleEntryPlugin, n as creditLimitPlugin, o as periodResolver, r as dailyLockPlugin, s as createLockPlugin, t as fxRealizationPlugin } from "../fx-realization.plugin-
|
|
1
|
+
import { a as watermarkResolver, c as idempotencyPlugin, i as fiscalLockPlugin, l as doubleEntryPlugin, n as creditLimitPlugin, o as periodResolver, r as dailyLockPlugin, s as createLockPlugin, t as fxRealizationPlugin } from "../fx-realization.plugin-Bxlb8cIx.mjs";
|
|
2
2
|
export { createLockPlugin, creditLimitPlugin, dailyLockPlugin, doubleEntryPlugin, fiscalLockPlugin, fxRealizationPlugin, idempotencyPlugin, periodResolver, watermarkResolver };
|
package/dist/reports/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { $ as AgedBalanceParams, A as generateDimensionBreakdown, C as FiscalReopenResult, D as DimensionBreakdownParams, E as DimensionBreakdownOptions, F as BudgetVsActualReport, I as BudgetVsActualRow, L as generateBudgetVsActual, M as generateCashFlow, N as BudgetVsActualOptions, O as DimensionBreakdownReport, P as BudgetVsActualParams, Q as AgedBalanceOptions, R as BalanceSheetOptions, S as FiscalCloseResult, T as reopenFiscalPeriod, _ as IncomeStatementOptions, a as RevaluationReport, b as generateGeneralLedger, et as AgedBalanceReport, f as PartnerLedgerLine, g as generatePartnerLedger, h as PartnerLedgerReport, i as RevaluationParams, it as generateAgedBalance, j as CashFlowOptions, k as DimensionBreakdownRow, m as PartnerLedgerParams, n as generateTrialBalance, nt as AgedBucketConfig, o as generateRevaluation, p as PartnerLedgerOptions, r as RevaluationOptions, rt as DEFAULT_BUCKETS, t as TrialBalanceOptions, tt as AgedBalanceRow, v as generateIncomeStatement, w as closeFiscalPeriod, x as FiscalCloseOptions, y as GeneralLedgerOptions, z as generateBalanceSheet } from "../trial-balance-
|
|
1
|
+
import { $ as AgedBalanceParams, A as generateDimensionBreakdown, C as FiscalReopenResult, D as DimensionBreakdownParams, E as DimensionBreakdownOptions, F as BudgetVsActualReport, I as BudgetVsActualRow, L as generateBudgetVsActual, M as generateCashFlow, N as BudgetVsActualOptions, O as DimensionBreakdownReport, P as BudgetVsActualParams, Q as AgedBalanceOptions, R as BalanceSheetOptions, S as FiscalCloseResult, T as reopenFiscalPeriod, _ as IncomeStatementOptions, a as RevaluationReport, b as generateGeneralLedger, et as AgedBalanceReport, f as PartnerLedgerLine, g as generatePartnerLedger, h as PartnerLedgerReport, i as RevaluationParams, it as generateAgedBalance, j as CashFlowOptions, k as DimensionBreakdownRow, m as PartnerLedgerParams, n as generateTrialBalance, nt as AgedBucketConfig, o as generateRevaluation, p as PartnerLedgerOptions, r as RevaluationOptions, rt as DEFAULT_BUCKETS, t as TrialBalanceOptions, tt as AgedBalanceRow, v as generateIncomeStatement, w as closeFiscalPeriod, x as FiscalCloseOptions, y as GeneralLedgerOptions, z as generateBalanceSheet } from "../trial-balance-DyNm5bFu.mjs";
|
|
2
2
|
export { type AgedBalanceOptions, type AgedBalanceParams, type AgedBalanceReport, type AgedBalanceRow, type AgedBucketConfig, type BalanceSheetOptions, type BudgetVsActualOptions, type BudgetVsActualParams, type BudgetVsActualReport, type BudgetVsActualRow, type CashFlowOptions, DEFAULT_BUCKETS, type DimensionBreakdownOptions, type DimensionBreakdownParams, type DimensionBreakdownReport, type DimensionBreakdownRow, type FiscalCloseOptions, type FiscalCloseResult, type FiscalReopenResult, type GeneralLedgerOptions, type IncomeStatementOptions, type PartnerLedgerLine, type PartnerLedgerOptions, type PartnerLedgerParams, type PartnerLedgerReport, type RevaluationOptions, type RevaluationParams, type RevaluationReport, type TrialBalanceOptions, closeFiscalPeriod, generateAgedBalance, generateBalanceSheet, generateBudgetVsActual, generateCashFlow, generateDimensionBreakdown, generateGeneralLedger, generateIncomeStatement, generatePartnerLedger, generateRevaluation, generateTrialBalance, reopenFiscalPeriod };
|
package/dist/reports/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { T as generateAgedBalance, c as generateRevaluation, d as generateIncomeStatement, f as generateGeneralLedger, g as generateBalanceSheet, h as generateBudgetVsActual, m as generateCashFlow, n as closeFiscalPeriod, p as generateDimensionBreakdown, r as reopenFiscalPeriod, s as generateTrialBalance, t as generatePartnerLedger, w as DEFAULT_BUCKETS } from "../partner-ledger-
|
|
1
|
+
import { T as generateAgedBalance, c as generateRevaluation, d as generateIncomeStatement, f as generateGeneralLedger, g as generateBalanceSheet, h as generateBudgetVsActual, m as generateCashFlow, n as closeFiscalPeriod, p as generateDimensionBreakdown, r as reopenFiscalPeriod, s as generateTrialBalance, t as generatePartnerLedger, w as DEFAULT_BUCKETS } from "../partner-ledger-BoebloHk.mjs";
|
|
2
2
|
export { DEFAULT_BUCKETS, closeFiscalPeriod, generateAgedBalance, generateBalanceSheet, generateBudgetVsActual, generateCashFlow, generateDimensionBreakdown, generateGeneralLedger, generateIncomeStatement, generatePartnerLedger, generateRevaluation, generateTrialBalance, reopenFiscalPeriod };
|
package/dist/sync/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as ImportMapper, c as JournalItemInput, i as ImportError, l as WireExportArgs, n as ExportSink, o as ImportReport, r as ImportContext, s as JournalEntryInput, t as ExportReport, u as WireImportArgs } from "../sync-
|
|
1
|
+
import { a as ImportMapper, c as JournalItemInput, i as ImportError, l as WireExportArgs, n as ExportSink, o as ImportReport, r as ImportContext, s as JournalEntryInput, t as ExportReport, u as WireImportArgs } from "../sync-JvchM3FO.mjs";
|
|
2
2
|
import { CanonicalInvoice, CanonicalJournalEntry, CanonicalTransaction } from "@classytic/fin-io";
|
|
3
3
|
|
|
4
4
|
//#region src/sync/builders/opening-balance.d.ts
|
package/dist/sync/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as buildOpeningBalanceEntry } from "../opening-balance-
|
|
1
|
+
import { t as buildOpeningBalanceEntry } from "../opening-balance-1cixYh6Y.mjs";
|
|
2
2
|
//#region src/sync/ledger-bridge.ts
|
|
3
3
|
const isCustomerSide = (t) => t === "out_invoice" || t === "out_refund" || t === "receipt";
|
|
4
4
|
const isRefund = (t) => t === "out_refund" || t === "in_refund";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { c as DateRange } from "./core-
|
|
2
|
-
import { t as CountryPack } from "./index-
|
|
1
|
+
import { c as DateRange } from "./core-DwjkrRkJ.mjs";
|
|
2
|
+
import { t as CountryPack } from "./index-08IpHhrU.mjs";
|
|
3
3
|
import { ClientSession, Model } from "mongoose";
|
|
4
4
|
|
|
5
5
|
//#region src/utils/logger.d.ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@classytic/ledger",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.1",
|
|
4
4
|
"description": "Production-grade double-entry accounting engine for MongoDB — schemas, reports, tax, multi-tenant",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -47,6 +47,16 @@
|
|
|
47
47
|
"types": "./dist/sync/index.d.mts",
|
|
48
48
|
"import": "./dist/sync/index.mjs",
|
|
49
49
|
"default": "./dist/sync/index.mjs"
|
|
50
|
+
},
|
|
51
|
+
"./events": {
|
|
52
|
+
"types": "./dist/events/index.d.mts",
|
|
53
|
+
"import": "./dist/events/index.mjs",
|
|
54
|
+
"default": "./dist/events/index.mjs"
|
|
55
|
+
},
|
|
56
|
+
"./bridges": {
|
|
57
|
+
"types": "./dist/bridges/index.d.mts",
|
|
58
|
+
"import": "./dist/bridges/index.mjs",
|
|
59
|
+
"default": "./dist/bridges/index.mjs"
|
|
50
60
|
}
|
|
51
61
|
},
|
|
52
62
|
"files": [
|
|
@@ -80,11 +90,11 @@
|
|
|
80
90
|
"license": "MIT",
|
|
81
91
|
"repository": {
|
|
82
92
|
"type": "git",
|
|
83
|
-
"url": "git+https://github.com/classytic/
|
|
93
|
+
"url": "git+https://github.com/classytic/ledger.git"
|
|
84
94
|
},
|
|
85
95
|
"peerDependencies": {
|
|
86
96
|
"@classytic/fin-io": ">=0.1.0",
|
|
87
|
-
"@classytic/mongokit": ">=3.
|
|
97
|
+
"@classytic/mongokit": ">=3.6.4",
|
|
88
98
|
"mongoose": ">=9.4.1"
|
|
89
99
|
},
|
|
90
100
|
"peerDependenciesMeta": {
|
|
@@ -93,17 +103,17 @@
|
|
|
93
103
|
}
|
|
94
104
|
},
|
|
95
105
|
"devDependencies": {
|
|
96
|
-
"@biomejs/biome": "^2.4.
|
|
97
|
-
"@classytic/fin-io": "
|
|
98
|
-
"@classytic/mongokit": "^3.
|
|
99
|
-
"@types/node": "^
|
|
100
|
-
"@vitest/coverage-v8": "^
|
|
101
|
-
"knip": "^6.
|
|
102
|
-
"mongodb-memory-server": "^
|
|
106
|
+
"@biomejs/biome": "^2.4.12",
|
|
107
|
+
"@classytic/fin-io": "^0.1.0",
|
|
108
|
+
"@classytic/mongokit": "^3.6.4",
|
|
109
|
+
"@types/node": "^25.5.0",
|
|
110
|
+
"@vitest/coverage-v8": "^4.1.4",
|
|
111
|
+
"knip": "^6.4.1",
|
|
112
|
+
"mongodb-memory-server": "^11.0.1",
|
|
103
113
|
"mongoose": "^9.4.1",
|
|
104
|
-
"tsdown": "^0.21.
|
|
114
|
+
"tsdown": "^0.21.8",
|
|
105
115
|
"typescript": "^5.7.0",
|
|
106
|
-
"vitest": "^
|
|
116
|
+
"vitest": "^4.1.4"
|
|
107
117
|
},
|
|
108
118
|
"engines": {
|
|
109
119
|
"node": ">=22"
|
|
@@ -111,8 +121,11 @@
|
|
|
111
121
|
"scripts": {
|
|
112
122
|
"build": "tsdown",
|
|
113
123
|
"dev": "tsdown --watch",
|
|
114
|
-
"test": "vitest run",
|
|
115
|
-
"test:
|
|
124
|
+
"test": "vitest run --project unit --project integration",
|
|
125
|
+
"test:unit": "vitest run --project unit",
|
|
126
|
+
"test:integration": "vitest run --project integration",
|
|
127
|
+
"test:all": "vitest run",
|
|
128
|
+
"test:watch": "vitest --project unit --project integration",
|
|
116
129
|
"test:coverage": "vitest run --coverage",
|
|
117
130
|
"typecheck": "tsc --noEmit",
|
|
118
131
|
"lint": "biome check src/",
|
package/dist/errors-CSDQPNyt.mjs
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
//#region src/utils/errors.ts
|
|
2
|
-
var AccountingError = class extends Error {
|
|
3
|
-
status;
|
|
4
|
-
code;
|
|
5
|
-
fields;
|
|
6
|
-
constructor(message, status = 400, code = "ACCOUNTING_ERROR", fields) {
|
|
7
|
-
super(message);
|
|
8
|
-
this.name = "AccountingError";
|
|
9
|
-
this.status = status;
|
|
10
|
-
this.code = code;
|
|
11
|
-
if (fields && fields.length > 0) this.fields = Object.freeze([...fields]);
|
|
12
|
-
}
|
|
13
|
-
/** Serialize to a plain object for API responses and logs. */
|
|
14
|
-
toJSON() {
|
|
15
|
-
return {
|
|
16
|
-
name: this.name,
|
|
17
|
-
message: this.message,
|
|
18
|
-
status: this.status,
|
|
19
|
-
code: this.code,
|
|
20
|
-
...this.fields ? { fields: this.fields } : {}
|
|
21
|
-
};
|
|
22
|
-
}
|
|
23
|
-
};
|
|
24
|
-
/** Convenience factory functions. */
|
|
25
|
-
const Errors = {
|
|
26
|
-
validation: (msg, fields) => new AccountingError(msg, 400, "VALIDATION_ERROR", fields),
|
|
27
|
-
notFound: (msg, fields) => new AccountingError(msg, 404, "NOT_FOUND", fields),
|
|
28
|
-
conflict: (msg, fields) => new AccountingError(msg, 409, "CONFLICT", fields),
|
|
29
|
-
immutable: (msg, fields) => new AccountingError(msg, 403, "IMMUTABLE_ENTRY", fields),
|
|
30
|
-
locked: (scope, msg, fields) => new AccountingError(msg, 409, `PERIOD_LOCKED_${scope.toUpperCase()}`, fields)
|
|
31
|
-
};
|
|
32
|
-
//#endregion
|
|
33
|
-
export { Errors as n, AccountingError as t };
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|