code:
"use strict";

/*
 * Based on the packages get-port https://www.npmjs.com/package/get-port
 * and portfinder https://www.npmjs.com/package/portfinder
 * The code structure is similar to get-port, but it searches
 * ports deterministically like portfinder
 */
const net = require("net");
const os = require("os");

const minPort = 1024;
const maxPort = 65_535;

/**
 * @return {Set<string|undefined>}
 */
const getLocalHosts = () => {
  const interfaces = os.networkInterfaces();

  // Add undefined value for createServer function to use default host,
  // and default IPv4 host in case createServer defaults to IPv6.
  // eslint-disable-next-line no-undefined
  const results = new Set([undefined, "0.0.0.0"]);

  for (const _interface of Object.values(interfaces)) {
    if (_interface) {
      for (const config of _interface) {
        results.add(config.address);
      }
    }
  }

  return results;
};

/**
 * @param {number} basePort
 * @param {string | undefined} host
 * @return {Promise<number>}
 */
const checkAvailablePort = (basePort, host) =>
  new Promise((resolve, reject) => {
    const server = net.createServer();
    server.unref();
    server.on("error", reject);

    server.listen(basePort, host, () => {
      // Next line should return AdressInfo because we're calling it after listen() and before close()
      const { port } = /** @type {import("net").AddressInfo} */ (
        server.address()
      );
      server.close(() => {
        resolve(port);
      });
    });
  });

/**
 * @param {number} port
 * @param {Set<string|undefined>} hosts
 * @return {Promise<number>}
 */
const getAvailablePort = async (port, hosts) => {
  /**
   * Errors that mean that host is not available.
   * @type {Set<string | undefined>}
   */
  const nonExistentInterfaceErrors = new Set(["EADDRNOTAVAIL", "EINVAL"]);
  /* Check if the post is available on every local host name */
  for (const host of hosts) {
    try {
      await checkAvailablePort(port, host); // eslint-disable-line no-await-in-loop
    } catch (error) {
      /* We throw an error only if the interface exists */
      if (
        !nonExistentInterfaceErrors.has(
          /** @type {NodeJS.ErrnoException} */ (error).code
        )
      ) {
        throw error;
      }
    }
  }

  return port;
};

/**
 * @param {number} basePort
 * @param {string=} host
 * @return {Promise<number>}
 */
async function getPorts(basePort, host) {
  if (basePort < minPort || basePort > maxPort) {
    throw new Error(`Port number must lie between ${minPort} and ${maxPort}`);
  }

  let port = basePort;
  const localhosts = getLocalHosts();
  let hosts;
  if (host && !localhosts.has(host)) {
    hosts = new Set([host]);
  } else {
    /* If the host is equivalent to localhost
       we need to check every equivalent host
       else the port might falsely appear as available
       on some operating systems  */
    hosts = localhosts;
  }
  /** @type {Set<string | undefined>} */
  const portUnavailableErrors = new Set(["EADDRINUSE", "EACCES"]);
  while (port <= maxPort) {
    try {
      const availablePort = await getAvailablePort(port, hosts); // eslint-disable-line no-await-in-loop
      return availablePort;
    } catch (error) {
      /* Try next port if port is busy; throw for any other error */
      if (
        !portUnavailableErrors.has(
          /** @type {NodeJS.ErrnoException} */ (error).code
        )
      ) {
        throw error;
      }
      port += 1;
    }
  }

  throw new Error("No available ports found");
}

module.exports = getPorts;

license: mit


title: Dev Server options

type: object

type: array

$ref: #/definitions/AllowedHostsItem

enum: auto all

description: Allows to enumerate the hosts from which access to the dev server are allowed (useful when you are proxying dev server, by default is 'auto').

type: string

type: boolean

negatedDescription: Disallows to broadcasts dev server via ZeroConf networking on start.

description: Options for bonjour.

description: Allows to broadcasts dev server via ZeroConf networking on start.

description: Allows to specify options for client script in the browser or disable client script.

negatedDescription: Disables client script.

$ref: #/definitions/ClientLogging

$ref: #/definitions/ClientOverlay

$ref: #/definitions/ClientProgress

$ref: #/definitions/ClientReconnect

$ref: #/definitions/ClientWebSocketTransport

$ref: #/definitions/ClientWebSocketURL

enum: none error warn info log verbose

description: Allows to set log level in the browser.

description: Enables a full-screen overlay in the browser when there are compiler errors or warnings.

negatedDescription: Disables the full-screen overlay in the browser when there are compiler errors or warnings.

description: Enables a full-screen overlay in the browser when there are compiler errors.

negatedDescription: Disables the full-screen overlay in the browser when there are compiler errors.

instanceof: Function

description: Filter compiler errors. Return true to include and return false to exclude.

description: Enables a full-screen overlay in the browser when there are compiler warnings.

negatedDescription: Disables the full-screen overlay in the browser when there are compiler warnings.

description: Filter compiler warnings. Return true to include and return false to exclude.

description: Enables a full-screen overlay in the browser when there are uncaught runtime errors.

negatedDescription: Disables the full-screen overlay in the browser when there are uncaught runtime errors.

description: Filter uncaught runtime errors. Return true to include and return false to exclude.

description: The name of a Trusted Types policy for the overlay. Defaults to 'webpack-dev-server#overlay'.

description: Prints compilation progress in percentage in the browser.

negatedDescription: Does not print compilation progress in percentage in the browser.

description: Tells dev-server the number of times it should try to reconnect the client.

negatedDescription: Tells dev-server to not to try to reconnect the client.

type: number

description: Allows to set custom web socket transport to communicate with dev server.

enum: sockjs ws

