@aderis-erp/cli 1.0.2 → 1.0.4

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 (191) hide show
  1. package/README.md +6 -0
  2. package/dist/commands/access-groups 3.d.ts +40 -0
  3. package/dist/commands/{access-groups 2.js → access-groups 3.js } +106 -40
  4. package/dist/commands/access-groups.d.ts +40 -0
  5. package/dist/commands/access-groups.js +1074 -0
  6. package/dist/commands/account-transactions.d.ts +42 -0
  7. package/dist/commands/account-transactions.js +1088 -0
  8. package/dist/commands/accounts 2.d.ts +41 -0
  9. package/dist/commands/accounts 2.js +1078 -0
  10. package/dist/commands/accounts.d.ts +41 -0
  11. package/dist/commands/accounts.js +1080 -0
  12. package/dist/commands/agent-runs.d.ts +40 -0
  13. package/dist/commands/agent-runs.js +1071 -0
  14. package/dist/commands/async-endpoints-internal 3.d.ts +40 -0
  15. package/dist/commands/{processing-logs.js → async-endpoints-internal 3.js } +110 -46
  16. package/dist/commands/async-endpoints-internal.d.ts +40 -0
  17. package/dist/commands/async-endpoints-internal.js +1064 -0
  18. package/dist/commands/audit-log 3.d.ts +40 -0
  19. package/dist/commands/audit-log 3.js +1066 -0
  20. package/dist/commands/audit-log.d.ts +40 -0
  21. package/dist/commands/audit-log.js +1068 -0
  22. package/dist/commands/auth/login.d.ts +14 -0
  23. package/dist/commands/auth/login.js +116 -0
  24. package/dist/commands/auth/logout.d.ts +10 -0
  25. package/dist/commands/auth/logout.js +58 -0
  26. package/dist/commands/auth/status.d.ts +12 -0
  27. package/dist/commands/auth/status.js +101 -0
  28. package/dist/commands/auth/tenant.d.ts +19 -0
  29. package/dist/commands/auth/tenant.js +184 -0
  30. package/dist/commands/auth.d.ts +37 -0
  31. package/dist/commands/auth.js +871 -0
  32. package/dist/commands/bank-accounts.d.ts +42 -0
  33. package/dist/commands/bank-accounts.js +1088 -0
  34. package/dist/commands/bank-integrations.d.ts +1 -0
  35. package/dist/commands/bank-integrations.js +122 -54
  36. package/dist/commands/business-partners 3.d.ts +41 -0
  37. package/dist/commands/business-partners 3.js +1078 -0
  38. package/dist/commands/business-partners---contacts 3.d.ts +42 -0
  39. package/dist/commands/business-partners---contacts 3.js +1072 -0
  40. package/dist/commands/business-partners---contacts.d.ts +1 -0
  41. package/dist/commands/business-partners---contacts.js +114 -46
  42. package/dist/commands/business-partners.d.ts +1 -0
  43. package/dist/commands/business-partners.js +114 -46
  44. package/dist/commands/config/add.d.ts +13 -0
  45. package/dist/commands/config/add.js +120 -0
  46. package/dist/commands/config/current.d.ts +9 -0
  47. package/dist/commands/config/current.js +43 -0
  48. package/dist/commands/config/delete.d.ts +12 -0
  49. package/dist/commands/config/delete.js +67 -0
  50. package/dist/commands/config/list.d.ts +9 -0
  51. package/dist/commands/config/list.js +50 -0
  52. package/dist/commands/config/use.d.ts +9 -0
  53. package/dist/commands/config/use.js +40 -0
  54. package/dist/commands/credit-card-accounts 3.d.ts +42 -0
  55. package/dist/commands/credit-card-accounts 3.js +1084 -0
  56. package/dist/commands/credit-card-accounts.d.ts +1 -0
  57. package/dist/commands/credit-card-accounts.js +119 -51
  58. package/dist/commands/documents.d.ts +1 -0
  59. package/dist/commands/documents.js +110 -42
  60. package/dist/commands/dunning-configs 3.d.ts +40 -0
  61. package/dist/commands/dunning-configs 3.js +1072 -0
  62. package/dist/commands/dunning-configs.d.ts +1 -0
  63. package/dist/commands/dunning-configs.js +109 -41
  64. package/dist/commands/dunning-reminders.d.ts +1 -0
  65. package/dist/commands/dunning-reminders.js +112 -44
  66. package/dist/commands/dunning-runs 3.d.ts +40 -0
  67. package/dist/commands/{pubsub.js → dunning-runs 3.js } +108 -43
  68. package/dist/commands/dunning-runs.d.ts +1 -0
  69. package/dist/commands/dunning-runs.js +105 -37
  70. package/dist/commands/employees.d.ts +1 -0
  71. package/dist/commands/employees.js +136 -68
  72. package/dist/commands/event-processor-mappings 3.d.ts +40 -0
  73. package/dist/commands/event-processor-mappings 3.js +1071 -0
  74. package/dist/commands/event-processor-mappings.d.ts +1 -0
  75. package/dist/commands/event-processor-mappings.js +109 -41
  76. package/dist/commands/files-internal 3.d.ts +40 -0
  77. package/dist/commands/files-internal 3.js +1073 -0
  78. package/dist/commands/files-internal.d.ts +1 -0
  79. package/dist/commands/files-internal.js +113 -45
  80. package/dist/commands/health 3.d.ts +40 -0
  81. package/dist/commands/health 3.js +1067 -0
  82. package/dist/commands/health.d.ts +1 -0
  83. package/dist/commands/health.js +109 -41
  84. package/dist/commands/{pubsub.d.ts → inbox 3.d.ts } +2 -1
  85. package/dist/commands/inbox 3.js +1065 -0
  86. package/dist/commands/inbox.d.ts +1 -0
  87. package/dist/commands/inbox.js +110 -40
  88. package/dist/commands/integrations 3.d.ts +41 -0
  89. package/dist/commands/integrations 3.js +1067 -0
  90. package/dist/commands/integrations.d.ts +1 -0
  91. package/dist/commands/integrations.js +107 -39
  92. package/dist/commands/item-categories 3.d.ts +40 -0
  93. package/dist/commands/item-categories 3.js +1072 -0
  94. package/dist/commands/item-categories.d.ts +1 -0
  95. package/dist/commands/item-categories.js +109 -41
  96. package/dist/commands/items 3.d.ts +40 -0
  97. package/dist/commands/items 3.js +1072 -0
  98. package/dist/commands/items.d.ts +1 -0
  99. package/dist/commands/items.js +109 -41
  100. package/dist/commands/journal-lines.d.ts +1 -0
  101. package/dist/commands/journal-lines.js +105 -37
  102. package/dist/commands/journals 3.d.ts +42 -0
  103. package/dist/commands/journals 3.js +1088 -0
  104. package/dist/commands/journals.d.ts +1 -0
  105. package/dist/commands/journals.js +123 -55
  106. package/dist/commands/ledgers.d.ts +1 -0
  107. package/dist/commands/ledgers.js +120 -52
  108. package/dist/commands/office-locations 3.d.ts +40 -0
  109. package/dist/commands/office-locations 3.js +1072 -0
  110. package/dist/commands/office-locations.d.ts +1 -0
  111. package/dist/commands/office-locations.js +109 -41
  112. package/dist/commands/payment-method-ledger-mappings 3.d.ts +41 -0
  113. package/dist/commands/payment-method-ledger-mappings 3.js +1066 -0
  114. package/dist/commands/payment-method-ledger-mappings.d.ts +1 -0
  115. package/dist/commands/payment-method-ledger-mappings.js +109 -41
  116. package/dist/commands/payment-methods 3.d.ts +40 -0
  117. package/dist/commands/payment-methods 3.js +1072 -0
  118. package/dist/commands/payment-methods.d.ts +1 -0
  119. package/dist/commands/payment-methods.js +109 -41
  120. package/dist/commands/payment-runs 3.d.ts +42 -0
  121. package/dist/commands/payment-runs 3.js +1087 -0
  122. package/dist/commands/payment-runs.d.ts +1 -0
  123. package/dist/commands/payment-runs.js +122 -54
  124. package/dist/commands/payment-terms 3.d.ts +40 -0
  125. package/dist/commands/payment-terms 3.js +1073 -0
  126. package/dist/commands/payment-terms.d.ts +1 -0
  127. package/dist/commands/payment-terms.js +110 -42
  128. package/dist/commands/price-lists 3.d.ts +41 -0
  129. package/dist/commands/price-lists 3.js +1078 -0
  130. package/dist/commands/price-lists.d.ts +1 -0
  131. package/dist/commands/price-lists.js +114 -46
  132. package/dist/commands/processor-mappings 2.d.ts +40 -0
  133. package/dist/commands/processor-mappings 2.js +1070 -0
  134. package/dist/commands/processor-mappings.d.ts +1 -0
  135. package/dist/commands/processor-mappings.js +108 -40
  136. package/dist/commands/processors.d.ts +1 -0
  137. package/dist/commands/processors.js +113 -45
  138. package/dist/commands/reconciliation 3.d.ts +40 -0
  139. package/dist/commands/reconciliation 3.js +1069 -0
  140. package/dist/commands/reconciliation.d.ts +1 -0
  141. package/dist/commands/reconciliation.js +110 -42
  142. package/dist/commands/reports.d.ts +1 -0
  143. package/dist/commands/reports.js +110 -39
  144. package/dist/commands/salary-types 3.d.ts +40 -0
  145. package/dist/commands/salary-types 3.js +1072 -0
  146. package/dist/commands/salary-types.d.ts +1 -0
  147. package/dist/commands/salary-types.js +1074 -0
  148. package/dist/commands/sales-invoices 3.d.ts +43 -0
  149. package/dist/commands/sales-invoices 3.js +1100 -0
  150. package/dist/commands/sales-invoices.d.ts +1 -0
  151. package/dist/commands/sales-invoices.js +134 -66
  152. package/dist/commands/sales-orders 3.d.ts +43 -0
  153. package/dist/commands/sales-orders 3.js +1098 -0
  154. package/dist/commands/sales-orders.d.ts +1 -0
  155. package/dist/commands/sales-orders.js +133 -64
  156. package/dist/commands/switch.d.ts +1 -0
  157. package/dist/commands/switch.js +58 -3
  158. package/dist/commands/{processing-logs.d.ts → tags 3.d.ts } +2 -1
  159. package/dist/commands/tags 3.js +1072 -0
  160. package/dist/commands/tags.d.ts +1 -0
  161. package/dist/commands/tags.js +109 -41
  162. package/dist/commands/tax-codes 3.d.ts +40 -0
  163. package/dist/commands/tax-codes 3.js +1075 -0
  164. package/dist/commands/tax-codes.d.ts +1 -0
  165. package/dist/commands/tax-codes.js +112 -44
  166. package/dist/commands/tax-matrix.d.ts +1 -0
  167. package/dist/commands/tax-matrix.js +109 -41
  168. package/dist/commands/tenants.d.ts +1 -0
  169. package/dist/commands/tenants.js +109 -41
  170. package/dist/commands/text-templates 3.d.ts +40 -0
  171. package/dist/commands/text-templates 3.js +1072 -0
  172. package/dist/commands/text-templates.d.ts +1 -0
  173. package/dist/commands/text-templates.js +109 -41
  174. package/dist/commands/tools.d.ts +1 -0
  175. package/dist/commands/tools.js +106 -38
  176. package/dist/commands/vendor-invoices.d.ts +1 -0
  177. package/dist/commands/vendor-invoices.js +139 -69
  178. package/dist/commands/webhooks 3.d.ts +40 -0
  179. package/dist/commands/webhooks 3.js +1074 -0
  180. package/dist/commands/webhooks.d.ts +1 -0
  181. package/dist/commands/webhooks.js +111 -43
  182. package/dist/commands/workflows.d.ts +1 -0
  183. package/dist/commands/workflows.js +107 -39
  184. package/dist/lib/api-client.d.ts +5 -1
  185. package/dist/lib/api-client.js +19 -5
  186. package/dist/lib/auth.d.ts +16 -1
  187. package/dist/lib/auth.js +170 -45
  188. package/dist/lib/config.d.ts +7 -0
  189. package/dist/lib/config.js +7 -1
  190. package/oclif.manifest.json +7464 -653
  191. package/package.json +2 -2
