@aderis-erp/cli 1.0.15 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -8
- package/dist/commands/access-groups.d.ts +0 -1
- package/dist/commands/access-groups.js +54 -78
- package/dist/commands/account-transaction-allocations.d.ts +0 -1
- package/dist/commands/account-transaction-allocations.js +51 -75
- package/dist/commands/account-transactions.d.ts +0 -1
- package/dist/commands/account-transactions.js +80 -94
- package/dist/commands/accounts.d.ts +0 -1
- package/dist/commands/accounts.js +59 -83
- package/dist/commands/agent-platform.d.ts +0 -1
- package/dist/commands/agent-platform.js +58 -82
- package/dist/commands/agent-runs.d.ts +39 -0
- package/dist/commands/agent-runs.js +1155 -0
- package/dist/commands/analytics.d.ts +0 -1
- package/dist/commands/analytics.js +52 -76
- package/dist/commands/{text-templates.d.ts → api-keys.d.ts} +1 -2
- package/dist/commands/api-keys.js +1150 -0
- package/dist/commands/async-jobs.d.ts +39 -0
- package/dist/commands/async-jobs.js +1158 -0
- package/dist/commands/audit-log.d.ts +0 -1
- package/dist/commands/audit-log.js +51 -75
- package/dist/commands/auth/login.d.ts +9 -0
- package/dist/commands/auth/login.js +73 -20
- package/dist/commands/auth/logout.d.ts +4 -0
- package/dist/commands/auth/logout.js +4 -0
- package/dist/commands/auth/status.js +26 -17
- package/dist/commands/auth/tenant.js +3 -6
- package/dist/commands/auth.d.ts +0 -1
- package/dist/commands/auth.js +5 -34
- package/dist/commands/bank-accounts.d.ts +0 -1
- package/dist/commands/bank-accounts.js +68 -91
- package/dist/commands/bank-integrations.d.ts +1 -1
- package/dist/commands/bank-integrations.js +71 -92
- package/dist/commands/business-partners.d.ts +1 -1
- package/dist/commands/business-partners.js +84 -100
- package/dist/commands/chat.d.ts +0 -1
- package/dist/commands/chat.js +57 -80
- package/dist/commands/config/add.d.ts +3 -0
- package/dist/commands/config/add.js +34 -16
- package/dist/commands/config/current.js +3 -0
- package/dist/commands/config/list.js +3 -0
- package/dist/commands/credit-card-accounts.d.ts +1 -1
- package/dist/commands/credit-card-accounts.js +72 -90
- package/dist/commands/delivery-notes.d.ts +0 -1
- package/dist/commands/delivery-notes.js +83 -105
- package/dist/commands/dunning-configs.d.ts +0 -1
- package/dist/commands/dunning-configs.js +54 -78
- package/dist/commands/dunning-reminders.d.ts +0 -1
- package/dist/commands/dunning-reminders.js +57 -81
- package/dist/commands/dunning-runs.d.ts +0 -1
- package/dist/commands/dunning-runs.js +50 -74
- package/dist/commands/email-transactions.d.ts +0 -1
- package/dist/commands/email-transactions.js +52 -76
- package/dist/commands/employees.d.ts +0 -1
- package/dist/commands/employees.js +81 -105
- package/dist/commands/entity-configurations.d.ts +0 -1
- package/dist/commands/entity-configurations.js +52 -76
- package/dist/commands/event-processor-mappings.d.ts +0 -1
- package/dist/commands/event-processor-mappings.js +54 -78
- package/dist/commands/files.d.ts +0 -1
- package/dist/commands/files.js +61 -85
- package/dist/commands/health.d.ts +0 -1
- package/dist/commands/health.js +54 -78
- package/dist/commands/imports.d.ts +39 -0
- package/dist/commands/imports.js +1151 -0
- package/dist/commands/inbox.d.ts +0 -1
- package/dist/commands/inbox.js +57 -80
- package/dist/commands/integration-identities.d.ts +40 -0
- package/dist/commands/integration-identities.js +1151 -0
- package/dist/commands/integrations.d.ts +0 -1
- package/dist/commands/integrations.js +52 -76
- package/dist/commands/item-categories.d.ts +0 -1
- package/dist/commands/item-categories.js +54 -78
- package/dist/commands/items.d.ts +0 -1
- package/dist/commands/items.js +54 -78
- package/dist/commands/journal-lines.d.ts +0 -1
- package/dist/commands/journal-lines.js +50 -74
- package/dist/commands/journals.d.ts +1 -1
- package/dist/commands/journals.js +75 -96
- package/dist/commands/ledgers.d.ts +3 -2
- package/dist/commands/ledgers.js +100 -95
- package/dist/commands/my-account.d.ts +39 -0
- package/dist/commands/my-account.js +1160 -0
- package/dist/commands/office-locations.d.ts +0 -1
- package/dist/commands/office-locations.js +54 -78
- package/dist/commands/payment-methods.d.ts +0 -1
- package/dist/commands/payment-methods.js +59 -83
- package/dist/commands/payment-runs.d.ts +0 -1
- package/dist/commands/payment-runs.js +66 -90
- package/dist/commands/payment-terms.d.ts +0 -1
- package/dist/commands/payment-terms.js +55 -79
- package/dist/commands/payments.d.ts +0 -1
- package/dist/commands/payments.js +56 -80
- package/dist/commands/payroll-runs.d.ts +43 -0
- package/dist/commands/payroll-runs.js +1188 -0
- package/dist/commands/permissions.d.ts +39 -0
- package/dist/commands/permissions.js +1146 -0
- package/dist/commands/price-lists.d.ts +0 -1
- package/dist/commands/price-lists.js +59 -83
- package/dist/commands/processor-mappings.d.ts +0 -1
- package/dist/commands/processor-mappings.js +53 -77
- package/dist/commands/processors.d.ts +0 -1
- package/dist/commands/processors.js +60 -85
- package/dist/commands/purchase-order-types.d.ts +0 -1
- package/dist/commands/purchase-order-types.js +54 -78
- package/dist/commands/purchase-orders.d.ts +0 -1
- package/dist/commands/purchase-orders.js +74 -97
- package/dist/commands/reports.d.ts +0 -1
- package/dist/commands/reports.js +54 -78
- package/dist/commands/roles.d.ts +39 -0
- package/dist/commands/{text-templates.js → roles.js} +64 -90
- package/dist/commands/salary-types.d.ts +0 -1
- package/dist/commands/salary-types.js +54 -78
- package/dist/commands/sales-invoices.d.ts +0 -1
- package/dist/commands/sales-invoices.js +90 -110
- package/dist/commands/sales-orders.d.ts +0 -1
- package/dist/commands/sales-orders.js +83 -105
- package/dist/commands/saved-views.d.ts +0 -1
- package/dist/commands/saved-views.js +52 -76
- package/dist/commands/scheduled-processor-mappings.d.ts +0 -1
- package/dist/commands/scheduled-processor-mappings.js +54 -78
- package/dist/commands/schedules.d.ts +0 -1
- package/dist/commands/schedules.js +58 -82
- package/dist/commands/switch.js +4 -4
- package/dist/commands/tag-configurations.d.ts +0 -1
- package/dist/commands/tag-configurations.js +56 -79
- package/dist/commands/tags.d.ts +0 -1
- package/dist/commands/tags.js +54 -78
- package/dist/commands/tax-codes.d.ts +0 -1
- package/dist/commands/tax-codes.js +57 -81
- package/dist/commands/tax-matrix.d.ts +0 -1
- package/dist/commands/tax-matrix.js +54 -78
- package/dist/commands/templates.d.ts +39 -0
- package/dist/commands/templates.js +1157 -0
- package/dist/commands/tenants.d.ts +0 -1
- package/dist/commands/tenants.js +58 -81
- package/dist/commands/tools.d.ts +0 -1
- package/dist/commands/tools.js +51 -75
- package/dist/commands/users.d.ts +42 -0
- package/dist/commands/users.js +1174 -0
- package/dist/commands/vat-declarations.d.ts +3 -1
- package/dist/commands/vat-declarations.js +78 -93
- package/dist/commands/vendor-invoices.d.ts +0 -1
- package/dist/commands/vendor-invoices.js +87 -110
- package/dist/commands/webhooks.d.ts +0 -1
- package/dist/commands/webhooks.js +56 -80
- package/dist/commands/workflows.d.ts +0 -1
- package/dist/commands/workflows.js +52 -76
- package/dist/lib/api-client.d.ts +6 -0
- package/dist/lib/api-client.js +16 -6
- package/dist/lib/auth/constants.d.ts +11 -0
- package/dist/lib/auth/constants.js +11 -0
- package/dist/lib/auth/errors.d.ts +17 -0
- package/dist/lib/auth/errors.js +22 -0
- package/dist/lib/auth/flow.d.ts +27 -0
- package/dist/lib/auth/flow.js +163 -0
- package/dist/lib/auth/guards.d.ts +5 -0
- package/dist/lib/auth/guards.js +14 -0
- package/dist/lib/auth/http.d.ts +16 -0
- package/dist/lib/auth/http.js +49 -0
- package/dist/lib/auth/index.d.ts +49 -0
- package/dist/lib/auth/index.js +228 -0
- package/dist/lib/auth/jwks.d.ts +19 -0
- package/dist/lib/auth/jwks.js +112 -0
- package/dist/lib/auth/keycloak-provider.d.ts +91 -0
- package/dist/lib/auth/keycloak-provider.js +244 -0
- package/dist/lib/auth/pages.d.ts +25 -0
- package/dist/lib/auth/pages.js +123 -0
- package/dist/lib/auth/pkce.d.ts +11 -0
- package/dist/lib/auth/pkce.js +17 -0
- package/dist/lib/auth/tokens.d.ts +59 -0
- package/dist/lib/auth/tokens.js +105 -0
- package/dist/lib/auth/types.d.ts +61 -0
- package/dist/lib/auth/types.js +1 -0
- package/dist/lib/auth/validated-url.d.ts +6 -0
- package/dist/lib/auth/validated-url.js +53 -0
- package/dist/lib/config.d.ts +13 -3
- package/dist/lib/config.js +24 -19
- package/oclif.manifest.json +2447 -641
- package/package.json +5 -4
- package/dist/lib/auth.d.ts +0 -43
- package/dist/lib/auth.js +0 -610
|
@@ -1,36 +1,37 @@
|
|
|
1
1
|
import { Command, Args, Flags } from '@oclif/core';
|
|
2
|
-
import { apiRequest, ApiError, normalizeSortBy } from '../lib/api-client.js';
|
|
2
|
+
import { apiRequest, ApiError, isTextualMediaType, normalizeSortBy } from '../lib/api-client.js';
|
|
3
3
|
import { getCurrentContext, getContext, getBaseUrls, hasCredentials, missingCredentialsMessage } from '../lib/config.js';
|
|
4
4
|
// Add 'import' action if both create and update exist
|
|
5
5
|
const HAS_IMPORT = true;
|
|
6
6
|
const HAS_EXPORT = true;
|
|
7
7
|
const HAS_CAMT053 = false;
|
|
8
8
|
const NESTED_IMPORTS = ["line-items", "notes", "files"];
|
|
9
|
-
const SUBCOMMANDS = [...["list", "create", "get", "update", "delete", "submit", "approve", "decline", "cancel", "create-line-items", "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", "get", "update", "delete", "submit", "approve", "copy", "decline", "cancel", "create-line-items", "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
|
-
'list': { method: 'GET', path: '/v1/purchase-orders', summary: 'Get all purchase orders with pagination', pathParams: [], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
|
|
12
|
-
'create': { method: 'POST', path: '/v1/purchase-orders', summary: 'Create a new purchase order', pathParams: [], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: ['tagIds', 'tagCodes', 'files', 'notes', 'discounts', 'lineItems'] },
|
|
13
|
-
'get': { method: 'GET', path: '/v1/purchase-orders/{id}', summary: 'Get a purchase order by ID', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
|
|
14
|
-
'update': { method: 'PATCH', path: '/v1/purchase-orders/{id}', summary: 'Update a purchase order', pathParams: ['id'], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: ['tagIds', 'tagCodes', 'files', 'notes', 'discounts', 'lineItems', 'removeFileIds'] },
|
|
15
|
-
'delete': { method: 'DELETE', path: '/v1/purchase-orders/{id}', summary: 'Delete a purchase order', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
|
|
16
|
-
'submit': { method: 'POST', path: '/v1/purchase-orders/{id}/submit', summary: 'Submit order for approval (DRAFT → PENDING_APPROVAL)', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
|
|
17
|
-
'approve': { method: 'POST', path: '/v1/purchase-orders/{id}/approve', summary: 'Approve order (PENDING_APPROVAL → APPROVED). Generates order number if missing.', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
|
|
18
|
-
'
|
|
19
|
-
'
|
|
20
|
-
'
|
|
21
|
-
'
|
|
22
|
-
'
|
|
23
|
-
'
|
|
24
|
-
'
|
|
25
|
-
'
|
|
26
|
-
'
|
|
27
|
-
'
|
|
28
|
-
'
|
|
29
|
-
'
|
|
30
|
-
'
|
|
31
|
-
'
|
|
32
|
-
'
|
|
33
|
-
'files
|
|
11
|
+
'list': { method: 'GET', path: '/v1/purchase-orders', summary: 'Get all purchase orders with pagination', pathParams: [], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
12
|
+
'create': { method: 'POST', path: '/v1/purchase-orders', summary: 'Create a new purchase order', pathParams: [], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: ['tagIds', 'tagCodes', 'files', 'notes', 'discounts', 'lineItems'] },
|
|
13
|
+
'get': { method: 'GET', path: '/v1/purchase-orders/{id}', summary: 'Get a purchase order by ID', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
14
|
+
'update': { method: 'PATCH', path: '/v1/purchase-orders/{id}', summary: 'Update a purchase order', pathParams: ['id'], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: ['tagIds', 'tagCodes', 'files', 'notes', 'discounts', 'lineItems', 'removeFileIds'] },
|
|
15
|
+
'delete': { method: 'DELETE', path: '/v1/purchase-orders/{id}', summary: 'Delete a purchase order', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
16
|
+
'submit': { method: 'POST', path: '/v1/purchase-orders/{id}/submit', summary: 'Submit order for approval (DRAFT → PENDING_APPROVAL)', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
17
|
+
'approve': { method: 'POST', path: '/v1/purchase-orders/{id}/approve', summary: 'Approve order (PENDING_APPROVAL → APPROVED). Generates order number if missing.', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
18
|
+
'copy': { method: 'POST', path: '/v1/purchase-orders/{id}/copy', summary: 'Create a copy of a purchase order as a new draft', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
19
|
+
'decline': { method: 'POST', path: '/v1/purchase-orders/{id}/decline', summary: 'Decline order (PENDING_APPROVAL → DECLINED)', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
20
|
+
'cancel': { method: 'POST', path: '/v1/purchase-orders/{id}/cancel', summary: 'Cancel order (DRAFT, PENDING_APPROVAL or APPROVED → CANCELLED)', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
21
|
+
'create-line-items': { method: 'POST', path: '/v1/purchase-orders/{orderId}/line-items', summary: 'Add a line item to a purchase order', pathParams: ['orderId'], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: ['discounts', 'tagIds', 'tagCodes'] },
|
|
22
|
+
'update-line-items': { method: 'PATCH', path: '/v1/purchase-orders/{orderId}/line-items/{lineItemId}', summary: 'Update a line item on a purchase order', pathParams: ['orderId', 'lineItemId'], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: ['discounts', 'tagIds', 'tagCodes'] },
|
|
23
|
+
'delete-line-items': { method: 'DELETE', path: '/v1/purchase-orders/{orderId}/line-items/{lineItemId}', summary: 'Remove a line item from a purchase order', pathParams: ['orderId', 'lineItemId'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
24
|
+
'list-notes': { method: 'GET', path: '/v1/purchase-orders/{purchaseOrderId}/notes', summary: 'Get all notes for a purchase order', pathParams: ['purchaseOrderId'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
25
|
+
'create-notes': { method: 'POST', path: '/v1/purchase-orders/{purchaseOrderId}/notes', summary: 'Create a note for a purchase order', pathParams: ['purchaseOrderId'], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
26
|
+
'get-notes': { method: 'GET', path: '/v1/purchase-orders/{purchaseOrderId}/notes/{noteId}', summary: 'Get a specific note for a purchase order', pathParams: ['purchaseOrderId', 'noteId'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
27
|
+
'update-notes': { method: 'PATCH', path: '/v1/purchase-orders/{purchaseOrderId}/notes/{noteId}', summary: 'Update a note for a purchase order', pathParams: ['purchaseOrderId', 'noteId'], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
28
|
+
'delete-notes': { method: 'DELETE', path: '/v1/purchase-orders/{purchaseOrderId}/notes/{noteId}', summary: 'Delete a note from a purchase order', pathParams: ['purchaseOrderId', 'noteId'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
29
|
+
'list-files': { method: 'GET', path: '/v1/purchase-orders/{parentId}/files', summary: 'List file attachments for a purchase order', pathParams: ['parentId'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
30
|
+
'create-files': { method: 'POST', path: '/v1/purchase-orders/{parentId}/files', summary: 'Upload a file attachment to a purchase order', pathParams: ['parentId'], hasBody: false, isMultipart: true, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
31
|
+
'get-files': { method: 'GET', path: '/v1/purchase-orders/{parentId}/files/{fileId}', summary: 'Get a file attachment for a purchase order', pathParams: ['parentId', 'fileId'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
32
|
+
'update-files': { method: 'PATCH', path: '/v1/purchase-orders/{parentId}/files/{fileId}', summary: 'Update file attachment metadata for a purchase order', pathParams: ['parentId', 'fileId'], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
33
|
+
'delete-files': { method: 'DELETE', path: '/v1/purchase-orders/{parentId}/files/{fileId}', summary: 'Delete a file attachment from a purchase order', pathParams: ['parentId', 'fileId'], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
34
|
+
'files-download': { method: 'GET', path: '/v1/purchase-orders/{parentId}/files/{fileId}/download', summary: 'Download a file attachment from a purchase order', pathParams: ['parentId', 'fileId'], hasBody: false, isMultipart: false, isBinaryResponse: true, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
34
35
|
};
|
|
35
36
|
export default class PurchaseOrders extends Command {
|
|
36
37
|
static description = 'Manage purchase orders';
|
|
@@ -64,7 +65,7 @@ export default class PurchaseOrders extends Command {
|
|
|
64
65
|
'sort-by': Flags.string({ description: 'Sort field(s), comma-separated. Direction (:ASC/:DESC) is optional; date-like fields default to DESC, others to ASC.' }),
|
|
65
66
|
filter: Flags.string({ description: 'Filter (e.g. --filter status=ACTIVE). Operators: in:A,B, like:%, gt:, lt:, null:', multiple: true }),
|
|
66
67
|
query: Flags.string({ description: 'Additional query params as JSON' }),
|
|
67
|
-
fields: Flags.string({ description: 'Comma-separated list of fields to
|
|
68
|
+
fields: Flags.string({ description: 'Comma-separated list of fields to return, applied by the API (e.g. --fields=id,name,status)' }),
|
|
68
69
|
sanitize: Flags.boolean({ description: 'Remove null values, audit fields, and duplicate UUIDs from output' }),
|
|
69
70
|
'show-http-request': Flags.boolean({ description: 'Show HTTP request details (method, URL, body)' }),
|
|
70
71
|
};
|
|
@@ -136,6 +137,8 @@ export default class PurchaseOrders extends Command {
|
|
|
136
137
|
queryParams.search = flags.search;
|
|
137
138
|
if (flags['sort-by'])
|
|
138
139
|
queryParams.sortBy = normalizeSortBy(flags['sort-by']);
|
|
140
|
+
if (flags.fields)
|
|
141
|
+
queryParams.fields = flags.fields;
|
|
139
142
|
if (flags.query) {
|
|
140
143
|
try {
|
|
141
144
|
Object.assign(queryParams, JSON.parse(flags.query));
|
|
@@ -283,10 +286,11 @@ export default class PurchaseOrders extends Command {
|
|
|
283
286
|
process.stderr.write('\n');
|
|
284
287
|
}
|
|
285
288
|
try {
|
|
286
|
-
// Binary response:
|
|
289
|
+
// Binary response: to -f / --file, or to stdout when it is redirected.
|
|
287
290
|
if (endpoint.isBinaryResponse) {
|
|
288
|
-
|
|
289
|
-
|
|
291
|
+
const toStdout = !flags.file;
|
|
292
|
+
if (toStdout && process.stdout.isTTY) {
|
|
293
|
+
this.error(`Endpoint returns a binary file. Specify the output path with -f / --file (e.g. -f report.xlsx), or redirect stdout to a file.`);
|
|
290
294
|
}
|
|
291
295
|
const binResponse = await apiRequest(endpoint.method, apiPath, {
|
|
292
296
|
params: Object.keys(queryParams).length > 0 ? queryParams : undefined,
|
|
@@ -294,24 +298,55 @@ export default class PurchaseOrders extends Command {
|
|
|
294
298
|
contextName: flags.context,
|
|
295
299
|
binary: true,
|
|
296
300
|
});
|
|
297
|
-
const fsModule = await import('node:fs');
|
|
298
301
|
const binData = binResponse.data;
|
|
299
302
|
const buffer = Buffer.isBuffer(binData)
|
|
300
303
|
? binData
|
|
301
304
|
: Buffer.from(binData);
|
|
305
|
+
if (toStdout) {
|
|
306
|
+
// Nothing else may reach stdout here — it is the file.
|
|
307
|
+
process.stdout.write(buffer);
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
const fsModule = await import('node:fs');
|
|
302
311
|
fsModule.writeFileSync(flags.file, buffer);
|
|
303
312
|
this.log(`Saved ${buffer.length} bytes to ${flags.file}`);
|
|
304
313
|
return;
|
|
305
314
|
}
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
315
|
+
let response;
|
|
316
|
+
if (endpoint.hasBinaryVariant) {
|
|
317
|
+
// This route answers JSON or a file depending on the request body, so the
|
|
318
|
+
// bytes are read first and the response's own content-type decides. Asking
|
|
319
|
+
// for text here would corrupt an xlsx/pdf before anything could inspect it.
|
|
320
|
+
const raw = await apiRequest(endpoint.method, apiPath, {
|
|
321
|
+
params: Object.keys(queryParams).length > 0 ? queryParams : undefined,
|
|
322
|
+
data,
|
|
323
|
+
contextName: flags.context,
|
|
324
|
+
binary: true,
|
|
325
|
+
});
|
|
326
|
+
const rawType = String(raw.headers['content-type'] || '').toLowerCase();
|
|
327
|
+
const rawData = raw.data;
|
|
328
|
+
const buffer = Buffer.isBuffer(rawData) ? rawData : Buffer.from(rawData);
|
|
329
|
+
if (!isTextualMediaType(rawType)) {
|
|
330
|
+
if (process.stdout.isTTY) {
|
|
331
|
+
this.error(`The API returned ${rawType || 'binary data'}. Redirect stdout to a file, e.g. ... > report.xlsx`);
|
|
332
|
+
}
|
|
333
|
+
// Nothing else may reach stdout here — it is the file.
|
|
334
|
+
process.stdout.write(buffer);
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
response = { data: buffer.toString('utf8'), headers: raw.headers, status: raw.status };
|
|
338
|
+
}
|
|
339
|
+
else {
|
|
340
|
+
response = await apiRequest(endpoint.method, apiPath, {
|
|
341
|
+
params: Object.keys(queryParams).length > 0 ? queryParams : undefined,
|
|
342
|
+
data,
|
|
343
|
+
contextName: flags.context,
|
|
344
|
+
acceptAny: true,
|
|
345
|
+
});
|
|
346
|
+
}
|
|
312
347
|
// Check content-type for non-JSON responses (XML, text, etc.)
|
|
313
348
|
const contentType = (response.headers['content-type'] || '').toLowerCase();
|
|
314
|
-
if (contentType
|
|
349
|
+
if (isTextualMediaType(contentType) && !contentType.startsWith('application/json')) {
|
|
315
350
|
// Output raw content for XML/text responses (CSV, plain, HTML, etc.)
|
|
316
351
|
this.log(String(response.data));
|
|
317
352
|
return;
|
|
@@ -338,11 +373,6 @@ export default class PurchaseOrders extends Command {
|
|
|
338
373
|
output = obj[arrayKeys[0]];
|
|
339
374
|
}
|
|
340
375
|
}
|
|
341
|
-
// Filter fields if --fields flag is provided
|
|
342
|
-
if (flags.fields) {
|
|
343
|
-
const fieldList = flags.fields.split(',').map(f => f.trim());
|
|
344
|
-
output = this.filterFields(output, fieldList);
|
|
345
|
-
}
|
|
346
376
|
// Sanitize output if requested
|
|
347
377
|
if (flags.sanitize) {
|
|
348
378
|
output = this.sanitizeOutput(output);
|
|
@@ -597,6 +627,8 @@ export default class PurchaseOrders extends Command {
|
|
|
597
627
|
baseParams.sortBy = normalizeSortBy(flags['sort-by']);
|
|
598
628
|
if (flags.include)
|
|
599
629
|
baseParams.include = flags.include;
|
|
630
|
+
if (flags.fields)
|
|
631
|
+
baseParams.fields = flags.fields;
|
|
600
632
|
if (flags.query) {
|
|
601
633
|
try {
|
|
602
634
|
Object.assign(baseParams, JSON.parse(flags.query));
|
|
@@ -651,12 +683,7 @@ export default class PurchaseOrders extends Command {
|
|
|
651
683
|
}
|
|
652
684
|
}
|
|
653
685
|
process.stderr.write(' done\n');
|
|
654
|
-
// Filter fields if specified
|
|
655
686
|
let output = allItems;
|
|
656
|
-
if (flags.fields) {
|
|
657
|
-
const fieldList = flags.fields.split(',').map(f => f.trim());
|
|
658
|
-
output = this.filterFields(allItems, fieldList);
|
|
659
|
-
}
|
|
660
687
|
// Sanitize output if requested
|
|
661
688
|
if (flags.sanitize) {
|
|
662
689
|
output = this.sanitizeOutput(output);
|
|
@@ -985,56 +1012,6 @@ export default class PurchaseOrders extends Command {
|
|
|
985
1012
|
return `\$${op}`;
|
|
986
1013
|
return opRe.test(rest) ? `\$${op}:${this.parseFilterValue(rest)}` : `\$${op}:${rest}`;
|
|
987
1014
|
}
|
|
988
|
-
filterFields(data, fields) {
|
|
989
|
-
const isUnsafeKey = (k) => k === '__proto__' || k === 'constructor' || k === 'prototype';
|
|
990
|
-
const pick = (obj, keys) => {
|
|
991
|
-
// Group keys by their first segment so sibling sub-paths
|
|
992
|
-
// (e.g. 'items.amount' + 'items._type') resolve in one recursive pass
|
|
993
|
-
// and don't clobber each other on merge.
|
|
994
|
-
const directKeys = new Set();
|
|
995
|
-
const nestedKeys = new Map();
|
|
996
|
-
for (const key of keys) {
|
|
997
|
-
if (key.split('.').some(isUnsafeKey))
|
|
998
|
-
continue;
|
|
999
|
-
if (key.includes('.')) {
|
|
1000
|
-
const [first, ...rest] = key.split('.');
|
|
1001
|
-
if (isUnsafeKey(first))
|
|
1002
|
-
continue;
|
|
1003
|
-
const list = nestedKeys.get(first);
|
|
1004
|
-
if (list) {
|
|
1005
|
-
list.push(rest.join('.'));
|
|
1006
|
-
}
|
|
1007
|
-
else {
|
|
1008
|
-
nestedKeys.set(first, [rest.join('.')]);
|
|
1009
|
-
}
|
|
1010
|
-
}
|
|
1011
|
-
else {
|
|
1012
|
-
directKeys.add(key);
|
|
1013
|
-
}
|
|
1014
|
-
}
|
|
1015
|
-
const result = {};
|
|
1016
|
-
for (const key of directKeys) {
|
|
1017
|
-
if (key in obj)
|
|
1018
|
-
result[key] = obj[key];
|
|
1019
|
-
}
|
|
1020
|
-
for (const [first, restKeys] of nestedKeys) {
|
|
1021
|
-
const val = obj[first];
|
|
1022
|
-
if (!val || typeof val !== 'object')
|
|
1023
|
-
continue;
|
|
1024
|
-
if (Array.isArray(val)) {
|
|
1025
|
-
result[first] = val.map(item => pick(item, restKeys));
|
|
1026
|
-
}
|
|
1027
|
-
else {
|
|
1028
|
-
result[first] = pick(val, restKeys);
|
|
1029
|
-
}
|
|
1030
|
-
}
|
|
1031
|
-
return result;
|
|
1032
|
-
};
|
|
1033
|
-
if (Array.isArray(data)) {
|
|
1034
|
-
return data.map(item => pick(item, fields));
|
|
1035
|
-
}
|
|
1036
|
-
return pick(data, fields);
|
|
1037
|
-
}
|
|
1038
1015
|
sanitizeOutput(data) {
|
|
1039
1016
|
const auditFields = ['_type', 'tenantId', 'createdAt', 'updatedAt', 'createdBy', 'updatedBy'];
|
|
1040
1017
|
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
package/dist/commands/reports.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Command, Args, Flags } from '@oclif/core';
|
|
2
|
-
import { apiRequest, ApiError, normalizeSortBy } from '../lib/api-client.js';
|
|
2
|
+
import { apiRequest, ApiError, isTextualMediaType, normalizeSortBy } from '../lib/api-client.js';
|
|
3
3
|
import { getCurrentContext, getContext, getBaseUrls, hasCredentials, missingCredentialsMessage } from '../lib/config.js';
|
|
4
4
|
// Add 'import' action if both create and update exist
|
|
5
5
|
const HAS_IMPORT = false;
|
|
@@ -8,11 +8,11 @@ const HAS_CAMT053 = false;
|
|
|
8
8
|
const NESTED_IMPORTS = [];
|
|
9
9
|
const SUBCOMMANDS = [...["profit-and-loss", "balance-sheet", "gl-detail", "gl-detail-export-xlsx", "gl-detail-export-pdf"], ...(HAS_IMPORT ? ['import'] : []), ...(HAS_EXPORT ? ['export'] : []), ...NESTED_IMPORTS.map(n => `import-${n}`)];
|
|
10
10
|
const ENDPOINTS = {
|
|
11
|
-
'profit-and-loss': { method: '
|
|
12
|
-
'balance-sheet': { method: 'GET', path: '/v1/reports/balance-sheet', summary: 'Generate Balance Sheet report', pathParams: [], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
|
|
13
|
-
'gl-detail': { method: 'POST', path: '/v1/reports/gl-detail', summary: 'Get GL Detail report', pathParams: [], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: ['accountIds', 'accountCodes'] },
|
|
14
|
-
'gl-detail-export-xlsx': { method: 'POST', path: '/v1/reports/gl-detail/export/xlsx', summary: 'Export GL Detail report as Excel (one sheet per account)', pathParams: [], hasBody: true, isMultipart: false, isBinaryResponse: true, bodyArrayFields: ['accountIds', 'accountCodes'] },
|
|
15
|
-
'gl-detail-export-pdf': { method: 'POST', path: '/v1/reports/gl-detail/export/pdf', summary: 'Export GL Detail report as PDF (one page per account)', pathParams: [], hasBody: true, isMultipart: false, isBinaryResponse: true, bodyArrayFields: ['accountIds', 'accountCodes'] },
|
|
11
|
+
'profit-and-loss': { method: 'POST', path: '/v1/reports/profit-and-loss', summary: 'Get Profit & Loss report', pathParams: [], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: true, bodyArrayFields: ['ledgerIds', 'periods'] },
|
|
12
|
+
'balance-sheet': { method: 'GET', path: '/v1/reports/balance-sheet', summary: 'Generate Balance Sheet report', pathParams: [], hasBody: false, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: [] },
|
|
13
|
+
'gl-detail': { method: 'POST', path: '/v1/reports/gl-detail', summary: 'Get GL Detail report', pathParams: [], hasBody: true, isMultipart: false, isBinaryResponse: false, hasBinaryVariant: false, bodyArrayFields: ['accountIds', 'accountCodes'] },
|
|
14
|
+
'gl-detail-export-xlsx': { method: 'POST', path: '/v1/reports/gl-detail/export/xlsx', summary: 'Export GL Detail report as Excel (one sheet per account)', pathParams: [], hasBody: true, isMultipart: false, isBinaryResponse: true, hasBinaryVariant: false, bodyArrayFields: ['accountIds', 'accountCodes'] },
|
|
15
|
+
'gl-detail-export-pdf': { method: 'POST', path: '/v1/reports/gl-detail/export/pdf', summary: 'Export GL Detail report as PDF (one page per account)', pathParams: [], hasBody: true, isMultipart: false, isBinaryResponse: true, hasBinaryVariant: false, bodyArrayFields: ['accountIds', 'accountCodes'] },
|
|
16
16
|
};
|
|
17
17
|
export default class Reports extends Command {
|
|
18
18
|
static description = 'Manage reports';
|
|
@@ -36,7 +36,7 @@ export default class Reports extends Command {
|
|
|
36
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
|
-
fields: Flags.string({ description: 'Comma-separated list of fields to
|
|
39
|
+
fields: Flags.string({ description: 'Comma-separated list of fields to return, applied by the API (e.g. --fields=id,name,status)' }),
|
|
40
40
|
sanitize: Flags.boolean({ description: 'Remove null values, audit fields, and duplicate UUIDs from output' }),
|
|
41
41
|
'show-http-request': Flags.boolean({ description: 'Show HTTP request details (method, URL, body)' }),
|
|
42
42
|
};
|
|
@@ -108,6 +108,8 @@ export default class Reports extends Command {
|
|
|
108
108
|
queryParams.search = flags.search;
|
|
109
109
|
if (flags['sort-by'])
|
|
110
110
|
queryParams.sortBy = normalizeSortBy(flags['sort-by']);
|
|
111
|
+
if (flags.fields)
|
|
112
|
+
queryParams.fields = flags.fields;
|
|
111
113
|
if (flags.query) {
|
|
112
114
|
try {
|
|
113
115
|
Object.assign(queryParams, JSON.parse(flags.query));
|
|
@@ -255,10 +257,11 @@ export default class Reports extends Command {
|
|
|
255
257
|
process.stderr.write('\n');
|
|
256
258
|
}
|
|
257
259
|
try {
|
|
258
|
-
// Binary response:
|
|
260
|
+
// Binary response: to -f / --file, or to stdout when it is redirected.
|
|
259
261
|
if (endpoint.isBinaryResponse) {
|
|
260
|
-
|
|
261
|
-
|
|
262
|
+
const toStdout = !flags.file;
|
|
263
|
+
if (toStdout && process.stdout.isTTY) {
|
|
264
|
+
this.error(`Endpoint returns a binary file. Specify the output path with -f / --file (e.g. -f report.xlsx), or redirect stdout to a file.`);
|
|
262
265
|
}
|
|
263
266
|
const binResponse = await apiRequest(endpoint.method, apiPath, {
|
|
264
267
|
params: Object.keys(queryParams).length > 0 ? queryParams : undefined,
|
|
@@ -266,24 +269,55 @@ export default class Reports extends Command {
|
|
|
266
269
|
contextName: flags.context,
|
|
267
270
|
binary: true,
|
|
268
271
|
});
|
|
269
|
-
const fsModule = await import('node:fs');
|
|
270
272
|
const binData = binResponse.data;
|
|
271
273
|
const buffer = Buffer.isBuffer(binData)
|
|
272
274
|
? binData
|
|
273
275
|
: Buffer.from(binData);
|
|
276
|
+
if (toStdout) {
|
|
277
|
+
// Nothing else may reach stdout here — it is the file.
|
|
278
|
+
process.stdout.write(buffer);
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
const fsModule = await import('node:fs');
|
|
274
282
|
fsModule.writeFileSync(flags.file, buffer);
|
|
275
283
|
this.log(`Saved ${buffer.length} bytes to ${flags.file}`);
|
|
276
284
|
return;
|
|
277
285
|
}
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
286
|
+
let response;
|
|
287
|
+
if (endpoint.hasBinaryVariant) {
|
|
288
|
+
// This route answers JSON or a file depending on the request body, so the
|
|
289
|
+
// bytes are read first and the response's own content-type decides. Asking
|
|
290
|
+
// for text here would corrupt an xlsx/pdf before anything could inspect it.
|
|
291
|
+
const raw = await apiRequest(endpoint.method, apiPath, {
|
|
292
|
+
params: Object.keys(queryParams).length > 0 ? queryParams : undefined,
|
|
293
|
+
data,
|
|
294
|
+
contextName: flags.context,
|
|
295
|
+
binary: true,
|
|
296
|
+
});
|
|
297
|
+
const rawType = String(raw.headers['content-type'] || '').toLowerCase();
|
|
298
|
+
const rawData = raw.data;
|
|
299
|
+
const buffer = Buffer.isBuffer(rawData) ? rawData : Buffer.from(rawData);
|
|
300
|
+
if (!isTextualMediaType(rawType)) {
|
|
301
|
+
if (process.stdout.isTTY) {
|
|
302
|
+
this.error(`The API returned ${rawType || 'binary data'}. Redirect stdout to a file, e.g. ... > report.xlsx`);
|
|
303
|
+
}
|
|
304
|
+
// Nothing else may reach stdout here — it is the file.
|
|
305
|
+
process.stdout.write(buffer);
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
response = { data: buffer.toString('utf8'), headers: raw.headers, status: raw.status };
|
|
309
|
+
}
|
|
310
|
+
else {
|
|
311
|
+
response = await apiRequest(endpoint.method, apiPath, {
|
|
312
|
+
params: Object.keys(queryParams).length > 0 ? queryParams : undefined,
|
|
313
|
+
data,
|
|
314
|
+
contextName: flags.context,
|
|
315
|
+
acceptAny: true,
|
|
316
|
+
});
|
|
317
|
+
}
|
|
284
318
|
// Check content-type for non-JSON responses (XML, text, etc.)
|
|
285
319
|
const contentType = (response.headers['content-type'] || '').toLowerCase();
|
|
286
|
-
if (contentType
|
|
320
|
+
if (isTextualMediaType(contentType) && !contentType.startsWith('application/json')) {
|
|
287
321
|
// Output raw content for XML/text responses (CSV, plain, HTML, etc.)
|
|
288
322
|
this.log(String(response.data));
|
|
289
323
|
return;
|
|
@@ -310,11 +344,6 @@ export default class Reports extends Command {
|
|
|
310
344
|
output = obj[arrayKeys[0]];
|
|
311
345
|
}
|
|
312
346
|
}
|
|
313
|
-
// Filter fields if --fields flag is provided
|
|
314
|
-
if (flags.fields) {
|
|
315
|
-
const fieldList = flags.fields.split(',').map(f => f.trim());
|
|
316
|
-
output = this.filterFields(output, fieldList);
|
|
317
|
-
}
|
|
318
347
|
// Sanitize output if requested
|
|
319
348
|
if (flags.sanitize) {
|
|
320
349
|
output = this.sanitizeOutput(output);
|
|
@@ -569,6 +598,8 @@ export default class Reports extends Command {
|
|
|
569
598
|
baseParams.sortBy = normalizeSortBy(flags['sort-by']);
|
|
570
599
|
if (flags.include)
|
|
571
600
|
baseParams.include = flags.include;
|
|
601
|
+
if (flags.fields)
|
|
602
|
+
baseParams.fields = flags.fields;
|
|
572
603
|
if (flags.query) {
|
|
573
604
|
try {
|
|
574
605
|
Object.assign(baseParams, JSON.parse(flags.query));
|
|
@@ -623,12 +654,7 @@ export default class Reports extends Command {
|
|
|
623
654
|
}
|
|
624
655
|
}
|
|
625
656
|
process.stderr.write(' done\n');
|
|
626
|
-
// Filter fields if specified
|
|
627
657
|
let output = allItems;
|
|
628
|
-
if (flags.fields) {
|
|
629
|
-
const fieldList = flags.fields.split(',').map(f => f.trim());
|
|
630
|
-
output = this.filterFields(allItems, fieldList);
|
|
631
|
-
}
|
|
632
658
|
// Sanitize output if requested
|
|
633
659
|
if (flags.sanitize) {
|
|
634
660
|
output = this.sanitizeOutput(output);
|
|
@@ -957,56 +983,6 @@ export default class Reports extends Command {
|
|
|
957
983
|
return `\$${op}`;
|
|
958
984
|
return opRe.test(rest) ? `\$${op}:${this.parseFilterValue(rest)}` : `\$${op}:${rest}`;
|
|
959
985
|
}
|
|
960
|
-
filterFields(data, fields) {
|
|
961
|
-
const isUnsafeKey = (k) => k === '__proto__' || k === 'constructor' || k === 'prototype';
|
|
962
|
-
const pick = (obj, keys) => {
|
|
963
|
-
// Group keys by their first segment so sibling sub-paths
|
|
964
|
-
// (e.g. 'items.amount' + 'items._type') resolve in one recursive pass
|
|
965
|
-
// and don't clobber each other on merge.
|
|
966
|
-
const directKeys = new Set();
|
|
967
|
-
const nestedKeys = new Map();
|
|
968
|
-
for (const key of keys) {
|
|
969
|
-
if (key.split('.').some(isUnsafeKey))
|
|
970
|
-
continue;
|
|
971
|
-
if (key.includes('.')) {
|
|
972
|
-
const [first, ...rest] = key.split('.');
|
|
973
|
-
if (isUnsafeKey(first))
|
|
974
|
-
continue;
|
|
975
|
-
const list = nestedKeys.get(first);
|
|
976
|
-
if (list) {
|
|
977
|
-
list.push(rest.join('.'));
|
|
978
|
-
}
|
|
979
|
-
else {
|
|
980
|
-
nestedKeys.set(first, [rest.join('.')]);
|
|
981
|
-
}
|
|
982
|
-
}
|
|
983
|
-
else {
|
|
984
|
-
directKeys.add(key);
|
|
985
|
-
}
|
|
986
|
-
}
|
|
987
|
-
const result = {};
|
|
988
|
-
for (const key of directKeys) {
|
|
989
|
-
if (key in obj)
|
|
990
|
-
result[key] = obj[key];
|
|
991
|
-
}
|
|
992
|
-
for (const [first, restKeys] of nestedKeys) {
|
|
993
|
-
const val = obj[first];
|
|
994
|
-
if (!val || typeof val !== 'object')
|
|
995
|
-
continue;
|
|
996
|
-
if (Array.isArray(val)) {
|
|
997
|
-
result[first] = val.map(item => pick(item, restKeys));
|
|
998
|
-
}
|
|
999
|
-
else {
|
|
1000
|
-
result[first] = pick(val, restKeys);
|
|
1001
|
-
}
|
|
1002
|
-
}
|
|
1003
|
-
return result;
|
|
1004
|
-
};
|
|
1005
|
-
if (Array.isArray(data)) {
|
|
1006
|
-
return data.map(item => pick(item, fields));
|
|
1007
|
-
}
|
|
1008
|
-
return pick(data, fields);
|
|
1009
|
-
}
|
|
1010
986
|
sanitizeOutput(data) {
|
|
1011
987
|
const auditFields = ['_type', 'tenantId', 'createdAt', 'updatedAt', 'createdBy', 'updatedBy'];
|
|
1012
988
|
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
export default class Roles 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 sanitizeOutput;
|
|
35
|
+
private getColumns;
|
|
36
|
+
private getValue;
|
|
37
|
+
private printTable;
|
|
38
|
+
private printCsv;
|
|
39
|
+
}
|