@aderis-erp/cli 1.1.4 → 1.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/access-groups.js +42 -8
- package/dist/commands/account-transaction-allocations.js +38 -4
- package/dist/commands/account-transactions.d.ts +2 -0
- package/dist/commands/account-transactions.js +68 -32
- package/dist/commands/accounts.js +46 -12
- package/dist/commands/agent-platform.js +37 -3
- package/dist/commands/agent-runs.js +49 -15
- package/dist/commands/analytics.js +39 -5
- package/dist/commands/api-clients.js +47 -13
- package/dist/commands/api-keys.js +40 -6
- package/dist/commands/async-jobs.js +45 -11
- package/dist/commands/audit-log.js +38 -4
- package/dist/commands/bank-accounts.js +54 -20
- package/dist/commands/bank-integrations.js +56 -22
- package/dist/commands/business-partners.js +77 -43
- package/dist/commands/chat.js +43 -9
- package/dist/commands/credit-card-accounts.js +57 -23
- package/dist/commands/currencies.js +37 -3
- package/dist/commands/custody-accounts.js +41 -7
- package/dist/commands/dashboards.js +52 -18
- package/dist/commands/delivery-notes.js +69 -35
- package/dist/commands/document-checksums.d.ts +1 -0
- package/dist/commands/document-checksums.js +38 -3
- package/dist/commands/dunning-configs.js +41 -7
- package/dist/commands/dunning-reminders.js +44 -10
- package/dist/commands/dunning-runs.js +37 -3
- package/dist/commands/email-transactions.js +39 -5
- package/dist/commands/employees.js +77 -43
- package/dist/commands/entity-configurations.js +39 -5
- package/dist/commands/event-mapping-rules.js +37 -3
- package/dist/commands/event-processor-mappings.js +41 -7
- package/dist/commands/files.js +48 -14
- package/dist/commands/financial-instrument-transactions.d.ts +56 -0
- package/dist/commands/financial-instrument-transactions.js +1369 -0
- package/dist/commands/financial-instrument-types.js +41 -7
- package/dist/commands/financial-instruments.js +41 -7
- package/dist/commands/health.js +41 -7
- package/dist/commands/imports.js +39 -5
- package/dist/commands/inbox.js +42 -8
- package/dist/commands/integrations.js +39 -5
- package/dist/commands/item-categories.js +41 -7
- package/dist/commands/items.js +42 -8
- package/dist/commands/journal-lines.js +37 -3
- package/dist/commands/journals.js +61 -27
- package/dist/commands/kpis.js +44 -10
- package/dist/commands/ledgers.js +83 -49
- package/dist/commands/my-account.js +54 -20
- package/dist/commands/notifications.js +37 -3
- package/dist/commands/office-locations.js +41 -7
- package/dist/commands/payment-methods.js +46 -12
- package/dist/commands/payment-runs.js +54 -20
- package/dist/commands/payment-terms.js +42 -8
- package/dist/commands/payments.js +43 -9
- package/dist/commands/payroll-runs.js +71 -37
- package/dist/commands/permissions.js +37 -3
- package/dist/commands/price-lists.js +48 -14
- package/dist/commands/processor-mappings.js +40 -6
- package/dist/commands/processors.js +46 -12
- package/dist/commands/purchase-order-types.js +41 -7
- package/dist/commands/purchase-orders.js +60 -26
- package/dist/commands/reports.js +43 -8
- package/dist/commands/roles.js +40 -6
- package/dist/commands/salary-types.js +41 -7
- package/dist/commands/sales-invoices.js +85 -51
- package/dist/commands/sales-orders.js +69 -35
- package/dist/commands/saved-views.js +39 -5
- package/dist/commands/scheduled-processor-mappings.js +41 -7
- package/dist/commands/schedules.js +45 -11
- package/dist/commands/settings.js +38 -4
- package/dist/commands/tags.js +42 -8
- package/dist/commands/tax-codes.js +44 -10
- package/dist/commands/tax-matrix.js +41 -7
- package/dist/commands/templates.js +49 -15
- package/dist/commands/tenants.js +44 -10
- package/dist/commands/tools.js +38 -4
- package/dist/commands/users.js +58 -24
- package/dist/commands/vat-declarations.js +61 -27
- package/dist/commands/vendor-invoices.js +81 -47
- package/dist/commands/webhooks.js +43 -9
- package/dist/commands/work-summary.js +37 -3
- package/dist/lib/paths.d.ts +8 -0
- package/dist/lib/paths.js +16 -0
- package/dist/lib/production-guard.js +2 -0
- package/oclif.manifest.json +199 -2
- package/package.json +9 -3
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Command, Args, Flags } from '@oclif/core';
|
|
2
2
|
import { apiRequest, ApiError, isTextualMediaType, normalizeSortBy } from '../lib/api-client.js';
|
|
3
3
|
import { getCurrentContext, getContext, getBaseUrls, hasCredentials, missingCredentialsMessage } from '../lib/config.js';
|
|
4
|
+
import { resolveUserPath } from '../lib/paths.js';
|
|
4
5
|
// 'upsert' loops create/update from the CLI, one request per record. It exists
|
|
5
6
|
// only where the API has no import endpoint of its own; those keep the name
|
|
6
7
|
// 'import' and are listed in SERVER_IMPORTS.
|
|
@@ -11,47 +12,47 @@ const SERVER_IMPORTS = [];
|
|
|
11
12
|
const NESTED_UPSERTS = ["notes", "files", "contacts", "contacts-notes", "beneficiary-accounts"];
|
|
12
13
|
const SUBCOMMANDS = [...["list", "create", "match-candidates", "get", "update", "delete", "merge", "activate", "get-favicon", "update-favicon", "trigger-favicon-backfill", "list-notes", "create-notes", "get-notes", "update-notes", "delete-notes", "list-files", "create-files", "get-files", "update-files", "delete-files", "files-download", "list-contacts", "create-contacts", "get-contacts", "update-contacts", "delete-contacts", "list-contacts-notes", "create-contacts-notes", "get-contacts-notes", "update-contacts-notes", "delete-contacts-notes", "list-beneficiary-accounts", "create-beneficiary-accounts", "get-beneficiary-accounts", "update-beneficiary-accounts", "delete-beneficiary-accounts", "beneficiary-accounts-approve", "beneficiary-accounts-retire", "beneficiary-accounts-reactivate", "beneficiary-accounts-default"], ...(HAS_UPSERT ? ['upsert'] : []), ...(HAS_EXPORT ? ['export'] : []), ...NESTED_UPSERTS.map(n => `upsert-${n}`)];
|
|
13
14
|
const ENDPOINTS = {
|
|
14
|
-
'list': { method: 'GET', path: '/v1/business-partners', summary: 'Get all business partners with pagination', pathParams: [], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
15
|
-
'create': { method: 'POST', path: '/v1/business-partners', summary: 'Create a new business partner', pathParams: [], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: ['salesOrderRecipientCc', 'salesOrderRecipientBcc', 'salesInvoiceRecipientCc', 'salesInvoiceRecipientBcc', 'deliveryNoteRecipientCc', 'deliveryNoteRecipientBcc', 'dunningRecipientCc', 'dunningRecipientBcc', 'contacts', 'tagIds', 'tagCodes', 'salesEarlyPaymentDiscounts', 'purchaseEarlyPaymentDiscounts', 'notes'] },
|
|
16
|
-
'match-candidates': { method: 'GET', path: '/v1/business-partners/match-candidates', summary: 'Rank the business partners whose names resemble a bank counterparty text', pathParams: [], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
17
|
-
'get': { method: 'GET', path: '/v1/business-partners/{id}', summary: 'Get a business partner by ID', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
18
|
-
'update': { method: 'PATCH', path: '/v1/business-partners/{id}', summary: 'Update a business partner', pathParams: ['id'], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: ['salesOrderRecipientCc', 'salesOrderRecipientBcc', 'salesInvoiceRecipientCc', 'salesInvoiceRecipientBcc', 'deliveryNoteRecipientCc', 'deliveryNoteRecipientBcc', 'dunningRecipientCc', 'dunningRecipientBcc', 'contacts', 'tagIds', 'tagCodes', 'salesEarlyPaymentDiscounts', 'purchaseEarlyPaymentDiscounts', 'notes'] },
|
|
19
|
-
'delete': { method: 'DELETE', path: '/v1/business-partners/{id}', summary: 'Delete a business partner', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
20
|
-
'merge': { method: 'POST', path: '/v1/business-partners/{id}/merge', summary: 'Merge a business partner into another', pathParams: ['id'], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
21
|
-
'activate': { method: 'POST', path: '/v1/business-partners/{id}/activate', summary: 'Activate a business partner', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
22
|
-
'get-favicon': { method: 'GET', path: '/v1/business-partners/{id}/favicon', summary: 'Download a business partner\'s stored favicon', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: true, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
23
|
-
'update-favicon': { method: 'PUT', path: '/v1/business-partners/{id}/favicon', summary: 'Manually upload a business partner\'s favicon', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
24
|
-
'trigger-favicon-backfill': { method: 'POST', path: '/v1/business-partners/favicon-backfill', summary: 'Fetch favicons for every business partner in this tenant that has none yet', pathParams: [], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
25
|
-
'list-notes': { method: 'GET', path: '/v1/business-partners/{businessPartnerId}/notes', summary: 'Get all notes for a business partner', pathParams: ['businessPartnerId'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
26
|
-
'create-notes': { method: 'POST', path: '/v1/business-partners/{businessPartnerId}/notes', summary: 'Create a note for a business partner', pathParams: ['businessPartnerId'], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
27
|
-
'get-notes': { method: 'GET', path: '/v1/business-partners/{businessPartnerId}/notes/{noteId}', summary: 'Get a specific note for a business partner', pathParams: ['businessPartnerId', 'noteId'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
28
|
-
'update-notes': { method: 'PATCH', path: '/v1/business-partners/{businessPartnerId}/notes/{noteId}', summary: 'Update a note for a business partner', pathParams: ['businessPartnerId', 'noteId'], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
29
|
-
'delete-notes': { method: 'DELETE', path: '/v1/business-partners/{businessPartnerId}/notes/{noteId}', summary: 'Delete a note from a business partner', pathParams: ['businessPartnerId', 'noteId'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
30
|
-
'list-files': { method: 'GET', path: '/v1/business-partners/{parentId}/files', summary: 'List file attachments for a business partner', pathParams: ['parentId'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
31
|
-
'create-files': { method: 'POST', path: '/v1/business-partners/{parentId}/files', summary: 'Upload a file attachment to a business partner', pathParams: ['parentId'], hasBody: false, isMultipart: true, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
32
|
-
'get-files': { method: 'GET', path: '/v1/business-partners/{parentId}/files/{fileId}', summary: 'Get a file attachment for a business partner', pathParams: ['parentId', 'fileId'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
33
|
-
'update-files': { method: 'PATCH', path: '/v1/business-partners/{parentId}/files/{fileId}', summary: 'Update file attachment metadata for a business partner', pathParams: ['parentId', 'fileId'], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
34
|
-
'delete-files': { method: 'DELETE', path: '/v1/business-partners/{parentId}/files/{fileId}', summary: 'Delete a file attachment from a business partner', pathParams: ['parentId', 'fileId'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
35
|
-
'files-download': { method: 'GET', path: '/v1/business-partners/{parentId}/files/{fileId}/download', summary: 'Download a file attachment from a business partner', pathParams: ['parentId', 'fileId'], hasBody: false, isMultipart: false, isBinaryResponse: true, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
36
|
-
'list-contacts': { method: 'GET', path: '/v1/business-partners/{businessPartnerId}/contacts', summary: 'Get all contacts for a business partner with pagination', pathParams: ['businessPartnerId'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
37
|
-
'create-contacts': { method: 'POST', path: '/v1/business-partners/{businessPartnerId}/contacts', summary: 'Create a new contact for a business partner', pathParams: ['businessPartnerId'], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: ['tagIds', 'tagCodes', 'notes'] },
|
|
38
|
-
'get-contacts': { method: 'GET', path: '/v1/business-partners/{businessPartnerId}/contacts/{id}', summary: 'Get a contact by ID', pathParams: ['id', 'businessPartnerId'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
39
|
-
'update-contacts': { method: 'PATCH', path: '/v1/business-partners/{businessPartnerId}/contacts/{id}', summary: 'Update a contact', pathParams: ['id', 'businessPartnerId'], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: ['tagIds', 'tagCodes', 'notes'] },
|
|
40
|
-
'delete-contacts': { method: 'DELETE', path: '/v1/business-partners/{businessPartnerId}/contacts/{id}', summary: 'Delete a contact', pathParams: ['id', 'businessPartnerId'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
41
|
-
'list-contacts-notes': { method: 'GET', path: '/v1/business-partners/contacts/{contactId}/notes', summary: 'Get all notes for a contact', pathParams: ['contactId'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
42
|
-
'create-contacts-notes': { method: 'POST', path: '/v1/business-partners/contacts/{contactId}/notes', summary: 'Create a note for a contact', pathParams: ['contactId'], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
43
|
-
'get-contacts-notes': { method: 'GET', path: '/v1/business-partners/contacts/{contactId}/notes/{noteId}', summary: 'Get a specific note for a contact', pathParams: ['contactId', 'noteId'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
44
|
-
'update-contacts-notes': { method: 'PATCH', path: '/v1/business-partners/contacts/{contactId}/notes/{noteId}', summary: 'Update a note for a contact', pathParams: ['contactId', 'noteId'], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
45
|
-
'delete-contacts-notes': { method: 'DELETE', path: '/v1/business-partners/contacts/{contactId}/notes/{noteId}', summary: 'Delete a note from a contact', pathParams: ['contactId', 'noteId'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
46
|
-
'list-beneficiary-accounts': { method: 'GET', path: '/v1/business-partners/{businessPartnerId}/beneficiary-accounts', summary: 'List the beneficiary bank accounts of a business partner', pathParams: ['businessPartnerId'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
47
|
-
'create-beneficiary-accounts': { method: 'POST', path: '/v1/business-partners/{businessPartnerId}/beneficiary-accounts', summary: 'Store a new beneficiary bank account (status NEW)', pathParams: ['businessPartnerId'], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
48
|
-
'get-beneficiary-accounts': { method: 'GET', path: '/v1/business-partners/{businessPartnerId}/beneficiary-accounts/{id}', summary: 'Get one beneficiary bank account of a business partner', pathParams: ['businessPartnerId', 'id'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
49
|
-
'update-beneficiary-accounts': { method: 'PATCH', path: '/v1/business-partners/{businessPartnerId}/beneficiary-accounts/{id}', summary: 'Edit a beneficiary bank account', pathParams: ['businessPartnerId', 'id'], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
50
|
-
'delete-beneficiary-accounts': { method: 'DELETE', path: '/v1/business-partners/{businessPartnerId}/beneficiary-accounts/{id}', summary: 'Delete a beneficiary bank account', pathParams: ['businessPartnerId', 'id'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
51
|
-
'beneficiary-accounts-approve': { method: 'POST', path: '/v1/business-partners/{businessPartnerId}/beneficiary-accounts/{id}/approve', summary: 'Approve a beneficiary bank account', pathParams: ['businessPartnerId', 'id'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
52
|
-
'beneficiary-accounts-retire': { method: 'POST', path: '/v1/business-partners/{businessPartnerId}/beneficiary-accounts/{id}/retire', summary: 'Retire a beneficiary bank account; clears its default flag', pathParams: ['businessPartnerId', 'id'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
53
|
-
'beneficiary-accounts-reactivate': { method: 'POST', path: '/v1/business-partners/{businessPartnerId}/beneficiary-accounts/{id}/reactivate', summary: 'Reactivate a retired account: NEW again, both approvals cleared', pathParams: ['businessPartnerId', 'id'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
54
|
-
'beneficiary-accounts-default': { method: 'POST', path: '/v1/business-partners/{businessPartnerId}/beneficiary-accounts/{id}/default', summary: 'Make this account the partner default; the previous one is unset', pathParams: ['businessPartnerId', 'id'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
15
|
+
'list': { method: 'GET', path: '/v1/business-partners', summary: 'Get all business partners with pagination', pathParams: [], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
16
|
+
'create': { method: 'POST', path: '/v1/business-partners', summary: 'Create a new business partner', pathParams: [], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: ['salesOrderRecipientCc', 'salesOrderRecipientBcc', 'salesInvoiceRecipientCc', 'salesInvoiceRecipientBcc', 'deliveryNoteRecipientCc', 'deliveryNoteRecipientBcc', 'dunningRecipientCc', 'dunningRecipientBcc', 'contacts', 'tagIds', 'tagCodes', 'salesEarlyPaymentDiscounts', 'purchaseEarlyPaymentDiscounts', 'notes'], bodyMediaType: '', specParams: [] },
|
|
17
|
+
'match-candidates': { method: 'GET', path: '/v1/business-partners/match-candidates', summary: 'Rank the business partners whose names resemble a bank counterparty text', pathParams: [], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
18
|
+
'get': { method: 'GET', path: '/v1/business-partners/{id}', summary: 'Get a business partner by ID', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
19
|
+
'update': { method: 'PATCH', path: '/v1/business-partners/{id}', summary: 'Update a business partner', pathParams: ['id'], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: ['salesOrderRecipientCc', 'salesOrderRecipientBcc', 'salesInvoiceRecipientCc', 'salesInvoiceRecipientBcc', 'deliveryNoteRecipientCc', 'deliveryNoteRecipientBcc', 'dunningRecipientCc', 'dunningRecipientBcc', 'contacts', 'tagIds', 'tagCodes', 'salesEarlyPaymentDiscounts', 'purchaseEarlyPaymentDiscounts', 'notes'], bodyMediaType: '', specParams: [] },
|
|
20
|
+
'delete': { method: 'DELETE', path: '/v1/business-partners/{id}', summary: 'Delete a business partner', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
21
|
+
'merge': { method: 'POST', path: '/v1/business-partners/{id}/merge', summary: 'Merge a business partner into another', pathParams: ['id'], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
22
|
+
'activate': { method: 'POST', path: '/v1/business-partners/{id}/activate', summary: 'Activate a business partner', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
23
|
+
'get-favicon': { method: 'GET', path: '/v1/business-partners/{id}/favicon', summary: 'Download a business partner\'s stored favicon', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: true, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
24
|
+
'update-favicon': { method: 'PUT', path: '/v1/business-partners/{id}/favicon', summary: 'Manually upload a business partner\'s favicon', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
25
|
+
'trigger-favicon-backfill': { method: 'POST', path: '/v1/business-partners/favicon-backfill', summary: 'Fetch favicons for every business partner in this tenant that has none yet', pathParams: [], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
26
|
+
'list-notes': { method: 'GET', path: '/v1/business-partners/{businessPartnerId}/notes', summary: 'Get all notes for a business partner', pathParams: ['businessPartnerId'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
27
|
+
'create-notes': { method: 'POST', path: '/v1/business-partners/{businessPartnerId}/notes', summary: 'Create a note for a business partner', pathParams: ['businessPartnerId'], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
28
|
+
'get-notes': { method: 'GET', path: '/v1/business-partners/{businessPartnerId}/notes/{noteId}', summary: 'Get a specific note for a business partner', pathParams: ['businessPartnerId', 'noteId'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
29
|
+
'update-notes': { method: 'PATCH', path: '/v1/business-partners/{businessPartnerId}/notes/{noteId}', summary: 'Update a note for a business partner', pathParams: ['businessPartnerId', 'noteId'], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
30
|
+
'delete-notes': { method: 'DELETE', path: '/v1/business-partners/{businessPartnerId}/notes/{noteId}', summary: 'Delete a note from a business partner', pathParams: ['businessPartnerId', 'noteId'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
31
|
+
'list-files': { method: 'GET', path: '/v1/business-partners/{parentId}/files', summary: 'List file attachments for a business partner', pathParams: ['parentId'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
32
|
+
'create-files': { method: 'POST', path: '/v1/business-partners/{parentId}/files', summary: 'Upload a file attachment to a business partner', pathParams: ['parentId'], hasBody: false, isMultipart: true, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
33
|
+
'get-files': { method: 'GET', path: '/v1/business-partners/{parentId}/files/{fileId}', summary: 'Get a file attachment for a business partner', pathParams: ['parentId', 'fileId'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
34
|
+
'update-files': { method: 'PATCH', path: '/v1/business-partners/{parentId}/files/{fileId}', summary: 'Update file attachment metadata for a business partner', pathParams: ['parentId', 'fileId'], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
35
|
+
'delete-files': { method: 'DELETE', path: '/v1/business-partners/{parentId}/files/{fileId}', summary: 'Delete a file attachment from a business partner', pathParams: ['parentId', 'fileId'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
36
|
+
'files-download': { method: 'GET', path: '/v1/business-partners/{parentId}/files/{fileId}/download', summary: 'Download a file attachment from a business partner', pathParams: ['parentId', 'fileId'], hasBody: false, isMultipart: false, isBinaryResponse: true, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
37
|
+
'list-contacts': { method: 'GET', path: '/v1/business-partners/{businessPartnerId}/contacts', summary: 'Get all contacts for a business partner with pagination', pathParams: ['businessPartnerId'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
38
|
+
'create-contacts': { method: 'POST', path: '/v1/business-partners/{businessPartnerId}/contacts', summary: 'Create a new contact for a business partner', pathParams: ['businessPartnerId'], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: ['tagIds', 'tagCodes', 'notes'], bodyMediaType: '', specParams: [] },
|
|
39
|
+
'get-contacts': { method: 'GET', path: '/v1/business-partners/{businessPartnerId}/contacts/{id}', summary: 'Get a contact by ID', pathParams: ['id', 'businessPartnerId'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
40
|
+
'update-contacts': { method: 'PATCH', path: '/v1/business-partners/{businessPartnerId}/contacts/{id}', summary: 'Update a contact', pathParams: ['id', 'businessPartnerId'], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: ['tagIds', 'tagCodes', 'notes'], bodyMediaType: '', specParams: [] },
|
|
41
|
+
'delete-contacts': { method: 'DELETE', path: '/v1/business-partners/{businessPartnerId}/contacts/{id}', summary: 'Delete a contact', pathParams: ['id', 'businessPartnerId'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
42
|
+
'list-contacts-notes': { method: 'GET', path: '/v1/business-partners/contacts/{contactId}/notes', summary: 'Get all notes for a contact', pathParams: ['contactId'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
43
|
+
'create-contacts-notes': { method: 'POST', path: '/v1/business-partners/contacts/{contactId}/notes', summary: 'Create a note for a contact', pathParams: ['contactId'], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
44
|
+
'get-contacts-notes': { method: 'GET', path: '/v1/business-partners/contacts/{contactId}/notes/{noteId}', summary: 'Get a specific note for a contact', pathParams: ['contactId', 'noteId'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
45
|
+
'update-contacts-notes': { method: 'PATCH', path: '/v1/business-partners/contacts/{contactId}/notes/{noteId}', summary: 'Update a note for a contact', pathParams: ['contactId', 'noteId'], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
46
|
+
'delete-contacts-notes': { method: 'DELETE', path: '/v1/business-partners/contacts/{contactId}/notes/{noteId}', summary: 'Delete a note from a contact', pathParams: ['contactId', 'noteId'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
47
|
+
'list-beneficiary-accounts': { method: 'GET', path: '/v1/business-partners/{businessPartnerId}/beneficiary-accounts', summary: 'List the beneficiary bank accounts of a business partner', pathParams: ['businessPartnerId'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
48
|
+
'create-beneficiary-accounts': { method: 'POST', path: '/v1/business-partners/{businessPartnerId}/beneficiary-accounts', summary: 'Store a new beneficiary bank account (status NEW)', pathParams: ['businessPartnerId'], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
49
|
+
'get-beneficiary-accounts': { method: 'GET', path: '/v1/business-partners/{businessPartnerId}/beneficiary-accounts/{id}', summary: 'Get one beneficiary bank account of a business partner', pathParams: ['businessPartnerId', 'id'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
50
|
+
'update-beneficiary-accounts': { method: 'PATCH', path: '/v1/business-partners/{businessPartnerId}/beneficiary-accounts/{id}', summary: 'Edit a beneficiary bank account', pathParams: ['businessPartnerId', 'id'], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
51
|
+
'delete-beneficiary-accounts': { method: 'DELETE', path: '/v1/business-partners/{businessPartnerId}/beneficiary-accounts/{id}', summary: 'Delete a beneficiary bank account', pathParams: ['businessPartnerId', 'id'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
52
|
+
'beneficiary-accounts-approve': { method: 'POST', path: '/v1/business-partners/{businessPartnerId}/beneficiary-accounts/{id}/approve', summary: 'Approve a beneficiary bank account', pathParams: ['businessPartnerId', 'id'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
53
|
+
'beneficiary-accounts-retire': { method: 'POST', path: '/v1/business-partners/{businessPartnerId}/beneficiary-accounts/{id}/retire', summary: 'Retire a beneficiary bank account; clears its default flag', pathParams: ['businessPartnerId', 'id'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
54
|
+
'beneficiary-accounts-reactivate': { method: 'POST', path: '/v1/business-partners/{businessPartnerId}/beneficiary-accounts/{id}/reactivate', summary: 'Reactivate a retired account: NEW again, both approvals cleared', pathParams: ['businessPartnerId', 'id'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
55
|
+
'beneficiary-accounts-default': { method: 'POST', path: '/v1/business-partners/{businessPartnerId}/beneficiary-accounts/{id}/default', summary: 'Make this account the partner default; the previous one is unset', pathParams: ['businessPartnerId', 'id'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
55
56
|
};
|
|
56
57
|
export default class BusinessPartners extends Command {
|
|
57
58
|
static description = 'Manage business partners';
|
|
@@ -73,7 +74,7 @@ export default class BusinessPartners extends Command {
|
|
|
73
74
|
table: Flags.boolean({ char: 't', description: 'Output as table (shortcut for --output table)' }),
|
|
74
75
|
csv: Flags.boolean({ description: 'Output as CSV (shortcut for --output csv)' }),
|
|
75
76
|
data: Flags.string({ char: 'd', description: 'JSON data for request body' }),
|
|
76
|
-
file: Flags.string({ char: 'f', description: 'Read request body from file' }),
|
|
77
|
+
file: Flags.string({ char: 'f', description: 'Read request body from file', parse: async (input) => resolveUserPath(input) }),
|
|
77
78
|
set: Flags.string({ char: 's', description: 'Set individual field (e.g. --set firstName=John)', multiple: true }),
|
|
78
79
|
'note-id': Flags.string({ description: 'Path param: noteId' }),
|
|
79
80
|
'file-id': Flags.string({ description: 'Path param: fileId' }),
|
|
@@ -208,6 +209,17 @@ export default class BusinessPartners extends Command {
|
|
|
208
209
|
}
|
|
209
210
|
}
|
|
210
211
|
}
|
|
212
|
+
// Flags generated from this endpoint's own parameters. Raw-body endpoints
|
|
213
|
+
// have them: their body is not JSON, so --set cannot carry a value there.
|
|
214
|
+
for (const param of endpoint.specParams) {
|
|
215
|
+
const value = flags[param.flag];
|
|
216
|
+
if (value === undefined || value === '') {
|
|
217
|
+
if (param.required)
|
|
218
|
+
this.error(`Missing required flag: --${param.flag}`);
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
221
|
+
queryParams[param.name] = value;
|
|
222
|
+
}
|
|
211
223
|
let data;
|
|
212
224
|
if (endpoint.isMultipart) {
|
|
213
225
|
if (!flags.file)
|
|
@@ -228,6 +240,25 @@ export default class BusinessPartners extends Command {
|
|
|
228
240
|
}
|
|
229
241
|
data = form;
|
|
230
242
|
}
|
|
243
|
+
else if (endpoint.bodyMediaType) {
|
|
244
|
+
// The body is not JSON (today only application/x-ndjson): it is sent
|
|
245
|
+
// verbatim, under the content type the endpoint asks for.
|
|
246
|
+
if (flags.file) {
|
|
247
|
+
const fsModule = await import('node:fs');
|
|
248
|
+
try {
|
|
249
|
+
data = fsModule.readFileSync(flags.file, 'utf-8');
|
|
250
|
+
}
|
|
251
|
+
catch {
|
|
252
|
+
this.error(`Failed to read file: ${flags.file}`);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
else if (flags.data) {
|
|
256
|
+
data = flags.data;
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
this.error(`This endpoint takes its body as ${endpoint.bodyMediaType}. Pass the file with -f / --file, or the text with --data.`);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
231
262
|
else if (endpoint.hasBody) {
|
|
232
263
|
// For binary-response endpoints, --file is the output path, not a JSON
|
|
233
264
|
// input file — skip the read-as-body branch.
|
|
@@ -323,7 +354,7 @@ export default class BusinessPartners extends Command {
|
|
|
323
354
|
process.stderr.write(`Body: [multipart/form-data file upload]\n`);
|
|
324
355
|
}
|
|
325
356
|
else if (data) {
|
|
326
|
-
process.stderr.write(`Body: ${JSON.stringify(data, null, 2)}\n`);
|
|
357
|
+
process.stderr.write(`Body: ${typeof data === 'string' ? data : JSON.stringify(data, null, 2)}\n`);
|
|
327
358
|
}
|
|
328
359
|
process.stderr.write('\n');
|
|
329
360
|
}
|
|
@@ -337,6 +368,7 @@ export default class BusinessPartners extends Command {
|
|
|
337
368
|
const binResponse = await apiRequest(endpoint.method, apiPath, {
|
|
338
369
|
params: Object.keys(queryParams).length > 0 ? queryParams : undefined,
|
|
339
370
|
data,
|
|
371
|
+
contentType: endpoint.bodyMediaType || undefined,
|
|
340
372
|
contextName: flags.context,
|
|
341
373
|
binary: true,
|
|
342
374
|
});
|
|
@@ -362,6 +394,7 @@ export default class BusinessPartners extends Command {
|
|
|
362
394
|
const raw = await apiRequest(endpoint.method, apiPath, {
|
|
363
395
|
params: Object.keys(queryParams).length > 0 ? queryParams : undefined,
|
|
364
396
|
data,
|
|
397
|
+
contentType: endpoint.bodyMediaType || undefined,
|
|
365
398
|
contextName: flags.context,
|
|
366
399
|
binary: true,
|
|
367
400
|
});
|
|
@@ -382,6 +415,7 @@ export default class BusinessPartners extends Command {
|
|
|
382
415
|
response = await apiRequest(endpoint.method, apiPath, {
|
|
383
416
|
params: Object.keys(queryParams).length > 0 ? queryParams : undefined,
|
|
384
417
|
data,
|
|
418
|
+
contentType: endpoint.bodyMediaType || undefined,
|
|
385
419
|
contextName: flags.context,
|
|
386
420
|
acceptAny: true,
|
|
387
421
|
});
|
package/dist/commands/chat.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Command, Args, Flags } from '@oclif/core';
|
|
2
2
|
import { apiRequest, ApiError, isTextualMediaType, normalizeSortBy } from '../lib/api-client.js';
|
|
3
3
|
import { getCurrentContext, getContext, getBaseUrls, hasCredentials, missingCredentialsMessage } from '../lib/config.js';
|
|
4
|
+
import { resolveUserPath } from '../lib/paths.js';
|
|
4
5
|
// 'upsert' loops create/update from the CLI, one request per record. It exists
|
|
5
6
|
// only where the API has no import endpoint of its own; those keep the name
|
|
6
7
|
// 'import' and are listed in SERVER_IMPORTS.
|
|
@@ -11,13 +12,13 @@ const SERVER_IMPORTS = [];
|
|
|
11
12
|
const NESTED_UPSERTS = [];
|
|
12
13
|
const SUBCOMMANDS = [...["create", "get", "get-all", "update", "delete", "stream", "token-refresh"], ...(HAS_UPSERT ? ['upsert'] : []), ...(HAS_EXPORT ? ['export'] : []), ...NESTED_UPSERTS.map(n => `upsert-${n}`)];
|
|
13
14
|
const ENDPOINTS = {
|
|
14
|
-
'create': { method: 'POST', path: '/v1/chat', summary: 'Send a chat message and stream the assistant reply (SSE).', pathParams: [], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: ['attachments'] },
|
|
15
|
-
'get': { method: 'GET', path: '/v1/conversations', summary: 'List the caller\'s chat conversations, most recently updated first.', pathParams: [], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
16
|
-
'get-all': { method: 'GET', path: '/v1/conversations/{id}', summary: 'Fetch one conversation with its messages.', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
17
|
-
'update': { method: 'PATCH', path: '/v1/conversations/{id}', summary: 'Store client-owned UI state on a conversation.', pathParams: ['id'], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
18
|
-
'delete': { method: 'DELETE', path: '/v1/conversations/{id}', summary: 'Delete one conversation.', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
19
|
-
'stream': { method: 'GET', path: '/v1/conversations/{id}/stream', summary: 'Reattach to a conversation\'s running turn (SSE replay + follow).', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
20
|
-
'token-refresh': { method: 'POST', path: '/v1/chat/token/refresh', summary: 'Refresh the delegated token a chat turn runs on', pathParams: [], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
15
|
+
'create': { method: 'POST', path: '/v1/chat', summary: 'Send a chat message and stream the assistant reply (SSE).', pathParams: [], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: ['attachments'], bodyMediaType: '', specParams: [] },
|
|
16
|
+
'get': { method: 'GET', path: '/v1/conversations', summary: 'List the caller\'s chat conversations, most recently updated first.', pathParams: [], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
17
|
+
'get-all': { method: 'GET', path: '/v1/conversations/{id}', summary: 'Fetch one conversation with its messages.', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
18
|
+
'update': { method: 'PATCH', path: '/v1/conversations/{id}', summary: 'Store client-owned UI state on a conversation.', pathParams: ['id'], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
19
|
+
'delete': { method: 'DELETE', path: '/v1/conversations/{id}', summary: 'Delete one conversation.', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
20
|
+
'stream': { method: 'GET', path: '/v1/conversations/{id}/stream', summary: 'Reattach to a conversation\'s running turn (SSE replay + follow).', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
21
|
+
'token-refresh': { method: 'POST', path: '/v1/chat/token/refresh', summary: 'Refresh the delegated token a chat turn runs on', pathParams: [], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
21
22
|
};
|
|
22
23
|
export default class Chat extends Command {
|
|
23
24
|
static description = 'Manage chat';
|
|
@@ -37,7 +38,7 @@ export default class Chat extends Command {
|
|
|
37
38
|
table: Flags.boolean({ char: 't', description: 'Output as table (shortcut for --output table)' }),
|
|
38
39
|
csv: Flags.boolean({ description: 'Output as CSV (shortcut for --output csv)' }),
|
|
39
40
|
data: Flags.string({ char: 'd', description: 'JSON data for request body' }),
|
|
40
|
-
file: Flags.string({ char: 'f', description: 'Read request body from file' }),
|
|
41
|
+
file: Flags.string({ char: 'f', description: 'Read request body from file', parse: async (input) => resolveUserPath(input) }),
|
|
41
42
|
set: Flags.string({ char: 's', description: 'Set individual field (e.g. --set firstName=John)', multiple: true }),
|
|
42
43
|
page: Flags.string({ description: 'Page number' }),
|
|
43
44
|
limit: Flags.string({ description: 'Items per page' }),
|
|
@@ -168,6 +169,17 @@ export default class Chat extends Command {
|
|
|
168
169
|
}
|
|
169
170
|
}
|
|
170
171
|
}
|
|
172
|
+
// Flags generated from this endpoint's own parameters. Raw-body endpoints
|
|
173
|
+
// have them: their body is not JSON, so --set cannot carry a value there.
|
|
174
|
+
for (const param of endpoint.specParams) {
|
|
175
|
+
const value = flags[param.flag];
|
|
176
|
+
if (value === undefined || value === '') {
|
|
177
|
+
if (param.required)
|
|
178
|
+
this.error(`Missing required flag: --${param.flag}`);
|
|
179
|
+
continue;
|
|
180
|
+
}
|
|
181
|
+
queryParams[param.name] = value;
|
|
182
|
+
}
|
|
171
183
|
let data;
|
|
172
184
|
if (endpoint.isMultipart) {
|
|
173
185
|
if (!flags.file)
|
|
@@ -188,6 +200,25 @@ export default class Chat extends Command {
|
|
|
188
200
|
}
|
|
189
201
|
data = form;
|
|
190
202
|
}
|
|
203
|
+
else if (endpoint.bodyMediaType) {
|
|
204
|
+
// The body is not JSON (today only application/x-ndjson): it is sent
|
|
205
|
+
// verbatim, under the content type the endpoint asks for.
|
|
206
|
+
if (flags.file) {
|
|
207
|
+
const fsModule = await import('node:fs');
|
|
208
|
+
try {
|
|
209
|
+
data = fsModule.readFileSync(flags.file, 'utf-8');
|
|
210
|
+
}
|
|
211
|
+
catch {
|
|
212
|
+
this.error(`Failed to read file: ${flags.file}`);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
else if (flags.data) {
|
|
216
|
+
data = flags.data;
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
this.error(`This endpoint takes its body as ${endpoint.bodyMediaType}. Pass the file with -f / --file, or the text with --data.`);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
191
222
|
else if (endpoint.hasBody) {
|
|
192
223
|
// For binary-response endpoints, --file is the output path, not a JSON
|
|
193
224
|
// input file — skip the read-as-body branch.
|
|
@@ -283,7 +314,7 @@ export default class Chat extends Command {
|
|
|
283
314
|
process.stderr.write(`Body: [multipart/form-data file upload]\n`);
|
|
284
315
|
}
|
|
285
316
|
else if (data) {
|
|
286
|
-
process.stderr.write(`Body: ${JSON.stringify(data, null, 2)}\n`);
|
|
317
|
+
process.stderr.write(`Body: ${typeof data === 'string' ? data : JSON.stringify(data, null, 2)}\n`);
|
|
287
318
|
}
|
|
288
319
|
process.stderr.write('\n');
|
|
289
320
|
}
|
|
@@ -297,6 +328,7 @@ export default class Chat extends Command {
|
|
|
297
328
|
const binResponse = await apiRequest(endpoint.method, apiPath, {
|
|
298
329
|
params: Object.keys(queryParams).length > 0 ? queryParams : undefined,
|
|
299
330
|
data,
|
|
331
|
+
contentType: endpoint.bodyMediaType || undefined,
|
|
300
332
|
contextName: flags.context,
|
|
301
333
|
binary: true,
|
|
302
334
|
});
|
|
@@ -322,6 +354,7 @@ export default class Chat extends Command {
|
|
|
322
354
|
const raw = await apiRequest(endpoint.method, apiPath, {
|
|
323
355
|
params: Object.keys(queryParams).length > 0 ? queryParams : undefined,
|
|
324
356
|
data,
|
|
357
|
+
contentType: endpoint.bodyMediaType || undefined,
|
|
325
358
|
contextName: flags.context,
|
|
326
359
|
binary: true,
|
|
327
360
|
});
|
|
@@ -342,6 +375,7 @@ export default class Chat extends Command {
|
|
|
342
375
|
response = await apiRequest(endpoint.method, apiPath, {
|
|
343
376
|
params: Object.keys(queryParams).length > 0 ? queryParams : undefined,
|
|
344
377
|
data,
|
|
378
|
+
contentType: endpoint.bodyMediaType || undefined,
|
|
345
379
|
contextName: flags.context,
|
|
346
380
|
acceptAny: true,
|
|
347
381
|
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Command, Args, Flags } from '@oclif/core';
|
|
2
2
|
import { apiRequest, ApiError, isTextualMediaType, normalizeSortBy } from '../lib/api-client.js';
|
|
3
3
|
import { getCurrentContext, getContext, getBaseUrls, hasCredentials, missingCredentialsMessage } from '../lib/config.js';
|
|
4
|
+
import { resolveUserPath } from '../lib/paths.js';
|
|
4
5
|
// 'upsert' loops create/update from the CLI, one request per record. It exists
|
|
5
6
|
// only where the API has no import endpoint of its own; those keep the name
|
|
6
7
|
// 'import' and are listed in SERVER_IMPORTS.
|
|
@@ -11,27 +12,27 @@ const SERVER_IMPORTS = ["import-cards"];
|
|
|
11
12
|
const NESTED_UPSERTS = ["ledger-mappings", "notes"];
|
|
12
13
|
const SUBCOMMANDS = [...["list", "create", "get", "update", "delete", "list-ledger-mappings", "create-ledger-mappings", "get-ledger-mappings", "update-ledger-mappings", "delete-ledger-mappings", "list-notes", "create-notes", "get-notes", "update-notes", "delete-notes", "list-cards", "create-cards", "get-cards", "update-cards", "delete-cards", "import-cards"], ...(HAS_UPSERT ? ['upsert'] : []), ...(HAS_EXPORT ? ['export'] : []), ...NESTED_UPSERTS.map(n => `upsert-${n}`)];
|
|
13
14
|
const ENDPOINTS = {
|
|
14
|
-
'list': { method: 'GET', path: '/v1/credit-card-accounts', summary: 'Get all credit card accounts with pagination', pathParams: [], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
15
|
-
'create': { method: 'POST', path: '/v1/credit-card-accounts', summary: 'Create a new credit card account (with optional notes)', pathParams: [], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: ['notes'] },
|
|
16
|
-
'get': { method: 'GET', path: '/v1/credit-card-accounts/{id}', summary: 'Get a credit card account by ID', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
17
|
-
'update': { method: 'PATCH', path: '/v1/credit-card-accounts/{id}', summary: 'Update a credit card account', pathParams: ['id'], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: ['notes'] },
|
|
18
|
-
'delete': { method: 'DELETE', path: '/v1/credit-card-accounts/{id}', summary: 'Delete a credit card account', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
19
|
-
'list-ledger-mappings': { method: 'GET', path: '/v1/credit-card-accounts/{creditCardAccountId}/ledger-mappings', summary: 'Get all ledger mappings for a credit card account', pathParams: ['creditCardAccountId'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
20
|
-
'create-ledger-mappings': { method: 'POST', path: '/v1/credit-card-accounts/{creditCardAccountId}/ledger-mappings', summary: 'Create a ledger mapping for a credit card account', pathParams: ['creditCardAccountId'], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
21
|
-
'get-ledger-mappings': { method: 'GET', path: '/v1/credit-card-accounts/{creditCardAccountId}/ledger-mappings/{mappingId}', summary: 'Get a ledger mapping by ID', pathParams: ['creditCardAccountId', 'mappingId'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
22
|
-
'update-ledger-mappings': { method: 'PATCH', path: '/v1/credit-card-accounts/{creditCardAccountId}/ledger-mappings/{mappingId}', summary: 'Update a ledger mapping', pathParams: ['creditCardAccountId', 'mappingId'], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
23
|
-
'delete-ledger-mappings': { method: 'DELETE', path: '/v1/credit-card-accounts/{creditCardAccountId}/ledger-mappings/{mappingId}', summary: 'Delete a ledger mapping', pathParams: ['creditCardAccountId', 'mappingId'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
24
|
-
'list-notes': { method: 'GET', path: '/v1/credit-card-accounts/{creditCardAccountId}/notes', summary: 'Get all notes for a credit card account', pathParams: ['creditCardAccountId'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
25
|
-
'create-notes': { method: 'POST', path: '/v1/credit-card-accounts/{creditCardAccountId}/notes', summary: 'Create a note for a credit card account', pathParams: ['creditCardAccountId'], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
26
|
-
'get-notes': { method: 'GET', path: '/v1/credit-card-accounts/{creditCardAccountId}/notes/{noteId}', summary: 'Get a specific note for a credit card account', pathParams: ['creditCardAccountId', 'noteId'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
27
|
-
'update-notes': { method: 'PATCH', path: '/v1/credit-card-accounts/{creditCardAccountId}/notes/{noteId}', summary: 'Update a note for a credit card account', pathParams: ['creditCardAccountId', 'noteId'], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
28
|
-
'delete-notes': { method: 'DELETE', path: '/v1/credit-card-accounts/{creditCardAccountId}/notes/{noteId}', summary: 'Delete a note from a credit card account', pathParams: ['creditCardAccountId', 'noteId'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
29
|
-
'list-cards': { method: 'GET', path: '/v1/credit-card-accounts/{creditCardAccountId}/cards', summary: 'Get all cards on a credit card account', pathParams: ['creditCardAccountId'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
30
|
-
'create-cards': { method: 'POST', path: '/v1/credit-card-accounts/{creditCardAccountId}/cards', summary: 'Create a card on a credit card account', pathParams: ['creditCardAccountId'], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
31
|
-
'get-cards': { method: 'GET', path: '/v1/credit-card-accounts/{creditCardAccountId}/cards/{cardId}', summary: 'Get a card by ID', pathParams: ['creditCardAccountId', 'cardId'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
32
|
-
'update-cards': { method: 'PATCH', path: '/v1/credit-card-accounts/{creditCardAccountId}/cards/{cardId}', summary: 'Update a card', pathParams: ['creditCardAccountId', 'cardId'], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
33
|
-
'delete-cards': { method: 'DELETE', path: '/v1/credit-card-accounts/{creditCardAccountId}/cards/{cardId}', summary: 'Delete a manual card', pathParams: ['creditCardAccountId', 'cardId'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
34
|
-
'import-cards': { method: 'POST', path: '/v1/credit-card-accounts/{creditCardAccountId}/cards/import', summary: 'Import provider cards into a credit card account', pathParams: ['creditCardAccountId'], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
15
|
+
'list': { method: 'GET', path: '/v1/credit-card-accounts', summary: 'Get all credit card accounts with pagination', pathParams: [], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
16
|
+
'create': { method: 'POST', path: '/v1/credit-card-accounts', summary: 'Create a new credit card account (with optional notes)', pathParams: [], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: ['notes'], bodyMediaType: '', specParams: [] },
|
|
17
|
+
'get': { method: 'GET', path: '/v1/credit-card-accounts/{id}', summary: 'Get a credit card account by ID', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
18
|
+
'update': { method: 'PATCH', path: '/v1/credit-card-accounts/{id}', summary: 'Update a credit card account', pathParams: ['id'], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: ['notes'], bodyMediaType: '', specParams: [] },
|
|
19
|
+
'delete': { method: 'DELETE', path: '/v1/credit-card-accounts/{id}', summary: 'Delete a credit card account', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
20
|
+
'list-ledger-mappings': { method: 'GET', path: '/v1/credit-card-accounts/{creditCardAccountId}/ledger-mappings', summary: 'Get all ledger mappings for a credit card account', pathParams: ['creditCardAccountId'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
21
|
+
'create-ledger-mappings': { method: 'POST', path: '/v1/credit-card-accounts/{creditCardAccountId}/ledger-mappings', summary: 'Create a ledger mapping for a credit card account', pathParams: ['creditCardAccountId'], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
22
|
+
'get-ledger-mappings': { method: 'GET', path: '/v1/credit-card-accounts/{creditCardAccountId}/ledger-mappings/{mappingId}', summary: 'Get a ledger mapping by ID', pathParams: ['creditCardAccountId', 'mappingId'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
23
|
+
'update-ledger-mappings': { method: 'PATCH', path: '/v1/credit-card-accounts/{creditCardAccountId}/ledger-mappings/{mappingId}', summary: 'Update a ledger mapping', pathParams: ['creditCardAccountId', 'mappingId'], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
24
|
+
'delete-ledger-mappings': { method: 'DELETE', path: '/v1/credit-card-accounts/{creditCardAccountId}/ledger-mappings/{mappingId}', summary: 'Delete a ledger mapping', pathParams: ['creditCardAccountId', 'mappingId'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
25
|
+
'list-notes': { method: 'GET', path: '/v1/credit-card-accounts/{creditCardAccountId}/notes', summary: 'Get all notes for a credit card account', pathParams: ['creditCardAccountId'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
26
|
+
'create-notes': { method: 'POST', path: '/v1/credit-card-accounts/{creditCardAccountId}/notes', summary: 'Create a note for a credit card account', pathParams: ['creditCardAccountId'], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
27
|
+
'get-notes': { method: 'GET', path: '/v1/credit-card-accounts/{creditCardAccountId}/notes/{noteId}', summary: 'Get a specific note for a credit card account', pathParams: ['creditCardAccountId', 'noteId'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
28
|
+
'update-notes': { method: 'PATCH', path: '/v1/credit-card-accounts/{creditCardAccountId}/notes/{noteId}', summary: 'Update a note for a credit card account', pathParams: ['creditCardAccountId', 'noteId'], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
29
|
+
'delete-notes': { method: 'DELETE', path: '/v1/credit-card-accounts/{creditCardAccountId}/notes/{noteId}', summary: 'Delete a note from a credit card account', pathParams: ['creditCardAccountId', 'noteId'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
30
|
+
'list-cards': { method: 'GET', path: '/v1/credit-card-accounts/{creditCardAccountId}/cards', summary: 'Get all cards on a credit card account', pathParams: ['creditCardAccountId'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
31
|
+
'create-cards': { method: 'POST', path: '/v1/credit-card-accounts/{creditCardAccountId}/cards', summary: 'Create a card on a credit card account', pathParams: ['creditCardAccountId'], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
32
|
+
'get-cards': { method: 'GET', path: '/v1/credit-card-accounts/{creditCardAccountId}/cards/{cardId}', summary: 'Get a card by ID', pathParams: ['creditCardAccountId', 'cardId'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
33
|
+
'update-cards': { method: 'PATCH', path: '/v1/credit-card-accounts/{creditCardAccountId}/cards/{cardId}', summary: 'Update a card', pathParams: ['creditCardAccountId', 'cardId'], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
34
|
+
'delete-cards': { method: 'DELETE', path: '/v1/credit-card-accounts/{creditCardAccountId}/cards/{cardId}', summary: 'Delete a manual card', pathParams: ['creditCardAccountId', 'cardId'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
35
|
+
'import-cards': { method: 'POST', path: '/v1/credit-card-accounts/{creditCardAccountId}/cards/import', summary: 'Import provider cards into a credit card account', pathParams: ['creditCardAccountId'], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [], bodyMediaType: '', specParams: [] },
|
|
35
36
|
};
|
|
36
37
|
export default class CreditCardAccounts extends Command {
|
|
37
38
|
static description = 'Manage credit card accounts';
|
|
@@ -53,7 +54,7 @@ export default class CreditCardAccounts extends Command {
|
|
|
53
54
|
table: Flags.boolean({ char: 't', description: 'Output as table (shortcut for --output table)' }),
|
|
54
55
|
csv: Flags.boolean({ description: 'Output as CSV (shortcut for --output csv)' }),
|
|
55
56
|
data: Flags.string({ char: 'd', description: 'JSON data for request body' }),
|
|
56
|
-
file: Flags.string({ char: 'f', description: 'Read request body from file' }),
|
|
57
|
+
file: Flags.string({ char: 'f', description: 'Read request body from file', parse: async (input) => resolveUserPath(input) }),
|
|
57
58
|
set: Flags.string({ char: 's', description: 'Set individual field (e.g. --set firstName=John)', multiple: true }),
|
|
58
59
|
mode: Flags.string({ description: 'Import mode: upsert (default) creates, updates or skips each record; create refuses records that already exist; update refuses records that do not', options: ['upsert', 'create', 'update'] }),
|
|
59
60
|
reference: Flags.string({ description: 'Caller-defined text stored on the import run, for tracking and filtering' }),
|
|
@@ -191,6 +192,17 @@ export default class CreditCardAccounts extends Command {
|
|
|
191
192
|
}
|
|
192
193
|
}
|
|
193
194
|
}
|
|
195
|
+
// Flags generated from this endpoint's own parameters. Raw-body endpoints
|
|
196
|
+
// have them: their body is not JSON, so --set cannot carry a value there.
|
|
197
|
+
for (const param of endpoint.specParams) {
|
|
198
|
+
const value = flags[param.flag];
|
|
199
|
+
if (value === undefined || value === '') {
|
|
200
|
+
if (param.required)
|
|
201
|
+
this.error(`Missing required flag: --${param.flag}`);
|
|
202
|
+
continue;
|
|
203
|
+
}
|
|
204
|
+
queryParams[param.name] = value;
|
|
205
|
+
}
|
|
194
206
|
let data;
|
|
195
207
|
if (endpoint.isMultipart) {
|
|
196
208
|
if (!flags.file)
|
|
@@ -211,6 +223,25 @@ export default class CreditCardAccounts extends Command {
|
|
|
211
223
|
}
|
|
212
224
|
data = form;
|
|
213
225
|
}
|
|
226
|
+
else if (endpoint.bodyMediaType) {
|
|
227
|
+
// The body is not JSON (today only application/x-ndjson): it is sent
|
|
228
|
+
// verbatim, under the content type the endpoint asks for.
|
|
229
|
+
if (flags.file) {
|
|
230
|
+
const fsModule = await import('node:fs');
|
|
231
|
+
try {
|
|
232
|
+
data = fsModule.readFileSync(flags.file, 'utf-8');
|
|
233
|
+
}
|
|
234
|
+
catch {
|
|
235
|
+
this.error(`Failed to read file: ${flags.file}`);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
else if (flags.data) {
|
|
239
|
+
data = flags.data;
|
|
240
|
+
}
|
|
241
|
+
else {
|
|
242
|
+
this.error(`This endpoint takes its body as ${endpoint.bodyMediaType}. Pass the file with -f / --file, or the text with --data.`);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
214
245
|
else if (endpoint.hasBody) {
|
|
215
246
|
// For binary-response endpoints, --file is the output path, not a JSON
|
|
216
247
|
// input file — skip the read-as-body branch.
|
|
@@ -306,7 +337,7 @@ export default class CreditCardAccounts extends Command {
|
|
|
306
337
|
process.stderr.write(`Body: [multipart/form-data file upload]\n`);
|
|
307
338
|
}
|
|
308
339
|
else if (data) {
|
|
309
|
-
process.stderr.write(`Body: ${JSON.stringify(data, null, 2)}\n`);
|
|
340
|
+
process.stderr.write(`Body: ${typeof data === 'string' ? data : JSON.stringify(data, null, 2)}\n`);
|
|
310
341
|
}
|
|
311
342
|
process.stderr.write('\n');
|
|
312
343
|
}
|
|
@@ -320,6 +351,7 @@ export default class CreditCardAccounts extends Command {
|
|
|
320
351
|
const binResponse = await apiRequest(endpoint.method, apiPath, {
|
|
321
352
|
params: Object.keys(queryParams).length > 0 ? queryParams : undefined,
|
|
322
353
|
data,
|
|
354
|
+
contentType: endpoint.bodyMediaType || undefined,
|
|
323
355
|
contextName: flags.context,
|
|
324
356
|
binary: true,
|
|
325
357
|
});
|
|
@@ -345,6 +377,7 @@ export default class CreditCardAccounts extends Command {
|
|
|
345
377
|
const raw = await apiRequest(endpoint.method, apiPath, {
|
|
346
378
|
params: Object.keys(queryParams).length > 0 ? queryParams : undefined,
|
|
347
379
|
data,
|
|
380
|
+
contentType: endpoint.bodyMediaType || undefined,
|
|
348
381
|
contextName: flags.context,
|
|
349
382
|
binary: true,
|
|
350
383
|
});
|
|
@@ -365,6 +398,7 @@ export default class CreditCardAccounts extends Command {
|
|
|
365
398
|
response = await apiRequest(endpoint.method, apiPath, {
|
|
366
399
|
params: Object.keys(queryParams).length > 0 ? queryParams : undefined,
|
|
367
400
|
data,
|
|
401
|
+
contentType: endpoint.bodyMediaType || undefined,
|
|
368
402
|
contextName: flags.context,
|
|
369
403
|
acceptAny: true,
|
|
370
404
|
});
|