@mulmoclaude/accounting-plugin 0.1.0 → 0.1.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.
@@ -1,11 +1,13 @@
1
1
  export interface WriteAtomicOptions {
2
- /** Adds a unique suffix to the tmp filename so concurrent writers to
3
- * the same destination don't collide at the OS layer. */
2
+ /** Use a per-write unique tmp filename. Defaults to `true` so two
3
+ * concurrent writers targeting the same destination never race on a
4
+ * shared `${filePath}.tmp` (one renaming/unlinking the other's tmp).
5
+ * Pass `false` only when a stable tmp name is required. */
4
6
  uniqueTmp?: boolean;
5
7
  }
6
8
  /** True for a `not found` filesystem error. */
7
9
  export declare function isEnoent(err: unknown): boolean;
8
- /** Atomic write: tmp alongside destination, then rename. */
10
+ /** Atomic write: unique tmp alongside destination, then rename. */
9
11
  export declare function writeFileAtomic(filePath: string, content: string, opts?: WriteAtomicOptions): Promise<void>;
10
12
  /** Atomic JSON write (2-space indent), the only serialization shape the
11
13
  * accounting io layer needs. */
@@ -1 +1 @@
1
- {"version":3,"file":"atomic.d.ts","sourceRoot":"","sources":["../../src/server/atomic.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,kBAAkB;IACjC;8DAC0D;IAC1D,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,+CAA+C;AAC/C,wBAAgB,QAAQ,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAE9C;AAED,4DAA4D;AAC5D,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,kBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAUrH;AAED;iCACiC;AACjC,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,GAAE,kBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAEnH"}
1
+ {"version":3,"file":"atomic.d.ts","sourceRoot":"","sources":["../../src/server/atomic.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,kBAAkB;IACjC;;;gEAG4D;IAC5D,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,+CAA+C;AAC/C,wBAAgB,QAAQ,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAE9C;AAiCD,mEAAmE;AACnE,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,kBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAWrH;AAED;iCACiC;AACjC,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,GAAE,kBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAEnH"}
@@ -29,11 +29,4 @@ export declare function defaultWorkspaceRoot(): string;
29
29
  /** Logger proxy — forwards to the injected logger, console fallback
30
30
  * before configuration. Lets call sites keep `log.warn("accounting", …)`. */
31
31
  export declare const log: AccountingLogger;
32
- /** Workspace-relative directories this plugin owns. Mirrors the host
33
- * META's `workspaceDirs` (kept in sync by value; the host META stays
34
- * the codegen-discoverable source for the aggregator merge). */
35
- export declare const ACCOUNTING_DIRS: {
36
- readonly accounting: "data/accounting";
37
- readonly accountingBooks: "data/accounting/books";
38
- };
39
32
  //# sourceMappingURL=context.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/server/context.ts"],"names":[],"mappings":"AAcA;;kEAEkE;AAClE,MAAM,WAAW,OAAO;IACtB,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;CACtD;AAED;;;gDAGgD;AAChD,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IACpF,IAAI,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IACnF,IAAI,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IACnF,KAAK,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;CACrF;AAED,MAAM,WAAW,oBAAoB;IACnC;4EACwE;IACxE,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,gBAAgB,CAAC;CAC1B;AAID,uEAAuE;AACvE,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,oBAAoB,GAAG,IAAI,CAE7E;AAED;;yEAEyE;AACzE,wBAAgB,oBAAoB,IAAI,MAAM,CAK7C;AASD;8EAC8E;AAC9E,eAAO,MAAM,GAAG,EAAE,gBAKjB,CAAC;AAEF;;iEAEiE;AACjE,eAAO,MAAM,eAAe;;;CAGlB,CAAC"}
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/server/context.ts"],"names":[],"mappings":"AAcA;;kEAEkE;AAClE,MAAM,WAAW,OAAO;IACtB,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;CACtD;AAED;;;gDAGgD;AAChD,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IACpF,IAAI,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IACnF,IAAI,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IACnF,KAAK,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;CACrF;AAED,MAAM,WAAW,oBAAoB;IACnC;4EACwE;IACxE,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,gBAAgB,CAAC;CAC1B;AAID,uEAAuE;AACvE,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,oBAAoB,GAAG,IAAI,CAE7E;AAED;;yEAEyE;AACzE,wBAAgB,oBAAoB,IAAI,MAAM,CAK7C;AASD;8EAC8E;AAC9E,eAAO,MAAM,GAAG,EAAE,gBAKjB,CAAC"}
@@ -1,3 +1,3 @@
1
- import type { Request, Response } from "express";
2
- export declare function asyncHandler<TReq = Request, TRes = Response>(namespace: string, fallbackMessage: string, handler: (req: TReq, res: TRes) => Promise<void>): (req: TReq, res: TRes) => Promise<void>;
1
+ import type { Request, Response, NextFunction } from "express";
2
+ export declare function asyncHandler<TReq = Request, TRes = Response>(namespace: string, fallbackMessage: string, handler: (req: TReq, res: TRes) => Promise<void>): (req: TReq, res: TRes, next: NextFunction) => Promise<void>;
3
3
  //# sourceMappingURL=http.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/server/http.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAIjD,wBAAgB,YAAY,CAAC,IAAI,GAAG,OAAO,EAAE,IAAI,GAAG,QAAQ,EAC1D,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE,MAAM,EACvB,OAAO,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,GAC/C,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,CAazC"}
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/server/http.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAI/D,wBAAgB,YAAY,CAAC,IAAI,GAAG,OAAO,EAAE,IAAI,GAAG,QAAQ,EAC1D,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE,MAAM,EACvB,OAAO,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,GAC/C,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAkB7D"}
@@ -1 +1 @@
1
- {"version":3,"file":"io.d.ts","sourceRoot":"","sources":["../../src/server/io.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,gBAAgB,EAAE,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAsBzF,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEpD;AAQD,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,CAGvE;AAiDD,wBAAsB,UAAU,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAEzF;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE,gBAAgB,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEjG;AAID,wBAAsB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAG7F;AAED,wBAAsB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE9G;AAID;iEACiE;AACjE,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAQnD;AAED;;;;;;;;;;;;;kBAakB;AAClB,wBAAsB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAK9G;AAaD;;;;;;;;;6DAS6D;AAC7D,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,YAAY,EAAE,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAShI;AAED;;4DAE4D;AAC5D,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,YAAY,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAoBpJ;AAED;;qBAEqB;AACrB,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAYlG;AAID,wBAAsB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAExH;AAED,wBAAsB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CASlH;AAED;;eAEe;AACf,wBAAsB,uBAAuB,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAmBxI;AAED;;4CAE4C;AAC5C,wBAAsB,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAEnH;AAID,wBAAsB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAEzF;AAED,wBAAsB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAIzF;AAED;qDACqD;AACrD,wBAAsB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEzF"}
1
+ {"version":3,"file":"io.d.ts","sourceRoot":"","sources":["../../src/server/io.ts"],"names":[],"mappings":"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"}
package/dist/server.cjs CHANGED
@@ -54,26 +54,42 @@ var log = {
54
54
  info: (namespace, msg, data) => (deps?.logger ?? consoleLogger).info(namespace, msg, data),
55
55
  debug: (namespace, msg, data) => (deps?.logger ?? consoleLogger).debug(namespace, msg, data)
56
56
  };
57
- /** Workspace-relative directories this plugin owns. Mirrors the host
58
- * META's `workspaceDirs` (kept in sync by value; the host META stays
59
- * the codegen-discoverable source for the aggregator merge). */
60
- var ACCOUNTING_DIRS = {
61
- accounting: "data/accounting",
62
- accountingBooks: "data/accounting/books"
63
- };
64
57
  //#endregion
65
58
  //#region src/server/atomic.ts
66
59
  /** True for a `not found` filesystem error. */
67
60
  function isEnoent(err) {
68
61
  return typeof err === "object" && err !== null && "code" in err && err.code === "ENOENT";
69
62
  }
70
- /** Atomic write: tmp alongside destination, then rename. */
63
+ var IS_WINDOWS = process.platform === "win32";
64
+ var RENAME_RETRY_DELAYS_MS = [
65
+ 30,
66
+ 100,
67
+ 300
68
+ ];
69
+ function hasErrnoCode(err) {
70
+ return typeof err === "object" && err !== null && "code" in err && typeof err.code === "string";
71
+ }
72
+ function isTransientRenameError(err) {
73
+ if (!IS_WINDOWS || !hasErrnoCode(err)) return false;
74
+ return err.code === "EPERM" || err.code === "EBUSY" || err.code === "EACCES";
75
+ }
76
+ async function renameWithWindowsRetry(fromPath, toPath) {
77
+ for (const delayMs of RENAME_RETRY_DELAYS_MS) try {
78
+ await node_fs.promises.rename(fromPath, toPath);
79
+ return;
80
+ } catch (err) {
81
+ if (!isTransientRenameError(err)) throw err;
82
+ await new Promise((resolve) => setTimeout(resolve, delayMs));
83
+ }
84
+ await node_fs.promises.rename(fromPath, toPath);
85
+ }
86
+ /** Atomic write: unique tmp alongside destination, then rename. */
71
87
  async function writeFileAtomic(filePath, content, opts = {}) {
72
- const tmp = opts.uniqueTmp ? `${filePath}.${(0, node_crypto.randomUUID)()}.tmp` : `${filePath}.tmp`;
88
+ const tmp = opts.uniqueTmp ?? true ? `${filePath}.${(0, node_crypto.randomUUID)()}.tmp` : `${filePath}.tmp`;
73
89
  await node_fs.promises.mkdir(node_path.default.dirname(filePath), { recursive: true });
74
90
  try {
75
91
  await node_fs.promises.writeFile(tmp, content, { encoding: "utf-8" });
76
- await node_fs.promises.rename(tmp, filePath);
92
+ await renameWithWindowsRetry(tmp, filePath);
77
93
  } catch (err) {
78
94
  await node_fs.promises.unlink(tmp).catch(() => {});
79
95
  throw err;
@@ -88,7 +104,7 @@ async function writeJsonAtomic(filePath, data, opts = {}) {
88
104
  //#region src/server/io.ts
89
105
  var root = (workspaceRoot) => workspaceRoot ?? defaultWorkspaceRoot();
90
106
  function accountingRoot(workspaceRoot) {
91
- return node_path.default.join(root(workspaceRoot), ACCOUNTING_DIRS.accounting);
107
+ return node_path.default.join(root(workspaceRoot), require_shared.ACCOUNTING_DIRS.accounting);
92
108
  }
93
109
  function configPath(workspaceRoot) {
94
110
  return node_path.default.join(accountingRoot(workspaceRoot), "config.json");
@@ -110,7 +126,7 @@ function assertSafeBookId(bookId) {
110
126
  }
111
127
  function bookRoot(bookId, workspaceRoot) {
112
128
  assertSafeBookId(bookId);
113
- return node_path.default.join(root(workspaceRoot), ACCOUNTING_DIRS.accountingBooks, bookId);
129
+ return node_path.default.join(root(workspaceRoot), require_shared.ACCOUNTING_DIRS.accountingBooks, bookId);
114
130
  }
115
131
  function accountsPath(bookId, workspaceRoot) {
116
132
  return node_path.default.join(bookRoot(bookId, workspaceRoot), "accounts.json");
@@ -1851,7 +1867,7 @@ async function rebuildSnapshots(input, workspaceRoot) {
1851
1867
  //#endregion
1852
1868
  //#region src/server/http.ts
1853
1869
  function asyncHandler(namespace, fallbackMessage, handler) {
1854
- return async (req, res) => {
1870
+ return async (req, res, next) => {
1855
1871
  try {
1856
1872
  await handler(req, res);
1857
1873
  } catch (err) {
@@ -1861,7 +1877,11 @@ function asyncHandler(namespace, fallbackMessage, handler) {
1861
1877
  route: expressReq.path,
1862
1878
  error: require_shared.errorMessage(err)
1863
1879
  });
1864
- if (!expressRes.headersSent) expressRes.status(500).json({ error: fallbackMessage });
1880
+ if (expressRes.headersSent) {
1881
+ next(err);
1882
+ return;
1883
+ }
1884
+ expressRes.status(500).json({ error: fallbackMessage });
1865
1885
  }
1866
1886
  };
1867
1887
  }
@@ -2061,7 +2081,7 @@ async function dispatch(body) {
2061
2081
  * with `app.use(...)`. */
2062
2082
  function createAccountingRouter() {
2063
2083
  const router = (0, express.Router)();
2064
- router.post("/api/accounting", asyncHandler("accounting", "accounting dispatch failed", async (req, res) => {
2084
+ router.post(require_shared.ACCOUNTING_API.dispatch.path, asyncHandler("accounting", "accounting dispatch failed", async (req, res) => {
2065
2085
  const { body } = req;
2066
2086
  if (!body || typeof body !== "object" || typeof body.action !== "string") {
2067
2087
  log.warn("accounting", "POST dispatch: invalid body");