@aderis-erp/cli 1.0.15 → 1.0.17

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 (163) hide show
  1. package/README.md +30 -8
  2. package/dist/commands/access-groups.d.ts +0 -1
  3. package/dist/commands/access-groups.js +5 -61
  4. package/dist/commands/account-transaction-allocations.d.ts +0 -1
  5. package/dist/commands/account-transaction-allocations.js +5 -61
  6. package/dist/commands/account-transactions.d.ts +0 -1
  7. package/dist/commands/account-transactions.js +9 -63
  8. package/dist/commands/accounts.d.ts +0 -1
  9. package/dist/commands/accounts.js +5 -61
  10. package/dist/commands/agent-platform.d.ts +0 -1
  11. package/dist/commands/agent-platform.js +5 -61
  12. package/dist/commands/analytics.d.ts +0 -1
  13. package/dist/commands/analytics.js +5 -61
  14. package/dist/commands/api-keys.d.ts +39 -0
  15. package/dist/commands/api-keys.js +1117 -0
  16. package/dist/commands/audit-log.d.ts +0 -1
  17. package/dist/commands/audit-log.js +5 -61
  18. package/dist/commands/auth/login.d.ts +9 -0
  19. package/dist/commands/auth/login.js +73 -20
  20. package/dist/commands/auth/logout.d.ts +4 -0
  21. package/dist/commands/auth/logout.js +4 -0
  22. package/dist/commands/auth/status.js +26 -17
  23. package/dist/commands/auth/tenant.js +3 -6
  24. package/dist/commands/auth.d.ts +0 -1
  25. package/dist/commands/auth.js +5 -34
  26. package/dist/commands/bank-accounts.d.ts +0 -1
  27. package/dist/commands/bank-accounts.js +5 -61
  28. package/dist/commands/bank-integrations.d.ts +0 -1
  29. package/dist/commands/bank-integrations.js +5 -61
  30. package/dist/commands/business-partners.d.ts +1 -1
  31. package/dist/commands/business-partners.js +14 -63
  32. package/dist/commands/chat.d.ts +0 -1
  33. package/dist/commands/chat.js +5 -61
  34. package/dist/commands/config/add.d.ts +3 -0
  35. package/dist/commands/config/add.js +34 -16
  36. package/dist/commands/config/current.js +3 -0
  37. package/dist/commands/config/list.js +3 -0
  38. package/dist/commands/credit-card-accounts.d.ts +0 -1
  39. package/dist/commands/credit-card-accounts.js +5 -61
  40. package/dist/commands/delivery-notes.d.ts +0 -1
  41. package/dist/commands/delivery-notes.js +7 -63
  42. package/dist/commands/dunning-configs.d.ts +0 -1
  43. package/dist/commands/dunning-configs.js +5 -61
  44. package/dist/commands/dunning-reminders.d.ts +0 -1
  45. package/dist/commands/dunning-reminders.js +5 -61
  46. package/dist/commands/dunning-runs.d.ts +0 -1
  47. package/dist/commands/dunning-runs.js +5 -61
  48. package/dist/commands/email-transactions.d.ts +0 -1
  49. package/dist/commands/email-transactions.js +5 -61
  50. package/dist/commands/employees.d.ts +0 -1
  51. package/dist/commands/employees.js +5 -61
  52. package/dist/commands/entity-configurations.d.ts +0 -1
  53. package/dist/commands/entity-configurations.js +5 -61
  54. package/dist/commands/event-processor-mappings.d.ts +0 -1
  55. package/dist/commands/event-processor-mappings.js +5 -61
  56. package/dist/commands/files.d.ts +0 -1
  57. package/dist/commands/files.js +5 -61
  58. package/dist/commands/health.d.ts +0 -1
  59. package/dist/commands/health.js +5 -61
  60. package/dist/commands/inbox.d.ts +0 -1
  61. package/dist/commands/inbox.js +5 -61
  62. package/dist/commands/integrations.d.ts +0 -1
  63. package/dist/commands/integrations.js +5 -61
  64. package/dist/commands/item-categories.d.ts +0 -1
  65. package/dist/commands/item-categories.js +5 -61
  66. package/dist/commands/items.d.ts +0 -1
  67. package/dist/commands/items.js +5 -61
  68. package/dist/commands/journal-lines.d.ts +0 -1
  69. package/dist/commands/journal-lines.js +5 -61
  70. package/dist/commands/journals.d.ts +1 -1
  71. package/dist/commands/journals.js +9 -62
  72. package/dist/commands/ledgers.d.ts +0 -1
  73. package/dist/commands/ledgers.js +5 -61
  74. package/dist/commands/nango-integrations.d.ts +39 -0
  75. package/dist/commands/nango-integrations.js +1115 -0
  76. package/dist/commands/office-locations.d.ts +0 -1
  77. package/dist/commands/office-locations.js +5 -61
  78. package/dist/commands/payment-methods.d.ts +0 -1
  79. package/dist/commands/payment-methods.js +5 -61
  80. package/dist/commands/payment-runs.d.ts +0 -1
  81. package/dist/commands/payment-runs.js +5 -61
  82. package/dist/commands/payment-terms.d.ts +0 -1
  83. package/dist/commands/payment-terms.js +5 -61
  84. package/dist/commands/payments.d.ts +0 -1
  85. package/dist/commands/payments.js +5 -61
  86. package/dist/commands/price-lists.d.ts +0 -1
  87. package/dist/commands/price-lists.js +5 -61
  88. package/dist/commands/processor-mappings.d.ts +0 -1
  89. package/dist/commands/processor-mappings.js +5 -61
  90. package/dist/commands/processors.d.ts +0 -1
  91. package/dist/commands/processors.js +5 -61
  92. package/dist/commands/purchase-order-types.d.ts +0 -1
  93. package/dist/commands/purchase-order-types.js +5 -61
  94. package/dist/commands/purchase-orders.d.ts +0 -1
  95. package/dist/commands/purchase-orders.js +7 -63
  96. package/dist/commands/reports.d.ts +0 -1
  97. package/dist/commands/reports.js +6 -62
  98. package/dist/commands/salary-types.d.ts +0 -1
  99. package/dist/commands/salary-types.js +5 -61
  100. package/dist/commands/sales-invoices.d.ts +0 -1
  101. package/dist/commands/sales-invoices.js +12 -65
  102. package/dist/commands/sales-orders.d.ts +0 -1
  103. package/dist/commands/sales-orders.js +7 -63
  104. package/dist/commands/saved-views.d.ts +0 -1
  105. package/dist/commands/saved-views.js +5 -61
  106. package/dist/commands/scheduled-processor-mappings.d.ts +0 -1
  107. package/dist/commands/scheduled-processor-mappings.js +5 -61
  108. package/dist/commands/schedules.d.ts +0 -1
  109. package/dist/commands/schedules.js +5 -61
  110. package/dist/commands/switch.js +4 -4
  111. package/dist/commands/tag-configurations.d.ts +0 -1
  112. package/dist/commands/tag-configurations.js +9 -64
  113. package/dist/commands/tags.d.ts +0 -1
  114. package/dist/commands/tags.js +5 -61
  115. package/dist/commands/tax-codes.d.ts +0 -1
  116. package/dist/commands/tax-codes.js +5 -61
  117. package/dist/commands/tax-matrix.d.ts +0 -1
  118. package/dist/commands/tax-matrix.js +5 -61
  119. package/dist/commands/tenants.d.ts +0 -1
  120. package/dist/commands/tenants.js +7 -62
  121. package/dist/commands/text-templates.d.ts +0 -1
  122. package/dist/commands/text-templates.js +5 -61
  123. package/dist/commands/tools.d.ts +0 -1
  124. package/dist/commands/tools.js +5 -61
  125. package/dist/commands/vat-declarations.d.ts +1 -1
  126. package/dist/commands/vat-declarations.js +11 -62
  127. package/dist/commands/vendor-invoices.d.ts +0 -1
  128. package/dist/commands/vendor-invoices.js +10 -65
  129. package/dist/commands/webhooks.d.ts +0 -1
  130. package/dist/commands/webhooks.js +5 -61
  131. package/dist/commands/workflows.d.ts +0 -1
  132. package/dist/commands/workflows.js +5 -61
  133. package/dist/lib/api-client.js +3 -6
  134. package/dist/lib/auth/constants.d.ts +11 -0
  135. package/dist/lib/auth/constants.js +11 -0
  136. package/dist/lib/auth/errors.d.ts +17 -0
  137. package/dist/lib/auth/errors.js +22 -0
  138. package/dist/lib/auth/flow.d.ts +27 -0
  139. package/dist/lib/auth/flow.js +163 -0
  140. package/dist/lib/auth/guards.d.ts +5 -0
  141. package/dist/lib/auth/guards.js +14 -0
  142. package/dist/lib/auth/http.d.ts +16 -0
  143. package/dist/lib/auth/http.js +49 -0
  144. package/dist/lib/auth/index.d.ts +49 -0
  145. package/dist/lib/auth/index.js +217 -0
  146. package/dist/lib/auth/keycloak-provider.d.ts +75 -0
  147. package/dist/lib/auth/keycloak-provider.js +215 -0
  148. package/dist/lib/auth/pages.d.ts +25 -0
  149. package/dist/lib/auth/pages.js +123 -0
  150. package/dist/lib/auth/pkce.d.ts +11 -0
  151. package/dist/lib/auth/pkce.js +17 -0
  152. package/dist/lib/auth/tokens.d.ts +54 -0
  153. package/dist/lib/auth/tokens.js +104 -0
  154. package/dist/lib/auth/types.d.ts +57 -0
  155. package/dist/lib/auth/types.js +1 -0
  156. package/dist/lib/auth/validated-url.d.ts +6 -0
  157. package/dist/lib/auth/validated-url.js +53 -0
  158. package/dist/lib/config.d.ts +13 -3
  159. package/dist/lib/config.js +24 -19
  160. package/oclif.manifest.json +440 -71
  161. package/package.json +2 -1
  162. package/dist/lib/auth.d.ts +0 -43
  163. package/dist/lib/auth.js +0 -610
