@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.
- package/README.md +30 -8
- package/dist/commands/access-groups.d.ts +0 -1
- package/dist/commands/access-groups.js +5 -61
- package/dist/commands/account-transaction-allocations.d.ts +0 -1
- package/dist/commands/account-transaction-allocations.js +5 -61
- package/dist/commands/account-transactions.d.ts +0 -1
- package/dist/commands/account-transactions.js +9 -63
- package/dist/commands/accounts.d.ts +0 -1
- package/dist/commands/accounts.js +5 -61
- package/dist/commands/agent-platform.d.ts +0 -1
- package/dist/commands/agent-platform.js +5 -61
- package/dist/commands/analytics.d.ts +0 -1
- package/dist/commands/analytics.js +5 -61
- package/dist/commands/api-keys.d.ts +39 -0
- package/dist/commands/api-keys.js +1117 -0
- package/dist/commands/audit-log.d.ts +0 -1
- package/dist/commands/audit-log.js +5 -61
- package/dist/commands/auth/login.d.ts +9 -0
- package/dist/commands/auth/login.js +73 -20
- package/dist/commands/auth/logout.d.ts +4 -0
- package/dist/commands/auth/logout.js +4 -0
- package/dist/commands/auth/status.js +26 -17
- package/dist/commands/auth/tenant.js +3 -6
- package/dist/commands/auth.d.ts +0 -1
- package/dist/commands/auth.js +5 -34
- package/dist/commands/bank-accounts.d.ts +0 -1
- package/dist/commands/bank-accounts.js +5 -61
- package/dist/commands/bank-integrations.d.ts +0 -1
- package/dist/commands/bank-integrations.js +5 -61
- package/dist/commands/business-partners.d.ts +1 -1
- package/dist/commands/business-partners.js +14 -63
- package/dist/commands/chat.d.ts +0 -1
- package/dist/commands/chat.js +5 -61
- package/dist/commands/config/add.d.ts +3 -0
- package/dist/commands/config/add.js +34 -16
- package/dist/commands/config/current.js +3 -0
- package/dist/commands/config/list.js +3 -0
- package/dist/commands/credit-card-accounts.d.ts +0 -1
- package/dist/commands/credit-card-accounts.js +5 -61
- package/dist/commands/delivery-notes.d.ts +0 -1
- package/dist/commands/delivery-notes.js +7 -63
- package/dist/commands/dunning-configs.d.ts +0 -1
- package/dist/commands/dunning-configs.js +5 -61
- package/dist/commands/dunning-reminders.d.ts +0 -1
- package/dist/commands/dunning-reminders.js +5 -61
- package/dist/commands/dunning-runs.d.ts +0 -1
- package/dist/commands/dunning-runs.js +5 -61
- package/dist/commands/email-transactions.d.ts +0 -1
- package/dist/commands/email-transactions.js +5 -61
- package/dist/commands/employees.d.ts +0 -1
- package/dist/commands/employees.js +5 -61
- package/dist/commands/entity-configurations.d.ts +0 -1
- package/dist/commands/entity-configurations.js +5 -61
- package/dist/commands/event-processor-mappings.d.ts +0 -1
- package/dist/commands/event-processor-mappings.js +5 -61
- package/dist/commands/files.d.ts +0 -1
- package/dist/commands/files.js +5 -61
- package/dist/commands/health.d.ts +0 -1
- package/dist/commands/health.js +5 -61
- package/dist/commands/inbox.d.ts +0 -1
- package/dist/commands/inbox.js +5 -61
- package/dist/commands/integrations.d.ts +0 -1
- package/dist/commands/integrations.js +5 -61
- package/dist/commands/item-categories.d.ts +0 -1
- package/dist/commands/item-categories.js +5 -61
- package/dist/commands/items.d.ts +0 -1
- package/dist/commands/items.js +5 -61
- package/dist/commands/journal-lines.d.ts +0 -1
- package/dist/commands/journal-lines.js +5 -61
- package/dist/commands/journals.d.ts +1 -1
- package/dist/commands/journals.js +9 -62
- package/dist/commands/ledgers.d.ts +0 -1
- package/dist/commands/ledgers.js +5 -61
- package/dist/commands/nango-integrations.d.ts +39 -0
- package/dist/commands/nango-integrations.js +1115 -0
- package/dist/commands/office-locations.d.ts +0 -1
- package/dist/commands/office-locations.js +5 -61
- package/dist/commands/payment-methods.d.ts +0 -1
- package/dist/commands/payment-methods.js +5 -61
- package/dist/commands/payment-runs.d.ts +0 -1
- package/dist/commands/payment-runs.js +5 -61
- package/dist/commands/payment-terms.d.ts +0 -1
- package/dist/commands/payment-terms.js +5 -61
- package/dist/commands/payments.d.ts +0 -1
- package/dist/commands/payments.js +5 -61
- package/dist/commands/price-lists.d.ts +0 -1
- package/dist/commands/price-lists.js +5 -61
- package/dist/commands/processor-mappings.d.ts +0 -1
- package/dist/commands/processor-mappings.js +5 -61
- package/dist/commands/processors.d.ts +0 -1
- package/dist/commands/processors.js +5 -61
- package/dist/commands/purchase-order-types.d.ts +0 -1
- package/dist/commands/purchase-order-types.js +5 -61
- package/dist/commands/purchase-orders.d.ts +0 -1
- package/dist/commands/purchase-orders.js +7 -63
- package/dist/commands/reports.d.ts +0 -1
- package/dist/commands/reports.js +6 -62
- package/dist/commands/salary-types.d.ts +0 -1
- package/dist/commands/salary-types.js +5 -61
- package/dist/commands/sales-invoices.d.ts +0 -1
- package/dist/commands/sales-invoices.js +12 -65
- package/dist/commands/sales-orders.d.ts +0 -1
- package/dist/commands/sales-orders.js +7 -63
- package/dist/commands/saved-views.d.ts +0 -1
- package/dist/commands/saved-views.js +5 -61
- package/dist/commands/scheduled-processor-mappings.d.ts +0 -1
- package/dist/commands/scheduled-processor-mappings.js +5 -61
- package/dist/commands/schedules.d.ts +0 -1
- package/dist/commands/schedules.js +5 -61
- package/dist/commands/switch.js +4 -4
- package/dist/commands/tag-configurations.d.ts +0 -1
- package/dist/commands/tag-configurations.js +9 -64
- package/dist/commands/tags.d.ts +0 -1
- package/dist/commands/tags.js +5 -61
- package/dist/commands/tax-codes.d.ts +0 -1
- package/dist/commands/tax-codes.js +5 -61
- package/dist/commands/tax-matrix.d.ts +0 -1
- package/dist/commands/tax-matrix.js +5 -61
- package/dist/commands/tenants.d.ts +0 -1
- package/dist/commands/tenants.js +7 -62
- package/dist/commands/text-templates.d.ts +0 -1
- package/dist/commands/text-templates.js +5 -61
- package/dist/commands/tools.d.ts +0 -1
- package/dist/commands/tools.js +5 -61
- package/dist/commands/vat-declarations.d.ts +1 -1
- package/dist/commands/vat-declarations.js +11 -62
- package/dist/commands/vendor-invoices.d.ts +0 -1
- package/dist/commands/vendor-invoices.js +10 -65
- package/dist/commands/webhooks.d.ts +0 -1
- package/dist/commands/webhooks.js +5 -61
- package/dist/commands/workflows.d.ts +0 -1
- package/dist/commands/workflows.js +5 -61
- package/dist/lib/api-client.js +3 -6
- package/dist/lib/auth/constants.d.ts +11 -0
- package/dist/lib/auth/constants.js +11 -0
- package/dist/lib/auth/errors.d.ts +17 -0
- package/dist/lib/auth/errors.js +22 -0
- package/dist/lib/auth/flow.d.ts +27 -0
- package/dist/lib/auth/flow.js +163 -0
- package/dist/lib/auth/guards.d.ts +5 -0
- package/dist/lib/auth/guards.js +14 -0
- package/dist/lib/auth/http.d.ts +16 -0
- package/dist/lib/auth/http.js +49 -0
- package/dist/lib/auth/index.d.ts +49 -0
- package/dist/lib/auth/index.js +217 -0
- package/dist/lib/auth/keycloak-provider.d.ts +75 -0
- package/dist/lib/auth/keycloak-provider.js +215 -0
- package/dist/lib/auth/pages.d.ts +25 -0
- package/dist/lib/auth/pages.js +123 -0
- package/dist/lib/auth/pkce.d.ts +11 -0
- package/dist/lib/auth/pkce.js +17 -0
- package/dist/lib/auth/tokens.d.ts +54 -0
- package/dist/lib/auth/tokens.js +104 -0
- package/dist/lib/auth/types.d.ts +57 -0
- package/dist/lib/auth/types.js +1 -0
- package/dist/lib/auth/validated-url.d.ts +6 -0
- package/dist/lib/auth/validated-url.js +53 -0
- package/dist/lib/config.d.ts +13 -3
- package/dist/lib/config.js +24 -19
- package/oclif.manifest.json +440 -71
- package/package.json +2 -1
- package/dist/lib/auth.d.ts +0 -43
- package/dist/lib/auth.js +0 -610
|
@@ -55,7 +55,7 @@ export default class CreditCardAccounts extends Command {
|
|
|
55
55
|
'sort-by': Flags.string({ description: 'Sort field(s), comma-separated. Direction (:ASC/:DESC) is optional; date-like fields default to DESC, others to ASC.' }),
|
|
56
56
|
filter: Flags.string({ description: 'Filter (e.g. --filter status=ACTIVE). Operators: in:A,B, like:%, gt:, lt:, null:', multiple: true }),
|
|
57
57
|
query: Flags.string({ description: 'Additional query params as JSON' }),
|
|
58
|
-
fields: Flags.string({ description: 'Comma-separated list of fields to
|
|
58
|
+
fields: Flags.string({ description: 'Comma-separated list of fields to return, applied by the API (e.g. --fields=id,name,status)' }),
|
|
59
59
|
sanitize: Flags.boolean({ description: 'Remove null values, audit fields, and duplicate UUIDs from output' }),
|
|
60
60
|
'show-http-request': Flags.boolean({ description: 'Show HTTP request details (method, URL, body)' }),
|
|
61
61
|
};
|
|
@@ -127,6 +127,8 @@ export default class CreditCardAccounts extends Command {
|
|
|
127
127
|
queryParams.search = flags.search;
|
|
128
128
|
if (flags['sort-by'])
|
|
129
129
|
queryParams.sortBy = normalizeSortBy(flags['sort-by']);
|
|
130
|
+
if (flags.fields)
|
|
131
|
+
queryParams.fields = flags.fields;
|
|
130
132
|
if (flags.query) {
|
|
131
133
|
try {
|
|
132
134
|
Object.assign(queryParams, JSON.parse(flags.query));
|
|
@@ -329,11 +331,6 @@ export default class CreditCardAccounts extends Command {
|
|
|
329
331
|
output = obj[arrayKeys[0]];
|
|
330
332
|
}
|
|
331
333
|
}
|
|
332
|
-
// Filter fields if --fields flag is provided
|
|
333
|
-
if (flags.fields) {
|
|
334
|
-
const fieldList = flags.fields.split(',').map(f => f.trim());
|
|
335
|
-
output = this.filterFields(output, fieldList);
|
|
336
|
-
}
|
|
337
334
|
// Sanitize output if requested
|
|
338
335
|
if (flags.sanitize) {
|
|
339
336
|
output = this.sanitizeOutput(output);
|
|
@@ -588,6 +585,8 @@ export default class CreditCardAccounts extends Command {
|
|
|
588
585
|
baseParams.sortBy = normalizeSortBy(flags['sort-by']);
|
|
589
586
|
if (flags.include)
|
|
590
587
|
baseParams.include = flags.include;
|
|
588
|
+
if (flags.fields)
|
|
589
|
+
baseParams.fields = flags.fields;
|
|
591
590
|
if (flags.query) {
|
|
592
591
|
try {
|
|
593
592
|
Object.assign(baseParams, JSON.parse(flags.query));
|
|
@@ -642,12 +641,7 @@ export default class CreditCardAccounts extends Command {
|
|
|
642
641
|
}
|
|
643
642
|
}
|
|
644
643
|
process.stderr.write(' done\n');
|
|
645
|
-
// Filter fields if specified
|
|
646
644
|
let output = allItems;
|
|
647
|
-
if (flags.fields) {
|
|
648
|
-
const fieldList = flags.fields.split(',').map(f => f.trim());
|
|
649
|
-
output = this.filterFields(allItems, fieldList);
|
|
650
|
-
}
|
|
651
645
|
// Sanitize output if requested
|
|
652
646
|
if (flags.sanitize) {
|
|
653
647
|
output = this.sanitizeOutput(output);
|
|
@@ -976,56 +970,6 @@ export default class CreditCardAccounts extends Command {
|
|
|
976
970
|
return `\$${op}`;
|
|
977
971
|
return opRe.test(rest) ? `\$${op}:${this.parseFilterValue(rest)}` : `\$${op}:${rest}`;
|
|
978
972
|
}
|
|
979
|
-
filterFields(data, fields) {
|
|
980
|
-
const isUnsafeKey = (k) => k === '__proto__' || k === 'constructor' || k === 'prototype';
|
|
981
|
-
const pick = (obj, keys) => {
|
|
982
|
-
// Group keys by their first segment so sibling sub-paths
|
|
983
|
-
// (e.g. 'items.amount' + 'items._type') resolve in one recursive pass
|
|
984
|
-
// and don't clobber each other on merge.
|
|
985
|
-
const directKeys = new Set();
|
|
986
|
-
const nestedKeys = new Map();
|
|
987
|
-
for (const key of keys) {
|
|
988
|
-
if (key.split('.').some(isUnsafeKey))
|
|
989
|
-
continue;
|
|
990
|
-
if (key.includes('.')) {
|
|
991
|
-
const [first, ...rest] = key.split('.');
|
|
992
|
-
if (isUnsafeKey(first))
|
|
993
|
-
continue;
|
|
994
|
-
const list = nestedKeys.get(first);
|
|
995
|
-
if (list) {
|
|
996
|
-
list.push(rest.join('.'));
|
|
997
|
-
}
|
|
998
|
-
else {
|
|
999
|
-
nestedKeys.set(first, [rest.join('.')]);
|
|
1000
|
-
}
|
|
1001
|
-
}
|
|
1002
|
-
else {
|
|
1003
|
-
directKeys.add(key);
|
|
1004
|
-
}
|
|
1005
|
-
}
|
|
1006
|
-
const result = {};
|
|
1007
|
-
for (const key of directKeys) {
|
|
1008
|
-
if (key in obj)
|
|
1009
|
-
result[key] = obj[key];
|
|
1010
|
-
}
|
|
1011
|
-
for (const [first, restKeys] of nestedKeys) {
|
|
1012
|
-
const val = obj[first];
|
|
1013
|
-
if (!val || typeof val !== 'object')
|
|
1014
|
-
continue;
|
|
1015
|
-
if (Array.isArray(val)) {
|
|
1016
|
-
result[first] = val.map(item => pick(item, restKeys));
|
|
1017
|
-
}
|
|
1018
|
-
else {
|
|
1019
|
-
result[first] = pick(val, restKeys);
|
|
1020
|
-
}
|
|
1021
|
-
}
|
|
1022
|
-
return result;
|
|
1023
|
-
};
|
|
1024
|
-
if (Array.isArray(data)) {
|
|
1025
|
-
return data.map(item => pick(item, fields));
|
|
1026
|
-
}
|
|
1027
|
-
return pick(data, fields);
|
|
1028
|
-
}
|
|
1029
973
|
sanitizeOutput(data) {
|
|
1030
974
|
const auditFields = ['_type', 'tenantId', 'createdAt', 'updatedAt', 'createdBy', 'updatedBy'];
|
|
1031
975
|
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
@@ -24,9 +24,9 @@ const ENDPOINTS = {
|
|
|
24
24
|
'deliver': { method: 'POST', path: '/v1/delivery-notes/{id}/deliver', summary: 'Mark a delivery note as delivered (SHIPPED → DELIVERED)', pathParams: ['id'], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
|
|
25
25
|
'ship': { method: 'POST', path: '/v1/delivery-notes/{id}/ship', summary: 'Ship a delivery note (APPROVED → SHIPPED)', pathParams: ['id'], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: ['lineItems'] },
|
|
26
26
|
'send': { method: 'POST', path: '/v1/delivery-notes/{id}/send', summary: 'Send a delivery note to its recipient by email', pathParams: ['id'], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: ['emailCc', 'emailBcc'] },
|
|
27
|
-
'create-line-items': { method: 'POST', path: '/v1/delivery-notes/{noteId}/line-items', summary: 'Add a line item to a delivery note', pathParams: ['noteId'], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: ['salesOrderLineItems'] },
|
|
27
|
+
'create-line-items': { method: 'POST', path: '/v1/delivery-notes/{noteId}/line-items', summary: 'Add a line item to a delivery note', pathParams: ['noteId'], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: ['salesOrderLineItems', 'tagIds', 'tagCodes'] },
|
|
28
28
|
'update-line-items-reorder': { method: 'PATCH', path: '/v1/delivery-notes/{noteId}/line-items/reorder', summary: 'Bulk reorder line items (drag-and-drop)', pathParams: ['noteId'], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: ['items'] },
|
|
29
|
-
'update-line-items': { method: 'PATCH', path: '/v1/delivery-notes/{noteId}/line-items/{lineItemId}', summary: 'Update a line item on a delivery note', pathParams: ['noteId', 'lineItemId'], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: ['salesOrderLineItems'] },
|
|
29
|
+
'update-line-items': { method: 'PATCH', path: '/v1/delivery-notes/{noteId}/line-items/{lineItemId}', summary: 'Update a line item on a delivery note', pathParams: ['noteId', 'lineItemId'], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: ['salesOrderLineItems', 'tagIds', 'tagCodes'] },
|
|
30
30
|
'delete-line-items': { method: 'DELETE', path: '/v1/delivery-notes/{noteId}/line-items/{lineItemId}', summary: 'Remove a line item from a delivery note', pathParams: ['noteId', 'lineItemId'], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
|
|
31
31
|
'list-notes': { method: 'GET', path: '/v1/delivery-notes/{deliveryNoteId}/notes', summary: 'Get all notes for a delivery note', pathParams: ['deliveryNoteId'], hasBody: false, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
|
|
32
32
|
'create-notes': { method: 'POST', path: '/v1/delivery-notes/{deliveryNoteId}/notes', summary: 'Create a note for a delivery note', pathParams: ['deliveryNoteId'], hasBody: true, isMultipart: false, isBinaryResponse: false, bodyArrayFields: [] },
|
|
@@ -72,7 +72,7 @@ export default class DeliveryNotes extends Command {
|
|
|
72
72
|
'sort-by': Flags.string({ description: 'Sort field(s), comma-separated. Direction (:ASC/:DESC) is optional; date-like fields default to DESC, others to ASC.' }),
|
|
73
73
|
filter: Flags.string({ description: 'Filter (e.g. --filter status=ACTIVE). Operators: in:A,B, like:%, gt:, lt:, null:', multiple: true }),
|
|
74
74
|
query: Flags.string({ description: 'Additional query params as JSON' }),
|
|
75
|
-
fields: Flags.string({ description: 'Comma-separated list of fields to
|
|
75
|
+
fields: Flags.string({ description: 'Comma-separated list of fields to return, applied by the API (e.g. --fields=id,name,status)' }),
|
|
76
76
|
sanitize: Flags.boolean({ description: 'Remove null values, audit fields, and duplicate UUIDs from output' }),
|
|
77
77
|
'show-http-request': Flags.boolean({ description: 'Show HTTP request details (method, URL, body)' }),
|
|
78
78
|
};
|
|
@@ -144,6 +144,8 @@ export default class DeliveryNotes extends Command {
|
|
|
144
144
|
queryParams.search = flags.search;
|
|
145
145
|
if (flags['sort-by'])
|
|
146
146
|
queryParams.sortBy = normalizeSortBy(flags['sort-by']);
|
|
147
|
+
if (flags.fields)
|
|
148
|
+
queryParams.fields = flags.fields;
|
|
147
149
|
if (flags.query) {
|
|
148
150
|
try {
|
|
149
151
|
Object.assign(queryParams, JSON.parse(flags.query));
|
|
@@ -346,11 +348,6 @@ export default class DeliveryNotes extends Command {
|
|
|
346
348
|
output = obj[arrayKeys[0]];
|
|
347
349
|
}
|
|
348
350
|
}
|
|
349
|
-
// Filter fields if --fields flag is provided
|
|
350
|
-
if (flags.fields) {
|
|
351
|
-
const fieldList = flags.fields.split(',').map(f => f.trim());
|
|
352
|
-
output = this.filterFields(output, fieldList);
|
|
353
|
-
}
|
|
354
351
|
// Sanitize output if requested
|
|
355
352
|
if (flags.sanitize) {
|
|
356
353
|
output = this.sanitizeOutput(output);
|
|
@@ -605,6 +602,8 @@ export default class DeliveryNotes extends Command {
|
|
|
605
602
|
baseParams.sortBy = normalizeSortBy(flags['sort-by']);
|
|
606
603
|
if (flags.include)
|
|
607
604
|
baseParams.include = flags.include;
|
|
605
|
+
if (flags.fields)
|
|
606
|
+
baseParams.fields = flags.fields;
|
|
608
607
|
if (flags.query) {
|
|
609
608
|
try {
|
|
610
609
|
Object.assign(baseParams, JSON.parse(flags.query));
|
|
@@ -659,12 +658,7 @@ export default class DeliveryNotes extends Command {
|
|
|
659
658
|
}
|
|
660
659
|
}
|
|
661
660
|
process.stderr.write(' done\n');
|
|
662
|
-
// Filter fields if specified
|
|
663
661
|
let output = allItems;
|
|
664
|
-
if (flags.fields) {
|
|
665
|
-
const fieldList = flags.fields.split(',').map(f => f.trim());
|
|
666
|
-
output = this.filterFields(allItems, fieldList);
|
|
667
|
-
}
|
|
668
662
|
// Sanitize output if requested
|
|
669
663
|
if (flags.sanitize) {
|
|
670
664
|
output = this.sanitizeOutput(output);
|
|
@@ -993,56 +987,6 @@ export default class DeliveryNotes extends Command {
|
|
|
993
987
|
return `\$${op}`;
|
|
994
988
|
return opRe.test(rest) ? `\$${op}:${this.parseFilterValue(rest)}` : `\$${op}:${rest}`;
|
|
995
989
|
}
|
|
996
|
-
filterFields(data, fields) {
|
|
997
|
-
const isUnsafeKey = (k) => k === '__proto__' || k === 'constructor' || k === 'prototype';
|
|
998
|
-
const pick = (obj, keys) => {
|
|
999
|
-
// Group keys by their first segment so sibling sub-paths
|
|
1000
|
-
// (e.g. 'items.amount' + 'items._type') resolve in one recursive pass
|
|
1001
|
-
// and don't clobber each other on merge.
|
|
1002
|
-
const directKeys = new Set();
|
|
1003
|
-
const nestedKeys = new Map();
|
|
1004
|
-
for (const key of keys) {
|
|
1005
|
-
if (key.split('.').some(isUnsafeKey))
|
|
1006
|
-
continue;
|
|
1007
|
-
if (key.includes('.')) {
|
|
1008
|
-
const [first, ...rest] = key.split('.');
|
|
1009
|
-
if (isUnsafeKey(first))
|
|
1010
|
-
continue;
|
|
1011
|
-
const list = nestedKeys.get(first);
|
|
1012
|
-
if (list) {
|
|
1013
|
-
list.push(rest.join('.'));
|
|
1014
|
-
}
|
|
1015
|
-
else {
|
|
1016
|
-
nestedKeys.set(first, [rest.join('.')]);
|
|
1017
|
-
}
|
|
1018
|
-
}
|
|
1019
|
-
else {
|
|
1020
|
-
directKeys.add(key);
|
|
1021
|
-
}
|
|
1022
|
-
}
|
|
1023
|
-
const result = {};
|
|
1024
|
-
for (const key of directKeys) {
|
|
1025
|
-
if (key in obj)
|
|
1026
|
-
result[key] = obj[key];
|
|
1027
|
-
}
|
|
1028
|
-
for (const [first, restKeys] of nestedKeys) {
|
|
1029
|
-
const val = obj[first];
|
|
1030
|
-
if (!val || typeof val !== 'object')
|
|
1031
|
-
continue;
|
|
1032
|
-
if (Array.isArray(val)) {
|
|
1033
|
-
result[first] = val.map(item => pick(item, restKeys));
|
|
1034
|
-
}
|
|
1035
|
-
else {
|
|
1036
|
-
result[first] = pick(val, restKeys);
|
|
1037
|
-
}
|
|
1038
|
-
}
|
|
1039
|
-
return result;
|
|
1040
|
-
};
|
|
1041
|
-
if (Array.isArray(data)) {
|
|
1042
|
-
return data.map(item => pick(item, fields));
|
|
1043
|
-
}
|
|
1044
|
-
return pick(data, fields);
|
|
1045
|
-
}
|
|
1046
990
|
sanitizeOutput(data) {
|
|
1047
991
|
const auditFields = ['_type', 'tenantId', 'createdAt', 'updatedAt', 'createdBy', 'updatedBy'];
|
|
1048
992
|
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
@@ -43,7 +43,7 @@ export default class DunningConfigs 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
|
|
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 DunningConfigs 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 DunningConfigs 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 DunningConfigs 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 DunningConfigs 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 DunningConfigs 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;
|
|
@@ -44,7 +44,7 @@ export default class DunningReminders 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
|
|
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 DunningReminders 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 DunningReminders 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 DunningReminders 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 DunningReminders 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 DunningReminders 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;
|
|
@@ -32,7 +32,7 @@ export default class DunningRuns extends Command {
|
|
|
32
32
|
'sort-by': Flags.string({ description: 'Sort field(s), comma-separated. Direction (:ASC/:DESC) is optional; date-like fields default to DESC, others to ASC.' }),
|
|
33
33
|
filter: Flags.string({ description: 'Filter (e.g. --filter status=ACTIVE). Operators: in:A,B, like:%, gt:, lt:, null:', multiple: true }),
|
|
34
34
|
query: Flags.string({ description: 'Additional query params as JSON' }),
|
|
35
|
-
fields: Flags.string({ description: 'Comma-separated list of fields to
|
|
35
|
+
fields: Flags.string({ description: 'Comma-separated list of fields to return, applied by the API (e.g. --fields=id,name,status)' }),
|
|
36
36
|
sanitize: Flags.boolean({ description: 'Remove null values, audit fields, and duplicate UUIDs from output' }),
|
|
37
37
|
'show-http-request': Flags.boolean({ description: 'Show HTTP request details (method, URL, body)' }),
|
|
38
38
|
};
|
|
@@ -104,6 +104,8 @@ export default class DunningRuns extends Command {
|
|
|
104
104
|
queryParams.search = flags.search;
|
|
105
105
|
if (flags['sort-by'])
|
|
106
106
|
queryParams.sortBy = normalizeSortBy(flags['sort-by']);
|
|
107
|
+
if (flags.fields)
|
|
108
|
+
queryParams.fields = flags.fields;
|
|
107
109
|
if (flags.query) {
|
|
108
110
|
try {
|
|
109
111
|
Object.assign(queryParams, JSON.parse(flags.query));
|
|
@@ -306,11 +308,6 @@ export default class DunningRuns extends Command {
|
|
|
306
308
|
output = obj[arrayKeys[0]];
|
|
307
309
|
}
|
|
308
310
|
}
|
|
309
|
-
// Filter fields if --fields flag is provided
|
|
310
|
-
if (flags.fields) {
|
|
311
|
-
const fieldList = flags.fields.split(',').map(f => f.trim());
|
|
312
|
-
output = this.filterFields(output, fieldList);
|
|
313
|
-
}
|
|
314
311
|
// Sanitize output if requested
|
|
315
312
|
if (flags.sanitize) {
|
|
316
313
|
output = this.sanitizeOutput(output);
|
|
@@ -565,6 +562,8 @@ export default class DunningRuns extends Command {
|
|
|
565
562
|
baseParams.sortBy = normalizeSortBy(flags['sort-by']);
|
|
566
563
|
if (flags.include)
|
|
567
564
|
baseParams.include = flags.include;
|
|
565
|
+
if (flags.fields)
|
|
566
|
+
baseParams.fields = flags.fields;
|
|
568
567
|
if (flags.query) {
|
|
569
568
|
try {
|
|
570
569
|
Object.assign(baseParams, JSON.parse(flags.query));
|
|
@@ -619,12 +618,7 @@ export default class DunningRuns extends Command {
|
|
|
619
618
|
}
|
|
620
619
|
}
|
|
621
620
|
process.stderr.write(' done\n');
|
|
622
|
-
// Filter fields if specified
|
|
623
621
|
let output = allItems;
|
|
624
|
-
if (flags.fields) {
|
|
625
|
-
const fieldList = flags.fields.split(',').map(f => f.trim());
|
|
626
|
-
output = this.filterFields(allItems, fieldList);
|
|
627
|
-
}
|
|
628
622
|
// Sanitize output if requested
|
|
629
623
|
if (flags.sanitize) {
|
|
630
624
|
output = this.sanitizeOutput(output);
|
|
@@ -953,56 +947,6 @@ export default class DunningRuns extends Command {
|
|
|
953
947
|
return `\$${op}`;
|
|
954
948
|
return opRe.test(rest) ? `\$${op}:${this.parseFilterValue(rest)}` : `\$${op}:${rest}`;
|
|
955
949
|
}
|
|
956
|
-
filterFields(data, fields) {
|
|
957
|
-
const isUnsafeKey = (k) => k === '__proto__' || k === 'constructor' || k === 'prototype';
|
|
958
|
-
const pick = (obj, keys) => {
|
|
959
|
-
// Group keys by their first segment so sibling sub-paths
|
|
960
|
-
// (e.g. 'items.amount' + 'items._type') resolve in one recursive pass
|
|
961
|
-
// and don't clobber each other on merge.
|
|
962
|
-
const directKeys = new Set();
|
|
963
|
-
const nestedKeys = new Map();
|
|
964
|
-
for (const key of keys) {
|
|
965
|
-
if (key.split('.').some(isUnsafeKey))
|
|
966
|
-
continue;
|
|
967
|
-
if (key.includes('.')) {
|
|
968
|
-
const [first, ...rest] = key.split('.');
|
|
969
|
-
if (isUnsafeKey(first))
|
|
970
|
-
continue;
|
|
971
|
-
const list = nestedKeys.get(first);
|
|
972
|
-
if (list) {
|
|
973
|
-
list.push(rest.join('.'));
|
|
974
|
-
}
|
|
975
|
-
else {
|
|
976
|
-
nestedKeys.set(first, [rest.join('.')]);
|
|
977
|
-
}
|
|
978
|
-
}
|
|
979
|
-
else {
|
|
980
|
-
directKeys.add(key);
|
|
981
|
-
}
|
|
982
|
-
}
|
|
983
|
-
const result = {};
|
|
984
|
-
for (const key of directKeys) {
|
|
985
|
-
if (key in obj)
|
|
986
|
-
result[key] = obj[key];
|
|
987
|
-
}
|
|
988
|
-
for (const [first, restKeys] of nestedKeys) {
|
|
989
|
-
const val = obj[first];
|
|
990
|
-
if (!val || typeof val !== 'object')
|
|
991
|
-
continue;
|
|
992
|
-
if (Array.isArray(val)) {
|
|
993
|
-
result[first] = val.map(item => pick(item, restKeys));
|
|
994
|
-
}
|
|
995
|
-
else {
|
|
996
|
-
result[first] = pick(val, restKeys);
|
|
997
|
-
}
|
|
998
|
-
}
|
|
999
|
-
return result;
|
|
1000
|
-
};
|
|
1001
|
-
if (Array.isArray(data)) {
|
|
1002
|
-
return data.map(item => pick(item, fields));
|
|
1003
|
-
}
|
|
1004
|
-
return pick(data, fields);
|
|
1005
|
-
}
|
|
1006
950
|
sanitizeOutput(data) {
|
|
1007
951
|
const auditFields = ['_type', 'tenantId', 'createdAt', 'updatedAt', 'createdBy', 'updatedBy'];
|
|
1008
952
|
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|