@aderis-erp/cli 1.0.1 → 1.0.3
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 -1
- package/dist/commands/access-groups.js +36 -22
- package/dist/commands/account-transactions.js +30 -18
- package/dist/commands/accounts.js +30 -18
- package/dist/commands/agent-runs.js +33 -21
- package/dist/commands/{processing-logs.d.ts → async-endpoints-internal.d.ts} +2 -2
- package/dist/commands/{processing-logs.js → async-endpoints-internal.js} +39 -28
- package/dist/commands/audit-log.js +30 -18
- package/dist/commands/auth/tenant.d.ts +1 -0
- package/dist/commands/auth/tenant.js +23 -7
- package/dist/commands/bank-accounts.js +30 -18
- package/dist/commands/bank-integrations.d.ts +2 -0
- package/dist/commands/bank-integrations.js +41 -19
- package/dist/commands/business-partners---contacts.js +30 -18
- package/dist/commands/business-partners.js +30 -18
- package/dist/commands/credit-card-accounts.js +30 -18
- package/dist/commands/documents.js +36 -22
- package/dist/commands/dunning-configs.js +30 -18
- package/dist/commands/dunning-reminders.js +30 -18
- package/dist/commands/dunning-runs.js +30 -18
- package/dist/commands/employees.js +30 -18
- package/dist/commands/event-processor-mappings.js +30 -18
- package/dist/commands/files-internal.js +30 -18
- package/dist/commands/health.js +30 -18
- package/dist/commands/inbox.js +34 -20
- package/dist/commands/integrations.js +30 -18
- package/dist/commands/item-categories.js +30 -18
- package/dist/commands/items.js +30 -18
- package/dist/commands/journal-lines.js +30 -18
- package/dist/commands/journals.js +30 -18
- package/dist/commands/ledgers.js +30 -18
- package/dist/commands/office-locations.js +30 -18
- package/dist/commands/payment-method-ledger-mappings.js +30 -18
- package/dist/commands/payment-methods.js +30 -18
- package/dist/commands/payment-runs.js +30 -18
- package/dist/commands/payment-terms.js +30 -18
- package/dist/commands/price-lists.js +30 -18
- package/dist/commands/processor-mappings.js +30 -18
- package/dist/commands/processors.js +31 -19
- package/dist/commands/reconciliation.js +30 -18
- package/dist/commands/reports.js +30 -18
- package/dist/commands/salary-types.js +30 -18
- package/dist/commands/sales-invoices.js +32 -19
- package/dist/commands/sales-orders.js +33 -19
- package/dist/commands/switch.d.ts +1 -0
- package/dist/commands/switch.js +58 -3
- package/dist/commands/tags.js +30 -18
- package/dist/commands/tax-codes.js +30 -18
- package/dist/commands/tax-matrix.js +30 -18
- package/dist/commands/tenants.js +30 -18
- package/dist/commands/text-templates.js +30 -18
- package/dist/commands/tools.js +30 -18
- package/dist/commands/vendor-invoices.js +33 -19
- package/dist/commands/webhooks.js +30 -18
- package/dist/commands/workflows.js +30 -18
- package/dist/index 2.js +1 -0
- package/dist/index.d 2.ts +1 -0
- package/dist/lib/auth.d.ts +16 -1
- package/dist/lib/auth.js +167 -50
- package/dist/lib/config.d.ts +7 -0
- package/dist/lib/config.js +6 -0
- package/oclif.manifest.json +65 -385
- package/package.json +2 -2
- package/dist/commands/account-statement-runs.d.ts +0 -40
- package/dist/commands/account-statement-runs.js +0 -1004
- package/dist/commands/bank-statements.d.ts +0 -40
- package/dist/commands/bank-statements.js +0 -998
|
@@ -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 = [...["initiate", "providers-supported", "providers-consent-status", "delete-providers-consent", "list", "create", "get", "update", "delete", "log"], ...(HAS_IMPORT ? ['import'] : []), ...(HAS_EXPORT ? ['export'] : []), ...NESTED_IMPORTS.map(n => `import-${n}`)];
|
|
9
|
+
const SUBCOMMANDS = [...["initiate", "providers-supported", "providers-consent-status", "delete-providers-consent", "list", "create", "get", "update", "delete", "log", "list-account-statement-runs", "trigger-account-statement-runs", "get-account-statement-runs", "account-statement-runs-files", "trigger-account-statement-runs-reimport", "list-statements", "statements", "download-statements-xml"], ...(HAS_IMPORT ? ['import'] : []), ...(HAS_EXPORT ? ['export'] : []), ...NESTED_IMPORTS.map(n => `import-${n}`)];
|
|
10
10
|
const ENDPOINTS = {
|
|
11
11
|
'initiate': { method: 'POST', path: '/v1/bank-integrations/initiate', summary: 'Initiate the OAuth/auth flow for a bank integration', pathParams: [], hasBody: true, isMultipart: false },
|
|
12
12
|
'providers-supported': { method: 'GET', path: '/v1/bank-integrations/providers/supported', summary: 'List supported bLink providers', pathParams: [], hasBody: false, isMultipart: false },
|
|
@@ -18,6 +18,14 @@ const ENDPOINTS = {
|
|
|
18
18
|
'update': { method: 'PATCH', path: '/v1/bank-integrations/{id}', summary: 'Update the display name of a BankIntegration', pathParams: ['id'], hasBody: true, isMultipart: false },
|
|
19
19
|
'delete': { method: 'DELETE', path: '/v1/bank-integrations/{id}', summary: 'Delete a BankIntegration', pathParams: ['id'], hasBody: false, isMultipart: false },
|
|
20
20
|
'log': { method: 'GET', path: '/v1/bank-integrations/{id}/log', summary: 'Get activity log for a bank integration', pathParams: ['id'], hasBody: false, isMultipart: false },
|
|
21
|
+
'list-account-statement-runs': { method: 'GET', path: '/v1/bank-integrations/{bankIntegrationId}/account-statement-runs', summary: 'List bank statement import runs', pathParams: ['bankIntegrationId'], hasBody: false, isMultipart: false },
|
|
22
|
+
'trigger-account-statement-runs': { method: 'POST', path: '/v1/bank-integrations/{bankIntegrationId}/account-statement-runs', summary: 'Trigger a bank statement import', pathParams: ['bankIntegrationId'], hasBody: true, isMultipart: false },
|
|
23
|
+
'get-account-statement-runs': { method: 'GET', path: '/v1/bank-integrations/{bankIntegrationId}/account-statement-runs/{importRunId}', summary: 'Get import run details', pathParams: ['bankIntegrationId', 'importRunId'], hasBody: false, isMultipart: false },
|
|
24
|
+
'account-statement-runs-files': { method: 'GET', path: '/v1/bank-integrations/{bankIntegrationId}/account-statement-runs/{importRunId}/files', summary: 'Get files for an import run', pathParams: ['bankIntegrationId', 'importRunId'], hasBody: false, isMultipart: false },
|
|
25
|
+
'trigger-account-statement-runs-reimport': { method: 'POST', path: '/v1/bank-integrations/{bankIntegrationId}/account-statement-runs/{importRunId}/reimport', summary: 'Trigger reimport of an existing account statement import run', pathParams: ['bankIntegrationId', 'importRunId'], hasBody: true, isMultipart: false },
|
|
26
|
+
'list-statements': { method: 'GET', path: '/v1/bank-integrations/{bankIntegrationId}/statements', summary: 'List CAMT.053 statements for a bank integration', pathParams: ['bankIntegrationId'], hasBody: false, isMultipart: false },
|
|
27
|
+
'statements': { method: 'GET', path: '/v1/bank-integrations/{bankIntegrationId}/statements/{statementId}', summary: 'Get CAMT.053 statement detail', pathParams: ['bankIntegrationId', 'statementId'], hasBody: false, isMultipart: false },
|
|
28
|
+
'download-statements-xml': { method: 'GET', path: '/v1/bank-integrations/{bankIntegrationId}/statements/{statementId}/xml', summary: 'Get raw CAMT.053 XML for a statement', pathParams: ['bankIntegrationId', 'statementId'], hasBody: false, isMultipart: false },
|
|
21
29
|
};
|
|
22
30
|
export default class BankIntegrations extends Command {
|
|
23
31
|
static description = 'Manage bank integrations';
|
|
@@ -41,6 +49,8 @@ export default class BankIntegrations extends Command {
|
|
|
41
49
|
data: Flags.string({ char: 'd', description: 'JSON data for request body' }),
|
|
42
50
|
file: Flags.string({ char: 'f', description: 'Read request body from file' }),
|
|
43
51
|
set: Flags.string({ char: 's', description: 'Set individual field (e.g. --set firstName=John)', multiple: true }),
|
|
52
|
+
'import-run-id': Flags.string({ description: 'Path param: importRunId' }),
|
|
53
|
+
'statement-id': Flags.string({ description: 'Path param: statementId' }),
|
|
44
54
|
page: Flags.string({ description: 'Page number' }),
|
|
45
55
|
limit: Flags.string({ description: 'Items per page' }),
|
|
46
56
|
include: Flags.string({ description: 'Relations to include' }),
|
|
@@ -824,32 +834,44 @@ export default class BankIntegrations extends Command {
|
|
|
824
834
|
filterFields(data, fields) {
|
|
825
835
|
const isUnsafeKey = (k) => k === '__proto__' || k === 'constructor' || k === 'prototype';
|
|
826
836
|
const pick = (obj, keys) => {
|
|
827
|
-
|
|
837
|
+
// Group keys by their first segment so sibling sub-paths
|
|
838
|
+
// (e.g. 'items.amount' + 'items._type') resolve in one recursive pass
|
|
839
|
+
// and don't clobber each other on merge.
|
|
840
|
+
const directKeys = new Set();
|
|
841
|
+
const nestedKeys = new Map();
|
|
828
842
|
for (const key of keys) {
|
|
829
843
|
if (key.split('.').some(isUnsafeKey))
|
|
830
844
|
continue;
|
|
831
845
|
if (key.includes('.')) {
|
|
832
|
-
// Handle nested fields like 'customer.name' or 'allocations.salesInvoiceId'
|
|
833
846
|
const [first, ...rest] = key.split('.');
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
const existing = Array.isArray(result[first]) ? result[first] : [];
|
|
840
|
-
result[first] = val.map((item, i) => ({
|
|
841
|
-
...(existing[i] || {}),
|
|
842
|
-
...pick(item, [restKey]),
|
|
843
|
-
}));
|
|
844
|
-
}
|
|
845
|
-
else {
|
|
846
|
-
const nested = pick(val, [restKey]);
|
|
847
|
-
result[first] = { ...(result[first] || {}), ...nested };
|
|
848
|
-
}
|
|
847
|
+
if (isUnsafeKey(first))
|
|
848
|
+
continue;
|
|
849
|
+
const list = nestedKeys.get(first);
|
|
850
|
+
if (list) {
|
|
851
|
+
list.push(rest.join('.'));
|
|
849
852
|
}
|
|
853
|
+
else {
|
|
854
|
+
nestedKeys.set(first, [rest.join('.')]);
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
else {
|
|
858
|
+
directKeys.add(key);
|
|
850
859
|
}
|
|
851
|
-
|
|
860
|
+
}
|
|
861
|
+
const result = {};
|
|
862
|
+
for (const key of directKeys) {
|
|
863
|
+
if (key in obj)
|
|
852
864
|
result[key] = obj[key];
|
|
865
|
+
}
|
|
866
|
+
for (const [first, restKeys] of nestedKeys) {
|
|
867
|
+
const val = obj[first];
|
|
868
|
+
if (!val || typeof val !== 'object')
|
|
869
|
+
continue;
|
|
870
|
+
if (Array.isArray(val)) {
|
|
871
|
+
result[first] = val.map(item => pick(item, restKeys));
|
|
872
|
+
}
|
|
873
|
+
else {
|
|
874
|
+
result[first] = pick(val, restKeys);
|
|
853
875
|
}
|
|
854
876
|
}
|
|
855
877
|
return result;
|
|
@@ -819,32 +819,44 @@ export default class BusinessPartnersContacts extends Command {
|
|
|
819
819
|
filterFields(data, fields) {
|
|
820
820
|
const isUnsafeKey = (k) => k === '__proto__' || k === 'constructor' || k === 'prototype';
|
|
821
821
|
const pick = (obj, keys) => {
|
|
822
|
-
|
|
822
|
+
// Group keys by their first segment so sibling sub-paths
|
|
823
|
+
// (e.g. 'items.amount' + 'items._type') resolve in one recursive pass
|
|
824
|
+
// and don't clobber each other on merge.
|
|
825
|
+
const directKeys = new Set();
|
|
826
|
+
const nestedKeys = new Map();
|
|
823
827
|
for (const key of keys) {
|
|
824
828
|
if (key.split('.').some(isUnsafeKey))
|
|
825
829
|
continue;
|
|
826
830
|
if (key.includes('.')) {
|
|
827
|
-
// Handle nested fields like 'customer.name' or 'allocations.salesInvoiceId'
|
|
828
831
|
const [first, ...rest] = key.split('.');
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
const existing = Array.isArray(result[first]) ? result[first] : [];
|
|
835
|
-
result[first] = val.map((item, i) => ({
|
|
836
|
-
...(existing[i] || {}),
|
|
837
|
-
...pick(item, [restKey]),
|
|
838
|
-
}));
|
|
839
|
-
}
|
|
840
|
-
else {
|
|
841
|
-
const nested = pick(val, [restKey]);
|
|
842
|
-
result[first] = { ...(result[first] || {}), ...nested };
|
|
843
|
-
}
|
|
832
|
+
if (isUnsafeKey(first))
|
|
833
|
+
continue;
|
|
834
|
+
const list = nestedKeys.get(first);
|
|
835
|
+
if (list) {
|
|
836
|
+
list.push(rest.join('.'));
|
|
844
837
|
}
|
|
838
|
+
else {
|
|
839
|
+
nestedKeys.set(first, [rest.join('.')]);
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
else {
|
|
843
|
+
directKeys.add(key);
|
|
845
844
|
}
|
|
846
|
-
|
|
845
|
+
}
|
|
846
|
+
const result = {};
|
|
847
|
+
for (const key of directKeys) {
|
|
848
|
+
if (key in obj)
|
|
847
849
|
result[key] = obj[key];
|
|
850
|
+
}
|
|
851
|
+
for (const [first, restKeys] of nestedKeys) {
|
|
852
|
+
const val = obj[first];
|
|
853
|
+
if (!val || typeof val !== 'object')
|
|
854
|
+
continue;
|
|
855
|
+
if (Array.isArray(val)) {
|
|
856
|
+
result[first] = val.map(item => pick(item, restKeys));
|
|
857
|
+
}
|
|
858
|
+
else {
|
|
859
|
+
result[first] = pick(val, restKeys);
|
|
848
860
|
}
|
|
849
861
|
}
|
|
850
862
|
return result;
|
|
@@ -825,32 +825,44 @@ export default class BusinessPartners extends Command {
|
|
|
825
825
|
filterFields(data, fields) {
|
|
826
826
|
const isUnsafeKey = (k) => k === '__proto__' || k === 'constructor' || k === 'prototype';
|
|
827
827
|
const pick = (obj, keys) => {
|
|
828
|
-
|
|
828
|
+
// Group keys by their first segment so sibling sub-paths
|
|
829
|
+
// (e.g. 'items.amount' + 'items._type') resolve in one recursive pass
|
|
830
|
+
// and don't clobber each other on merge.
|
|
831
|
+
const directKeys = new Set();
|
|
832
|
+
const nestedKeys = new Map();
|
|
829
833
|
for (const key of keys) {
|
|
830
834
|
if (key.split('.').some(isUnsafeKey))
|
|
831
835
|
continue;
|
|
832
836
|
if (key.includes('.')) {
|
|
833
|
-
// Handle nested fields like 'customer.name' or 'allocations.salesInvoiceId'
|
|
834
837
|
const [first, ...rest] = key.split('.');
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
const existing = Array.isArray(result[first]) ? result[first] : [];
|
|
841
|
-
result[first] = val.map((item, i) => ({
|
|
842
|
-
...(existing[i] || {}),
|
|
843
|
-
...pick(item, [restKey]),
|
|
844
|
-
}));
|
|
845
|
-
}
|
|
846
|
-
else {
|
|
847
|
-
const nested = pick(val, [restKey]);
|
|
848
|
-
result[first] = { ...(result[first] || {}), ...nested };
|
|
849
|
-
}
|
|
838
|
+
if (isUnsafeKey(first))
|
|
839
|
+
continue;
|
|
840
|
+
const list = nestedKeys.get(first);
|
|
841
|
+
if (list) {
|
|
842
|
+
list.push(rest.join('.'));
|
|
850
843
|
}
|
|
844
|
+
else {
|
|
845
|
+
nestedKeys.set(first, [rest.join('.')]);
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
else {
|
|
849
|
+
directKeys.add(key);
|
|
851
850
|
}
|
|
852
|
-
|
|
851
|
+
}
|
|
852
|
+
const result = {};
|
|
853
|
+
for (const key of directKeys) {
|
|
854
|
+
if (key in obj)
|
|
853
855
|
result[key] = obj[key];
|
|
856
|
+
}
|
|
857
|
+
for (const [first, restKeys] of nestedKeys) {
|
|
858
|
+
const val = obj[first];
|
|
859
|
+
if (!val || typeof val !== 'object')
|
|
860
|
+
continue;
|
|
861
|
+
if (Array.isArray(val)) {
|
|
862
|
+
result[first] = val.map(item => pick(item, restKeys));
|
|
863
|
+
}
|
|
864
|
+
else {
|
|
865
|
+
result[first] = pick(val, restKeys);
|
|
854
866
|
}
|
|
855
867
|
}
|
|
856
868
|
return result;
|
|
@@ -831,32 +831,44 @@ export default class CreditCardAccounts extends Command {
|
|
|
831
831
|
filterFields(data, fields) {
|
|
832
832
|
const isUnsafeKey = (k) => k === '__proto__' || k === 'constructor' || k === 'prototype';
|
|
833
833
|
const pick = (obj, keys) => {
|
|
834
|
-
|
|
834
|
+
// Group keys by their first segment so sibling sub-paths
|
|
835
|
+
// (e.g. 'items.amount' + 'items._type') resolve in one recursive pass
|
|
836
|
+
// and don't clobber each other on merge.
|
|
837
|
+
const directKeys = new Set();
|
|
838
|
+
const nestedKeys = new Map();
|
|
835
839
|
for (const key of keys) {
|
|
836
840
|
if (key.split('.').some(isUnsafeKey))
|
|
837
841
|
continue;
|
|
838
842
|
if (key.includes('.')) {
|
|
839
|
-
// Handle nested fields like 'customer.name' or 'allocations.salesInvoiceId'
|
|
840
843
|
const [first, ...rest] = key.split('.');
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
const existing = Array.isArray(result[first]) ? result[first] : [];
|
|
847
|
-
result[first] = val.map((item, i) => ({
|
|
848
|
-
...(existing[i] || {}),
|
|
849
|
-
...pick(item, [restKey]),
|
|
850
|
-
}));
|
|
851
|
-
}
|
|
852
|
-
else {
|
|
853
|
-
const nested = pick(val, [restKey]);
|
|
854
|
-
result[first] = { ...(result[first] || {}), ...nested };
|
|
855
|
-
}
|
|
844
|
+
if (isUnsafeKey(first))
|
|
845
|
+
continue;
|
|
846
|
+
const list = nestedKeys.get(first);
|
|
847
|
+
if (list) {
|
|
848
|
+
list.push(rest.join('.'));
|
|
856
849
|
}
|
|
850
|
+
else {
|
|
851
|
+
nestedKeys.set(first, [rest.join('.')]);
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
else {
|
|
855
|
+
directKeys.add(key);
|
|
857
856
|
}
|
|
858
|
-
|
|
857
|
+
}
|
|
858
|
+
const result = {};
|
|
859
|
+
for (const key of directKeys) {
|
|
860
|
+
if (key in obj)
|
|
859
861
|
result[key] = obj[key];
|
|
862
|
+
}
|
|
863
|
+
for (const [first, restKeys] of nestedKeys) {
|
|
864
|
+
const val = obj[first];
|
|
865
|
+
if (!val || typeof val !== 'object')
|
|
866
|
+
continue;
|
|
867
|
+
if (Array.isArray(val)) {
|
|
868
|
+
result[first] = val.map(item => pick(item, restKeys));
|
|
869
|
+
}
|
|
870
|
+
else {
|
|
871
|
+
result[first] = pick(val, restKeys);
|
|
860
872
|
}
|
|
861
873
|
}
|
|
862
874
|
return result;
|
|
@@ -3,14 +3,14 @@ import { apiRequest, ApiError } from '../lib/api-client.js';
|
|
|
3
3
|
import { getCurrentContext, getContext, getBaseUrls } from '../lib/config.js';
|
|
4
4
|
// Add 'import' action if both create and update exist
|
|
5
5
|
const HAS_IMPORT = true;
|
|
6
|
-
const HAS_EXPORT =
|
|
6
|
+
const HAS_EXPORT = true;
|
|
7
7
|
const HAS_CAMT053 = false;
|
|
8
8
|
const NESTED_IMPORTS = [];
|
|
9
|
-
const SUBCOMMANDS = [...["
|
|
9
|
+
const SUBCOMMANDS = [...["list", "create", "get", "update", "delete", "reclassify"], ...(HAS_IMPORT ? ['import'] : []), ...(HAS_EXPORT ? ['export'] : []), ...NESTED_IMPORTS.map(n => `import-${n}`)];
|
|
10
10
|
const ENDPOINTS = {
|
|
11
|
-
'
|
|
11
|
+
'list': { method: 'GET', path: '/v1/documents', summary: 'List documents (paginated)', pathParams: [], hasBody: false, isMultipart: false },
|
|
12
12
|
'create': { method: 'POST', path: '/v1/documents', summary: 'Create a new document (letterbox)', pathParams: [], hasBody: true, isMultipart: false },
|
|
13
|
-
'get
|
|
13
|
+
'get': { method: 'GET', path: '/v1/documents/{id}', summary: 'Get document detail with files, audit log, and notes placeholder', pathParams: ['id'], hasBody: false, isMultipart: false },
|
|
14
14
|
'update': { method: 'PATCH', path: '/v1/documents/{id}', summary: 'Patch an existing document', pathParams: ['id'], hasBody: true, isMultipart: false },
|
|
15
15
|
'delete': { method: 'DELETE', path: '/v1/documents/{id}', summary: 'Soft-delete (discard) a document', pathParams: ['id'], hasBody: true, isMultipart: false },
|
|
16
16
|
'reclassify': { method: 'POST', path: '/v1/documents/{id}/reclassify', summary: 'Reclassify a document to a new type', pathParams: ['id'], hasBody: true, isMultipart: false },
|
|
@@ -18,10 +18,12 @@ const ENDPOINTS = {
|
|
|
18
18
|
export default class Documents extends Command {
|
|
19
19
|
static description = 'Manage documents';
|
|
20
20
|
static examples = [
|
|
21
|
+
'<%= config.bin %> documents list',
|
|
21
22
|
'<%= config.bin %> documents get <id>',
|
|
22
23
|
'<%= config.bin %> documents create --data \'{...}\'',
|
|
23
24
|
'<%= config.bin %> documents update <id> --set field=value',
|
|
24
25
|
'<%= config.bin %> documents import --file data.json',
|
|
26
|
+
'<%= config.bin %> documents export --csv > documents.csv',
|
|
25
27
|
];
|
|
26
28
|
static args = {
|
|
27
29
|
action: Args.string({ description: 'Action: ' + SUBCOMMANDS.join(', '), required: true }),
|
|
@@ -818,32 +820,44 @@ export default class Documents extends Command {
|
|
|
818
820
|
filterFields(data, fields) {
|
|
819
821
|
const isUnsafeKey = (k) => k === '__proto__' || k === 'constructor' || k === 'prototype';
|
|
820
822
|
const pick = (obj, keys) => {
|
|
821
|
-
|
|
823
|
+
// Group keys by their first segment so sibling sub-paths
|
|
824
|
+
// (e.g. 'items.amount' + 'items._type') resolve in one recursive pass
|
|
825
|
+
// and don't clobber each other on merge.
|
|
826
|
+
const directKeys = new Set();
|
|
827
|
+
const nestedKeys = new Map();
|
|
822
828
|
for (const key of keys) {
|
|
823
829
|
if (key.split('.').some(isUnsafeKey))
|
|
824
830
|
continue;
|
|
825
831
|
if (key.includes('.')) {
|
|
826
|
-
// Handle nested fields like 'customer.name' or 'allocations.salesInvoiceId'
|
|
827
832
|
const [first, ...rest] = key.split('.');
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
const existing = Array.isArray(result[first]) ? result[first] : [];
|
|
834
|
-
result[first] = val.map((item, i) => ({
|
|
835
|
-
...(existing[i] || {}),
|
|
836
|
-
...pick(item, [restKey]),
|
|
837
|
-
}));
|
|
838
|
-
}
|
|
839
|
-
else {
|
|
840
|
-
const nested = pick(val, [restKey]);
|
|
841
|
-
result[first] = { ...(result[first] || {}), ...nested };
|
|
842
|
-
}
|
|
833
|
+
if (isUnsafeKey(first))
|
|
834
|
+
continue;
|
|
835
|
+
const list = nestedKeys.get(first);
|
|
836
|
+
if (list) {
|
|
837
|
+
list.push(rest.join('.'));
|
|
843
838
|
}
|
|
839
|
+
else {
|
|
840
|
+
nestedKeys.set(first, [rest.join('.')]);
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
else {
|
|
844
|
+
directKeys.add(key);
|
|
844
845
|
}
|
|
845
|
-
|
|
846
|
+
}
|
|
847
|
+
const result = {};
|
|
848
|
+
for (const key of directKeys) {
|
|
849
|
+
if (key in obj)
|
|
846
850
|
result[key] = obj[key];
|
|
851
|
+
}
|
|
852
|
+
for (const [first, restKeys] of nestedKeys) {
|
|
853
|
+
const val = obj[first];
|
|
854
|
+
if (!val || typeof val !== 'object')
|
|
855
|
+
continue;
|
|
856
|
+
if (Array.isArray(val)) {
|
|
857
|
+
result[first] = val.map(item => pick(item, restKeys));
|
|
858
|
+
}
|
|
859
|
+
else {
|
|
860
|
+
result[first] = pick(val, restKeys);
|
|
847
861
|
}
|
|
848
862
|
}
|
|
849
863
|
return result;
|
|
@@ -819,32 +819,44 @@ export default class DunningConfigs extends Command {
|
|
|
819
819
|
filterFields(data, fields) {
|
|
820
820
|
const isUnsafeKey = (k) => k === '__proto__' || k === 'constructor' || k === 'prototype';
|
|
821
821
|
const pick = (obj, keys) => {
|
|
822
|
-
|
|
822
|
+
// Group keys by their first segment so sibling sub-paths
|
|
823
|
+
// (e.g. 'items.amount' + 'items._type') resolve in one recursive pass
|
|
824
|
+
// and don't clobber each other on merge.
|
|
825
|
+
const directKeys = new Set();
|
|
826
|
+
const nestedKeys = new Map();
|
|
823
827
|
for (const key of keys) {
|
|
824
828
|
if (key.split('.').some(isUnsafeKey))
|
|
825
829
|
continue;
|
|
826
830
|
if (key.includes('.')) {
|
|
827
|
-
// Handle nested fields like 'customer.name' or 'allocations.salesInvoiceId'
|
|
828
831
|
const [first, ...rest] = key.split('.');
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
const existing = Array.isArray(result[first]) ? result[first] : [];
|
|
835
|
-
result[first] = val.map((item, i) => ({
|
|
836
|
-
...(existing[i] || {}),
|
|
837
|
-
...pick(item, [restKey]),
|
|
838
|
-
}));
|
|
839
|
-
}
|
|
840
|
-
else {
|
|
841
|
-
const nested = pick(val, [restKey]);
|
|
842
|
-
result[first] = { ...(result[first] || {}), ...nested };
|
|
843
|
-
}
|
|
832
|
+
if (isUnsafeKey(first))
|
|
833
|
+
continue;
|
|
834
|
+
const list = nestedKeys.get(first);
|
|
835
|
+
if (list) {
|
|
836
|
+
list.push(rest.join('.'));
|
|
844
837
|
}
|
|
838
|
+
else {
|
|
839
|
+
nestedKeys.set(first, [rest.join('.')]);
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
else {
|
|
843
|
+
directKeys.add(key);
|
|
845
844
|
}
|
|
846
|
-
|
|
845
|
+
}
|
|
846
|
+
const result = {};
|
|
847
|
+
for (const key of directKeys) {
|
|
848
|
+
if (key in obj)
|
|
847
849
|
result[key] = obj[key];
|
|
850
|
+
}
|
|
851
|
+
for (const [first, restKeys] of nestedKeys) {
|
|
852
|
+
const val = obj[first];
|
|
853
|
+
if (!val || typeof val !== 'object')
|
|
854
|
+
continue;
|
|
855
|
+
if (Array.isArray(val)) {
|
|
856
|
+
result[first] = val.map(item => pick(item, restKeys));
|
|
857
|
+
}
|
|
858
|
+
else {
|
|
859
|
+
result[first] = pick(val, restKeys);
|
|
848
860
|
}
|
|
849
861
|
}
|
|
850
862
|
return result;
|
|
@@ -820,32 +820,44 @@ export default class DunningReminders extends Command {
|
|
|
820
820
|
filterFields(data, fields) {
|
|
821
821
|
const isUnsafeKey = (k) => k === '__proto__' || k === 'constructor' || k === 'prototype';
|
|
822
822
|
const pick = (obj, keys) => {
|
|
823
|
-
|
|
823
|
+
// Group keys by their first segment so sibling sub-paths
|
|
824
|
+
// (e.g. 'items.amount' + 'items._type') resolve in one recursive pass
|
|
825
|
+
// and don't clobber each other on merge.
|
|
826
|
+
const directKeys = new Set();
|
|
827
|
+
const nestedKeys = new Map();
|
|
824
828
|
for (const key of keys) {
|
|
825
829
|
if (key.split('.').some(isUnsafeKey))
|
|
826
830
|
continue;
|
|
827
831
|
if (key.includes('.')) {
|
|
828
|
-
// Handle nested fields like 'customer.name' or 'allocations.salesInvoiceId'
|
|
829
832
|
const [first, ...rest] = key.split('.');
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
const existing = Array.isArray(result[first]) ? result[first] : [];
|
|
836
|
-
result[first] = val.map((item, i) => ({
|
|
837
|
-
...(existing[i] || {}),
|
|
838
|
-
...pick(item, [restKey]),
|
|
839
|
-
}));
|
|
840
|
-
}
|
|
841
|
-
else {
|
|
842
|
-
const nested = pick(val, [restKey]);
|
|
843
|
-
result[first] = { ...(result[first] || {}), ...nested };
|
|
844
|
-
}
|
|
833
|
+
if (isUnsafeKey(first))
|
|
834
|
+
continue;
|
|
835
|
+
const list = nestedKeys.get(first);
|
|
836
|
+
if (list) {
|
|
837
|
+
list.push(rest.join('.'));
|
|
845
838
|
}
|
|
839
|
+
else {
|
|
840
|
+
nestedKeys.set(first, [rest.join('.')]);
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
else {
|
|
844
|
+
directKeys.add(key);
|
|
846
845
|
}
|
|
847
|
-
|
|
846
|
+
}
|
|
847
|
+
const result = {};
|
|
848
|
+
for (const key of directKeys) {
|
|
849
|
+
if (key in obj)
|
|
848
850
|
result[key] = obj[key];
|
|
851
|
+
}
|
|
852
|
+
for (const [first, restKeys] of nestedKeys) {
|
|
853
|
+
const val = obj[first];
|
|
854
|
+
if (!val || typeof val !== 'object')
|
|
855
|
+
continue;
|
|
856
|
+
if (Array.isArray(val)) {
|
|
857
|
+
result[first] = val.map(item => pick(item, restKeys));
|
|
858
|
+
}
|
|
859
|
+
else {
|
|
860
|
+
result[first] = pick(val, restKeys);
|
|
849
861
|
}
|
|
850
862
|
}
|
|
851
863
|
return result;
|
|
@@ -808,32 +808,44 @@ export default class DunningRuns extends Command {
|
|
|
808
808
|
filterFields(data, fields) {
|
|
809
809
|
const isUnsafeKey = (k) => k === '__proto__' || k === 'constructor' || k === 'prototype';
|
|
810
810
|
const pick = (obj, keys) => {
|
|
811
|
-
|
|
811
|
+
// Group keys by their first segment so sibling sub-paths
|
|
812
|
+
// (e.g. 'items.amount' + 'items._type') resolve in one recursive pass
|
|
813
|
+
// and don't clobber each other on merge.
|
|
814
|
+
const directKeys = new Set();
|
|
815
|
+
const nestedKeys = new Map();
|
|
812
816
|
for (const key of keys) {
|
|
813
817
|
if (key.split('.').some(isUnsafeKey))
|
|
814
818
|
continue;
|
|
815
819
|
if (key.includes('.')) {
|
|
816
|
-
// Handle nested fields like 'customer.name' or 'allocations.salesInvoiceId'
|
|
817
820
|
const [first, ...rest] = key.split('.');
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
const existing = Array.isArray(result[first]) ? result[first] : [];
|
|
824
|
-
result[first] = val.map((item, i) => ({
|
|
825
|
-
...(existing[i] || {}),
|
|
826
|
-
...pick(item, [restKey]),
|
|
827
|
-
}));
|
|
828
|
-
}
|
|
829
|
-
else {
|
|
830
|
-
const nested = pick(val, [restKey]);
|
|
831
|
-
result[first] = { ...(result[first] || {}), ...nested };
|
|
832
|
-
}
|
|
821
|
+
if (isUnsafeKey(first))
|
|
822
|
+
continue;
|
|
823
|
+
const list = nestedKeys.get(first);
|
|
824
|
+
if (list) {
|
|
825
|
+
list.push(rest.join('.'));
|
|
833
826
|
}
|
|
827
|
+
else {
|
|
828
|
+
nestedKeys.set(first, [rest.join('.')]);
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
else {
|
|
832
|
+
directKeys.add(key);
|
|
834
833
|
}
|
|
835
|
-
|
|
834
|
+
}
|
|
835
|
+
const result = {};
|
|
836
|
+
for (const key of directKeys) {
|
|
837
|
+
if (key in obj)
|
|
836
838
|
result[key] = obj[key];
|
|
839
|
+
}
|
|
840
|
+
for (const [first, restKeys] of nestedKeys) {
|
|
841
|
+
const val = obj[first];
|
|
842
|
+
if (!val || typeof val !== 'object')
|
|
843
|
+
continue;
|
|
844
|
+
if (Array.isArray(val)) {
|
|
845
|
+
result[first] = val.map(item => pick(item, restKeys));
|
|
846
|
+
}
|
|
847
|
+
else {
|
|
848
|
+
result[first] = pick(val, restKeys);
|
|
837
849
|
}
|
|
838
850
|
}
|
|
839
851
|
return result;
|
|
@@ -850,32 +850,44 @@ export default class Employees extends Command {
|
|
|
850
850
|
filterFields(data, fields) {
|
|
851
851
|
const isUnsafeKey = (k) => k === '__proto__' || k === 'constructor' || k === 'prototype';
|
|
852
852
|
const pick = (obj, keys) => {
|
|
853
|
-
|
|
853
|
+
// Group keys by their first segment so sibling sub-paths
|
|
854
|
+
// (e.g. 'items.amount' + 'items._type') resolve in one recursive pass
|
|
855
|
+
// and don't clobber each other on merge.
|
|
856
|
+
const directKeys = new Set();
|
|
857
|
+
const nestedKeys = new Map();
|
|
854
858
|
for (const key of keys) {
|
|
855
859
|
if (key.split('.').some(isUnsafeKey))
|
|
856
860
|
continue;
|
|
857
861
|
if (key.includes('.')) {
|
|
858
|
-
// Handle nested fields like 'customer.name' or 'allocations.salesInvoiceId'
|
|
859
862
|
const [first, ...rest] = key.split('.');
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
const existing = Array.isArray(result[first]) ? result[first] : [];
|
|
866
|
-
result[first] = val.map((item, i) => ({
|
|
867
|
-
...(existing[i] || {}),
|
|
868
|
-
...pick(item, [restKey]),
|
|
869
|
-
}));
|
|
870
|
-
}
|
|
871
|
-
else {
|
|
872
|
-
const nested = pick(val, [restKey]);
|
|
873
|
-
result[first] = { ...(result[first] || {}), ...nested };
|
|
874
|
-
}
|
|
863
|
+
if (isUnsafeKey(first))
|
|
864
|
+
continue;
|
|
865
|
+
const list = nestedKeys.get(first);
|
|
866
|
+
if (list) {
|
|
867
|
+
list.push(rest.join('.'));
|
|
875
868
|
}
|
|
869
|
+
else {
|
|
870
|
+
nestedKeys.set(first, [rest.join('.')]);
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
else {
|
|
874
|
+
directKeys.add(key);
|
|
876
875
|
}
|
|
877
|
-
|
|
876
|
+
}
|
|
877
|
+
const result = {};
|
|
878
|
+
for (const key of directKeys) {
|
|
879
|
+
if (key in obj)
|
|
878
880
|
result[key] = obj[key];
|
|
881
|
+
}
|
|
882
|
+
for (const [first, restKeys] of nestedKeys) {
|
|
883
|
+
const val = obj[first];
|
|
884
|
+
if (!val || typeof val !== 'object')
|
|
885
|
+
continue;
|
|
886
|
+
if (Array.isArray(val)) {
|
|
887
|
+
result[first] = val.map(item => pick(item, restKeys));
|
|
888
|
+
}
|
|
889
|
+
else {
|
|
890
|
+
result[first] = pick(val, restKeys);
|
|
879
891
|
}
|
|
880
892
|
}
|
|
881
893
|
return result;
|