@bank-mcp/server 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 +564 -0
- package/dist/config.d.ts +11 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +79 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +33 -0
- package/dist/index.js.map +1 -0
- package/dist/init.d.ts +6 -0
- package/dist/init.d.ts.map +1 -0
- package/dist/init.js +96 -0
- package/dist/init.js.map +1 -0
- package/dist/providers/base.d.ts +22 -0
- package/dist/providers/base.d.ts.map +1 -0
- package/dist/providers/base.js +9 -0
- package/dist/providers/base.js.map +1 -0
- package/dist/providers/enable-banking/auth.d.ts +9 -0
- package/dist/providers/enable-banking/auth.d.ts.map +1 -0
- package/dist/providers/enable-banking/auth.js +30 -0
- package/dist/providers/enable-banking/auth.js.map +1 -0
- package/dist/providers/enable-banking/index.d.ts +12 -0
- package/dist/providers/enable-banking/index.d.ts.map +1 -0
- package/dist/providers/enable-banking/index.js +171 -0
- package/dist/providers/enable-banking/index.js.map +1 -0
- package/dist/providers/mock/index.d.ts +18 -0
- package/dist/providers/mock/index.d.ts.map +1 -0
- package/dist/providers/mock/index.js +151 -0
- package/dist/providers/mock/index.js.map +1 -0
- package/dist/providers/plaid/index.d.ts +12 -0
- package/dist/providers/plaid/index.d.ts.map +1 -0
- package/dist/providers/plaid/index.js +213 -0
- package/dist/providers/plaid/index.js.map +1 -0
- package/dist/providers/registry.d.ts +4 -0
- package/dist/providers/registry.d.ts.map +1 -0
- package/dist/providers/registry.js +26 -0
- package/dist/providers/registry.js.map +1 -0
- package/dist/providers/teller/index.d.ts +12 -0
- package/dist/providers/teller/index.d.ts.map +1 -0
- package/dist/providers/teller/index.js +215 -0
- package/dist/providers/teller/index.js.map +1 -0
- package/dist/providers/tink/index.d.ts +12 -0
- package/dist/providers/tink/index.d.ts.map +1 -0
- package/dist/providers/tink/index.js +169 -0
- package/dist/providers/tink/index.js.map +1 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +90 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/get-balance.d.ts +8 -0
- package/dist/tools/get-balance.d.ts.map +1 -0
- package/dist/tools/get-balance.js +39 -0
- package/dist/tools/get-balance.js.map +1 -0
- package/dist/tools/list-accounts.d.ts +7 -0
- package/dist/tools/list-accounts.d.ts.map +1 -0
- package/dist/tools/list-accounts.js +33 -0
- package/dist/tools/list-accounts.js.map +1 -0
- package/dist/tools/list-transactions.d.ts +17 -0
- package/dist/tools/list-transactions.d.ts.map +1 -0
- package/dist/tools/list-transactions.js +104 -0
- package/dist/tools/list-transactions.js.map +1 -0
- package/dist/tools/search-transactions.d.ts +10 -0
- package/dist/tools/search-transactions.d.ts.map +1 -0
- package/dist/tools/search-transactions.js +27 -0
- package/dist/tools/search-transactions.js.map +1 -0
- package/dist/tools/spending-summary.d.ts +25 -0
- package/dist/tools/spending-summary.d.ts.map +1 -0
- package/dist/tools/spending-summary.js +65 -0
- package/dist/tools/spending-summary.js.map +1 -0
- package/dist/types.d.ts +65 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +21 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/cache.d.ts +19 -0
- package/dist/utils/cache.d.ts.map +1 -0
- package/dist/utils/cache.js +33 -0
- package/dist/utils/cache.js.map +1 -0
- package/dist/utils/http.d.ts +12 -0
- package/dist/utils/http.d.ts.map +1 -0
- package/dist/utils/http.js +34 -0
- package/dist/utils/http.js.map +1 -0
- package/dist/utils/zod-to-json.d.ts +9 -0
- package/dist/utils/zod-to-json.d.ts.map +1 -0
- package/dist/utils/zod-to-json.js +62 -0
- package/dist/utils/zod-to-json.js.map +1 -0
- package/package.json +58 -0
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { BankProvider } from "../base.js";
|
|
2
|
+
import { httpFetch } from "../../utils/http.js";
|
|
3
|
+
const BASE_URL = "https://api.tink.com";
|
|
4
|
+
function parseConfig(raw) {
|
|
5
|
+
const accessToken = raw.accessToken;
|
|
6
|
+
if (!accessToken) {
|
|
7
|
+
throw new Error("Tink config requires: accessToken");
|
|
8
|
+
}
|
|
9
|
+
return { accessToken };
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* GET request to Tink API with Bearer token auth.
|
|
13
|
+
*/
|
|
14
|
+
async function tinkGet(config, path, params) {
|
|
15
|
+
let url = `${BASE_URL}${path}`;
|
|
16
|
+
if (params) {
|
|
17
|
+
const qs = new URLSearchParams(params).toString();
|
|
18
|
+
if (qs)
|
|
19
|
+
url += `?${qs}`;
|
|
20
|
+
}
|
|
21
|
+
return httpFetch(url, {
|
|
22
|
+
method: "GET",
|
|
23
|
+
headers: {
|
|
24
|
+
Authorization: `Bearer ${config.accessToken}`,
|
|
25
|
+
},
|
|
26
|
+
timeoutMs: 30000,
|
|
27
|
+
retries: 2,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Parse Tink's fixed-point decimal amount.
|
|
32
|
+
*
|
|
33
|
+
* Tink represents amounts as { unscaledValue, scale } where
|
|
34
|
+
* actual = unscaledValue * 10^(-scale).
|
|
35
|
+
*
|
|
36
|
+
* Example: { unscaledValue: "15099", scale: 2 } → 150.99
|
|
37
|
+
*/
|
|
38
|
+
function parseAmount(amount) {
|
|
39
|
+
const unscaled = parseFloat(amount.unscaledValue);
|
|
40
|
+
return unscaled * Math.pow(10, -(amount.scale ?? 0));
|
|
41
|
+
}
|
|
42
|
+
export class TinkProvider extends BankProvider {
|
|
43
|
+
name = "tink";
|
|
44
|
+
displayName = "Tink (EU Open Banking)";
|
|
45
|
+
validateConfig(config) {
|
|
46
|
+
parseConfig(config);
|
|
47
|
+
}
|
|
48
|
+
getConfigSchema() {
|
|
49
|
+
return [
|
|
50
|
+
{
|
|
51
|
+
name: "accessToken",
|
|
52
|
+
label: "Access token (from Tink Console)",
|
|
53
|
+
type: "string",
|
|
54
|
+
required: true,
|
|
55
|
+
secret: true,
|
|
56
|
+
},
|
|
57
|
+
];
|
|
58
|
+
}
|
|
59
|
+
async listAccounts(config) {
|
|
60
|
+
const tc = parseConfig(config);
|
|
61
|
+
const data = (await tinkGet(tc, "/data/v2/accounts"));
|
|
62
|
+
return data.accounts.map((a) => ({
|
|
63
|
+
uid: a.id,
|
|
64
|
+
iban: a.identifiers?.iban?.iban || a.id,
|
|
65
|
+
name: a.name,
|
|
66
|
+
currency: a.balances?.booked?.amount?.currencyCode || "EUR",
|
|
67
|
+
connectionId: "",
|
|
68
|
+
}));
|
|
69
|
+
}
|
|
70
|
+
async listTransactions(config, accountId, filter) {
|
|
71
|
+
const tc = parseConfig(config);
|
|
72
|
+
const allTx = [];
|
|
73
|
+
let pageToken;
|
|
74
|
+
// nextPageToken cursor pagination
|
|
75
|
+
do {
|
|
76
|
+
const params = {
|
|
77
|
+
accountIdIn: accountId,
|
|
78
|
+
pageSize: "100",
|
|
79
|
+
};
|
|
80
|
+
if (filter?.dateFrom)
|
|
81
|
+
params.bookedDateGte = filter.dateFrom;
|
|
82
|
+
if (filter?.dateTo)
|
|
83
|
+
params.bookedDateLte = filter.dateTo;
|
|
84
|
+
if (pageToken)
|
|
85
|
+
params.pageToken = pageToken;
|
|
86
|
+
const data = (await tinkGet(tc, "/data/v2/transactions", params));
|
|
87
|
+
for (const raw of data.transactions) {
|
|
88
|
+
allTx.push(normalizeTransaction(raw));
|
|
89
|
+
}
|
|
90
|
+
pageToken = data.nextPageToken || undefined;
|
|
91
|
+
} while (pageToken);
|
|
92
|
+
// Apply local filters
|
|
93
|
+
let filtered = allTx;
|
|
94
|
+
if (filter?.amountMin !== undefined) {
|
|
95
|
+
filtered = filtered.filter((t) => Math.abs(t.amount) >= filter.amountMin);
|
|
96
|
+
}
|
|
97
|
+
if (filter?.amountMax !== undefined) {
|
|
98
|
+
filtered = filtered.filter((t) => Math.abs(t.amount) <= filter.amountMax);
|
|
99
|
+
}
|
|
100
|
+
if (filter?.type) {
|
|
101
|
+
filtered = filtered.filter((t) => t.type === filter.type);
|
|
102
|
+
}
|
|
103
|
+
if (filter?.limit) {
|
|
104
|
+
filtered = filtered.slice(0, filter.limit);
|
|
105
|
+
}
|
|
106
|
+
return filtered;
|
|
107
|
+
}
|
|
108
|
+
async getBalance(config, accountId) {
|
|
109
|
+
const tc = parseConfig(config);
|
|
110
|
+
const data = (await tinkGet(tc, `/data/v2/accounts/${accountId}/balances`));
|
|
111
|
+
const balances = [];
|
|
112
|
+
if (data.balances?.bookedBalance) {
|
|
113
|
+
const amt = data.balances.bookedBalance.amount;
|
|
114
|
+
balances.push({
|
|
115
|
+
accountId,
|
|
116
|
+
amount: parseAmount(amt),
|
|
117
|
+
currency: amt.currencyCode,
|
|
118
|
+
type: "booked",
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
if (data.balances?.availableBalance) {
|
|
122
|
+
const amt = data.balances.availableBalance.amount;
|
|
123
|
+
balances.push({
|
|
124
|
+
accountId,
|
|
125
|
+
amount: parseAmount(amt),
|
|
126
|
+
currency: amt.currencyCode,
|
|
127
|
+
type: "available",
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
return balances;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Normalize a Tink transaction to our standard format.
|
|
135
|
+
*
|
|
136
|
+
* Amount: Tink uses fixed-point { unscaledValue, scale }.
|
|
137
|
+
* Sign: Tink amounts are always positive; the `types.type` field
|
|
138
|
+
* indicates DEBIT (money out) vs CREDIT (money in).
|
|
139
|
+
* We negate DEBIT amounts to match our convention (negative = expense).
|
|
140
|
+
*
|
|
141
|
+
* Descriptions: Tink provides three levels:
|
|
142
|
+
* display (cleanest) > original (raw) > detailed.unstructured
|
|
143
|
+
*/
|
|
144
|
+
function normalizeTransaction(raw) {
|
|
145
|
+
const absAmount = parseAmount(raw.amount);
|
|
146
|
+
const isDebit = raw.types?.type === "DEBIT";
|
|
147
|
+
const amount = isDebit ? -absAmount : absAmount;
|
|
148
|
+
const merchantName = raw.merchantInformation?.merchantName || undefined;
|
|
149
|
+
const category = raw.categories?.pfm?.name || undefined;
|
|
150
|
+
// Best description: display > original > detailed
|
|
151
|
+
const description = raw.descriptions.display ||
|
|
152
|
+
raw.descriptions.original ||
|
|
153
|
+
raw.descriptions.detailed?.unstructured ||
|
|
154
|
+
"Unknown";
|
|
155
|
+
return {
|
|
156
|
+
id: raw.id,
|
|
157
|
+
accountId: raw.accountId,
|
|
158
|
+
date: raw.dates.booked,
|
|
159
|
+
amount,
|
|
160
|
+
currency: raw.amount.currencyCode,
|
|
161
|
+
description: merchantName || description,
|
|
162
|
+
merchantName,
|
|
163
|
+
category,
|
|
164
|
+
type: isDebit ? "debit" : "credit",
|
|
165
|
+
reference: raw.reference || description,
|
|
166
|
+
rawData: raw,
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/providers/tink/index.ts"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAqEA,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAqDjD"}
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
2
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
3
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
import { listAccountsSchema, listAccounts } from "./tools/list-accounts.js";
|
|
6
|
+
import { listTransactionsSchema, listTransactions, } from "./tools/list-transactions.js";
|
|
7
|
+
import { searchTransactionsSchema, searchTransactions, } from "./tools/search-transactions.js";
|
|
8
|
+
import { getBalanceSchema, getBalance } from "./tools/get-balance.js";
|
|
9
|
+
import { spendingSummarySchema, spendingSummary, } from "./tools/spending-summary.js";
|
|
10
|
+
const TOOLS = [
|
|
11
|
+
{
|
|
12
|
+
name: "list_accounts",
|
|
13
|
+
description: "List all bank accounts across configured connections. Returns account UIDs, IBANs, names, and currencies.",
|
|
14
|
+
inputSchema: z.toJSONSchema(listAccountsSchema),
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
name: "list_transactions",
|
|
18
|
+
description: "List bank transactions with optional filters. Defaults to last 90 days. Supports date range, amount range, and debit/credit type filtering.",
|
|
19
|
+
inputSchema: z.toJSONSchema(listTransactionsSchema),
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
name: "search_transactions",
|
|
23
|
+
description: "Full-text search across transaction descriptions, merchant names, and references. Use for finding specific payments or payees.",
|
|
24
|
+
inputSchema: z.toJSONSchema(searchTransactionsSchema),
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
name: "get_balance",
|
|
28
|
+
description: "Get current account balance(s). Returns closing booked balance and expected balance when available.",
|
|
29
|
+
inputSchema: z.toJSONSchema(getBalanceSchema),
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
name: "spending_summary",
|
|
33
|
+
description: 'Group expenses by merchant or category with totals. Shows where money is being spent. Use groupBy "merchant" for vendor breakdown, "category" for category breakdown.',
|
|
34
|
+
inputSchema: z.toJSONSchema(spendingSummarySchema),
|
|
35
|
+
},
|
|
36
|
+
];
|
|
37
|
+
const handlers = {
|
|
38
|
+
list_accounts: (args) => listAccounts(listAccountsSchema.parse(args)),
|
|
39
|
+
list_transactions: (args) => listTransactions(listTransactionsSchema.parse(args)),
|
|
40
|
+
search_transactions: (args) => searchTransactions(searchTransactionsSchema.parse(args)),
|
|
41
|
+
get_balance: (args) => getBalance(getBalanceSchema.parse(args)),
|
|
42
|
+
spending_summary: (args) => spendingSummary(spendingSummarySchema.parse(args)),
|
|
43
|
+
};
|
|
44
|
+
export async function startServer() {
|
|
45
|
+
const server = new Server({ name: "bank-mcp", version: "0.1.0" }, { capabilities: { tools: {} } });
|
|
46
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
47
|
+
tools: TOOLS,
|
|
48
|
+
}));
|
|
49
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
50
|
+
const { name, arguments: args } = request.params;
|
|
51
|
+
const handler = handlers[name];
|
|
52
|
+
if (!handler) {
|
|
53
|
+
return {
|
|
54
|
+
content: [
|
|
55
|
+
{
|
|
56
|
+
type: "text",
|
|
57
|
+
text: JSON.stringify({ error: true, code: "unknown_tool", message: `Unknown tool: ${name}` }),
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
isError: true,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
try {
|
|
64
|
+
const result = await handler(args || {});
|
|
65
|
+
return {
|
|
66
|
+
content: [
|
|
67
|
+
{ type: "text", text: JSON.stringify(result, null, 2) },
|
|
68
|
+
],
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
catch (err) {
|
|
72
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
73
|
+
// Return structured error as text so LLMs can explain it
|
|
74
|
+
return {
|
|
75
|
+
content: [
|
|
76
|
+
{
|
|
77
|
+
type: "text",
|
|
78
|
+
text: JSON.stringify({ error: true, code: "tool_error", message }),
|
|
79
|
+
},
|
|
80
|
+
],
|
|
81
|
+
isError: true,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
const transport = new StdioServerTransport();
|
|
86
|
+
await server.connect(transport);
|
|
87
|
+
// All logging to stderr — stdout is the MCP wire protocol
|
|
88
|
+
console.error("[bank-mcp] Server started");
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { Balance } from "../types.js";
|
|
3
|
+
export declare const getBalanceSchema: z.ZodObject<{
|
|
4
|
+
connectionId: z.ZodOptional<z.ZodString>;
|
|
5
|
+
accountId: z.ZodOptional<z.ZodString>;
|
|
6
|
+
}, z.core.$strip>;
|
|
7
|
+
export declare function getBalance(args: z.infer<typeof getBalanceSchema>): Promise<Balance[]>;
|
|
8
|
+
//# sourceMappingURL=get-balance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-balance.d.ts","sourceRoot":"","sources":["../../src/tools/get-balance.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,eAAO,MAAM,gBAAgB;;;iBAG3B,CAAC;AAEH,wBAAsB,UAAU,CAC9B,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,GACrC,OAAO,CAAC,OAAO,EAAE,CAAC,CAmCpB"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { loadConfig, getConnection, getAllConnections } from "../config.js";
|
|
3
|
+
import { getProvider } from "../providers/registry.js";
|
|
4
|
+
import { cache, TTL } from "../utils/cache.js";
|
|
5
|
+
export const getBalanceSchema = z.object({
|
|
6
|
+
connectionId: z.string().optional(),
|
|
7
|
+
accountId: z.string().optional().describe("Account UID. If omitted, returns balances for all accounts."),
|
|
8
|
+
});
|
|
9
|
+
export async function getBalance(args) {
|
|
10
|
+
const config = loadConfig();
|
|
11
|
+
const connections = args.connectionId
|
|
12
|
+
? [getConnection(config, args.connectionId)]
|
|
13
|
+
: getAllConnections(config);
|
|
14
|
+
const allBalances = [];
|
|
15
|
+
for (const conn of connections) {
|
|
16
|
+
const provider = getProvider(conn.provider);
|
|
17
|
+
let accountIds;
|
|
18
|
+
if (args.accountId) {
|
|
19
|
+
accountIds = [args.accountId];
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
const accounts = await provider.listAccounts(conn.config);
|
|
23
|
+
accountIds = accounts.map((a) => a.uid);
|
|
24
|
+
}
|
|
25
|
+
for (const accId of accountIds) {
|
|
26
|
+
const cacheKey = `bal:${conn.id}:${accId}`;
|
|
27
|
+
const cached = cache.get(cacheKey);
|
|
28
|
+
if (cached) {
|
|
29
|
+
allBalances.push(...cached);
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
const balances = await provider.getBalance(conn.config, accId);
|
|
33
|
+
cache.set(cacheKey, balances, TTL.BALANCES);
|
|
34
|
+
allBalances.push(...balances);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return allBalances;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=get-balance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-balance.js","sourceRoot":"","sources":["../../src/tools/get-balance.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAC5E,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAG/C,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IACvC,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACnC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,6DAA6D,CAAC;CACzG,CAAC,CAAC;AAEH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,IAAsC;IAEtC,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAE5B,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY;QACnC,CAAC,CAAC,CAAC,aAAa,CAAC,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;QAC5C,CAAC,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAE9B,MAAM,WAAW,GAAc,EAAE,CAAC;IAElC,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;QAC/B,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAE5C,IAAI,UAAoB,CAAC;QACzB,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnB,UAAU,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAChC,CAAC;aAAM,CAAC;YACN,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC1D,UAAU,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAC1C,CAAC;QAED,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE,CAAC;YAC/B,MAAM,QAAQ,GAAG,OAAO,IAAI,CAAC,EAAE,IAAI,KAAK,EAAE,CAAC;YAC3C,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAY,QAAQ,CAAC,CAAC;YAC9C,IAAI,MAAM,EAAE,CAAC;gBACX,WAAW,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC;gBAC5B,SAAS;YACX,CAAC;YAED,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;YAC/D,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;YAC5C,WAAW,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { BankAccount } from "../types.js";
|
|
3
|
+
export declare const listAccountsSchema: z.ZodObject<{
|
|
4
|
+
connectionId: z.ZodOptional<z.ZodString>;
|
|
5
|
+
}, z.core.$strip>;
|
|
6
|
+
export declare function listAccounts(args: z.infer<typeof listAccountsSchema>): Promise<BankAccount[]>;
|
|
7
|
+
//# sourceMappingURL=list-accounts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-accounts.d.ts","sourceRoot":"","sources":["../../src/tools/list-accounts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,eAAO,MAAM,kBAAkB;;iBAK7B,CAAC;AAEH,wBAAsB,YAAY,CAChC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,GACvC,OAAO,CAAC,WAAW,EAAE,CAAC,CA2BxB"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { loadConfig, getConnection, getAllConnections } from "../config.js";
|
|
3
|
+
import { getProvider } from "../providers/registry.js";
|
|
4
|
+
import { cache, TTL } from "../utils/cache.js";
|
|
5
|
+
export const listAccountsSchema = z.object({
|
|
6
|
+
connectionId: z
|
|
7
|
+
.string()
|
|
8
|
+
.optional()
|
|
9
|
+
.describe("Connection ID to query. If omitted, queries all connections."),
|
|
10
|
+
});
|
|
11
|
+
export async function listAccounts(args) {
|
|
12
|
+
const config = loadConfig();
|
|
13
|
+
const connections = args.connectionId
|
|
14
|
+
? [getConnection(config, args.connectionId)]
|
|
15
|
+
: getAllConnections(config);
|
|
16
|
+
const allAccounts = [];
|
|
17
|
+
for (const conn of connections) {
|
|
18
|
+
const cacheKey = `accounts:${conn.id}`;
|
|
19
|
+
const cached = cache.get(cacheKey);
|
|
20
|
+
if (cached) {
|
|
21
|
+
allAccounts.push(...cached);
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
const provider = getProvider(conn.provider);
|
|
25
|
+
const accounts = await provider.listAccounts(conn.config);
|
|
26
|
+
// Tag each account with its connection
|
|
27
|
+
const tagged = accounts.map((a) => ({ ...a, connectionId: conn.id }));
|
|
28
|
+
cache.set(cacheKey, tagged, TTL.ACCOUNTS);
|
|
29
|
+
allAccounts.push(...tagged);
|
|
30
|
+
}
|
|
31
|
+
return allAccounts;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=list-accounts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-accounts.js","sourceRoot":"","sources":["../../src/tools/list-accounts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAC5E,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAG/C,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,YAAY,EAAE,CAAC;SACZ,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,8DAA8D,CAAC;CAC5E,CAAC,CAAC;AAEH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,IAAwC;IAExC,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAE5B,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY;QACnC,CAAC,CAAC,CAAC,aAAa,CAAC,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;QAC5C,CAAC,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAE9B,MAAM,WAAW,GAAkB,EAAE,CAAC;IAEtC,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;QAC/B,MAAM,QAAQ,GAAG,YAAY,IAAI,CAAC,EAAE,EAAE,CAAC;QACvC,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAgB,QAAQ,CAAC,CAAC;QAClD,IAAI,MAAM,EAAE,CAAC;YACX,WAAW,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC;YAC5B,SAAS;QACX,CAAC;QAED,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC5C,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAE1D,uCAAuC;QACvC,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,YAAY,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QACtE,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC1C,WAAW,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC;IAC9B,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { Transaction } from "../types.js";
|
|
3
|
+
export declare const listTransactionsSchema: z.ZodObject<{
|
|
4
|
+
connectionId: z.ZodOptional<z.ZodString>;
|
|
5
|
+
accountId: z.ZodOptional<z.ZodString>;
|
|
6
|
+
dateFrom: z.ZodOptional<z.ZodString>;
|
|
7
|
+
dateTo: z.ZodOptional<z.ZodString>;
|
|
8
|
+
amountMin: z.ZodOptional<z.ZodNumber>;
|
|
9
|
+
amountMax: z.ZodOptional<z.ZodNumber>;
|
|
10
|
+
type: z.ZodOptional<z.ZodEnum<{
|
|
11
|
+
debit: "debit";
|
|
12
|
+
credit: "credit";
|
|
13
|
+
}>>;
|
|
14
|
+
limit: z.ZodOptional<z.ZodNumber>;
|
|
15
|
+
}, z.core.$strip>;
|
|
16
|
+
export declare function listTransactions(args: z.infer<typeof listTransactionsSchema>): Promise<Transaction[]>;
|
|
17
|
+
//# sourceMappingURL=list-transactions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-transactions.d.ts","sourceRoot":"","sources":["../../src/tools/list-transactions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,OAAO,KAAK,EAAE,WAAW,EAAqB,MAAM,aAAa,CAAC;AAElE,eAAO,MAAM,sBAAsB;;;;;;;;;;;;iBAiCjC,CAAC;AAEH,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,GAC3C,OAAO,CAAC,WAAW,EAAE,CAAC,CAwDxB"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { loadConfig, getConnection, getAllConnections } from "../config.js";
|
|
3
|
+
import { getProvider } from "../providers/registry.js";
|
|
4
|
+
import { cache, TTL } from "../utils/cache.js";
|
|
5
|
+
export const listTransactionsSchema = z.object({
|
|
6
|
+
connectionId: z
|
|
7
|
+
.string()
|
|
8
|
+
.optional()
|
|
9
|
+
.describe("Connection ID. If omitted, queries all connections."),
|
|
10
|
+
accountId: z
|
|
11
|
+
.string()
|
|
12
|
+
.optional()
|
|
13
|
+
.describe("Account UID. If omitted, queries all accounts."),
|
|
14
|
+
dateFrom: z
|
|
15
|
+
.string()
|
|
16
|
+
.optional()
|
|
17
|
+
.describe('Start date (YYYY-MM-DD). Defaults to 90 days ago.'),
|
|
18
|
+
dateTo: z
|
|
19
|
+
.string()
|
|
20
|
+
.optional()
|
|
21
|
+
.describe('End date (YYYY-MM-DD). Defaults to today.'),
|
|
22
|
+
amountMin: z
|
|
23
|
+
.number()
|
|
24
|
+
.optional()
|
|
25
|
+
.describe("Minimum absolute amount."),
|
|
26
|
+
amountMax: z
|
|
27
|
+
.number()
|
|
28
|
+
.optional()
|
|
29
|
+
.describe("Maximum absolute amount."),
|
|
30
|
+
type: z
|
|
31
|
+
.enum(["debit", "credit"])
|
|
32
|
+
.optional()
|
|
33
|
+
.describe("Filter by transaction type."),
|
|
34
|
+
limit: z
|
|
35
|
+
.number()
|
|
36
|
+
.optional()
|
|
37
|
+
.describe("Maximum number of transactions to return."),
|
|
38
|
+
});
|
|
39
|
+
export async function listTransactions(args) {
|
|
40
|
+
const config = loadConfig();
|
|
41
|
+
const dateFrom = args.dateFrom || defaultDateFrom(config.defaults.transactionDays);
|
|
42
|
+
const dateTo = args.dateTo || today();
|
|
43
|
+
const filter = {
|
|
44
|
+
dateFrom,
|
|
45
|
+
dateTo,
|
|
46
|
+
amountMin: args.amountMin,
|
|
47
|
+
amountMax: args.amountMax,
|
|
48
|
+
type: args.type,
|
|
49
|
+
limit: args.limit,
|
|
50
|
+
};
|
|
51
|
+
// Resolve which connections and accounts to query
|
|
52
|
+
const connections = args.connectionId
|
|
53
|
+
? [getConnection(config, args.connectionId)]
|
|
54
|
+
: getAllConnections(config);
|
|
55
|
+
const allTx = [];
|
|
56
|
+
for (const conn of connections) {
|
|
57
|
+
const provider = getProvider(conn.provider);
|
|
58
|
+
// Get account list (may come from cache)
|
|
59
|
+
let accountIds;
|
|
60
|
+
if (args.accountId) {
|
|
61
|
+
accountIds = [args.accountId];
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
const accounts = await provider.listAccounts(conn.config);
|
|
65
|
+
accountIds = accounts.map((a) => a.uid);
|
|
66
|
+
}
|
|
67
|
+
for (const accId of accountIds) {
|
|
68
|
+
const cacheKey = `tx:${conn.id}:${accId}:${dateFrom}:${dateTo}`;
|
|
69
|
+
const cached = cache.get(cacheKey);
|
|
70
|
+
if (cached) {
|
|
71
|
+
allTx.push(...applyLocalFilters(cached, filter));
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
const transactions = await provider.listTransactions(conn.config, accId, { dateFrom, dateTo });
|
|
75
|
+
cache.set(cacheKey, transactions, TTL.TRANSACTIONS);
|
|
76
|
+
allTx.push(...applyLocalFilters(transactions, filter));
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// Sort by date descending (most recent first)
|
|
80
|
+
allTx.sort((a, b) => b.date.localeCompare(a.date));
|
|
81
|
+
return args.limit ? allTx.slice(0, args.limit) : allTx;
|
|
82
|
+
}
|
|
83
|
+
function applyLocalFilters(txs, f) {
|
|
84
|
+
let result = txs;
|
|
85
|
+
if (f.amountMin !== undefined) {
|
|
86
|
+
result = result.filter((t) => Math.abs(t.amount) >= f.amountMin);
|
|
87
|
+
}
|
|
88
|
+
if (f.amountMax !== undefined) {
|
|
89
|
+
result = result.filter((t) => Math.abs(t.amount) <= f.amountMax);
|
|
90
|
+
}
|
|
91
|
+
if (f.type) {
|
|
92
|
+
result = result.filter((t) => t.type === f.type);
|
|
93
|
+
}
|
|
94
|
+
return result;
|
|
95
|
+
}
|
|
96
|
+
function defaultDateFrom(days) {
|
|
97
|
+
const d = new Date();
|
|
98
|
+
d.setDate(d.getDate() - days);
|
|
99
|
+
return d.toISOString().slice(0, 10);
|
|
100
|
+
}
|
|
101
|
+
function today() {
|
|
102
|
+
return new Date().toISOString().slice(0, 10);
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=list-transactions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-transactions.js","sourceRoot":"","sources":["../../src/tools/list-transactions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const searchTransactionsSchema: z.ZodObject<{
|
|
3
|
+
query: z.ZodString;
|
|
4
|
+
connectionId: z.ZodOptional<z.ZodString>;
|
|
5
|
+
dateFrom: z.ZodOptional<z.ZodString>;
|
|
6
|
+
dateTo: z.ZodOptional<z.ZodString>;
|
|
7
|
+
limit: z.ZodOptional<z.ZodNumber>;
|
|
8
|
+
}, z.core.$strip>;
|
|
9
|
+
export declare function searchTransactions(args: z.infer<typeof searchTransactionsSchema>): Promise<unknown>;
|
|
10
|
+
//# sourceMappingURL=search-transactions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-transactions.d.ts","sourceRoot":"","sources":["../../src/tools/search-transactions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAO,MAAM,wBAAwB;;;;;;iBAQnC,CAAC;AAEH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,GAC7C,OAAO,CAAC,OAAO,CAAC,CAiBlB"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { listTransactions } from "./list-transactions.js";
|
|
3
|
+
export const searchTransactionsSchema = z.object({
|
|
4
|
+
query: z
|
|
5
|
+
.string()
|
|
6
|
+
.describe("Search text — matched against description, merchant name, and reference."),
|
|
7
|
+
connectionId: z.string().optional(),
|
|
8
|
+
dateFrom: z.string().optional(),
|
|
9
|
+
dateTo: z.string().optional(),
|
|
10
|
+
limit: z.number().optional().describe("Max results. Default 50."),
|
|
11
|
+
});
|
|
12
|
+
export async function searchTransactions(args) {
|
|
13
|
+
// Fetch all transactions for the date range, then filter locally
|
|
14
|
+
const transactions = await listTransactions({
|
|
15
|
+
connectionId: args.connectionId,
|
|
16
|
+
dateFrom: args.dateFrom,
|
|
17
|
+
dateTo: args.dateTo,
|
|
18
|
+
});
|
|
19
|
+
const q = args.query.toLowerCase();
|
|
20
|
+
const limit = args.limit || 50;
|
|
21
|
+
const matches = transactions.filter((t) => {
|
|
22
|
+
const fields = [t.description, t.merchantName, t.reference].filter(Boolean);
|
|
23
|
+
return fields.some((f) => f.toLowerCase().includes(q));
|
|
24
|
+
});
|
|
25
|
+
return matches.slice(0, limit);
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=search-transactions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-transactions.js","sourceRoot":"","sources":["../../src/tools/search-transactions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE1D,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC/C,KAAK,EAAE,CAAC;SACL,MAAM,EAAE;SACR,QAAQ,CAAC,0EAA0E,CAAC;IACvF,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACnC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC/B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC7B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,0BAA0B,CAAC;CAClE,CAAC,CAAC;AAEH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,IAA8C;IAE9C,iEAAiE;IACjE,MAAM,YAAY,GAAG,MAAM,gBAAgB,CAAC;QAC1C,YAAY,EAAE,IAAI,CAAC,YAAY;QAC/B,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,MAAM,EAAE,IAAI,CAAC,MAAM;KACpB,CAAC,CAAC;IAEH,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;IACnC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;IAE/B,MAAM,OAAO,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;QACxC,MAAM,MAAM,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC5E,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAE,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;IAEH,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;AACjC,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const spendingSummarySchema: z.ZodObject<{
|
|
3
|
+
connectionId: z.ZodOptional<z.ZodString>;
|
|
4
|
+
dateFrom: z.ZodOptional<z.ZodString>;
|
|
5
|
+
dateTo: z.ZodOptional<z.ZodString>;
|
|
6
|
+
groupBy: z.ZodOptional<z.ZodEnum<{
|
|
7
|
+
merchant: "merchant";
|
|
8
|
+
category: "category";
|
|
9
|
+
}>>;
|
|
10
|
+
limit: z.ZodOptional<z.ZodNumber>;
|
|
11
|
+
}, z.core.$strip>;
|
|
12
|
+
interface SpendingGroup {
|
|
13
|
+
name: string;
|
|
14
|
+
totalSpent: number;
|
|
15
|
+
transactionCount: number;
|
|
16
|
+
currency: string;
|
|
17
|
+
}
|
|
18
|
+
export declare function spendingSummary(args: z.infer<typeof spendingSummarySchema>): Promise<{
|
|
19
|
+
groups: SpendingGroup[];
|
|
20
|
+
totalSpent: number;
|
|
21
|
+
currency: string;
|
|
22
|
+
period: string;
|
|
23
|
+
}>;
|
|
24
|
+
export {};
|
|
25
|
+
//# sourceMappingURL=spending-summary.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spending-summary.d.ts","sourceRoot":"","sources":["../../src/tools/spending-summary.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,eAAO,MAAM,qBAAqB;;;;;;;;;iBAYhC,CAAC;AAEH,UAAU,aAAa;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wBAAsB,eAAe,CACnC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,GAC1C,OAAO,CAAC;IAAE,MAAM,EAAE,aAAa,EAAE,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAkD5F"}
|