Skip to content

Commit

Permalink
feat(api-service): fix additional properties issue (#7434)
Browse files Browse the repository at this point in the history
  • Loading branch information
djabarovgeorge authored Jan 6, 2025
1 parent f282fab commit 84beb77
Showing 1 changed file with 71 additions and 35 deletions.
106 changes: 71 additions & 35 deletions apps/api/src/app/workflows-v2/util/build-variables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import { Variable, extractLiquidTemplateVariables, TemplateVariables } from './t
import { transformMailyContentToLiquid } from '../usecases/generate-preview/transform-maily-content-to-liquid';
import { isStringTipTapNode } from './tip-tap.util';

const DOT_PROPERTIES = '.properties';
const DOT_ADDITIONAL_PROPERTIES = '.additionalProperties';

export function buildVariables(
variableSchema: Record<string, unknown> | undefined,
controlValue: unknown | Record<string, unknown>,
Expand Down Expand Up @@ -41,53 +44,86 @@ export function buildVariables(
};
}

/**
* Validates variables against a schema to identify which ones are valid/invalid.
* Returns an object containing arrays of valid and invalid variables.
*/
function identifyUnknownVariables(
type PathValidationResult = {
isValid: boolean;
additionalPropertiesFound?: boolean;
};

function validateVariablePath(variableSchema: Record<string, unknown>, variableName: string): PathValidationResult {
const parts = variableName.split('.');
let currentPath = 'properties';

for (const part of parts) {
currentPath += `.${part}`;
const valueExists = _.get(variableSchema, currentPath) !== undefined;
const propertiesPath = `${currentPath}${DOT_PROPERTIES}`;
const propertiesExist = _.get(variableSchema, propertiesPath) !== undefined;

if (!valueExists && !propertiesExist) {
const additionalPropertiesResult = checkAdditionalProperties(variableSchema, propertiesPath);
if (additionalPropertiesResult.isValid) {
return { isValid: true, additionalPropertiesFound: true };
}

return { isValid: false };
}

currentPath = propertiesPath;
}

return { isValid: true };
}

function checkAdditionalProperties(
variableSchema: Record<string, unknown>,
validVariables: Variable[]
): TemplateVariables {
const validVariablesCopy: Variable[] = _.cloneDeep(validVariables);
propertiesPath: string
): PathValidationResult {
let currentPath = propertiesPath;

const result = validVariablesCopy.reduce<TemplateVariables>(
(acc, variable: Variable) => {
const parts = variable.name.split('.');
let isValid = true;
let currentPath = 'properties';
while (currentPath.length > 0) {
const additionalPropertiesPath = `${currentPath.slice(0, -DOT_PROPERTIES.length)}${DOT_ADDITIONAL_PROPERTIES}`;
const additionalPropertiesValue = _.get(variableSchema, additionalPropertiesPath);

for (const part of parts) {
currentPath += `.${part}`;
const valueSearch = _.get(variableSchema, currentPath);
if (additionalPropertiesValue !== undefined) {
return { isValid: additionalPropertiesValue === true };
}

currentPath += '.properties';
const propertiesSearch = _.get(variableSchema, currentPath);
const pathParts = currentPath.split('.');
if (pathParts.length <= 2) break;

if (valueSearch === undefined && propertiesSearch === undefined) {
isValid = false;
break;
}
}
currentPath = pathParts.slice(0, -2).join('.');
}

return { isValid: false };
}

function createInvalidVariable(variable: Variable): Variable {
return {
name: variable.output,
context: variable.context,
message: 'Variable is not supported',
output: variable.output,
};
}

function identifyUnknownVariables(
variableSchema: Record<string, unknown>,
validVariables: Variable[]
): TemplateVariables {
const variables = _.cloneDeep(validVariables);

return variables.reduce<TemplateVariables>(
(acc, variable) => {
const { isValid } = validateVariablePath(variableSchema, variable.name);

if (isValid) {
acc.validVariables.push(variable);
} else {
acc.invalidVariables.push({
name: variable.output,
context: variable.context,
message: 'Variable is not supported',
output: variable.output,
});
acc.invalidVariables.push(createInvalidVariable(variable));
}

return acc;
},
{
validVariables: [] as Variable[],
invalidVariables: [] as Variable[],
} as TemplateVariables
{ validVariables: [], invalidVariables: [] }
);

return result;
}

0 comments on commit 84beb77

Please sign in to comment.