@aderis-erp/cli 1.0.13 → 1.0.15

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 (86) hide show
  1. package/dist/commands/access-groups.js +21 -21
  2. package/dist/commands/account-transaction-allocations.js +21 -21
  3. package/dist/commands/account-transactions.js +23 -23
  4. package/dist/commands/accounts.js +23 -23
  5. package/dist/commands/agent-platform.js +23 -22
  6. package/dist/commands/analytics.d.ts +40 -0
  7. package/dist/commands/{documents.js → analytics.js} +33 -43
  8. package/dist/commands/audit-log.js +24 -24
  9. package/dist/commands/auth/login.js +11 -2
  10. package/dist/commands/auth/logout.d.ts +2 -0
  11. package/dist/commands/auth/logout.js +19 -6
  12. package/dist/commands/auth/status.js +26 -12
  13. package/dist/commands/auth/tenant.js +12 -3
  14. package/dist/commands/auth.js +32 -17
  15. package/dist/commands/bank-accounts.js +21 -21
  16. package/dist/commands/bank-integrations.js +21 -21
  17. package/dist/commands/business-partners.js +29 -26
  18. package/dist/commands/chat.js +21 -21
  19. package/dist/commands/config/add.d.ts +9 -0
  20. package/dist/commands/config/add.js +64 -2
  21. package/dist/commands/config/current.js +9 -4
  22. package/dist/commands/config/list.js +9 -4
  23. package/dist/commands/config/set-api-key.d.ts +10 -0
  24. package/dist/commands/config/set-api-key.js +49 -0
  25. package/dist/commands/config/use.js +3 -4
  26. package/dist/commands/credit-card-accounts.js +21 -21
  27. package/dist/commands/delivery-notes.js +28 -25
  28. package/dist/commands/dunning-configs.js +21 -21
  29. package/dist/commands/dunning-reminders.js +21 -21
  30. package/dist/commands/dunning-runs.js +21 -21
  31. package/dist/commands/email-transactions.js +21 -21
  32. package/dist/commands/employees.js +23 -23
  33. package/dist/commands/entity-configurations.js +21 -21
  34. package/dist/commands/event-processor-mappings.js +21 -21
  35. package/dist/commands/{documents.d.ts → files.d.ts} +1 -1
  36. package/dist/commands/{files-internal.js → files.js} +39 -33
  37. package/dist/commands/health.js +21 -21
  38. package/dist/commands/inbox.d.ts +1 -0
  39. package/dist/commands/inbox.js +25 -23
  40. package/dist/commands/integrations.js +21 -21
  41. package/dist/commands/item-categories.js +21 -21
  42. package/dist/commands/items.js +23 -23
  43. package/dist/commands/journal-lines.js +21 -21
  44. package/dist/commands/journals.js +27 -24
  45. package/dist/commands/ledgers.js +25 -22
  46. package/dist/commands/office-locations.js +21 -21
  47. package/dist/commands/payment-methods.js +21 -21
  48. package/dist/commands/payment-runs.js +23 -22
  49. package/dist/commands/payment-terms.js +21 -21
  50. package/dist/commands/payments.js +21 -21
  51. package/dist/commands/price-lists.js +21 -21
  52. package/dist/commands/processor-mappings.js +21 -21
  53. package/dist/commands/processors.js +21 -21
  54. package/dist/commands/purchase-order-types.js +21 -21
  55. package/dist/commands/purchase-orders.d.ts +1 -0
  56. package/dist/commands/purchase-orders.js +32 -25
  57. package/dist/commands/reports.js +21 -21
  58. package/dist/commands/salary-types.js +21 -21
  59. package/dist/commands/sales-invoices.js +33 -31
  60. package/dist/commands/sales-orders.js +23 -23
  61. package/dist/commands/saved-views.js +21 -21
  62. package/dist/commands/scheduled-processor-mappings.d.ts +40 -0
  63. package/dist/commands/scheduled-processor-mappings.js +1178 -0
  64. package/dist/commands/schedules.js +21 -21
  65. package/dist/commands/switch.js +10 -3
  66. package/dist/commands/{files-internal.d.ts → tag-configurations.d.ts} +1 -1
  67. package/dist/commands/tag-configurations.js +1178 -0
  68. package/dist/commands/tags.js +21 -21
  69. package/dist/commands/tax-codes.js +21 -21
  70. package/dist/commands/tax-matrix.js +21 -21
  71. package/dist/commands/tenants.js +23 -23
  72. package/dist/commands/text-templates.js +21 -21
  73. package/dist/commands/tools.js +21 -21
  74. package/dist/commands/vat-declarations.js +21 -21
  75. package/dist/commands/vendor-invoices.js +25 -25
  76. package/dist/commands/webhooks.js +21 -21
  77. package/dist/commands/workflows.js +21 -21
  78. package/dist/lib/api-client.d.ts +8 -0
  79. package/dist/lib/api-client.js +31 -6
  80. package/dist/lib/auth.d.ts +8 -0
  81. package/dist/lib/auth.js +51 -7
  82. package/dist/lib/base-api-command.js +6 -4
  83. package/dist/lib/config.d.ts +31 -1
  84. package/dist/lib/config.js +31 -0
  85. package/oclif.manifest.json +1099 -443
  86. package/package.json +2 -2
@@ -1,6 +1,6 @@
1
1
  import { Command, Args, Flags } from '@oclif/core';
2
- import { apiRequest, ApiError } from '../lib/api-client.js';
3
- import { getCurrentContext, getContext, getBaseUrls } from '../lib/config.js';
2
+ import { apiRequest, ApiError, normalizeSortBy } from '../lib/api-client.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;
@@ -29,7 +29,7 @@ export default class AccessGroups extends Command {
29
29
  id: Args.string({ description: 'Resource ID (for get, update, delete operations)', required: false }),
30
30
  };
