feat: add store (JSON persistence) and Enable Banking API client
store.js: read/write ./data/store.json; holds config, tokens, agreements, requisitions, account mappings. eb-client.js: RS256 JWT auth (cached, refreshed 60s before expiry), wrappers for /aspsps, /auth, /sessions, /accounts/* endpoints. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
* Persistent JSON store — backed by ./data/store.json (Docker volume mount).
|
||||
*
|
||||
* Schema:
|
||||
* {
|
||||
* config: { eb_app_id, eb_private_key, gc_secret_id, gc_secret_key } | null,
|
||||
* gc_tokens: { [token]: { type: "access"|"refresh", expires_at } },
|
||||
* institutions_cache: [...] | null,
|
||||
* institutions_cache_at: 0,
|
||||
* agreements: { [gc_id]: { id, created, institution_id, max_historical_days,
|
||||
* access_valid_for_days, access_scope } },
|
||||
* requisitions: { [gc_id]: { id, created, status, institution_id, agreements,
|
||||
* accounts, reference, redirect, link,
|
||||
* eb_auth_id, eb_session_id } },
|
||||
* accounts: { [gc_id]: { gc_id, eb_uid, institution_id, iban, currency,
|
||||
* owner_name, name, product, created, last_accessed } }
|
||||
* }
|
||||
*/
|
||||
|
||||
import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs';
|
||||
import { dirname } from 'path';
|
||||
|
||||
const STORE_PATH = process.env.STORE_PATH || './data/store.json';
|
||||
|
||||
const EMPTY = () => ({
|
||||
config: null,
|
||||
gc_tokens: {},
|
||||
institutions_cache: null,
|
||||
institutions_cache_at: 0,
|
||||
agreements: {},
|
||||
requisitions: {},
|
||||
accounts: {},
|
||||
});
|
||||
|
||||
let _store = null;
|
||||
|
||||
export function load() {
|
||||
if (!existsSync(STORE_PATH)) return EMPTY();
|
||||
try {
|
||||
return JSON.parse(readFileSync(STORE_PATH, 'utf8'));
|
||||
} catch {
|
||||
return EMPTY();
|
||||
}
|
||||
}
|
||||
|
||||
export function get() {
|
||||
if (!_store) _store = load();
|
||||
return _store;
|
||||
}
|
||||
|
||||
export function save() {
|
||||
const dir = dirname(STORE_PATH);
|
||||
mkdirSync(dir, { recursive: true });
|
||||
writeFileSync(STORE_PATH, JSON.stringify(_store ?? EMPTY(), null, 2));
|
||||
}
|
||||
|
||||
/** Apply a mutation function and persist immediately. */
|
||||
export function update(fn) {
|
||||
const s = get();
|
||||
fn(s);
|
||||
save();
|
||||
}
|
||||
Reference in New Issue
Block a user