@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.
Files changed (167) hide show
  1. package/README.md +30 -8
  2. package/dist/commands/access-groups.d.ts +0 -1
  3. package/dist/commands/access-groups.js +22 -78
  4. package/dist/commands/account-transaction-allocations.d.ts +0 -1
  5. package/dist/commands/account-transaction-allocations.js +22 -78
  6. package/dist/commands/account-transactions.d.ts +0 -1
  7. package/dist/commands/account-transactions.js +28 -82
  8. package/dist/commands/accounts.d.ts +0 -1
  9. package/dist/commands/accounts.js +24 -80
  10. package/dist/commands/agent-platform.d.ts +0 -1
  11. package/dist/commands/agent-platform.js +24 -79
  12. package/dist/commands/analytics.d.ts +39 -0
  13. package/dist/commands/analytics.js +1113 -0
  14. package/dist/commands/{documents.d.ts → api-keys.d.ts} +1 -2
  15. package/dist/commands/api-keys.js +1117 -0
  16. package/dist/commands/audit-log.d.ts +0 -1
  17. package/dist/commands/audit-log.js +22 -78
  18. package/dist/commands/auth/login.d.ts +9 -0
  19. package/dist/commands/auth/login.js +83 -21
  20. package/dist/commands/auth/logout.d.ts +6 -0
  21. package/dist/commands/auth/logout.js +23 -6
  22. package/dist/commands/auth/status.js +46 -23
  23. package/dist/commands/auth/tenant.js +15 -9
  24. package/dist/commands/auth.d.ts +0 -1
  25. package/dist/commands/auth.js +37 -51
  26. package/dist/commands/bank-accounts.d.ts +0 -1
  27. package/dist/commands/bank-accounts.js +22 -78
  28. package/dist/commands/bank-integrations.d.ts +0 -1
  29. package/dist/commands/bank-integrations.js +22 -78
  30. package/dist/commands/business-partners.d.ts +1 -1
  31. package/dist/commands/business-partners.js +38 -84
  32. package/dist/commands/chat.d.ts +0 -1
  33. package/dist/commands/chat.js +22 -78
  34. package/dist/commands/config/add.d.ts +12 -0
  35. package/dist/commands/config/add.js +97 -17
  36. package/dist/commands/config/current.js +12 -4
  37. package/dist/commands/config/list.js +12 -4
  38. package/dist/commands/config/set-api-key.d.ts +10 -0
  39. package/dist/commands/config/set-api-key.js +49 -0
  40. package/dist/commands/config/use.js +3 -4
  41. package/dist/commands/credit-card-accounts.d.ts +0 -1
  42. package/dist/commands/credit-card-accounts.js +22 -78
  43. package/dist/commands/delivery-notes.d.ts +0 -1
  44. package/dist/commands/delivery-notes.js +29 -84
  45. package/dist/commands/dunning-configs.d.ts +0 -1
  46. package/dist/commands/dunning-configs.js +22 -78
  47. package/dist/commands/dunning-reminders.d.ts +0 -1
  48. package/dist/commands/dunning-reminders.js +22 -78
  49. package/dist/commands/dunning-runs.d.ts +0 -1
  50. package/dist/commands/dunning-runs.js +22 -78
  51. package/dist/commands/email-transactions.d.ts +0 -1
  52. package/dist/commands/email-transactions.js +22 -78
  53. package/dist/commands/employees.d.ts +0 -1
  54. package/dist/commands/employees.js +24 -80
  55. package/dist/commands/entity-configurations.d.ts +0 -1
  56. package/dist/commands/entity-configurations.js +22 -78
  57. package/dist/commands/event-processor-mappings.d.ts +0 -1
  58. package/dist/commands/event-processor-mappings.js +22 -78
  59. package/dist/commands/{files-internal.d.ts → files.d.ts} +1 -2
  60. package/dist/commands/{files-internal.js → files.js} +40 -90
  61. package/dist/commands/health.d.ts +0 -1
  62. package/dist/commands/health.js +22 -78
  63. package/dist/commands/inbox.d.ts +0 -1
  64. package/dist/commands/inbox.js +22 -78
  65. package/dist/commands/integrations.d.ts +0 -1
  66. package/dist/commands/integrations.js +22 -78
  67. package/dist/commands/item-categories.d.ts +0 -1
  68. package/dist/commands/item-categories.js +22 -78
  69. package/dist/commands/items.d.ts +0 -1
  70. package/dist/commands/items.js +24 -80
  71. package/dist/commands/journal-lines.d.ts +0 -1
  72. package/dist/commands/journal-lines.js +22 -78
  73. package/dist/commands/journals.d.ts +1 -1
  74. package/dist/commands/journals.js +29 -81
  75. package/dist/commands/ledgers.d.ts +0 -1
  76. package/dist/commands/ledgers.js +26 -79
  77. package/dist/commands/nango-integrations.d.ts +39 -0
  78. package/dist/commands/nango-integrations.js +1115 -0
  79. package/dist/commands/office-locations.d.ts +0 -1
  80. package/dist/commands/office-locations.js +22 -78
  81. package/dist/commands/payment-methods.d.ts +0 -1
  82. package/dist/commands/payment-methods.js +22 -78
  83. package/dist/commands/payment-runs.d.ts +0 -1
  84. package/dist/commands/payment-runs.js +24 -79
  85. package/dist/commands/payment-terms.d.ts +0 -1
  86. package/dist/commands/payment-terms.js +22 -78
  87. package/dist/commands/payments.d.ts +0 -1
  88. package/dist/commands/payments.js +22 -78
  89. package/dist/commands/price-lists.d.ts +0 -1
  90. package/dist/commands/price-lists.js +22 -78
  91. package/dist/commands/processor-mappings.d.ts +0 -1
  92. package/dist/commands/processor-mappings.js +22 -78
  93. package/dist/commands/processors.d.ts +0 -1
  94. package/dist/commands/processors.js +22 -78
  95. package/dist/commands/purchase-order-types.d.ts +0 -1
  96. package/dist/commands/purchase-order-types.js +22 -78
  97. package/dist/commands/purchase-orders.d.ts +1 -1
  98. package/dist/commands/purchase-orders.js +35 -84
  99. package/dist/commands/reports.d.ts +0 -1
  100. package/dist/commands/reports.js +23 -79
  101. package/dist/commands/salary-types.d.ts +0 -1
  102. package/dist/commands/salary-types.js +22 -78
  103. package/dist/commands/sales-invoices.d.ts +0 -1
  104. package/dist/commands/sales-invoices.js +38 -89
  105. package/dist/commands/sales-orders.d.ts +0 -1
  106. package/dist/commands/sales-orders.js +26 -82
  107. package/dist/commands/saved-views.d.ts +0 -1
  108. package/dist/commands/saved-views.js +22 -78
  109. package/dist/commands/scheduled-processor-mappings.d.ts +0 -1
  110. package/dist/commands/scheduled-processor-mappings.js +22 -78
  111. package/dist/commands/schedules.d.ts +0 -1
  112. package/dist/commands/schedules.js +22 -78
  113. package/dist/commands/switch.js +14 -7
  114. package/dist/commands/tag-configurations.d.ts +39 -0
  115. package/dist/commands/{documents.js → tag-configurations.js} +40 -96
  116. package/dist/commands/tags.d.ts +0 -1
  117. package/dist/commands/tags.js +22 -78
  118. package/dist/commands/tax-codes.d.ts +0 -1
  119. package/dist/commands/tax-codes.js +22 -78
  120. package/dist/commands/tax-matrix.d.ts +0 -1
  121. package/dist/commands/tax-matrix.js +22 -78
  122. package/dist/commands/tenants.d.ts +0 -1
  123. package/dist/commands/tenants.js +24 -79
  124. package/dist/commands/text-templates.d.ts +0 -1
  125. package/dist/commands/text-templates.js +22 -78
  126. package/dist/commands/tools.d.ts +0 -1
  127. package/dist/commands/tools.js +22 -78
  128. package/dist/commands/vat-declarations.d.ts +1 -1
  129. package/dist/commands/vat-declarations.js +28 -79
  130. package/dist/commands/vendor-invoices.d.ts +0 -1
  131. package/dist/commands/vendor-invoices.js +31 -86
  132. package/dist/commands/webhooks.d.ts +0 -1
  133. package/dist/commands/webhooks.js +22 -78
  134. package/dist/commands/workflows.d.ts +0 -1
  135. package/dist/commands/workflows.js +22 -78
  136. package/dist/lib/api-client.js +8 -6
  137. package/dist/lib/auth/constants.d.ts +11 -0
  138. package/dist/lib/auth/constants.js +11 -0
  139. package/dist/lib/auth/errors.d.ts +17 -0
  140. package/dist/lib/auth/errors.js +22 -0
  141. package/dist/lib/auth/flow.d.ts +27 -0
  142. package/dist/lib/auth/flow.js +163 -0
  143. package/dist/lib/auth/guards.d.ts +5 -0
  144. package/dist/lib/auth/guards.js +14 -0
  145. package/dist/lib/auth/http.d.ts +16 -0
  146. package/dist/lib/auth/http.js +49 -0
  147. package/dist/lib/auth/index.d.ts +49 -0
  148. package/dist/lib/auth/index.js +217 -0
  149. package/dist/lib/auth/keycloak-provider.d.ts +75 -0
  150. package/dist/lib/auth/keycloak-provider.js +215 -0
  151. package/dist/lib/auth/pages.d.ts +25 -0
  152. package/dist/lib/auth/pages.js +123 -0
  153. package/dist/lib/auth/pkce.d.ts +11 -0
  154. package/dist/lib/auth/pkce.js +17 -0
  155. package/dist/lib/auth/tokens.d.ts +54 -0
  156. package/dist/lib/auth/tokens.js +104 -0
  157. package/dist/lib/auth/types.d.ts +57 -0
  158. package/dist/lib/auth/types.js +1 -0
  159. package/dist/lib/auth/validated-url.d.ts +6 -0
  160. package/dist/lib/auth/validated-url.js +53 -0
  161. package/dist/lib/base-api-command.js +6 -4
  162. package/dist/lib/config.d.ts +44 -4
  163. package/dist/lib/config.js +55 -19
  164. package/oclif.manifest.json +1181 -330
  165. package/package.json +3 -2
  166. package/dist/lib/auth.d.ts +0 -35
  167. package/dist/lib/auth.js +0 -566
