@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
|
@@ -425,76 +425,126 @@ export default class AccountTransactionAllocations extends Command {
|
|
|
425
425
|
return '';
|
|
426
426
|
};
|
|
427
427
|
const results = [];
|
|
428
|
-
|
|
428
|
+
// Stream output row-by-row so progress is visible during long imports.
|
|
429
|
+
// Pre-compute the identifier column width from the input items so the
|
|
430
|
+
// table stays aligned without buffering all rows.
|
|
431
|
+
// When stdout is piped (IDE terminals, tee, CI), Node switches to async-buffered
|
|
432
|
+
// mode and rows accumulate in the pipe buffer until it fills. Force blocking
|
|
433
|
+
// mode so each \n-terminated write flushes immediately.
|
|
434
|
+
const stdoutHandle = process.stdout._handle;
|
|
435
|
+
if (stdoutHandle?.setBlocking)
|
|
436
|
+
stdoutHandle.setBlocking(true);
|
|
437
|
+
const outputFormat = flags.output || 'table';
|
|
438
|
+
const useCsv = outputFormat === 'csv' || Boolean(flags.csv);
|
|
439
|
+
const useJson = outputFormat === 'json';
|
|
440
|
+
const statusWidth = 8;
|
|
441
|
+
const identifierWidth = Math.max(10, ...items.map(i => getItemIdentifier(i).length));
|
|
442
|
+
if (useCsv) {
|
|
443
|
+
this.log('status,identifier,id,error');
|
|
444
|
+
}
|
|
445
|
+
else if (!useJson) {
|
|
446
|
+
this.log(`${'status'.padEnd(statusWidth)} ${'identifier'.padEnd(identifierWidth)} error`);
|
|
447
|
+
this.log(`${'-'.repeat(statusWidth)} ${'-'.repeat(identifierWidth)} ${'-'.repeat(50)}`);
|
|
448
|
+
}
|
|
449
|
+
const emitRow = (r) => {
|
|
450
|
+
if (useJson)
|
|
451
|
+
return;
|
|
452
|
+
if (useCsv) {
|
|
453
|
+
const err = (r.error || '').replace(/"/g, '""');
|
|
454
|
+
this.log(`${r.status},${r.identifier || ''},${r.id || ''},"${err}"`);
|
|
455
|
+
}
|
|
456
|
+
else {
|
|
457
|
+
this.log(`${r.status.padEnd(statusWidth)} ${(r.identifier || '').padEnd(identifierWidth)} ${r.error || ''}`);
|
|
458
|
+
}
|
|
459
|
+
};
|
|
460
|
+
// Server-managed fields the API rejects in create/update bodies. Stripped
|
|
461
|
+
// before every request so re-importing a previously-exported payload Just Works.
|
|
462
|
+
const STRIP_FIELDS = new Set(['id', '_type', 'tenantId', 'createdAt', 'updatedAt', 'createdBy', 'updatedBy']);
|
|
463
|
+
const stripServerFields = (item) => {
|
|
464
|
+
const out = {};
|
|
465
|
+
for (const [k, v] of Object.entries(item)) {
|
|
466
|
+
if (!STRIP_FIELDS.has(k))
|
|
467
|
+
out[k] = v;
|
|
468
|
+
}
|
|
469
|
+
return out;
|
|
470
|
+
};
|
|
471
|
+
const processItem = async (item) => {
|
|
429
472
|
const identifier = getItemIdentifier(item);
|
|
473
|
+
const body = stripServerFields(item);
|
|
474
|
+
// If the payload carries an id (e.g. re-importing an export), PATCH directly.
|
|
475
|
+
// Fall through to POST only on 404 (so a missing record still gets created).
|
|
476
|
+
const itemId = typeof item.id === 'string' ? item.id : undefined;
|
|
477
|
+
if (itemId) {
|
|
478
|
+
try {
|
|
479
|
+
const updatePath = updateEndpoint.path.replace('{id}', itemId);
|
|
480
|
+
await apiRequest('PATCH', updatePath, {
|
|
481
|
+
data: body,
|
|
482
|
+
contextName: flags.context,
|
|
483
|
+
});
|
|
484
|
+
return { status: 'updated', id: itemId, identifier };
|
|
485
|
+
}
|
|
486
|
+
catch (error) {
|
|
487
|
+
if (!(error instanceof ApiError && error.status === 404)) {
|
|
488
|
+
const msg = error instanceof ApiError ? `(${error.status}) ${error.message}` : String(error);
|
|
489
|
+
return { status: 'error', id: itemId, identifier, error: msg };
|
|
490
|
+
}
|
|
491
|
+
// 404 → record gone, try create below
|
|
492
|
+
}
|
|
493
|
+
}
|
|
430
494
|
try {
|
|
431
|
-
// Try to create
|
|
432
495
|
const response = await apiRequest('POST', createEndpoint.path, {
|
|
433
|
-
data:
|
|
496
|
+
data: body,
|
|
434
497
|
contextName: flags.context,
|
|
435
498
|
});
|
|
436
499
|
const id = response.data?.id;
|
|
437
|
-
|
|
500
|
+
return { status: 'created', id: id ? String(id) : undefined, identifier };
|
|
438
501
|
}
|
|
439
502
|
catch (error) {
|
|
440
503
|
if (error instanceof ApiError && error.status === 409) {
|
|
441
|
-
// Conflict - try to update existing
|
|
442
504
|
const errorData = error.data;
|
|
443
505
|
const existingId = errorData?.existingId;
|
|
444
506
|
if (existingId) {
|
|
445
507
|
try {
|
|
446
508
|
const updatePath = updateEndpoint.path.replace('{id}', existingId);
|
|
447
509
|
await apiRequest('PATCH', updatePath, {
|
|
448
|
-
data:
|
|
510
|
+
data: body,
|
|
449
511
|
contextName: flags.context,
|
|
450
512
|
});
|
|
451
|
-
|
|
513
|
+
return { status: 'updated', id: existingId, identifier };
|
|
452
514
|
}
|
|
453
515
|
catch (updateError) {
|
|
454
516
|
const msg = updateError instanceof ApiError ? updateError.message : String(updateError);
|
|
455
|
-
|
|
517
|
+
return { status: 'error', id: existingId, identifier, error: `Update failed: ${msg}` };
|
|
456
518
|
}
|
|
457
519
|
}
|
|
458
|
-
|
|
459
|
-
results.push({ status: 'error', identifier, error: 'Conflict but no existingId returned' });
|
|
460
|
-
}
|
|
461
|
-
}
|
|
462
|
-
else {
|
|
463
|
-
const msg = error instanceof ApiError ? `(${error.status}) ${error.message}` : String(error);
|
|
464
|
-
results.push({ status: 'error', identifier, error: msg });
|
|
520
|
+
return { status: 'error', identifier, error: 'Conflict but no existingId returned' };
|
|
465
521
|
}
|
|
522
|
+
const msg = error instanceof ApiError ? `(${error.status}) ${error.message}` : String(error);
|
|
523
|
+
return { status: 'error', identifier, error: msg };
|
|
466
524
|
}
|
|
467
|
-
}
|
|
525
|
+
};
|
|
526
|
+
// Worker pool: keep N requests in flight at all times. Rows are emitted as
|
|
527
|
+
// each request resolves (so output order may differ from input order). The
|
|
528
|
+
// summary at the end remains accurate regardless.
|
|
529
|
+
const concurrency = 4;
|
|
530
|
+
const queue = [...items];
|
|
531
|
+
await Promise.all(Array.from({ length: Math.min(concurrency, queue.length) }, async () => {
|
|
532
|
+
for (;;) {
|
|
533
|
+
const item = queue.shift();
|
|
534
|
+
if (!item)
|
|
535
|
+
return;
|
|
536
|
+
const r = await processItem(item);
|
|
537
|
+
results.push(r);
|
|
538
|
+
emitRow(r);
|
|
539
|
+
}
|
|
540
|
+
}));
|
|
468
541
|
// Summary counts
|
|
469
542
|
const created = results.filter(r => r.status === 'created').length;
|
|
470
543
|
const updated = results.filter(r => r.status === 'updated').length;
|
|
471
544
|
const errors = results.filter(r => r.status === 'error');
|
|
472
|
-
|
|
473
|
-
const outputFormat = flags.output || 'table';
|
|
474
|
-
if (outputFormat === 'json') {
|
|
545
|
+
if (useJson) {
|
|
475
546
|
this.log(JSON.stringify(results, null, 2));
|
|
476
547
|
}
|
|
477
|
-
else if (outputFormat === 'csv' || flags.csv) {
|
|
478
|
-
// CSV output
|
|
479
|
-
this.log('status,identifier,id,error');
|
|
480
|
-
for (const r of results) {
|
|
481
|
-
const err = (r.error || '').replace(/"/g, '""');
|
|
482
|
-
this.log(`${r.status},${r.identifier || ''},${r.id || ''},"${err}"`);
|
|
483
|
-
}
|
|
484
|
-
}
|
|
485
|
-
else {
|
|
486
|
-
// Table output (default)
|
|
487
|
-
if (results.length > 0) {
|
|
488
|
-
const statusWidth = 8;
|
|
489
|
-
const identifierWidth = Math.max(10, ...results.map(r => (r.identifier || '').length));
|
|
490
|
-
this.log(`${'status'.padEnd(statusWidth)} ${'identifier'.padEnd(identifierWidth)} error`);
|
|
491
|
-
this.log(`${'-'.repeat(statusWidth)} ${'-'.repeat(identifierWidth)} ${'-'.repeat(50)}`);
|
|
492
|
-
for (const r of results) {
|
|
493
|
-
const status = r.status === 'created' ? 'created' : r.status === 'updated' ? 'updated' : 'error';
|
|
494
|
-
this.log(`${status.padEnd(statusWidth)} ${(r.identifier || '').padEnd(identifierWidth)} ${r.error || ''}`);
|
|
495
|
-
}
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
548
|
// Always show summary at the end
|
|
499
549
|
this.log('');
|
|
500
550
|
this.log(`Summary: ${created} created, ${updated} updated, ${errors.length} failed`);
|
|
@@ -774,80 +824,122 @@ export default class AccountTransactionAllocations extends Command {
|
|
|
774
824
|
return '';
|
|
775
825
|
};
|
|
776
826
|
const results = [];
|
|
777
|
-
|
|
827
|
+
const stdoutHandle = process.stdout._handle;
|
|
828
|
+
if (stdoutHandle?.setBlocking)
|
|
829
|
+
stdoutHandle.setBlocking(true);
|
|
830
|
+
const outputFormat = flags.output || 'table';
|
|
831
|
+
const useCsv = outputFormat === 'csv' || Boolean(flags.csv);
|
|
832
|
+
const useJson = outputFormat === 'json';
|
|
833
|
+
const statusWidth = 8;
|
|
834
|
+
const identifierWidth = Math.max(10, ...items.map(i => getItemIdentifier(i).length));
|
|
835
|
+
if (useCsv) {
|
|
836
|
+
this.log('status,identifier,id,error');
|
|
837
|
+
}
|
|
838
|
+
else if (!useJson) {
|
|
839
|
+
this.log(`${'status'.padEnd(statusWidth)} ${'identifier'.padEnd(identifierWidth)} error`);
|
|
840
|
+
this.log(`${'-'.repeat(statusWidth)} ${'-'.repeat(identifierWidth)} ${'-'.repeat(50)}`);
|
|
841
|
+
}
|
|
842
|
+
const emitRow = (r) => {
|
|
843
|
+
if (useJson)
|
|
844
|
+
return;
|
|
845
|
+
if (useCsv) {
|
|
846
|
+
const err = (r.error || '').replace(/"/g, '""');
|
|
847
|
+
this.log(`${r.status},${r.identifier || ''},${r.id || ''},"${err}"`);
|
|
848
|
+
}
|
|
849
|
+
else {
|
|
850
|
+
this.log(`${r.status.padEnd(statusWidth)} ${(r.identifier || '').padEnd(identifierWidth)} ${r.error || ''}`);
|
|
851
|
+
}
|
|
852
|
+
};
|
|
853
|
+
const STRIP_FIELDS = new Set(['id', '_type', 'tenantId', 'createdAt', 'updatedAt', 'createdBy', 'updatedBy']);
|
|
854
|
+
const stripServerFields = (item) => {
|
|
855
|
+
const out = {};
|
|
856
|
+
for (const [k, v] of Object.entries(item)) {
|
|
857
|
+
if (!STRIP_FIELDS.has(k))
|
|
858
|
+
out[k] = v;
|
|
859
|
+
}
|
|
860
|
+
return out;
|
|
861
|
+
};
|
|
862
|
+
const buildUpdatePath = (existingId) => {
|
|
863
|
+
const firstUpdateParam = updateEndpoint.pathParams[0];
|
|
864
|
+
const nestedIdParam = updateEndpoint.pathParams.find((p, i) => i > 0);
|
|
865
|
+
let updatePath = updateEndpoint.path.replace(`{${firstUpdateParam}}`, parentId);
|
|
866
|
+
if (nestedIdParam) {
|
|
867
|
+
updatePath = updatePath.replace(`{${nestedIdParam}}`, existingId);
|
|
868
|
+
}
|
|
869
|
+
return updatePath;
|
|
870
|
+
};
|
|
871
|
+
const processItem = async (item) => {
|
|
778
872
|
const identifier = getItemIdentifier(item);
|
|
873
|
+
const body = stripServerFields(item);
|
|
874
|
+
const itemId = typeof item.id === 'string' ? item.id : undefined;
|
|
875
|
+
if (itemId) {
|
|
876
|
+
try {
|
|
877
|
+
await apiRequest('PATCH', buildUpdatePath(itemId), {
|
|
878
|
+
data: body,
|
|
879
|
+
contextName: flags.context,
|
|
880
|
+
});
|
|
881
|
+
return { status: 'updated', id: itemId, identifier };
|
|
882
|
+
}
|
|
883
|
+
catch (error) {
|
|
884
|
+
if (!(error instanceof ApiError && error.status === 404)) {
|
|
885
|
+
const msg = error instanceof ApiError ? `(${error.status}) ${error.message}` : String(error);
|
|
886
|
+
return { status: 'error', id: itemId, identifier, error: msg };
|
|
887
|
+
}
|
|
888
|
+
// 404 → fall through and try create
|
|
889
|
+
}
|
|
890
|
+
}
|
|
779
891
|
try {
|
|
780
|
-
// Try to create
|
|
781
892
|
const response = await apiRequest('POST', basePath, {
|
|
782
|
-
data:
|
|
893
|
+
data: body,
|
|
783
894
|
contextName: flags.context,
|
|
784
895
|
});
|
|
785
896
|
const id = response.data?.id;
|
|
786
|
-
|
|
897
|
+
return { status: 'created', id: id ? String(id) : undefined, identifier };
|
|
787
898
|
}
|
|
788
899
|
catch (error) {
|
|
789
900
|
if (error instanceof ApiError && error.status === 409) {
|
|
790
|
-
// Conflict - try to update existing
|
|
791
901
|
const errorData = error.data;
|
|
792
902
|
const existingId = errorData?.existingId || item.id;
|
|
793
903
|
if (existingId) {
|
|
794
904
|
try {
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
const nestedIdParam = updateEndpoint.pathParams.find((p, i) => i > 0);
|
|
798
|
-
let updatePath = updateEndpoint.path.replace(`{${firstUpdateParam}}`, parentId);
|
|
799
|
-
if (nestedIdParam) {
|
|
800
|
-
updatePath = updatePath.replace(`{${nestedIdParam}}`, existingId);
|
|
801
|
-
}
|
|
802
|
-
await apiRequest('PATCH', updatePath, {
|
|
803
|
-
data: item,
|
|
905
|
+
await apiRequest('PATCH', buildUpdatePath(existingId), {
|
|
906
|
+
data: body,
|
|
804
907
|
contextName: flags.context,
|
|
805
908
|
});
|
|
806
|
-
|
|
909
|
+
return { status: 'updated', id: existingId, identifier };
|
|
807
910
|
}
|
|
808
911
|
catch (updateError) {
|
|
809
912
|
const msg = updateError instanceof ApiError ? updateError.message : String(updateError);
|
|
810
|
-
|
|
913
|
+
return { status: 'error', id: existingId, identifier, error: `Update failed: ${msg}` };
|
|
811
914
|
}
|
|
812
915
|
}
|
|
813
|
-
|
|
814
|
-
results.push({ status: 'error', identifier, error: 'Conflict but no existingId returned' });
|
|
815
|
-
}
|
|
816
|
-
}
|
|
817
|
-
else {
|
|
818
|
-
const msg = error instanceof ApiError ? `(${error.status}) ${error.message}` : String(error);
|
|
819
|
-
results.push({ status: 'error', identifier, error: msg });
|
|
916
|
+
return { status: 'error', identifier, error: 'Conflict but no existingId returned' };
|
|
820
917
|
}
|
|
918
|
+
const msg = error instanceof ApiError ? `(${error.status}) ${error.message}` : String(error);
|
|
919
|
+
return { status: 'error', identifier, error: msg };
|
|
821
920
|
}
|
|
822
|
-
}
|
|
921
|
+
};
|
|
922
|
+
// Worker pool: 4 requests in flight at a time. Rows are emitted as each
|
|
923
|
+
// request resolves so output order may differ from input order.
|
|
924
|
+
const concurrency = 4;
|
|
925
|
+
const queue = [...items];
|
|
926
|
+
await Promise.all(Array.from({ length: Math.min(concurrency, queue.length) }, async () => {
|
|
927
|
+
for (;;) {
|
|
928
|
+
const item = queue.shift();
|
|
929
|
+
if (!item)
|
|
930
|
+
return;
|
|
931
|
+
const r = await processItem(item);
|
|
932
|
+
results.push(r);
|
|
933
|
+
emitRow(r);
|
|
934
|
+
}
|
|
935
|
+
}));
|
|
823
936
|
// Summary counts
|
|
824
937
|
const created = results.filter(r => r.status === 'created').length;
|
|
825
938
|
const updated = results.filter(r => r.status === 'updated').length;
|
|
826
939
|
const errors = results.filter(r => r.status === 'error');
|
|
827
|
-
|
|
828
|
-
const outputFormat = flags.output || 'table';
|
|
829
|
-
if (outputFormat === 'json') {
|
|
940
|
+
if (useJson) {
|
|
830
941
|
this.log(JSON.stringify(results, null, 2));
|
|
831
942
|
}
|
|
832
|
-
else if (outputFormat === 'csv' || flags.csv) {
|
|
833
|
-
this.log('status,identifier,id,error');
|
|
834
|
-
for (const r of results) {
|
|
835
|
-
const err = (r.error || '').replace(/"/g, '""');
|
|
836
|
-
this.log(`${r.status},${r.identifier || ''},${r.id || ''},"${err}"`);
|
|
837
|
-
}
|
|
838
|
-
}
|
|
839
|
-
else {
|
|
840
|
-
if (results.length > 0) {
|
|
841
|
-
const statusWidth = 8;
|
|
842
|
-
const identifierWidth = Math.max(10, ...results.map(r => (r.identifier || '').length));
|
|
843
|
-
this.log(`${'status'.padEnd(statusWidth)} ${'identifier'.padEnd(identifierWidth)} error`);
|
|
844
|
-
this.log(`${'-'.repeat(statusWidth)} ${'-'.repeat(identifierWidth)} ${'-'.repeat(50)}`);
|
|
845
|
-
for (const r of results) {
|
|
846
|
-
const status = r.status === 'created' ? 'created' : r.status === 'updated' ? 'updated' : 'error';
|
|
847
|
-
this.log(`${status.padEnd(statusWidth)} ${(r.identifier || '').padEnd(identifierWidth)} ${r.error || ''}`);
|
|
848
|
-
}
|
|
849
|
-
}
|
|
850
|
-
}
|
|
851
943
|
this.log('');
|
|
852
944
|
this.log(`Summary: ${created} created, ${updated} updated, ${errors.length} failed`);
|
|
853
945
|
}
|
|
@@ -1011,12 +1103,24 @@ export default class AccountTransactionAllocations extends Command {
|
|
|
1011
1103
|
return { cols: flatten ? cols : cols.slice(0, 8), items: items };
|
|
1012
1104
|
}
|
|
1013
1105
|
getValue(row, col) {
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1106
|
+
if (!col.includes('.'))
|
|
1107
|
+
return String(row[col] ?? '');
|
|
1108
|
+
const parts = col.split('.');
|
|
1109
|
+
// Walk the dot-path; descending through an array branches into every
|
|
1110
|
+
// element so leaf values get collected from each one. Multiple leaves are
|
|
1111
|
+
// joined with ';' (e.g. dunningReminders.id -> "uuid1;uuid2").
|
|
1112
|
+
const walk = (o, idx) => {
|
|
1113
|
+
if (idx >= parts.length)
|
|
1114
|
+
return [o];
|
|
1115
|
+
if (o == null)
|
|
1116
|
+
return [];
|
|
1117
|
+
if (Array.isArray(o))
|
|
1118
|
+
return o.flatMap(item => walk(item, idx));
|
|
1119
|
+
if (typeof o === 'object')
|
|
1120
|
+
return walk(o[parts[idx]], idx + 1);
|
|
1121
|
+
return [];
|
|
1122
|
+
};
|
|
1123
|
+
return walk(row, 0).filter(v => v !== undefined && v !== null).map(v => String(v)).join(';');
|
|
1020
1124
|
}
|
|
1021
1125
|
printTable(data, fields) {
|
|
1022
1126
|
const { cols, items } = this.getColumns(data, fields);
|