@ktmcp-cli/nordigen 1.0.0 → 1.0.2
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/AGENT.md +153 -434
- package/README.md +133 -321
- package/bin/nordigen.js +2 -76
- package/package.json +21 -21
- package/src/api.js +229 -0
- package/src/config.js +59 -0
- package/src/index.js +633 -0
- package/.env.example +0 -11
- package/.eslintrc.json +0 -17
- package/CHANGELOG.md +0 -69
- package/CONTRIBUTING.md +0 -198
- package/EXAMPLES.md +0 -561
- package/INDEX.md +0 -193
- package/OPENCLAW.md +0 -468
- package/PROJECT.md +0 -366
- package/QUICKREF.md +0 -231
- package/SETUP.md +0 -259
- package/SUMMARY.md +0 -419
- package/banner.png +0 -0
- package/logo.png +0 -0
- package/scripts/quickstart.sh +0 -110
- package/src/commands/accounts.js +0 -205
- package/src/commands/agreements.js +0 -241
- package/src/commands/auth.js +0 -86
- package/src/commands/config.js +0 -173
- package/src/commands/institutions.js +0 -181
- package/src/commands/payments.js +0 -228
- package/src/commands/requisitions.js +0 -239
- package/src/lib/api.js +0 -491
- package/src/lib/auth.js +0 -113
- package/src/lib/config.js +0 -145
- package/src/lib/output.js +0 -255
- package/test/api.test.js +0 -88
package/scripts/quickstart.sh
DELETED
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
|
|
3
|
-
# Nordigen CLI Quick Start Script
|
|
4
|
-
# This script helps you get started with the Nordigen CLI
|
|
5
|
-
|
|
6
|
-
set -e
|
|
7
|
-
|
|
8
|
-
echo "======================================"
|
|
9
|
-
echo "Nordigen CLI - Quick Start"
|
|
10
|
-
echo "======================================"
|
|
11
|
-
echo
|
|
12
|
-
|
|
13
|
-
# Check if Node.js is installed
|
|
14
|
-
if ! command -v node &> /dev/null; then
|
|
15
|
-
echo "Error: Node.js is not installed"
|
|
16
|
-
echo "Please install Node.js 18+ from https://nodejs.org"
|
|
17
|
-
exit 1
|
|
18
|
-
fi
|
|
19
|
-
|
|
20
|
-
NODE_VERSION=$(node --version | cut -d'v' -f2 | cut -d'.' -f1)
|
|
21
|
-
if [ "$NODE_VERSION" -lt 18 ]; then
|
|
22
|
-
echo "Error: Node.js version 18 or higher is required"
|
|
23
|
-
echo "Current version: $(node --version)"
|
|
24
|
-
exit 1
|
|
25
|
-
fi
|
|
26
|
-
|
|
27
|
-
echo "Node.js version: $(node --version) ✓"
|
|
28
|
-
echo
|
|
29
|
-
|
|
30
|
-
# Install dependencies
|
|
31
|
-
echo "Installing dependencies..."
|
|
32
|
-
npm install
|
|
33
|
-
echo "Dependencies installed ✓"
|
|
34
|
-
echo
|
|
35
|
-
|
|
36
|
-
# Make CLI executable
|
|
37
|
-
chmod +x bin/nordigen.js
|
|
38
|
-
echo "Made CLI executable ✓"
|
|
39
|
-
echo
|
|
40
|
-
|
|
41
|
-
# Link CLI
|
|
42
|
-
echo "Linking CLI globally..."
|
|
43
|
-
npm link
|
|
44
|
-
echo "CLI linked ✓"
|
|
45
|
-
echo
|
|
46
|
-
|
|
47
|
-
# Check if credentials are set
|
|
48
|
-
if [ -z "$NORDIGEN_SECRET_ID" ] || [ -z "$NORDIGEN_SECRET_KEY" ]; then
|
|
49
|
-
echo "======================================"
|
|
50
|
-
echo "Setup Instructions"
|
|
51
|
-
echo "======================================"
|
|
52
|
-
echo
|
|
53
|
-
echo "1. Get API credentials:"
|
|
54
|
-
echo " Visit https://nordigen.com/en/account/login/"
|
|
55
|
-
echo " Navigate to: User Secrets → Create New Secret"
|
|
56
|
-
echo
|
|
57
|
-
echo "2. Set environment variables:"
|
|
58
|
-
echo " export NORDIGEN_SECRET_ID='your_secret_id'"
|
|
59
|
-
echo " export NORDIGEN_SECRET_KEY='your_secret_key'"
|
|
60
|
-
echo
|
|
61
|
-
echo "3. Authenticate:"
|
|
62
|
-
echo " nordigen auth login \\"
|
|
63
|
-
echo " --secret-id \$NORDIGEN_SECRET_ID \\"
|
|
64
|
-
echo " --secret-key \$NORDIGEN_SECRET_KEY"
|
|
65
|
-
echo
|
|
66
|
-
echo "4. Test the CLI:"
|
|
67
|
-
echo " nordigen institutions list --country GB"
|
|
68
|
-
echo
|
|
69
|
-
else
|
|
70
|
-
echo "======================================"
|
|
71
|
-
echo "Authenticating..."
|
|
72
|
-
echo "======================================"
|
|
73
|
-
echo
|
|
74
|
-
|
|
75
|
-
if nordigen auth login \
|
|
76
|
-
--secret-id "$NORDIGEN_SECRET_ID" \
|
|
77
|
-
--secret-key "$NORDIGEN_SECRET_KEY"; then
|
|
78
|
-
echo
|
|
79
|
-
echo "Authentication successful ✓"
|
|
80
|
-
echo
|
|
81
|
-
|
|
82
|
-
# Test with a simple command
|
|
83
|
-
echo "Testing CLI..."
|
|
84
|
-
if nordigen institutions list --country GB --json > /dev/null 2>&1; then
|
|
85
|
-
echo "CLI test successful ✓"
|
|
86
|
-
echo
|
|
87
|
-
|
|
88
|
-
echo "======================================"
|
|
89
|
-
echo "Quick Start Complete!"
|
|
90
|
-
echo "======================================"
|
|
91
|
-
echo
|
|
92
|
-
echo "Try these commands:"
|
|
93
|
-
echo " nordigen --help"
|
|
94
|
-
echo " nordigen institutions list --country GB"
|
|
95
|
-
echo " nordigen auth status"
|
|
96
|
-
echo
|
|
97
|
-
else
|
|
98
|
-
echo "Warning: CLI test failed"
|
|
99
|
-
echo "Check your credentials and try again"
|
|
100
|
-
fi
|
|
101
|
-
else
|
|
102
|
-
echo
|
|
103
|
-
echo "Authentication failed"
|
|
104
|
-
echo "Please check your credentials and try again"
|
|
105
|
-
exit 1
|
|
106
|
-
fi
|
|
107
|
-
fi
|
|
108
|
-
|
|
109
|
-
echo "For more information, see README.md"
|
|
110
|
-
echo
|
package/src/commands/accounts.js
DELETED
|
@@ -1,205 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Account Commands
|
|
3
|
-
*
|
|
4
|
-
* @fileoverview Commands for managing and retrieving account data
|
|
5
|
-
* @module commands/accounts
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { Command } from 'commander';
|
|
9
|
-
import chalk from 'chalk';
|
|
10
|
-
import ora from 'ora';
|
|
11
|
-
import { createClient } from '../lib/api.js';
|
|
12
|
-
import { ensureAuth } from '../lib/auth.js';
|
|
13
|
-
import {
|
|
14
|
-
printJSON,
|
|
15
|
-
printSuccess,
|
|
16
|
-
printError,
|
|
17
|
-
printSection,
|
|
18
|
-
printRow,
|
|
19
|
-
printAccountSummary,
|
|
20
|
-
printTransaction,
|
|
21
|
-
formatCurrency,
|
|
22
|
-
formatDateString,
|
|
23
|
-
formatStatus,
|
|
24
|
-
} from '../lib/output.js';
|
|
25
|
-
|
|
26
|
-
export const accountsCommand = new Command('accounts')
|
|
27
|
-
.description('Account information and data retrieval')
|
|
28
|
-
.alias('acc');
|
|
29
|
-
|
|
30
|
-
// Get account metadata
|
|
31
|
-
accountsCommand
|
|
32
|
-
.command('get')
|
|
33
|
-
.description('Get account metadata')
|
|
34
|
-
.argument('<account-id>', 'Account UUID')
|
|
35
|
-
.option('-j, --json', 'Output as JSON')
|
|
36
|
-
.action(async (accountId, options) => {
|
|
37
|
-
const spinner = ora('Fetching account...').start();
|
|
38
|
-
|
|
39
|
-
try {
|
|
40
|
-
await ensureAuth();
|
|
41
|
-
const api = createClient();
|
|
42
|
-
const account = await api.getAccount(accountId);
|
|
43
|
-
|
|
44
|
-
spinner.succeed('Account retrieved');
|
|
45
|
-
|
|
46
|
-
if (options.json) {
|
|
47
|
-
printJSON(account);
|
|
48
|
-
} else {
|
|
49
|
-
printAccountSummary(account);
|
|
50
|
-
}
|
|
51
|
-
} catch (error) {
|
|
52
|
-
spinner.fail('Failed to fetch account');
|
|
53
|
-
printError(error.message, error);
|
|
54
|
-
process.exit(1);
|
|
55
|
-
}
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
// Get account balances
|
|
59
|
-
accountsCommand
|
|
60
|
-
.command('balances')
|
|
61
|
-
.description('Get account balances')
|
|
62
|
-
.argument('<account-id>', 'Account UUID')
|
|
63
|
-
.option('-j, --json', 'Output as JSON')
|
|
64
|
-
.action(async (accountId, options) => {
|
|
65
|
-
const spinner = ora('Fetching balances...').start();
|
|
66
|
-
|
|
67
|
-
try {
|
|
68
|
-
await ensureAuth();
|
|
69
|
-
const api = createClient();
|
|
70
|
-
const data = await api.getAccountBalances(accountId);
|
|
71
|
-
|
|
72
|
-
spinner.succeed('Balances retrieved');
|
|
73
|
-
|
|
74
|
-
if (options.json) {
|
|
75
|
-
printJSON(data);
|
|
76
|
-
} else {
|
|
77
|
-
printSection('Account Balances');
|
|
78
|
-
|
|
79
|
-
if (data.balances && data.balances.length > 0) {
|
|
80
|
-
data.balances.forEach((balance) => {
|
|
81
|
-
const amount = balance.balanceAmount || {};
|
|
82
|
-
const type = balance.balanceType || 'N/A';
|
|
83
|
-
console.log(
|
|
84
|
-
chalk.cyan(type.padEnd(20)),
|
|
85
|
-
formatCurrency(amount.amount, amount.currency),
|
|
86
|
-
balance.referenceDate ? chalk.gray(`(${formatDateString(balance.referenceDate)})`) : ''
|
|
87
|
-
);
|
|
88
|
-
});
|
|
89
|
-
} else {
|
|
90
|
-
console.log(chalk.yellow('No balance information available'));
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
} catch (error) {
|
|
94
|
-
spinner.fail('Failed to fetch balances');
|
|
95
|
-
printError(error.message, error);
|
|
96
|
-
process.exit(1);
|
|
97
|
-
}
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
// Get account details
|
|
101
|
-
accountsCommand
|
|
102
|
-
.command('details')
|
|
103
|
-
.description('Get account details')
|
|
104
|
-
.argument('<account-id>', 'Account UUID')
|
|
105
|
-
.option('-j, --json', 'Output as JSON')
|
|
106
|
-
.action(async (accountId, options) => {
|
|
107
|
-
const spinner = ora('Fetching account details...').start();
|
|
108
|
-
|
|
109
|
-
try {
|
|
110
|
-
await ensureAuth();
|
|
111
|
-
const api = createClient();
|
|
112
|
-
const data = await api.getAccountDetails(accountId);
|
|
113
|
-
|
|
114
|
-
spinner.succeed('Account details retrieved');
|
|
115
|
-
|
|
116
|
-
if (options.json) {
|
|
117
|
-
printJSON(data);
|
|
118
|
-
} else {
|
|
119
|
-
printSection('Account Details');
|
|
120
|
-
|
|
121
|
-
const account = data.account || {};
|
|
122
|
-
if (account.iban) printRow('IBAN', account.iban);
|
|
123
|
-
if (account.bban) printRow('BBAN', account.bban);
|
|
124
|
-
if (account.name) printRow('Name', account.name);
|
|
125
|
-
if (account.product) printRow('Product', account.product);
|
|
126
|
-
if (account.cashAccountType) printRow('Type', account.cashAccountType);
|
|
127
|
-
if (account.currency) printRow('Currency', account.currency);
|
|
128
|
-
if (account.ownerName) printRow('Owner', account.ownerName);
|
|
129
|
-
}
|
|
130
|
-
} catch (error) {
|
|
131
|
-
spinner.fail('Failed to fetch account details');
|
|
132
|
-
printError(error.message, error);
|
|
133
|
-
process.exit(1);
|
|
134
|
-
}
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
// Get account transactions
|
|
138
|
-
accountsCommand
|
|
139
|
-
.command('transactions')
|
|
140
|
-
.description('Get account transactions')
|
|
141
|
-
.argument('<account-id>', 'Account UUID')
|
|
142
|
-
.option('--from <date>', 'Start date (YYYY-MM-DD)')
|
|
143
|
-
.option('--to <date>', 'End date (YYYY-MM-DD)')
|
|
144
|
-
.option('--premium', 'Use premium endpoint')
|
|
145
|
-
.option('--country <code>', 'Country code (required for premium)')
|
|
146
|
-
.option('-j, --json', 'Output as JSON')
|
|
147
|
-
.action(async (accountId, options) => {
|
|
148
|
-
const spinner = ora('Fetching transactions...').start();
|
|
149
|
-
|
|
150
|
-
try {
|
|
151
|
-
await ensureAuth();
|
|
152
|
-
const api = createClient();
|
|
153
|
-
|
|
154
|
-
const params = {};
|
|
155
|
-
if (options.from) params.date_from = options.from;
|
|
156
|
-
if (options.to) params.date_to = options.to;
|
|
157
|
-
|
|
158
|
-
let data;
|
|
159
|
-
if (options.premium) {
|
|
160
|
-
if (!options.country) {
|
|
161
|
-
spinner.fail('Country code required for premium transactions');
|
|
162
|
-
printError('Use --country <code> to specify country');
|
|
163
|
-
process.exit(1);
|
|
164
|
-
}
|
|
165
|
-
data = await api.getPremiumTransactions(accountId, options.country, params);
|
|
166
|
-
} else {
|
|
167
|
-
data = await api.getAccountTransactions(accountId, params);
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
spinner.succeed('Transactions retrieved');
|
|
171
|
-
|
|
172
|
-
if (options.json) {
|
|
173
|
-
printJSON(data);
|
|
174
|
-
} else {
|
|
175
|
-
printSection('Transactions');
|
|
176
|
-
|
|
177
|
-
const transactions = data.transactions?.booked || [];
|
|
178
|
-
const pending = data.transactions?.pending || [];
|
|
179
|
-
|
|
180
|
-
if (transactions.length > 0) {
|
|
181
|
-
console.log(chalk.bold('Booked Transactions:'));
|
|
182
|
-
console.log();
|
|
183
|
-
transactions.forEach((tx) => printTransaction(tx));
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
if (pending.length > 0) {
|
|
187
|
-
console.log();
|
|
188
|
-
console.log(chalk.bold('Pending Transactions:'));
|
|
189
|
-
console.log();
|
|
190
|
-
pending.forEach((tx) => printTransaction(tx));
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
if (transactions.length === 0 && pending.length === 0) {
|
|
194
|
-
console.log(chalk.yellow('No transactions found'));
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
console.log();
|
|
198
|
-
console.log(chalk.gray(`Total: ${transactions.length} booked, ${pending.length} pending`));
|
|
199
|
-
}
|
|
200
|
-
} catch (error) {
|
|
201
|
-
spinner.fail('Failed to fetch transactions');
|
|
202
|
-
printError(error.message, error);
|
|
203
|
-
process.exit(1);
|
|
204
|
-
}
|
|
205
|
-
});
|
|
@@ -1,241 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* End User Agreement Commands
|
|
3
|
-
*
|
|
4
|
-
* @fileoverview Commands for managing end user agreements (EUAs)
|
|
5
|
-
* @module commands/agreements
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { Command } from 'commander';
|
|
9
|
-
import chalk from 'chalk';
|
|
10
|
-
import ora from 'ora';
|
|
11
|
-
import { createClient } from '../lib/api.js';
|
|
12
|
-
import { ensureAuth } from '../lib/auth.js';
|
|
13
|
-
import {
|
|
14
|
-
printJSON,
|
|
15
|
-
printSuccess,
|
|
16
|
-
printError,
|
|
17
|
-
printSection,
|
|
18
|
-
printRow,
|
|
19
|
-
formatDateString,
|
|
20
|
-
formatStatus,
|
|
21
|
-
} from '../lib/output.js';
|
|
22
|
-
|
|
23
|
-
export const agreementsCommand = new Command('agreements')
|
|
24
|
-
.description('Manage end user agreements (EUAs)')
|
|
25
|
-
.alias('eua');
|
|
26
|
-
|
|
27
|
-
// List agreements
|
|
28
|
-
agreementsCommand
|
|
29
|
-
.command('list')
|
|
30
|
-
.description('List all end user agreements')
|
|
31
|
-
.option('--limit <number>', 'Results per page', '100')
|
|
32
|
-
.option('--offset <number>', 'Pagination offset', '0')
|
|
33
|
-
.option('-j, --json', 'Output as JSON')
|
|
34
|
-
.action(async (options) => {
|
|
35
|
-
const spinner = ora('Fetching agreements...').start();
|
|
36
|
-
|
|
37
|
-
try {
|
|
38
|
-
await ensureAuth();
|
|
39
|
-
const api = createClient();
|
|
40
|
-
|
|
41
|
-
const params = {
|
|
42
|
-
limit: parseInt(options.limit),
|
|
43
|
-
offset: parseInt(options.offset),
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
const data = await api.listAgreements(params);
|
|
47
|
-
|
|
48
|
-
spinner.succeed(`Found ${data.count || data.results?.length || 0} agreements`);
|
|
49
|
-
|
|
50
|
-
if (options.json) {
|
|
51
|
-
printJSON(data);
|
|
52
|
-
} else {
|
|
53
|
-
const agreements = data.results || [];
|
|
54
|
-
|
|
55
|
-
if (agreements.length === 0) {
|
|
56
|
-
console.log(chalk.yellow('No agreements found'));
|
|
57
|
-
return;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
printSection('End User Agreements');
|
|
61
|
-
|
|
62
|
-
agreements.forEach((agreement, index) => {
|
|
63
|
-
console.log(chalk.cyan(`${index + 1}.`), chalk.bold(agreement.id));
|
|
64
|
-
console.log(' Institution:', agreement.institution_id);
|
|
65
|
-
console.log(' Created:', formatDateString(agreement.created));
|
|
66
|
-
console.log(' Max Historical Days:', agreement.max_historical_days);
|
|
67
|
-
console.log(' Access Valid For:', agreement.access_valid_for_days, 'days');
|
|
68
|
-
console.log(' Status:', formatStatus(agreement.accepted ? 'ACCEPTED' : 'PENDING'));
|
|
69
|
-
|
|
70
|
-
if (agreement.access_scope && agreement.access_scope.length > 0) {
|
|
71
|
-
console.log(' Access Scope:', agreement.access_scope.join(', '));
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
console.log();
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
if (data.next) {
|
|
78
|
-
console.log(chalk.gray('More results available. Use --offset to paginate.'));
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
} catch (error) {
|
|
82
|
-
spinner.fail('Failed to fetch agreements');
|
|
83
|
-
printError(error.message, error);
|
|
84
|
-
process.exit(1);
|
|
85
|
-
}
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
// Create agreement
|
|
89
|
-
agreementsCommand
|
|
90
|
-
.command('create')
|
|
91
|
-
.description('Create a new end user agreement')
|
|
92
|
-
.requiredOption('-i, --institution-id <id>', 'Institution ID')
|
|
93
|
-
.option('--max-days <days>', 'Maximum historical days', '90')
|
|
94
|
-
.option('--valid-days <days>', 'Access valid for days', '90')
|
|
95
|
-
.option('--scope <scopes...>', 'Access scope (balances, details, transactions)')
|
|
96
|
-
.option('-j, --json', 'Output as JSON')
|
|
97
|
-
.action(async (options) => {
|
|
98
|
-
const spinner = ora('Creating agreement...').start();
|
|
99
|
-
|
|
100
|
-
try {
|
|
101
|
-
await ensureAuth();
|
|
102
|
-
const api = createClient();
|
|
103
|
-
|
|
104
|
-
const data = {
|
|
105
|
-
institution_id: options.institutionId,
|
|
106
|
-
max_historical_days: parseInt(options.maxDays),
|
|
107
|
-
access_valid_for_days: parseInt(options.validDays),
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
if (options.scope) {
|
|
111
|
-
data.access_scope = options.scope;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
const agreement = await api.createAgreement(data);
|
|
115
|
-
|
|
116
|
-
spinner.succeed('Agreement created');
|
|
117
|
-
|
|
118
|
-
if (options.json) {
|
|
119
|
-
printJSON(agreement);
|
|
120
|
-
} else {
|
|
121
|
-
printSection('Agreement Created');
|
|
122
|
-
printRow('Agreement ID', agreement.id);
|
|
123
|
-
printRow('Institution', agreement.institution_id);
|
|
124
|
-
printRow('Max Historical Days', agreement.max_historical_days);
|
|
125
|
-
printRow('Access Valid For', `${agreement.access_valid_for_days} days`);
|
|
126
|
-
|
|
127
|
-
if (agreement.access_scope) {
|
|
128
|
-
printRow('Access Scope', agreement.access_scope.join(', '));
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
printSuccess('Agreement created successfully');
|
|
132
|
-
}
|
|
133
|
-
} catch (error) {
|
|
134
|
-
spinner.fail('Failed to create agreement');
|
|
135
|
-
printError(error.message, error);
|
|
136
|
-
process.exit(1);
|
|
137
|
-
}
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
// Get agreement
|
|
141
|
-
agreementsCommand
|
|
142
|
-
.command('get')
|
|
143
|
-
.description('Get agreement details')
|
|
144
|
-
.argument('<agreement-id>', 'Agreement UUID')
|
|
145
|
-
.option('-j, --json', 'Output as JSON')
|
|
146
|
-
.action(async (agreementId, options) => {
|
|
147
|
-
const spinner = ora('Fetching agreement...').start();
|
|
148
|
-
|
|
149
|
-
try {
|
|
150
|
-
await ensureAuth();
|
|
151
|
-
const api = createClient();
|
|
152
|
-
const agreement = await api.getAgreement(agreementId);
|
|
153
|
-
|
|
154
|
-
spinner.succeed('Agreement retrieved');
|
|
155
|
-
|
|
156
|
-
if (options.json) {
|
|
157
|
-
printJSON(agreement);
|
|
158
|
-
} else {
|
|
159
|
-
printSection('Agreement Details');
|
|
160
|
-
printRow('Agreement ID', agreement.id);
|
|
161
|
-
printRow('Institution', agreement.institution_id);
|
|
162
|
-
printRow('Created', formatDateString(agreement.created));
|
|
163
|
-
printRow('Max Historical Days', agreement.max_historical_days);
|
|
164
|
-
printRow('Access Valid For', `${agreement.access_valid_for_days} days`);
|
|
165
|
-
printRow('Status', formatStatus(agreement.accepted ? 'ACCEPTED' : 'PENDING'));
|
|
166
|
-
|
|
167
|
-
if (agreement.access_scope) {
|
|
168
|
-
printRow('Access Scope', agreement.access_scope.join(', '));
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
} catch (error) {
|
|
172
|
-
spinner.fail('Failed to fetch agreement');
|
|
173
|
-
printError(error.message, error);
|
|
174
|
-
process.exit(1);
|
|
175
|
-
}
|
|
176
|
-
});
|
|
177
|
-
|
|
178
|
-
// Delete agreement
|
|
179
|
-
agreementsCommand
|
|
180
|
-
.command('delete')
|
|
181
|
-
.description('Delete an end user agreement')
|
|
182
|
-
.argument('<agreement-id>', 'Agreement UUID')
|
|
183
|
-
.option('-y, --yes', 'Skip confirmation')
|
|
184
|
-
.action(async (agreementId, options) => {
|
|
185
|
-
if (!options.yes) {
|
|
186
|
-
console.log(chalk.yellow('Warning: This will permanently delete the agreement'));
|
|
187
|
-
console.log('Use --yes to confirm deletion');
|
|
188
|
-
process.exit(0);
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
const spinner = ora('Deleting agreement...').start();
|
|
192
|
-
|
|
193
|
-
try {
|
|
194
|
-
await ensureAuth();
|
|
195
|
-
const api = createClient();
|
|
196
|
-
await api.deleteAgreement(agreementId);
|
|
197
|
-
|
|
198
|
-
spinner.succeed('Agreement deleted');
|
|
199
|
-
printSuccess('Agreement deleted successfully');
|
|
200
|
-
} catch (error) {
|
|
201
|
-
spinner.fail('Failed to delete agreement');
|
|
202
|
-
printError(error.message, error);
|
|
203
|
-
process.exit(1);
|
|
204
|
-
}
|
|
205
|
-
});
|
|
206
|
-
|
|
207
|
-
// Accept agreement
|
|
208
|
-
agreementsCommand
|
|
209
|
-
.command('accept')
|
|
210
|
-
.description('Accept an end user agreement')
|
|
211
|
-
.argument('<agreement-id>', 'Agreement UUID')
|
|
212
|
-
.requiredOption('--user-agent <ua>', 'User agent string')
|
|
213
|
-
.requiredOption('--ip <address>', 'User IP address')
|
|
214
|
-
.option('-j, --json', 'Output as JSON')
|
|
215
|
-
.action(async (agreementId, options) => {
|
|
216
|
-
const spinner = ora('Accepting agreement...').start();
|
|
217
|
-
|
|
218
|
-
try {
|
|
219
|
-
await ensureAuth();
|
|
220
|
-
const api = createClient();
|
|
221
|
-
|
|
222
|
-
const data = {
|
|
223
|
-
user_agent: options.userAgent,
|
|
224
|
-
ip_address: options.ip,
|
|
225
|
-
};
|
|
226
|
-
|
|
227
|
-
const agreement = await api.acceptAgreement(agreementId, data);
|
|
228
|
-
|
|
229
|
-
spinner.succeed('Agreement accepted');
|
|
230
|
-
|
|
231
|
-
if (options.json) {
|
|
232
|
-
printJSON(agreement);
|
|
233
|
-
} else {
|
|
234
|
-
printSuccess('Agreement accepted successfully');
|
|
235
|
-
}
|
|
236
|
-
} catch (error) {
|
|
237
|
-
spinner.fail('Failed to accept agreement');
|
|
238
|
-
printError(error.message, error);
|
|
239
|
-
process.exit(1);
|
|
240
|
-
}
|
|
241
|
-
});
|
package/src/commands/auth.js
DELETED
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Authentication Commands
|
|
3
|
-
*
|
|
4
|
-
* @fileoverview Commands for authentication and token management
|
|
5
|
-
* @module commands/auth
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { Command } from 'commander';
|
|
9
|
-
import chalk from 'chalk';
|
|
10
|
-
import ora from 'ora';
|
|
11
|
-
import { login, logout, getAuthStatus } from '../lib/auth.js';
|
|
12
|
-
import { printSuccess, printError, printSection, printRow, formatDuration } from '../lib/output.js';
|
|
13
|
-
|
|
14
|
-
export const authCommand = new Command('auth')
|
|
15
|
-
.description('Authentication and token management');
|
|
16
|
-
|
|
17
|
-
// Login command
|
|
18
|
-
authCommand
|
|
19
|
-
.command('login')
|
|
20
|
-
.description('Authenticate with Nordigen API')
|
|
21
|
-
.requiredOption('--secret-id <id>', 'Secret ID from Nordigen dashboard')
|
|
22
|
-
.requiredOption('--secret-key <key>', 'Secret Key from Nordigen dashboard')
|
|
23
|
-
.action(async (options) => {
|
|
24
|
-
const spinner = ora('Authenticating...').start();
|
|
25
|
-
|
|
26
|
-
try {
|
|
27
|
-
const result = await login(options.secretId, options.secretKey);
|
|
28
|
-
spinner.succeed('Authentication successful');
|
|
29
|
-
|
|
30
|
-
printSection('Token Information');
|
|
31
|
-
printRow('Access Token Expires In', formatDuration(result.access_expires));
|
|
32
|
-
printRow('Refresh Token Expires In', formatDuration(result.refresh_expires));
|
|
33
|
-
|
|
34
|
-
printSuccess('Credentials saved securely');
|
|
35
|
-
} catch (error) {
|
|
36
|
-
spinner.fail('Authentication failed');
|
|
37
|
-
printError(error.message, error);
|
|
38
|
-
process.exit(1);
|
|
39
|
-
}
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
// Logout command
|
|
43
|
-
authCommand
|
|
44
|
-
.command('logout')
|
|
45
|
-
.description('Clear stored credentials')
|
|
46
|
-
.action(() => {
|
|
47
|
-
try {
|
|
48
|
-
logout();
|
|
49
|
-
printSuccess('Logged out successfully');
|
|
50
|
-
} catch (error) {
|
|
51
|
-
printError('Logout failed', error);
|
|
52
|
-
process.exit(1);
|
|
53
|
-
}
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
// Status command
|
|
57
|
-
authCommand
|
|
58
|
-
.command('status')
|
|
59
|
-
.description('Show authentication status')
|
|
60
|
-
.action(() => {
|
|
61
|
-
try {
|
|
62
|
-
const status = getAuthStatus();
|
|
63
|
-
|
|
64
|
-
printSection('Authentication Status');
|
|
65
|
-
|
|
66
|
-
if (status.authenticated) {
|
|
67
|
-
printRow('Status', chalk.green('Authenticated'));
|
|
68
|
-
printRow('Access Token', status.accessTokenValid ? chalk.green('Valid') : chalk.yellow('Expired'));
|
|
69
|
-
printRow('Refresh Token', status.refreshTokenValid ? chalk.green('Valid') : chalk.yellow('Expired'));
|
|
70
|
-
|
|
71
|
-
if (status.accessTokenValid) {
|
|
72
|
-
printRow('Access Expires In', formatDuration(status.accessExpiresIn));
|
|
73
|
-
}
|
|
74
|
-
if (status.refreshTokenValid) {
|
|
75
|
-
printRow('Refresh Expires In', formatDuration(status.refreshExpiresIn));
|
|
76
|
-
}
|
|
77
|
-
} else {
|
|
78
|
-
printRow('Status', chalk.red('Not Authenticated'));
|
|
79
|
-
console.log();
|
|
80
|
-
console.log('Login with:', chalk.cyan('nordigen auth login --secret-id <id> --secret-key <key>'));
|
|
81
|
-
}
|
|
82
|
-
} catch (error) {
|
|
83
|
-
printError('Failed to get auth status', error);
|
|
84
|
-
process.exit(1);
|
|
85
|
-
}
|
|
86
|
-
});
|