@aderis-erp/cli 1.0.10 → 1.0.12
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/chat.d.ts +40 -0
- package/dist/commands/chat.js +1173 -0
- 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/email-transactions.d.ts +40 -0
- package/dist/commands/email-transactions.js +1173 -0
- 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 +42 -0
- package/dist/commands/purchase-orders.js +1192 -0
- package/dist/commands/reports.js +178 -86
- package/dist/commands/salary-types.js +178 -86
- package/dist/commands/sales-invoices.js +187 -93
- package/dist/commands/sales-orders.js +186 -93
- package/dist/commands/saved-views.js +178 -86
- package/dist/commands/tags.js +178 -86
- package/dist/commands/tax-codes.js +180 -88
- package/dist/commands/tax-matrix.js +178 -86
- package/dist/commands/tenants.js +180 -88
- 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 +181 -87
- 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 +1174 -328
- package/package.json +2 -1
|
@@ -432,76 +432,126 @@ export default class FilesInternal extends Command {
|
|
|
432
432
|
return '';
|
|
433
433
|
};
|
|
434
434
|
const results = [];
|
|
435
|
-
|
|
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) => {
|
|
436
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
|
+
}
|
|
437
501
|
try {
|
|
438
|
-
// Try to create
|
|
439
502
|
const response = await apiRequest('POST', createEndpoint.path, {
|
|
440
|
-
data:
|
|
503
|
+
data: body,
|
|
441
504
|
contextName: flags.context,
|
|
442
505
|
});
|
|
443
506
|
const id = response.data?.id;
|
|
444
|
-
|
|
507
|
+
return { status: 'created', id: id ? String(id) : undefined, identifier };
|
|
445
508
|
}
|
|
446
509
|
catch (error) {
|
|
447
510
|
if (error instanceof ApiError && error.status === 409) {
|
|
448
|
-
// Conflict - try to update existing
|
|
449
511
|
const errorData = error.data;
|
|
450
512
|
const existingId = errorData?.existingId;
|
|
451
513
|
if (existingId) {
|
|
452
514
|
try {
|
|
453
515
|
const updatePath = updateEndpoint.path.replace('{id}', existingId);
|
|
454
516
|
await apiRequest('PATCH', updatePath, {
|
|
455
|
-
data:
|
|
517
|
+
data: body,
|
|
456
518
|
contextName: flags.context,
|
|
457
519
|
});
|
|
458
|
-
|
|
520
|
+
return { status: 'updated', id: existingId, identifier };
|
|
459
521
|
}
|
|
460
522
|
catch (updateError) {
|
|
461
523
|
const msg = updateError instanceof ApiError ? updateError.message : String(updateError);
|
|
462
|
-
|
|
524
|
+
return { status: 'error', id: existingId, identifier, error: `Update failed: ${msg}` };
|
|
463
525
|
}
|
|
464
526
|
}
|
|
465
|
-
|
|
466
|
-
results.push({ status: 'error', identifier, error: 'Conflict but no existingId returned' });
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
else {
|
|
470
|
-
const msg = error instanceof ApiError ? `(${error.status}) ${error.message}` : String(error);
|
|
471
|
-
results.push({ status: 'error', identifier, error: msg });
|
|
527
|
+
return { status: 'error', identifier, error: 'Conflict but no existingId returned' };
|
|
472
528
|
}
|
|
529
|
+
const msg = error instanceof ApiError ? `(${error.status}) ${error.message}` : String(error);
|
|
530
|
+
return { status: 'error', identifier, error: msg };
|
|
473
531
|
}
|
|
474
|
-
}
|
|
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
|
+
}));
|
|
475
548
|
// Summary counts
|
|
476
549
|
const created = results.filter(r => r.status === 'created').length;
|
|
477
550
|
const updated = results.filter(r => r.status === 'updated').length;
|
|
478
551
|
const errors = results.filter(r => r.status === 'error');
|
|
479
|
-
|
|
480
|
-
const outputFormat = flags.output || 'table';
|
|
481
|
-
if (outputFormat === 'json') {
|
|
552
|
+
if (useJson) {
|
|
482
553
|
this.log(JSON.stringify(results, null, 2));
|
|
483
554
|
}
|
|
484
|
-
else if (outputFormat === 'csv' || flags.csv) {
|
|
485
|
-
// CSV output
|
|
486
|
-
this.log('status,identifier,id,error');
|
|
487
|
-
for (const r of results) {
|
|
488
|
-
const err = (r.error || '').replace(/"/g, '""');
|
|
489
|
-
this.log(`${r.status},${r.identifier || ''},${r.id || ''},"${err}"`);
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
else {
|
|
493
|
-
// Table output (default)
|
|
494
|
-
if (results.length > 0) {
|
|
495
|
-
const statusWidth = 8;
|
|
496
|
-
const identifierWidth = Math.max(10, ...results.map(r => (r.identifier || '').length));
|
|
497
|
-
this.log(`${'status'.padEnd(statusWidth)} ${'identifier'.padEnd(identifierWidth)} error`);
|
|
498
|
-
this.log(`${'-'.repeat(statusWidth)} ${'-'.repeat(identifierWidth)} ${'-'.repeat(50)}`);
|
|
499
|
-
for (const r of results) {
|
|
500
|
-
const status = r.status === 'created' ? 'created' : r.status === 'updated' ? 'updated' : 'error';
|
|
501
|
-
this.log(`${status.padEnd(statusWidth)} ${(r.identifier || '').padEnd(identifierWidth)} ${r.error || ''}`);
|
|
502
|
-
}
|
|
503
|
-
}
|
|
504
|
-
}
|
|
505
555
|
// Always show summary at the end
|
|
506
556
|
this.log('');
|
|
507
557
|
this.log(`Summary: ${created} created, ${updated} updated, ${errors.length} failed`);
|
|
@@ -781,80 +831,122 @@ export default class FilesInternal extends Command {
|
|
|
781
831
|
return '';
|
|
782
832
|
};
|
|
783
833
|
const results = [];
|
|
784
|
-
|
|
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) => {
|
|
785
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
|
+
}
|
|
786
898
|
try {
|
|
787
|
-
// Try to create
|
|
788
899
|
const response = await apiRequest('POST', basePath, {
|
|
789
|
-
data:
|
|
900
|
+
data: body,
|
|
790
901
|
contextName: flags.context,
|
|
791
902
|
});
|
|
792
903
|
const id = response.data?.id;
|
|
793
|
-
|
|
904
|
+
return { status: 'created', id: id ? String(id) : undefined, identifier };
|
|
794
905
|
}
|
|
795
906
|
catch (error) {
|
|
796
907
|
if (error instanceof ApiError && error.status === 409) {
|
|
797
|
-
// Conflict - try to update existing
|
|
798
908
|
const errorData = error.data;
|
|
799
909
|
const existingId = errorData?.existingId || item.id;
|
|
800
910
|
if (existingId) {
|
|
801
911
|
try {
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
const nestedIdParam = updateEndpoint.pathParams.find((p, i) => i > 0);
|
|
805
|
-
let updatePath = updateEndpoint.path.replace(`{${firstUpdateParam}}`, parentId);
|
|
806
|
-
if (nestedIdParam) {
|
|
807
|
-
updatePath = updatePath.replace(`{${nestedIdParam}}`, existingId);
|
|
808
|
-
}
|
|
809
|
-
await apiRequest('PATCH', updatePath, {
|
|
810
|
-
data: item,
|
|
912
|
+
await apiRequest('PATCH', buildUpdatePath(existingId), {
|
|
913
|
+
data: body,
|
|
811
914
|
contextName: flags.context,
|
|
812
915
|
});
|
|
813
|
-
|
|
916
|
+
return { status: 'updated', id: existingId, identifier };
|
|
814
917
|
}
|
|
815
918
|
catch (updateError) {
|
|
816
919
|
const msg = updateError instanceof ApiError ? updateError.message : String(updateError);
|
|
817
|
-
|
|
920
|
+
return { status: 'error', id: existingId, identifier, error: `Update failed: ${msg}` };
|
|
818
921
|
}
|
|
819
922
|
}
|
|
820
|
-
|
|
821
|
-
results.push({ status: 'error', identifier, error: 'Conflict but no existingId returned' });
|
|
822
|
-
}
|
|
823
|
-
}
|
|
824
|
-
else {
|
|
825
|
-
const msg = error instanceof ApiError ? `(${error.status}) ${error.message}` : String(error);
|
|
826
|
-
results.push({ status: 'error', identifier, error: msg });
|
|
923
|
+
return { status: 'error', identifier, error: 'Conflict but no existingId returned' };
|
|
827
924
|
}
|
|
925
|
+
const msg = error instanceof ApiError ? `(${error.status}) ${error.message}` : String(error);
|
|
926
|
+
return { status: 'error', identifier, error: msg };
|
|
828
927
|
}
|
|
829
|
-
}
|
|
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
|
+
}));
|
|
830
943
|
// Summary counts
|
|
831
944
|
const created = results.filter(r => r.status === 'created').length;
|
|
832
945
|
const updated = results.filter(r => r.status === 'updated').length;
|
|
833
946
|
const errors = results.filter(r => r.status === 'error');
|
|
834
|
-
|
|
835
|
-
const outputFormat = flags.output || 'table';
|
|
836
|
-
if (outputFormat === 'json') {
|
|
947
|
+
if (useJson) {
|
|
837
948
|
this.log(JSON.stringify(results, null, 2));
|
|
838
949
|
}
|
|
839
|
-
else if (outputFormat === 'csv' || flags.csv) {
|
|
840
|
-
this.log('status,identifier,id,error');
|
|
841
|
-
for (const r of results) {
|
|
842
|
-
const err = (r.error || '').replace(/"/g, '""');
|
|
843
|
-
this.log(`${r.status},${r.identifier || ''},${r.id || ''},"${err}"`);
|
|
844
|
-
}
|
|
845
|
-
}
|
|
846
|
-
else {
|
|
847
|
-
if (results.length > 0) {
|
|
848
|
-
const statusWidth = 8;
|
|
849
|
-
const identifierWidth = Math.max(10, ...results.map(r => (r.identifier || '').length));
|
|
850
|
-
this.log(`${'status'.padEnd(statusWidth)} ${'identifier'.padEnd(identifierWidth)} error`);
|
|
851
|
-
this.log(`${'-'.repeat(statusWidth)} ${'-'.repeat(identifierWidth)} ${'-'.repeat(50)}`);
|
|
852
|
-
for (const r of results) {
|
|
853
|
-
const status = r.status === 'created' ? 'created' : r.status === 'updated' ? 'updated' : 'error';
|
|
854
|
-
this.log(`${status.padEnd(statusWidth)} ${(r.identifier || '').padEnd(identifierWidth)} ${r.error || ''}`);
|
|
855
|
-
}
|
|
856
|
-
}
|
|
857
|
-
}
|
|
858
950
|
this.log('');
|
|
859
951
|
this.log(`Summary: ${created} created, ${updated} updated, ${errors.length} failed`);
|
|
860
952
|
}
|