export function processPathInputs()

in libs/designer/src/lib/core/utils/swagger/inputsbuilder.ts [537:680]


export function processPathInputs(pathValue: string, pathTemplate: string): Record<string, any> {
  const intl = getIntl();
  const pathInputs: Record<string, any> = {};
  const regex = /{(.*?)}/g;
  // Pathkeys are of the form {key} within the path template.
  const pathKeys = pathTemplate.match(regex);
  const builder = new ExpressionBuilder();

  if (pathKeys && pathKeys.length) {
    const sanitizedTemplateString = pathTemplate.replace(regex, operationPathDelimiter);
    let sanitizedValueString = pathValue;
    let functionSegments: ExpressionFunction[] = [];

    const errorMessage = intl.formatMessage(
      {
        defaultMessage: 'Invalid operation path input value. Path value - {pathValue}, Path template - {pathTemplate}',
        id: 'apZgmJ',
        description: 'Error message while parsing ',
      },
      { pathValue, pathTemplate }
    );
    if (isTemplateExpression(pathValue)) {
      let result: Expression;
      try {
        result = ExpressionParser.parseTemplateExpression(pathValue);
      } catch (error: any) {
        if (error?.name === ExpressionExceptionCode) {
          throw new Error(errorMessage);
        }
        throw new AssertionException(AssertionErrorCode.INVALID_EXPRESSION_IN_PATH_VALUE_SEGMENT, errorMessage, { pathValue }, error);
      }

      if (!isStringInterpolation(result)) {
        throw new Error(errorMessage);
      }

      functionSegments = result.segments.filter(isFunction) as ExpressionFunction[];
      const sanitizedSegments = result.segments.map((segment) => {
        if (isFunction(segment)) {
          return { type: ExpressionType.StringLiteral, value: operationPathDelimiter };
        }
        return segment;
      });

      sanitizedValueString = builder.buildTemplateExpression({ type: ExpressionType.StringInterpolation, segments: sanitizedSegments });
    }

    const templateSections = sanitizedTemplateString.split('/');
    const valueSections = sanitizedValueString.split('/');

    if (templateSections.length !== valueSections.length) {
      throw new Error(errorMessage);
    }

    const errorMismatchSegments = intl.formatMessage(
      {
        defaultMessage: 'Operation path value does not match the template for segment. Path {pathValue}, Template {pathTemplate}',
        id: 'hq1mk6',
        description: 'Error while parsing expression for path value',
      },
      { pathValue, pathTemplate }
    );

    let parameterIndex = 0;
    let functionIndex = 0;
    for (let i = 0; i < templateSections.length; i++) {
      const templateSection = templateSections[i];
      const valueSection = valueSections[i];
      const parameterCountInTemplateSection = countOccurrence(templateSection, operationPathDelimiter);
      const parameterCountInValueSection = countOccurrence(valueSection, operationPathDelimiter);

      if (templateSection !== valueSection && parameterCountInTemplateSection === 0) {
        throw new Error(errorMismatchSegments);
      }

      if (parameterCountInTemplateSection > 0) {
        // NOTE: If the path template section contains one parameter, its value could be literal or expression segments.
        // If the path template section contains more than one parameter, the corresponding value must be expression value segments generated by the designer.
        if (parameterCountInTemplateSection > 1 && parameterCountInTemplateSection > parameterCountInValueSection) {
          throw new Error(errorMismatchSegments);
        }

        if (parameterCountInTemplateSection === 1) {
          // NOTE: If the section just contains one parameter, just use prefix/suffix to match the value
          const placeHolderPosition = templateSection.indexOf(operationPathDelimiter);
          const nameKey = pathKeys[parameterIndex];
          const pathParameterName = nameKey.substring(1, nameKey.length - 1);
          let parameterValue: string;

          if (templateSection === operationPathDelimiter) {
            if (valueSection === operationPathDelimiter) {
              const functionSegment = functionSegments[functionIndex];
              parameterValue = getStringInterpolatedFunctionExpression(functionSegment);
              functionIndex++;
            } else {
              parameterValue = valueSection;
            }
          } else {
            const prefix = templateSection.substring(0, placeHolderPosition);
            const suffix = templateSection.substring(placeHolderPosition + operationPathDelimiter.length);
            if (!valueSection.startsWith(prefix) || !valueSection.endsWith(suffix)) {
              throw new Error(errorMismatchSegments);
            }

            if (valueSection.indexOf(operationPathDelimiter) < 0) {
              parameterValue = valueSection.substring(prefix.length, valueSection.length - suffix.length);
            } else {
              const functionSegment = functionSegments[functionIndex];
              parameterValue = getStringInterpolatedFunctionExpression(functionSegment);
              functionIndex++;
            }
          }

          pathInputs[pathParameterName] = parameterValue;
          parameterIndex++;
        } else {
          if (templateSection !== valueSection) {
            throw new Error(errorMismatchSegments);
          }

          // Note: if the section contains more than one parameter, split the section by placeholder, then match each segment using prefix
          let startPos = 0;
          let pos = templateSection.indexOf(operationPathDelimiter, startPos);
          while (pos > -1) {
            const nameKey = pathKeys[parameterIndex++];
            const pathParameterName = nameKey.substring(1, nameKey.length - 1);
            const prefix = templateSection.substring(startPos, pos);
            if (!valueSection.startsWith(prefix, startPos)) {
              throw new Error(errorMismatchSegments);
            }

            const functionSegment = functionSegments[functionIndex++];
            const parameterValue = getStringInterpolatedFunctionExpression(functionSegment);
            pathInputs[pathParameterName] = parameterValue;
            startPos = pos + 1;
            pos = templateSection.indexOf(operationPathDelimiter, startPos);
          }
        }
      }
    }
  }

  return pathInputs;
}