code:
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;
var _memorize = _interopRequireDefault(require("./util/memorize"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/** @typedef {import("json-schema").JSONSchema6} JSONSchema6 */
/** @typedef {import("json-schema").JSONSchema7} JSONSchema7 */

/** @typedef {import("./validate").Schema} Schema */
/** @typedef {import("./validate").ValidationErrorConfiguration} ValidationErrorConfiguration */
/** @typedef {import("./validate").PostFormatter} PostFormatter */
/** @typedef {import("./validate").SchemaUtilErrorObject} SchemaUtilErrorObject */
/** @enum {number} */
const SPECIFICITY = {
  type: 1,
  not: 1,
  oneOf: 1,
  anyOf: 1,
  if: 1,
  enum: 1,
  const: 1,
  instanceof: 1,
  required: 2,
  pattern: 2,
  patternRequired: 2,
  format: 2,
  formatMinimum: 2,
  formatMaximum: 2,
  minimum: 2,
  exclusiveMinimum: 2,
  maximum: 2,
  exclusiveMaximum: 2,
  multipleOf: 2,
  uniqueItems: 2,
  contains: 2,
  minLength: 2,
  maxLength: 2,
  minItems: 2,
  maxItems: 2,
  minProperties: 2,
  maxProperties: 2,
  dependencies: 2,
  propertyNames: 2,
  additionalItems: 2,
  additionalProperties: 2,
  absolutePath: 2
};

/**
 * @param {string} value
 * @returns {value is number}
 */
function isNumeric(value) {
  return /^-?\d+$/.test(value);
}

/**
 *
 * @param {Array<SchemaUtilErrorObject>} array
 * @param {(item: SchemaUtilErrorObject) => number} fn
 * @returns {Array<SchemaUtilErrorObject>}
 */
function filterMax(array, fn) {
  const evaluatedMax = array.reduce((max, item) => Math.max(max, fn(item)), 0);
  return array.filter(item => fn(item) === evaluatedMax);
}

/**
 *
 * @param {Array<SchemaUtilErrorObject>} children
 * @returns {Array<SchemaUtilErrorObject>}
 */
function filterChildren(children) {
  let newChildren = children;
  newChildren = filterMax(newChildren,
  /**
   *
   * @param {SchemaUtilErrorObject} error
   * @returns {number}
   */
  error => error.instancePath ? error.instancePath.length : 0);
  newChildren = filterMax(newChildren,
  /**
   * @param {SchemaUtilErrorObject} error
   * @returns {number}
   */
  error => SPECIFICITY[/** @type {keyof typeof SPECIFICITY} */error.keyword] || 2);
  return newChildren;
}

/**
 * Find all children errors
 * @param {Array<SchemaUtilErrorObject>} children
 * @param {Array<string>} schemaPaths
 * @return {number} returns index of first child
 */
function findAllChildren(children, schemaPaths) {
  let i = children.length - 1;
  const predicate =
  /**
   * @param {string} schemaPath
   * @returns {boolean}
   */
  schemaPath => children[i].schemaPath.indexOf(schemaPath) !== 0;
  while (i > -1 && !schemaPaths.every(predicate)) {
    if (children[i].keyword === "anyOf" || children[i].keyword === "oneOf") {
      const refs = extractRefs(children[i]);
      const childrenStart = findAllChildren(children.slice(0, i), refs.concat(children[i].schemaPath));
      i = childrenStart - 1;
    } else {
      i -= 1;
    }
  }
  return i + 1;
}

/**
 * Extracts all refs from schema
 * @param {SchemaUtilErrorObject} error
 * @return {Array<string>}
 */
function extractRefs(error) {
  const {
    schema
  } = error;
  if (!Array.isArray(schema)) {
    return [];
  }
  return schema.map(({
    $ref
  }) => $ref).filter(s => s);
}

/**
 * Groups children by their first level parent (assuming that error is root)
 * @param {Array<SchemaUtilErrorObject>} children
 * @return {Array<SchemaUtilErrorObject>}
 */
function groupChildrenByFirstChild(children) {
  const result = [];
  let i = children.length - 1;
  while (i > 0) {
    const child = children[i];
    if (child.keyword === "anyOf" || child.keyword === "oneOf") {
      const refs = extractRefs(child);
      const childrenStart = findAllChildren(children.slice(0, i), refs.concat(child.schemaPath));
      if (childrenStart !== i) {
        result.push(Object.assign({}, child, {
          children: children.slice(childrenStart, i)
        }));
        i = childrenStart;
      } else {
        result.push(child);
      }
    } else {
      result.push(child);
    }
    i -= 1;
  }
  if (i === 0) {
    result.push(children[i]);
  }
  return result.reverse();
}

/**
 * @param {string} str
 * @param {string} prefix
 * @returns {string}
 */
function indent(str, prefix) {
  return str.replace(/\n(?!$)/g, `\n${prefix}`);
}

/**
 * @param {Schema} schema
 * @returns {schema is (Schema & {not: Schema})}
 */
function hasNotInSchema(schema) {
  return !!schema.not;
}

/**
 * @param {Schema} schema
 * @return {Schema}
 */
function findFirstTypedSchema(schema) {
  if (hasNotInSchema(schema)) {
    return findFirstTypedSchema(schema.not);
  }
  return schema;
}

/**
 * @param {Schema} schema
 * @return {boolean}
 */
function canApplyNot(schema) {
  const typedSchema = findFirstTypedSchema(schema);
  return likeNumber(typedSchema) || likeInteger(typedSchema) || likeString(typedSchema) || likeNull(typedSchema) || likeBoolean(typedSchema);
}

/**
 * @param {any} maybeObj
 * @returns {boolean}
 */
function isObject(maybeObj) {
  return typeof maybeObj === "object" && maybeObj !== null;
}

/**
 * @param {Schema} schema
 * @returns {boolean}
 */
function likeNumber(schema) {
  return schema.type === "number" || typeof schema.minimum !== "undefined" || typeof schema.exclusiveMinimum !== "undefined" || typeof schema.maximum !== "undefined" || typeof schema.exclusiveMaximum !== "undefined" || typeof schema.multipleOf !== "undefined";
}

/**
 * @param {Schema} schema
 * @returns {boolean}
 */
function likeInteger(schema) {
  return schema.type === "integer" || typeof schema.minimum !== "undefined" || typeof schema.exclusiveMinimum !== "undefined" || typeof schema.maximum !== "undefined" || typeof schema.exclusiveMaximum !== "undefined" || typeof schema.multipleOf !== "undefined";
}

/**
 * @param {Schema} schema
 * @returns {boolean}
 */
function likeString(schema) {
  return schema.type === "string" || typeof schema.minLength !== "undefined" || typeof schema.maxLength !== "undefined" || typeof schema.pattern !== "undefined" || typeof schema.format !== "undefined" || typeof schema.formatMinimum !== "undefined" || typeof schema.formatMaximum !== "undefined";
}

/**
 * @param {Schema} schema
 * @returns {boolean}
 */
function likeBoolean(schema) {
  return schema.type === "boolean";
}

/**
 * @param {Schema} schema
 * @returns {boolean}
 */
function likeArray(schema) {
  return schema.type === "array" || typeof schema.minItems === "number" || typeof schema.maxItems === "number" || typeof schema.uniqueItems !== "undefined" || typeof schema.items !== "undefined" || typeof schema.additionalItems !== "undefined" || typeof schema.contains !== "undefined";
}

/**
 * @param {Schema & {patternRequired?: Array<string>}} schema
 * @returns {boolean}
 */
function likeObject(schema) {
  return schema.type === "object" || typeof schema.minProperties !== "undefined" || typeof schema.maxProperties !== "undefined" || typeof schema.required !== "undefined" || typeof schema.properties !== "undefined" || typeof schema.patternProperties !== "undefined" || typeof schema.additionalProperties !== "undefined" || typeof schema.dependencies !== "undefined" || typeof schema.propertyNames !== "undefined" || typeof schema.patternRequired !== "undefined";
}

/**
 * @param {Schema} schema
 * @returns {boolean}
 */
function likeNull(schema) {
  return schema.type === "null";
}

/**
 * @param {string} type
 * @returns {string}
 */
function getArticle(type) {
  if (/^[aeiou]/i.test(type)) {
    return "an";
  }
  return "a";
}

/**
 * @param {Schema=} schema
 * @returns {string}
 */
function getSchemaNonTypes(schema) {
  if (!schema) {
    return "";
  }
  if (!schema.type) {
    if (likeNumber(schema) || likeInteger(schema)) {
      return " | should be any non-number";
    }
    if (likeString(schema)) {
      return " | should be any non-string";
    }
    if (likeArray(schema)) {
      return " | should be any non-array";
    }
    if (likeObject(schema)) {
      return " | should be any non-object";
    }
  }
  return "";
}

/**
 * @param {Array<string>} hints
 * @returns {string}
 */
function formatHints(hints) {
  return hints.length > 0 ? `(${hints.join(", ")})` : "";
}
const getUtilHints = (0, _memorize.default)(() =>
// eslint-disable-next-line global-require
require("./util/hints"));

/**
 * @param {Schema} schema
 * @param {boolean} logic
 * @returns {string[]}
 */
function getHints(schema, logic) {
  if (likeNumber(schema) || likeInteger(schema)) {
    const util = getUtilHints();
    return util.numberHints(schema, logic);
  } else if (likeString(schema)) {
    const util = getUtilHints();
    return util.stringHints(schema, logic);
  }
  return [];
}
class ValidationError extends Error {
  /**
   * @param {Array<SchemaUtilErrorObject>} errors
   * @param {Schema} schema
   * @param {ValidationErrorConfiguration} configuration
   */
  constructor(errors, schema, configuration = {}) {
    super();

    /** @type {string} */
    this.name = "ValidationError";
    /** @type {Array<SchemaUtilErrorObject>} */
    this.errors = errors;
    /** @type {Schema} */
    this.schema = schema;
    let headerNameFromSchema;
    let baseDataPathFromSchema;
    if (schema.title && (!configuration.name || !configuration.baseDataPath)) {
      const splittedTitleFromSchema = schema.title.match(/^(.+) (.+)$/);
      if (splittedTitleFromSchema) {
        if (!configuration.name) {
          [, headerNameFromSchema] = splittedTitleFromSchema;
        }
        if (!configuration.baseDataPath) {
          [,, baseDataPathFromSchema] = splittedTitleFromSchema;
        }
      }
    }

    /** @type {string} */
    this.headerName = configuration.name || headerNameFromSchema || "Object";
    /** @type {string} */
    this.baseDataPath = configuration.baseDataPath || baseDataPathFromSchema || "configuration";

    /** @type {PostFormatter | null} */
    this.postFormatter = configuration.postFormatter || null;
    const header = `Invalid ${this.baseDataPath} object. ${this.headerName} has been initialized using ${getArticle(this.baseDataPath)} ${this.baseDataPath} object that does not match the API schema.\n`;

    /** @type {string} */
    this.message = `${header}${this.formatValidationErrors(errors)}`;
    Error.captureStackTrace(this, this.constructor);
  }

  /**
   * @param {string} path
   * @returns {Schema}
   */
  getSchemaPart(path) {
    const newPath = path.split("/");
    let schemaPart = this.schema;
    for (let i = 1; i < newPath.length; i++) {
      const inner = schemaPart[/** @type {keyof Schema} */newPath[i]];
      if (!inner) {
        break;
      }
      schemaPart = inner;
    }
    return schemaPart;
  }

  /**
   * @param {Schema} schema
   * @param {boolean} logic
   * @param {Array<Object>} prevSchemas
   * @returns {string}
   */
  formatSchema(schema, logic = true, prevSchemas = []) {
    let newLogic = logic;
    const formatInnerSchema =
    /**
     *
     * @param {Object} innerSchema
     * @param {boolean=} addSelf
     * @returns {string}
     */
    (innerSchema, addSelf) => {
      if (!addSelf) {
        return this.formatSchema(innerSchema, newLogic, prevSchemas);
      }
      if (prevSchemas.includes(innerSchema)) {
        return "(recursive)";
      }
      return this.formatSchema(innerSchema, newLogic, prevSchemas.concat(schema));
    };
    if (hasNotInSchema(schema) && !likeObject(schema)) {
      if (canApplyNot(schema.not)) {
        newLogic = !logic;
        return formatInnerSchema(schema.not);
      }
      const needApplyLogicHere = !schema.not.not;
      const prefix = logic ? "" : "non ";
      newLogic = !logic;
      return needApplyLogicHere ? prefix + formatInnerSchema(schema.not) : formatInnerSchema(schema.not);
    }
    if ( /** @type {Schema & {instanceof: string | Array<string>}} */schema.instanceof) {
      const {
        instanceof: value
      } = /** @type {Schema & {instanceof: string | Array<string>}} */schema;
      const values = !Array.isArray(value) ? [value] : value;
      return values.map(
      /**
       * @param {string} item
       * @returns {string}
       */
      item => item === "Function" ? "function" : item).join(" | ");
    }
    if (schema.enum) {
      const enumValues = /** @type {Array<any>} */schema.enum.map(item => {
        if (item === null && schema.undefinedAsNull) {
          return `${JSON.stringify(item)} | undefined`;
        }
        return JSON.stringify(item);
      }).join(" | ");
      return `${enumValues}`;
    }
    if (typeof schema.const !== "undefined") {
      return JSON.stringify(schema.const);
    }
    if (schema.oneOf) {
      return (/** @type {Array<Schema>} */schema.oneOf.map(item => formatInnerSchema(item, true)).join(" | ")
      );
    }
    if (schema.anyOf) {
      return (/** @type {Array<Schema>} */schema.anyOf.map(item => formatInnerSchema(item, true)).join(" | ")
      );
    }
    if (schema.allOf) {
      return (/** @type {Array<Schema>} */schema.allOf.map(item => formatInnerSchema(item, true)).join(" & ")
      );
    }
    if ( /** @type {JSONSchema7} */schema.if) {
      const {
        if: ifValue,
        then: thenValue,
        else: elseValue
      } = /** @type {JSONSchema7} */schema;
      return `${ifValue ? `if ${formatInnerSchema(ifValue)}` : ""}${thenValue ? ` then ${formatInnerSchema(thenValue)}` : ""}${elseValue ? ` else ${formatInnerSchema(elseValue)}` : ""}`;
    }
    if (schema.$ref) {
      return formatInnerSchema(this.getSchemaPart(schema.$ref), true);
    }
    if (likeNumber(schema) || likeInteger(schema)) {
      const [type, ...hints] = getHints(schema, logic);
      const str = `${type}${hints.length > 0 ? ` ${formatHints(hints)}` : ""}`;
      return logic ? str : hints.length > 0 ? `non-${type} | ${str}` : `non-${type}`;
    }
    if (likeString(schema)) {
      const [type, ...hints] = getHints(schema, logic);
      const str = `${type}${hints.length > 0 ? ` ${formatHints(hints)}` : ""}`;
      return logic ? str : str === "string" ? "non-string" : `non-string | ${str}`;
    }
    if (likeBoolean(schema)) {
      return `${logic ? "" : "non-"}boolean`;
    }
    if (likeArray(schema)) {
      // not logic already applied in formatValidationError
      newLogic = true;
      const hints = [];
      if (typeof schema.minItems === "number") {
        hints.push(`should not have fewer than ${schema.minItems} item${schema.minItems > 1 ? "s" : ""}`);
      }
      if (typeof schema.maxItems === "number") {
        hints.push(`should not have more than ${schema.maxItems} item${schema.maxItems > 1 ? "s" : ""}`);
      }
      if (schema.uniqueItems) {
        hints.push("should not have duplicate items");
      }
      const hasAdditionalItems = typeof schema.additionalItems === "undefined" || Boolean(schema.additionalItems);
      let items = "";
      if (schema.items) {
        if (Array.isArray(schema.items) && schema.items.length > 0) {
          items = `${
          /** @type {Array<Schema>} */schema.items.map(item => formatInnerSchema(item)).join(", ")}`;
          if (hasAdditionalItems) {
            if (schema.additionalItems && isObject(schema.additionalItems) && Object.keys(schema.additionalItems).length > 0) {
              hints.push(`additional items should be ${formatInnerSchema(schema.additionalItems)}`);
            }
          }
        } else if (schema.items && Object.keys(schema.items).length > 0) {
          // "additionalItems" is ignored
          items = `${formatInnerSchema(schema.items)}`;
        } else {
          // Fallback for empty `items` value
          items = "any";
        }
      } else {
        // "additionalItems" is ignored
        items = "any";
      }
      if (schema.contains && Object.keys(schema.contains).length > 0) {
        hints.push(`should contains at least one ${this.formatSchema(schema.contains)} item`);
      }
      return `[${items}${hasAdditionalItems ? ", ..." : ""}]${hints.length > 0 ? ` (${hints.join(", ")})` : ""}`;
    }
    if (likeObject(schema)) {
      // not logic already applied in formatValidationError
      newLogic = true;
      const hints = [];
      if (typeof schema.minProperties === "number") {
        hints.push(`should not have fewer than ${schema.minProperties} ${schema.minProperties > 1 ? "properties" : "property"}`);
      }
      if (typeof schema.maxProperties === "number") {
        hints.push(`should not have more than ${schema.maxProperties} ${schema.minProperties && schema.minProperties > 1 ? "properties" : "property"}`);
      }
      if (schema.patternProperties && Object.keys(schema.patternProperties).length > 0) {
        const patternProperties = Object.keys(schema.patternProperties);
        hints.push(`additional property names should match pattern${patternProperties.length > 1 ? "s" : ""} ${patternProperties.map(pattern => JSON.stringify(pattern)).join(" | ")}`);
      }
      const properties = schema.properties ? Object.keys(schema.properties) : [];
      /** @type {Array<string>} */
      // @ts-ignore
      const required = schema.required ? schema.required : [];
      const allProperties = [...new Set( /** @type {Array<string>} */[].concat(required).concat(properties))];
      const objectStructure = allProperties.map(property => {
        const isRequired = required.includes(property);

        // Some properties need quotes, maybe we should add check
        // Maybe we should output type of property (`foo: string`), but it is looks very unreadable
        return `${property}${isRequired ? "" : "?"}`;
      }).concat(typeof schema.additionalProperties === "undefined" || Boolean(schema.additionalProperties) ? schema.additionalProperties && isObject(schema.additionalProperties) ? [`<key>: ${formatInnerSchema(schema.additionalProperties)}`] : ["…"] : []).join(", ");
      const {
        dependencies,
        propertyNames,
        patternRequired
      } = /** @type {Schema & {patternRequired?: Array<string>;}} */schema;
      if (dependencies) {
        Object.keys(dependencies).forEach(dependencyName => {
          const dependency = dependencies[dependencyName];
          if (Array.isArray(dependency)) {
            hints.push(`should have ${dependency.length > 1 ? "properties" : "property"} ${dependency.map(dep => `'${dep}'`).join(", ")} when property '${dependencyName}' is present`);
          } else {
            hints.push(`should be valid according to the schema ${formatInnerSchema(dependency)} when property '${dependencyName}' is present`);
          }
        });
      }
      if (propertyNames && Object.keys(propertyNames).length > 0) {
        hints.push(`each property name should match format ${JSON.stringify(schema.propertyNames.format)}`);
      }
      if (patternRequired && patternRequired.length > 0) {
        hints.push(`should have property matching pattern ${patternRequired.map(
        /**
         * @param {string} item
         * @returns {string}
         */
        item => JSON.stringify(item))}`);
      }
      return `object {${objectStructure ? ` ${objectStructure} ` : ""}}${hints.length > 0 ? ` (${hints.join(", ")})` : ""}`;
    }
    if (likeNull(schema)) {
      return `${logic ? "" : "non-"}null`;
    }
    if (Array.isArray(schema.type)) {
      // not logic already applied in formatValidationError
      return `${schema.type.join(" | ")}`;
    }

    // Fallback for unknown keywords
    // not logic already applied in formatValidationError
    /* istanbul ignore next */
    return JSON.stringify(schema, null, 2);
  }

  /**
   * @param {Schema=} schemaPart
   * @param {(boolean | Array<string>)=} additionalPath
   * @param {boolean=} needDot
   * @param {boolean=} logic
   * @returns {string}
   */
  getSchemaPartText(schemaPart, additionalPath, needDot = false, logic = true) {
    if (!schemaPart) {
      return "";
    }
    if (Array.isArray(additionalPath)) {
      for (let i = 0; i < additionalPath.length; i++) {
        /** @type {Schema | undefined} */
        const inner = schemaPart[/** @type {keyof Schema} */additionalPath[i]];
        if (inner) {
          // eslint-disable-next-line no-param-reassign
          schemaPart = inner;
        } else {
          break;
        }
      }
    }
    while (schemaPart.$ref) {
      // eslint-disable-next-line no-param-reassign
      schemaPart = this.getSchemaPart(schemaPart.$ref);
    }
    let schemaText = `${this.formatSchema(schemaPart, logic)}${needDot ? "." : ""}`;
    if (schemaPart.description) {
      schemaText += `\n-> ${schemaPart.description}`;
    }
    if (schemaPart.link) {
      schemaText += `\n-> Read more at ${schemaPart.link}`;
    }
    return schemaText;
  }

  /**
   * @param {Schema=} schemaPart
   * @returns {string}
   */
  getSchemaPartDescription(schemaPart) {
    if (!schemaPart) {
      return "";
    }
    while (schemaPart.$ref) {
      // eslint-disable-next-line no-param-reassign
      schemaPart = this.getSchemaPart(schemaPart.$ref);
    }
    let schemaText = "";
    if (schemaPart.description) {
      schemaText += `\n-> ${schemaPart.description}`;
    }
    if (schemaPart.link) {
      schemaText += `\n-> Read more at ${schemaPart.link}`;
    }
    return schemaText;
  }

  /**
   * @param {SchemaUtilErrorObject} error
   * @returns {string}
   */
  formatValidationError(error) {
    const {
      keyword,
      instancePath: errorInstancePath
    } = error;
    const splittedInstancePath = errorInstancePath.split("/");
    /**
     * @type {Array<string>}
     */
    const defaultValue = [];
    const prettyInstancePath = splittedInstancePath.reduce((acc, val) => {
      if (val.length > 0) {
        if (isNumeric(val)) {
          acc.push(`[${val}]`);
        } else if (/^\[/.test(val)) {
          acc.push(val);
        } else {
          acc.push(`.${val}`);
        }
      }
      return acc;
    }, defaultValue).join("");
    const instancePath = `${this.baseDataPath}${prettyInstancePath}`;

    // const { keyword, instancePath: errorInstancePath } = error;
    // const instancePath = `${this.baseDataPath}${errorInstancePath.replace(/\//g, '.')}`;

    switch (keyword) {
      case "type":
        {
          const {
            parentSchema,
            params
          } = error;
          switch (params.type) {
            case "number":
              return `${instancePath} should be a ${this.getSchemaPartText(parentSchema, false, true)}`;
            case "integer":
              return `${instancePath} should be an ${this.getSchemaPartText(parentSchema, false, true)}`;
            case "string":
              return `${instancePath} should be a ${this.getSchemaPartText(parentSchema, false, true)}`;
            case "boolean":
              return `${instancePath} should be a ${this.getSchemaPartText(parentSchema, false, true)}`;
            case "array":
              return `${instancePath} should be an array:\n${this.getSchemaPartText(parentSchema)}`;
            case "object":
              return `${instancePath} should be an object:\n${this.getSchemaPartText(parentSchema)}`;
            case "null":
              return `${instancePath} should be a ${this.getSchemaPartText(parentSchema, false, true)}`;
            default:
              return `${instancePath} should be:\n${this.getSchemaPartText(parentSchema)}`;
          }
        }
      case "instanceof":
        {
          const {
            parentSchema
          } = error;
          return `${instancePath} should be an instance of ${this.getSchemaPartText(parentSchema, false, true)}`;
        }
      case "pattern":
        {
          const {
            params,
            parentSchema
          } = error;
          const {
            pattern
          } = params;
          return `${instancePath} should match pattern ${JSON.stringify(pattern)}${getSchemaNonTypes(parentSchema)}.${this.getSchemaPartDescription(parentSchema)}`;
        }
      case "format":
        {
          const {
            params,
            parentSchema
          } = error;
          const {
            format
          } = params;
          return `${instancePath} should match format ${JSON.stringify(format)}${getSchemaNonTypes(parentSchema)}.${this.getSchemaPartDescription(parentSchema)}`;
        }
      case "formatMinimum":
      case "formatExclusiveMinimum":
      case "formatMaximum":
      case "formatExclusiveMaximum":
        {
          const {
            params,
            parentSchema
          } = error;
          const {
            comparison,
            limit
          } = params;
          return `${instancePath} should be ${comparison} ${JSON.stringify(limit)}${getSchemaNonTypes(parentSchema)}.${this.getSchemaPartDescription(parentSchema)}`;
        }
      case "minimum":
      case "maximum":
      case "exclusiveMinimum":
      case "exclusiveMaximum":
        {
          const {
            parentSchema,
            params
          } = error;
          const {
            comparison,
            limit
          } = params;
          const [, ...hints] = getHints( /** @type {Schema} */parentSchema, true);
          if (hints.length === 0) {
            hints.push(`should be ${comparison} ${limit}`);
          }
          return `${instancePath} ${hints.join(" ")}${getSchemaNonTypes(parentSchema)}.${this.getSchemaPartDescription(parentSchema)}`;
        }
      case "multipleOf":
        {
          const {
            params,
            parentSchema
          } = error;
          const {
            multipleOf
          } = params;
          return `${instancePath} should be multiple of ${multipleOf}${getSchemaNonTypes(parentSchema)}.${this.getSchemaPartDescription(parentSchema)}`;
        }
      case "patternRequired":
        {
          const {
            params,
            parentSchema
          } = error;
          const {
            missingPattern
          } = params;
          return `${instancePath} should have property matching pattern ${JSON.stringify(missingPattern)}${getSchemaNonTypes(parentSchema)}.${this.getSchemaPartDescription(parentSchema)}`;
        }
      case "minLength":
        {
          const {
            params,
            parentSchema
          } = error;
          const {
            limit
          } = params;
          if (limit === 1) {
            return `${instancePath} should be a non-empty string${getSchemaNonTypes(parentSchema)}.${this.getSchemaPartDescription(parentSchema)}`;
          }
          const length = limit - 1;
          return `${instancePath} should be longer than ${length} character${length > 1 ? "s" : ""}${getSchemaNonTypes(parentSchema)}.${this.getSchemaPartDescription(parentSchema)}`;
        }
      case "minItems":
        {
          const {
            params,
            parentSchema
          } = error;
          const {
            limit
          } = params;
          if (limit === 1) {
            return `${instancePath} should be a non-empty array${getSchemaNonTypes(parentSchema)}.${this.getSchemaPartDescription(parentSchema)}`;
          }
          return `${instancePath} should not have fewer than ${limit} items${getSchemaNonTypes(parentSchema)}.${this.getSchemaPartDescription(parentSchema)}`;
        }
      case "minProperties":
        {
          const {
            params,
            parentSchema
          } = error;
          const {
            limit
          } = params;
          if (limit === 1) {
            return `${instancePath} should be a non-empty object${getSchemaNonTypes(parentSchema)}.${this.getSchemaPartDescription(parentSchema)}`;
          }
          return `${instancePath} should not have fewer than ${limit} properties${getSchemaNonTypes(parentSchema)}.${this.getSchemaPartDescription(parentSchema)}`;
        }
      case "maxLength":
        {
          const {
            params,
            parentSchema
          } = error;
          const {
            limit
          } = params;
          const max = limit + 1;
          return `${instancePath} should be shorter than ${max} character${max > 1 ? "s" : ""}${getSchemaNonTypes(parentSchema)}.${this.getSchemaPartDescription(parentSchema)}`;
        }
      case "maxItems":
        {
          const {
            params,
            parentSchema
          } = error;
          const {
            limit
          } = params;
          return `${instancePath} should not have more than ${limit} items${getSchemaNonTypes(parentSchema)}.${this.getSchemaPartDescription(parentSchema)}`;
        }
      case "maxProperties":
        {
          const {
            params,
            parentSchema
          } = error;
          const {
            limit
          } = params;
          return `${instancePath} should not have more than ${limit} properties${getSchemaNonTypes(parentSchema)}.${this.getSchemaPartDescription(parentSchema)}`;
        }
      case "uniqueItems":
        {
          const {
            params,
            parentSchema
          } = error;
          const {
            i
          } = params;
          return `${instancePath} should not contain the item '${
          /** @type {{ data: Array<any> }} **/error.data[i]}' twice${getSchemaNonTypes(parentSchema)}.${this.getSchemaPartDescription(parentSchema)}`;
        }
      case "additionalItems":
        {
          const {
            params,
            parentSchema
          } = error;
          const {
            limit
          } = params;
          return `${instancePath} should not have more than ${limit} items${getSchemaNonTypes(parentSchema)}. These items are valid:\n${this.getSchemaPartText(parentSchema)}`;
        }
      case "contains":
        {
          const {
            parentSchema
          } = error;
          return `${instancePath} should contains at least one ${this.getSchemaPartText(parentSchema, ["contains"])} item${getSchemaNonTypes(parentSchema)}.`;
        }
      case "required":
        {
          const {
            parentSchema,
            params
          } = error;
          const missingProperty = params.missingProperty.replace(/^\./, "");
          const hasProperty = parentSchema && Boolean( /** @type {Schema} */
          parentSchema.properties && /** @type {Schema} */
          parentSchema.properties[missingProperty]);
          return `${instancePath} misses the property '${missingProperty}'${getSchemaNonTypes(parentSchema)}.${hasProperty ? ` Should be:\n${this.getSchemaPartText(parentSchema, ["properties", missingProperty])}` : this.getSchemaPartDescription(parentSchema)}`;
        }
      case "additionalProperties":
        {
          const {
            params,
            parentSchema
          } = error;
          const {
            additionalProperty
          } = params;
          return `${instancePath} has an unknown property '${additionalProperty}'${getSchemaNonTypes(parentSchema)}. These properties are valid:\n${this.getSchemaPartText(parentSchema)}`;
        }
      case "dependencies":
        {
          const {
            params,
            parentSchema
          } = error;
          const {
            property,
            deps
          } = params;
          const dependencies = deps.split(",").map(
          /**
           * @param {string} dep
           * @returns {string}
           */
          dep => `'${dep.trim()}'`).join(", ");
          return `${instancePath} should have properties ${dependencies} when property '${property}' is present${getSchemaNonTypes(parentSchema)}.${this.getSchemaPartDescription(parentSchema)}`;
        }
      case "propertyNames":
        {
          const {
            params,
            parentSchema,
            schema
          } = error;
          const {
            propertyName
          } = params;
          return `${instancePath} property name '${propertyName}' is invalid${getSchemaNonTypes(parentSchema)}. Property names should be match format ${JSON.stringify(schema.format)}.${this.getSchemaPartDescription(parentSchema)}`;
        }
      case "enum":
        {
          const {
            parentSchema
          } = error;
          if (parentSchema && /** @type {Schema} */
          parentSchema.enum && /** @type {Schema} */
          parentSchema.enum.length === 1) {
            return `${instancePath} should be ${this.getSchemaPartText(parentSchema, false, true)}`;
          }
          return `${instancePath} should be one of these:\n${this.getSchemaPartText(parentSchema)}`;
        }
      case "const":
        {
          const {
            parentSchema
          } = error;
          return `${instancePath} should be equal to constant ${this.getSchemaPartText(parentSchema, false, true)}`;
        }
      case "not":
        {
          const postfix = likeObject( /** @type {Schema} */error.parentSchema) ? `\n${this.getSchemaPartText(error.parentSchema)}` : "";
          const schemaOutput = this.getSchemaPartText(error.schema, false, false, false);
          if (canApplyNot(error.schema)) {
            return `${instancePath} should be any ${schemaOutput}${postfix}.`;
          }
          const {
            schema,
            parentSchema
          } = error;
          return `${instancePath} should not be ${this.getSchemaPartText(schema, false, true)}${parentSchema && likeObject(parentSchema) ? `\n${this.getSchemaPartText(parentSchema)}` : ""}`;
        }
      case "oneOf":
      case "anyOf":
        {
          const {
            parentSchema,
            children
          } = error;
          if (children && children.length > 0) {
            if (error.schema.length === 1) {
              const lastChild = children[children.length - 1];
              const remainingChildren = children.slice(0, children.length - 1);
              return this.formatValidationError(Object.assign({}, lastChild, {
                children: remainingChildren,
                parentSchema: Object.assign({}, parentSchema, lastChild.parentSchema)
              }));
            }
            let filteredChildren = filterChildren(children);
            if (filteredChildren.length === 1) {
              return this.formatValidationError(filteredChildren[0]);
            }
            filteredChildren = groupChildrenByFirstChild(filteredChildren);
            return `${instancePath} should be one of these:\n${this.getSchemaPartText(parentSchema)}\nDetails:\n${filteredChildren.map(
            /**
             * @param {SchemaUtilErrorObject} nestedError
             * @returns {string}
             */
            nestedError => ` * ${indent(this.formatValidationError(nestedError), "   ")}`).join("\n")}`;
          }
          return `${instancePath} should be one of these:\n${this.getSchemaPartText(parentSchema)}`;
        }
      case "if":
        {
          const {
            params,
            parentSchema
          } = error;
          const {
            failingKeyword
          } = params;
          return `${instancePath} should match "${failingKeyword}" schema:\n${this.getSchemaPartText(parentSchema, [failingKeyword])}`;
        }
      case "absolutePath":
        {
          const {
            message,
            parentSchema
          } = error;
          return `${instancePath}: ${message}${this.getSchemaPartDescription(parentSchema)}`;
        }
      /* istanbul ignore next */
      default:
        {
          const {
            message,
            parentSchema
          } = error;
          const ErrorInJSON = JSON.stringify(error, null, 2);

          // For `custom`, `false schema`, `$ref` keywords
          // Fallback for unknown keywords
          return `${instancePath} ${message} (${ErrorInJSON}).\n${this.getSchemaPartText(parentSchema, false)}`;
        }
    }
  }

  /**
   * @param {Array<SchemaUtilErrorObject>} errors
   * @returns {string}
   */
  formatValidationErrors(errors) {
    return errors.map(error => {
      let formattedError = this.formatValidationError(error);
      if (this.postFormatter) {
        formattedError = this.postFormatter(formattedError, error);
      }
      return ` - ${indent(formattedError, "   ")}`;
    }).join("\n");
  }
}
var _default = ValidationError;
exports.default = _default;


code:
"use strict";

const {
  validate,
  ValidationError,
  enableValidation,
  disableValidation,
  needValidate
} = require("./validate");
module.exports = {
  validate,
  ValidationError,
  enableValidation,
  disableValidation,
  needValidate
};

license: mit


code:
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;
/** @typedef {import("ajv").default} Ajv */
/** @typedef {import("ajv").SchemaValidateFunction} SchemaValidateFunction */
/** @typedef {import("ajv").AnySchemaObject} AnySchemaObject */
/** @typedef {import("../validate").SchemaUtilErrorObject} SchemaUtilErrorObject */

/**
 * @param {string} message
 * @param {object} schema
 * @param {string} data
 * @returns {SchemaUtilErrorObject}
 */
function errorMessage(message, schema, data) {
  return {
    // @ts-ignore
    // eslint-disable-next-line no-undefined
    dataPath: undefined,
    // @ts-ignore
    // eslint-disable-next-line no-undefined
    schemaPath: undefined,
    keyword: "absolutePath",
    params: {
      absolutePath: data
    },
    message,
    parentSchema: schema
  };
}

/**
 * @param {boolean} shouldBeAbsolute
 * @param {object} schema
 * @param {string} data
 * @returns {SchemaUtilErrorObject}
 */
function getErrorFor(shouldBeAbsolute, schema, data) {
  const message = shouldBeAbsolute ? `The provided value ${JSON.stringify(data)} is not an absolute path!` : `A relative path is expected. However, the provided value ${JSON.stringify(data)} is an absolute path!`;
  return errorMessage(message, schema, data);
}

/**
 *
 * @param {Ajv} ajv
 * @returns {Ajv}
 */
function addAbsolutePathKeyword(ajv) {
  ajv.addKeyword({
    keyword: "absolutePath",
    type: "string",
    errors: true,
    /**
     * @param {boolean} schema
     * @param {AnySchemaObject} parentSchema
     * @returns {SchemaValidateFunction}
     */
    compile(schema, parentSchema) {
      /** @type {SchemaValidateFunction} */
      const callback = data => {
        let passes = true;
        const isExclamationMarkPresent = data.includes("!");
        if (isExclamationMarkPresent) {
          callback.errors = [errorMessage(`The provided value ${JSON.stringify(data)} contains exclamation mark (!) which is not allowed because it's reserved for loader syntax.`, parentSchema, data)];
          passes = false;
        }

        // ?:[A-Za-z]:\\ - Windows absolute path
        // \\\\ - Windows network absolute path
        // \/ - Unix-like OS absolute path
        const isCorrectAbsolutePath = schema === /^(?:[A-Za-z]:(\\|\/)|\\\\|\/)/.test(data);
        if (!isCorrectAbsolutePath) {
          callback.errors = [getErrorFor(schema, parentSchema, data)];
          passes = false;
        }
        return passes;
      };
      callback.errors = [];
      return callback;
    }
  });
  return ajv;
}
var _default = addAbsolutePathKeyword;
exports.default = _default;


code:
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;
/** @typedef {import("ajv").default} Ajv */
/** @typedef {import("ajv").SchemaValidateFunction} SchemaValidateFunction */
/** @typedef {import("ajv").AnySchemaObject} AnySchemaObject */
/** @typedef {import("ajv").ValidateFunction} ValidateFunction */

/**
 *
 * @param {Ajv} ajv
 * @returns {Ajv}
 */
function addUndefinedAsNullKeyword(ajv) {
  ajv.addKeyword({
    keyword: "undefinedAsNull",
    before: "enum",
    modifying: true,
    /** @type {SchemaValidateFunction} */
    validate(kwVal, data, metadata, dataCxt) {
      if (kwVal && dataCxt && metadata && typeof metadata.enum !== "undefined") {
        const idx = dataCxt.parentDataProperty;
        if (typeof dataCxt.parentData[idx] === "undefined") {
          // eslint-disable-next-line no-param-reassign
          dataCxt.parentData[dataCxt.parentDataProperty] = null;
        }
      }
      return true;
    }
  });
  return ajv;
}
var _default = addUndefinedAsNullKeyword;
exports.default = _default;


code:
"use strict";

/**
 * @typedef {[number, boolean]} RangeValue
 */

/**
 * @callback RangeValueCallback
 * @param {RangeValue} rangeValue
 * @returns {boolean}
 */

class Range {
  /**
   * @param {"left" | "right"} side
   * @param {boolean} exclusive
   * @returns {">" | ">=" | "<" | "<="}
   */
  static getOperator(side, exclusive) {
    if (side === "left") {
      return exclusive ? ">" : ">=";
    }
    return exclusive ? "<" : "<=";
  }

  /**
   * @param {number} value
   * @param {boolean} logic is not logic applied
   * @param {boolean} exclusive is range exclusive
   * @returns {string}
   */
  static formatRight(value, logic, exclusive) {
    if (logic === false) {
      return Range.formatLeft(value, !logic, !exclusive);
    }
    return `should be ${Range.getOperator("right", exclusive)} ${value}`;
  }

  /**
   * @param {number} value
   * @param {boolean} logic is not logic applied
   * @param {boolean} exclusive is range exclusive
   * @returns {string}
   */
  static formatLeft(value, logic, exclusive) {
    if (logic === false) {
      return Range.formatRight(value, !logic, !exclusive);
    }
    return `should be ${Range.getOperator("left", exclusive)} ${value}`;
  }

  /**
   * @param {number} start left side value
   * @param {number} end right side value
   * @param {boolean} startExclusive is range exclusive from left side
   * @param {boolean} endExclusive is range exclusive from right side
   * @param {boolean} logic is not logic applied
   * @returns {string}
   */
  static formatRange(start, end, startExclusive, endExclusive, logic) {
    let result = "should be";
    result += ` ${Range.getOperator(logic ? "left" : "right", logic ? startExclusive : !startExclusive)} ${start} `;
    result += logic ? "and" : "or";
    result += ` ${Range.getOperator(logic ? "right" : "left", logic ? endExclusive : !endExclusive)} ${end}`;
    return result;
  }

  /**
   * @param {Array<RangeValue>} values
   * @param {boolean} logic is not logic applied
   * @return {RangeValue} computed value and it's exclusive flag
   */
  static getRangeValue(values, logic) {
    let minMax = logic ? Infinity : -Infinity;
    let j = -1;
    const predicate = logic ? /** @type {RangeValueCallback} */
    ([value]) => value <= minMax : /** @type {RangeValueCallback} */
    ([value]) => value >= minMax;
    for (let i = 0; i < values.length; i++) {
      if (predicate(values[i])) {
        [minMax] = values[i];
        j = i;
      }
    }
    if (j > -1) {
      return values[j];
    }
    return [Infinity, true];
  }
  constructor() {
    /** @type {Array<RangeValue>} */
    this._left = [];
    /** @type {Array<RangeValue>} */
    this._right = [];
  }

  /**
   * @param {number} value
   * @param {boolean=} exclusive
   */
  left(value, exclusive = false) {
    this._left.push([value, exclusive]);
  }

  /**
   * @param {number} value
   * @param {boolean=} exclusive
   */
  right(value, exclusive = false) {
    this._right.push([value, exclusive]);
  }

  /**
   * @param {boolean} logic is not logic applied
   * @return {string} "smart" range string representation
   */
  format(logic = true) {
    const [start, leftExclusive] = Range.getRangeValue(this._left, logic);
    const [end, rightExclusive] = Range.getRangeValue(this._right, !logic);
    if (!Number.isFinite(start) && !Number.isFinite(end)) {
      return "";
    }
    const realStart = leftExclusive ? start + 1 : start;
    const realEnd = rightExclusive ? end - 1 : end;

    // e.g. 5 < x < 7, 5 < x <= 6, 6 <= x <= 6
    if (realStart === realEnd) {
      return `should be ${logic ? "" : "!"}= ${realStart}`;
    }

    // e.g. 4 < x < ∞
    if (Number.isFinite(start) && !Number.isFinite(end)) {
      return Range.formatLeft(start, logic, leftExclusive);
    }

    // e.g. ∞ < x < 4
    if (!Number.isFinite(start) && Number.isFinite(end)) {
      return Range.formatRight(end, logic, rightExclusive);
    }
    return Range.formatRange(start, end, leftExclusive, rightExclusive, logic);
  }
}
module.exports = Range;


code:
"use strict";

const Range = require("./Range");

/** @typedef {import("../validate").Schema} Schema */

/**
 * @param {Schema} schema
 * @param {boolean} logic
 * @return {string[]}
 */
module.exports.stringHints = function stringHints(schema, logic) {
  const hints = [];
  let type = "string";
  const currentSchema = {
    ...schema
  };
  if (!logic) {
    const tmpLength = currentSchema.minLength;
    const tmpFormat = currentSchema.formatMinimum;
    currentSchema.minLength = currentSchema.maxLength;
    currentSchema.maxLength = tmpLength;
    currentSchema.formatMinimum = currentSchema.formatMaximum;
    currentSchema.formatMaximum = tmpFormat;
  }
  if (typeof currentSchema.minLength === "number") {
    if (currentSchema.minLength === 1) {
      type = "non-empty string";
    } else {
      const length = Math.max(currentSchema.minLength - 1, 0);
      hints.push(`should be longer than ${length} character${length > 1 ? "s" : ""}`);
    }
  }
  if (typeof currentSchema.maxLength === "number") {
    if (currentSchema.maxLength === 0) {
      type = "empty string";
    } else {
      const length = currentSchema.maxLength + 1;
      hints.push(`should be shorter than ${length} character${length > 1 ? "s" : ""}`);
    }
  }
  if (currentSchema.pattern) {
    hints.push(`should${logic ? "" : " not"} match pattern ${JSON.stringify(currentSchema.pattern)}`);
  }
  if (currentSchema.format) {
    hints.push(`should${logic ? "" : " not"} match format ${JSON.stringify(currentSchema.format)}`);
  }
  if (currentSchema.formatMinimum) {
    hints.push(`should be ${currentSchema.formatExclusiveMinimum ? ">" : ">="} ${JSON.stringify(currentSchema.formatMinimum)}`);
  }
  if (currentSchema.formatMaximum) {
    hints.push(`should be ${currentSchema.formatExclusiveMaximum ? "<" : "<="} ${JSON.stringify(currentSchema.formatMaximum)}`);
  }
  return [type].concat(hints);
};

/**
 * @param {Schema} schema
 * @param {boolean} logic
 * @return {string[]}
 */
module.exports.numberHints = function numberHints(schema, logic) {
  const hints = [schema.type === "integer" ? "integer" : "number"];
  const range = new Range();
  if (typeof schema.minimum === "number") {
    range.left(schema.minimum);
  }
  if (typeof schema.exclusiveMinimum === "number") {
    range.left(schema.exclusiveMinimum, true);
  }
  if (typeof schema.maximum === "number") {
    range.right(schema.maximum);
  }
  if (typeof schema.exclusiveMaximum === "number") {
    range.right(schema.exclusiveMaximum, true);
  }
  const rangeFormat = range.format(logic);
  if (rangeFormat) {
    hints.push(rangeFormat);
  }
  if (typeof schema.multipleOf === "number") {
    hints.push(`should${logic ? "" : " not"} be multiple of ${schema.multipleOf}`);
  }
  return hints;
};


code:
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;
/**
 * @template T
 * @param fn {(function(): any) | undefined}
 * @returns {function(): T}
 */
const memoize = fn => {
  let cache = false;
  /** @type {T} */
  let result;
  return () => {
    if (cache) {
      return result;
    }
    result = /** @type {function(): any} */fn();
    cache = true;
    // Allow to clean up memory for fn
    // and all dependent resources
    // eslint-disable-next-line no-undefined, no-param-reassign
    fn = undefined;
    return result;
  };
};
var _default = memoize;
exports.default = _default;


code:
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
Object.defineProperty(exports, "ValidationError", {
  enumerable: true,
  get: function () {
    return _ValidationError.default;
  }
});
exports.disableValidation = disableValidation;
exports.enableValidation = enableValidation;
exports.needValidate = needValidate;
exports.validate = validate;
var _ValidationError = _interopRequireDefault(require("./ValidationError"));
var _memorize = _interopRequireDefault(require("./util/memorize"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const getAjv = (0, _memorize.default)(() => {
  // Use CommonJS require for ajv libs so TypeScript consumers aren't locked into esModuleInterop (see #110).
  // eslint-disable-next-line global-require
  const Ajv = require("ajv").default;
  // eslint-disable-next-line global-require
  const ajvKeywords = require("ajv-keywords").default;
  // eslint-disable-next-line global-require
  const addFormats = require("ajv-formats").default;

  /**
   * @type {Ajv}
   */
  const ajv = new Ajv({
    strict: false,
    allErrors: true,
    verbose: true,
    $data: true
  });
  ajvKeywords(ajv, ["instanceof", "patternRequired"]);
  addFormats(ajv, {
    keywords: true
  });

  // Custom keywords
  // eslint-disable-next-line global-require
  const addAbsolutePathKeyword = require("./keywords/absolutePath").default;
  addAbsolutePathKeyword(ajv);
  const addUndefinedAsNullKeyword =
  // eslint-disable-next-line global-require
  require("./keywords/undefinedAsNull").default;
  addUndefinedAsNullKeyword(ajv);
  return ajv;
});

/** @typedef {import("json-schema").JSONSchema4} JSONSchema4 */
/** @typedef {import("json-schema").JSONSchema6} JSONSchema6 */
/** @typedef {import("json-schema").JSONSchema7} JSONSchema7 */
/** @typedef {import("ajv").ErrorObject} ErrorObject */

/**
 * @typedef {Object} Extend
 * @property {string=} formatMinimum
 * @property {string=} formatMaximum
 * @property {string=} formatExclusiveMinimum
 * @property {string=} formatExclusiveMaximum
 * @property {string=} link
 * @property {boolean=} undefinedAsNull
 */

/** @typedef {(JSONSchema4 | JSONSchema6 | JSONSchema7) & Extend} Schema */

/** @typedef {ErrorObject & { children?: Array<ErrorObject> }} SchemaUtilErrorObject */

/**
 * @callback PostFormatter
 * @param {string} formattedError
 * @param {SchemaUtilErrorObject} error
 * @returns {string}
 */

/**
 * @typedef {Object} ValidationErrorConfiguration
 * @property {string=} name
 * @property {string=} baseDataPath
 * @property {PostFormatter=} postFormatter
 */

/**
 * @param {SchemaUtilErrorObject} error
 * @param {number} idx
 * @returns {SchemaUtilErrorObject}
 */
function applyPrefix(error, idx) {
  // eslint-disable-next-line no-param-reassign
  error.instancePath = `[${idx}]${error.instancePath}`;
  if (error.children) {
    error.children.forEach(err => applyPrefix(err, idx));
  }
  return error;
}
let skipValidation = false;

// We use `process.env.SKIP_VALIDATION` because you can have multiple `schema-utils` with different version,
// so we want to disable it globally, `process.env` doesn't supported by browsers, so we have the local `skipValidation` variables

// Enable validation
function enableValidation() {
  skipValidation = false;

  // Disable validation for any versions
  if (process && process.env) {
    process.env.SKIP_VALIDATION = "n";
  }
}

// Disable validation
function disableValidation() {
  skipValidation = true;
  if (process && process.env) {
    process.env.SKIP_VALIDATION = "y";
  }
}

// Check if we need to confirm
function needValidate() {
  if (skipValidation) {
    return false;
  }
  if (process && process.env && process.env.SKIP_VALIDATION) {
    const value = process.env.SKIP_VALIDATION.trim();
    if (/^(?:y|yes|true|1|on)$/i.test(value)) {
      return false;
    }
    if (/^(?:n|no|false|0|off)$/i.test(value)) {
      return true;
    }
  }
  return true;
}

/**
 * @param {Schema} schema
 * @param {Array<object> | object} options
 * @param {ValidationErrorConfiguration=} configuration
 * @returns {void}
 */
function validate(schema, options, configuration) {
  if (!needValidate()) {
    return;
  }
  let errors = [];
  if (Array.isArray(options)) {
    for (let i = 0; i <= options.length - 1; i++) {
      errors.push(...validateObject(schema, options[i]).map(err => applyPrefix(err, i)));
    }
  } else {
    errors = validateObject(schema, options);
  }
  if (errors.length > 0) {
    throw new _ValidationError.default(errors, schema, configuration);
  }
}

/**
 * @param {Schema} schema
 * @param {Array<object> | object} options
 * @returns {Array<SchemaUtilErrorObject>}
 */
function validateObject(schema, options) {
  // Not need to cache, because `ajv@8` has built-in cache
  const compiledSchema = getAjv().compile(schema);
  const valid = compiledSchema(options);
  if (valid) return [];
  return compiledSchema.errors ? filterErrors(compiledSchema.errors) : [];
}

/**
 * @param {Array<ErrorObject>} errors
 * @returns {Array<SchemaUtilErrorObject>}
 */
function filterErrors(errors) {
  /** @type {Array<SchemaUtilErrorObject>} */
  let newErrors = [];
  for (const error of /** @type {Array<SchemaUtilErrorObject>} */errors) {
    const {
      instancePath
    } = error;
    /** @type {Array<SchemaUtilErrorObject>} */
    let children = [];
    newErrors = newErrors.filter(oldError => {
      if (oldError.instancePath.includes(instancePath)) {
        if (oldError.children) {
          children = children.concat(oldError.children.slice(0));
        }

        // eslint-disable-next-line no-undefined, no-param-reassign
        oldError.children = undefined;
        children.push(oldError);
        return false;
      }
      return true;
    });
    if (children.length) {
      error.children = children;
    }
    newErrors.push(error);
  }
  return newErrors;
}


schema-utils

description: webpack Validation Utils

license: MIT

repository: webpack/schema-utils

type: opencollective

start: npm run build -- -w

clean: del-cli dist declarations

prebuild: npm run clean

build:types: tsc --declaration --emitDeclarationOnly --outDir declarations && prettier "declarations/**/*.ts" --write

build:code: cross-env NODE_ENV=production babel src -d dist --copy-files

build: npm-run-all -p "build:**"

commitlint: commitlint --from=master

security: npm audit --production

lint:js: eslint --cache .

lint:types: tsc --pretty --noEmit

lint: npm-run-all lint:js lint:types fmt:check

fmt: npm run fmt:check -- --write

fix:js: npm run lint:js -- --fix

fix: npm-run-all fix:js fmt

test:only: cross-env NODE_ENV=test jest

test:watch: npm run test:only -- --watch

test:coverage: npm run test:only -- --collectCoverageFrom="src/**/*.js" --coverage

pretest: npm run lint

test: npm run test:coverage

prepare: npm run build && husky install

release: standard-version

files: dist declarations


code:
/* eslint-env browser */
'use strict';

function getChromeVersion() {
	const matches = /(Chrome|Chromium)\/(?<chromeVersion>\d+)\./.exec(navigator.userAgent);

	if (!matches) {
		return;
	}

	return Number.parseInt(matches.groups.chromeVersion, 10);
}

const colorSupport = getChromeVersion() >= 69 ? {
	level: 1,
	hasBasic: true,
	has256: false,
	has16m: false
} : false;

module.exports = {
	stdout: colorSupport,
	stderr: colorSupport
};


code:
'use strict';
const os = require('os');
const tty = require('tty');
const hasFlag = require('has-flag');

const {env} = process;

let flagForceColor;
if (hasFlag('no-color') ||
	hasFlag('no-colors') ||
	hasFlag('color=false') ||
	hasFlag('color=never')) {
	flagForceColor = 0;
} else if (hasFlag('color') ||
	hasFlag('colors') ||
	hasFlag('color=true') ||
	hasFlag('color=always')) {
	flagForceColor = 1;
}

function envForceColor() {
	if ('FORCE_COLOR' in env) {
		if (env.FORCE_COLOR === 'true') {
			return 1;
		}

		if (env.FORCE_COLOR === 'false') {
			return 0;
		}

		return env.FORCE_COLOR.length === 0 ? 1 : Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3);
	}
}

function translateLevel(level) {
	if (level === 0) {
		return false;
	}

	return {
		level,
		hasBasic: true,
		has256: level >= 2,
		has16m: level >= 3
	};
}

function supportsColor(haveStream, {streamIsTTY, sniffFlags = true} = {}) {
	const noFlagForceColor = envForceColor();
	if (noFlagForceColor !== undefined) {
		flagForceColor = noFlagForceColor;
	}

	const forceColor = sniffFlags ? flagForceColor : noFlagForceColor;

	if (forceColor === 0) {
		return 0;
	}

	if (sniffFlags) {
		if (hasFlag('color=16m') ||
			hasFlag('color=full') ||
			hasFlag('color=truecolor')) {
			return 3;
		}

		if (hasFlag('color=256')) {
			return 2;
		}
	}

	if (haveStream && !streamIsTTY && forceColor === undefined) {
		return 0;
	}

	const min = forceColor || 0;

	if (env.TERM === 'dumb') {
		return min;
	}

	if (process.platform === 'win32') {
		// Windows 10 build 10586 is the first Windows release that supports 256 colors.
		// Windows 10 build 14931 is the first release that supports 16m/TrueColor.
		const osRelease = os.release().split('.');
		if (
			Number(osRelease[0]) >= 10 &&
			Number(osRelease[2]) >= 10586
		) {
			return Number(osRelease[2]) >= 14931 ? 3 : 2;
		}

		return 1;
	}

	if ('CI' in env) {
		if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI', 'GITHUB_ACTIONS', 'BUILDKITE', 'DRONE'].some(sign => sign in env) || env.CI_NAME === 'codeship') {
			return 1;
		}

		return min;
	}

	if ('TEAMCITY_VERSION' in env) {
		return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
	}

	if (env.COLORTERM === 'truecolor') {
		return 3;
	}

	if ('TERM_PROGRAM' in env) {
		const version = Number.parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10);

		switch (env.TERM_PROGRAM) {
			case 'iTerm.app':
				return version >= 3 ? 3 : 2;
			case 'Apple_Terminal':
				return 2;
			// No default
		}
	}

	if (/-256(color)?$/i.test(env.TERM)) {
		return 2;
	}

	if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {
		return 1;
	}

	if ('COLORTERM' in env) {
		return 1;
	}

	return min;
}

function getSupportLevel(stream, options = {}) {
	const level = supportsColor(stream, {
		streamIsTTY: stream && stream.isTTY,
		...options
	});

	return translateLevel(level);
}

module.exports = {
	supportsColor: getSupportLevel,
	stdout: getSupportLevel({isTTY: tty.isatty(1)}),
	stderr: getSupportLevel({isTTY: tty.isatty(2)})
};


supports-color

description: Detect whether a terminal supports color

repository: chalk/supports-color

test: xo && ava

keywords: color colour colors terminal console cli ansi styles tty rgb 256 shell xterm command-line support supports capability detect truecolor 16m


code:
# supports-color

> Detect whether a terminal supports color

## Install

```
$ npm install supports-color
```

## Usage

```js
const supportsColor = require('supports-color');

if (supportsColor.stdout) {
	console.log('Terminal stdout supports color');
}

if (supportsColor.stdout.has256) {
	console.log('Terminal stdout supports 256 colors');
}

if (supportsColor.stderr.has16m) {
	console.log('Terminal stderr supports 16 million colors (truecolor)');
}
```

## API

Returns an `Object` with a `stdout` and `stderr` property for testing either streams. Each property is an `Object`, or `false` if color is not supported.

The `stdout`/`stderr` objects specifies a level of support for color through a `.level` property and a corresponding flag:

- `.level = 1` and `.hasBasic = true`: Basic color support (16 colors)
- `.level = 2` and `.has256 = true`: 256 color support
- `.level = 3` and `.has16m = true`: Truecolor support (16 million colors)

### `require('supports-color').supportsColor(stream, options?)`

Additionally, `supports-color` exposes the `.supportsColor()` function that takes an arbitrary write stream (e.g. `process.stdout`) and an optional options object to (re-)evaluate color support for an arbitrary stream.

For example, `require('supports-color').stdout` is the equivalent of `require('supports-color').supportsColor(process.stdout)`.

The options object supports a single boolean property `sniffFlags`. By default it is `true`, which instructs `supportsColor()` to sniff `process.argv` for the multitude of `--color` flags (see _Info_ below). If `false`, then `process.argv` is not considered when determining color support.

## Info

It obeys the `--color` and `--no-color` CLI flags.

For situations where using `--color` is not possible, use the environment variable `FORCE_COLOR=1` (level 1), `FORCE_COLOR=2` (level 2), or `FORCE_COLOR=3` (level 3) to forcefully enable color, or `FORCE_COLOR=0` to forcefully disable. The use of `FORCE_COLOR` overrides all other color support checks.

Explicit 256/Truecolor mode can be enabled using the `--color=256` and `--color=16m` flags, respectively.

## Related

- [supports-color-cli](https://github.com/chalk/supports-color-cli) - CLI for this module
- [chalk](https://github.com/chalk/chalk) - Terminal string styling done right

## Maintainers

- [Sindre Sorhus](https://github.com/sindresorhus)
- [Josh Junon](https://github.com/qix-)

---

		Get professional support for this package with a Tidelift subscription

		Tidelift helps make open source sustainable for maintainers while giving companies
assurances about security, maintenance, and licensing for their dependencies.

---


eslint-webpack-plugin

description: A ESLint plugin for webpack

repository: webpack-contrib/eslint-webpack-plugin

author: Ricardo Gobbo de Souza <ricardogobbosouza@yahoo.com.br>

clean: del-cli dist types

build:types: tsc --declaration --emitDeclarationOnly --outDir types && prettier "types/**/*.ts" --write

security: npm audit

lint:prettier: prettier -w --list-different .

lint: npm-run-all -l -p "lint:**"

test:only: cross-env NODE_ENV=test jest --testTimeout=60000

prepare: npm run build

files: dist types

keywords: eslint lint linter plugin webpack


code:
export = ESLintError;
declare class ESLintError extends Error {
  /**
   * @param {string=} messages
   */
  constructor(messages?: string | undefined);
  stack: string;
}


code:
export type ESLint = import('eslint').ESLint;
export type LintResult = import('eslint').ESLint.LintResult;
export type Options = import('./options').Options;
export type AsyncTask = () => Promise<void>;
export type LintTask = (files: string | string[]) => Promise<LintResult[]>;
export type Linter = {
  threads: number;
  ESLint: ESLint;
  eslint: ESLint;
  lintFiles: LintTask;
  cleanup: AsyncTask;
};
export type Worker = JestWorker & {
  lintFiles: LintTask;
};
/** @typedef {import('eslint').ESLint} ESLint */
/** @typedef {import('eslint').ESLint.LintResult} LintResult */
/** @typedef {import('./options').Options} Options */
/** @typedef {() => Promise<void>} AsyncTask */
/** @typedef {(files: string|string[]) => Promise<LintResult[]>} LintTask */
/** @typedef {{threads: number, ESLint: ESLint, eslint: ESLint, lintFiles: LintTask, cleanup: AsyncTask}} Linter */
/** @typedef {JestWorker & {lintFiles: LintTask}} Worker */
/**
 * @param {Options} options
 * @returns {Linter}
 */
export function loadESLint(options: Options): Linter;
/**
 * @param {string|undefined} key
 * @param {number} poolSize
 * @param {Options} options
 * @returns {Linter}
 */
export function loadESLintThreaded(
  key: string | undefined,
  poolSize: number,
  options: Options
): Linter;
/**
 * @param {string|undefined} key
 * @param {Options} options
 * @returns {Linter}
 */
export function getESLint(
  key: string | undefined,
  { threads, ...options }: Options
): Linter;
import { Worker as JestWorker } from 'jest-worker';


code:
export = ESLintWebpackPlugin;
declare class ESLintWebpackPlugin {
  /**
   * @param {Options} options
   */
  constructor(options?: Options);
  key: string;
  options: import('./options').PluginOptions;
  /**
   * @param {Compiler} compiler
   * @param {Omit<Options, 'resourceQueryExclude'> & {resourceQueryExclude: RegExp[]}} options
   * @param {string[]} wanted
   * @param {string[]} exclude
   */
  run(
    compiler: Compiler,
    options: Omit<Options, 'resourceQueryExclude'> & {
      resourceQueryExclude: RegExp[];
    },
    wanted: string[],
    exclude: string[]
  ): Promise<void>;
  /**
   * @param {Compiler} compiler
   * @returns {void}
   */
  apply(compiler: Compiler): void;
  /**
   *
   * @param {Compiler} compiler
   * @returns {string}
   */
  getContext(compiler: Compiler): string;
}
declare namespace ESLintWebpackPlugin {
  export { Compiler, Options };
}
type Compiler = import('webpack').Compiler;
type Options = import('./options').Options;


code:
export = linter;
/**
 * @param {string|undefined} key
 * @param {Options} options
 * @param {Compilation} compilation
 * @returns {{lint: Linter, report: Reporter, threads: number}}
 */
declare function linter(
  key: string | undefined,
  options: Options,
  compilation: Compilation
): {
  lint: Linter;
  report: Reporter;
  threads: number;
};
declare namespace linter {
  export {
    ESLint,
    Formatter,
    LintResult,
    Compiler,
    Compilation,
    Options,
    FormatterFunction,
    GenerateReport,
    Report,
    Reporter,
    Linter,
    LintResultMap,
  };
}
type Options = import('./options').Options;
type Compilation = import('webpack').Compilation;
type Linter = (files: string | string[]) => void;
type Reporter = () => Promise<Report>;
type ESLint = import('eslint').ESLint;
type Formatter = import('eslint').ESLint.Formatter;
type LintResult = import('eslint').ESLint.LintResult;
type Compiler = import('webpack').Compiler;
type FormatterFunction = import('./options').FormatterFunction;
type GenerateReport = (compilation: Compilation) => Promise<void>;
type Report = {
  errors?: ESLintError;
  warnings?: ESLintError;
  generateReportAsset?: GenerateReport;
};
type LintResultMap = {
  [files: string]: import('eslint').ESLint.LintResult;
};
import ESLintError = require('./ESLintError');


code:
export type ESLintOptions = import('eslint').ESLint.Options;
export type LintResult = import('eslint').ESLint.LintResult;
export type LintResultData = import('eslint').ESLint.LintResultData;
export type FormatterFunction = (
  results: LintResult[],
  data?: LintResultData | undefined
) => string;
export type OutputReport = {
  filePath?: string | undefined;
  formatter?: (string | FormatterFunction) | undefined;
};
export type PluginOptions = {
  context?: string | undefined;
  emitError?: boolean | undefined;
  emitWarning?: boolean | undefined;
  eslintPath?: string | undefined;
  exclude?: (string | string[]) | undefined;
  extensions?: (string | string[]) | undefined;
  failOnError?: boolean | undefined;
  failOnWarning?: boolean | undefined;
  files?: (string | string[]) | undefined;
  fix?: boolean | undefined;
  formatter?: (string | FormatterFunction) | undefined;
  lintDirtyModulesOnly?: boolean | undefined;
  quiet?: boolean | undefined;
  outputReport?: OutputReport | undefined;
  threads?: (number | boolean) | undefined;
  resourceQueryExclude?: (RegExp | RegExp[]) | undefined;
};
export type Options = PluginOptions & ESLintOptions;
/** @typedef {import("eslint").ESLint.Options} ESLintOptions */
/** @typedef {import('eslint').ESLint.LintResult} LintResult */
/** @typedef {import('eslint').ESLint.LintResultData} LintResultData */
/**
 * @callback FormatterFunction
 * @param {LintResult[]} results
 * @param {LintResultData=} data
 * @returns {string}
 */
/**
 * @typedef {Object} OutputReport
 * @property {string=} filePath
 * @property {string|FormatterFunction=} formatter
 */
/**
 * @typedef {Object} PluginOptions
 * @property {string=} context
 * @property {boolean=} emitError
 * @property {boolean=} emitWarning
 * @property {string=} eslintPath
 * @property {string|string[]=} exclude
 * @property {string|string[]=} extensions
 * @property {boolean=} failOnError
 * @property {boolean=} failOnWarning
 * @property {string|string[]=} files
 * @property {boolean=} fix
 * @property {string|FormatterFunction=} formatter
 * @property {boolean=} lintDirtyModulesOnly
 * @property {boolean=} quiet
 * @property {OutputReport=} outputReport
 * @property {number|boolean=} threads
 * @property {RegExp|RegExp[]=} resourceQueryExclude
 */
/** @typedef {PluginOptions & ESLintOptions} Options */
/**
 * @param {Options} pluginOptions
 * @returns {PluginOptions}
 */
export function getOptions(pluginOptions: Options): PluginOptions;
/**
 * @param {Options} loaderOptions
 * @returns {ESLintOptions}
 */
export function getESLintOptions(loaderOptions: Options): ESLintOptions;


code:
/**
 * @template T
 * @param {T} value
 * @return {
   T extends (null | undefined)
     ? []
     : T extends string
       ? [string]
       : T extends readonly unknown[]
         ? T
         : T extends Iterable<infer T>
           ? T[]
           : [T]
 }
 */
export function arrify<T>(
  value: T
): T extends null | undefined
  ? []
  : T extends string
  ? [string]
  : T extends readonly unknown[]
  ? T
  : T extends Iterable<infer T_1>
  ? T_1[]
  : [T];
/**
 * @param {string|string[]} files
 * @param {string} context
 * @returns {string[]}
 */
export function parseFiles(files: string | string[], context: string): string[];
/**
 * @param {string|string[]} patterns
 * @param {string|string[]} extensions
 * @returns {string[]}
 */
export function parseFoldersToGlobs(
  patterns: string | string[],
  extensions?: string | string[]
): string[];
/**
 * @param {string} _ key, but unused
 * @param {any} value
 */
export function jsonStringifyReplacerSortKeys(_: string, value: any): any;


code:
export type setupOptions = {
  /**
   * - import path of eslint
   */
  eslintPath?: string | undefined;
  /**
   * - linter options
   */
  eslintOptions?: ESLintOptions | undefined;
};
export type ESLint = import('eslint').ESLint;
export type ESLintOptions = import('eslint').ESLint.Options;


code:
#!/usr/bin/env node

/**
 * @fileoverview Main CLI that is run via the eslint command.
 * @author Nicholas C. Zakas
 */

/* eslint no-console:off -- CLI */

"use strict";

// must do this initialization *before* other requires in order to work
if (process.argv.includes("--debug")) {
    require("debug").enable("eslint:*,-eslint:code-path,eslintrc:*");
}

//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------

/**
 * Read data from stdin til the end.
 *
 * Note: See
 * - https://github.com/nodejs/node/blob/master/doc/api/process.md#processstdin
 * - https://github.com/nodejs/node/blob/master/doc/api/process.md#a-note-on-process-io
 * - https://lists.gnu.org/archive/html/bug-gnu-emacs/2016-01/msg00419.html
 * - https://github.com/nodejs/node/issues/7439 (historical)
 *
 * On Windows using `fs.readFileSync(STDIN_FILE_DESCRIPTOR, "utf8")` seems
 * to read 4096 bytes before blocking and never drains to read further data.
 *
 * The investigation on the Emacs thread indicates:
 *
 * > Emacs on MS-Windows uses pipes to communicate with subprocesses; a
 * > pipe on Windows has a 4K buffer. So as soon as Emacs writes more than
 * > 4096 bytes to the pipe, the pipe becomes full, and Emacs then waits for
 * > the subprocess to read its end of the pipe, at which time Emacs will
 * > write the rest of the stuff.
 * @returns {Promise<string>} The read text.
 */
function readStdin() {
    return new Promise((resolve, reject) => {
        let content = "";
        let chunk = "";

        process.stdin
            .setEncoding("utf8")
            .on("readable", () => {
                while ((chunk = process.stdin.read()) !== null) {
                    content += chunk;
                }
            })
            .on("end", () => resolve(content))
            .on("error", reject);
    });
}

/**
 * Get the error message of a given value.
 * @param {any} error The value to get.
 * @returns {string} The error message.
 */
function getErrorMessage(error) {

    // Lazy loading because this is used only if an error happened.
    const util = require("util");

    // Foolproof -- third-party module might throw non-object.
    if (typeof error !== "object" || error === null) {
        return String(error);
    }

    // Use templates if `error.messageTemplate` is present.
    if (typeof error.messageTemplate === "string") {
        try {
            const template = require(`../messages/${error.messageTemplate}.js`);

            return template(error.messageData || {});
        } catch {

            // Ignore template error then fallback to use `error.stack`.
        }
    }

    // Use the stacktrace if it's an error object.
    if (typeof error.stack === "string") {
        return error.stack;
    }

    // Otherwise, dump the object.
    return util.format("%o", error);
}

/**
 * Tracks error messages that are shown to the user so we only ever show the
 * same message once.
 * @type {Set<string>}
 */
const displayedErrors = new Set();

/**
 * Tracks whether an unexpected error was caught
 * @type {boolean}
 */
let hadFatalError = false;

/**
 * Catch and report unexpected error.
 * @param {any} error The thrown error object.
 * @returns {void}
 */
function onFatalError(error) {
    process.exitCode = 2;
    hadFatalError = true;

    const { version } = require("../package.json");
    const message = `
Oops! Something went wrong! :(

ESLint: ${version}

${getErrorMessage(error)}`;

    if (!displayedErrors.has(message)) {
        console.error(message);
        displayedErrors.add(message);
    }
}

//------------------------------------------------------------------------------
// Execution
//------------------------------------------------------------------------------

(async function main() {
    process.on("uncaughtException", onFatalError);
    process.on("unhandledRejection", onFatalError);

    // Call the config initializer if `--init` is present.
    if (process.argv.includes("--init")) {

        // `eslint --init` has been moved to `@eslint/create-config`
        console.warn("You can also run this command directly using 'npm init @eslint/config'.");

        const spawn = require("cross-spawn");

        spawn.sync("npm", ["init", "@eslint/config"], { encoding: "utf8", stdio: "inherit" });
        return;
    }

    // Otherwise, call the CLI.
    const exitCode = await require("../lib/cli").execute(
        process.argv,
        process.argv.includes("--stdin") ? await readStdin() : null,
        true
    );

    /*
     * If an uncaught exception or unhandled rejection was detected in the meantime,
     * keep the fatal exit code 2 that is already assigned to `process.exitCode`.
     * Without this condition, exit code 2 (unsuccessful execution) could be overwritten with
     * 1 (successful execution, lint problems found) or even 0 (successful execution, no lint problems found).
     * This ensures that unexpected errors that seemingly don't affect the success
     * of the execution will still cause a non-zero exit code, as it's a common
     * practice and the default behavior of Node.js to exit with non-zero
     * in case of an uncaught exception or unhandled rejection.
     *
     * Otherwise, assign the exit code returned from CLI.
     */
    if (!hadFatalError) {
        process.exitCode = exitCode;
    }
}()).catch(onFatalError);


code:
/*
 * STOP!!! DO NOT MODIFY.
 *
 * This file is part of the ongoing work to move the eslintrc-style config
 * system into the @eslint/eslintrc package. This file needs to remain
 * unchanged in order for this work to proceed.
 *
 * If you think you need to change this file, please contact @nzakas first.
 *
 * Thanks in advance for your cooperation.
 */

/**
 * @fileoverview Defines a schema for configs.
 * @author Sylvan Mably
 */

"use strict";

const baseConfigProperties = {
    $schema: { type: "string" },
    env: { type: "object" },
    extends: { $ref: "#/definitions/stringOrStrings" },
    globals: { type: "object" },
    overrides: {
        type: "array",
        items: { $ref: "#/definitions/overrideConfig" },
        additionalItems: false
    },
    parser: { type: ["string", "null"] },
    parserOptions: { type: "object" },
    plugins: { type: "array" },
    processor: { type: "string" },
    rules: { type: "object" },
    settings: { type: "object" },
    noInlineConfig: { type: "boolean" },
    reportUnusedDisableDirectives: { type: "boolean" },

    ecmaFeatures: { type: "object" } // deprecated; logs a warning when used
};

const configSchema = {
    definitions: {
        stringOrStrings: {
            oneOf: [
                { type: "string" },
                {
                    type: "array",
                    items: { type: "string" },
                    additionalItems: false
                }
            ]
        },
        stringOrStringsRequired: {
            oneOf: [
                { type: "string" },
                {
                    type: "array",
                    items: { type: "string" },
                    additionalItems: false,
                    minItems: 1
                }
            ]
        },

        // Config at top-level.
        objectConfig: {
            type: "object",
            properties: {
                root: { type: "boolean" },
                ignorePatterns: { $ref: "#/definitions/stringOrStrings" },
                ...baseConfigProperties
            },
            additionalProperties: false
        },

        // Config in `overrides`.
        overrideConfig: {
            type: "object",
            properties: {
                excludedFiles: { $ref: "#/definitions/stringOrStrings" },
                files: { $ref: "#/definitions/stringOrStringsRequired" },
                ...baseConfigProperties
            },
            required: ["files"],
            additionalProperties: false
        }
    },

    $ref: "#/definitions/objectConfig"
};

module.exports = configSchema;


code:
/**
 * @fileoverview Default CLIEngineOptions.
 * @author Ian VanSchooten
 */

"use strict";

module.exports = {
    configFile: null,
    baseConfig: false,
    rulePaths: [],
    useEslintrc: true,
    envs: [],
    globals: [],
    extensions: null,
    ignore: true,
    ignorePath: void 0,
    cache: false,

    /*
     * in order to honor the cacheFile option if specified
     * this option should not have a default value otherwise
     * it will always be used
     */
    cacheLocation: "",
    cacheFile: ".eslintcache",
    cacheStrategy: "metadata",
    fix: false,
    allowInlineConfig: true,
    reportUnusedDisableDirectives: void 0,
    globInputPaths: true
};


code:
/**
 * @fileoverview Globals for ecmaVersion/sourceType
 * @author Nicholas C. Zakas
 */

"use strict";

//-----------------------------------------------------------------------------
// Globals
//-----------------------------------------------------------------------------

const commonjs = {
    exports: true,
    global: false,
    module: false,
    require: false
};

const es3 = {
    Array: false,
    Boolean: false,
    constructor: false,
    Date: false,
    decodeURI: false,
    decodeURIComponent: false,
    encodeURI: false,
    encodeURIComponent: false,
    Error: false,
    escape: false,
    eval: false,
    EvalError: false,
    Function: false,
    hasOwnProperty: false,
    Infinity: false,
    isFinite: false,
    isNaN: false,
    isPrototypeOf: false,
    Math: false,
    NaN: false,
    Number: false,
    Object: false,
    parseFloat: false,
    parseInt: false,
    propertyIsEnumerable: false,
    RangeError: false,
    ReferenceError: false,
    RegExp: false,
    String: false,
    SyntaxError: false,
    toLocaleString: false,
    toString: false,
    TypeError: false,
    undefined: false,
    unescape: false,
    URIError: false,
    valueOf: false
};

const es5 = {
    ...es3,
    JSON: false
};

const es2015 = {
    ...es5,
    ArrayBuffer: false,
    DataView: false,
    Float32Array: false,
    Float64Array: false,
    Int16Array: false,
    Int32Array: false,
    Int8Array: false,
    Map: false,
    Promise: false,
    Proxy: false,
    Reflect: false,
    Set: false,
    Symbol: false,
    Uint16Array: false,
    Uint32Array: false,
    Uint8Array: false,
    Uint8ClampedArray: false,
    WeakMap: false,
    WeakSet: false
};

// no new globals in ES2016
const es2016 = {
    ...es2015
};

const es2017 = {
    ...es2016,
    Atomics: false,
    SharedArrayBuffer: false
};

// no new globals in ES2018
const es2018 = {
    ...es2017
};

// no new globals in ES2019
const es2019 = {
    ...es2018
};

const es2020 = {
    ...es2019,
    BigInt: false,
    BigInt64Array: false,
    BigUint64Array: false,
    globalThis: false
};

const es2021 = {
    ...es2020,
    AggregateError: false,
    FinalizationRegistry: false,
    WeakRef: false
};

const es2022 = {
    ...es2021
};

const es2023 = {
    ...es2022
};

const es2024 = {
    ...es2023
};

//-----------------------------------------------------------------------------
// Exports
//-----------------------------------------------------------------------------

module.exports = {
    commonjs,
    es3,
    es5,
    es2015,
    es2016,
    es2017,
    es2018,
    es2019,
    es2020,
    es2021,
    es2022,
    es2023,
    es2024
};


removed: generator-star

removed: global-strict

removed: no-arrow-condition

removed: no-comma-dangle

removed: no-empty-class

removed: no-empty-label

removed: no-extra-strict

removed: no-reserved-keys

removed: no-space-before-semi

removed: no-wrap-func

removed: space-after-function-name

removed: space-after-keywords

removed: space-before-function-parentheses

removed: space-before-keywords

removed: space-in-brackets

removed: space-return-throw-case

removed: space-unary-word-ops

removed: spaced-line-comment


code:
/**
 * @fileoverview Expose out ESLint and CLI to require.
 * @author Ian Christian Myers
 */

"use strict";

//-----------------------------------------------------------------------------
// Requirements
//-----------------------------------------------------------------------------

const { ESLint, FlatESLint } = require("./eslint");
const { shouldUseFlatConfig } = require("./eslint/flat-eslint");
const { Linter } = require("./linter");
const { RuleTester } = require("./rule-tester");
const { SourceCode } = require("./source-code");

//-----------------------------------------------------------------------------
// Functions
//-----------------------------------------------------------------------------

/**
 * Loads the correct ESLint constructor given the options.
 * @param {Object} [options] The options object
 * @param {boolean} [options.useFlatConfig] Whether or not to use a flat config
 * @param {string} [options.cwd] The current working directory
 * @returns {Promise<ESLint|LegacyESLint>} The ESLint constructor
 */
async function loadESLint({ useFlatConfig, cwd = process.cwd() } = {}) {

    /*
     * Note: The v9.x version of this function doesn't have a cwd option
     * because it's not used. It's only used in the v8.x version of this
     * function.
     */

    const shouldESLintUseFlatConfig = typeof useFlatConfig === "boolean"
        ? useFlatConfig
        : await shouldUseFlatConfig({ cwd });

    return shouldESLintUseFlatConfig ? FlatESLint : ESLint;
}

//-----------------------------------------------------------------------------
// Exports
//-----------------------------------------------------------------------------

module.exports = {
    Linter,
    loadESLint,
    ESLint,
    RuleTester,
    SourceCode
};