description: Allows to specify URL to web socket server (useful when you're proxying dev server and client script does not always know where to connect to).

description: Tells clients connected to devServer to use the provided hostname.

description: Tells clients connected to devServer to use the provided path to connect.

description: Tells clients connected to devServer to use the provided password to authenticate.

description: Tells clients connected to devServer to use the provided port.

description: Tells clients connected to devServer to use the provided protocol.

description: Tells clients connected to devServer to use the provided username to authenticate.

description: Enables gzip compression for everything served.

negatedDescription: Disables gzip compression for everything served.

description: Provide options to 'webpack-dev-middleware' which handles webpack assets.

description: Allows to serve over HTTP/2 using SPDY. Deprecated, use the `server` option.

negatedDescription: Does not serve over HTTP/2 using SPDY.

negatedDescription: Disallows to configure the server's listening socket for TLS (by default, dev server will be served over HTTP).

description: Passphrase for a pfx file. Deprecated, use the `server.options.passphrase` option.

description: Request for an SSL certificate. Deprecated, use the `server.options.requestCert` option.

negatedDescription: Does not request for an SSL certificate.

instanceof: Buffer

description: Path to an SSL CA certificate or content of an SSL CA certificate. Deprecated, use the `server.options.ca` option.

description: Path to an SSL certificate or content of an SSL certificate. Deprecated, use the `server.options.cert` option.

description: Path to PEM formatted CRLs (Certificate Revocation Lists) or content of PEM formatted CRLs (Certificate Revocation Lists). Deprecated, use the `server.options.crl` option.

description: Path to an SSL key or content of an SSL key. Deprecated, use the `server.options.key` option.

description: Path to an SSL pfx file or content of an SSL pfx file. Deprecated, use the `server.options.pfx` option.

description: Allows to configure the server's listening socket for TLS (by default, dev server will be served over HTTP). Deprecated, use the `server` option.

description: key of header.

description: value of header.

$ref: #/definitions/HeaderObject

description: Allows to set custom headers on response.

negatedDescription: Disallows to proxy requests through a specified index page.

description: Options for `historyApiFallback`.

description: Allows to proxy requests through a specified index page (by default 'index.html'), useful for Single Page Applications that utilise the HTML5 History API.

description: Allows to specify a hostname to use.

negatedDescription: Disables Hot Module Replacement.

description: Enables Hot Module Replacement.

description: Listen to a unix socket.

description: Enables reload/refresh the page(s) when file changes are detected (enabled by default).

negatedDescription: Disables reload/refresh the page(s) when file changes are detected (enabled by default).

description: Tells dev-server whether to enable magic HTML routes (routes corresponding to your webpack output, for example '/main' for 'main.js').

negatedDescription: Disables magic HTML routes (routes corresponding to your webpack output, for example '/main' for 'main.js').

description: Provides the ability to execute a custom function and apply custom middleware(s) after all other middlewares. Deprecated: please use the 'setupMiddlewares' option.

description: Provides the ability to execute a custom function and apply custom middleware(s) prior to all other middlewares. Deprecated: please use the 'setupMiddlewares' option.

description: Provides the ability to execute a custom function when dev server starts listening.

description: Allows to configure dev server to open the browser(s) and page(s) after server had been started (set it to true to open your default browser).

description: Opens specified page in browser.

description: Open specified browser.

description: Open specified browser. Deprecated: please use '--open-app-name'.

description: Open specified browser.

description: Allows to specify a port to use.

description: Allows to proxy requests, can be useful when you have a separate API backend development server and you want to send API requests on the same domain.

description: Allows to set server and options (by default 'http').

description: Passphrase for a pfx file.

description: Request for an SSL certificate.

description: Path to an SSL key or content of an SSL key.

description: Path to an SSL pfx file or content of an SSL pfx file.

description: Allows to close dev server and exit the process on SIGINT and SIGTERM signals (enabled by default for CLI).

description: Provides the ability to execute a custom function and apply custom middleware(s).

negatedDescription: Disallows to configure options for serving static files from directory.

description: Allows to configure options for serving static files from directory (by default 'public' directory).

description: Directory for static contents.

description: The static files will be available in the browser under this public path.

negatedDescription: Does not tell dev server to use serveIndex middleware.

description: Tells dev server to use serveIndex middleware when enabled.

negatedDescription: Does not watch for files in static content directory.

description: Options for watch.

description: Watches for files in static content directory.

description: Allows to configure list of globs/directories/files to watch for file changes.

description: Path(s) of globs/directories/files to watch for file changes.

description: Configure advanced options for watching. See the chokidar documentation for the possible options.

description: Allows to set web socket server and options (by default 'ws').

negatedDescription: Disallows to set web socket server and options.

description: Deprecated: please use '--web-socket-server-type' option.


code:
"use strict";

/** @typedef {import("../Server").ClientConnection} ClientConnection */

// base class that users should extend if they are making their own
// server implementation
module.exports = class BaseServer {
  /**
   * @param {import("../Server")} server
   */
  constructor(server) {
    /** @type {import("../Server")} */
    this.server = server;

    /** @type {ClientConnection[]} */
    this.clients = [];
  }
};


code:
"use strict";

const sockjs = require("sockjs");
const BaseServer = require("./BaseServer");

/** @typedef {import("../Server").WebSocketServerConfiguration} WebSocketServerConfiguration */
/** @typedef {import("../Server").ClientConnection} ClientConnection */

// Workaround for sockjs@~0.3.19
// sockjs will remove Origin header, however Origin header is required for checking host.
// See https://github.com/webpack/webpack-dev-server/issues/1604 for more information
{
  // @ts-ignore
  const SockjsSession = require("sockjs/lib/transport").Session;
  const decorateConnection = SockjsSession.prototype.decorateConnection;

  /**
   * @param {import("http").IncomingMessage} req
   */
  // eslint-disable-next-line func-names
  SockjsSession.prototype.decorateConnection = function (req) {
    decorateConnection.call(this, req);

    const connection = this.connection;

    if (
      connection.headers &&
      !("origin" in connection.headers) &&
      "origin" in req.headers
    ) {
      connection.headers.origin = req.headers.origin;
    }
  };
}

module.exports = class SockJSServer extends BaseServer {
  // options has: error (function), debug (function), server (http/s server), path (string)
  /**
   * @param {import("../Server")} server
   */
  constructor(server) {
    super(server);

    const webSocketServerOptions =
      /** @type {NonNullable<WebSocketServerConfiguration["options"]>} */
      (
        /** @type {WebSocketServerConfiguration} */
        (this.server.options.webSocketServer).options
      );

    /**
     * @param {NonNullable<WebSocketServerConfiguration["options"]>} options
     * @returns {string}
     */
    const getSockjsUrl = (options) => {
      if (typeof options.sockjsUrl !== "undefined") {
        return options.sockjsUrl;
      }

      return "/__webpack_dev_server__/sockjs.bundle.js";
    };

    this.implementation = sockjs.createServer({
      // Use provided up-to-date sockjs-client
      sockjs_url: getSockjsUrl(webSocketServerOptions),
      // Default logger is very annoy. Limit useless logs.
      /**
       * @param {string} severity
       * @param {string} line
       */
      log: (severity, line) => {
        if (severity === "error") {
          this.server.logger.error(line);
        } else if (severity === "info") {
          this.server.logger.log(line);
        } else {
          this.server.logger.debug(line);
        }
      },
    });

    /**
     * @param {import("sockjs").ServerOptions & { path?: string }} options
     * @returns {string | undefined}
     */
    const getPrefix = (options) => {
      if (typeof options.prefix !== "undefined") {
        return options.prefix;
      }

      return options.path;
    };

    const options = {
      ...webSocketServerOptions,
      prefix: getPrefix(webSocketServerOptions),
    };

    this.implementation.installHandlers(
      /** @type {import("http").Server} */ (this.server.server),
      options
    );

    this.implementation.on("connection", (client) => {
      // @ts-ignore
      // Implement the the same API as for `ws`
      client.send = client.write;
      // @ts-ignore
      client.terminate = client.close;

      this.clients.push(/** @type {ClientConnection} */ (client));

      client.on("close", () => {
        this.clients.splice(
          this.clients.indexOf(/** @type {ClientConnection} */ (client)),
          1
        );
      });
    });

    // @ts-ignore
    this.implementation.close = (callback) => {
      callback();
    };
  }
};


code:
"use strict";

const WebSocket = require("ws");
const BaseServer = require("./BaseServer");

/** @typedef {import("../Server").WebSocketServerConfiguration} WebSocketServerConfiguration */
/** @typedef {import("../Server").ClientConnection} ClientConnection */

module.exports = class WebsocketServer extends BaseServer {
  static heartbeatInterval = 1000;

  /**
   * @param {import("../Server")} server
   */
  constructor(server) {
    super(server);

    /** @type {import("ws").ServerOptions} */
    const options = {
      .../** @type {WebSocketServerConfiguration} */
      (this.server.options.webSocketServer).options,
      clientTracking: false,
    };
    const isNoServerMode =
      typeof options.port === "undefined" &&
      typeof options.server === "undefined";

    if (isNoServerMode) {
      options.noServer = true;
    }

    this.implementation = new WebSocket.Server(options);

    /** @type {import("http").Server} */
    (this.server.server).on(
      "upgrade",
      /**
       * @param {import("http").IncomingMessage} req
       * @param {import("stream").Duplex} sock
       * @param {Buffer} head
       */
      (req, sock, head) => {
        if (!this.implementation.shouldHandle(req)) {
          return;
        }

        this.implementation.handleUpgrade(req, sock, head, (connection) => {
          this.implementation.emit("connection", connection, req);
        });
      }
    );

    this.implementation.on(
      "error",
      /**
       * @param {Error} err
       */
      (err) => {
        this.server.logger.error(err.message);
      }
    );

    const interval = setInterval(() => {
      this.clients.forEach(
        /**
         * @param {ClientConnection} client
         */
        (client) => {
          if (client.isAlive === false) {
            client.terminate();

            return;
          }

          client.isAlive = false;
          client.ping(() => {});
        }
      );
    }, WebsocketServer.heartbeatInterval);

    this.implementation.on(
      "connection",
      /**
       * @param {ClientConnection} client
       */
      (client) => {
        this.clients.push(client);

        client.isAlive = true;

        client.on("pong", () => {
          client.isAlive = true;
        });

        client.on("close", () => {
          this.clients.splice(this.clients.indexOf(client), 1);
        });
      }
    );

    this.implementation.on("close", () => {
      clearInterval(interval);
    });
  }
};


code:
# ajv-keywords

Custom JSON-Schema keywords for [Ajv](https://github.com/epoberezkin/ajv) validator

[![build](https://github.com/ajv-validator/ajv-keywords/workflows/build/badge.svg)](https://github.com/ajv-validator/ajv-keywords/actions?query=workflow%3Abuild)
[![npm](https://img.shields.io/npm/v/ajv-keywords.svg)](https://www.npmjs.com/package/ajv-keywords)
[![npm downloads](https://img.shields.io/npm/dm/ajv-keywords.svg)](https://www.npmjs.com/package/ajv-keywords)
[![coverage](https://coveralls.io/repos/github/ajv-validator/ajv-keywords/badge.svg?branch=master)](https://coveralls.io/github/ajv-validator/ajv-keywords?branch=master)
[![gitter](https://img.shields.io/gitter/room/ajv-validator/ajv.svg)](https://gitter.im/ajv-validator/ajv)

**Please note**: This readme file is for [ajv-keywords v5.0.0](https://github.com/ajv-validator/ajv-keywords/releases/tag/v5.0.0) that should be used with [ajv v8](https://github.com/ajv-validator/ajv).

[ajv-keywords v3](https://github.com/ajv-validator/ajv-keywords/tree/v3) should be used with [ajv v6](https://github.com/ajv-validator/ajv/tree/v6).

## Contents

- [Install](#install)
- [Usage](#usage)
- [Keywords](#keywords)
  - [Types](#types)
    - [typeof](#typeof)
    - [instanceof](#instanceof)\+
  - [Keywords for numbers](#keywords-for-numbers)
    - [range and exclusiveRange](#range-and-exclusiverange)
  - [Keywords for strings](#keywords-for-strings)
    - [regexp](#regexp)
    - [transform](#transform)\*
  - [Keywords for arrays](#keywords-for-arrays)
    - [uniqueItemProperties](#uniqueitemproperties)\+
  - [Keywords for objects](#keywords-for-objects)
    - [allRequired](#allrequired)
    - [anyRequired](#anyrequired)
    - [oneRequired](#onerequired)
    - [patternRequired](#patternrequired)
    - [prohibited](#prohibited)
    - [deepProperties](#deepproperties)
    - [deepRequired](#deeprequired)
    - [dynamicDefaults](#dynamicdefaults)\*\+
  - [Keywords for all types](#keywords-for-all-types)
    - [select/selectCases/selectDefault](#selectselectcasesselectdefault)
- [Security contact](#security-contact)
- [Open-source software support](#open-source-software-support)
- [License](#license)

\* - keywords that modify data
\+ - keywords that are not supported in [standalone validation code](https://github.com/ajv-validator/ajv/blob/master/docs/standalone.md)

## Install

To install version 4 to use with [Ajv v7](https://github.com/ajv-validator/ajv):

```
npm install ajv-keywords
```

## Usage

To add all available keywords:

```javascript
const Ajv = require("ajv")
const ajv = new Ajv()
require("ajv-keywords")(ajv)

ajv.validate({instanceof: "RegExp"}, /.*/) // true
ajv.validate({instanceof: "RegExp"}, ".*") // false
```

To add a single keyword:

```javascript
require("ajv-keywords")(ajv, "instanceof")
```

To add multiple keywords:

```javascript
require("ajv-keywords")(ajv, ["typeof", "instanceof"])
```

To add a single keyword directly (to avoid adding unused code):

```javascript
require("ajv-keywords/dist/keywords/select")(ajv, opts)
```

To add all keywords via Ajv options:

```javascript
const ajv = new Ajv({keywords: require("ajv-keywords/dist/definitions")(opts)})
```

To add one or several keywords via options:

```javascript
const ajv = new Ajv({
  keywords: [
    require("ajv-keywords/dist/definitions/typeof")(),
    require("ajv-keywords/dist/definitions/instanceof")(),
    // select exports an array of 3 definitions - see "select" in docs
    ...require("ajv-keywords/dist/definitions/select")(opts),
  ],
})
```

`opts` is an optional object with a property `defaultMeta` - URI of meta-schema to use for keywords that use subschemas (`select` and `deepProperties`). The default is `"http://json-schema.org/schema"`.

## Keywords

### Types

#### `typeof`

Based on JavaScript `typeof` operation.

The value of the keyword should be a string (`"undefined"`, `"string"`, `"number"`, `"object"`, `"function"`, `"boolean"` or `"symbol"`) or an array of strings.

To pass validation the result of `typeof` operation on the value should be equal to the string (or one of the strings in the array).

```javascript
ajv.validate({typeof: "undefined"}, undefined) // true
ajv.validate({typeof: "undefined"}, null) // false
ajv.validate({typeof: ["undefined", "object"]}, null) // true
```

#### `instanceof`

Based on JavaScript `instanceof` operation.

The value of the keyword should be a string (`"Object"`, `"Array"`, `"Function"`, `"Number"`, `"String"`, `"Date"`, `"RegExp"` or `"Promise"`) or an array of strings.

To pass validation the result of `data instanceof ...` operation on the value should be true:

```javascript
ajv.validate({instanceof: "Array"}, []) // true
ajv.validate({instanceof: "Array"}, {}) // false
ajv.validate({instanceof: ["Array", "Function"]}, function () {}) // true
```

You can add your own constructor function to be recognised by this keyword:

```javascript
class MyClass {}
const instanceofDef = require("ajv-keywords/dist/definitions/instanceof")
instanceofDef.CONSTRUCTORS.MyClass = MyClass
ajv.validate({instanceof: "MyClass"}, new MyClass()) // true
```

**Please note**: currently `instanceof` is not supported in [standalone validation code](https://github.com/ajv-validator/ajv/blob/master/docs/standalone.md) - it has to be implemented as [`code` keyword](https://github.com/ajv-validator/ajv/blob/master/docs/keywords.md#define-keyword-with-code-generation-function) to support it (PR is welcome).

### Keywords for numbers

#### `range` and `exclusiveRange`

Syntax sugar for the combination of minimum and maximum keywords (or exclusiveMinimum and exclusiveMaximum), also fails schema compilation if there are no numbers in the range.

The value of these keywords must be an array consisting of two numbers, the second must be greater or equal than the first one.

If the validated value is not a number the validation passes, otherwise to pass validation the value should be greater (or equal) than the first number and smaller (or equal) than the second number in the array.

```javascript
const schema = {type: "number", range: [1, 3]}
ajv.validate(schema, 1) // true
ajv.validate(schema, 2) // true
ajv.validate(schema, 3) // true
ajv.validate(schema, 0.99) // false
ajv.validate(schema, 3.01) // false

const schema = {type: "number", exclusiveRange: [1, 3]}
ajv.validate(schema, 1.01) // true
ajv.validate(schema, 2) // true
ajv.validate(schema, 2.99) // true
ajv.validate(schema, 1) // false
ajv.validate(schema, 3) // false
```

### Keywords for strings

#### `regexp`

This keyword allows to use regular expressions with flags in schemas, and also without `"u"` flag when needed (the standard `pattern` keyword does not support flags and implies the presence of `"u"` flag).

This keyword applies only to strings. If the data is not a string, the validation succeeds.

The value of this keyword can be either a string (the result of `regexp.toString()`) or an object with the properties `pattern` and `flags` (the same strings that should be passed to RegExp constructor).

```javascript
const schema = {
  type: "object",
  properties: {
    foo: {type: "string", regexp: "/foo/i"},
    bar: {type: "string", regexp: {pattern: "bar", flags: "i"}},
  },
}

const validData = {
  foo: "Food",
  bar: "Barmen",
}

const invalidData = {
  foo: "fog",
  bar: "bad",
}
```

#### `transform`

This keyword allows a string to be modified during validation.

This keyword applies only to strings. If the data is not a string, the `transform` keyword is ignored.

A standalone string cannot be modified, i.e. `data = 'a'; ajv.validate(schema, data);`, because strings are passed by value

**Supported transformations:**

- `trim`: remove whitespace from start and end
- `trimStart`/`trimLeft`: remove whitespace from start
- `trimEnd`/`trimRight`: remove whitespace from end
- `toLowerCase`: convert to lower case
- `toUpperCase`: convert to upper case
- `toEnumCase`: change string case to be equal to one of `enum` values in the schema

Transformations are applied in the order they are listed.

Note: `toEnumCase` requires that all allowed values are unique when case insensitive.

**Example: multiple transformations**

```javascript
require("ajv-keywords")(ajv, "transform")

const schema = {
  type: "array",
  items: {
    type: "string",
    transform: ["trim", "toLowerCase"],
  },
}

const data = ["  MixCase  "]
ajv.validate(schema, data)
console.log(data) // ['mixcase']
```

**Example: `enumcase`**

```javascript
require("ajv-keywords")(ajv, ["transform"])

const schema = {
  type: "array",
  items: {
    type: "string",
    transform: ["trim", "toEnumCase"],
    enum: ["pH"],
  },
}

const data = ["ph", " Ph", "PH", "pH "]
ajv.validate(schema, data)
console.log(data) // ['pH','pH','pH','pH']
```

### Keywords for arrays

#### `uniqueItemProperties`

The keyword allows to check that some properties in array items are unique.

This keyword applies only to arrays. If the data is not an array, the validation succeeds.

The value of this keyword must be an array of strings - property names that should have unique values across all items.

```javascript
const schema = {
  type: "array",
  uniqueItemProperties: ["id", "name"],
}

const validData = [{id: 1}, {id: 2}, {id: 3}]

const invalidData1 = [
  {id: 1},
  {id: 1}, // duplicate "id"
  {id: 3},
]

const invalidData2 = [
  {id: 1, name: "taco"},
  {id: 2, name: "taco"}, // duplicate "name"
  {id: 3, name: "salsa"},
]
```

This keyword is contributed by [@blainesch](https://github.com/blainesch).

**Please note**: currently `uniqueItemProperties` is not supported in [standalone validation code](https://github.com/ajv-validator/ajv/blob/master/docs/standalone.md) - it has to be implemented as [`code` keyword](https://github.com/ajv-validator/ajv/blob/master/docs/keywords.md#define-keyword-with-code-generation-function) to support it (PR is welcome).

### Keywords for objects

#### `allRequired`

This keyword allows to require the presence of all properties used in `properties` keyword in the same schema object.

This keyword applies only to objects. If the data is not an object, the validation succeeds.

The value of this keyword must be boolean.

If the value of the keyword is `false`, the validation succeeds.

If the value of the keyword is `true`, the validation succeeds if the data contains all properties defined in `properties` keyword (in the same schema object).

If the `properties` keyword is not present in the same schema object, schema compilation will throw exception.

```javascript
const schema = {
  type: "object",
  properties: {
    foo: {type: "number"},
    bar: {type: "number"},
  },
  allRequired: true,
}

const validData = {foo: 1, bar: 2}
const alsoValidData = {foo: 1, bar: 2, baz: 3}

const invalidDataList = [{}, {foo: 1}, {bar: 2}]
```

#### `anyRequired`

This keyword allows to require the presence of any (at least one) property from the list.

This keyword applies only to objects. If the data is not an object, the validation succeeds.

The value of this keyword must be an array of strings, each string being a property name. For data object to be valid at least one of the properties in this array should be present in the object.

```javascript
const schema = {
  type: "object",
  anyRequired: ["foo", "bar"],
}

const validData = {foo: 1}
const alsoValidData = {foo: 1, bar: 2}

const invalidDataList = [{}, {baz: 3}]
```

#### `oneRequired`

This keyword allows to require the presence of only one property from the list.

This keyword applies only to objects. If the data is not an object, the validation succeeds.

The value of this keyword must be an array of strings, each string being a property name. For data object to be valid exactly one of the properties in this array should be present in the object.

```javascript
const schema = {
  type: "object",
  oneRequired: ["foo", "bar"],
}

const validData = {foo: 1}
const alsoValidData = {bar: 2, baz: 3}

const invalidDataList = [{}, {baz: 3}, {foo: 1, bar: 2}]
```

#### `patternRequired`

This keyword allows to require the presence of properties that match some pattern(s).

This keyword applies only to objects. If the data is not an object, the validation succeeds.

The value of this keyword should be an array of strings, each string being a regular expression. For data object to be valid each regular expression in this array should match at least one property name in the data object.

If the array contains multiple regular expressions, more than one expression can match the same property name.

```javascript
const schema = {
  type: "object",
  patternRequired: ["f.*o", "b.*r"],
}

const validData = {foo: 1, bar: 2}
const alsoValidData = {foobar: 3}

const invalidDataList = [{}, {foo: 1}, {bar: 2}]
```

#### `prohibited`

This keyword allows to prohibit that any of the properties in the list is present in the object.

This keyword applies only to objects. If the data is not an object, the validation succeeds.

The value of this keyword should be an array of strings, each string being a property name. For data object to be valid none of the properties in this array should be present in the object.

```javascript
const schema = {
  type: "object",
  prohibited: ["foo", "bar"],
}

const validData = {baz: 1}
const alsoValidData = {}

const invalidDataList = [{foo: 1}, {bar: 2}, {foo: 1, bar: 2}]
```

**Please note**: `{prohibited: ['foo', 'bar']}` is equivalent to `{not: {anyRequired: ['foo', 'bar']}}` (i.e. it has the same validation result for any data).

#### `deepProperties`

This keyword allows to validate deep properties (identified by JSON pointers).

This keyword applies only to objects. If the data is not an object, the validation succeeds.

The value should be an object, where keys are JSON pointers to the data, starting from the current position in data, and the values are JSON schemas. For data object to be valid the value of each JSON pointer should be valid according to the corresponding schema.

```javascript
const schema = {
  type: "object",
  deepProperties: {
    "/users/1/role": {enum: ["admin"]},
  },
}

const validData = {
  users: [
    {},
    {
      id: 123,
      role: "admin",
    },
  ],
}

const alsoValidData = {
  users: {
    1: {
      id: 123,
      role: "admin",
    },
  },
}

const invalidData = {
  users: [
    {},
    {
      id: 123,
      role: "user",
    },
  ],
}

const alsoInvalidData = {
  users: {
    1: {
      id: 123,
      role: "user",
    },
  },
}
```

#### `deepRequired`

This keyword allows to check that some deep properties (identified by JSON pointers) are available.

This keyword applies only to objects. If the data is not an object, the validation succeeds.

The value should be an array of JSON pointers to the data, starting from the current position in data. For data object to be valid each JSON pointer should be some existing part of the data.

```javascript
const schema = {
  type: "object",
  deepRequired: ["/users/1/role"],
}

const validData = {
  users: [
    {},
    {
      id: 123,
      role: "admin",
    },
  ],
}

const invalidData = {
  users: [
    {},
    {
      id: 123,
    },
  ],
}
```

See [json-schema-org/json-schema-spec#203](https://github.com/json-schema-org/json-schema-spec/issues/203#issue-197211916) for an example of the equivalent schema without `deepRequired` keyword.

### Keywords for all types

#### `select`/`selectCases`/`selectDefault`

**Please note**: these keywords are deprecated. It is recommended to use OpenAPI [discriminator](https://ajv.js.org/json-schema.html#discriminator) keyword supported by Ajv v8 instead of `select`.

These keywords allow to choose the schema to validate the data based on the value of some property in the validated data.

These keywords must be present in the same schema object (`selectDefault` is optional).

The value of `select` keyword should be a [\$data reference](https://github.com/ajv-validator/ajv/blob/master/docs/validation.md#data-reference) that points to any primitive JSON type (string, number, boolean or null) in the data that is validated. You can also use a constant of primitive type as the value of this keyword (e.g., for debugging purposes).

The value of `selectCases` keyword must be an object where each property name is a possible string representation of the value of `select` keyword and each property value is a corresponding schema (from draft-06 it can be boolean) that must be used to validate the data.

The value of `selectDefault` keyword is a schema (also can be boolean) that must be used to validate the data in case `selectCases` has no key equal to the stringified value of `select` keyword.

The validation succeeds in one of the following cases:

- the validation of data using selected schema succeeds,
- none of the schemas is selected for validation,
- the value of select is undefined (no property in the data that the data reference points to).

If `select` value (in data) is not a primitive type the validation fails.

This keyword correctly tracks evaluated properties and items to work with `unevaluatedProperties` and `unevaluatedItems` keywords - only properties and items from the subschema that was used (one of `selectCases` subschemas or `selectDefault` subschema) are marked as evaluated.

**Please note**: these keywords require Ajv `$data` option to support [\$data reference](https://github.com/ajv-validator/ajv/blob/master/docs/validation.md#data-reference).

```javascript
require("ajv-keywords")(ajv, "select")

const schema = {
  type: "object",
  required: ["kind"],
  properties: {
    kind: {type: "string"},
  },
  select: {$data: "0/kind"},
  selectCases: {
    foo: {
      required: ["foo"],
      properties: {
        kind: {},
        foo: {type: "string"},
      },
      additionalProperties: false,
    },
    bar: {
      required: ["bar"],
      properties: {
        kind: {},
        bar: {type: "number"},
      },
      additionalProperties: false,
    },
  },
  selectDefault: {
    propertyNames: {
      not: {enum: ["foo", "bar"]},
    },
  },
}

const validDataList = [
  {kind: "foo", foo: "any"},
  {kind: "bar", bar: 1},
  {kind: "anything_else", not_bar_or_foo: "any value"},
]

const invalidDataList = [
  {kind: "foo"}, // no property foo
  {kind: "bar"}, // no property bar
  {kind: "foo", foo: "any", another: "any value"}, // additional property
  {kind: "bar", bar: 1, another: "any value"}, // additional property
  {kind: "anything_else", foo: "any"}, // property foo not allowed
  {kind: "anything_else", bar: 1}, // property bar not allowed
]
```

#### `dynamicDefaults`

This keyword allows to assign dynamic defaults to properties, such as timestamps, unique IDs etc.

This keyword only works if `useDefaults` options is used and not inside `anyOf` keywords etc., in the same way as [default keyword treated by Ajv](https://github.com/epoberezkin/ajv#assigning-defaults).

The keyword should be added on the object level. Its value should be an object with each property corresponding to a property name, in the same way as in standard `properties` keyword. The value of each property can be:

- an identifier of dynamic default function (a string)
- an object with properties `func` (an identifier) and `args` (an object with parameters that will be passed to this function during schema compilation - see examples).

The properties used in `dynamicDefaults` should not be added to `required` keyword in the same schema (or validation will fail), because unlike `default` this keyword is processed after validation.

There are several predefined dynamic default functions:

- `"timestamp"` - current timestamp in milliseconds
- `"datetime"` - current date and time as string (ISO, valid according to `date-time` format)
- `"date"` - current date as string (ISO, valid according to `date` format)
- `"time"` - current time as string (ISO, valid according to `time` format)
- `"random"` - pseudo-random number in [0, 1) interval
- `"randomint"` - pseudo-random integer number. If string is used as a property value, the function will randomly return 0 or 1. If object `{ func: 'randomint', args: { max: N } }` is used then the default will be an integer number in [0, N) interval.
- `"seq"` - sequential integer number starting from 0. If string is used as a property value, the default sequence will be used. If object `{ func: 'seq', args: { name: 'foo'} }` is used then the sequence with name `"foo"` will be used. Sequences are global, even if different ajv instances are used.

```javascript
const schema = {
  type: "object",
  dynamicDefaults: {
    ts: "datetime",
    r: {func: "randomint", args: {max: 100}},
    id: {func: "seq", args: {name: "id"}},
  },
  properties: {
    ts: {
      type: "string",
      format: "date-time",
    },
    r: {
      type: "integer",
      minimum: 0,
      exclusiveMaximum: 100,
    },
    id: {
      type: "integer",
      minimum: 0,
    },
  },
}

const data = {}
ajv.validate(data) // true
data // { ts: '2016-12-01T22:07:28.829Z', r: 25, id: 0 }

const data1 = {}
ajv.validate(data1) // true
data1 // { ts: '2016-12-01T22:07:29.832Z', r: 68, id: 1 }

ajv.validate(data1) // true
data1 // didn't change, as all properties were defined
```

When using the `useDefaults` option value `"empty"`, properties and items equal to `null` or `""` (empty string) will be considered missing and assigned defaults. Use `allOf` [compound keyword](https://github.com/epoberezkin/ajv/blob/master/KEYWORDS.md#compound-keywords) to execute `dynamicDefaults` before validation.

```javascript
const schema = {
  type: "object",
  allOf: [
    {
      dynamicDefaults: {
        ts: "datetime",
        r: {func: "randomint", args: {min: 5, max: 100}},
        id: {func: "seq", args: {name: "id"}},
      },
    },
    {
      properties: {
        ts: {
          type: "string",
        },
        r: {
          type: "number",
          minimum: 5,
          exclusiveMaximum: 100,
        },
        id: {
          type: "integer",
          minimum: 0,
        },
      },
    },
  ],
}

const data = {ts: "", r: null}
ajv.validate(data) // true
data // { ts: '2016-12-01T22:07:28.829Z', r: 25, id: 0 }
```

You can add your own dynamic default function to be recognised by this keyword:

```javascript
const uuid = require("uuid")

const def = require("ajv-keywords/dist/definitions/dynamicDefaults")
def.DEFAULTS.uuid = () => uuid.v4

const schema = {
  dynamicDefaults: {id: "uuid"},
  properties: {id: {type: "string", format: "uuid"}},
}

const data = {}
ajv.validate(schema, data) // true
data // { id: 'a1183fbe-697b-4030-9bcc-cfeb282a9150' };

const data1 = {}
ajv.validate(schema, data1) // true
data1 // { id: '5b008de7-1669-467a-a5c6-70fa244d7209' }
```

You also can define dynamic default that accept parameters, e.g. version of uuid:

```javascript
const uuid = require("uuid")

function getUuid(args) {
  const version = "v" + ((arvs && args.v) || "4")
  return uuid[version]
}

const def = require("ajv-keywords/dist/definitions/dynamicDefaults")
def.DEFAULTS.uuid = getUuid

const schema = {
  dynamicDefaults: {
    id1: "uuid", // v4
    id2: {func: "uuid", v: 4}, // v4
    id3: {func: "uuid", v: 1}, // v1
  },
}
```

**Please note**: dynamic default functions are differentiated by the number of parameters they have (`function.length`). Functions that do not expect default must have one non-optional argument so that `function.length` > 0.

`dynamicDefaults` is not supported in [standalone validation code](https://github.com/ajv-validator/ajv/blob/master/docs/standalone.md).

## Security contact

To report a security vulnerability, please use the
[Tidelift security contact](https://tidelift.com/security).
Tidelift will coordinate the fix and disclosure.

Please do NOT report security vulnerabilities via GitHub issues.

## Open-source software support

Ajv-keywords is a part of [Tidelift subscription](https://tidelift.com/subscription/pkg/npm-ajv-keywords?utm_source=npm-ajv-keywords&utm_medium=referral&utm_campaign=readme) - it provides a centralised support to open-source software users, in addition to the support provided by software maintainers.

## License

[MIT](https://github.com/epoberezkin/ajv-keywords/blob/master/LICENSE)


code:
import type { MacroKeywordDefinition } from "ajv";
import type { GetDefinition } from "./_types";
declare type RangeKwd = "range" | "exclusiveRange";
export default function getRangeDef(keyword: RangeKwd): GetDefinition<MacroKeywordDefinition>;
export {};


code:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function getRangeDef(keyword) {
    return () => ({
        keyword,
        type: "number",
        schemaType: "array",
        macro: function ([min, max]) {
            validateRangeSchema(min, max);
            return keyword === "range"
                ? { minimum: min, maximum: max }
                : { exclusiveMinimum: min, exclusiveMaximum: max };
        },
        metaSchema: {
            type: "array",
            minItems: 2,
            maxItems: 2,
            items: { type: "number" },
        },
    });
    function validateRangeSchema(min, max) {
        if (min > max || (keyword === "exclusiveRange" && min === max)) {
            throw new Error("There are no numbers in range");
        }
    }
}
exports.default = getRangeDef;
//# sourceMappingURL=_range.js.map


code:
import type { MacroKeywordDefinition } from "ajv";
import type { GetDefinition } from "./_types";
declare type RequiredKwd = "anyRequired" | "oneRequired";
export default function getRequiredDef(keyword: RequiredKwd): GetDefinition<MacroKeywordDefinition>;
export {};


code:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function getRequiredDef(keyword) {
    return () => ({
        keyword,
        type: "object",
        schemaType: "array",
        macro(schema) {
            if (schema.length === 0)
                return true;
            if (schema.length === 1)
                return { required: schema };
            const comb = keyword === "anyRequired" ? "anyOf" : "oneOf";
            return { [comb]: schema.map((p) => ({ required: [p] })) };
        },
        metaSchema: {
            type: "array",
            items: { type: "string" },
        },
    });
}
exports.default = getRequiredDef;
//# sourceMappingURL=_required.js.map


code:
import type { KeywordDefinition } from "ajv";
export interface DefinitionOptions {
    defaultMeta?: string | boolean;
}
export declare type GetDefinition<T extends KeywordDefinition> = (opts?: DefinitionOptions) => T;


code:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=_types.js.map


code:
import type { DefinitionOptions } from "./_types";
import type { SchemaObject, KeywordCxt, Name } from "ajv";
export declare function metaSchemaRef({ defaultMeta }?: DefinitionOptions): SchemaObject;
export declare function usePattern({ gen, it: { opts } }: KeywordCxt, pattern: string, flags?: string): Name;


code:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.usePattern = exports.metaSchemaRef = void 0;
const codegen_1 = require("ajv/dist/compile/codegen");
const META_SCHEMA_ID = "http://json-schema.org/schema";
function metaSchemaRef({ defaultMeta } = {}) {
    return defaultMeta === false ? {} : { $ref: defaultMeta || META_SCHEMA_ID };
}
exports.metaSchemaRef = metaSchemaRef;
function usePattern({ gen, it: { opts } }, pattern, flags = opts.unicodeRegExp ? "u" : "") {
    const rx = new RegExp(pattern, flags);
    return gen.scopeValue("pattern", {
        key: rx.toString(),
        ref: rx,
        code: (0, codegen_1._) `new RegExp(${pattern}, ${flags})`,
    });
}
exports.usePattern = usePattern;
//# sourceMappingURL=_util.js.map


code:
import type { MacroKeywordDefinition } from "ajv";
export default function getDef(): MacroKeywordDefinition;


code:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function getDef() {
    return {
        keyword: "allRequired",
        type: "object",
        schemaType: "boolean",
        macro(schema, parentSchema) {
            if (!schema)
                return true;
            const required = Object.keys(parentSchema.properties);
            if (required.length === 0)
                return true;
            return { required };
        },
        dependencies: ["properties"],
    };
}
exports.default = getDef;
module.exports = getDef;
//# sourceMappingURL=allRequired.js.map


code:
import type { MacroKeywordDefinition } from "ajv";
import type { GetDefinition } from "./_types";
declare const getDef: GetDefinition<MacroKeywordDefinition>;
export default getDef;


code:
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const _required_1 = __importDefault(require("./_required"));
const getDef = (0, _required_1.default)("anyRequired");
exports.default = getDef;
module.exports = getDef;
//# sourceMappingURL=anyRequired.js.map


code:
import type { MacroKeywordDefinition } from "ajv";
import type { DefinitionOptions } from "./_types";
export default function getDef(opts?: DefinitionOptions): MacroKeywordDefinition;


code:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const _util_1 = require("./_util");
function getDef(opts) {
    return {
        keyword: "deepProperties",
        type: "object",
        schemaType: "object",
        macro: function (schema) {
            const allOf = [];
            for (const pointer in schema)
                allOf.push(getSchema(pointer, schema[pointer]));
            return { allOf };
        },
        metaSchema: {
            type: "object",
            propertyNames: { type: "string", format: "json-pointer" },
            additionalProperties: (0, _util_1.metaSchemaRef)(opts),
        },
    };
}
exports.default = getDef;
function getSchema(jsonPointer, schema) {
    const segments = jsonPointer.split("/");
    const rootSchema = {};
    let pointerSchema = rootSchema;
    for (let i = 1; i < segments.length; i++) {
        let segment = segments[i];
        const isLast = i === segments.length - 1;
        segment = unescapeJsonPointer(segment);
        const properties = (pointerSchema.properties = {});
        let items;
        if (/[0-9]+/.test(segment)) {
            let count = +segment;
            items = pointerSchema.items = [];
            pointerSchema.type = ["object", "array"];
            while (count--)
                items.push({});
        }
        else {
            pointerSchema.type = "object";
        }
        pointerSchema = isLast ? schema : {};
        properties[segment] = pointerSchema;
        if (items)
            items.push(pointerSchema);
    }
    return rootSchema;
}
function unescapeJsonPointer(str) {
    return str.replace(/~1/g, "/").replace(/~0/g, "~");
}
module.exports = getDef;
//# sourceMappingURL=deepProperties.js.map


code:
import type { CodeKeywordDefinition } from "ajv";
export default function getDef(): CodeKeywordDefinition;


code:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const codegen_1 = require("ajv/dist/compile/codegen");
function getDef() {
    return {
        keyword: "deepRequired",
        type: "object",
        schemaType: "array",
        code(ctx) {
            const { schema, data } = ctx;
            const props = schema.map((jp) => (0, codegen_1._) `(${getData(jp)}) === undefined`);
            ctx.fail((0, codegen_1.or)(...props));
            function getData(jsonPointer) {
                if (jsonPointer === "")
                    throw new Error("empty JSON pointer not allowed");
                const segments = jsonPointer.split("/");
                let x = data;
                const xs = segments.map((s, i) => i ? (x = (0, codegen_1._) `${x}${(0, codegen_1.getProperty)(unescapeJPSegment(s))}`) : x);
                return (0, codegen_1.and)(...xs);
            }
        },
        metaSchema: {
            type: "array",
            items: { type: "string", format: "json-pointer" },
        },
    };
}
exports.default = getDef;
function unescapeJPSegment(s) {
    return s.replace(/~1/g, "/").replace(/~0/g, "~");
}
module.exports = getDef;
//# sourceMappingURL=deepRequired.js.map


code:
import type { FuncKeywordDefinition } from "ajv";
export declare type DynamicDefaultFunc = (args?: Record<string, any>) => () => any;
declare const DEFAULTS: Record<string, DynamicDefaultFunc | undefined>;
declare const getDef: (() => FuncKeywordDefinition) & {
    DEFAULTS: typeof DEFAULTS;
};
export default getDef;


code:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const sequences = {};
const DEFAULTS = {
    timestamp: () => () => Date.now(),
    datetime: () => () => new Date().toISOString(),
    date: () => () => new Date().toISOString().slice(0, 10),
    time: () => () => new Date().toISOString().slice(11),
    random: () => () => Math.random(),
    randomint: (args) => {
        var _a;
        const max = (_a = args === null || args === void 0 ? void 0 : args.max) !== null && _a !== void 0 ? _a : 2;
        return () => Math.floor(Math.random() * max);
    },
    seq: (args) => {
        var _a;
        const name = (_a = args === null || args === void 0 ? void 0 : args.name) !== null && _a !== void 0 ? _a : "";
        sequences[name] || (sequences[name] = 0);
        return () => sequences[name]++;
    },
};
const getDef = Object.assign(_getDef, { DEFAULTS });
function _getDef() {
    return {
        keyword: "dynamicDefaults",
        type: "object",
        schemaType: ["string", "object"],
        modifying: true,
        valid: true,
        compile(schema, _parentSchema, it) {
            if (!it.opts.useDefaults || it.compositeRule)
                return () => true;
            const fs = {};
            for (const key in schema)
                fs[key] = getDefault(schema[key]);
            const empty = it.opts.useDefaults === "empty";
            return (data) => {
                for (const prop in schema) {
                    if (data[prop] === undefined || (empty && (data[prop] === null || data[prop] === ""))) {
                        data[prop] = fs[prop]();
                    }
                }
                return true;
            };
        },
        metaSchema: {
            type: "object",
            additionalProperties: {
                anyOf: [
                    { type: "string" },
                    {
                        type: "object",
                        additionalProperties: false,
                        required: ["func", "args"],
                        properties: {
                            func: { type: "string" },
                            args: { type: "object" },
                        },
                    },
                ],
            },
        },
    };
}
function getDefault(d) {
    return typeof d == "object" ? getObjDefault(d) : getStrDefault(d);
}
function getObjDefault({ func, args }) {
    const def = DEFAULTS[func];
    assertDefined(func, def);
    return def(args);
}
function getStrDefault(d = "") {
    const def = DEFAULTS[d];
    assertDefined(d, def);
    return def();
}
function assertDefined(name, def) {
    if (!def)
        throw new Error(`invalid "dynamicDefaults" keyword property value: ${name}`);
}
exports.default = getDef;
module.exports = getDef;
//# sourceMappingURL=dynamicDefaults.js.map


code:
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const _range_1 = __importDefault(require("./_range"));
const getDef = (0, _range_1.default)("exclusiveRange");
exports.default = getDef;
module.exports = getDef;
//# sourceMappingURL=exclusiveRange.js.map


code:
import type { Vocabulary, ErrorNoParams } from "ajv";
import type { DefinitionOptions } from "./_types";
import { PatternRequiredError } from "./patternRequired";
import { SelectError } from "./select";
export default function ajvKeywords(opts?: DefinitionOptions): Vocabulary;
export declare type AjvKeywordsError = PatternRequiredError | SelectError | ErrorNoParams<"range" | "exclusiveRange" | "anyRequired" | "oneRequired" | "allRequired" | "deepProperties" | "deepRequired" | "dynamicDefaults" | "instanceof" | "prohibited" | "regexp" | "transform" | "uniqueItemProperties">;


code:
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const typeof_1 = __importDefault(require("./typeof"));
const instanceof_1 = __importDefault(require("./instanceof"));
const range_1 = __importDefault(require("./range"));
const exclusiveRange_1 = __importDefault(require("./exclusiveRange"));
const regexp_1 = __importDefault(require("./regexp"));
const transform_1 = __importDefault(require("./transform"));
const uniqueItemProperties_1 = __importDefault(require("./uniqueItemProperties"));
const allRequired_1 = __importDefault(require("./allRequired"));
const anyRequired_1 = __importDefault(require("./anyRequired"));
const oneRequired_1 = __importDefault(require("./oneRequired"));
const patternRequired_1 = __importDefault(require("./patternRequired"));
const prohibited_1 = __importDefault(require("./prohibited"));
const deepProperties_1 = __importDefault(require("./deepProperties"));
const deepRequired_1 = __importDefault(require("./deepRequired"));
const dynamicDefaults_1 = __importDefault(require("./dynamicDefaults"));
const select_1 = __importDefault(require("./select"));
const definitions = [
    typeof_1.default,
    instanceof_1.default,
    range_1.default,
    exclusiveRange_1.default,
    regexp_1.default,
    transform_1.default,
    uniqueItemProperties_1.default,
    allRequired_1.default,
    anyRequired_1.default,
    oneRequired_1.default,
    patternRequired_1.default,
    prohibited_1.default,
    deepProperties_1.default,
    deepRequired_1.default,
    dynamicDefaults_1.default,
];
function ajvKeywords(opts) {
    return definitions.map((d) => d(opts)).concat((0, select_1.default)(opts));
}
exports.default = ajvKeywords;
module.exports = ajvKeywords;
//# sourceMappingURL=index.js.map


code:
import type { FuncKeywordDefinition } from "ajv";
declare type Constructor = new (...args: any[]) => any;
declare const CONSTRUCTORS: Record<string, Constructor | undefined>;
declare const getDef: (() => FuncKeywordDefinition) & {
    CONSTRUCTORS: typeof CONSTRUCTORS;
};
export default getDef;


code:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const CONSTRUCTORS = {
    Object,
    Array,
    Function,
    Number,
    String,
    Date,
    RegExp,
};
/* istanbul ignore else */
if (typeof Buffer != "undefined")
    CONSTRUCTORS.Buffer = Buffer;
/* istanbul ignore else */
if (typeof Promise != "undefined")
    CONSTRUCTORS.Promise = Promise;
const getDef = Object.assign(_getDef, { CONSTRUCTORS });
function _getDef() {
    return {
        keyword: "instanceof",
        schemaType: ["string", "array"],
        compile(schema) {
            if (typeof schema == "string") {
                const C = getConstructor(schema);
                return (data) => data instanceof C;
            }
            if (Array.isArray(schema)) {
                const constructors = schema.map(getConstructor);
                return (data) => {
                    for (const C of constructors) {
                        if (data instanceof C)
                            return true;
                    }
                    return false;
                };
            }
            /* istanbul ignore next */
            throw new Error("ajv implementation error");
        },
        metaSchema: {
            anyOf: [{ type: "string" }, { type: "array", items: { type: "string" } }],
        },
    };
}
function getConstructor(c) {
    const C = CONSTRUCTORS[c];
    if (C)
        return C;
    throw new Error(`invalid "instanceof" keyword value ${c}`);
}
exports.default = getDef;
module.exports = getDef;
//# sourceMappingURL=instanceof.js.map


code:
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const _required_1 = __importDefault(require("./_required"));
const getDef = (0, _required_1.default)("oneRequired");
exports.default = getDef;
module.exports = getDef;
//# sourceMappingURL=oneRequired.js.map


code:
import type { CodeKeywordDefinition, ErrorObject } from "ajv";
export declare type PatternRequiredError = ErrorObject<"patternRequired", {
    missingPattern: string;
}>;
export default function getDef(): CodeKeywordDefinition;


code:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const codegen_1 = require("ajv/dist/compile/codegen");
const _util_1 = require("./_util");
const error = {
    message: ({ params: { missingPattern } }) => (0, codegen_1.str) `should have property matching pattern '${missingPattern}'`,
    params: ({ params: { missingPattern } }) => (0, codegen_1._) `{missingPattern: ${missingPattern}}`,
};
function getDef() {
    return {
        keyword: "patternRequired",
        type: "object",
        schemaType: "array",
        error,
        code(cxt) {
            const { gen, schema, data } = cxt;
            if (schema.length === 0)
                return;
            const valid = gen.let("valid", true);
            for (const pat of schema)
                validateProperties(pat);
            function validateProperties(pattern) {
                const matched = gen.let("matched", false);
                gen.forIn("key", data, (key) => {
                    gen.assign(matched, (0, codegen_1._) `${(0, _util_1.usePattern)(cxt, pattern)}.test(${key})`);
                    gen.if(matched, () => gen.break());
                });
                cxt.setParams({ missingPattern: pattern });
                gen.assign(valid, (0, codegen_1.and)(valid, matched));
                cxt.pass(valid);
            }
        },
        metaSchema: {
            type: "array",
            items: { type: "string", format: "regex" },
            uniqueItems: true,
        },
    };
}
exports.default = getDef;
module.exports = getDef;
//# sourceMappingURL=patternRequired.js.map


code:
import type { MacroKeywordDefinition } from "ajv";
export default function getDef(): MacroKeywordDefinition;


code:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function getDef() {
    return {
        keyword: "prohibited",
        type: "object",
        schemaType: "array",
        macro: function (schema) {
            if (schema.length === 0)
                return true;
            if (schema.length === 1)
                return { not: { required: schema } };
            return { not: { anyOf: schema.map((p) => ({ required: [p] })) } };
        },
        metaSchema: {
            type: "array",
            items: { type: "string" },
        },
    };
}
exports.default = getDef;
module.exports = getDef;
//# sourceMappingURL=prohibited.js.map


code:
import type { MacroKeywordDefinition } from "ajv";
import type { GetDefinition } from "./_types";
declare const getDef: GetDefinition<MacroKeywordDefinition>;
export default getDef;


code:
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const _range_1 = __importDefault(require("./_range"));
const getDef = (0, _range_1.default)("range");
exports.default = getDef;
module.exports = getDef;
//# sourceMappingURL=range.js.map


code:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const codegen_1 = require("ajv/dist/compile/codegen");
const _util_1 = require("./_util");
const regexpMetaSchema = {
    type: "object",
    properties: {
        pattern: { type: "string" },
        flags: { type: "string", nullable: true },
    },
    required: ["pattern"],
    additionalProperties: false,
};
const metaRegexp = /^\/(.*)\/([gimuy]*)$/;
function getDef() {
    return {
        keyword: "regexp",
        type: "string",
        schemaType: ["string", "object"],
        code(cxt) {
            const { data, schema } = cxt;
            const regx = getRegExp(schema);
            cxt.pass((0, codegen_1._) `${regx}.test(${data})`);
            function getRegExp(sch) {
                if (typeof sch == "object")
                    return (0, _util_1.usePattern)(cxt, sch.pattern, sch.flags);
                const rx = metaRegexp.exec(sch);
                if (rx)
                    return (0, _util_1.usePattern)(cxt, rx[1], rx[2]);
                throw new Error("cannot parse string into RegExp");
            }
        },
        metaSchema: {
            anyOf: [{ type: "string" }, regexpMetaSchema],
        },
    };
}
exports.default = getDef;
module.exports = getDef;
//# sourceMappingURL=regexp.js.map


code:
import type { KeywordDefinition, ErrorObject } from "ajv";
import type { DefinitionOptions } from "./_types";
export declare type SelectError = ErrorObject<"select", {
    failingCase?: string;
    failingDefault?: true;
}>;
export default function getDef(opts?: DefinitionOptions): KeywordDefinition[];


code:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const codegen_1 = require("ajv/dist/compile/codegen");
const _util_1 = require("./_util");
const error = {
    message: ({ params: { schemaProp } }) => schemaProp
        ? (0, codegen_1.str) `should match case "${schemaProp}" schema`
        : (0, codegen_1.str) `should match default case schema`,
    params: ({ params: { schemaProp } }) => schemaProp ? (0, codegen_1._) `{failingCase: ${schemaProp}}` : (0, codegen_1._) `{failingDefault: true}`,
};
function getDef(opts) {
    const metaSchema = (0, _util_1.metaSchemaRef)(opts);
    return [
        {
            keyword: "select",
            schemaType: ["string", "number", "boolean", "null"],
            $data: true,
            error,
            dependencies: ["selectCases"],
            code(cxt) {
                const { gen, schemaCode, parentSchema } = cxt;
                cxt.block$data(codegen_1.nil, () => {
                    const valid = gen.let("valid", true);
                    const schValid = gen.name("_valid");
                    const value = gen.const("value", (0, codegen_1._) `${schemaCode} === null ? "null" : ${schemaCode}`);
                    gen.if(false); // optimizer should remove it from generated code
                    for (const schemaProp in parentSchema.selectCases) {
                        cxt.setParams({ schemaProp });
                        gen.elseIf((0, codegen_1._) `"" + ${value} == ${schemaProp}`); // intentional ==, to match numbers and booleans
                        const schCxt = cxt.subschema({ keyword: "selectCases", schemaProp }, schValid);
                        cxt.mergeEvaluated(schCxt, codegen_1.Name);
                        gen.assign(valid, schValid);
                    }
                    gen.else();
                    if (parentSchema.selectDefault !== undefined) {
                        cxt.setParams({ schemaProp: undefined });
                        const schCxt = cxt.subschema({ keyword: "selectDefault" }, schValid);
                        cxt.mergeEvaluated(schCxt, codegen_1.Name);
                        gen.assign(valid, schValid);
                    }
                    gen.endIf();
                    cxt.pass(valid);
                });
            },
        },
        {
            keyword: "selectCases",
            dependencies: ["select"],
            metaSchema: {
                type: "object",
                additionalProperties: metaSchema,
            },
        },
        {
            keyword: "selectDefault",
            dependencies: ["select", "selectCases"],
            metaSchema,
        },
    ];
}
exports.default = getDef;
module.exports = getDef;
//# sourceMappingURL=select.js.map


code:
import type { CodeKeywordDefinition } from "ajv";
declare type TransformName = "trimStart" | "trimEnd" | "trimLeft" | "trimRight" | "trim" | "toLowerCase" | "toUpperCase" | "toEnumCase";
interface TransformConfig {
    hash: Record<string, string | undefined>;
}
declare type Transform = (s: string, cfg?: TransformConfig) => string;
declare const transform: {
    [key in TransformName]: Transform;
};
declare const getDef: (() => CodeKeywordDefinition) & {
    transform: typeof transform;
};
export default getDef;


code:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const codegen_1 = require("ajv/dist/compile/codegen");
const transform = {
    trimStart: (s) => s.trimStart(),
    trimEnd: (s) => s.trimEnd(),
    trimLeft: (s) => s.trimStart(),
    trimRight: (s) => s.trimEnd(),
    trim: (s) => s.trim(),
    toLowerCase: (s) => s.toLowerCase(),
    toUpperCase: (s) => s.toUpperCase(),
    toEnumCase: (s, cfg) => (cfg === null || cfg === void 0 ? void 0 : cfg.hash[configKey(s)]) || s,
};
const getDef = Object.assign(_getDef, { transform });
function _getDef() {
    return {
        keyword: "transform",
        schemaType: "array",
        before: "enum",
        code(cxt) {
            const { gen, data, schema, parentSchema, it } = cxt;
            const { parentData, parentDataProperty } = it;
            const tNames = schema;
            if (!tNames.length)
                return;
            let cfg;
            if (tNames.includes("toEnumCase")) {
                const config = getEnumCaseCfg(parentSchema);
                cfg = gen.scopeValue("obj", { ref: config, code: (0, codegen_1.stringify)(config) });
            }
            gen.if((0, codegen_1._) `typeof ${data} == "string" && ${parentData} !== undefined`, () => {
                gen.assign(data, transformExpr(tNames.slice()));
                gen.assign((0, codegen_1._) `${parentData}[${parentDataProperty}]`, data);
            });
            function transformExpr(ts) {
                if (!ts.length)
                    return data;
                const t = ts.pop();
                if (!(t in transform))
                    throw new Error(`transform: unknown transformation ${t}`);
                const func = gen.scopeValue("func", {
                    ref: transform[t],
                    code: (0, codegen_1._) `require("ajv-keywords/dist/definitions/transform").transform${(0, codegen_1.getProperty)(t)}`,
                });
                const arg = transformExpr(ts);
                return cfg && t === "toEnumCase" ? (0, codegen_1._) `${func}(${arg}, ${cfg})` : (0, codegen_1._) `${func}(${arg})`;
            }
        },
        metaSchema: {
            type: "array",
            items: { type: "string", enum: Object.keys(transform) },
        },
    };
}
function getEnumCaseCfg(parentSchema) {
    // build hash table to enum values
    const cfg = { hash: {} };
    // requires `enum` in the same schema as transform
    if (!parentSchema.enum)
        throw new Error('transform: "toEnumCase" requires "enum"');
    for (const v of parentSchema.enum) {
        if (typeof v !== "string")
            continue;
        const k = configKey(v);
        // requires all `enum` values have unique keys
        if (cfg.hash[k]) {
            throw new Error('transform: "toEnumCase" requires all lowercased "enum" values to be unique');
        }
        cfg.hash[k] = v;
    }
    return cfg;
}
function configKey(s) {
    return s.toLowerCase();
}
exports.default = getDef;
module.exports = getDef;
//# sourceMappingURL=transform.js.map


code:
import type { CodeKeywordDefinition } from "ajv";
export default function getDef(): CodeKeywordDefinition;


code:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const codegen_1 = require("ajv/dist/compile/codegen");
const TYPES = ["undefined", "string", "number", "object", "function", "boolean", "symbol"];
function getDef() {
    return {
        keyword: "typeof",
        schemaType: ["string", "array"],
        code(cxt) {
            const { data, schema, schemaValue } = cxt;
            cxt.fail(typeof schema == "string"
                ? (0, codegen_1._) `typeof ${data} != ${schema}`
                : (0, codegen_1._) `${schemaValue}.indexOf(typeof ${data}) < 0`);
        },
        metaSchema: {
            anyOf: [
                { type: "string", enum: TYPES },
                { type: "array", items: { type: "string", enum: TYPES } },
            ],
        },
    };
}
exports.default = getDef;
module.exports = getDef;
//# sourceMappingURL=typeof.js.map


code:
import type { FuncKeywordDefinition } from "ajv";
export default function getDef(): FuncKeywordDefinition;


code:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const equal = require("fast-deep-equal");
const SCALAR_TYPES = ["number", "integer", "string", "boolean", "null"];
function getDef() {
    return {
        keyword: "uniqueItemProperties",
        type: "array",
        schemaType: "array",
        compile(keys, parentSchema) {
            const scalar = getScalarKeys(keys, parentSchema);
            return (data) => {
                if (data.length <= 1)
                    return true;
                for (let k = 0; k < keys.length; k++) {
                    const key = keys[k];
                    if (scalar[k]) {
                        const hash = {};
                        for (const x of data) {
                            if (!x || typeof x != "object")
                                continue;
                            let p = x[key];
                            if (p && typeof p == "object")
                                continue;
                            if (typeof p == "string")
                                p = '"' + p;
                            if (hash[p])
                                return false;
                            hash[p] = true;
                        }
                    }
                    else {
                        for (let i = data.length; i--;) {
                            const x = data[i];
                            if (!x || typeof x != "object")
                                continue;
                            for (let j = i; j--;) {
                                const y = data[j];
                                if (y && typeof y == "object" && equal(x[key], y[key]))
                                    return false;
                            }
                        }
                    }
                }
                return true;
            };
        },
        metaSchema: {
            type: "array",
            items: { type: "string" },
        },
    };
}
exports.default = getDef;
function getScalarKeys(keys, schema) {
    return keys.map((key) => {
        var _a, _b, _c;
        const t = (_c = (_b = (_a = schema.items) === null || _a === void 0 ? void 0 : _a.properties) === null || _b === void 0 ? void 0 : _b[key]) === null || _c === void 0 ? void 0 : _c.type;
        return Array.isArray(t)
            ? !t.includes("object") && !t.includes("array")
            : SCALAR_TYPES.includes(t);
    });
}
module.exports = getDef;
//# sourceMappingURL=uniqueItemProperties.js.map


code:
import type { Plugin } from "ajv";
export { AjvKeywordsError } from "./definitions";
declare const ajvKeywords: Plugin<string | string[]>;
export default ajvKeywords;


code:
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const keywords_1 = __importDefault(require("./keywords"));
const ajvKeywords = (ajv, keyword) => {
    if (Array.isArray(keyword)) {
        for (const k of keyword)
            get(k)(ajv);
        return ajv;
    }
    if (keyword) {
        get(keyword)(ajv);
        return ajv;
    }
    for (keyword in keywords_1.default)
        get(keyword)(ajv);
    return ajv;
};
ajvKeywords.get = get;
function get(keyword) {
    const defFunc = keywords_1.default[keyword];
    if (!defFunc)
        throw new Error("Unknown keyword " + keyword);
    return defFunc;
}
exports.default = ajvKeywords;
module.exports = ajvKeywords;
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
module.exports.default = ajvKeywords;
//# sourceMappingURL=index.js.map


code:
import type { Plugin } from "ajv";
declare const allRequired: Plugin<undefined>;
export default allRequired;


code:
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const allRequired_1 = __importDefault(require("../definitions/allRequired"));
const allRequired = (ajv) => ajv.addKeyword((0, allRequired_1.default)());
exports.default = allRequired;
module.exports = allRequired;
//# sourceMappingURL=allRequired.js.map


code:
import type { Plugin } from "ajv";
declare const anyRequired: Plugin<undefined>;
export default anyRequired;


code:
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const anyRequired_1 = __importDefault(require("../definitions/anyRequired"));
const anyRequired = (ajv) => ajv.addKeyword((0, anyRequired_1.default)());
exports.default = anyRequired;
module.exports = anyRequired;
//# sourceMappingURL=anyRequired.js.map


code:
import type { Plugin } from "ajv";
import type { DefinitionOptions } from "../definitions/_types";
declare const deepProperties: Plugin<DefinitionOptions>;
export default deepProperties;


code:
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const deepProperties_1 = __importDefault(require("../definitions/deepProperties"));
const deepProperties = (ajv, opts) => ajv.addKeyword((0, deepProperties_1.default)(opts));
exports.default = deepProperties;
module.exports = deepProperties;
//# sourceMappingURL=deepProperties.js.map


code:
import type { Plugin } from "ajv";
declare const deepRequired: Plugin<undefined>;
export default deepRequired;


code:
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const deepRequired_1 = __importDefault(require("../definitions/deepRequired"));
const deepRequired = (ajv) => ajv.addKeyword((0, deepRequired_1.default)());
exports.default = deepRequired;
module.exports = deepRequired;
//# sourceMappingURL=deepRequired.js.map


code:
import type { Plugin } from "ajv";
declare const dynamicDefaults: Plugin<undefined>;
export default dynamicDefaults;


code:
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const dynamicDefaults_1 = __importDefault(require("../definitions/dynamicDefaults"));
const dynamicDefaults = (ajv) => ajv.addKeyword((0, dynamicDefaults_1.default)());
exports.default = dynamicDefaults;
module.exports = dynamicDefaults;
//# sourceMappingURL=dynamicDefaults.js.map


code:
import type { Plugin } from "ajv";
declare const exclusiveRange: Plugin<undefined>;
export default exclusiveRange;


code:
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const exclusiveRange_1 = __importDefault(require("../definitions/exclusiveRange"));
const exclusiveRange = (ajv) => ajv.addKeyword((0, exclusiveRange_1.default)());
exports.default = exclusiveRange;
module.exports = exclusiveRange;
//# sourceMappingURL=exclusiveRange.js.map


code:
import type { Plugin } from "ajv";
declare const ajvKeywords: Record<string, Plugin<any> | undefined>;
export default ajvKeywords;


code:
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const typeof_1 = __importDefault(require("./typeof"));
const instanceof_1 = __importDefault(require("./instanceof"));
const range_1 = __importDefault(require("./range"));
const exclusiveRange_1 = __importDefault(require("./exclusiveRange"));
const regexp_1 = __importDefault(require("./regexp"));
const transform_1 = __importDefault(require("./transform"));
const uniqueItemProperties_1 = __importDefault(require("./uniqueItemProperties"));
const allRequired_1 = __importDefault(require("./allRequired"));
const anyRequired_1 = __importDefault(require("./anyRequired"));
const oneRequired_1 = __importDefault(require("./oneRequired"));
const patternRequired_1 = __importDefault(require("./patternRequired"));
const prohibited_1 = __importDefault(require("./prohibited"));
const deepProperties_1 = __importDefault(require("./deepProperties"));
const deepRequired_1 = __importDefault(require("./deepRequired"));
const dynamicDefaults_1 = __importDefault(require("./dynamicDefaults"));
const select_1 = __importDefault(require("./select"));
// TODO type
const ajvKeywords = {
    typeof: typeof_1.default,
    instanceof: instanceof_1.default,
    range: range_1.default,
    exclusiveRange: exclusiveRange_1.default,
    regexp: regexp_1.default,
    transform: transform_1.default,
    uniqueItemProperties: uniqueItemProperties_1.default,
    allRequired: allRequired_1.default,
    anyRequired: anyRequired_1.default,
    oneRequired: oneRequired_1.default,
    patternRequired: patternRequired_1.default,
    prohibited: prohibited_1.default,
    deepProperties: deepProperties_1.default,
    deepRequired: deepRequired_1.default,
    dynamicDefaults: dynamicDefaults_1.default,
    select: select_1.default,
};
exports.default = ajvKeywords;
module.exports = ajvKeywords;
//# sourceMappingURL=index.js.map


code:
import type { Plugin } from "ajv";
declare const instanceofPlugin: Plugin<undefined>;
export default instanceofPlugin;


code:
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const instanceof_1 = __importDefault(require("../definitions/instanceof"));
const instanceofPlugin = (ajv) => ajv.addKeyword((0, instanceof_1.default)());
exports.default = instanceofPlugin;
module.exports = instanceofPlugin;
//# sourceMappingURL=instanceof.js.map


code:
import type { Plugin } from "ajv";
declare const oneRequired: Plugin<undefined>;
export default oneRequired;


code:
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const oneRequired_1 = __importDefault(require("../definitions/oneRequired"));
const oneRequired = (ajv) => ajv.addKeyword((0, oneRequired_1.default)());
exports.default = oneRequired;
module.exports = oneRequired;
//# sourceMappingURL=oneRequired.js.map


code:
import type { Plugin } from "ajv";
declare const patternRequired: Plugin<undefined>;
export default patternRequired;


code:
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const patternRequired_1 = __importDefault(require("../definitions/patternRequired"));
const patternRequired = (ajv) => ajv.addKeyword((0, patternRequired_1.default)());
exports.default = patternRequired;
module.exports = patternRequired;
//# sourceMappingURL=patternRequired.js.map


code:
import type { Plugin } from "ajv";
declare const prohibited: Plugin<undefined>;
export default prohibited;


code:
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const prohibited_1 = __importDefault(require("../definitions/prohibited"));
const prohibited = (ajv) => ajv.addKeyword((0, prohibited_1.default)());
exports.default = prohibited;
module.exports = prohibited;
//# sourceMappingURL=prohibited.js.map


code:
import type { Plugin } from "ajv";
declare const range: Plugin<undefined>;
export default range;


code:
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const range_1 = __importDefault(require("../definitions/range"));
const range = (ajv) => ajv.addKeyword((0, range_1.default)());
exports.default = range;
module.exports = range;
//# sourceMappingURL=range.js.map


code:
import type { Plugin } from "ajv";
declare const regexp: Plugin<undefined>;
export default regexp;


code:
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const regexp_1 = __importDefault(require("../definitions/regexp"));
const regexp = (ajv) => ajv.addKeyword((0, regexp_1.default)());
exports.default = regexp;
module.exports = regexp;
//# sourceMappingURL=regexp.js.map


code:
import type { Plugin } from "ajv";
import type { DefinitionOptions } from "../definitions/_types";
declare const select: Plugin<DefinitionOptions>;
export default select;


code:
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const select_1 = __importDefault(require("../definitions/select"));
const select = (ajv, opts) => {
    (0, select_1.default)(opts).forEach((d) => ajv.addKeyword(d));
    return ajv;
};
exports.default = select;
module.exports = select;
//# sourceMappingURL=select.js.map


code:
import type { Plugin } from "ajv";
declare const transform: Plugin<undefined>;
export default transform;


code:
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const transform_1 = __importDefault(require("../definitions/transform"));
const transform = (ajv) => ajv.addKeyword((0, transform_1.default)());
exports.default = transform;
module.exports = transform;
//# sourceMappingURL=transform.js.map


code:
import type { Plugin } from "ajv";
declare const typeofPlugin: Plugin<undefined>;
export default typeofPlugin;


code:
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const typeof_1 = __importDefault(require("../definitions/typeof"));
const typeofPlugin = (ajv) => ajv.addKeyword((0, typeof_1.default)());
exports.default = typeofPlugin;
module.exports = typeofPlugin;
//# sourceMappingURL=typeof.js.map


code:
import type { Plugin } from "ajv";
declare const uniqueItemProperties: Plugin<undefined>;
export default uniqueItemProperties;


code:
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const uniqueItemProperties_1 = __importDefault(require("../definitions/uniqueItemProperties"));
const uniqueItemProperties = (ajv) => ajv.addKeyword((0, uniqueItemProperties_1.default)());
exports.default = uniqueItemProperties;
module.exports = uniqueItemProperties;
//# sourceMappingURL=uniqueItemProperties.js.map


ajv-keywords

description: Additional JSON-Schema keywords for Ajv JSON validator

build: rm -rf dist && tsc

prepublish: npm run build

test: npm link && npm link ajv-keywords && npm run eslint && npm run test-cov

test-spec: jest spec/*.ts

test-cov: jest spec/*.ts --coverage

type: git

keywords: JSON-Schema ajv keywords

files: src dist ajv-keywords.d.ts

author: Evgeny Poberezkin

license: MIT

pre-commit: lint-staged && npm test

*.{md,json,yaml,js,ts}: prettier --write


code:
import type {MacroKeywordDefinition} from "ajv"
import type {GetDefinition} from "./_types"

type RangeKwd = "range" | "exclusiveRange"

export default function getRangeDef(keyword: RangeKwd): GetDefinition<MacroKeywordDefinition> {
  return () => ({
    keyword,
    type: "number",
    schemaType: "array",
    macro: function ([min, max]: [number, number]) {
      validateRangeSchema(min, max)
      return keyword === "range"
        ? {minimum: min, maximum: max}
        : {exclusiveMinimum: min, exclusiveMaximum: max}
    },
    metaSchema: {
      type: "array",
      minItems: 2,
      maxItems: 2,
      items: {type: "number"},
    },
  })

  function validateRangeSchema(min: number, max: number): void {
    if (min > max || (keyword === "exclusiveRange" && min === max)) {
      throw new Error("There are no numbers in range")
    }
  }
}


code:
import type {MacroKeywordDefinition} from "ajv"
import type {GetDefinition} from "./_types"

type RequiredKwd = "anyRequired" | "oneRequired"

export default function getRequiredDef(
  keyword: RequiredKwd
): GetDefinition<MacroKeywordDefinition> {
  return () => ({
    keyword,
    type: "object",
    schemaType: "array",
    macro(schema: string[]) {
      if (schema.length === 0) return true
      if (schema.length === 1) return {required: schema}
      const comb = keyword === "anyRequired" ? "anyOf" : "oneOf"
      return {[comb]: schema.map((p) => ({required: [p]}))}
    },
    metaSchema: {
      type: "array",
      items: {type: "string"},
    },
  })
}


code:
import type {KeywordDefinition} from "ajv"

export interface DefinitionOptions {
  defaultMeta?: string | boolean
}

export type GetDefinition<T extends KeywordDefinition> = (opts?: DefinitionOptions) => T


code:
import type {DefinitionOptions} from "./_types"
import type {SchemaObject, KeywordCxt, Name} from "ajv"
import {_} from "ajv/dist/compile/codegen"

const META_SCHEMA_ID = "http://json-schema.org/schema"

export function metaSchemaRef({defaultMeta}: DefinitionOptions = {}): SchemaObject {
  return defaultMeta === false ? {} : {$ref: defaultMeta || META_SCHEMA_ID}
}

export function usePattern(
  {gen, it: {opts}}: KeywordCxt,
  pattern: string,
  flags = opts.unicodeRegExp ? "u" : ""
): Name {
  const rx = new RegExp(pattern, flags)
  return gen.scopeValue("pattern", {
    key: rx.toString(),
    ref: rx,
    code: _`new RegExp(${pattern}, ${flags})`,
  })
}


code:
import type {MacroKeywordDefinition} from "ajv"

export default function getDef(): MacroKeywordDefinition {
  return {
    keyword: "allRequired",
    type: "object",
    schemaType: "boolean",
    macro(schema: boolean, parentSchema) {
      if (!schema) return true
      const required = Object.keys(parentSchema.properties)
      if (required.length === 0) return true
      return {required}
    },
    dependencies: ["properties"],
  }
}

module.exports = getDef


code:
import type {MacroKeywordDefinition} from "ajv"
import type {GetDefinition} from "./_types"
import getRequiredDef from "./_required"

const getDef: GetDefinition<MacroKeywordDefinition> = getRequiredDef("anyRequired")

export default getDef
module.exports = getDef


code:
import type {MacroKeywordDefinition, SchemaObject, Schema} from "ajv"
import type {DefinitionOptions} from "./_types"
import {metaSchemaRef} from "./_util"

export default function getDef(opts?: DefinitionOptions): MacroKeywordDefinition {
  return {
    keyword: "deepProperties",
    type: "object",
    schemaType: "object",
    macro: function (schema: Record<string, SchemaObject>) {
      const allOf = []
      for (const pointer in schema) allOf.push(getSchema(pointer, schema[pointer]))
      return {allOf}
    },
    metaSchema: {
      type: "object",
      propertyNames: {type: "string", format: "json-pointer"},
      additionalProperties: metaSchemaRef(opts),
    },
  }
}

function getSchema(jsonPointer: string, schema: SchemaObject): SchemaObject {
  const segments = jsonPointer.split("/")
  const rootSchema: SchemaObject = {}
  let pointerSchema: SchemaObject = rootSchema
  for (let i = 1; i < segments.length; i++) {
    let segment: string = segments[i]
    const isLast = i === segments.length - 1
    segment = unescapeJsonPointer(segment)
    const properties: Record<string, Schema> = (pointerSchema.properties = {})
    let items: SchemaObject[] | undefined
    if (/[0-9]+/.test(segment)) {
      let count = +segment
      items = pointerSchema.items = []
      pointerSchema.type = ["object", "array"]
      while (count--) items.push({})
    } else {
      pointerSchema.type = "object"
    }
    pointerSchema = isLast ? schema : {}
    properties[segment] = pointerSchema
    if (items) items.push(pointerSchema)
  }
  return rootSchema
}

function unescapeJsonPointer(str: string): string {
  return str.replace(/~1/g, "/").replace(/~0/g, "~")
}

module.exports = getDef


code:
import type {CodeKeywordDefinition, KeywordCxt} from "ajv"
import {_, or, and, getProperty, Code} from "ajv/dist/compile/codegen"

export default function getDef(): CodeKeywordDefinition {
  return {
    keyword: "deepRequired",
    type: "object",
    schemaType: "array",
    code(ctx: KeywordCxt) {
      const {schema, data} = ctx
      const props = (schema as string[]).map((jp: string) => _`(${getData(jp)}) === undefined`)
      ctx.fail(or(...props))

      function getData(jsonPointer: string): Code {
        if (jsonPointer === "") throw new Error("empty JSON pointer not allowed")
        const segments = jsonPointer.split("/")
        let x: Code = data
        const xs = segments.map((s, i) =>
          i ? (x = _`${x}${getProperty(unescapeJPSegment(s))}`) : x
        )
        return and(...xs)
      }
    },
    metaSchema: {
      type: "array",
      items: {type: "string", format: "json-pointer"},
    },
  }
}

function unescapeJPSegment(s: string): string {
  return s.replace(/~1/g, "/").replace(/~0/g, "~")
}

module.exports = getDef


code:
import type {FuncKeywordDefinition, SchemaCxt} from "ajv"

const sequences: Record<string, number | undefined> = {}

export type DynamicDefaultFunc = (args?: Record<string, any>) => () => any

const DEFAULTS: Record<string, DynamicDefaultFunc | undefined> = {
  timestamp: () => () => Date.now(),
  datetime: () => () => new Date().toISOString(),
  date: () => () => new Date().toISOString().slice(0, 10),
  time: () => () => new Date().toISOString().slice(11),
  random: () => () => Math.random(),
  randomint: (args?: {max?: number}) => {
    const max = args?.max ?? 2
    return () => Math.floor(Math.random() * max)
  },
  seq: (args?: {name?: string}) => {
    const name = args?.name ?? ""
    sequences[name] ||= 0
    return () => (sequences[name] as number)++
  },
}

interface PropertyDefaultSchema {
  func: string
  args: Record<string, any>
}

type DefaultSchema = Record<string, string | PropertyDefaultSchema | undefined>

const getDef: (() => FuncKeywordDefinition) & {
  DEFAULTS: typeof DEFAULTS
} = Object.assign(_getDef, {DEFAULTS})

function _getDef(): FuncKeywordDefinition {
  return {
    keyword: "dynamicDefaults",
    type: "object",
    schemaType: ["string", "object"],
    modifying: true,
    valid: true,
    compile(schema: DefaultSchema, _parentSchema, it: SchemaCxt) {
      if (!it.opts.useDefaults || it.compositeRule) return () => true
      const fs: Record<string, () => any> = {}
      for (const key in schema) fs[key] = getDefault(schema[key])
      const empty = it.opts.useDefaults === "empty"

      return (data: Record<string, any>) => {
        for (const prop in schema) {
          if (data[prop] === undefined || (empty && (data[prop] === null || data[prop] === ""))) {
            data[prop] = fs[prop]()
          }
        }
        return true
      }
    },
    metaSchema: {
      type: "object",
      additionalProperties: {
        anyOf: [
          {type: "string"},
          {
            type: "object",
            additionalProperties: false,
            required: ["func", "args"],
            properties: {
              func: {type: "string"},
              args: {type: "object"},
            },
          },
        ],
      },
    },
  }
}

function getDefault(d: string | PropertyDefaultSchema | undefined): () => any {
  return typeof d == "object" ? getObjDefault(d) : getStrDefault(d)
}

function getObjDefault({func, args}: PropertyDefaultSchema): () => any {
  const def = DEFAULTS[func]
  assertDefined(func, def)
  return def(args)
}

function getStrDefault(d = ""): () => any {
  const def = DEFAULTS[d]
  assertDefined(d, def)
  return def()
}

function assertDefined(name: string, def?: DynamicDefaultFunc): asserts def is DynamicDefaultFunc {
  if (!def) throw new Error(`invalid "dynamicDefaults" keyword property value: ${name}`)
}

export default getDef
module.exports = getDef


code:
import type {MacroKeywordDefinition} from "ajv"
import type {GetDefinition} from "./_types"
import getRangeDef from "./_range"

const getDef: GetDefinition<MacroKeywordDefinition> = getRangeDef("exclusiveRange")

export default getDef
module.exports = getDef


code:
import type {Vocabulary, KeywordDefinition, ErrorNoParams} from "ajv"
import type {DefinitionOptions, GetDefinition} from "./_types"
import typeofDef from "./typeof"
import instanceofDef from "./instanceof"
import range from "./range"
import exclusiveRange from "./exclusiveRange"
import regexp from "./regexp"
import transform from "./transform"
import uniqueItemProperties from "./uniqueItemProperties"
import allRequired from "./allRequired"
import anyRequired from "./anyRequired"
import oneRequired from "./oneRequired"
import patternRequired, {PatternRequiredError} from "./patternRequired"
import prohibited from "./prohibited"
import deepProperties from "./deepProperties"
import deepRequired from "./deepRequired"
import dynamicDefaults from "./dynamicDefaults"
import selectDef, {SelectError} from "./select"

const definitions: GetDefinition<KeywordDefinition>[] = [
  typeofDef,
  instanceofDef,
  range,
  exclusiveRange,
  regexp,
  transform,
  uniqueItemProperties,
  allRequired,
  anyRequired,
  oneRequired,
  patternRequired,
  prohibited,
  deepProperties,
  deepRequired,
  dynamicDefaults,
]

export default function ajvKeywords(opts?: DefinitionOptions): Vocabulary {
  return definitions.map((d) => d(opts)).concat(selectDef(opts))
}

export type AjvKeywordsError =
  | PatternRequiredError
  | SelectError
  | ErrorNoParams<
      | "range"
      | "exclusiveRange"
      | "anyRequired"
      | "oneRequired"
      | "allRequired"
      | "deepProperties"
      | "deepRequired"
      | "dynamicDefaults"
      | "instanceof"
      | "prohibited"
      | "regexp"
      | "transform"
      | "uniqueItemProperties"
    >

module.exports = ajvKeywords