private validateRequest()

in lib/swaggerValidator/modelValidator.ts [311:442]


  private validateRequest(operation: Operation, exampleContent: any, exampleFileUrl: string) {
    const parameterizedHostDef = operation._path._spec["x-ms-parameterized-host"];
    const useSchemePrefix = parameterizedHostDef
      ? parameterizedHostDef.useSchemePrefix === undefined
        ? true
        : parameterizedHostDef.useSchemePrefix
      : null;
    const pathTemplate = operation._path._pathTemplate;
    const parameters = operation.parameters;
    const publicParameters = operation._path.parameters;
    const mergedParameters = [...(parameters ?? []), ...(publicParameters ?? [])];
    const pathParameters: { [key: string]: string } = {};
    let bodyParameter: any = {};
    const queryParameters: ParsedUrlQuery = {};
    const formData: { [key: string]: string } = {};
    const exampleRequestHeaders: { [propertyName: string]: string } = {};
    if (mergedParameters === undefined) {
      return;
    }
    for (const p of mergedParameters) {
      const parameter = this.jsonLoader.resolveRefObj(p);
      let parameterValue = exampleContent?.parameters[parameter.name];
      if (!parameterValue) {
        if (parameter.required) {
          const meta = getOavErrorMeta(
            ErrorCodeConstants.REQUIRED_PARAMETER_EXAMPLE_NOT_FOUND as any,
            { operationId: operation.operationId, name: parameter.name }
          );
          this.addErrorsFromErrorCode(
            operation.operationId!,
            exampleFileUrl,
            meta,
            operation,
            undefined,
            p
          );
          break;
        }
        continue;
      }
      const location = parameter.in;
      if (location === "path") {
        if (location === "path" && parameterValue && typeof parameterValue === "string") {
          // "/{scope}/scopes/resourceGroups/{resourceGroupName}" In the aforementioned path
          // template, we will search for the path parameter based on it's name
          // for example: "scope". Find it's index in the string and move backwards by 2 positions.
          // If the character at that position is a forward slash "/" and
          // the value for the parameter starts with a forward slash "/" then we have found the case
          // where there will be duplicate forward slashes in the url.
          if (
            pathTemplate.charAt(pathTemplate.indexOf(`${parameter.name}`) - 2) === "/" &&
            parameterValue.startsWith("/")
          ) {
            const meta = getOavErrorMeta(ErrorCodeConstants.DOUBLE_FORWARD_SLASHES_IN_URL as any, {
              operationId: operation.operationId,
              parameterName: parameter.name,
              parameterValue,
              pathTemplate,
            });
            this.addErrorsFromErrorCode(
              operation.operationId!,
              exampleFileUrl,
              meta,
              operation,
              undefined,
              p
            );
            break;
          }
          // replacing characters that may cause validator failed  with empty string because this messes up Sways regex
          // validation of path segment.
          parameterValue = parameterValue.replace(/\//gi, "");

          // replacing scheme that may cause validator failed when x-ms-parameterized-host enbaled & useSchemePrefix enabled
          // because if useSchemePrefix enabled ,the parameter value in x-ms-parameterized-host should not has the scheme (http://|https://)
          if (useSchemePrefix) {
            parameterValue = (parameterValue as string).replace(/^https{0,1}:/gi, "");
          }
        }
        // todo skip url encoding
        pathParameters[parameter.name] = parameterValue;
      } else if (location === "query") {
        // validate the api version value
        if (parameter.name === "api-version" && parameterValue !== this.swagger.info.version) {
          const meta = getOavErrorMeta("INVALID_REQUEST_PARAMETER", {
            parameterName: "api-version",
            apiVersion: parameterValue,
          });
          this.addErrorsFromErrorCode(
            operation.operationId!,
            exampleFileUrl,
            meta,
            operation,
            undefined,
            exampleContent?.parameters,
            `$parameters["api-version"]`
          );
          continue;
        }
        queryParameters[parameter.name] = parameterValue;
      } else if (location === "body") {
        if ((parameter as BodyParameter).schema?.format === "file") {
          continue;
        }
        bodyParameter = parameterValue;
      } else if (location === "header") {
        exampleRequestHeaders[parameter.name] = parameterValue;
      } else if (location === "formData") {
        formData[parameter.name] = parameterValue;
      }
    } // end of mergedParameters for loop
    transformMapValue(queryParameters, operation._queryTransform);
    transformMapValue(pathParameters, operation._pathTransform);
    const validate = operation._validate!;
    const ctx = { isResponse: false };
    const headers = transformLiveHeader(exampleRequestHeaders, operation);
    const ajvValidatorErrors = validate(ctx, {
      path: pathParameters,
      body: transformBodyValue(bodyParameter, operation),
      query: queryParameters,
      headers,
      formData,
    });
    this.schemaIssuesToModelValidationIssues(
      operation.operationId!,
      true,
      ajvValidatorErrors,
      exampleFileUrl,
      exampleContent,
      mergedParameters
    );
  }