@@ -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({ char: 'c', description: 'Context to use' }),
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 show (e.g. --fields=id,name,status)' }),
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('No context configured. Run: aderis auth login --new');
100
- if (!context.tokens)
101
- this.error('Not logged in. Run: aderis auth login');
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('No context configured. Run: aderis auth login --new');
363
- if (!context.tokens)
364
- this.error('Not logged in. Run: aderis auth login');
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('No context configured. Run: aderis auth login --new');
450
- if (!context.tokens)
451
- this.error('Not logged in. Run: aderis auth login');
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('No context configured. Run: aderis auth login --new');
526
- if (!context.tokens)
527
- this.error('Not logged in. Run: aderis auth login');
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('No context configured. Run: aderis auth login --new');
680
- if (!context.tokens)
681
- this.error('Not logged in. Run: aderis auth login');
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) {
@@ -33,7 +33,6 @@ export default class BankAccounts extends Command {
33
33
  private runCamt053Import;
34
34
  private runNestedImport;
35
35
  private parseFilterValue;
36
- private filterFields;
37
36
  private sanitizeOutput;
38
37
  private getColumns;
39
38
  private getValue;
@@ -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 show (e.g. --fields=id,name,status)' }),
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.tokens)
120
- this.error('Not logged in. Run: aderis auth login');
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.tokens)
365
- this.error('Not logged in. Run: aderis auth login');
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.tokens)
577
- this.error('Not logged in. Run: aderis auth login');
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.tokens)
671
- this.error('Not logged in. Run: aderis auth login');
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.tokens)
761
- this.error('Not logged in. Run: aderis auth login');
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;
@@ -33,7 +33,6 @@ export default class BankIntegrations extends Command {
33
33
  private runCamt053Import;
34
34
  private runNestedImport;
35
35
  private parseFilterValue;
36
- private filterFields;
37
36
  private sanitizeOutput;
38
37
  private getColumns;
39
38
  private getValue;
@@ -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 show (e.g. --fields=id,name,status)' }),
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.tokens)
121
- this.error('Not logged in. Run: aderis auth login');
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.tokens)
366
- this.error('Not logged in. Run: aderis auth login');
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.tokens)
578
- this.error('Not logged in. Run: aderis auth login');
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.tokens)
672
- this.error('Not logged in. Run: aderis auth login');
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.tokens)
762
- this.error('Not logged in. Run: aderis auth login');
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;