@aderis-erp/cli 1.0.14 → 1.0.17
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/README.md +30 -8
- package/dist/commands/access-groups.d.ts +0 -1
- package/dist/commands/access-groups.js +22 -78
- package/dist/commands/account-transaction-allocations.d.ts +0 -1
- package/dist/commands/account-transaction-allocations.js +22 -78
- package/dist/commands/account-transactions.d.ts +0 -1
- package/dist/commands/account-transactions.js +28 -82
- package/dist/commands/accounts.d.ts +0 -1
- package/dist/commands/accounts.js +24 -80
- package/dist/commands/agent-platform.d.ts +0 -1
- package/dist/commands/agent-platform.js +24 -79
- package/dist/commands/analytics.d.ts +39 -0
- package/dist/commands/analytics.js +1113 -0
- package/dist/commands/{documents.d.ts → api-keys.d.ts} +1 -2
- package/dist/commands/api-keys.js +1117 -0
- package/dist/commands/audit-log.d.ts +0 -1
- package/dist/commands/audit-log.js +22 -78
- package/dist/commands/auth/login.d.ts +9 -0
- package/dist/commands/auth/login.js +83 -21
- package/dist/commands/auth/logout.d.ts +6 -0
- package/dist/commands/auth/logout.js +23 -6
- package/dist/commands/auth/status.js +46 -23
- package/dist/commands/auth/tenant.js +15 -9
- package/dist/commands/auth.d.ts +0 -1
- package/dist/commands/auth.js +37 -51
- package/dist/commands/bank-accounts.d.ts +0 -1
- package/dist/commands/bank-accounts.js +22 -78
- package/dist/commands/bank-integrations.d.ts +0 -1
- package/dist/commands/bank-integrations.js +22 -78
- package/dist/commands/business-partners.d.ts +1 -1
- package/dist/commands/business-partners.js +38 -84
- package/dist/commands/chat.d.ts +0 -1
- package/dist/commands/chat.js +22 -78
- package/dist/commands/config/add.d.ts +12 -0
- package/dist/commands/config/add.js +97 -17
- package/dist/commands/config/current.js +12 -4
- package/dist/commands/config/list.js +12 -4
- package/dist/commands/config/set-api-key.d.ts +10 -0
- package/dist/commands/config/set-api-key.js +49 -0
- package/dist/commands/config/use.js +3 -4
- package/dist/commands/credit-card-accounts.d.ts +0 -1
- package/dist/commands/credit-card-accounts.js +22 -78
- package/dist/commands/delivery-notes.d.ts +0 -1
- package/dist/commands/delivery-notes.js +29 -84
- package/dist/commands/dunning-configs.d.ts +0 -1
- package/dist/commands/dunning-configs.js +22 -78
- package/dist/commands/dunning-reminders.d.ts +0 -1
- package/dist/commands/dunning-reminders.js +22 -78
- package/dist/commands/dunning-runs.d.ts +0 -1
- package/dist/commands/dunning-runs.js +22 -78
- package/dist/commands/email-transactions.d.ts +0 -1
- package/dist/commands/email-transactions.js +22 -78
- package/dist/commands/employees.d.ts +0 -1
- package/dist/commands/employees.js +24 -80
- package/dist/commands/entity-configurations.d.ts +0 -1
- package/dist/commands/entity-configurations.js +22 -78
- package/dist/commands/event-processor-mappings.d.ts +0 -1
- package/dist/commands/event-processor-mappings.js +22 -78
- package/dist/commands/{files-internal.d.ts → files.d.ts} +1 -2
- package/dist/commands/{files-internal.js → files.js} +40 -90
- package/dist/commands/health.d.ts +0 -1
- package/dist/commands/health.js +22 -78
- package/dist/commands/inbox.d.ts +0 -1
- package/dist/commands/inbox.js +22 -78
- package/dist/commands/integrations.d.ts +0 -1
- package/dist/commands/integrations.js +22 -78
- package/dist/commands/item-categories.d.ts +0 -1
- package/dist/commands/item-categories.js +22 -78
- package/dist/commands/items.d.ts +0 -1
- package/dist/commands/items.js +24 -80
- package/dist/commands/journal-lines.d.ts +0 -1
- package/dist/commands/journal-lines.js +22 -78
- package/dist/commands/journals.d.ts +1 -1
- package/dist/commands/journals.js +29 -81
- package/dist/commands/ledgers.d.ts +0 -1
- package/dist/commands/ledgers.js +26 -79
- package/dist/commands/nango-integrations.d.ts +39 -0
- package/dist/commands/nango-integrations.js +1115 -0
- package/dist/commands/office-locations.d.ts +0 -1
- package/dist/commands/office-locations.js +22 -78
- package/dist/commands/payment-methods.d.ts +0 -1
- package/dist/commands/payment-methods.js +22 -78
- package/dist/commands/payment-runs.d.ts +0 -1
- package/dist/commands/payment-runs.js +24 -79
- package/dist/commands/payment-terms.d.ts +0 -1
- package/dist/commands/payment-terms.js +22 -78
- package/dist/commands/payments.d.ts +0 -1
- package/dist/commands/payments.js +22 -78
- package/dist/commands/price-lists.d.ts +0 -1
- package/dist/commands/price-lists.js +22 -78
- package/dist/commands/processor-mappings.d.ts +0 -1
- package/dist/commands/processor-mappings.js +22 -78
- package/dist/commands/processors.d.ts +0 -1
- package/dist/commands/processors.js +22 -78
- package/dist/commands/purchase-order-types.d.ts +0 -1
- package/dist/commands/purchase-order-types.js +22 -78
- package/dist/commands/purchase-orders.d.ts +1 -1
- package/dist/commands/purchase-orders.js +35 -84
- package/dist/commands/reports.d.ts +0 -1
- package/dist/commands/reports.js +23 -79
- package/dist/commands/salary-types.d.ts +0 -1
- package/dist/commands/salary-types.js +22 -78
- package/dist/commands/sales-invoices.d.ts +0 -1
- package/dist/commands/sales-invoices.js +38 -89
- package/dist/commands/sales-orders.d.ts +0 -1
- package/dist/commands/sales-orders.js +26 -82
- package/dist/commands/saved-views.d.ts +0 -1
- package/dist/commands/saved-views.js +22 -78
- package/dist/commands/scheduled-processor-mappings.d.ts +0 -1
- package/dist/commands/scheduled-processor-mappings.js +22 -78
- package/dist/commands/schedules.d.ts +0 -1
- package/dist/commands/schedules.js +22 -78
- package/dist/commands/switch.js +14 -7
- package/dist/commands/tag-configurations.d.ts +39 -0
- package/dist/commands/{documents.js → tag-configurations.js} +40 -96
- package/dist/commands/tags.d.ts +0 -1
- package/dist/commands/tags.js +22 -78
- package/dist/commands/tax-codes.d.ts +0 -1
- package/dist/commands/tax-codes.js +22 -78
- package/dist/commands/tax-matrix.d.ts +0 -1
- package/dist/commands/tax-matrix.js +22 -78
- package/dist/commands/tenants.d.ts +0 -1
- package/dist/commands/tenants.js +24 -79
- package/dist/commands/text-templates.d.ts +0 -1
- package/dist/commands/text-templates.js +22 -78
- package/dist/commands/tools.d.ts +0 -1
- package/dist/commands/tools.js +22 -78
- package/dist/commands/vat-declarations.d.ts +1 -1
- package/dist/commands/vat-declarations.js +28 -79
- package/dist/commands/vendor-invoices.d.ts +0 -1
- package/dist/commands/vendor-invoices.js +31 -86
- package/dist/commands/webhooks.d.ts +0 -1
- package/dist/commands/webhooks.js +22 -78
- package/dist/commands/workflows.d.ts +0 -1
- package/dist/commands/workflows.js +22 -78
- package/dist/lib/api-client.js +8 -6
- package/dist/lib/auth/constants.d.ts +11 -0
- package/dist/lib/auth/constants.js +11 -0
- package/dist/lib/auth/errors.d.ts +17 -0
- package/dist/lib/auth/errors.js +22 -0
- package/dist/lib/auth/flow.d.ts +27 -0
- package/dist/lib/auth/flow.js +163 -0
- package/dist/lib/auth/guards.d.ts +5 -0
- package/dist/lib/auth/guards.js +14 -0
- package/dist/lib/auth/http.d.ts +16 -0
- package/dist/lib/auth/http.js +49 -0
- package/dist/lib/auth/index.d.ts +49 -0
- package/dist/lib/auth/index.js +217 -0
- package/dist/lib/auth/keycloak-provider.d.ts +75 -0
- package/dist/lib/auth/keycloak-provider.js +215 -0
- package/dist/lib/auth/pages.d.ts +25 -0
- package/dist/lib/auth/pages.js +123 -0
- package/dist/lib/auth/pkce.d.ts +11 -0
- package/dist/lib/auth/pkce.js +17 -0
- package/dist/lib/auth/tokens.d.ts +54 -0
- package/dist/lib/auth/tokens.js +104 -0
- package/dist/lib/auth/types.d.ts +57 -0
- package/dist/lib/auth/types.js +1 -0
- package/dist/lib/auth/validated-url.d.ts +6 -0
- package/dist/lib/auth/validated-url.js +53 -0
- package/dist/lib/base-api-command.js +6 -4
- package/dist/lib/config.d.ts +44 -4
- package/dist/lib/config.js +55 -19
- package/oclif.manifest.json +1181 -330
- package/package.json +3 -2
- package/dist/lib/auth.d.ts +0 -35
- package/dist/lib/auth.js +0 -566
package/dist/commands/auth.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Args, Command, Flags } from '@oclif/core';
|
|
2
2
|
import { ApiError, apiRequest } from '../lib/api-client.js';
|
|
3
|
-
import { getContext, getCurrentContext } from '../lib/config.js';
|
|
3
|
+
import { getContext, getCurrentContext, hasCredentials, missingCredentialsMessage } from '../lib/config.js';
|
|
4
4
|
// Add 'import' action if both create and update exist
|
|
5
5
|
const HAS_IMPORT = false;
|
|
6
6
|
const HAS_EXPORT = false;
|
|
@@ -40,10 +40,15 @@ export default class Auth extends Command {
|
|
|
40
40
|
static description = 'Manage auth';
|
|
41
41
|
static examples = [];
|
|
42
42
|
static flags = {
|
|
43
|
-
context: Flags.string({
|
|
43
|
+
context: Flags.string({
|
|
44
|
+
aliases: ['config'],
|
|
45
|
+
char: 'c',
|
|
46
|
+
description: 'Context to use for this command, overriding the current context (alias: --config)',
|
|
47
|
+
env: 'ADERIS_CONTEXT',
|
|
48
|
+
}),
|
|
44
49
|
csv: Flags.boolean({ description: 'Output as CSV (shortcut for --output csv)' }),
|
|
45
50
|
data: Flags.string({ char: 'd', description: 'JSON data for request body' }),
|
|
46
|
-
fields: Flags.string({ description: 'Comma-separated list of fields to
|
|
51
|
+
fields: Flags.string({ description: 'Comma-separated list of fields to return, applied by the API (e.g. --fields=id,name,status)' }),
|
|
47
52
|
file: Flags.string({ char: 'f', description: 'Read request body from file' }),
|
|
48
53
|
include: Flags.string({ description: 'Relations to include' }),
|
|
49
54
|
limit: Flags.string({ description: 'Items per page' }),
|
|
@@ -96,9 +101,11 @@ export default class Auth extends Command {
|
|
|
96
101
|
this.error(`Unknown action: ${args.action}. Available: ${SUBCOMMANDS.join(', ')}`);
|
|
97
102
|
const context = flags.context ? getContext(flags.context) : getCurrentContext();
|
|
98
103
|
if (!context)
|
|
99
|
-
this.error(
|
|
100
|
-
|
|
101
|
-
|
|
104
|
+
this.error(flags.context
|
|
105
|
+
? `Context "${flags.context}" not found. List contexts with: aderis config list`
|
|
106
|
+
: 'No context configured. Run: aderis auth login --new');
|
|
107
|
+
if (!hasCredentials(context))
|
|
108
|
+
this.error(missingCredentialsMessage(context));
|
|
102
109
|
let apiPath = endpoint.path;
|
|
103
110
|
for (const param of endpoint.pathParams) {
|
|
104
111
|
let value;
|
|
@@ -131,6 +138,8 @@ export default class Auth extends Command {
|
|
|
131
138
|
queryParams.search = flags.search;
|
|
132
139
|
if (flags['sort-by'])
|
|
133
140
|
queryParams.sortBy = flags['sort-by'];
|
|
141
|
+
if (flags.fields)
|
|
142
|
+
queryParams.fields = flags.fields;
|
|
134
143
|
if (flags.query) {
|
|
135
144
|
try {
|
|
136
145
|
Object.assign(queryParams, JSON.parse(flags.query));
|
|
@@ -215,11 +224,6 @@ export default class Auth extends Command {
|
|
|
215
224
|
if (args.action === 'list' && output && typeof output === 'object' && 'data' in output) {
|
|
216
225
|
output = output.data;
|
|
217
226
|
}
|
|
218
|
-
// Filter fields if --fields flag is provided
|
|
219
|
-
if (flags.fields) {
|
|
220
|
-
const fieldList = flags.fields.split(',').map((f) => f.trim());
|
|
221
|
-
output = this.filterFields(output, fieldList);
|
|
222
|
-
}
|
|
223
227
|
// Sanitize output if requested
|
|
224
228
|
if (flags.sanitize) {
|
|
225
229
|
output = this.sanitizeOutput(output);
|
|
@@ -241,29 +245,6 @@ export default class Auth extends Command {
|
|
|
241
245
|
throw error;
|
|
242
246
|
}
|
|
243
247
|
}
|
|
244
|
-
filterFields(data, fields) {
|
|
245
|
-
const pick = (obj, keys) => {
|
|
246
|
-
const result = {};
|
|
247
|
-
for (const key of keys) {
|
|
248
|
-
if (key.includes('.')) {
|
|
249
|
-
// Handle nested fields like 'customer.name'
|
|
250
|
-
const [first, ...rest] = key.split('.');
|
|
251
|
-
if (obj[first] && typeof obj[first] === 'object') {
|
|
252
|
-
const nested = pick(obj[first], [rest.join('.')]);
|
|
253
|
-
result[first] = { ...result[first], ...nested };
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
else if (key in obj) {
|
|
257
|
-
result[key] = obj[key];
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
return result;
|
|
261
|
-
};
|
|
262
|
-
if (Array.isArray(data)) {
|
|
263
|
-
return data.map((item) => pick(item, fields));
|
|
264
|
-
}
|
|
265
|
-
return pick(data, fields);
|
|
266
|
-
}
|
|
267
248
|
getColumns(data, fields, flatten = false) {
|
|
268
249
|
const items = Array.isArray(data) ? data : [data];
|
|
269
250
|
if (items.length === 0)
|
|
@@ -359,9 +340,11 @@ export default class Auth extends Command {
|
|
|
359
340
|
async runCamt053Import(flags) {
|
|
360
341
|
const context = flags.context ? getContext(flags.context) : getCurrentContext();
|
|
361
342
|
if (!context)
|
|
362
|
-
this.error(
|
|
363
|
-
|
|
364
|
-
|
|
343
|
+
this.error(flags.context
|
|
344
|
+
? `Context "${flags.context}" not found. List contexts with: aderis config list`
|
|
345
|
+
: 'No context configured. Run: aderis auth login --new');
|
|
346
|
+
if (!hasCredentials(context))
|
|
347
|
+
this.error(missingCredentialsMessage(context));
|
|
365
348
|
if (!flags.file) {
|
|
366
349
|
this.error('CAMT.053 import requires --file (-f) flag with path to XML file');
|
|
367
350
|
}
|
|
@@ -446,9 +429,11 @@ export default class Auth extends Command {
|
|
|
446
429
|
async runExport(flags) {
|
|
447
430
|
const context = flags.context ? getContext(flags.context) : getCurrentContext();
|
|
448
431
|
if (!context)
|
|
449
|
-
this.error(
|
|
450
|
-
|
|
451
|
-
|
|
432
|
+
this.error(flags.context
|
|
433
|
+
? `Context "${flags.context}" not found. List contexts with: aderis config list`
|
|
434
|
+
: 'No context configured. Run: aderis auth login --new');
|
|
435
|
+
if (!hasCredentials(context))
|
|
436
|
+
this.error(missingCredentialsMessage(context));
|
|
452
437
|
const listEndpoint = ENDPOINTS.list;
|
|
453
438
|
if (!listEndpoint)
|
|
454
439
|
this.error('Export requires a list endpoint');
|
|
@@ -464,6 +449,8 @@ export default class Auth extends Command {
|
|
|
464
449
|
baseParams.sortBy = flags['sort-by'];
|
|
465
450
|
if (flags.include)
|
|
466
451
|
baseParams.include = flags.include;
|
|
452
|
+
if (flags.fields)
|
|
453
|
+
baseParams.fields = flags.fields;
|
|
467
454
|
if (flags.query) {
|
|
468
455
|
try {
|
|
469
456
|
Object.assign(baseParams, JSON.parse(flags.query));
|
|
@@ -500,12 +487,7 @@ export default class Auth extends Command {
|
|
|
500
487
|
}
|
|
501
488
|
}
|
|
502
489
|
process.stderr.write(' done\n');
|
|
503
|
-
// Filter fields if specified
|
|
504
490
|
let output = allItems;
|
|
505
|
-
if (flags.fields) {
|
|
506
|
-
const fieldList = flags.fields.split(',').map((f) => f.trim());
|
|
507
|
-
output = this.filterFields(allItems, fieldList);
|
|
508
|
-
}
|
|
509
491
|
// Sanitize output if requested
|
|
510
492
|
if (flags.sanitize) {
|
|
511
493
|
output = this.sanitizeOutput(output);
|
|
@@ -522,9 +504,11 @@ export default class Auth extends Command {
|
|
|
522
504
|
async runImport(flags) {
|
|
523
505
|
const context = flags.context ? getContext(flags.context) : getCurrentContext();
|
|
524
506
|
if (!context)
|
|
525
|
-
this.error(
|
|
526
|
-
|
|
527
|
-
|
|
507
|
+
this.error(flags.context
|
|
508
|
+
? `Context "${flags.context}" not found. List contexts with: aderis config list`
|
|
509
|
+
: 'No context configured. Run: aderis auth login --new');
|
|
510
|
+
if (!hasCredentials(context))
|
|
511
|
+
this.error(missingCredentialsMessage(context));
|
|
528
512
|
// Get data from file, --data, or --set flags
|
|
529
513
|
let items = [];
|
|
530
514
|
if (flags.file) {
|
|
@@ -676,9 +660,11 @@ export default class Auth extends Command {
|
|
|
676
660
|
}
|
|
677
661
|
const context = flags.context ? getContext(flags.context) : getCurrentContext();
|
|
678
662
|
if (!context)
|
|
679
|
-
this.error(
|
|
680
|
-
|
|
681
|
-
|
|
663
|
+
this.error(flags.context
|
|
664
|
+
? `Context "${flags.context}" not found. List contexts with: aderis config list`
|
|
665
|
+
: 'No context configured. Run: aderis auth login --new');
|
|
666
|
+
if (!hasCredentials(context))
|
|
667
|
+
this.error(missingCredentialsMessage(context));
|
|
682
668
|
// Get data from file, --data, or --set flags
|
|
683
669
|
let items = [];
|
|
684
670
|
if (flags.file) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Command, Args, Flags } from '@oclif/core';
|
|
2
2
|
import { apiRequest, ApiError, normalizeSortBy } from '../lib/api-client.js';
|
|
3
|
-
import { getCurrentContext, getContext, getBaseUrls } from '../lib/config.js';
|
|
3
|
+
import { getCurrentContext, getContext, getBaseUrls, hasCredentials, missingCredentialsMessage } from '../lib/config.js';
|
|
4
4
|
// Add 'import' action if both create and update exist
|
|
5
5
|
const HAS_IMPORT = true;
|
|
6
6
|
const HAS_EXPORT = true;
|
|
@@ -41,7 +41,7 @@ export default class BankAccounts extends Command {
|
|
|
41
41
|
id: Args.string({ description: 'Resource ID (for get, update, delete operations)', required: false }),
|
|
42
42
|
};
|
|
43
43
|
static flags = {
|
|
44
|
-
context: Flags.string({ char: 'c', description: 'Context to use' }),
|
|
44
|
+
context: Flags.string({ char: 'c', aliases: ['config'], env: 'ADERIS_CONTEXT', description: 'Context to use for this command, overriding the current context (alias: --config)' }),
|
|
45
45
|
output: Flags.string({ char: 'o', description: 'Output format (default: table for import, json for other commands)', options: ['json', 'table', 'csv'] }),
|
|
46
46
|
table: Flags.boolean({ char: 't', description: 'Output as table (shortcut for --output table)' }),
|
|
47
47
|
csv: Flags.boolean({ description: 'Output as CSV (shortcut for --output csv)' }),
|
|
@@ -57,7 +57,7 @@ export default class BankAccounts extends Command {
|
|
|
57
57
|
'sort-by': Flags.string({ description: 'Sort field(s), comma-separated. Direction (:ASC/:DESC) is optional; date-like fields default to DESC, others to ASC.' }),
|
|
58
58
|
filter: Flags.string({ description: 'Filter (e.g. --filter status=ACTIVE). Operators: in:A,B, like:%, gt:, lt:, null:', multiple: true }),
|
|
59
59
|
query: Flags.string({ description: 'Additional query params as JSON' }),
|
|
60
|
-
fields: Flags.string({ description: 'Comma-separated list of fields to
|
|
60
|
+
fields: Flags.string({ description: 'Comma-separated list of fields to return, applied by the API (e.g. --fields=id,name,status)' }),
|
|
61
61
|
sanitize: Flags.boolean({ description: 'Remove null values, audit fields, and duplicate UUIDs from output' }),
|
|
62
62
|
'show-http-request': Flags.boolean({ description: 'Show HTTP request details (method, URL, body)' }),
|
|
63
63
|
};
|
|
@@ -115,9 +115,9 @@ export default class BankAccounts extends Command {
|
|
|
115
115
|
}
|
|
116
116
|
const context = flags.context ? getContext(flags.context) : getCurrentContext();
|
|
117
117
|
if (!context)
|
|
118
|
-
this.error('No context configured. Run: aderis auth login --new');
|
|
119
|
-
if (!context
|
|
120
|
-
this.error(
|
|
118
|
+
this.error(flags.context ? `Context "${flags.context}" not found. List contexts with: aderis config list` : 'No context configured. Run: aderis auth login --new');
|
|
119
|
+
if (!hasCredentials(context))
|
|
120
|
+
this.error(missingCredentialsMessage(context));
|
|
121
121
|
const queryParams = {};
|
|
122
122
|
if (flags.page)
|
|
123
123
|
queryParams.page = flags.page;
|
|
@@ -129,6 +129,8 @@ export default class BankAccounts extends Command {
|
|
|
129
129
|
queryParams.search = flags.search;
|
|
130
130
|
if (flags['sort-by'])
|
|
131
131
|
queryParams.sortBy = normalizeSortBy(flags['sort-by']);
|
|
132
|
+
if (flags.fields)
|
|
133
|
+
queryParams.fields = flags.fields;
|
|
132
134
|
if (flags.query) {
|
|
133
135
|
try {
|
|
134
136
|
Object.assign(queryParams, JSON.parse(flags.query));
|
|
@@ -331,11 +333,6 @@ export default class BankAccounts extends Command {
|
|
|
331
333
|
output = obj[arrayKeys[0]];
|
|
332
334
|
}
|
|
333
335
|
}
|
|
334
|
-
// Filter fields if --fields flag is provided
|
|
335
|
-
if (flags.fields) {
|
|
336
|
-
const fieldList = flags.fields.split(',').map(f => f.trim());
|
|
337
|
-
output = this.filterFields(output, fieldList);
|
|
338
|
-
}
|
|
339
336
|
// Sanitize output if requested
|
|
340
337
|
if (flags.sanitize) {
|
|
341
338
|
output = this.sanitizeOutput(output);
|
|
@@ -360,9 +357,9 @@ export default class BankAccounts extends Command {
|
|
|
360
357
|
async runImport(flags) {
|
|
361
358
|
const context = flags.context ? getContext(flags.context) : getCurrentContext();
|
|
362
359
|
if (!context)
|
|
363
|
-
this.error('No context configured. Run: aderis auth login --new');
|
|
364
|
-
if (!context
|
|
365
|
-
this.error(
|
|
360
|
+
this.error(flags.context ? `Context "${flags.context}" not found. List contexts with: aderis config list` : 'No context configured. Run: aderis auth login --new');
|
|
361
|
+
if (!hasCredentials(context))
|
|
362
|
+
this.error(missingCredentialsMessage(context));
|
|
366
363
|
// Get data from file, --data, or --set flags
|
|
367
364
|
let items = [];
|
|
368
365
|
if (flags.file) {
|
|
@@ -572,9 +569,9 @@ export default class BankAccounts extends Command {
|
|
|
572
569
|
async runExport(flags) {
|
|
573
570
|
const context = flags.context ? getContext(flags.context) : getCurrentContext();
|
|
574
571
|
if (!context)
|
|
575
|
-
this.error('No context configured. Run: aderis auth login --new');
|
|
576
|
-
if (!context
|
|
577
|
-
this.error(
|
|
572
|
+
this.error(flags.context ? `Context "${flags.context}" not found. List contexts with: aderis config list` : 'No context configured. Run: aderis auth login --new');
|
|
573
|
+
if (!hasCredentials(context))
|
|
574
|
+
this.error(missingCredentialsMessage(context));
|
|
578
575
|
const listEndpoint = ENDPOINTS['list'];
|
|
579
576
|
if (!listEndpoint)
|
|
580
577
|
this.error('Export requires a list endpoint');
|
|
@@ -590,6 +587,8 @@ export default class BankAccounts extends Command {
|
|
|
590
587
|
baseParams.sortBy = normalizeSortBy(flags['sort-by']);
|
|
591
588
|
if (flags.include)
|
|
592
589
|
baseParams.include = flags.include;
|
|
590
|
+
if (flags.fields)
|
|
591
|
+
baseParams.fields = flags.fields;
|
|
593
592
|
if (flags.query) {
|
|
594
593
|
try {
|
|
595
594
|
Object.assign(baseParams, JSON.parse(flags.query));
|
|
@@ -644,12 +643,7 @@ export default class BankAccounts extends Command {
|
|
|
644
643
|
}
|
|
645
644
|
}
|
|
646
645
|
process.stderr.write(' done\n');
|
|
647
|
-
// Filter fields if specified
|
|
648
646
|
let output = allItems;
|
|
649
|
-
if (flags.fields) {
|
|
650
|
-
const fieldList = flags.fields.split(',').map(f => f.trim());
|
|
651
|
-
output = this.filterFields(allItems, fieldList);
|
|
652
|
-
}
|
|
653
647
|
// Sanitize output if requested
|
|
654
648
|
if (flags.sanitize) {
|
|
655
649
|
output = this.sanitizeOutput(output);
|
|
@@ -666,9 +660,9 @@ export default class BankAccounts extends Command {
|
|
|
666
660
|
async runCamt053Import(flags) {
|
|
667
661
|
const context = flags.context ? getContext(flags.context) : getCurrentContext();
|
|
668
662
|
if (!context)
|
|
669
|
-
this.error('No context configured. Run: aderis auth login --new');
|
|
670
|
-
if (!context
|
|
671
|
-
this.error(
|
|
663
|
+
this.error(flags.context ? `Context "${flags.context}" not found. List contexts with: aderis config list` : 'No context configured. Run: aderis auth login --new');
|
|
664
|
+
if (!hasCredentials(context))
|
|
665
|
+
this.error(missingCredentialsMessage(context));
|
|
672
666
|
if (!flags.file) {
|
|
673
667
|
this.error('CAMT.053 import requires --file (-f) flag with path to XML file');
|
|
674
668
|
}
|
|
@@ -756,9 +750,9 @@ export default class BankAccounts extends Command {
|
|
|
756
750
|
}
|
|
757
751
|
const context = flags.context ? getContext(flags.context) : getCurrentContext();
|
|
758
752
|
if (!context)
|
|
759
|
-
this.error('No context configured. Run: aderis auth login --new');
|
|
760
|
-
if (!context
|
|
761
|
-
this.error(
|
|
753
|
+
this.error(flags.context ? `Context "${flags.context}" not found. List contexts with: aderis config list` : 'No context configured. Run: aderis auth login --new');
|
|
754
|
+
if (!hasCredentials(context))
|
|
755
|
+
this.error(missingCredentialsMessage(context));
|
|
762
756
|
// Get data from file, --data, or --set flags
|
|
763
757
|
let items = [];
|
|
764
758
|
if (flags.file) {
|
|
@@ -978,56 +972,6 @@ export default class BankAccounts extends Command {
|
|
|
978
972
|
return `\$${op}`;
|
|
979
973
|
return opRe.test(rest) ? `\$${op}:${this.parseFilterValue(rest)}` : `\$${op}:${rest}`;
|
|
980
974
|
}
|
|
981
|
-
filterFields(data, fields) {
|
|
982
|
-
const isUnsafeKey = (k) => k === '__proto__' || k === 'constructor' || k === 'prototype';
|
|
983
|
-
const pick = (obj, keys) => {
|
|
984
|
-
// Group keys by their first segment so sibling sub-paths
|
|
985
|
-
// (e.g. 'items.amount' + 'items._type') resolve in one recursive pass
|
|
986
|
-
// and don't clobber each other on merge.
|
|
987
|
-
const directKeys = new Set();
|
|
988
|
-
const nestedKeys = new Map();
|
|
989
|
-
for (const key of keys) {
|
|
990
|
-
if (key.split('.').some(isUnsafeKey))
|
|
991
|
-
continue;
|
|
992
|
-
if (key.includes('.')) {
|
|
993
|
-
const [first, ...rest] = key.split('.');
|
|
994
|
-
if (isUnsafeKey(first))
|
|
995
|
-
continue;
|
|
996
|
-
const list = nestedKeys.get(first);
|
|
997
|
-
if (list) {
|
|
998
|
-
list.push(rest.join('.'));
|
|
999
|
-
}
|
|
1000
|
-
else {
|
|
1001
|
-
nestedKeys.set(first, [rest.join('.')]);
|
|
1002
|
-
}
|
|
1003
|
-
}
|
|
1004
|
-
else {
|
|
1005
|
-
directKeys.add(key);
|
|
1006
|
-
}
|
|
1007
|
-
}
|
|
1008
|
-
const result = {};
|
|
1009
|
-
for (const key of directKeys) {
|
|
1010
|
-
if (key in obj)
|
|
1011
|
-
result[key] = obj[key];
|
|
1012
|
-
}
|
|
1013
|
-
for (const [first, restKeys] of nestedKeys) {
|
|
1014
|
-
const val = obj[first];
|
|
1015
|
-
if (!val || typeof val !== 'object')
|
|
1016
|
-
continue;
|
|
1017
|
-
if (Array.isArray(val)) {
|
|
1018
|
-
result[first] = val.map(item => pick(item, restKeys));
|
|
1019
|
-
}
|
|
1020
|
-
else {
|
|
1021
|
-
result[first] = pick(val, restKeys);
|
|
1022
|
-
}
|
|
1023
|
-
}
|
|
1024
|
-
return result;
|
|
1025
|
-
};
|
|
1026
|
-
if (Array.isArray(data)) {
|
|
1027
|
-
return data.map(item => pick(item, fields));
|
|
1028
|
-
}
|
|
1029
|
-
return pick(data, fields);
|
|
1030
|
-
}
|
|
1031
975
|
sanitizeOutput(data) {
|
|
1032
976
|
const auditFields = ['_type', 'tenantId', 'createdAt', 'updatedAt', 'createdBy', 'updatedBy'];
|
|
1033
977
|
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Command, Args, Flags } from '@oclif/core';
|
|
2
2
|
import { apiRequest, ApiError, normalizeSortBy } from '../lib/api-client.js';
|
|
3
|
-
import { getCurrentContext, getContext, getBaseUrls } from '../lib/config.js';
|
|
3
|
+
import { getCurrentContext, getContext, getBaseUrls, hasCredentials, missingCredentialsMessage } from '../lib/config.js';
|
|
4
4
|
// Add 'import' action if both create and update exist
|
|
5
5
|
const HAS_IMPORT = true;
|
|
6
6
|
const HAS_EXPORT = true;
|
|
@@ -42,7 +42,7 @@ export default class BankIntegrations extends Command {
|
|
|
42
42
|
id: Args.string({ description: 'Resource ID (for get, update, delete operations)', required: false }),
|
|
43
43
|
};
|
|
44
44
|
static flags = {
|
|
45
|
-
context: Flags.string({ char: 'c', description: 'Context to use' }),
|
|
45
|
+
context: Flags.string({ char: 'c', aliases: ['config'], env: 'ADERIS_CONTEXT', description: 'Context to use for this command, overriding the current context (alias: --config)' }),
|
|
46
46
|
output: Flags.string({ char: 'o', description: 'Output format (default: table for import, json for other commands)', options: ['json', 'table', 'csv'] }),
|
|
47
47
|
table: Flags.boolean({ char: 't', description: 'Output as table (shortcut for --output table)' }),
|
|
48
48
|
csv: Flags.boolean({ description: 'Output as CSV (shortcut for --output csv)' }),
|
|
@@ -58,7 +58,7 @@ export default class BankIntegrations extends Command {
|
|
|
58
58
|
'sort-by': Flags.string({ description: 'Sort field(s), comma-separated. Direction (:ASC/:DESC) is optional; date-like fields default to DESC, others to ASC.' }),
|
|
59
59
|
filter: Flags.string({ description: 'Filter (e.g. --filter status=ACTIVE). Operators: in:A,B, like:%, gt:, lt:, null:', multiple: true }),
|
|
60
60
|
query: Flags.string({ description: 'Additional query params as JSON' }),
|
|
61
|
-
fields: Flags.string({ description: 'Comma-separated list of fields to
|
|
61
|
+
fields: Flags.string({ description: 'Comma-separated list of fields to return, applied by the API (e.g. --fields=id,name,status)' }),
|
|
62
62
|
sanitize: Flags.boolean({ description: 'Remove null values, audit fields, and duplicate UUIDs from output' }),
|
|
63
63
|
'show-http-request': Flags.boolean({ description: 'Show HTTP request details (method, URL, body)' }),
|
|
64
64
|
};
|
|
@@ -116,9 +116,9 @@ export default class BankIntegrations extends Command {
|
|
|
116
116
|
}
|
|
117
117
|
const context = flags.context ? getContext(flags.context) : getCurrentContext();
|
|
118
118
|
if (!context)
|
|
119
|
-
this.error('No context configured. Run: aderis auth login --new');
|
|
120
|
-
if (!context
|
|
121
|
-
this.error(
|
|
119
|
+
this.error(flags.context ? `Context "${flags.context}" not found. List contexts with: aderis config list` : 'No context configured. Run: aderis auth login --new');
|
|
120
|
+
if (!hasCredentials(context))
|
|
121
|
+
this.error(missingCredentialsMessage(context));
|
|
122
122
|
const queryParams = {};
|
|
123
123
|
if (flags.page)
|
|
124
124
|
queryParams.page = flags.page;
|
|
@@ -130,6 +130,8 @@ export default class BankIntegrations extends Command {
|
|
|
130
130
|
queryParams.search = flags.search;
|
|
131
131
|
if (flags['sort-by'])
|
|
132
132
|
queryParams.sortBy = normalizeSortBy(flags['sort-by']);
|
|
133
|
+
if (flags.fields)
|
|
134
|
+
queryParams.fields = flags.fields;
|
|
133
135
|
if (flags.query) {
|
|
134
136
|
try {
|
|
135
137
|
Object.assign(queryParams, JSON.parse(flags.query));
|
|
@@ -332,11 +334,6 @@ export default class BankIntegrations extends Command {
|
|
|
332
334
|
output = obj[arrayKeys[0]];
|
|
333
335
|
}
|
|
334
336
|
}
|
|
335
|
-
// Filter fields if --fields flag is provided
|
|
336
|
-
if (flags.fields) {
|
|
337
|
-
const fieldList = flags.fields.split(',').map(f => f.trim());
|
|
338
|
-
output = this.filterFields(output, fieldList);
|
|
339
|
-
}
|
|
340
337
|
// Sanitize output if requested
|
|
341
338
|
if (flags.sanitize) {
|
|
342
339
|
output = this.sanitizeOutput(output);
|
|
@@ -361,9 +358,9 @@ export default class BankIntegrations extends Command {
|
|
|
361
358
|
async runImport(flags) {
|
|
362
359
|
const context = flags.context ? getContext(flags.context) : getCurrentContext();
|
|
363
360
|
if (!context)
|
|
364
|
-
this.error('No context configured. Run: aderis auth login --new');
|
|
365
|
-
if (!context
|
|
366
|
-
this.error(
|
|
361
|
+
this.error(flags.context ? `Context "${flags.context}" not found. List contexts with: aderis config list` : 'No context configured. Run: aderis auth login --new');
|
|
362
|
+
if (!hasCredentials(context))
|
|
363
|
+
this.error(missingCredentialsMessage(context));
|
|
367
364
|
// Get data from file, --data, or --set flags
|
|
368
365
|
let items = [];
|
|
369
366
|
if (flags.file) {
|
|
@@ -573,9 +570,9 @@ export default class BankIntegrations extends Command {
|
|
|
573
570
|
async runExport(flags) {
|
|
574
571
|
const context = flags.context ? getContext(flags.context) : getCurrentContext();
|
|
575
572
|
if (!context)
|
|
576
|
-
this.error('No context configured. Run: aderis auth login --new');
|
|
577
|
-
if (!context
|
|
578
|
-
this.error(
|
|
573
|
+
this.error(flags.context ? `Context "${flags.context}" not found. List contexts with: aderis config list` : 'No context configured. Run: aderis auth login --new');
|
|
574
|
+
if (!hasCredentials(context))
|
|
575
|
+
this.error(missingCredentialsMessage(context));
|
|
579
576
|
const listEndpoint = ENDPOINTS['list'];
|
|
580
577
|
if (!listEndpoint)
|
|
581
578
|
this.error('Export requires a list endpoint');
|
|
@@ -591,6 +588,8 @@ export default class BankIntegrations extends Command {
|
|
|
591
588
|
baseParams.sortBy = normalizeSortBy(flags['sort-by']);
|
|
592
589
|
if (flags.include)
|
|
593
590
|
baseParams.include = flags.include;
|
|
591
|
+
if (flags.fields)
|
|
592
|
+
baseParams.fields = flags.fields;
|
|
594
593
|
if (flags.query) {
|
|
595
594
|
try {
|
|
596
595
|
Object.assign(baseParams, JSON.parse(flags.query));
|
|
@@ -645,12 +644,7 @@ export default class BankIntegrations extends Command {
|
|
|
645
644
|
}
|
|
646
645
|
}
|
|
647
646
|
process.stderr.write(' done\n');
|
|
648
|
-
// Filter fields if specified
|
|
649
647
|
let output = allItems;
|
|
650
|
-
if (flags.fields) {
|
|
651
|
-
const fieldList = flags.fields.split(',').map(f => f.trim());
|
|
652
|
-
output = this.filterFields(allItems, fieldList);
|
|
653
|
-
}
|
|
654
648
|
// Sanitize output if requested
|
|
655
649
|
if (flags.sanitize) {
|
|
656
650
|
output = this.sanitizeOutput(output);
|
|
@@ -667,9 +661,9 @@ export default class BankIntegrations extends Command {
|
|
|
667
661
|
async runCamt053Import(flags) {
|
|
668
662
|
const context = flags.context ? getContext(flags.context) : getCurrentContext();
|
|
669
663
|
if (!context)
|
|
670
|
-
this.error('No context configured. Run: aderis auth login --new');
|
|
671
|
-
if (!context
|
|
672
|
-
this.error(
|
|
664
|
+
this.error(flags.context ? `Context "${flags.context}" not found. List contexts with: aderis config list` : 'No context configured. Run: aderis auth login --new');
|
|
665
|
+
if (!hasCredentials(context))
|
|
666
|
+
this.error(missingCredentialsMessage(context));
|
|
673
667
|
if (!flags.file) {
|
|
674
668
|
this.error('CAMT.053 import requires --file (-f) flag with path to XML file');
|
|
675
669
|
}
|
|
@@ -757,9 +751,9 @@ export default class BankIntegrations extends Command {
|
|
|
757
751
|
}
|
|
758
752
|
const context = flags.context ? getContext(flags.context) : getCurrentContext();
|
|
759
753
|
if (!context)
|
|
760
|
-
this.error('No context configured. Run: aderis auth login --new');
|
|
761
|
-
if (!context
|
|
762
|
-
this.error(
|
|
754
|
+
this.error(flags.context ? `Context "${flags.context}" not found. List contexts with: aderis config list` : 'No context configured. Run: aderis auth login --new');
|
|
755
|
+
if (!hasCredentials(context))
|
|
756
|
+
this.error(missingCredentialsMessage(context));
|
|
763
757
|
// Get data from file, --data, or --set flags
|
|
764
758
|
let items = [];
|
|
765
759
|
if (flags.file) {
|
|
@@ -979,56 +973,6 @@ export default class BankIntegrations extends Command {
|
|
|
979
973
|
return `\$${op}`;
|
|
980
974
|
return opRe.test(rest) ? `\$${op}:${this.parseFilterValue(rest)}` : `\$${op}:${rest}`;
|
|
981
975
|
}
|
|
982
|
-
filterFields(data, fields) {
|
|
983
|
-
const isUnsafeKey = (k) => k === '__proto__' || k === 'constructor' || k === 'prototype';
|
|
984
|
-
const pick = (obj, keys) => {
|
|
985
|
-
// Group keys by their first segment so sibling sub-paths
|
|
986
|
-
// (e.g. 'items.amount' + 'items._type') resolve in one recursive pass
|
|
987
|
-
// and don't clobber each other on merge.
|
|
988
|
-
const directKeys = new Set();
|
|
989
|
-
const nestedKeys = new Map();
|
|
990
|
-
for (const key of keys) {
|
|
991
|
-
if (key.split('.').some(isUnsafeKey))
|
|
992
|
-
continue;
|
|
993
|
-
if (key.includes('.')) {
|
|
994
|
-
const [first, ...rest] = key.split('.');
|
|
995
|
-
if (isUnsafeKey(first))
|
|
996
|
-
continue;
|
|
997
|
-
const list = nestedKeys.get(first);
|
|
998
|
-
if (list) {
|
|
999
|
-
list.push(rest.join('.'));
|
|
1000
|
-
}
|
|
1001
|
-
else {
|
|
1002
|
-
nestedKeys.set(first, [rest.join('.')]);
|
|
1003
|
-
}
|
|
1004
|
-
}
|
|
1005
|
-
else {
|
|
1006
|
-
directKeys.add(key);
|
|
1007
|
-
}
|
|
1008
|
-
}
|
|
1009
|
-
const result = {};
|
|
1010
|
-
for (const key of directKeys) {
|
|
1011
|
-
if (key in obj)
|
|
1012
|
-
result[key] = obj[key];
|
|
1013
|
-
}
|
|
1014
|
-
for (const [first, restKeys] of nestedKeys) {
|
|
1015
|
-
const val = obj[first];
|
|
1016
|
-
if (!val || typeof val !== 'object')
|
|
1017
|
-
continue;
|
|
1018
|
-
if (Array.isArray(val)) {
|
|
1019
|
-
result[first] = val.map(item => pick(item, restKeys));
|
|
1020
|
-
}
|
|
1021
|
-
else {
|
|
1022
|
-
result[first] = pick(val, restKeys);
|
|
1023
|
-
}
|
|
1024
|
-
}
|
|
1025
|
-
return result;
|
|
1026
|
-
};
|
|
1027
|
-
if (Array.isArray(data)) {
|
|
1028
|
-
return data.map(item => pick(item, fields));
|
|
1029
|
-
}
|
|
1030
|
-
return pick(data, fields);
|
|
1031
|
-
}
|
|
1032
976
|
sanitizeOutput(data) {
|
|
1033
977
|
const auditFields = ['_type', 'tenantId', 'createdAt', 'updatedAt', 'createdBy', 'updatedBy'];
|
|
1034
978
|
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
@@ -15,6 +15,7 @@ export default class BusinessPartners extends Command {
|
|
|
15
15
|
file: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
16
16
|
set: import("@oclif/core/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
17
17
|
'note-id': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
18
|
+
'file-id': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
18
19
|
'business-partner-id': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
19
20
|
page: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
20
21
|
limit: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
@@ -33,7 +34,6 @@ export default class BusinessPartners extends Command {
|
|
|
33
34
|
private runCamt053Import;
|
|
34
35
|
private runNestedImport;
|
|
35
36
|
private parseFilterValue;
|
|
36
|
-
private filterFields;
|
|
37
37
|
private sanitizeOutput;
|
|
38
38
|
private getColumns;
|
|
39
39
|
private getValue;
|