@aderis-erp/cli 1.0.12 → 1.0.14

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 (73) hide show
  1. package/dist/commands/access-groups.js +4 -4
  2. package/dist/commands/account-transaction-allocations.js +4 -4
  3. package/dist/commands/account-transactions.js +4 -4
  4. package/dist/commands/accounts.js +4 -4
  5. package/dist/commands/{agent-runs.d.ts → agent-platform.d.ts} +2 -2
  6. package/dist/commands/agent-platform.js +1175 -0
  7. package/dist/commands/audit-log.js +7 -7
  8. package/dist/commands/auth/login.js +2 -3
  9. package/dist/commands/bank-accounts.js +4 -4
  10. package/dist/commands/bank-integrations.js +4 -4
  11. package/dist/commands/business-partners.js +6 -6
  12. package/dist/commands/chat.js +12 -8
  13. package/dist/commands/config/add.js +2 -3
  14. package/dist/commands/config/rename.d.ts +10 -0
  15. package/dist/commands/config/rename.js +68 -0
  16. package/dist/commands/credit-card-accounts.js +4 -4
  17. package/dist/commands/delivery-notes.d.ts +43 -0
  18. package/dist/commands/delivery-notes.js +1206 -0
  19. package/dist/commands/documents.js +5 -5
  20. package/dist/commands/dunning-configs.js +4 -4
  21. package/dist/commands/dunning-reminders.js +4 -4
  22. package/dist/commands/dunning-runs.js +4 -4
  23. package/dist/commands/email-transactions.js +4 -4
  24. package/dist/commands/employees.js +4 -4
  25. package/dist/commands/entity-configurations.js +4 -4
  26. package/dist/commands/event-processor-mappings.js +4 -4
  27. package/dist/commands/files-internal.js +4 -4
  28. package/dist/commands/health.js +4 -4
  29. package/dist/commands/inbox.d.ts +1 -0
  30. package/dist/commands/inbox.js +10 -8
  31. package/dist/commands/integrations.js +4 -4
  32. package/dist/commands/item-categories.js +4 -4
  33. package/dist/commands/items.js +4 -4
  34. package/dist/commands/journal-lines.js +4 -4
  35. package/dist/commands/journals.js +7 -5
  36. package/dist/commands/ledgers.js +4 -4
  37. package/dist/commands/office-locations.js +4 -4
  38. package/dist/commands/payment-methods.js +4 -4
  39. package/dist/commands/payment-runs.js +5 -7
  40. package/dist/commands/payment-terms.js +4 -4
  41. package/dist/commands/payments.d.ts +40 -0
  42. package/dist/commands/payments.js +1180 -0
  43. package/dist/commands/price-lists.js +4 -4
  44. package/dist/commands/processor-mappings.js +4 -4
  45. package/dist/commands/processors.js +4 -4
  46. package/dist/commands/purchase-order-types.js +4 -4
  47. package/dist/commands/purchase-orders.js +4 -4
  48. package/dist/commands/reports.js +4 -4
  49. package/dist/commands/salary-types.js +4 -4
  50. package/dist/commands/sales-invoices.js +13 -12
  51. package/dist/commands/sales-orders.js +7 -5
  52. package/dist/commands/saved-views.js +4 -4
  53. package/dist/commands/scheduled-processor-mappings.d.ts +40 -0
  54. package/dist/commands/{agent-runs.js → scheduled-processor-mappings.js} +22 -23
  55. package/dist/commands/schedules.d.ts +40 -0
  56. package/dist/commands/schedules.js +1182 -0
  57. package/dist/commands/tags.js +4 -4
  58. package/dist/commands/tax-codes.js +4 -4
  59. package/dist/commands/tax-matrix.js +4 -4
  60. package/dist/commands/tenants.js +9 -7
  61. package/dist/commands/text-templates.js +4 -4
  62. package/dist/commands/tools.js +4 -4
  63. package/dist/commands/vat-declarations.js +4 -4
  64. package/dist/commands/vendor-invoices.js +8 -8
  65. package/dist/commands/webhooks.js +4 -4
  66. package/dist/commands/workflows.js +4 -4
  67. package/dist/lib/api-client.d.ts +8 -0
  68. package/dist/lib/api-client.js +20 -0
  69. package/dist/lib/auth.js +2 -2
  70. package/dist/lib/config.d.ts +2 -1
  71. package/dist/lib/config.js +20 -5
  72. package/oclif.manifest.json +956 -231
  73. package/package.json +2 -2
@@ -1,5 +1,5 @@
1
1
  import { Command, Args, Flags } from '@oclif/core';
2
- import { apiRequest, ApiError } from '../lib/api-client.js';
2
+ import { apiRequest, ApiError, normalizeSortBy } from '../lib/api-client.js';
3
3
  import { getCurrentContext, getContext, getBaseUrls } from '../lib/config.js';
4
4
  // Add 'import' action if both create and update exist
5
5
  const HAS_IMPORT = true;
