APIDevTools / swagger-parser

Swagger 2.0 and OpenAPI 3.0 parser/validator
https://apitools.dev/swagger-parser
MIT License
1.1k stars 155 forks source link

Parameterise the validator function #240

Open souhailaS opened 1 year ago

souhailaS commented 1 year ago

The AjvDraft4 options are hard coded.

souhailaS commented 1 year ago
/**
 * Validates the given Swagger API against the Swagger 2.0 or OpenAPI 3.0 and 3.1 schemas.
 *
 * @param {SwaggerObject} api
 * @param {boolean} [allErrors=false] - If true, all errors will be reported. Otherwise, only the first error will be reported.
 * @param {boolean} [strict=false] - If true, additional validation rules will be applied.
 * @param {boolean} [validateFormats=false] - If true, format validation will be performed.
 */
function validateSchema(
  api,
  allErrors = false,
  strict = false,
  validateFormats = false
) {
  let ajv;

  // Choose the appropriate schema (Swagger or OpenAPI)
  let schema;

  if (api.swagger) {
    schema = openapi.v2;
    ajv = initializeAjv( /* draft04 = */ true, allErrors, strict, validateFormats);
  } else {
    if (api.openapi.startsWith("3.1")) {
      schema = openapi.v31;

      // There's a bug with Ajv in how it handles `$dynamicRef` in the way that it's used within the 3.1 schema so we
      // need to do some adhoc workarounds.
      // https://github.com/OAI/OpenAPI-Specification/issues/2689
      // https://github.com/ajv-validator/ajv/issues/1573
      const schemaDynamicRef = schema.$defs.schema;
      delete schemaDynamicRef.$dynamicAnchor;

      schema.$defs.components.properties.schemas.additionalProperties =
        schemaDynamicRef;
      schema.$defs.header.dependentSchemas.schema.properties.schema =
        schemaDynamicRef;
      schema.$defs["media-type"].properties.schema = schemaDynamicRef;
      schema.$defs.parameter.properties.schema = schemaDynamicRef;

      ajv = initializeAjv(false, allErrors, strict, validateFormats);
    } else {
      schema = openapi.v3;
      ajv = initializeAjv(true, allErrors, strict, validateFormats);
    }
  }

  // Validate against the schema
  let isValid = ajv.validate(schema, api);
  if (!isValid) {
    let err = ajv.errors;
    let message = "Swagger schema validation failed.\n" + formatAjvError(err);
    throw ono.syntax(err, { details: err }, message);
  }
}
/**
 * Determines which version of Ajv to load and prepares it for use.
 *
 * @param {bool} draft04
 * @param {bool} allErrors
 * @param {bool} strict
 * @param {bool} validateFormats
 * @returns {Ajv}
 * 
 */
function initializeAjv(
  draft04 = true,
  allErrors = false,
  strict = false,
  validateFormats = false
) {
  const opts = {
    allErrors: allErrors,
    strict: strict,
    validateFormats: validateFormats,
  };

  if (draft04) {
    return new AjvDraft4(opts);
  }

  return new Ajv(opts);
}