@festapp/banksync 0.0.0-bootstrap.20260831

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/dist/index.cjs ADDED
@@ -0,0 +1,42 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+
10
+
11
+
12
+
13
+
14
+
15
+
16
+
17
+
18
+
19
+
20
+
21
+ var _chunkPBN2BUNRcjs = require('./chunk-PBN2BUNR.cjs');
22
+
23
+
24
+
25
+
26
+
27
+
28
+
29
+
30
+
31
+
32
+
33
+
34
+
35
+
36
+
37
+
38
+
39
+
40
+
41
+
42
+ exports.BANK_CODES = _chunkPBN2BUNRcjs.BANK_CODES; exports.FioApiError = _chunkPBN2BUNRcjs.FioApiError; exports.FioRateLimited = _chunkPBN2BUNRcjs.FioRateLimited; exports.FioTransientFailure = _chunkPBN2BUNRcjs.FioTransientFailure; exports.WebhookVerificationError = _chunkPBN2BUNRcjs.WebhookVerificationError; exports.buildWebhookEnvelope = _chunkPBN2BUNRcjs.buildWebhookEnvelope; exports.decodeRf = _chunkPBN2BUNRcjs.decodeRf; exports.detectProvider = _chunkPBN2BUNRcjs.detectProvider; exports.encodeRf = _chunkPBN2BUNRcjs.encodeRf; exports.extractReferenceCandidates = _chunkPBN2BUNRcjs.extractReferenceCandidates; exports.fetchNewTransactions = _chunkPBN2BUNRcjs.fetchNewTransactions; exports.mapFioTransaction = _chunkPBN2BUNRcjs.mapFioTransaction; exports.normalizeCurrency = _chunkPBN2BUNRcjs.normalizeCurrency; exports.parseEmail = _chunkPBN2BUNRcjs.parseEmail; exports.resolveVariableSymbol = _chunkPBN2BUNRcjs.resolveVariableSymbol; exports.setFioPointer = _chunkPBN2BUNRcjs.setFioPointer; exports.signWebhook = _chunkPBN2BUNRcjs.signWebhook; exports.toCents = _chunkPBN2BUNRcjs.toCents; exports.verifyWebhook = _chunkPBN2BUNRcjs.verifyWebhook;
@@ -0,0 +1,121 @@
1
+ import { T as Transaction, W as WebhookEnvelope } from './types-Cb5l2lXq.cjs';
2
+ export { B as BankAccount, a as WebhookConsumer, b as WebhookSubscription } from './types-Cb5l2lXq.cjs';
3
+
4
+ declare const BANK_CODES: Record<string, string>;
5
+ type EmailProvider = 'fio_email' | 'airbank_email';
6
+ declare function detectProvider(text: string, accountNumber: string | null): 'fio_email' | 'airbank_email' | 'unknown';
7
+ type ParsedEmailTransaction = Omit<Transaction, 'id' | 'bank_account_id' | 'created_at' | 'date'> & {
8
+ date: string | null;
9
+ };
10
+ declare function parseEmail(text: string, provider: EmailProvider): ParsedEmailTransaction | null;
11
+
12
+ declare function normalizeCurrency(raw: string): string;
13
+ declare function toCents(amount: number, currency: string): number;
14
+
15
+ /**
16
+ * Payment identification — the one place that knows what an order identifier
17
+ * looks like in free text. banksync extracts *candidate* tokens; the billing
18
+ * resolver (`billing_credit_mark_paid`) decides which pending order they hit.
19
+ *
20
+ * Carriers, in descending confidence:
21
+ * 1. the structured `vs` field (Czech variable symbol)
22
+ * 2. a labelled `VS<digits>` / `/VS/<digits>` token in the message
23
+ * 3. an ISO 11649 `RF` creditor reference (our EUR/EPC rail wraps the VS in it)
24
+ * 4. a bare VS-shaped 6–10 digit run
25
+ *
26
+ * A candidate only ever credits when it EQUALS a pending order's ledger-unique
27
+ * VS and the amount/currency guard passes — so over-generating here is safe.
28
+ */
29
+ interface ReferenceSource {
30
+ vs?: string | null;
31
+ ss?: string | null;
32
+ message?: string | null;
33
+ user_identification?: string | null;
34
+ comment?: string | null;
35
+ }
36
+ /**
37
+ * Canonical persistence value for a bank transaction. A real structured VS
38
+ * wins. Otherwise only a checksum-valid RF carrying a 1-10 digit VS may fill
39
+ * the field; labelled/bare free-text candidates remain resolver hints and are
40
+ * never promoted into stored structured data.
41
+ */
42
+ declare function resolveVariableSymbol(src: ReferenceSource): string | null;
43
+ declare function extractReferenceCandidates(src: ReferenceSource): string[];
44
+
45
+ interface SignedWebhook {
46
+ bodyBytes: Uint8Array;
47
+ headers: {
48
+ 'Content-Type': 'application/json';
49
+ 'X-BankSync-Timestamp': string;
50
+ 'X-BankSync-Delivery-Id': string;
51
+ 'X-BankSync-Signature': string;
52
+ };
53
+ }
54
+ declare function buildWebhookEnvelope(args: {
55
+ delivery_id: string;
56
+ pairing_code: string;
57
+ transaction: Transaction;
58
+ }): WebhookEnvelope;
59
+ declare function signWebhook(args: {
60
+ envelope: WebhookEnvelope;
61
+ secret: string;
62
+ timestamp?: number;
63
+ }): Promise<SignedWebhook>;
64
+ type WebhookVerificationCode = 'timestamp_invalid' | 'timestamp_out_of_range' | 'signature_invalid' | 'body_invalid' | 'delivery_id_mismatch' | 'event_unsupported' | 'event_version_unsupported';
65
+ declare class WebhookVerificationError extends Error {
66
+ readonly code: WebhookVerificationCode;
67
+ constructor(code: WebhookVerificationCode);
68
+ }
69
+ interface VerifyWebhookArgs {
70
+ secret: string;
71
+ timestamp: string;
72
+ deliveryId: string;
73
+ bodyBytes: Uint8Array;
74
+ signature: string;
75
+ toleranceSeconds?: number;
76
+ nowSeconds?: number;
77
+ }
78
+ /**
79
+ * Safe public verification contract. Consumers must durably claim the returned
80
+ * delivery_id before performing side effects; transport verification cannot
81
+ * provide durable replay protection by itself.
82
+ */
83
+ declare function verifyWebhook(args: VerifyWebhookArgs): Promise<WebhookEnvelope>;
84
+
85
+ /** Encode an alphanumeric payload as an ISO 11649 creditor reference. */
86
+ declare function encodeRf(input: string): string;
87
+ /** Validate an ISO 11649 creditor reference and return its payload. */
88
+ declare function decodeRf(input: unknown): string | null;
89
+
90
+ interface FioColumn {
91
+ value?: unknown;
92
+ }
93
+ type FioTransaction = Record<`column${number}`, FioColumn | undefined>;
94
+ declare class FioApiError extends Error {
95
+ readonly status: number;
96
+ constructor(message: string, status: number);
97
+ }
98
+ declare class FioRateLimited extends FioApiError {
99
+ readonly retryAfterS: number | null;
100
+ constructor(status: number, retryAfterS: number | null);
101
+ }
102
+ declare class FioTransientFailure extends FioApiError {
103
+ constructor(status: number);
104
+ }
105
+ /**
106
+ * Egress relay for Fio pulls. Cloudflare Workers `fetch()` to fioapi.fio.cz
107
+ * fails the TLS handshake (HTTP 525) — Fio blocks Cloudflare egress — while a
108
+ * a relay on a network accepted by Fio can reach it. When configured,
109
+ * Fio requests are POSTed to the proxy edge function which makes the real call
110
+ * from a non-Cloudflare IP and forwards Fio's status + body verbatim. When
111
+ * unset, requests go directly to Fio (legacy behaviour, used by unit tests).
112
+ */
113
+ interface FioProxyConfig {
114
+ url: string;
115
+ secret: string;
116
+ }
117
+ declare function fetchNewTransactions(token: string, proxy?: FioProxyConfig): Promise<FioTransaction[]>;
118
+ declare function setFioPointer(token: string, yyyyMmDd: string, proxy?: FioProxyConfig): Promise<void>;
119
+ declare function mapFioTransaction(raw: FioTransaction): Omit<Transaction, 'id' | 'bank_account_id'> | null;
120
+
121
+ export { BANK_CODES, type EmailProvider, FioApiError, type FioColumn, type FioProxyConfig, FioRateLimited, type FioTransaction, FioTransientFailure, type ParsedEmailTransaction, type ReferenceSource, type SignedWebhook, Transaction, type VerifyWebhookArgs, WebhookEnvelope, type WebhookVerificationCode, WebhookVerificationError, buildWebhookEnvelope, decodeRf, detectProvider, encodeRf, extractReferenceCandidates, fetchNewTransactions, mapFioTransaction, normalizeCurrency, parseEmail, resolveVariableSymbol, setFioPointer, signWebhook, toCents, verifyWebhook };
@@ -0,0 +1,121 @@
1
+ import { T as Transaction, W as WebhookEnvelope } from './types-Cb5l2lXq.js';
2
+ export { B as BankAccount, a as WebhookConsumer, b as WebhookSubscription } from './types-Cb5l2lXq.js';
3
+
4
+ declare const BANK_CODES: Record<string, string>;
5
+ type EmailProvider = 'fio_email' | 'airbank_email';
6
+ declare function detectProvider(text: string, accountNumber: string | null): 'fio_email' | 'airbank_email' | 'unknown';
7
+ type ParsedEmailTransaction = Omit<Transaction, 'id' | 'bank_account_id' | 'created_at' | 'date'> & {
8
+ date: string | null;
9
+ };
10
+ declare function parseEmail(text: string, provider: EmailProvider): ParsedEmailTransaction | null;
11
+
12
+ declare function normalizeCurrency(raw: string): string;
13
+ declare function toCents(amount: number, currency: string): number;
14
+
15
+ /**
16
+ * Payment identification — the one place that knows what an order identifier
17
+ * looks like in free text. banksync extracts *candidate* tokens; the billing
18
+ * resolver (`billing_credit_mark_paid`) decides which pending order they hit.
19
+ *
20
+ * Carriers, in descending confidence:
21
+ * 1. the structured `vs` field (Czech variable symbol)
22
+ * 2. a labelled `VS<digits>` / `/VS/<digits>` token in the message
23
+ * 3. an ISO 11649 `RF` creditor reference (our EUR/EPC rail wraps the VS in it)
24
+ * 4. a bare VS-shaped 6–10 digit run
25
+ *
26
+ * A candidate only ever credits when it EQUALS a pending order's ledger-unique
27
+ * VS and the amount/currency guard passes — so over-generating here is safe.
28
+ */
29
+ interface ReferenceSource {
30
+ vs?: string | null;
31
+ ss?: string | null;
32
+ message?: string | null;
33
+ user_identification?: string | null;
34
+ comment?: string | null;
35
+ }
36
+ /**
37
+ * Canonical persistence value for a bank transaction. A real structured VS
38
+ * wins. Otherwise only a checksum-valid RF carrying a 1-10 digit VS may fill
39
+ * the field; labelled/bare free-text candidates remain resolver hints and are
40
+ * never promoted into stored structured data.
41
+ */
42
+ declare function resolveVariableSymbol(src: ReferenceSource): string | null;
43
+ declare function extractReferenceCandidates(src: ReferenceSource): string[];
44
+
45
+ interface SignedWebhook {
46
+ bodyBytes: Uint8Array;
47
+ headers: {
48
+ 'Content-Type': 'application/json';
49
+ 'X-BankSync-Timestamp': string;
50
+ 'X-BankSync-Delivery-Id': string;
51
+ 'X-BankSync-Signature': string;
52
+ };
53
+ }
54
+ declare function buildWebhookEnvelope(args: {
55
+ delivery_id: string;
56
+ pairing_code: string;
57
+ transaction: Transaction;
58
+ }): WebhookEnvelope;
59
+ declare function signWebhook(args: {
60
+ envelope: WebhookEnvelope;
61
+ secret: string;
62
+ timestamp?: number;
63
+ }): Promise<SignedWebhook>;
64
+ type WebhookVerificationCode = 'timestamp_invalid' | 'timestamp_out_of_range' | 'signature_invalid' | 'body_invalid' | 'delivery_id_mismatch' | 'event_unsupported' | 'event_version_unsupported';
65
+ declare class WebhookVerificationError extends Error {
66
+ readonly code: WebhookVerificationCode;
67
+ constructor(code: WebhookVerificationCode);
68
+ }
69
+ interface VerifyWebhookArgs {
70
+ secret: string;
71
+ timestamp: string;
72
+ deliveryId: string;
73
+ bodyBytes: Uint8Array;
74
+ signature: string;
75
+ toleranceSeconds?: number;
76
+ nowSeconds?: number;
77
+ }
78
+ /**
79
+ * Safe public verification contract. Consumers must durably claim the returned
80
+ * delivery_id before performing side effects; transport verification cannot
81
+ * provide durable replay protection by itself.
82
+ */
83
+ declare function verifyWebhook(args: VerifyWebhookArgs): Promise<WebhookEnvelope>;
84
+
85
+ /** Encode an alphanumeric payload as an ISO 11649 creditor reference. */
86
+ declare function encodeRf(input: string): string;
87
+ /** Validate an ISO 11649 creditor reference and return its payload. */
88
+ declare function decodeRf(input: unknown): string | null;
89
+
90
+ interface FioColumn {
91
+ value?: unknown;
92
+ }
93
+ type FioTransaction = Record<`column${number}`, FioColumn | undefined>;
94
+ declare class FioApiError extends Error {
95
+ readonly status: number;
96
+ constructor(message: string, status: number);
97
+ }
98
+ declare class FioRateLimited extends FioApiError {
99
+ readonly retryAfterS: number | null;
100
+ constructor(status: number, retryAfterS: number | null);
101
+ }
102
+ declare class FioTransientFailure extends FioApiError {
103
+ constructor(status: number);
104
+ }
105
+ /**
106
+ * Egress relay for Fio pulls. Cloudflare Workers `fetch()` to fioapi.fio.cz
107
+ * fails the TLS handshake (HTTP 525) — Fio blocks Cloudflare egress — while a
108
+ * a relay on a network accepted by Fio can reach it. When configured,
109
+ * Fio requests are POSTed to the proxy edge function which makes the real call
110
+ * from a non-Cloudflare IP and forwards Fio's status + body verbatim. When
111
+ * unset, requests go directly to Fio (legacy behaviour, used by unit tests).
112
+ */
113
+ interface FioProxyConfig {
114
+ url: string;
115
+ secret: string;
116
+ }
117
+ declare function fetchNewTransactions(token: string, proxy?: FioProxyConfig): Promise<FioTransaction[]>;
118
+ declare function setFioPointer(token: string, yyyyMmDd: string, proxy?: FioProxyConfig): Promise<void>;
119
+ declare function mapFioTransaction(raw: FioTransaction): Omit<Transaction, 'id' | 'bank_account_id'> | null;
120
+
121
+ export { BANK_CODES, type EmailProvider, FioApiError, type FioColumn, type FioProxyConfig, FioRateLimited, type FioTransaction, FioTransientFailure, type ParsedEmailTransaction, type ReferenceSource, type SignedWebhook, Transaction, type VerifyWebhookArgs, WebhookEnvelope, type WebhookVerificationCode, WebhookVerificationError, buildWebhookEnvelope, decodeRf, detectProvider, encodeRf, extractReferenceCandidates, fetchNewTransactions, mapFioTransaction, normalizeCurrency, parseEmail, resolveVariableSymbol, setFioPointer, signWebhook, toCents, verifyWebhook };
package/dist/index.js ADDED
@@ -0,0 +1,42 @@
1
+ import {
2
+ BANK_CODES,
3
+ FioApiError,
4
+ FioRateLimited,
5
+ FioTransientFailure,
6
+ WebhookVerificationError,
7
+ buildWebhookEnvelope,
8
+ decodeRf,
9
+ detectProvider,
10
+ encodeRf,
11
+ extractReferenceCandidates,
12
+ fetchNewTransactions,
13
+ mapFioTransaction,
14
+ normalizeCurrency,
15
+ parseEmail,
16
+ resolveVariableSymbol,
17
+ setFioPointer,
18
+ signWebhook,
19
+ toCents,
20
+ verifyWebhook
21
+ } from "./chunk-5QXHZGAW.js";
22
+ export {
23
+ BANK_CODES,
24
+ FioApiError,
25
+ FioRateLimited,
26
+ FioTransientFailure,
27
+ WebhookVerificationError,
28
+ buildWebhookEnvelope,
29
+ decodeRf,
30
+ detectProvider,
31
+ encodeRf,
32
+ extractReferenceCandidates,
33
+ fetchNewTransactions,
34
+ mapFioTransaction,
35
+ normalizeCurrency,
36
+ parseEmail,
37
+ resolveVariableSymbol,
38
+ setFioPointer,
39
+ signWebhook,
40
+ toCents,
41
+ verifyWebhook
42
+ };
@@ -0,0 +1,86 @@
1
+ interface BankAccount {
2
+ id: number;
3
+ account_number: string;
4
+ account_type: string;
5
+ ingest_mode: 'email' | 'api' | 'both';
6
+ pairing_code: string;
7
+ label: string | null;
8
+ owner_app_id: string | null;
9
+ /** CF Email Routing rule id (set when banksync calls CF API on account create); null in dev/test environments without CF_API_TOKEN. */
10
+ cf_rule_id: string | null;
11
+ api_token_set: boolean;
12
+ api_token_prefix: string | null;
13
+ api_fetch_enabled: boolean;
14
+ api_last_fetch_at: string | null;
15
+ api_last_success_at: string | null;
16
+ api_last_error: string | null;
17
+ api_backfill_done: boolean;
18
+ created_at: string;
19
+ }
20
+ interface Transaction {
21
+ id: number;
22
+ bank_account_id: number;
23
+ /** INTEGER, lowest unit (e.g. 1990 = 19.90 CZK), incoming-only — always positive */
24
+ amount_cents: number;
25
+ /** ISO 4217 alpha-3 uppercase (CZK/EUR/USD) */
26
+ currency: string;
27
+ counter_account: string | null;
28
+ bank_code: string | null;
29
+ bank_name: string | null;
30
+ vs: string | null;
31
+ ks: string | null;
32
+ ss: string | null;
33
+ message: string | null;
34
+ sender_name: string | null;
35
+ /** Fio API column7, available only from Fio API pull */
36
+ user_identification: string | null;
37
+ /** Fio API column8, available only from Fio API pull */
38
+ transaction_type: string | null;
39
+ /** Fio API column9, available only from Fio API pull */
40
+ performed_by: string | null;
41
+ /** Fio API column25, available only from Fio API pull */
42
+ comment: string | null;
43
+ /** Fio API column17 — ID pokynu, available only from Fio API pull */
44
+ command_id: string | null;
45
+ source: 'email' | 'fio_api';
46
+ date: string;
47
+ /** Original timezone offset in minutes (e.g. CET=60, CEST=120). Debug only — all queries use UTC date. */
48
+ date_offset_min: number | null;
49
+ transaction_id: string | null;
50
+ external_id: string | null;
51
+ }
52
+ interface WebhookEnvelope {
53
+ event: 'transaction.received';
54
+ /** Bumped when shape of `data` or signing string changes */
55
+ event_version: '1';
56
+ /** ULID, stable across retries — sole idempotence key */
57
+ delivery_id: string;
58
+ pairing_code: string;
59
+ data: Transaction;
60
+ }
61
+ interface WebhookConsumer {
62
+ id: number;
63
+ app_id: string;
64
+ callback_url: string;
65
+ /** AES-GCM ciphertext; base64(iv || ct || tag) */
66
+ secret_cipher: string;
67
+ /** SHA-256(plaintext) hex — audit / mismatch detection */
68
+ secret_hash: string;
69
+ /** First 6 characters of plaintext for identification */
70
+ secret_prefix: string;
71
+ /** Previous secret ciphertext during rotation grace period */
72
+ prev_secret_cipher: string | null;
73
+ /** UTC ISO; NULL when no active rotation grace */
74
+ prev_expires_at: string | null;
75
+ admin_key_hash: string | null;
76
+ admin_key_prefix: string | null;
77
+ created_at: string;
78
+ }
79
+ interface WebhookSubscription {
80
+ id: number;
81
+ bank_account_id: number;
82
+ consumer_app_id: string;
83
+ created_at: string;
84
+ }
85
+
86
+ export type { BankAccount as B, Transaction as T, WebhookEnvelope as W, WebhookConsumer as a, WebhookSubscription as b };
@@ -0,0 +1,86 @@
1
+ interface BankAccount {
2
+ id: number;
3
+ account_number: string;
4
+ account_type: string;
5
+ ingest_mode: 'email' | 'api' | 'both';
6
+ pairing_code: string;
7
+ label: string | null;
8
+ owner_app_id: string | null;
9
+ /** CF Email Routing rule id (set when banksync calls CF API on account create); null in dev/test environments without CF_API_TOKEN. */
10
+ cf_rule_id: string | null;
11
+ api_token_set: boolean;
12
+ api_token_prefix: string | null;
13
+ api_fetch_enabled: boolean;
14
+ api_last_fetch_at: string | null;
15
+ api_last_success_at: string | null;
16
+ api_last_error: string | null;
17
+ api_backfill_done: boolean;
18
+ created_at: string;
19
+ }
20
+ interface Transaction {
21
+ id: number;
22
+ bank_account_id: number;
23
+ /** INTEGER, lowest unit (e.g. 1990 = 19.90 CZK), incoming-only — always positive */
24
+ amount_cents: number;
25
+ /** ISO 4217 alpha-3 uppercase (CZK/EUR/USD) */
26
+ currency: string;
27
+ counter_account: string | null;
28
+ bank_code: string | null;
29
+ bank_name: string | null;
30
+ vs: string | null;
31
+ ks: string | null;
32
+ ss: string | null;
33
+ message: string | null;
34
+ sender_name: string | null;
35
+ /** Fio API column7, available only from Fio API pull */
36
+ user_identification: string | null;
37
+ /** Fio API column8, available only from Fio API pull */
38
+ transaction_type: string | null;
39
+ /** Fio API column9, available only from Fio API pull */
40
+ performed_by: string | null;
41
+ /** Fio API column25, available only from Fio API pull */
42
+ comment: string | null;
43
+ /** Fio API column17 — ID pokynu, available only from Fio API pull */
44
+ command_id: string | null;
45
+ source: 'email' | 'fio_api';
46
+ date: string;
47
+ /** Original timezone offset in minutes (e.g. CET=60, CEST=120). Debug only — all queries use UTC date. */
48
+ date_offset_min: number | null;
49
+ transaction_id: string | null;
50
+ external_id: string | null;
51
+ }
52
+ interface WebhookEnvelope {
53
+ event: 'transaction.received';
54
+ /** Bumped when shape of `data` or signing string changes */
55
+ event_version: '1';
56
+ /** ULID, stable across retries — sole idempotence key */
57
+ delivery_id: string;
58
+ pairing_code: string;
59
+ data: Transaction;
60
+ }
61
+ interface WebhookConsumer {
62
+ id: number;
63
+ app_id: string;
64
+ callback_url: string;
65
+ /** AES-GCM ciphertext; base64(iv || ct || tag) */
66
+ secret_cipher: string;
67
+ /** SHA-256(plaintext) hex — audit / mismatch detection */
68
+ secret_hash: string;
69
+ /** First 6 characters of plaintext for identification */
70
+ secret_prefix: string;
71
+ /** Previous secret ciphertext during rotation grace period */
72
+ prev_secret_cipher: string | null;
73
+ /** UTC ISO; NULL when no active rotation grace */
74
+ prev_expires_at: string | null;
75
+ admin_key_hash: string | null;
76
+ admin_key_prefix: string | null;
77
+ created_at: string;
78
+ }
79
+ interface WebhookSubscription {
80
+ id: number;
81
+ bank_account_id: number;
82
+ consumer_app_id: string;
83
+ created_at: string;
84
+ }
85
+
86
+ export type { BankAccount as B, Transaction as T, WebhookEnvelope as W, WebhookConsumer as a, WebhookSubscription as b };