@@ -46,7 +46,7 @@ export default class PriceLists 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)' }),
@@ -120,7 +120,7 @@ export default class PriceLists 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));
@@ -579,7 +579,7 @@ export default class PriceLists 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) {
@@ -1,5 +1,5 @@
1
1
  import { Command, Args, Flags } from '@oclif/core';
2
- import { apiRequest, ApiError } from '../lib/api-client.js';
2
+ import { apiRequest, ApiError, normalizeSortBy } from '../lib/api-client.js';
3
3
  import { getCurrentContext, getContext, getBaseUrls } from '../lib/config.js';
4
4
  // Add 'import' action if both create and update exist
5
5
  const HAS_IMPORT = true;
@@ -38,7 +38,7 @@ export default class ProcessorMappings extends Command {
38
38
  limit: Flags.string({ description: 'Items per page' }),
39
39
  include: Flags.string({ description: 'Relations to include' }),
40
40
  search: Flags.string({ description: 'Search term' }),
41
- '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.' }),
42
42
  filter: Flags.string({ description: 'Filter (e.g. --filter status=ACTIVE). Operators: in:A,B, like:%, gt:, lt:, null:', multiple: true }),
43
43
  query: Flags.string({ description: 'Additional query params as JSON' }),
44
44
  fields: Flags.string({ description: 'Comma-separated list of fields to show (e.g. --fields=id,name,status)' }),
