@profullstack/coinpay 0.13.0 → 0.15.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/CHANGELOG.md +53 -0
- package/bin/coinpay.js +52 -12
- package/package.json +1 -1
- package/src/finances-commands.js +78 -19
- package/src/finances-reports.d.ts +39 -3
- package/src/finances-reports.js +46 -5
- package/src/mcp.js +31 -1
- package/src/statements-fetch.d.ts +85 -4
- package/src/statements-fetch.js +495 -36
- package/src/statements-throttle.js +158 -0
|
@@ -14,6 +14,52 @@ export interface Institution {
|
|
|
14
14
|
name: string;
|
|
15
15
|
url: string | null;
|
|
16
16
|
accounts: FetcherAccount[];
|
|
17
|
+
/** 'tax' for an agency (FTB, IRS), 'brokerage' for a brokerage with no linked account (Webull); absent for a bank. */
|
|
18
|
+
kind?: 'tax' | 'brokerage';
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface TaxSource {
|
|
22
|
+
key: string;
|
|
23
|
+
kind: 'tax';
|
|
24
|
+
name: string;
|
|
25
|
+
login: string;
|
|
26
|
+
lockoutMinutes: number;
|
|
27
|
+
cloudWarning?: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface BrokerageSource {
|
|
31
|
+
key: string;
|
|
32
|
+
kind: 'brokerage';
|
|
33
|
+
name: string;
|
|
34
|
+
login: string;
|
|
35
|
+
statements?: string;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface BrokerageDocumentInfo {
|
|
39
|
+
category: 'statement' | 'tax';
|
|
40
|
+
docType: 'form' | null;
|
|
41
|
+
taxYear: number | null;
|
|
42
|
+
periodLabel: string;
|
|
43
|
+
title: string;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface ThrottleLimits {
|
|
47
|
+
windowMs: number;
|
|
48
|
+
perWindow: number;
|
|
49
|
+
perDay: number;
|
|
50
|
+
defaultLockoutMinutes: number;
|
|
51
|
+
marginMinutes: number;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export type ThrottleVerdict = { ok: true } | { ok: false; reason: 'locked' | 'daily_limit' | 'window_limit'; retryAt: string; message: string };
|
|
55
|
+
|
|
56
|
+
export interface TaxDocumentInfo {
|
|
57
|
+
docType: 'transcript' | 'notice' | 'letter' | 'form' | 'return' | 'other';
|
|
58
|
+
code: string | null;
|
|
59
|
+
taxYear: number | null;
|
|
60
|
+
noticeDate: string | null;
|
|
61
|
+
periodLabel: string;
|
|
62
|
+
title: string;
|
|
17
63
|
}
|
|
18
64
|
|
|
19
65
|
export interface Period {
|
|
@@ -55,7 +101,7 @@ export interface Download {
|
|
|
55
101
|
key: string | null;
|
|
56
102
|
}
|
|
57
103
|
|
|
58
|
-
export type PageStatus = 'ok' | 'login_needed' | 'no_statements';
|
|
104
|
+
export type PageStatus = 'ok' | 'login_needed' | 'no_statements' | 'locked';
|
|
59
105
|
|
|
60
106
|
export function lastFour(name: string): string | null;
|
|
61
107
|
export function slug(value: string): string;
|
|
@@ -63,6 +109,37 @@ export function institutionKey(domain: string | null | undefined, name: string |
|
|
|
63
109
|
export function groupInstitutions(accounts: ReadonlyArray<{ id: string; name: string; org_name?: string | null; org_domain?: string | null; is_hidden?: boolean }>): Institution[];
|
|
64
110
|
export function pickInstitution(institutions: readonly Institution[], name: string): Institution;
|
|
65
111
|
export const DRIVERS: ReadonlyArray<{ key: string; login: string; statements?: string }>;
|
|
112
|
+
export const HOST_KEYS: ReadonlyArray<[RegExp, string]>;
|
|
113
|
+
export const TAX_SOURCES: readonly TaxSource[];
|
|
114
|
+
export function taxSource(key: string): TaxSource | null;
|
|
115
|
+
export const BROKERAGE_SOURCES: readonly BrokerageSource[];
|
|
116
|
+
export function brokerageSource(key: string): BrokerageSource | null;
|
|
117
|
+
export function isBrokerageSource(institution: { key: string; kind?: string; accounts?: readonly unknown[] } | null | undefined): boolean;
|
|
118
|
+
export function sourceMode(institution: { key: string; kind?: string; accounts?: readonly unknown[] }): 'statements' | 'tax' | 'documents';
|
|
119
|
+
export function standaloneSources(): Institution[];
|
|
120
|
+
export function withStandaloneSources(institutions: readonly Institution[]): Institution[];
|
|
121
|
+
export function isTaxSource(institution: { key: string; kind?: string; accounts?: readonly unknown[] } | null | undefined): boolean;
|
|
122
|
+
export function keepCandidate(mode: 'statements' | 'tax' | 'documents', label: string, context: string, href: string | null): boolean;
|
|
123
|
+
export function collectScript(mode?: 'statements' | 'tax' | 'documents'): string;
|
|
124
|
+
export const COLLECT_TAX: string;
|
|
125
|
+
export const OPEN_TAX_DOCS: string;
|
|
126
|
+
export const COLLECT_DOCS: string;
|
|
127
|
+
export const OPEN_DOCUMENTS: string;
|
|
128
|
+
export const PAGE_TEXT: string;
|
|
129
|
+
export function classifyTaxDocument(download: { label?: string; context?: string; suggestedName?: string }, fetchedAt?: Date): TaxDocumentInfo;
|
|
130
|
+
export function keepTaxDocument(options: Record<string, unknown>): Promise<Record<string, unknown>>;
|
|
131
|
+
export function classifyBrokerageDocument(download: { label?: string; context?: string; suggestedName?: string }, fetchedAt?: Date): BrokerageDocumentInfo;
|
|
132
|
+
export function keepBrokerageDocument(options: Record<string, unknown>): Promise<Record<string, unknown>>;
|
|
133
|
+
export const TAX_THROTTLE: ThrottleLimits;
|
|
134
|
+
export function evaluateThrottle(source: { attempts?: ReadonlyArray<string | { at: string }>; lockedUntil?: string | null; lockReason?: string | null }, now?: Date, limits?: ThrottleLimits): ThrottleVerdict;
|
|
135
|
+
export function detectLockout(text: string | null | undefined): { minutes: number | null } | null;
|
|
136
|
+
export function lockoutUntil(found: { minutes: number | null } | null, now?: Date, limits?: ThrottleLimits, defaultMinutes?: number): string;
|
|
137
|
+
export function throttlePath(home: string): string;
|
|
138
|
+
export function loadThrottle(home: string): { sources: Record<string, { attempts: Array<{ at: string; kind: string }>; lockedUntil: string | null; lockReason: string | null }> };
|
|
139
|
+
export function saveThrottle(ledger: unknown, home: string): void;
|
|
140
|
+
export function checkLocalThrottle(home: string, key: string, now?: Date, limits?: ThrottleLimits): ThrottleVerdict;
|
|
141
|
+
export function takeLocalAttempt(home: string, key: string, kind: string, now?: Date, limits?: ThrottleLimits): ThrottleVerdict;
|
|
142
|
+
export function recordLocalLockout(home: string, key: string, until: string, reason?: string): unknown;
|
|
66
143
|
export function startUrls(institution: { key: string; url: string | null }, learnt?: string | null): { login: string | null; fetch: string | null };
|
|
67
144
|
export function isSignInUrl(url: string): boolean;
|
|
68
145
|
export function findDates(source: string | null | undefined): { date: string; precise: boolean }[];
|
|
@@ -106,10 +183,13 @@ export function fetchInstitution(
|
|
|
106
183
|
renderMs?: number;
|
|
107
184
|
onFile: (download: Download) => Promise<void> | void;
|
|
108
185
|
log?: (line: string) => void;
|
|
186
|
+
mode?: 'statements' | 'tax' | 'documents';
|
|
187
|
+
watchLockout?: boolean;
|
|
188
|
+
pauseMs?: number;
|
|
109
189
|
},
|
|
110
|
-
): Promise<{ status: PageStatus; url: string; candidates: number; silent: string[] }>;
|
|
111
|
-
export function loginWindow(browser: Browser, url: string): Promise<string | null>;
|
|
112
|
-
export function assistWindow(browser: Browser, options: { start: string; onFile: (download: Download) => Promise<void> | void }): Promise<number>;
|
|
190
|
+
): Promise<{ status: PageStatus; url: string; candidates: number; silent: string[]; lockout?: { minutes: number | null } }>;
|
|
191
|
+
export function loginWindow(browser: Browser, url: string, options?: { onPageText?: (text: string) => unknown }): Promise<string | null>;
|
|
192
|
+
export function assistWindow(browser: Browser, options: { start: string; onFile: (download: Download) => Promise<void> | void; onPageText?: (text: string) => unknown }): Promise<number>;
|
|
113
193
|
export function loadLocal(home?: string): { institutions: Record<string, Record<string, unknown>>; entries: Record<string, unknown>[] };
|
|
114
194
|
export function saveLocal(state: unknown, home?: string): void;
|
|
115
195
|
export function archive(home: string, institution: Institution, account: FetcherAccount | null, period: Period | null, suggestedName: string, bytes: Uint8Array): string;
|
|
@@ -119,5 +199,6 @@ export function clientApi(client: unknown): Promise<{
|
|
|
119
199
|
listAccounts(): Promise<unknown[]>;
|
|
120
200
|
importStatement(options: Record<string, unknown>): Promise<unknown>;
|
|
121
201
|
reportRun(run: Record<string, unknown>): Promise<unknown>;
|
|
202
|
+
fileDocument(options: Record<string, unknown>): Promise<{ document?: { id: string }; duplicate?: boolean }>;
|
|
122
203
|
}>;
|
|
123
204
|
export function retryImports(options: Record<string, unknown>): Promise<{ imported: number; skipped: number; failed: number }>;
|