Skip to content

Commit

Permalink
feat: add object with deepObject style in query parameters (#2631)
Browse files Browse the repository at this point in the history
This commit adds support for using objects with the deepObject style in
the TryIt component.

A parameter `id` with the value `{"role": "admin", "firstName": "Alex"}`
will create the query parameters `id[role]=admin&id[firstName]=Alex`.

Co-authored-by: Nauman <[email protected]>
  • Loading branch information
maraino and mnaumanali94 authored Nov 5, 2024
1 parent d6358d2 commit c4fc263
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,14 @@ export const httpOperation: IHttpOperation = {
style: HttpParamStyles.Form,
explode: false,
},
{
schema: {
type: 'object',
},
name: 'deep_object',
style: HttpParamStyles.DeepObject,
explode: true,
},
{
schema: {
type: 'boolean',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,14 @@ export const httpOperation: IHttpOperation = {
name: 'pairs',
style: HttpParamStyles.Form,
},
{
id: '?http-query-pagination?',
schema: {
type: 'object',
},
name: 'pagination',
style: HttpParamStyles.DeepObject,
},
{
id: '?http-query-items?',
schema: {
Expand Down
6 changes: 6 additions & 0 deletions packages/elements-core/src/components/TryIt/TryIt.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ describe('TryIt', () => {
'limit*',
'super_duper_long_parameter_name_with_unnecessary_text*',
'completed',
'deep_object',
'default_style_items',
'items',
'items_not_exploded',
Expand Down Expand Up @@ -283,6 +284,9 @@ describe('TryIt', () => {
const pairsField = screen.getByLabelText('pairs');
userEvent.type(pairsField, '{ "nestedKey": "nestedValue" }');

const pagination = screen.getByLabelText('pagination');
userEvent.type(pagination, '{ "first": 50, "after": "cursor" }');

const itemsField = screen.getByLabelText('items');
userEvent.type(itemsField, '["first", "second"]');

Expand Down Expand Up @@ -312,6 +316,8 @@ describe('TryIt', () => {
expect(queryParams.get('optional_value_with_default')).toBeNull();
expect(queryParams.get('nestedKey')).toBe('nestedValue');
expect(queryParams.get('pairs')).toBeNull();
expect(queryParams.get('pagination[first]')).toBe('50');
expect(queryParams.get('pagination[after]')).toBe('cursor');
expect(queryParams.getAll('items')).toEqual(['first', 'second']);
// assert that headers are passed
const headers = new Headers(fetchMock.mock.calls[0][1]!.headers);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ describe('Build Request', () => {
}).toThrowError('JSON array expected');
});

it('Supports form style', () => {
it('Supports form and deepObject style', () => {
const params = getQueryParams({
httpOperation,
parameterValues: {
Expand All @@ -46,6 +46,7 @@ describe('Build Request', () => {
default_style_items: '["first","second"]',
nested: '{"key":"value"}',
nested_not_exploded: '{"key":"value"}',
deep_object: '{"key":"value", "number": 2}',
},
});

Expand All @@ -58,6 +59,8 @@ describe('Build Request', () => {
{ name: 'default_style_items', value: 'second' },
{ name: 'key', value: 'value' },
{ name: 'nested_not_exploded', value: 'key,value' },
{ name: 'deep_object[key]', value: 'value' },
{ name: 'deep_object[number]', value: '2' },
]);
});

Expand Down
29 changes: 20 additions & 9 deletions packages/elements-core/src/components/TryIt/build-request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export const getQueryParams = ({

const explode = param.explode ?? true;

if (param.schema?.type === 'object' && param.style === 'form' && value) {
if (param.schema?.type === 'object' && value) {
let nested: Dictionary<string, string>;
try {
nested = JSON.parse(value);
Expand All @@ -80,15 +80,26 @@ export const getQueryParams = ({
throw new Error(`Cannot use param value "${value}". JSON object expected.`);
}

if (explode) {
acc.push(...Object.entries(nested).map(([name, value]) => ({ name, value: value.toString() })));
if (param.style === 'form') {
if (explode) {
acc.push(...Object.entries(nested).map(([name, value]) => ({ name, value: value.toString() })));
} else {
acc.push({
name: param.name,
value: Object.entries(nested)
.map(entry => entry.join(','))
.join(','),
});
}
} else if (param.style === 'deepObject') {
acc.push(
...Object.entries(nested).map(([name, value]) => ({
name: `${param.name}[${name}]`,
value: value.toString(),
})),
);
} else {
acc.push({
name: param.name,
value: Object.entries(nested)
.map(entry => entry.join(','))
.join(','),
});
acc.push({ name: param.name, value });
}
} else if (param.schema?.type === 'array' && value) {
let nested: string[];
Expand Down

0 comments on commit c4fc263

Please sign in to comment.