code:
# Changelog

All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.

## [3.3.0](https://github.com/webpack/schema-utils/compare/v3.2.0...v3.3.0) (2023-06-14)

### Features

* added API to disable and enable validation ([#183](https://github.com/webpack/schema-utils/issues/183)) ([d4d334f](https://github.com/webpack/schema-utils/commit/d4d334f0ba22eb6b6564b1119e8f3ea439e1f2bb))

### Bug Fixes

* **perf:** cache compiled schema ([#182](https://github.com/webpack/schema-utils/issues/182)) ([02aa068](https://github.com/webpack/schema-utils/commit/02aa068df80d99cc576a5ed385f947eb5204c5db))

## [3.2.0](https://github.com/webpack/schema-utils/compare/v3.1.2...v3.2.0) (2023-06-07)

### Features

* implement `undefinedAsNull` keyword for `enum` type ([#176](https://github.com/webpack/schema-utils/issues/176)) ([95826eb](https://github.com/webpack/schema-utils/commit/95826eb9e14bc4b10ab95f962ac2bdca447880a3))

### [3.1.2](https://github.com/webpack/schema-utils/compare/v3.1.1...v3.1.2) (2023-04-15)

### Bug Fixes

* **perf:** reduced initial start time ([#170](https://github.com/webpack/schema-utils/issues/170)) ([8d052e6](https://github.com/webpack/schema-utils/commit/8d052e6764dc9247e7d5b7b1ae8f87ca5047b2b0))

### [3.1.1](https://github.com/webpack/schema-utils/compare/v3.1.0...v3.1.1) (2021-07-19)

### Bug Fixes

* update error message for `integer` ([#136](https://github.com/webpack/schema-utils/issues/136)) ([2daa97e](https://github.com/webpack/schema-utils/commit/2daa97eae87e6790b92711746a6a527b859ac13b))

## [3.1.0](https://github.com/webpack/schema-utils/compare/v3.0.0...v3.1.0) (2021-06-30)

### Features

* added the `link` property in validation error ([589aa59](https://github.com/webpack/schema-utils/commit/589aa5993424a8bc45ec22b67dff55be92c456a9))

### Bug Fixes

* non-empty validation error message ([#116](https://github.com/webpack/schema-utils/issues/116)) ([c51abef](https://github.com/webpack/schema-utils/commit/c51abefa4d4d62e1346b3a105182d36675595077))

## [3.0.0](https://github.com/webpack/schema-utils/compare/v2.7.1...v3.0.0) (2020-10-05)

### ⚠ BREAKING CHANGES

* minimum supported `Node.js` version is `10.13.0`,
* the packages exports was changed, please use `const { validate } = require('schema-utils');`
* the `ValidateError` export was removed in favor the `ValidationError` export, please use `const { ValidationError } = require('schema-utils');`

### [2.7.1](https://github.com/webpack/schema-utils/compare/v2.7.0...v2.7.1) (2020-08-31)

### Bug Fixes

* remove esModuleInterop from tsconfig ([#110](https://github.com/webpack/schema-utils/issues/110)) ([#111](https://github.com/webpack/schema-utils/issues/111)) ([2f40154](https://github.com/webpack/schema-utils/commit/2f40154b91e45b393258ae9dd8f10cc3b8590b7d))

## [2.7.0](https://github.com/webpack/schema-utils/compare/v2.6.6...v2.7.0) (2020-05-29)

### Features

* improve hints ([a36e535](https://github.com/webpack/schema-utils/commit/a36e535faca1b01e27c3bfa3c8bee9227c3f836c))
* smart not case ([#101](https://github.com/webpack/schema-utils/issues/101)) ([698d8b0](https://github.com/webpack/schema-utils/commit/698d8b05462d86aadb217e25a45c7b953a79a52e))

### Bug Fixes

* move @types/json-schema from devDependencies to dependencies ([#97](https://github.com/webpack/schema-utils/issues/97)) ([#98](https://github.com/webpack/schema-utils/issues/98)) ([945e67d](https://github.com/webpack/schema-utils/commit/945e67db5e19baf7ec7df72813b0739dd56f950d))

### [2.6.6](https://github.com/webpack/schema-utils/compare/v2.6.5...v2.6.6) (2020-04-17)

### Bug Fixes

* improve perf

### [2.6.5](https://github.com/webpack/schema-utils/compare/v2.6.4...v2.6.5) (2020-03-11)

### Bug Fixes

* correct dots at end of sentence ([7284beb](https://github.com/webpack/schema-utils/commit/7284bebe00cd570f1bef2c15951a07b9794038e6))

### [2.6.4](https://github.com/webpack/schema-utils/compare/v2.6.3...v2.6.4) (2020-01-17)

### Bug Fixes

* change `initialised` to `initialized` ([#87](https://github.com/webpack/schema-utils/issues/87)) ([70f12d3](https://github.com/webpack/schema-utils/commit/70f12d33a8eaa27249bc9c1a27f886724cf91ea7))

### [2.6.3](https://github.com/webpack/schema-utils/compare/v2.6.2...v2.6.3) (2020-01-17)

### Bug Fixes

* prefer the `baseDataPath` option from arguments ([#86](https://github.com/webpack/schema-utils/issues/86)) ([e236859](https://github.com/webpack/schema-utils/commit/e236859e85b28e35e1294f86fc1ff596a5031cea))

### [2.6.2](https://github.com/webpack/schema-utils/compare/v2.6.1...v2.6.2) (2020-01-14)

### Bug Fixes

* better handle Windows absolute paths ([#85](https://github.com/webpack/schema-utils/issues/85)) ([1fa2930](https://github.com/webpack/schema-utils/commit/1fa2930a161e907b9fc53a7233d605910afdb883))

### [2.6.1](https://github.com/webpack/schema-utils/compare/v2.6.0...v2.6.1) (2019-11-28)

### Bug Fixes

* typescript declarations ([#84](https://github.com/webpack/schema-utils/issues/84)) ([89d55a9](https://github.com/webpack/schema-utils/commit/89d55a9a8edfa6a8ac8b112f226bb3154e260319))

## [2.6.0](https://github.com/webpack/schema-utils/compare/v2.5.0...v2.6.0) (2019-11-27)

### Features

* support configuration via title ([#81](https://github.com/webpack/schema-utils/issues/81)) ([afddc10](https://github.com/webpack/schema-utils/commit/afddc109f6891cd37a9f1835d50862d119a072bf))

### Bug Fixes

* typescript definitions ([#70](https://github.com/webpack/schema-utils/issues/70)) ([f38158d](https://github.com/webpack/schema-utils/commit/f38158d6d040e2c701622778ae8122fb26a4f990))

## [2.5.0](https://github.com/webpack/schema-utils/compare/v2.4.1...v2.5.0) (2019-10-15)

### Bug Fixes

* rework format for maxLength, minLength ([#67](https://github.com/webpack/schema-utils/issues/67)) ([0d12259](https://github.com/webpack/schema-utils/commit/0d12259))
* support all cases with one number in range ([#64](https://github.com/webpack/schema-utils/issues/64)) ([7fc8069](https://github.com/webpack/schema-utils/commit/7fc8069))
* typescript definition and export naming ([#69](https://github.com/webpack/schema-utils/issues/69)) ([a435b79](https://github.com/webpack/schema-utils/commit/a435b79))

### Features

* "smart" numbers range ([62fb107](https://github.com/webpack/schema-utils/commit/62fb107))

### [2.4.1](https://github.com/webpack/schema-utils/compare/v2.4.0...v2.4.1) (2019-09-27)

### Bug Fixes

* publish definitions ([#58](https://github.com/webpack/schema-utils/issues/58)) ([1885faa](https://github.com/webpack/schema-utils/commit/1885faa))

## [2.4.0](https://github.com/webpack/schema-utils/compare/v2.3.0...v2.4.0) (2019-09-26)

### Features

* better errors when the `type` keyword doesn't exist ([0988be2](https://github.com/webpack/schema-utils/commit/0988be2))
* support $data reference ([#56](https://github.com/webpack/schema-utils/issues/56)) ([d2f11d6](https://github.com/webpack/schema-utils/commit/d2f11d6))
* types definitions ([#52](https://github.com/webpack/schema-utils/issues/52)) ([facb431](https://github.com/webpack/schema-utils/commit/facb431))

## [2.3.0](https://github.com/webpack/schema-utils/compare/v2.2.0...v2.3.0) (2019-09-26)

### Features

* support `not` keyword ([#53](https://github.com/webpack/schema-utils/issues/53)) ([765f458](https://github.com/webpack/schema-utils/commit/765f458))

## [2.2.0](https://github.com/webpack/schema-utils/compare/v2.1.0...v2.2.0) (2019-09-02)

### Features

* better error output for `oneOf` and `anyOf` ([#48](https://github.com/webpack/schema-utils/issues/48)) ([#50](https://github.com/webpack/schema-utils/issues/50)) ([332242f](https://github.com/webpack/schema-utils/commit/332242f))

## [2.1.0](https://github.com/webpack-contrib/schema-utils/compare/v2.0.1...v2.1.0) (2019-08-07)

### Bug Fixes

* throw error on sparse arrays ([#47](https://github.com/webpack-contrib/schema-utils/issues/47)) ([b85ac38](https://github.com/webpack-contrib/schema-utils/commit/b85ac38))

### Features

* export `ValidateError` ([#46](https://github.com/webpack-contrib/schema-utils/issues/46)) ([ff781d7](https://github.com/webpack-contrib/schema-utils/commit/ff781d7))

### [2.0.1](https://github.com/webpack-contrib/schema-utils/compare/v2.0.0...v2.0.1) (2019-07-18)

### Bug Fixes

* error message for empty object ([#44](https://github.com/webpack-contrib/schema-utils/issues/44)) ([0b4b4a2](https://github.com/webpack-contrib/schema-utils/commit/0b4b4a2))

### [2.0.0](https://github.com/webpack-contrib/schema-utils/compare/v1.0.0...v2.0.0) (2019-07-17)

### BREAKING CHANGES

* drop support for Node.js < 8.9.0
* drop support `errorMessage`, please use `description` for links.
* api was changed, please look documentation.
* error messages was fully rewritten.

# [1.0.0](https://github.com/webpack-contrib/schema-utils/compare/v0.4.7...v1.0.0) (2018-08-07)

### Features

* **src:** add support for custom error messages ([#33](https://github.com/webpack-contrib/schema-utils/issues/33)) ([1cbe4ef](https://github.com/webpack-contrib/schema-utils/commit/1cbe4ef))

## [0.4.7](https://github.com/webpack-contrib/schema-utils/compare/v0.4.6...v0.4.7) (2018-08-07)

### Bug Fixes

* **src:** `node >= v4.0.0` support ([#32](https://github.com/webpack-contrib/schema-utils/issues/32)) ([cb13dd4](https://github.com/webpack-contrib/schema-utils/commit/cb13dd4))

## [0.4.6](https://github.com/webpack-contrib/schema-utils/compare/v0.4.5...v0.4.6) (2018-08-06)

### Bug Fixes

* **package:** remove lockfile ([#28](https://github.com/webpack-contrib/schema-utils/issues/28)) ([69f1a81](https://github.com/webpack-contrib/schema-utils/commit/69f1a81))
* **package:** remove unnecessary `webpack` dependency ([#26](https://github.com/webpack-contrib/schema-utils/issues/26)) ([532eaa5](https://github.com/webpack-contrib/schema-utils/commit/532eaa5))

## [0.4.5](https://github.com/webpack-contrib/schema-utils/compare/v0.4.4...v0.4.5) (2018-02-13)

### Bug Fixes

* **CHANGELOG:** update broken links ([4483b9f](https://github.com/webpack-contrib/schema-utils/commit/4483b9f))
* **package:** update broken links ([f2494ba](https://github.com/webpack-contrib/schema-utils/commit/f2494ba))

## [0.4.4](https://github.com/webpack-contrib/schema-utils/compare/v0.4.3...v0.4.4) (2018-02-13)

### Bug Fixes

* **package:** update `dependencies` ([#22](https://github.com/webpack-contrib/schema-utils/issues/22)) ([3aecac6](https://github.com/webpack-contrib/schema-utils/commit/3aecac6))

## [0.4.3](https://github.com/webpack-contrib/schema-utils/compare/v0.4.2...v0.4.3) (2017-12-14)

### Bug Fixes

* **validateOptions:** throw `err` instead of `process.exit(1)` ([#17](https://github.com/webpack-contrib/schema-utils/issues/17)) ([c595eda](https://github.com/webpack-contrib/schema-utils/commit/c595eda))
* **ValidationError:** never return `this` in the ctor ([#16](https://github.com/webpack-contrib/schema-utils/issues/16)) ([c723791](https://github.com/webpack-contrib/schema-utils/commit/c723791))

## [0.4.2](https://github.com/webpack-contrib/schema-utils/compare/v0.4.1...v0.4.2) (2017-11-09)

### Bug Fixes

* **validateOptions:** catch `ValidationError` and handle it internally ([#15](https://github.com/webpack-contrib/schema-utils/issues/15)) ([9c5ef5e](https://github.com/webpack-contrib/schema-utils/commit/9c5ef5e))

## [0.4.1](https://github.com/webpack-contrib/schema-utils/compare/v0.4.0...v0.4.1) (2017-11-03)

### Bug Fixes

* **ValidationError:** use `Error.captureStackTrace` for `err.stack` handling ([#14](https://github.com/webpack-contrib/schema-utils/issues/14)) ([a6fb974](https://github.com/webpack-contrib/schema-utils/commit/a6fb974))

# [0.4.0](https://github.com/webpack-contrib/schema-utils/compare/v0.3.0...v0.4.0) (2017-10-28)

### Features

* add support for `typeof`, `instanceof` (`{Function\|RegExp}`) ([#10](https://github.com/webpack-contrib/schema-utils/issues/10)) ([9f01816](https://github.com/webpack-contrib/schema-utils/commit/9f01816))

# [0.3.0](https://github.com/webpack-contrib/schema-utils/compare/v0.2.1...v0.3.0) (2017-04-29)

### Features

* add ValidationError ([#8](https://github.com/webpack-contrib/schema-utils/issues/8)) ([d48f0fb](https://github.com/webpack-contrib/schema-utils/commit/d48f0fb))

## [0.2.1](https://github.com/webpack-contrib/schema-utils/compare/v0.2.0...v0.2.1) (2017-03-13)

### Bug Fixes

* Include .babelrc to `files` ([28f0363](https://github.com/webpack-contrib/schema-utils/commit/28f0363))
* Include source to `files` ([43b0f2f](https://github.com/webpack-contrib/schema-utils/commit/43b0f2f))

# [0.2.0](https://github.com/webpack-contrib/schema-utils/compare/v0.1.0...v0.2.0) (2017-03-12)

# 0.1.0 (2017-03-07)

### Features

* **validations:** add validateOptions module ([ae9b47b](https://github.com/webpack-contrib/schema-utils/commit/ae9b47b))

# Change Log

All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.


code:
[![npm][npm]][npm-url]
[![node][node]][node-url]
[![deps][deps]][deps-url]
[![tests][tests]][tests-url]
[![coverage][cover]][cover-url]
[![chat][chat]][chat-url]
[![size][size]][size-url]

# schema-utils

Package for validate options in loaders and plugins.

## Getting Started

To begin, you'll need to install `schema-utils`:

```console
npm install schema-utils
```

## API

**schema.json**

```json
{
  "type": "object",
  "properties": {
    "option": {
      "type": "boolean"
    }
  },
  "additionalProperties": false
}
```

```js
import schema from "./path/to/schema.json";
import { validate } from "schema-utils";

const options = { option: true };
const configuration = { name: "Loader Name/Plugin Name/Name" };

validate(schema, options, configuration);
```

### `schema`

Type: `String`

JSON schema.

Simple example of schema:

```json
{
  "type": "object",
  "properties": {
    "name": {
      "description": "This is description of option.",
      "type": "string"
    }
  },
  "additionalProperties": false
}
```

### `options`

Type: `Object`

Object with options.

```js
import schema from "./path/to/schema.json";
import { validate } from "schema-utils";

const options = { foo: "bar" };

validate(schema, { name: 123 }, { name: "MyPlugin" });
```

### `configuration`

Allow to configure validator.

There is an alternative method to configure the `name` and`baseDataPath` options via the `title` property in the schema.
For example:

```json
{
  "title": "My Loader options",
  "type": "object",
  "properties": {
    "name": {
      "description": "This is description of option.",
      "type": "string"
    }
  },
  "additionalProperties": false
}
```

The last word used for the `baseDataPath` option, other words used for the `name` option.
Based on the example above the `name` option equals `My Loader`, the `baseDataPath` option equals `options`.

#### `name`

Type: `Object`
Default: `"Object"`

Allow to setup name in validation errors.

```js
import schema from "./path/to/schema.json";
import { validate } from "schema-utils";

const options = { foo: "bar" };

validate(schema, options, { name: "MyPlugin" });
```

```shell
Invalid configuration object. MyPlugin has been initialised using a configuration object that does not match the API schema.
 - configuration.optionName should be a integer.
```

#### `baseDataPath`

Type: `String`
Default: `"configuration"`

Allow to setup base data path in validation errors.

```js
import schema from "./path/to/schema.json";
import { validate } from "schema-utils";

const options = { foo: "bar" };

validate(schema, options, { name: "MyPlugin", baseDataPath: "options" });
```

```shell
Invalid options object. MyPlugin has been initialised using an options object that does not match the API schema.
 - options.optionName should be a integer.
```

#### `postFormatter`

Type: `Function`
Default: `undefined`

Allow to reformat errors.

```js
import schema from "./path/to/schema.json";
import { validate } from "schema-utils";

const options = { foo: "bar" };

validate(schema, options, {
  name: "MyPlugin",
  postFormatter: (formattedError, error) => {
    if (error.keyword === "type") {
      return `${formattedError}\nAdditional Information.`;
    }

    return formattedError;
  },
});
```

```shell
Invalid options object. MyPlugin has been initialized using an options object that does not match the API schema.
 - options.optionName should be a integer.
   Additional Information.
```

## Examples

**schema.json**

```json
{
  "type": "object",
  "properties": {
    "name": {
      "type": "string"
    },
    "test": {
      "anyOf": [
        { "type": "array" },
        { "type": "string" },
        { "instanceof": "RegExp" }
      ]
    },
    "transform": {
      "instanceof": "Function"
    },
    "sourceMap": {
      "type": "boolean"
    }
  },
  "additionalProperties": false
}
```

### `Loader`

```js
import { getOptions } from "loader-utils";
import { validate } from "schema-utils";

import schema from "path/to/schema.json";

function loader(src, map) {
  const options = getOptions(this);

  validate(schema, options, {
    name: "Loader Name",
    baseDataPath: "options",
  });

  // Code...
}

export default loader;
```

### `Plugin`

```js
import { validate } from "schema-utils";

import schema from "path/to/schema.json";

class Plugin {
  constructor(options) {
    validate(schema, options, {
      name: "Plugin Name",
      baseDataPath: "options",
    });

    this.options = options;
  }

  apply(compiler) {
    // Code...
  }
}

export default Plugin;
```

## Contributing

Please take a moment to read our contributing guidelines if you haven't yet done so.

[CONTRIBUTING](./.github/CONTRIBUTING.md)

## License

[MIT](./LICENSE)

[npm]: https://img.shields.io/npm/v/schema-utils.svg
[npm-url]: https://npmjs.com/package/schema-utils
[node]: https://img.shields.io/node/v/schema-utils.svg
[node-url]: https://nodejs.org
[deps]: https://david-dm.org/webpack/schema-utils.svg
[deps-url]: https://david-dm.org/webpack/schema-utils
[tests]: https://github.com/webpack/schema-utils/workflows/schema-utils/badge.svg
[tests-url]: https://github.com/webpack/schema-utils/actions
[cover]: https://codecov.io/gh/webpack/schema-utils/branch/master/graph/badge.svg
[cover-url]: https://codecov.io/gh/webpack/schema-utils
[chat]: https://badges.gitter.im/webpack/webpack.svg
[chat-url]: https://gitter.im/webpack/webpack
[size]: https://packagephobia.com/badge?p=schema-utils
[size-url]: https://packagephobia.com/result?p=schema-utils

license: mit


code:
export default ValidationError;
export type JSONSchema6 = import("json-schema").JSONSchema6;
export type JSONSchema7 = import("json-schema").JSONSchema7;
export type Schema = import("./validate").Schema;
export type ValidationErrorConfiguration =
  import("./validate").ValidationErrorConfiguration;
export type PostFormatter = import("./validate").PostFormatter;
export type SchemaUtilErrorObject = import("./validate").SchemaUtilErrorObject;
declare class ValidationError extends Error {
  /**
   * @param {Array<SchemaUtilErrorObject>} errors
   * @param {Schema} schema
   * @param {ValidationErrorConfiguration} configuration
   */
  constructor(
    errors: Array<SchemaUtilErrorObject>,
    schema: Schema,
    configuration?: ValidationErrorConfiguration
  );
  /** @type {Array<SchemaUtilErrorObject>} */
  errors: Array<SchemaUtilErrorObject>;
  /** @type {Schema} */
  schema: Schema;
  /** @type {string} */
  headerName: string;
  /** @type {string} */
  baseDataPath: string;
  /** @type {PostFormatter | null} */
  postFormatter: PostFormatter | null;
  /**
   * @param {string} path
   * @returns {Schema}
   */
  getSchemaPart(path: string): Schema;
  /**
   * @param {Schema} schema
   * @param {boolean} logic
   * @param {Array<Object>} prevSchemas
   * @returns {string}
   */
  formatSchema(
    schema: Schema,
    logic?: boolean,
    prevSchemas?: Array<Object>
  ): string;
  /**
   * @param {Schema=} schemaPart
   * @param {(boolean | Array<string>)=} additionalPath
   * @param {boolean=} needDot
   * @param {boolean=} logic
   * @returns {string}
   */
  getSchemaPartText(
    schemaPart?: Schema | undefined,
    additionalPath?: (boolean | Array<string>) | undefined,
    needDot?: boolean | undefined,
    logic?: boolean | undefined
  ): string;
  /**
   * @param {Schema=} schemaPart
   * @returns {string}
   */
  getSchemaPartDescription(schemaPart?: Schema | undefined): string;
  /**
   * @param {SchemaUtilErrorObject} error
   * @returns {string}
   */
  formatValidationError(error: SchemaUtilErrorObject): string;
  /**
   * @param {Array<SchemaUtilErrorObject>} errors
   * @returns {string}
   */
  formatValidationErrors(errors: Array<SchemaUtilErrorObject>): string;
}


code:
import { validate } from "./validate";
import { ValidationError } from "./validate";
import { enableValidation } from "./validate";
import { disableValidation } from "./validate";
import { needValidate } from "./validate";
export {
  validate,
  ValidationError,
  enableValidation,
  disableValidation,
  needValidate,
};


code:
export default addAbsolutePathKeyword;
export type Ajv = import("ajv").Ajv;
export type ValidateFunction = import("ajv").ValidateFunction;
export type SchemaUtilErrorObject = import("../validate").SchemaUtilErrorObject;
/**
 *
 * @param {Ajv} ajv
 * @returns {Ajv}
 */
declare function addAbsolutePathKeyword(ajv: Ajv): Ajv;


code:
export default addUndefinedAsNullKeyword;
export type Ajv = import("ajv").Ajv;
/**
 *
 * @param {Ajv} ajv
 * @returns {Ajv}
 */
declare function addUndefinedAsNullKeyword(ajv: Ajv): Ajv;


code:
export = Range;
/**
 * @typedef {[number, boolean]} RangeValue
 */
/**
 * @callback RangeValueCallback
 * @param {RangeValue} rangeValue
 * @returns {boolean}
 */
declare class Range {
  /**
   * @param {"left" | "right"} side
   * @param {boolean} exclusive
   * @returns {">" | ">=" | "<" | "<="}
   */
  static getOperator(
    side: "left" | "right",
    exclusive: boolean
  ): ">" | ">=" | "<" | "<=";
  /**
   * @param {number} value
   * @param {boolean} logic is not logic applied
   * @param {boolean} exclusive is range exclusive
   * @returns {string}
   */
  static formatRight(value: number, logic: boolean, exclusive: boolean): string;
  /**
   * @param {number} value
   * @param {boolean} logic is not logic applied
   * @param {boolean} exclusive is range exclusive
   * @returns {string}
   */
  static formatLeft(value: number, logic: boolean, exclusive: boolean): string;
  /**
   * @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: number,
    end: number,
    startExclusive: boolean,
    endExclusive: boolean,
    logic: boolean
  ): string;
  /**
   * @param {Array<RangeValue>} values
   * @param {boolean} logic is not logic applied
   * @return {RangeValue} computed value and it's exclusive flag
   */
  static getRangeValue(values: Array<RangeValue>, logic: boolean): RangeValue;
  /** @type {Array<RangeValue>} */
  _left: Array<RangeValue>;
  /** @type {Array<RangeValue>} */
  _right: Array<RangeValue>;
  /**
   * @param {number} value
   * @param {boolean=} exclusive
   */
  left(value: number, exclusive?: boolean | undefined): void;
  /**
   * @param {number} value
   * @param {boolean=} exclusive
   */
  right(value: number, exclusive?: boolean | undefined): void;
  /**
   * @param {boolean} logic is not logic applied
   * @return {string} "smart" range string representation
   */
  format(logic?: boolean): string;
}
declare namespace Range {
  export { RangeValue, RangeValueCallback };
}
type RangeValue = [number, boolean];
type RangeValueCallback = (rangeValue: RangeValue) => boolean;


code:
export function stringHints(schema: Schema, logic: boolean): string[];
export function numberHints(schema: Schema, logic: boolean): string[];
export type Schema = import("../validate").Schema;


code:
export type JSONSchema4 = import("json-schema").JSONSchema4;
export type JSONSchema6 = import("json-schema").JSONSchema6;
export type JSONSchema7 = import("json-schema").JSONSchema7;
export type ErrorObject = import("ajv").ErrorObject;
export type ValidateFunction = import("ajv").ValidateFunction;
export type Extend = {
  formatMinimum?: number | undefined;
  formatMaximum?: number | undefined;
  formatExclusiveMinimum?: boolean | undefined;
  formatExclusiveMaximum?: boolean | undefined;
  link?: string | undefined;
  undefinedAsNull?: boolean | undefined;
};
export type Schema = (JSONSchema4 | JSONSchema6 | JSONSchema7) & Extend;
export type SchemaUtilErrorObject = ErrorObject & {
  children?: Array<ErrorObject>;
};
export type PostFormatter = (
  formattedError: string,
  error: SchemaUtilErrorObject
) => string;
export type ValidationErrorConfiguration = {
  name?: string | undefined;
  baseDataPath?: string | undefined;
  postFormatter?: PostFormatter | undefined;
};
/**
 * @param {Schema} schema
 * @param {Array<object> | object} options
 * @param {ValidationErrorConfiguration=} configuration
 * @returns {void}
 */
export function validate(
  schema: Schema,
  options: Array<object> | object,
  configuration?: ValidationErrorConfiguration | undefined
): void;
export function enableValidation(): void;
export function disableValidation(): void;
export function needValidate(): boolean;
import ValidationError from "./ValidationError";
export { ValidationError };


code:
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

const {
  stringHints,
  numberHints
} = require("./util/hints");
/** @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 {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.dataPath ? error.dataPath.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(", ")})` : "";
}
/**
 * @param {Schema} schema
 * @param {boolean} logic
 * @returns {string[]}
 */

function getHints(schema, logic) {
  if (likeNumber(schema) || likeInteger(schema)) {
    return numberHints(schema, logic);
  } else if (likeString(schema)) {
    return 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) : [];
      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,
      dataPath: errorDataPath
    } = error;
    const dataPath = `${this.baseDataPath}${errorDataPath}`;

    switch (keyword) {
      case "type":
        {
          const {
            parentSchema,
            params
          } = error; // eslint-disable-next-line default-case

          switch (
          /** @type {import("ajv").TypeParams} */
          params.type) {
            case "number":
              return `${dataPath} should be a ${this.getSchemaPartText(parentSchema, false, true)}`;

            case "integer":
              return `${dataPath} should be an ${this.getSchemaPartText(parentSchema, false, true)}`;

            case "string":
              return `${dataPath} should be a ${this.getSchemaPartText(parentSchema, false, true)}`;

            case "boolean":
              return `${dataPath} should be a ${this.getSchemaPartText(parentSchema, false, true)}`;

            case "array":
              return `${dataPath} should be an array:\n${this.getSchemaPartText(parentSchema)}`;

            case "object":
              return `${dataPath} should be an object:\n${this.getSchemaPartText(parentSchema)}`;

            case "null":
              return `${dataPath} should be a ${this.getSchemaPartText(parentSchema, false, true)}`;

            default:
              return `${dataPath} should be:\n${this.getSchemaPartText(parentSchema)}`;
          }
        }

      case "instanceof":
        {
          const {
            parentSchema
          } = error;
          return `${dataPath} should be an instance of ${this.getSchemaPartText(parentSchema, false, true)}`;
        }

      case "pattern":
        {
          const {
            params,
            parentSchema
          } = error;
          const {
            pattern
          } =
          /** @type {import("ajv").PatternParams} */
          params;
          return `${dataPath} should match pattern ${JSON.stringify(pattern)}${getSchemaNonTypes(parentSchema)}.${this.getSchemaPartDescription(parentSchema)}`;
        }

      case "format":
        {
          const {
            params,
            parentSchema
          } = error;
          const {
            format
          } =
          /** @type {import("ajv").FormatParams} */
          params;
          return `${dataPath} should match format ${JSON.stringify(format)}${getSchemaNonTypes(parentSchema)}.${this.getSchemaPartDescription(parentSchema)}`;
        }

      case "formatMinimum":
      case "formatMaximum":
        {
          const {
            params,
            parentSchema
          } = error;
          const {
            comparison,
            limit
          } =
          /** @type {import("ajv").ComparisonParams} */
          params;
          return `${dataPath} 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
          } =
          /** @type {import("ajv").ComparisonParams} */
          params;
          const [, ...hints] = getHints(
          /** @type {Schema} */
          parentSchema, true);

          if (hints.length === 0) {
            hints.push(`should be ${comparison} ${limit}`);
          }

          return `${dataPath} ${hints.join(" ")}${getSchemaNonTypes(parentSchema)}.${this.getSchemaPartDescription(parentSchema)}`;
        }

      case "multipleOf":
        {
          const {
            params,
            parentSchema
          } = error;
          const {
            multipleOf
          } =
          /** @type {import("ajv").MultipleOfParams} */
          params;
          return `${dataPath} should be multiple of ${multipleOf}${getSchemaNonTypes(parentSchema)}.${this.getSchemaPartDescription(parentSchema)}`;
        }

      case "patternRequired":
        {
          const {
            params,
            parentSchema
          } = error;
          const {
            missingPattern
          } =
          /** @type {import("ajv").PatternRequiredParams} */
          params;
          return `${dataPath} should have property matching pattern ${JSON.stringify(missingPattern)}${getSchemaNonTypes(parentSchema)}.${this.getSchemaPartDescription(parentSchema)}`;
        }

      case "minLength":
        {
          const {
            params,
            parentSchema
          } = error;
          const {
            limit
          } =
          /** @type {import("ajv").LimitParams} */
          params;

          if (limit === 1) {
            return `${dataPath} should be a non-empty string${getSchemaNonTypes(parentSchema)}.${this.getSchemaPartDescription(parentSchema)}`;
          }

          const length = limit - 1;
          return `${dataPath} should be longer than ${length} character${length > 1 ? "s" : ""}${getSchemaNonTypes(parentSchema)}.${this.getSchemaPartDescription(parentSchema)}`;
        }

      case "minItems":
        {
          const {
            params,
            parentSchema
          } = error;
          const {
            limit
          } =
          /** @type {import("ajv").LimitParams} */
          params;

          if (limit === 1) {
            return `${dataPath} should be a non-empty array${getSchemaNonTypes(parentSchema)}.${this.getSchemaPartDescription(parentSchema)}`;
          }

          return `${dataPath} should not have fewer than ${limit} items${getSchemaNonTypes(parentSchema)}.${this.getSchemaPartDescription(parentSchema)}`;
        }

      case "minProperties":
        {
          const {
            params,
            parentSchema
          } = error;
          const {
            limit
          } =
          /** @type {import("ajv").LimitParams} */
          params;

          if (limit === 1) {
            return `${dataPath} should be a non-empty object${getSchemaNonTypes(parentSchema)}.${this.getSchemaPartDescription(parentSchema)}`;
          }

          return `${dataPath} should not have fewer than ${limit} properties${getSchemaNonTypes(parentSchema)}.${this.getSchemaPartDescription(parentSchema)}`;
        }

      case "maxLength":
        {
          const {
            params,
            parentSchema
          } = error;
          const {
            limit
          } =
          /** @type {import("ajv").LimitParams} */
          params;
          const max = limit + 1;
          return `${dataPath} should be shorter than ${max} character${max > 1 ? "s" : ""}${getSchemaNonTypes(parentSchema)}.${this.getSchemaPartDescription(parentSchema)}`;
        }

      case "maxItems":
        {
          const {
            params,
            parentSchema
          } = error;
          const {
            limit
          } =
          /** @type {import("ajv").LimitParams} */
          params;
          return `${dataPath} should not have more than ${limit} items${getSchemaNonTypes(parentSchema)}.${this.getSchemaPartDescription(parentSchema)}`;
        }

      case "maxProperties":
        {
          const {
            params,
            parentSchema
          } = error;
          const {
            limit
          } =
          /** @type {import("ajv").LimitParams} */
          params;
          return `${dataPath} should not have more than ${limit} properties${getSchemaNonTypes(parentSchema)}.${this.getSchemaPartDescription(parentSchema)}`;
        }

      case "uniqueItems":
        {
          const {
            params,
            parentSchema
          } = error;
          const {
            i
          } =
          /** @type {import("ajv").UniqueItemsParams} */
          params;
          return `${dataPath} should not contain the item '${error.data[i]}' twice${getSchemaNonTypes(parentSchema)}.${this.getSchemaPartDescription(parentSchema)}`;
        }

      case "additionalItems":
        {
          const {
            params,
            parentSchema
          } = error;
          const {
            limit
          } =
          /** @type {import("ajv").LimitParams} */
          params;
          return `${dataPath} should not have more than ${limit} items${getSchemaNonTypes(parentSchema)}. These items are valid:\n${this.getSchemaPartText(parentSchema)}`;
        }

      case "contains":
        {
          const {
            parentSchema
          } = error;
          return `${dataPath} should contains at least one ${this.getSchemaPartText(parentSchema, ["contains"])} item${getSchemaNonTypes(parentSchema)}.`;
        }

      case "required":
        {
          const {
            parentSchema,
            params
          } = error;
          const missingProperty =
          /** @type {import("ajv").DependenciesParams} */
          params.missingProperty.replace(/^\./, "");
          const hasProperty = parentSchema && Boolean(
          /** @type {Schema} */
          parentSchema.properties &&
          /** @type {Schema} */
          parentSchema.properties[missingProperty]);
          return `${dataPath} 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
          } =
          /** @type {import("ajv").AdditionalPropertiesParams} */
          params;
          return `${dataPath} has an unknown property '${additionalProperty}'${getSchemaNonTypes(parentSchema)}. These properties are valid:\n${this.getSchemaPartText(parentSchema)}`;
        }

      case "dependencies":
        {
          const {
            params,
            parentSchema
          } = error;
          const {
            property,
            deps
          } =
          /** @type {import("ajv").DependenciesParams} */
          params;
          const dependencies = deps.split(",").map(
          /**
           * @param {string} dep
           * @returns {string}
           */
          dep => `'${dep.trim()}'`).join(", ");
          return `${dataPath} should have properties ${dependencies} when property '${property}' is present${getSchemaNonTypes(parentSchema)}.${this.getSchemaPartDescription(parentSchema)}`;
        }

      case "propertyNames":
        {
          const {
            params,
            parentSchema,
            schema
          } = error;
          const {
            propertyName
          } =
          /** @type {import("ajv").PropertyNamesParams} */
          params;
          return `${dataPath} 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 `${dataPath} should be ${this.getSchemaPartText(parentSchema, false, true)}`;
          }

          return `${dataPath} should be one of these:\n${this.getSchemaPartText(parentSchema)}`;
        }

      case "const":
        {
          const {
            parentSchema
          } = error;
          return `${dataPath} 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 `${dataPath} should be any ${schemaOutput}${postfix}.`;
          }

          const {
            schema,
            parentSchema
          } = error;
          return `${dataPath} 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 `${dataPath} 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 `${dataPath} should be one of these:\n${this.getSchemaPartText(parentSchema)}`;
        }

      case "if":
        {
          const {
            params,
            parentSchema
          } = error;
          const {
            failingKeyword
          } =
          /** @type {import("ajv").IfParams} */
          params;
          return `${dataPath} should match "${failingKeyword}" schema:\n${this.getSchemaPartText(parentSchema, [failingKeyword])}`;
        }

      case "absolutePath":
        {
          const {
            message,
            parentSchema
          } = error;
          return `${dataPath}: ${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 `${dataPath} ${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
};


code:
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

/** @typedef {import("ajv").Ajv} Ajv */

/** @typedef {import("ajv").ValidateFunction} ValidateFunction */

/** @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("absolutePath", {
    errors: true,
    type: "string",

    compile(schema, parentSchema) {
      /** @type {ValidateFunction} */
      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").Ajv} Ajv */

/**
 *
 * @param {Ajv} ajv
 * @param {string} keyword
 * @param {any} definition
 */
function addKeyword(ajv, keyword, definition) {
  let customRuleCode;

  try {
    // @ts-ignore
    // eslint-disable-next-line global-require
    customRuleCode = require("ajv/lib/dotjs/custom"); // @ts-ignore

    const {
      RULES
    } = ajv;
    let ruleGroup;

    for (let i = 0; i < RULES.length; i++) {
      const rg = RULES[i];

      if (typeof rg.type === "undefined") {
        ruleGroup = rg;
        break;
      }
    }

    const rule = {
      keyword,
      definition,
      custom: true,
      code: customRuleCode,
      implements: definition.implements
    };
    ruleGroup.rules.unshift(rule);
    RULES.custom[keyword] = rule;
    RULES.keywords[keyword] = true;
    RULES.all[keyword] = true;
  } catch (e) {// Nothing, fallback
  }
}
/**
 *
 * @param {Ajv} ajv
 * @returns {Ajv}
 */

function addUndefinedAsNullKeyword(ajv) {
  // There is workaround for old versions of ajv, where `before` is not implemented
  addKeyword(ajv, "undefinedAsNull", {
    modifying: true,

    /**
     * @param {boolean} kwVal
     * @param {unknown} data
     * @param {any} parentSchema
     * @param {string} dataPath
     * @param {unknown} parentData
     * @param {number | string} parentDataProperty
     * @return {boolean}
     */
    validate(kwVal, data, parentSchema, dataPath, parentData, parentDataProperty) {
      if (kwVal && parentSchema && typeof parentSchema.enum !== "undefined" && parentData && typeof parentDataProperty === "number") {
        const idx =
        /** @type {number} */
        parentDataProperty;
        const parentDataRef =
        /** @type {any[]} */
        parentData;

        if (typeof parentDataRef[idx] === "undefined") {
          parentDataRef[idx] = 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;
    const tmpExclusive = currentSchema.formatExclusiveMaximum;
    currentSchema.minLength = currentSchema.maxLength;
    currentSchema.maxLength = tmpLength;
    currentSchema.formatMinimum = currentSchema.formatMaximum;
    currentSchema.formatMaximum = tmpFormat;
    currentSchema.formatExclusiveMaximum = !currentSchema.formatExclusiveMinimum;
    currentSchema.formatExclusiveMinimum = !tmpExclusive;
  }

  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.validate = validate;
exports.enableValidation = enableValidation;
exports.disableValidation = disableValidation;
exports.needValidate = needValidate;
Object.defineProperty(exports, "ValidationError", {
  enumerable: true,
  get: function () {
    return _ValidationError.default;
  }
});

var _absolutePath = _interopRequireDefault(require("./keywords/absolutePath"));

var _undefinedAsNull = _interopRequireDefault(require("./keywords/undefinedAsNull"));

var _ValidationError = _interopRequireDefault(require("./ValidationError"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/**
 * @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;
  };
};

const getAjv = memoize(() => {
  // 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"); // eslint-disable-next-line global-require

  const ajvKeywords = require("ajv-keywords");

  const ajv = new Ajv({
    allErrors: true,
    verbose: true,
    $data: true
  });
  ajvKeywords(ajv, ["instanceof", "formatMinimum", "formatMaximum", "patternRequired"]); // Custom keywords

  (0, _absolutePath.default)(ajv);
  (0, _undefinedAsNull.default)(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 {import("ajv").ValidateFunction} ValidateFunction */

/**
 * @typedef {Object} Extend
 * @property {number=} formatMinimum
 * @property {number=} formatMaximum
 * @property {boolean=} formatExclusiveMinimum
 * @property {boolean=} 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.dataPath = `[${idx}]${error.dataPath}`;

  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);
  }
}
/** @typedef {WeakMap<Schema, ValidateFunction>} */

const schemaCache = new WeakMap();
/**
 * @param {Schema} schema
 * @param {Array<object> | object} options
 * @returns {Array<SchemaUtilErrorObject>}
 */

function validateObject(schema, options) {
  let compiledSchema = schemaCache.get(schema);

  if (!compiledSchema) {
    compiledSchema = getAjv().compile(schema);
    schemaCache.set(schema, compiledSchema);
  }

  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 {
      dataPath
    } = error;
    /** @type {Array<SchemaUtilErrorObject>} */

    let children = [];
    newErrors = newErrors.filter(oldError => {
      if (oldError.dataPath.includes(dataPath)) {
        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


thread-loader

description: Runs the following loaders in a worker pool

repository: webpack-contrib/thread-loader

author: Tobias Koppers @sokra

clean: del-cli dist

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

security: npm audit

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

test:only: cross-env NODE_ENV=test jest --forceExit

prepare: npm run build


code:
# thunky

Delay the evaluation of a paramless async function and cache the result (see [thunk](http://en.wikipedia.org/wiki/Thunk_%28functional_programming%29)).

```
npm install thunky
```

[![build status](http://img.shields.io/travis/mafintosh/thunky.svg?style=flat)](http://travis-ci.org/mafintosh/thunky)

## Example

Let's make a simple function that returns a random number 1 second after it is called for the first time

``` js
var thunky = require('thunky')

var test = thunky(function (callback) { // the inner function should only accept a callback
  console.log('waiting 1s and returning random number')
  setTimeout(function () {
    callback(Math.random())
  }, 1000)
})

test(function (num) {  // inner function is called the first time we call test
  console.log(num) // prints random number
})

test(function (num) {  // subsequent calls waits for the first call to finish and return the same value
  console.log(num) // prints the same random number as above
})
```

## Lazy evaluation

Thunky makes it easy to implement a lazy evaluation pattern.

``` js
var getDb = thunky(function (callback) {
  db.open(myConnectionString, callback)
})

var queryDb = function (query, callback) {
  getDb(function (err, db) {
    if (err) return callback(err)
    db.query(query, callback)
  })
}

queryDb('some query', function (err, result) { ... } )

queryDb('some other query', function (err, result) { ... } )
```

The first time `getDb` is called it will try do open a connection to the database.
Any subsequent calls will just wait for the first call to complete and then call your callback.

A nice property of this pattern is that it *easily* allows us to pass any error caused by `getDb` to the `queryDb` callback.

## Error → No caching

If the thunk callback is called with an `Error` object as the first argument it will not cache the result

``` js
var fails = thunky(function (callback) {
  console.log('returning an error')
  callback(new Error('bad stuff'))
})

fails(function (err) { // inner function is called
  console.log(err)
});

fails(function (err) { // inner function is called again as it returned an error before
  console.log(err)
})
```

## Promise version

A promise version is available as well

``` js
var thunkyp = require('thunky/promise')

var ready = thunkyp(async function () {
  // ... do async stuff
  return 42
})

// same semantics as the callback version
await ready()
```

## License

MIT


code:
'use strict'

var nextTick = nextTickArgs
process.nextTick(upgrade, 42) // pass 42 and see if upgrade is called with it

module.exports = thunky

function thunky (fn) {
  var state = run
  return thunk

  function thunk (callback) {
    state(callback || noop)
  }

  function run (callback) {
    var stack = [callback]
    state = wait
    fn(done)

    function wait (callback) {
      stack.push(callback)
    }

    function done (err) {
      var args = arguments
      state = isError(err) ? run : finished
      while (stack.length) finished(stack.shift())

      function finished (callback) {
        nextTick(apply, callback, args)
      }
    }
  }
}

function isError (err) { // inlined from util so this works in the browser
  return Object.prototype.toString.call(err) === '[object Error]'
}

function noop () {}

function apply (callback, args) {
  callback.apply(null, args)
}

function upgrade (val) {
  if (val === 42) nextTick = process.nextTick
}

function nextTickArgs (fn, a, b) {
  process.nextTick(function () {
    fn(a, b)
  })
}


thunky

description: delay the evaluation of a paramless async function and cache the result

type: git

test: standard && tape test.js

keywords: memo thunk async lazy control flow cache

author: Mathias Buus Madsen <mathiasbuus@gmail.com>


code:
module.exports = thunkyp

function thunkyp (fn) {
  let running = null

  return ready

  function ready () {
    if (running) return running
    const p = fn()
    if (!(p instanceof Promise)) running = Promise.resolve(p)
    else running = p
    running.catch(onerror)
    return running
  }

  function onerror () {
    running = null
  }
}


code:
var tape = require('tape')
var thunky = require('./')

tape('run only once', function (t) {
  t.plan(3)

  var ran = 0
  var run = thunky(function (cb) {
    ran++
    cb()
  })

  run(function () {
    t.same(ran, 1, 'ran once')
  })
  run(function () {
    t.same(ran, 1, 'ran once')
  })
  run(function () {
    t.same(ran, 1, 'ran once')
  })
})

tape('run only once async', function (t) {
  t.plan(3)

  var ran = 0
  var run = thunky(function (cb) {
    process.nextTick(function () {
      ran++
      cb()
    })
  })

  run(function () {
    t.same(ran, 1, 'ran once')
  })
  run(function () {
    t.same(ran, 1, 'ran once')
  })
  run(function () {
    t.same(ran, 1, 'ran once')
  })
})

tape('re-run on error', function (t) {
  t.plan(3)

  var ran = 0
  var run = thunky(function (cb) {
    ran++
    cb(new Error('stop'))
  })

  run(function () {
    t.same(ran, 1, 'ran once')
    run(function () {
      t.same(ran, 2, 'ran once')
      run(function () {
        t.same(ran, 3, 'ran once')
      })
    })
  })
})

tape('pass arguments', function (t) {
  t.plan(6)

  var ran = 0
  var run = thunky(function (fn) {
    ran++
    fn({ hello: 'world' })
  })

  run(function (val) {
    t.same(ran, 1, 'ran once')
    t.same(val, { hello: 'world' })
    run(function (val) {
      t.same(ran, 1, 'ran once')
      t.same(val, { hello: 'world' })
      run(function (val) {
        t.same(ran, 1, 'ran once')
        t.same(val, { hello: 'world' })
      })
    })
  })
})

tape('callback is optional', function (t) {
  t.plan(2)

  var ran = 0
  var run = thunky(function (fn) {
    ran++
    fn({ hello: 'world' })
  })

  run()
  run(function (val) {
    t.same(ran, 1, 'ran once')
    t.same(val, { hello: 'world' })
  })
})

tape('always async', function (t) {
  t.plan(2)

  var run = thunky(function (cb) {
    process.nextTick(cb)
  })

  var sync = true
  run(function () {
    t.ok(!sync, 'not sync')
    var innerSync = true
    run(function () {
      t.ok(!innerSync, 'not sync')
    })
    innerSync = false
  })
  sync = false
})


code:
sudo: false

language: node_js

node_js:
  - "5"
  - "4"
  - "0.12"
  - "0.10"


code:
# to-buffer

Pass in a string, get a buffer back. Pass in a buffer, get the same buffer back.

```
npm install to-buffer
```

[![build status](https://travis-ci.org/mafintosh/to-buffer.svg?branch=master)](https://travis-ci.org/mafintosh/to-buffer)

## Usage

``` js
var toBuffer = require('to-buffer')
console.log(toBuffer('hi')) // <Buffer 68 69>
console.log(toBuffer(Buffer('hi'))) // <Buffer 68 69>
console.log(toBuffer('6869', 'hex')) // <Buffer 68 69>
console.log(toBuffer(43)) // throws
```

## License

MIT


code:
module.exports = toBuffer

var makeBuffer = Buffer.from && Buffer.from !== Uint8Array.from ? Buffer.from : bufferFrom

function bufferFrom (buf, enc) {
  return new Buffer(buf, enc)
}

function toBuffer (buf, enc) {
  if (Buffer.isBuffer(buf)) return buf
  if (typeof buf === 'string') return makeBuffer(buf, enc)
  if (Array.isArray(buf)) return makeBuffer(buf)
  throw new Error('Input should be a buffer or a string')
}


to-buffer

description: Pass in a string, get a buffer back. Pass in a buffer, get the same buffer back

author: Mathias Buus (@mafintosh)


code:
var tape = require('tape')
var toBuffer = require('./')

tape('buffer returns buffer', function (t) {
  t.same(toBuffer(Buffer('hi')), Buffer('hi'))
  t.end()
})

tape('string returns buffer', function (t) {
  t.same(toBuffer('hi'), Buffer('hi'))
  t.end()
})

tape('string + enc returns buffer', function (t) {
  t.same(toBuffer('6869', 'hex'), Buffer('hi'))
  t.end()
})

tape('other input throws', function (t) {
  try {
    toBuffer(42)
  } catch (err) {
    t.same(err.message, 'Input should be a buffer or a string')
    t.end()
  }
})