@@ -31,7 +31,6 @@ export default class OfficeLocations extends Command {
31
31
  private runCamt053Import;
32
32
  private runNestedImport;
33
33
  private parseFilterValue;
34
- private filterFields;
35
34
  private sanitizeOutput;
36
35
  private getColumns;
37
36
  private getValue;
@@ -43,7 +43,7 @@ export default class OfficeLocations extends Command {
43
43
  'sort-by': Flags.string({ description: 'Sort field(s), comma-separated. Direction (:ASC/:DESC) is optional; date-like fields default to DESC, others to ASC.' }),
44
44
  filter: Flags.string({ description: 'Filter (e.g. --filter status=ACTIVE). Operators: in:A,B, like:%, gt:, lt:, null:', multiple: true }),
45
45
  query: Flags.string({ description: 'Additional query params as JSON' }),
46
- fields: Flags.string({ description: 'Comma-separated list of fields to show (e.g. --fields=id,name,status)' }),
46
+ fields: Flags.string({ description: 'Comma-separated list of fields to return, applied by the API (e.g. --fields=id,name,status)' }),
47
47
  sanitize: Flags.boolean({ description: 'Remove null values, audit fields, and duplicate UUIDs from output' }),
48
48
  'show-http-request': Flags.boolean({ description: 'Show HTTP request details (method, URL, body)' }),
49
49
  };
@@ -115,6 +115,8 @@ export default class OfficeLocations extends Command {
115
115
  queryParams.search = flags.search;
116
116
  if (flags['sort-by'])
117
117
  queryParams.sortBy = normalizeSortBy(flags['sort-by']);
118
+ if (flags.fields)
119
+ queryParams.fields = flags.fields;
118
120
  if (flags.query) {
119
121
  try {
120
122
  Object.assign(queryParams, JSON.parse(flags.query));
@@ -317,11 +319,6 @@ export default class OfficeLocations extends Command {
317
319
  output = obj[arrayKeys[0]];
318
320
  }
319
321
  }
320
- // Filter fields if --fields flag is provided
321
- if (flags.fields) {
322
- const fieldList = flags.fields.split(',').map(f => f.trim());
323
- output = this.filterFields(output, fieldList);
324
- }
325
322
  // Sanitize output if requested
326
323
  if (flags.sanitize) {
327
324
  output = this.sanitizeOutput(output);
@@ -576,6 +573,8 @@ export default class OfficeLocations extends Command {
576
573
  baseParams.sortBy = normalizeSortBy(flags['sort-by']);
577
574
  if (flags.include)
578
575
  baseParams.include = flags.include;
576
+ if (flags.fields)
577
+ baseParams.fields = flags.fields;
579
578
  if (flags.query) {
580
579
  try {
581
580
  Object.assign(baseParams, JSON.parse(flags.query));
@@ -630,12 +629,7 @@ export default class OfficeLocations extends Command {
630
629
  }
631
630
  }
632
631
  process.stderr.write(' done\n');
633
- // Filter fields if specified
634
632
  let output = allItems;
635
- if (flags.fields) {
636
- const fieldList = flags.fields.split(',').map(f => f.trim());
637
- output = this.filterFields(allItems, fieldList);
638
- }
639
633
  // Sanitize output if requested
640
634
  if (flags.sanitize) {
641
635
  output = this.sanitizeOutput(output);
@@ -964,56 +958,6 @@ export default class OfficeLocations extends Command {
964
958
  return `\$${op}`;
965
959
  return opRe.test(rest) ? `\$${op}:${this.parseFilterValue(rest)}` : `\$${op}:${rest}`;
966
960
  }
967
- filterFields(data, fields) {
968
- const isUnsafeKey = (k) => k === '__proto__' || k === 'constructor' || k === 'prototype';
969
- const pick = (obj, keys) => {
970
- // Group keys by their first segment so sibling sub-paths
971
- // (e.g. 'items.amount' + 'items._type') resolve in one recursive pass
972
- // and don't clobber each other on merge.
973
- const directKeys = new Set();
974
- const nestedKeys = new Map();
975
- for (const key of keys) {
976
- if (key.split('.').some(isUnsafeKey))
977
- continue;
978
- if (key.includes('.')) {
979
- const [first, ...rest] = key.split('.');
980
- if (isUnsafeKey(first))
981
- continue;
982
- const list = nestedKeys.get(first);
983
- if (list) {
984
- list.push(rest.join('.'));
985
- }
986
- else {
987
- nestedKeys.set(first, [rest.join('.')]);
988
- }
989
- }
990
- else {
991
- directKeys.add(key);
992
- }
993
- }
994
- const result = {};
995
- for (const key of directKeys) {
996
- if (key in obj)
997
- result[key] = obj[key];
998
- }
999
- for (const [first, restKeys] of nestedKeys) {
1000
- const val = obj[first];
1001
- if (!val || typeof val !== 'object')
1002
- continue;
1003
- if (Array.isArray(val)) {
1004
- result[first] = val.map(item => pick(item, restKeys));
1005
- }
1006
- else {
1007
- result[first] = pick(val, restKeys);
1008
- }
1009
- }
1010
- return result;
1011
- };
1012
- if (Array.isArray(data)) {
1013
- return data.map(item => pick(item, fields));
1014
- }
1015
- return pick(data, fields);
1016
- }
1017
961
  sanitizeOutput(data) {
1018
962
  const auditFields = ['_type', 'tenantId', 'createdAt', 'updatedAt', 'createdBy', 'updatedBy'];
1019
963
  const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
@@ -32,7 +32,6 @@ export default class PaymentMethods extends Command {
32
32
  private runCamt053Import;
33
33
  private runNestedImport;
34
34
  private parseFilterValue;
35
- private filterFields;
36
35
  private sanitizeOutput;
37
36
  private getColumns;
38
37
  private getValue;
@@ -49,7 +49,7 @@ export default class PaymentMethods extends Command {
49
49
  'sort-by': Flags.string({ description: 'Sort field(s), comma-separated. Direction (:ASC/:DESC) is optional; date-like fields default to DESC, others to ASC.' }),
50
50
  filter: Flags.string({ description: 'Filter (e.g. --filter status=ACTIVE). Operators: in:A,B, like:%, gt:, lt:, null:', multiple: true }),
51
51
  query: Flags.string({ description: 'Additional query params as JSON' }),
52
- fields: Flags.string({ description: 'Comma-separated list of fields to show (e.g. --fields=id,name,status)' }),
52
+ fields: Flags.string({ description: 'Comma-separated list of fields to return, applied by the API (e.g. --fields=id,name,status)' }),
53
53
  sanitize: Flags.boolean({ description: 'Remove null values, audit fields, and duplicate UUIDs from output' }),
54
54
  'show-http-request': Flags.boolean({ description: 'Show HTTP request details (method, URL, body)' }),
55
55
  };
@@ -121,6 +121,8 @@ export default class PaymentMethods extends Command {
121
121
  queryParams.search = flags.search;
122
122
  if (flags['sort-by'])
123
123
  queryParams.sortBy = normalizeSortBy(flags['sort-by']);
124
+ if (flags.fields)
125
+ queryParams.fields = flags.fields;
124
126
  if (flags.query) {
125
127
  try {
126
128
  Object.assign(queryParams, JSON.parse(flags.query));
@@ -323,11 +325,6 @@ export default class PaymentMethods extends Command {
323
325
  output = obj[arrayKeys[0]];
324
326
  }
325
327
  }
326
- // Filter fields if --fields flag is provided
327
- if (flags.fields) {
328
- const fieldList = flags.fields.split(',').map(f => f.trim());
329
- output = this.filterFields(output, fieldList);
330
- }
331
328
  // Sanitize output if requested
332
329
  if (flags.sanitize) {
333
330
  output = this.sanitizeOutput(output);
@@ -582,6 +579,8 @@ export default class PaymentMethods extends Command {
582
579
  baseParams.sortBy = normalizeSortBy(flags['sort-by']);
583
580
  if (flags.include)
584
581
  baseParams.include = flags.include;
582
+ if (flags.fields)
583
+ baseParams.fields = flags.fields;
585
584
  if (flags.query) {
586
585
  try {
587
586
  Object.assign(baseParams, JSON.parse(flags.query));
@@ -636,12 +635,7 @@ export default class PaymentMethods extends Command {
636
635
  }
637
636
  }
638
637
  process.stderr.write(' done\n');
639
- // Filter fields if specified
640
638
  let output = allItems;
641
- if (flags.fields) {
642
- const fieldList = flags.fields.split(',').map(f => f.trim());
643
- output = this.filterFields(allItems, fieldList);
644
- }
645
639
  // Sanitize output if requested
646
640
  if (flags.sanitize) {
647
641
  output = this.sanitizeOutput(output);
@@ -970,56 +964,6 @@ export default class PaymentMethods extends Command {
970
964
  return `\$${op}`;
971
965
  return opRe.test(rest) ? `\$${op}:${this.parseFilterValue(rest)}` : `\$${op}:${rest}`;
972
966
  }
973
- filterFields(data, fields) {
974
- const isUnsafeKey = (k) => k === '__proto__' || k === 'constructor' || k === 'prototype';
975
- const pick = (obj, keys) => {
976
- // Group keys by their first segment so sibling sub-paths
977
- // (e.g. 'items.amount' + 'items._type') resolve in one recursive pass
978
- // and don't clobber each other on merge.
979
- const directKeys = new Set();
980
- const nestedKeys = new Map();
981
- for (const key of keys) {
982
- if (key.split('.').some(isUnsafeKey))
983
- continue;
984
- if (key.includes('.')) {
985
- const [first, ...rest] = key.split('.');
986
- if (isUnsafeKey(first))
987
- continue;
988
- const list = nestedKeys.get(first);
989
- if (list) {
990
- list.push(rest.join('.'));
991
- }
992
- else {
993
- nestedKeys.set(first, [rest.join('.')]);
994
- }
995
- }
996
- else {
997
- directKeys.add(key);
998
- }
999
- }
1000
- const result = {};
1001
- for (const key of directKeys) {
1002
- if (key in obj)
1003
- result[key] = obj[key];
1004
- }
1005
- for (const [first, restKeys] of nestedKeys) {
1006
- const val = obj[first];
1007
- if (!val || typeof val !== 'object')
1008
- continue;
1009
- if (Array.isArray(val)) {
1010
- result[first] = val.map(item => pick(item, restKeys));
1011
- }
1012
- else {
1013
- result[first] = pick(val, restKeys);
1014
- }
1015
- }
1016
- return result;
1017
- };
1018
- if (Array.isArray(data)) {
1019
- return data.map(item => pick(item, fields));
1020
- }
1021
- return pick(data, fields);
1022
- }
1023
967
  sanitizeOutput(data) {
1024
968
  const auditFields = ['_type', 'tenantId', 'createdAt', 'updatedAt', 'createdBy', 'updatedBy'];
1025
969
  const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
@@ -33,7 +33,6 @@ export default class PaymentRuns extends Command {
33
33
  private runCamt053Import;
34
34
  private runNestedImport;
35
35
  private parseFilterValue;
36
- private filterFields;
37
36
  private sanitizeOutput;
38
37
  private getColumns;
39
38
  private getValue;
@@ -57,7 +57,7 @@ export default class PaymentRuns extends Command {
57
57
  'sort-by': Flags.string({ description: 'Sort field(s), comma-separated. Direction (:ASC/:DESC) is optional; date-like fields default to DESC, others to ASC.' }),
58
58
  filter: Flags.string({ description: 'Filter (e.g. --filter status=ACTIVE). Operators: in:A,B, like:%, gt:, lt:, null:', multiple: true }),
59
59
  query: Flags.string({ description: 'Additional query params as JSON' }),
60
- fields: Flags.string({ description: 'Comma-separated list of fields to show (e.g. --fields=id,name,status)' }),
60
+ fields: Flags.string({ description: 'Comma-separated list of fields to return, applied by the API (e.g. --fields=id,name,status)' }),
61
61
  sanitize: Flags.boolean({ description: 'Remove null values, audit fields, and duplicate UUIDs from output' }),
62
62
  'show-http-request': Flags.boolean({ description: 'Show HTTP request details (method, URL, body)' }),
63
63
  };
@@ -129,6 +129,8 @@ export default class PaymentRuns extends Command {
129
129
  queryParams.search = flags.search;
130
130
  if (flags['sort-by'])
131
131
  queryParams.sortBy = normalizeSortBy(flags['sort-by']);
132
+ if (flags.fields)
133
+ queryParams.fields = flags.fields;
132
134
  if (flags.query) {
133
135
  try {
134
136
  Object.assign(queryParams, JSON.parse(flags.query));
@@ -331,11 +333,6 @@ export default class PaymentRuns extends Command {
331
333
  output = obj[arrayKeys[0]];
332
334
  }
333
335
  }
334
- // Filter fields if --fields flag is provided
335
- if (flags.fields) {
336
- const fieldList = flags.fields.split(',').map(f => f.trim());
337
- output = this.filterFields(output, fieldList);
338
- }
339
336
  // Sanitize output if requested
340
337
  if (flags.sanitize) {
341
338
  output = this.sanitizeOutput(output);
@@ -590,6 +587,8 @@ export default class PaymentRuns extends Command {
590
587
  baseParams.sortBy = normalizeSortBy(flags['sort-by']);
591
588
  if (flags.include)
592
589
  baseParams.include = flags.include;
590
+ if (flags.fields)
591
+ baseParams.fields = flags.fields;
593
592
  if (flags.query) {
594
593
  try {
595
594
  Object.assign(baseParams, JSON.parse(flags.query));
@@ -644,12 +643,7 @@ export default class PaymentRuns extends Command {
644
643
  }
645
644
  }
646
645
  process.stderr.write(' done\n');
647
- // Filter fields if specified
648
646
  let output = allItems;
649
- if (flags.fields) {
650
- const fieldList = flags.fields.split(',').map(f => f.trim());
651
- output = this.filterFields(allItems, fieldList);
652
- }
653
647
  // Sanitize output if requested
654
648
  if (flags.sanitize) {
655
649
  output = this.sanitizeOutput(output);
@@ -978,56 +972,6 @@ export default class PaymentRuns extends Command {
978
972
  return `\$${op}`;
979
973
  return opRe.test(rest) ? `\$${op}:${this.parseFilterValue(rest)}` : `\$${op}:${rest}`;
980
974
  }
981
- filterFields(data, fields) {
982
- const isUnsafeKey = (k) => k === '__proto__' || k === 'constructor' || k === 'prototype';
983
- const pick = (obj, keys) => {
984
- // Group keys by their first segment so sibling sub-paths
985
- // (e.g. 'items.amount' + 'items._type') resolve in one recursive pass
986
- // and don't clobber each other on merge.
987
- const directKeys = new Set();
988
- const nestedKeys = new Map();
989
- for (const key of keys) {
990
- if (key.split('.').some(isUnsafeKey))
991
- continue;
992
- if (key.includes('.')) {
993
- const [first, ...rest] = key.split('.');
994
- if (isUnsafeKey(first))
995
- continue;
996
- const list = nestedKeys.get(first);
997
- if (list) {
998
- list.push(rest.join('.'));
999
- }
1000
- else {
1001
- nestedKeys.set(first, [rest.join('.')]);
1002
- }
1003
- }
1004
- else {
1005
- directKeys.add(key);
1006
- }
1007
- }
1008
- const result = {};
1009
- for (const key of directKeys) {
1010
- if (key in obj)
1011
- result[key] = obj[key];
1012
- }
1013
- for (const [first, restKeys] of nestedKeys) {
1014
- const val = obj[first];
1015
- if (!val || typeof val !== 'object')
1016
- continue;
1017
- if (Array.isArray(val)) {
1018
- result[first] = val.map(item => pick(item, restKeys));
1019
- }
1020
- else {
1021
- result[first] = pick(val, restKeys);
1022
- }
1023
- }
1024
- return result;
1025
- };
1026
- if (Array.isArray(data)) {
1027
- return data.map(item => pick(item, fields));
1028
- }
1029
- return pick(data, fields);
1030
- }
1031
975
  sanitizeOutput(data) {
1032
976
  const auditFields = ['_type', 'tenantId', 'createdAt', 'updatedAt', 'createdBy', 'updatedBy'];
1033
977
  const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
@@ -31,7 +31,6 @@ export default class PaymentTerms extends Command {
31
31
  private runCamt053Import;
32
32
  private runNestedImport;
33
33
  private parseFilterValue;
34
- private filterFields;
35
34
  private sanitizeOutput;
36
35
  private getColumns;
37
36
  private getValue;
@@ -44,7 +44,7 @@ export default class PaymentTerms extends Command {
44
44
  'sort-by': Flags.string({ description: 'Sort field(s), comma-separated. Direction (:ASC/:DESC) is optional; date-like fields default to DESC, others to ASC.' }),
45
45
  filter: Flags.string({ description: 'Filter (e.g. --filter status=ACTIVE). Operators: in:A,B, like:%, gt:, lt:, null:', multiple: true }),
46
46
  query: Flags.string({ description: 'Additional query params as JSON' }),
47
- fields: Flags.string({ description: 'Comma-separated list of fields to show (e.g. --fields=id,name,status)' }),
47
+ fields: Flags.string({ description: 'Comma-separated list of fields to return, applied by the API (e.g. --fields=id,name,status)' }),
48
48
  sanitize: Flags.boolean({ description: 'Remove null values, audit fields, and duplicate UUIDs from output' }),
49
49
  'show-http-request': Flags.boolean({ description: 'Show HTTP request details (method, URL, body)' }),
50
50
  };
@@ -116,6 +116,8 @@ export default class PaymentTerms extends Command {
116
116
  queryParams.search = flags.search;
117
117
  if (flags['sort-by'])
118
118
  queryParams.sortBy = normalizeSortBy(flags['sort-by']);
119
+ if (flags.fields)
120
+ queryParams.fields = flags.fields;
119
121
  if (flags.query) {
120
122
  try {
121
123
  Object.assign(queryParams, JSON.parse(flags.query));
@@ -318,11 +320,6 @@ export default class PaymentTerms extends Command {
318
320
  output = obj[arrayKeys[0]];
319
321
  }
320
322
  }
321
- // Filter fields if --fields flag is provided
322
- if (flags.fields) {
323
- const fieldList = flags.fields.split(',').map(f => f.trim());
324
- output = this.filterFields(output, fieldList);
325
- }
326
323
  // Sanitize output if requested
327
324
  if (flags.sanitize) {
328
325
  output = this.sanitizeOutput(output);
@@ -577,6 +574,8 @@ export default class PaymentTerms extends Command {
577
574
  baseParams.sortBy = normalizeSortBy(flags['sort-by']);
578
575
  if (flags.include)
579
576
  baseParams.include = flags.include;
577
+ if (flags.fields)
578
+ baseParams.fields = flags.fields;
580
579
  if (flags.query) {
581
580
  try {
582
581
  Object.assign(baseParams, JSON.parse(flags.query));
@@ -631,12 +630,7 @@ export default class PaymentTerms extends Command {
631
630
  }
632
631
  }
633
632
  process.stderr.write(' done\n');
634
- // Filter fields if specified
635
633
  let output = allItems;
636
- if (flags.fields) {
637
- const fieldList = flags.fields.split(',').map(f => f.trim());
638
- output = this.filterFields(allItems, fieldList);
639
- }
640
634
  // Sanitize output if requested
641
635
  if (flags.sanitize) {
642
636
  output = this.sanitizeOutput(output);
@@ -965,56 +959,6 @@ export default class PaymentTerms extends Command {
965
959
  return `\$${op}`;
966
960
  return opRe.test(rest) ? `\$${op}:${this.parseFilterValue(rest)}` : `\$${op}:${rest}`;
967
961
  }
968
- filterFields(data, fields) {
969
- const isUnsafeKey = (k) => k === '__proto__' || k === 'constructor' || k === 'prototype';
970
- const pick = (obj, keys) => {
971
- // Group keys by their first segment so sibling sub-paths
972
- // (e.g. 'items.amount' + 'items._type') resolve in one recursive pass
973
- // and don't clobber each other on merge.
974
- const directKeys = new Set();
975
- const nestedKeys = new Map();
976
- for (const key of keys) {
977
- if (key.split('.').some(isUnsafeKey))
978
- continue;
979
- if (key.includes('.')) {
980
- const [first, ...rest] = key.split('.');
981
- if (isUnsafeKey(first))
982
- continue;
983
- const list = nestedKeys.get(first);
984
- if (list) {
985
- list.push(rest.join('.'));
986
- }
987
- else {
988
- nestedKeys.set(first, [rest.join('.')]);
989
- }
990
- }
991
- else {
992
- directKeys.add(key);
993
- }
994
- }
995
- const result = {};
996
- for (const key of directKeys) {
997
- if (key in obj)
998
- result[key] = obj[key];
999
- }
1000
- for (const [first, restKeys] of nestedKeys) {
1001
- const val = obj[first];
1002
- if (!val || typeof val !== 'object')
1003
- continue;
1004
- if (Array.isArray(val)) {
1005
- result[first] = val.map(item => pick(item, restKeys));
1006
- }
1007
- else {
1008
- result[first] = pick(val, restKeys);
1009
- }
1010
- }
1011
- return result;
1012
- };
1013
- if (Array.isArray(data)) {
1014
- return data.map(item => pick(item, fields));
1015
- }
1016
- return pick(data, fields);
1017
- }
1018
962
  sanitizeOutput(data) {
1019
963
  const auditFields = ['_type', 'tenantId', 'createdAt', 'updatedAt', 'createdBy', 'updatedBy'];
1020
964
  const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
@@ -31,7 +31,6 @@ export default class Payments extends Command {
31
31
  private runCamt053Import;
32
32
  private runNestedImport;
33
33
  private parseFilterValue;
34
- private filterFields;
35
34
  private sanitizeOutput;
36
35
  private getColumns;
37
36
  private getValue;
@@ -45,7 +45,7 @@ export default class Payments extends Command {
45
45
  'sort-by': Flags.string({ description: 'Sort field(s), comma-separated. Direction (:ASC/:DESC) is optional; date-like fields default to DESC, others to ASC.' }),
46
46
  filter: Flags.string({ description: 'Filter (e.g. --filter status=ACTIVE). Operators: in:A,B, like:%, gt:, lt:, null:', multiple: true }),
47
47
  query: Flags.string({ description: 'Additional query params as JSON' }),
48
- fields: Flags.string({ description: 'Comma-separated list of fields to show (e.g. --fields=id,name,status)' }),
48
+ fields: Flags.string({ description: 'Comma-separated list of fields to return, applied by the API (e.g. --fields=id,name,status)' }),
49
49
  sanitize: Flags.boolean({ description: 'Remove null values, audit fields, and duplicate UUIDs from output' }),
50
50
  'show-http-request': Flags.boolean({ description: 'Show HTTP request details (method, URL, body)' }),
51
51
  };
@@ -117,6 +117,8 @@ export default class Payments extends Command {
117
117
  queryParams.search = flags.search;
118
118
  if (flags['sort-by'])
119
119
  queryParams.sortBy = normalizeSortBy(flags['sort-by']);
120
+ if (flags.fields)
121
+ queryParams.fields = flags.fields;
120
122
  if (flags.query) {
121
123
  try {
122
124
  Object.assign(queryParams, JSON.parse(flags.query));
@@ -319,11 +321,6 @@ export default class Payments extends Command {
319
321
  output = obj[arrayKeys[0]];
320
322
  }
321
323
  }
322
- // Filter fields if --fields flag is provided
323
- if (flags.fields) {
324
- const fieldList = flags.fields.split(',').map(f => f.trim());
325
- output = this.filterFields(output, fieldList);
326
- }
327
324
  // Sanitize output if requested
328
325
  if (flags.sanitize) {
329
326
  output = this.sanitizeOutput(output);
@@ -578,6 +575,8 @@ export default class Payments extends Command {
578
575
  baseParams.sortBy = normalizeSortBy(flags['sort-by']);
579
576
  if (flags.include)
580
577
  baseParams.include = flags.include;
578
+ if (flags.fields)
579
+ baseParams.fields = flags.fields;
581
580
  if (flags.query) {
582
581
  try {
583
582
  Object.assign(baseParams, JSON.parse(flags.query));
@@ -632,12 +631,7 @@ export default class Payments extends Command {
632
631
  }
633
632
  }
634
633
  process.stderr.write(' done\n');
635
- // Filter fields if specified
636
634
  let output = allItems;
637
- if (flags.fields) {
638
- const fieldList = flags.fields.split(',').map(f => f.trim());
639
- output = this.filterFields(allItems, fieldList);
640
- }
641
635
  // Sanitize output if requested
642
636
  if (flags.sanitize) {
643
637
  output = this.sanitizeOutput(output);
@@ -966,56 +960,6 @@ export default class Payments extends Command {
966
960
  return `\$${op}`;
967
961
  return opRe.test(rest) ? `\$${op}:${this.parseFilterValue(rest)}` : `\$${op}:${rest}`;
968
962
  }
969
- filterFields(data, fields) {
970
- const isUnsafeKey = (k) => k === '__proto__' || k === 'constructor' || k === 'prototype';
971
- const pick = (obj, keys) => {
972
- // Group keys by their first segment so sibling sub-paths
973
- // (e.g. 'items.amount' + 'items._type') resolve in one recursive pass
974
- // and don't clobber each other on merge.
975
- const directKeys = new Set();
976
- const nestedKeys = new Map();
977
- for (const key of keys) {
978
- if (key.split('.').some(isUnsafeKey))
979
- continue;
980
- if (key.includes('.')) {
981
- const [first, ...rest] = key.split('.');
982
- if (isUnsafeKey(first))
983
- continue;
984
- const list = nestedKeys.get(first);
985
- if (list) {
986
- list.push(rest.join('.'));
987
- }
988
- else {
989
- nestedKeys.set(first, [rest.join('.')]);
990
- }
991
- }
992
- else {
993
- directKeys.add(key);
994
- }
995
- }
996
- const result = {};
997
- for (const key of directKeys) {
998
- if (key in obj)
999
- result[key] = obj[key];
1000
- }
1001
- for (const [first, restKeys] of nestedKeys) {
1002
- const val = obj[first];
1003
- if (!val || typeof val !== 'object')
1004
- continue;
1005
- if (Array.isArray(val)) {
1006
- result[first] = val.map(item => pick(item, restKeys));
1007
- }
1008
- else {
1009
- result[first] = pick(val, restKeys);
1010
- }
1011
- }
1012
- return result;
1013
- };
1014
- if (Array.isArray(data)) {
1015
- return data.map(item => pick(item, fields));
1016
- }
1017
- return pick(data, fields);
1018
- }
1019
963
  sanitizeOutput(data) {
1020
964
  const auditFields = ['_type', 'tenantId', 'createdAt', 'updatedAt', 'createdBy', 'updatedBy'];
1021
965
  const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
@@ -32,7 +32,6 @@ export default class PriceLists extends Command {
32
32
  private runCamt053Import;
33
33
  private runNestedImport;
34
34
  private parseFilterValue;
35
- private filterFields;
36
35
  private sanitizeOutput;
37
36
  private getColumns;
38
37
  private getValue;