BREAKING CHANGE(core): implement complete stateless architecture with consumer-controlled session persistence
This commit is contained in:
172
example.stateless.ts
Normal file
172
example.stateless.ts
Normal file
@@ -0,0 +1,172 @@
|
||||
import * as bunq from './ts/index.js';
|
||||
|
||||
// Example of stateless usage of the bunq library
|
||||
|
||||
// 1. Initial session creation
|
||||
async function createNewSession() {
|
||||
const bunqAccount = new bunq.BunqAccount({
|
||||
apiKey: 'your-api-key',
|
||||
deviceName: 'my-app',
|
||||
environment: 'PRODUCTION',
|
||||
});
|
||||
|
||||
// Initialize and get session data
|
||||
const sessionData = await bunqAccount.init();
|
||||
|
||||
// Save session data to your preferred storage (database, file, etc.)
|
||||
await saveSessionToDatabase(sessionData);
|
||||
|
||||
// Use the account
|
||||
const { accounts } = await bunqAccount.getAccounts();
|
||||
console.log('Found accounts:', accounts.length);
|
||||
|
||||
return sessionData;
|
||||
}
|
||||
|
||||
// 2. Reusing an existing session
|
||||
async function reuseExistingSession() {
|
||||
// Load session data from your storage
|
||||
const sessionData = await loadSessionFromDatabase();
|
||||
|
||||
const bunqAccount = new bunq.BunqAccount({
|
||||
apiKey: 'your-api-key',
|
||||
deviceName: 'my-app',
|
||||
environment: 'PRODUCTION',
|
||||
});
|
||||
|
||||
// Initialize with existing session
|
||||
await bunqAccount.initWithSession(sessionData);
|
||||
|
||||
// Use the account - session refresh happens automatically
|
||||
const { accounts, sessionData: updatedSession } = await bunqAccount.getAccounts();
|
||||
|
||||
// If session was refreshed, save the updated session data
|
||||
if (updatedSession) {
|
||||
await saveSessionToDatabase(updatedSession);
|
||||
}
|
||||
|
||||
return accounts;
|
||||
}
|
||||
|
||||
// 3. OAuth token with existing installation
|
||||
async function oauthWithExistingInstallation() {
|
||||
const bunqAccount = new bunq.BunqAccount({
|
||||
apiKey: 'oauth-access-token',
|
||||
deviceName: 'my-oauth-app',
|
||||
environment: 'PRODUCTION',
|
||||
isOAuthToken: true,
|
||||
});
|
||||
|
||||
try {
|
||||
// Try normal initialization
|
||||
const sessionData = await bunqAccount.init();
|
||||
await saveSessionToDatabase(sessionData);
|
||||
} catch (error) {
|
||||
// If OAuth token already has installation, use existing
|
||||
const existingInstallation = await loadInstallationFromDatabase();
|
||||
const sessionData = await bunqAccount.initOAuthWithExistingInstallation(existingInstallation);
|
||||
await saveSessionToDatabase(sessionData);
|
||||
}
|
||||
}
|
||||
|
||||
// 4. Session validation
|
||||
async function validateAndRefreshSession() {
|
||||
const sessionData = await loadSessionFromDatabase();
|
||||
|
||||
const bunqAccount = new bunq.BunqAccount({
|
||||
apiKey: 'your-api-key',
|
||||
deviceName: 'my-app',
|
||||
environment: 'PRODUCTION',
|
||||
});
|
||||
|
||||
try {
|
||||
await bunqAccount.initWithSession(sessionData);
|
||||
|
||||
if (!bunqAccount.isSessionValid()) {
|
||||
// Session expired, create new one
|
||||
const newSessionData = await bunqAccount.init();
|
||||
await saveSessionToDatabase(newSessionData);
|
||||
}
|
||||
} catch (error) {
|
||||
// Session invalid, create new one
|
||||
const newSessionData = await bunqAccount.init();
|
||||
await saveSessionToDatabase(newSessionData);
|
||||
}
|
||||
}
|
||||
|
||||
// 5. Complete example with error handling
|
||||
async function completeExample() {
|
||||
let bunqAccount: bunq.BunqAccount;
|
||||
let sessionData: bunq.ISessionData;
|
||||
|
||||
try {
|
||||
// Try to load existing session
|
||||
const existingSession = await loadSessionFromDatabase();
|
||||
|
||||
bunqAccount = new bunq.BunqAccount({
|
||||
apiKey: process.env.BUNQ_API_KEY!,
|
||||
deviceName: 'my-production-app',
|
||||
environment: 'PRODUCTION',
|
||||
});
|
||||
|
||||
if (existingSession) {
|
||||
try {
|
||||
await bunqAccount.initWithSession(existingSession);
|
||||
console.log('Reused existing session');
|
||||
} catch (error) {
|
||||
// Session invalid, create new one
|
||||
sessionData = await bunqAccount.init();
|
||||
await saveSessionToDatabase(sessionData);
|
||||
console.log('Created new session');
|
||||
}
|
||||
} else {
|
||||
// No existing session, create new one
|
||||
sessionData = await bunqAccount.init();
|
||||
await saveSessionToDatabase(sessionData);
|
||||
console.log('Created new session');
|
||||
}
|
||||
|
||||
// Use the API
|
||||
const { accounts, sessionData: updatedSession } = await bunqAccount.getAccounts();
|
||||
|
||||
// Save updated session if it was refreshed
|
||||
if (updatedSession) {
|
||||
await saveSessionToDatabase(updatedSession);
|
||||
console.log('Session was refreshed');
|
||||
}
|
||||
|
||||
// Make a payment
|
||||
const account = accounts[0];
|
||||
const payment = await bunq.BunqPayment.builder(bunqAccount, account)
|
||||
.amount('10.00', 'EUR')
|
||||
.toIban('NL91ABNA0417164300', 'Test Recipient')
|
||||
.description('Test payment')
|
||||
.create();
|
||||
|
||||
console.log('Payment created:', payment.id);
|
||||
|
||||
// Clean up
|
||||
await bunqAccount.stop();
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// Mock storage functions (implement these with your actual storage)
|
||||
async function saveSessionToDatabase(sessionData: bunq.ISessionData): Promise<void> {
|
||||
// Implement your storage logic here
|
||||
// Example: await db.sessions.save(sessionData);
|
||||
}
|
||||
|
||||
async function loadSessionFromDatabase(): Promise<bunq.ISessionData | null> {
|
||||
// Implement your storage logic here
|
||||
// Example: return await db.sessions.findLatest();
|
||||
return null;
|
||||
}
|
||||
|
||||
async function loadInstallationFromDatabase(): Promise<Partial<bunq.ISessionData> | undefined> {
|
||||
// Load just the installation data needed for OAuth
|
||||
// Example: return await db.installations.findByApiKey();
|
||||
return undefined;
|
||||
}
|
Reference in New Issue
Block a user