@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.
Files changed (67) hide show
  1. package/README.md +1 -1
  2. package/dist/commands/access-groups.js +36 -22
  3. package/dist/commands/account-transactions.js +30 -18
  4. package/dist/commands/accounts.js +30 -18
  5. package/dist/commands/agent-runs.js +33 -21
  6. package/dist/commands/{processing-logs.d.ts → async-endpoints-internal.d.ts} +2 -2
  7. package/dist/commands/{processing-logs.js → async-endpoints-internal.js} +39 -28
  8. package/dist/commands/audit-log.js +30 -18
  9. package/dist/commands/auth/tenant.d.ts +1 -0
  10. package/dist/commands/auth/tenant.js +23 -7
  11. package/dist/commands/bank-accounts.js +30 -18
  12. package/dist/commands/bank-integrations.d.ts +2 -0
  13. package/dist/commands/bank-integrations.js +41 -19
  14. package/dist/commands/business-partners---contacts.js +30 -18
  15. package/dist/commands/business-partners.js +30 -18
  16. package/dist/commands/credit-card-accounts.js +30 -18
  17. package/dist/commands/documents.js +36 -22
  18. package/dist/commands/dunning-configs.js +30 -18
  19. package/dist/commands/dunning-reminders.js +30 -18
  20. package/dist/commands/dunning-runs.js +30 -18
  21. package/dist/commands/employees.js +30 -18
  22. package/dist/commands/event-processor-mappings.js +30 -18
  23. package/dist/commands/files-internal.js +30 -18
  24. package/dist/commands/health.js +30 -18
  25. package/dist/commands/inbox.js +34 -20
  26. package/dist/commands/integrations.js +30 -18
  27. package/dist/commands/item-categories.js +30 -18
  28. package/dist/commands/items.js +30 -18
  29. package/dist/commands/journal-lines.js +30 -18
  30. package/dist/commands/journals.js +30 -18
  31. package/dist/commands/ledgers.js +30 -18
  32. package/dist/commands/office-locations.js +30 -18
  33. package/dist/commands/payment-method-ledger-mappings.js +30 -18
  34. package/dist/commands/payment-methods.js +30 -18
  35. package/dist/commands/payment-runs.js +30 -18
  36. package/dist/commands/payment-terms.js +30 -18
  37. package/dist/commands/price-lists.js +30 -18
  38. package/dist/commands/processor-mappings.js +30 -18
  39. package/dist/commands/processors.js +31 -19
  40. package/dist/commands/reconciliation.js +30 -18
  41. package/dist/commands/reports.js +30 -18
  42. package/dist/commands/salary-types.js +30 -18
  43. package/dist/commands/sales-invoices.js +32 -19
  44. package/dist/commands/sales-orders.js +33 -19
  45. package/dist/commands/switch.d.ts +1 -0
  46. package/dist/commands/switch.js +58 -3
  47. package/dist/commands/tags.js +30 -18
  48. package/dist/commands/tax-codes.js +30 -18
  49. package/dist/commands/tax-matrix.js +30 -18
  50. package/dist/commands/tenants.js +30 -18
  51. package/dist/commands/text-templates.js +30 -18
  52. package/dist/commands/tools.js +30 -18
  53. package/dist/commands/vendor-invoices.js +33 -19
  54. package/dist/commands/webhooks.js +30 -18
  55. package/dist/commands/workflows.js +30 -18
  56. package/dist/index 2.js +1 -0
  57. package/dist/index.d 2.ts +1 -0
  58. package/dist/lib/auth.d.ts +16 -1
  59. package/dist/lib/auth.js +167 -50
  60. package/dist/lib/config.d.ts +7 -0
  61. package/dist/lib/config.js +6 -0
  62. package/oclif.manifest.json +65 -385
  63. package/package.json +2 -2
  64. package/dist/commands/account-statement-runs.d.ts +0 -40
  65. package/dist/commands/account-statement-runs.js +0 -1004
  66. package/dist/commands/bank-statements.d.ts +0 -40
  67. package/dist/commands/bank-statements.js +0 -998
