@mulmoclaude/accounting-plugin 0.3.3 → 1.0.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/dist/server/accountNormalize.d.ts +1 -1
- package/dist/server/accountNormalize.d.ts.map +1 -1
- package/dist/server/context.d.ts +3 -10
- package/dist/server/context.d.ts.map +1 -1
- package/dist/server/defaultAccounts.d.ts +1 -1
- package/dist/server/defaultAccounts.d.ts.map +1 -1
- package/dist/server/http.d.ts.map +1 -1
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/io.d.ts +2 -1
- package/dist/server/io.d.ts.map +1 -1
- package/dist/server/journal.d.ts +1 -1
- package/dist/server/journal.d.ts.map +1 -1
- package/dist/server/openingBalances.d.ts +1 -1
- package/dist/server/openingBalances.d.ts.map +1 -1
- package/dist/server/report.d.ts +6 -64
- package/dist/server/report.d.ts.map +1 -1
- package/dist/server/service.d.ts +1 -1
- package/dist/server/service.d.ts.map +1 -1
- package/dist/server/snapshotCache.d.ts +2 -1
- package/dist/server/snapshotCache.d.ts.map +1 -1
- package/dist/server/timeSeries.d.ts +1 -1
- package/dist/server/timeSeries.d.ts.map +1 -1
- package/dist/server/types.d.ts +1 -123
- package/dist/server/types.d.ts.map +1 -1
- package/dist/server.cjs +22 -73
- package/dist/server.cjs.map +1 -1
- package/dist/server.js +14 -65
- package/dist/server.js.map +1 -1
- package/dist/shared/errors.d.ts +1 -1
- package/dist/shared/errors.d.ts.map +1 -1
- package/dist/shared/index.d.ts +1 -0
- package/dist/shared/index.d.ts.map +1 -1
- package/dist/shared/types.d.ts +188 -0
- package/dist/shared/types.d.ts.map +1 -0
- package/dist/shared-CcU3_qAa.cjs +749 -0
- package/dist/shared-CcU3_qAa.cjs.map +1 -0
- package/dist/shared-MOpJ1kUa.js +516 -0
- package/dist/shared-MOpJ1kUa.js.map +1 -0
- package/dist/shared.cjs +40 -519
- package/dist/shared.js +2 -483
- package/dist/vue/api.d.ts +2 -121
- package/dist/vue/api.d.ts.map +1 -1
- package/dist/vue/lang/index.d.ts +204 -215
- package/dist/vue/lang/index.d.ts.map +1 -1
- package/dist/vue.cjs +1651 -1678
- package/dist/vue.cjs.map +1 -1
- package/dist/vue.js +1652 -1679
- package/dist/vue.js.map +1 -1
- package/package.json +11 -6
- package/dist/server/atomic.d.ts +0 -15
- package/dist/server/atomic.d.ts.map +0 -1
- package/dist/shared.cjs.map +0 -1
- package/dist/shared.js.map +0 -1
package/dist/server.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { A as resolveFiscalYearEnd, D as isFiscalYearEnd, F as bookChannel, L as BALANCE_SHEET_ACCOUNT_TYPES, M as errorMessage, N as ACCOUNTING_BOOKS_CHANNEL, P as BOOK_EVENT_KINDS, R as ACCOUNTING_API, S as FISCAL_YEAR_END_MONTHS, T as fiscalYearEndMonth, _ as SUPPORTED_COUNTRY_CODES, j as ACCOUNTING_DIRS, n as TIME_SERIES_METRICS, t as TIME_SERIES_GRANULARITIES, y as isSupportedCountryCode, z as ACCOUNTING_ACTIONS } from "./shared-MOpJ1kUa.js";
|
|
2
2
|
import { Router } from "express";
|
|
3
3
|
import { randomUUID } from "node:crypto";
|
|
4
4
|
import { promises } from "node:fs";
|
|
5
5
|
import path from "node:path";
|
|
6
|
+
import { isEnoent, writeJsonAtomic } from "@mulmoclaude/core/files";
|
|
6
7
|
//#region src/server/context.ts
|
|
7
8
|
var deps = null;
|
|
8
9
|
/** Called once by the host before the accounting router is mounted. */
|
|
@@ -31,52 +32,6 @@ var log = {
|
|
|
31
32
|
debug: (namespace, msg, data) => (deps?.logger ?? consoleLogger).debug(namespace, msg, data)
|
|
32
33
|
};
|
|
33
34
|
//#endregion
|
|
34
|
-
//#region src/server/atomic.ts
|
|
35
|
-
/** True for a `not found` filesystem error. */
|
|
36
|
-
function isEnoent(err) {
|
|
37
|
-
return typeof err === "object" && err !== null && "code" in err && err.code === "ENOENT";
|
|
38
|
-
}
|
|
39
|
-
var IS_WINDOWS = process.platform === "win32";
|
|
40
|
-
var RENAME_RETRY_DELAYS_MS = [
|
|
41
|
-
30,
|
|
42
|
-
100,
|
|
43
|
-
300
|
|
44
|
-
];
|
|
45
|
-
function hasErrnoCode(err) {
|
|
46
|
-
return typeof err === "object" && err !== null && "code" in err && typeof err.code === "string";
|
|
47
|
-
}
|
|
48
|
-
function isTransientRenameError(err) {
|
|
49
|
-
if (!IS_WINDOWS || !hasErrnoCode(err)) return false;
|
|
50
|
-
return err.code === "EPERM" || err.code === "EBUSY" || err.code === "EACCES";
|
|
51
|
-
}
|
|
52
|
-
async function renameWithWindowsRetry(fromPath, toPath) {
|
|
53
|
-
for (const delayMs of RENAME_RETRY_DELAYS_MS) try {
|
|
54
|
-
await promises.rename(fromPath, toPath);
|
|
55
|
-
return;
|
|
56
|
-
} catch (err) {
|
|
57
|
-
if (!isTransientRenameError(err)) throw err;
|
|
58
|
-
await new Promise((resolve) => setTimeout(resolve, delayMs));
|
|
59
|
-
}
|
|
60
|
-
await promises.rename(fromPath, toPath);
|
|
61
|
-
}
|
|
62
|
-
/** Atomic write: unique tmp alongside destination, then rename. */
|
|
63
|
-
async function writeFileAtomic(filePath, content, opts = {}) {
|
|
64
|
-
const tmp = opts.uniqueTmp ?? true ? `${filePath}.${randomUUID()}.tmp` : `${filePath}.tmp`;
|
|
65
|
-
await promises.mkdir(path.dirname(filePath), { recursive: true });
|
|
66
|
-
try {
|
|
67
|
-
await promises.writeFile(tmp, content, { encoding: "utf-8" });
|
|
68
|
-
await renameWithWindowsRetry(tmp, filePath);
|
|
69
|
-
} catch (err) {
|
|
70
|
-
await promises.unlink(tmp).catch(() => {});
|
|
71
|
-
throw err;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
/** Atomic JSON write (2-space indent), the only serialization shape the
|
|
75
|
-
* accounting io layer needs. */
|
|
76
|
-
async function writeJsonAtomic(filePath, data, opts = {}) {
|
|
77
|
-
await writeFileAtomic(filePath, JSON.stringify(data, null, 2), opts);
|
|
78
|
-
}
|
|
79
|
-
//#endregion
|
|
80
35
|
//#region src/server/io.ts
|
|
81
36
|
var root = (workspaceRoot) => workspaceRoot ?? defaultWorkspaceRoot();
|
|
82
37
|
function accountingRoot(workspaceRoot) {
|
|
@@ -325,16 +280,6 @@ async function removeBookDir(bookId, workspaceRoot) {
|
|
|
325
280
|
});
|
|
326
281
|
}
|
|
327
282
|
//#endregion
|
|
328
|
-
//#region src/server/types.ts
|
|
329
|
-
/** B/S accounts (assets / liabilities / equity). Used by opening
|
|
330
|
-
* balance validation: opening entries reference balance-sheet
|
|
331
|
-
* accounts only. */
|
|
332
|
-
var BALANCE_SHEET_ACCOUNT_TYPES = [
|
|
333
|
-
"asset",
|
|
334
|
-
"liability",
|
|
335
|
-
"equity"
|
|
336
|
-
];
|
|
337
|
-
//#endregion
|
|
338
283
|
//#region src/server/journal.ts
|
|
339
284
|
/** Floating-point tolerance for the debit = credit check. Currency
|
|
340
285
|
* amounts arrive as JavaScript numbers (the on-wire format is JSON,
|
|
@@ -637,6 +582,16 @@ function normalizeStoredAccount(input, existing) {
|
|
|
637
582
|
//#endregion
|
|
638
583
|
//#region src/server/report.ts
|
|
639
584
|
var ZERO_TOLERANCE = .0049;
|
|
585
|
+
/** Collapse an accountCode → netDebit map into the sorted
|
|
586
|
+
* `AccountBalance[]` wire shape. Shared by `aggregateBalances` and
|
|
587
|
+
* the snapshot cache's `mergeBalances` so the two produce identical,
|
|
588
|
+
* deterministically ordered output. */
|
|
589
|
+
function sortedBalancesFromMap(balanceByCode) {
|
|
590
|
+
return Array.from(balanceByCode.entries()).map(([accountCode, netDebit]) => ({
|
|
591
|
+
accountCode,
|
|
592
|
+
netDebit
|
|
593
|
+
})).sort((lhs, rhs) => lhs.accountCode.localeCompare(rhs.accountCode));
|
|
594
|
+
}
|
|
640
595
|
/** Returns net (debit − credit) per account across the supplied
|
|
641
596
|
* entries. Voids work by having an original + reverse pair that
|
|
642
597
|
* cancel mathematically — both are included in aggregation (their
|
|
@@ -658,10 +613,7 @@ function aggregateBalances(entries) {
|
|
|
658
613
|
map.set(line.accountCode, cur + debit - credit);
|
|
659
614
|
}
|
|
660
615
|
}
|
|
661
|
-
return
|
|
662
|
-
accountCode,
|
|
663
|
-
netDebit
|
|
664
|
-
})).sort((lhs, rhs) => lhs.accountCode.localeCompare(rhs.accountCode));
|
|
616
|
+
return sortedBalancesFromMap(map);
|
|
665
617
|
}
|
|
666
618
|
function naturalSign$1(type, netDebit) {
|
|
667
619
|
if (type === "asset" || type === "expense") return netDebit;
|
|
@@ -1012,10 +964,7 @@ function mergeBalances(base, delta) {
|
|
|
1012
964
|
const map = /* @__PURE__ */ new Map();
|
|
1013
965
|
for (const row of base) map.set(row.accountCode, row.netDebit);
|
|
1014
966
|
for (const row of delta) map.set(row.accountCode, (map.get(row.accountCode) ?? 0) + row.netDebit);
|
|
1015
|
-
return
|
|
1016
|
-
accountCode,
|
|
1017
|
-
netDebit
|
|
1018
|
-
})).sort((lhs, rhs) => lhs.accountCode.localeCompare(rhs.accountCode));
|
|
967
|
+
return sortedBalancesFromMap(map);
|
|
1019
968
|
}
|
|
1020
969
|
async function buildEmptySnapshot(bookId, period, workspaceRoot) {
|
|
1021
970
|
const empty = {
|