@@ -0,0 +1,40 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class AsyncEndpointsInternal 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 filterFields;
35
+ private sanitizeOutput;
36
+ private getColumns;
37
+ private getValue;
38
+ private printTable;
39
+ private printCsv;
40
+ }
@@ -6,16 +6,14 @@ const HAS_IMPORT = false;
6
6
  const HAS_EXPORT = false;
7
7
  const HAS_CAMT053 = false;
8
8
  const NESTED_IMPORTS = [];
9
- const SUBCOMMANDS = [...["get", "get-processingId"], ...(HAS_IMPORT ? ['import'] : []), ...(HAS_EXPORT ? ['export'] : []), ...NESTED_IMPORTS.map(n => `import-${n}`)];
9
+ const SUBCOMMANDS = [...["processor-jobs", "webhook-events"], ...(HAS_IMPORT ? ['import'] : []), ...(HAS_EXPORT ? ['export'] : []), ...NESTED_IMPORTS.map(n => `import-${n}`)];
10
10
  const ENDPOINTS = {
11
- 'get': { method: 'GET', path: '/v1/processing-logs', summary: 'List recent inbox processing logs (newest first)', pathParams: [], hasBody: false, isMultipart: false },
12
- 'get-processingId': { method: 'GET', path: '/v1/processing-logs/{processingId}', summary: 'Get a processing run by its processing identifier', pathParams: ['processingId'], hasBody: false, isMultipart: false },
11
+ 'processor-jobs': { method: 'POST', path: '/v1/pubsub/processor-jobs', summary: '[INTERNAL] Async push endpoint for processor-job.v1 envelopes', pathParams: [], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
12
+ 'webhook-events': { method: 'POST', path: '/v1/pubsub/webhook-events', summary: '[INTERNAL] Async push endpoint for webhook event delivery', pathParams: [], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
13
13
  };
14
- export default class ProcessingLogs extends Command {
15
- static description = 'Manage processing logs';
16
- static examples = [
17
- '<%= config.bin %> processing-logs get <id>',
18
- ];
14
+ export default class AsyncEndpointsInternal extends Command {
15
+ static description = 'Manage async endpoints internal';
16
+ static examples = [];
19
17
  static args = {
20
18
  action: Args.string({ description: 'Action: ' + SUBCOMMANDS.join(', '), required: true }),
21
19
  id: Args.string({ description: 'Resource ID (for get, update, delete operations)', required: false }),
@@ -40,7 +38,7 @@ export default class ProcessingLogs extends Command {
40
38
  'show-http-request': Flags.boolean({ description: 'Show HTTP request details (method, URL, body)' }),
41
39
  };
42
40
  async run() {
43
- const { args, flags } = await this.parse(ProcessingLogs);
41
+ const { args, flags } = await this.parse(AsyncEndpointsInternal);
44
42
  // Handle import action specially
45
43
  if (args.action === 'import') {
46
44
  if (!HAS_IMPORT)
@@ -86,7 +84,7 @@ export default class ProcessingLogs extends Command {
86
84
  // First path param always comes from positional argument
87
85
  value = args.id;
88
86
  if (!value)
89
- this.error('Missing required argument: id. Usage: aderis processing-logs <action> <id>');
87
+ this.error('Missing required argument: id. Usage: aderis async-endpoints-internal <action> <id>');
90
88
  }
91
89
  else {
92
90
  const flagName = param.replace(/\./g, '-').replace(/([A-Z])/g, '-$1').toLowerCase().replace(/^-/, '');
@@ -122,15 +120,7 @@ export default class ProcessingLogs extends Command {
122
120
  if (eqIndex === -1)
123
121
  this.error(`Invalid --filter format: ${f}. Use: --filter key=value`);
124
122
  const key = f.slice(0, eqIndex);
125
- let value = f.slice(eqIndex + 1);
126
- // Check for operator prefix (with or without $)
127
- const opMatch = value.match(/^\$?(eq|ne|in|like|gt|gte|lt|lte|null):/);
128
- if (opMatch) {
129
- value = `\$${opMatch[1]}:${value.slice(opMatch[0].length)}`;
130
- }
131
- else {
132
- value = `\$eq:${value}`;
133
- }
123
+ const value = this.parseFilterValue(f.slice(eqIndex + 1));
134
124
  const filterKey = `filter.${key}`;
135
125
  if (filterKey in queryParams) {
136
126
  // Multiple filters on same field: collect as array
@@ -185,6 +175,7 @@ export default class ProcessingLogs extends Command {
185
175
  if (!data)
186
176
  data = {};
187
177
  const body = data;
178
+ const arrayFields = new Set(endpoint.bodyArrayFields);
188
179
  for (const pair of flags.set) {
189
180
  const eqIndex = pair.indexOf('=');
190
181
  if (eqIndex === -1)
@@ -196,6 +187,19 @@ export default class ProcessingLogs extends Command {
196
187
  value = JSON.parse(value);
197
188
  }
198
189
  catch { /* keep as string */ }
190
+ // For top-level keys typed as array in the API schema, split bare
191
+ // comma-separated input (e.g. "1171,1170" -> ["1171","1170"]) and
192
+ // wrap a lone scalar in a single-element array. Skips when --set
193
+ // already provided a JSON array.
194
+ const isArrayField = !key.includes('.') && arrayFields.has(key);
195
+ if (isArrayField && !Array.isArray(value)) {
196
+ if (typeof value === 'string') {
197
+ value = value.split(',').map(v => v.trim()).filter(v => v.length > 0);
198
+ }
199
+ else if (value !== undefined && value !== null) {
200
+ value = [value];
201
+ }
202
+ }
199
203
  // Support nested keys like "address.city"
200
204
  const keys = key.split('.');
201
205
  if (keys.some(k => k === '__proto__' || k === 'constructor' || k === 'prototype')) {
@@ -246,6 +250,26 @@ export default class ProcessingLogs extends Command {
246
250
  process.stderr.write('\n');
247
251
  }
248
252
  try {
253
+ // Binary response: download to file
254
+ if (endpoint.isBinaryResponse) {
255
+ if (!flags.file) {
256
+ this.error(`Endpoint returns a binary file. Specify the output path with -f / --file (e.g. -f report.xlsx).`);
257
+ }
258
+ const binResponse = await apiRequest(endpoint.method, apiPath, {
259
+ params: Object.keys(queryParams).length > 0 ? queryParams : undefined,
260
+ data,
261
+ contextName: flags.context,
262
+ binary: true,
263
+ });
264
+ const fsModule = await import('node:fs');
265
+ const binData = binResponse.data;
266
+ const buffer = Buffer.isBuffer(binData)
267
+ ? binData
268
+ : Buffer.from(binData);
269
+ fsModule.writeFileSync(flags.file, buffer);
270
+ this.log(`Saved ${buffer.length} bytes to ${flags.file}`);
271
+ return;
272
+ }
249
273
  const response = await apiRequest(endpoint.method, apiPath, {
250
274
  params: Object.keys(queryParams).length > 0 ? queryParams : undefined,
251
275
  data,
@@ -336,6 +360,7 @@ export default class ProcessingLogs extends Command {
336
360
  }
337
361
  else if (flags.set && flags.set.length > 0) {
338
362
  const item = {};
363
+ const arrayFields = new Set(ENDPOINTS['create']?.bodyArrayFields ?? []);
339
364
  for (const pair of flags.set) {
340
365
  const eqIndex = pair.indexOf('=');
341
366
  if (eqIndex === -1)
@@ -346,6 +371,15 @@ export default class ProcessingLogs extends Command {
346
371
  value = JSON.parse(value);
347
372
  }
348
373
  catch { /* keep as string */ }
374
+ const isArrayField = !key.includes('.') && arrayFields.has(key);
375
+ if (isArrayField && !Array.isArray(value)) {
376
+ if (typeof value === 'string') {
377
+ value = value.split(',').map(v => v.trim()).filter(v => v.length > 0);
378
+ }
379
+ else if (value !== undefined && value !== null) {
380
+ value = [value];
381
+ }
382
+ }
349
383
  const keys = key.split('.');
350
384
  if (keys.some(k => k === '__proto__' || k === 'constructor' || k === 'prototype')) {
351
385
  this.error(`Invalid --set key: ${key}`);
@@ -495,14 +529,7 @@ export default class ProcessingLogs extends Command {
495
529
  if (eqIndex === -1)
496
530
  this.error(`Invalid --filter format: ${f}. Use: --filter key=value`);
497
531
  const key = f.slice(0, eqIndex);
498
- let value = f.slice(eqIndex + 1);
499
- const opMatch = value.match(/^\$?(eq|ne|in|like|gt|gte|lt|lte|null):/);
500
- if (opMatch) {
501
- value = `\$${opMatch[1]}:${value.slice(opMatch[0].length)}`;
502
- }
503
- else {
504
- value = `\$eq:${value}`;
505
- }
532
+ const value = this.parseFilterValue(f.slice(eqIndex + 1));
506
533
  const filterKey = `filter.${key}`;
507
534
  if (filterKey in baseParams) {
508
535
  const existing = baseParams[filterKey];
@@ -649,7 +676,7 @@ export default class ProcessingLogs extends Command {
649
676
  }
650
677
  async runNestedImport(suffix, parentId, flags) {
651
678
  if (!parentId) {
652
- this.error(`Missing required argument: id. Usage: aderis processing-logs import-${suffix} <parent-id> --file data.json`);
679
+ this.error(`Missing required argument: id. Usage: aderis async-endpoints-internal import-${suffix} <parent-id> --file data.json`);
653
680
  }
654
681
  const context = flags.context ? getContext(flags.context) : getCurrentContext();
655
682
  if (!context)
@@ -679,6 +706,7 @@ export default class ProcessingLogs extends Command {
679
706
  }
680
707
  else if (flags.set && flags.set.length > 0) {
681
708
  const item = {};
709
+ const arrayFields = new Set(ENDPOINTS[`create-${suffix}`]?.bodyArrayFields ?? []);
682
710
  for (const pair of flags.set) {
683
711
  const eqIndex = pair.indexOf('=');
684
712
  if (eqIndex === -1)
@@ -689,6 +717,15 @@ export default class ProcessingLogs extends Command {
689
717
  value = JSON.parse(value);
690
718
  }
691
719
  catch { /* keep as string */ }
720
+ const isArrayField = !key.includes('.') && arrayFields.has(key);
721
+ if (isArrayField && !Array.isArray(value)) {
722
+ if (typeof value === 'string') {
723
+ value = value.split(',').map(v => v.trim()).filter(v => v.length > 0);
724
+ }
725
+ else if (value !== undefined && value !== null) {
726
+ value = [value];
727
+ }
728
+ }
692
729
  const keys = key.split('.');
693
730
  if (keys.some(k => k === '__proto__' || k === 'constructor' || k === 'prototype')) {
694
731
  this.error(`Invalid --set key: ${key}`);
@@ -808,35 +845,62 @@ export default class ProcessingLogs extends Command {
808
845
  this.log('');
809
846
  this.log(`Summary: ${created} created, ${updated} updated, ${errors.length} failed`);
810
847
  }
848
+ parseFilterValue(value) {
849
+ // Recognises the nestjs-paginate operator set (with or without the leading $)
850
+ // and recursively unwraps chained operators like 'not:null' -> '$not:$null'
851
+ // or 'not:like:John' -> '$not:$like:John'. Falls back to '$eq:<value>' when
852
+ // no operator prefix is present.
853
+ const opRe = /^\$?(and|or|not|eq|gt|gte|in|null|lt|lte|btw|ne|ilike|like|sw|contains)(?::|$)/;
854
+ const m = value.match(opRe);
855
+ if (!m)
856
+ return `\$eq:${value}`;
857
+ const op = m[1];
858
+ const rest = value.slice(m[0].length);
859
+ if (rest === '')
860
+ return `\$${op}`;
861
+ return opRe.test(rest) ? `\$${op}:${this.parseFilterValue(rest)}` : `\$${op}:${rest}`;
862
+ }
811
863
  filterFields(data, fields) {
812
864
  const isUnsafeKey = (k) => k === '__proto__' || k === 'constructor' || k === 'prototype';
813
865
  const pick = (obj, keys) => {
814
- const result = {};
866
+ // Group keys by their first segment so sibling sub-paths
867
+ // (e.g. 'items.amount' + 'items._type') resolve in one recursive pass
868
+ // and don't clobber each other on merge.
869
+ const directKeys = new Set();
870
+ const nestedKeys = new Map();
815
871
  for (const key of keys) {
816
872
  if (key.split('.').some(isUnsafeKey))
817
873
  continue;
818
874
  if (key.includes('.')) {
819
- // Handle nested fields like 'customer.name' or 'allocations.salesInvoiceId'
820
875
  const [first, ...rest] = key.split('.');
821
- const val = obj[first];
822
- if (val && typeof val === 'object') {
823
- const restKey = rest.join('.');
824
- if (Array.isArray(val)) {
825
- // Map over array elements (e.g., allocations[].salesInvoiceId)
826
- const existing = Array.isArray(result[first]) ? result[first] : [];
827
- result[first] = val.map((item, i) => ({
828
- ...(existing[i] || {}),
829
- ...pick(item, [restKey]),
830
- }));
831
- }
832
- else {
833
- const nested = pick(val, [restKey]);
834
- result[first] = { ...(result[first] || {}), ...nested };
835
- }
876
+ if (isUnsafeKey(first))
877
+ continue;
878
+ const list = nestedKeys.get(first);
879
+ if (list) {
880
+ list.push(rest.join('.'));
881
+ }
882
+ else {
883
+ nestedKeys.set(first, [rest.join('.')]);
836
884
  }
837
885
  }
838
- else if (key in obj) {
886
+ else {
887
+ directKeys.add(key);
888
+ }
889
+ }
890
+ const result = {};
891
+ for (const key of directKeys) {
892
+ if (key in obj)
839
893
  result[key] = obj[key];
894
+ }
895
+ for (const [first, restKeys] of nestedKeys) {
896
+ const val = obj[first];
897
+ if (!val || typeof val !== 'object')
898
+ continue;
899
+ if (Array.isArray(val)) {
900
+ result[first] = val.map(item => pick(item, restKeys));
901
+ }
902
+ else {
903
+ result[first] = pick(val, restKeys);
840
904
  }
841
905
  }
842
906
  return result;
@@ -0,0 +1,40 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class AsyncEndpointsInternal 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 filterFields;
35
+ private sanitizeOutput;
36
+ private getColumns;
37
+ private getValue;
38
+ private printTable;
39
+ private printCsv;
40
+ }