Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
IntegrationPattern,
JsonPath,
} from '../../../aws-stepfunctions';
import { isValidJsonataExpression } from '../../../aws-stepfunctions/lib/private/jsonata';
import { Aws, UnscopedValidationError } from '../../../core';

/**
Expand Down Expand Up @@ -35,16 +36,9 @@ export function integrationResourceArn(service: string, api: string, integration
(integrationPattern ? resourceArnSuffix[integrationPattern] : '');
}

/**
* Determines if the indicated string is an JSONata expression
*/
export function isJsonataExpression(value: string) {
return /^{%(.*)%}$/.test(value);
}

/**
* Determines if the indicated string is an encoded JSON path or JSONata expression
*/
export function isJsonPathOrJsonataExpression(value: string) {
return JsonPath.isEncodedJsonPath(value) || isJsonataExpression(value);
return JsonPath.isEncodedJsonPath(value) || isValidJsonataExpression(value);
}
5 changes: 3 additions & 2 deletions packages/aws-cdk-lib/aws-stepfunctions/lib/condition.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { UnscopedValidationError } from '../../core';
import { isValidJsonataExpression } from './private/jsonata';

/**
* A Condition for use in a Choice state branch
Expand Down Expand Up @@ -467,8 +468,8 @@ class NotCondition extends Condition {
class JsonataCondition extends Condition {
constructor(private readonly condition: string) {
super();
if (!/^{%(.*)%}$/.test(condition)) {
throw new UnscopedValidationError(`JSONata expression must be start with '{%' and end with '%}', got '${condition}'`);
if (!isValidJsonataExpression(condition)) {
throw new UnscopedValidationError(`JSONata expression must start with '{%' and end with '%}', got '${condition}'`);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export const isValidJsonataExpression = (expression: string) => /^{%(.*)%}$/.test(expression);
export const isValidJsonataExpression = (expression: string) => /^{%(.*)%}$/s.test(expression);

export const findJsonataExpressions = (value: any): Set<string> => {
const recursive = (v: any): string[] => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { findJsonataExpressions, isValidJsonataExpression } from '../../lib/private/jsonata';

describe('jsonata', () => {
describe('isValidJsonataExpression', () => {
test('should return true for valid expressions', () => {
expect(isValidJsonataExpression('{% $value %}')).toBe(true);
expect(isValidJsonataExpression('{%$.some.field%}')).toBe(true);
expect(isValidJsonataExpression(`{%
$someFunction();
%}`)).toBe(true);
});

test('should return false for invalid expressions', () => {
expect(isValidJsonataExpression('$value')).toBe(false);
expect(isValidJsonataExpression('{$value%}')).toBe(false);
expect(isValidJsonataExpression('{% $value }')).toBe(false);
expect(isValidJsonataExpression('some random string')).toBe(false);
});

describe('findJsonataExpressions', () => {
test('finds all valid JSONata expressions and ignores invalid/other types', () => {
const input = [
'{% $expr1 %}',
'not an expr',
null,
123,
{ a: '{% $expr2 %}', b: ['{% $expr3 %}', { c: '{% $expr4 %}' }] },
`{%
$expr5
%}`,
{ d: '{$invalid%}' },
];

const result = findJsonataExpressions(input);
expect(Array.from(result)).toEqual([
'{% $expr1 %}',
'{% $expr2 %}',
'{% $expr3 %}',
'{% $expr4 %}',
`{%
$expr5
%}`,
]);
});
});
});
});
Loading