Skip to content

Commit 6750708

Browse files
authored
feat: Support metadata query with array (#581)
1 parent 2ec8e7f commit 6750708

2 files changed

Lines changed: 99 additions & 17 deletions

File tree

src/commands/metadata-query.js

Lines changed: 57 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,26 +8,48 @@ class MetadataQueryCommand extends BoxCommand {
88
async run() {
99
const { flags, args } = await this.parse(MetadataQueryCommand);
1010

11-
const { extra_fields: extraFields, ...rest } = mapKeys(
12-
omit(flags, Object.keys(BoxCommand.flags)),
13-
(value, key) => snakeCase(key)
11+
const {
12+
extra_fields: extraFields,
13+
query_params: queryParams,
14+
query_param: queryParam,
15+
query_param_array: queryParamArray,
16+
...rest
17+
} = mapKeys(omit(flags, Object.keys(BoxCommand.flags)), (value, key) =>
18+
snakeCase(key),
1419
);
1520

21+
let combinedQueryParams = queryParams || {};
22+
if (queryParam) {
23+
combinedQueryParams = {
24+
...combinedQueryParams,
25+
...queryParam,
26+
};
27+
}
28+
if (queryParamArray) {
29+
combinedQueryParams = {
30+
...combinedQueryParams,
31+
...queryParamArray,
32+
};
33+
}
34+
1635
const items = await this.client.metadata.query(
1736
args.from,
1837
args.ancestorFolderId,
1938
{
2039
...(extraFields && { fields: extraFields }),
40+
...(combinedQueryParams && { query_params: combinedQueryParams }),
2141
...rest,
22-
}
42+
},
2343
);
2444
await this.output(items);
2545
}
2646
}
2747

2848
MetadataQueryCommand.description =
2949
'Create a search using SQL-like syntax to return items that match specific metadata';
30-
MetadataQueryCommand.examples = ['box metadata-query enterprise_12345.someTemplate 5555 --query "amount >= :minAmount AND amount <= :maxAmount" --query-params minAmount=100f,maxAmount=200f --use-index amountAsc --order-by amount=ASC --extra-fields created_at,metadata.enterprise_1234.contracts'];
50+
MetadataQueryCommand.examples = [
51+
'box metadata-query enterprise_12345.someTemplate 5555 --query "amount >= :minAmount AND amount <= :maxAmount" --query-params minAmount=100f,maxAmount=200f --use-index amountAsc --order-by amount=ASC --extra-fields created_at,metadata.enterprise_1234.contracts',
52+
];
3153
MetadataQueryCommand._endpoint = 'post_metadata_queries_execute_read';
3254

3355
MetadataQueryCommand.flags = {
@@ -36,16 +58,14 @@ MetadataQueryCommand.flags = {
3658
description: 'The logical expression of the query',
3759
}),
3860
'query-params': Flags.string({
39-
description: 'Required if query present. The arguments for the query.',
61+
description:
62+
'The arguments for the query. Can be specified as a comma-separated list of key-value pairs. i.e. key1=value1,key2=value2',
4063
dependsOn: ['query'],
4164
parse(input) {
4265
return Object.assign(
4366
{},
44-
...input.split(',').map(param => {
45-
const [
46-
key,
47-
value
48-
] = param.split('=');
67+
...input.split(',').map((param) => {
68+
const [key, value] = param.split('=');
4969
/* eslint-disable multiline-ternary */
5070
return {
5171
[key]:
@@ -54,22 +74,42 @@ MetadataQueryCommand.flags = {
5474
: value,
5575
};
5676
/* eslint-enable multiline-ternary */
57-
})
77+
}),
5878
);
5979
},
6080
}),
81+
'query-param': Flags.string({
82+
description: 'One query param key-value pair, i.e. key=value. If this key duplicates with query-params, this flag will take precedence.',
83+
dependsOn: ['query'],
84+
parse(input) {
85+
const key = input.split('=')[0];
86+
const value = input.substring(key.length + 1);
87+
return {
88+
[key]: value,
89+
};
90+
},
91+
}),
92+
'query-param-array': Flags.string({
93+
description:
94+
'One query param key-multiple-value pair, use for multiple-values fields, i.e. key=value1,value2,value3. If this key duplicates with query-params or query-param, this flag will take precedence.',
95+
dependsOn: ['query'],
96+
parse(input) {
97+
const key = input.split('=')[0];
98+
const value = input.substring(key.length + 1).split(',');
99+
return {
100+
[key]: value,
101+
};
102+
},
103+
}),
61104
'use-index': Flags.string({
62105
description: 'The name of the search index to use for this query.',
63106
}),
64107
'order-by': Flags.string({
65108
description:
66109
'A list of template fields and directions to sort the metadata query results by.',
67110
parse(input) {
68-
return input.split(',').map(param => {
69-
const [
70-
fieldKey,
71-
direction
72-
] = param.split('=');
111+
return input.split(',').map((param) => {
112+
const [fieldKey, direction] = param.split('=');
73113
return { field_key: fieldKey, direction };
74114
});
75115
},

test/commands/metadata-query.test.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,26 @@ describe('Metadata Query', () => {
2626
],
2727
limit: 100,
2828
},
29+
requestWithMultipleValues = {
30+
from: 'enterprise_123456.contractTemplate',
31+
query: 'name = :customerName',
32+
query_params: {
33+
customerName: ['John Doe', 'Jane Doe'],
34+
},
35+
fields: [
36+
'created_at',
37+
'metadata.enterprise_123456.contractTemplate.amount',
38+
'metadata.enterprise_123456.contractTemplate.customerName',
39+
],
40+
ancestor_folder_id: '5555',
41+
order_by: [
42+
{
43+
field_key: 'amount',
44+
direction: 'asc',
45+
},
46+
],
47+
limit: 100,
48+
},
2949
fixture = getFixture('metadata-query/post_metadata_queries_execute_read');
3050

3151
test
@@ -49,5 +69,27 @@ describe('Metadata Query', () => {
4969
.it('should query metadata', ctx => {
5070
assert.equal(ctx.stdout, fixture);
5171
});
72+
73+
test
74+
.nock(TEST_API_ROOT, api => api
75+
.post('/2.0/metadata_queries/execute_read', requestWithMultipleValues)
76+
.reply(200, fixture)
77+
)
78+
.stdout()
79+
.command([
80+
'metadata-query',
81+
requestWithMultipleValues.from,
82+
requestWithMultipleValues.ancestor_folder_id,
83+
`--query=${requestWithMultipleValues.query}`,
84+
`--query-param-array=customerName=${requestWithMultipleValues.query_params.customerName.join(',')}`,
85+
`--extra-fields=${requestWithMultipleValues.fields.join(',')}`,
86+
`--order-by=${requestWithMultipleValues.order_by[0].field_key}=${requestWithMultipleValues.order_by[0].direction}`,
87+
`--limit=${requestWithMultipleValues.limit}`,
88+
'--json',
89+
'--token=test',
90+
])
91+
.it('should query metadata with query-param', ctx => {
92+
assert.equal(ctx.stdout, fixture);
93+
});
5294
});
5395
});

0 commit comments

Comments
 (0)