cata-centavo 0.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/LICENSE +21 -0
- package/README.md +159 -0
- package/dist/bin/cata-centavo.js +226 -0
- package/dist/bin/cata-centavo.js.map +1 -0
- package/dist/cli/dispatch.js +67 -0
- package/dist/cli/dispatch.js.map +1 -0
- package/dist/cli/doctor.js +178 -0
- package/dist/cli/doctor.js.map +1 -0
- package/dist/cli/init.js +125 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/progress.js +85 -0
- package/dist/cli/progress.js.map +1 -0
- package/dist/cli/sync.js +26 -0
- package/dist/cli/sync.js.map +1 -0
- package/dist/config.js +119 -0
- package/dist/config.js.map +1 -0
- package/dist/core/account.js +12 -0
- package/dist/core/account.js.map +1 -0
- package/dist/core/accounts.js +91 -0
- package/dist/core/accounts.js.map +1 -0
- package/dist/core/aggregate.js +83 -0
- package/dist/core/aggregate.js.map +1 -0
- package/dist/core/balance.js +68 -0
- package/dist/core/balance.js.map +1 -0
- package/dist/core/bill-rows.js +132 -0
- package/dist/core/bill-rows.js.map +1 -0
- package/dist/core/bill.js +103 -0
- package/dist/core/bill.js.map +1 -0
- package/dist/core/category-source.js +26 -0
- package/dist/core/category-source.js.map +1 -0
- package/dist/core/category.js +72 -0
- package/dist/core/category.js.map +1 -0
- package/dist/core/consent.js +19 -0
- package/dist/core/consent.js.map +1 -0
- package/dist/core/contracts.js +9 -0
- package/dist/core/contracts.js.map +1 -0
- package/dist/core/counterparty.js +69 -0
- package/dist/core/counterparty.js.map +1 -0
- package/dist/core/date.js +25 -0
- package/dist/core/date.js.map +1 -0
- package/dist/core/description.js +58 -0
- package/dist/core/description.js.map +1 -0
- package/dist/core/diagnose.js +32 -0
- package/dist/core/diagnose.js.map +1 -0
- package/dist/core/mcc.js +124 -0
- package/dist/core/mcc.js.map +1 -0
- package/dist/core/refresh.js +142 -0
- package/dist/core/refresh.js.map +1 -0
- package/dist/core/self-transfer.js +22 -0
- package/dist/core/self-transfer.js.map +1 -0
- package/dist/core/taxonomy-tree.js +148 -0
- package/dist/core/taxonomy-tree.js.map +1 -0
- package/dist/core/taxonomy.js +70 -0
- package/dist/core/taxonomy.js.map +1 -0
- package/dist/core/transaction.js +2 -0
- package/dist/core/transaction.js.map +1 -0
- package/dist/core/transactions.js +46 -0
- package/dist/core/transactions.js.map +1 -0
- package/dist/logging.js +93 -0
- package/dist/logging.js.map +1 -0
- package/dist/mcp/cursor.js +64 -0
- package/dist/mcp/cursor.js.map +1 -0
- package/dist/mcp/format.js +38 -0
- package/dist/mcp/format.js.map +1 -0
- package/dist/mcp/server.js +50 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/source.js +2 -0
- package/dist/mcp/source.js.map +1 -0
- package/dist/mcp/tools/accounts.js +144 -0
- package/dist/mcp/tools/accounts.js.map +1 -0
- package/dist/mcp/tools/balance.js +96 -0
- package/dist/mcp/tools/balance.js.map +1 -0
- package/dist/mcp/tools/bill-summary-format.js +161 -0
- package/dist/mcp/tools/bill-summary-format.js.map +1 -0
- package/dist/mcp/tools/bill-summary.js +105 -0
- package/dist/mcp/tools/bill-summary.js.map +1 -0
- package/dist/mcp/tools/bills.js +144 -0
- package/dist/mcp/tools/bills.js.map +1 -0
- package/dist/mcp/tools/closing-days.js +90 -0
- package/dist/mcp/tools/closing-days.js.map +1 -0
- package/dist/mcp/tools/list-transactions.js +122 -0
- package/dist/mcp/tools/list-transactions.js.map +1 -0
- package/dist/mcp/tools/result.js +12 -0
- package/dist/mcp/tools/result.js.map +1 -0
- package/dist/mcp/tools/set-category.js +74 -0
- package/dist/mcp/tools/set-category.js.map +1 -0
- package/dist/mcp/tools/sources.js +73 -0
- package/dist/mcp/tools/sources.js.map +1 -0
- package/dist/mcp/tools/transaction-details.js +146 -0
- package/dist/mcp/tools/transaction-details.js.map +1 -0
- package/dist/mcp/tools/transaction-input.js +51 -0
- package/dist/mcp/tools/transaction-input.js.map +1 -0
- package/dist/mcp/tools/transactions.js +186 -0
- package/dist/mcp/tools/transactions.js.map +1 -0
- package/dist/pluggy/client.js +123 -0
- package/dist/pluggy/client.js.map +1 -0
- package/dist/pluggy/errors.js +152 -0
- package/dist/pluggy/errors.js.map +1 -0
- package/dist/pluggy/mapper.js +155 -0
- package/dist/pluggy/mapper.js.map +1 -0
- package/dist/pluggy/money.js +53 -0
- package/dist/pluggy/money.js.map +1 -0
- package/dist/pluggy/transaction-mapper.js +124 -0
- package/dist/pluggy/transaction-mapper.js.map +1 -0
- package/dist/pluggy/transport.js +170 -0
- package/dist/pluggy/transport.js.map +1 -0
- package/dist/pluggy/wire.js +207 -0
- package/dist/pluggy/wire.js.map +1 -0
- package/dist/storage/categories.js +101 -0
- package/dist/storage/categories.js.map +1 -0
- package/dist/storage/category-sql.js +37 -0
- package/dist/storage/category-sql.js.map +1 -0
- package/dist/storage/closing-days.js +27 -0
- package/dist/storage/closing-days.js.map +1 -0
- package/dist/storage/db.js +162 -0
- package/dist/storage/db.js.map +1 -0
- package/dist/storage/diagnostics.js +57 -0
- package/dist/storage/diagnostics.js.map +1 -0
- package/dist/storage/harvest.js +87 -0
- package/dist/storage/harvest.js.map +1 -0
- package/dist/storage/migrations.js +125 -0
- package/dist/storage/migrations.js.map +1 -0
- package/dist/storage/transaction-row.js +74 -0
- package/dist/storage/transaction-row.js.map +1 -0
- package/dist/storage/transactions.js +213 -0
- package/dist/storage/transactions.js.map +1 -0
- package/package.json +70 -0
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import { DERIVED_CATEGORY, DERIVED_COLUMNS } from "./category-sql.js";
|
|
2
|
+
import { harvest } from "./harvest.js";
|
|
3
|
+
import { rowToDerived, transactionValues } from "./transaction-row.js";
|
|
4
|
+
const TRANSACTION_COLUMNS = [
|
|
5
|
+
"id", "account_id", "connection_id", "account_type", "account_subtype",
|
|
6
|
+
"occurred_at", "local_date", "amount_cents", "currency", "original_amount_cents",
|
|
7
|
+
"original_currency", "description", "description_norm", "category_id", "document",
|
|
8
|
+
"counterparty_name", "payment_method", "mcc", "bill_id", "instalment_number",
|
|
9
|
+
"bill_forecast_date", "instalment_total", "purchase_date", "top_category_id",
|
|
10
|
+
];
|
|
11
|
+
function placeholders(n) {
|
|
12
|
+
return Array(n).fill("?").join(", ");
|
|
13
|
+
}
|
|
14
|
+
const TRANSACTION_INSERT = `
|
|
15
|
+
INSERT INTO transactions (${TRANSACTION_COLUMNS.join(", ")})
|
|
16
|
+
VALUES (${placeholders(TRANSACTION_COLUMNS.length)})
|
|
17
|
+
ON CONFLICT(id) DO UPDATE SET
|
|
18
|
+
account_id = excluded.account_id,
|
|
19
|
+
connection_id = excluded.connection_id,
|
|
20
|
+
account_type = excluded.account_type,
|
|
21
|
+
account_subtype = excluded.account_subtype,
|
|
22
|
+
occurred_at = excluded.occurred_at,
|
|
23
|
+
local_date = excluded.local_date,
|
|
24
|
+
amount_cents = excluded.amount_cents,
|
|
25
|
+
currency = excluded.currency,
|
|
26
|
+
original_amount_cents = excluded.original_amount_cents,
|
|
27
|
+
original_currency = excluded.original_currency,
|
|
28
|
+
description = excluded.description,
|
|
29
|
+
description_norm = excluded.description_norm,
|
|
30
|
+
category_id = excluded.category_id,
|
|
31
|
+
document = excluded.document,
|
|
32
|
+
counterparty_name = excluded.counterparty_name,
|
|
33
|
+
payment_method = excluded.payment_method,
|
|
34
|
+
mcc = excluded.mcc,
|
|
35
|
+
bill_id = excluded.bill_id,
|
|
36
|
+
instalment_number = excluded.instalment_number,
|
|
37
|
+
bill_forecast_date = excluded.bill_forecast_date,
|
|
38
|
+
instalment_total = excluded.instalment_total,
|
|
39
|
+
purchase_date = excluded.purchase_date,
|
|
40
|
+
top_category_id = excluded.top_category_id
|
|
41
|
+
`;
|
|
42
|
+
const systemClock = { now: () => new Date() };
|
|
43
|
+
export function createTransactionStore(db, log, clock = systemClock) {
|
|
44
|
+
const insert = db.prepare(TRANSACTION_INSERT);
|
|
45
|
+
const deleteMissing = db.prepare("DELETE FROM transactions WHERE account_id = ? AND id NOT IN (SELECT value FROM json_each(?))");
|
|
46
|
+
const stamp = db.prepare(`
|
|
47
|
+
INSERT INTO transaction_sync (account_id, connection_id, last_updated_at)
|
|
48
|
+
VALUES (?, ?, ?)
|
|
49
|
+
ON CONFLICT(account_id) DO UPDATE SET
|
|
50
|
+
connection_id = excluded.connection_id,
|
|
51
|
+
last_updated_at = excluded.last_updated_at
|
|
52
|
+
`);
|
|
53
|
+
return {
|
|
54
|
+
syncedLastUpdatedAt: (accountId) => readFreshness(db, accountId),
|
|
55
|
+
replaceAccount: (accountId, connectionId, rows, lastUpdatedAt) => {
|
|
56
|
+
return replaceAccount({ db, insert, deleteMissing, stamp, accountId, connectionId, rows, lastUpdatedAt, log, clock });
|
|
57
|
+
},
|
|
58
|
+
query: (filter) => queryTransactions(db, filter),
|
|
59
|
+
byIds: (ids) => findByIds(db, ids),
|
|
60
|
+
cardRows: (accountId) => findCardRows(db, accountId),
|
|
61
|
+
dataThrough: (accountIds, today) => readDataThrough(db, accountIds, today),
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
function replaceAccount(options) {
|
|
65
|
+
options.db.exec("BEGIN");
|
|
66
|
+
try {
|
|
67
|
+
for (const row of options.rows) {
|
|
68
|
+
options.insert.run(...transactionValues(row, options.log));
|
|
69
|
+
}
|
|
70
|
+
const deleteResult = options.deleteMissing.run(options.accountId, JSON.stringify(options.rows.map((row) => row.id)));
|
|
71
|
+
options.stamp.run(options.accountId, options.connectionId, options.lastUpdatedAt);
|
|
72
|
+
harvest({ db: options.db, rows: options.rows, log: options.log, clock: options.clock });
|
|
73
|
+
options.db.exec("COMMIT");
|
|
74
|
+
return Number(deleteResult.changes);
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
options.db.exec("ROLLBACK");
|
|
78
|
+
throw error;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
function queryTransactions(db, filter) {
|
|
82
|
+
// Stryker disable next-line ConditionalExpression,BlockStatement: an empty SQL IN list is already empty in SQLite; this guard keeps the domain contract explicit.
|
|
83
|
+
if (filter.accountIds.length === 0) {
|
|
84
|
+
return [];
|
|
85
|
+
}
|
|
86
|
+
const query = buildQuery(filter);
|
|
87
|
+
const rows = db.prepare(query.sql).all(...query.parameters);
|
|
88
|
+
return rows.map((row) => rowToDerived(row));
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* The cheap filters run inside the CTE so the six correlated subqueries of
|
|
92
|
+
* `DERIVED_COLUMNS` only touch rows that already survived them. The category
|
|
93
|
+
* filter has to run outside, because it compares the derived value.
|
|
94
|
+
*/
|
|
95
|
+
function buildQuery(filter) {
|
|
96
|
+
const conditions = [
|
|
97
|
+
`t.account_id IN (${placeholders(filter.accountIds.length)})`,
|
|
98
|
+
"t.local_date >= ?",
|
|
99
|
+
"t.local_date <= ?",
|
|
100
|
+
];
|
|
101
|
+
const parameters = [...filter.accountIds, filter.from, filter.to];
|
|
102
|
+
addAmountFilters(conditions, parameters, filter.minAmountCents, filter.maxAmountCents);
|
|
103
|
+
addAccountFilters(conditions, parameters, filter.accountType, filter.accountSubtype);
|
|
104
|
+
addKeysetFilter(conditions, parameters, filter.after);
|
|
105
|
+
let sql = `WITH derived AS (
|
|
106
|
+
SELECT t.${TRANSACTION_COLUMNS.join(", t.")}, ${DERIVED_COLUMNS}
|
|
107
|
+
FROM transactions t
|
|
108
|
+
WHERE ${conditions.join(" AND ")}
|
|
109
|
+
) SELECT * FROM derived`;
|
|
110
|
+
if (filter.categories !== undefined) {
|
|
111
|
+
const category = categoryCondition(filter.categories);
|
|
112
|
+
sql += ` WHERE ${category.sql}`;
|
|
113
|
+
parameters.push(...category.parameters);
|
|
114
|
+
}
|
|
115
|
+
sql += " ORDER BY local_date DESC, id DESC";
|
|
116
|
+
if (filter.limit !== undefined) {
|
|
117
|
+
sql += " LIMIT ?";
|
|
118
|
+
parameters.push(filter.limit);
|
|
119
|
+
}
|
|
120
|
+
return { sql, parameters };
|
|
121
|
+
}
|
|
122
|
+
function categoryCondition(categories) {
|
|
123
|
+
// Stryker disable next-line ConditionalExpression,BlockStatement: an empty category filter must remain an explicit no-match query.
|
|
124
|
+
if (categories.length === 0) {
|
|
125
|
+
return { sql: "1 = 0", parameters: [] };
|
|
126
|
+
}
|
|
127
|
+
const ids = categories.filter((value) => value !== "none");
|
|
128
|
+
const wantsNone = categories.length !== ids.length;
|
|
129
|
+
const clauses = [];
|
|
130
|
+
if (ids.length > 0) {
|
|
131
|
+
clauses.push(`${DERIVED_CATEGORY} IN (${placeholders(ids.length)})`);
|
|
132
|
+
}
|
|
133
|
+
if (wantsNone) {
|
|
134
|
+
clauses.push(`${DERIVED_CATEGORY} IS NULL`);
|
|
135
|
+
}
|
|
136
|
+
return { sql: `(${clauses.join(" OR ")})`, parameters: ids };
|
|
137
|
+
}
|
|
138
|
+
function addAmountFilters(conditions, parameters, minAmountCents, maxAmountCents) {
|
|
139
|
+
if (minAmountCents !== undefined) {
|
|
140
|
+
conditions.push("t.amount_cents >= ?");
|
|
141
|
+
parameters.push(minAmountCents);
|
|
142
|
+
}
|
|
143
|
+
if (maxAmountCents !== undefined) {
|
|
144
|
+
conditions.push("t.amount_cents <= ?");
|
|
145
|
+
parameters.push(maxAmountCents);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
function addAccountFilters(conditions, parameters, accountType, accountSubtype) {
|
|
149
|
+
if (accountType !== undefined) {
|
|
150
|
+
conditions.push("t.account_type = ?");
|
|
151
|
+
parameters.push(accountType);
|
|
152
|
+
}
|
|
153
|
+
if (accountSubtype !== undefined) {
|
|
154
|
+
conditions.push("t.account_subtype = ?");
|
|
155
|
+
parameters.push(accountSubtype);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
function addKeysetFilter(conditions, parameters, after) {
|
|
159
|
+
if (after === undefined) {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
conditions.push("(t.local_date, t.id) < (?, ?)");
|
|
163
|
+
parameters.push(after.localDate, after.id);
|
|
164
|
+
}
|
|
165
|
+
function findByIds(db, ids) {
|
|
166
|
+
// Stryker disable next-line ConditionalExpression,BlockStatement: the details boundary rejects empty ids, and this storage guard avoids generating an empty IN list.
|
|
167
|
+
if (ids.length === 0) {
|
|
168
|
+
return [];
|
|
169
|
+
}
|
|
170
|
+
const sql = `WITH derived AS (
|
|
171
|
+
SELECT t.${TRANSACTION_COLUMNS.join(", t.")}, ${DERIVED_COLUMNS}
|
|
172
|
+
FROM transactions t
|
|
173
|
+
WHERE t.id IN (${placeholders(ids.length)})
|
|
174
|
+
) SELECT * FROM derived ORDER BY local_date DESC, id DESC`;
|
|
175
|
+
const rows = db.prepare(sql).all(...ids);
|
|
176
|
+
return rows.map((row) => rowToDerived(row));
|
|
177
|
+
}
|
|
178
|
+
function findCardRows(db, accountId) {
|
|
179
|
+
const sql = `WITH derived AS (
|
|
180
|
+
SELECT t.${TRANSACTION_COLUMNS.join(", t.")}, ${DERIVED_COLUMNS}
|
|
181
|
+
FROM transactions t
|
|
182
|
+
WHERE t.account_id = ?
|
|
183
|
+
) SELECT * FROM derived ORDER BY local_date, id`;
|
|
184
|
+
const rows = db.prepare(sql).all(accountId);
|
|
185
|
+
return rows.map((row) => rowToDerived(row));
|
|
186
|
+
}
|
|
187
|
+
function readFreshness(db, accountId) {
|
|
188
|
+
const row = db.prepare("SELECT last_updated_at FROM transaction_sync WHERE account_id = ?").get(accountId);
|
|
189
|
+
if (row === undefined) {
|
|
190
|
+
return undefined;
|
|
191
|
+
}
|
|
192
|
+
const value = row["last_updated_at"];
|
|
193
|
+
// Stryker disable next-line ConditionalExpression: SQLite returns NULL for this nullable column; the undefined branch is defensive for unusual row objects.
|
|
194
|
+
if (value === null || value === undefined) {
|
|
195
|
+
return null;
|
|
196
|
+
}
|
|
197
|
+
return String(value);
|
|
198
|
+
}
|
|
199
|
+
function readDataThrough(db, accountIds, today) {
|
|
200
|
+
// Stryker disable next-line ConditionalExpression,BlockStatement: an empty SQL IN list is already empty in SQLite; this guard avoids dialect-dependent SQL.
|
|
201
|
+
if (accountIds.length === 0) {
|
|
202
|
+
return new Map();
|
|
203
|
+
}
|
|
204
|
+
const sql = `SELECT connection_id, MAX(local_date) AS through FROM transactions WHERE account_id IN (${placeholders(accountIds.length)}) AND local_date <= ? GROUP BY connection_id`;
|
|
205
|
+
const rows = db.prepare(sql).all(...accountIds, today);
|
|
206
|
+
return new Map(rows.map((row) => [String(row["connection_id"]), String(row["through"])]));
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* The roll-up runs here, at insert, so SQL only ever compares a 22-valued
|
|
210
|
+
* column against a 22-valued filter (design D2). Doing it at read time is what
|
|
211
|
+
* let `categories: ["11000000"]` silently exclude every row tagged `11010000`.
|
|
212
|
+
*/
|
|
213
|
+
//# sourceMappingURL=transactions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transactions.js","sourceRoot":"","sources":["../../src/storage/transactions.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "cata-centavo",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "MCP server for Brazilian Open Finance data, via Pluggy",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"mcp",
|
|
7
|
+
"model-context-protocol",
|
|
8
|
+
"open-finance",
|
|
9
|
+
"pluggy",
|
|
10
|
+
"finance"
|
|
11
|
+
],
|
|
12
|
+
"license": "MIT",
|
|
13
|
+
"author": "Marcus Xavier",
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "git+https://github.com/MarcusXavierr/cata-centavo.git"
|
|
17
|
+
},
|
|
18
|
+
"homepage": "https://github.com/MarcusXavierr/cata-centavo#readme",
|
|
19
|
+
"bugs": {
|
|
20
|
+
"url": "https://github.com/MarcusXavierr/cata-centavo/issues"
|
|
21
|
+
},
|
|
22
|
+
"type": "module",
|
|
23
|
+
"bin": {
|
|
24
|
+
"cata-centavo": "./dist/bin/cata-centavo.js"
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"dist",
|
|
28
|
+
"README.md",
|
|
29
|
+
"LICENSE"
|
|
30
|
+
],
|
|
31
|
+
"engines": {
|
|
32
|
+
"node": ">=22.13.0"
|
|
33
|
+
},
|
|
34
|
+
"publishConfig": {
|
|
35
|
+
"access": "public"
|
|
36
|
+
},
|
|
37
|
+
"scripts": {
|
|
38
|
+
"dev": "node src/bin/cata-centavo.ts",
|
|
39
|
+
"typecheck": "tsc --noEmit",
|
|
40
|
+
"lint": "eslint src tests --format ./tools/eslint-formatter-agent.js",
|
|
41
|
+
"lint:fix": "eslint src tests --fix --format ./tools/eslint-formatter-agent.js",
|
|
42
|
+
"lint:sensor": "eslint src tests --format ./tools/eslint-formatter-sensor.js",
|
|
43
|
+
"deps": "depcruise src tests --output-type plugin:$PWD/tools/depcruise-reporter-agent.js",
|
|
44
|
+
"test": "node --test",
|
|
45
|
+
"test:watch": "node --test --watch",
|
|
46
|
+
"precoverage": "node -e \"require('node:fs').mkdirSync('coverage', { recursive: true })\"",
|
|
47
|
+
"coverage": "node --test --experimental-test-coverage --test-coverage-include=\"src/**/*.ts\" --test-reporter=spec --test-reporter-destination=stdout --test-reporter=lcov --test-reporter-destination=coverage/lcov.info",
|
|
48
|
+
"mutation": "stryker run && npm run mutation:report",
|
|
49
|
+
"mutation:report": "node tools/stryker-report-agent.js",
|
|
50
|
+
"build": "tsc -p tsconfig.build.json",
|
|
51
|
+
"prepack": "npm run build",
|
|
52
|
+
"prepublishOnly": "npm run typecheck && npm run lint && npm run deps && npm test"
|
|
53
|
+
},
|
|
54
|
+
"dependencies": {
|
|
55
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
56
|
+
"pino": "^10.3.1",
|
|
57
|
+
"pino-roll": "^4.0.0",
|
|
58
|
+
"pluggy-sdk": "^0.90.0",
|
|
59
|
+
"zod": "^4.4.3"
|
|
60
|
+
},
|
|
61
|
+
"devDependencies": {
|
|
62
|
+
"@stryker-mutator/core": "^9.6.1",
|
|
63
|
+
"@stryker-mutator/tap-runner": "^9.6.1",
|
|
64
|
+
"@types/node": "^24.13.3",
|
|
65
|
+
"dependency-cruiser": "^18.1.0",
|
|
66
|
+
"eslint": "^10.8.0",
|
|
67
|
+
"typescript": "~6.0.3",
|
|
68
|
+
"typescript-eslint": "^8.65.0"
|
|
69
|
+
}
|
|
70
|
+
}
|