31
31
  static flags = {
32
- context: Flags.string({ char: 'c', description: 'Context to use' }),
32
+ context: Flags.string({ char: 'c', aliases: ['config'], env: 'ADERIS_CONTEXT', description: 'Context to use for this command, overriding the current context (alias: --config)' }),
33
33
  output: Flags.string({ char: 'o', description: 'Output format (default: table for import, json for other commands)', options: ['json', 'table', 'csv'] }),
34
34
  table: Flags.boolean({ char: 't', description: 'Output as table (shortcut for --output table)' }),
35
35
  csv: Flags.boolean({ description: 'Output as CSV (shortcut for --output csv)' }),
@@ -40,7 +40,7 @@ export default class AccessGroups extends Command {
40
40
  limit: Flags.string({ description: 'Items per page' }),
41
41
  include: Flags.string({ description: 'Relations to include' }),
42
42
  search: Flags.string({ description: 'Search term' }),
43
- 'sort-by': Flags.string({ description: 'Sort field' }),
43
+ 'sort-by': Flags.string({ description: 'Sort field(s), comma-separated. Direction (:ASC/:DESC) is optional; date-like fields default to DESC, others to ASC.' }),
44
44
  filter: Flags.string({ description: 'Filter (e.g. --filter status=ACTIVE). Operators: in:A,B, like:%, gt:, lt:, null:', multiple: true }),
45
45
  query: Flags.string({ description: 'Additional query params as JSON' }),
46
46
  fields: Flags.string({ description: 'Comma-separated list of fields to show (e.g. --fields=id,name,status)' }),
@@ -101,9 +101,9 @@ export default class AccessGroups extends Command {
101
101
  }
102
102
  const context = flags.context ? getContext(flags.context) : getCurrentContext();
103
103
  if (!context)
104
- this.error('No context configured. Run: aderis auth login --new');
105
- if (!context.tokens)
106
- this.error('Not logged in. Run: aderis auth login');
104
+ this.error(flags.context ? `Context "${flags.context}" not found. List contexts with: aderis config list` : 'No context configured. Run: aderis auth login --new');
105
+ if (!hasCredentials(context))
106
+ this.error(missingCredentialsMessage(context));
107
107
  const queryParams = {};
108
108
  if (flags.page)
109
109
  queryParams.page = flags.page;
@@ -114,7 +114,7 @@ export default class AccessGroups extends Command {
114
114
  if (flags.search)
115
115
  queryParams.search = flags.search;
116
116
  if (flags['sort-by'])
117
- queryParams.sortBy = flags['sort-by'];
117
+ queryParams.sortBy = normalizeSortBy(flags['sort-by']);
118
118
  if (flags.query) {
119
119
  try {
120
120
  Object.assign(queryParams, JSON.parse(flags.query));
@@ -346,9 +346,9 @@ export default class AccessGroups extends Command {
346
346
  async runImport(flags) {
347
347
  const context = flags.context ? getContext(flags.context) : getCurrentContext();
348
348
  if (!context)
349
- this.error('No context configured. Run: aderis auth login --new');
350
- if (!context.tokens)
351
- this.error('Not logged in. Run: aderis auth login');
349
+ this.error(flags.context ? `Context "${flags.context}" not found. List contexts with: aderis config list` : 'No context configured. Run: aderis auth login --new');
350
+ if (!hasCredentials(context))
351
+ this.error(missingCredentialsMessage(context));
352
352
  // Get data from file, --data, or --set flags
353
353
  let items = [];
354
354
  if (flags.file) {
@@ -558,9 +558,9 @@ export default class AccessGroups extends Command {
558
558
  async runExport(flags) {
559
559
  const context = flags.context ? getContext(flags.context) : getCurrentContext();
560
560
  if (!context)
561
- this.error('No context configured. Run: aderis auth login --new');
562
- if (!context.tokens)
563
- this.error('Not logged in. Run: aderis auth login');
561
+ this.error(flags.context ? `Context "${flags.context}" not found. List contexts with: aderis config list` : 'No context configured. Run: aderis auth login --new');
562
+ if (!hasCredentials(context))
563
+ this.error(missingCredentialsMessage(context));
564
564
  const listEndpoint = ENDPOINTS['list'];
565
565
  if (!listEndpoint)
566
566
  this.error('Export requires a list endpoint');
@@ -573,7 +573,7 @@ export default class AccessGroups extends Command {
573
573
  if (flags.search)
574
574
  baseParams.search = flags.search;
575
575
  if (flags['sort-by'])
576
- baseParams.sortBy = flags['sort-by'];
576
+ baseParams.sortBy = normalizeSortBy(flags['sort-by']);
577
577
  if (flags.include)
578
578
  baseParams.include = flags.include;
579
579
  if (flags.query) {
@@ -652,9 +652,9 @@ export default class AccessGroups extends Command {
652
652
  async runCamt053Import(flags) {
653
653
  const context = flags.context ? getContext(flags.context) : getCurrentContext();
654
654
  if (!context)
655
- this.error('No context configured. Run: aderis auth login --new');
656
- if (!context.tokens)
657
- this.error('Not logged in. Run: aderis auth login');
655
+ this.error(flags.context ? `Context "${flags.context}" not found. List contexts with: aderis config list` : 'No context configured. Run: aderis auth login --new');
656
+ if (!hasCredentials(context))
657
+ this.error(missingCredentialsMessage(context));
658
658
  if (!flags.file) {
659
659
  this.error('CAMT.053 import requires --file (-f) flag with path to XML file');
660
660
  }
@@ -742,9 +742,9 @@ export default class AccessGroups extends Command {
742
742
  }
743
743
  const context = flags.context ? getContext(flags.context) : getCurrentContext();
744
744
  if (!context)
745
- this.error('No context configured. Run: aderis auth login --new');
746
- if (!context.tokens)
747
- this.error('Not logged in. Run: aderis auth login');
745
+ this.error(flags.context ? `Context "${flags.context}" not found. List contexts with: aderis config list` : 'No context configured. Run: aderis auth login --new');
746
+ if (!hasCredentials(context))
747
+ this.error(missingCredentialsMessage(context));
748
748
  // Get data from file, --data, or --set flags
749
749
  let items = [];
750
750
  if (flags.file) {
@@ -1,6 +1,6 @@
1
1
  import { Command, Args, Flags } from '@oclif/core';
2
- import { apiRequest, ApiError } from '../lib/api-client.js';
3
- import { getCurrentContext, getContext, getBaseUrls } from '../lib/config.js';
2
+ import { apiRequest, ApiError, normalizeSortBy } from '../lib/api-client.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 = false;
6
6
  const HAS_EXPORT = true;
@@ -23,7 +23,7 @@ export default class AccountTransactionAllocations extends Command {
23
23
  id: Args.string({ description: 'Resource ID (for get, update, delete operations)', required: false }),
24
24
  };
25
25
  static flags = {
26
- context: Flags.string({ char: 'c', description: 'Context to use' }),
26
+ context: Flags.string({ char: 'c', aliases: ['config'], env: 'ADERIS_CONTEXT', description: 'Context to use for this command, overriding the current context (alias: --config)' }),
27
27
  output: Flags.string({ char: 'o', description: 'Output format (default: table for import, json for other commands)', options: ['json', 'table', 'csv'] }),
28
28
  table: Flags.boolean({ char: 't', description: 'Output as table (shortcut for --output table)' }),
29
29
  csv: Flags.boolean({ description: 'Output as CSV (shortcut for --output csv)' }),
@@ -34,7 +34,7 @@ export default class AccountTransactionAllocations extends Command {
34
34
  limit: Flags.string({ description: 'Items per page' }),
35
35
  include: Flags.string({ description: 'Relations to include' }),
36
36
  search: Flags.string({ description: 'Search term' }),
37
- 'sort-by': Flags.string({ description: 'Sort field' }),
37
+ 'sort-by': Flags.string({ description: 'Sort field(s), comma-separated. Direction (:ASC/:DESC) is optional; date-like fields default to DESC, others to ASC.' }),
38
38
  filter: Flags.string({ description: 'Filter (e.g. --filter status=ACTIVE). Operators: in:A,B, like:%, gt:, lt:, null:', multiple: true }),
39
39
  query: Flags.string({ description: 'Additional query params as JSON' }),
40
40
  fields: Flags.string({ description: 'Comma-separated list of fields to show (e.g. --fields=id,name,status)' }),
@@ -95,9 +95,9 @@ export default class AccountTransactionAllocations extends Command {
95
95
  }
96
96
  const context = flags.context ? getContext(flags.context) : getCurrentContext();
97
97
  if (!context)
98
- this.error('No context configured. Run: aderis auth login --new');
99
- if (!context.tokens)
100
- this.error('Not logged in. Run: aderis auth login');
98
+ this.error(flags.context ? `Context "${flags.context}" not found. List contexts with: aderis config list` : 'No context configured. Run: aderis auth login --new');
99
+ if (!hasCredentials(context))
100
+ this.error(missingCredentialsMessage(context));
101
101
  const queryParams = {};
102
102
  if (flags.page)
103
103
  queryParams.page = flags.page;
@@ -108,7 +108,7 @@ export default class AccountTransactionAllocations extends Command {
108
108
  if (flags.search)
109
109
  queryParams.search = flags.search;
110
110
  if (flags['sort-by'])
111
- queryParams.sortBy = flags['sort-by'];
111
+ queryParams.sortBy = normalizeSortBy(flags['sort-by']);
112
112
  if (flags.query) {
113
113
  try {
114
114
  Object.assign(queryParams, JSON.parse(flags.query));
@@ -340,9 +340,9 @@ export default class AccountTransactionAllocations extends Command {
340
340
  async runImport(flags) {
341
341
  const context = flags.context ? getContext(flags.context) : getCurrentContext();
342
342
  if (!context)
343
- this.error('No context configured. Run: aderis auth login --new');
344
- if (!context.tokens)
345
- this.error('Not logged in. Run: aderis auth login');
343
+ this.error(flags.context ? `Context "${flags.context}" not found. List contexts with: aderis config list` : 'No context configured. Run: aderis auth login --new');
344
+ if (!hasCredentials(context))
345
+ this.error(missingCredentialsMessage(context));
346
346
  // Get data from file, --data, or --set flags
347
347
  let items = [];
348
348
  if (flags.file) {
@@ -552,9 +552,9 @@ export default class AccountTransactionAllocations extends Command {
552
552
  async runExport(flags) {
553
553
  const context = flags.context ? getContext(flags.context) : getCurrentContext();
554
554
  if (!context)
555
- this.error('No context configured. Run: aderis auth login --new');
556
- if (!context.tokens)
557
- this.error('Not logged in. Run: aderis auth login');
555
+ this.error(flags.context ? `Context "${flags.context}" not found. List contexts with: aderis config list` : 'No context configured. Run: aderis auth login --new');
556
+ if (!hasCredentials(context))
557
+ this.error(missingCredentialsMessage(context));
558
558
  const listEndpoint = ENDPOINTS['list'];
559
559
  if (!listEndpoint)
560
560
  this.error('Export requires a list endpoint');
@@ -567,7 +567,7 @@ export default class AccountTransactionAllocations extends Command {
567
567
  if (flags.search)
568
568
  baseParams.search = flags.search;
569
569
  if (flags['sort-by'])
570
- baseParams.sortBy = flags['sort-by'];
570
+ baseParams.sortBy = normalizeSortBy(flags['sort-by']);
571
571
  if (flags.include)
572
572
  baseParams.include = flags.include;
573
573
  if (flags.query) {
@@ -646,9 +646,9 @@ export default class AccountTransactionAllocations extends Command {
646
646
  async runCamt053Import(flags) {
647
647
  const context = flags.context ? getContext(flags.context) : getCurrentContext();
648
648
  if (!context)
649
- this.error('No context configured. Run: aderis auth login --new');
650
- if (!context.tokens)
651
- this.error('Not logged in. Run: aderis auth login');
649
+ this.error(flags.context ? `Context "${flags.context}" not found. List contexts with: aderis config list` : 'No context configured. Run: aderis auth login --new');
650
+ if (!hasCredentials(context))
651
+ this.error(missingCredentialsMessage(context));
652
652
  if (!flags.file) {
653
653
  this.error('CAMT.053 import requires --file (-f) flag with path to XML file');
654
654
  }
@@ -736,9 +736,9 @@ export default class AccountTransactionAllocations extends Command {
736
736
  }
737
737
  const context = flags.context ? getContext(flags.context) : getCurrentContext();
738
738
  if (!context)
739
- this.error('No context configured. Run: aderis auth login --new');
740
- if (!context.tokens)
741
- this.error('Not logged in. Run: aderis auth login');
739
+ this.error(flags.context ? `Context "${flags.context}" not found. List contexts with: aderis config list` : 'No context configured. Run: aderis auth login --new');
740
+ if (!hasCredentials(context))
741
+ this.error(missingCredentialsMessage(context));
742
742
  // Get data from file, --data, or --set flags
743
743
  let items = [];
744
744
  if (flags.file) {
@@ -1,6 +1,6 @@
1
1
  import { Command, Args, Flags } from '@oclif/core';
2
- import { apiRequest, ApiError } from '../lib/api-client.js';
3
- import { getCurrentContext, getContext, getBaseUrls } from '../lib/config.js';
2
+ import { apiRequest, ApiError, normalizeSortBy } from '../lib/api-client.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;
@@ -13,8 +13,8 @@ const ENDPOINTS = {
13
13
  'get': { method: 'GET', path: '/v1/account-transactions/{id}', summary: 'Get an account transaction by ID', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
14
14
  'update': { method: 'PATCH', path: '/v1/account-transactions/{id}', summary: 'Update an account transaction', pathParams: ['id'], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: ['allocations'] },
15
15
  'delete': { method: 'DELETE', path: '/v1/account-transactions/{id}', summary: 'Delete an account transaction', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
16
- 'allocations-reprocess-unbooked': { method: 'POST', path: '/v1/account-transactions/allocations/reprocess-unbooked', summary: 'Internal — re-book confirmed allocations that have no journal', pathParams: [], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: ['allocationIds'] },
17
- 'allocations-unbooked': { method: 'GET', path: '/v1/account-transactions/allocations/unbooked', summary: 'Internal — list confirmed allocations that have no journal', pathParams: [], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
16
+ 'allocations-reprocess-unbooked': { method: 'POST', path: '/v1/account-transactions/allocations/reprocess-unbooked', summary: 'Internal — re-book or repair allocations stuck at CONFIRMED', pathParams: [], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: ['allocationIds'] },
17
+ 'allocations-unbooked': { method: 'GET', path: '/v1/account-transactions/allocations/unbooked', summary: 'Internal — list allocations stuck at CONFIRMED', pathParams: [], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
18
18
  'list-allocations': { method: 'GET', path: '/v1/account-transactions/{transactionId}/allocations', summary: 'Get all allocations for an account transaction', pathParams: ['transactionId'], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
19
19
  'create-allocations': { method: 'POST', path: '/v1/account-transactions/{transactionId}/allocations', summary: 'Create an allocation for an account transaction', pathParams: ['transactionId'], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: ['notes'] },
20
20
  'get-allocations': { method: 'GET', path: '/v1/account-transactions/{transactionId}/allocations/{allocationId}', summary: 'Get an allocation by ID', pathParams: ['transactionId', 'allocationId'], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
@@ -43,7 +43,7 @@ export default class AccountTransactions extends Command {
43
43
  id: Args.string({ description: 'Resource ID (for get, update, delete operations)', required: false }),
44
44
  };
45
45
  static flags = {
46
- context: Flags.string({ char: 'c', description: 'Context to use' }),
46
+ context: Flags.string({ char: 'c', aliases: ['config'], env: 'ADERIS_CONTEXT', description: 'Context to use for this command, overriding the current context (alias: --config)' }),
47
47
  output: Flags.string({ char: 'o', description: 'Output format (default: table for import, json for other commands)', options: ['json', 'table', 'csv'] }),
48
48
  table: Flags.boolean({ char: 't', description: 'Output as table (shortcut for --output table)' }),
49
49
  csv: Flags.boolean({ description: 'Output as CSV (shortcut for --output csv)' }),
@@ -56,7 +56,7 @@ export default class AccountTransactions extends Command {
56
56
  limit: Flags.string({ description: 'Items per page' }),
57
57
  include: Flags.string({ description: 'Relations to include' }),
58
58
  search: Flags.string({ description: 'Search term' }),
59
- 'sort-by': Flags.string({ description: 'Sort field' }),
59
+ 'sort-by': Flags.string({ description: 'Sort field(s), comma-separated. Direction (:ASC/:DESC) is optional; date-like fields default to DESC, others to ASC.' }),
60
60
  filter: Flags.string({ description: 'Filter (e.g. --filter status=ACTIVE). Operators: in:A,B, like:%, gt:, lt:, null:', multiple: true }),
61
61
  query: Flags.string({ description: 'Additional query params as JSON' }),
62
62
  fields: Flags.string({ description: 'Comma-separated list of fields to show (e.g. --fields=id,name,status)' }),
@@ -117,9 +117,9 @@ export default class AccountTransactions extends Command {
117
117
  }
118
118
  const context = flags.context ? getContext(flags.context) : getCurrentContext();
119
119
  if (!context)
120
- this.error('No context configured. Run: aderis auth login --new');
121
- if (!context.tokens)
122
- this.error('Not logged in. Run: aderis auth login');
120
+ this.error(flags.context ? `Context "${flags.context}" not found. List contexts with: aderis config list` : 'No context configured. Run: aderis auth login --new');
121
+ if (!hasCredentials(context))
122
+ this.error(missingCredentialsMessage(context));
123
123
  const queryParams = {};
124
124
  if (flags.page)
125
125
  queryParams.page = flags.page;
@@ -130,7 +130,7 @@ export default class AccountTransactions extends Command {
130
130
  if (flags.search)
131
131
  queryParams.search = flags.search;
132
132
  if (flags['sort-by'])
133
- queryParams.sortBy = flags['sort-by'];
133
+ queryParams.sortBy = normalizeSortBy(flags['sort-by']);
134
134
  if (flags.query) {
135
135
  try {
136
136
  Object.assign(queryParams, JSON.parse(flags.query));
@@ -362,9 +362,9 @@ export default class AccountTransactions extends Command {
362
362
  async runImport(flags) {
363
363
  const context = flags.context ? getContext(flags.context) : getCurrentContext();
364
364
  if (!context)
365
- this.error('No context configured. Run: aderis auth login --new');
366
- if (!context.tokens)
367
- this.error('Not logged in. Run: aderis auth login');
365
+ this.error(flags.context ? `Context "${flags.context}" not found. List contexts with: aderis config list` : 'No context configured. Run: aderis auth login --new');
366
+ if (!hasCredentials(context))
367
+ this.error(missingCredentialsMessage(context));
368
368
  // Get data from file, --data, or --set flags
369
369
  let items = [];
370
370
  if (flags.file) {
@@ -574,9 +574,9 @@ export default class AccountTransactions extends Command {
574
574
  async runExport(flags) {
575
575
  const context = flags.context ? getContext(flags.context) : getCurrentContext();
576
576
  if (!context)
577
- this.error('No context configured. Run: aderis auth login --new');
578
- if (!context.tokens)
579
- this.error('Not logged in. Run: aderis auth login');
577
+ this.error(flags.context ? `Context "${flags.context}" not found. List contexts with: aderis config list` : 'No context configured. Run: aderis auth login --new');
578
+ if (!hasCredentials(context))
579
+ this.error(missingCredentialsMessage(context));
580
580
  const listEndpoint = ENDPOINTS['list'];
581
581
  if (!listEndpoint)
582
582
  this.error('Export requires a list endpoint');
@@ -589,7 +589,7 @@ export default class AccountTransactions extends Command {
589
589
  if (flags.search)
590
590
  baseParams.search = flags.search;
591
591
  if (flags['sort-by'])
592
- baseParams.sortBy = flags['sort-by'];
592
+ baseParams.sortBy = normalizeSortBy(flags['sort-by']);
593
593
  if (flags.include)
594
594
  baseParams.include = flags.include;
595
595
  if (flags.query) {
@@ -668,9 +668,9 @@ export default class AccountTransactions extends Command {
668
668
  async runCamt053Import(flags) {
669
669
  const context = flags.context ? getContext(flags.context) : getCurrentContext();
670
670
  if (!context)
671
- this.error('No context configured. Run: aderis auth login --new');
672
- if (!context.tokens)
673
- this.error('Not logged in. Run: aderis auth login');
671
+ this.error(flags.context ? `Context "${flags.context}" not found. List contexts with: aderis config list` : 'No context configured. Run: aderis auth login --new');
672
+ if (!hasCredentials(context))
673
+ this.error(missingCredentialsMessage(context));
674
674
  if (!flags.file) {
675
675
  this.error('CAMT.053 import requires --file (-f) flag with path to XML file');
676
676
  }
@@ -758,9 +758,9 @@ export default class AccountTransactions extends Command {
758
758
  }
759
759
  const context = flags.context ? getContext(flags.context) : getCurrentContext();
760
760
  if (!context)
761
- this.error('No context configured. Run: aderis auth login --new');
762
- if (!context.tokens)
763
- this.error('Not logged in. Run: aderis auth login');
761
+ this.error(flags.context ? `Context "${flags.context}" not found. List contexts with: aderis config list` : 'No context configured. Run: aderis auth login --new');
762
+ if (!hasCredentials(context))
763
+ this.error(missingCredentialsMessage(context));
764
764
  // Get data from file, --data, or --set flags
765
765
  let items = [];
766
766
  if (flags.file) {
@@ -1,6 +1,6 @@
1
1
  import { Command, Args, Flags } from '@oclif/core';
2
- import { apiRequest, ApiError } from '../lib/api-client.js';
3
- import { getCurrentContext, getContext, getBaseUrls } from '../lib/config.js';
2
+ import { apiRequest, ApiError, normalizeSortBy } from '../lib/api-client.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;
@@ -9,9 +9,9 @@ const NESTED_IMPORTS = ["notes"];
9
9
  const SUBCOMMANDS = [...["list", "create", "get", "update", "delete", "list-notes", "create-notes", "get-notes", "update-notes", "delete-notes"], ...(HAS_IMPORT ? ['import'] : []), ...(HAS_EXPORT ? ['export'] : []), ...NESTED_IMPORTS.map(n => `import-${n}`)];
10
10
  const ENDPOINTS = {
11
11
  'list': { method: 'GET', path: '/v1/accounts', summary: 'List all accounts', pathParams: [], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
12
- 'create': { method: 'POST', path: '/v1/accounts', summary: 'Create a new account', pathParams: [], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: ['tagIds', 'notes'] },
12
+ 'create': { method: 'POST', path: '/v1/accounts', summary: 'Create a new account', pathParams: [], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: ['tagIds', 'tagCodes', 'notes'] },
13
13
  'get': { method: 'GET', path: '/v1/accounts/{id}', summary: 'Get an account by ID', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
14
- 'update': { method: 'PATCH', path: '/v1/accounts/{id}', summary: 'Update an account', pathParams: ['id'], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: ['tagIds'] },
14
+ 'update': { method: 'PATCH', path: '/v1/accounts/{id}', summary: 'Update an account', pathParams: ['id'], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: ['tagIds', 'tagCodes'] },
15
15
  'delete': { method: 'DELETE', path: '/v1/accounts/{id}', summary: 'Delete an account', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
16
16
  'list-notes': { method: 'GET', path: '/v1/accounts/{accountId}/notes', summary: 'Get all notes for an account', pathParams: ['accountId'], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
17
17
  'create-notes': { method: 'POST', path: '/v1/accounts/{accountId}/notes', summary: 'Create a note for an account', pathParams: ['accountId'], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
@@ -34,7 +34,7 @@ export default class Accounts extends Command {
34
34
  id: Args.string({ description: 'Resource ID (for get, update, delete operations)', required: false }),
35
35
  };
36
36
  static flags = {
37
- context: Flags.string({ char: 'c', description: 'Context to use' }),
37
+ context: Flags.string({ char: 'c', aliases: ['config'], env: 'ADERIS_CONTEXT', description: 'Context to use for this command, overriding the current context (alias: --config)' }),
38
38
  output: Flags.string({ char: 'o', description: 'Output format (default: table for import, json for other commands)', options: ['json', 'table', 'csv'] }),
39
39
  table: Flags.boolean({ char: 't', description: 'Output as table (shortcut for --output table)' }),
40
40
  csv: Flags.boolean({ description: 'Output as CSV (shortcut for --output csv)' }),
@@ -46,7 +46,7 @@ export default class Accounts extends Command {
46
46
  limit: Flags.string({ description: 'Items per page' }),
47
47
  include: Flags.string({ description: 'Relations to include' }),
48
48
  search: Flags.string({ description: 'Search term' }),
49
- 'sort-by': Flags.string({ description: 'Sort field' }),
49
+ 'sort-by': Flags.string({ description: 'Sort field(s), comma-separated. Direction (:ASC/:DESC) is optional; date-like fields default to DESC, others to ASC.' }),
50
50
  filter: Flags.string({ description: 'Filter (e.g. --filter status=ACTIVE). Operators: in:A,B, like:%, gt:, lt:, null:', multiple: true }),
51
51
  query: Flags.string({ description: 'Additional query params as JSON' }),
52
52
  fields: Flags.string({ description: 'Comma-separated list of fields to show (e.g. --fields=id,name,status)' }),
@@ -107,9 +107,9 @@ export default class Accounts extends Command {
107
107
  }
108
108
  const context = flags.context ? getContext(flags.context) : getCurrentContext();
109
109
  if (!context)
110
- this.error('No context configured. Run: aderis auth login --new');
111
- if (!context.tokens)
112
- this.error('Not logged in. Run: aderis auth login');
110
+ this.error(flags.context ? `Context "${flags.context}" not found. List contexts with: aderis config list` : 'No context configured. Run: aderis auth login --new');
111
+ if (!hasCredentials(context))
112
+ this.error(missingCredentialsMessage(context));
113
113
  const queryParams = {};
114
114
  if (flags.page)
115
115
  queryParams.page = flags.page;
@@ -120,7 +120,7 @@ export default class Accounts extends Command {
120
120
  if (flags.search)
121
121
  queryParams.search = flags.search;
122
122
  if (flags['sort-by'])
123
- queryParams.sortBy = flags['sort-by'];
123
+ queryParams.sortBy = normalizeSortBy(flags['sort-by']);
124
124
  if (flags.query) {
125
125
  try {
126
126
  Object.assign(queryParams, JSON.parse(flags.query));
@@ -352,9 +352,9 @@ export default class Accounts extends Command {
352
352
  async runImport(flags) {
353
353
  const context = flags.context ? getContext(flags.context) : getCurrentContext();
354
354
  if (!context)
355
- this.error('No context configured. Run: aderis auth login --new');
356
- if (!context.tokens)
357
- this.error('Not logged in. Run: aderis auth login');
355
+ this.error(flags.context ? `Context "${flags.context}" not found. List contexts with: aderis config list` : 'No context configured. Run: aderis auth login --new');
356
+ if (!hasCredentials(context))
357
+ this.error(missingCredentialsMessage(context));
358
358
  // Get data from file, --data, or --set flags
359
359
  let items = [];
360
360
  if (flags.file) {
@@ -564,9 +564,9 @@ export default class Accounts extends Command {
564
564
  async runExport(flags) {
565
565
  const context = flags.context ? getContext(flags.context) : getCurrentContext();
566
566
  if (!context)
567
- this.error('No context configured. Run: aderis auth login --new');
568
- if (!context.tokens)
569
- this.error('Not logged in. Run: aderis auth login');
567
+ this.error(flags.context ? `Context "${flags.context}" not found. List contexts with: aderis config list` : 'No context configured. Run: aderis auth login --new');
568
+ if (!hasCredentials(context))
569
+ this.error(missingCredentialsMessage(context));
570
570
  const listEndpoint = ENDPOINTS['list'];
571
571
  if (!listEndpoint)
572
572
  this.error('Export requires a list endpoint');
@@ -579,7 +579,7 @@ export default class Accounts extends Command {
579
579
  if (flags.search)
580
580
  baseParams.search = flags.search;
581
581
  if (flags['sort-by'])
582
- baseParams.sortBy = flags['sort-by'];
582
+ baseParams.sortBy = normalizeSortBy(flags['sort-by']);
583
583
  if (flags.include)
584
584
  baseParams.include = flags.include;
585
585
  if (flags.query) {
@@ -658,9 +658,9 @@ export default class Accounts extends Command {
658
658
  async runCamt053Import(flags) {
659
659
  const context = flags.context ? getContext(flags.context) : getCurrentContext();
660
660
  if (!context)
661
- this.error('No context configured. Run: aderis auth login --new');
662
- if (!context.tokens)
663
- this.error('Not logged in. Run: aderis auth login');
661
+ this.error(flags.context ? `Context "${flags.context}" not found. List contexts with: aderis config list` : 'No context configured. Run: aderis auth login --new');
662
+ if (!hasCredentials(context))
663
+ this.error(missingCredentialsMessage(context));
664
664
  if (!flags.file) {
665
665
  this.error('CAMT.053 import requires --file (-f) flag with path to XML file');
666
666
  }
@@ -748,9 +748,9 @@ export default class Accounts extends Command {
748
748
  }
749
749
  const context = flags.context ? getContext(flags.context) : getCurrentContext();
750
750
  if (!context)
751
- this.error('No context configured. Run: aderis auth login --new');
752
- if (!context.tokens)
753
- this.error('Not logged in. Run: aderis auth login');
751
+ this.error(flags.context ? `Context "${flags.context}" not found. List contexts with: aderis config list` : 'No context configured. Run: aderis auth login --new');
752
+ if (!hasCredentials(context))
753
+ this.error(missingCredentialsMessage(context));
754
754
  // Get data from file, --data, or --set flags
755
755
  let items = [];
756
756
  if (flags.file) {
@@ -1,12 +1,12 @@
1
1
  import { Command, Args, Flags } from '@oclif/core';
2
- import { apiRequest, ApiError } from '../lib/api-client.js';
3
- import { getCurrentContext, getContext, getBaseUrls } from '../lib/config.js';
2
+ import { apiRequest, ApiError, normalizeSortBy } from '../lib/api-client.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 = false;
6
6
  const HAS_EXPORT = false;
7
7
  const HAS_CAMT053 = false;
8
8
  const NESTED_IMPORTS = [];
9
- const SUBCOMMANDS = [...["get-runs", "get-runs-runId", "runs-retry", "runs-restart", "runs-discard", "uploads", "uploads-counts", "uploads-files"], ...(HAS_IMPORT ? ['import'] : []), ...(HAS_EXPORT ? ['export'] : []), ...NESTED_IMPORTS.map(n => `import-${n}`)];
9
+ const SUBCOMMANDS = [...["get-runs", "get-runs-runId", "runs-retry", "runs-restart", "runs-discard", "uploads", "uploads-counts", "uploads-files", "usage"], ...(HAS_IMPORT ? ['import'] : []), ...(HAS_EXPORT ? ['export'] : []), ...NESTED_IMPORTS.map(n => `import-${n}`)];
10
10
  const ENDPOINTS = {
11
11
  'get-runs': { method: 'GET', path: '/v1/agent-platform/runs', summary: 'List agent runs (agents-platform pass-through).', pathParams: [], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
12
12
  'get-runs-runId': { method: 'GET', path: '/v1/agent-platform/runs/{runId}', summary: 'Fetch one agent run (agents-platform pass-through).', pathParams: ['runId'], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
@@ -16,6 +16,7 @@ const ENDPOINTS = {
16
16
  'uploads': { method: 'GET', path: '/v1/agent-platform/uploads', summary: 'List uploads (agents-platform pass-through).', pathParams: [], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
17
17
  'uploads-counts': { method: 'GET', path: '/v1/agent-platform/uploads/counts', summary: 'Fetch upload counts (agents-platform pass-through).', pathParams: [], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
18
18
  'uploads-files': { method: 'GET', path: '/v1/agent-platform/uploads/{processingId}/files/{fileId}', summary: 'Fetch one of an upload\'s files (agents-platform pass-through).', pathParams: ['processingId', 'fileId'], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
19
+ 'usage': { method: 'GET', path: '/v1/agent-platform/usage', summary: 'Fetch tenant LLM usage report (agents-platform pass-through).', pathParams: [], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
19
20
  };
20
21
  export default class AgentPlatform extends Command {
21
22
  static description = 'Manage agent platform';
@@ -25,7 +26,7 @@ export default class AgentPlatform extends Command {
25
26
  id: Args.string({ description: 'Resource ID (for get, update, delete operations)', required: false }),
26
27
  };
27
28
  static flags = {
28
- context: Flags.string({ char: 'c', description: 'Context to use' }),
29
+ context: Flags.string({ char: 'c', aliases: ['config'], env: 'ADERIS_CONTEXT', description: 'Context to use for this command, overriding the current context (alias: --config)' }),
29
30
  output: Flags.string({ char: 'o', description: 'Output format (default: table for import, json for other commands)', options: ['json', 'table', 'csv'] }),
30
31
  table: Flags.boolean({ char: 't', description: 'Output as table (shortcut for --output table)' }),
31
32
  csv: Flags.boolean({ description: 'Output as CSV (shortcut for --output csv)' }),
@@ -37,7 +38,7 @@ export default class AgentPlatform extends Command {
37
38
  limit: Flags.string({ description: 'Items per page' }),
38
39
  include: Flags.string({ description: 'Relations to include' }),
39
40
  search: Flags.string({ description: 'Search term' }),
40
- 'sort-by': Flags.string({ description: 'Sort field' }),
41
+ 'sort-by': Flags.string({ description: 'Sort field(s), comma-separated. Direction (:ASC/:DESC) is optional; date-like fields default to DESC, others to ASC.' }),
41
42
  filter: Flags.string({ description: 'Filter (e.g. --filter status=ACTIVE). Operators: in:A,B, like:%, gt:, lt:, null:', multiple: true }),
42
43
  query: Flags.string({ description: 'Additional query params as JSON' }),
43
44
  fields: Flags.string({ description: 'Comma-separated list of fields to show (e.g. --fields=id,name,status)' }),
@@ -98,9 +99,9 @@ export default class AgentPlatform extends Command {
98
99
  }
99
100
  const context = flags.context ? getContext(flags.context) : getCurrentContext();
100
101
  if (!context)
101
- this.error('No context configured. Run: aderis auth login --new');
102
- if (!context.tokens)
103
- this.error('Not logged in. Run: aderis auth login');
102
+ this.error(flags.context ? `Context "${flags.context}" not found. List contexts with: aderis config list` : 'No context configured. Run: aderis auth login --new');
103
+ if (!hasCredentials(context))
104
+ this.error(missingCredentialsMessage(context));
104
105
  const queryParams = {};
105
106
  if (flags.page)
106
107
  queryParams.page = flags.page;
@@ -111,7 +112,7 @@ export default class AgentPlatform extends Command {
111
112
  if (flags.search)
112
113
  queryParams.search = flags.search;
113
114
  if (flags['sort-by'])
114
- queryParams.sortBy = flags['sort-by'];
115
+ queryParams.sortBy = normalizeSortBy(flags['sort-by']);
115
116
  if (flags.query) {
116
117
  try {
117
118
  Object.assign(queryParams, JSON.parse(flags.query));
@@ -343,9 +344,9 @@ export default class AgentPlatform extends Command {
343
344
  async runImport(flags) {
344
345
  const context = flags.context ? getContext(flags.context) : getCurrentContext();
345
346
  if (!context)
346
- this.error('No context configured. Run: aderis auth login --new');
347
- if (!context.tokens)
348
- this.error('Not logged in. Run: aderis auth login');
347
+ this.error(flags.context ? `Context "${flags.context}" not found. List contexts with: aderis config list` : 'No context configured. Run: aderis auth login --new');
348
+ if (!hasCredentials(context))
349
+ this.error(missingCredentialsMessage(context));
349
350
  // Get data from file, --data, or --set flags
350
351
  let items = [];
351
352
  if (flags.file) {
@@ -555,9 +556,9 @@ export default class AgentPlatform extends Command {
555
556
  async runExport(flags) {
556
557
  const context = flags.context ? getContext(flags.context) : getCurrentContext();
557
558
  if (!context)
558
- this.error('No context configured. Run: aderis auth login --new');
559
- if (!context.tokens)
560
- this.error('Not logged in. Run: aderis auth login');
559
+ this.error(flags.context ? `Context "${flags.context}" not found. List contexts with: aderis config list` : 'No context configured. Run: aderis auth login --new');
560
+ if (!hasCredentials(context))
561
+ this.error(missingCredentialsMessage(context));
561
562
  const listEndpoint = ENDPOINTS['list'];
562
563
  if (!listEndpoint)
563
564
  this.error('Export requires a list endpoint');
@@ -570,7 +571,7 @@ export default class AgentPlatform extends Command {
570
571
  if (flags.search)
571
572
  baseParams.search = flags.search;
572
573
  if (flags['sort-by'])
573
- baseParams.sortBy = flags['sort-by'];
574
+ baseParams.sortBy = normalizeSortBy(flags['sort-by']);
574
575
  if (flags.include)
575
576
  baseParams.include = flags.include;
576
577
  if (flags.query) {
@@ -649,9 +650,9 @@ export default class AgentPlatform extends Command {
649
650
  async runCamt053Import(flags) {
650
651
  const context = flags.context ? getContext(flags.context) : getCurrentContext();
651
652
  if (!context)
652
- this.error('No context configured. Run: aderis auth login --new');
653
- if (!context.tokens)
654
- this.error('Not logged in. Run: aderis auth login');
653
+ this.error(flags.context ? `Context "${flags.context}" not found. List contexts with: aderis config list` : 'No context configured. Run: aderis auth login --new');
654
+ if (!hasCredentials(context))
655
+ this.error(missingCredentialsMessage(context));
655
656
  if (!flags.file) {
656
657
  this.error('CAMT.053 import requires --file (-f) flag with path to XML file');
657
658
  }
@@ -739,9 +740,9 @@ export default class AgentPlatform extends Command {
739
740
  }
740
741
  const context = flags.context ? getContext(flags.context) : getCurrentContext();
741
742
  if (!context)
742
- this.error('No context configured. Run: aderis auth login --new');
743
- if (!context.tokens)
744
- this.error('Not logged in. Run: aderis auth login');
743
+ this.error(flags.context ? `Context "${flags.context}" not found. List contexts with: aderis config list` : 'No context configured. Run: aderis auth login --new');
744
+ if (!hasCredentials(context))
745
+ this.error(missingCredentialsMessage(context));
745
746
  // Get data from file, --data, or --set flags
746
747
  let items = [];
747
748
  if (flags.file) {