@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
|
@@ -445,76 +445,126 @@ export default class BankAccounts extends Command {
|
|
|
445
445
|
return '';
|
|
446
446
|
};
|
|
447
447
|
const results = [];
|
|
448
|
-
|
|
448
|
+
// Stream output row-by-row so progress is visible during long imports.
|
|
449
|
+
// Pre-compute the identifier column width from the input items so the
|
|
450
|
+
// table stays aligned without buffering all rows.
|
|
451
|
+
// When stdout is piped (IDE terminals, tee, CI), Node switches to async-buffered
|
|
452
|
+
// mode and rows accumulate in the pipe buffer until it fills. Force blocking
|
|
453
|
+
// mode so each \n-terminated write flushes immediately.
|
|
454
|
+
const stdoutHandle = process.stdout._handle;
|
|
455
|
+
if (stdoutHandle?.setBlocking)
|
|
456
|
+
stdoutHandle.setBlocking(true);
|
|
457
|
+
const outputFormat = flags.output || 'table';
|
|
458
|
+
const useCsv = outputFormat === 'csv' || Boolean(flags.csv);
|
|
459
|
+
const useJson = outputFormat === 'json';
|
|
460
|
+
const statusWidth = 8;
|
|
461
|
+
const identifierWidth = Math.max(10, ...items.map(i => getItemIdentifier(i).length));
|
|
462
|
+
if (useCsv) {
|
|
463
|
+
this.log('status,identifier,id,error');
|
|
464
|
+
}
|
|
465
|
+
else if (!useJson) {
|
|
466
|
+
this.log(`${'status'.padEnd(statusWidth)} ${'identifier'.padEnd(identifierWidth)} error`);
|
|
467
|
+
this.log(`${'-'.repeat(statusWidth)} ${'-'.repeat(identifierWidth)} ${'-'.repeat(50)}`);
|
|
468
|
+
}
|
|
469
|
+
const emitRow = (r) => {
|
|
470
|
+
if (useJson)
|
|
471
|
+
return;
|
|
472
|
+
if (useCsv) {
|
|
473
|
+
const err = (r.error || '').replace(/"/g, '""');
|
|
474
|
+
this.log(`${r.status},${r.identifier || ''},${r.id || ''},"${err}"`);
|
|
475
|
+
}
|
|
476
|
+
else {
|
|
477
|
+
this.log(`${r.status.padEnd(statusWidth)} ${(r.identifier || '').padEnd(identifierWidth)} ${r.error || ''}`);
|
|
478
|
+
}
|
|
479
|
+
};
|
|
480
|
+
// Server-managed fields the API rejects in create/update bodies. Stripped
|
|
481
|
+
// before every request so re-importing a previously-exported payload Just Works.
|
|
482
|
+
const STRIP_FIELDS = new Set(['id', '_type', 'tenantId', 'createdAt', 'updatedAt', 'createdBy', 'updatedBy']);
|
|
483
|
+
const stripServerFields = (item) => {
|
|
484
|
+
const out = {};
|
|
485
|
+
for (const [k, v] of Object.entries(item)) {
|
|
486
|
+
if (!STRIP_FIELDS.has(k))
|
|
487
|
+
out[k] = v;
|
|
488
|
+
}
|
|
489
|
+
return out;
|
|
490
|
+
};
|
|
491
|
+
const processItem = async (item) => {
|
|
449
492
|
const identifier = getItemIdentifier(item);
|
|
493
|
+
const body = stripServerFields(item);
|
|
494
|
+
// If the payload carries an id (e.g. re-importing an export), PATCH directly.
|
|
495
|
+
// Fall through to POST only on 404 (so a missing record still gets created).
|
|
496
|
+
const itemId = typeof item.id === 'string' ? item.id : undefined;
|
|
497
|
+
if (itemId) {
|
|
498
|
+
try {
|
|
499
|
+
const updatePath = updateEndpoint.path.replace('{id}', itemId);
|
|
500
|
+
await apiRequest('PATCH', updatePath, {
|
|
501
|
+
data: body,
|
|
502
|
+
contextName: flags.context,
|
|
503
|
+
});
|
|
504
|
+
return { status: 'updated', id: itemId, identifier };
|
|
505
|
+
}
|
|
506
|
+
catch (error) {
|
|
507
|
+
if (!(error instanceof ApiError && error.status === 404)) {
|
|
508
|
+
const msg = error instanceof ApiError ? `(${error.status}) ${error.message}` : String(error);
|
|
509
|
+
return { status: 'error', id: itemId, identifier, error: msg };
|
|
510
|
+
}
|
|
511
|
+
// 404 → record gone, try create below
|
|
512
|
+
}
|
|
513
|
+
}
|
|
450
514
|
try {
|
|
451
|
-
// Try to create
|
|
452
515
|
const response = await apiRequest('POST', createEndpoint.path, {
|
|
453
|
-
data:
|
|
516
|
+
data: body,
|
|
454
517
|
contextName: flags.context,
|
|
455
518
|
});
|
|
456
519
|
const id = response.data?.id;
|
|
457
|
-
|
|
520
|
+
return { status: 'created', id: id ? String(id) : undefined, identifier };
|
|
458
521
|
}
|
|
459
522
|
catch (error) {
|
|
460
523
|
if (error instanceof ApiError && error.status === 409) {
|
|
461
|
-
// Conflict - try to update existing
|
|
462
524
|
const errorData = error.data;
|
|
463
525
|
const existingId = errorData?.existingId;
|
|
464
526
|
if (existingId) {
|
|
465
527
|
try {
|
|
466
528
|
const updatePath = updateEndpoint.path.replace('{id}', existingId);
|
|
467
529
|
await apiRequest('PATCH', updatePath, {
|
|
468
|
-
data:
|
|
530
|
+
data: body,
|
|
469
531
|
contextName: flags.context,
|
|
470
532
|
});
|
|
471
|
-
|
|
533
|
+
return { status: 'updated', id: existingId, identifier };
|
|
472
534
|
}
|
|
473
535
|
catch (updateError) {
|
|
474
536
|
const msg = updateError instanceof ApiError ? updateError.message : String(updateError);
|
|
475
|
-
|
|
537
|
+
return { status: 'error', id: existingId, identifier, error: `Update failed: ${msg}` };
|
|
476
538
|
}
|
|
477
539
|
}
|
|
478
|
-
|
|
479
|
-
results.push({ status: 'error', identifier, error: 'Conflict but no existingId returned' });
|
|
480
|
-
}
|
|
481
|
-
}
|
|
482
|
-
else {
|
|
483
|
-
const msg = error instanceof ApiError ? `(${error.status}) ${error.message}` : String(error);
|
|
484
|
-
results.push({ status: 'error', identifier, error: msg });
|
|
540
|
+
return { status: 'error', identifier, error: 'Conflict but no existingId returned' };
|
|
485
541
|
}
|
|
542
|
+
const msg = error instanceof ApiError ? `(${error.status}) ${error.message}` : String(error);
|
|
543
|
+
return { status: 'error', identifier, error: msg };
|
|
486
544
|
}
|
|
487
|
-
}
|
|
545
|
+
};
|
|
546
|
+
// Worker pool: keep N requests in flight at all times. Rows are emitted as
|
|
547
|
+
// each request resolves (so output order may differ from input order). The
|
|
548
|
+
// summary at the end remains accurate regardless.
|
|
549
|
+
const concurrency = 4;
|
|
550
|
+
const queue = [...items];
|
|
551
|
+
await Promise.all(Array.from({ length: Math.min(concurrency, queue.length) }, async () => {
|
|
552
|
+
for (;;) {
|
|
553
|
+
const item = queue.shift();
|
|
554
|
+
if (!item)
|
|
555
|
+
return;
|
|
556
|
+
const r = await processItem(item);
|
|
557
|
+
results.push(r);
|
|
558
|
+
emitRow(r);
|
|
559
|
+
}
|
|
560
|
+
}));
|
|
488
561
|
// Summary counts
|
|
489
562
|
const created = results.filter(r => r.status === 'created').length;
|
|
490
563
|
const updated = results.filter(r => r.status === 'updated').length;
|
|
491
564
|
const errors = results.filter(r => r.status === 'error');
|
|
492
|
-
|
|
493
|
-
const outputFormat = flags.output || 'table';
|
|
494
|
-
if (outputFormat === 'json') {
|
|
565
|
+
if (useJson) {
|
|
495
566
|
this.log(JSON.stringify(results, null, 2));
|
|
496
567
|
}
|
|
497
|
-
else if (outputFormat === 'csv' || flags.csv) {
|
|
498
|
-
// CSV output
|
|
499
|
-
this.log('status,identifier,id,error');
|
|
500
|
-
for (const r of results) {
|
|
501
|
-
const err = (r.error || '').replace(/"/g, '""');
|
|
502
|
-
this.log(`${r.status},${r.identifier || ''},${r.id || ''},"${err}"`);
|
|
503
|
-
}
|
|
504
|
-
}
|
|
505
|
-
else {
|
|
506
|
-
// Table output (default)
|
|
507
|
-
if (results.length > 0) {
|
|
508
|
-
const statusWidth = 8;
|
|
509
|
-
const identifierWidth = Math.max(10, ...results.map(r => (r.identifier || '').length));
|
|
510
|
-
this.log(`${'status'.padEnd(statusWidth)} ${'identifier'.padEnd(identifierWidth)} error`);
|
|
511
|
-
this.log(`${'-'.repeat(statusWidth)} ${'-'.repeat(identifierWidth)} ${'-'.repeat(50)}`);
|
|
512
|
-
for (const r of results) {
|
|
513
|
-
const status = r.status === 'created' ? 'created' : r.status === 'updated' ? 'updated' : 'error';
|
|
514
|
-
this.log(`${status.padEnd(statusWidth)} ${(r.identifier || '').padEnd(identifierWidth)} ${r.error || ''}`);
|
|
515
|
-
}
|
|
516
|
-
}
|
|
517
|
-
}
|
|
518
568
|
// Always show summary at the end
|
|
519
569
|
this.log('');
|
|
520
570
|
this.log(`Summary: ${created} created, ${updated} updated, ${errors.length} failed`);
|
|
@@ -794,80 +844,122 @@ export default class BankAccounts extends Command {
|
|
|
794
844
|
return '';
|
|
795
845
|
};
|
|
796
846
|
const results = [];
|
|
797
|
-
|
|
847
|
+
const stdoutHandle = process.stdout._handle;
|
|
848
|
+
if (stdoutHandle?.setBlocking)
|
|
849
|
+
stdoutHandle.setBlocking(true);
|
|
850
|
+
const outputFormat = flags.output || 'table';
|
|
851
|
+
const useCsv = outputFormat === 'csv' || Boolean(flags.csv);
|
|
852
|
+
const useJson = outputFormat === 'json';
|
|
853
|
+
const statusWidth = 8;
|
|
854
|
+
const identifierWidth = Math.max(10, ...items.map(i => getItemIdentifier(i).length));
|
|
855
|
+
if (useCsv) {
|
|
856
|
+
this.log('status,identifier,id,error');
|
|
857
|
+
}
|
|
858
|
+
else if (!useJson) {
|
|
859
|
+
this.log(`${'status'.padEnd(statusWidth)} ${'identifier'.padEnd(identifierWidth)} error`);
|
|
860
|
+
this.log(`${'-'.repeat(statusWidth)} ${'-'.repeat(identifierWidth)} ${'-'.repeat(50)}`);
|
|
861
|
+
}
|
|
862
|
+
const emitRow = (r) => {
|
|
863
|
+
if (useJson)
|
|
864
|
+
return;
|
|
865
|
+
if (useCsv) {
|
|
866
|
+
const err = (r.error || '').replace(/"/g, '""');
|
|
867
|
+
this.log(`${r.status},${r.identifier || ''},${r.id || ''},"${err}"`);
|
|
868
|
+
}
|
|
869
|
+
else {
|
|
870
|
+
this.log(`${r.status.padEnd(statusWidth)} ${(r.identifier || '').padEnd(identifierWidth)} ${r.error || ''}`);
|
|
871
|
+
}
|
|
872
|
+
};
|
|
873
|
+
const STRIP_FIELDS = new Set(['id', '_type', 'tenantId', 'createdAt', 'updatedAt', 'createdBy', 'updatedBy']);
|
|
874
|
+
const stripServerFields = (item) => {
|
|
875
|
+
const out = {};
|
|
876
|
+
for (const [k, v] of Object.entries(item)) {
|
|
877
|
+
if (!STRIP_FIELDS.has(k))
|
|
878
|
+
out[k] = v;
|
|
879
|
+
}
|
|
880
|
+
return out;
|
|
881
|
+
};
|
|
882
|
+
const buildUpdatePath = (existingId) => {
|
|
883
|
+
const firstUpdateParam = updateEndpoint.pathParams[0];
|
|
884
|
+
const nestedIdParam = updateEndpoint.pathParams.find((p, i) => i > 0);
|
|
885
|
+
let updatePath = updateEndpoint.path.replace(`{${firstUpdateParam}}`, parentId);
|
|
886
|
+
if (nestedIdParam) {
|
|
887
|
+
updatePath = updatePath.replace(`{${nestedIdParam}}`, existingId);
|
|
888
|
+
}
|
|
889
|
+
return updatePath;
|
|
890
|
+
};
|
|
891
|
+
const processItem = async (item) => {
|
|
798
892
|
const identifier = getItemIdentifier(item);
|
|
893
|
+
const body = stripServerFields(item);
|
|
894
|
+
const itemId = typeof item.id === 'string' ? item.id : undefined;
|
|
895
|
+
if (itemId) {
|
|
896
|
+
try {
|
|
897
|
+
await apiRequest('PATCH', buildUpdatePath(itemId), {
|
|
898
|
+
data: body,
|
|
899
|
+
contextName: flags.context,
|
|
900
|
+
});
|
|
901
|
+
return { status: 'updated', id: itemId, identifier };
|
|
902
|
+
}
|
|
903
|
+
catch (error) {
|
|
904
|
+
if (!(error instanceof ApiError && error.status === 404)) {
|
|
905
|
+
const msg = error instanceof ApiError ? `(${error.status}) ${error.message}` : String(error);
|
|
906
|
+
return { status: 'error', id: itemId, identifier, error: msg };
|
|
907
|
+
}
|
|
908
|
+
// 404 → fall through and try create
|
|
909
|
+
}
|
|
910
|
+
}
|
|
799
911
|
try {
|
|
800
|
-
// Try to create
|
|
801
912
|
const response = await apiRequest('POST', basePath, {
|
|
802
|
-
data:
|
|
913
|
+
data: body,
|
|
803
914
|
contextName: flags.context,
|
|
804
915
|
});
|
|
805
916
|
const id = response.data?.id;
|
|
806
|
-
|
|
917
|
+
return { status: 'created', id: id ? String(id) : undefined, identifier };
|
|
807
918
|
}
|
|
808
919
|
catch (error) {
|
|
809
920
|
if (error instanceof ApiError && error.status === 409) {
|
|
810
|
-
// Conflict - try to update existing
|
|
811
921
|
const errorData = error.data;
|
|
812
922
|
const existingId = errorData?.existingId || item.id;
|
|
813
923
|
if (existingId) {
|
|
814
924
|
try {
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
const nestedIdParam = updateEndpoint.pathParams.find((p, i) => i > 0);
|
|
818
|
-
let updatePath = updateEndpoint.path.replace(`{${firstUpdateParam}}`, parentId);
|
|
819
|
-
if (nestedIdParam) {
|
|
820
|
-
updatePath = updatePath.replace(`{${nestedIdParam}}`, existingId);
|
|
821
|
-
}
|
|
822
|
-
await apiRequest('PATCH', updatePath, {
|
|
823
|
-
data: item,
|
|
925
|
+
await apiRequest('PATCH', buildUpdatePath(existingId), {
|
|
926
|
+
data: body,
|
|
824
927
|
contextName: flags.context,
|
|
825
928
|
});
|
|
826
|
-
|
|
929
|
+
return { status: 'updated', id: existingId, identifier };
|
|
827
930
|
}
|
|
828
931
|
catch (updateError) {
|
|
829
932
|
const msg = updateError instanceof ApiError ? updateError.message : String(updateError);
|
|
830
|
-
|
|
933
|
+
return { status: 'error', id: existingId, identifier, error: `Update failed: ${msg}` };
|
|
831
934
|
}
|
|
832
935
|
}
|
|
833
|
-
|
|
834
|
-
results.push({ status: 'error', identifier, error: 'Conflict but no existingId returned' });
|
|
835
|
-
}
|
|
836
|
-
}
|
|
837
|
-
else {
|
|
838
|
-
const msg = error instanceof ApiError ? `(${error.status}) ${error.message}` : String(error);
|
|
839
|
-
results.push({ status: 'error', identifier, error: msg });
|
|
936
|
+
return { status: 'error', identifier, error: 'Conflict but no existingId returned' };
|
|
840
937
|
}
|
|
938
|
+
const msg = error instanceof ApiError ? `(${error.status}) ${error.message}` : String(error);
|
|
939
|
+
return { status: 'error', identifier, error: msg };
|
|
841
940
|
}
|
|
842
|
-
}
|
|
941
|
+
};
|
|
942
|
+
// Worker pool: 4 requests in flight at a time. Rows are emitted as each
|
|
943
|
+
// request resolves so output order may differ from input order.
|
|
944
|
+
const concurrency = 4;
|
|
945
|
+
const queue = [...items];
|
|
946
|
+
await Promise.all(Array.from({ length: Math.min(concurrency, queue.length) }, async () => {
|
|
947
|
+
for (;;) {
|
|
948
|
+
const item = queue.shift();
|
|
949
|
+
if (!item)
|
|
950
|
+
return;
|
|
951
|
+
const r = await processItem(item);
|
|
952
|
+
results.push(r);
|
|
953
|
+
emitRow(r);
|
|
954
|
+
}
|
|
955
|
+
}));
|
|
843
956
|
// Summary counts
|
|
844
957
|
const created = results.filter(r => r.status === 'created').length;
|
|
845
958
|
const updated = results.filter(r => r.status === 'updated').length;
|
|
846
959
|
const errors = results.filter(r => r.status === 'error');
|
|
847
|
-
|
|
848
|
-
const outputFormat = flags.output || 'table';
|
|
849
|
-
if (outputFormat === 'json') {
|
|
960
|
+
if (useJson) {
|
|
850
961
|
this.log(JSON.stringify(results, null, 2));
|
|
851
962
|
}
|
|
852
|
-
else if (outputFormat === 'csv' || flags.csv) {
|
|
853
|
-
this.log('status,identifier,id,error');
|
|
854
|
-
for (const r of results) {
|
|
855
|
-
const err = (r.error || '').replace(/"/g, '""');
|
|
856
|
-
this.log(`${r.status},${r.identifier || ''},${r.id || ''},"${err}"`);
|
|
857
|
-
}
|
|
858
|
-
}
|
|
859
|
-
else {
|
|
860
|
-
if (results.length > 0) {
|
|
861
|
-
const statusWidth = 8;
|
|
862
|
-
const identifierWidth = Math.max(10, ...results.map(r => (r.identifier || '').length));
|
|
863
|
-
this.log(`${'status'.padEnd(statusWidth)} ${'identifier'.padEnd(identifierWidth)} error`);
|
|
864
|
-
this.log(`${'-'.repeat(statusWidth)} ${'-'.repeat(identifierWidth)} ${'-'.repeat(50)}`);
|
|
865
|
-
for (const r of results) {
|
|
866
|
-
const status = r.status === 'created' ? 'created' : r.status === 'updated' ? 'updated' : 'error';
|
|
867
|
-
this.log(`${status.padEnd(statusWidth)} ${(r.identifier || '').padEnd(identifierWidth)} ${r.error || ''}`);
|
|
868
|
-
}
|
|
869
|
-
}
|
|
870
|
-
}
|
|
871
963
|
this.log('');
|
|
872
964
|
this.log(`Summary: ${created} created, ${updated} updated, ${errors.length} failed`);
|
|
873
965
|
}
|