@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
@@ -35,7 +35,7 @@ export default class JournalLines extends Command {
35
35
  'sort-by': Flags.string({ description: 'Sort field(s), comma-separated. Direction (:ASC/:DESC) is optional; date-like fields default to DESC, others to ASC.' }),
36
36
  filter: Flags.string({ description: 'Filter (e.g. --filter status=ACTIVE). Operators: in:A,B, like:%, gt:, lt:, null:', multiple: true }),
37
37
  query: Flags.string({ description: 'Additional query params as JSON' }),
38
- fields: Flags.string({ description: 'Comma-separated list of fields to show (e.g. --fields=id,name,status)' }),
38
+ fields: Flags.string({ description: 'Comma-separated list of fields to return, applied by the API (e.g. --fields=id,name,status)' }),
39
39
  sanitize: Flags.boolean({ description: 'Remove null values, audit fields, and duplicate UUIDs from output' }),
40
40
  'show-http-request': Flags.boolean({ description: 'Show HTTP request details (method, URL, body)' }),
41
41
  };
@@ -107,6 +107,8 @@ export default class JournalLines extends Command {
107
107
  queryParams.search = flags.search;
108
108
  if (flags['sort-by'])
109
109
  queryParams.sortBy = normalizeSortBy(flags['sort-by']);
110
+ if (flags.fields)
111
+ queryParams.fields = flags.fields;
110
112
  if (flags.query) {
111
113
  try {
112
114
  Object.assign(queryParams, JSON.parse(flags.query));
@@ -309,11 +311,6 @@ export default class JournalLines extends Command {
309
311
  output = obj[arrayKeys[0]];
310
312
  }
311
313
  }
312
- // Filter fields if --fields flag is provided
313
- if (flags.fields) {
314
- const fieldList = flags.fields.split(',').map(f => f.trim());
315
- output = this.filterFields(output, fieldList);
316
- }
317
314
  // Sanitize output if requested
318
315
  if (flags.sanitize) {
319
316
  output = this.sanitizeOutput(output);
@@ -568,6 +565,8 @@ export default class JournalLines extends Command {
568
565
  baseParams.sortBy = normalizeSortBy(flags['sort-by']);
569
566
  if (flags.include)
570
567
  baseParams.include = flags.include;
568
+ if (flags.fields)
569
+ baseParams.fields = flags.fields;
571
570
  if (flags.query) {
572
571
  try {
573
572
  Object.assign(baseParams, JSON.parse(flags.query));
@@ -622,12 +621,7 @@ export default class JournalLines extends Command {
622
621
  }
623
622
  }
624
623
  process.stderr.write(' done\n');
625
- // Filter fields if specified
626
624
  let output = allItems;
627
- if (flags.fields) {
628
- const fieldList = flags.fields.split(',').map(f => f.trim());
629
- output = this.filterFields(allItems, fieldList);
630
- }
631
625
  // Sanitize output if requested
632
626
  if (flags.sanitize) {
633
627
  output = this.sanitizeOutput(output);
@@ -956,56 +950,6 @@ export default class JournalLines extends Command {
956
950
  return `\$${op}`;
957
951
  return opRe.test(rest) ? `\$${op}:${this.parseFilterValue(rest)}` : `\$${op}:${rest}`;
958
952
  }
959
- filterFields(data, fields) {
960
- const isUnsafeKey = (k) => k === '__proto__' || k === 'constructor' || k === 'prototype';
961
- const pick = (obj, keys) => {
962
- // Group keys by their first segment so sibling sub-paths
963
- // (e.g. 'items.amount' + 'items._type') resolve in one recursive pass
964
- // and don't clobber each other on merge.
965
- const directKeys = new Set();
966
- const nestedKeys = new Map();
967
- for (const key of keys) {
968
- if (key.split('.').some(isUnsafeKey))
969
- continue;
970
- if (key.includes('.')) {
971
- const [first, ...rest] = key.split('.');
972
- if (isUnsafeKey(first))
973
- continue;
974
- const list = nestedKeys.get(first);
975
- if (list) {
976
- list.push(rest.join('.'));
977
- }
978
- else {
979
- nestedKeys.set(first, [rest.join('.')]);
980
- }
981
- }
982
- else {
983
- directKeys.add(key);
984
- }
985
- }
986
- const result = {};
987
- for (const key of directKeys) {
988
- if (key in obj)
989
- result[key] = obj[key];
990
- }
991
- for (const [first, restKeys] of nestedKeys) {
992
- const val = obj[first];
993
- if (!val || typeof val !== 'object')
994
- continue;
995
- if (Array.isArray(val)) {
996
- result[first] = val.map(item => pick(item, restKeys));
997
- }
998
- else {
999
- result[first] = pick(val, restKeys);
1000
- }
1001
- }
1002
- return result;
1003
- };
1004
- if (Array.isArray(data)) {
1005
- return data.map(item => pick(item, fields));
1006
- }
1007
- return pick(data, fields);
1008
- }
1009
953
  sanitizeOutput(data) {
1010
954
  const auditFields = ['_type', 'tenantId', 'createdAt', 'updatedAt', 'createdBy', 'updatedBy'];
1011
955
  const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
@@ -14,6 +14,7 @@ export default class Journals extends Command {
14
14
  data: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
15
15
  file: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
16
16
  set: import("@oclif/core/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/interfaces").CustomOptions>;
17
+ 'line-id': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
17
18
  'note-id': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
18
19
  'file-id': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
19
20
  page: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
@@ -33,7 +34,6 @@ export default class Journals extends Command {
33
34
  private runCamt053Import;
34
35
  private runNestedImport;
35
36
  private parseFilterValue;
36
- private filterFields;
37
37
  private sanitizeOutput;
38
38
  private getColumns;
39
39
  private getValue;
@@ -6,10 +6,11 @@ const HAS_IMPORT = true;
6
6
  const HAS_EXPORT = true;
7
7
  const HAS_CAMT053 = false;
8
8
  const NESTED_IMPORTS = ["notes", "files"];
9
- const SUBCOMMANDS = [...["list", "create", "get", "update", "delete", "post", "approve", "cancel", "reverse", "get-deferrals", "create-deferrals", "list-notes", "create-notes", "get-notes", "update-notes", "delete-notes", "list-files", "create-files", "get-files", "update-files", "delete-files", "files-download"], ...(HAS_IMPORT ? ['import'] : []), ...(HAS_EXPORT ? ['export'] : []), ...NESTED_IMPORTS.map(n => `import-${n}`)];
9
+ const SUBCOMMANDS = [...["list", "create", "stats", "get", "update", "delete", "post", "approve", "cancel", "reverse", "update-lines", "get-deferrals", "create-deferrals", "list-notes", "create-notes", "get-notes", "update-notes", "delete-notes", "list-files", "create-files", "get-files", "update-files", "delete-files", "files-download"], ...(HAS_IMPORT ? ['import'] : []), ...(HAS_EXPORT ? ['export'] : []), ...NESTED_IMPORTS.map(n => `import-${n}`)];
10
10
  const ENDPOINTS = {
11
11
  'list': { method: 'GET', path: '/v1/journals', summary: 'List all journals', pathParams: [], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
12
12
  'create': { method: 'POST', path: '/v1/journals', summary: 'Create a new journal (with embedded lines)', pathParams: [], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: ['lines', 'notes'] },
13
+ 'stats': { method: 'GET', path: '/v1/journals/stats', summary: 'Journal counts and debit totals per date range', pathParams: [], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
13
14
  'get': { method: 'GET', path: '/v1/journals/{id}', summary: 'Get a journal by ID', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
14
15
  'update': { method: 'PATCH', path: '/v1/journals/{id}', summary: 'Update a journal (with embedded lines upsert)', pathParams: ['id'], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: ['lines'] },
15
16
  'delete': { method: 'DELETE', path: '/v1/journals/{id}', summary: 'Delete a journal', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
@@ -17,6 +18,7 @@ const ENDPOINTS = {
17
18
  'approve': { method: 'POST', path: '/v1/journals/{id}/approve', summary: 'Approve a journal (transitions DRAFT to APPROVED)', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
18
19
  'cancel': { method: 'POST', path: '/v1/journals/{id}/cancel', summary: 'Cancel a journal', pathParams: ['id'], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
19
20
  'reverse': { method: 'POST', path: '/v1/journals/{id}/reverse', summary: 'Reverse a posted journal', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
21
+ 'update-lines': { method: 'PATCH', path: '/v1/journals/{id}/lines/{lineId}', summary: 'Update a single journal line in place', pathParams: ['id', 'lineId'], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: ['tagIds', 'tagCodes'] },
20
22
  'get-deferrals': { method: 'GET', path: '/v1/journals/{id}/deferrals', summary: 'List the deferral schedules of a journal', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
21
23
  'create-deferrals': { method: 'POST', path: '/v1/journals/{id}/deferrals', summary: 'Create deferral schedules for one line of a journal (manual trigger)', pathParams: ['id'], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: ['periods'] },
22
24
  'list-notes': { method: 'GET', path: '/v1/journals/{journalId}/notes', summary: 'Get all notes for a journal', pathParams: ['journalId'], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
@@ -53,6 +55,7 @@ export default class Journals extends Command {
53
55
  data: Flags.string({ char: 'd', description: 'JSON data for request body' }),
54
56
  file: Flags.string({ char: 'f', description: 'Read request body from file' }),
55
57
  set: Flags.string({ char: 's', description: 'Set individual field (e.g. --set firstName=John)', multiple: true }),
58
+ 'line-id': Flags.string({ description: 'Path param: lineId' }),
56
59
  'note-id': Flags.string({ description: 'Path param: noteId' }),
57
60
  'file-id': Flags.string({ description: 'Path param: fileId' }),
58
61
  page: Flags.string({ description: 'Page number' }),
@@ -62,7 +65,7 @@ export default class Journals extends Command {
62
65
  'sort-by': Flags.string({ description: 'Sort field(s), comma-separated. Direction (:ASC/:DESC) is optional; date-like fields default to DESC, others to ASC.' }),
63
66
  filter: Flags.string({ description: 'Filter (e.g. --filter status=ACTIVE). Operators: in:A,B, like:%, gt:, lt:, null:', multiple: true }),
64
67
  query: Flags.string({ description: 'Additional query params as JSON' }),
65
- fields: Flags.string({ description: 'Comma-separated list of fields to show (e.g. --fields=id,name,status)' }),
68
+ fields: Flags.string({ description: 'Comma-separated list of fields to return, applied by the API (e.g. --fields=id,name,status)' }),
66
69
  sanitize: Flags.boolean({ description: 'Remove null values, audit fields, and duplicate UUIDs from output' }),
67
70
  'show-http-request': Flags.boolean({ description: 'Show HTTP request details (method, URL, body)' }),
68
71
  };
@@ -134,6 +137,8 @@ export default class Journals extends Command {
134
137
  queryParams.search = flags.search;
135
138
  if (flags['sort-by'])
136
139
  queryParams.sortBy = normalizeSortBy(flags['sort-by']);
140
+ if (flags.fields)
141
+ queryParams.fields = flags.fields;
137
142
  if (flags.query) {
138
143
  try {
139
144
  Object.assign(queryParams, JSON.parse(flags.query));
@@ -336,11 +341,6 @@ export default class Journals extends Command {
336
341
  output = obj[arrayKeys[0]];
337
342
  }
338
343
  }
339
- // Filter fields if --fields flag is provided
340
- if (flags.fields) {
341
- const fieldList = flags.fields.split(',').map(f => f.trim());
342
- output = this.filterFields(output, fieldList);
343
- }
344
344
  // Sanitize output if requested
345
345
  if (flags.sanitize) {
346
346
  output = this.sanitizeOutput(output);
@@ -595,6 +595,8 @@ export default class Journals extends Command {
595
595
  baseParams.sortBy = normalizeSortBy(flags['sort-by']);
596
596
  if (flags.include)
597
597
  baseParams.include = flags.include;
598
+ if (flags.fields)
599
+ baseParams.fields = flags.fields;
598
600
  if (flags.query) {
599
601
  try {
600
602
  Object.assign(baseParams, JSON.parse(flags.query));
@@ -649,12 +651,7 @@ export default class Journals extends Command {
649
651
  }
650
652
  }
651
653
  process.stderr.write(' done\n');
652
- // Filter fields if specified
653
654
  let output = allItems;
654
- if (flags.fields) {
655
- const fieldList = flags.fields.split(',').map(f => f.trim());
656
- output = this.filterFields(allItems, fieldList);
657
- }
658
655
  // Sanitize output if requested
659
656
  if (flags.sanitize) {
660
657
  output = this.sanitizeOutput(output);
@@ -983,56 +980,6 @@ export default class Journals extends Command {
983
980
  return `\$${op}`;
984
981
  return opRe.test(rest) ? `\$${op}:${this.parseFilterValue(rest)}` : `\$${op}:${rest}`;
985
982
  }
986
- filterFields(data, fields) {
987
- const isUnsafeKey = (k) => k === '__proto__' || k === 'constructor' || k === 'prototype';
988
- const pick = (obj, keys) => {
989
- // Group keys by their first segment so sibling sub-paths
990
- // (e.g. 'items.amount' + 'items._type') resolve in one recursive pass
991
- // and don't clobber each other on merge.
992
- const directKeys = new Set();
993
- const nestedKeys = new Map();
994
- for (const key of keys) {
995
- if (key.split('.').some(isUnsafeKey))
996
- continue;
997
- if (key.includes('.')) {
998
- const [first, ...rest] = key.split('.');
999
- if (isUnsafeKey(first))
1000
- continue;
1001
- const list = nestedKeys.get(first);
1002
- if (list) {
1003
- list.push(rest.join('.'));
1004
- }
1005
- else {
1006
- nestedKeys.set(first, [rest.join('.')]);
1007
- }
1008
- }
1009
- else {
1010
- directKeys.add(key);
1011
- }
1012
- }
1013
- const result = {};
1014
- for (const key of directKeys) {
1015
- if (key in obj)
1016
- result[key] = obj[key];
1017
- }
1018
- for (const [first, restKeys] of nestedKeys) {
1019
- const val = obj[first];
1020
- if (!val || typeof val !== 'object')
1021
- continue;
1022
- if (Array.isArray(val)) {
1023
- result[first] = val.map(item => pick(item, restKeys));
1024
- }
1025
- else {
1026
- result[first] = pick(val, restKeys);
1027
- }
1028
- }
1029
- return result;
1030
- };
1031
- if (Array.isArray(data)) {
1032
- return data.map(item => pick(item, fields));
1033
- }
1034
- return pick(data, fields);
1035
- }
1036
983
  sanitizeOutput(data) {
1037
984
  const auditFields = ['_type', 'tenantId', 'createdAt', 'updatedAt', 'createdBy', 'updatedBy'];
1038
985
  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 Ledgers 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;
@@ -59,7 +59,7 @@ export default class Ledgers extends Command {
59
59
  'sort-by': Flags.string({ description: 'Sort field(s), comma-separated. Direction (:ASC/:DESC) is optional; date-like fields default to DESC, others to ASC.' }),
60
60
  filter: Flags.string({ description: 'Filter (e.g. --filter status=ACTIVE). Operators: in:A,B, like:%, gt:, lt:, null:', multiple: true }),
61
61
  query: Flags.string({ description: 'Additional query params as JSON' }),
62
- fields: Flags.string({ description: 'Comma-separated list of fields to show (e.g. --fields=id,name,status)' }),
62
+ fields: Flags.string({ description: 'Comma-separated list of fields to return, applied by the API (e.g. --fields=id,name,status)' }),
63
63
  sanitize: Flags.boolean({ description: 'Remove null values, audit fields, and duplicate UUIDs from output' }),
64
64
  'show-http-request': Flags.boolean({ description: 'Show HTTP request details (method, URL, body)' }),
65
65
  };
@@ -131,6 +131,8 @@ export default class Ledgers extends Command {
131
131
  queryParams.search = flags.search;
132
132
  if (flags['sort-by'])
133
133
  queryParams.sortBy = normalizeSortBy(flags['sort-by']);
134
+ if (flags.fields)
135
+ queryParams.fields = flags.fields;
134
136
  if (flags.query) {
135
137
  try {
136
138
  Object.assign(queryParams, JSON.parse(flags.query));
@@ -333,11 +335,6 @@ export default class Ledgers extends Command {
333
335
  output = obj[arrayKeys[0]];
334
336
  }
335
337
  }
336
- // Filter fields if --fields flag is provided
337
- if (flags.fields) {
338
- const fieldList = flags.fields.split(',').map(f => f.trim());
339
- output = this.filterFields(output, fieldList);
340
- }
341
338
  // Sanitize output if requested
342
339
  if (flags.sanitize) {
343
340
  output = this.sanitizeOutput(output);
@@ -592,6 +589,8 @@ export default class Ledgers extends Command {
592
589
  baseParams.sortBy = normalizeSortBy(flags['sort-by']);
593
590
  if (flags.include)
594
591
  baseParams.include = flags.include;
592
+ if (flags.fields)
593
+ baseParams.fields = flags.fields;
595
594
  if (flags.query) {
596
595
  try {
597
596
  Object.assign(baseParams, JSON.parse(flags.query));
@@ -646,12 +645,7 @@ export default class Ledgers extends Command {
646
645
  }
647
646
  }
648
647
  process.stderr.write(' done\n');
649
- // Filter fields if specified
650
648
  let output = allItems;
651
- if (flags.fields) {
652
- const fieldList = flags.fields.split(',').map(f => f.trim());
653
- output = this.filterFields(allItems, fieldList);
654
- }
655
649
  // Sanitize output if requested
656
650
  if (flags.sanitize) {
657
651
  output = this.sanitizeOutput(output);
@@ -980,56 +974,6 @@ export default class Ledgers extends Command {
980
974
  return `\$${op}`;
981
975
  return opRe.test(rest) ? `\$${op}:${this.parseFilterValue(rest)}` : `\$${op}:${rest}`;
982
976
  }
983
- filterFields(data, fields) {
984
- const isUnsafeKey = (k) => k === '__proto__' || k === 'constructor' || k === 'prototype';
985
- const pick = (obj, keys) => {
986
- // Group keys by their first segment so sibling sub-paths
987
- // (e.g. 'items.amount' + 'items._type') resolve in one recursive pass
988
- // and don't clobber each other on merge.
989
- const directKeys = new Set();
990
- const nestedKeys = new Map();
991
- for (const key of keys) {
992
- if (key.split('.').some(isUnsafeKey))
993
- continue;
994
- if (key.includes('.')) {
995
- const [first, ...rest] = key.split('.');
996
- if (isUnsafeKey(first))
997
- continue;
998
- const list = nestedKeys.get(first);
999
- if (list) {
1000
- list.push(rest.join('.'));
1001
- }
1002
- else {
1003
- nestedKeys.set(first, [rest.join('.')]);
1004
- }
1005
- }
1006
- else {
1007
- directKeys.add(key);
1008
- }
1009
- }
1010
- const result = {};
1011
- for (const key of directKeys) {
1012
- if (key in obj)
1013
- result[key] = obj[key];
1014
- }
1015
- for (const [first, restKeys] of nestedKeys) {
1016
- const val = obj[first];
1017
- if (!val || typeof val !== 'object')
1018
- continue;
1019
- if (Array.isArray(val)) {
1020
- result[first] = val.map(item => pick(item, restKeys));
1021
- }
1022
- else {
1023
- result[first] = pick(val, restKeys);
1024
- }
1025
- }
1026
- return result;
1027
- };
1028
- if (Array.isArray(data)) {
1029
- return data.map(item => pick(item, fields));
1030
- }
1031
- return pick(data, fields);
1032
- }
1033
977
  sanitizeOutput(data) {
1034
978
  const auditFields = ['_type', 'tenantId', 'createdAt', 'updatedAt', 'createdBy', 'updatedBy'];
1035
979
  const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
@@ -0,0 +1,39 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class NangoIntegrations extends Command {
3
+ static description: string;
4
+ static examples: never[];
5
+ static args: {
6
+ action: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
7
+ id: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
8
+ };
9
+ static flags: {
10
+ context: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
+ output: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
12
+ table: import("@oclif/core/interfaces").BooleanFlag<boolean>;
13
+ csv: import("@oclif/core/interfaces").BooleanFlag<boolean>;
14
+ data: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
15
+ file: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
16
+ set: import("@oclif/core/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/interfaces").CustomOptions>;
17
+ page: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
18
+ limit: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
19
+ include: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
20
+ search: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
21
+ 'sort-by': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
22
+ filter: import("@oclif/core/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/interfaces").CustomOptions>;
23
+ query: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
24
+ fields: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
25
+ sanitize: import("@oclif/core/interfaces").BooleanFlag<boolean>;
26
+ 'show-http-request': import("@oclif/core/interfaces").BooleanFlag<boolean>;
27
+ };
28
+ run(): Promise<void>;
29
+ private runImport;
30
+ private runExport;
31
+ private runCamt053Import;
32
+ private runNestedImport;
33
+ private parseFilterValue;
34
+ private sanitizeOutput;
35
+ private getColumns;
36
+ private getValue;
37
+ private printTable;
38
+ private printCsv;
39
+ }