Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/hungry-spies-stand.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@redocly/respect-core": patch
---

Resolved an issue in Respect where the response list with nested object was not correctly assigned to the output.
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,16 @@ const runtimeExpressionContext = {
'Join us as we review and classify a rare collection of 20 thingamabobs, gadgets, gizmos, whoosits, and whatsits, kindly donated by Ariel.',
dates: ['2023-12-15', '2023-12-22'],
price: 0,
items: [
{
name: 'item1',
description: 'item1 description',
},
{
name: 'item2',
description: 'item2 description',
},
],
},
statusCode: 201,
header: {
Expand Down Expand Up @@ -229,7 +239,16 @@ const runtimeExpressionContext = {
eventDescription: 'Join us as we review and classify a rare collection of 20 thingamabobs.',
dates: ['2023-12-15', '2023-12-22'],
price: 0,
items: [],
items: [
{
name: 'item1',
description: 'item1 description',
},
{
name: 'item2',
description: 'item2 description',
},
],
device_code: '123',
piNumber: 3.14,
},
Expand Down Expand Up @@ -394,7 +413,16 @@ describe('evaluateRuntimeExpressionPayload', () => {
eventDescription: 'Join us as we review and classify a rare collection of 20 thingamabobs.',
dates: ['2023-12-15', '2023-12-22'],
price: 0,
items: [],
items: [
{
name: 'item1',
description: 'item1 description',
},
{
name: 'item2',
description: 'item2 description',
},
],
piNumber: 3.14,
});
});
Expand Down Expand Up @@ -639,4 +667,18 @@ describe('evaluateRuntimeExpression', () => {
expect(evaluateRuntimeExpression(expression2, runtimeExpressionContext, logger)).toEqual(true);
expect(evaluateRuntimeExpression(expression3, runtimeExpressionContext, logger)).toEqual(false);
});

it('should evaluate list runtime expression value', () => {
const expression = '$response.body#/items';
expect(evaluateRuntimeExpression(expression, runtimeExpressionContext, logger)).toEqual([
{
name: 'item1',
description: 'item1 description',
},
{
name: 'item2',
description: 'item2 description',
},
]);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const ajvStrict = new Ajv({
validateSchema: false,
discriminator: true,
allowUnionTypes: true,
validateFormats: false,
validateFormats: true,
logger: false,
verbose: true,
defaultUnevaluatedProperties: false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,17 @@ function normalizeExpression(expression: string, context: RuntimeExpressionConte
// Normalize the expression for evaluation by replacing hyphens with underscores and converting to lowercase
const normalizedSymbolsExpression = normalizeSymbolsExpression(modifiedJsExpression);

// Remove the curly braces surrounding the expression (if any)
const cleanedJsExpression = normalizedSymbolsExpression.replace(/{(.*?)}/g, '$1');
// Remove the curly braces surrounding the ENTIRE expression (if any), but not braces within JSON
let cleanedJsExpression = normalizedSymbolsExpression;

if (cleanedJsExpression.startsWith('{') && cleanedJsExpression.endsWith('}')) {
// A runtime expression wrapper has the form {$variable...} with no nested braces until the end
const potentialUnwrapped = cleanedJsExpression.slice(1, -1);
// Unwrap if it doesn't look like JSON (i.e., doesn't start with { or [)
if (!potentialUnwrapped.trim().startsWith('{') && !potentialUnwrapped.trim().startsWith('[')) {
cleanedJsExpression = potentialUnwrapped;
}
}

// Convert numeric indices (e.g., `.0`) into square bracket notation (e.g., `[0]`)
const expressionWithBrackets = convertNumericIndices(cleanedJsExpression);
Expand Down