@aderis-erp/cli 1.0.9 → 1.0.11
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 +1 -0
- package/dist/commands/access-groups.js +196 -92
- package/dist/commands/account-transaction-allocations.js +196 -92
- package/dist/commands/account-transactions.js +199 -93
- package/dist/commands/accounts.js +196 -92
- package/dist/commands/agent-runs.d.ts +1 -0
- package/dist/commands/agent-runs.js +201 -93
- package/dist/commands/audit-log.js +196 -92
- package/dist/commands/auth/login.js +4 -3
- package/dist/commands/bank-accounts.js +196 -92
- package/dist/commands/bank-integrations.js +196 -92
- package/dist/commands/business-partners.js +196 -92
- package/dist/commands/config/add.js +4 -3
- package/dist/commands/credit-card-accounts.js +196 -92
- package/dist/commands/documents.js +196 -92
- package/dist/commands/dunning-configs.js +198 -94
- package/dist/commands/dunning-reminders.js +196 -92
- package/dist/commands/dunning-runs.js +196 -92
- package/dist/commands/employees.js +198 -94
- package/dist/commands/entity-configurations.d.ts +40 -0
- package/dist/commands/entity-configurations.js +1169 -0
- package/dist/commands/event-processor-mappings.js +196 -92
- package/dist/commands/files-internal.js +196 -92
- package/dist/commands/health.js +196 -92
- package/dist/commands/inbox.js +199 -95
- package/dist/commands/integrations.js +196 -92
- package/dist/commands/item-categories.js +196 -92
- package/dist/commands/items.js +196 -92
- package/dist/commands/journal-lines.js +196 -92
- package/dist/commands/journals.js +196 -92
- package/dist/commands/ledgers.js +196 -92
- package/dist/commands/office-locations.js +196 -92
- package/dist/commands/payment-methods.js +196 -92
- package/dist/commands/payment-runs.js +196 -92
- package/dist/commands/payment-terms.js +196 -92
- package/dist/commands/price-lists.js +196 -92
- package/dist/commands/processor-mappings.js +196 -92
- package/dist/commands/processors.js +199 -93
- package/dist/commands/purchase-order-types.d.ts +40 -0
- package/dist/commands/purchase-order-types.js +1178 -0
- package/dist/commands/purchase-orders.d.ts +40 -0
- package/dist/commands/purchase-orders.js +1182 -0
- package/dist/commands/reports.js +196 -92
- package/dist/commands/salary-types.js +196 -92
- package/dist/commands/sales-invoices.js +196 -92
- package/dist/commands/sales-orders.js +200 -95
- package/dist/commands/saved-views.js +196 -92
- package/dist/commands/tags.js +196 -92
- package/dist/commands/tax-codes.js +196 -92
- package/dist/commands/tax-matrix.js +196 -92
- package/dist/commands/tenants.js +196 -92
- package/dist/commands/text-templates.js +196 -92
- package/dist/commands/tools.js +196 -92
- package/dist/commands/vat-declarations.d.ts +1 -0
- package/dist/commands/vat-declarations.js +206 -95
- package/dist/commands/vendor-invoices.js +196 -92
- package/dist/commands/webhooks.js +196 -92
- package/dist/commands/workflows.js +196 -92
- package/dist/lib/auth.js +2 -2
- package/dist/lib/config.d.ts +1 -1
- package/dist/lib/config.js +5 -0
- package/oclif.manifest.json +516 -9
- package/package.json +1 -1
|
@@ -6,7 +6,7 @@ const HAS_IMPORT = true;
|
|
|
6
6
|
const HAS_EXPORT = true;
|
|
7
7
|
const HAS_CAMT053 = false;
|
|
8
8
|
const NESTED_IMPORTS = [];
|
|
9
|
-
const SUBCOMMANDS = [...["list-tools", "list", "create", "resolve", "resolve-event", "get", "update", "delete", "template"], ...(HAS_IMPORT ? ['import'] : []), ...(HAS_EXPORT ? ['export'] : []), ...NESTED_IMPORTS.map(n => `import-${n}`)];
|
|
9
|
+
const SUBCOMMANDS = [...["list-tools", "list", "create", "resolve", "resolve-event", "get", "update", "delete", "template", "update-config", "delete-config"], ...(HAS_IMPORT ? ['import'] : []), ...(HAS_EXPORT ? ['export'] : []), ...NESTED_IMPORTS.map(n => `import-${n}`)];
|
|
10
10
|
const ENDPOINTS = {
|
|
11
11
|
'list-tools': { method: 'GET', path: '/v1/processors/tools', summary: 'List all available tools', pathParams: [], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
|
|
12
12
|
'list': { method: 'GET', path: '/v1/processors', summary: 'List processors available to the tenant', pathParams: [], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
|
|
@@ -17,6 +17,8 @@ const ENDPOINTS = {
|
|
|
17
17
|
'update': { method: 'PATCH', path: '/v1/processors/{id}', summary: 'Update a tenant-scoped processor', pathParams: ['id'], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: ['processorTools', 'options'] },
|
|
18
18
|
'delete': { method: 'DELETE', path: '/v1/processors/{id}', summary: 'Delete a tenant-scoped processor', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
|
|
19
19
|
'template': { method: 'POST', path: '/v1/processors/{id}/template', summary: 'Upload a PDF template for a processor', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
|
|
20
|
+
'update-config': { method: 'PUT', path: '/v1/processors/{id}/config', summary: 'Set or replace a tenant prompt overlay on a system processor', pathParams: ['id'], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
|
|
21
|
+
'delete-config': { method: 'DELETE', path: '/v1/processors/{id}/config', summary: 'Remove the tenant prompt overlay on a system processor', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
|
|
20
22
|
};
|
|
21
23
|
export default class Processors extends Command {
|
|
22
24
|
static description = 'Manage processors';
|
|
@@ -435,76 +437,126 @@ export default class Processors extends Command {
|
|
|
435
437
|
return '';
|
|
436
438
|
};
|
|
437
439
|
const results = [];
|
|
438
|
-
|
|
440
|
+
// Stream output row-by-row so progress is visible during long imports.
|
|
441
|
+
// Pre-compute the identifier column width from the input items so the
|
|
442
|
+
// table stays aligned without buffering all rows.
|
|
443
|
+
// When stdout is piped (IDE terminals, tee, CI), Node switches to async-buffered
|
|
444
|
+
// mode and rows accumulate in the pipe buffer until it fills. Force blocking
|
|
445
|
+
// mode so each \n-terminated write flushes immediately.
|
|
446
|
+
const stdoutHandle = process.stdout._handle;
|
|
447
|
+
if (stdoutHandle?.setBlocking)
|
|
448
|
+
stdoutHandle.setBlocking(true);
|
|
449
|
+
const outputFormat = flags.output || 'table';
|
|
450
|
+
const useCsv = outputFormat === 'csv' || Boolean(flags.csv);
|
|
451
|
+
const useJson = outputFormat === 'json';
|
|
452
|
+
const statusWidth = 8;
|
|
453
|
+
const identifierWidth = Math.max(10, ...items.map(i => getItemIdentifier(i).length));
|
|
454
|
+
if (useCsv) {
|
|
455
|
+
this.log('status,identifier,id,error');
|
|
456
|
+
}
|
|
457
|
+
else if (!useJson) {
|
|
458
|
+
this.log(`${'status'.padEnd(statusWidth)} ${'identifier'.padEnd(identifierWidth)} error`);
|
|
459
|
+
this.log(`${'-'.repeat(statusWidth)} ${'-'.repeat(identifierWidth)} ${'-'.repeat(50)}`);
|
|
460
|
+
}
|
|
461
|
+
const emitRow = (r) => {
|
|
462
|
+
if (useJson)
|
|
463
|
+
return;
|
|
464
|
+
if (useCsv) {
|
|
465
|
+
const err = (r.error || '').replace(/"/g, '""');
|
|
466
|
+
this.log(`${r.status},${r.identifier || ''},${r.id || ''},"${err}"`);
|
|
467
|
+
}
|
|
468
|
+
else {
|
|
469
|
+
this.log(`${r.status.padEnd(statusWidth)} ${(r.identifier || '').padEnd(identifierWidth)} ${r.error || ''}`);
|
|
470
|
+
}
|
|
471
|
+
};
|
|
472
|
+
// Server-managed fields the API rejects in create/update bodies. Stripped
|
|
473
|
+
// before every request so re-importing a previously-exported payload Just Works.
|
|
474
|
+
const STRIP_FIELDS = new Set(['id', '_type', 'tenantId', 'createdAt', 'updatedAt', 'createdBy', 'updatedBy']);
|
|
475
|
+
const stripServerFields = (item) => {
|
|
476
|
+
const out = {};
|
|
477
|
+
for (const [k, v] of Object.entries(item)) {
|
|
478
|
+
if (!STRIP_FIELDS.has(k))
|
|
479
|
+
out[k] = v;
|
|
480
|
+
}
|
|
481
|
+
return out;
|
|
482
|
+
};
|
|
483
|
+
const processItem = async (item) => {
|
|
439
484
|
const identifier = getItemIdentifier(item);
|
|
485
|
+
const body = stripServerFields(item);
|
|
486
|
+
// If the payload carries an id (e.g. re-importing an export), PATCH directly.
|
|
487
|
+
// Fall through to POST only on 404 (so a missing record still gets created).
|
|
488
|
+
const itemId = typeof item.id === 'string' ? item.id : undefined;
|
|
489
|
+
if (itemId) {
|
|
490
|
+
try {
|
|
491
|
+
const updatePath = updateEndpoint.path.replace('{id}', itemId);
|
|
492
|
+
await apiRequest('PATCH', updatePath, {
|
|
493
|
+
data: body,
|
|
494
|
+
contextName: flags.context,
|
|
495
|
+
});
|
|
496
|
+
return { status: 'updated', id: itemId, identifier };
|
|
497
|
+
}
|
|
498
|
+
catch (error) {
|
|
499
|
+
if (!(error instanceof ApiError && error.status === 404)) {
|
|
500
|
+
const msg = error instanceof ApiError ? `(${error.status}) ${error.message}` : String(error);
|
|
501
|
+
return { status: 'error', id: itemId, identifier, error: msg };
|
|
502
|
+
}
|
|
503
|
+
// 404 → record gone, try create below
|
|
504
|
+
}
|
|
505
|
+
}
|
|
440
506
|
try {
|
|
441
|
-
// Try to create
|
|
442
507
|
const response = await apiRequest('POST', createEndpoint.path, {
|
|
443
|
-
data:
|
|
508
|
+
data: body,
|
|
444
509
|
contextName: flags.context,
|
|
445
510
|
});
|
|
446
511
|
const id = response.data?.id;
|
|
447
|
-
|
|
512
|
+
return { status: 'created', id: id ? String(id) : undefined, identifier };
|
|
448
513
|
}
|
|
449
514
|
catch (error) {
|
|
450
515
|
if (error instanceof ApiError && error.status === 409) {
|
|
451
|
-
// Conflict - try to update existing
|
|
452
516
|
const errorData = error.data;
|
|
453
517
|
const existingId = errorData?.existingId;
|
|
454
518
|
if (existingId) {
|
|
455
519
|
try {
|
|
456
520
|
const updatePath = updateEndpoint.path.replace('{id}', existingId);
|
|
457
521
|
await apiRequest('PATCH', updatePath, {
|
|
458
|
-
data:
|
|
522
|
+
data: body,
|
|
459
523
|
contextName: flags.context,
|
|
460
524
|
});
|
|
461
|
-
|
|
525
|
+
return { status: 'updated', id: existingId, identifier };
|
|
462
526
|
}
|
|
463
527
|
catch (updateError) {
|
|
464
528
|
const msg = updateError instanceof ApiError ? updateError.message : String(updateError);
|
|
465
|
-
|
|
529
|
+
return { status: 'error', id: existingId, identifier, error: `Update failed: ${msg}` };
|
|
466
530
|
}
|
|
467
531
|
}
|
|
468
|
-
|
|
469
|
-
results.push({ status: 'error', identifier, error: 'Conflict but no existingId returned' });
|
|
470
|
-
}
|
|
471
|
-
}
|
|
472
|
-
else {
|
|
473
|
-
const msg = error instanceof ApiError ? `(${error.status}) ${error.message}` : String(error);
|
|
474
|
-
results.push({ status: 'error', identifier, error: msg });
|
|
532
|
+
return { status: 'error', identifier, error: 'Conflict but no existingId returned' };
|
|
475
533
|
}
|
|
534
|
+
const msg = error instanceof ApiError ? `(${error.status}) ${error.message}` : String(error);
|
|
535
|
+
return { status: 'error', identifier, error: msg };
|
|
476
536
|
}
|
|
477
|
-
}
|
|
537
|
+
};
|
|
538
|
+
// Worker pool: keep N requests in flight at all times. Rows are emitted as
|
|
539
|
+
// each request resolves (so output order may differ from input order). The
|
|
540
|
+
// summary at the end remains accurate regardless.
|
|
541
|
+
const concurrency = 4;
|
|
542
|
+
const queue = [...items];
|
|
543
|
+
await Promise.all(Array.from({ length: Math.min(concurrency, queue.length) }, async () => {
|
|
544
|
+
for (;;) {
|
|
545
|
+
const item = queue.shift();
|
|
546
|
+
if (!item)
|
|
547
|
+
return;
|
|
548
|
+
const r = await processItem(item);
|
|
549
|
+
results.push(r);
|
|
550
|
+
emitRow(r);
|
|
551
|
+
}
|
|
552
|
+
}));
|
|
478
553
|
// Summary counts
|
|
479
554
|
const created = results.filter(r => r.status === 'created').length;
|
|
480
555
|
const updated = results.filter(r => r.status === 'updated').length;
|
|
481
556
|
const errors = results.filter(r => r.status === 'error');
|
|
482
|
-
|
|
483
|
-
const outputFormat = flags.output || 'table';
|
|
484
|
-
if (outputFormat === 'json') {
|
|
557
|
+
if (useJson) {
|
|
485
558
|
this.log(JSON.stringify(results, null, 2));
|
|
486
559
|
}
|
|
487
|
-
else if (outputFormat === 'csv' || flags.csv) {
|
|
488
|
-
// CSV output
|
|
489
|
-
this.log('status,identifier,id,error');
|
|
490
|
-
for (const r of results) {
|
|
491
|
-
const err = (r.error || '').replace(/"/g, '""');
|
|
492
|
-
this.log(`${r.status},${r.identifier || ''},${r.id || ''},"${err}"`);
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
|
-
else {
|
|
496
|
-
// Table output (default)
|
|
497
|
-
if (results.length > 0) {
|
|
498
|
-
const statusWidth = 8;
|
|
499
|
-
const identifierWidth = Math.max(10, ...results.map(r => (r.identifier || '').length));
|
|
500
|
-
this.log(`${'status'.padEnd(statusWidth)} ${'identifier'.padEnd(identifierWidth)} error`);
|
|
501
|
-
this.log(`${'-'.repeat(statusWidth)} ${'-'.repeat(identifierWidth)} ${'-'.repeat(50)}`);
|
|
502
|
-
for (const r of results) {
|
|
503
|
-
const status = r.status === 'created' ? 'created' : r.status === 'updated' ? 'updated' : 'error';
|
|
504
|
-
this.log(`${status.padEnd(statusWidth)} ${(r.identifier || '').padEnd(identifierWidth)} ${r.error || ''}`);
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
560
|
// Always show summary at the end
|
|
509
561
|
this.log('');
|
|
510
562
|
this.log(`Summary: ${created} created, ${updated} updated, ${errors.length} failed`);
|
|
@@ -784,80 +836,122 @@ export default class Processors extends Command {
|
|
|
784
836
|
return '';
|
|
785
837
|
};
|
|
786
838
|
const results = [];
|
|
787
|
-
|
|
839
|
+
const stdoutHandle = process.stdout._handle;
|
|
840
|
+
if (stdoutHandle?.setBlocking)
|
|
841
|
+
stdoutHandle.setBlocking(true);
|
|
842
|
+
const outputFormat = flags.output || 'table';
|
|
843
|
+
const useCsv = outputFormat === 'csv' || Boolean(flags.csv);
|
|
844
|
+
const useJson = outputFormat === 'json';
|
|
845
|
+
const statusWidth = 8;
|
|
846
|
+
const identifierWidth = Math.max(10, ...items.map(i => getItemIdentifier(i).length));
|
|
847
|
+
if (useCsv) {
|
|
848
|
+
this.log('status,identifier,id,error');
|
|
849
|
+
}
|
|
850
|
+
else if (!useJson) {
|
|
851
|
+
this.log(`${'status'.padEnd(statusWidth)} ${'identifier'.padEnd(identifierWidth)} error`);
|
|
852
|
+
this.log(`${'-'.repeat(statusWidth)} ${'-'.repeat(identifierWidth)} ${'-'.repeat(50)}`);
|
|
853
|
+
}
|
|
854
|
+
const emitRow = (r) => {
|
|
855
|
+
if (useJson)
|
|
856
|
+
return;
|
|
857
|
+
if (useCsv) {
|
|
858
|
+
const err = (r.error || '').replace(/"/g, '""');
|
|
859
|
+
this.log(`${r.status},${r.identifier || ''},${r.id || ''},"${err}"`);
|
|
860
|
+
}
|
|
861
|
+
else {
|
|
862
|
+
this.log(`${r.status.padEnd(statusWidth)} ${(r.identifier || '').padEnd(identifierWidth)} ${r.error || ''}`);
|
|
863
|
+
}
|
|
864
|
+
};
|
|
865
|
+
const STRIP_FIELDS = new Set(['id', '_type', 'tenantId', 'createdAt', 'updatedAt', 'createdBy', 'updatedBy']);
|
|
866
|
+
const stripServerFields = (item) => {
|
|
867
|
+
const out = {};
|
|
868
|
+
for (const [k, v] of Object.entries(item)) {
|
|
869
|
+
if (!STRIP_FIELDS.has(k))
|
|
870
|
+
out[k] = v;
|
|
871
|
+
}
|
|
872
|
+
return out;
|
|
873
|
+
};
|
|
874
|
+
const buildUpdatePath = (existingId) => {
|
|
875
|
+
const firstUpdateParam = updateEndpoint.pathParams[0];
|
|
876
|
+
const nestedIdParam = updateEndpoint.pathParams.find((p, i) => i > 0);
|
|
877
|
+
let updatePath = updateEndpoint.path.replace(`{${firstUpdateParam}}`, parentId);
|
|
878
|
+
if (nestedIdParam) {
|
|
879
|
+
updatePath = updatePath.replace(`{${nestedIdParam}}`, existingId);
|
|
880
|
+
}
|
|
881
|
+
return updatePath;
|
|
882
|
+
};
|
|
883
|
+
const processItem = async (item) => {
|
|
788
884
|
const identifier = getItemIdentifier(item);
|
|
885
|
+
const body = stripServerFields(item);
|
|
886
|
+
const itemId = typeof item.id === 'string' ? item.id : undefined;
|
|
887
|
+
if (itemId) {
|
|
888
|
+
try {
|
|
889
|
+
await apiRequest('PATCH', buildUpdatePath(itemId), {
|
|
890
|
+
data: body,
|
|
891
|
+
contextName: flags.context,
|
|
892
|
+
});
|
|
893
|
+
return { status: 'updated', id: itemId, identifier };
|
|
894
|
+
}
|
|
895
|
+
catch (error) {
|
|
896
|
+
if (!(error instanceof ApiError && error.status === 404)) {
|
|
897
|
+
const msg = error instanceof ApiError ? `(${error.status}) ${error.message}` : String(error);
|
|
898
|
+
return { status: 'error', id: itemId, identifier, error: msg };
|
|
899
|
+
}
|
|
900
|
+
// 404 → fall through and try create
|
|
901
|
+
}
|
|
902
|
+
}
|
|
789
903
|
try {
|
|
790
|
-
// Try to create
|
|
791
904
|
const response = await apiRequest('POST', basePath, {
|
|
792
|
-
data:
|
|
905
|
+
data: body,
|
|
793
906
|
contextName: flags.context,
|
|
794
907
|
});
|
|
795
908
|
const id = response.data?.id;
|
|
796
|
-
|
|
909
|
+
return { status: 'created', id: id ? String(id) : undefined, identifier };
|
|
797
910
|
}
|
|
798
911
|
catch (error) {
|
|
799
912
|
if (error instanceof ApiError && error.status === 409) {
|
|
800
|
-
// Conflict - try to update existing
|
|
801
913
|
const errorData = error.data;
|
|
802
914
|
const existingId = errorData?.existingId || item.id;
|
|
803
915
|
if (existingId) {
|
|
804
916
|
try {
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
const nestedIdParam = updateEndpoint.pathParams.find((p, i) => i > 0);
|
|
808
|
-
let updatePath = updateEndpoint.path.replace(`{${firstUpdateParam}}`, parentId);
|
|
809
|
-
if (nestedIdParam) {
|
|
810
|
-
updatePath = updatePath.replace(`{${nestedIdParam}}`, existingId);
|
|
811
|
-
}
|
|
812
|
-
await apiRequest('PATCH', updatePath, {
|
|
813
|
-
data: item,
|
|
917
|
+
await apiRequest('PATCH', buildUpdatePath(existingId), {
|
|
918
|
+
data: body,
|
|
814
919
|
contextName: flags.context,
|
|
815
920
|
});
|
|
816
|
-
|
|
921
|
+
return { status: 'updated', id: existingId, identifier };
|
|
817
922
|
}
|
|
818
923
|
catch (updateError) {
|
|
819
924
|
const msg = updateError instanceof ApiError ? updateError.message : String(updateError);
|
|
820
|
-
|
|
925
|
+
return { status: 'error', id: existingId, identifier, error: `Update failed: ${msg}` };
|
|
821
926
|
}
|
|
822
927
|
}
|
|
823
|
-
|
|
824
|
-
results.push({ status: 'error', identifier, error: 'Conflict but no existingId returned' });
|
|
825
|
-
}
|
|
826
|
-
}
|
|
827
|
-
else {
|
|
828
|
-
const msg = error instanceof ApiError ? `(${error.status}) ${error.message}` : String(error);
|
|
829
|
-
results.push({ status: 'error', identifier, error: msg });
|
|
928
|
+
return { status: 'error', identifier, error: 'Conflict but no existingId returned' };
|
|
830
929
|
}
|
|
930
|
+
const msg = error instanceof ApiError ? `(${error.status}) ${error.message}` : String(error);
|
|
931
|
+
return { status: 'error', identifier, error: msg };
|
|
831
932
|
}
|
|
832
|
-
}
|
|
933
|
+
};
|
|
934
|
+
// Worker pool: 4 requests in flight at a time. Rows are emitted as each
|
|
935
|
+
// request resolves so output order may differ from input order.
|
|
936
|
+
const concurrency = 4;
|
|
937
|
+
const queue = [...items];
|
|
938
|
+
await Promise.all(Array.from({ length: Math.min(concurrency, queue.length) }, async () => {
|
|
939
|
+
for (;;) {
|
|
940
|
+
const item = queue.shift();
|
|
941
|
+
if (!item)
|
|
942
|
+
return;
|
|
943
|
+
const r = await processItem(item);
|
|
944
|
+
results.push(r);
|
|
945
|
+
emitRow(r);
|
|
946
|
+
}
|
|
947
|
+
}));
|
|
833
948
|
// Summary counts
|
|
834
949
|
const created = results.filter(r => r.status === 'created').length;
|
|
835
950
|
const updated = results.filter(r => r.status === 'updated').length;
|
|
836
951
|
const errors = results.filter(r => r.status === 'error');
|
|
837
|
-
|
|
838
|
-
const outputFormat = flags.output || 'table';
|
|
839
|
-
if (outputFormat === 'json') {
|
|
952
|
+
if (useJson) {
|
|
840
953
|
this.log(JSON.stringify(results, null, 2));
|
|
841
954
|
}
|
|
842
|
-
else if (outputFormat === 'csv' || flags.csv) {
|
|
843
|
-
this.log('status,identifier,id,error');
|
|
844
|
-
for (const r of results) {
|
|
845
|
-
const err = (r.error || '').replace(/"/g, '""');
|
|
846
|
-
this.log(`${r.status},${r.identifier || ''},${r.id || ''},"${err}"`);
|
|
847
|
-
}
|
|
848
|
-
}
|
|
849
|
-
else {
|
|
850
|
-
if (results.length > 0) {
|
|
851
|
-
const statusWidth = 8;
|
|
852
|
-
const identifierWidth = Math.max(10, ...results.map(r => (r.identifier || '').length));
|
|
853
|
-
this.log(`${'status'.padEnd(statusWidth)} ${'identifier'.padEnd(identifierWidth)} error`);
|
|
854
|
-
this.log(`${'-'.repeat(statusWidth)} ${'-'.repeat(identifierWidth)} ${'-'.repeat(50)}`);
|
|
855
|
-
for (const r of results) {
|
|
856
|
-
const status = r.status === 'created' ? 'created' : r.status === 'updated' ? 'updated' : 'error';
|
|
857
|
-
this.log(`${status.padEnd(statusWidth)} ${(r.identifier || '').padEnd(identifierWidth)} ${r.error || ''}`);
|
|
858
|
-
}
|
|
859
|
-
}
|
|
860
|
-
}
|
|
861
955
|
this.log('');
|
|
862
956
|
this.log(`Summary: ${created} created, ${updated} updated, ${errors.length} failed`);
|
|
863
957
|
}
|
|
@@ -1021,12 +1115,24 @@ export default class Processors extends Command {
|
|
|
1021
1115
|
return { cols: flatten ? cols : cols.slice(0, 8), items: items };
|
|
1022
1116
|
}
|
|
1023
1117
|
getValue(row, col) {
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1118
|
+
if (!col.includes('.'))
|
|
1119
|
+
return String(row[col] ?? '');
|
|
1120
|
+
const parts = col.split('.');
|
|
1121
|
+
// Walk the dot-path; descending through an array branches into every
|
|
1122
|
+
// element so leaf values get collected from each one. Multiple leaves are
|
|
1123
|
+
// joined with ';' (e.g. dunningReminders.id -> "uuid1;uuid2").
|
|
1124
|
+
const walk = (o, idx) => {
|
|
1125
|
+
if (idx >= parts.length)
|
|
1126
|
+
return [o];
|
|
1127
|
+
if (o == null)
|
|
1128
|
+
return [];
|
|
1129
|
+
if (Array.isArray(o))
|
|
1130
|
+
return o.flatMap(item => walk(item, idx));
|
|
1131
|
+
if (typeof o === 'object')
|
|
1132
|
+
return walk(o[parts[idx]], idx + 1);
|
|
1133
|
+
return [];
|
|
1134
|
+
};
|
|
1135
|
+
return walk(row, 0).filter(v => v !== undefined && v !== null).map(v => String(v)).join(';');
|
|
1030
1136
|
}
|
|
1031
1137
|
printTable(data, fields) {
|
|
1032
1138
|
const { cols, items } = this.getColumns(data, fields);
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
export default class PurchaseOrderTypes extends Command {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
action: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
|
+
id: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
8
|
+
};
|
|
9
|
+
static flags: {
|
|
10
|
+
context: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
+
output: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
|
+
table: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
13
|
+
csv: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
14
|
+
data: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
15
|
+
file: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
16
|
+
set: import("@oclif/core/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
17
|
+
page: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
18
|
+
limit: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
19
|
+
include: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
20
|
+
search: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
21
|
+
'sort-by': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
22
|
+
filter: import("@oclif/core/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
23
|
+
query: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
24
|
+
fields: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
25
|
+
sanitize: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
26
|
+
'show-http-request': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
27
|
+
};
|
|
28
|
+
run(): Promise<void>;
|
|
29
|
+
private runImport;
|
|
30
|
+
private runExport;
|
|
31
|
+
private runCamt053Import;
|
|
32
|
+
private runNestedImport;
|
|
33
|
+
private parseFilterValue;
|
|
34
|
+
private filterFields;
|
|
35
|
+
private sanitizeOutput;
|
|
36
|
+
private getColumns;
|
|
37
|
+
private getValue;
|
|
38
|
+
private printTable;
|
|
39
|
+
private printCsv;
|
|
40
|
+
}
|