@@ -112,7 +112,7 @@ export default class ProcessorMappings extends Command {
112
112
  if (flags.search)
113
113
  queryParams.search = flags.search;
114
114
  if (flags['sort-by'])
115
- queryParams.sortBy = flags['sort-by'];
115
+ queryParams.sortBy = normalizeSortBy(flags['sort-by']);
116
116
  if (flags.query) {
117
117
  try {
118
118
  Object.assign(queryParams, JSON.parse(flags.query));
@@ -571,7 +571,7 @@ export default class ProcessorMappings extends Command {
571
571
  if (flags.search)
572
572
  baseParams.search = flags.search;
573
573
  if (flags['sort-by'])
574
- baseParams.sortBy = flags['sort-by'];
574
+ baseParams.sortBy = normalizeSortBy(flags['sort-by']);
575
575
  if (flags.include)
576
576
  baseParams.include = flags.include;
577
577
  if (flags.query) {
@@ -1,5 +1,5 @@
1
1
  import { Command, Args, Flags } from '@oclif/core';
2
- import { apiRequest, ApiError } from '../lib/api-client.js';
2
+ import { apiRequest, ApiError, normalizeSortBy } from '../lib/api-client.js';
3
3
  import { getCurrentContext, getContext, getBaseUrls } from '../lib/config.js';
4
4
  // Add 'import' action if both create and update exist
5
5
  const HAS_IMPORT = true;
@@ -46,7 +46,7 @@ export default class Processors 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)' }),
@@ -120,7 +120,7 @@ export default class Processors 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));
@@ -579,7 +579,7 @@ export default class Processors 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) {
@@ -1,5 +1,5 @@
1
1
  import { Command, Args, Flags } from '@oclif/core';
2
- import { apiRequest, ApiError } from '../lib/api-client.js';
2
+ import { apiRequest, ApiError, normalizeSortBy } from '../lib/api-client.js';
3
3
  import { getCurrentContext, getContext, getBaseUrls } from '../lib/config.js';
4
4
  // Add 'import' action if both create and update exist
5
5
  const HAS_IMPORT = true;
@@ -40,7 +40,7 @@ export default class PurchaseOrderTypes 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)' }),
@@ -114,7 +114,7 @@ export default class PurchaseOrderTypes 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));
@@ -573,7 +573,7 @@ export default class PurchaseOrderTypes 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) {
@@ -1,5 +1,5 @@
1
1
  import { Command, Args, Flags } from '@oclif/core';
2
- import { apiRequest, ApiError } from '../lib/api-client.js';
2
+ import { apiRequest, ApiError, normalizeSortBy } from '../lib/api-client.js';
3
3
  import { getCurrentContext, getContext, getBaseUrls } from '../lib/config.js';
4
4
  // Add 'import' action if both create and update exist
5
5
  const HAS_IMPORT = true;
@@ -54,7 +54,7 @@ export default class PurchaseOrders extends Command {
54
54
  limit: Flags.string({ description: 'Items per page' }),
55
55
  include: Flags.string({ description: 'Relations to include' }),
56
56
  search: Flags.string({ description: 'Search term' }),
57
- 'sort-by': Flags.string({ description: 'Sort field' }),
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
60
  fields: Flags.string({ description: 'Comma-separated list of fields to show (e.g. --fields=id,name,status)' }),
@@ -128,7 +128,7 @@ export default class PurchaseOrders extends Command {
128
128
  if (flags.search)
129
129
  queryParams.search = flags.search;
130
130
  if (flags['sort-by'])
131
- queryParams.sortBy = flags['sort-by'];
131
+ queryParams.sortBy = normalizeSortBy(flags['sort-by']);
132
132
  if (flags.query) {
133
133
  try {
134
134
  Object.assign(queryParams, JSON.parse(flags.query));
@@ -587,7 +587,7 @@ export default class PurchaseOrders extends Command {
587
587
  if (flags.search)
588
588
  baseParams.search = flags.search;
589
589
  if (flags['sort-by'])
590
- baseParams.sortBy = flags['sort-by'];
590
+ baseParams.sortBy = normalizeSortBy(flags['sort-by']);
591
591
  if (flags.include)
592
592
  baseParams.include = flags.include;
593
593
  if (flags.query) {
@@ -1,5 +1,5 @@
1
1
  import { Command, Args, Flags } from '@oclif/core';
2
- import { apiRequest, ApiError } from '../lib/api-client.js';
2
+ import { apiRequest, ApiError, normalizeSortBy } from '../lib/api-client.js';
3
3
  import { getCurrentContext, getContext, getBaseUrls } from '../lib/config.js';
4
4
  // Add 'import' action if both create and update exist
5
5
  const HAS_IMPORT = false;
@@ -33,7 +33,7 @@ export default class Reports extends Command {
33
33
  limit: Flags.string({ description: 'Items per page' }),
34
34
  include: Flags.string({ description: 'Relations to include' }),
35
35
  search: Flags.string({ description: 'Search term' }),
36
- 'sort-by': Flags.string({ description: 'Sort field' }),
36
+ 'sort-by': Flags.string({ description: 'Sort field(s), comma-separated. Direction (:ASC/:DESC) is optional; date-like fields default to DESC, others to ASC.' }),
37
37
  filter: Flags.string({ description: 'Filter (e.g. --filter status=ACTIVE). Operators: in:A,B, like:%, gt:, lt:, null:', multiple: true }),
38
38
  query: Flags.string({ description: 'Additional query params as JSON' }),
39
39
  fields: Flags.string({ description: 'Comma-separated list of fields to show (e.g. --fields=id,name,status)' }),
@@ -107,7 +107,7 @@ export default class Reports extends Command {
107
107
  if (flags.search)
108
108
  queryParams.search = flags.search;
109
109
  if (flags['sort-by'])
110
- queryParams.sortBy = flags['sort-by'];
110
+ queryParams.sortBy = normalizeSortBy(flags['sort-by']);
111
111
  if (flags.query) {
112
112
  try {
113
113
  Object.assign(queryParams, JSON.parse(flags.query));
@@ -566,7 +566,7 @@ export default class Reports extends Command {
566
566
  if (flags.search)
567
567
  baseParams.search = flags.search;
568
568
  if (flags['sort-by'])
569
- baseParams.sortBy = flags['sort-by'];
569
+ baseParams.sortBy = normalizeSortBy(flags['sort-by']);
570
570
  if (flags.include)
571
571
  baseParams.include = flags.include;
572
572
  if (flags.query) {
@@ -1,5 +1,5 @@
1
1
  import { Command, Args, Flags } from '@oclif/core';
2
- import { apiRequest, ApiError } from '../lib/api-client.js';
2
+ import { apiRequest, ApiError, normalizeSortBy } from '../lib/api-client.js';
3
3
  import { getCurrentContext, getContext, getBaseUrls } from '../lib/config.js';
4
4
  // Add 'import' action if both create and update exist
5
5
  const HAS_IMPORT = true;
@@ -40,7 +40,7 @@ export default class SalaryTypes 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)' }),
@@ -114,7 +114,7 @@ export default class SalaryTypes 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));
@@ -573,7 +573,7 @@ export default class SalaryTypes 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) {
@@ -1,33 +1,34 @@
1
1
  import { Command, Args, Flags } from '@oclif/core';
2
- import { apiRequest, ApiError } from '../lib/api-client.js';
2
+ import { apiRequest, ApiError, normalizeSortBy } from '../lib/api-client.js';
3
3
  import { getCurrentContext, getContext, getBaseUrls } 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;
7
7
  const HAS_CAMT053 = false;
8
8
  const NESTED_IMPORTS = ["line-items", "notes", "files"];
9
- const SUBCOMMANDS = [...["list", "create", "create-migrated-invoice", "pdf", "get", "update", "delete", "approve", "match-sales-orders", "validate", "request-approval", "send", "send-resend", "cancel", "copy", "replace", "create-line-items", "line-items-from-sales-order", "update-line-items-reorder", "update-line-items", "delete-line-items", "list-notes", "create-notes", "get-notes", "update-notes", "delete-notes", "list-files", "create-files", "get-files", "update-files", "delete-files", "files-download"], ...(HAS_IMPORT ? ['import'] : []), ...(HAS_EXPORT ? ['export'] : []), ...NESTED_IMPORTS.map(n => `import-${n}`)];
9
+ const SUBCOMMANDS = [...["list", "create", "create-migrated-invoice", "pdf", "get", "update", "delete", "approve", "match-sales-orders", "validate", "request-approval", "send", "send-resend", "cancel", "copy", "replace", "merge", "create-line-items", "line-items-from-sales-order", "update-line-items-reorder", "update-line-items", "delete-line-items", "list-notes", "create-notes", "get-notes", "update-notes", "delete-notes", "list-files", "create-files", "get-files", "update-files", "delete-files", "files-download"], ...(HAS_IMPORT ? ['import'] : []), ...(HAS_EXPORT ? ['export'] : []), ...NESTED_IMPORTS.map(n => `import-${n}`)];
10
10
  const ENDPOINTS = {
11
11
  'list': { method: 'GET', path: '/v1/sales-invoices', summary: 'Get all sales invoices with pagination', pathParams: [], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
12
- 'create': { method: 'POST', path: '/v1/sales-invoices', summary: 'Create a new sales invoice', pathParams: [], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: ['lineItems', 'discounts', 'files', 'notes', 'totalAmountByTaxRate', 'tagIds', 'invoiceEmailCc'] },
12
+ 'create': { method: 'POST', path: '/v1/sales-invoices', summary: 'Create a new sales invoice', pathParams: [], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: ['earlyPaymentDiscounts', 'lineItems', 'discounts', 'files', 'notes', 'totalAmountByTaxRate', 'tagIds', 'invoiceEmailCc'] },
13
13
  'create-migrated-invoice': { method: 'POST', path: '/v1/sales-invoices/create-migrated-invoice', summary: 'Create a sales invoice with explicit tax codes on line items (for data migration)', pathParams: [], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: ['lineItems', 'files', 'notes', 'totalAmountByTaxRate', 'tagIds', 'invoiceEmailCc'] },
14
14
  'pdf': { method: 'GET', path: '/v1/sales-invoices/{id}/pdf', summary: 'Generate a PDF preview of a sales invoice', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
15
15
  'get': { method: 'GET', path: '/v1/sales-invoices/{id}', summary: 'Get a sales invoice by ID', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
16
- 'update': { method: 'PATCH', path: '/v1/sales-invoices/{id}', summary: 'Update a sales invoice', pathParams: ['id'], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: ['lineItems', 'discounts', 'files', 'notes', 'totalAmountByTaxRate', 'tagIds', 'invoiceEmailCc', 'removeFileIds'] },
16
+ 'update': { method: 'PATCH', path: '/v1/sales-invoices/{id}', summary: 'Update a sales invoice', pathParams: ['id'], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: ['earlyPaymentDiscounts', 'lineItems', 'discounts', 'files', 'notes', 'totalAmountByTaxRate', 'tagIds', 'invoiceEmailCc', 'removeFileIds'] },
17
17
  'delete': { method: 'DELETE', path: '/v1/sales-invoices/{id}', summary: 'Delete a sales invoice', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
18
- 'approve': { method: 'POST', path: '/v1/sales-invoices/{id}/approve', summary: 'Approve a sales invoice from DRAFT or PENDING_APPROVAL status (generates invoice number and finalizes)', pathParams: ['id'], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: ['lineItems', 'discounts', 'files', 'notes', 'totalAmountByTaxRate', 'tagIds', 'invoiceEmailCc', 'removeFileIds'] },
18
+ 'approve': { method: 'POST', path: '/v1/sales-invoices/{id}/approve', summary: 'Approve a sales invoice from DRAFT or PENDING_APPROVAL status (generates invoice number and finalizes)', pathParams: ['id'], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: ['earlyPaymentDiscounts', 'lineItems', 'discounts', 'files', 'notes', 'totalAmountByTaxRate', 'tagIds', 'invoiceEmailCc', 'removeFileIds'] },
19
19
  'match-sales-orders': { method: 'POST', path: '/v1/sales-invoices/{id}/match-sales-orders', summary: 'Match this invoice\'s lines to sales-order lines', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
20
- 'validate': { method: 'POST', path: '/v1/sales-invoices/{id}/validate', summary: 'Validate a sales invoice update without persisting changes', pathParams: ['id'], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: ['lineItems', 'discounts', 'files', 'notes', 'totalAmountByTaxRate', 'tagIds', 'invoiceEmailCc', 'removeFileIds'] },
20
+ 'validate': { method: 'POST', path: '/v1/sales-invoices/{id}/validate', summary: 'Validate a sales invoice update without persisting changes', pathParams: ['id'], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: ['earlyPaymentDiscounts', 'lineItems', 'discounts', 'files', 'notes', 'totalAmountByTaxRate', 'tagIds', 'invoiceEmailCc', 'removeFileIds'] },
21
21
  'request-approval': { method: 'POST', path: '/v1/sales-invoices/{id}/request-approval', summary: 'Request approval for sales invoice (DRAFT → PENDING_APPROVAL)', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
22
22
  'send': { method: 'POST', path: '/v1/sales-invoices/{id}/send', summary: 'Mark invoice as sent to customer (APPROVED → SENT)', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
23
- 'send-resend': { method: 'POST', path: '/v1/sales-invoices/{id}/resend', summary: 'Resend a sales invoice to the original delivery recipient or an alternative one', pathParams: ['id'], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: ['emailCc'] },
23
+ 'send-resend': { method: 'POST', path: '/v1/sales-invoices/{id}/resend', summary: 'Resend a sales invoice to the original delivery recipient or an alternative one', pathParams: ['id'], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: ['emailCc', 'emailBcc'] },
24
24
  'cancel': { method: 'POST', path: '/v1/sales-invoices/{id}/cancel', summary: 'Cancel a sales invoice', pathParams: ['id'], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
25
25
  'copy': { method: 'POST', path: '/v1/sales-invoices/{id}/copy', summary: 'Create a copy of a cancelled invoice', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
26
26
  'replace': { method: 'POST', path: '/v1/sales-invoices/{id}/replace', summary: 'Replace invoice with corrected version (creates new CORRECTED_INVOICE)', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
27
- 'create-line-items': { method: 'POST', path: '/v1/sales-invoices/{invoiceId}/line-items', summary: 'Add a line item to a sales invoice', pathParams: ['invoiceId'], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: ['discounts', 'salesOrderLineItems'] },
27
+ 'merge': { method: 'POST', path: '/v1/sales-invoices/{id}/merge', summary: 'Merge draft invoices into this master', pathParams: ['id'], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: ['sourceIds'] },
28
+ 'create-line-items': { method: 'POST', path: '/v1/sales-invoices/{invoiceId}/line-items', summary: 'Add a line item to a sales invoice', pathParams: ['invoiceId'], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: ['discounts', 'salesOrderLineItems', 'deliveryNoteLineItems'] },
28
29
  'line-items-from-sales-order': { method: 'POST', path: '/v1/sales-invoices/{invoiceId}/line-items/from-sales-order', summary: 'Add line items to a sales invoice from a sales order', pathParams: ['invoiceId'], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: ['lines'] },
29
30
  'update-line-items-reorder': { method: 'PATCH', path: '/v1/sales-invoices/{invoiceId}/line-items/reorder', summary: 'Bulk reorder line items (drag-and-drop)', pathParams: ['invoiceId'], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: ['items'] },
30
- 'update-line-items': { method: 'PATCH', path: '/v1/sales-invoices/{invoiceId}/line-items/{lineItemId}', summary: 'Update a line item on a sales invoice', pathParams: ['invoiceId', 'lineItemId'], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: ['discounts', 'salesOrderLineItems'] },
31
+ 'update-line-items': { method: 'PATCH', path: '/v1/sales-invoices/{invoiceId}/line-items/{lineItemId}', summary: 'Update a line item on a sales invoice', pathParams: ['invoiceId', 'lineItemId'], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: ['discounts', 'salesOrderLineItems', 'deliveryNoteLineItems'] },
31
32
  'delete-line-items': { method: 'DELETE', path: '/v1/sales-invoices/{invoiceId}/line-items/{lineItemId}', summary: 'Remove a line item from a sales invoice', pathParams: ['invoiceId', 'lineItemId'], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
32
33
  'list-notes': { method: 'GET', path: '/v1/sales-invoices/{salesInvoiceId}/notes', summary: 'Get all notes for a sales invoice', pathParams: ['salesInvoiceId'], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
33
34
  'create-notes': { method: 'POST', path: '/v1/sales-invoices/{salesInvoiceId}/notes', summary: 'Create a note for a sales invoice', pathParams: ['salesInvoiceId'], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
@@ -70,7 +71,7 @@ export default class SalesInvoices extends Command {
70
71
  limit: Flags.string({ description: 'Items per page' }),
71
72
  include: Flags.string({ description: 'Relations to include' }),
72
73
  search: Flags.string({ description: 'Search term' }),
73
- 'sort-by': Flags.string({ description: 'Sort field' }),
74
+ 'sort-by': Flags.string({ description: 'Sort field(s), comma-separated. Direction (:ASC/:DESC) is optional; date-like fields default to DESC, others to ASC.' }),
74
75
  filter: Flags.string({ description: 'Filter (e.g. --filter status=ACTIVE). Operators: in:A,B, like:%, gt:, lt:, null:', multiple: true }),
75
76
  query: Flags.string({ description: 'Additional query params as JSON' }),
76
77
  fields: Flags.string({ description: 'Comma-separated list of fields to show (e.g. --fields=id,name,status)' }),
@@ -144,7 +145,7 @@ export default class SalesInvoices extends Command {
144
145
  if (flags.search)
145
146
  queryParams.search = flags.search;
146
147
  if (flags['sort-by'])
147
- queryParams.sortBy = flags['sort-by'];
148
+ queryParams.sortBy = normalizeSortBy(flags['sort-by']);
148
149
  if (flags.query) {
149
150
  try {
150
151
  Object.assign(queryParams, JSON.parse(flags.query));
@@ -603,7 +604,7 @@ export default class SalesInvoices extends Command {
603
604
  if (flags.search)
604
605
  baseParams.search = flags.search;
605
606
  if (flags['sort-by'])
606
- baseParams.sortBy = flags['sort-by'];
607
+ baseParams.sortBy = normalizeSortBy(flags['sort-by']);
607
608
  if (flags.include)
608
609
  baseParams.include = flags.include;
609
610
  if (flags.query) {
@@ -1,15 +1,16 @@
1
1
  import { Command, Args, Flags } from '@oclif/core';
2
- import { apiRequest, ApiError } from '../lib/api-client.js';
2
+ import { apiRequest, ApiError, normalizeSortBy } from '../lib/api-client.js';
3
3
  import { getCurrentContext, getContext, getBaseUrls } 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;
7
7
  const HAS_CAMT053 = false;
8
8
  const NESTED_IMPORTS = ["line-items", "notes", "files"];
9
- const SUBCOMMANDS = [...["list", "create", "get", "update", "delete", "pdf", "submit", "approve", "accept", "terminate", "cancel", "replace", "create-invoice", "send", "create-line-items", "update-line-items-reorder", "update-line-items", "delete-line-items", "list-notes", "create-notes", "get-notes", "update-notes", "delete-notes", "list-files", "create-files", "get-files", "update-files", "delete-files", "files-download"], ...(HAS_IMPORT ? ['import'] : []), ...(HAS_EXPORT ? ['export'] : []), ...NESTED_IMPORTS.map(n => `import-${n}`)];
9
+ const SUBCOMMANDS = [...["list", "create", "create-invoices", "get", "update", "delete", "pdf", "submit", "approve", "accept", "terminate", "cancel", "replace", "merge", "create-invoice", "send", "create-line-items", "update-line-items-reorder", "update-line-items", "delete-line-items", "list-notes", "create-notes", "get-notes", "update-notes", "delete-notes", "list-files", "create-files", "get-files", "update-files", "delete-files", "files-download"], ...(HAS_IMPORT ? ['import'] : []), ...(HAS_EXPORT ? ['export'] : []), ...NESTED_IMPORTS.map(n => `import-${n}`)];
10
10
  const ENDPOINTS = {
11
11
  'list': { method: 'GET', path: '/v1/sales-orders', summary: 'Get all sales orders with pagination', pathParams: [], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
12
12
  'create': { method: 'POST', path: '/v1/sales-orders', summary: 'Create a new sales order', pathParams: [], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: ['files', 'notes', 'tagIds', 'discounts', 'lineItems'] },
13
+ 'create-invoices': { method: 'POST', path: '/v1/sales-orders/create-invoices', summary: 'Create ONE draft invoice from several sales orders (same customer)', pathParams: [], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: ['salesOrderIds'] },
13
14
  'get': { method: 'GET', path: '/v1/sales-orders/{id}', summary: 'Get a sales order by ID', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
14
15
  'update': { method: 'PATCH', path: '/v1/sales-orders/{id}', summary: 'Update a sales order', pathParams: ['id'], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: ['files', 'notes', 'tagIds', 'discounts', 'lineItems', 'removeFileIds'] },
15
16
  'delete': { method: 'DELETE', path: '/v1/sales-orders/{id}', summary: 'Delete a sales order', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
@@ -20,6 +21,7 @@ const ENDPOINTS = {
20
21
  'terminate': { method: 'POST', path: '/v1/sales-orders/{id}/terminate', summary: 'Terminate order (ACCEPTED → TERMINATED). Requires billingEndDate.', pathParams: ['id'], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
21
22
  'cancel': { method: 'POST', path: '/v1/sales-orders/{id}/cancel', summary: 'Cancel order (any pre-active status → CANCELLED)', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
22
23
  'replace': { method: 'POST', path: '/v1/sales-orders/{id}/replace', summary: 'Replace order with corrected version (APPROVED → creates new DRAFT)', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
24
+ 'merge': { method: 'POST', path: '/v1/sales-orders/{id}/merge', summary: 'Merge draft orders into this master', pathParams: ['id'], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: ['sourceIds'] },
23
25
  'create-invoice': { method: 'POST', path: '/v1/sales-orders/{id}/create-invoice', summary: 'Create invoice from sales order (ACCEPTED → creates DRAFT invoice)', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
24
26
  'send': { method: 'POST', path: '/v1/sales-orders/{id}/send', summary: 'Send a sales order to the customer by email', pathParams: ['id'], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: ['emailCc', 'emailBcc', 'files'] },
25
27
  'create-line-items': { method: 'POST', path: '/v1/sales-orders/{orderId}/line-items', summary: 'Add a line item to a sales order', pathParams: ['orderId'], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: ['discounts'] },
@@ -67,7 +69,7 @@ export default class SalesOrders extends Command {
67
69
  limit: Flags.string({ description: 'Items per page' }),
68
70
  include: Flags.string({ description: 'Relations to include' }),
69
71
  search: Flags.string({ description: 'Search term' }),
70
- 'sort-by': Flags.string({ description: 'Sort field' }),
72
+ 'sort-by': Flags.string({ description: 'Sort field(s), comma-separated. Direction (:ASC/:DESC) is optional; date-like fields default to DESC, others to ASC.' }),
71
73
  filter: Flags.string({ description: 'Filter (e.g. --filter status=ACTIVE). Operators: in:A,B, like:%, gt:, lt:, null:', multiple: true }),
72
74
  query: Flags.string({ description: 'Additional query params as JSON' }),
73
75
  fields: Flags.string({ description: 'Comma-separated list of fields to show (e.g. --fields=id,name,status)' }),
@@ -141,7 +143,7 @@ export default class SalesOrders extends Command {
141
143
  if (flags.search)
142
144
  queryParams.search = flags.search;
143
145
  if (flags['sort-by'])
144
- queryParams.sortBy = flags['sort-by'];
146
+ queryParams.sortBy = normalizeSortBy(flags['sort-by']);
145
147
  if (flags.query) {
146
148
  try {
147
149
  Object.assign(queryParams, JSON.parse(flags.query));
@@ -600,7 +602,7 @@ export default class SalesOrders extends Command {
600
602
  if (flags.search)
601
603
  baseParams.search = flags.search;
602
604
  if (flags['sort-by'])
603
- baseParams.sortBy = flags['sort-by'];
605
+ baseParams.sortBy = normalizeSortBy(flags['sort-by']);
604
606
  if (flags.include)
605
607
  baseParams.include = flags.include;
606
608
  if (flags.query) {
@@ -1,5 +1,5 @@
1
1
  import { Command, Args, Flags } from '@oclif/core';
2
- import { apiRequest, ApiError } from '../lib/api-client.js';
2
+ import { apiRequest, ApiError, normalizeSortBy } from '../lib/api-client.js';
3
3
  import { getCurrentContext, getContext, getBaseUrls } from '../lib/config.js';
4
4
  // Add 'import' action if both create and update exist
5
5
  const HAS_IMPORT = false;
@@ -34,7 +34,7 @@ export default class SavedViews 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)' }),
@@ -108,7 +108,7 @@ export default class SavedViews 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));
@@ -567,7 +567,7 @@ export default class SavedViews 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) {
@@ -0,0 +1,40 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class ScheduledProcessorMappings extends Command {
3
+ static description: string;
4
+ static examples: string[];
5
+ static args: {
6
+ action: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
7
+ id: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
8
+ };
9
+ static flags: {
10
+ context: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
+ output: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
12
+ table: import("@oclif/core/interfaces").BooleanFlag<boolean>;
13
+ csv: import("@oclif/core/interfaces").BooleanFlag<boolean>;
14
+ data: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
15
+ file: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
16
+ set: import("@oclif/core/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/interfaces").CustomOptions>;
17
+ page: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
18
+ limit: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
19
+ include: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
20
+ search: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
21
+ 'sort-by': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
22
+ filter: import("@oclif/core/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/interfaces").CustomOptions>;
23
+ query: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
24
+ fields: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
25
+ sanitize: import("@oclif/core/interfaces").BooleanFlag<boolean>;
26
+ 'show-http-request': import("@oclif/core/interfaces").BooleanFlag<boolean>;
27
+ };
28
+ run(): Promise<void>;
29
+ private runImport;
30
+ private runExport;
31
+ private runCamt053Import;
32
+ private runNestedImport;
33
+ private parseFilterValue;
34
+ private filterFields;
35
+ private sanitizeOutput;
36
+ private getColumns;
37
+ private getValue;
38
+ private printTable;
39
+ private printCsv;
40
+ }
@@ -1,28 +1,28 @@
1
1
  import { Command, Args, Flags } from '@oclif/core';
2
- import { apiRequest, ApiError } from '../lib/api-client.js';
2
+ import { apiRequest, ApiError, normalizeSortBy } from '../lib/api-client.js';
3
3
  import { getCurrentContext, getContext, getBaseUrls } from '../lib/config.js';
4
4
  // Add 'import' action if both create and update exist
5
- const HAS_IMPORT = false;
5
+ const HAS_IMPORT = true;
6
6
  const HAS_EXPORT = true;
7
7
  const HAS_CAMT053 = false;
8
8
  const NESTED_IMPORTS = [];
9
- const SUBCOMMANDS = [...["inbox", "inbox-counts", "inbox-files", "list", "get", "retry", "restart", "discard"], ...(HAS_IMPORT ? ['import'] : []), ...(HAS_EXPORT ? ['export'] : []), ...NESTED_IMPORTS.map(n => `import-${n}`)];
9
+ const SUBCOMMANDS = [...["list", "create", "get", "update", "delete"], ...(HAS_IMPORT ? ['import'] : []), ...(HAS_EXPORT ? ['export'] : []), ...NESTED_IMPORTS.map(n => `import-${n}`)];
10
10
  const ENDPOINTS = {
11
- 'inbox': { method: 'GET', path: '/v1/agent-runs/inbox', summary: 'List uploaded documents with their root pipeline run status', pathParams: [], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
12
- 'inbox-counts': { method: 'GET', path: '/v1/agent-runs/inbox/counts', summary: 'Get per-status upload counts for the inbox status chips', pathParams: [], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
13
- 'inbox-files': { method: 'GET', path: '/v1/agent-runs/inbox/{processingId}/files/{fileId}', summary: 'Get one uploaded file with its file-scoped agent-run tree', pathParams: ['processingId', 'fileId'], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
14
- 'list': { method: 'GET', path: '/v1/agent-runs', summary: 'List agent runs for the current tenant', pathParams: [], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
15
- 'get': { method: 'GET', path: '/v1/agent-runs/{runId}', summary: 'Get an agent-run detail by id', pathParams: ['runId'], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
16
- 'retry': { method: 'POST', path: '/v1/agent-runs/{runId}/retry', summary: 'Retry an agent run from NEEDS_REVIEW with a reviewer instruction', pathParams: ['runId'], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
17
- 'restart': { method: 'POST', path: '/v1/agent-runs/{runId}/restart', summary: 'Restart a FAILED agent run from its existing state', pathParams: ['runId'], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
18
- 'discard': { method: 'POST', path: '/v1/agent-runs/{runId}/discard', summary: 'Discard an agent run with an optional reviewer reason', pathParams: ['runId'], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
11
+ 'list': { method: 'GET', path: '/v1/scheduled-processor-mappings', summary: 'List all scheduled processor mappings for the tenant', pathParams: [], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
12
+ 'create': { method: 'POST', path: '/v1/scheduled-processor-mappings', summary: 'Schedule a processor to run on a cron expression', pathParams: [], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
13
+ 'get': { method: 'GET', path: '/v1/scheduled-processor-mappings/{id}', summary: 'Get a scheduled processor mapping by ID', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
14
+ 'update': { method: 'PATCH', path: '/v1/scheduled-processor-mappings/{id}', summary: 'Update a scheduled processor mapping', pathParams: ['id'], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
15
+ 'delete': { method: 'DELETE', path: '/v1/scheduled-processor-mappings/{id}', summary: 'Delete a scheduled processor mapping and its schedule', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
19
16
  };
20
- export default class AgentRuns extends Command {
21
- static description = 'Manage agent runs';
17
+ export default class ScheduledProcessorMappings extends Command {
18
+ static description = 'Manage scheduled processor mappings';
22
19
  static examples = [
23
- '<%= config.bin %> agent-runs list',
24
- '<%= config.bin %> agent-runs get <id>',
25
- '<%= config.bin %> agent-runs export --csv > agent-runs.csv',
20
+ '<%= config.bin %> scheduled-processor-mappings list',
21
+ '<%= config.bin %> scheduled-processor-mappings get <id>',
22
+ '<%= config.bin %> scheduled-processor-mappings create --data \'{...}\'',
23
+ '<%= config.bin %> scheduled-processor-mappings update <id> --set field=value',
24
+ '<%= config.bin %> scheduled-processor-mappings import --file data.json',
25
+ '<%= config.bin %> scheduled-processor-mappings export --csv > scheduled-processor-mappings.csv',
26
26
  ];
27
27
  static args = {
28
28
  action: Args.string({ description: 'Action: ' + SUBCOMMANDS.join(', '), required: true }),
@@ -36,12 +36,11 @@ export default class AgentRuns extends Command {
36
36
  data: Flags.string({ char: 'd', description: 'JSON data for request body' }),
37
37
  file: Flags.string({ char: 'f', description: 'Read request body from file' }),
38
38
  set: Flags.string({ char: 's', description: 'Set individual field (e.g. --set firstName=John)', multiple: true }),
39
- 'file-id': Flags.string({ description: 'Path param: fileId' }),
40
39
  page: Flags.string({ description: 'Page number' }),
41
40
  limit: Flags.string({ description: 'Items per page' }),
42
41
  include: Flags.string({ description: 'Relations to include' }),
43
42
  search: Flags.string({ description: 'Search term' }),
44
- '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.' }),
45
44
  filter: Flags.string({ description: 'Filter (e.g. --filter status=ACTIVE). Operators: in:A,B, like:%, gt:, lt:, null:', multiple: true }),
46
45
  query: Flags.string({ description: 'Additional query params as JSON' }),
47
46
  fields: Flags.string({ description: 'Comma-separated list of fields to show (e.g. --fields=id,name,status)' }),
@@ -49,7 +48,7 @@ export default class AgentRuns extends Command {
49
48
  'show-http-request': Flags.boolean({ description: 'Show HTTP request details (method, URL, body)' }),
50
49
  };
51
50
  async run() {
52
- const { args, flags } = await this.parse(AgentRuns);
51
+ const { args, flags } = await this.parse(ScheduledProcessorMappings);
53
52
  // Handle import action specially
54
53
  if (args.action === 'import') {
55
54
  if (!HAS_IMPORT)
@@ -90,7 +89,7 @@ export default class AgentRuns extends Command {
90
89
  // First path param always comes from positional argument
91
90
  value = args.id;
92
91
  if (!value)
93
- this.error('Missing required argument: id. Usage: aderis agent-runs <action> <id>');
92
+ this.error('Missing required argument: id. Usage: aderis scheduled-processor-mappings <action> <id>');
94
93
  }
95
94
  else {
96
95
  const flagName = param.replace(/\./g, '-').replace(/([A-Z])/g, '-$1').toLowerCase().replace(/^-/, '');
@@ -115,7 +114,7 @@ export default class AgentRuns extends Command {
115
114
  if (flags.search)
116
115
  queryParams.search = flags.search;
117
116
  if (flags['sort-by'])
118
- queryParams.sortBy = flags['sort-by'];
117
+ queryParams.sortBy = normalizeSortBy(flags['sort-by']);
119
118
  if (flags.query) {
120
119
  try {
121
120
  Object.assign(queryParams, JSON.parse(flags.query));
@@ -574,7 +573,7 @@ export default class AgentRuns extends Command {
574
573
  if (flags.search)
575
574
  baseParams.search = flags.search;
576
575
  if (flags['sort-by'])
577
- baseParams.sortBy = flags['sort-by'];
576
+ baseParams.sortBy = normalizeSortBy(flags['sort-by']);
578
577
  if (flags.include)
579
578
  baseParams.include = flags.include;
580
579
  if (flags.query) {
@@ -739,7 +738,7 @@ export default class AgentRuns extends Command {
739
738
  }
740
739
  async runNestedImport(suffix, parentId, flags) {
741
740
  if (!parentId) {
742
- this.error(`Missing required argument: id. Usage: aderis agent-runs import-${suffix} <parent-id> --file data.json`);
741
+ this.error(`Missing required argument: id. Usage: aderis scheduled-processor-mappings import-${suffix} <parent-id> --file data.json`);
743
742
  }
744
743
  const context = flags.context ? getContext(flags.context) : getCurrentContext();
745
744
  if (!context)