@aderis-erp/cli 1.0.10 → 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 +178 -86
- package/dist/commands/account-transaction-allocations.js +178 -86
- package/dist/commands/account-transactions.js +181 -87
- package/dist/commands/accounts.js +178 -86
- package/dist/commands/agent-runs.d.ts +1 -0
- package/dist/commands/agent-runs.js +183 -87
- package/dist/commands/audit-log.js +178 -86
- package/dist/commands/auth/login.js +4 -3
- package/dist/commands/bank-accounts.js +178 -86
- package/dist/commands/bank-integrations.js +178 -86
- package/dist/commands/business-partners.js +178 -86
- package/dist/commands/config/add.js +4 -3
- package/dist/commands/credit-card-accounts.js +178 -86
- package/dist/commands/documents.js +178 -86
- package/dist/commands/dunning-configs.js +180 -88
- package/dist/commands/dunning-reminders.js +178 -86
- package/dist/commands/dunning-runs.js +178 -86
- package/dist/commands/employees.js +180 -88
- package/dist/commands/entity-configurations.d.ts +40 -0
- package/dist/commands/entity-configurations.js +1169 -0
- package/dist/commands/event-processor-mappings.js +178 -86
- package/dist/commands/files-internal.js +178 -86
- package/dist/commands/health.js +178 -86
- package/dist/commands/inbox.js +181 -89
- package/dist/commands/integrations.js +178 -86
- package/dist/commands/item-categories.js +178 -86
- package/dist/commands/items.js +178 -86
- package/dist/commands/journal-lines.js +178 -86
- package/dist/commands/journals.js +178 -86
- package/dist/commands/ledgers.js +178 -86
- package/dist/commands/office-locations.js +178 -86
- package/dist/commands/payment-methods.js +178 -86
- package/dist/commands/payment-runs.js +178 -86
- package/dist/commands/payment-terms.js +178 -86
- package/dist/commands/price-lists.js +178 -86
- package/dist/commands/processor-mappings.js +178 -86
- package/dist/commands/processors.js +181 -87
- 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 +178 -86
- package/dist/commands/salary-types.js +178 -86
- package/dist/commands/sales-invoices.js +178 -86
- package/dist/commands/sales-orders.js +182 -89
- package/dist/commands/saved-views.js +178 -86
- package/dist/commands/tags.js +178 -86
- package/dist/commands/tax-codes.js +178 -86
- package/dist/commands/tax-matrix.js +178 -86
- package/dist/commands/tenants.js +178 -86
- package/dist/commands/text-templates.js +178 -86
- package/dist/commands/tools.js +178 -86
- package/dist/commands/vat-declarations.d.ts +1 -0
- package/dist/commands/vat-declarations.js +188 -89
- package/dist/commands/vendor-invoices.js +178 -86
- package/dist/commands/webhooks.js +178 -86
- package/dist/commands/workflows.js +178 -86
- 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,8 +6,11 @@ const HAS_IMPORT = false;
|
|
|
6
6
|
const HAS_EXPORT = true;
|
|
7
7
|
const HAS_CAMT053 = false;
|
|
8
8
|
const NESTED_IMPORTS = [];
|
|
9
|
-
const SUBCOMMANDS = [...["list", "get", "retry", "restart", "discard"], ...(HAS_IMPORT ? ['import'] : []), ...(HAS_EXPORT ? ['export'] : []), ...NESTED_IMPORTS.map(n => `import-${n}`)];
|
|
9
|
+
const SUBCOMMANDS = [...["inbox", "inbox-counts", "inbox-files", "list", "get", "retry", "restart", "discard"], ...(HAS_IMPORT ? ['import'] : []), ...(HAS_EXPORT ? ['export'] : []), ...NESTED_IMPORTS.map(n => `import-${n}`)];
|
|
10
10
|
const ENDPOINTS = {
|
|
11
|
+
'inbox': { method: 'GET', path: '/v1/agent-runs/inbox', summary: 'List uploaded documents with their root pipeline run status', pathParams: [], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
|
|
12
|
+
'inbox-counts': { method: 'GET', path: '/v1/agent-runs/inbox/counts', summary: 'Get per-status upload counts for the inbox status chips', pathParams: [], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
|
|
13
|
+
'inbox-files': { method: 'GET', path: '/v1/agent-runs/inbox/{processingId}/files/{fileId}', summary: 'Get one uploaded file with its file-scoped agent-run tree', pathParams: ['processingId', 'fileId'], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
|
|
11
14
|
'list': { method: 'GET', path: '/v1/agent-runs', summary: 'List agent runs for the current tenant', pathParams: [], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
|
|
12
15
|
'get': { method: 'GET', path: '/v1/agent-runs/{runId}', summary: 'Get an agent-run detail by id', pathParams: ['runId'], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
|
|
13
16
|
'retry': { method: 'POST', path: '/v1/agent-runs/{runId}/retry', summary: 'Retry an agent run from NEEDS_REVIEW with a reviewer instruction', pathParams: ['runId'], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
|
|
@@ -33,6 +36,7 @@ export default class AgentRuns extends Command {
|
|
|
33
36
|
data: Flags.string({ char: 'd', description: 'JSON data for request body' }),
|
|
34
37
|
file: Flags.string({ char: 'f', description: 'Read request body from file' }),
|
|
35
38
|
set: Flags.string({ char: 's', description: 'Set individual field (e.g. --set firstName=John)', multiple: true }),
|
|
39
|
+
'file-id': Flags.string({ description: 'Path param: fileId' }),
|
|
36
40
|
page: Flags.string({ description: 'Page number' }),
|
|
37
41
|
limit: Flags.string({ description: 'Items per page' }),
|
|
38
42
|
include: Flags.string({ description: 'Relations to include' }),
|
|
@@ -428,76 +432,126 @@ export default class AgentRuns extends Command {
|
|
|
428
432
|
return '';
|
|
429
433
|
};
|
|
430
434
|
const results = [];
|
|
431
|
-
|
|
435
|
+
// Stream output row-by-row so progress is visible during long imports.
|
|
436
|
+
// Pre-compute the identifier column width from the input items so the
|
|
437
|
+
// table stays aligned without buffering all rows.
|
|
438
|
+
// When stdout is piped (IDE terminals, tee, CI), Node switches to async-buffered
|
|
439
|
+
// mode and rows accumulate in the pipe buffer until it fills. Force blocking
|
|
440
|
+
// mode so each \n-terminated write flushes immediately.
|
|
441
|
+
const stdoutHandle = process.stdout._handle;
|
|
442
|
+
if (stdoutHandle?.setBlocking)
|
|
443
|
+
stdoutHandle.setBlocking(true);
|
|
444
|
+
const outputFormat = flags.output || 'table';
|
|
445
|
+
const useCsv = outputFormat === 'csv' || Boolean(flags.csv);
|
|
446
|
+
const useJson = outputFormat === 'json';
|
|
447
|
+
const statusWidth = 8;
|
|
448
|
+
const identifierWidth = Math.max(10, ...items.map(i => getItemIdentifier(i).length));
|
|
449
|
+
if (useCsv) {
|
|
450
|
+
this.log('status,identifier,id,error');
|
|
451
|
+
}
|
|
452
|
+
else if (!useJson) {
|
|
453
|
+
this.log(`${'status'.padEnd(statusWidth)} ${'identifier'.padEnd(identifierWidth)} error`);
|
|
454
|
+
this.log(`${'-'.repeat(statusWidth)} ${'-'.repeat(identifierWidth)} ${'-'.repeat(50)}`);
|
|
455
|
+
}
|
|
456
|
+
const emitRow = (r) => {
|
|
457
|
+
if (useJson)
|
|
458
|
+
return;
|
|
459
|
+
if (useCsv) {
|
|
460
|
+
const err = (r.error || '').replace(/"/g, '""');
|
|
461
|
+
this.log(`${r.status},${r.identifier || ''},${r.id || ''},"${err}"`);
|
|
462
|
+
}
|
|
463
|
+
else {
|
|
464
|
+
this.log(`${r.status.padEnd(statusWidth)} ${(r.identifier || '').padEnd(identifierWidth)} ${r.error || ''}`);
|
|
465
|
+
}
|
|
466
|
+
};
|
|
467
|
+
// Server-managed fields the API rejects in create/update bodies. Stripped
|
|
468
|
+
// before every request so re-importing a previously-exported payload Just Works.
|
|
469
|
+
const STRIP_FIELDS = new Set(['id', '_type', 'tenantId', 'createdAt', 'updatedAt', 'createdBy', 'updatedBy']);
|
|
470
|
+
const stripServerFields = (item) => {
|
|
471
|
+
const out = {};
|
|
472
|
+
for (const [k, v] of Object.entries(item)) {
|
|
473
|
+
if (!STRIP_FIELDS.has(k))
|
|
474
|
+
out[k] = v;
|
|
475
|
+
}
|
|
476
|
+
return out;
|
|
477
|
+
};
|
|
478
|
+
const processItem = async (item) => {
|
|
432
479
|
const identifier = getItemIdentifier(item);
|
|
480
|
+
const body = stripServerFields(item);
|
|
481
|
+
// If the payload carries an id (e.g. re-importing an export), PATCH directly.
|
|
482
|
+
// Fall through to POST only on 404 (so a missing record still gets created).
|
|
483
|
+
const itemId = typeof item.id === 'string' ? item.id : undefined;
|
|
484
|
+
if (itemId) {
|
|
485
|
+
try {
|
|
486
|
+
const updatePath = updateEndpoint.path.replace('{id}', itemId);
|
|
487
|
+
await apiRequest('PATCH', updatePath, {
|
|
488
|
+
data: body,
|
|
489
|
+
contextName: flags.context,
|
|
490
|
+
});
|
|
491
|
+
return { status: 'updated', id: itemId, identifier };
|
|
492
|
+
}
|
|
493
|
+
catch (error) {
|
|
494
|
+
if (!(error instanceof ApiError && error.status === 404)) {
|
|
495
|
+
const msg = error instanceof ApiError ? `(${error.status}) ${error.message}` : String(error);
|
|
496
|
+
return { status: 'error', id: itemId, identifier, error: msg };
|
|
497
|
+
}
|
|
498
|
+
// 404 → record gone, try create below
|
|
499
|
+
}
|
|
500
|
+
}
|
|
433
501
|
try {
|
|
434
|
-
// Try to create
|
|
435
502
|
const response = await apiRequest('POST', createEndpoint.path, {
|
|
436
|
-
data:
|
|
503
|
+
data: body,
|
|
437
504
|
contextName: flags.context,
|
|
438
505
|
});
|
|
439
506
|
const id = response.data?.id;
|
|
440
|
-
|
|
507
|
+
return { status: 'created', id: id ? String(id) : undefined, identifier };
|
|
441
508
|
}
|
|
442
509
|
catch (error) {
|
|
443
510
|
if (error instanceof ApiError && error.status === 409) {
|
|
444
|
-
// Conflict - try to update existing
|
|
445
511
|
const errorData = error.data;
|
|
446
512
|
const existingId = errorData?.existingId;
|
|
447
513
|
if (existingId) {
|
|
448
514
|
try {
|
|
449
515
|
const updatePath = updateEndpoint.path.replace('{id}', existingId);
|
|
450
516
|
await apiRequest('PATCH', updatePath, {
|
|
451
|
-
data:
|
|
517
|
+
data: body,
|
|
452
518
|
contextName: flags.context,
|
|
453
519
|
});
|
|
454
|
-
|
|
520
|
+
return { status: 'updated', id: existingId, identifier };
|
|
455
521
|
}
|
|
456
522
|
catch (updateError) {
|
|
457
523
|
const msg = updateError instanceof ApiError ? updateError.message : String(updateError);
|
|
458
|
-
|
|
524
|
+
return { status: 'error', id: existingId, identifier, error: `Update failed: ${msg}` };
|
|
459
525
|
}
|
|
460
526
|
}
|
|
461
|
-
|
|
462
|
-
results.push({ status: 'error', identifier, error: 'Conflict but no existingId returned' });
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
else {
|
|
466
|
-
const msg = error instanceof ApiError ? `(${error.status}) ${error.message}` : String(error);
|
|
467
|
-
results.push({ status: 'error', identifier, error: msg });
|
|
527
|
+
return { status: 'error', identifier, error: 'Conflict but no existingId returned' };
|
|
468
528
|
}
|
|
529
|
+
const msg = error instanceof ApiError ? `(${error.status}) ${error.message}` : String(error);
|
|
530
|
+
return { status: 'error', identifier, error: msg };
|
|
469
531
|
}
|
|
470
|
-
}
|
|
532
|
+
};
|
|
533
|
+
// Worker pool: keep N requests in flight at all times. Rows are emitted as
|
|
534
|
+
// each request resolves (so output order may differ from input order). The
|
|
535
|
+
// summary at the end remains accurate regardless.
|
|
536
|
+
const concurrency = 4;
|
|
537
|
+
const queue = [...items];
|
|
538
|
+
await Promise.all(Array.from({ length: Math.min(concurrency, queue.length) }, async () => {
|
|
539
|
+
for (;;) {
|
|
540
|
+
const item = queue.shift();
|
|
541
|
+
if (!item)
|
|
542
|
+
return;
|
|
543
|
+
const r = await processItem(item);
|
|
544
|
+
results.push(r);
|
|
545
|
+
emitRow(r);
|
|
546
|
+
}
|
|
547
|
+
}));
|
|
471
548
|
// Summary counts
|
|
472
549
|
const created = results.filter(r => r.status === 'created').length;
|
|
473
550
|
const updated = results.filter(r => r.status === 'updated').length;
|
|
474
551
|
const errors = results.filter(r => r.status === 'error');
|
|
475
|
-
|
|
476
|
-
const outputFormat = flags.output || 'table';
|
|
477
|
-
if (outputFormat === 'json') {
|
|
552
|
+
if (useJson) {
|
|
478
553
|
this.log(JSON.stringify(results, null, 2));
|
|
479
554
|
}
|
|
480
|
-
else if (outputFormat === 'csv' || flags.csv) {
|
|
481
|
-
// CSV output
|
|
482
|
-
this.log('status,identifier,id,error');
|
|
483
|
-
for (const r of results) {
|
|
484
|
-
const err = (r.error || '').replace(/"/g, '""');
|
|
485
|
-
this.log(`${r.status},${r.identifier || ''},${r.id || ''},"${err}"`);
|
|
486
|
-
}
|
|
487
|
-
}
|
|
488
|
-
else {
|
|
489
|
-
// Table output (default)
|
|
490
|
-
if (results.length > 0) {
|
|
491
|
-
const statusWidth = 8;
|
|
492
|
-
const identifierWidth = Math.max(10, ...results.map(r => (r.identifier || '').length));
|
|
493
|
-
this.log(`${'status'.padEnd(statusWidth)} ${'identifier'.padEnd(identifierWidth)} error`);
|
|
494
|
-
this.log(`${'-'.repeat(statusWidth)} ${'-'.repeat(identifierWidth)} ${'-'.repeat(50)}`);
|
|
495
|
-
for (const r of results) {
|
|
496
|
-
const status = r.status === 'created' ? 'created' : r.status === 'updated' ? 'updated' : 'error';
|
|
497
|
-
this.log(`${status.padEnd(statusWidth)} ${(r.identifier || '').padEnd(identifierWidth)} ${r.error || ''}`);
|
|
498
|
-
}
|
|
499
|
-
}
|
|
500
|
-
}
|
|
501
555
|
// Always show summary at the end
|
|
502
556
|
this.log('');
|
|
503
557
|
this.log(`Summary: ${created} created, ${updated} updated, ${errors.length} failed`);
|
|
@@ -777,80 +831,122 @@ export default class AgentRuns extends Command {
|
|
|
777
831
|
return '';
|
|
778
832
|
};
|
|
779
833
|
const results = [];
|
|
780
|
-
|
|
834
|
+
const stdoutHandle = process.stdout._handle;
|
|
835
|
+
if (stdoutHandle?.setBlocking)
|
|
836
|
+
stdoutHandle.setBlocking(true);
|
|
837
|
+
const outputFormat = flags.output || 'table';
|
|
838
|
+
const useCsv = outputFormat === 'csv' || Boolean(flags.csv);
|
|
839
|
+
const useJson = outputFormat === 'json';
|
|
840
|
+
const statusWidth = 8;
|
|
841
|
+
const identifierWidth = Math.max(10, ...items.map(i => getItemIdentifier(i).length));
|
|
842
|
+
if (useCsv) {
|
|
843
|
+
this.log('status,identifier,id,error');
|
|
844
|
+
}
|
|
845
|
+
else if (!useJson) {
|
|
846
|
+
this.log(`${'status'.padEnd(statusWidth)} ${'identifier'.padEnd(identifierWidth)} error`);
|
|
847
|
+
this.log(`${'-'.repeat(statusWidth)} ${'-'.repeat(identifierWidth)} ${'-'.repeat(50)}`);
|
|
848
|
+
}
|
|
849
|
+
const emitRow = (r) => {
|
|
850
|
+
if (useJson)
|
|
851
|
+
return;
|
|
852
|
+
if (useCsv) {
|
|
853
|
+
const err = (r.error || '').replace(/"/g, '""');
|
|
854
|
+
this.log(`${r.status},${r.identifier || ''},${r.id || ''},"${err}"`);
|
|
855
|
+
}
|
|
856
|
+
else {
|
|
857
|
+
this.log(`${r.status.padEnd(statusWidth)} ${(r.identifier || '').padEnd(identifierWidth)} ${r.error || ''}`);
|
|
858
|
+
}
|
|
859
|
+
};
|
|
860
|
+
const STRIP_FIELDS = new Set(['id', '_type', 'tenantId', 'createdAt', 'updatedAt', 'createdBy', 'updatedBy']);
|
|
861
|
+
const stripServerFields = (item) => {
|
|
862
|
+
const out = {};
|
|
863
|
+
for (const [k, v] of Object.entries(item)) {
|
|
864
|
+
if (!STRIP_FIELDS.has(k))
|
|
865
|
+
out[k] = v;
|
|
866
|
+
}
|
|
867
|
+
return out;
|
|
868
|
+
};
|
|
869
|
+
const buildUpdatePath = (existingId) => {
|
|
870
|
+
const firstUpdateParam = updateEndpoint.pathParams[0];
|
|
871
|
+
const nestedIdParam = updateEndpoint.pathParams.find((p, i) => i > 0);
|
|
872
|
+
let updatePath = updateEndpoint.path.replace(`{${firstUpdateParam}}`, parentId);
|
|
873
|
+
if (nestedIdParam) {
|
|
874
|
+
updatePath = updatePath.replace(`{${nestedIdParam}}`, existingId);
|
|
875
|
+
}
|
|
876
|
+
return updatePath;
|
|
877
|
+
};
|
|
878
|
+
const processItem = async (item) => {
|
|
781
879
|
const identifier = getItemIdentifier(item);
|
|
880
|
+
const body = stripServerFields(item);
|
|
881
|
+
const itemId = typeof item.id === 'string' ? item.id : undefined;
|
|
882
|
+
if (itemId) {
|
|
883
|
+
try {
|
|
884
|
+
await apiRequest('PATCH', buildUpdatePath(itemId), {
|
|
885
|
+
data: body,
|
|
886
|
+
contextName: flags.context,
|
|
887
|
+
});
|
|
888
|
+
return { status: 'updated', id: itemId, identifier };
|
|
889
|
+
}
|
|
890
|
+
catch (error) {
|
|
891
|
+
if (!(error instanceof ApiError && error.status === 404)) {
|
|
892
|
+
const msg = error instanceof ApiError ? `(${error.status}) ${error.message}` : String(error);
|
|
893
|
+
return { status: 'error', id: itemId, identifier, error: msg };
|
|
894
|
+
}
|
|
895
|
+
// 404 → fall through and try create
|
|
896
|
+
}
|
|
897
|
+
}
|
|
782
898
|
try {
|
|
783
|
-
// Try to create
|
|
784
899
|
const response = await apiRequest('POST', basePath, {
|
|
785
|
-
data:
|
|
900
|
+
data: body,
|
|
786
901
|
contextName: flags.context,
|
|
787
902
|
});
|
|
788
903
|
const id = response.data?.id;
|
|
789
|
-
|
|
904
|
+
return { status: 'created', id: id ? String(id) : undefined, identifier };
|
|
790
905
|
}
|
|
791
906
|
catch (error) {
|
|
792
907
|
if (error instanceof ApiError && error.status === 409) {
|
|
793
|
-
// Conflict - try to update existing
|
|
794
908
|
const errorData = error.data;
|
|
795
909
|
const existingId = errorData?.existingId || item.id;
|
|
796
910
|
if (existingId) {
|
|
797
911
|
try {
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
const nestedIdParam = updateEndpoint.pathParams.find((p, i) => i > 0);
|
|
801
|
-
let updatePath = updateEndpoint.path.replace(`{${firstUpdateParam}}`, parentId);
|
|
802
|
-
if (nestedIdParam) {
|
|
803
|
-
updatePath = updatePath.replace(`{${nestedIdParam}}`, existingId);
|
|
804
|
-
}
|
|
805
|
-
await apiRequest('PATCH', updatePath, {
|
|
806
|
-
data: item,
|
|
912
|
+
await apiRequest('PATCH', buildUpdatePath(existingId), {
|
|
913
|
+
data: body,
|
|
807
914
|
contextName: flags.context,
|
|
808
915
|
});
|
|
809
|
-
|
|
916
|
+
return { status: 'updated', id: existingId, identifier };
|
|
810
917
|
}
|
|
811
918
|
catch (updateError) {
|
|
812
919
|
const msg = updateError instanceof ApiError ? updateError.message : String(updateError);
|
|
813
|
-
|
|
920
|
+
return { status: 'error', id: existingId, identifier, error: `Update failed: ${msg}` };
|
|
814
921
|
}
|
|
815
922
|
}
|
|
816
|
-
|
|
817
|
-
results.push({ status: 'error', identifier, error: 'Conflict but no existingId returned' });
|
|
818
|
-
}
|
|
819
|
-
}
|
|
820
|
-
else {
|
|
821
|
-
const msg = error instanceof ApiError ? `(${error.status}) ${error.message}` : String(error);
|
|
822
|
-
results.push({ status: 'error', identifier, error: msg });
|
|
923
|
+
return { status: 'error', identifier, error: 'Conflict but no existingId returned' };
|
|
823
924
|
}
|
|
925
|
+
const msg = error instanceof ApiError ? `(${error.status}) ${error.message}` : String(error);
|
|
926
|
+
return { status: 'error', identifier, error: msg };
|
|
824
927
|
}
|
|
825
|
-
}
|
|
928
|
+
};
|
|
929
|
+
// Worker pool: 4 requests in flight at a time. Rows are emitted as each
|
|
930
|
+
// request resolves so output order may differ from input order.
|
|
931
|
+
const concurrency = 4;
|
|
932
|
+
const queue = [...items];
|
|
933
|
+
await Promise.all(Array.from({ length: Math.min(concurrency, queue.length) }, async () => {
|
|
934
|
+
for (;;) {
|
|
935
|
+
const item = queue.shift();
|
|
936
|
+
if (!item)
|
|
937
|
+
return;
|
|
938
|
+
const r = await processItem(item);
|
|
939
|
+
results.push(r);
|
|
940
|
+
emitRow(r);
|
|
941
|
+
}
|
|
942
|
+
}));
|
|
826
943
|
// Summary counts
|
|
827
944
|
const created = results.filter(r => r.status === 'created').length;
|
|
828
945
|
const updated = results.filter(r => r.status === 'updated').length;
|
|
829
946
|
const errors = results.filter(r => r.status === 'error');
|
|
830
|
-
|
|
831
|
-
const outputFormat = flags.output || 'table';
|
|
832
|
-
if (outputFormat === 'json') {
|
|
947
|
+
if (useJson) {
|
|
833
948
|
this.log(JSON.stringify(results, null, 2));
|
|
834
949
|
}
|
|
835
|
-
else if (outputFormat === 'csv' || flags.csv) {
|
|
836
|
-
this.log('status,identifier,id,error');
|
|
837
|
-
for (const r of results) {
|
|
838
|
-
const err = (r.error || '').replace(/"/g, '""');
|
|
839
|
-
this.log(`${r.status},${r.identifier || ''},${r.id || ''},"${err}"`);
|
|
840
|
-
}
|
|
841
|
-
}
|
|
842
|
-
else {
|
|
843
|
-
if (results.length > 0) {
|
|
844
|
-
const statusWidth = 8;
|
|
845
|
-
const identifierWidth = Math.max(10, ...results.map(r => (r.identifier || '').length));
|
|
846
|
-
this.log(`${'status'.padEnd(statusWidth)} ${'identifier'.padEnd(identifierWidth)} error`);
|
|
847
|
-
this.log(`${'-'.repeat(statusWidth)} ${'-'.repeat(identifierWidth)} ${'-'.repeat(50)}`);
|
|
848
|
-
for (const r of results) {
|
|
849
|
-
const status = r.status === 'created' ? 'created' : r.status === 'updated' ? 'updated' : 'error';
|
|
850
|
-
this.log(`${status.padEnd(statusWidth)} ${(r.identifier || '').padEnd(identifierWidth)} ${r.error || ''}`);
|
|
851
|
-
}
|
|
852
|
-
}
|
|
853
|
-
}
|
|
854
950
|
this.log('');
|
|
855
951
|
this.log(`Summary: ${created} created, ${updated} updated, ${errors.length} failed`);
|
|
856
952
|
}
|