@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.
@@ -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 }>;