@@ -819,32 +819,44 @@ export default class OfficeLocations 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
- const result = {};
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
- const val = obj[first];
830
- if (val && typeof val === 'object') {
831
- const restKey = rest.join('.');
832
- if (Array.isArray(val)) {
833
- // Map over array elements (e.g., allocations[].salesInvoiceId)
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
- else if (key in obj) {
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;
@@ -813,32 +813,44 @@ export default class PaymentMethodLedgerMappings extends Command {
813
813
  filterFields(data, fields) {
814
814
  const isUnsafeKey = (k) => k === '__proto__' || k === 'constructor' || k === 'prototype';
815
815
  const pick = (obj, keys) => {
816
- const result = {};
816
+ // Group keys by their first segment so sibling sub-paths
817
+ // (e.g. 'items.amount' + 'items._type') resolve in one recursive pass
818
+ // and don't clobber each other on merge.
819
+ const directKeys = new Set();
820
+ const nestedKeys = new Map();
817
821
  for (const key of keys) {
818
822
  if (key.split('.').some(isUnsafeKey))
819
823
  continue;
820
824
  if (key.includes('.')) {
821
- // Handle nested fields like 'customer.name' or 'allocations.salesInvoiceId'
822
825
  const [first, ...rest] = key.split('.');
823
- const val = obj[first];
824
- if (val && typeof val === 'object') {
825
- const restKey = rest.join('.');
826
- if (Array.isArray(val)) {
827
- // Map over array elements (e.g., allocations[].salesInvoiceId)
828
- const existing = Array.isArray(result[first]) ? result[first] : [];
829
- result[first] = val.map((item, i) => ({
830
- ...(existing[i] || {}),
831
- ...pick(item, [restKey]),
832
- }));
833
- }
834
- else {
835
- const nested = pick(val, [restKey]);
836
- result[first] = { ...(result[first] || {}), ...nested };
837
- }
826
+ if (isUnsafeKey(first))
827
+ continue;
828
+ const list = nestedKeys.get(first);
829
+ if (list) {
830
+ list.push(rest.join('.'));
838
831
  }
832
+ else {
833
+ nestedKeys.set(first, [rest.join('.')]);
834
+ }
835
+ }
836
+ else {
837
+ directKeys.add(key);
839
838
  }
840
- else if (key in obj) {
839
+ }
840
+ const result = {};
841
+ for (const key of directKeys) {
842
+ if (key in obj)
841
843
  result[key] = obj[key];
844
+ }
845
+ for (const [first, restKeys] of nestedKeys) {
846
+ const val = obj[first];
847
+ if (!val || typeof val !== 'object')
848
+ continue;
849
+ if (Array.isArray(val)) {
850
+ result[first] = val.map(item => pick(item, restKeys));
851
+ }
852
+ else {
853
+ result[first] = pick(val, restKeys);
842
854
  }
843
855
  }
844
856
  return result;
@@ -819,32 +819,44 @@ export default class PaymentMethods 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
- const result = {};
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
- const val = obj[first];
830
- if (val && typeof val === 'object') {
831
- const restKey = rest.join('.');
832
- if (Array.isArray(val)) {
833
- // Map over array elements (e.g., allocations[].salesInvoiceId)
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
- else if (key in obj) {
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;
@@ -834,32 +834,44 @@ export default class PaymentRuns extends Command {
834
834
  filterFields(data, fields) {
835
835
  const isUnsafeKey = (k) => k === '__proto__' || k === 'constructor' || k === 'prototype';
836
836
  const pick = (obj, keys) => {
837
- const result = {};
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();
838
842
  for (const key of keys) {
839
843
  if (key.split('.').some(isUnsafeKey))
840
844
  continue;
841
845
  if (key.includes('.')) {
842
- // Handle nested fields like 'customer.name' or 'allocations.salesInvoiceId'
843
846
  const [first, ...rest] = key.split('.');
844
- const val = obj[first];
845
- if (val && typeof val === 'object') {
846
- const restKey = rest.join('.');
847
- if (Array.isArray(val)) {
848
- // Map over array elements (e.g., allocations[].salesInvoiceId)
849
- const existing = Array.isArray(result[first]) ? result[first] : [];
850
- result[first] = val.map((item, i) => ({
851
- ...(existing[i] || {}),
852
- ...pick(item, [restKey]),
853
- }));
854
- }
855
- else {
856
- const nested = pick(val, [restKey]);
857
- result[first] = { ...(result[first] || {}), ...nested };
858
- }
847
+ if (isUnsafeKey(first))
848
+ continue;
849
+ const list = nestedKeys.get(first);
850
+ if (list) {
851
+ list.push(rest.join('.'));
859
852
  }
853
+ else {
854
+ nestedKeys.set(first, [rest.join('.')]);
855
+ }
856
+ }
857
+ else {
858
+ directKeys.add(key);
860
859
  }
861
- else if (key in obj) {
860
+ }
861
+ const result = {};
862
+ for (const key of directKeys) {
863
+ if (key in obj)
862
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);
863
875
  }
864
876
  }
865
877
  return result;
@@ -820,32 +820,44 @@ export default class PaymentTerms 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
- const result = {};
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
- const val = obj[first];
831
- if (val && typeof val === 'object') {
832
- const restKey = rest.join('.');
833
- if (Array.isArray(val)) {
834
- // Map over array elements (e.g., allocations[].salesInvoiceId)
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
- else if (key in obj) {
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;
@@ -825,32 +825,44 @@ export default class PriceLists 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
- const result = {};
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
- const val = obj[first];
836
- if (val && typeof val === 'object') {
837
- const restKey = rest.join('.');
838
- if (Array.isArray(val)) {
839
- // Map over array elements (e.g., allocations[].salesInvoiceId)
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
- else if (key in obj) {
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;
@@ -817,32 +817,44 @@ export default class ProcessorMappings extends Command {
817
817
  filterFields(data, fields) {
818
818
  const isUnsafeKey = (k) => k === '__proto__' || k === 'constructor' || k === 'prototype';
819
819
  const pick = (obj, keys) => {
820
- const result = {};
820
+ // Group keys by their first segment so sibling sub-paths
821
+ // (e.g. 'items.amount' + 'items._type') resolve in one recursive pass
822
+ // and don't clobber each other on merge.
823
+ const directKeys = new Set();
824
+ const nestedKeys = new Map();
821
825
  for (const key of keys) {
822
826
  if (key.split('.').some(isUnsafeKey))
823
827
  continue;
824
828
  if (key.includes('.')) {
825
- // Handle nested fields like 'customer.name' or 'allocations.salesInvoiceId'
826
829
  const [first, ...rest] = key.split('.');
827
- const val = obj[first];
828
- if (val && typeof val === 'object') {
829
- const restKey = rest.join('.');
830
- if (Array.isArray(val)) {
831
- // Map over array elements (e.g., allocations[].salesInvoiceId)
832
- const existing = Array.isArray(result[first]) ? result[first] : [];
833
- result[first] = val.map((item, i) => ({
834
- ...(existing[i] || {}),
835
- ...pick(item, [restKey]),
836
- }));
837
- }
838
- else {
839
- const nested = pick(val, [restKey]);
840
- result[first] = { ...(result[first] || {}), ...nested };
841
- }
830
+ if (isUnsafeKey(first))
831
+ continue;
832
+ const list = nestedKeys.get(first);
833
+ if (list) {
834
+ list.push(rest.join('.'));
842
835
  }
836
+ else {
837
+ nestedKeys.set(first, [rest.join('.')]);
838
+ }
839
+ }
840
+ else {
841
+ directKeys.add(key);
843
842
  }
844
- else if (key in obj) {
843
+ }
844
+ const result = {};
845
+ for (const key of directKeys) {
846
+ if (key in obj)
845
847
  result[key] = obj[key];
848
+ }
849
+ for (const [first, restKeys] of nestedKeys) {
850
+ const val = obj[first];
851
+ if (!val || typeof val !== 'object')
852
+ continue;
853
+ if (Array.isArray(val)) {
854
+ result[first] = val.map(item => pick(item, restKeys));
855
+ }
856
+ else {
857
+ result[first] = pick(val, restKeys);
846
858
  }
847
859
  }
848
860
  return result;
@@ -9,7 +9,7 @@ const NESTED_IMPORTS = [];
9
9
  const SUBCOMMANDS = [...["list-tools", "list", "create", "resolve", "resolve-event", "get", "update", "delete", "template"], ...(HAS_IMPORT ? ['import'] : []), ...(HAS_EXPORT ? ['export'] : []), ...NESTED_IMPORTS.map(n => `import-${n}`)];
10
10
  const ENDPOINTS = {
11
11
  'list-tools': { method: 'GET', path: '/v1/processors/tools', summary: 'List all available tools', pathParams: [], hasBody: false, isMultipart: false },
12
- 'list': { method: 'GET', path: '/v1/processors', summary: 'List all processors (tenant and system)', pathParams: [], hasBody: false, isMultipart: false },
12
+ 'list': { method: 'GET', path: '/v1/processors', summary: 'List processors available to the tenant', pathParams: [], hasBody: false, isMultipart: false },
13
13
  'create': { method: 'POST', path: '/v1/processors', summary: 'Create a new tenant-scoped processor', pathParams: [], hasBody: true, isMultipart: false },
14
14
  'resolve': { method: 'GET', path: '/v1/processors/resolve/{documentType}', summary: 'Resolve processor for a document type', pathParams: ['documentType'], hasBody: false, isMultipart: false },
15
15
  'resolve-event': { method: 'GET', path: '/v1/processors/resolve/event/{eventType}', summary: 'Resolve processors for an event type', pathParams: ['eventType'], hasBody: false, isMultipart: false },
@@ -823,32 +823,44 @@ export default class Processors extends Command {
823
823
  filterFields(data, fields) {
824
824
  const isUnsafeKey = (k) => k === '__proto__' || k === 'constructor' || k === 'prototype';
825
825
  const pick = (obj, keys) => {
826
- const result = {};
826
+ // Group keys by their first segment so sibling sub-paths
827
+ // (e.g. 'items.amount' + 'items._type') resolve in one recursive pass
828
+ // and don't clobber each other on merge.
829
+ const directKeys = new Set();
830
+ const nestedKeys = new Map();
827
831
  for (const key of keys) {
828
832
  if (key.split('.').some(isUnsafeKey))
829
833
  continue;
830
834
  if (key.includes('.')) {
831
- // Handle nested fields like 'customer.name' or 'allocations.salesInvoiceId'
832
835
  const [first, ...rest] = key.split('.');
833
- const val = obj[first];
834
- if (val && typeof val === 'object') {
835
- const restKey = rest.join('.');
836
- if (Array.isArray(val)) {
837
- // Map over array elements (e.g., allocations[].salesInvoiceId)
838
- const existing = Array.isArray(result[first]) ? result[first] : [];
839
- result[first] = val.map((item, i) => ({
840
- ...(existing[i] || {}),
841
- ...pick(item, [restKey]),
842
- }));
843
- }
844
- else {
845
- const nested = pick(val, [restKey]);
846
- result[first] = { ...(result[first] || {}), ...nested };
847
- }
836
+ if (isUnsafeKey(first))
837
+ continue;
838
+ const list = nestedKeys.get(first);
839
+ if (list) {
840
+ list.push(rest.join('.'));
848
841
  }
842
+ else {
843
+ nestedKeys.set(first, [rest.join('.')]);
844
+ }
845
+ }
846
+ else {
847
+ directKeys.add(key);
849
848
  }
850
- else if (key in obj) {
849
+ }
850
+ const result = {};
851
+ for (const key of directKeys) {
852
+ if (key in obj)
851
853
  result[key] = obj[key];
854
+ }
855
+ for (const [first, restKeys] of nestedKeys) {
856
+ const val = obj[first];
857
+ if (!val || typeof val !== 'object')
858
+ continue;
859
+ if (Array.isArray(val)) {
860
+ result[first] = val.map(item => pick(item, restKeys));
861
+ }
862
+ else {
863
+ result[first] = pick(val, restKeys);
852
864
  }
853
865
  }
854
866
  return result;
@@ -816,32 +816,44 @@ export default class Reconciliation extends Command {
816
816
  filterFields(data, fields) {
817
817
  const isUnsafeKey = (k) => k === '__proto__' || k === 'constructor' || k === 'prototype';
818
818
  const pick = (obj, keys) => {
819
- const result = {};
819
+ // Group keys by their first segment so sibling sub-paths
820
+ // (e.g. 'items.amount' + 'items._type') resolve in one recursive pass
821
+ // and don't clobber each other on merge.
822
+ const directKeys = new Set();
823
+ const nestedKeys = new Map();
820
824
  for (const key of keys) {
821
825
  if (key.split('.').some(isUnsafeKey))
822
826
  continue;
823
827
  if (key.includes('.')) {
824
- // Handle nested fields like 'customer.name' or 'allocations.salesInvoiceId'
825
828
  const [first, ...rest] = key.split('.');
826
- const val = obj[first];
827
- if (val && typeof val === 'object') {
828
- const restKey = rest.join('.');
829
- if (Array.isArray(val)) {
830
- // Map over array elements (e.g., allocations[].salesInvoiceId)
831
- const existing = Array.isArray(result[first]) ? result[first] : [];
832
- result[first] = val.map((item, i) => ({
833
- ...(existing[i] || {}),
834
- ...pick(item, [restKey]),
835
- }));
836
- }
837
- else {
838
- const nested = pick(val, [restKey]);
839
- result[first] = { ...(result[first] || {}), ...nested };
840
- }
829
+ if (isUnsafeKey(first))
830
+ continue;
831
+ const list = nestedKeys.get(first);
832
+ if (list) {
833
+ list.push(rest.join('.'));
841
834
  }
835
+ else {
836
+ nestedKeys.set(first, [rest.join('.')]);
837
+ }
838
+ }
839
+ else {
840
+ directKeys.add(key);
842
841
  }
843
- else if (key in obj) {
842
+ }
843
+ const result = {};
844
+ for (const key of directKeys) {
845
+ if (key in obj)
844
846
  result[key] = obj[key];
847
+ }
848
+ for (const [first, restKeys] of nestedKeys) {
849
+ const val = obj[first];
850
+ if (!val || typeof val !== 'object')
851
+ continue;
852
+ if (Array.isArray(val)) {
853
+ result[first] = val.map(item => pick(item, restKeys));
854
+ }
855
+ else {
856
+ result[first] = pick(val, restKeys);
845
857
  }
846
858
  }
847
859
  return result;
@@ -809,32 +809,44 @@ export default class Reports extends Command {
809
809
  filterFields(data, fields) {
810
810
  const isUnsafeKey = (k) => k === '__proto__' || k === 'constructor' || k === 'prototype';
811
811
  const pick = (obj, keys) => {
812
- const result = {};
812
+ // Group keys by their first segment so sibling sub-paths
813
+ // (e.g. 'items.amount' + 'items._type') resolve in one recursive pass
814
+ // and don't clobber each other on merge.
815
+ const directKeys = new Set();
816
+ const nestedKeys = new Map();
813
817
  for (const key of keys) {
814
818
  if (key.split('.').some(isUnsafeKey))
815
819
  continue;
816
820
  if (key.includes('.')) {
817
- // Handle nested fields like 'customer.name' or 'allocations.salesInvoiceId'
818
821
  const [first, ...rest] = key.split('.');
819
- const val = obj[first];
820
- if (val && typeof val === 'object') {
821
- const restKey = rest.join('.');
822
- if (Array.isArray(val)) {
823
- // Map over array elements (e.g., allocations[].salesInvoiceId)
824
- const existing = Array.isArray(result[first]) ? result[first] : [];
825
- result[first] = val.map((item, i) => ({
826
- ...(existing[i] || {}),
827
- ...pick(item, [restKey]),
828
- }));
829
- }
830
- else {
831
- const nested = pick(val, [restKey]);
832
- result[first] = { ...(result[first] || {}), ...nested };
833
- }
822
+ if (isUnsafeKey(first))
823
+ continue;
824
+ const list = nestedKeys.get(first);
825
+ if (list) {
826
+ list.push(rest.join('.'));
834
827
  }
828
+ else {
829
+ nestedKeys.set(first, [rest.join('.')]);
830
+ }
831
+ }
832
+ else {
833
+ directKeys.add(key);
835
834
  }
836
- else if (key in obj) {
835
+ }
836
+ const result = {};
837
+ for (const key of directKeys) {
838
+ if (key in obj)
837
839
  result[key] = obj[key];
840
+ }
841
+ for (const [first, restKeys] of nestedKeys) {
842
+ const val = obj[first];
843
+ if (!val || typeof val !== 'object')
844
+ continue;
845
+ if (Array.isArray(val)) {
846
+ result[first] = val.map(item => pick(item, restKeys));
847
+ }
848
+ else {
849
+ result[first] = pick(val, restKeys);
838
850
  }
839
851
  }
840
852
  return result;