mirror of
https://github.com/DigiLive/mushroom-strategy.git
synced 2025-09-26 21:20:55 +02:00
Updated node_modules
This commit is contained in:
317
node_modules/schema-utils/README.md
generated
vendored
Normal file
317
node_modules/schema-utils/README.md
generated
vendored
Normal file
@@ -0,0 +1,317 @@
|
||||
<div align="center">
|
||||
<a href="http://json-schema.org">
|
||||
<img width="160" height="160"
|
||||
src="https://raw.githubusercontent.com/webpack-contrib/schema-utils/master/.github/assets/logo.png">
|
||||
</a>
|
||||
<a href="https://github.com/webpack/webpack">
|
||||
<img width="200" height="200"
|
||||
src="https://webpack.js.org/assets/icon-square-big.svg">
|
||||
</a>
|
||||
</div>
|
||||
|
||||
[![npm][npm]][npm-url]
|
||||
[![node][node]][node-url]
|
||||
[![tests][tests]][tests-url]
|
||||
[![coverage][cover]][cover-url]
|
||||
[![GitHub Discussions][discussion]][discussion-url]
|
||||
[![size][size]][size-url]
|
||||
|
||||
# schema-utils
|
||||
|
||||
Package for validate options in loaders and plugins.
|
||||
|
||||
## Getting Started
|
||||
|
||||
To begin, you'll need to install `schema-utils`:
|
||||
|
||||
```console
|
||||
npm install schema-utils
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
**schema.json**
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"option": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
import schema from "./path/to/schema.json";
|
||||
import { validate } from "schema-utils";
|
||||
|
||||
const options = { option: true };
|
||||
const configuration = { name: "Loader Name/Plugin Name/Name" };
|
||||
|
||||
validate(schema, options, configuration);
|
||||
```
|
||||
|
||||
### `schema`
|
||||
|
||||
Type: `String`
|
||||
|
||||
JSON schema.
|
||||
|
||||
Simple example of schema:
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"description": "This is description of option.",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
```
|
||||
|
||||
### `options`
|
||||
|
||||
Type: `Object`
|
||||
|
||||
Object with options.
|
||||
|
||||
```js
|
||||
import schema from "./path/to/schema.json";
|
||||
import { validate } from "schema-utils";
|
||||
|
||||
const options = { foo: "bar" };
|
||||
|
||||
validate(schema, { name: 123 }, { name: "MyPlugin" });
|
||||
```
|
||||
|
||||
### `configuration`
|
||||
|
||||
Allow to configure validator.
|
||||
|
||||
There is an alternative method to configure the `name` and`baseDataPath` options via the `title` property in the schema.
|
||||
For example:
|
||||
|
||||
```json
|
||||
{
|
||||
"title": "My Loader options",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"description": "This is description of option.",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
```
|
||||
|
||||
The last word used for the `baseDataPath` option, other words used for the `name` option.
|
||||
Based on the example above the `name` option equals `My Loader`, the `baseDataPath` option equals `options`.
|
||||
|
||||
#### `name`
|
||||
|
||||
Type: `Object`
|
||||
Default: `"Object"`
|
||||
|
||||
Allow to setup name in validation errors.
|
||||
|
||||
```js
|
||||
import schema from "./path/to/schema.json";
|
||||
import { validate } from "schema-utils";
|
||||
|
||||
const options = { foo: "bar" };
|
||||
|
||||
validate(schema, options, { name: "MyPlugin" });
|
||||
```
|
||||
|
||||
```shell
|
||||
Invalid configuration object. MyPlugin has been initialised using a configuration object that does not match the API schema.
|
||||
- configuration.optionName should be a integer.
|
||||
```
|
||||
|
||||
#### `baseDataPath`
|
||||
|
||||
Type: `String`
|
||||
Default: `"configuration"`
|
||||
|
||||
Allow to setup base data path in validation errors.
|
||||
|
||||
```js
|
||||
import schema from "./path/to/schema.json";
|
||||
import { validate } from "schema-utils";
|
||||
|
||||
const options = { foo: "bar" };
|
||||
|
||||
validate(schema, options, { name: "MyPlugin", baseDataPath: "options" });
|
||||
```
|
||||
|
||||
```shell
|
||||
Invalid options object. MyPlugin has been initialised using an options object that does not match the API schema.
|
||||
- options.optionName should be a integer.
|
||||
```
|
||||
|
||||
#### `postFormatter`
|
||||
|
||||
Type: `Function`
|
||||
Default: `undefined`
|
||||
|
||||
Allow to reformat errors.
|
||||
|
||||
```js
|
||||
import schema from "./path/to/schema.json";
|
||||
import { validate } from "schema-utils";
|
||||
|
||||
const options = { foo: "bar" };
|
||||
|
||||
validate(schema, options, {
|
||||
name: "MyPlugin",
|
||||
postFormatter: (formattedError, error) => {
|
||||
if (error.keyword === "type") {
|
||||
return `${formattedError}\nAdditional Information.`;
|
||||
}
|
||||
|
||||
return formattedError;
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
```shell
|
||||
Invalid options object. MyPlugin has been initialized using an options object that does not match the API schema.
|
||||
- options.optionName should be a integer.
|
||||
Additional Information.
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
**schema.json**
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"test": {
|
||||
"anyOf": [
|
||||
{ "type": "array" },
|
||||
{ "type": "string" },
|
||||
{ "instanceof": "RegExp" }
|
||||
]
|
||||
},
|
||||
"transform": {
|
||||
"instanceof": "Function"
|
||||
},
|
||||
"sourceMap": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
```
|
||||
|
||||
### `Loader`
|
||||
|
||||
```js
|
||||
import { getOptions } from "loader-utils";
|
||||
import { validate } from "schema-utils";
|
||||
|
||||
import schema from "path/to/schema.json";
|
||||
|
||||
function loader(src, map) {
|
||||
const options = getOptions(this);
|
||||
|
||||
validate(schema, options, {
|
||||
name: "Loader Name",
|
||||
baseDataPath: "options",
|
||||
});
|
||||
|
||||
// Code...
|
||||
}
|
||||
|
||||
export default loader;
|
||||
```
|
||||
|
||||
### `Plugin`
|
||||
|
||||
```js
|
||||
import { validate } from "schema-utils";
|
||||
|
||||
import schema from "path/to/schema.json";
|
||||
|
||||
class Plugin {
|
||||
constructor(options) {
|
||||
validate(schema, options, {
|
||||
name: "Plugin Name",
|
||||
baseDataPath: "options",
|
||||
});
|
||||
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
apply(compiler) {
|
||||
// Code...
|
||||
}
|
||||
}
|
||||
|
||||
export default Plugin;
|
||||
```
|
||||
|
||||
### Allow to disable and enable validation (the `validate` function do nothing)
|
||||
|
||||
This can be useful when you don't want to do validation for `production` builds.
|
||||
|
||||
```js
|
||||
import { disableValidation, enableValidation, validate } from "schema-utils";
|
||||
|
||||
// Disable validation
|
||||
disableValidation();
|
||||
// Do nothing
|
||||
validate(schema, options);
|
||||
|
||||
// Enable validation
|
||||
enableValidation();
|
||||
// Will throw an error if schema is not valid
|
||||
validate(schema, options);
|
||||
|
||||
// Allow to undestand do you need validation or not
|
||||
const need = needValidate();
|
||||
|
||||
console.log(need);
|
||||
```
|
||||
|
||||
Also you can enable/disable validation using the `process.env.SKIP_VALIDATION` env variable.
|
||||
|
||||
Supported values (case insensitive):
|
||||
|
||||
- `yes`/`y`/`true`/`1`/`on`
|
||||
- `no`/`n`/`false`/`0`/`off`
|
||||
|
||||
## Contributing
|
||||
|
||||
Please take a moment to read our contributing guidelines if you haven't yet done so.
|
||||
|
||||
[CONTRIBUTING](./.github/CONTRIBUTING.md)
|
||||
|
||||
## License
|
||||
|
||||
[MIT](./LICENSE)
|
||||
|
||||
[npm]: https://img.shields.io/npm/v/schema-utils.svg
|
||||
[npm-url]: https://npmjs.com/package/schema-utils
|
||||
[node]: https://img.shields.io/node/v/schema-utils.svg
|
||||
[node-url]: https://nodejs.org
|
||||
[tests]: https://github.com/webpack/schema-utils/workflows/schema-utils/badge.svg
|
||||
[tests-url]: https://github.com/webpack/schema-utils/actions
|
||||
[cover]: https://codecov.io/gh/webpack/schema-utils/branch/master/graph/badge.svg
|
||||
[cover-url]: https://codecov.io/gh/webpack/schema-utils
|
||||
[discussion]: https://img.shields.io/github/discussions/webpack/webpack
|
||||
[discussion-url]: https://github.com/webpack/webpack/discussions
|
||||
[size]: https://packagephobia.com/badge?p=schema-utils
|
||||
[size-url]: https://packagephobia.com/result?p=schema-utils
|
22
node_modules/schema-utils/node_modules/ajv/LICENSE
generated
vendored
Normal file
22
node_modules/schema-utils/node_modules/ajv/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015-2021 Evgeny Poberezkin
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
207
node_modules/schema-utils/node_modules/ajv/README.md
generated
vendored
Normal file
207
node_modules/schema-utils/node_modules/ajv/README.md
generated
vendored
Normal file
@@ -0,0 +1,207 @@
|
||||
<img align="right" alt="Ajv logo" width="160" src="https://ajv.js.org/img/ajv.svg">
|
||||
|
||||
|
||||
|
||||
# Ajv JSON schema validator
|
||||
|
||||
The fastest JSON validator for Node.js and browser.
|
||||
|
||||
Supports JSON Schema draft-04/06/07/2019-09/2020-12 ([draft-04 support](https://ajv.js.org/json-schema.html#draft-04) requires ajv-draft-04 package) and JSON Type Definition [RFC8927](https://datatracker.ietf.org/doc/rfc8927/).
|
||||
|
||||
[](https://github.com/ajv-validator/ajv/actions?query=workflow%3Abuild)
|
||||
[](https://www.npmjs.com/package/ajv)
|
||||
[](https://www.npmjs.com/package/ajv)
|
||||
[](https://coveralls.io/github/ajv-validator/ajv?branch=master)
|
||||
[](https://simplex.chat/contact#/?v=1-2&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2F8KvvURM6J38Gdq9dCuPswMOkMny0xCOJ%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAr8rPVRuMOXv6kwF2yUAap-eoVg-9ssOFCi1fIrxTUw0%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion&data=%7B%22type%22%3A%22group%22%2C%22groupLinkId%22%3A%224pwLRgWHU9tlroMWHz0uOg%3D%3D%22%7D)
|
||||
[](https://gitter.im/ajv-validator/ajv)
|
||||
[](https://github.com/sponsors/epoberezkin)
|
||||
|
||||
## Ajv sponsors
|
||||
|
||||
[<img src="https://ajv.js.org/img/mozilla.svg" width="45%" alt="Mozilla">](https://www.mozilla.org)<img src="https://ajv.js.org/img/gap.svg" width="9%">[<img src="https://ajv.js.org/img/reserved.svg" width="45%">](https://opencollective.com/ajv)
|
||||
|
||||
[<img src="https://ajv.js.org/img/microsoft.png" width="31%" alt="Microsoft">](https://opensource.microsoft.com)<img src="https://ajv.js.org/img/gap.svg" width="3%">[<img src="https://ajv.js.org/img/reserved.svg" width="31%">](https://opencollective.com/ajv)<img src="https://ajv.js.org/img/gap.svg" width="3%">[<img src="https://ajv.js.org/img/reserved.svg" width="31%">](https://opencollective.com/ajv)
|
||||
|
||||
[<img src="https://ajv.js.org/img/retool.svg" width="22.5%" alt="Retool">](https://retool.com/?utm_source=sponsor&utm_campaign=ajv)<img src="https://ajv.js.org/img/gap.svg" width="3%">[<img src="https://ajv.js.org/img/tidelift.svg" width="22.5%" alt="Tidelift">](https://tidelift.com/subscription/pkg/npm-ajv?utm_source=npm-ajv&utm_medium=referral&utm_campaign=enterprise)<img src="https://ajv.js.org/img/gap.svg" width="3%">[<img src="https://ajv.js.org/img/simplex.svg" width="22.5%" alt="SimpleX">](https://github.com/simplex-chat/simplex-chat)<img src="https://ajv.js.org/img/gap.svg" width="3%">[<img src="https://ajv.js.org/img/reserved.svg" width="22.5%">](https://opencollective.com/ajv)
|
||||
|
||||
## Contributing
|
||||
|
||||
More than 100 people contributed to Ajv, and we would love to have you join the development. We welcome implementing new features that will benefit many users and ideas to improve our documentation.
|
||||
|
||||
Please review [Contributing guidelines](./CONTRIBUTING.md) and [Code components](https://ajv.js.org/components.html).
|
||||
|
||||
## Documentation
|
||||
|
||||
All documentation is available on the [Ajv website](https://ajv.js.org).
|
||||
|
||||
Some useful site links:
|
||||
|
||||
- [Getting started](https://ajv.js.org/guide/getting-started.html)
|
||||
- [JSON Schema vs JSON Type Definition](https://ajv.js.org/guide/schema-language.html)
|
||||
- [API reference](https://ajv.js.org/api.html)
|
||||
- [Strict mode](https://ajv.js.org/strict-mode.html)
|
||||
- [Standalone validation code](https://ajv.js.org/standalone.html)
|
||||
- [Security considerations](https://ajv.js.org/security.html)
|
||||
- [Command line interface](https://ajv.js.org/packages/ajv-cli.html)
|
||||
- [Frequently Asked Questions](https://ajv.js.org/faq.html)
|
||||
|
||||
## <a name="sponsors"></a>Please [sponsor Ajv development](https://github.com/sponsors/epoberezkin)
|
||||
|
||||
Since I asked to support Ajv development 40 people and 6 organizations contributed via GitHub and OpenCollective - this support helped receiving the MOSS grant!
|
||||
|
||||
Your continuing support is very important - the funds will be used to develop and maintain Ajv once the next major version is released.
|
||||
|
||||
Please sponsor Ajv via:
|
||||
|
||||
- [GitHub sponsors page](https://github.com/sponsors/epoberezkin) (GitHub will match it)
|
||||
- [Ajv Open Collective](https://opencollective.com/ajv)
|
||||
|
||||
Thank you.
|
||||
|
||||
#### Open Collective sponsors
|
||||
|
||||
<a href="https://opencollective.com/ajv"><img src="https://opencollective.com/ajv/individuals.svg?width=890"></a>
|
||||
|
||||
<a href="https://opencollective.com/ajv/organization/0/website"><img src="https://opencollective.com/ajv/organization/0/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ajv/organization/1/website"><img src="https://opencollective.com/ajv/organization/1/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ajv/organization/2/website"><img src="https://opencollective.com/ajv/organization/2/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ajv/organization/3/website"><img src="https://opencollective.com/ajv/organization/3/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ajv/organization/4/website"><img src="https://opencollective.com/ajv/organization/4/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ajv/organization/5/website"><img src="https://opencollective.com/ajv/organization/5/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ajv/organization/6/website"><img src="https://opencollective.com/ajv/organization/6/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ajv/organization/7/website"><img src="https://opencollective.com/ajv/organization/7/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ajv/organization/8/website"><img src="https://opencollective.com/ajv/organization/8/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ajv/organization/9/website"><img src="https://opencollective.com/ajv/organization/9/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ajv/organization/10/website"><img src="https://opencollective.com/ajv/organization/10/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ajv/organization/11/website"><img src="https://opencollective.com/ajv/organization/11/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ajv/organization/12/website"><img src="https://opencollective.com/ajv/organization/12/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ajv/organization/13/website"><img src="https://opencollective.com/ajv/organization/13/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ajv/organization/14/website"><img src="https://opencollective.com/ajv/organization/14/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ajv/organization/15/website"><img src="https://opencollective.com/ajv/organization/15/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ajv/organization/16/website"><img src="https://opencollective.com/ajv/organization/16/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ajv/organization/17/website"><img src="https://opencollective.com/ajv/organization/17/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ajv/organization/18/website"><img src="https://opencollective.com/ajv/organization/18/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ajv/organization/19/website"><img src="https://opencollective.com/ajv/organization/19/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ajv/organization/20/website"><img src="https://opencollective.com/ajv/organization/20/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ajv/organization/21/website"><img src="https://opencollective.com/ajv/organization/21/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ajv/organization/22/website"><img src="https://opencollective.com/ajv/organization/22/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ajv/organization/23/website"><img src="https://opencollective.com/ajv/organization/23/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ajv/organization/24/website"><img src="https://opencollective.com/ajv/organization/24/avatar.svg"></a>
|
||||
|
||||
## Performance
|
||||
|
||||
Ajv generates code to turn JSON Schemas into super-fast validation functions that are efficient for v8 optimization.
|
||||
|
||||
Currently Ajv is the fastest and the most standard compliant validator according to these benchmarks:
|
||||
|
||||
- [json-schema-benchmark](https://github.com/ebdrup/json-schema-benchmark) - 50% faster than the second place
|
||||
- [jsck benchmark](https://github.com/pandastrike/jsck#benchmarks) - 20-190% faster
|
||||
- [z-schema benchmark](https://rawgit.com/zaggino/z-schema/master/benchmark/results.html)
|
||||
- [themis benchmark](https://cdn.rawgit.com/playlyfe/themis/master/benchmark/results.html)
|
||||
|
||||
Performance of different validators by [json-schema-benchmark](https://github.com/ebdrup/json-schema-benchmark):
|
||||
|
||||
[](https://github.com/ebdrup/json-schema-benchmark/blob/master/README.md#performance)
|
||||
|
||||
## Features
|
||||
|
||||
- Ajv implements JSON Schema [draft-06/07/2019-09/2020-12](http://json-schema.org/) standards (draft-04 is supported in v6):
|
||||
- all validation keywords (see [JSON Schema validation keywords](https://ajv.js.org/json-schema.html))
|
||||
- [OpenAPI](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.3.md) extensions:
|
||||
- NEW: keyword [discriminator](https://ajv.js.org/json-schema.html#discriminator).
|
||||
- keyword [nullable](https://ajv.js.org/json-schema.html#nullable).
|
||||
- full support of remote references (remote schemas have to be added with `addSchema` or compiled to be available)
|
||||
- support of recursive references between schemas
|
||||
- correct string lengths for strings with unicode pairs
|
||||
- JSON Schema [formats](https://ajv.js.org/guide/formats.html) (with [ajv-formats](https://github.com/ajv-validator/ajv-formats) plugin).
|
||||
- [validates schemas against meta-schema](https://ajv.js.org/api.html#api-validateschema)
|
||||
- NEW: supports [JSON Type Definition](https://datatracker.ietf.org/doc/rfc8927/):
|
||||
- all keywords (see [JSON Type Definition schema forms](https://ajv.js.org/json-type-definition.html))
|
||||
- meta-schema for JTD schemas
|
||||
- "union" keyword and user-defined keywords (can be used inside "metadata" member of the schema)
|
||||
- supports [browsers](https://ajv.js.org/guide/environments.html#browsers) and Node.js 10.x - current
|
||||
- [asynchronous loading](https://ajv.js.org/guide/managing-schemas.html#asynchronous-schema-loading) of referenced schemas during compilation
|
||||
- "All errors" validation mode with [option allErrors](https://ajv.js.org/options.html#allerrors)
|
||||
- [error messages with parameters](https://ajv.js.org/api.html#validation-errors) describing error reasons to allow error message generation
|
||||
- i18n error messages support with [ajv-i18n](https://github.com/ajv-validator/ajv-i18n) package
|
||||
- [removing-additional-properties](https://ajv.js.org/guide/modifying-data.html#removing-additional-properties)
|
||||
- [assigning defaults](https://ajv.js.org/guide/modifying-data.html#assigning-defaults) to missing properties and items
|
||||
- [coercing data](https://ajv.js.org/guide/modifying-data.html#coercing-data-types) to the types specified in `type` keywords
|
||||
- [user-defined keywords](https://ajv.js.org/guide/user-keywords.html)
|
||||
- additional extension keywords with [ajv-keywords](https://github.com/ajv-validator/ajv-keywords) package
|
||||
- [\$data reference](https://ajv.js.org/guide/combining-schemas.html#data-reference) to use values from the validated data as values for the schema keywords
|
||||
- [asynchronous validation](https://ajv.js.org/guide/async-validation.html) of user-defined formats and keywords
|
||||
|
||||
## Install
|
||||
|
||||
To install version 8:
|
||||
|
||||
```
|
||||
npm install ajv
|
||||
```
|
||||
|
||||
## <a name="usage"></a>Getting started
|
||||
|
||||
Try it in the Node.js REPL: https://runkit.com/npm/ajv
|
||||
|
||||
In JavaScript:
|
||||
|
||||
```javascript
|
||||
// or ESM/TypeScript import
|
||||
import Ajv from "ajv"
|
||||
// Node.js require:
|
||||
const Ajv = require("ajv")
|
||||
|
||||
const ajv = new Ajv() // options can be passed, e.g. {allErrors: true}
|
||||
|
||||
const schema = {
|
||||
type: "object",
|
||||
properties: {
|
||||
foo: {type: "integer"},
|
||||
bar: {type: "string"},
|
||||
},
|
||||
required: ["foo"],
|
||||
additionalProperties: false,
|
||||
}
|
||||
|
||||
const data = {
|
||||
foo: 1,
|
||||
bar: "abc",
|
||||
}
|
||||
|
||||
const validate = ajv.compile(schema)
|
||||
const valid = validate(data)
|
||||
if (!valid) console.log(validate.errors)
|
||||
```
|
||||
|
||||
Learn how to use Ajv and see more examples in the [Guide: getting started](https://ajv.js.org/guide/getting-started.html)
|
||||
|
||||
## Changes history
|
||||
|
||||
See [https://github.com/ajv-validator/ajv/releases](https://github.com/ajv-validator/ajv/releases)
|
||||
|
||||
**Please note**: [Changes in version 8.0.0](https://github.com/ajv-validator/ajv/releases/tag/v8.0.0)
|
||||
|
||||
[Version 7.0.0](https://github.com/ajv-validator/ajv/releases/tag/v7.0.0)
|
||||
|
||||
[Version 6.0.0](https://github.com/ajv-validator/ajv/releases/tag/v6.0.0).
|
||||
|
||||
## Code of conduct
|
||||
|
||||
Please review and follow the [Code of conduct](./CODE_OF_CONDUCT.md).
|
||||
|
||||
Please report any unacceptable behaviour to ajv.validator@gmail.com - it will be reviewed by the project team.
|
||||
|
||||
## 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 is a part of [Tidelift subscription](https://tidelift.com/subscription/pkg/npm-ajv?utm_source=npm-ajv&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](./LICENSE)
|
1
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/index.js.map
generated
vendored
Normal file
1
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/index.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../lib/vocabularies/validation/index.ts"],"names":[],"mappings":";;AACA,+CAA2D;AAC3D,6CAAwD;AACxD,+CAAuC;AACvC,uCAA+C;AAC/C,uDAA+C;AAC/C,yCAAkD;AAClD,6CAAqC;AACrC,+CAA2D;AAC3D,mCAAgD;AAChD,iCAA6C;AAE7C,MAAM,UAAU,GAAe;IAC7B,SAAS;IACT,qBAAW;IACX,oBAAU;IACV,SAAS;IACT,qBAAW;IACX,iBAAO;IACP,SAAS;IACT,yBAAe;IACf,kBAAQ;IACR,QAAQ;IACR,oBAAU;IACV,qBAAW;IACX,MAAM;IACN,EAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAC;IAClD,EAAC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAAC;IAC5C,eAAY;IACZ,cAAW;CACZ,CAAA;AAED,kBAAe,UAAU,CAAA"}
|
3
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/limitContains.d.ts
generated
vendored
Normal file
3
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/limitContains.d.ts
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
import type { CodeKeywordDefinition } from "../../types";
|
||||
declare const def: CodeKeywordDefinition;
|
||||
export default def;
|
15
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/limitContains.js
generated
vendored
Normal file
15
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/limitContains.js
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const util_1 = require("../../compile/util");
|
||||
const def = {
|
||||
keyword: ["maxContains", "minContains"],
|
||||
type: "array",
|
||||
schemaType: "number",
|
||||
code({ keyword, parentSchema, it }) {
|
||||
if (parentSchema.contains === undefined) {
|
||||
(0, util_1.checkStrictMode)(it, `"${keyword}" without "contains" is ignored`);
|
||||
}
|
||||
},
|
||||
};
|
||||
exports.default = def;
|
||||
//# sourceMappingURL=limitContains.js.map
|
1
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/limitContains.js.map
generated
vendored
Normal file
1
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/limitContains.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"limitContains.js","sourceRoot":"","sources":["../../../lib/vocabularies/validation/limitContains.ts"],"names":[],"mappings":";;AAEA,6CAAkD;AAElD,MAAM,GAAG,GAA0B;IACjC,OAAO,EAAE,CAAC,aAAa,EAAE,aAAa,CAAC;IACvC,IAAI,EAAE,OAAO;IACb,UAAU,EAAE,QAAQ;IACpB,IAAI,CAAC,EAAC,OAAO,EAAE,YAAY,EAAE,EAAE,EAAa;QAC1C,IAAI,YAAY,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;YACxC,IAAA,sBAAe,EAAC,EAAE,EAAE,IAAI,OAAO,iCAAiC,CAAC,CAAA;QACnE,CAAC;IACH,CAAC;CACF,CAAA;AAED,kBAAe,GAAG,CAAA"}
|
3
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/limitItems.d.ts
generated
vendored
Normal file
3
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/limitItems.d.ts
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
import type { CodeKeywordDefinition } from "../../types";
|
||||
declare const def: CodeKeywordDefinition;
|
||||
export default def;
|
24
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/limitItems.js
generated
vendored
Normal file
24
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/limitItems.js
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const codegen_1 = require("../../compile/codegen");
|
||||
const error = {
|
||||
message({ keyword, schemaCode }) {
|
||||
const comp = keyword === "maxItems" ? "more" : "fewer";
|
||||
return (0, codegen_1.str) `must NOT have ${comp} than ${schemaCode} items`;
|
||||
},
|
||||
params: ({ schemaCode }) => (0, codegen_1._) `{limit: ${schemaCode}}`,
|
||||
};
|
||||
const def = {
|
||||
keyword: ["maxItems", "minItems"],
|
||||
type: "array",
|
||||
schemaType: "number",
|
||||
$data: true,
|
||||
error,
|
||||
code(cxt) {
|
||||
const { keyword, data, schemaCode } = cxt;
|
||||
const op = keyword === "maxItems" ? codegen_1.operators.GT : codegen_1.operators.LT;
|
||||
cxt.fail$data((0, codegen_1._) `${data}.length ${op} ${schemaCode}`);
|
||||
},
|
||||
};
|
||||
exports.default = def;
|
||||
//# sourceMappingURL=limitItems.js.map
|
1
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/limitItems.js.map
generated
vendored
Normal file
1
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/limitItems.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"limitItems.js","sourceRoot":"","sources":["../../../lib/vocabularies/validation/limitItems.ts"],"names":[],"mappings":";;AAEA,mDAAuD;AAEvD,MAAM,KAAK,GAA2B;IACpC,OAAO,CAAC,EAAC,OAAO,EAAE,UAAU,EAAC;QAC3B,MAAM,IAAI,GAAG,OAAO,KAAK,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAA;QACtD,OAAO,IAAA,aAAG,EAAA,iBAAiB,IAAI,SAAS,UAAU,QAAQ,CAAA;IAC5D,CAAC;IACD,MAAM,EAAE,CAAC,EAAC,UAAU,EAAC,EAAE,EAAE,CAAC,IAAA,WAAC,EAAA,WAAW,UAAU,GAAG;CACpD,CAAA;AAED,MAAM,GAAG,GAA0B;IACjC,OAAO,EAAE,CAAC,UAAU,EAAE,UAAU,CAAC;IACjC,IAAI,EAAE,OAAO;IACb,UAAU,EAAE,QAAQ;IACpB,KAAK,EAAE,IAAI;IACX,KAAK;IACL,IAAI,CAAC,GAAe;QAClB,MAAM,EAAC,OAAO,EAAE,IAAI,EAAE,UAAU,EAAC,GAAG,GAAG,CAAA;QACvC,MAAM,EAAE,GAAG,OAAO,KAAK,UAAU,CAAC,CAAC,CAAC,mBAAS,CAAC,EAAE,CAAC,CAAC,CAAC,mBAAS,CAAC,EAAE,CAAA;QAC/D,GAAG,CAAC,SAAS,CAAC,IAAA,WAAC,EAAA,GAAG,IAAI,WAAW,EAAE,IAAI,UAAU,EAAE,CAAC,CAAA;IACtD,CAAC;CACF,CAAA;AAED,kBAAe,GAAG,CAAA"}
|
3
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/limitLength.d.ts
generated
vendored
Normal file
3
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/limitLength.d.ts
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
import type { CodeKeywordDefinition } from "../../types";
|
||||
declare const def: CodeKeywordDefinition;
|
||||
export default def;
|
27
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/limitLength.js
generated
vendored
Normal file
27
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/limitLength.js
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const codegen_1 = require("../../compile/codegen");
|
||||
const util_1 = require("../../compile/util");
|
||||
const ucs2length_1 = require("../../runtime/ucs2length");
|
||||
const error = {
|
||||
message({ keyword, schemaCode }) {
|
||||
const comp = keyword === "maxLength" ? "more" : "fewer";
|
||||
return (0, codegen_1.str) `must NOT have ${comp} than ${schemaCode} characters`;
|
||||
},
|
||||
params: ({ schemaCode }) => (0, codegen_1._) `{limit: ${schemaCode}}`,
|
||||
};
|
||||
const def = {
|
||||
keyword: ["maxLength", "minLength"],
|
||||
type: "string",
|
||||
schemaType: "number",
|
||||
$data: true,
|
||||
error,
|
||||
code(cxt) {
|
||||
const { keyword, data, schemaCode, it } = cxt;
|
||||
const op = keyword === "maxLength" ? codegen_1.operators.GT : codegen_1.operators.LT;
|
||||
const len = it.opts.unicode === false ? (0, codegen_1._) `${data}.length` : (0, codegen_1._) `${(0, util_1.useFunc)(cxt.gen, ucs2length_1.default)}(${data})`;
|
||||
cxt.fail$data((0, codegen_1._) `${len} ${op} ${schemaCode}`);
|
||||
},
|
||||
};
|
||||
exports.default = def;
|
||||
//# sourceMappingURL=limitLength.js.map
|
1
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/limitLength.js.map
generated
vendored
Normal file
1
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/limitLength.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"limitLength.js","sourceRoot":"","sources":["../../../lib/vocabularies/validation/limitLength.ts"],"names":[],"mappings":";;AAEA,mDAAuD;AACvD,6CAA0C;AAC1C,yDAAiD;AAEjD,MAAM,KAAK,GAA2B;IACpC,OAAO,CAAC,EAAC,OAAO,EAAE,UAAU,EAAC;QAC3B,MAAM,IAAI,GAAG,OAAO,KAAK,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAA;QACvD,OAAO,IAAA,aAAG,EAAA,iBAAiB,IAAI,SAAS,UAAU,aAAa,CAAA;IACjE,CAAC;IACD,MAAM,EAAE,CAAC,EAAC,UAAU,EAAC,EAAE,EAAE,CAAC,IAAA,WAAC,EAAA,WAAW,UAAU,GAAG;CACpD,CAAA;AAED,MAAM,GAAG,GAA0B;IACjC,OAAO,EAAE,CAAC,WAAW,EAAE,WAAW,CAAC;IACnC,IAAI,EAAE,QAAQ;IACd,UAAU,EAAE,QAAQ;IACpB,KAAK,EAAE,IAAI;IACX,KAAK;IACL,IAAI,CAAC,GAAe;QAClB,MAAM,EAAC,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAC,GAAG,GAAG,CAAA;QAC3C,MAAM,EAAE,GAAG,OAAO,KAAK,WAAW,CAAC,CAAC,CAAC,mBAAS,CAAC,EAAE,CAAC,CAAC,CAAC,mBAAS,CAAC,EAAE,CAAA;QAChE,MAAM,GAAG,GACP,EAAE,CAAC,IAAI,CAAC,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,IAAA,WAAC,EAAA,GAAG,IAAI,SAAS,CAAC,CAAC,CAAC,IAAA,WAAC,EAAA,GAAG,IAAA,cAAO,EAAC,GAAG,CAAC,GAAG,EAAE,oBAAU,CAAC,IAAI,IAAI,GAAG,CAAA;QAC7F,GAAG,CAAC,SAAS,CAAC,IAAA,WAAC,EAAA,GAAG,GAAG,IAAI,EAAE,IAAI,UAAU,EAAE,CAAC,CAAA;IAC9C,CAAC;CACF,CAAA;AAED,kBAAe,GAAG,CAAA"}
|
11
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/limitNumber.d.ts
generated
vendored
Normal file
11
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/limitNumber.d.ts
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
import type { CodeKeywordDefinition, ErrorObject } from "../../types";
|
||||
type Kwd = "maximum" | "minimum" | "exclusiveMaximum" | "exclusiveMinimum";
|
||||
type Comparison = "<=" | ">=" | "<" | ">";
|
||||
export type LimitNumberError = ErrorObject<Kwd, {
|
||||
limit: number;
|
||||
comparison: Comparison;
|
||||
}, number | {
|
||||
$data: string;
|
||||
}>;
|
||||
declare const def: CodeKeywordDefinition;
|
||||
export default def;
|
27
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/limitNumber.js
generated
vendored
Normal file
27
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/limitNumber.js
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const codegen_1 = require("../../compile/codegen");
|
||||
const ops = codegen_1.operators;
|
||||
const KWDs = {
|
||||
maximum: { okStr: "<=", ok: ops.LTE, fail: ops.GT },
|
||||
minimum: { okStr: ">=", ok: ops.GTE, fail: ops.LT },
|
||||
exclusiveMaximum: { okStr: "<", ok: ops.LT, fail: ops.GTE },
|
||||
exclusiveMinimum: { okStr: ">", ok: ops.GT, fail: ops.LTE },
|
||||
};
|
||||
const error = {
|
||||
message: ({ keyword, schemaCode }) => (0, codegen_1.str) `must be ${KWDs[keyword].okStr} ${schemaCode}`,
|
||||
params: ({ keyword, schemaCode }) => (0, codegen_1._) `{comparison: ${KWDs[keyword].okStr}, limit: ${schemaCode}}`,
|
||||
};
|
||||
const def = {
|
||||
keyword: Object.keys(KWDs),
|
||||
type: "number",
|
||||
schemaType: "number",
|
||||
$data: true,
|
||||
error,
|
||||
code(cxt) {
|
||||
const { keyword, data, schemaCode } = cxt;
|
||||
cxt.fail$data((0, codegen_1._) `${data} ${KWDs[keyword].fail} ${schemaCode} || isNaN(${data})`);
|
||||
},
|
||||
};
|
||||
exports.default = def;
|
||||
//# sourceMappingURL=limitNumber.js.map
|
1
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/limitNumber.js.map
generated
vendored
Normal file
1
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/limitNumber.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"limitNumber.js","sourceRoot":"","sources":["../../../lib/vocabularies/validation/limitNumber.ts"],"names":[],"mappings":";;AAEA,mDAA6D;AAE7D,MAAM,GAAG,GAAG,mBAAS,CAAA;AAMrB,MAAM,IAAI,GAA4D;IACpE,OAAO,EAAE,EAAC,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC,EAAE,EAAC;IACjD,OAAO,EAAE,EAAC,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC,EAAE,EAAC;IACjD,gBAAgB,EAAE,EAAC,KAAK,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,GAAG,EAAC;IACzD,gBAAgB,EAAE,EAAC,KAAK,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,GAAG,EAAC;CAC1D,CAAA;AAQD,MAAM,KAAK,GAA2B;IACpC,OAAO,EAAE,CAAC,EAAC,OAAO,EAAE,UAAU,EAAC,EAAE,EAAE,CAAC,IAAA,aAAG,EAAA,WAAW,IAAI,CAAC,OAAc,CAAC,CAAC,KAAK,IAAI,UAAU,EAAE;IAC5F,MAAM,EAAE,CAAC,EAAC,OAAO,EAAE,UAAU,EAAC,EAAE,EAAE,CAChC,IAAA,WAAC,EAAA,gBAAgB,IAAI,CAAC,OAAc,CAAC,CAAC,KAAK,YAAY,UAAU,GAAG;CACvE,CAAA;AAED,MAAM,GAAG,GAA0B;IACjC,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;IAC1B,IAAI,EAAE,QAAQ;IACd,UAAU,EAAE,QAAQ;IACpB,KAAK,EAAE,IAAI;IACX,KAAK;IACL,IAAI,CAAC,GAAe;QAClB,MAAM,EAAC,OAAO,EAAE,IAAI,EAAE,UAAU,EAAC,GAAG,GAAG,CAAA;QACvC,GAAG,CAAC,SAAS,CAAC,IAAA,WAAC,EAAA,GAAG,IAAI,IAAI,IAAI,CAAC,OAAc,CAAC,CAAC,IAAI,IAAI,UAAU,aAAa,IAAI,GAAG,CAAC,CAAA;IACxF,CAAC;CACF,CAAA;AAED,kBAAe,GAAG,CAAA"}
|
3
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/limitProperties.d.ts
generated
vendored
Normal file
3
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/limitProperties.d.ts
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
import type { CodeKeywordDefinition } from "../../types";
|
||||
declare const def: CodeKeywordDefinition;
|
||||
export default def;
|
24
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/limitProperties.js
generated
vendored
Normal file
24
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/limitProperties.js
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const codegen_1 = require("../../compile/codegen");
|
||||
const error = {
|
||||
message({ keyword, schemaCode }) {
|
||||
const comp = keyword === "maxProperties" ? "more" : "fewer";
|
||||
return (0, codegen_1.str) `must NOT have ${comp} than ${schemaCode} properties`;
|
||||
},
|
||||
params: ({ schemaCode }) => (0, codegen_1._) `{limit: ${schemaCode}}`,
|
||||
};
|
||||
const def = {
|
||||
keyword: ["maxProperties", "minProperties"],
|
||||
type: "object",
|
||||
schemaType: "number",
|
||||
$data: true,
|
||||
error,
|
||||
code(cxt) {
|
||||
const { keyword, data, schemaCode } = cxt;
|
||||
const op = keyword === "maxProperties" ? codegen_1.operators.GT : codegen_1.operators.LT;
|
||||
cxt.fail$data((0, codegen_1._) `Object.keys(${data}).length ${op} ${schemaCode}`);
|
||||
},
|
||||
};
|
||||
exports.default = def;
|
||||
//# sourceMappingURL=limitProperties.js.map
|
1
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/limitProperties.js.map
generated
vendored
Normal file
1
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/limitProperties.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"limitProperties.js","sourceRoot":"","sources":["../../../lib/vocabularies/validation/limitProperties.ts"],"names":[],"mappings":";;AAEA,mDAAuD;AAEvD,MAAM,KAAK,GAA2B;IACpC,OAAO,CAAC,EAAC,OAAO,EAAE,UAAU,EAAC;QAC3B,MAAM,IAAI,GAAG,OAAO,KAAK,eAAe,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAA;QAC3D,OAAO,IAAA,aAAG,EAAA,iBAAiB,IAAI,SAAS,UAAU,aAAa,CAAA;IACjE,CAAC;IACD,MAAM,EAAE,CAAC,EAAC,UAAU,EAAC,EAAE,EAAE,CAAC,IAAA,WAAC,EAAA,WAAW,UAAU,GAAG;CACpD,CAAA;AAED,MAAM,GAAG,GAA0B;IACjC,OAAO,EAAE,CAAC,eAAe,EAAE,eAAe,CAAC;IAC3C,IAAI,EAAE,QAAQ;IACd,UAAU,EAAE,QAAQ;IACpB,KAAK,EAAE,IAAI;IACX,KAAK;IACL,IAAI,CAAC,GAAe;QAClB,MAAM,EAAC,OAAO,EAAE,IAAI,EAAE,UAAU,EAAC,GAAG,GAAG,CAAA;QACvC,MAAM,EAAE,GAAG,OAAO,KAAK,eAAe,CAAC,CAAC,CAAC,mBAAS,CAAC,EAAE,CAAC,CAAC,CAAC,mBAAS,CAAC,EAAE,CAAA;QACpE,GAAG,CAAC,SAAS,CAAC,IAAA,WAAC,EAAA,eAAe,IAAI,YAAY,EAAE,IAAI,UAAU,EAAE,CAAC,CAAA;IACnE,CAAC;CACF,CAAA;AAED,kBAAe,GAAG,CAAA"}
|
8
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/multipleOf.d.ts
generated
vendored
Normal file
8
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/multipleOf.d.ts
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
import type { CodeKeywordDefinition, ErrorObject } from "../../types";
|
||||
export type MultipleOfError = ErrorObject<"multipleOf", {
|
||||
multipleOf: number;
|
||||
}, number | {
|
||||
$data: string;
|
||||
}>;
|
||||
declare const def: CodeKeywordDefinition;
|
||||
export default def;
|
26
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/multipleOf.js
generated
vendored
Normal file
26
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/multipleOf.js
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const codegen_1 = require("../../compile/codegen");
|
||||
const error = {
|
||||
message: ({ schemaCode }) => (0, codegen_1.str) `must be multiple of ${schemaCode}`,
|
||||
params: ({ schemaCode }) => (0, codegen_1._) `{multipleOf: ${schemaCode}}`,
|
||||
};
|
||||
const def = {
|
||||
keyword: "multipleOf",
|
||||
type: "number",
|
||||
schemaType: "number",
|
||||
$data: true,
|
||||
error,
|
||||
code(cxt) {
|
||||
const { gen, data, schemaCode, it } = cxt;
|
||||
// const bdt = bad$DataType(schemaCode, <string>def.schemaType, $data)
|
||||
const prec = it.opts.multipleOfPrecision;
|
||||
const res = gen.let("res");
|
||||
const invalid = prec
|
||||
? (0, codegen_1._) `Math.abs(Math.round(${res}) - ${res}) > 1e-${prec}`
|
||||
: (0, codegen_1._) `${res} !== parseInt(${res})`;
|
||||
cxt.fail$data((0, codegen_1._) `(${schemaCode} === 0 || (${res} = ${data}/${schemaCode}, ${invalid}))`);
|
||||
},
|
||||
};
|
||||
exports.default = def;
|
||||
//# sourceMappingURL=multipleOf.js.map
|
1
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/multipleOf.js.map
generated
vendored
Normal file
1
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/multipleOf.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"multipleOf.js","sourceRoot":"","sources":["../../../lib/vocabularies/validation/multipleOf.ts"],"names":[],"mappings":";;AAEA,mDAA4C;AAQ5C,MAAM,KAAK,GAA2B;IACpC,OAAO,EAAE,CAAC,EAAC,UAAU,EAAC,EAAE,EAAE,CAAC,IAAA,aAAG,EAAA,uBAAuB,UAAU,EAAE;IACjE,MAAM,EAAE,CAAC,EAAC,UAAU,EAAC,EAAE,EAAE,CAAC,IAAA,WAAC,EAAA,gBAAgB,UAAU,GAAG;CACzD,CAAA;AAED,MAAM,GAAG,GAA0B;IACjC,OAAO,EAAE,YAAY;IACrB,IAAI,EAAE,QAAQ;IACd,UAAU,EAAE,QAAQ;IACpB,KAAK,EAAE,IAAI;IACX,KAAK;IACL,IAAI,CAAC,GAAe;QAClB,MAAM,EAAC,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAC,GAAG,GAAG,CAAA;QACvC,sEAAsE;QACtE,MAAM,IAAI,GAAG,EAAE,CAAC,IAAI,CAAC,mBAAmB,CAAA;QACxC,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;QAC1B,MAAM,OAAO,GAAG,IAAI;YAClB,CAAC,CAAC,IAAA,WAAC,EAAA,uBAAuB,GAAG,OAAO,GAAG,UAAU,IAAI,EAAE;YACvD,CAAC,CAAC,IAAA,WAAC,EAAA,GAAG,GAAG,iBAAiB,GAAG,GAAG,CAAA;QAClC,GAAG,CAAC,SAAS,CAAC,IAAA,WAAC,EAAA,IAAI,UAAU,cAAc,GAAG,MAAM,IAAI,IAAI,UAAU,KAAK,OAAO,IAAI,CAAC,CAAA;IACzF,CAAC;CACF,CAAA;AAED,kBAAe,GAAG,CAAA"}
|
8
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/pattern.d.ts
generated
vendored
Normal file
8
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/pattern.d.ts
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
import type { CodeKeywordDefinition, ErrorObject } from "../../types";
|
||||
export type PatternError = ErrorObject<"pattern", {
|
||||
pattern: string;
|
||||
}, string | {
|
||||
$data: string;
|
||||
}>;
|
||||
declare const def: CodeKeywordDefinition;
|
||||
export default def;
|
24
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/pattern.js
generated
vendored
Normal file
24
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/pattern.js
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const code_1 = require("../code");
|
||||
const codegen_1 = require("../../compile/codegen");
|
||||
const error = {
|
||||
message: ({ schemaCode }) => (0, codegen_1.str) `must match pattern "${schemaCode}"`,
|
||||
params: ({ schemaCode }) => (0, codegen_1._) `{pattern: ${schemaCode}}`,
|
||||
};
|
||||
const def = {
|
||||
keyword: "pattern",
|
||||
type: "string",
|
||||
schemaType: "string",
|
||||
$data: true,
|
||||
error,
|
||||
code(cxt) {
|
||||
const { data, $data, schema, schemaCode, it } = cxt;
|
||||
// TODO regexp should be wrapped in try/catchs
|
||||
const u = it.opts.unicodeRegExp ? "u" : "";
|
||||
const regExp = $data ? (0, codegen_1._) `(new RegExp(${schemaCode}, ${u}))` : (0, code_1.usePattern)(cxt, schema);
|
||||
cxt.fail$data((0, codegen_1._) `!${regExp}.test(${data})`);
|
||||
},
|
||||
};
|
||||
exports.default = def;
|
||||
//# sourceMappingURL=pattern.js.map
|
1
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/pattern.js.map
generated
vendored
Normal file
1
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/pattern.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"pattern.js","sourceRoot":"","sources":["../../../lib/vocabularies/validation/pattern.ts"],"names":[],"mappings":";;AAEA,kCAAkC;AAClC,mDAA4C;AAI5C,MAAM,KAAK,GAA2B;IACpC,OAAO,EAAE,CAAC,EAAC,UAAU,EAAC,EAAE,EAAE,CAAC,IAAA,aAAG,EAAA,uBAAuB,UAAU,GAAG;IAClE,MAAM,EAAE,CAAC,EAAC,UAAU,EAAC,EAAE,EAAE,CAAC,IAAA,WAAC,EAAA,aAAa,UAAU,GAAG;CACtD,CAAA;AAED,MAAM,GAAG,GAA0B;IACjC,OAAO,EAAE,SAAS;IAClB,IAAI,EAAE,QAAQ;IACd,UAAU,EAAE,QAAQ;IACpB,KAAK,EAAE,IAAI;IACX,KAAK;IACL,IAAI,CAAC,GAAe;QAClB,MAAM,EAAC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,EAAC,GAAG,GAAG,CAAA;QACjD,8CAA8C;QAC9C,MAAM,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAA;QAC1C,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,IAAA,WAAC,EAAA,eAAe,UAAU,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAA,iBAAU,EAAC,GAAG,EAAE,MAAM,CAAC,CAAA;QACrF,GAAG,CAAC,SAAS,CAAC,IAAA,WAAC,EAAA,IAAI,MAAM,SAAS,IAAI,GAAG,CAAC,CAAA;IAC5C,CAAC;CACF,CAAA;AAED,kBAAe,GAAG,CAAA"}
|
8
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/required.d.ts
generated
vendored
Normal file
8
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/required.d.ts
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
import type { CodeKeywordDefinition, ErrorObject } from "../../types";
|
||||
export type RequiredError = ErrorObject<"required", {
|
||||
missingProperty: string;
|
||||
}, string[] | {
|
||||
$data: string;
|
||||
}>;
|
||||
declare const def: CodeKeywordDefinition;
|
||||
export default def;
|
79
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/required.js
generated
vendored
Normal file
79
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/required.js
generated
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const code_1 = require("../code");
|
||||
const codegen_1 = require("../../compile/codegen");
|
||||
const util_1 = require("../../compile/util");
|
||||
const error = {
|
||||
message: ({ params: { missingProperty } }) => (0, codegen_1.str) `must have required property '${missingProperty}'`,
|
||||
params: ({ params: { missingProperty } }) => (0, codegen_1._) `{missingProperty: ${missingProperty}}`,
|
||||
};
|
||||
const def = {
|
||||
keyword: "required",
|
||||
type: "object",
|
||||
schemaType: "array",
|
||||
$data: true,
|
||||
error,
|
||||
code(cxt) {
|
||||
const { gen, schema, schemaCode, data, $data, it } = cxt;
|
||||
const { opts } = it;
|
||||
if (!$data && schema.length === 0)
|
||||
return;
|
||||
const useLoop = schema.length >= opts.loopRequired;
|
||||
if (it.allErrors)
|
||||
allErrorsMode();
|
||||
else
|
||||
exitOnErrorMode();
|
||||
if (opts.strictRequired) {
|
||||
const props = cxt.parentSchema.properties;
|
||||
const { definedProperties } = cxt.it;
|
||||
for (const requiredKey of schema) {
|
||||
if ((props === null || props === void 0 ? void 0 : props[requiredKey]) === undefined && !definedProperties.has(requiredKey)) {
|
||||
const schemaPath = it.schemaEnv.baseId + it.errSchemaPath;
|
||||
const msg = `required property "${requiredKey}" is not defined at "${schemaPath}" (strictRequired)`;
|
||||
(0, util_1.checkStrictMode)(it, msg, it.opts.strictRequired);
|
||||
}
|
||||
}
|
||||
}
|
||||
function allErrorsMode() {
|
||||
if (useLoop || $data) {
|
||||
cxt.block$data(codegen_1.nil, loopAllRequired);
|
||||
}
|
||||
else {
|
||||
for (const prop of schema) {
|
||||
(0, code_1.checkReportMissingProp)(cxt, prop);
|
||||
}
|
||||
}
|
||||
}
|
||||
function exitOnErrorMode() {
|
||||
const missing = gen.let("missing");
|
||||
if (useLoop || $data) {
|
||||
const valid = gen.let("valid", true);
|
||||
cxt.block$data(valid, () => loopUntilMissing(missing, valid));
|
||||
cxt.ok(valid);
|
||||
}
|
||||
else {
|
||||
gen.if((0, code_1.checkMissingProp)(cxt, schema, missing));
|
||||
(0, code_1.reportMissingProp)(cxt, missing);
|
||||
gen.else();
|
||||
}
|
||||
}
|
||||
function loopAllRequired() {
|
||||
gen.forOf("prop", schemaCode, (prop) => {
|
||||
cxt.setParams({ missingProperty: prop });
|
||||
gen.if((0, code_1.noPropertyInData)(gen, data, prop, opts.ownProperties), () => cxt.error());
|
||||
});
|
||||
}
|
||||
function loopUntilMissing(missing, valid) {
|
||||
cxt.setParams({ missingProperty: missing });
|
||||
gen.forOf(missing, schemaCode, () => {
|
||||
gen.assign(valid, (0, code_1.propertyInData)(gen, data, missing, opts.ownProperties));
|
||||
gen.if((0, codegen_1.not)(valid), () => {
|
||||
cxt.error();
|
||||
gen.break();
|
||||
});
|
||||
}, codegen_1.nil);
|
||||
}
|
||||
},
|
||||
};
|
||||
exports.default = def;
|
||||
//# sourceMappingURL=required.js.map
|
1
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/required.js.map
generated
vendored
Normal file
1
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/required.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"required.js","sourceRoot":"","sources":["../../../lib/vocabularies/validation/required.ts"],"names":[],"mappings":";;AAEA,kCAMgB;AAChB,mDAAkE;AAClE,6CAAkD;AAQlD,MAAM,KAAK,GAA2B;IACpC,OAAO,EAAE,CAAC,EAAC,MAAM,EAAE,EAAC,eAAe,EAAC,EAAC,EAAE,EAAE,CAAC,IAAA,aAAG,EAAA,gCAAgC,eAAe,GAAG;IAC/F,MAAM,EAAE,CAAC,EAAC,MAAM,EAAE,EAAC,eAAe,EAAC,EAAC,EAAE,EAAE,CAAC,IAAA,WAAC,EAAA,qBAAqB,eAAe,GAAG;CAClF,CAAA;AAED,MAAM,GAAG,GAA0B;IACjC,OAAO,EAAE,UAAU;IACnB,IAAI,EAAE,QAAQ;IACd,UAAU,EAAE,OAAO;IACnB,KAAK,EAAE,IAAI;IACX,KAAK;IACL,IAAI,CAAC,GAAe;QAClB,MAAM,EAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAC,GAAG,GAAG,CAAA;QACtD,MAAM,EAAC,IAAI,EAAC,GAAG,EAAE,CAAA;QACjB,IAAI,CAAC,KAAK,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;YAAE,OAAM;QACzC,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,IAAI,IAAI,CAAC,YAAY,CAAA;QAClD,IAAI,EAAE,CAAC,SAAS;YAAE,aAAa,EAAE,CAAA;;YAC5B,eAAe,EAAE,CAAA;QAEtB,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,MAAM,KAAK,GAAG,GAAG,CAAC,YAAY,CAAC,UAAU,CAAA;YACzC,MAAM,EAAC,iBAAiB,EAAC,GAAG,GAAG,CAAC,EAAE,CAAA;YAClC,KAAK,MAAM,WAAW,IAAI,MAAM,EAAE,CAAC;gBACjC,IAAI,CAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAG,WAAW,CAAC,MAAK,SAAS,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC;oBAC9E,MAAM,UAAU,GAAG,EAAE,CAAC,SAAS,CAAC,MAAM,GAAG,EAAE,CAAC,aAAa,CAAA;oBACzD,MAAM,GAAG,GAAG,sBAAsB,WAAW,wBAAwB,UAAU,oBAAoB,CAAA;oBACnG,IAAA,sBAAe,EAAC,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,CAAA;gBAClD,CAAC;YACH,CAAC;QACH,CAAC;QAED,SAAS,aAAa;YACpB,IAAI,OAAO,IAAI,KAAK,EAAE,CAAC;gBACrB,GAAG,CAAC,UAAU,CAAC,aAAG,EAAE,eAAe,CAAC,CAAA;YACtC,CAAC;iBAAM,CAAC;gBACN,KAAK,MAAM,IAAI,IAAI,MAAM,EAAE,CAAC;oBAC1B,IAAA,6BAAsB,EAAC,GAAG,EAAE,IAAI,CAAC,CAAA;gBACnC,CAAC;YACH,CAAC;QACH,CAAC;QAED,SAAS,eAAe;YACtB,MAAM,OAAO,GAAG,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;YAClC,IAAI,OAAO,IAAI,KAAK,EAAE,CAAC;gBACrB,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;gBACpC,GAAG,CAAC,UAAU,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,gBAAgB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAA;gBAC7D,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,CAAA;YACf,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,EAAE,CAAC,IAAA,uBAAgB,EAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;gBAC9C,IAAA,wBAAiB,EAAC,GAAG,EAAE,OAAO,CAAC,CAAA;gBAC/B,GAAG,CAAC,IAAI,EAAE,CAAA;YACZ,CAAC;QACH,CAAC;QAED,SAAS,eAAe;YACtB,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,UAAkB,EAAE,CAAC,IAAI,EAAE,EAAE;gBAC7C,GAAG,CAAC,SAAS,CAAC,EAAC,eAAe,EAAE,IAAI,EAAC,CAAC,CAAA;gBACtC,GAAG,CAAC,EAAE,CAAC,IAAA,uBAAgB,EAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,aAAa,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAA;YAClF,CAAC,CAAC,CAAA;QACJ,CAAC;QAED,SAAS,gBAAgB,CAAC,OAAa,EAAE,KAAW;YAClD,GAAG,CAAC,SAAS,CAAC,EAAC,eAAe,EAAE,OAAO,EAAC,CAAC,CAAA;YACzC,GAAG,CAAC,KAAK,CACP,OAAO,EACP,UAAkB,EAClB,GAAG,EAAE;gBACH,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,IAAA,qBAAc,EAAC,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC,CAAA;gBACzE,GAAG,CAAC,EAAE,CAAC,IAAA,aAAG,EAAC,KAAK,CAAC,EAAE,GAAG,EAAE;oBACtB,GAAG,CAAC,KAAK,EAAE,CAAA;oBACX,GAAG,CAAC,KAAK,EAAE,CAAA;gBACb,CAAC,CAAC,CAAA;YACJ,CAAC,EACD,aAAG,CACJ,CAAA;QACH,CAAC;IACH,CAAC;CACF,CAAA;AAED,kBAAe,GAAG,CAAA"}
|
9
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/uniqueItems.d.ts
generated
vendored
Normal file
9
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/uniqueItems.d.ts
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
import type { CodeKeywordDefinition, ErrorObject } from "../../types";
|
||||
export type UniqueItemsError = ErrorObject<"uniqueItems", {
|
||||
i: number;
|
||||
j: number;
|
||||
}, boolean | {
|
||||
$data: string;
|
||||
}>;
|
||||
declare const def: CodeKeywordDefinition;
|
||||
export default def;
|
64
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/uniqueItems.js
generated
vendored
Normal file
64
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/uniqueItems.js
generated
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const dataType_1 = require("../../compile/validate/dataType");
|
||||
const codegen_1 = require("../../compile/codegen");
|
||||
const util_1 = require("../../compile/util");
|
||||
const equal_1 = require("../../runtime/equal");
|
||||
const error = {
|
||||
message: ({ params: { i, j } }) => (0, codegen_1.str) `must NOT have duplicate items (items ## ${j} and ${i} are identical)`,
|
||||
params: ({ params: { i, j } }) => (0, codegen_1._) `{i: ${i}, j: ${j}}`,
|
||||
};
|
||||
const def = {
|
||||
keyword: "uniqueItems",
|
||||
type: "array",
|
||||
schemaType: "boolean",
|
||||
$data: true,
|
||||
error,
|
||||
code(cxt) {
|
||||
const { gen, data, $data, schema, parentSchema, schemaCode, it } = cxt;
|
||||
if (!$data && !schema)
|
||||
return;
|
||||
const valid = gen.let("valid");
|
||||
const itemTypes = parentSchema.items ? (0, dataType_1.getSchemaTypes)(parentSchema.items) : [];
|
||||
cxt.block$data(valid, validateUniqueItems, (0, codegen_1._) `${schemaCode} === false`);
|
||||
cxt.ok(valid);
|
||||
function validateUniqueItems() {
|
||||
const i = gen.let("i", (0, codegen_1._) `${data}.length`);
|
||||
const j = gen.let("j");
|
||||
cxt.setParams({ i, j });
|
||||
gen.assign(valid, true);
|
||||
gen.if((0, codegen_1._) `${i} > 1`, () => (canOptimize() ? loopN : loopN2)(i, j));
|
||||
}
|
||||
function canOptimize() {
|
||||
return itemTypes.length > 0 && !itemTypes.some((t) => t === "object" || t === "array");
|
||||
}
|
||||
function loopN(i, j) {
|
||||
const item = gen.name("item");
|
||||
const wrongType = (0, dataType_1.checkDataTypes)(itemTypes, item, it.opts.strictNumbers, dataType_1.DataType.Wrong);
|
||||
const indices = gen.const("indices", (0, codegen_1._) `{}`);
|
||||
gen.for((0, codegen_1._) `;${i}--;`, () => {
|
||||
gen.let(item, (0, codegen_1._) `${data}[${i}]`);
|
||||
gen.if(wrongType, (0, codegen_1._) `continue`);
|
||||
if (itemTypes.length > 1)
|
||||
gen.if((0, codegen_1._) `typeof ${item} == "string"`, (0, codegen_1._) `${item} += "_"`);
|
||||
gen
|
||||
.if((0, codegen_1._) `typeof ${indices}[${item}] == "number"`, () => {
|
||||
gen.assign(j, (0, codegen_1._) `${indices}[${item}]`);
|
||||
cxt.error();
|
||||
gen.assign(valid, false).break();
|
||||
})
|
||||
.code((0, codegen_1._) `${indices}[${item}] = ${i}`);
|
||||
});
|
||||
}
|
||||
function loopN2(i, j) {
|
||||
const eql = (0, util_1.useFunc)(gen, equal_1.default);
|
||||
const outer = gen.name("outer");
|
||||
gen.label(outer).for((0, codegen_1._) `;${i}--;`, () => gen.for((0, codegen_1._) `${j} = ${i}; ${j}--;`, () => gen.if((0, codegen_1._) `${eql}(${data}[${i}], ${data}[${j}])`, () => {
|
||||
cxt.error();
|
||||
gen.assign(valid, false).break(outer);
|
||||
})));
|
||||
}
|
||||
},
|
||||
};
|
||||
exports.default = def;
|
||||
//# sourceMappingURL=uniqueItems.js.map
|
1
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/uniqueItems.js.map
generated
vendored
Normal file
1
node_modules/schema-utils/node_modules/ajv/dist/vocabularies/validation/uniqueItems.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"uniqueItems.js","sourceRoot":"","sources":["../../../lib/vocabularies/validation/uniqueItems.ts"],"names":[],"mappings":";;AAEA,8DAAwF;AACxF,mDAAkD;AAClD,6CAA0C;AAC1C,+CAAuC;AAQvC,MAAM,KAAK,GAA2B;IACpC,OAAO,EAAE,CAAC,EAAC,MAAM,EAAE,EAAC,CAAC,EAAE,CAAC,EAAC,EAAC,EAAE,EAAE,CAC5B,IAAA,aAAG,EAAA,2CAA2C,CAAC,QAAQ,CAAC,iBAAiB;IAC3E,MAAM,EAAE,CAAC,EAAC,MAAM,EAAE,EAAC,CAAC,EAAE,CAAC,EAAC,EAAC,EAAE,EAAE,CAAC,IAAA,WAAC,EAAA,OAAO,CAAC,QAAQ,CAAC,GAAG;CACpD,CAAA;AAED,MAAM,GAAG,GAA0B;IACjC,OAAO,EAAE,aAAa;IACtB,IAAI,EAAE,OAAO;IACb,UAAU,EAAE,SAAS;IACrB,KAAK,EAAE,IAAI;IACX,KAAK;IACL,IAAI,CAAC,GAAe;QAClB,MAAM,EAAC,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,UAAU,EAAE,EAAE,EAAC,GAAG,GAAG,CAAA;QACpE,IAAI,CAAC,KAAK,IAAI,CAAC,MAAM;YAAE,OAAM;QAC7B,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;QAC9B,MAAM,SAAS,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,IAAA,yBAAc,EAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;QAC9E,GAAG,CAAC,UAAU,CAAC,KAAK,EAAE,mBAAmB,EAAE,IAAA,WAAC,EAAA,GAAG,UAAU,YAAY,CAAC,CAAA;QACtE,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,CAAA;QAEb,SAAS,mBAAmB;YAC1B,MAAM,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,IAAA,WAAC,EAAA,GAAG,IAAI,SAAS,CAAC,CAAA;YACzC,MAAM,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YACtB,GAAG,CAAC,SAAS,CAAC,EAAC,CAAC,EAAE,CAAC,EAAC,CAAC,CAAA;YACrB,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;YACvB,GAAG,CAAC,EAAE,CAAC,IAAA,WAAC,EAAA,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QACnE,CAAC;QAED,SAAS,WAAW;YAClB,OAAO,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,OAAO,CAAC,CAAA;QACxF,CAAC;QAED,SAAS,KAAK,CAAC,CAAO,EAAE,CAAO;YAC7B,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;YAC7B,MAAM,SAAS,GAAG,IAAA,yBAAc,EAAC,SAAS,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,EAAE,mBAAQ,CAAC,KAAK,CAAC,CAAA;YACxF,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE,IAAA,WAAC,EAAA,IAAI,CAAC,CAAA;YAC3C,GAAG,CAAC,GAAG,CAAC,IAAA,WAAC,EAAA,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE;gBACxB,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,IAAA,WAAC,EAAA,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAA;gBAC/B,GAAG,CAAC,EAAE,CAAC,SAAS,EAAE,IAAA,WAAC,EAAA,UAAU,CAAC,CAAA;gBAC9B,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC;oBAAE,GAAG,CAAC,EAAE,CAAC,IAAA,WAAC,EAAA,UAAU,IAAI,cAAc,EAAE,IAAA,WAAC,EAAA,GAAG,IAAI,SAAS,CAAC,CAAA;gBAClF,GAAG;qBACA,EAAE,CAAC,IAAA,WAAC,EAAA,UAAU,OAAO,IAAI,IAAI,eAAe,EAAE,GAAG,EAAE;oBAClD,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,IAAA,WAAC,EAAA,GAAG,OAAO,IAAI,IAAI,GAAG,CAAC,CAAA;oBACrC,GAAG,CAAC,KAAK,EAAE,CAAA;oBACX,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,KAAK,EAAE,CAAA;gBAClC,CAAC,CAAC;qBACD,IAAI,CAAC,IAAA,WAAC,EAAA,GAAG,OAAO,IAAI,IAAI,OAAO,CAAC,EAAE,CAAC,CAAA;YACxC,CAAC,CAAC,CAAA;QACJ,CAAC;QAED,SAAS,MAAM,CAAC,CAAO,EAAE,CAAO;YAC9B,MAAM,GAAG,GAAG,IAAA,cAAO,EAAC,GAAG,EAAE,eAAK,CAAC,CAAA;YAC/B,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;YAC/B,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,IAAA,WAAC,EAAA,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,CACrC,GAAG,CAAC,GAAG,CAAC,IAAA,WAAC,EAAA,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,EAAE,CACpC,GAAG,CAAC,EAAE,CAAC,IAAA,WAAC,EAAA,GAAG,GAAG,IAAI,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE;gBACnD,GAAG,CAAC,KAAK,EAAE,CAAA;gBACX,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;YACvC,CAAC,CAAC,CACH,CACF,CAAA;QACH,CAAC;IACH,CAAC;CACF,CAAA;AAED,kBAAe,GAAG,CAAA"}
|
81
node_modules/schema-utils/node_modules/ajv/lib/2019.ts
generated
vendored
Normal file
81
node_modules/schema-utils/node_modules/ajv/lib/2019.ts
generated
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
import type {AnySchemaObject} from "./types"
|
||||
import AjvCore, {Options} from "./core"
|
||||
|
||||
import draft7Vocabularies from "./vocabularies/draft7"
|
||||
import dynamicVocabulary from "./vocabularies/dynamic"
|
||||
import nextVocabulary from "./vocabularies/next"
|
||||
import unevaluatedVocabulary from "./vocabularies/unevaluated"
|
||||
import discriminator from "./vocabularies/discriminator"
|
||||
import addMetaSchema2019 from "./refs/json-schema-2019-09"
|
||||
|
||||
const META_SCHEMA_ID = "https://json-schema.org/draft/2019-09/schema"
|
||||
|
||||
export class Ajv2019 extends AjvCore {
|
||||
constructor(opts: Options = {}) {
|
||||
super({
|
||||
...opts,
|
||||
dynamicRef: true,
|
||||
next: true,
|
||||
unevaluated: true,
|
||||
})
|
||||
}
|
||||
|
||||
_addVocabularies(): void {
|
||||
super._addVocabularies()
|
||||
this.addVocabulary(dynamicVocabulary)
|
||||
draft7Vocabularies.forEach((v) => this.addVocabulary(v))
|
||||
this.addVocabulary(nextVocabulary)
|
||||
this.addVocabulary(unevaluatedVocabulary)
|
||||
if (this.opts.discriminator) this.addKeyword(discriminator)
|
||||
}
|
||||
|
||||
_addDefaultMetaSchema(): void {
|
||||
super._addDefaultMetaSchema()
|
||||
const {$data, meta} = this.opts
|
||||
if (!meta) return
|
||||
addMetaSchema2019.call(this, $data)
|
||||
this.refs["http://json-schema.org/schema"] = META_SCHEMA_ID
|
||||
}
|
||||
|
||||
defaultMeta(): string | AnySchemaObject | undefined {
|
||||
return (this.opts.defaultMeta =
|
||||
super.defaultMeta() || (this.getSchema(META_SCHEMA_ID) ? META_SCHEMA_ID : undefined))
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = exports = Ajv2019
|
||||
module.exports.Ajv2019 = Ajv2019
|
||||
Object.defineProperty(exports, "__esModule", {value: true})
|
||||
|
||||
export default Ajv2019
|
||||
|
||||
export {
|
||||
Format,
|
||||
FormatDefinition,
|
||||
AsyncFormatDefinition,
|
||||
KeywordDefinition,
|
||||
KeywordErrorDefinition,
|
||||
CodeKeywordDefinition,
|
||||
MacroKeywordDefinition,
|
||||
FuncKeywordDefinition,
|
||||
Vocabulary,
|
||||
Schema,
|
||||
SchemaObject,
|
||||
AnySchemaObject,
|
||||
AsyncSchema,
|
||||
AnySchema,
|
||||
ValidateFunction,
|
||||
AsyncValidateFunction,
|
||||
ErrorObject,
|
||||
ErrorNoParams,
|
||||
} from "./types"
|
||||
|
||||
export {Plugin, Options, CodeOptions, InstanceOptions, Logger, ErrorsTextOptions} from "./core"
|
||||
export {SchemaCxt, SchemaObjCxt} from "./compile"
|
||||
export {KeywordCxt} from "./compile/validate"
|
||||
export {DefinedError} from "./vocabularies/errors"
|
||||
export {JSONType} from "./compile/rules"
|
||||
export {JSONSchemaType} from "./types/json-schema"
|
||||
export {_, str, stringify, nil, Name, Code, CodeGen, CodeGenOptions} from "./compile/codegen"
|
||||
export {default as ValidationError} from "./runtime/validation_error"
|
||||
export {default as MissingRefError} from "./compile/ref_error"
|
75
node_modules/schema-utils/node_modules/ajv/lib/2020.ts
generated
vendored
Normal file
75
node_modules/schema-utils/node_modules/ajv/lib/2020.ts
generated
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
import type {AnySchemaObject} from "./types"
|
||||
import AjvCore, {Options} from "./core"
|
||||
|
||||
import draft2020Vocabularies from "./vocabularies/draft2020"
|
||||
import discriminator from "./vocabularies/discriminator"
|
||||
import addMetaSchema2020 from "./refs/json-schema-2020-12"
|
||||
|
||||
const META_SCHEMA_ID = "https://json-schema.org/draft/2020-12/schema"
|
||||
|
||||
export class Ajv2020 extends AjvCore {
|
||||
constructor(opts: Options = {}) {
|
||||
super({
|
||||
...opts,
|
||||
dynamicRef: true,
|
||||
next: true,
|
||||
unevaluated: true,
|
||||
})
|
||||
}
|
||||
|
||||
_addVocabularies(): void {
|
||||
super._addVocabularies()
|
||||
draft2020Vocabularies.forEach((v) => this.addVocabulary(v))
|
||||
if (this.opts.discriminator) this.addKeyword(discriminator)
|
||||
}
|
||||
|
||||
_addDefaultMetaSchema(): void {
|
||||
super._addDefaultMetaSchema()
|
||||
const {$data, meta} = this.opts
|
||||
if (!meta) return
|
||||
addMetaSchema2020.call(this, $data)
|
||||
this.refs["http://json-schema.org/schema"] = META_SCHEMA_ID
|
||||
}
|
||||
|
||||
defaultMeta(): string | AnySchemaObject | undefined {
|
||||
return (this.opts.defaultMeta =
|
||||
super.defaultMeta() || (this.getSchema(META_SCHEMA_ID) ? META_SCHEMA_ID : undefined))
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = exports = Ajv2020
|
||||
module.exports.Ajv2020 = Ajv2020
|
||||
Object.defineProperty(exports, "__esModule", {value: true})
|
||||
|
||||
export default Ajv2020
|
||||
|
||||
export {
|
||||
Format,
|
||||
FormatDefinition,
|
||||
AsyncFormatDefinition,
|
||||
KeywordDefinition,
|
||||
KeywordErrorDefinition,
|
||||
CodeKeywordDefinition,
|
||||
MacroKeywordDefinition,
|
||||
FuncKeywordDefinition,
|
||||
Vocabulary,
|
||||
Schema,
|
||||
SchemaObject,
|
||||
AnySchemaObject,
|
||||
AsyncSchema,
|
||||
AnySchema,
|
||||
ValidateFunction,
|
||||
AsyncValidateFunction,
|
||||
ErrorObject,
|
||||
ErrorNoParams,
|
||||
} from "./types"
|
||||
|
||||
export {Plugin, Options, CodeOptions, InstanceOptions, Logger, ErrorsTextOptions} from "./core"
|
||||
export {SchemaCxt, SchemaObjCxt} from "./compile"
|
||||
export {KeywordCxt} from "./compile/validate"
|
||||
export {DefinedError} from "./vocabularies/errors"
|
||||
export {JSONType} from "./compile/rules"
|
||||
export {JSONSchemaType} from "./types/json-schema"
|
||||
export {_, str, stringify, nil, Name, Code, CodeGen, CodeGenOptions} from "./compile/codegen"
|
||||
export {default as ValidationError} from "./runtime/validation_error"
|
||||
export {default as MissingRefError} from "./compile/ref_error"
|
70
node_modules/schema-utils/node_modules/ajv/lib/ajv.ts
generated
vendored
Normal file
70
node_modules/schema-utils/node_modules/ajv/lib/ajv.ts
generated
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
import type {AnySchemaObject} from "./types"
|
||||
import AjvCore from "./core"
|
||||
import draft7Vocabularies from "./vocabularies/draft7"
|
||||
import discriminator from "./vocabularies/discriminator"
|
||||
import * as draft7MetaSchema from "./refs/json-schema-draft-07.json"
|
||||
|
||||
const META_SUPPORT_DATA = ["/properties"]
|
||||
|
||||
const META_SCHEMA_ID = "http://json-schema.org/draft-07/schema"
|
||||
|
||||
export class Ajv extends AjvCore {
|
||||
_addVocabularies(): void {
|
||||
super._addVocabularies()
|
||||
draft7Vocabularies.forEach((v) => this.addVocabulary(v))
|
||||
if (this.opts.discriminator) this.addKeyword(discriminator)
|
||||
}
|
||||
|
||||
_addDefaultMetaSchema(): void {
|
||||
super._addDefaultMetaSchema()
|
||||
if (!this.opts.meta) return
|
||||
const metaSchema = this.opts.$data
|
||||
? this.$dataMetaSchema(draft7MetaSchema, META_SUPPORT_DATA)
|
||||
: draft7MetaSchema
|
||||
this.addMetaSchema(metaSchema, META_SCHEMA_ID, false)
|
||||
this.refs["http://json-schema.org/schema"] = META_SCHEMA_ID
|
||||
}
|
||||
|
||||
defaultMeta(): string | AnySchemaObject | undefined {
|
||||
return (this.opts.defaultMeta =
|
||||
super.defaultMeta() || (this.getSchema(META_SCHEMA_ID) ? META_SCHEMA_ID : undefined))
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = exports = Ajv
|
||||
module.exports.Ajv = Ajv
|
||||
Object.defineProperty(exports, "__esModule", {value: true})
|
||||
|
||||
export default Ajv
|
||||
|
||||
export {
|
||||
Format,
|
||||
FormatDefinition,
|
||||
AsyncFormatDefinition,
|
||||
KeywordDefinition,
|
||||
KeywordErrorDefinition,
|
||||
CodeKeywordDefinition,
|
||||
MacroKeywordDefinition,
|
||||
FuncKeywordDefinition,
|
||||
Vocabulary,
|
||||
Schema,
|
||||
SchemaObject,
|
||||
AnySchemaObject,
|
||||
AsyncSchema,
|
||||
AnySchema,
|
||||
ValidateFunction,
|
||||
AsyncValidateFunction,
|
||||
SchemaValidateFunction,
|
||||
ErrorObject,
|
||||
ErrorNoParams,
|
||||
} from "./types"
|
||||
|
||||
export {Plugin, Options, CodeOptions, InstanceOptions, Logger, ErrorsTextOptions} from "./core"
|
||||
export {SchemaCxt, SchemaObjCxt} from "./compile"
|
||||
export {KeywordCxt} from "./compile/validate"
|
||||
export {DefinedError} from "./vocabularies/errors"
|
||||
export {JSONType} from "./compile/rules"
|
||||
export {JSONSchemaType} from "./types/json-schema"
|
||||
export {_, str, stringify, nil, Name, Code, CodeGen, CodeGenOptions} from "./compile/codegen"
|
||||
export {default as ValidationError} from "./runtime/validation_error"
|
||||
export {default as MissingRefError} from "./compile/ref_error"
|
169
node_modules/schema-utils/node_modules/ajv/lib/compile/codegen/code.ts
generated
vendored
Normal file
169
node_modules/schema-utils/node_modules/ajv/lib/compile/codegen/code.ts
generated
vendored
Normal file
@@ -0,0 +1,169 @@
|
||||
// eslint-disable-next-line @typescript-eslint/no-extraneous-class
|
||||
export abstract class _CodeOrName {
|
||||
abstract readonly str: string
|
||||
abstract readonly names: UsedNames
|
||||
abstract toString(): string
|
||||
abstract emptyStr(): boolean
|
||||
}
|
||||
|
||||
export const IDENTIFIER = /^[a-z$_][a-z$_0-9]*$/i
|
||||
|
||||
export class Name extends _CodeOrName {
|
||||
readonly str: string
|
||||
constructor(s: string) {
|
||||
super()
|
||||
if (!IDENTIFIER.test(s)) throw new Error("CodeGen: name must be a valid identifier")
|
||||
this.str = s
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return this.str
|
||||
}
|
||||
|
||||
emptyStr(): boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
get names(): UsedNames {
|
||||
return {[this.str]: 1}
|
||||
}
|
||||
}
|
||||
|
||||
export class _Code extends _CodeOrName {
|
||||
readonly _items: readonly CodeItem[]
|
||||
private _str?: string
|
||||
private _names?: UsedNames
|
||||
|
||||
constructor(code: string | readonly CodeItem[]) {
|
||||
super()
|
||||
this._items = typeof code === "string" ? [code] : code
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return this.str
|
||||
}
|
||||
|
||||
emptyStr(): boolean {
|
||||
if (this._items.length > 1) return false
|
||||
const item = this._items[0]
|
||||
return item === "" || item === '""'
|
||||
}
|
||||
|
||||
get str(): string {
|
||||
return (this._str ??= this._items.reduce((s: string, c: CodeItem) => `${s}${c}`, ""))
|
||||
}
|
||||
|
||||
get names(): UsedNames {
|
||||
return (this._names ??= this._items.reduce((names: UsedNames, c) => {
|
||||
if (c instanceof Name) names[c.str] = (names[c.str] || 0) + 1
|
||||
return names
|
||||
}, {}))
|
||||
}
|
||||
}
|
||||
|
||||
export type CodeItem = Name | string | number | boolean | null
|
||||
|
||||
export type UsedNames = Record<string, number | undefined>
|
||||
|
||||
export type Code = _Code | Name
|
||||
|
||||
export type SafeExpr = Code | number | boolean | null
|
||||
|
||||
export const nil = new _Code("")
|
||||
|
||||
type CodeArg = SafeExpr | string | undefined
|
||||
|
||||
export function _(strs: TemplateStringsArray, ...args: CodeArg[]): _Code {
|
||||
const code: CodeItem[] = [strs[0]]
|
||||
let i = 0
|
||||
while (i < args.length) {
|
||||
addCodeArg(code, args[i])
|
||||
code.push(strs[++i])
|
||||
}
|
||||
return new _Code(code)
|
||||
}
|
||||
|
||||
const plus = new _Code("+")
|
||||
|
||||
export function str(strs: TemplateStringsArray, ...args: (CodeArg | string[])[]): _Code {
|
||||
const expr: CodeItem[] = [safeStringify(strs[0])]
|
||||
let i = 0
|
||||
while (i < args.length) {
|
||||
expr.push(plus)
|
||||
addCodeArg(expr, args[i])
|
||||
expr.push(plus, safeStringify(strs[++i]))
|
||||
}
|
||||
optimize(expr)
|
||||
return new _Code(expr)
|
||||
}
|
||||
|
||||
export function addCodeArg(code: CodeItem[], arg: CodeArg | string[]): void {
|
||||
if (arg instanceof _Code) code.push(...arg._items)
|
||||
else if (arg instanceof Name) code.push(arg)
|
||||
else code.push(interpolate(arg))
|
||||
}
|
||||
|
||||
function optimize(expr: CodeItem[]): void {
|
||||
let i = 1
|
||||
while (i < expr.length - 1) {
|
||||
if (expr[i] === plus) {
|
||||
const res = mergeExprItems(expr[i - 1], expr[i + 1])
|
||||
if (res !== undefined) {
|
||||
expr.splice(i - 1, 3, res)
|
||||
continue
|
||||
}
|
||||
expr[i++] = "+"
|
||||
}
|
||||
i++
|
||||
}
|
||||
}
|
||||
|
||||
function mergeExprItems(a: CodeItem, b: CodeItem): CodeItem | undefined {
|
||||
if (b === '""') return a
|
||||
if (a === '""') return b
|
||||
if (typeof a == "string") {
|
||||
if (b instanceof Name || a[a.length - 1] !== '"') return
|
||||
if (typeof b != "string") return `${a.slice(0, -1)}${b}"`
|
||||
if (b[0] === '"') return a.slice(0, -1) + b.slice(1)
|
||||
return
|
||||
}
|
||||
if (typeof b == "string" && b[0] === '"' && !(a instanceof Name)) return `"${a}${b.slice(1)}`
|
||||
return
|
||||
}
|
||||
|
||||
export function strConcat(c1: Code, c2: Code): Code {
|
||||
return c2.emptyStr() ? c1 : c1.emptyStr() ? c2 : str`${c1}${c2}`
|
||||
}
|
||||
|
||||
// TODO do not allow arrays here
|
||||
function interpolate(x?: string | string[] | number | boolean | null): SafeExpr | string {
|
||||
return typeof x == "number" || typeof x == "boolean" || x === null
|
||||
? x
|
||||
: safeStringify(Array.isArray(x) ? x.join(",") : x)
|
||||
}
|
||||
|
||||
export function stringify(x: unknown): Code {
|
||||
return new _Code(safeStringify(x))
|
||||
}
|
||||
|
||||
export function safeStringify(x: unknown): string {
|
||||
return JSON.stringify(x)
|
||||
.replace(/\u2028/g, "\\u2028")
|
||||
.replace(/\u2029/g, "\\u2029")
|
||||
}
|
||||
|
||||
export function getProperty(key: Code | string | number): Code {
|
||||
return typeof key == "string" && IDENTIFIER.test(key) ? new _Code(`.${key}`) : _`[${key}]`
|
||||
}
|
||||
|
||||
//Does best effort to format the name properly
|
||||
export function getEsmExportName(key: Code | string | number): Code {
|
||||
if (typeof key == "string" && IDENTIFIER.test(key)) {
|
||||
return new _Code(`${key}`)
|
||||
}
|
||||
throw new Error(`CodeGen: invalid export name: ${key}, use explicit $id name mapping`)
|
||||
}
|
||||
|
||||
export function regexpCode(rx: RegExp): Code {
|
||||
return new _Code(rx.toString())
|
||||
}
|
852
node_modules/schema-utils/node_modules/ajv/lib/compile/codegen/index.ts
generated
vendored
Normal file
852
node_modules/schema-utils/node_modules/ajv/lib/compile/codegen/index.ts
generated
vendored
Normal file
@@ -0,0 +1,852 @@
|
||||
import type {ScopeValueSets, NameValue, ValueScope, ValueScopeName} from "./scope"
|
||||
import {_, nil, _Code, Code, Name, UsedNames, CodeItem, addCodeArg, _CodeOrName} from "./code"
|
||||
import {Scope, varKinds} from "./scope"
|
||||
|
||||
export {_, str, strConcat, nil, getProperty, stringify, regexpCode, Name, Code} from "./code"
|
||||
export {Scope, ScopeStore, ValueScope, ValueScopeName, ScopeValueSets, varKinds} from "./scope"
|
||||
|
||||
// type for expressions that can be safely inserted in code without quotes
|
||||
export type SafeExpr = Code | number | boolean | null
|
||||
|
||||
// type that is either Code of function that adds code to CodeGen instance using its methods
|
||||
export type Block = Code | (() => void)
|
||||
|
||||
export const operators = {
|
||||
GT: new _Code(">"),
|
||||
GTE: new _Code(">="),
|
||||
LT: new _Code("<"),
|
||||
LTE: new _Code("<="),
|
||||
EQ: new _Code("==="),
|
||||
NEQ: new _Code("!=="),
|
||||
NOT: new _Code("!"),
|
||||
OR: new _Code("||"),
|
||||
AND: new _Code("&&"),
|
||||
ADD: new _Code("+"),
|
||||
}
|
||||
|
||||
abstract class Node {
|
||||
abstract readonly names: UsedNames
|
||||
|
||||
optimizeNodes(): this | ChildNode | ChildNode[] | undefined {
|
||||
return this
|
||||
}
|
||||
|
||||
optimizeNames(_names: UsedNames, _constants: Constants): this | undefined {
|
||||
return this
|
||||
}
|
||||
|
||||
// get count(): number {
|
||||
// return 1
|
||||
// }
|
||||
}
|
||||
|
||||
class Def extends Node {
|
||||
constructor(
|
||||
private readonly varKind: Name,
|
||||
private readonly name: Name,
|
||||
private rhs?: SafeExpr
|
||||
) {
|
||||
super()
|
||||
}
|
||||
|
||||
render({es5, _n}: CGOptions): string {
|
||||
const varKind = es5 ? varKinds.var : this.varKind
|
||||
const rhs = this.rhs === undefined ? "" : ` = ${this.rhs}`
|
||||
return `${varKind} ${this.name}${rhs};` + _n
|
||||
}
|
||||
|
||||
optimizeNames(names: UsedNames, constants: Constants): this | undefined {
|
||||
if (!names[this.name.str]) return
|
||||
if (this.rhs) this.rhs = optimizeExpr(this.rhs, names, constants)
|
||||
return this
|
||||
}
|
||||
|
||||
get names(): UsedNames {
|
||||
return this.rhs instanceof _CodeOrName ? this.rhs.names : {}
|
||||
}
|
||||
}
|
||||
|
||||
class Assign extends Node {
|
||||
constructor(
|
||||
readonly lhs: Code,
|
||||
public rhs: SafeExpr,
|
||||
private readonly sideEffects?: boolean
|
||||
) {
|
||||
super()
|
||||
}
|
||||
|
||||
render({_n}: CGOptions): string {
|
||||
return `${this.lhs} = ${this.rhs};` + _n
|
||||
}
|
||||
|
||||
optimizeNames(names: UsedNames, constants: Constants): this | undefined {
|
||||
if (this.lhs instanceof Name && !names[this.lhs.str] && !this.sideEffects) return
|
||||
this.rhs = optimizeExpr(this.rhs, names, constants)
|
||||
return this
|
||||
}
|
||||
|
||||
get names(): UsedNames {
|
||||
const names = this.lhs instanceof Name ? {} : {...this.lhs.names}
|
||||
return addExprNames(names, this.rhs)
|
||||
}
|
||||
}
|
||||
|
||||
class AssignOp extends Assign {
|
||||
constructor(
|
||||
lhs: Code,
|
||||
private readonly op: Code,
|
||||
rhs: SafeExpr,
|
||||
sideEffects?: boolean
|
||||
) {
|
||||
super(lhs, rhs, sideEffects)
|
||||
}
|
||||
|
||||
render({_n}: CGOptions): string {
|
||||
return `${this.lhs} ${this.op}= ${this.rhs};` + _n
|
||||
}
|
||||
}
|
||||
|
||||
class Label extends Node {
|
||||
readonly names: UsedNames = {}
|
||||
constructor(readonly label: Name) {
|
||||
super()
|
||||
}
|
||||
|
||||
render({_n}: CGOptions): string {
|
||||
return `${this.label}:` + _n
|
||||
}
|
||||
}
|
||||
|
||||
class Break extends Node {
|
||||
readonly names: UsedNames = {}
|
||||
constructor(readonly label?: Code) {
|
||||
super()
|
||||
}
|
||||
|
||||
render({_n}: CGOptions): string {
|
||||
const label = this.label ? ` ${this.label}` : ""
|
||||
return `break${label};` + _n
|
||||
}
|
||||
}
|
||||
|
||||
class Throw extends Node {
|
||||
constructor(readonly error: Code) {
|
||||
super()
|
||||
}
|
||||
|
||||
render({_n}: CGOptions): string {
|
||||
return `throw ${this.error};` + _n
|
||||
}
|
||||
|
||||
get names(): UsedNames {
|
||||
return this.error.names
|
||||
}
|
||||
}
|
||||
|
||||
class AnyCode extends Node {
|
||||
constructor(private code: SafeExpr) {
|
||||
super()
|
||||
}
|
||||
|
||||
render({_n}: CGOptions): string {
|
||||
return `${this.code};` + _n
|
||||
}
|
||||
|
||||
optimizeNodes(): this | undefined {
|
||||
return `${this.code}` ? this : undefined
|
||||
}
|
||||
|
||||
optimizeNames(names: UsedNames, constants: Constants): this {
|
||||
this.code = optimizeExpr(this.code, names, constants)
|
||||
return this
|
||||
}
|
||||
|
||||
get names(): UsedNames {
|
||||
return this.code instanceof _CodeOrName ? this.code.names : {}
|
||||
}
|
||||
}
|
||||
|
||||
abstract class ParentNode extends Node {
|
||||
constructor(readonly nodes: ChildNode[] = []) {
|
||||
super()
|
||||
}
|
||||
|
||||
render(opts: CGOptions): string {
|
||||
return this.nodes.reduce((code, n) => code + n.render(opts), "")
|
||||
}
|
||||
|
||||
optimizeNodes(): this | ChildNode | ChildNode[] | undefined {
|
||||
const {nodes} = this
|
||||
let i = nodes.length
|
||||
while (i--) {
|
||||
const n = nodes[i].optimizeNodes()
|
||||
if (Array.isArray(n)) nodes.splice(i, 1, ...n)
|
||||
else if (n) nodes[i] = n
|
||||
else nodes.splice(i, 1)
|
||||
}
|
||||
return nodes.length > 0 ? this : undefined
|
||||
}
|
||||
|
||||
optimizeNames(names: UsedNames, constants: Constants): this | undefined {
|
||||
const {nodes} = this
|
||||
let i = nodes.length
|
||||
while (i--) {
|
||||
// iterating backwards improves 1-pass optimization
|
||||
const n = nodes[i]
|
||||
if (n.optimizeNames(names, constants)) continue
|
||||
subtractNames(names, n.names)
|
||||
nodes.splice(i, 1)
|
||||
}
|
||||
return nodes.length > 0 ? this : undefined
|
||||
}
|
||||
|
||||
get names(): UsedNames {
|
||||
return this.nodes.reduce((names: UsedNames, n) => addNames(names, n.names), {})
|
||||
}
|
||||
|
||||
// get count(): number {
|
||||
// return this.nodes.reduce((c, n) => c + n.count, 1)
|
||||
// }
|
||||
}
|
||||
|
||||
abstract class BlockNode extends ParentNode {
|
||||
render(opts: CGOptions): string {
|
||||
return "{" + opts._n + super.render(opts) + "}" + opts._n
|
||||
}
|
||||
}
|
||||
|
||||
class Root extends ParentNode {}
|
||||
|
||||
class Else extends BlockNode {
|
||||
static readonly kind = "else"
|
||||
}
|
||||
|
||||
class If extends BlockNode {
|
||||
static readonly kind = "if"
|
||||
else?: If | Else
|
||||
constructor(
|
||||
private condition: Code | boolean,
|
||||
nodes?: ChildNode[]
|
||||
) {
|
||||
super(nodes)
|
||||
}
|
||||
|
||||
render(opts: CGOptions): string {
|
||||
let code = `if(${this.condition})` + super.render(opts)
|
||||
if (this.else) code += "else " + this.else.render(opts)
|
||||
return code
|
||||
}
|
||||
|
||||
optimizeNodes(): If | ChildNode[] | undefined {
|
||||
super.optimizeNodes()
|
||||
const cond = this.condition
|
||||
if (cond === true) return this.nodes // else is ignored here
|
||||
let e = this.else
|
||||
if (e) {
|
||||
const ns = e.optimizeNodes()
|
||||
e = this.else = Array.isArray(ns) ? new Else(ns) : (ns as Else | undefined)
|
||||
}
|
||||
if (e) {
|
||||
if (cond === false) return e instanceof If ? e : e.nodes
|
||||
if (this.nodes.length) return this
|
||||
return new If(not(cond), e instanceof If ? [e] : e.nodes)
|
||||
}
|
||||
if (cond === false || !this.nodes.length) return undefined
|
||||
return this
|
||||
}
|
||||
|
||||
optimizeNames(names: UsedNames, constants: Constants): this | undefined {
|
||||
this.else = this.else?.optimizeNames(names, constants)
|
||||
if (!(super.optimizeNames(names, constants) || this.else)) return
|
||||
this.condition = optimizeExpr(this.condition, names, constants)
|
||||
return this
|
||||
}
|
||||
|
||||
get names(): UsedNames {
|
||||
const names = super.names
|
||||
addExprNames(names, this.condition)
|
||||
if (this.else) addNames(names, this.else.names)
|
||||
return names
|
||||
}
|
||||
|
||||
// get count(): number {
|
||||
// return super.count + (this.else?.count || 0)
|
||||
// }
|
||||
}
|
||||
|
||||
abstract class For extends BlockNode {
|
||||
static readonly kind = "for"
|
||||
}
|
||||
|
||||
class ForLoop extends For {
|
||||
constructor(private iteration: Code) {
|
||||
super()
|
||||
}
|
||||
|
||||
render(opts: CGOptions): string {
|
||||
return `for(${this.iteration})` + super.render(opts)
|
||||
}
|
||||
|
||||
optimizeNames(names: UsedNames, constants: Constants): this | undefined {
|
||||
if (!super.optimizeNames(names, constants)) return
|
||||
this.iteration = optimizeExpr(this.iteration, names, constants)
|
||||
return this
|
||||
}
|
||||
|
||||
get names(): UsedNames {
|
||||
return addNames(super.names, this.iteration.names)
|
||||
}
|
||||
}
|
||||
|
||||
class ForRange extends For {
|
||||
constructor(
|
||||
private readonly varKind: Name,
|
||||
private readonly name: Name,
|
||||
private readonly from: SafeExpr,
|
||||
private readonly to: SafeExpr
|
||||
) {
|
||||
super()
|
||||
}
|
||||
|
||||
render(opts: CGOptions): string {
|
||||
const varKind = opts.es5 ? varKinds.var : this.varKind
|
||||
const {name, from, to} = this
|
||||
return `for(${varKind} ${name}=${from}; ${name}<${to}; ${name}++)` + super.render(opts)
|
||||
}
|
||||
|
||||
get names(): UsedNames {
|
||||
const names = addExprNames(super.names, this.from)
|
||||
return addExprNames(names, this.to)
|
||||
}
|
||||
}
|
||||
|
||||
class ForIter extends For {
|
||||
constructor(
|
||||
private readonly loop: "of" | "in",
|
||||
private readonly varKind: Name,
|
||||
private readonly name: Name,
|
||||
private iterable: Code
|
||||
) {
|
||||
super()
|
||||
}
|
||||
|
||||
render(opts: CGOptions): string {
|
||||
return `for(${this.varKind} ${this.name} ${this.loop} ${this.iterable})` + super.render(opts)
|
||||
}
|
||||
|
||||
optimizeNames(names: UsedNames, constants: Constants): this | undefined {
|
||||
if (!super.optimizeNames(names, constants)) return
|
||||
this.iterable = optimizeExpr(this.iterable, names, constants)
|
||||
return this
|
||||
}
|
||||
|
||||
get names(): UsedNames {
|
||||
return addNames(super.names, this.iterable.names)
|
||||
}
|
||||
}
|
||||
|
||||
class Func extends BlockNode {
|
||||
static readonly kind = "func"
|
||||
constructor(
|
||||
public name: Name,
|
||||
public args: Code,
|
||||
public async?: boolean
|
||||
) {
|
||||
super()
|
||||
}
|
||||
|
||||
render(opts: CGOptions): string {
|
||||
const _async = this.async ? "async " : ""
|
||||
return `${_async}function ${this.name}(${this.args})` + super.render(opts)
|
||||
}
|
||||
}
|
||||
|
||||
class Return extends ParentNode {
|
||||
static readonly kind = "return"
|
||||
|
||||
render(opts: CGOptions): string {
|
||||
return "return " + super.render(opts)
|
||||
}
|
||||
}
|
||||
|
||||
class Try extends BlockNode {
|
||||
catch?: Catch
|
||||
finally?: Finally
|
||||
|
||||
render(opts: CGOptions): string {
|
||||
let code = "try" + super.render(opts)
|
||||
if (this.catch) code += this.catch.render(opts)
|
||||
if (this.finally) code += this.finally.render(opts)
|
||||
return code
|
||||
}
|
||||
|
||||
optimizeNodes(): this {
|
||||
super.optimizeNodes()
|
||||
this.catch?.optimizeNodes() as Catch | undefined
|
||||
this.finally?.optimizeNodes() as Finally | undefined
|
||||
return this
|
||||
}
|
||||
|
||||
optimizeNames(names: UsedNames, constants: Constants): this {
|
||||
super.optimizeNames(names, constants)
|
||||
this.catch?.optimizeNames(names, constants)
|
||||
this.finally?.optimizeNames(names, constants)
|
||||
return this
|
||||
}
|
||||
|
||||
get names(): UsedNames {
|
||||
const names = super.names
|
||||
if (this.catch) addNames(names, this.catch.names)
|
||||
if (this.finally) addNames(names, this.finally.names)
|
||||
return names
|
||||
}
|
||||
|
||||
// get count(): number {
|
||||
// return super.count + (this.catch?.count || 0) + (this.finally?.count || 0)
|
||||
// }
|
||||
}
|
||||
|
||||
class Catch extends BlockNode {
|
||||
static readonly kind = "catch"
|
||||
constructor(readonly error: Name) {
|
||||
super()
|
||||
}
|
||||
|
||||
render(opts: CGOptions): string {
|
||||
return `catch(${this.error})` + super.render(opts)
|
||||
}
|
||||
}
|
||||
|
||||
class Finally extends BlockNode {
|
||||
static readonly kind = "finally"
|
||||
render(opts: CGOptions): string {
|
||||
return "finally" + super.render(opts)
|
||||
}
|
||||
}
|
||||
|
||||
type StartBlockNode = If | For | Func | Return | Try
|
||||
|
||||
type LeafNode = Def | Assign | Label | Break | Throw | AnyCode
|
||||
|
||||
type ChildNode = StartBlockNode | LeafNode
|
||||
|
||||
type EndBlockNodeType =
|
||||
| typeof If
|
||||
| typeof Else
|
||||
| typeof For
|
||||
| typeof Func
|
||||
| typeof Return
|
||||
| typeof Catch
|
||||
| typeof Finally
|
||||
|
||||
type Constants = Record<string, SafeExpr | undefined>
|
||||
|
||||
export interface CodeGenOptions {
|
||||
es5?: boolean
|
||||
lines?: boolean
|
||||
ownProperties?: boolean
|
||||
}
|
||||
|
||||
interface CGOptions extends CodeGenOptions {
|
||||
_n: "\n" | ""
|
||||
}
|
||||
|
||||
export class CodeGen {
|
||||
readonly _scope: Scope
|
||||
readonly _extScope: ValueScope
|
||||
readonly _values: ScopeValueSets = {}
|
||||
private readonly _nodes: ParentNode[]
|
||||
private readonly _blockStarts: number[] = []
|
||||
private readonly _constants: Constants = {}
|
||||
private readonly opts: CGOptions
|
||||
|
||||
constructor(extScope: ValueScope, opts: CodeGenOptions = {}) {
|
||||
this.opts = {...opts, _n: opts.lines ? "\n" : ""}
|
||||
this._extScope = extScope
|
||||
this._scope = new Scope({parent: extScope})
|
||||
this._nodes = [new Root()]
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return this._root.render(this.opts)
|
||||
}
|
||||
|
||||
// returns unique name in the internal scope
|
||||
name(prefix: string): Name {
|
||||
return this._scope.name(prefix)
|
||||
}
|
||||
|
||||
// reserves unique name in the external scope
|
||||
scopeName(prefix: string): ValueScopeName {
|
||||
return this._extScope.name(prefix)
|
||||
}
|
||||
|
||||
// reserves unique name in the external scope and assigns value to it
|
||||
scopeValue(prefixOrName: ValueScopeName | string, value: NameValue): Name {
|
||||
const name = this._extScope.value(prefixOrName, value)
|
||||
const vs = this._values[name.prefix] || (this._values[name.prefix] = new Set())
|
||||
vs.add(name)
|
||||
return name
|
||||
}
|
||||
|
||||
getScopeValue(prefix: string, keyOrRef: unknown): ValueScopeName | undefined {
|
||||
return this._extScope.getValue(prefix, keyOrRef)
|
||||
}
|
||||
|
||||
// return code that assigns values in the external scope to the names that are used internally
|
||||
// (same names that were returned by gen.scopeName or gen.scopeValue)
|
||||
scopeRefs(scopeName: Name): Code {
|
||||
return this._extScope.scopeRefs(scopeName, this._values)
|
||||
}
|
||||
|
||||
scopeCode(): Code {
|
||||
return this._extScope.scopeCode(this._values)
|
||||
}
|
||||
|
||||
private _def(
|
||||
varKind: Name,
|
||||
nameOrPrefix: Name | string,
|
||||
rhs?: SafeExpr,
|
||||
constant?: boolean
|
||||
): Name {
|
||||
const name = this._scope.toName(nameOrPrefix)
|
||||
if (rhs !== undefined && constant) this._constants[name.str] = rhs
|
||||
this._leafNode(new Def(varKind, name, rhs))
|
||||
return name
|
||||
}
|
||||
|
||||
// `const` declaration (`var` in es5 mode)
|
||||
const(nameOrPrefix: Name | string, rhs: SafeExpr, _constant?: boolean): Name {
|
||||
return this._def(varKinds.const, nameOrPrefix, rhs, _constant)
|
||||
}
|
||||
|
||||
// `let` declaration with optional assignment (`var` in es5 mode)
|
||||
let(nameOrPrefix: Name | string, rhs?: SafeExpr, _constant?: boolean): Name {
|
||||
return this._def(varKinds.let, nameOrPrefix, rhs, _constant)
|
||||
}
|
||||
|
||||
// `var` declaration with optional assignment
|
||||
var(nameOrPrefix: Name | string, rhs?: SafeExpr, _constant?: boolean): Name {
|
||||
return this._def(varKinds.var, nameOrPrefix, rhs, _constant)
|
||||
}
|
||||
|
||||
// assignment code
|
||||
assign(lhs: Code, rhs: SafeExpr, sideEffects?: boolean): CodeGen {
|
||||
return this._leafNode(new Assign(lhs, rhs, sideEffects))
|
||||
}
|
||||
|
||||
// `+=` code
|
||||
add(lhs: Code, rhs: SafeExpr): CodeGen {
|
||||
return this._leafNode(new AssignOp(lhs, operators.ADD, rhs))
|
||||
}
|
||||
|
||||
// appends passed SafeExpr to code or executes Block
|
||||
code(c: Block | SafeExpr): CodeGen {
|
||||
if (typeof c == "function") c()
|
||||
else if (c !== nil) this._leafNode(new AnyCode(c))
|
||||
return this
|
||||
}
|
||||
|
||||
// returns code for object literal for the passed argument list of key-value pairs
|
||||
object(...keyValues: [Name | string, SafeExpr | string][]): _Code {
|
||||
const code: CodeItem[] = ["{"]
|
||||
for (const [key, value] of keyValues) {
|
||||
if (code.length > 1) code.push(",")
|
||||
code.push(key)
|
||||
if (key !== value || this.opts.es5) {
|
||||
code.push(":")
|
||||
addCodeArg(code, value)
|
||||
}
|
||||
}
|
||||
code.push("}")
|
||||
return new _Code(code)
|
||||
}
|
||||
|
||||
// `if` clause (or statement if `thenBody` and, optionally, `elseBody` are passed)
|
||||
if(condition: Code | boolean, thenBody?: Block, elseBody?: Block): CodeGen {
|
||||
this._blockNode(new If(condition))
|
||||
|
||||
if (thenBody && elseBody) {
|
||||
this.code(thenBody).else().code(elseBody).endIf()
|
||||
} else if (thenBody) {
|
||||
this.code(thenBody).endIf()
|
||||
} else if (elseBody) {
|
||||
throw new Error('CodeGen: "else" body without "then" body')
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
// `else if` clause - invalid without `if` or after `else` clauses
|
||||
elseIf(condition: Code | boolean): CodeGen {
|
||||
return this._elseNode(new If(condition))
|
||||
}
|
||||
|
||||
// `else` clause - only valid after `if` or `else if` clauses
|
||||
else(): CodeGen {
|
||||
return this._elseNode(new Else())
|
||||
}
|
||||
|
||||
// end `if` statement (needed if gen.if was used only with condition)
|
||||
endIf(): CodeGen {
|
||||
return this._endBlockNode(If, Else)
|
||||
}
|
||||
|
||||
private _for(node: For, forBody?: Block): CodeGen {
|
||||
this._blockNode(node)
|
||||
if (forBody) this.code(forBody).endFor()
|
||||
return this
|
||||
}
|
||||
|
||||
// a generic `for` clause (or statement if `forBody` is passed)
|
||||
for(iteration: Code, forBody?: Block): CodeGen {
|
||||
return this._for(new ForLoop(iteration), forBody)
|
||||
}
|
||||
|
||||
// `for` statement for a range of values
|
||||
forRange(
|
||||
nameOrPrefix: Name | string,
|
||||
from: SafeExpr,
|
||||
to: SafeExpr,
|
||||
forBody: (index: Name) => void,
|
||||
varKind: Code = this.opts.es5 ? varKinds.var : varKinds.let
|
||||
): CodeGen {
|
||||
const name = this._scope.toName(nameOrPrefix)
|
||||
return this._for(new ForRange(varKind, name, from, to), () => forBody(name))
|
||||
}
|
||||
|
||||
// `for-of` statement (in es5 mode replace with a normal for loop)
|
||||
forOf(
|
||||
nameOrPrefix: Name | string,
|
||||
iterable: Code,
|
||||
forBody: (item: Name) => void,
|
||||
varKind: Code = varKinds.const
|
||||
): CodeGen {
|
||||
const name = this._scope.toName(nameOrPrefix)
|
||||
if (this.opts.es5) {
|
||||
const arr = iterable instanceof Name ? iterable : this.var("_arr", iterable)
|
||||
return this.forRange("_i", 0, _`${arr}.length`, (i) => {
|
||||
this.var(name, _`${arr}[${i}]`)
|
||||
forBody(name)
|
||||
})
|
||||
}
|
||||
return this._for(new ForIter("of", varKind, name, iterable), () => forBody(name))
|
||||
}
|
||||
|
||||
// `for-in` statement.
|
||||
// With option `ownProperties` replaced with a `for-of` loop for object keys
|
||||
forIn(
|
||||
nameOrPrefix: Name | string,
|
||||
obj: Code,
|
||||
forBody: (item: Name) => void,
|
||||
varKind: Code = this.opts.es5 ? varKinds.var : varKinds.const
|
||||
): CodeGen {
|
||||
if (this.opts.ownProperties) {
|
||||
return this.forOf(nameOrPrefix, _`Object.keys(${obj})`, forBody)
|
||||
}
|
||||
const name = this._scope.toName(nameOrPrefix)
|
||||
return this._for(new ForIter("in", varKind, name, obj), () => forBody(name))
|
||||
}
|
||||
|
||||
// end `for` loop
|
||||
endFor(): CodeGen {
|
||||
return this._endBlockNode(For)
|
||||
}
|
||||
|
||||
// `label` statement
|
||||
label(label: Name): CodeGen {
|
||||
return this._leafNode(new Label(label))
|
||||
}
|
||||
|
||||
// `break` statement
|
||||
break(label?: Code): CodeGen {
|
||||
return this._leafNode(new Break(label))
|
||||
}
|
||||
|
||||
// `return` statement
|
||||
return(value: Block | SafeExpr): CodeGen {
|
||||
const node = new Return()
|
||||
this._blockNode(node)
|
||||
this.code(value)
|
||||
if (node.nodes.length !== 1) throw new Error('CodeGen: "return" should have one node')
|
||||
return this._endBlockNode(Return)
|
||||
}
|
||||
|
||||
// `try` statement
|
||||
try(tryBody: Block, catchCode?: (e: Name) => void, finallyCode?: Block): CodeGen {
|
||||
if (!catchCode && !finallyCode) throw new Error('CodeGen: "try" without "catch" and "finally"')
|
||||
const node = new Try()
|
||||
this._blockNode(node)
|
||||
this.code(tryBody)
|
||||
if (catchCode) {
|
||||
const error = this.name("e")
|
||||
this._currNode = node.catch = new Catch(error)
|
||||
catchCode(error)
|
||||
}
|
||||
if (finallyCode) {
|
||||
this._currNode = node.finally = new Finally()
|
||||
this.code(finallyCode)
|
||||
}
|
||||
return this._endBlockNode(Catch, Finally)
|
||||
}
|
||||
|
||||
// `throw` statement
|
||||
throw(error: Code): CodeGen {
|
||||
return this._leafNode(new Throw(error))
|
||||
}
|
||||
|
||||
// start self-balancing block
|
||||
block(body?: Block, nodeCount?: number): CodeGen {
|
||||
this._blockStarts.push(this._nodes.length)
|
||||
if (body) this.code(body).endBlock(nodeCount)
|
||||
return this
|
||||
}
|
||||
|
||||
// end the current self-balancing block
|
||||
endBlock(nodeCount?: number): CodeGen {
|
||||
const len = this._blockStarts.pop()
|
||||
if (len === undefined) throw new Error("CodeGen: not in self-balancing block")
|
||||
const toClose = this._nodes.length - len
|
||||
if (toClose < 0 || (nodeCount !== undefined && toClose !== nodeCount)) {
|
||||
throw new Error(`CodeGen: wrong number of nodes: ${toClose} vs ${nodeCount} expected`)
|
||||
}
|
||||
this._nodes.length = len
|
||||
return this
|
||||
}
|
||||
|
||||
// `function` heading (or definition if funcBody is passed)
|
||||
func(name: Name, args: Code = nil, async?: boolean, funcBody?: Block): CodeGen {
|
||||
this._blockNode(new Func(name, args, async))
|
||||
if (funcBody) this.code(funcBody).endFunc()
|
||||
return this
|
||||
}
|
||||
|
||||
// end function definition
|
||||
endFunc(): CodeGen {
|
||||
return this._endBlockNode(Func)
|
||||
}
|
||||
|
||||
optimize(n = 1): void {
|
||||
while (n-- > 0) {
|
||||
this._root.optimizeNodes()
|
||||
this._root.optimizeNames(this._root.names, this._constants)
|
||||
}
|
||||
}
|
||||
|
||||
private _leafNode(node: LeafNode): CodeGen {
|
||||
this._currNode.nodes.push(node)
|
||||
return this
|
||||
}
|
||||
|
||||
private _blockNode(node: StartBlockNode): void {
|
||||
this._currNode.nodes.push(node)
|
||||
this._nodes.push(node)
|
||||
}
|
||||
|
||||
private _endBlockNode(N1: EndBlockNodeType, N2?: EndBlockNodeType): CodeGen {
|
||||
const n = this._currNode
|
||||
if (n instanceof N1 || (N2 && n instanceof N2)) {
|
||||
this._nodes.pop()
|
||||
return this
|
||||
}
|
||||
throw new Error(`CodeGen: not in block "${N2 ? `${N1.kind}/${N2.kind}` : N1.kind}"`)
|
||||
}
|
||||
|
||||
private _elseNode(node: If | Else): CodeGen {
|
||||
const n = this._currNode
|
||||
if (!(n instanceof If)) {
|
||||
throw new Error('CodeGen: "else" without "if"')
|
||||
}
|
||||
this._currNode = n.else = node
|
||||
return this
|
||||
}
|
||||
|
||||
private get _root(): Root {
|
||||
return this._nodes[0] as Root
|
||||
}
|
||||
|
||||
private get _currNode(): ParentNode {
|
||||
const ns = this._nodes
|
||||
return ns[ns.length - 1]
|
||||
}
|
||||
|
||||
private set _currNode(node: ParentNode) {
|
||||
const ns = this._nodes
|
||||
ns[ns.length - 1] = node
|
||||
}
|
||||
|
||||
// get nodeCount(): number {
|
||||
// return this._root.count
|
||||
// }
|
||||
}
|
||||
|
||||
function addNames(names: UsedNames, from: UsedNames): UsedNames {
|
||||
for (const n in from) names[n] = (names[n] || 0) + (from[n] || 0)
|
||||
return names
|
||||
}
|
||||
|
||||
function addExprNames(names: UsedNames, from: SafeExpr): UsedNames {
|
||||
return from instanceof _CodeOrName ? addNames(names, from.names) : names
|
||||
}
|
||||
|
||||
function optimizeExpr<T extends SafeExpr | Code>(expr: T, names: UsedNames, constants: Constants): T
|
||||
function optimizeExpr(expr: SafeExpr, names: UsedNames, constants: Constants): SafeExpr {
|
||||
if (expr instanceof Name) return replaceName(expr)
|
||||
if (!canOptimize(expr)) return expr
|
||||
return new _Code(
|
||||
expr._items.reduce((items: CodeItem[], c: SafeExpr | string) => {
|
||||
if (c instanceof Name) c = replaceName(c)
|
||||
if (c instanceof _Code) items.push(...c._items)
|
||||
else items.push(c)
|
||||
return items
|
||||
}, [])
|
||||
)
|
||||
|
||||
function replaceName(n: Name): SafeExpr {
|
||||
const c = constants[n.str]
|
||||
if (c === undefined || names[n.str] !== 1) return n
|
||||
delete names[n.str]
|
||||
return c
|
||||
}
|
||||
|
||||
function canOptimize(e: SafeExpr): e is _Code {
|
||||
return (
|
||||
e instanceof _Code &&
|
||||
e._items.some(
|
||||
(c) => c instanceof Name && names[c.str] === 1 && constants[c.str] !== undefined
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
function subtractNames(names: UsedNames, from: UsedNames): void {
|
||||
for (const n in from) names[n] = (names[n] || 0) - (from[n] || 0)
|
||||
}
|
||||
|
||||
export function not<T extends Code | SafeExpr>(x: T): T
|
||||
export function not(x: Code | SafeExpr): Code | SafeExpr {
|
||||
return typeof x == "boolean" || typeof x == "number" || x === null ? !x : _`!${par(x)}`
|
||||
}
|
||||
|
||||
const andCode = mappend(operators.AND)
|
||||
|
||||
// boolean AND (&&) expression with the passed arguments
|
||||
export function and(...args: Code[]): Code {
|
||||
return args.reduce(andCode)
|
||||
}
|
||||
|
||||
const orCode = mappend(operators.OR)
|
||||
|
||||
// boolean OR (||) expression with the passed arguments
|
||||
export function or(...args: Code[]): Code {
|
||||
return args.reduce(orCode)
|
||||
}
|
||||
|
||||
type MAppend = (x: Code, y: Code) => Code
|
||||
|
||||
function mappend(op: Code): MAppend {
|
||||
return (x, y) => (x === nil ? y : y === nil ? x : _`${par(x)} ${op} ${par(y)}`)
|
||||
}
|
||||
|
||||
function par(x: Code): Code {
|
||||
return x instanceof Name ? x : _`(${x})`
|
||||
}
|
215
node_modules/schema-utils/node_modules/ajv/lib/compile/codegen/scope.ts
generated
vendored
Normal file
215
node_modules/schema-utils/node_modules/ajv/lib/compile/codegen/scope.ts
generated
vendored
Normal file
@@ -0,0 +1,215 @@
|
||||
import {_, nil, Code, Name} from "./code"
|
||||
|
||||
interface NameGroup {
|
||||
prefix: string
|
||||
index: number
|
||||
}
|
||||
|
||||
export interface NameValue {
|
||||
ref: ValueReference // this is the reference to any value that can be referred to from generated code via `globals` var in the closure
|
||||
key?: unknown // any key to identify a global to avoid duplicates, if not passed ref is used
|
||||
code?: Code // this is the code creating the value needed for standalone code wit_out closure - can be a primitive value, function or import (`require`)
|
||||
}
|
||||
|
||||
export type ValueReference = unknown // possibly make CodeGen parameterized type on this type
|
||||
|
||||
class ValueError extends Error {
|
||||
readonly value?: NameValue
|
||||
constructor(name: ValueScopeName) {
|
||||
super(`CodeGen: "code" for ${name} not defined`)
|
||||
this.value = name.value
|
||||
}
|
||||
}
|
||||
|
||||
interface ScopeOptions {
|
||||
prefixes?: Set<string>
|
||||
parent?: Scope
|
||||
}
|
||||
|
||||
interface ValueScopeOptions extends ScopeOptions {
|
||||
scope: ScopeStore
|
||||
es5?: boolean
|
||||
lines?: boolean
|
||||
}
|
||||
|
||||
export type ScopeStore = Record<string, ValueReference[] | undefined>
|
||||
|
||||
type ScopeValues = {
|
||||
[Prefix in string]?: Map<unknown, ValueScopeName>
|
||||
}
|
||||
|
||||
export type ScopeValueSets = {
|
||||
[Prefix in string]?: Set<ValueScopeName>
|
||||
}
|
||||
|
||||
export enum UsedValueState {
|
||||
Started,
|
||||
Completed,
|
||||
}
|
||||
|
||||
export type UsedScopeValues = {
|
||||
[Prefix in string]?: Map<ValueScopeName, UsedValueState | undefined>
|
||||
}
|
||||
|
||||
export const varKinds = {
|
||||
const: new Name("const"),
|
||||
let: new Name("let"),
|
||||
var: new Name("var"),
|
||||
}
|
||||
|
||||
export class Scope {
|
||||
protected readonly _names: {[Prefix in string]?: NameGroup} = {}
|
||||
protected readonly _prefixes?: Set<string>
|
||||
protected readonly _parent?: Scope
|
||||
|
||||
constructor({prefixes, parent}: ScopeOptions = {}) {
|
||||
this._prefixes = prefixes
|
||||
this._parent = parent
|
||||
}
|
||||
|
||||
toName(nameOrPrefix: Name | string): Name {
|
||||
return nameOrPrefix instanceof Name ? nameOrPrefix : this.name(nameOrPrefix)
|
||||
}
|
||||
|
||||
name(prefix: string): Name {
|
||||
return new Name(this._newName(prefix))
|
||||
}
|
||||
|
||||
protected _newName(prefix: string): string {
|
||||
const ng = this._names[prefix] || this._nameGroup(prefix)
|
||||
return `${prefix}${ng.index++}`
|
||||
}
|
||||
|
||||
private _nameGroup(prefix: string): NameGroup {
|
||||
if (this._parent?._prefixes?.has(prefix) || (this._prefixes && !this._prefixes.has(prefix))) {
|
||||
throw new Error(`CodeGen: prefix "${prefix}" is not allowed in this scope`)
|
||||
}
|
||||
return (this._names[prefix] = {prefix, index: 0})
|
||||
}
|
||||
}
|
||||
|
||||
interface ScopePath {
|
||||
property: string
|
||||
itemIndex: number
|
||||
}
|
||||
|
||||
export class ValueScopeName extends Name {
|
||||
readonly prefix: string
|
||||
value?: NameValue
|
||||
scopePath?: Code
|
||||
|
||||
constructor(prefix: string, nameStr: string) {
|
||||
super(nameStr)
|
||||
this.prefix = prefix
|
||||
}
|
||||
|
||||
setValue(value: NameValue, {property, itemIndex}: ScopePath): void {
|
||||
this.value = value
|
||||
this.scopePath = _`.${new Name(property)}[${itemIndex}]`
|
||||
}
|
||||
}
|
||||
|
||||
interface VSOptions extends ValueScopeOptions {
|
||||
_n: Code
|
||||
}
|
||||
|
||||
const line = _`\n`
|
||||
|
||||
export class ValueScope extends Scope {
|
||||
protected readonly _values: ScopeValues = {}
|
||||
protected readonly _scope: ScopeStore
|
||||
readonly opts: VSOptions
|
||||
|
||||
constructor(opts: ValueScopeOptions) {
|
||||
super(opts)
|
||||
this._scope = opts.scope
|
||||
this.opts = {...opts, _n: opts.lines ? line : nil}
|
||||
}
|
||||
|
||||
get(): ScopeStore {
|
||||
return this._scope
|
||||
}
|
||||
|
||||
name(prefix: string): ValueScopeName {
|
||||
return new ValueScopeName(prefix, this._newName(prefix))
|
||||
}
|
||||
|
||||
value(nameOrPrefix: ValueScopeName | string, value: NameValue): ValueScopeName {
|
||||
if (value.ref === undefined) throw new Error("CodeGen: ref must be passed in value")
|
||||
const name = this.toName(nameOrPrefix) as ValueScopeName
|
||||
const {prefix} = name
|
||||
const valueKey = value.key ?? value.ref
|
||||
let vs = this._values[prefix]
|
||||
if (vs) {
|
||||
const _name = vs.get(valueKey)
|
||||
if (_name) return _name
|
||||
} else {
|
||||
vs = this._values[prefix] = new Map()
|
||||
}
|
||||
vs.set(valueKey, name)
|
||||
|
||||
const s = this._scope[prefix] || (this._scope[prefix] = [])
|
||||
const itemIndex = s.length
|
||||
s[itemIndex] = value.ref
|
||||
name.setValue(value, {property: prefix, itemIndex})
|
||||
return name
|
||||
}
|
||||
|
||||
getValue(prefix: string, keyOrRef: unknown): ValueScopeName | undefined {
|
||||
const vs = this._values[prefix]
|
||||
if (!vs) return
|
||||
return vs.get(keyOrRef)
|
||||
}
|
||||
|
||||
scopeRefs(scopeName: Name, values: ScopeValues | ScopeValueSets = this._values): Code {
|
||||
return this._reduceValues(values, (name: ValueScopeName) => {
|
||||
if (name.scopePath === undefined) throw new Error(`CodeGen: name "${name}" has no value`)
|
||||
return _`${scopeName}${name.scopePath}`
|
||||
})
|
||||
}
|
||||
|
||||
scopeCode(
|
||||
values: ScopeValues | ScopeValueSets = this._values,
|
||||
usedValues?: UsedScopeValues,
|
||||
getCode?: (n: ValueScopeName) => Code | undefined
|
||||
): Code {
|
||||
return this._reduceValues(
|
||||
values,
|
||||
(name: ValueScopeName) => {
|
||||
if (name.value === undefined) throw new Error(`CodeGen: name "${name}" has no value`)
|
||||
return name.value.code
|
||||
},
|
||||
usedValues,
|
||||
getCode
|
||||
)
|
||||
}
|
||||
|
||||
private _reduceValues(
|
||||
values: ScopeValues | ScopeValueSets,
|
||||
valueCode: (n: ValueScopeName) => Code | undefined,
|
||||
usedValues: UsedScopeValues = {},
|
||||
getCode?: (n: ValueScopeName) => Code | undefined
|
||||
): Code {
|
||||
let code: Code = nil
|
||||
for (const prefix in values) {
|
||||
const vs = values[prefix]
|
||||
if (!vs) continue
|
||||
const nameSet = (usedValues[prefix] = usedValues[prefix] || new Map())
|
||||
vs.forEach((name: ValueScopeName) => {
|
||||
if (nameSet.has(name)) return
|
||||
nameSet.set(name, UsedValueState.Started)
|
||||
let c = valueCode(name)
|
||||
if (c) {
|
||||
const def = this.opts.es5 ? varKinds.var : varKinds.const
|
||||
code = _`${code}${def} ${name} = ${c};${this.opts._n}`
|
||||
} else if ((c = getCode?.(name))) {
|
||||
code = _`${code}${c}${this.opts._n}`
|
||||
} else {
|
||||
throw new ValueError(name)
|
||||
}
|
||||
nameSet.set(name, UsedValueState.Completed)
|
||||
})
|
||||
}
|
||||
return code
|
||||
}
|
||||
}
|
184
node_modules/schema-utils/node_modules/ajv/lib/compile/errors.ts
generated
vendored
Normal file
184
node_modules/schema-utils/node_modules/ajv/lib/compile/errors.ts
generated
vendored
Normal file
@@ -0,0 +1,184 @@
|
||||
import type {KeywordErrorCxt, KeywordErrorDefinition} from "../types"
|
||||
import type {SchemaCxt} from "./index"
|
||||
import {CodeGen, _, str, strConcat, Code, Name} from "./codegen"
|
||||
import {SafeExpr} from "./codegen/code"
|
||||
import {getErrorPath, Type} from "./util"
|
||||
import N from "./names"
|
||||
|
||||
export const keywordError: KeywordErrorDefinition = {
|
||||
message: ({keyword}) => str`must pass "${keyword}" keyword validation`,
|
||||
}
|
||||
|
||||
export const keyword$DataError: KeywordErrorDefinition = {
|
||||
message: ({keyword, schemaType}) =>
|
||||
schemaType
|
||||
? str`"${keyword}" keyword must be ${schemaType} ($data)`
|
||||
: str`"${keyword}" keyword is invalid ($data)`,
|
||||
}
|
||||
|
||||
export interface ErrorPaths {
|
||||
instancePath?: Code
|
||||
schemaPath?: string
|
||||
parentSchema?: boolean
|
||||
}
|
||||
|
||||
export function reportError(
|
||||
cxt: KeywordErrorCxt,
|
||||
error: KeywordErrorDefinition = keywordError,
|
||||
errorPaths?: ErrorPaths,
|
||||
overrideAllErrors?: boolean
|
||||
): void {
|
||||
const {it} = cxt
|
||||
const {gen, compositeRule, allErrors} = it
|
||||
const errObj = errorObjectCode(cxt, error, errorPaths)
|
||||
if (overrideAllErrors ?? (compositeRule || allErrors)) {
|
||||
addError(gen, errObj)
|
||||
} else {
|
||||
returnErrors(it, _`[${errObj}]`)
|
||||
}
|
||||
}
|
||||
|
||||
export function reportExtraError(
|
||||
cxt: KeywordErrorCxt,
|
||||
error: KeywordErrorDefinition = keywordError,
|
||||
errorPaths?: ErrorPaths
|
||||
): void {
|
||||
const {it} = cxt
|
||||
const {gen, compositeRule, allErrors} = it
|
||||
const errObj = errorObjectCode(cxt, error, errorPaths)
|
||||
addError(gen, errObj)
|
||||
if (!(compositeRule || allErrors)) {
|
||||
returnErrors(it, N.vErrors)
|
||||
}
|
||||
}
|
||||
|
||||
export function resetErrorsCount(gen: CodeGen, errsCount: Name): void {
|
||||
gen.assign(N.errors, errsCount)
|
||||
gen.if(_`${N.vErrors} !== null`, () =>
|
||||
gen.if(
|
||||
errsCount,
|
||||
() => gen.assign(_`${N.vErrors}.length`, errsCount),
|
||||
() => gen.assign(N.vErrors, null)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
export function extendErrors({
|
||||
gen,
|
||||
keyword,
|
||||
schemaValue,
|
||||
data,
|
||||
errsCount,
|
||||
it,
|
||||
}: KeywordErrorCxt): void {
|
||||
/* istanbul ignore if */
|
||||
if (errsCount === undefined) throw new Error("ajv implementation error")
|
||||
const err = gen.name("err")
|
||||
gen.forRange("i", errsCount, N.errors, (i) => {
|
||||
gen.const(err, _`${N.vErrors}[${i}]`)
|
||||
gen.if(_`${err}.instancePath === undefined`, () =>
|
||||
gen.assign(_`${err}.instancePath`, strConcat(N.instancePath, it.errorPath))
|
||||
)
|
||||
gen.assign(_`${err}.schemaPath`, str`${it.errSchemaPath}/${keyword}`)
|
||||
if (it.opts.verbose) {
|
||||
gen.assign(_`${err}.schema`, schemaValue)
|
||||
gen.assign(_`${err}.data`, data)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function addError(gen: CodeGen, errObj: Code): void {
|
||||
const err = gen.const("err", errObj)
|
||||
gen.if(
|
||||
_`${N.vErrors} === null`,
|
||||
() => gen.assign(N.vErrors, _`[${err}]`),
|
||||
_`${N.vErrors}.push(${err})`
|
||||
)
|
||||
gen.code(_`${N.errors}++`)
|
||||
}
|
||||
|
||||
function returnErrors(it: SchemaCxt, errs: Code): void {
|
||||
const {gen, validateName, schemaEnv} = it
|
||||
if (schemaEnv.$async) {
|
||||
gen.throw(_`new ${it.ValidationError as Name}(${errs})`)
|
||||
} else {
|
||||
gen.assign(_`${validateName}.errors`, errs)
|
||||
gen.return(false)
|
||||
}
|
||||
}
|
||||
|
||||
const E = {
|
||||
keyword: new Name("keyword"),
|
||||
schemaPath: new Name("schemaPath"), // also used in JTD errors
|
||||
params: new Name("params"),
|
||||
propertyName: new Name("propertyName"),
|
||||
message: new Name("message"),
|
||||
schema: new Name("schema"),
|
||||
parentSchema: new Name("parentSchema"),
|
||||
}
|
||||
|
||||
function errorObjectCode(
|
||||
cxt: KeywordErrorCxt,
|
||||
error: KeywordErrorDefinition,
|
||||
errorPaths?: ErrorPaths
|
||||
): Code {
|
||||
const {createErrors} = cxt.it
|
||||
if (createErrors === false) return _`{}`
|
||||
return errorObject(cxt, error, errorPaths)
|
||||
}
|
||||
|
||||
function errorObject(
|
||||
cxt: KeywordErrorCxt,
|
||||
error: KeywordErrorDefinition,
|
||||
errorPaths: ErrorPaths = {}
|
||||
): Code {
|
||||
const {gen, it} = cxt
|
||||
const keyValues: [Name, SafeExpr | string][] = [
|
||||
errorInstancePath(it, errorPaths),
|
||||
errorSchemaPath(cxt, errorPaths),
|
||||
]
|
||||
extraErrorProps(cxt, error, keyValues)
|
||||
return gen.object(...keyValues)
|
||||
}
|
||||
|
||||
function errorInstancePath({errorPath}: SchemaCxt, {instancePath}: ErrorPaths): [Name, Code] {
|
||||
const instPath = instancePath
|
||||
? str`${errorPath}${getErrorPath(instancePath, Type.Str)}`
|
||||
: errorPath
|
||||
return [N.instancePath, strConcat(N.instancePath, instPath)]
|
||||
}
|
||||
|
||||
function errorSchemaPath(
|
||||
{keyword, it: {errSchemaPath}}: KeywordErrorCxt,
|
||||
{schemaPath, parentSchema}: ErrorPaths
|
||||
): [Name, string | Code] {
|
||||
let schPath = parentSchema ? errSchemaPath : str`${errSchemaPath}/${keyword}`
|
||||
if (schemaPath) {
|
||||
schPath = str`${schPath}${getErrorPath(schemaPath, Type.Str)}`
|
||||
}
|
||||
return [E.schemaPath, schPath]
|
||||
}
|
||||
|
||||
function extraErrorProps(
|
||||
cxt: KeywordErrorCxt,
|
||||
{params, message}: KeywordErrorDefinition,
|
||||
keyValues: [Name, SafeExpr | string][]
|
||||
): void {
|
||||
const {keyword, data, schemaValue, it} = cxt
|
||||
const {opts, propertyName, topSchemaRef, schemaPath} = it
|
||||
keyValues.push(
|
||||
[E.keyword, keyword],
|
||||
[E.params, typeof params == "function" ? params(cxt) : params || _`{}`]
|
||||
)
|
||||
if (opts.messages) {
|
||||
keyValues.push([E.message, typeof message == "function" ? message(cxt) : message])
|
||||
}
|
||||
if (opts.verbose) {
|
||||
keyValues.push(
|
||||
[E.schema, schemaValue],
|
||||
[E.parentSchema, _`${topSchemaRef}${schemaPath}`],
|
||||
[N.data, data]
|
||||
)
|
||||
}
|
||||
if (propertyName) keyValues.push([E.propertyName, propertyName])
|
||||
}
|
324
node_modules/schema-utils/node_modules/ajv/lib/compile/index.ts
generated
vendored
Normal file
324
node_modules/schema-utils/node_modules/ajv/lib/compile/index.ts
generated
vendored
Normal file
@@ -0,0 +1,324 @@
|
||||
import type {
|
||||
AnySchema,
|
||||
AnySchemaObject,
|
||||
AnyValidateFunction,
|
||||
AsyncValidateFunction,
|
||||
EvaluatedProperties,
|
||||
EvaluatedItems,
|
||||
} from "../types"
|
||||
import type Ajv from "../core"
|
||||
import type {InstanceOptions} from "../core"
|
||||
import {CodeGen, _, nil, stringify, Name, Code, ValueScopeName} from "./codegen"
|
||||
import ValidationError from "../runtime/validation_error"
|
||||
import N from "./names"
|
||||
import {LocalRefs, getFullPath, _getFullPath, inlineRef, normalizeId, resolveUrl} from "./resolve"
|
||||
import {schemaHasRulesButRef, unescapeFragment} from "./util"
|
||||
import {validateFunctionCode} from "./validate"
|
||||
import {URIComponent} from "fast-uri"
|
||||
import {JSONType} from "./rules"
|
||||
|
||||
export type SchemaRefs = {
|
||||
[Ref in string]?: SchemaEnv | AnySchema
|
||||
}
|
||||
|
||||
export interface SchemaCxt {
|
||||
readonly gen: CodeGen
|
||||
readonly allErrors?: boolean // validation mode - whether to collect all errors or break on error
|
||||
readonly data: Name // Name with reference to the current part of data instance
|
||||
readonly parentData: Name // should be used in keywords modifying data
|
||||
readonly parentDataProperty: Code | number // should be used in keywords modifying data
|
||||
readonly dataNames: Name[]
|
||||
readonly dataPathArr: (Code | number)[]
|
||||
readonly dataLevel: number // the level of the currently validated data,
|
||||
// it can be used to access both the property names and the data on all levels from the top.
|
||||
dataTypes: JSONType[] // data types applied to the current part of data instance
|
||||
definedProperties: Set<string> // set of properties to keep track of for required checks
|
||||
readonly topSchemaRef: Code
|
||||
readonly validateName: Name
|
||||
evaluated?: Name
|
||||
readonly ValidationError?: Name
|
||||
readonly schema: AnySchema // current schema object - equal to parentSchema passed via KeywordCxt
|
||||
readonly schemaEnv: SchemaEnv
|
||||
readonly rootId: string
|
||||
baseId: string // the current schema base URI that should be used as the base for resolving URIs in references (\$ref)
|
||||
readonly schemaPath: Code // the run-time expression that evaluates to the property name of the current schema
|
||||
readonly errSchemaPath: string // this is actual string, should not be changed to Code
|
||||
readonly errorPath: Code
|
||||
readonly propertyName?: Name
|
||||
readonly compositeRule?: boolean // true indicates that the current schema is inside the compound keyword,
|
||||
// where failing some rule doesn't mean validation failure (`anyOf`, `oneOf`, `not`, `if`).
|
||||
// This flag is used to determine whether you can return validation result immediately after any error in case the option `allErrors` is not `true.
|
||||
// You only need to use it if you have many steps in your keywords and potentially can define multiple errors.
|
||||
props?: EvaluatedProperties | Name // properties evaluated by this schema - used by parent schema or assigned to validation function
|
||||
items?: EvaluatedItems | Name // last item evaluated by this schema - used by parent schema or assigned to validation function
|
||||
jtdDiscriminator?: string
|
||||
jtdMetadata?: boolean
|
||||
readonly createErrors?: boolean
|
||||
readonly opts: InstanceOptions // Ajv instance option.
|
||||
readonly self: Ajv // current Ajv instance
|
||||
}
|
||||
|
||||
export interface SchemaObjCxt extends SchemaCxt {
|
||||
readonly schema: AnySchemaObject
|
||||
}
|
||||
interface SchemaEnvArgs {
|
||||
readonly schema: AnySchema
|
||||
readonly schemaId?: "$id" | "id"
|
||||
readonly root?: SchemaEnv
|
||||
readonly baseId?: string
|
||||
readonly schemaPath?: string
|
||||
readonly localRefs?: LocalRefs
|
||||
readonly meta?: boolean
|
||||
}
|
||||
|
||||
export class SchemaEnv implements SchemaEnvArgs {
|
||||
readonly schema: AnySchema
|
||||
readonly schemaId?: "$id" | "id"
|
||||
readonly root: SchemaEnv
|
||||
baseId: string // TODO possibly, it should be readonly
|
||||
schemaPath?: string
|
||||
localRefs?: LocalRefs
|
||||
readonly meta?: boolean
|
||||
readonly $async?: boolean // true if the current schema is asynchronous.
|
||||
readonly refs: SchemaRefs = {}
|
||||
readonly dynamicAnchors: {[Ref in string]?: true} = {}
|
||||
validate?: AnyValidateFunction
|
||||
validateName?: ValueScopeName
|
||||
serialize?: (data: unknown) => string
|
||||
serializeName?: ValueScopeName
|
||||
parse?: (data: string) => unknown
|
||||
parseName?: ValueScopeName
|
||||
|
||||
constructor(env: SchemaEnvArgs) {
|
||||
let schema: AnySchemaObject | undefined
|
||||
if (typeof env.schema == "object") schema = env.schema
|
||||
this.schema = env.schema
|
||||
this.schemaId = env.schemaId
|
||||
this.root = env.root || this
|
||||
this.baseId = env.baseId ?? normalizeId(schema?.[env.schemaId || "$id"])
|
||||
this.schemaPath = env.schemaPath
|
||||
this.localRefs = env.localRefs
|
||||
this.meta = env.meta
|
||||
this.$async = schema?.$async
|
||||
this.refs = {}
|
||||
}
|
||||
}
|
||||
|
||||
// let codeSize = 0
|
||||
// let nodeCount = 0
|
||||
|
||||
// Compiles schema in SchemaEnv
|
||||
export function compileSchema(this: Ajv, sch: SchemaEnv): SchemaEnv {
|
||||
// TODO refactor - remove compilations
|
||||
const _sch = getCompilingSchema.call(this, sch)
|
||||
if (_sch) return _sch
|
||||
const rootId = getFullPath(this.opts.uriResolver, sch.root.baseId) // TODO if getFullPath removed 1 tests fails
|
||||
const {es5, lines} = this.opts.code
|
||||
const {ownProperties} = this.opts
|
||||
const gen = new CodeGen(this.scope, {es5, lines, ownProperties})
|
||||
let _ValidationError
|
||||
if (sch.$async) {
|
||||
_ValidationError = gen.scopeValue("Error", {
|
||||
ref: ValidationError,
|
||||
code: _`require("ajv/dist/runtime/validation_error").default`,
|
||||
})
|
||||
}
|
||||
|
||||
const validateName = gen.scopeName("validate")
|
||||
sch.validateName = validateName
|
||||
|
||||
const schemaCxt: SchemaCxt = {
|
||||
gen,
|
||||
allErrors: this.opts.allErrors,
|
||||
data: N.data,
|
||||
parentData: N.parentData,
|
||||
parentDataProperty: N.parentDataProperty,
|
||||
dataNames: [N.data],
|
||||
dataPathArr: [nil], // TODO can its length be used as dataLevel if nil is removed?
|
||||
dataLevel: 0,
|
||||
dataTypes: [],
|
||||
definedProperties: new Set<string>(),
|
||||
topSchemaRef: gen.scopeValue(
|
||||
"schema",
|
||||
this.opts.code.source === true
|
||||
? {ref: sch.schema, code: stringify(sch.schema)}
|
||||
: {ref: sch.schema}
|
||||
),
|
||||
validateName,
|
||||
ValidationError: _ValidationError,
|
||||
schema: sch.schema,
|
||||
schemaEnv: sch,
|
||||
rootId,
|
||||
baseId: sch.baseId || rootId,
|
||||
schemaPath: nil,
|
||||
errSchemaPath: sch.schemaPath || (this.opts.jtd ? "" : "#"),
|
||||
errorPath: _`""`,
|
||||
opts: this.opts,
|
||||
self: this,
|
||||
}
|
||||
|
||||
let sourceCode: string | undefined
|
||||
try {
|
||||
this._compilations.add(sch)
|
||||
validateFunctionCode(schemaCxt)
|
||||
gen.optimize(this.opts.code.optimize)
|
||||
// gen.optimize(1)
|
||||
const validateCode = gen.toString()
|
||||
sourceCode = `${gen.scopeRefs(N.scope)}return ${validateCode}`
|
||||
// console.log((codeSize += sourceCode.length), (nodeCount += gen.nodeCount))
|
||||
if (this.opts.code.process) sourceCode = this.opts.code.process(sourceCode, sch)
|
||||
// console.log("\n\n\n *** \n", sourceCode)
|
||||
const makeValidate = new Function(`${N.self}`, `${N.scope}`, sourceCode)
|
||||
const validate: AnyValidateFunction = makeValidate(this, this.scope.get())
|
||||
this.scope.value(validateName, {ref: validate})
|
||||
|
||||
validate.errors = null
|
||||
validate.schema = sch.schema
|
||||
validate.schemaEnv = sch
|
||||
if (sch.$async) (validate as AsyncValidateFunction).$async = true
|
||||
if (this.opts.code.source === true) {
|
||||
validate.source = {validateName, validateCode, scopeValues: gen._values}
|
||||
}
|
||||
if (this.opts.unevaluated) {
|
||||
const {props, items} = schemaCxt
|
||||
validate.evaluated = {
|
||||
props: props instanceof Name ? undefined : props,
|
||||
items: items instanceof Name ? undefined : items,
|
||||
dynamicProps: props instanceof Name,
|
||||
dynamicItems: items instanceof Name,
|
||||
}
|
||||
if (validate.source) validate.source.evaluated = stringify(validate.evaluated)
|
||||
}
|
||||
sch.validate = validate
|
||||
return sch
|
||||
} catch (e) {
|
||||
delete sch.validate
|
||||
delete sch.validateName
|
||||
if (sourceCode) this.logger.error("Error compiling schema, function code:", sourceCode)
|
||||
// console.log("\n\n\n *** \n", sourceCode, this.opts)
|
||||
throw e
|
||||
} finally {
|
||||
this._compilations.delete(sch)
|
||||
}
|
||||
}
|
||||
|
||||
export function resolveRef(
|
||||
this: Ajv,
|
||||
root: SchemaEnv,
|
||||
baseId: string,
|
||||
ref: string
|
||||
): AnySchema | SchemaEnv | undefined {
|
||||
ref = resolveUrl(this.opts.uriResolver, baseId, ref)
|
||||
const schOrFunc = root.refs[ref]
|
||||
if (schOrFunc) return schOrFunc
|
||||
|
||||
let _sch = resolve.call(this, root, ref)
|
||||
if (_sch === undefined) {
|
||||
const schema = root.localRefs?.[ref] // TODO maybe localRefs should hold SchemaEnv
|
||||
const {schemaId} = this.opts
|
||||
if (schema) _sch = new SchemaEnv({schema, schemaId, root, baseId})
|
||||
}
|
||||
|
||||
if (_sch === undefined) return
|
||||
return (root.refs[ref] = inlineOrCompile.call(this, _sch))
|
||||
}
|
||||
|
||||
function inlineOrCompile(this: Ajv, sch: SchemaEnv): AnySchema | SchemaEnv {
|
||||
if (inlineRef(sch.schema, this.opts.inlineRefs)) return sch.schema
|
||||
return sch.validate ? sch : compileSchema.call(this, sch)
|
||||
}
|
||||
|
||||
// Index of schema compilation in the currently compiled list
|
||||
export function getCompilingSchema(this: Ajv, schEnv: SchemaEnv): SchemaEnv | void {
|
||||
for (const sch of this._compilations) {
|
||||
if (sameSchemaEnv(sch, schEnv)) return sch
|
||||
}
|
||||
}
|
||||
|
||||
function sameSchemaEnv(s1: SchemaEnv, s2: SchemaEnv): boolean {
|
||||
return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId
|
||||
}
|
||||
|
||||
// resolve and compile the references ($ref)
|
||||
// TODO returns AnySchemaObject (if the schema can be inlined) or validation function
|
||||
function resolve(
|
||||
this: Ajv,
|
||||
root: SchemaEnv, // information about the root schema for the current schema
|
||||
ref: string // reference to resolve
|
||||
): SchemaEnv | undefined {
|
||||
let sch
|
||||
while (typeof (sch = this.refs[ref]) == "string") ref = sch
|
||||
return sch || this.schemas[ref] || resolveSchema.call(this, root, ref)
|
||||
}
|
||||
|
||||
// Resolve schema, its root and baseId
|
||||
export function resolveSchema(
|
||||
this: Ajv,
|
||||
root: SchemaEnv, // root object with properties schema, refs TODO below SchemaEnv is assigned to it
|
||||
ref: string // reference to resolve
|
||||
): SchemaEnv | undefined {
|
||||
const p = this.opts.uriResolver.parse(ref)
|
||||
const refPath = _getFullPath(this.opts.uriResolver, p)
|
||||
let baseId = getFullPath(this.opts.uriResolver, root.baseId, undefined)
|
||||
// TODO `Object.keys(root.schema).length > 0` should not be needed - but removing breaks 2 tests
|
||||
if (Object.keys(root.schema).length > 0 && refPath === baseId) {
|
||||
return getJsonPointer.call(this, p, root)
|
||||
}
|
||||
|
||||
const id = normalizeId(refPath)
|
||||
const schOrRef = this.refs[id] || this.schemas[id]
|
||||
if (typeof schOrRef == "string") {
|
||||
const sch = resolveSchema.call(this, root, schOrRef)
|
||||
if (typeof sch?.schema !== "object") return
|
||||
return getJsonPointer.call(this, p, sch)
|
||||
}
|
||||
|
||||
if (typeof schOrRef?.schema !== "object") return
|
||||
if (!schOrRef.validate) compileSchema.call(this, schOrRef)
|
||||
if (id === normalizeId(ref)) {
|
||||
const {schema} = schOrRef
|
||||
const {schemaId} = this.opts
|
||||
const schId = schema[schemaId]
|
||||
if (schId) baseId = resolveUrl(this.opts.uriResolver, baseId, schId)
|
||||
return new SchemaEnv({schema, schemaId, root, baseId})
|
||||
}
|
||||
return getJsonPointer.call(this, p, schOrRef)
|
||||
}
|
||||
|
||||
const PREVENT_SCOPE_CHANGE = new Set([
|
||||
"properties",
|
||||
"patternProperties",
|
||||
"enum",
|
||||
"dependencies",
|
||||
"definitions",
|
||||
])
|
||||
|
||||
function getJsonPointer(
|
||||
this: Ajv,
|
||||
parsedRef: URIComponent,
|
||||
{baseId, schema, root}: SchemaEnv
|
||||
): SchemaEnv | undefined {
|
||||
if (parsedRef.fragment?.[0] !== "/") return
|
||||
for (const part of parsedRef.fragment.slice(1).split("/")) {
|
||||
if (typeof schema === "boolean") return
|
||||
const partSchema = schema[unescapeFragment(part)]
|
||||
if (partSchema === undefined) return
|
||||
schema = partSchema
|
||||
// TODO PREVENT_SCOPE_CHANGE could be defined in keyword def?
|
||||
const schId = typeof schema === "object" && schema[this.opts.schemaId]
|
||||
if (!PREVENT_SCOPE_CHANGE.has(part) && schId) {
|
||||
baseId = resolveUrl(this.opts.uriResolver, baseId, schId)
|
||||
}
|
||||
}
|
||||
let env: SchemaEnv | undefined
|
||||
if (typeof schema != "boolean" && schema.$ref && !schemaHasRulesButRef(schema, this.RULES)) {
|
||||
const $ref = resolveUrl(this.opts.uriResolver, baseId, schema.$ref)
|
||||
env = resolveSchema.call(this, root, $ref)
|
||||
}
|
||||
// even though resolution failed we need to return SchemaEnv to throw exception
|
||||
// so that compileAsync loads missing schema.
|
||||
const {schemaId} = this.opts
|
||||
env = env || new SchemaEnv({schema, schemaId, root, baseId})
|
||||
if (env.schema !== env.root.schema) return env
|
||||
return undefined
|
||||
}
|
411
node_modules/schema-utils/node_modules/ajv/lib/compile/jtd/parse.ts
generated
vendored
Normal file
411
node_modules/schema-utils/node_modules/ajv/lib/compile/jtd/parse.ts
generated
vendored
Normal file
@@ -0,0 +1,411 @@
|
||||
import type Ajv from "../../core"
|
||||
import type {SchemaObject} from "../../types"
|
||||
import {jtdForms, JTDForm, SchemaObjectMap} from "./types"
|
||||
import {SchemaEnv, getCompilingSchema} from ".."
|
||||
import {_, str, and, or, nil, not, CodeGen, Code, Name, SafeExpr} from "../codegen"
|
||||
import MissingRefError from "../ref_error"
|
||||
import N from "../names"
|
||||
import {hasPropFunc} from "../../vocabularies/code"
|
||||
import {hasRef} from "../../vocabularies/jtd/ref"
|
||||
import {intRange, IntType} from "../../vocabularies/jtd/type"
|
||||
import {parseJson, parseJsonNumber, parseJsonString} from "../../runtime/parseJson"
|
||||
import {useFunc} from "../util"
|
||||
import validTimestamp from "../../runtime/timestamp"
|
||||
|
||||
type GenParse = (cxt: ParseCxt) => void
|
||||
|
||||
const genParse: {[F in JTDForm]: GenParse} = {
|
||||
elements: parseElements,
|
||||
values: parseValues,
|
||||
discriminator: parseDiscriminator,
|
||||
properties: parseProperties,
|
||||
optionalProperties: parseProperties,
|
||||
enum: parseEnum,
|
||||
type: parseType,
|
||||
ref: parseRef,
|
||||
}
|
||||
|
||||
interface ParseCxt {
|
||||
readonly gen: CodeGen
|
||||
readonly self: Ajv // current Ajv instance
|
||||
readonly schemaEnv: SchemaEnv
|
||||
readonly definitions: SchemaObjectMap
|
||||
schema: SchemaObject
|
||||
data: Code
|
||||
parseName: Name
|
||||
char: Name
|
||||
}
|
||||
|
||||
export default function compileParser(
|
||||
this: Ajv,
|
||||
sch: SchemaEnv,
|
||||
definitions: SchemaObjectMap
|
||||
): SchemaEnv {
|
||||
const _sch = getCompilingSchema.call(this, sch)
|
||||
if (_sch) return _sch
|
||||
const {es5, lines} = this.opts.code
|
||||
const {ownProperties} = this.opts
|
||||
const gen = new CodeGen(this.scope, {es5, lines, ownProperties})
|
||||
const parseName = gen.scopeName("parse")
|
||||
const cxt: ParseCxt = {
|
||||
self: this,
|
||||
gen,
|
||||
schema: sch.schema as SchemaObject,
|
||||
schemaEnv: sch,
|
||||
definitions,
|
||||
data: N.data,
|
||||
parseName,
|
||||
char: gen.name("c"),
|
||||
}
|
||||
|
||||
let sourceCode: string | undefined
|
||||
try {
|
||||
this._compilations.add(sch)
|
||||
sch.parseName = parseName
|
||||
parserFunction(cxt)
|
||||
gen.optimize(this.opts.code.optimize)
|
||||
const parseFuncCode = gen.toString()
|
||||
sourceCode = `${gen.scopeRefs(N.scope)}return ${parseFuncCode}`
|
||||
const makeParse = new Function(`${N.scope}`, sourceCode)
|
||||
const parse: (json: string) => unknown = makeParse(this.scope.get())
|
||||
this.scope.value(parseName, {ref: parse})
|
||||
sch.parse = parse
|
||||
} catch (e) {
|
||||
if (sourceCode) this.logger.error("Error compiling parser, function code:", sourceCode)
|
||||
delete sch.parse
|
||||
delete sch.parseName
|
||||
throw e
|
||||
} finally {
|
||||
this._compilations.delete(sch)
|
||||
}
|
||||
return sch
|
||||
}
|
||||
|
||||
const undef = _`undefined`
|
||||
|
||||
function parserFunction(cxt: ParseCxt): void {
|
||||
const {gen, parseName, char} = cxt
|
||||
gen.func(parseName, _`${N.json}, ${N.jsonPos}, ${N.jsonPart}`, false, () => {
|
||||
gen.let(N.data)
|
||||
gen.let(char)
|
||||
gen.assign(_`${parseName}.message`, undef)
|
||||
gen.assign(_`${parseName}.position`, undef)
|
||||
gen.assign(N.jsonPos, _`${N.jsonPos} || 0`)
|
||||
gen.const(N.jsonLen, _`${N.json}.length`)
|
||||
parseCode(cxt)
|
||||
skipWhitespace(cxt)
|
||||
gen.if(N.jsonPart, () => {
|
||||
gen.assign(_`${parseName}.position`, N.jsonPos)
|
||||
gen.return(N.data)
|
||||
})
|
||||
gen.if(_`${N.jsonPos} === ${N.jsonLen}`, () => gen.return(N.data))
|
||||
jsonSyntaxError(cxt)
|
||||
})
|
||||
}
|
||||
|
||||
function parseCode(cxt: ParseCxt): void {
|
||||
let form: JTDForm | undefined
|
||||
for (const key of jtdForms) {
|
||||
if (key in cxt.schema) {
|
||||
form = key
|
||||
break
|
||||
}
|
||||
}
|
||||
if (form) parseNullable(cxt, genParse[form])
|
||||
else parseEmpty(cxt)
|
||||
}
|
||||
|
||||
const parseBoolean = parseBooleanToken(true, parseBooleanToken(false, jsonSyntaxError))
|
||||
|
||||
function parseNullable(cxt: ParseCxt, parseForm: GenParse): void {
|
||||
const {gen, schema, data} = cxt
|
||||
if (!schema.nullable) return parseForm(cxt)
|
||||
tryParseToken(cxt, "null", parseForm, () => gen.assign(data, null))
|
||||
}
|
||||
|
||||
function parseElements(cxt: ParseCxt): void {
|
||||
const {gen, schema, data} = cxt
|
||||
parseToken(cxt, "[")
|
||||
const ix = gen.let("i", 0)
|
||||
gen.assign(data, _`[]`)
|
||||
parseItems(cxt, "]", () => {
|
||||
const el = gen.let("el")
|
||||
parseCode({...cxt, schema: schema.elements, data: el})
|
||||
gen.assign(_`${data}[${ix}++]`, el)
|
||||
})
|
||||
}
|
||||
|
||||
function parseValues(cxt: ParseCxt): void {
|
||||
const {gen, schema, data} = cxt
|
||||
parseToken(cxt, "{")
|
||||
gen.assign(data, _`{}`)
|
||||
parseItems(cxt, "}", () => parseKeyValue(cxt, schema.values))
|
||||
}
|
||||
|
||||
function parseItems(cxt: ParseCxt, endToken: string, block: () => void): void {
|
||||
tryParseItems(cxt, endToken, block)
|
||||
parseToken(cxt, endToken)
|
||||
}
|
||||
|
||||
function tryParseItems(cxt: ParseCxt, endToken: string, block: () => void): void {
|
||||
const {gen} = cxt
|
||||
gen.for(_`;${N.jsonPos}<${N.jsonLen} && ${jsonSlice(1)}!==${endToken};`, () => {
|
||||
block()
|
||||
tryParseToken(cxt, ",", () => gen.break(), hasItem)
|
||||
})
|
||||
|
||||
function hasItem(): void {
|
||||
tryParseToken(cxt, endToken, () => {}, jsonSyntaxError)
|
||||
}
|
||||
}
|
||||
|
||||
function parseKeyValue(cxt: ParseCxt, schema: SchemaObject): void {
|
||||
const {gen} = cxt
|
||||
const key = gen.let("key")
|
||||
parseString({...cxt, data: key})
|
||||
parseToken(cxt, ":")
|
||||
parsePropertyValue(cxt, key, schema)
|
||||
}
|
||||
|
||||
function parseDiscriminator(cxt: ParseCxt): void {
|
||||
const {gen, data, schema} = cxt
|
||||
const {discriminator, mapping} = schema
|
||||
parseToken(cxt, "{")
|
||||
gen.assign(data, _`{}`)
|
||||
const startPos = gen.const("pos", N.jsonPos)
|
||||
const value = gen.let("value")
|
||||
const tag = gen.let("tag")
|
||||
tryParseItems(cxt, "}", () => {
|
||||
const key = gen.let("key")
|
||||
parseString({...cxt, data: key})
|
||||
parseToken(cxt, ":")
|
||||
gen.if(
|
||||
_`${key} === ${discriminator}`,
|
||||
() => {
|
||||
parseString({...cxt, data: tag})
|
||||
gen.assign(_`${data}[${key}]`, tag)
|
||||
gen.break()
|
||||
},
|
||||
() => parseEmpty({...cxt, data: value}) // can be discarded/skipped
|
||||
)
|
||||
})
|
||||
gen.assign(N.jsonPos, startPos)
|
||||
gen.if(_`${tag} === undefined`)
|
||||
parsingError(cxt, str`discriminator tag not found`)
|
||||
for (const tagValue in mapping) {
|
||||
gen.elseIf(_`${tag} === ${tagValue}`)
|
||||
parseSchemaProperties({...cxt, schema: mapping[tagValue]}, discriminator)
|
||||
}
|
||||
gen.else()
|
||||
parsingError(cxt, str`discriminator value not in schema`)
|
||||
gen.endIf()
|
||||
}
|
||||
|
||||
function parseProperties(cxt: ParseCxt): void {
|
||||
const {gen, data} = cxt
|
||||
parseToken(cxt, "{")
|
||||
gen.assign(data, _`{}`)
|
||||
parseSchemaProperties(cxt)
|
||||
}
|
||||
|
||||
function parseSchemaProperties(cxt: ParseCxt, discriminator?: string): void {
|
||||
const {gen, schema, data} = cxt
|
||||
const {properties, optionalProperties, additionalProperties} = schema
|
||||
parseItems(cxt, "}", () => {
|
||||
const key = gen.let("key")
|
||||
parseString({...cxt, data: key})
|
||||
parseToken(cxt, ":")
|
||||
gen.if(false)
|
||||
parseDefinedProperty(cxt, key, properties)
|
||||
parseDefinedProperty(cxt, key, optionalProperties)
|
||||
if (discriminator) {
|
||||
gen.elseIf(_`${key} === ${discriminator}`)
|
||||
const tag = gen.let("tag")
|
||||
parseString({...cxt, data: tag}) // can be discarded, it is already assigned
|
||||
}
|
||||
gen.else()
|
||||
if (additionalProperties) {
|
||||
parseEmpty({...cxt, data: _`${data}[${key}]`})
|
||||
} else {
|
||||
parsingError(cxt, str`property ${key} not allowed`)
|
||||
}
|
||||
gen.endIf()
|
||||
})
|
||||
if (properties) {
|
||||
const hasProp = hasPropFunc(gen)
|
||||
const allProps: Code = and(
|
||||
...Object.keys(properties).map((p): Code => _`${hasProp}.call(${data}, ${p})`)
|
||||
)
|
||||
gen.if(not(allProps), () => parsingError(cxt, str`missing required properties`))
|
||||
}
|
||||
}
|
||||
|
||||
function parseDefinedProperty(cxt: ParseCxt, key: Name, schemas: SchemaObjectMap = {}): void {
|
||||
const {gen} = cxt
|
||||
for (const prop in schemas) {
|
||||
gen.elseIf(_`${key} === ${prop}`)
|
||||
parsePropertyValue(cxt, key, schemas[prop] as SchemaObject)
|
||||
}
|
||||
}
|
||||
|
||||
function parsePropertyValue(cxt: ParseCxt, key: Name, schema: SchemaObject): void {
|
||||
parseCode({...cxt, schema, data: _`${cxt.data}[${key}]`})
|
||||
}
|
||||
|
||||
function parseType(cxt: ParseCxt): void {
|
||||
const {gen, schema, data, self} = cxt
|
||||
switch (schema.type) {
|
||||
case "boolean":
|
||||
parseBoolean(cxt)
|
||||
break
|
||||
case "string":
|
||||
parseString(cxt)
|
||||
break
|
||||
case "timestamp": {
|
||||
parseString(cxt)
|
||||
const vts = useFunc(gen, validTimestamp)
|
||||
const {allowDate, parseDate} = self.opts
|
||||
const notValid = allowDate ? _`!${vts}(${data}, true)` : _`!${vts}(${data})`
|
||||
const fail: Code = parseDate
|
||||
? or(notValid, _`(${data} = new Date(${data}), false)`, _`isNaN(${data}.valueOf())`)
|
||||
: notValid
|
||||
gen.if(fail, () => parsingError(cxt, str`invalid timestamp`))
|
||||
break
|
||||
}
|
||||
case "float32":
|
||||
case "float64":
|
||||
parseNumber(cxt)
|
||||
break
|
||||
default: {
|
||||
const t = schema.type as IntType
|
||||
if (!self.opts.int32range && (t === "int32" || t === "uint32")) {
|
||||
parseNumber(cxt, 16) // 2 ** 53 - max safe integer
|
||||
if (t === "uint32") {
|
||||
gen.if(_`${data} < 0`, () => parsingError(cxt, str`integer out of range`))
|
||||
}
|
||||
} else {
|
||||
const [min, max, maxDigits] = intRange[t]
|
||||
parseNumber(cxt, maxDigits)
|
||||
gen.if(_`${data} < ${min} || ${data} > ${max}`, () =>
|
||||
parsingError(cxt, str`integer out of range`)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function parseString(cxt: ParseCxt): void {
|
||||
parseToken(cxt, '"')
|
||||
parseWith(cxt, parseJsonString)
|
||||
}
|
||||
|
||||
function parseEnum(cxt: ParseCxt): void {
|
||||
const {gen, data, schema} = cxt
|
||||
const enumSch = schema.enum
|
||||
parseToken(cxt, '"')
|
||||
// TODO loopEnum
|
||||
gen.if(false)
|
||||
for (const value of enumSch) {
|
||||
const valueStr = JSON.stringify(value).slice(1) // remove starting quote
|
||||
gen.elseIf(_`${jsonSlice(valueStr.length)} === ${valueStr}`)
|
||||
gen.assign(data, str`${value}`)
|
||||
gen.add(N.jsonPos, valueStr.length)
|
||||
}
|
||||
gen.else()
|
||||
jsonSyntaxError(cxt)
|
||||
gen.endIf()
|
||||
}
|
||||
|
||||
function parseNumber(cxt: ParseCxt, maxDigits?: number): void {
|
||||
const {gen} = cxt
|
||||
skipWhitespace(cxt)
|
||||
gen.if(
|
||||
_`"-0123456789".indexOf(${jsonSlice(1)}) < 0`,
|
||||
() => jsonSyntaxError(cxt),
|
||||
() => parseWith(cxt, parseJsonNumber, maxDigits)
|
||||
)
|
||||
}
|
||||
|
||||
function parseBooleanToken(bool: boolean, fail: GenParse): GenParse {
|
||||
return (cxt) => {
|
||||
const {gen, data} = cxt
|
||||
tryParseToken(
|
||||
cxt,
|
||||
`${bool}`,
|
||||
() => fail(cxt),
|
||||
() => gen.assign(data, bool)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
function parseRef(cxt: ParseCxt): void {
|
||||
const {gen, self, definitions, schema, schemaEnv} = cxt
|
||||
const {ref} = schema
|
||||
const refSchema = definitions[ref]
|
||||
if (!refSchema) throw new MissingRefError(self.opts.uriResolver, "", ref, `No definition ${ref}`)
|
||||
if (!hasRef(refSchema)) return parseCode({...cxt, schema: refSchema})
|
||||
const {root} = schemaEnv
|
||||
const sch = compileParser.call(self, new SchemaEnv({schema: refSchema, root}), definitions)
|
||||
partialParse(cxt, getParser(gen, sch), true)
|
||||
}
|
||||
|
||||
function getParser(gen: CodeGen, sch: SchemaEnv): Code {
|
||||
return sch.parse
|
||||
? gen.scopeValue("parse", {ref: sch.parse})
|
||||
: _`${gen.scopeValue("wrapper", {ref: sch})}.parse`
|
||||
}
|
||||
|
||||
function parseEmpty(cxt: ParseCxt): void {
|
||||
parseWith(cxt, parseJson)
|
||||
}
|
||||
|
||||
function parseWith(cxt: ParseCxt, parseFunc: {code: string}, args?: SafeExpr): void {
|
||||
partialParse(cxt, useFunc(cxt.gen, parseFunc), args)
|
||||
}
|
||||
|
||||
function partialParse(cxt: ParseCxt, parseFunc: Name, args?: SafeExpr): void {
|
||||
const {gen, data} = cxt
|
||||
gen.assign(data, _`${parseFunc}(${N.json}, ${N.jsonPos}${args ? _`, ${args}` : nil})`)
|
||||
gen.assign(N.jsonPos, _`${parseFunc}.position`)
|
||||
gen.if(_`${data} === undefined`, () => parsingError(cxt, _`${parseFunc}.message`))
|
||||
}
|
||||
|
||||
function parseToken(cxt: ParseCxt, tok: string): void {
|
||||
tryParseToken(cxt, tok, jsonSyntaxError)
|
||||
}
|
||||
|
||||
function tryParseToken(cxt: ParseCxt, tok: string, fail: GenParse, success?: GenParse): void {
|
||||
const {gen} = cxt
|
||||
const n = tok.length
|
||||
skipWhitespace(cxt)
|
||||
gen.if(
|
||||
_`${jsonSlice(n)} === ${tok}`,
|
||||
() => {
|
||||
gen.add(N.jsonPos, n)
|
||||
success?.(cxt)
|
||||
},
|
||||
() => fail(cxt)
|
||||
)
|
||||
}
|
||||
|
||||
function skipWhitespace({gen, char: c}: ParseCxt): void {
|
||||
gen.code(
|
||||
_`while((${c}=${N.json}[${N.jsonPos}],${c}===" "||${c}==="\\n"||${c}==="\\r"||${c}==="\\t"))${N.jsonPos}++;`
|
||||
)
|
||||
}
|
||||
|
||||
function jsonSlice(len: number | Name): Code {
|
||||
return len === 1
|
||||
? _`${N.json}[${N.jsonPos}]`
|
||||
: _`${N.json}.slice(${N.jsonPos}, ${N.jsonPos}+${len})`
|
||||
}
|
||||
|
||||
function jsonSyntaxError(cxt: ParseCxt): void {
|
||||
parsingError(cxt, _`"unexpected token " + ${N.json}[${N.jsonPos}]`)
|
||||
}
|
||||
|
||||
function parsingError({gen, parseName}: ParseCxt, msg: Code): void {
|
||||
gen.assign(_`${parseName}.message`, msg)
|
||||
gen.assign(_`${parseName}.position`, N.jsonPos)
|
||||
gen.return(undef)
|
||||
}
|
266
node_modules/schema-utils/node_modules/ajv/lib/compile/jtd/serialize.ts
generated
vendored
Normal file
266
node_modules/schema-utils/node_modules/ajv/lib/compile/jtd/serialize.ts
generated
vendored
Normal file
@@ -0,0 +1,266 @@
|
||||
import type Ajv from "../../core"
|
||||
import type {SchemaObject} from "../../types"
|
||||
import {jtdForms, JTDForm, SchemaObjectMap} from "./types"
|
||||
import {SchemaEnv, getCompilingSchema} from ".."
|
||||
import {_, str, and, getProperty, CodeGen, Code, Name} from "../codegen"
|
||||
import MissingRefError from "../ref_error"
|
||||
import N from "../names"
|
||||
import {isOwnProperty} from "../../vocabularies/code"
|
||||
import {hasRef} from "../../vocabularies/jtd/ref"
|
||||
import {useFunc} from "../util"
|
||||
import quote from "../../runtime/quote"
|
||||
|
||||
const genSerialize: {[F in JTDForm]: (cxt: SerializeCxt) => void} = {
|
||||
elements: serializeElements,
|
||||
values: serializeValues,
|
||||
discriminator: serializeDiscriminator,
|
||||
properties: serializeProperties,
|
||||
optionalProperties: serializeProperties,
|
||||
enum: serializeString,
|
||||
type: serializeType,
|
||||
ref: serializeRef,
|
||||
}
|
||||
|
||||
interface SerializeCxt {
|
||||
readonly gen: CodeGen
|
||||
readonly self: Ajv // current Ajv instance
|
||||
readonly schemaEnv: SchemaEnv
|
||||
readonly definitions: SchemaObjectMap
|
||||
schema: SchemaObject
|
||||
data: Code
|
||||
}
|
||||
|
||||
export default function compileSerializer(
|
||||
this: Ajv,
|
||||
sch: SchemaEnv,
|
||||
definitions: SchemaObjectMap
|
||||
): SchemaEnv {
|
||||
const _sch = getCompilingSchema.call(this, sch)
|
||||
if (_sch) return _sch
|
||||
const {es5, lines} = this.opts.code
|
||||
const {ownProperties} = this.opts
|
||||
const gen = new CodeGen(this.scope, {es5, lines, ownProperties})
|
||||
const serializeName = gen.scopeName("serialize")
|
||||
const cxt: SerializeCxt = {
|
||||
self: this,
|
||||
gen,
|
||||
schema: sch.schema as SchemaObject,
|
||||
schemaEnv: sch,
|
||||
definitions,
|
||||
data: N.data,
|
||||
}
|
||||
|
||||
let sourceCode: string | undefined
|
||||
try {
|
||||
this._compilations.add(sch)
|
||||
sch.serializeName = serializeName
|
||||
gen.func(serializeName, N.data, false, () => {
|
||||
gen.let(N.json, str``)
|
||||
serializeCode(cxt)
|
||||
gen.return(N.json)
|
||||
})
|
||||
gen.optimize(this.opts.code.optimize)
|
||||
const serializeFuncCode = gen.toString()
|
||||
sourceCode = `${gen.scopeRefs(N.scope)}return ${serializeFuncCode}`
|
||||
const makeSerialize = new Function(`${N.scope}`, sourceCode)
|
||||
const serialize: (data: unknown) => string = makeSerialize(this.scope.get())
|
||||
this.scope.value(serializeName, {ref: serialize})
|
||||
sch.serialize = serialize
|
||||
} catch (e) {
|
||||
if (sourceCode) this.logger.error("Error compiling serializer, function code:", sourceCode)
|
||||
delete sch.serialize
|
||||
delete sch.serializeName
|
||||
throw e
|
||||
} finally {
|
||||
this._compilations.delete(sch)
|
||||
}
|
||||
return sch
|
||||
}
|
||||
|
||||
function serializeCode(cxt: SerializeCxt): void {
|
||||
let form: JTDForm | undefined
|
||||
for (const key of jtdForms) {
|
||||
if (key in cxt.schema) {
|
||||
form = key
|
||||
break
|
||||
}
|
||||
}
|
||||
serializeNullable(cxt, form ? genSerialize[form] : serializeEmpty)
|
||||
}
|
||||
|
||||
function serializeNullable(cxt: SerializeCxt, serializeForm: (_cxt: SerializeCxt) => void): void {
|
||||
const {gen, schema, data} = cxt
|
||||
if (!schema.nullable) return serializeForm(cxt)
|
||||
gen.if(
|
||||
_`${data} === undefined || ${data} === null`,
|
||||
() => gen.add(N.json, _`"null"`),
|
||||
() => serializeForm(cxt)
|
||||
)
|
||||
}
|
||||
|
||||
function serializeElements(cxt: SerializeCxt): void {
|
||||
const {gen, schema, data} = cxt
|
||||
gen.add(N.json, str`[`)
|
||||
const first = gen.let("first", true)
|
||||
gen.forOf("el", data, (el) => {
|
||||
addComma(cxt, first)
|
||||
serializeCode({...cxt, schema: schema.elements, data: el})
|
||||
})
|
||||
gen.add(N.json, str`]`)
|
||||
}
|
||||
|
||||
function serializeValues(cxt: SerializeCxt): void {
|
||||
const {gen, schema, data} = cxt
|
||||
gen.add(N.json, str`{`)
|
||||
const first = gen.let("first", true)
|
||||
gen.forIn("key", data, (key) => serializeKeyValue(cxt, key, schema.values, first))
|
||||
gen.add(N.json, str`}`)
|
||||
}
|
||||
|
||||
function serializeKeyValue(cxt: SerializeCxt, key: Name, schema: SchemaObject, first?: Name): void {
|
||||
const {gen, data} = cxt
|
||||
addComma(cxt, first)
|
||||
serializeString({...cxt, data: key})
|
||||
gen.add(N.json, str`:`)
|
||||
const value = gen.const("value", _`${data}${getProperty(key)}`)
|
||||
serializeCode({...cxt, schema, data: value})
|
||||
}
|
||||
|
||||
function serializeDiscriminator(cxt: SerializeCxt): void {
|
||||
const {gen, schema, data} = cxt
|
||||
const {discriminator} = schema
|
||||
gen.add(N.json, str`{${JSON.stringify(discriminator)}:`)
|
||||
const tag = gen.const("tag", _`${data}${getProperty(discriminator)}`)
|
||||
serializeString({...cxt, data: tag})
|
||||
gen.if(false)
|
||||
for (const tagValue in schema.mapping) {
|
||||
gen.elseIf(_`${tag} === ${tagValue}`)
|
||||
const sch = schema.mapping[tagValue]
|
||||
serializeSchemaProperties({...cxt, schema: sch}, discriminator)
|
||||
}
|
||||
gen.endIf()
|
||||
gen.add(N.json, str`}`)
|
||||
}
|
||||
|
||||
function serializeProperties(cxt: SerializeCxt): void {
|
||||
const {gen} = cxt
|
||||
gen.add(N.json, str`{`)
|
||||
serializeSchemaProperties(cxt)
|
||||
gen.add(N.json, str`}`)
|
||||
}
|
||||
|
||||
function serializeSchemaProperties(cxt: SerializeCxt, discriminator?: string): void {
|
||||
const {gen, schema, data} = cxt
|
||||
const {properties, optionalProperties} = schema
|
||||
const props = keys(properties)
|
||||
const optProps = keys(optionalProperties)
|
||||
const allProps = allProperties(props.concat(optProps))
|
||||
let first = !discriminator
|
||||
let firstProp: Name | undefined
|
||||
|
||||
for (const key of props) {
|
||||
if (first) first = false
|
||||
else gen.add(N.json, str`,`)
|
||||
serializeProperty(key, properties[key], keyValue(key))
|
||||
}
|
||||
if (first) firstProp = gen.let("first", true)
|
||||
for (const key of optProps) {
|
||||
const value = keyValue(key)
|
||||
gen.if(and(_`${value} !== undefined`, isOwnProperty(gen, data, key)), () => {
|
||||
addComma(cxt, firstProp)
|
||||
serializeProperty(key, optionalProperties[key], value)
|
||||
})
|
||||
}
|
||||
if (schema.additionalProperties) {
|
||||
gen.forIn("key", data, (key) =>
|
||||
gen.if(isAdditional(key, allProps), () => serializeKeyValue(cxt, key, {}, firstProp))
|
||||
)
|
||||
}
|
||||
|
||||
function keys(ps?: SchemaObjectMap): string[] {
|
||||
return ps ? Object.keys(ps) : []
|
||||
}
|
||||
|
||||
function allProperties(ps: string[]): string[] {
|
||||
if (discriminator) ps.push(discriminator)
|
||||
if (new Set(ps).size !== ps.length) {
|
||||
throw new Error("JTD: properties/optionalProperties/disciminator overlap")
|
||||
}
|
||||
return ps
|
||||
}
|
||||
|
||||
function keyValue(key: string): Name {
|
||||
return gen.const("value", _`${data}${getProperty(key)}`)
|
||||
}
|
||||
|
||||
function serializeProperty(key: string, propSchema: SchemaObject, value: Name): void {
|
||||
gen.add(N.json, str`${JSON.stringify(key)}:`)
|
||||
serializeCode({...cxt, schema: propSchema, data: value})
|
||||
}
|
||||
|
||||
function isAdditional(key: Name, ps: string[]): Code | true {
|
||||
return ps.length ? and(...ps.map((p) => _`${key} !== ${p}`)) : true
|
||||
}
|
||||
}
|
||||
|
||||
function serializeType(cxt: SerializeCxt): void {
|
||||
const {gen, schema, data} = cxt
|
||||
switch (schema.type) {
|
||||
case "boolean":
|
||||
gen.add(N.json, _`${data} ? "true" : "false"`)
|
||||
break
|
||||
case "string":
|
||||
serializeString(cxt)
|
||||
break
|
||||
case "timestamp":
|
||||
gen.if(
|
||||
_`${data} instanceof Date`,
|
||||
() => gen.add(N.json, _`'"' + ${data}.toISOString() + '"'`),
|
||||
() => serializeString(cxt)
|
||||
)
|
||||
break
|
||||
default:
|
||||
serializeNumber(cxt)
|
||||
}
|
||||
}
|
||||
|
||||
function serializeString({gen, data}: SerializeCxt): void {
|
||||
gen.add(N.json, _`${useFunc(gen, quote)}(${data})`)
|
||||
}
|
||||
|
||||
function serializeNumber({gen, data}: SerializeCxt): void {
|
||||
gen.add(N.json, _`"" + ${data}`)
|
||||
}
|
||||
|
||||
function serializeRef(cxt: SerializeCxt): void {
|
||||
const {gen, self, data, definitions, schema, schemaEnv} = cxt
|
||||
const {ref} = schema
|
||||
const refSchema = definitions[ref]
|
||||
if (!refSchema) throw new MissingRefError(self.opts.uriResolver, "", ref, `No definition ${ref}`)
|
||||
if (!hasRef(refSchema)) return serializeCode({...cxt, schema: refSchema})
|
||||
const {root} = schemaEnv
|
||||
const sch = compileSerializer.call(self, new SchemaEnv({schema: refSchema, root}), definitions)
|
||||
gen.add(N.json, _`${getSerialize(gen, sch)}(${data})`)
|
||||
}
|
||||
|
||||
function getSerialize(gen: CodeGen, sch: SchemaEnv): Code {
|
||||
return sch.serialize
|
||||
? gen.scopeValue("serialize", {ref: sch.serialize})
|
||||
: _`${gen.scopeValue("wrapper", {ref: sch})}.serialize`
|
||||
}
|
||||
|
||||
function serializeEmpty({gen, data}: SerializeCxt): void {
|
||||
gen.add(N.json, _`JSON.stringify(${data})`)
|
||||
}
|
||||
|
||||
function addComma({gen}: SerializeCxt, first?: Name): void {
|
||||
if (first) {
|
||||
gen.if(
|
||||
first,
|
||||
() => gen.assign(first, false),
|
||||
() => gen.add(N.json, str`,`)
|
||||
)
|
||||
} else {
|
||||
gen.add(N.json, str`,`)
|
||||
}
|
||||
}
|
16
node_modules/schema-utils/node_modules/ajv/lib/compile/jtd/types.ts
generated
vendored
Normal file
16
node_modules/schema-utils/node_modules/ajv/lib/compile/jtd/types.ts
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
import type {SchemaObject} from "../../types"
|
||||
|
||||
export type SchemaObjectMap = {[Ref in string]?: SchemaObject}
|
||||
|
||||
export const jtdForms = [
|
||||
"elements",
|
||||
"values",
|
||||
"discriminator",
|
||||
"properties",
|
||||
"optionalProperties",
|
||||
"enum",
|
||||
"type",
|
||||
"ref",
|
||||
] as const
|
||||
|
||||
export type JTDForm = (typeof jtdForms)[number]
|
27
node_modules/schema-utils/node_modules/ajv/lib/compile/names.ts
generated
vendored
Normal file
27
node_modules/schema-utils/node_modules/ajv/lib/compile/names.ts
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
import {Name} from "./codegen"
|
||||
|
||||
const names = {
|
||||
// validation function arguments
|
||||
data: new Name("data"), // data passed to validation function
|
||||
// args passed from referencing schema
|
||||
valCxt: new Name("valCxt"), // validation/data context - should not be used directly, it is destructured to the names below
|
||||
instancePath: new Name("instancePath"),
|
||||
parentData: new Name("parentData"),
|
||||
parentDataProperty: new Name("parentDataProperty"),
|
||||
rootData: new Name("rootData"), // root data - same as the data passed to the first/top validation function
|
||||
dynamicAnchors: new Name("dynamicAnchors"), // used to support recursiveRef and dynamicRef
|
||||
// function scoped variables
|
||||
vErrors: new Name("vErrors"), // null or array of validation errors
|
||||
errors: new Name("errors"), // counter of validation errors
|
||||
this: new Name("this"),
|
||||
// "globals"
|
||||
self: new Name("self"),
|
||||
scope: new Name("scope"),
|
||||
// JTD serialize/parse name for JSON string and position
|
||||
json: new Name("json"),
|
||||
jsonPos: new Name("jsonPos"),
|
||||
jsonLen: new Name("jsonLen"),
|
||||
jsonPart: new Name("jsonPart"),
|
||||
}
|
||||
|
||||
export default names
|
13
node_modules/schema-utils/node_modules/ajv/lib/compile/ref_error.ts
generated
vendored
Normal file
13
node_modules/schema-utils/node_modules/ajv/lib/compile/ref_error.ts
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
import {resolveUrl, normalizeId, getFullPath} from "./resolve"
|
||||
import type {UriResolver} from "../types"
|
||||
|
||||
export default class MissingRefError extends Error {
|
||||
readonly missingRef: string
|
||||
readonly missingSchema: string
|
||||
|
||||
constructor(resolver: UriResolver, baseId: string, ref: string, msg?: string) {
|
||||
super(msg || `can't resolve reference ${ref} from id ${baseId}`)
|
||||
this.missingRef = resolveUrl(resolver, baseId, ref)
|
||||
this.missingSchema = normalizeId(getFullPath(resolver, this.missingRef))
|
||||
}
|
||||
}
|
149
node_modules/schema-utils/node_modules/ajv/lib/compile/resolve.ts
generated
vendored
Normal file
149
node_modules/schema-utils/node_modules/ajv/lib/compile/resolve.ts
generated
vendored
Normal file
@@ -0,0 +1,149 @@
|
||||
import type {AnySchema, AnySchemaObject, UriResolver} from "../types"
|
||||
import type Ajv from "../ajv"
|
||||
import type {URIComponent} from "fast-uri"
|
||||
import {eachItem} from "./util"
|
||||
import * as equal from "fast-deep-equal"
|
||||
import * as traverse from "json-schema-traverse"
|
||||
|
||||
// the hash of local references inside the schema (created by getSchemaRefs), used for inline resolution
|
||||
export type LocalRefs = {[Ref in string]?: AnySchemaObject}
|
||||
|
||||
// TODO refactor to use keyword definitions
|
||||
const SIMPLE_INLINED = new Set([
|
||||
"type",
|
||||
"format",
|
||||
"pattern",
|
||||
"maxLength",
|
||||
"minLength",
|
||||
"maxProperties",
|
||||
"minProperties",
|
||||
"maxItems",
|
||||
"minItems",
|
||||
"maximum",
|
||||
"minimum",
|
||||
"uniqueItems",
|
||||
"multipleOf",
|
||||
"required",
|
||||
"enum",
|
||||
"const",
|
||||
])
|
||||
|
||||
export function inlineRef(schema: AnySchema, limit: boolean | number = true): boolean {
|
||||
if (typeof schema == "boolean") return true
|
||||
if (limit === true) return !hasRef(schema)
|
||||
if (!limit) return false
|
||||
return countKeys(schema) <= limit
|
||||
}
|
||||
|
||||
const REF_KEYWORDS = new Set([
|
||||
"$ref",
|
||||
"$recursiveRef",
|
||||
"$recursiveAnchor",
|
||||
"$dynamicRef",
|
||||
"$dynamicAnchor",
|
||||
])
|
||||
|
||||
function hasRef(schema: AnySchemaObject): boolean {
|
||||
for (const key in schema) {
|
||||
if (REF_KEYWORDS.has(key)) return true
|
||||
const sch = schema[key]
|
||||
if (Array.isArray(sch) && sch.some(hasRef)) return true
|
||||
if (typeof sch == "object" && hasRef(sch)) return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
function countKeys(schema: AnySchemaObject): number {
|
||||
let count = 0
|
||||
for (const key in schema) {
|
||||
if (key === "$ref") return Infinity
|
||||
count++
|
||||
if (SIMPLE_INLINED.has(key)) continue
|
||||
if (typeof schema[key] == "object") {
|
||||
eachItem(schema[key], (sch) => (count += countKeys(sch)))
|
||||
}
|
||||
if (count === Infinity) return Infinity
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
export function getFullPath(resolver: UriResolver, id = "", normalize?: boolean): string {
|
||||
if (normalize !== false) id = normalizeId(id)
|
||||
const p = resolver.parse(id)
|
||||
return _getFullPath(resolver, p)
|
||||
}
|
||||
|
||||
export function _getFullPath(resolver: UriResolver, p: URIComponent): string {
|
||||
const serialized = resolver.serialize(p)
|
||||
return serialized.split("#")[0] + "#"
|
||||
}
|
||||
|
||||
const TRAILING_SLASH_HASH = /#\/?$/
|
||||
export function normalizeId(id: string | undefined): string {
|
||||
return id ? id.replace(TRAILING_SLASH_HASH, "") : ""
|
||||
}
|
||||
|
||||
export function resolveUrl(resolver: UriResolver, baseId: string, id: string): string {
|
||||
id = normalizeId(id)
|
||||
return resolver.resolve(baseId, id)
|
||||
}
|
||||
|
||||
const ANCHOR = /^[a-z_][-a-z0-9._]*$/i
|
||||
|
||||
export function getSchemaRefs(this: Ajv, schema: AnySchema, baseId: string): LocalRefs {
|
||||
if (typeof schema == "boolean") return {}
|
||||
const {schemaId, uriResolver} = this.opts
|
||||
const schId = normalizeId(schema[schemaId] || baseId)
|
||||
const baseIds: {[JsonPtr in string]?: string} = {"": schId}
|
||||
const pathPrefix = getFullPath(uriResolver, schId, false)
|
||||
const localRefs: LocalRefs = {}
|
||||
const schemaRefs: Set<string> = new Set()
|
||||
|
||||
traverse(schema, {allKeys: true}, (sch, jsonPtr, _, parentJsonPtr) => {
|
||||
if (parentJsonPtr === undefined) return
|
||||
const fullPath = pathPrefix + jsonPtr
|
||||
let innerBaseId = baseIds[parentJsonPtr]
|
||||
if (typeof sch[schemaId] == "string") innerBaseId = addRef.call(this, sch[schemaId])
|
||||
addAnchor.call(this, sch.$anchor)
|
||||
addAnchor.call(this, sch.$dynamicAnchor)
|
||||
baseIds[jsonPtr] = innerBaseId
|
||||
|
||||
function addRef(this: Ajv, ref: string): string {
|
||||
// eslint-disable-next-line @typescript-eslint/unbound-method
|
||||
const _resolve = this.opts.uriResolver.resolve
|
||||
ref = normalizeId(innerBaseId ? _resolve(innerBaseId, ref) : ref)
|
||||
if (schemaRefs.has(ref)) throw ambiguos(ref)
|
||||
schemaRefs.add(ref)
|
||||
let schOrRef = this.refs[ref]
|
||||
if (typeof schOrRef == "string") schOrRef = this.refs[schOrRef]
|
||||
if (typeof schOrRef == "object") {
|
||||
checkAmbiguosRef(sch, schOrRef.schema, ref)
|
||||
} else if (ref !== normalizeId(fullPath)) {
|
||||
if (ref[0] === "#") {
|
||||
checkAmbiguosRef(sch, localRefs[ref], ref)
|
||||
localRefs[ref] = sch
|
||||
} else {
|
||||
this.refs[ref] = fullPath
|
||||
}
|
||||
}
|
||||
return ref
|
||||
}
|
||||
|
||||
function addAnchor(this: Ajv, anchor: unknown): void {
|
||||
if (typeof anchor == "string") {
|
||||
if (!ANCHOR.test(anchor)) throw new Error(`invalid anchor "${anchor}"`)
|
||||
addRef.call(this, `#${anchor}`)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return localRefs
|
||||
|
||||
function checkAmbiguosRef(sch1: AnySchema, sch2: AnySchema | undefined, ref: string): void {
|
||||
if (sch2 !== undefined && !equal(sch1, sch2)) throw ambiguos(ref)
|
||||
}
|
||||
|
||||
function ambiguos(ref: string): Error {
|
||||
return new Error(`reference "${ref}" resolves to more than one schema`)
|
||||
}
|
||||
}
|
50
node_modules/schema-utils/node_modules/ajv/lib/compile/rules.ts
generated
vendored
Normal file
50
node_modules/schema-utils/node_modules/ajv/lib/compile/rules.ts
generated
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
import type {AddedKeywordDefinition} from "../types"
|
||||
|
||||
const _jsonTypes = ["string", "number", "integer", "boolean", "null", "object", "array"] as const
|
||||
|
||||
export type JSONType = (typeof _jsonTypes)[number]
|
||||
|
||||
const jsonTypes: Set<string> = new Set(_jsonTypes)
|
||||
|
||||
export function isJSONType(x: unknown): x is JSONType {
|
||||
return typeof x == "string" && jsonTypes.has(x)
|
||||
}
|
||||
|
||||
type ValidationTypes = {
|
||||
[K in JSONType]: boolean | RuleGroup | undefined
|
||||
}
|
||||
|
||||
export interface ValidationRules {
|
||||
rules: RuleGroup[]
|
||||
post: RuleGroup
|
||||
all: {[Key in string]?: boolean | Rule} // rules that have to be validated
|
||||
keywords: {[Key in string]?: boolean} // all known keywords (superset of "all")
|
||||
types: ValidationTypes
|
||||
}
|
||||
|
||||
export interface RuleGroup {
|
||||
type?: JSONType
|
||||
rules: Rule[]
|
||||
}
|
||||
|
||||
// This interface wraps KeywordDefinition because definition can have multiple keywords
|
||||
export interface Rule {
|
||||
keyword: string
|
||||
definition: AddedKeywordDefinition
|
||||
}
|
||||
|
||||
export function getRules(): ValidationRules {
|
||||
const groups: Record<"number" | "string" | "array" | "object", RuleGroup> = {
|
||||
number: {type: "number", rules: []},
|
||||
string: {type: "string", rules: []},
|
||||
array: {type: "array", rules: []},
|
||||
object: {type: "object", rules: []},
|
||||
}
|
||||
return {
|
||||
types: {...groups, integer: true, boolean: true, null: true},
|
||||
rules: [{rules: []}, groups.number, groups.string, groups.array, groups.object],
|
||||
post: {rules: []},
|
||||
all: {},
|
||||
keywords: {},
|
||||
}
|
||||
}
|
213
node_modules/schema-utils/node_modules/ajv/lib/compile/util.ts
generated
vendored
Normal file
213
node_modules/schema-utils/node_modules/ajv/lib/compile/util.ts
generated
vendored
Normal file
@@ -0,0 +1,213 @@
|
||||
import type {AnySchema, EvaluatedProperties, EvaluatedItems} from "../types"
|
||||
import type {SchemaCxt, SchemaObjCxt} from "."
|
||||
import {_, getProperty, Code, Name, CodeGen} from "./codegen"
|
||||
import {_Code} from "./codegen/code"
|
||||
import type {Rule, ValidationRules} from "./rules"
|
||||
|
||||
// TODO refactor to use Set
|
||||
export function toHash<T extends string = string>(arr: T[]): {[K in T]?: true} {
|
||||
const hash: {[K in T]?: true} = {}
|
||||
for (const item of arr) hash[item] = true
|
||||
return hash
|
||||
}
|
||||
|
||||
export function alwaysValidSchema(it: SchemaCxt, schema: AnySchema): boolean | void {
|
||||
if (typeof schema == "boolean") return schema
|
||||
if (Object.keys(schema).length === 0) return true
|
||||
checkUnknownRules(it, schema)
|
||||
return !schemaHasRules(schema, it.self.RULES.all)
|
||||
}
|
||||
|
||||
export function checkUnknownRules(it: SchemaCxt, schema: AnySchema = it.schema): void {
|
||||
const {opts, self} = it
|
||||
if (!opts.strictSchema) return
|
||||
if (typeof schema === "boolean") return
|
||||
const rules = self.RULES.keywords
|
||||
for (const key in schema) {
|
||||
if (!rules[key]) checkStrictMode(it, `unknown keyword: "${key}"`)
|
||||
}
|
||||
}
|
||||
|
||||
export function schemaHasRules(
|
||||
schema: AnySchema,
|
||||
rules: {[Key in string]?: boolean | Rule}
|
||||
): boolean {
|
||||
if (typeof schema == "boolean") return !schema
|
||||
for (const key in schema) if (rules[key]) return true
|
||||
return false
|
||||
}
|
||||
|
||||
export function schemaHasRulesButRef(schema: AnySchema, RULES: ValidationRules): boolean {
|
||||
if (typeof schema == "boolean") return !schema
|
||||
for (const key in schema) if (key !== "$ref" && RULES.all[key]) return true
|
||||
return false
|
||||
}
|
||||
|
||||
export function schemaRefOrVal(
|
||||
{topSchemaRef, schemaPath}: SchemaObjCxt,
|
||||
schema: unknown,
|
||||
keyword: string,
|
||||
$data?: string | false
|
||||
): Code | number | boolean {
|
||||
if (!$data) {
|
||||
if (typeof schema == "number" || typeof schema == "boolean") return schema
|
||||
if (typeof schema == "string") return _`${schema}`
|
||||
}
|
||||
return _`${topSchemaRef}${schemaPath}${getProperty(keyword)}`
|
||||
}
|
||||
|
||||
export function unescapeFragment(str: string): string {
|
||||
return unescapeJsonPointer(decodeURIComponent(str))
|
||||
}
|
||||
|
||||
export function escapeFragment(str: string | number): string {
|
||||
return encodeURIComponent(escapeJsonPointer(str))
|
||||
}
|
||||
|
||||
export function escapeJsonPointer(str: string | number): string {
|
||||
if (typeof str == "number") return `${str}`
|
||||
return str.replace(/~/g, "~0").replace(/\//g, "~1")
|
||||
}
|
||||
|
||||
export function unescapeJsonPointer(str: string): string {
|
||||
return str.replace(/~1/g, "/").replace(/~0/g, "~")
|
||||
}
|
||||
|
||||
export function eachItem<T>(xs: T | T[], f: (x: T) => void): void {
|
||||
if (Array.isArray(xs)) {
|
||||
for (const x of xs) f(x)
|
||||
} else {
|
||||
f(xs)
|
||||
}
|
||||
}
|
||||
|
||||
type SomeEvaluated = EvaluatedProperties | EvaluatedItems
|
||||
|
||||
type MergeEvaluatedFunc<T extends SomeEvaluated> = (
|
||||
gen: CodeGen,
|
||||
from: Name | T,
|
||||
to: Name | Exclude<T, true> | undefined,
|
||||
toName?: typeof Name
|
||||
) => Name | T
|
||||
|
||||
interface MakeMergeFuncArgs<T extends SomeEvaluated> {
|
||||
mergeNames: (gen: CodeGen, from: Name, to: Name) => void
|
||||
mergeToName: (gen: CodeGen, from: T, to: Name) => void
|
||||
mergeValues: (from: T, to: Exclude<T, true>) => T
|
||||
resultToName: (gen: CodeGen, res?: T) => Name
|
||||
}
|
||||
|
||||
function makeMergeEvaluated<T extends SomeEvaluated>({
|
||||
mergeNames,
|
||||
mergeToName,
|
||||
mergeValues,
|
||||
resultToName,
|
||||
}: MakeMergeFuncArgs<T>): MergeEvaluatedFunc<T> {
|
||||
return (gen, from, to, toName) => {
|
||||
const res =
|
||||
to === undefined
|
||||
? from
|
||||
: to instanceof Name
|
||||
? (from instanceof Name ? mergeNames(gen, from, to) : mergeToName(gen, from, to), to)
|
||||
: from instanceof Name
|
||||
? (mergeToName(gen, to, from), from)
|
||||
: mergeValues(from, to)
|
||||
return toName === Name && !(res instanceof Name) ? resultToName(gen, res) : res
|
||||
}
|
||||
}
|
||||
|
||||
interface MergeEvaluated {
|
||||
props: MergeEvaluatedFunc<EvaluatedProperties>
|
||||
items: MergeEvaluatedFunc<EvaluatedItems>
|
||||
}
|
||||
|
||||
export const mergeEvaluated: MergeEvaluated = {
|
||||
props: makeMergeEvaluated({
|
||||
mergeNames: (gen, from, to) =>
|
||||
gen.if(_`${to} !== true && ${from} !== undefined`, () => {
|
||||
gen.if(
|
||||
_`${from} === true`,
|
||||
() => gen.assign(to, true),
|
||||
() => gen.assign(to, _`${to} || {}`).code(_`Object.assign(${to}, ${from})`)
|
||||
)
|
||||
}),
|
||||
mergeToName: (gen, from, to) =>
|
||||
gen.if(_`${to} !== true`, () => {
|
||||
if (from === true) {
|
||||
gen.assign(to, true)
|
||||
} else {
|
||||
gen.assign(to, _`${to} || {}`)
|
||||
setEvaluated(gen, to, from)
|
||||
}
|
||||
}),
|
||||
mergeValues: (from, to) => (from === true ? true : {...from, ...to}),
|
||||
resultToName: evaluatedPropsToName,
|
||||
}),
|
||||
items: makeMergeEvaluated({
|
||||
mergeNames: (gen, from, to) =>
|
||||
gen.if(_`${to} !== true && ${from} !== undefined`, () =>
|
||||
gen.assign(to, _`${from} === true ? true : ${to} > ${from} ? ${to} : ${from}`)
|
||||
),
|
||||
mergeToName: (gen, from, to) =>
|
||||
gen.if(_`${to} !== true`, () =>
|
||||
gen.assign(to, from === true ? true : _`${to} > ${from} ? ${to} : ${from}`)
|
||||
),
|
||||
mergeValues: (from, to) => (from === true ? true : Math.max(from, to)),
|
||||
resultToName: (gen, items) => gen.var("items", items),
|
||||
}),
|
||||
}
|
||||
|
||||
export function evaluatedPropsToName(gen: CodeGen, ps?: EvaluatedProperties): Name {
|
||||
if (ps === true) return gen.var("props", true)
|
||||
const props = gen.var("props", _`{}`)
|
||||
if (ps !== undefined) setEvaluated(gen, props, ps)
|
||||
return props
|
||||
}
|
||||
|
||||
export function setEvaluated(gen: CodeGen, props: Name, ps: {[K in string]?: true}): void {
|
||||
Object.keys(ps).forEach((p) => gen.assign(_`${props}${getProperty(p)}`, true))
|
||||
}
|
||||
|
||||
const snippets: {[S in string]?: _Code} = {}
|
||||
|
||||
export function useFunc(gen: CodeGen, f: {code: string}): Name {
|
||||
return gen.scopeValue("func", {
|
||||
ref: f,
|
||||
code: snippets[f.code] || (snippets[f.code] = new _Code(f.code)),
|
||||
})
|
||||
}
|
||||
|
||||
export enum Type {
|
||||
Num,
|
||||
Str,
|
||||
}
|
||||
|
||||
export function getErrorPath(
|
||||
dataProp: Name | string | number,
|
||||
dataPropType?: Type,
|
||||
jsPropertySyntax?: boolean
|
||||
): Code | string {
|
||||
// let path
|
||||
if (dataProp instanceof Name) {
|
||||
const isNumber = dataPropType === Type.Num
|
||||
return jsPropertySyntax
|
||||
? isNumber
|
||||
? _`"[" + ${dataProp} + "]"`
|
||||
: _`"['" + ${dataProp} + "']"`
|
||||
: isNumber
|
||||
? _`"/" + ${dataProp}`
|
||||
: _`"/" + ${dataProp}.replace(/~/g, "~0").replace(/\\//g, "~1")` // TODO maybe use global escapePointer
|
||||
}
|
||||
return jsPropertySyntax ? getProperty(dataProp).toString() : "/" + escapeJsonPointer(dataProp)
|
||||
}
|
||||
|
||||
export function checkStrictMode(
|
||||
it: SchemaCxt,
|
||||
msg: string,
|
||||
mode: boolean | "log" = it.opts.strictSchema
|
||||
): void {
|
||||
if (!mode) return
|
||||
msg = `strict mode: ${msg}`
|
||||
if (mode === true) throw new Error(msg)
|
||||
it.self.logger.warn(msg)
|
||||
}
|
22
node_modules/schema-utils/node_modules/ajv/lib/compile/validate/applicability.ts
generated
vendored
Normal file
22
node_modules/schema-utils/node_modules/ajv/lib/compile/validate/applicability.ts
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
import type {AnySchemaObject} from "../../types"
|
||||
import type {SchemaObjCxt} from ".."
|
||||
import type {JSONType, RuleGroup, Rule} from "../rules"
|
||||
|
||||
export function schemaHasRulesForType(
|
||||
{schema, self}: SchemaObjCxt,
|
||||
type: JSONType
|
||||
): boolean | undefined {
|
||||
const group = self.RULES.types[type]
|
||||
return group && group !== true && shouldUseGroup(schema, group)
|
||||
}
|
||||
|
||||
export function shouldUseGroup(schema: AnySchemaObject, group: RuleGroup): boolean {
|
||||
return group.rules.some((rule) => shouldUseRule(schema, rule))
|
||||
}
|
||||
|
||||
export function shouldUseRule(schema: AnySchemaObject, rule: Rule): boolean | undefined {
|
||||
return (
|
||||
schema[rule.keyword] !== undefined ||
|
||||
rule.definition.implements?.some((kwd) => schema[kwd] !== undefined)
|
||||
)
|
||||
}
|
47
node_modules/schema-utils/node_modules/ajv/lib/compile/validate/boolSchema.ts
generated
vendored
Normal file
47
node_modules/schema-utils/node_modules/ajv/lib/compile/validate/boolSchema.ts
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
import type {KeywordErrorDefinition, KeywordErrorCxt} from "../../types"
|
||||
import type {SchemaCxt} from ".."
|
||||
import {reportError} from "../errors"
|
||||
import {_, Name} from "../codegen"
|
||||
import N from "../names"
|
||||
|
||||
const boolError: KeywordErrorDefinition = {
|
||||
message: "boolean schema is false",
|
||||
}
|
||||
|
||||
export function topBoolOrEmptySchema(it: SchemaCxt): void {
|
||||
const {gen, schema, validateName} = it
|
||||
if (schema === false) {
|
||||
falseSchemaError(it, false)
|
||||
} else if (typeof schema == "object" && schema.$async === true) {
|
||||
gen.return(N.data)
|
||||
} else {
|
||||
gen.assign(_`${validateName}.errors`, null)
|
||||
gen.return(true)
|
||||
}
|
||||
}
|
||||
|
||||
export function boolOrEmptySchema(it: SchemaCxt, valid: Name): void {
|
||||
const {gen, schema} = it
|
||||
if (schema === false) {
|
||||
gen.var(valid, false) // TODO var
|
||||
falseSchemaError(it)
|
||||
} else {
|
||||
gen.var(valid, true) // TODO var
|
||||
}
|
||||
}
|
||||
|
||||
function falseSchemaError(it: SchemaCxt, overrideAllErrors?: boolean): void {
|
||||
const {gen, data} = it
|
||||
// TODO maybe some other interface should be used for non-keyword validation errors...
|
||||
const cxt: KeywordErrorCxt = {
|
||||
gen,
|
||||
keyword: "false schema",
|
||||
data,
|
||||
schema: false,
|
||||
schemaCode: false,
|
||||
schemaValue: false,
|
||||
params: {},
|
||||
it,
|
||||
}
|
||||
reportError(cxt, boolError, undefined, overrideAllErrors)
|
||||
}
|
230
node_modules/schema-utils/node_modules/ajv/lib/compile/validate/dataType.ts
generated
vendored
Normal file
230
node_modules/schema-utils/node_modules/ajv/lib/compile/validate/dataType.ts
generated
vendored
Normal file
@@ -0,0 +1,230 @@
|
||||
import type {
|
||||
KeywordErrorDefinition,
|
||||
KeywordErrorCxt,
|
||||
ErrorObject,
|
||||
AnySchemaObject,
|
||||
} from "../../types"
|
||||
import type {SchemaObjCxt} from ".."
|
||||
import {isJSONType, JSONType} from "../rules"
|
||||
import {schemaHasRulesForType} from "./applicability"
|
||||
import {reportError} from "../errors"
|
||||
import {_, nil, and, not, operators, Code, Name} from "../codegen"
|
||||
import {toHash, schemaRefOrVal} from "../util"
|
||||
|
||||
export enum DataType {
|
||||
Correct,
|
||||
Wrong,
|
||||
}
|
||||
|
||||
export function getSchemaTypes(schema: AnySchemaObject): JSONType[] {
|
||||
const types = getJSONTypes(schema.type)
|
||||
const hasNull = types.includes("null")
|
||||
if (hasNull) {
|
||||
if (schema.nullable === false) throw new Error("type: null contradicts nullable: false")
|
||||
} else {
|
||||
if (!types.length && schema.nullable !== undefined) {
|
||||
throw new Error('"nullable" cannot be used without "type"')
|
||||
}
|
||||
if (schema.nullable === true) types.push("null")
|
||||
}
|
||||
return types
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents
|
||||
export function getJSONTypes(ts: unknown | unknown[]): JSONType[] {
|
||||
const types: unknown[] = Array.isArray(ts) ? ts : ts ? [ts] : []
|
||||
if (types.every(isJSONType)) return types
|
||||
throw new Error("type must be JSONType or JSONType[]: " + types.join(","))
|
||||
}
|
||||
|
||||
export function coerceAndCheckDataType(it: SchemaObjCxt, types: JSONType[]): boolean {
|
||||
const {gen, data, opts} = it
|
||||
const coerceTo = coerceToTypes(types, opts.coerceTypes)
|
||||
const checkTypes =
|
||||
types.length > 0 &&
|
||||
!(coerceTo.length === 0 && types.length === 1 && schemaHasRulesForType(it, types[0]))
|
||||
if (checkTypes) {
|
||||
const wrongType = checkDataTypes(types, data, opts.strictNumbers, DataType.Wrong)
|
||||
gen.if(wrongType, () => {
|
||||
if (coerceTo.length) coerceData(it, types, coerceTo)
|
||||
else reportTypeError(it)
|
||||
})
|
||||
}
|
||||
return checkTypes
|
||||
}
|
||||
|
||||
const COERCIBLE: Set<JSONType> = new Set(["string", "number", "integer", "boolean", "null"])
|
||||
function coerceToTypes(types: JSONType[], coerceTypes?: boolean | "array"): JSONType[] {
|
||||
return coerceTypes
|
||||
? types.filter((t) => COERCIBLE.has(t) || (coerceTypes === "array" && t === "array"))
|
||||
: []
|
||||
}
|
||||
|
||||
function coerceData(it: SchemaObjCxt, types: JSONType[], coerceTo: JSONType[]): void {
|
||||
const {gen, data, opts} = it
|
||||
const dataType = gen.let("dataType", _`typeof ${data}`)
|
||||
const coerced = gen.let("coerced", _`undefined`)
|
||||
if (opts.coerceTypes === "array") {
|
||||
gen.if(_`${dataType} == 'object' && Array.isArray(${data}) && ${data}.length == 1`, () =>
|
||||
gen
|
||||
.assign(data, _`${data}[0]`)
|
||||
.assign(dataType, _`typeof ${data}`)
|
||||
.if(checkDataTypes(types, data, opts.strictNumbers), () => gen.assign(coerced, data))
|
||||
)
|
||||
}
|
||||
gen.if(_`${coerced} !== undefined`)
|
||||
for (const t of coerceTo) {
|
||||
if (COERCIBLE.has(t) || (t === "array" && opts.coerceTypes === "array")) {
|
||||
coerceSpecificType(t)
|
||||
}
|
||||
}
|
||||
gen.else()
|
||||
reportTypeError(it)
|
||||
gen.endIf()
|
||||
|
||||
gen.if(_`${coerced} !== undefined`, () => {
|
||||
gen.assign(data, coerced)
|
||||
assignParentData(it, coerced)
|
||||
})
|
||||
|
||||
function coerceSpecificType(t: string): void {
|
||||
switch (t) {
|
||||
case "string":
|
||||
gen
|
||||
.elseIf(_`${dataType} == "number" || ${dataType} == "boolean"`)
|
||||
.assign(coerced, _`"" + ${data}`)
|
||||
.elseIf(_`${data} === null`)
|
||||
.assign(coerced, _`""`)
|
||||
return
|
||||
case "number":
|
||||
gen
|
||||
.elseIf(
|
||||
_`${dataType} == "boolean" || ${data} === null
|
||||
|| (${dataType} == "string" && ${data} && ${data} == +${data})`
|
||||
)
|
||||
.assign(coerced, _`+${data}`)
|
||||
return
|
||||
case "integer":
|
||||
gen
|
||||
.elseIf(
|
||||
_`${dataType} === "boolean" || ${data} === null
|
||||
|| (${dataType} === "string" && ${data} && ${data} == +${data} && !(${data} % 1))`
|
||||
)
|
||||
.assign(coerced, _`+${data}`)
|
||||
return
|
||||
case "boolean":
|
||||
gen
|
||||
.elseIf(_`${data} === "false" || ${data} === 0 || ${data} === null`)
|
||||
.assign(coerced, false)
|
||||
.elseIf(_`${data} === "true" || ${data} === 1`)
|
||||
.assign(coerced, true)
|
||||
return
|
||||
case "null":
|
||||
gen.elseIf(_`${data} === "" || ${data} === 0 || ${data} === false`)
|
||||
gen.assign(coerced, null)
|
||||
return
|
||||
|
||||
case "array":
|
||||
gen
|
||||
.elseIf(
|
||||
_`${dataType} === "string" || ${dataType} === "number"
|
||||
|| ${dataType} === "boolean" || ${data} === null`
|
||||
)
|
||||
.assign(coerced, _`[${data}]`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function assignParentData({gen, parentData, parentDataProperty}: SchemaObjCxt, expr: Name): void {
|
||||
// TODO use gen.property
|
||||
gen.if(_`${parentData} !== undefined`, () =>
|
||||
gen.assign(_`${parentData}[${parentDataProperty}]`, expr)
|
||||
)
|
||||
}
|
||||
|
||||
export function checkDataType(
|
||||
dataType: JSONType,
|
||||
data: Name,
|
||||
strictNums?: boolean | "log",
|
||||
correct = DataType.Correct
|
||||
): Code {
|
||||
const EQ = correct === DataType.Correct ? operators.EQ : operators.NEQ
|
||||
let cond: Code
|
||||
switch (dataType) {
|
||||
case "null":
|
||||
return _`${data} ${EQ} null`
|
||||
case "array":
|
||||
cond = _`Array.isArray(${data})`
|
||||
break
|
||||
case "object":
|
||||
cond = _`${data} && typeof ${data} == "object" && !Array.isArray(${data})`
|
||||
break
|
||||
case "integer":
|
||||
cond = numCond(_`!(${data} % 1) && !isNaN(${data})`)
|
||||
break
|
||||
case "number":
|
||||
cond = numCond()
|
||||
break
|
||||
default:
|
||||
return _`typeof ${data} ${EQ} ${dataType}`
|
||||
}
|
||||
return correct === DataType.Correct ? cond : not(cond)
|
||||
|
||||
function numCond(_cond: Code = nil): Code {
|
||||
return and(_`typeof ${data} == "number"`, _cond, strictNums ? _`isFinite(${data})` : nil)
|
||||
}
|
||||
}
|
||||
|
||||
export function checkDataTypes(
|
||||
dataTypes: JSONType[],
|
||||
data: Name,
|
||||
strictNums?: boolean | "log",
|
||||
correct?: DataType
|
||||
): Code {
|
||||
if (dataTypes.length === 1) {
|
||||
return checkDataType(dataTypes[0], data, strictNums, correct)
|
||||
}
|
||||
let cond: Code
|
||||
const types = toHash(dataTypes)
|
||||
if (types.array && types.object) {
|
||||
const notObj = _`typeof ${data} != "object"`
|
||||
cond = types.null ? notObj : _`!${data} || ${notObj}`
|
||||
delete types.null
|
||||
delete types.array
|
||||
delete types.object
|
||||
} else {
|
||||
cond = nil
|
||||
}
|
||||
if (types.number) delete types.integer
|
||||
for (const t in types) cond = and(cond, checkDataType(t as JSONType, data, strictNums, correct))
|
||||
return cond
|
||||
}
|
||||
|
||||
export type TypeError = ErrorObject<"type", {type: string}>
|
||||
|
||||
const typeError: KeywordErrorDefinition = {
|
||||
message: ({schema}) => `must be ${schema}`,
|
||||
params: ({schema, schemaValue}) =>
|
||||
typeof schema == "string" ? _`{type: ${schema}}` : _`{type: ${schemaValue}}`,
|
||||
}
|
||||
|
||||
export function reportTypeError(it: SchemaObjCxt): void {
|
||||
const cxt = getTypeErrorContext(it)
|
||||
reportError(cxt, typeError)
|
||||
}
|
||||
|
||||
function getTypeErrorContext(it: SchemaObjCxt): KeywordErrorCxt {
|
||||
const {gen, data, schema} = it
|
||||
const schemaCode = schemaRefOrVal(it, schema, "type")
|
||||
return {
|
||||
gen,
|
||||
keyword: "type",
|
||||
data,
|
||||
schema: schema.type,
|
||||
schemaCode,
|
||||
schemaValue: schemaCode,
|
||||
parentSchema: schema,
|
||||
params: {},
|
||||
it,
|
||||
}
|
||||
}
|
32
node_modules/schema-utils/node_modules/ajv/lib/compile/validate/defaults.ts
generated
vendored
Normal file
32
node_modules/schema-utils/node_modules/ajv/lib/compile/validate/defaults.ts
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
import type {SchemaObjCxt} from ".."
|
||||
import {_, getProperty, stringify} from "../codegen"
|
||||
import {checkStrictMode} from "../util"
|
||||
|
||||
export function assignDefaults(it: SchemaObjCxt, ty?: string): void {
|
||||
const {properties, items} = it.schema
|
||||
if (ty === "object" && properties) {
|
||||
for (const key in properties) {
|
||||
assignDefault(it, key, properties[key].default)
|
||||
}
|
||||
} else if (ty === "array" && Array.isArray(items)) {
|
||||
items.forEach((sch, i: number) => assignDefault(it, i, sch.default))
|
||||
}
|
||||
}
|
||||
|
||||
function assignDefault(it: SchemaObjCxt, prop: string | number, defaultValue: unknown): void {
|
||||
const {gen, compositeRule, data, opts} = it
|
||||
if (defaultValue === undefined) return
|
||||
const childData = _`${data}${getProperty(prop)}`
|
||||
if (compositeRule) {
|
||||
checkStrictMode(it, `default is ignored for: ${childData}`)
|
||||
return
|
||||
}
|
||||
|
||||
let condition = _`${childData} === undefined`
|
||||
if (opts.useDefaults === "empty") {
|
||||
condition = _`${condition} || ${childData} === null || ${childData} === ""`
|
||||
}
|
||||
// `${childData} === undefined` +
|
||||
// (opts.useDefaults === "empty" ? ` || ${childData} === null || ${childData} === ""` : "")
|
||||
gen.if(condition, _`${childData} = ${stringify(defaultValue)}`)
|
||||
}
|
582
node_modules/schema-utils/node_modules/ajv/lib/compile/validate/index.ts
generated
vendored
Normal file
582
node_modules/schema-utils/node_modules/ajv/lib/compile/validate/index.ts
generated
vendored
Normal file
@@ -0,0 +1,582 @@
|
||||
import type {
|
||||
AddedKeywordDefinition,
|
||||
AnySchema,
|
||||
AnySchemaObject,
|
||||
KeywordErrorCxt,
|
||||
KeywordCxtParams,
|
||||
} from "../../types"
|
||||
import type {SchemaCxt, SchemaObjCxt} from ".."
|
||||
import type {InstanceOptions} from "../../core"
|
||||
import {boolOrEmptySchema, topBoolOrEmptySchema} from "./boolSchema"
|
||||
import {coerceAndCheckDataType, getSchemaTypes} from "./dataType"
|
||||
import {shouldUseGroup, shouldUseRule} from "./applicability"
|
||||
import {checkDataType, checkDataTypes, reportTypeError, DataType} from "./dataType"
|
||||
import {assignDefaults} from "./defaults"
|
||||
import {funcKeywordCode, macroKeywordCode, validateKeywordUsage, validSchemaType} from "./keyword"
|
||||
import {getSubschema, extendSubschemaData, SubschemaArgs, extendSubschemaMode} from "./subschema"
|
||||
import {_, nil, str, or, not, getProperty, Block, Code, Name, CodeGen} from "../codegen"
|
||||
import N from "../names"
|
||||
import {resolveUrl} from "../resolve"
|
||||
import {
|
||||
schemaRefOrVal,
|
||||
schemaHasRulesButRef,
|
||||
checkUnknownRules,
|
||||
checkStrictMode,
|
||||
unescapeJsonPointer,
|
||||
mergeEvaluated,
|
||||
} from "../util"
|
||||
import type {JSONType, Rule, RuleGroup} from "../rules"
|
||||
import {
|
||||
ErrorPaths,
|
||||
reportError,
|
||||
reportExtraError,
|
||||
resetErrorsCount,
|
||||
keyword$DataError,
|
||||
} from "../errors"
|
||||
|
||||
// schema compilation - generates validation function, subschemaCode (below) is used for subschemas
|
||||
export function validateFunctionCode(it: SchemaCxt): void {
|
||||
if (isSchemaObj(it)) {
|
||||
checkKeywords(it)
|
||||
if (schemaCxtHasRules(it)) {
|
||||
topSchemaObjCode(it)
|
||||
return
|
||||
}
|
||||
}
|
||||
validateFunction(it, () => topBoolOrEmptySchema(it))
|
||||
}
|
||||
|
||||
function validateFunction(
|
||||
{gen, validateName, schema, schemaEnv, opts}: SchemaCxt,
|
||||
body: Block
|
||||
): void {
|
||||
if (opts.code.es5) {
|
||||
gen.func(validateName, _`${N.data}, ${N.valCxt}`, schemaEnv.$async, () => {
|
||||
gen.code(_`"use strict"; ${funcSourceUrl(schema, opts)}`)
|
||||
destructureValCxtES5(gen, opts)
|
||||
gen.code(body)
|
||||
})
|
||||
} else {
|
||||
gen.func(validateName, _`${N.data}, ${destructureValCxt(opts)}`, schemaEnv.$async, () =>
|
||||
gen.code(funcSourceUrl(schema, opts)).code(body)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
function destructureValCxt(opts: InstanceOptions): Code {
|
||||
return _`{${N.instancePath}="", ${N.parentData}, ${N.parentDataProperty}, ${N.rootData}=${
|
||||
N.data
|
||||
}${opts.dynamicRef ? _`, ${N.dynamicAnchors}={}` : nil}}={}`
|
||||
}
|
||||
|
||||
function destructureValCxtES5(gen: CodeGen, opts: InstanceOptions): void {
|
||||
gen.if(
|
||||
N.valCxt,
|
||||
() => {
|
||||
gen.var(N.instancePath, _`${N.valCxt}.${N.instancePath}`)
|
||||
gen.var(N.parentData, _`${N.valCxt}.${N.parentData}`)
|
||||
gen.var(N.parentDataProperty, _`${N.valCxt}.${N.parentDataProperty}`)
|
||||
gen.var(N.rootData, _`${N.valCxt}.${N.rootData}`)
|
||||
if (opts.dynamicRef) gen.var(N.dynamicAnchors, _`${N.valCxt}.${N.dynamicAnchors}`)
|
||||
},
|
||||
() => {
|
||||
gen.var(N.instancePath, _`""`)
|
||||
gen.var(N.parentData, _`undefined`)
|
||||
gen.var(N.parentDataProperty, _`undefined`)
|
||||
gen.var(N.rootData, N.data)
|
||||
if (opts.dynamicRef) gen.var(N.dynamicAnchors, _`{}`)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
function topSchemaObjCode(it: SchemaObjCxt): void {
|
||||
const {schema, opts, gen} = it
|
||||
validateFunction(it, () => {
|
||||
if (opts.$comment && schema.$comment) commentKeyword(it)
|
||||
checkNoDefault(it)
|
||||
gen.let(N.vErrors, null)
|
||||
gen.let(N.errors, 0)
|
||||
if (opts.unevaluated) resetEvaluated(it)
|
||||
typeAndKeywords(it)
|
||||
returnResults(it)
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
function resetEvaluated(it: SchemaObjCxt): void {
|
||||
// TODO maybe some hook to execute it in the end to check whether props/items are Name, as in assignEvaluated
|
||||
const {gen, validateName} = it
|
||||
it.evaluated = gen.const("evaluated", _`${validateName}.evaluated`)
|
||||
gen.if(_`${it.evaluated}.dynamicProps`, () => gen.assign(_`${it.evaluated}.props`, _`undefined`))
|
||||
gen.if(_`${it.evaluated}.dynamicItems`, () => gen.assign(_`${it.evaluated}.items`, _`undefined`))
|
||||
}
|
||||
|
||||
function funcSourceUrl(schema: AnySchema, opts: InstanceOptions): Code {
|
||||
const schId = typeof schema == "object" && schema[opts.schemaId]
|
||||
return schId && (opts.code.source || opts.code.process) ? _`/*# sourceURL=${schId} */` : nil
|
||||
}
|
||||
|
||||
// schema compilation - this function is used recursively to generate code for sub-schemas
|
||||
function subschemaCode(it: SchemaCxt, valid: Name): void {
|
||||
if (isSchemaObj(it)) {
|
||||
checkKeywords(it)
|
||||
if (schemaCxtHasRules(it)) {
|
||||
subSchemaObjCode(it, valid)
|
||||
return
|
||||
}
|
||||
}
|
||||
boolOrEmptySchema(it, valid)
|
||||
}
|
||||
|
||||
function schemaCxtHasRules({schema, self}: SchemaCxt): boolean {
|
||||
if (typeof schema == "boolean") return !schema
|
||||
for (const key in schema) if (self.RULES.all[key]) return true
|
||||
return false
|
||||
}
|
||||
|
||||
function isSchemaObj(it: SchemaCxt): it is SchemaObjCxt {
|
||||
return typeof it.schema != "boolean"
|
||||
}
|
||||
|
||||
function subSchemaObjCode(it: SchemaObjCxt, valid: Name): void {
|
||||
const {schema, gen, opts} = it
|
||||
if (opts.$comment && schema.$comment) commentKeyword(it)
|
||||
updateContext(it)
|
||||
checkAsyncSchema(it)
|
||||
const errsCount = gen.const("_errs", N.errors)
|
||||
typeAndKeywords(it, errsCount)
|
||||
// TODO var
|
||||
gen.var(valid, _`${errsCount} === ${N.errors}`)
|
||||
}
|
||||
|
||||
function checkKeywords(it: SchemaObjCxt): void {
|
||||
checkUnknownRules(it)
|
||||
checkRefsAndKeywords(it)
|
||||
}
|
||||
|
||||
function typeAndKeywords(it: SchemaObjCxt, errsCount?: Name): void {
|
||||
if (it.opts.jtd) return schemaKeywords(it, [], false, errsCount)
|
||||
const types = getSchemaTypes(it.schema)
|
||||
const checkedTypes = coerceAndCheckDataType(it, types)
|
||||
schemaKeywords(it, types, !checkedTypes, errsCount)
|
||||
}
|
||||
|
||||
function checkRefsAndKeywords(it: SchemaObjCxt): void {
|
||||
const {schema, errSchemaPath, opts, self} = it
|
||||
if (schema.$ref && opts.ignoreKeywordsWithRef && schemaHasRulesButRef(schema, self.RULES)) {
|
||||
self.logger.warn(`$ref: keywords ignored in schema at path "${errSchemaPath}"`)
|
||||
}
|
||||
}
|
||||
|
||||
function checkNoDefault(it: SchemaObjCxt): void {
|
||||
const {schema, opts} = it
|
||||
if (schema.default !== undefined && opts.useDefaults && opts.strictSchema) {
|
||||
checkStrictMode(it, "default is ignored in the schema root")
|
||||
}
|
||||
}
|
||||
|
||||
function updateContext(it: SchemaObjCxt): void {
|
||||
const schId = it.schema[it.opts.schemaId]
|
||||
if (schId) it.baseId = resolveUrl(it.opts.uriResolver, it.baseId, schId)
|
||||
}
|
||||
|
||||
function checkAsyncSchema(it: SchemaObjCxt): void {
|
||||
if (it.schema.$async && !it.schemaEnv.$async) throw new Error("async schema in sync schema")
|
||||
}
|
||||
|
||||
function commentKeyword({gen, schemaEnv, schema, errSchemaPath, opts}: SchemaObjCxt): void {
|
||||
const msg = schema.$comment
|
||||
if (opts.$comment === true) {
|
||||
gen.code(_`${N.self}.logger.log(${msg})`)
|
||||
} else if (typeof opts.$comment == "function") {
|
||||
const schemaPath = str`${errSchemaPath}/$comment`
|
||||
const rootName = gen.scopeValue("root", {ref: schemaEnv.root})
|
||||
gen.code(_`${N.self}.opts.$comment(${msg}, ${schemaPath}, ${rootName}.schema)`)
|
||||
}
|
||||
}
|
||||
|
||||
function returnResults(it: SchemaCxt): void {
|
||||
const {gen, schemaEnv, validateName, ValidationError, opts} = it
|
||||
if (schemaEnv.$async) {
|
||||
// TODO assign unevaluated
|
||||
gen.if(
|
||||
_`${N.errors} === 0`,
|
||||
() => gen.return(N.data),
|
||||
() => gen.throw(_`new ${ValidationError as Name}(${N.vErrors})`)
|
||||
)
|
||||
} else {
|
||||
gen.assign(_`${validateName}.errors`, N.vErrors)
|
||||
if (opts.unevaluated) assignEvaluated(it)
|
||||
gen.return(_`${N.errors} === 0`)
|
||||
}
|
||||
}
|
||||
|
||||
function assignEvaluated({gen, evaluated, props, items}: SchemaCxt): void {
|
||||
if (props instanceof Name) gen.assign(_`${evaluated}.props`, props)
|
||||
if (items instanceof Name) gen.assign(_`${evaluated}.items`, items)
|
||||
}
|
||||
|
||||
function schemaKeywords(
|
||||
it: SchemaObjCxt,
|
||||
types: JSONType[],
|
||||
typeErrors: boolean,
|
||||
errsCount?: Name
|
||||
): void {
|
||||
const {gen, schema, data, allErrors, opts, self} = it
|
||||
const {RULES} = self
|
||||
if (schema.$ref && (opts.ignoreKeywordsWithRef || !schemaHasRulesButRef(schema, RULES))) {
|
||||
gen.block(() => keywordCode(it, "$ref", (RULES.all.$ref as Rule).definition)) // TODO typecast
|
||||
return
|
||||
}
|
||||
if (!opts.jtd) checkStrictTypes(it, types)
|
||||
gen.block(() => {
|
||||
for (const group of RULES.rules) groupKeywords(group)
|
||||
groupKeywords(RULES.post)
|
||||
})
|
||||
|
||||
function groupKeywords(group: RuleGroup): void {
|
||||
if (!shouldUseGroup(schema, group)) return
|
||||
if (group.type) {
|
||||
gen.if(checkDataType(group.type, data, opts.strictNumbers))
|
||||
iterateKeywords(it, group)
|
||||
if (types.length === 1 && types[0] === group.type && typeErrors) {
|
||||
gen.else()
|
||||
reportTypeError(it)
|
||||
}
|
||||
gen.endIf()
|
||||
} else {
|
||||
iterateKeywords(it, group)
|
||||
}
|
||||
// TODO make it "ok" call?
|
||||
if (!allErrors) gen.if(_`${N.errors} === ${errsCount || 0}`)
|
||||
}
|
||||
}
|
||||
|
||||
function iterateKeywords(it: SchemaObjCxt, group: RuleGroup): void {
|
||||
const {
|
||||
gen,
|
||||
schema,
|
||||
opts: {useDefaults},
|
||||
} = it
|
||||
if (useDefaults) assignDefaults(it, group.type)
|
||||
gen.block(() => {
|
||||
for (const rule of group.rules) {
|
||||
if (shouldUseRule(schema, rule)) {
|
||||
keywordCode(it, rule.keyword, rule.definition, group.type)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function checkStrictTypes(it: SchemaObjCxt, types: JSONType[]): void {
|
||||
if (it.schemaEnv.meta || !it.opts.strictTypes) return
|
||||
checkContextTypes(it, types)
|
||||
if (!it.opts.allowUnionTypes) checkMultipleTypes(it, types)
|
||||
checkKeywordTypes(it, it.dataTypes)
|
||||
}
|
||||
|
||||
function checkContextTypes(it: SchemaObjCxt, types: JSONType[]): void {
|
||||
if (!types.length) return
|
||||
if (!it.dataTypes.length) {
|
||||
it.dataTypes = types
|
||||
return
|
||||
}
|
||||
types.forEach((t) => {
|
||||
if (!includesType(it.dataTypes, t)) {
|
||||
strictTypesError(it, `type "${t}" not allowed by context "${it.dataTypes.join(",")}"`)
|
||||
}
|
||||
})
|
||||
narrowSchemaTypes(it, types)
|
||||
}
|
||||
|
||||
function checkMultipleTypes(it: SchemaObjCxt, ts: JSONType[]): void {
|
||||
if (ts.length > 1 && !(ts.length === 2 && ts.includes("null"))) {
|
||||
strictTypesError(it, "use allowUnionTypes to allow union type keyword")
|
||||
}
|
||||
}
|
||||
|
||||
function checkKeywordTypes(it: SchemaObjCxt, ts: JSONType[]): void {
|
||||
const rules = it.self.RULES.all
|
||||
for (const keyword in rules) {
|
||||
const rule = rules[keyword]
|
||||
if (typeof rule == "object" && shouldUseRule(it.schema, rule)) {
|
||||
const {type} = rule.definition
|
||||
if (type.length && !type.some((t) => hasApplicableType(ts, t))) {
|
||||
strictTypesError(it, `missing type "${type.join(",")}" for keyword "${keyword}"`)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function hasApplicableType(schTs: JSONType[], kwdT: JSONType): boolean {
|
||||
return schTs.includes(kwdT) || (kwdT === "number" && schTs.includes("integer"))
|
||||
}
|
||||
|
||||
function includesType(ts: JSONType[], t: JSONType): boolean {
|
||||
return ts.includes(t) || (t === "integer" && ts.includes("number"))
|
||||
}
|
||||
|
||||
function narrowSchemaTypes(it: SchemaObjCxt, withTypes: JSONType[]): void {
|
||||
const ts: JSONType[] = []
|
||||
for (const t of it.dataTypes) {
|
||||
if (includesType(withTypes, t)) ts.push(t)
|
||||
else if (withTypes.includes("integer") && t === "number") ts.push("integer")
|
||||
}
|
||||
it.dataTypes = ts
|
||||
}
|
||||
|
||||
function strictTypesError(it: SchemaObjCxt, msg: string): void {
|
||||
const schemaPath = it.schemaEnv.baseId + it.errSchemaPath
|
||||
msg += ` at "${schemaPath}" (strictTypes)`
|
||||
checkStrictMode(it, msg, it.opts.strictTypes)
|
||||
}
|
||||
|
||||
export class KeywordCxt implements KeywordErrorCxt {
|
||||
readonly gen: CodeGen
|
||||
readonly allErrors?: boolean
|
||||
readonly keyword: string
|
||||
readonly data: Name // Name referencing the current level of the data instance
|
||||
readonly $data?: string | false
|
||||
schema: any // keyword value in the schema
|
||||
readonly schemaValue: Code | number | boolean // Code reference to keyword schema value or primitive value
|
||||
readonly schemaCode: Code | number | boolean // Code reference to resolved schema value (different if schema is $data)
|
||||
readonly schemaType: JSONType[] // allowed type(s) of keyword value in the schema
|
||||
readonly parentSchema: AnySchemaObject
|
||||
readonly errsCount?: Name // Name reference to the number of validation errors collected before this keyword,
|
||||
// requires option trackErrors in keyword definition
|
||||
params: KeywordCxtParams // object to pass parameters to error messages from keyword code
|
||||
readonly it: SchemaObjCxt // schema compilation context (schema is guaranteed to be an object, not boolean)
|
||||
readonly def: AddedKeywordDefinition
|
||||
|
||||
constructor(it: SchemaObjCxt, def: AddedKeywordDefinition, keyword: string) {
|
||||
validateKeywordUsage(it, def, keyword)
|
||||
this.gen = it.gen
|
||||
this.allErrors = it.allErrors
|
||||
this.keyword = keyword
|
||||
this.data = it.data
|
||||
this.schema = it.schema[keyword]
|
||||
this.$data = def.$data && it.opts.$data && this.schema && this.schema.$data
|
||||
this.schemaValue = schemaRefOrVal(it, this.schema, keyword, this.$data)
|
||||
this.schemaType = def.schemaType
|
||||
this.parentSchema = it.schema
|
||||
this.params = {}
|
||||
this.it = it
|
||||
this.def = def
|
||||
|
||||
if (this.$data) {
|
||||
this.schemaCode = it.gen.const("vSchema", getData(this.$data, it))
|
||||
} else {
|
||||
this.schemaCode = this.schemaValue
|
||||
if (!validSchemaType(this.schema, def.schemaType, def.allowUndefined)) {
|
||||
throw new Error(`${keyword} value must be ${JSON.stringify(def.schemaType)}`)
|
||||
}
|
||||
}
|
||||
|
||||
if ("code" in def ? def.trackErrors : def.errors !== false) {
|
||||
this.errsCount = it.gen.const("_errs", N.errors)
|
||||
}
|
||||
}
|
||||
|
||||
result(condition: Code, successAction?: () => void, failAction?: () => void): void {
|
||||
this.failResult(not(condition), successAction, failAction)
|
||||
}
|
||||
|
||||
failResult(condition: Code, successAction?: () => void, failAction?: () => void): void {
|
||||
this.gen.if(condition)
|
||||
if (failAction) failAction()
|
||||
else this.error()
|
||||
if (successAction) {
|
||||
this.gen.else()
|
||||
successAction()
|
||||
if (this.allErrors) this.gen.endIf()
|
||||
} else {
|
||||
if (this.allErrors) this.gen.endIf()
|
||||
else this.gen.else()
|
||||
}
|
||||
}
|
||||
|
||||
pass(condition: Code, failAction?: () => void): void {
|
||||
this.failResult(not(condition), undefined, failAction)
|
||||
}
|
||||
|
||||
fail(condition?: Code): void {
|
||||
if (condition === undefined) {
|
||||
this.error()
|
||||
if (!this.allErrors) this.gen.if(false) // this branch will be removed by gen.optimize
|
||||
return
|
||||
}
|
||||
this.gen.if(condition)
|
||||
this.error()
|
||||
if (this.allErrors) this.gen.endIf()
|
||||
else this.gen.else()
|
||||
}
|
||||
|
||||
fail$data(condition: Code): void {
|
||||
if (!this.$data) return this.fail(condition)
|
||||
const {schemaCode} = this
|
||||
this.fail(_`${schemaCode} !== undefined && (${or(this.invalid$data(), condition)})`)
|
||||
}
|
||||
|
||||
error(append?: boolean, errorParams?: KeywordCxtParams, errorPaths?: ErrorPaths): void {
|
||||
if (errorParams) {
|
||||
this.setParams(errorParams)
|
||||
this._error(append, errorPaths)
|
||||
this.setParams({})
|
||||
return
|
||||
}
|
||||
this._error(append, errorPaths)
|
||||
}
|
||||
|
||||
private _error(append?: boolean, errorPaths?: ErrorPaths): void {
|
||||
;(append ? reportExtraError : reportError)(this, this.def.error, errorPaths)
|
||||
}
|
||||
|
||||
$dataError(): void {
|
||||
reportError(this, this.def.$dataError || keyword$DataError)
|
||||
}
|
||||
|
||||
reset(): void {
|
||||
if (this.errsCount === undefined) throw new Error('add "trackErrors" to keyword definition')
|
||||
resetErrorsCount(this.gen, this.errsCount)
|
||||
}
|
||||
|
||||
ok(cond: Code | boolean): void {
|
||||
if (!this.allErrors) this.gen.if(cond)
|
||||
}
|
||||
|
||||
setParams(obj: KeywordCxtParams, assign?: true): void {
|
||||
if (assign) Object.assign(this.params, obj)
|
||||
else this.params = obj
|
||||
}
|
||||
|
||||
block$data(valid: Name, codeBlock: () => void, $dataValid: Code = nil): void {
|
||||
this.gen.block(() => {
|
||||
this.check$data(valid, $dataValid)
|
||||
codeBlock()
|
||||
})
|
||||
}
|
||||
|
||||
check$data(valid: Name = nil, $dataValid: Code = nil): void {
|
||||
if (!this.$data) return
|
||||
const {gen, schemaCode, schemaType, def} = this
|
||||
gen.if(or(_`${schemaCode} === undefined`, $dataValid))
|
||||
if (valid !== nil) gen.assign(valid, true)
|
||||
if (schemaType.length || def.validateSchema) {
|
||||
gen.elseIf(this.invalid$data())
|
||||
this.$dataError()
|
||||
if (valid !== nil) gen.assign(valid, false)
|
||||
}
|
||||
gen.else()
|
||||
}
|
||||
|
||||
invalid$data(): Code {
|
||||
const {gen, schemaCode, schemaType, def, it} = this
|
||||
return or(wrong$DataType(), invalid$DataSchema())
|
||||
|
||||
function wrong$DataType(): Code {
|
||||
if (schemaType.length) {
|
||||
/* istanbul ignore if */
|
||||
if (!(schemaCode instanceof Name)) throw new Error("ajv implementation error")
|
||||
const st = Array.isArray(schemaType) ? schemaType : [schemaType]
|
||||
return _`${checkDataTypes(st, schemaCode, it.opts.strictNumbers, DataType.Wrong)}`
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
function invalid$DataSchema(): Code {
|
||||
if (def.validateSchema) {
|
||||
const validateSchemaRef = gen.scopeValue("validate$data", {ref: def.validateSchema}) // TODO value.code for standalone
|
||||
return _`!${validateSchemaRef}(${schemaCode})`
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
subschema(appl: SubschemaArgs, valid: Name): SchemaCxt {
|
||||
const subschema = getSubschema(this.it, appl)
|
||||
extendSubschemaData(subschema, this.it, appl)
|
||||
extendSubschemaMode(subschema, appl)
|
||||
const nextContext = {...this.it, ...subschema, items: undefined, props: undefined}
|
||||
subschemaCode(nextContext, valid)
|
||||
return nextContext
|
||||
}
|
||||
|
||||
mergeEvaluated(schemaCxt: SchemaCxt, toName?: typeof Name): void {
|
||||
const {it, gen} = this
|
||||
if (!it.opts.unevaluated) return
|
||||
if (it.props !== true && schemaCxt.props !== undefined) {
|
||||
it.props = mergeEvaluated.props(gen, schemaCxt.props, it.props, toName)
|
||||
}
|
||||
if (it.items !== true && schemaCxt.items !== undefined) {
|
||||
it.items = mergeEvaluated.items(gen, schemaCxt.items, it.items, toName)
|
||||
}
|
||||
}
|
||||
|
||||
mergeValidEvaluated(schemaCxt: SchemaCxt, valid: Name): boolean | void {
|
||||
const {it, gen} = this
|
||||
if (it.opts.unevaluated && (it.props !== true || it.items !== true)) {
|
||||
gen.if(valid, () => this.mergeEvaluated(schemaCxt, Name))
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function keywordCode(
|
||||
it: SchemaObjCxt,
|
||||
keyword: string,
|
||||
def: AddedKeywordDefinition,
|
||||
ruleType?: JSONType
|
||||
): void {
|
||||
const cxt = new KeywordCxt(it, def, keyword)
|
||||
if ("code" in def) {
|
||||
def.code(cxt, ruleType)
|
||||
} else if (cxt.$data && def.validate) {
|
||||
funcKeywordCode(cxt, def)
|
||||
} else if ("macro" in def) {
|
||||
macroKeywordCode(cxt, def)
|
||||
} else if (def.compile || def.validate) {
|
||||
funcKeywordCode(cxt, def)
|
||||
}
|
||||
}
|
||||
|
||||
const JSON_POINTER = /^\/(?:[^~]|~0|~1)*$/
|
||||
const RELATIVE_JSON_POINTER = /^([0-9]+)(#|\/(?:[^~]|~0|~1)*)?$/
|
||||
export function getData(
|
||||
$data: string,
|
||||
{dataLevel, dataNames, dataPathArr}: SchemaCxt
|
||||
): Code | number {
|
||||
let jsonPointer
|
||||
let data: Code
|
||||
if ($data === "") return N.rootData
|
||||
if ($data[0] === "/") {
|
||||
if (!JSON_POINTER.test($data)) throw new Error(`Invalid JSON-pointer: ${$data}`)
|
||||
jsonPointer = $data
|
||||
data = N.rootData
|
||||
} else {
|
||||
const matches = RELATIVE_JSON_POINTER.exec($data)
|
||||
if (!matches) throw new Error(`Invalid JSON-pointer: ${$data}`)
|
||||
const up: number = +matches[1]
|
||||
jsonPointer = matches[2]
|
||||
if (jsonPointer === "#") {
|
||||
if (up >= dataLevel) throw new Error(errorMsg("property/index", up))
|
||||
return dataPathArr[dataLevel - up]
|
||||
}
|
||||
if (up > dataLevel) throw new Error(errorMsg("data", up))
|
||||
data = dataNames[dataLevel - up]
|
||||
if (!jsonPointer) return data
|
||||
}
|
||||
|
||||
let expr = data
|
||||
const segments = jsonPointer.split("/")
|
||||
for (const segment of segments) {
|
||||
if (segment) {
|
||||
data = _`${data}${getProperty(unescapeJsonPointer(segment))}`
|
||||
expr = _`${expr} && ${data}`
|
||||
}
|
||||
}
|
||||
return expr
|
||||
|
||||
function errorMsg(pointerType: string, up: number): string {
|
||||
return `Cannot access ${pointerType} ${up} levels up, current level is ${dataLevel}`
|
||||
}
|
||||
}
|
171
node_modules/schema-utils/node_modules/ajv/lib/compile/validate/keyword.ts
generated
vendored
Normal file
171
node_modules/schema-utils/node_modules/ajv/lib/compile/validate/keyword.ts
generated
vendored
Normal file
@@ -0,0 +1,171 @@
|
||||
import type {KeywordCxt} from "."
|
||||
import type {
|
||||
AnySchema,
|
||||
SchemaValidateFunction,
|
||||
AnyValidateFunction,
|
||||
AddedKeywordDefinition,
|
||||
MacroKeywordDefinition,
|
||||
FuncKeywordDefinition,
|
||||
} from "../../types"
|
||||
import type {SchemaObjCxt} from ".."
|
||||
import {_, nil, not, stringify, Code, Name, CodeGen} from "../codegen"
|
||||
import N from "../names"
|
||||
import type {JSONType} from "../rules"
|
||||
import {callValidateCode} from "../../vocabularies/code"
|
||||
import {extendErrors} from "../errors"
|
||||
|
||||
type KeywordCompilationResult = AnySchema | SchemaValidateFunction | AnyValidateFunction
|
||||
|
||||
export function macroKeywordCode(cxt: KeywordCxt, def: MacroKeywordDefinition): void {
|
||||
const {gen, keyword, schema, parentSchema, it} = cxt
|
||||
const macroSchema = def.macro.call(it.self, schema, parentSchema, it)
|
||||
const schemaRef = useKeyword(gen, keyword, macroSchema)
|
||||
if (it.opts.validateSchema !== false) it.self.validateSchema(macroSchema, true)
|
||||
|
||||
const valid = gen.name("valid")
|
||||
cxt.subschema(
|
||||
{
|
||||
schema: macroSchema,
|
||||
schemaPath: nil,
|
||||
errSchemaPath: `${it.errSchemaPath}/${keyword}`,
|
||||
topSchemaRef: schemaRef,
|
||||
compositeRule: true,
|
||||
},
|
||||
valid
|
||||
)
|
||||
cxt.pass(valid, () => cxt.error(true))
|
||||
}
|
||||
|
||||
export function funcKeywordCode(cxt: KeywordCxt, def: FuncKeywordDefinition): void {
|
||||
const {gen, keyword, schema, parentSchema, $data, it} = cxt
|
||||
checkAsyncKeyword(it, def)
|
||||
const validate =
|
||||
!$data && def.compile ? def.compile.call(it.self, schema, parentSchema, it) : def.validate
|
||||
const validateRef = useKeyword(gen, keyword, validate)
|
||||
const valid = gen.let("valid")
|
||||
cxt.block$data(valid, validateKeyword)
|
||||
cxt.ok(def.valid ?? valid)
|
||||
|
||||
function validateKeyword(): void {
|
||||
if (def.errors === false) {
|
||||
assignValid()
|
||||
if (def.modifying) modifyData(cxt)
|
||||
reportErrs(() => cxt.error())
|
||||
} else {
|
||||
const ruleErrs = def.async ? validateAsync() : validateSync()
|
||||
if (def.modifying) modifyData(cxt)
|
||||
reportErrs(() => addErrs(cxt, ruleErrs))
|
||||
}
|
||||
}
|
||||
|
||||
function validateAsync(): Name {
|
||||
const ruleErrs = gen.let("ruleErrs", null)
|
||||
gen.try(
|
||||
() => assignValid(_`await `),
|
||||
(e) =>
|
||||
gen.assign(valid, false).if(
|
||||
_`${e} instanceof ${it.ValidationError as Name}`,
|
||||
() => gen.assign(ruleErrs, _`${e}.errors`),
|
||||
() => gen.throw(e)
|
||||
)
|
||||
)
|
||||
return ruleErrs
|
||||
}
|
||||
|
||||
function validateSync(): Code {
|
||||
const validateErrs = _`${validateRef}.errors`
|
||||
gen.assign(validateErrs, null)
|
||||
assignValid(nil)
|
||||
return validateErrs
|
||||
}
|
||||
|
||||
function assignValid(_await: Code = def.async ? _`await ` : nil): void {
|
||||
const passCxt = it.opts.passContext ? N.this : N.self
|
||||
const passSchema = !(("compile" in def && !$data) || def.schema === false)
|
||||
gen.assign(
|
||||
valid,
|
||||
_`${_await}${callValidateCode(cxt, validateRef, passCxt, passSchema)}`,
|
||||
def.modifying
|
||||
)
|
||||
}
|
||||
|
||||
function reportErrs(errors: () => void): void {
|
||||
gen.if(not(def.valid ?? valid), errors)
|
||||
}
|
||||
}
|
||||
|
||||
function modifyData(cxt: KeywordCxt): void {
|
||||
const {gen, data, it} = cxt
|
||||
gen.if(it.parentData, () => gen.assign(data, _`${it.parentData}[${it.parentDataProperty}]`))
|
||||
}
|
||||
|
||||
function addErrs(cxt: KeywordCxt, errs: Code): void {
|
||||
const {gen} = cxt
|
||||
gen.if(
|
||||
_`Array.isArray(${errs})`,
|
||||
() => {
|
||||
gen
|
||||
.assign(N.vErrors, _`${N.vErrors} === null ? ${errs} : ${N.vErrors}.concat(${errs})`)
|
||||
.assign(N.errors, _`${N.vErrors}.length`)
|
||||
extendErrors(cxt)
|
||||
},
|
||||
() => cxt.error()
|
||||
)
|
||||
}
|
||||
|
||||
function checkAsyncKeyword({schemaEnv}: SchemaObjCxt, def: FuncKeywordDefinition): void {
|
||||
if (def.async && !schemaEnv.$async) throw new Error("async keyword in sync schema")
|
||||
}
|
||||
|
||||
function useKeyword(gen: CodeGen, keyword: string, result?: KeywordCompilationResult): Name {
|
||||
if (result === undefined) throw new Error(`keyword "${keyword}" failed to compile`)
|
||||
return gen.scopeValue(
|
||||
"keyword",
|
||||
typeof result == "function" ? {ref: result} : {ref: result, code: stringify(result)}
|
||||
)
|
||||
}
|
||||
|
||||
export function validSchemaType(
|
||||
schema: unknown,
|
||||
schemaType: JSONType[],
|
||||
allowUndefined = false
|
||||
): boolean {
|
||||
// TODO add tests
|
||||
return (
|
||||
!schemaType.length ||
|
||||
schemaType.some((st) =>
|
||||
st === "array"
|
||||
? Array.isArray(schema)
|
||||
: st === "object"
|
||||
? schema && typeof schema == "object" && !Array.isArray(schema)
|
||||
: typeof schema == st || (allowUndefined && typeof schema == "undefined")
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
export function validateKeywordUsage(
|
||||
{schema, opts, self, errSchemaPath}: SchemaObjCxt,
|
||||
def: AddedKeywordDefinition,
|
||||
keyword: string
|
||||
): void {
|
||||
/* istanbul ignore if */
|
||||
if (Array.isArray(def.keyword) ? !def.keyword.includes(keyword) : def.keyword !== keyword) {
|
||||
throw new Error("ajv implementation error")
|
||||
}
|
||||
|
||||
const deps = def.dependencies
|
||||
if (deps?.some((kwd) => !Object.prototype.hasOwnProperty.call(schema, kwd))) {
|
||||
throw new Error(`parent schema must have dependencies of ${keyword}: ${deps.join(",")}`)
|
||||
}
|
||||
|
||||
if (def.validateSchema) {
|
||||
const valid = def.validateSchema(schema[keyword])
|
||||
if (!valid) {
|
||||
const msg =
|
||||
`keyword "${keyword}" value is invalid at path "${errSchemaPath}": ` +
|
||||
self.errorsText(def.validateSchema.errors)
|
||||
if (opts.validateSchema === "log") self.logger.error(msg)
|
||||
else throw new Error(msg)
|
||||
}
|
||||
}
|
||||
}
|
135
node_modules/schema-utils/node_modules/ajv/lib/compile/validate/subschema.ts
generated
vendored
Normal file
135
node_modules/schema-utils/node_modules/ajv/lib/compile/validate/subschema.ts
generated
vendored
Normal file
@@ -0,0 +1,135 @@
|
||||
import type {AnySchema} from "../../types"
|
||||
import type {SchemaObjCxt} from ".."
|
||||
import {_, str, getProperty, Code, Name} from "../codegen"
|
||||
import {escapeFragment, getErrorPath, Type} from "../util"
|
||||
import type {JSONType} from "../rules"
|
||||
|
||||
export interface SubschemaContext {
|
||||
// TODO use Optional? align with SchemCxt property types
|
||||
schema: AnySchema
|
||||
schemaPath: Code
|
||||
errSchemaPath: string
|
||||
topSchemaRef?: Code
|
||||
errorPath?: Code
|
||||
dataLevel?: number
|
||||
dataTypes?: JSONType[]
|
||||
data?: Name
|
||||
parentData?: Name
|
||||
parentDataProperty?: Code | number
|
||||
dataNames?: Name[]
|
||||
dataPathArr?: (Code | number)[]
|
||||
propertyName?: Name
|
||||
jtdDiscriminator?: string
|
||||
jtdMetadata?: boolean
|
||||
compositeRule?: true
|
||||
createErrors?: boolean
|
||||
allErrors?: boolean
|
||||
}
|
||||
|
||||
export type SubschemaArgs = Partial<{
|
||||
keyword: string
|
||||
schemaProp: string | number
|
||||
schema: AnySchema
|
||||
schemaPath: Code
|
||||
errSchemaPath: string
|
||||
topSchemaRef: Code
|
||||
data: Name | Code
|
||||
dataProp: Code | string | number
|
||||
dataTypes: JSONType[]
|
||||
definedProperties: Set<string>
|
||||
propertyName: Name
|
||||
dataPropType: Type
|
||||
jtdDiscriminator: string
|
||||
jtdMetadata: boolean
|
||||
compositeRule: true
|
||||
createErrors: boolean
|
||||
allErrors: boolean
|
||||
}>
|
||||
|
||||
export function getSubschema(
|
||||
it: SchemaObjCxt,
|
||||
{keyword, schemaProp, schema, schemaPath, errSchemaPath, topSchemaRef}: SubschemaArgs
|
||||
): SubschemaContext {
|
||||
if (keyword !== undefined && schema !== undefined) {
|
||||
throw new Error('both "keyword" and "schema" passed, only one allowed')
|
||||
}
|
||||
|
||||
if (keyword !== undefined) {
|
||||
const sch = it.schema[keyword]
|
||||
return schemaProp === undefined
|
||||
? {
|
||||
schema: sch,
|
||||
schemaPath: _`${it.schemaPath}${getProperty(keyword)}`,
|
||||
errSchemaPath: `${it.errSchemaPath}/${keyword}`,
|
||||
}
|
||||
: {
|
||||
schema: sch[schemaProp],
|
||||
schemaPath: _`${it.schemaPath}${getProperty(keyword)}${getProperty(schemaProp)}`,
|
||||
errSchemaPath: `${it.errSchemaPath}/${keyword}/${escapeFragment(schemaProp)}`,
|
||||
}
|
||||
}
|
||||
|
||||
if (schema !== undefined) {
|
||||
if (schemaPath === undefined || errSchemaPath === undefined || topSchemaRef === undefined) {
|
||||
throw new Error('"schemaPath", "errSchemaPath" and "topSchemaRef" are required with "schema"')
|
||||
}
|
||||
return {
|
||||
schema,
|
||||
schemaPath,
|
||||
topSchemaRef,
|
||||
errSchemaPath,
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error('either "keyword" or "schema" must be passed')
|
||||
}
|
||||
|
||||
export function extendSubschemaData(
|
||||
subschema: SubschemaContext,
|
||||
it: SchemaObjCxt,
|
||||
{dataProp, dataPropType: dpType, data, dataTypes, propertyName}: SubschemaArgs
|
||||
): void {
|
||||
if (data !== undefined && dataProp !== undefined) {
|
||||
throw new Error('both "data" and "dataProp" passed, only one allowed')
|
||||
}
|
||||
|
||||
const {gen} = it
|
||||
|
||||
if (dataProp !== undefined) {
|
||||
const {errorPath, dataPathArr, opts} = it
|
||||
const nextData = gen.let("data", _`${it.data}${getProperty(dataProp)}`, true)
|
||||
dataContextProps(nextData)
|
||||
subschema.errorPath = str`${errorPath}${getErrorPath(dataProp, dpType, opts.jsPropertySyntax)}`
|
||||
subschema.parentDataProperty = _`${dataProp}`
|
||||
subschema.dataPathArr = [...dataPathArr, subschema.parentDataProperty]
|
||||
}
|
||||
|
||||
if (data !== undefined) {
|
||||
const nextData = data instanceof Name ? data : gen.let("data", data, true) // replaceable if used once?
|
||||
dataContextProps(nextData)
|
||||
if (propertyName !== undefined) subschema.propertyName = propertyName
|
||||
// TODO something is possibly wrong here with not changing parentDataProperty and not appending dataPathArr
|
||||
}
|
||||
|
||||
if (dataTypes) subschema.dataTypes = dataTypes
|
||||
|
||||
function dataContextProps(_nextData: Name): void {
|
||||
subschema.data = _nextData
|
||||
subschema.dataLevel = it.dataLevel + 1
|
||||
subschema.dataTypes = []
|
||||
it.definedProperties = new Set<string>()
|
||||
subschema.parentData = it.data
|
||||
subschema.dataNames = [...it.dataNames, _nextData]
|
||||
}
|
||||
}
|
||||
|
||||
export function extendSubschemaMode(
|
||||
subschema: SubschemaContext,
|
||||
{jtdDiscriminator, jtdMetadata, compositeRule, createErrors, allErrors}: SubschemaArgs
|
||||
): void {
|
||||
if (compositeRule !== undefined) subschema.compositeRule = compositeRule
|
||||
if (createErrors !== undefined) subschema.createErrors = createErrors
|
||||
if (allErrors !== undefined) subschema.allErrors = allErrors
|
||||
subschema.jtdDiscriminator = jtdDiscriminator // not inherited
|
||||
subschema.jtdMetadata = jtdMetadata // not inherited
|
||||
}
|
891
node_modules/schema-utils/node_modules/ajv/lib/core.ts
generated
vendored
Normal file
891
node_modules/schema-utils/node_modules/ajv/lib/core.ts
generated
vendored
Normal file
@@ -0,0 +1,891 @@
|
||||
export {
|
||||
Format,
|
||||
FormatDefinition,
|
||||
AsyncFormatDefinition,
|
||||
KeywordDefinition,
|
||||
KeywordErrorDefinition,
|
||||
CodeKeywordDefinition,
|
||||
MacroKeywordDefinition,
|
||||
FuncKeywordDefinition,
|
||||
Vocabulary,
|
||||
Schema,
|
||||
SchemaObject,
|
||||
AnySchemaObject,
|
||||
AsyncSchema,
|
||||
AnySchema,
|
||||
ValidateFunction,
|
||||
AsyncValidateFunction,
|
||||
AnyValidateFunction,
|
||||
ErrorObject,
|
||||
ErrorNoParams,
|
||||
} from "./types"
|
||||
|
||||
export {SchemaCxt, SchemaObjCxt} from "./compile"
|
||||
export interface Plugin<Opts> {
|
||||
(ajv: Ajv, options?: Opts): Ajv
|
||||
[prop: string]: any
|
||||
}
|
||||
|
||||
export {KeywordCxt} from "./compile/validate"
|
||||
export {DefinedError} from "./vocabularies/errors"
|
||||
export {JSONType} from "./compile/rules"
|
||||
export {JSONSchemaType} from "./types/json-schema"
|
||||
export {JTDSchemaType, SomeJTDSchemaType, JTDDataType} from "./types/jtd-schema"
|
||||
export {_, str, stringify, nil, Name, Code, CodeGen, CodeGenOptions} from "./compile/codegen"
|
||||
|
||||
import type {
|
||||
Schema,
|
||||
AnySchema,
|
||||
AnySchemaObject,
|
||||
SchemaObject,
|
||||
AsyncSchema,
|
||||
Vocabulary,
|
||||
KeywordDefinition,
|
||||
AddedKeywordDefinition,
|
||||
AnyValidateFunction,
|
||||
ValidateFunction,
|
||||
AsyncValidateFunction,
|
||||
ErrorObject,
|
||||
Format,
|
||||
AddedFormat,
|
||||
RegExpEngine,
|
||||
UriResolver,
|
||||
} from "./types"
|
||||
import type {JSONSchemaType} from "./types/json-schema"
|
||||
import type {JTDSchemaType, SomeJTDSchemaType, JTDDataType} from "./types/jtd-schema"
|
||||
import ValidationError from "./runtime/validation_error"
|
||||
import MissingRefError from "./compile/ref_error"
|
||||
import {getRules, ValidationRules, Rule, RuleGroup, JSONType} from "./compile/rules"
|
||||
import {SchemaEnv, compileSchema, resolveSchema} from "./compile"
|
||||
import {Code, ValueScope} from "./compile/codegen"
|
||||
import {normalizeId, getSchemaRefs} from "./compile/resolve"
|
||||
import {getJSONTypes} from "./compile/validate/dataType"
|
||||
import {eachItem} from "./compile/util"
|
||||
import * as $dataRefSchema from "./refs/data.json"
|
||||
|
||||
import DefaultUriResolver from "./runtime/uri"
|
||||
|
||||
const defaultRegExp: RegExpEngine = (str, flags) => new RegExp(str, flags)
|
||||
defaultRegExp.code = "new RegExp"
|
||||
|
||||
const META_IGNORE_OPTIONS: (keyof Options)[] = ["removeAdditional", "useDefaults", "coerceTypes"]
|
||||
const EXT_SCOPE_NAMES = new Set([
|
||||
"validate",
|
||||
"serialize",
|
||||
"parse",
|
||||
"wrapper",
|
||||
"root",
|
||||
"schema",
|
||||
"keyword",
|
||||
"pattern",
|
||||
"formats",
|
||||
"validate$data",
|
||||
"func",
|
||||
"obj",
|
||||
"Error",
|
||||
])
|
||||
|
||||
export type Options = CurrentOptions & DeprecatedOptions
|
||||
|
||||
export interface CurrentOptions {
|
||||
// strict mode options (NEW)
|
||||
strict?: boolean | "log"
|
||||
strictSchema?: boolean | "log"
|
||||
strictNumbers?: boolean | "log"
|
||||
strictTypes?: boolean | "log"
|
||||
strictTuples?: boolean | "log"
|
||||
strictRequired?: boolean | "log"
|
||||
allowMatchingProperties?: boolean // disables a strict mode restriction
|
||||
allowUnionTypes?: boolean
|
||||
validateFormats?: boolean
|
||||
// validation and reporting options:
|
||||
$data?: boolean
|
||||
allErrors?: boolean
|
||||
verbose?: boolean
|
||||
discriminator?: boolean
|
||||
unicodeRegExp?: boolean
|
||||
timestamp?: "string" | "date" // JTD only
|
||||
parseDate?: boolean // JTD only
|
||||
allowDate?: boolean // JTD only
|
||||
$comment?:
|
||||
| true
|
||||
| ((comment: string, schemaPath?: string, rootSchema?: AnySchemaObject) => unknown)
|
||||
formats?: {[Name in string]?: Format}
|
||||
keywords?: Vocabulary
|
||||
schemas?: AnySchema[] | {[Key in string]?: AnySchema}
|
||||
logger?: Logger | false
|
||||
loadSchema?: (uri: string) => Promise<AnySchemaObject>
|
||||
// options to modify validated data:
|
||||
removeAdditional?: boolean | "all" | "failing"
|
||||
useDefaults?: boolean | "empty"
|
||||
coerceTypes?: boolean | "array"
|
||||
// advanced options:
|
||||
next?: boolean // NEW
|
||||
unevaluated?: boolean // NEW
|
||||
dynamicRef?: boolean // NEW
|
||||
schemaId?: "id" | "$id"
|
||||
jtd?: boolean // NEW
|
||||
meta?: SchemaObject | boolean
|
||||
defaultMeta?: string | AnySchemaObject
|
||||
validateSchema?: boolean | "log"
|
||||
addUsedSchema?: boolean
|
||||
inlineRefs?: boolean | number
|
||||
passContext?: boolean
|
||||
loopRequired?: number
|
||||
loopEnum?: number // NEW
|
||||
ownProperties?: boolean
|
||||
multipleOfPrecision?: number
|
||||
int32range?: boolean // JTD only
|
||||
messages?: boolean
|
||||
code?: CodeOptions // NEW
|
||||
uriResolver?: UriResolver
|
||||
}
|
||||
|
||||
export interface CodeOptions {
|
||||
es5?: boolean
|
||||
esm?: boolean
|
||||
lines?: boolean
|
||||
optimize?: boolean | number
|
||||
formats?: Code // code to require (or construct) map of available formats - for standalone code
|
||||
source?: boolean
|
||||
process?: (code: string, schema?: SchemaEnv) => string
|
||||
regExp?: RegExpEngine
|
||||
}
|
||||
|
||||
interface InstanceCodeOptions extends CodeOptions {
|
||||
regExp: RegExpEngine
|
||||
optimize: number
|
||||
}
|
||||
|
||||
interface DeprecatedOptions {
|
||||
/** @deprecated */
|
||||
ignoreKeywordsWithRef?: boolean
|
||||
/** @deprecated */
|
||||
jsPropertySyntax?: boolean // added instead of jsonPointers
|
||||
/** @deprecated */
|
||||
unicode?: boolean
|
||||
}
|
||||
|
||||
interface RemovedOptions {
|
||||
format?: boolean
|
||||
errorDataPath?: "object" | "property"
|
||||
nullable?: boolean // "nullable" keyword is supported by default
|
||||
jsonPointers?: boolean
|
||||
extendRefs?: true | "ignore" | "fail"
|
||||
missingRefs?: true | "ignore" | "fail"
|
||||
processCode?: (code: string, schema?: SchemaEnv) => string
|
||||
sourceCode?: boolean
|
||||
strictDefaults?: boolean
|
||||
strictKeywords?: boolean
|
||||
uniqueItems?: boolean
|
||||
unknownFormats?: true | string[] | "ignore"
|
||||
cache?: any
|
||||
serialize?: (schema: AnySchema) => unknown
|
||||
ajvErrors?: boolean
|
||||
}
|
||||
|
||||
type OptionsInfo<T extends RemovedOptions | DeprecatedOptions> = {
|
||||
[K in keyof T]-?: string | undefined
|
||||
}
|
||||
|
||||
const removedOptions: OptionsInfo<RemovedOptions> = {
|
||||
errorDataPath: "",
|
||||
format: "`validateFormats: false` can be used instead.",
|
||||
nullable: '"nullable" keyword is supported by default.',
|
||||
jsonPointers: "Deprecated jsPropertySyntax can be used instead.",
|
||||
extendRefs: "Deprecated ignoreKeywordsWithRef can be used instead.",
|
||||
missingRefs: "Pass empty schema with $id that should be ignored to ajv.addSchema.",
|
||||
processCode: "Use option `code: {process: (code, schemaEnv: object) => string}`",
|
||||
sourceCode: "Use option `code: {source: true}`",
|
||||
strictDefaults: "It is default now, see option `strict`.",
|
||||
strictKeywords: "It is default now, see option `strict`.",
|
||||
uniqueItems: '"uniqueItems" keyword is always validated.',
|
||||
unknownFormats: "Disable strict mode or pass `true` to `ajv.addFormat` (or `formats` option).",
|
||||
cache: "Map is used as cache, schema object as key.",
|
||||
serialize: "Map is used as cache, schema object as key.",
|
||||
ajvErrors: "It is default now.",
|
||||
}
|
||||
|
||||
const deprecatedOptions: OptionsInfo<DeprecatedOptions> = {
|
||||
ignoreKeywordsWithRef: "",
|
||||
jsPropertySyntax: "",
|
||||
unicode: '"minLength"/"maxLength" account for unicode characters by default.',
|
||||
}
|
||||
|
||||
type RequiredInstanceOptions = {
|
||||
[K in
|
||||
| "strictSchema"
|
||||
| "strictNumbers"
|
||||
| "strictTypes"
|
||||
| "strictTuples"
|
||||
| "strictRequired"
|
||||
| "inlineRefs"
|
||||
| "loopRequired"
|
||||
| "loopEnum"
|
||||
| "meta"
|
||||
| "messages"
|
||||
| "schemaId"
|
||||
| "addUsedSchema"
|
||||
| "validateSchema"
|
||||
| "validateFormats"
|
||||
| "int32range"
|
||||
| "unicodeRegExp"
|
||||
| "uriResolver"]: NonNullable<Options[K]>
|
||||
} & {code: InstanceCodeOptions}
|
||||
|
||||
export type InstanceOptions = Options & RequiredInstanceOptions
|
||||
|
||||
const MAX_EXPRESSION = 200
|
||||
|
||||
// eslint-disable-next-line complexity
|
||||
function requiredOptions(o: Options): RequiredInstanceOptions {
|
||||
const s = o.strict
|
||||
const _optz = o.code?.optimize
|
||||
const optimize = _optz === true || _optz === undefined ? 1 : _optz || 0
|
||||
const regExp = o.code?.regExp ?? defaultRegExp
|
||||
const uriResolver = o.uriResolver ?? DefaultUriResolver
|
||||
return {
|
||||
strictSchema: o.strictSchema ?? s ?? true,
|
||||
strictNumbers: o.strictNumbers ?? s ?? true,
|
||||
strictTypes: o.strictTypes ?? s ?? "log",
|
||||
strictTuples: o.strictTuples ?? s ?? "log",
|
||||
strictRequired: o.strictRequired ?? s ?? false,
|
||||
code: o.code ? {...o.code, optimize, regExp} : {optimize, regExp},
|
||||
loopRequired: o.loopRequired ?? MAX_EXPRESSION,
|
||||
loopEnum: o.loopEnum ?? MAX_EXPRESSION,
|
||||
meta: o.meta ?? true,
|
||||
messages: o.messages ?? true,
|
||||
inlineRefs: o.inlineRefs ?? true,
|
||||
schemaId: o.schemaId ?? "$id",
|
||||
addUsedSchema: o.addUsedSchema ?? true,
|
||||
validateSchema: o.validateSchema ?? true,
|
||||
validateFormats: o.validateFormats ?? true,
|
||||
unicodeRegExp: o.unicodeRegExp ?? true,
|
||||
int32range: o.int32range ?? true,
|
||||
uriResolver: uriResolver,
|
||||
}
|
||||
}
|
||||
|
||||
export interface Logger {
|
||||
log(...args: unknown[]): unknown
|
||||
warn(...args: unknown[]): unknown
|
||||
error(...args: unknown[]): unknown
|
||||
}
|
||||
|
||||
export default class Ajv {
|
||||
opts: InstanceOptions
|
||||
errors?: ErrorObject[] | null // errors from the last validation
|
||||
logger: Logger
|
||||
// shared external scope values for compiled functions
|
||||
readonly scope: ValueScope
|
||||
readonly schemas: {[Key in string]?: SchemaEnv} = {}
|
||||
readonly refs: {[Ref in string]?: SchemaEnv | string} = {}
|
||||
readonly formats: {[Name in string]?: AddedFormat} = {}
|
||||
readonly RULES: ValidationRules
|
||||
readonly _compilations: Set<SchemaEnv> = new Set()
|
||||
private readonly _loading: {[Ref in string]?: Promise<AnySchemaObject>} = {}
|
||||
private readonly _cache: Map<AnySchema, SchemaEnv> = new Map()
|
||||
private readonly _metaOpts: InstanceOptions
|
||||
|
||||
static ValidationError = ValidationError
|
||||
static MissingRefError = MissingRefError
|
||||
|
||||
constructor(opts: Options = {}) {
|
||||
opts = this.opts = {...opts, ...requiredOptions(opts)}
|
||||
const {es5, lines} = this.opts.code
|
||||
|
||||
this.scope = new ValueScope({scope: {}, prefixes: EXT_SCOPE_NAMES, es5, lines})
|
||||
this.logger = getLogger(opts.logger)
|
||||
const formatOpt = opts.validateFormats
|
||||
opts.validateFormats = false
|
||||
|
||||
this.RULES = getRules()
|
||||
checkOptions.call(this, removedOptions, opts, "NOT SUPPORTED")
|
||||
checkOptions.call(this, deprecatedOptions, opts, "DEPRECATED", "warn")
|
||||
this._metaOpts = getMetaSchemaOptions.call(this)
|
||||
|
||||
if (opts.formats) addInitialFormats.call(this)
|
||||
this._addVocabularies()
|
||||
this._addDefaultMetaSchema()
|
||||
if (opts.keywords) addInitialKeywords.call(this, opts.keywords)
|
||||
if (typeof opts.meta == "object") this.addMetaSchema(opts.meta)
|
||||
addInitialSchemas.call(this)
|
||||
opts.validateFormats = formatOpt
|
||||
}
|
||||
|
||||
_addVocabularies(): void {
|
||||
this.addKeyword("$async")
|
||||
}
|
||||
|
||||
_addDefaultMetaSchema(): void {
|
||||
const {$data, meta, schemaId} = this.opts
|
||||
let _dataRefSchema: SchemaObject = $dataRefSchema
|
||||
if (schemaId === "id") {
|
||||
_dataRefSchema = {...$dataRefSchema}
|
||||
_dataRefSchema.id = _dataRefSchema.$id
|
||||
delete _dataRefSchema.$id
|
||||
}
|
||||
if (meta && $data) this.addMetaSchema(_dataRefSchema, _dataRefSchema[schemaId], false)
|
||||
}
|
||||
|
||||
defaultMeta(): string | AnySchemaObject | undefined {
|
||||
const {meta, schemaId} = this.opts
|
||||
return (this.opts.defaultMeta = typeof meta == "object" ? meta[schemaId] || meta : undefined)
|
||||
}
|
||||
|
||||
// Validate data using schema
|
||||
// AnySchema will be compiled and cached using schema itself as a key for Map
|
||||
validate(schema: Schema | string, data: unknown): boolean
|
||||
validate(schemaKeyRef: AnySchema | string, data: unknown): boolean | Promise<unknown>
|
||||
validate<T>(schema: Schema | JSONSchemaType<T> | string, data: unknown): data is T
|
||||
// Separated for type inference to work
|
||||
// eslint-disable-next-line @typescript-eslint/unified-signatures
|
||||
validate<T>(schema: JTDSchemaType<T>, data: unknown): data is T
|
||||
// This overload is only intended for typescript inference, the first
|
||||
// argument prevents manual type annotation from matching this overload
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
validate<N extends never, T extends SomeJTDSchemaType>(
|
||||
schema: T,
|
||||
data: unknown
|
||||
): data is JTDDataType<T>
|
||||
// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents
|
||||
validate<T>(schema: AsyncSchema, data: unknown | T): Promise<T>
|
||||
validate<T>(schemaKeyRef: AnySchema | string, data: unknown): data is T | Promise<T>
|
||||
validate<T>(
|
||||
schemaKeyRef: AnySchema | string, // key, ref or schema object
|
||||
// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents
|
||||
data: unknown | T // to be validated
|
||||
): boolean | Promise<T> {
|
||||
let v: AnyValidateFunction | undefined
|
||||
if (typeof schemaKeyRef == "string") {
|
||||
v = this.getSchema<T>(schemaKeyRef)
|
||||
if (!v) throw new Error(`no schema with key or ref "${schemaKeyRef}"`)
|
||||
} else {
|
||||
v = this.compile<T>(schemaKeyRef)
|
||||
}
|
||||
|
||||
const valid = v(data)
|
||||
if (!("$async" in v)) this.errors = v.errors
|
||||
return valid
|
||||
}
|
||||
|
||||
// Create validation function for passed schema
|
||||
// _meta: true if schema is a meta-schema. Used internally to compile meta schemas of user-defined keywords.
|
||||
compile<T = unknown>(schema: Schema | JSONSchemaType<T>, _meta?: boolean): ValidateFunction<T>
|
||||
// Separated for type inference to work
|
||||
// eslint-disable-next-line @typescript-eslint/unified-signatures
|
||||
compile<T = unknown>(schema: JTDSchemaType<T>, _meta?: boolean): ValidateFunction<T>
|
||||
// This overload is only intended for typescript inference, the first
|
||||
// argument prevents manual type annotation from matching this overload
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
compile<N extends never, T extends SomeJTDSchemaType>(
|
||||
schema: T,
|
||||
_meta?: boolean
|
||||
): ValidateFunction<JTDDataType<T>>
|
||||
compile<T = unknown>(schema: AsyncSchema, _meta?: boolean): AsyncValidateFunction<T>
|
||||
compile<T = unknown>(schema: AnySchema, _meta?: boolean): AnyValidateFunction<T>
|
||||
compile<T = unknown>(schema: AnySchema, _meta?: boolean): AnyValidateFunction<T> {
|
||||
const sch = this._addSchema(schema, _meta)
|
||||
return (sch.validate || this._compileSchemaEnv(sch)) as AnyValidateFunction<T>
|
||||
}
|
||||
|
||||
// Creates validating function for passed schema with asynchronous loading of missing schemas.
|
||||
// `loadSchema` option should be a function that accepts schema uri and returns promise that resolves with the schema.
|
||||
// TODO allow passing schema URI
|
||||
// meta - optional true to compile meta-schema
|
||||
compileAsync<T = unknown>(
|
||||
schema: SchemaObject | JSONSchemaType<T>,
|
||||
_meta?: boolean
|
||||
): Promise<ValidateFunction<T>>
|
||||
// Separated for type inference to work
|
||||
// eslint-disable-next-line @typescript-eslint/unified-signatures
|
||||
compileAsync<T = unknown>(schema: JTDSchemaType<T>, _meta?: boolean): Promise<ValidateFunction<T>>
|
||||
compileAsync<T = unknown>(schema: AsyncSchema, meta?: boolean): Promise<AsyncValidateFunction<T>>
|
||||
// eslint-disable-next-line @typescript-eslint/unified-signatures
|
||||
compileAsync<T = unknown>(
|
||||
schema: AnySchemaObject,
|
||||
meta?: boolean
|
||||
): Promise<AnyValidateFunction<T>>
|
||||
compileAsync<T = unknown>(
|
||||
schema: AnySchemaObject,
|
||||
meta?: boolean
|
||||
): Promise<AnyValidateFunction<T>> {
|
||||
if (typeof this.opts.loadSchema != "function") {
|
||||
throw new Error("options.loadSchema should be a function")
|
||||
}
|
||||
const {loadSchema} = this.opts
|
||||
return runCompileAsync.call(this, schema, meta)
|
||||
|
||||
async function runCompileAsync(
|
||||
this: Ajv,
|
||||
_schema: AnySchemaObject,
|
||||
_meta?: boolean
|
||||
): Promise<AnyValidateFunction> {
|
||||
await loadMetaSchema.call(this, _schema.$schema)
|
||||
const sch = this._addSchema(_schema, _meta)
|
||||
return sch.validate || _compileAsync.call(this, sch)
|
||||
}
|
||||
|
||||
async function loadMetaSchema(this: Ajv, $ref?: string): Promise<void> {
|
||||
if ($ref && !this.getSchema($ref)) {
|
||||
await runCompileAsync.call(this, {$ref}, true)
|
||||
}
|
||||
}
|
||||
|
||||
async function _compileAsync(this: Ajv, sch: SchemaEnv): Promise<AnyValidateFunction> {
|
||||
try {
|
||||
return this._compileSchemaEnv(sch)
|
||||
} catch (e) {
|
||||
if (!(e instanceof MissingRefError)) throw e
|
||||
checkLoaded.call(this, e)
|
||||
await loadMissingSchema.call(this, e.missingSchema)
|
||||
return _compileAsync.call(this, sch)
|
||||
}
|
||||
}
|
||||
|
||||
function checkLoaded(this: Ajv, {missingSchema: ref, missingRef}: MissingRefError): void {
|
||||
if (this.refs[ref]) {
|
||||
throw new Error(`AnySchema ${ref} is loaded but ${missingRef} cannot be resolved`)
|
||||
}
|
||||
}
|
||||
|
||||
async function loadMissingSchema(this: Ajv, ref: string): Promise<void> {
|
||||
const _schema = await _loadSchema.call(this, ref)
|
||||
if (!this.refs[ref]) await loadMetaSchema.call(this, _schema.$schema)
|
||||
if (!this.refs[ref]) this.addSchema(_schema, ref, meta)
|
||||
}
|
||||
|
||||
async function _loadSchema(this: Ajv, ref: string): Promise<AnySchemaObject> {
|
||||
const p = this._loading[ref]
|
||||
if (p) return p
|
||||
try {
|
||||
return await (this._loading[ref] = loadSchema(ref))
|
||||
} finally {
|
||||
delete this._loading[ref]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Adds schema to the instance
|
||||
addSchema(
|
||||
schema: AnySchema | AnySchema[], // If array is passed, `key` will be ignored
|
||||
key?: string, // Optional schema key. Can be passed to `validate` method instead of schema object or id/ref. One schema per instance can have empty `id` and `key`.
|
||||
_meta?: boolean, // true if schema is a meta-schema. Used internally, addMetaSchema should be used instead.
|
||||
_validateSchema = this.opts.validateSchema // false to skip schema validation. Used internally, option validateSchema should be used instead.
|
||||
): Ajv {
|
||||
if (Array.isArray(schema)) {
|
||||
for (const sch of schema) this.addSchema(sch, undefined, _meta, _validateSchema)
|
||||
return this
|
||||
}
|
||||
let id: string | undefined
|
||||
if (typeof schema === "object") {
|
||||
const {schemaId} = this.opts
|
||||
id = schema[schemaId]
|
||||
if (id !== undefined && typeof id != "string") {
|
||||
throw new Error(`schema ${schemaId} must be string`)
|
||||
}
|
||||
}
|
||||
key = normalizeId(key || id)
|
||||
this._checkUnique(key)
|
||||
this.schemas[key] = this._addSchema(schema, _meta, key, _validateSchema, true)
|
||||
return this
|
||||
}
|
||||
|
||||
// Add schema that will be used to validate other schemas
|
||||
// options in META_IGNORE_OPTIONS are alway set to false
|
||||
addMetaSchema(
|
||||
schema: AnySchemaObject,
|
||||
key?: string, // schema key
|
||||
_validateSchema = this.opts.validateSchema // false to skip schema validation, can be used to override validateSchema option for meta-schema
|
||||
): Ajv {
|
||||
this.addSchema(schema, key, true, _validateSchema)
|
||||
return this
|
||||
}
|
||||
|
||||
// Validate schema against its meta-schema
|
||||
validateSchema(schema: AnySchema, throwOrLogError?: boolean): boolean | Promise<unknown> {
|
||||
if (typeof schema == "boolean") return true
|
||||
let $schema: string | AnySchemaObject | undefined
|
||||
$schema = schema.$schema
|
||||
if ($schema !== undefined && typeof $schema != "string") {
|
||||
throw new Error("$schema must be a string")
|
||||
}
|
||||
$schema = $schema || this.opts.defaultMeta || this.defaultMeta()
|
||||
if (!$schema) {
|
||||
this.logger.warn("meta-schema not available")
|
||||
this.errors = null
|
||||
return true
|
||||
}
|
||||
const valid = this.validate($schema, schema)
|
||||
if (!valid && throwOrLogError) {
|
||||
const message = "schema is invalid: " + this.errorsText()
|
||||
if (this.opts.validateSchema === "log") this.logger.error(message)
|
||||
else throw new Error(message)
|
||||
}
|
||||
return valid
|
||||
}
|
||||
|
||||
// Get compiled schema by `key` or `ref`.
|
||||
// (`key` that was passed to `addSchema` or full schema reference - `schema.$id` or resolved id)
|
||||
getSchema<T = unknown>(keyRef: string): AnyValidateFunction<T> | undefined {
|
||||
let sch
|
||||
while (typeof (sch = getSchEnv.call(this, keyRef)) == "string") keyRef = sch
|
||||
if (sch === undefined) {
|
||||
const {schemaId} = this.opts
|
||||
const root = new SchemaEnv({schema: {}, schemaId})
|
||||
sch = resolveSchema.call(this, root, keyRef)
|
||||
if (!sch) return
|
||||
this.refs[keyRef] = sch
|
||||
}
|
||||
return (sch.validate || this._compileSchemaEnv(sch)) as AnyValidateFunction<T> | undefined
|
||||
}
|
||||
|
||||
// Remove cached schema(s).
|
||||
// If no parameter is passed all schemas but meta-schemas are removed.
|
||||
// If RegExp is passed all schemas with key/id matching pattern but meta-schemas are removed.
|
||||
// Even if schema is referenced by other schemas it still can be removed as other schemas have local references.
|
||||
removeSchema(schemaKeyRef?: AnySchema | string | RegExp): Ajv {
|
||||
if (schemaKeyRef instanceof RegExp) {
|
||||
this._removeAllSchemas(this.schemas, schemaKeyRef)
|
||||
this._removeAllSchemas(this.refs, schemaKeyRef)
|
||||
return this
|
||||
}
|
||||
switch (typeof schemaKeyRef) {
|
||||
case "undefined":
|
||||
this._removeAllSchemas(this.schemas)
|
||||
this._removeAllSchemas(this.refs)
|
||||
this._cache.clear()
|
||||
return this
|
||||
case "string": {
|
||||
const sch = getSchEnv.call(this, schemaKeyRef)
|
||||
if (typeof sch == "object") this._cache.delete(sch.schema)
|
||||
delete this.schemas[schemaKeyRef]
|
||||
delete this.refs[schemaKeyRef]
|
||||
return this
|
||||
}
|
||||
case "object": {
|
||||
const cacheKey = schemaKeyRef
|
||||
this._cache.delete(cacheKey)
|
||||
let id = schemaKeyRef[this.opts.schemaId]
|
||||
if (id) {
|
||||
id = normalizeId(id)
|
||||
delete this.schemas[id]
|
||||
delete this.refs[id]
|
||||
}
|
||||
return this
|
||||
}
|
||||
default:
|
||||
throw new Error("ajv.removeSchema: invalid parameter")
|
||||
}
|
||||
}
|
||||
|
||||
// add "vocabulary" - a collection of keywords
|
||||
addVocabulary(definitions: Vocabulary): Ajv {
|
||||
for (const def of definitions) this.addKeyword(def)
|
||||
return this
|
||||
}
|
||||
|
||||
addKeyword(
|
||||
kwdOrDef: string | KeywordDefinition,
|
||||
def?: KeywordDefinition // deprecated
|
||||
): Ajv {
|
||||
let keyword: string | string[]
|
||||
if (typeof kwdOrDef == "string") {
|
||||
keyword = kwdOrDef
|
||||
if (typeof def == "object") {
|
||||
this.logger.warn("these parameters are deprecated, see docs for addKeyword")
|
||||
def.keyword = keyword
|
||||
}
|
||||
} else if (typeof kwdOrDef == "object" && def === undefined) {
|
||||
def = kwdOrDef
|
||||
keyword = def.keyword
|
||||
if (Array.isArray(keyword) && !keyword.length) {
|
||||
throw new Error("addKeywords: keyword must be string or non-empty array")
|
||||
}
|
||||
} else {
|
||||
throw new Error("invalid addKeywords parameters")
|
||||
}
|
||||
|
||||
checkKeyword.call(this, keyword, def)
|
||||
if (!def) {
|
||||
eachItem(keyword, (kwd) => addRule.call(this, kwd))
|
||||
return this
|
||||
}
|
||||
keywordMetaschema.call(this, def)
|
||||
const definition: AddedKeywordDefinition = {
|
||||
...def,
|
||||
type: getJSONTypes(def.type),
|
||||
schemaType: getJSONTypes(def.schemaType),
|
||||
}
|
||||
eachItem(
|
||||
keyword,
|
||||
definition.type.length === 0
|
||||
? (k) => addRule.call(this, k, definition)
|
||||
: (k) => definition.type.forEach((t) => addRule.call(this, k, definition, t))
|
||||
)
|
||||
return this
|
||||
}
|
||||
|
||||
getKeyword(keyword: string): AddedKeywordDefinition | boolean {
|
||||
const rule = this.RULES.all[keyword]
|
||||
return typeof rule == "object" ? rule.definition : !!rule
|
||||
}
|
||||
|
||||
// Remove keyword
|
||||
removeKeyword(keyword: string): Ajv {
|
||||
// TODO return type should be Ajv
|
||||
const {RULES} = this
|
||||
delete RULES.keywords[keyword]
|
||||
delete RULES.all[keyword]
|
||||
for (const group of RULES.rules) {
|
||||
const i = group.rules.findIndex((rule) => rule.keyword === keyword)
|
||||
if (i >= 0) group.rules.splice(i, 1)
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
// Add format
|
||||
addFormat(name: string, format: Format): Ajv {
|
||||
if (typeof format == "string") format = new RegExp(format)
|
||||
this.formats[name] = format
|
||||
return this
|
||||
}
|
||||
|
||||
errorsText(
|
||||
errors: ErrorObject[] | null | undefined = this.errors, // optional array of validation errors
|
||||
{separator = ", ", dataVar = "data"}: ErrorsTextOptions = {} // optional options with properties `separator` and `dataVar`
|
||||
): string {
|
||||
if (!errors || errors.length === 0) return "No errors"
|
||||
return errors
|
||||
.map((e) => `${dataVar}${e.instancePath} ${e.message}`)
|
||||
.reduce((text, msg) => text + separator + msg)
|
||||
}
|
||||
|
||||
$dataMetaSchema(metaSchema: AnySchemaObject, keywordsJsonPointers: string[]): AnySchemaObject {
|
||||
const rules = this.RULES.all
|
||||
metaSchema = JSON.parse(JSON.stringify(metaSchema))
|
||||
for (const jsonPointer of keywordsJsonPointers) {
|
||||
const segments = jsonPointer.split("/").slice(1) // first segment is an empty string
|
||||
let keywords = metaSchema
|
||||
for (const seg of segments) keywords = keywords[seg] as AnySchemaObject
|
||||
|
||||
for (const key in rules) {
|
||||
const rule = rules[key]
|
||||
if (typeof rule != "object") continue
|
||||
const {$data} = rule.definition
|
||||
const schema = keywords[key] as AnySchemaObject | undefined
|
||||
if ($data && schema) keywords[key] = schemaOrData(schema)
|
||||
}
|
||||
}
|
||||
|
||||
return metaSchema
|
||||
}
|
||||
|
||||
private _removeAllSchemas(schemas: {[Ref in string]?: SchemaEnv | string}, regex?: RegExp): void {
|
||||
for (const keyRef in schemas) {
|
||||
const sch = schemas[keyRef]
|
||||
if (!regex || regex.test(keyRef)) {
|
||||
if (typeof sch == "string") {
|
||||
delete schemas[keyRef]
|
||||
} else if (sch && !sch.meta) {
|
||||
this._cache.delete(sch.schema)
|
||||
delete schemas[keyRef]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_addSchema(
|
||||
schema: AnySchema,
|
||||
meta?: boolean,
|
||||
baseId?: string,
|
||||
validateSchema = this.opts.validateSchema,
|
||||
addSchema = this.opts.addUsedSchema
|
||||
): SchemaEnv {
|
||||
let id: string | undefined
|
||||
const {schemaId} = this.opts
|
||||
if (typeof schema == "object") {
|
||||
id = schema[schemaId]
|
||||
} else {
|
||||
if (this.opts.jtd) throw new Error("schema must be object")
|
||||
else if (typeof schema != "boolean") throw new Error("schema must be object or boolean")
|
||||
}
|
||||
let sch = this._cache.get(schema)
|
||||
if (sch !== undefined) return sch
|
||||
|
||||
baseId = normalizeId(id || baseId)
|
||||
const localRefs = getSchemaRefs.call(this, schema, baseId)
|
||||
sch = new SchemaEnv({schema, schemaId, meta, baseId, localRefs})
|
||||
this._cache.set(sch.schema, sch)
|
||||
if (addSchema && !baseId.startsWith("#")) {
|
||||
// TODO atm it is allowed to overwrite schemas without id (instead of not adding them)
|
||||
if (baseId) this._checkUnique(baseId)
|
||||
this.refs[baseId] = sch
|
||||
}
|
||||
if (validateSchema) this.validateSchema(schema, true)
|
||||
return sch
|
||||
}
|
||||
|
||||
private _checkUnique(id: string): void {
|
||||
if (this.schemas[id] || this.refs[id]) {
|
||||
throw new Error(`schema with key or id "${id}" already exists`)
|
||||
}
|
||||
}
|
||||
|
||||
private _compileSchemaEnv(sch: SchemaEnv): AnyValidateFunction {
|
||||
if (sch.meta) this._compileMetaSchema(sch)
|
||||
else compileSchema.call(this, sch)
|
||||
|
||||
/* istanbul ignore if */
|
||||
if (!sch.validate) throw new Error("ajv implementation error")
|
||||
return sch.validate
|
||||
}
|
||||
|
||||
private _compileMetaSchema(sch: SchemaEnv): void {
|
||||
const currentOpts = this.opts
|
||||
this.opts = this._metaOpts
|
||||
try {
|
||||
compileSchema.call(this, sch)
|
||||
} finally {
|
||||
this.opts = currentOpts
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export interface ErrorsTextOptions {
|
||||
separator?: string
|
||||
dataVar?: string
|
||||
}
|
||||
|
||||
function checkOptions(
|
||||
this: Ajv,
|
||||
checkOpts: OptionsInfo<RemovedOptions | DeprecatedOptions>,
|
||||
options: Options & RemovedOptions,
|
||||
msg: string,
|
||||
log: "warn" | "error" = "error"
|
||||
): void {
|
||||
for (const key in checkOpts) {
|
||||
const opt = key as keyof typeof checkOpts
|
||||
if (opt in options) this.logger[log](`${msg}: option ${key}. ${checkOpts[opt]}`)
|
||||
}
|
||||
}
|
||||
|
||||
function getSchEnv(this: Ajv, keyRef: string): SchemaEnv | string | undefined {
|
||||
keyRef = normalizeId(keyRef) // TODO tests fail without this line
|
||||
return this.schemas[keyRef] || this.refs[keyRef]
|
||||
}
|
||||
|
||||
function addInitialSchemas(this: Ajv): void {
|
||||
const optsSchemas = this.opts.schemas
|
||||
if (!optsSchemas) return
|
||||
if (Array.isArray(optsSchemas)) this.addSchema(optsSchemas)
|
||||
else for (const key in optsSchemas) this.addSchema(optsSchemas[key] as AnySchema, key)
|
||||
}
|
||||
|
||||
function addInitialFormats(this: Ajv): void {
|
||||
for (const name in this.opts.formats) {
|
||||
const format = this.opts.formats[name]
|
||||
if (format) this.addFormat(name, format)
|
||||
}
|
||||
}
|
||||
|
||||
function addInitialKeywords(
|
||||
this: Ajv,
|
||||
defs: Vocabulary | {[K in string]?: KeywordDefinition}
|
||||
): void {
|
||||
if (Array.isArray(defs)) {
|
||||
this.addVocabulary(defs)
|
||||
return
|
||||
}
|
||||
this.logger.warn("keywords option as map is deprecated, pass array")
|
||||
for (const keyword in defs) {
|
||||
const def = defs[keyword] as KeywordDefinition
|
||||
if (!def.keyword) def.keyword = keyword
|
||||
this.addKeyword(def)
|
||||
}
|
||||
}
|
||||
|
||||
function getMetaSchemaOptions(this: Ajv): InstanceOptions {
|
||||
const metaOpts = {...this.opts}
|
||||
for (const opt of META_IGNORE_OPTIONS) delete metaOpts[opt]
|
||||
return metaOpts
|
||||
}
|
||||
|
||||
const noLogs = {log() {}, warn() {}, error() {}}
|
||||
|
||||
function getLogger(logger?: Partial<Logger> | false): Logger {
|
||||
if (logger === false) return noLogs
|
||||
if (logger === undefined) return console
|
||||
if (logger.log && logger.warn && logger.error) return logger as Logger
|
||||
throw new Error("logger must implement log, warn and error methods")
|
||||
}
|
||||
|
||||
const KEYWORD_NAME = /^[a-z_$][a-z0-9_$:-]*$/i
|
||||
|
||||
function checkKeyword(this: Ajv, keyword: string | string[], def?: KeywordDefinition): void {
|
||||
const {RULES} = this
|
||||
eachItem(keyword, (kwd) => {
|
||||
if (RULES.keywords[kwd]) throw new Error(`Keyword ${kwd} is already defined`)
|
||||
if (!KEYWORD_NAME.test(kwd)) throw new Error(`Keyword ${kwd} has invalid name`)
|
||||
})
|
||||
if (!def) return
|
||||
if (def.$data && !("code" in def || "validate" in def)) {
|
||||
throw new Error('$data keyword must have "code" or "validate" function')
|
||||
}
|
||||
}
|
||||
|
||||
function addRule(
|
||||
this: Ajv,
|
||||
keyword: string,
|
||||
definition?: AddedKeywordDefinition,
|
||||
dataType?: JSONType
|
||||
): void {
|
||||
const post = definition?.post
|
||||
if (dataType && post) throw new Error('keyword with "post" flag cannot have "type"')
|
||||
const {RULES} = this
|
||||
let ruleGroup = post ? RULES.post : RULES.rules.find(({type: t}) => t === dataType)
|
||||
if (!ruleGroup) {
|
||||
ruleGroup = {type: dataType, rules: []}
|
||||
RULES.rules.push(ruleGroup)
|
||||
}
|
||||
RULES.keywords[keyword] = true
|
||||
if (!definition) return
|
||||
|
||||
const rule: Rule = {
|
||||
keyword,
|
||||
definition: {
|
||||
...definition,
|
||||
type: getJSONTypes(definition.type),
|
||||
schemaType: getJSONTypes(definition.schemaType),
|
||||
},
|
||||
}
|
||||
if (definition.before) addBeforeRule.call(this, ruleGroup, rule, definition.before)
|
||||
else ruleGroup.rules.push(rule)
|
||||
RULES.all[keyword] = rule
|
||||
definition.implements?.forEach((kwd) => this.addKeyword(kwd))
|
||||
}
|
||||
|
||||
function addBeforeRule(this: Ajv, ruleGroup: RuleGroup, rule: Rule, before: string): void {
|
||||
const i = ruleGroup.rules.findIndex((_rule) => _rule.keyword === before)
|
||||
if (i >= 0) {
|
||||
ruleGroup.rules.splice(i, 0, rule)
|
||||
} else {
|
||||
ruleGroup.rules.push(rule)
|
||||
this.logger.warn(`rule ${before} is not defined`)
|
||||
}
|
||||
}
|
||||
|
||||
function keywordMetaschema(this: Ajv, def: KeywordDefinition): void {
|
||||
let {metaSchema} = def
|
||||
if (metaSchema === undefined) return
|
||||
if (def.$data && this.opts.$data) metaSchema = schemaOrData(metaSchema)
|
||||
def.validateSchema = this.compile(metaSchema, true)
|
||||
}
|
||||
|
||||
const $dataRef = {
|
||||
$ref: "https://raw.githubusercontent.com/ajv-validator/ajv/master/lib/refs/data.json#",
|
||||
}
|
||||
|
||||
function schemaOrData(schema: AnySchema): AnySchemaObject {
|
||||
return {anyOf: [schema, $dataRef]}
|
||||
}
|
132
node_modules/schema-utils/node_modules/ajv/lib/jtd.ts
generated
vendored
Normal file
132
node_modules/schema-utils/node_modules/ajv/lib/jtd.ts
generated
vendored
Normal file
@@ -0,0 +1,132 @@
|
||||
import type {AnySchemaObject, SchemaObject, JTDParser} from "./types"
|
||||
import type {JTDSchemaType, SomeJTDSchemaType, JTDDataType} from "./types/jtd-schema"
|
||||
import AjvCore, {CurrentOptions} from "./core"
|
||||
import jtdVocabulary from "./vocabularies/jtd"
|
||||
import jtdMetaSchema from "./refs/jtd-schema"
|
||||
import compileSerializer from "./compile/jtd/serialize"
|
||||
import compileParser from "./compile/jtd/parse"
|
||||
import {SchemaEnv} from "./compile"
|
||||
|
||||
const META_SCHEMA_ID = "JTD-meta-schema"
|
||||
|
||||
type JTDOptions = CurrentOptions & {
|
||||
// strict mode options not supported with JTD:
|
||||
strict?: never
|
||||
allowMatchingProperties?: never
|
||||
allowUnionTypes?: never
|
||||
validateFormats?: never
|
||||
// validation and reporting options not supported with JTD:
|
||||
$data?: never
|
||||
verbose?: boolean
|
||||
$comment?: never
|
||||
formats?: never
|
||||
loadSchema?: never
|
||||
// options to modify validated data:
|
||||
useDefaults?: never
|
||||
coerceTypes?: never
|
||||
// advanced options:
|
||||
next?: never
|
||||
unevaluated?: never
|
||||
dynamicRef?: never
|
||||
meta?: boolean
|
||||
defaultMeta?: never
|
||||
inlineRefs?: boolean
|
||||
loopRequired?: never
|
||||
multipleOfPrecision?: never
|
||||
}
|
||||
|
||||
export class Ajv extends AjvCore {
|
||||
constructor(opts: JTDOptions = {}) {
|
||||
super({
|
||||
...opts,
|
||||
jtd: true,
|
||||
})
|
||||
}
|
||||
|
||||
_addVocabularies(): void {
|
||||
super._addVocabularies()
|
||||
this.addVocabulary(jtdVocabulary)
|
||||
}
|
||||
|
||||
_addDefaultMetaSchema(): void {
|
||||
super._addDefaultMetaSchema()
|
||||
if (!this.opts.meta) return
|
||||
this.addMetaSchema(jtdMetaSchema, META_SCHEMA_ID, false)
|
||||
}
|
||||
|
||||
defaultMeta(): string | AnySchemaObject | undefined {
|
||||
return (this.opts.defaultMeta =
|
||||
super.defaultMeta() || (this.getSchema(META_SCHEMA_ID) ? META_SCHEMA_ID : undefined))
|
||||
}
|
||||
|
||||
compileSerializer<T = unknown>(schema: SchemaObject): (data: T) => string
|
||||
// Separated for type inference to work
|
||||
// eslint-disable-next-line @typescript-eslint/unified-signatures
|
||||
compileSerializer<T = unknown>(schema: JTDSchemaType<T>): (data: T) => string
|
||||
compileSerializer<T = unknown>(schema: SchemaObject): (data: T) => string {
|
||||
const sch = this._addSchema(schema)
|
||||
return sch.serialize || this._compileSerializer(sch)
|
||||
}
|
||||
|
||||
compileParser<T = unknown>(schema: SchemaObject): JTDParser<T>
|
||||
// Separated for type inference to work
|
||||
// eslint-disable-next-line @typescript-eslint/unified-signatures
|
||||
compileParser<T = unknown>(schema: JTDSchemaType<T>): JTDParser<T>
|
||||
compileParser<T = unknown>(schema: SchemaObject): JTDParser<T> {
|
||||
const sch = this._addSchema(schema)
|
||||
return (sch.parse || this._compileParser(sch)) as JTDParser<T>
|
||||
}
|
||||
|
||||
private _compileSerializer<T>(sch: SchemaEnv): (data: T) => string {
|
||||
compileSerializer.call(this, sch, (sch.schema as AnySchemaObject).definitions || {})
|
||||
/* istanbul ignore if */
|
||||
if (!sch.serialize) throw new Error("ajv implementation error")
|
||||
return sch.serialize
|
||||
}
|
||||
|
||||
private _compileParser(sch: SchemaEnv): JTDParser {
|
||||
compileParser.call(this, sch, (sch.schema as AnySchemaObject).definitions || {})
|
||||
/* istanbul ignore if */
|
||||
if (!sch.parse) throw new Error("ajv implementation error")
|
||||
return sch.parse
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = exports = Ajv
|
||||
module.exports.Ajv = Ajv
|
||||
Object.defineProperty(exports, "__esModule", {value: true})
|
||||
|
||||
export default Ajv
|
||||
|
||||
export {
|
||||
Format,
|
||||
FormatDefinition,
|
||||
AsyncFormatDefinition,
|
||||
KeywordDefinition,
|
||||
KeywordErrorDefinition,
|
||||
CodeKeywordDefinition,
|
||||
MacroKeywordDefinition,
|
||||
FuncKeywordDefinition,
|
||||
Vocabulary,
|
||||
Schema,
|
||||
SchemaObject,
|
||||
AnySchemaObject,
|
||||
AsyncSchema,
|
||||
AnySchema,
|
||||
ValidateFunction,
|
||||
AsyncValidateFunction,
|
||||
ErrorObject,
|
||||
ErrorNoParams,
|
||||
JTDParser,
|
||||
} from "./types"
|
||||
|
||||
export {Plugin, Options, CodeOptions, InstanceOptions, Logger, ErrorsTextOptions} from "./core"
|
||||
export {SchemaCxt, SchemaObjCxt} from "./compile"
|
||||
export {KeywordCxt} from "./compile/validate"
|
||||
export {JTDErrorObject} from "./vocabularies/jtd"
|
||||
export {_, str, stringify, nil, Name, Code, CodeGen, CodeGenOptions} from "./compile/codegen"
|
||||
|
||||
export {JTDSchemaType, SomeJTDSchemaType, JTDDataType}
|
||||
export {JTDOptions}
|
||||
export {default as ValidationError} from "./runtime/validation_error"
|
||||
export {default as MissingRefError} from "./compile/ref_error"
|
13
node_modules/schema-utils/node_modules/ajv/lib/refs/data.json
generated
vendored
Normal file
13
node_modules/schema-utils/node_modules/ajv/lib/refs/data.json
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"$id": "https://raw.githubusercontent.com/ajv-validator/ajv/master/lib/refs/data.json#",
|
||||
"description": "Meta-schema for $data reference (JSON AnySchema extension proposal)",
|
||||
"type": "object",
|
||||
"required": ["$data"],
|
||||
"properties": {
|
||||
"$data": {
|
||||
"type": "string",
|
||||
"anyOf": [{"format": "relative-json-pointer"}, {"format": "json-pointer"}]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
28
node_modules/schema-utils/node_modules/ajv/lib/refs/json-schema-2019-09/index.ts
generated
vendored
Normal file
28
node_modules/schema-utils/node_modules/ajv/lib/refs/json-schema-2019-09/index.ts
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
import type Ajv from "../../core"
|
||||
import type {AnySchemaObject} from "../../types"
|
||||
import * as metaSchema from "./schema.json"
|
||||
import * as applicator from "./meta/applicator.json"
|
||||
import * as content from "./meta/content.json"
|
||||
import * as core from "./meta/core.json"
|
||||
import * as format from "./meta/format.json"
|
||||
import * as metadata from "./meta/meta-data.json"
|
||||
import * as validation from "./meta/validation.json"
|
||||
|
||||
const META_SUPPORT_DATA = ["/properties"]
|
||||
|
||||
export default function addMetaSchema2019(this: Ajv, $data?: boolean): Ajv {
|
||||
;[
|
||||
metaSchema,
|
||||
applicator,
|
||||
content,
|
||||
core,
|
||||
with$data(this, format),
|
||||
metadata,
|
||||
with$data(this, validation),
|
||||
].forEach((sch) => this.addMetaSchema(sch, undefined, false))
|
||||
return this
|
||||
|
||||
function with$data(ajv: Ajv, sch: AnySchemaObject): AnySchemaObject {
|
||||
return $data ? ajv.$dataMetaSchema(sch, META_SUPPORT_DATA) : sch
|
||||
}
|
||||
}
|
53
node_modules/schema-utils/node_modules/ajv/lib/refs/json-schema-2019-09/meta/applicator.json
generated
vendored
Normal file
53
node_modules/schema-utils/node_modules/ajv/lib/refs/json-schema-2019-09/meta/applicator.json
generated
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2019-09/schema",
|
||||
"$id": "https://json-schema.org/draft/2019-09/meta/applicator",
|
||||
"$vocabulary": {
|
||||
"https://json-schema.org/draft/2019-09/vocab/applicator": true
|
||||
},
|
||||
"$recursiveAnchor": true,
|
||||
|
||||
"title": "Applicator vocabulary meta-schema",
|
||||
"type": ["object", "boolean"],
|
||||
"properties": {
|
||||
"additionalItems": {"$recursiveRef": "#"},
|
||||
"unevaluatedItems": {"$recursiveRef": "#"},
|
||||
"items": {
|
||||
"anyOf": [{"$recursiveRef": "#"}, {"$ref": "#/$defs/schemaArray"}]
|
||||
},
|
||||
"contains": {"$recursiveRef": "#"},
|
||||
"additionalProperties": {"$recursiveRef": "#"},
|
||||
"unevaluatedProperties": {"$recursiveRef": "#"},
|
||||
"properties": {
|
||||
"type": "object",
|
||||
"additionalProperties": {"$recursiveRef": "#"},
|
||||
"default": {}
|
||||
},
|
||||
"patternProperties": {
|
||||
"type": "object",
|
||||
"additionalProperties": {"$recursiveRef": "#"},
|
||||
"propertyNames": {"format": "regex"},
|
||||
"default": {}
|
||||
},
|
||||
"dependentSchemas": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$recursiveRef": "#"
|
||||
}
|
||||
},
|
||||
"propertyNames": {"$recursiveRef": "#"},
|
||||
"if": {"$recursiveRef": "#"},
|
||||
"then": {"$recursiveRef": "#"},
|
||||
"else": {"$recursiveRef": "#"},
|
||||
"allOf": {"$ref": "#/$defs/schemaArray"},
|
||||
"anyOf": {"$ref": "#/$defs/schemaArray"},
|
||||
"oneOf": {"$ref": "#/$defs/schemaArray"},
|
||||
"not": {"$recursiveRef": "#"}
|
||||
},
|
||||
"$defs": {
|
||||
"schemaArray": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {"$recursiveRef": "#"}
|
||||
}
|
||||
}
|
||||
}
|
17
node_modules/schema-utils/node_modules/ajv/lib/refs/json-schema-2019-09/meta/content.json
generated
vendored
Normal file
17
node_modules/schema-utils/node_modules/ajv/lib/refs/json-schema-2019-09/meta/content.json
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2019-09/schema",
|
||||
"$id": "https://json-schema.org/draft/2019-09/meta/content",
|
||||
"$vocabulary": {
|
||||
"https://json-schema.org/draft/2019-09/vocab/content": true
|
||||
},
|
||||
"$recursiveAnchor": true,
|
||||
|
||||
"title": "Content vocabulary meta-schema",
|
||||
|
||||
"type": ["object", "boolean"],
|
||||
"properties": {
|
||||
"contentMediaType": {"type": "string"},
|
||||
"contentEncoding": {"type": "string"},
|
||||
"contentSchema": {"$recursiveRef": "#"}
|
||||
}
|
||||
}
|
57
node_modules/schema-utils/node_modules/ajv/lib/refs/json-schema-2019-09/meta/core.json
generated
vendored
Normal file
57
node_modules/schema-utils/node_modules/ajv/lib/refs/json-schema-2019-09/meta/core.json
generated
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2019-09/schema",
|
||||
"$id": "https://json-schema.org/draft/2019-09/meta/core",
|
||||
"$vocabulary": {
|
||||
"https://json-schema.org/draft/2019-09/vocab/core": true
|
||||
},
|
||||
"$recursiveAnchor": true,
|
||||
|
||||
"title": "Core vocabulary meta-schema",
|
||||
"type": ["object", "boolean"],
|
||||
"properties": {
|
||||
"$id": {
|
||||
"type": "string",
|
||||
"format": "uri-reference",
|
||||
"$comment": "Non-empty fragments not allowed.",
|
||||
"pattern": "^[^#]*#?$"
|
||||
},
|
||||
"$schema": {
|
||||
"type": "string",
|
||||
"format": "uri"
|
||||
},
|
||||
"$anchor": {
|
||||
"type": "string",
|
||||
"pattern": "^[A-Za-z][-A-Za-z0-9.:_]*$"
|
||||
},
|
||||
"$ref": {
|
||||
"type": "string",
|
||||
"format": "uri-reference"
|
||||
},
|
||||
"$recursiveRef": {
|
||||
"type": "string",
|
||||
"format": "uri-reference"
|
||||
},
|
||||
"$recursiveAnchor": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"$vocabulary": {
|
||||
"type": "object",
|
||||
"propertyNames": {
|
||||
"type": "string",
|
||||
"format": "uri"
|
||||
},
|
||||
"additionalProperties": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"$comment": {
|
||||
"type": "string"
|
||||
},
|
||||
"$defs": {
|
||||
"type": "object",
|
||||
"additionalProperties": {"$recursiveRef": "#"},
|
||||
"default": {}
|
||||
}
|
||||
}
|
||||
}
|
14
node_modules/schema-utils/node_modules/ajv/lib/refs/json-schema-2019-09/meta/format.json
generated
vendored
Normal file
14
node_modules/schema-utils/node_modules/ajv/lib/refs/json-schema-2019-09/meta/format.json
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2019-09/schema",
|
||||
"$id": "https://json-schema.org/draft/2019-09/meta/format",
|
||||
"$vocabulary": {
|
||||
"https://json-schema.org/draft/2019-09/vocab/format": true
|
||||
},
|
||||
"$recursiveAnchor": true,
|
||||
|
||||
"title": "Format vocabulary meta-schema",
|
||||
"type": ["object", "boolean"],
|
||||
"properties": {
|
||||
"format": {"type": "string"}
|
||||
}
|
||||
}
|
37
node_modules/schema-utils/node_modules/ajv/lib/refs/json-schema-2019-09/meta/meta-data.json
generated
vendored
Normal file
37
node_modules/schema-utils/node_modules/ajv/lib/refs/json-schema-2019-09/meta/meta-data.json
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2019-09/schema",
|
||||
"$id": "https://json-schema.org/draft/2019-09/meta/meta-data",
|
||||
"$vocabulary": {
|
||||
"https://json-schema.org/draft/2019-09/vocab/meta-data": true
|
||||
},
|
||||
"$recursiveAnchor": true,
|
||||
|
||||
"title": "Meta-data vocabulary meta-schema",
|
||||
|
||||
"type": ["object", "boolean"],
|
||||
"properties": {
|
||||
"title": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"default": true,
|
||||
"deprecated": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"readOnly": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"writeOnly": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"examples": {
|
||||
"type": "array",
|
||||
"items": true
|
||||
}
|
||||
}
|
||||
}
|
90
node_modules/schema-utils/node_modules/ajv/lib/refs/json-schema-2019-09/meta/validation.json
generated
vendored
Normal file
90
node_modules/schema-utils/node_modules/ajv/lib/refs/json-schema-2019-09/meta/validation.json
generated
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2019-09/schema",
|
||||
"$id": "https://json-schema.org/draft/2019-09/meta/validation",
|
||||
"$vocabulary": {
|
||||
"https://json-schema.org/draft/2019-09/vocab/validation": true
|
||||
},
|
||||
"$recursiveAnchor": true,
|
||||
|
||||
"title": "Validation vocabulary meta-schema",
|
||||
"type": ["object", "boolean"],
|
||||
"properties": {
|
||||
"multipleOf": {
|
||||
"type": "number",
|
||||
"exclusiveMinimum": 0
|
||||
},
|
||||
"maximum": {
|
||||
"type": "number"
|
||||
},
|
||||
"exclusiveMaximum": {
|
||||
"type": "number"
|
||||
},
|
||||
"minimum": {
|
||||
"type": "number"
|
||||
},
|
||||
"exclusiveMinimum": {
|
||||
"type": "number"
|
||||
},
|
||||
"maxLength": {"$ref": "#/$defs/nonNegativeInteger"},
|
||||
"minLength": {"$ref": "#/$defs/nonNegativeIntegerDefault0"},
|
||||
"pattern": {
|
||||
"type": "string",
|
||||
"format": "regex"
|
||||
},
|
||||
"maxItems": {"$ref": "#/$defs/nonNegativeInteger"},
|
||||
"minItems": {"$ref": "#/$defs/nonNegativeIntegerDefault0"},
|
||||
"uniqueItems": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"maxContains": {"$ref": "#/$defs/nonNegativeInteger"},
|
||||
"minContains": {
|
||||
"$ref": "#/$defs/nonNegativeInteger",
|
||||
"default": 1
|
||||
},
|
||||
"maxProperties": {"$ref": "#/$defs/nonNegativeInteger"},
|
||||
"minProperties": {"$ref": "#/$defs/nonNegativeIntegerDefault0"},
|
||||
"required": {"$ref": "#/$defs/stringArray"},
|
||||
"dependentRequired": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/$defs/stringArray"
|
||||
}
|
||||
},
|
||||
"const": true,
|
||||
"enum": {
|
||||
"type": "array",
|
||||
"items": true
|
||||
},
|
||||
"type": {
|
||||
"anyOf": [
|
||||
{"$ref": "#/$defs/simpleTypes"},
|
||||
{
|
||||
"type": "array",
|
||||
"items": {"$ref": "#/$defs/simpleTypes"},
|
||||
"minItems": 1,
|
||||
"uniqueItems": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"$defs": {
|
||||
"nonNegativeInteger": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"nonNegativeIntegerDefault0": {
|
||||
"$ref": "#/$defs/nonNegativeInteger",
|
||||
"default": 0
|
||||
},
|
||||
"simpleTypes": {
|
||||
"enum": ["array", "boolean", "integer", "null", "number", "object", "string"]
|
||||
},
|
||||
"stringArray": {
|
||||
"type": "array",
|
||||
"items": {"type": "string"},
|
||||
"uniqueItems": true,
|
||||
"default": []
|
||||
}
|
||||
}
|
||||
}
|
39
node_modules/schema-utils/node_modules/ajv/lib/refs/json-schema-2019-09/schema.json
generated
vendored
Normal file
39
node_modules/schema-utils/node_modules/ajv/lib/refs/json-schema-2019-09/schema.json
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2019-09/schema",
|
||||
"$id": "https://json-schema.org/draft/2019-09/schema",
|
||||
"$vocabulary": {
|
||||
"https://json-schema.org/draft/2019-09/vocab/core": true,
|
||||
"https://json-schema.org/draft/2019-09/vocab/applicator": true,
|
||||
"https://json-schema.org/draft/2019-09/vocab/validation": true,
|
||||
"https://json-schema.org/draft/2019-09/vocab/meta-data": true,
|
||||
"https://json-schema.org/draft/2019-09/vocab/format": false,
|
||||
"https://json-schema.org/draft/2019-09/vocab/content": true
|
||||
},
|
||||
"$recursiveAnchor": true,
|
||||
|
||||
"title": "Core and Validation specifications meta-schema",
|
||||
"allOf": [
|
||||
{"$ref": "meta/core"},
|
||||
{"$ref": "meta/applicator"},
|
||||
{"$ref": "meta/validation"},
|
||||
{"$ref": "meta/meta-data"},
|
||||
{"$ref": "meta/format"},
|
||||
{"$ref": "meta/content"}
|
||||
],
|
||||
"type": ["object", "boolean"],
|
||||
"properties": {
|
||||
"definitions": {
|
||||
"$comment": "While no longer an official keyword as it is replaced by $defs, this keyword is retained in the meta-schema to prevent incompatible extensions as it remains in common use.",
|
||||
"type": "object",
|
||||
"additionalProperties": {"$recursiveRef": "#"},
|
||||
"default": {}
|
||||
},
|
||||
"dependencies": {
|
||||
"$comment": "\"dependencies\" is no longer a keyword, but schema authors should avoid redefining it to facilitate a smooth transition to \"dependentSchemas\" and \"dependentRequired\"",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"anyOf": [{"$recursiveRef": "#"}, {"$ref": "meta/validation#/$defs/stringArray"}]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
30
node_modules/schema-utils/node_modules/ajv/lib/refs/json-schema-2020-12/index.ts
generated
vendored
Normal file
30
node_modules/schema-utils/node_modules/ajv/lib/refs/json-schema-2020-12/index.ts
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
import type Ajv from "../../core"
|
||||
import type {AnySchemaObject} from "../../types"
|
||||
import * as metaSchema from "./schema.json"
|
||||
import * as applicator from "./meta/applicator.json"
|
||||
import * as unevaluated from "./meta/unevaluated.json"
|
||||
import * as content from "./meta/content.json"
|
||||
import * as core from "./meta/core.json"
|
||||
import * as format from "./meta/format-annotation.json"
|
||||
import * as metadata from "./meta/meta-data.json"
|
||||
import * as validation from "./meta/validation.json"
|
||||
|
||||
const META_SUPPORT_DATA = ["/properties"]
|
||||
|
||||
export default function addMetaSchema2020(this: Ajv, $data?: boolean): Ajv {
|
||||
;[
|
||||
metaSchema,
|
||||
applicator,
|
||||
unevaluated,
|
||||
content,
|
||||
core,
|
||||
with$data(this, format),
|
||||
metadata,
|
||||
with$data(this, validation),
|
||||
].forEach((sch) => this.addMetaSchema(sch, undefined, false))
|
||||
return this
|
||||
|
||||
function with$data(ajv: Ajv, sch: AnySchemaObject): AnySchemaObject {
|
||||
return $data ? ajv.$dataMetaSchema(sch, META_SUPPORT_DATA) : sch
|
||||
}
|
||||
}
|
48
node_modules/schema-utils/node_modules/ajv/lib/refs/json-schema-2020-12/meta/applicator.json
generated
vendored
Normal file
48
node_modules/schema-utils/node_modules/ajv/lib/refs/json-schema-2020-12/meta/applicator.json
generated
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://json-schema.org/draft/2020-12/meta/applicator",
|
||||
"$vocabulary": {
|
||||
"https://json-schema.org/draft/2020-12/vocab/applicator": true
|
||||
},
|
||||
"$dynamicAnchor": "meta",
|
||||
|
||||
"title": "Applicator vocabulary meta-schema",
|
||||
"type": ["object", "boolean"],
|
||||
"properties": {
|
||||
"prefixItems": {"$ref": "#/$defs/schemaArray"},
|
||||
"items": {"$dynamicRef": "#meta"},
|
||||
"contains": {"$dynamicRef": "#meta"},
|
||||
"additionalProperties": {"$dynamicRef": "#meta"},
|
||||
"properties": {
|
||||
"type": "object",
|
||||
"additionalProperties": {"$dynamicRef": "#meta"},
|
||||
"default": {}
|
||||
},
|
||||
"patternProperties": {
|
||||
"type": "object",
|
||||
"additionalProperties": {"$dynamicRef": "#meta"},
|
||||
"propertyNames": {"format": "regex"},
|
||||
"default": {}
|
||||
},
|
||||
"dependentSchemas": {
|
||||
"type": "object",
|
||||
"additionalProperties": {"$dynamicRef": "#meta"},
|
||||
"default": {}
|
||||
},
|
||||
"propertyNames": {"$dynamicRef": "#meta"},
|
||||
"if": {"$dynamicRef": "#meta"},
|
||||
"then": {"$dynamicRef": "#meta"},
|
||||
"else": {"$dynamicRef": "#meta"},
|
||||
"allOf": {"$ref": "#/$defs/schemaArray"},
|
||||
"anyOf": {"$ref": "#/$defs/schemaArray"},
|
||||
"oneOf": {"$ref": "#/$defs/schemaArray"},
|
||||
"not": {"$dynamicRef": "#meta"}
|
||||
},
|
||||
"$defs": {
|
||||
"schemaArray": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {"$dynamicRef": "#meta"}
|
||||
}
|
||||
}
|
||||
}
|
17
node_modules/schema-utils/node_modules/ajv/lib/refs/json-schema-2020-12/meta/content.json
generated
vendored
Normal file
17
node_modules/schema-utils/node_modules/ajv/lib/refs/json-schema-2020-12/meta/content.json
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://json-schema.org/draft/2020-12/meta/content",
|
||||
"$vocabulary": {
|
||||
"https://json-schema.org/draft/2020-12/vocab/content": true
|
||||
},
|
||||
"$dynamicAnchor": "meta",
|
||||
|
||||
"title": "Content vocabulary meta-schema",
|
||||
|
||||
"type": ["object", "boolean"],
|
||||
"properties": {
|
||||
"contentEncoding": {"type": "string"},
|
||||
"contentMediaType": {"type": "string"},
|
||||
"contentSchema": {"$dynamicRef": "#meta"}
|
||||
}
|
||||
}
|
51
node_modules/schema-utils/node_modules/ajv/lib/refs/json-schema-2020-12/meta/core.json
generated
vendored
Normal file
51
node_modules/schema-utils/node_modules/ajv/lib/refs/json-schema-2020-12/meta/core.json
generated
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://json-schema.org/draft/2020-12/meta/core",
|
||||
"$vocabulary": {
|
||||
"https://json-schema.org/draft/2020-12/vocab/core": true
|
||||
},
|
||||
"$dynamicAnchor": "meta",
|
||||
|
||||
"title": "Core vocabulary meta-schema",
|
||||
"type": ["object", "boolean"],
|
||||
"properties": {
|
||||
"$id": {
|
||||
"$ref": "#/$defs/uriReferenceString",
|
||||
"$comment": "Non-empty fragments not allowed.",
|
||||
"pattern": "^[^#]*#?$"
|
||||
},
|
||||
"$schema": {"$ref": "#/$defs/uriString"},
|
||||
"$ref": {"$ref": "#/$defs/uriReferenceString"},
|
||||
"$anchor": {"$ref": "#/$defs/anchorString"},
|
||||
"$dynamicRef": {"$ref": "#/$defs/uriReferenceString"},
|
||||
"$dynamicAnchor": {"$ref": "#/$defs/anchorString"},
|
||||
"$vocabulary": {
|
||||
"type": "object",
|
||||
"propertyNames": {"$ref": "#/$defs/uriString"},
|
||||
"additionalProperties": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"$comment": {
|
||||
"type": "string"
|
||||
},
|
||||
"$defs": {
|
||||
"type": "object",
|
||||
"additionalProperties": {"$dynamicRef": "#meta"}
|
||||
}
|
||||
},
|
||||
"$defs": {
|
||||
"anchorString": {
|
||||
"type": "string",
|
||||
"pattern": "^[A-Za-z_][-A-Za-z0-9._]*$"
|
||||
},
|
||||
"uriString": {
|
||||
"type": "string",
|
||||
"format": "uri"
|
||||
},
|
||||
"uriReferenceString": {
|
||||
"type": "string",
|
||||
"format": "uri-reference"
|
||||
}
|
||||
}
|
||||
}
|
14
node_modules/schema-utils/node_modules/ajv/lib/refs/json-schema-2020-12/meta/format-annotation.json
generated
vendored
Normal file
14
node_modules/schema-utils/node_modules/ajv/lib/refs/json-schema-2020-12/meta/format-annotation.json
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://json-schema.org/draft/2020-12/meta/format-annotation",
|
||||
"$vocabulary": {
|
||||
"https://json-schema.org/draft/2020-12/vocab/format-annotation": true
|
||||
},
|
||||
"$dynamicAnchor": "meta",
|
||||
|
||||
"title": "Format vocabulary meta-schema for annotation results",
|
||||
"type": ["object", "boolean"],
|
||||
"properties": {
|
||||
"format": {"type": "string"}
|
||||
}
|
||||
}
|
37
node_modules/schema-utils/node_modules/ajv/lib/refs/json-schema-2020-12/meta/meta-data.json
generated
vendored
Normal file
37
node_modules/schema-utils/node_modules/ajv/lib/refs/json-schema-2020-12/meta/meta-data.json
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://json-schema.org/draft/2020-12/meta/meta-data",
|
||||
"$vocabulary": {
|
||||
"https://json-schema.org/draft/2020-12/vocab/meta-data": true
|
||||
},
|
||||
"$dynamicAnchor": "meta",
|
||||
|
||||
"title": "Meta-data vocabulary meta-schema",
|
||||
|
||||
"type": ["object", "boolean"],
|
||||
"properties": {
|
||||
"title": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"default": true,
|
||||
"deprecated": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"readOnly": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"writeOnly": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"examples": {
|
||||
"type": "array",
|
||||
"items": true
|
||||
}
|
||||
}
|
||||
}
|
15
node_modules/schema-utils/node_modules/ajv/lib/refs/json-schema-2020-12/meta/unevaluated.json
generated
vendored
Normal file
15
node_modules/schema-utils/node_modules/ajv/lib/refs/json-schema-2020-12/meta/unevaluated.json
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://json-schema.org/draft/2020-12/meta/unevaluated",
|
||||
"$vocabulary": {
|
||||
"https://json-schema.org/draft/2020-12/vocab/unevaluated": true
|
||||
},
|
||||
"$dynamicAnchor": "meta",
|
||||
|
||||
"title": "Unevaluated applicator vocabulary meta-schema",
|
||||
"type": ["object", "boolean"],
|
||||
"properties": {
|
||||
"unevaluatedItems": {"$dynamicRef": "#meta"},
|
||||
"unevaluatedProperties": {"$dynamicRef": "#meta"}
|
||||
}
|
||||
}
|
90
node_modules/schema-utils/node_modules/ajv/lib/refs/json-schema-2020-12/meta/validation.json
generated
vendored
Normal file
90
node_modules/schema-utils/node_modules/ajv/lib/refs/json-schema-2020-12/meta/validation.json
generated
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://json-schema.org/draft/2020-12/meta/validation",
|
||||
"$vocabulary": {
|
||||
"https://json-schema.org/draft/2020-12/vocab/validation": true
|
||||
},
|
||||
"$dynamicAnchor": "meta",
|
||||
|
||||
"title": "Validation vocabulary meta-schema",
|
||||
"type": ["object", "boolean"],
|
||||
"properties": {
|
||||
"type": {
|
||||
"anyOf": [
|
||||
{"$ref": "#/$defs/simpleTypes"},
|
||||
{
|
||||
"type": "array",
|
||||
"items": {"$ref": "#/$defs/simpleTypes"},
|
||||
"minItems": 1,
|
||||
"uniqueItems": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"const": true,
|
||||
"enum": {
|
||||
"type": "array",
|
||||
"items": true
|
||||
},
|
||||
"multipleOf": {
|
||||
"type": "number",
|
||||
"exclusiveMinimum": 0
|
||||
},
|
||||
"maximum": {
|
||||
"type": "number"
|
||||
},
|
||||
"exclusiveMaximum": {
|
||||
"type": "number"
|
||||
},
|
||||
"minimum": {
|
||||
"type": "number"
|
||||
},
|
||||
"exclusiveMinimum": {
|
||||
"type": "number"
|
||||
},
|
||||
"maxLength": {"$ref": "#/$defs/nonNegativeInteger"},
|
||||
"minLength": {"$ref": "#/$defs/nonNegativeIntegerDefault0"},
|
||||
"pattern": {
|
||||
"type": "string",
|
||||
"format": "regex"
|
||||
},
|
||||
"maxItems": {"$ref": "#/$defs/nonNegativeInteger"},
|
||||
"minItems": {"$ref": "#/$defs/nonNegativeIntegerDefault0"},
|
||||
"uniqueItems": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"maxContains": {"$ref": "#/$defs/nonNegativeInteger"},
|
||||
"minContains": {
|
||||
"$ref": "#/$defs/nonNegativeInteger",
|
||||
"default": 1
|
||||
},
|
||||
"maxProperties": {"$ref": "#/$defs/nonNegativeInteger"},
|
||||
"minProperties": {"$ref": "#/$defs/nonNegativeIntegerDefault0"},
|
||||
"required": {"$ref": "#/$defs/stringArray"},
|
||||
"dependentRequired": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/$defs/stringArray"
|
||||
}
|
||||
}
|
||||
},
|
||||
"$defs": {
|
||||
"nonNegativeInteger": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"nonNegativeIntegerDefault0": {
|
||||
"$ref": "#/$defs/nonNegativeInteger",
|
||||
"default": 0
|
||||
},
|
||||
"simpleTypes": {
|
||||
"enum": ["array", "boolean", "integer", "null", "number", "object", "string"]
|
||||
},
|
||||
"stringArray": {
|
||||
"type": "array",
|
||||
"items": {"type": "string"},
|
||||
"uniqueItems": true,
|
||||
"default": []
|
||||
}
|
||||
}
|
||||
}
|
55
node_modules/schema-utils/node_modules/ajv/lib/refs/json-schema-2020-12/schema.json
generated
vendored
Normal file
55
node_modules/schema-utils/node_modules/ajv/lib/refs/json-schema-2020-12/schema.json
generated
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$vocabulary": {
|
||||
"https://json-schema.org/draft/2020-12/vocab/core": true,
|
||||
"https://json-schema.org/draft/2020-12/vocab/applicator": true,
|
||||
"https://json-schema.org/draft/2020-12/vocab/unevaluated": true,
|
||||
"https://json-schema.org/draft/2020-12/vocab/validation": true,
|
||||
"https://json-schema.org/draft/2020-12/vocab/meta-data": true,
|
||||
"https://json-schema.org/draft/2020-12/vocab/format-annotation": true,
|
||||
"https://json-schema.org/draft/2020-12/vocab/content": true
|
||||
},
|
||||
"$dynamicAnchor": "meta",
|
||||
|
||||
"title": "Core and Validation specifications meta-schema",
|
||||
"allOf": [
|
||||
{"$ref": "meta/core"},
|
||||
{"$ref": "meta/applicator"},
|
||||
{"$ref": "meta/unevaluated"},
|
||||
{"$ref": "meta/validation"},
|
||||
{"$ref": "meta/meta-data"},
|
||||
{"$ref": "meta/format-annotation"},
|
||||
{"$ref": "meta/content"}
|
||||
],
|
||||
"type": ["object", "boolean"],
|
||||
"$comment": "This meta-schema also defines keywords that have appeared in previous drafts in order to prevent incompatible extensions as they remain in common use.",
|
||||
"properties": {
|
||||
"definitions": {
|
||||
"$comment": "\"definitions\" has been replaced by \"$defs\".",
|
||||
"type": "object",
|
||||
"additionalProperties": {"$dynamicRef": "#meta"},
|
||||
"deprecated": true,
|
||||
"default": {}
|
||||
},
|
||||
"dependencies": {
|
||||
"$comment": "\"dependencies\" has been split and replaced by \"dependentSchemas\" and \"dependentRequired\" in order to serve their differing semantics.",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"anyOf": [{"$dynamicRef": "#meta"}, {"$ref": "meta/validation#/$defs/stringArray"}]
|
||||
},
|
||||
"deprecated": true,
|
||||
"default": {}
|
||||
},
|
||||
"$recursiveAnchor": {
|
||||
"$comment": "\"$recursiveAnchor\" has been replaced by \"$dynamicAnchor\".",
|
||||
"$ref": "meta/core#/$defs/anchorString",
|
||||
"deprecated": true
|
||||
},
|
||||
"$recursiveRef": {
|
||||
"$comment": "\"$recursiveRef\" has been replaced by \"$dynamicRef\".",
|
||||
"$ref": "meta/core#/$defs/uriReferenceString",
|
||||
"deprecated": true
|
||||
}
|
||||
}
|
||||
}
|
137
node_modules/schema-utils/node_modules/ajv/lib/refs/json-schema-draft-06.json
generated
vendored
Normal file
137
node_modules/schema-utils/node_modules/ajv/lib/refs/json-schema-draft-06.json
generated
vendored
Normal file
@@ -0,0 +1,137 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-06/schema#",
|
||||
"$id": "http://json-schema.org/draft-06/schema#",
|
||||
"title": "Core schema meta-schema",
|
||||
"definitions": {
|
||||
"schemaArray": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {"$ref": "#"}
|
||||
},
|
||||
"nonNegativeInteger": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"nonNegativeIntegerDefault0": {
|
||||
"allOf": [{"$ref": "#/definitions/nonNegativeInteger"}, {"default": 0}]
|
||||
},
|
||||
"simpleTypes": {
|
||||
"enum": ["array", "boolean", "integer", "null", "number", "object", "string"]
|
||||
},
|
||||
"stringArray": {
|
||||
"type": "array",
|
||||
"items": {"type": "string"},
|
||||
"uniqueItems": true,
|
||||
"default": []
|
||||
}
|
||||
},
|
||||
"type": ["object", "boolean"],
|
||||
"properties": {
|
||||
"$id": {
|
||||
"type": "string",
|
||||
"format": "uri-reference"
|
||||
},
|
||||
"$schema": {
|
||||
"type": "string",
|
||||
"format": "uri"
|
||||
},
|
||||
"$ref": {
|
||||
"type": "string",
|
||||
"format": "uri-reference"
|
||||
},
|
||||
"title": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"default": {},
|
||||
"examples": {
|
||||
"type": "array",
|
||||
"items": {}
|
||||
},
|
||||
"multipleOf": {
|
||||
"type": "number",
|
||||
"exclusiveMinimum": 0
|
||||
},
|
||||
"maximum": {
|
||||
"type": "number"
|
||||
},
|
||||
"exclusiveMaximum": {
|
||||
"type": "number"
|
||||
},
|
||||
"minimum": {
|
||||
"type": "number"
|
||||
},
|
||||
"exclusiveMinimum": {
|
||||
"type": "number"
|
||||
},
|
||||
"maxLength": {"$ref": "#/definitions/nonNegativeInteger"},
|
||||
"minLength": {"$ref": "#/definitions/nonNegativeIntegerDefault0"},
|
||||
"pattern": {
|
||||
"type": "string",
|
||||
"format": "regex"
|
||||
},
|
||||
"additionalItems": {"$ref": "#"},
|
||||
"items": {
|
||||
"anyOf": [{"$ref": "#"}, {"$ref": "#/definitions/schemaArray"}],
|
||||
"default": {}
|
||||
},
|
||||
"maxItems": {"$ref": "#/definitions/nonNegativeInteger"},
|
||||
"minItems": {"$ref": "#/definitions/nonNegativeIntegerDefault0"},
|
||||
"uniqueItems": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"contains": {"$ref": "#"},
|
||||
"maxProperties": {"$ref": "#/definitions/nonNegativeInteger"},
|
||||
"minProperties": {"$ref": "#/definitions/nonNegativeIntegerDefault0"},
|
||||
"required": {"$ref": "#/definitions/stringArray"},
|
||||
"additionalProperties": {"$ref": "#"},
|
||||
"definitions": {
|
||||
"type": "object",
|
||||
"additionalProperties": {"$ref": "#"},
|
||||
"default": {}
|
||||
},
|
||||
"properties": {
|
||||
"type": "object",
|
||||
"additionalProperties": {"$ref": "#"},
|
||||
"default": {}
|
||||
},
|
||||
"patternProperties": {
|
||||
"type": "object",
|
||||
"additionalProperties": {"$ref": "#"},
|
||||
"default": {}
|
||||
},
|
||||
"dependencies": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"anyOf": [{"$ref": "#"}, {"$ref": "#/definitions/stringArray"}]
|
||||
}
|
||||
},
|
||||
"propertyNames": {"$ref": "#"},
|
||||
"const": {},
|
||||
"enum": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"uniqueItems": true
|
||||
},
|
||||
"type": {
|
||||
"anyOf": [
|
||||
{"$ref": "#/definitions/simpleTypes"},
|
||||
{
|
||||
"type": "array",
|
||||
"items": {"$ref": "#/definitions/simpleTypes"},
|
||||
"minItems": 1,
|
||||
"uniqueItems": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"format": {"type": "string"},
|
||||
"allOf": {"$ref": "#/definitions/schemaArray"},
|
||||
"anyOf": {"$ref": "#/definitions/schemaArray"},
|
||||
"oneOf": {"$ref": "#/definitions/schemaArray"},
|
||||
"not": {"$ref": "#"}
|
||||
},
|
||||
"default": {}
|
||||
}
|
151
node_modules/schema-utils/node_modules/ajv/lib/refs/json-schema-draft-07.json
generated
vendored
Normal file
151
node_modules/schema-utils/node_modules/ajv/lib/refs/json-schema-draft-07.json
generated
vendored
Normal file
@@ -0,0 +1,151 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"$id": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "Core schema meta-schema",
|
||||
"definitions": {
|
||||
"schemaArray": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {"$ref": "#"}
|
||||
},
|
||||
"nonNegativeInteger": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"nonNegativeIntegerDefault0": {
|
||||
"allOf": [{"$ref": "#/definitions/nonNegativeInteger"}, {"default": 0}]
|
||||
},
|
||||
"simpleTypes": {
|
||||
"enum": ["array", "boolean", "integer", "null", "number", "object", "string"]
|
||||
},
|
||||
"stringArray": {
|
||||
"type": "array",
|
||||
"items": {"type": "string"},
|
||||
"uniqueItems": true,
|
||||
"default": []
|
||||
}
|
||||
},
|
||||
"type": ["object", "boolean"],
|
||||
"properties": {
|
||||
"$id": {
|
||||
"type": "string",
|
||||
"format": "uri-reference"
|
||||
},
|
||||
"$schema": {
|
||||
"type": "string",
|
||||
"format": "uri"
|
||||
},
|
||||
"$ref": {
|
||||
"type": "string",
|
||||
"format": "uri-reference"
|
||||
},
|
||||
"$comment": {
|
||||
"type": "string"
|
||||
},
|
||||
"title": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"default": true,
|
||||
"readOnly": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"examples": {
|
||||
"type": "array",
|
||||
"items": true
|
||||
},
|
||||
"multipleOf": {
|
||||
"type": "number",
|
||||
"exclusiveMinimum": 0
|
||||
},
|
||||
"maximum": {
|
||||
"type": "number"
|
||||
},
|
||||
"exclusiveMaximum": {
|
||||
"type": "number"
|
||||
},
|
||||
"minimum": {
|
||||
"type": "number"
|
||||
},
|
||||
"exclusiveMinimum": {
|
||||
"type": "number"
|
||||
},
|
||||
"maxLength": {"$ref": "#/definitions/nonNegativeInteger"},
|
||||
"minLength": {"$ref": "#/definitions/nonNegativeIntegerDefault0"},
|
||||
"pattern": {
|
||||
"type": "string",
|
||||
"format": "regex"
|
||||
},
|
||||
"additionalItems": {"$ref": "#"},
|
||||
"items": {
|
||||
"anyOf": [{"$ref": "#"}, {"$ref": "#/definitions/schemaArray"}],
|
||||
"default": true
|
||||
},
|
||||
"maxItems": {"$ref": "#/definitions/nonNegativeInteger"},
|
||||
"minItems": {"$ref": "#/definitions/nonNegativeIntegerDefault0"},
|
||||
"uniqueItems": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"contains": {"$ref": "#"},
|
||||
"maxProperties": {"$ref": "#/definitions/nonNegativeInteger"},
|
||||
"minProperties": {"$ref": "#/definitions/nonNegativeIntegerDefault0"},
|
||||
"required": {"$ref": "#/definitions/stringArray"},
|
||||
"additionalProperties": {"$ref": "#"},
|
||||
"definitions": {
|
||||
"type": "object",
|
||||
"additionalProperties": {"$ref": "#"},
|
||||
"default": {}
|
||||
},
|
||||
"properties": {
|
||||
"type": "object",
|
||||
"additionalProperties": {"$ref": "#"},
|
||||
"default": {}
|
||||
},
|
||||
"patternProperties": {
|
||||
"type": "object",
|
||||
"additionalProperties": {"$ref": "#"},
|
||||
"propertyNames": {"format": "regex"},
|
||||
"default": {}
|
||||
},
|
||||
"dependencies": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"anyOf": [{"$ref": "#"}, {"$ref": "#/definitions/stringArray"}]
|
||||
}
|
||||
},
|
||||
"propertyNames": {"$ref": "#"},
|
||||
"const": true,
|
||||
"enum": {
|
||||
"type": "array",
|
||||
"items": true,
|
||||
"minItems": 1,
|
||||
"uniqueItems": true
|
||||
},
|
||||
"type": {
|
||||
"anyOf": [
|
||||
{"$ref": "#/definitions/simpleTypes"},
|
||||
{
|
||||
"type": "array",
|
||||
"items": {"$ref": "#/definitions/simpleTypes"},
|
||||
"minItems": 1,
|
||||
"uniqueItems": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"format": {"type": "string"},
|
||||
"contentMediaType": {"type": "string"},
|
||||
"contentEncoding": {"type": "string"},
|
||||
"if": {"$ref": "#"},
|
||||
"then": {"$ref": "#"},
|
||||
"else": {"$ref": "#"},
|
||||
"allOf": {"$ref": "#/definitions/schemaArray"},
|
||||
"anyOf": {"$ref": "#/definitions/schemaArray"},
|
||||
"oneOf": {"$ref": "#/definitions/schemaArray"},
|
||||
"not": {"$ref": "#"}
|
||||
},
|
||||
"default": true
|
||||
}
|
88
node_modules/schema-utils/node_modules/ajv/lib/refs/json-schema-secure.json
generated
vendored
Normal file
88
node_modules/schema-utils/node_modules/ajv/lib/refs/json-schema-secure.json
generated
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"$id": "https://raw.githubusercontent.com/ajv-validator/ajv/master/lib/refs/json-schema-secure.json#",
|
||||
"title": "Meta-schema for the security assessment of JSON Schemas",
|
||||
"description": "If a JSON AnySchema fails validation against this meta-schema, it may be unsafe to validate untrusted data",
|
||||
"definitions": {
|
||||
"schemaArray": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {"$ref": "#"}
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"patternProperties": {
|
||||
"description": "prevent slow validation of large property names",
|
||||
"required": ["propertyNames"],
|
||||
"properties": {
|
||||
"propertyNames": {
|
||||
"required": ["maxLength"]
|
||||
}
|
||||
}
|
||||
},
|
||||
"uniqueItems": {
|
||||
"description": "prevent slow validation of large non-scalar arrays",
|
||||
"if": {
|
||||
"properties": {
|
||||
"uniqueItems": {"const": true},
|
||||
"items": {
|
||||
"properties": {
|
||||
"type": {
|
||||
"anyOf": [
|
||||
{
|
||||
"enum": ["object", "array"]
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"contains": {"enum": ["object", "array"]}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"then": {
|
||||
"required": ["maxItems"]
|
||||
}
|
||||
},
|
||||
"pattern": {
|
||||
"description": "prevent slow pattern matching of large strings",
|
||||
"required": ["maxLength"]
|
||||
},
|
||||
"format": {
|
||||
"description": "prevent slow format validation of large strings",
|
||||
"required": ["maxLength"]
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"additionalItems": {"$ref": "#"},
|
||||
"additionalProperties": {"$ref": "#"},
|
||||
"dependencies": {
|
||||
"additionalProperties": {
|
||||
"anyOf": [{"type": "array"}, {"$ref": "#"}]
|
||||
}
|
||||
},
|
||||
"items": {
|
||||
"anyOf": [{"$ref": "#"}, {"$ref": "#/definitions/schemaArray"}]
|
||||
},
|
||||
"definitions": {
|
||||
"additionalProperties": {"$ref": "#"}
|
||||
},
|
||||
"patternProperties": {
|
||||
"additionalProperties": {"$ref": "#"}
|
||||
},
|
||||
"properties": {
|
||||
"additionalProperties": {"$ref": "#"}
|
||||
},
|
||||
"if": {"$ref": "#"},
|
||||
"then": {"$ref": "#"},
|
||||
"else": {"$ref": "#"},
|
||||
"allOf": {"$ref": "#/definitions/schemaArray"},
|
||||
"anyOf": {"$ref": "#/definitions/schemaArray"},
|
||||
"oneOf": {"$ref": "#/definitions/schemaArray"},
|
||||
"not": {"$ref": "#"},
|
||||
"contains": {"$ref": "#"},
|
||||
"propertyNames": {"$ref": "#"}
|
||||
}
|
||||
}
|
130
node_modules/schema-utils/node_modules/ajv/lib/refs/jtd-schema.ts
generated
vendored
Normal file
130
node_modules/schema-utils/node_modules/ajv/lib/refs/jtd-schema.ts
generated
vendored
Normal file
@@ -0,0 +1,130 @@
|
||||
import {SchemaObject} from "../types"
|
||||
|
||||
type MetaSchema = (root: boolean) => SchemaObject
|
||||
|
||||
const shared: MetaSchema = (root) => {
|
||||
const sch: SchemaObject = {
|
||||
nullable: {type: "boolean"},
|
||||
metadata: {
|
||||
optionalProperties: {
|
||||
union: {elements: {ref: "schema"}},
|
||||
},
|
||||
additionalProperties: true,
|
||||
},
|
||||
}
|
||||
if (root) sch.definitions = {values: {ref: "schema"}}
|
||||
return sch
|
||||
}
|
||||
|
||||
const emptyForm: MetaSchema = (root) => ({
|
||||
optionalProperties: shared(root),
|
||||
})
|
||||
|
||||
const refForm: MetaSchema = (root) => ({
|
||||
properties: {
|
||||
ref: {type: "string"},
|
||||
},
|
||||
optionalProperties: shared(root),
|
||||
})
|
||||
|
||||
const typeForm: MetaSchema = (root) => ({
|
||||
properties: {
|
||||
type: {
|
||||
enum: [
|
||||
"boolean",
|
||||
"timestamp",
|
||||
"string",
|
||||
"float32",
|
||||
"float64",
|
||||
"int8",
|
||||
"uint8",
|
||||
"int16",
|
||||
"uint16",
|
||||
"int32",
|
||||
"uint32",
|
||||
],
|
||||
},
|
||||
},
|
||||
optionalProperties: shared(root),
|
||||
})
|
||||
|
||||
const enumForm: MetaSchema = (root) => ({
|
||||
properties: {
|
||||
enum: {elements: {type: "string"}},
|
||||
},
|
||||
optionalProperties: shared(root),
|
||||
})
|
||||
|
||||
const elementsForm: MetaSchema = (root) => ({
|
||||
properties: {
|
||||
elements: {ref: "schema"},
|
||||
},
|
||||
optionalProperties: shared(root),
|
||||
})
|
||||
|
||||
const propertiesForm: MetaSchema = (root) => ({
|
||||
properties: {
|
||||
properties: {values: {ref: "schema"}},
|
||||
},
|
||||
optionalProperties: {
|
||||
optionalProperties: {values: {ref: "schema"}},
|
||||
additionalProperties: {type: "boolean"},
|
||||
...shared(root),
|
||||
},
|
||||
})
|
||||
|
||||
const optionalPropertiesForm: MetaSchema = (root) => ({
|
||||
properties: {
|
||||
optionalProperties: {values: {ref: "schema"}},
|
||||
},
|
||||
optionalProperties: {
|
||||
additionalProperties: {type: "boolean"},
|
||||
...shared(root),
|
||||
},
|
||||
})
|
||||
|
||||
const discriminatorForm: MetaSchema = (root) => ({
|
||||
properties: {
|
||||
discriminator: {type: "string"},
|
||||
mapping: {
|
||||
values: {
|
||||
metadata: {
|
||||
union: [propertiesForm(false), optionalPropertiesForm(false)],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
optionalProperties: shared(root),
|
||||
})
|
||||
|
||||
const valuesForm: MetaSchema = (root) => ({
|
||||
properties: {
|
||||
values: {ref: "schema"},
|
||||
},
|
||||
optionalProperties: shared(root),
|
||||
})
|
||||
|
||||
const schema: MetaSchema = (root) => ({
|
||||
metadata: {
|
||||
union: [
|
||||
emptyForm,
|
||||
refForm,
|
||||
typeForm,
|
||||
enumForm,
|
||||
elementsForm,
|
||||
propertiesForm,
|
||||
optionalPropertiesForm,
|
||||
discriminatorForm,
|
||||
valuesForm,
|
||||
].map((s) => s(root)),
|
||||
},
|
||||
})
|
||||
|
||||
const jtdMetaSchema: SchemaObject = {
|
||||
definitions: {
|
||||
schema: schema(false),
|
||||
},
|
||||
...schema(true),
|
||||
}
|
||||
|
||||
export default jtdMetaSchema
|
7
node_modules/schema-utils/node_modules/ajv/lib/runtime/equal.ts
generated
vendored
Normal file
7
node_modules/schema-utils/node_modules/ajv/lib/runtime/equal.ts
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
// https://github.com/ajv-validator/ajv/issues/889
|
||||
import * as equal from "fast-deep-equal"
|
||||
|
||||
type Equal = typeof equal & {code: string}
|
||||
;(equal as Equal).code = 'require("ajv/dist/runtime/equal").default'
|
||||
|
||||
export default equal as Equal
|
177
node_modules/schema-utils/node_modules/ajv/lib/runtime/parseJson.ts
generated
vendored
Normal file
177
node_modules/schema-utils/node_modules/ajv/lib/runtime/parseJson.ts
generated
vendored
Normal file
@@ -0,0 +1,177 @@
|
||||
const rxParseJson = /position\s(\d+)(?: \(line \d+ column \d+\))?$/
|
||||
|
||||
export function parseJson(s: string, pos: number): unknown {
|
||||
let endPos: number | undefined
|
||||
parseJson.message = undefined
|
||||
let matches: RegExpExecArray | null
|
||||
if (pos) s = s.slice(pos)
|
||||
try {
|
||||
parseJson.position = pos + s.length
|
||||
return JSON.parse(s)
|
||||
} catch (e) {
|
||||
matches = rxParseJson.exec((e as Error).message)
|
||||
if (!matches) {
|
||||
parseJson.message = "unexpected end"
|
||||
return undefined
|
||||
}
|
||||
endPos = +matches[1]
|
||||
const c = s[endPos]
|
||||
s = s.slice(0, endPos)
|
||||
parseJson.position = pos + endPos
|
||||
try {
|
||||
return JSON.parse(s)
|
||||
} catch (e1) {
|
||||
parseJson.message = `unexpected token ${c}`
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
parseJson.message = undefined as string | undefined
|
||||
parseJson.position = 0 as number
|
||||
parseJson.code = 'require("ajv/dist/runtime/parseJson").parseJson'
|
||||
|
||||
export function parseJsonNumber(s: string, pos: number, maxDigits?: number): number | undefined {
|
||||
let numStr = ""
|
||||
let c: string
|
||||
parseJsonNumber.message = undefined
|
||||
if (s[pos] === "-") {
|
||||
numStr += "-"
|
||||
pos++
|
||||
}
|
||||
if (s[pos] === "0") {
|
||||
numStr += "0"
|
||||
pos++
|
||||
} else {
|
||||
if (!parseDigits(maxDigits)) {
|
||||
errorMessage()
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
if (maxDigits) {
|
||||
parseJsonNumber.position = pos
|
||||
return +numStr
|
||||
}
|
||||
if (s[pos] === ".") {
|
||||
numStr += "."
|
||||
pos++
|
||||
if (!parseDigits()) {
|
||||
errorMessage()
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
if (((c = s[pos]), c === "e" || c === "E")) {
|
||||
numStr += "e"
|
||||
pos++
|
||||
if (((c = s[pos]), c === "+" || c === "-")) {
|
||||
numStr += c
|
||||
pos++
|
||||
}
|
||||
if (!parseDigits()) {
|
||||
errorMessage()
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
parseJsonNumber.position = pos
|
||||
return +numStr
|
||||
|
||||
function parseDigits(maxLen?: number): boolean {
|
||||
let digit = false
|
||||
while (((c = s[pos]), c >= "0" && c <= "9" && (maxLen === undefined || maxLen-- > 0))) {
|
||||
digit = true
|
||||
numStr += c
|
||||
pos++
|
||||
}
|
||||
return digit
|
||||
}
|
||||
|
||||
function errorMessage(): void {
|
||||
parseJsonNumber.position = pos
|
||||
parseJsonNumber.message = pos < s.length ? `unexpected token ${s[pos]}` : "unexpected end"
|
||||
}
|
||||
}
|
||||
|
||||
parseJsonNumber.message = undefined as string | undefined
|
||||
parseJsonNumber.position = 0 as number
|
||||
parseJsonNumber.code = 'require("ajv/dist/runtime/parseJson").parseJsonNumber'
|
||||
|
||||
const escapedChars: {[X in string]?: string} = {
|
||||
b: "\b",
|
||||
f: "\f",
|
||||
n: "\n",
|
||||
r: "\r",
|
||||
t: "\t",
|
||||
'"': '"',
|
||||
"/": "/",
|
||||
"\\": "\\",
|
||||
}
|
||||
|
||||
const CODE_A: number = "a".charCodeAt(0)
|
||||
const CODE_0: number = "0".charCodeAt(0)
|
||||
|
||||
export function parseJsonString(s: string, pos: number): string | undefined {
|
||||
let str = ""
|
||||
let c: string | undefined
|
||||
parseJsonString.message = undefined
|
||||
// eslint-disable-next-line no-constant-condition, @typescript-eslint/no-unnecessary-condition
|
||||
while (true) {
|
||||
c = s[pos++]
|
||||
if (c === '"') break
|
||||
if (c === "\\") {
|
||||
c = s[pos]
|
||||
if (c in escapedChars) {
|
||||
str += escapedChars[c]
|
||||
pos++
|
||||
} else if (c === "u") {
|
||||
pos++
|
||||
let count = 4
|
||||
let code = 0
|
||||
while (count--) {
|
||||
code <<= 4
|
||||
c = s[pos]
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||
if (c === undefined) {
|
||||
errorMessage("unexpected end")
|
||||
return undefined
|
||||
}
|
||||
c = c.toLowerCase()
|
||||
if (c >= "a" && c <= "f") {
|
||||
code += c.charCodeAt(0) - CODE_A + 10
|
||||
} else if (c >= "0" && c <= "9") {
|
||||
code += c.charCodeAt(0) - CODE_0
|
||||
} else {
|
||||
errorMessage(`unexpected token ${c}`)
|
||||
return undefined
|
||||
}
|
||||
pos++
|
||||
}
|
||||
str += String.fromCharCode(code)
|
||||
} else {
|
||||
errorMessage(`unexpected token ${c}`)
|
||||
return undefined
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||
} else if (c === undefined) {
|
||||
errorMessage("unexpected end")
|
||||
return undefined
|
||||
} else {
|
||||
if (c.charCodeAt(0) >= 0x20) {
|
||||
str += c
|
||||
} else {
|
||||
errorMessage(`unexpected token ${c}`)
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
parseJsonString.position = pos
|
||||
return str
|
||||
|
||||
function errorMessage(msg: string): void {
|
||||
parseJsonString.position = pos
|
||||
parseJsonString.message = msg
|
||||
}
|
||||
}
|
||||
|
||||
parseJsonString.message = undefined as string | undefined
|
||||
parseJsonString.position = 0 as number
|
||||
parseJsonString.code = 'require("ajv/dist/runtime/parseJson").parseJsonString'
|
31
node_modules/schema-utils/node_modules/ajv/lib/runtime/quote.ts
generated
vendored
Normal file
31
node_modules/schema-utils/node_modules/ajv/lib/runtime/quote.ts
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
const rxEscapable =
|
||||
// eslint-disable-next-line no-control-regex, no-misleading-character-class
|
||||
/[\\"\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g
|
||||
|
||||
const escaped: {[K in string]?: string} = {
|
||||
"\b": "\\b",
|
||||
"\t": "\\t",
|
||||
"\n": "\\n",
|
||||
"\f": "\\f",
|
||||
"\r": "\\r",
|
||||
'"': '\\"',
|
||||
"\\": "\\\\",
|
||||
}
|
||||
|
||||
export default function quote(s: string): string {
|
||||
rxEscapable.lastIndex = 0
|
||||
return (
|
||||
'"' +
|
||||
(rxEscapable.test(s)
|
||||
? s.replace(rxEscapable, (a) => {
|
||||
const c = escaped[a]
|
||||
return typeof c === "string"
|
||||
? c
|
||||
: "\\u" + ("0000" + a.charCodeAt(0).toString(16)).slice(-4)
|
||||
})
|
||||
: s) +
|
||||
'"'
|
||||
)
|
||||
}
|
||||
|
||||
quote.code = 'require("ajv/dist/runtime/quote").default'
|
6
node_modules/schema-utils/node_modules/ajv/lib/runtime/re2.ts
generated
vendored
Normal file
6
node_modules/schema-utils/node_modules/ajv/lib/runtime/re2.ts
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
import * as re2 from "re2"
|
||||
|
||||
type Re2 = typeof re2 & {code: string}
|
||||
;(re2 as Re2).code = 'require("ajv/dist/runtime/re2").default'
|
||||
|
||||
export default re2 as Re2
|
46
node_modules/schema-utils/node_modules/ajv/lib/runtime/timestamp.ts
generated
vendored
Normal file
46
node_modules/schema-utils/node_modules/ajv/lib/runtime/timestamp.ts
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
const DT_SEPARATOR = /t|\s/i
|
||||
const DATE = /^(\d\d\d\d)-(\d\d)-(\d\d)$/
|
||||
const TIME = /^(\d\d):(\d\d):(\d\d)(?:\.\d+)?(?:z|([+-]\d\d)(?::?(\d\d))?)$/i
|
||||
const DAYS = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
|
||||
|
||||
export default function validTimestamp(str: string, allowDate: boolean): boolean {
|
||||
// http://tools.ietf.org/html/rfc3339#section-5.6
|
||||
const dt: string[] = str.split(DT_SEPARATOR)
|
||||
return (
|
||||
(dt.length === 2 && validDate(dt[0]) && validTime(dt[1])) ||
|
||||
(allowDate && dt.length === 1 && validDate(dt[0]))
|
||||
)
|
||||
}
|
||||
|
||||
function validDate(str: string): boolean {
|
||||
const matches: string[] | null = DATE.exec(str)
|
||||
if (!matches) return false
|
||||
const y: number = +matches[1]
|
||||
const m: number = +matches[2]
|
||||
const d: number = +matches[3]
|
||||
return (
|
||||
m >= 1 &&
|
||||
m <= 12 &&
|
||||
d >= 1 &&
|
||||
(d <= DAYS[m] ||
|
||||
// leap year: https://tools.ietf.org/html/rfc3339#appendix-C
|
||||
(m === 2 && d === 29 && (y % 100 === 0 ? y % 400 === 0 : y % 4 === 0)))
|
||||
)
|
||||
}
|
||||
|
||||
function validTime(str: string): boolean {
|
||||
const matches: string[] | null = TIME.exec(str)
|
||||
if (!matches) return false
|
||||
const hr: number = +matches[1]
|
||||
const min: number = +matches[2]
|
||||
const sec: number = +matches[3]
|
||||
const tzH: number = +(matches[4] || 0)
|
||||
const tzM: number = +(matches[5] || 0)
|
||||
return (
|
||||
(hr <= 23 && min <= 59 && sec <= 59) ||
|
||||
// leap second
|
||||
(hr - tzH === 23 && min - tzM === 59 && sec === 60)
|
||||
)
|
||||
}
|
||||
|
||||
validTimestamp.code = 'require("ajv/dist/runtime/timestamp").default'
|
20
node_modules/schema-utils/node_modules/ajv/lib/runtime/ucs2length.ts
generated
vendored
Normal file
20
node_modules/schema-utils/node_modules/ajv/lib/runtime/ucs2length.ts
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
// https://mathiasbynens.be/notes/javascript-encoding
|
||||
// https://github.com/bestiejs/punycode.js - punycode.ucs2.decode
|
||||
export default function ucs2length(str: string): number {
|
||||
const len = str.length
|
||||
let length = 0
|
||||
let pos = 0
|
||||
let value: number
|
||||
while (pos < len) {
|
||||
length++
|
||||
value = str.charCodeAt(pos++)
|
||||
if (value >= 0xd800 && value <= 0xdbff && pos < len) {
|
||||
// high surrogate, and there is a next character
|
||||
value = str.charCodeAt(pos)
|
||||
if ((value & 0xfc00) === 0xdc00) pos++ // low surrogate
|
||||
}
|
||||
}
|
||||
return length
|
||||
}
|
||||
|
||||
ucs2length.code = 'require("ajv/dist/runtime/ucs2length").default'
|
6
node_modules/schema-utils/node_modules/ajv/lib/runtime/uri.ts
generated
vendored
Normal file
6
node_modules/schema-utils/node_modules/ajv/lib/runtime/uri.ts
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
import * as uri from "fast-uri"
|
||||
|
||||
type URI = typeof uri & {code: string}
|
||||
;(uri as URI).code = 'require("ajv/dist/runtime/uri").default'
|
||||
|
||||
export default uri as URI
|
13
node_modules/schema-utils/node_modules/ajv/lib/runtime/validation_error.ts
generated
vendored
Normal file
13
node_modules/schema-utils/node_modules/ajv/lib/runtime/validation_error.ts
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
import type {ErrorObject} from "../types"
|
||||
|
||||
export default class ValidationError extends Error {
|
||||
readonly errors: Partial<ErrorObject>[]
|
||||
readonly ajv: true
|
||||
readonly validation: true
|
||||
|
||||
constructor(errors: Partial<ErrorObject>[]) {
|
||||
super("validation failed")
|
||||
this.errors = errors
|
||||
this.ajv = this.validation = true
|
||||
}
|
||||
}
|
100
node_modules/schema-utils/node_modules/ajv/lib/standalone/index.ts
generated
vendored
Normal file
100
node_modules/schema-utils/node_modules/ajv/lib/standalone/index.ts
generated
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
import type AjvCore from "../core"
|
||||
import type {AnyValidateFunction, SourceCode} from "../types"
|
||||
import type {SchemaEnv} from "../compile"
|
||||
import {UsedScopeValues, UsedValueState, ValueScopeName, varKinds} from "../compile/codegen/scope"
|
||||
import {_, nil, _Code, Code, getProperty, getEsmExportName} from "../compile/codegen/code"
|
||||
|
||||
function standaloneCode(
|
||||
ajv: AjvCore,
|
||||
refsOrFunc?: {[K in string]?: string} | AnyValidateFunction
|
||||
): string {
|
||||
if (!ajv.opts.code.source) {
|
||||
throw new Error("moduleCode: ajv instance must have code.source option")
|
||||
}
|
||||
const {_n} = ajv.scope.opts
|
||||
return typeof refsOrFunc == "function"
|
||||
? funcExportCode(refsOrFunc.source)
|
||||
: refsOrFunc !== undefined
|
||||
? multiExportsCode<string>(refsOrFunc, getValidate)
|
||||
: multiExportsCode<SchemaEnv>(ajv.schemas, (sch) =>
|
||||
sch.meta ? undefined : ajv.compile(sch.schema)
|
||||
)
|
||||
|
||||
function getValidate(id: string): AnyValidateFunction {
|
||||
const v = ajv.getSchema(id)
|
||||
if (!v) throw new Error(`moduleCode: no schema with id ${id}`)
|
||||
return v
|
||||
}
|
||||
|
||||
function funcExportCode(source?: SourceCode): string {
|
||||
const usedValues: UsedScopeValues = {}
|
||||
const n = source?.validateName
|
||||
const vCode = validateCode(usedValues, source)
|
||||
if (ajv.opts.code.esm) {
|
||||
// Always do named export as `validate` rather than the variable `n` which is `validateXX` for known export value
|
||||
return `"use strict";${_n}export const validate = ${n};${_n}export default ${n};${_n}${vCode}`
|
||||
}
|
||||
return `"use strict";${_n}module.exports = ${n};${_n}module.exports.default = ${n};${_n}${vCode}`
|
||||
}
|
||||
|
||||
function multiExportsCode<T extends SchemaEnv | string>(
|
||||
schemas: {[K in string]?: T},
|
||||
getValidateFunc: (schOrId: T) => AnyValidateFunction | undefined
|
||||
): string {
|
||||
const usedValues: UsedScopeValues = {}
|
||||
let code = _`"use strict";`
|
||||
for (const name in schemas) {
|
||||
const v = getValidateFunc(schemas[name] as T)
|
||||
if (v) {
|
||||
const vCode = validateCode(usedValues, v.source)
|
||||
const exportSyntax = ajv.opts.code.esm
|
||||
? _`export const ${getEsmExportName(name)}`
|
||||
: _`exports${getProperty(name)}`
|
||||
code = _`${code}${_n}${exportSyntax} = ${v.source?.validateName};${_n}${vCode}`
|
||||
}
|
||||
}
|
||||
return `${code}`
|
||||
}
|
||||
|
||||
function validateCode(usedValues: UsedScopeValues, s?: SourceCode): Code {
|
||||
if (!s) throw new Error('moduleCode: function does not have "source" property')
|
||||
if (usedState(s.validateName) === UsedValueState.Completed) return nil
|
||||
setUsedState(s.validateName, UsedValueState.Started)
|
||||
|
||||
const scopeCode = ajv.scope.scopeCode(s.scopeValues, usedValues, refValidateCode)
|
||||
const code = new _Code(`${scopeCode}${_n}${s.validateCode}`)
|
||||
return s.evaluated ? _`${code}${s.validateName}.evaluated = ${s.evaluated};${_n}` : code
|
||||
|
||||
function refValidateCode(n: ValueScopeName): Code | undefined {
|
||||
const vRef = n.value?.ref
|
||||
if (n.prefix === "validate" && typeof vRef == "function") {
|
||||
const v = vRef as AnyValidateFunction
|
||||
return validateCode(usedValues, v.source)
|
||||
} else if ((n.prefix === "root" || n.prefix === "wrapper") && typeof vRef == "object") {
|
||||
const {validate, validateName} = vRef as SchemaEnv
|
||||
if (!validateName) throw new Error("ajv internal error")
|
||||
const def = ajv.opts.code.es5 ? varKinds.var : varKinds.const
|
||||
const wrapper = _`${def} ${n} = {validate: ${validateName}};`
|
||||
if (usedState(validateName) === UsedValueState.Started) return wrapper
|
||||
const vCode = validateCode(usedValues, validate?.source)
|
||||
return _`${wrapper}${_n}${vCode}`
|
||||
}
|
||||
return undefined
|
||||
}
|
||||
|
||||
function usedState(name: ValueScopeName): UsedValueState | undefined {
|
||||
return usedValues[name.prefix]?.get(name)
|
||||
}
|
||||
|
||||
function setUsedState(name: ValueScopeName, state: UsedValueState): void {
|
||||
const {prefix} = name
|
||||
const names = (usedValues[prefix] = usedValues[prefix] || new Map())
|
||||
names.set(name, state)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = exports = standaloneCode
|
||||
Object.defineProperty(exports, "__esModule", {value: true})
|
||||
|
||||
export default standaloneCode
|
36
node_modules/schema-utils/node_modules/ajv/lib/standalone/instance.ts
generated
vendored
Normal file
36
node_modules/schema-utils/node_modules/ajv/lib/standalone/instance.ts
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
import Ajv, {AnySchema, AnyValidateFunction, ErrorObject} from "../core"
|
||||
import standaloneCode from "."
|
||||
import * as requireFromString from "require-from-string"
|
||||
|
||||
export default class AjvPack {
|
||||
errors?: ErrorObject[] | null // errors from the last validation
|
||||
constructor(readonly ajv: Ajv) {}
|
||||
|
||||
validate(schemaKeyRef: AnySchema | string, data: unknown): boolean | Promise<unknown> {
|
||||
return Ajv.prototype.validate.call(this, schemaKeyRef, data)
|
||||
}
|
||||
|
||||
compile<T = unknown>(schema: AnySchema, meta?: boolean): AnyValidateFunction<T> {
|
||||
return this.getStandalone(this.ajv.compile<T>(schema, meta))
|
||||
}
|
||||
|
||||
getSchema<T = unknown>(keyRef: string): AnyValidateFunction<T> | undefined {
|
||||
const v = this.ajv.getSchema<T>(keyRef)
|
||||
if (!v) return undefined
|
||||
return this.getStandalone(v)
|
||||
}
|
||||
|
||||
private getStandalone<T = unknown>(v: AnyValidateFunction<T>): AnyValidateFunction<T> {
|
||||
return requireFromString(standaloneCode(this.ajv, v)) as AnyValidateFunction<T>
|
||||
}
|
||||
|
||||
addSchema(...args: Parameters<typeof Ajv.prototype.addSchema>): AjvPack {
|
||||
this.ajv.addSchema.call(this.ajv, ...args)
|
||||
return this
|
||||
}
|
||||
|
||||
addKeyword(...args: Parameters<typeof Ajv.prototype.addKeyword>): AjvPack {
|
||||
this.ajv.addKeyword.call(this.ajv, ...args)
|
||||
return this
|
||||
}
|
||||
}
|
244
node_modules/schema-utils/node_modules/ajv/lib/types/index.ts
generated
vendored
Normal file
244
node_modules/schema-utils/node_modules/ajv/lib/types/index.ts
generated
vendored
Normal file
@@ -0,0 +1,244 @@
|
||||
import {URIComponent} from "fast-uri"
|
||||
import type {CodeGen, Code, Name, ScopeValueSets, ValueScopeName} from "../compile/codegen"
|
||||
import type {SchemaEnv, SchemaCxt, SchemaObjCxt} from "../compile"
|
||||
import type {JSONType} from "../compile/rules"
|
||||
import type {KeywordCxt} from "../compile/validate"
|
||||
import type Ajv from "../core"
|
||||
|
||||
interface _SchemaObject {
|
||||
id?: string
|
||||
$id?: string
|
||||
$schema?: string
|
||||
[x: string]: any // TODO
|
||||
}
|
||||
|
||||
export interface SchemaObject extends _SchemaObject {
|
||||
id?: string
|
||||
$id?: string
|
||||
$schema?: string
|
||||
$async?: false
|
||||
[x: string]: any // TODO
|
||||
}
|
||||
|
||||
export interface AsyncSchema extends _SchemaObject {
|
||||
$async: true
|
||||
}
|
||||
|
||||
export type AnySchemaObject = SchemaObject | AsyncSchema
|
||||
|
||||
export type Schema = SchemaObject | boolean
|
||||
|
||||
export type AnySchema = Schema | AsyncSchema
|
||||
|
||||
export type SchemaMap = {[Key in string]?: AnySchema}
|
||||
|
||||
export interface SourceCode {
|
||||
validateName: ValueScopeName
|
||||
validateCode: string
|
||||
scopeValues: ScopeValueSets
|
||||
evaluated?: Code
|
||||
}
|
||||
|
||||
export interface DataValidationCxt<T extends string | number = string | number> {
|
||||
instancePath: string
|
||||
parentData: {[K in T]: any} // object or array
|
||||
parentDataProperty: T // string or number
|
||||
rootData: Record<string, any> | any[]
|
||||
dynamicAnchors: {[Ref in string]?: ValidateFunction}
|
||||
}
|
||||
|
||||
export interface ValidateFunction<T = unknown> {
|
||||
// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents
|
||||
(this: Ajv | any, data: any, dataCxt?: DataValidationCxt): data is T
|
||||
errors?: null | ErrorObject[]
|
||||
evaluated?: Evaluated
|
||||
schema: AnySchema
|
||||
schemaEnv: SchemaEnv
|
||||
source?: SourceCode
|
||||
}
|
||||
|
||||
export interface JTDParser<T = unknown> {
|
||||
(json: string): T | undefined
|
||||
message?: string
|
||||
position?: number
|
||||
}
|
||||
|
||||
export type EvaluatedProperties = {[K in string]?: true} | true
|
||||
|
||||
export type EvaluatedItems = number | true
|
||||
|
||||
export interface Evaluated {
|
||||
// determined at compile time if staticProps/Items is true
|
||||
props?: EvaluatedProperties
|
||||
items?: EvaluatedItems
|
||||
// whether props/items determined at compile time
|
||||
dynamicProps: boolean
|
||||
dynamicItems: boolean
|
||||
}
|
||||
|
||||
export interface AsyncValidateFunction<T = unknown> extends ValidateFunction<T> {
|
||||
(...args: Parameters<ValidateFunction<T>>): Promise<T>
|
||||
$async: true
|
||||
}
|
||||
|
||||
export type AnyValidateFunction<T = any> = ValidateFunction<T> | AsyncValidateFunction<T>
|
||||
|
||||
export interface ErrorObject<K extends string = string, P = Record<string, any>, S = unknown> {
|
||||
keyword: K
|
||||
instancePath: string
|
||||
schemaPath: string
|
||||
params: P
|
||||
// Added to validation errors of "propertyNames" keyword schema
|
||||
propertyName?: string
|
||||
// Excluded if option `messages` set to false.
|
||||
message?: string
|
||||
// These are added with the `verbose` option.
|
||||
schema?: S
|
||||
parentSchema?: AnySchemaObject
|
||||
data?: unknown
|
||||
}
|
||||
|
||||
export type ErrorNoParams<K extends string, S = unknown> = ErrorObject<K, Record<string, never>, S>
|
||||
|
||||
interface _KeywordDef {
|
||||
keyword: string | string[]
|
||||
type?: JSONType | JSONType[] // data types that keyword applies to
|
||||
schemaType?: JSONType | JSONType[] // allowed type(s) of keyword value in the schema
|
||||
allowUndefined?: boolean // used for keywords that can be invoked by other keywords, not being present in the schema
|
||||
$data?: boolean // keyword supports [$data reference](../../docs/guide/combining-schemas.md#data-reference)
|
||||
implements?: string[] // other schema keywords that this keyword implements
|
||||
before?: string // keyword should be executed before this keyword (should be applicable to the same type)
|
||||
post?: boolean // keyword should be executed after other keywords without post flag
|
||||
metaSchema?: AnySchemaObject // meta-schema for keyword schema value - it is better to use schemaType where applicable
|
||||
validateSchema?: AnyValidateFunction // compiled keyword metaSchema - should not be passed
|
||||
dependencies?: string[] // keywords that must be present in the same schema
|
||||
error?: KeywordErrorDefinition
|
||||
$dataError?: KeywordErrorDefinition
|
||||
}
|
||||
|
||||
export interface CodeKeywordDefinition extends _KeywordDef {
|
||||
code: (cxt: KeywordCxt, ruleType?: string) => void
|
||||
trackErrors?: boolean
|
||||
}
|
||||
|
||||
export type MacroKeywordFunc = (
|
||||
schema: any,
|
||||
parentSchema: AnySchemaObject,
|
||||
it: SchemaCxt
|
||||
) => AnySchema
|
||||
|
||||
export type CompileKeywordFunc = (
|
||||
schema: any,
|
||||
parentSchema: AnySchemaObject,
|
||||
it: SchemaObjCxt
|
||||
) => DataValidateFunction
|
||||
|
||||
export interface DataValidateFunction {
|
||||
(...args: Parameters<ValidateFunction>): boolean | Promise<any>
|
||||
errors?: Partial<ErrorObject>[]
|
||||
}
|
||||
|
||||
export interface SchemaValidateFunction {
|
||||
(
|
||||
schema: any,
|
||||
data: any,
|
||||
parentSchema?: AnySchemaObject,
|
||||
dataCxt?: DataValidationCxt
|
||||
): boolean | Promise<any>
|
||||
errors?: Partial<ErrorObject>[]
|
||||
}
|
||||
|
||||
export interface FuncKeywordDefinition extends _KeywordDef {
|
||||
validate?: SchemaValidateFunction | DataValidateFunction
|
||||
compile?: CompileKeywordFunc
|
||||
// schema: false makes validate not to expect schema (DataValidateFunction)
|
||||
schema?: boolean // requires "validate"
|
||||
modifying?: boolean
|
||||
async?: boolean
|
||||
valid?: boolean
|
||||
errors?: boolean | "full"
|
||||
}
|
||||
|
||||
export interface MacroKeywordDefinition extends FuncKeywordDefinition {
|
||||
macro: MacroKeywordFunc
|
||||
}
|
||||
|
||||
export type KeywordDefinition =
|
||||
| CodeKeywordDefinition
|
||||
| FuncKeywordDefinition
|
||||
| MacroKeywordDefinition
|
||||
|
||||
export type AddedKeywordDefinition = KeywordDefinition & {
|
||||
type: JSONType[]
|
||||
schemaType: JSONType[]
|
||||
}
|
||||
|
||||
export interface KeywordErrorDefinition {
|
||||
message: string | Code | ((cxt: KeywordErrorCxt) => string | Code)
|
||||
params?: Code | ((cxt: KeywordErrorCxt) => Code)
|
||||
}
|
||||
|
||||
export type Vocabulary = (KeywordDefinition | string)[]
|
||||
|
||||
export interface KeywordErrorCxt {
|
||||
gen: CodeGen
|
||||
keyword: string
|
||||
data: Name
|
||||
$data?: string | false
|
||||
schema: any // TODO
|
||||
parentSchema?: AnySchemaObject
|
||||
schemaCode: Code | number | boolean
|
||||
schemaValue: Code | number | boolean
|
||||
schemaType?: JSONType[]
|
||||
errsCount?: Name
|
||||
params: KeywordCxtParams
|
||||
it: SchemaCxt
|
||||
}
|
||||
|
||||
export type KeywordCxtParams = {[P in string]?: Code | string | number}
|
||||
|
||||
export type FormatValidator<T extends string | number> = (data: T) => boolean
|
||||
|
||||
export type FormatCompare<T extends string | number> = (data1: T, data2: T) => number | undefined
|
||||
|
||||
export type AsyncFormatValidator<T extends string | number> = (data: T) => Promise<boolean>
|
||||
|
||||
export interface FormatDefinition<T extends string | number> {
|
||||
type?: T extends string ? "string" | undefined : "number"
|
||||
validate: FormatValidator<T> | (T extends string ? string | RegExp : never)
|
||||
async?: false | undefined
|
||||
compare?: FormatCompare<T>
|
||||
}
|
||||
|
||||
export interface AsyncFormatDefinition<T extends string | number> {
|
||||
type?: T extends string ? "string" | undefined : "number"
|
||||
validate: AsyncFormatValidator<T>
|
||||
async: true
|
||||
compare?: FormatCompare<T>
|
||||
}
|
||||
|
||||
export type AddedFormat =
|
||||
| true
|
||||
| RegExp
|
||||
| FormatValidator<string>
|
||||
| FormatDefinition<string>
|
||||
| FormatDefinition<number>
|
||||
| AsyncFormatDefinition<string>
|
||||
| AsyncFormatDefinition<number>
|
||||
|
||||
export type Format = AddedFormat | string
|
||||
|
||||
export interface RegExpEngine {
|
||||
(pattern: string, u: string): RegExpLike
|
||||
code: string
|
||||
}
|
||||
|
||||
export interface RegExpLike {
|
||||
test: (s: string) => boolean
|
||||
}
|
||||
|
||||
export interface UriResolver {
|
||||
parse(uri: string): URIComponent
|
||||
resolve(base: string, path: string): string
|
||||
serialize(component: URIComponent): string
|
||||
}
|
187
node_modules/schema-utils/node_modules/ajv/lib/types/json-schema.ts
generated
vendored
Normal file
187
node_modules/schema-utils/node_modules/ajv/lib/types/json-schema.ts
generated
vendored
Normal file
@@ -0,0 +1,187 @@
|
||||
/* eslint-disable @typescript-eslint/no-empty-interface */
|
||||
type StrictNullChecksWrapper<Name extends string, Type> = undefined extends null
|
||||
? `strictNullChecks must be true in tsconfig to use ${Name}`
|
||||
: Type
|
||||
|
||||
type UnionToIntersection<U> = (U extends any ? (_: U) => void : never) extends (_: infer I) => void
|
||||
? I
|
||||
: never
|
||||
|
||||
export type SomeJSONSchema = UncheckedJSONSchemaType<Known, true>
|
||||
|
||||
type UncheckedPartialSchema<T> = Partial<UncheckedJSONSchemaType<T, true>>
|
||||
|
||||
export type PartialSchema<T> = StrictNullChecksWrapper<"PartialSchema", UncheckedPartialSchema<T>>
|
||||
|
||||
type JSONType<T extends string, IsPartial extends boolean> = IsPartial extends true
|
||||
? T | undefined
|
||||
: T
|
||||
|
||||
interface NumberKeywords {
|
||||
minimum?: number
|
||||
maximum?: number
|
||||
exclusiveMinimum?: number
|
||||
exclusiveMaximum?: number
|
||||
multipleOf?: number
|
||||
format?: string
|
||||
}
|
||||
|
||||
interface StringKeywords {
|
||||
minLength?: number
|
||||
maxLength?: number
|
||||
pattern?: string
|
||||
format?: string
|
||||
}
|
||||
|
||||
type UncheckedJSONSchemaType<T, IsPartial extends boolean> = (
|
||||
| // these two unions allow arbitrary unions of types
|
||||
{
|
||||
anyOf: readonly UncheckedJSONSchemaType<T, IsPartial>[]
|
||||
}
|
||||
| {
|
||||
oneOf: readonly UncheckedJSONSchemaType<T, IsPartial>[]
|
||||
}
|
||||
// this union allows for { type: (primitive)[] } style schemas
|
||||
| ({
|
||||
type: readonly (T extends number
|
||||
? JSONType<"number" | "integer", IsPartial>
|
||||
: T extends string
|
||||
? JSONType<"string", IsPartial>
|
||||
: T extends boolean
|
||||
? JSONType<"boolean", IsPartial>
|
||||
: never)[]
|
||||
} & UnionToIntersection<
|
||||
T extends number
|
||||
? NumberKeywords
|
||||
: T extends string
|
||||
? StringKeywords
|
||||
: T extends boolean
|
||||
? // eslint-disable-next-line @typescript-eslint/ban-types
|
||||
{}
|
||||
: never
|
||||
>)
|
||||
// this covers "normal" types; it's last so typescript looks to it first for errors
|
||||
| ((T extends number
|
||||
? {
|
||||
type: JSONType<"number" | "integer", IsPartial>
|
||||
} & NumberKeywords
|
||||
: T extends string
|
||||
? {
|
||||
type: JSONType<"string", IsPartial>
|
||||
} & StringKeywords
|
||||
: T extends boolean
|
||||
? {
|
||||
type: JSONType<"boolean", IsPartial>
|
||||
}
|
||||
: T extends readonly [any, ...any[]]
|
||||
? {
|
||||
// JSON AnySchema for tuple
|
||||
type: JSONType<"array", IsPartial>
|
||||
items: {
|
||||
readonly [K in keyof T]-?: UncheckedJSONSchemaType<T[K], false> & Nullable<T[K]>
|
||||
} & {length: T["length"]}
|
||||
minItems: T["length"]
|
||||
} & ({maxItems: T["length"]} | {additionalItems: false})
|
||||
: T extends readonly any[]
|
||||
? {
|
||||
type: JSONType<"array", IsPartial>
|
||||
items: UncheckedJSONSchemaType<T[0], false>
|
||||
contains?: UncheckedPartialSchema<T[0]>
|
||||
minItems?: number
|
||||
maxItems?: number
|
||||
minContains?: number
|
||||
maxContains?: number
|
||||
uniqueItems?: true
|
||||
additionalItems?: never
|
||||
}
|
||||
: T extends Record<string, any>
|
||||
? {
|
||||
// JSON AnySchema for records and dictionaries
|
||||
// "required" is not optional because it is often forgotten
|
||||
// "properties" are optional for more concise dictionary schemas
|
||||
// "patternProperties" and can be only used with interfaces that have string index
|
||||
type: JSONType<"object", IsPartial>
|
||||
additionalProperties?: boolean | UncheckedJSONSchemaType<T[string], false>
|
||||
unevaluatedProperties?: boolean | UncheckedJSONSchemaType<T[string], false>
|
||||
properties?: IsPartial extends true
|
||||
? Partial<UncheckedPropertiesSchema<T>>
|
||||
: UncheckedPropertiesSchema<T>
|
||||
patternProperties?: Record<string, UncheckedJSONSchemaType<T[string], false>>
|
||||
propertyNames?: Omit<UncheckedJSONSchemaType<string, false>, "type"> & {type?: "string"}
|
||||
dependencies?: {[K in keyof T]?: readonly (keyof T)[] | UncheckedPartialSchema<T>}
|
||||
dependentRequired?: {[K in keyof T]?: readonly (keyof T)[]}
|
||||
dependentSchemas?: {[K in keyof T]?: UncheckedPartialSchema<T>}
|
||||
minProperties?: number
|
||||
maxProperties?: number
|
||||
} & (IsPartial extends true // "required" is not necessary if it's a non-partial type with no required keys // are listed it only asserts that optional cannot be listed. // "required" type does not guarantee that all required properties
|
||||
? {required: readonly (keyof T)[]}
|
||||
: [UncheckedRequiredMembers<T>] extends [never]
|
||||
? {required?: readonly UncheckedRequiredMembers<T>[]}
|
||||
: {required: readonly UncheckedRequiredMembers<T>[]})
|
||||
: T extends null
|
||||
? {
|
||||
type: JSONType<"null", IsPartial>
|
||||
nullable: true
|
||||
}
|
||||
: never) & {
|
||||
allOf?: readonly UncheckedPartialSchema<T>[]
|
||||
anyOf?: readonly UncheckedPartialSchema<T>[]
|
||||
oneOf?: readonly UncheckedPartialSchema<T>[]
|
||||
if?: UncheckedPartialSchema<T>
|
||||
then?: UncheckedPartialSchema<T>
|
||||
else?: UncheckedPartialSchema<T>
|
||||
not?: UncheckedPartialSchema<T>
|
||||
})
|
||||
) & {
|
||||
[keyword: string]: any
|
||||
$id?: string
|
||||
$ref?: string
|
||||
$defs?: Record<string, UncheckedJSONSchemaType<Known, true>>
|
||||
definitions?: Record<string, UncheckedJSONSchemaType<Known, true>>
|
||||
}
|
||||
|
||||
export type JSONSchemaType<T> = StrictNullChecksWrapper<
|
||||
"JSONSchemaType",
|
||||
UncheckedJSONSchemaType<T, false>
|
||||
>
|
||||
|
||||
type Known =
|
||||
| {[key: string]: Known}
|
||||
| [Known, ...Known[]]
|
||||
| Known[]
|
||||
| number
|
||||
| string
|
||||
| boolean
|
||||
| null
|
||||
|
||||
type UncheckedPropertiesSchema<T> = {
|
||||
[K in keyof T]-?: (UncheckedJSONSchemaType<T[K], false> & Nullable<T[K]>) | {$ref: string}
|
||||
}
|
||||
|
||||
export type PropertiesSchema<T> = StrictNullChecksWrapper<
|
||||
"PropertiesSchema",
|
||||
UncheckedPropertiesSchema<T>
|
||||
>
|
||||
|
||||
type UncheckedRequiredMembers<T> = {
|
||||
[K in keyof T]-?: undefined extends T[K] ? never : K
|
||||
}[keyof T]
|
||||
|
||||
export type RequiredMembers<T> = StrictNullChecksWrapper<
|
||||
"RequiredMembers",
|
||||
UncheckedRequiredMembers<T>
|
||||
>
|
||||
|
||||
type Nullable<T> = undefined extends T
|
||||
? {
|
||||
nullable: true
|
||||
const?: null // any non-null value would fail `const: null`, `null` would fail any other value in const
|
||||
enum?: readonly (T | null)[] // `null` must be explicitly included in "enum" for `null` to pass
|
||||
default?: T | null
|
||||
}
|
||||
: {
|
||||
nullable?: false
|
||||
const?: T
|
||||
enum?: readonly T[]
|
||||
default?: T
|
||||
}
|
273
node_modules/schema-utils/node_modules/ajv/lib/types/jtd-schema.ts
generated
vendored
Normal file
273
node_modules/schema-utils/node_modules/ajv/lib/types/jtd-schema.ts
generated
vendored
Normal file
@@ -0,0 +1,273 @@
|
||||
/** numeric strings */
|
||||
type NumberType = "float32" | "float64" | "int8" | "uint8" | "int16" | "uint16" | "int32" | "uint32"
|
||||
|
||||
/** string strings */
|
||||
type StringType = "string" | "timestamp"
|
||||
|
||||
/** Generic JTD Schema without inference of the represented type */
|
||||
export type SomeJTDSchemaType = (
|
||||
| // ref
|
||||
{ref: string}
|
||||
// primitives
|
||||
| {type: NumberType | StringType | "boolean"}
|
||||
// enum
|
||||
| {enum: string[]}
|
||||
// elements
|
||||
| {elements: SomeJTDSchemaType}
|
||||
// values
|
||||
| {values: SomeJTDSchemaType}
|
||||
// properties
|
||||
| {
|
||||
properties: Record<string, SomeJTDSchemaType>
|
||||
optionalProperties?: Record<string, SomeJTDSchemaType>
|
||||
additionalProperties?: boolean
|
||||
}
|
||||
| {
|
||||
properties?: Record<string, SomeJTDSchemaType>
|
||||
optionalProperties: Record<string, SomeJTDSchemaType>
|
||||
additionalProperties?: boolean
|
||||
}
|
||||
// discriminator
|
||||
| {discriminator: string; mapping: Record<string, SomeJTDSchemaType>}
|
||||
// empty
|
||||
// NOTE see the end of
|
||||
// https://github.com/typescript-eslint/typescript-eslint/issues/2063#issuecomment-675156492
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
| {}
|
||||
) & {
|
||||
nullable?: boolean
|
||||
metadata?: Record<string, unknown>
|
||||
definitions?: Record<string, SomeJTDSchemaType>
|
||||
}
|
||||
|
||||
/** required keys of an object, not undefined */
|
||||
type RequiredKeys<T> = {
|
||||
[K in keyof T]-?: undefined extends T[K] ? never : K
|
||||
}[keyof T]
|
||||
|
||||
/** optional or undifined-able keys of an object */
|
||||
type OptionalKeys<T> = {
|
||||
[K in keyof T]-?: undefined extends T[K] ? K : never
|
||||
}[keyof T]
|
||||
|
||||
/** type is true if T is a union type */
|
||||
type IsUnion_<T, U extends T = T> = false extends (
|
||||
T extends unknown ? ([U] extends [T] ? false : true) : never
|
||||
)
|
||||
? false
|
||||
: true
|
||||
type IsUnion<T> = IsUnion_<T>
|
||||
|
||||
/** type is true if T is identically E */
|
||||
type TypeEquality<T, E> = [T] extends [E] ? ([E] extends [T] ? true : false) : false
|
||||
|
||||
/** type is true if T or null is identically E or null*/
|
||||
type NullTypeEquality<T, E> = TypeEquality<T | null, E | null>
|
||||
|
||||
/** gets only the string literals of a type or null if a type isn't a string literal */
|
||||
type EnumString<T> = [T] extends [never]
|
||||
? null
|
||||
: T extends string
|
||||
? string extends T
|
||||
? null
|
||||
: T
|
||||
: null
|
||||
|
||||
/** true if type is a union of string literals */
|
||||
type IsEnum<T> = null extends EnumString<T> ? false : true
|
||||
|
||||
/** true only if all types are array types (not tuples) */
|
||||
// NOTE relies on the fact that tuples don't have an index at 0.5, but arrays
|
||||
// have an index at every number
|
||||
type IsElements<T> = false extends IsUnion<T>
|
||||
? [T] extends [readonly unknown[]]
|
||||
? undefined extends T[0.5]
|
||||
? false
|
||||
: true
|
||||
: false
|
||||
: false
|
||||
|
||||
/** true if the the type is a values type */
|
||||
type IsValues<T> = false extends IsUnion<T> ? TypeEquality<keyof T, string> : false
|
||||
|
||||
/** true if type is a properties type and Union is false, or type is a discriminator type and Union is true */
|
||||
type IsRecord<T, Union extends boolean> = Union extends IsUnion<T>
|
||||
? null extends EnumString<keyof T>
|
||||
? false
|
||||
: true
|
||||
: false
|
||||
|
||||
/** true if type represents an empty record */
|
||||
type IsEmptyRecord<T> = [T] extends [Record<string, never>]
|
||||
? [T] extends [never]
|
||||
? false
|
||||
: true
|
||||
: false
|
||||
|
||||
/** actual schema */
|
||||
export type JTDSchemaType<T, D extends Record<string, unknown> = Record<string, never>> = (
|
||||
| // refs - where null wasn't specified, must match exactly
|
||||
(null extends EnumString<keyof D>
|
||||
? never
|
||||
:
|
||||
| ({[K in keyof D]: [T] extends [D[K]] ? {ref: K} : never}[keyof D] & {nullable?: false})
|
||||
// nulled refs - if ref is nullable and nullable is specified, then it can
|
||||
// match either null or non-null definitions
|
||||
| (null extends T
|
||||
? {
|
||||
[K in keyof D]: [Exclude<T, null>] extends [Exclude<D[K], null>]
|
||||
? {ref: K}
|
||||
: never
|
||||
}[keyof D] & {nullable: true}
|
||||
: never))
|
||||
// empty - empty schemas also treat nullable differently in that it's now fully ignored
|
||||
| (unknown extends T ? {nullable?: boolean} : never)
|
||||
// all other types // numbers - only accepts the type number
|
||||
| ((true extends NullTypeEquality<T, number>
|
||||
? {type: NumberType}
|
||||
: // booleans - accepts the type boolean
|
||||
true extends NullTypeEquality<T, boolean>
|
||||
? {type: "boolean"}
|
||||
: // strings - only accepts the type string
|
||||
true extends NullTypeEquality<T, string>
|
||||
? {type: StringType}
|
||||
: // strings - only accepts the type Date
|
||||
true extends NullTypeEquality<T, Date>
|
||||
? {type: "timestamp"}
|
||||
: // enums - only accepts union of string literals
|
||||
// TODO we can't actually check that everything in the union was specified
|
||||
true extends IsEnum<Exclude<T, null>>
|
||||
? {enum: EnumString<Exclude<T, null>>[]}
|
||||
: // arrays - only accepts arrays, could be array of unions to be resolved later
|
||||
true extends IsElements<Exclude<T, null>>
|
||||
? T extends readonly (infer E)[]
|
||||
? {
|
||||
elements: JTDSchemaType<E, D>
|
||||
}
|
||||
: never
|
||||
: // empty properties
|
||||
true extends IsEmptyRecord<Exclude<T, null>>
|
||||
?
|
||||
| {properties: Record<string, never>; optionalProperties?: Record<string, never>}
|
||||
| {optionalProperties: Record<string, never>}
|
||||
: // values
|
||||
true extends IsValues<Exclude<T, null>>
|
||||
? T extends Record<string, infer V>
|
||||
? {
|
||||
values: JTDSchemaType<V, D>
|
||||
}
|
||||
: never
|
||||
: // properties
|
||||
true extends IsRecord<Exclude<T, null>, false>
|
||||
? ([RequiredKeys<Exclude<T, null>>] extends [never]
|
||||
? {
|
||||
properties?: Record<string, never>
|
||||
}
|
||||
: {
|
||||
properties: {[K in RequiredKeys<T>]: JTDSchemaType<T[K], D>}
|
||||
}) &
|
||||
([OptionalKeys<Exclude<T, null>>] extends [never]
|
||||
? {
|
||||
optionalProperties?: Record<string, never>
|
||||
}
|
||||
: {
|
||||
optionalProperties: {
|
||||
[K in OptionalKeys<T>]: JTDSchemaType<Exclude<T[K], undefined>, D>
|
||||
}
|
||||
}) & {
|
||||
additionalProperties?: boolean
|
||||
}
|
||||
: // discriminator
|
||||
true extends IsRecord<Exclude<T, null>, true>
|
||||
? {
|
||||
[K in keyof Exclude<T, null>]-?: Exclude<T, null>[K] extends string
|
||||
? {
|
||||
discriminator: K
|
||||
mapping: {
|
||||
// TODO currently allows descriminator to be present in schema
|
||||
[M in Exclude<T, null>[K]]: JTDSchemaType<
|
||||
Omit<T extends Record<K, M> ? T : never, K>,
|
||||
D
|
||||
>
|
||||
}
|
||||
}
|
||||
: never
|
||||
}[keyof Exclude<T, null>]
|
||||
: never) &
|
||||
(null extends T
|
||||
? {
|
||||
nullable: true
|
||||
}
|
||||
: {nullable?: false}))
|
||||
) & {
|
||||
// extra properties
|
||||
metadata?: Record<string, unknown>
|
||||
// TODO these should only be allowed at the top level
|
||||
definitions?: {[K in keyof D]: JTDSchemaType<D[K], D>}
|
||||
}
|
||||
|
||||
type JTDDataDef<S, D extends Record<string, unknown>> =
|
||||
| // ref
|
||||
(S extends {ref: string}
|
||||
? D extends {[K in S["ref"]]: infer V}
|
||||
? JTDDataDef<V, D>
|
||||
: never
|
||||
: // type
|
||||
S extends {type: NumberType}
|
||||
? number
|
||||
: S extends {type: "boolean"}
|
||||
? boolean
|
||||
: S extends {type: "string"}
|
||||
? string
|
||||
: S extends {type: "timestamp"}
|
||||
? string | Date
|
||||
: // enum
|
||||
S extends {enum: readonly (infer E)[]}
|
||||
? string extends E
|
||||
? never
|
||||
: [E] extends [string]
|
||||
? E
|
||||
: never
|
||||
: // elements
|
||||
S extends {elements: infer E}
|
||||
? JTDDataDef<E, D>[]
|
||||
: // properties
|
||||
S extends {
|
||||
properties: Record<string, unknown>
|
||||
optionalProperties?: Record<string, unknown>
|
||||
additionalProperties?: boolean
|
||||
}
|
||||
? {-readonly [K in keyof S["properties"]]-?: JTDDataDef<S["properties"][K], D>} & {
|
||||
-readonly [K in keyof S["optionalProperties"]]+?: JTDDataDef<
|
||||
S["optionalProperties"][K],
|
||||
D
|
||||
>
|
||||
} & ([S["additionalProperties"]] extends [true] ? Record<string, unknown> : unknown)
|
||||
: S extends {
|
||||
properties?: Record<string, unknown>
|
||||
optionalProperties: Record<string, unknown>
|
||||
additionalProperties?: boolean
|
||||
}
|
||||
? {-readonly [K in keyof S["properties"]]-?: JTDDataDef<S["properties"][K], D>} & {
|
||||
-readonly [K in keyof S["optionalProperties"]]+?: JTDDataDef<
|
||||
S["optionalProperties"][K],
|
||||
D
|
||||
>
|
||||
} & ([S["additionalProperties"]] extends [true] ? Record<string, unknown> : unknown)
|
||||
: // values
|
||||
S extends {values: infer V}
|
||||
? Record<string, JTDDataDef<V, D>>
|
||||
: // discriminator
|
||||
S extends {discriminator: infer M; mapping: Record<string, unknown>}
|
||||
? [M] extends [string]
|
||||
? {
|
||||
[K in keyof S["mapping"]]: JTDDataDef<S["mapping"][K], D> & {[KM in M]: K}
|
||||
}[keyof S["mapping"]]
|
||||
: never
|
||||
: // empty
|
||||
unknown)
|
||||
| (S extends {nullable: true} ? null : never)
|
||||
|
||||
export type JTDDataType<S> = S extends {definitions: Record<string, unknown>}
|
||||
? JTDDataDef<S, S["definitions"]>
|
||||
: JTDDataDef<S, Record<string, never>>
|
56
node_modules/schema-utils/node_modules/ajv/lib/vocabularies/applicator/additionalItems.ts
generated
vendored
Normal file
56
node_modules/schema-utils/node_modules/ajv/lib/vocabularies/applicator/additionalItems.ts
generated
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
import type {
|
||||
CodeKeywordDefinition,
|
||||
ErrorObject,
|
||||
KeywordErrorDefinition,
|
||||
AnySchema,
|
||||
} from "../../types"
|
||||
import type {KeywordCxt} from "../../compile/validate"
|
||||
import {_, str, not, Name} from "../../compile/codegen"
|
||||
import {alwaysValidSchema, checkStrictMode, Type} from "../../compile/util"
|
||||
|
||||
export type AdditionalItemsError = ErrorObject<"additionalItems", {limit: number}, AnySchema>
|
||||
|
||||
const error: KeywordErrorDefinition = {
|
||||
message: ({params: {len}}) => str`must NOT have more than ${len} items`,
|
||||
params: ({params: {len}}) => _`{limit: ${len}}`,
|
||||
}
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: "additionalItems" as const,
|
||||
type: "array",
|
||||
schemaType: ["boolean", "object"],
|
||||
before: "uniqueItems",
|
||||
error,
|
||||
code(cxt: KeywordCxt) {
|
||||
const {parentSchema, it} = cxt
|
||||
const {items} = parentSchema
|
||||
if (!Array.isArray(items)) {
|
||||
checkStrictMode(it, '"additionalItems" is ignored when "items" is not an array of schemas')
|
||||
return
|
||||
}
|
||||
validateAdditionalItems(cxt, items)
|
||||
},
|
||||
}
|
||||
|
||||
export function validateAdditionalItems(cxt: KeywordCxt, items: AnySchema[]): void {
|
||||
const {gen, schema, data, keyword, it} = cxt
|
||||
it.items = true
|
||||
const len = gen.const("len", _`${data}.length`)
|
||||
if (schema === false) {
|
||||
cxt.setParams({len: items.length})
|
||||
cxt.pass(_`${len} <= ${items.length}`)
|
||||
} else if (typeof schema == "object" && !alwaysValidSchema(it, schema)) {
|
||||
const valid = gen.var("valid", _`${len} <= ${items.length}`) // TODO var
|
||||
gen.if(not(valid), () => validateItems(valid))
|
||||
cxt.ok(valid)
|
||||
}
|
||||
|
||||
function validateItems(valid: Name): void {
|
||||
gen.forRange("i", items.length, len, (i) => {
|
||||
cxt.subschema({keyword, dataProp: i, dataPropType: Type.Num}, valid)
|
||||
if (!it.allErrors) gen.if(not(valid), () => gen.break())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export default def
|
118
node_modules/schema-utils/node_modules/ajv/lib/vocabularies/applicator/additionalProperties.ts
generated
vendored
Normal file
118
node_modules/schema-utils/node_modules/ajv/lib/vocabularies/applicator/additionalProperties.ts
generated
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
import type {
|
||||
CodeKeywordDefinition,
|
||||
AddedKeywordDefinition,
|
||||
ErrorObject,
|
||||
KeywordErrorDefinition,
|
||||
AnySchema,
|
||||
} from "../../types"
|
||||
import {allSchemaProperties, usePattern, isOwnProperty} from "../code"
|
||||
import {_, nil, or, not, Code, Name} from "../../compile/codegen"
|
||||
import N from "../../compile/names"
|
||||
import type {SubschemaArgs} from "../../compile/validate/subschema"
|
||||
import {alwaysValidSchema, schemaRefOrVal, Type} from "../../compile/util"
|
||||
|
||||
export type AdditionalPropertiesError = ErrorObject<
|
||||
"additionalProperties",
|
||||
{additionalProperty: string},
|
||||
AnySchema
|
||||
>
|
||||
|
||||
const error: KeywordErrorDefinition = {
|
||||
message: "must NOT have additional properties",
|
||||
params: ({params}) => _`{additionalProperty: ${params.additionalProperty}}`,
|
||||
}
|
||||
|
||||
const def: CodeKeywordDefinition & AddedKeywordDefinition = {
|
||||
keyword: "additionalProperties",
|
||||
type: ["object"],
|
||||
schemaType: ["boolean", "object"],
|
||||
allowUndefined: true,
|
||||
trackErrors: true,
|
||||
error,
|
||||
code(cxt) {
|
||||
const {gen, schema, parentSchema, data, errsCount, it} = cxt
|
||||
/* istanbul ignore if */
|
||||
if (!errsCount) throw new Error("ajv implementation error")
|
||||
const {allErrors, opts} = it
|
||||
it.props = true
|
||||
if (opts.removeAdditional !== "all" && alwaysValidSchema(it, schema)) return
|
||||
const props = allSchemaProperties(parentSchema.properties)
|
||||
const patProps = allSchemaProperties(parentSchema.patternProperties)
|
||||
checkAdditionalProperties()
|
||||
cxt.ok(_`${errsCount} === ${N.errors}`)
|
||||
|
||||
function checkAdditionalProperties(): void {
|
||||
gen.forIn("key", data, (key: Name) => {
|
||||
if (!props.length && !patProps.length) additionalPropertyCode(key)
|
||||
else gen.if(isAdditional(key), () => additionalPropertyCode(key))
|
||||
})
|
||||
}
|
||||
|
||||
function isAdditional(key: Name): Code {
|
||||
let definedProp: Code
|
||||
if (props.length > 8) {
|
||||
// TODO maybe an option instead of hard-coded 8?
|
||||
const propsSchema = schemaRefOrVal(it, parentSchema.properties, "properties")
|
||||
definedProp = isOwnProperty(gen, propsSchema as Code, key)
|
||||
} else if (props.length) {
|
||||
definedProp = or(...props.map((p) => _`${key} === ${p}`))
|
||||
} else {
|
||||
definedProp = nil
|
||||
}
|
||||
if (patProps.length) {
|
||||
definedProp = or(definedProp, ...patProps.map((p) => _`${usePattern(cxt, p)}.test(${key})`))
|
||||
}
|
||||
return not(definedProp)
|
||||
}
|
||||
|
||||
function deleteAdditional(key: Name): void {
|
||||
gen.code(_`delete ${data}[${key}]`)
|
||||
}
|
||||
|
||||
function additionalPropertyCode(key: Name): void {
|
||||
if (opts.removeAdditional === "all" || (opts.removeAdditional && schema === false)) {
|
||||
deleteAdditional(key)
|
||||
return
|
||||
}
|
||||
|
||||
if (schema === false) {
|
||||
cxt.setParams({additionalProperty: key})
|
||||
cxt.error()
|
||||
if (!allErrors) gen.break()
|
||||
return
|
||||
}
|
||||
|
||||
if (typeof schema == "object" && !alwaysValidSchema(it, schema)) {
|
||||
const valid = gen.name("valid")
|
||||
if (opts.removeAdditional === "failing") {
|
||||
applyAdditionalSchema(key, valid, false)
|
||||
gen.if(not(valid), () => {
|
||||
cxt.reset()
|
||||
deleteAdditional(key)
|
||||
})
|
||||
} else {
|
||||
applyAdditionalSchema(key, valid)
|
||||
if (!allErrors) gen.if(not(valid), () => gen.break())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function applyAdditionalSchema(key: Name, valid: Name, errors?: false): void {
|
||||
const subschema: SubschemaArgs = {
|
||||
keyword: "additionalProperties",
|
||||
dataProp: key,
|
||||
dataPropType: Type.Str,
|
||||
}
|
||||
if (errors === false) {
|
||||
Object.assign(subschema, {
|
||||
compositeRule: true,
|
||||
createErrors: false,
|
||||
allErrors: false,
|
||||
})
|
||||
}
|
||||
cxt.subschema(subschema, valid)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
export default def
|
22
node_modules/schema-utils/node_modules/ajv/lib/vocabularies/applicator/allOf.ts
generated
vendored
Normal file
22
node_modules/schema-utils/node_modules/ajv/lib/vocabularies/applicator/allOf.ts
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
import type {CodeKeywordDefinition, AnySchema} from "../../types"
|
||||
import type {KeywordCxt} from "../../compile/validate"
|
||||
import {alwaysValidSchema} from "../../compile/util"
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: "allOf",
|
||||
schemaType: "array",
|
||||
code(cxt: KeywordCxt) {
|
||||
const {gen, schema, it} = cxt
|
||||
/* istanbul ignore if */
|
||||
if (!Array.isArray(schema)) throw new Error("ajv implementation error")
|
||||
const valid = gen.name("valid")
|
||||
schema.forEach((sch: AnySchema, i: number) => {
|
||||
if (alwaysValidSchema(it, sch)) return
|
||||
const schCxt = cxt.subschema({keyword: "allOf", schemaProp: i}, valid)
|
||||
cxt.ok(valid)
|
||||
cxt.mergeEvaluated(schCxt)
|
||||
})
|
||||
},
|
||||
}
|
||||
|
||||
export default def
|
14
node_modules/schema-utils/node_modules/ajv/lib/vocabularies/applicator/anyOf.ts
generated
vendored
Normal file
14
node_modules/schema-utils/node_modules/ajv/lib/vocabularies/applicator/anyOf.ts
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
import type {CodeKeywordDefinition, ErrorNoParams, AnySchema} from "../../types"
|
||||
import {validateUnion} from "../code"
|
||||
|
||||
export type AnyOfError = ErrorNoParams<"anyOf", AnySchema[]>
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: "anyOf",
|
||||
schemaType: "array",
|
||||
trackErrors: true,
|
||||
code: validateUnion,
|
||||
error: {message: "must match a schema in anyOf"},
|
||||
}
|
||||
|
||||
export default def
|
109
node_modules/schema-utils/node_modules/ajv/lib/vocabularies/applicator/contains.ts
generated
vendored
Normal file
109
node_modules/schema-utils/node_modules/ajv/lib/vocabularies/applicator/contains.ts
generated
vendored
Normal file
@@ -0,0 +1,109 @@
|
||||
import type {
|
||||
CodeKeywordDefinition,
|
||||
KeywordErrorDefinition,
|
||||
ErrorObject,
|
||||
AnySchema,
|
||||
} from "../../types"
|
||||
import type {KeywordCxt} from "../../compile/validate"
|
||||
import {_, str, Name} from "../../compile/codegen"
|
||||
import {alwaysValidSchema, checkStrictMode, Type} from "../../compile/util"
|
||||
|
||||
export type ContainsError = ErrorObject<
|
||||
"contains",
|
||||
{minContains: number; maxContains?: number},
|
||||
AnySchema
|
||||
>
|
||||
|
||||
const error: KeywordErrorDefinition = {
|
||||
message: ({params: {min, max}}) =>
|
||||
max === undefined
|
||||
? str`must contain at least ${min} valid item(s)`
|
||||
: str`must contain at least ${min} and no more than ${max} valid item(s)`,
|
||||
params: ({params: {min, max}}) =>
|
||||
max === undefined ? _`{minContains: ${min}}` : _`{minContains: ${min}, maxContains: ${max}}`,
|
||||
}
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: "contains",
|
||||
type: "array",
|
||||
schemaType: ["object", "boolean"],
|
||||
before: "uniqueItems",
|
||||
trackErrors: true,
|
||||
error,
|
||||
code(cxt: KeywordCxt) {
|
||||
const {gen, schema, parentSchema, data, it} = cxt
|
||||
let min: number
|
||||
let max: number | undefined
|
||||
const {minContains, maxContains} = parentSchema
|
||||
if (it.opts.next) {
|
||||
min = minContains === undefined ? 1 : minContains
|
||||
max = maxContains
|
||||
} else {
|
||||
min = 1
|
||||
}
|
||||
const len = gen.const("len", _`${data}.length`)
|
||||
cxt.setParams({min, max})
|
||||
if (max === undefined && min === 0) {
|
||||
checkStrictMode(it, `"minContains" == 0 without "maxContains": "contains" keyword ignored`)
|
||||
return
|
||||
}
|
||||
if (max !== undefined && min > max) {
|
||||
checkStrictMode(it, `"minContains" > "maxContains" is always invalid`)
|
||||
cxt.fail()
|
||||
return
|
||||
}
|
||||
if (alwaysValidSchema(it, schema)) {
|
||||
let cond = _`${len} >= ${min}`
|
||||
if (max !== undefined) cond = _`${cond} && ${len} <= ${max}`
|
||||
cxt.pass(cond)
|
||||
return
|
||||
}
|
||||
|
||||
it.items = true
|
||||
const valid = gen.name("valid")
|
||||
if (max === undefined && min === 1) {
|
||||
validateItems(valid, () => gen.if(valid, () => gen.break()))
|
||||
} else if (min === 0) {
|
||||
gen.let(valid, true)
|
||||
if (max !== undefined) gen.if(_`${data}.length > 0`, validateItemsWithCount)
|
||||
} else {
|
||||
gen.let(valid, false)
|
||||
validateItemsWithCount()
|
||||
}
|
||||
cxt.result(valid, () => cxt.reset())
|
||||
|
||||
function validateItemsWithCount(): void {
|
||||
const schValid = gen.name("_valid")
|
||||
const count = gen.let("count", 0)
|
||||
validateItems(schValid, () => gen.if(schValid, () => checkLimits(count)))
|
||||
}
|
||||
|
||||
function validateItems(_valid: Name, block: () => void): void {
|
||||
gen.forRange("i", 0, len, (i) => {
|
||||
cxt.subschema(
|
||||
{
|
||||
keyword: "contains",
|
||||
dataProp: i,
|
||||
dataPropType: Type.Num,
|
||||
compositeRule: true,
|
||||
},
|
||||
_valid
|
||||
)
|
||||
block()
|
||||
})
|
||||
}
|
||||
|
||||
function checkLimits(count: Name): void {
|
||||
gen.code(_`${count}++`)
|
||||
if (max === undefined) {
|
||||
gen.if(_`${count} >= ${min}`, () => gen.assign(valid, true).break())
|
||||
} else {
|
||||
gen.if(_`${count} > ${max}`, () => gen.assign(valid, false).break())
|
||||
if (min === 1) gen.assign(valid, true)
|
||||
else gen.if(_`${count} >= ${min}`, () => gen.assign(valid, true))
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
export default def
|
112
node_modules/schema-utils/node_modules/ajv/lib/vocabularies/applicator/dependencies.ts
generated
vendored
Normal file
112
node_modules/schema-utils/node_modules/ajv/lib/vocabularies/applicator/dependencies.ts
generated
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
import type {
|
||||
CodeKeywordDefinition,
|
||||
ErrorObject,
|
||||
KeywordErrorDefinition,
|
||||
SchemaMap,
|
||||
AnySchema,
|
||||
} from "../../types"
|
||||
import type {KeywordCxt} from "../../compile/validate"
|
||||
import {_, str} from "../../compile/codegen"
|
||||
import {alwaysValidSchema} from "../../compile/util"
|
||||
import {checkReportMissingProp, checkMissingProp, reportMissingProp, propertyInData} from "../code"
|
||||
|
||||
export type PropertyDependencies = {[K in string]?: string[]}
|
||||
|
||||
export interface DependenciesErrorParams {
|
||||
property: string
|
||||
missingProperty: string
|
||||
depsCount: number
|
||||
deps: string // TODO change to string[]
|
||||
}
|
||||
|
||||
type SchemaDependencies = SchemaMap
|
||||
|
||||
export type DependenciesError = ErrorObject<
|
||||
"dependencies",
|
||||
DependenciesErrorParams,
|
||||
{[K in string]?: string[] | AnySchema}
|
||||
>
|
||||
|
||||
export const error: KeywordErrorDefinition = {
|
||||
message: ({params: {property, depsCount, deps}}) => {
|
||||
const property_ies = depsCount === 1 ? "property" : "properties"
|
||||
return str`must have ${property_ies} ${deps} when property ${property} is present`
|
||||
},
|
||||
params: ({params: {property, depsCount, deps, missingProperty}}) =>
|
||||
_`{property: ${property},
|
||||
missingProperty: ${missingProperty},
|
||||
depsCount: ${depsCount},
|
||||
deps: ${deps}}`, // TODO change to reference
|
||||
}
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: "dependencies",
|
||||
type: "object",
|
||||
schemaType: "object",
|
||||
error,
|
||||
code(cxt: KeywordCxt) {
|
||||
const [propDeps, schDeps] = splitDependencies(cxt)
|
||||
validatePropertyDeps(cxt, propDeps)
|
||||
validateSchemaDeps(cxt, schDeps)
|
||||
},
|
||||
}
|
||||
|
||||
function splitDependencies({schema}: KeywordCxt): [PropertyDependencies, SchemaDependencies] {
|
||||
const propertyDeps: PropertyDependencies = {}
|
||||
const schemaDeps: SchemaDependencies = {}
|
||||
for (const key in schema) {
|
||||
if (key === "__proto__") continue
|
||||
const deps = Array.isArray(schema[key]) ? propertyDeps : schemaDeps
|
||||
deps[key] = schema[key]
|
||||
}
|
||||
return [propertyDeps, schemaDeps]
|
||||
}
|
||||
|
||||
export function validatePropertyDeps(
|
||||
cxt: KeywordCxt,
|
||||
propertyDeps: {[K in string]?: string[]} = cxt.schema
|
||||
): void {
|
||||
const {gen, data, it} = cxt
|
||||
if (Object.keys(propertyDeps).length === 0) return
|
||||
const missing = gen.let("missing")
|
||||
for (const prop in propertyDeps) {
|
||||
const deps = propertyDeps[prop] as string[]
|
||||
if (deps.length === 0) continue
|
||||
const hasProperty = propertyInData(gen, data, prop, it.opts.ownProperties)
|
||||
cxt.setParams({
|
||||
property: prop,
|
||||
depsCount: deps.length,
|
||||
deps: deps.join(", "),
|
||||
})
|
||||
if (it.allErrors) {
|
||||
gen.if(hasProperty, () => {
|
||||
for (const depProp of deps) {
|
||||
checkReportMissingProp(cxt, depProp)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
gen.if(_`${hasProperty} && (${checkMissingProp(cxt, deps, missing)})`)
|
||||
reportMissingProp(cxt, missing)
|
||||
gen.else()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function validateSchemaDeps(cxt: KeywordCxt, schemaDeps: SchemaMap = cxt.schema): void {
|
||||
const {gen, data, keyword, it} = cxt
|
||||
const valid = gen.name("valid")
|
||||
for (const prop in schemaDeps) {
|
||||
if (alwaysValidSchema(it, schemaDeps[prop] as AnySchema)) continue
|
||||
gen.if(
|
||||
propertyInData(gen, data, prop, it.opts.ownProperties),
|
||||
() => {
|
||||
const schCxt = cxt.subschema({keyword, schemaProp: prop}, valid)
|
||||
cxt.mergeValidEvaluated(schCxt, valid)
|
||||
},
|
||||
() => gen.var(valid, true) // TODO var
|
||||
)
|
||||
cxt.ok(valid)
|
||||
}
|
||||
}
|
||||
|
||||
export default def
|
11
node_modules/schema-utils/node_modules/ajv/lib/vocabularies/applicator/dependentSchemas.ts
generated
vendored
Normal file
11
node_modules/schema-utils/node_modules/ajv/lib/vocabularies/applicator/dependentSchemas.ts
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
import type {CodeKeywordDefinition} from "../../types"
|
||||
import {validateSchemaDeps} from "./dependencies"
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: "dependentSchemas",
|
||||
type: "object",
|
||||
schemaType: "object",
|
||||
code: (cxt) => validateSchemaDeps(cxt),
|
||||
}
|
||||
|
||||
export default def
|
80
node_modules/schema-utils/node_modules/ajv/lib/vocabularies/applicator/if.ts
generated
vendored
Normal file
80
node_modules/schema-utils/node_modules/ajv/lib/vocabularies/applicator/if.ts
generated
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
import type {
|
||||
CodeKeywordDefinition,
|
||||
ErrorObject,
|
||||
KeywordErrorDefinition,
|
||||
AnySchema,
|
||||
} from "../../types"
|
||||
import type {SchemaObjCxt} from "../../compile"
|
||||
import type {KeywordCxt} from "../../compile/validate"
|
||||
import {_, str, not, Name} from "../../compile/codegen"
|
||||
import {alwaysValidSchema, checkStrictMode} from "../../compile/util"
|
||||
|
||||
export type IfKeywordError = ErrorObject<"if", {failingKeyword: string}, AnySchema>
|
||||
|
||||
const error: KeywordErrorDefinition = {
|
||||
message: ({params}) => str`must match "${params.ifClause}" schema`,
|
||||
params: ({params}) => _`{failingKeyword: ${params.ifClause}}`,
|
||||
}
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: "if",
|
||||
schemaType: ["object", "boolean"],
|
||||
trackErrors: true,
|
||||
error,
|
||||
code(cxt: KeywordCxt) {
|
||||
const {gen, parentSchema, it} = cxt
|
||||
if (parentSchema.then === undefined && parentSchema.else === undefined) {
|
||||
checkStrictMode(it, '"if" without "then" and "else" is ignored')
|
||||
}
|
||||
const hasThen = hasSchema(it, "then")
|
||||
const hasElse = hasSchema(it, "else")
|
||||
if (!hasThen && !hasElse) return
|
||||
|
||||
const valid = gen.let("valid", true)
|
||||
const schValid = gen.name("_valid")
|
||||
validateIf()
|
||||
cxt.reset()
|
||||
|
||||
if (hasThen && hasElse) {
|
||||
const ifClause = gen.let("ifClause")
|
||||
cxt.setParams({ifClause})
|
||||
gen.if(schValid, validateClause("then", ifClause), validateClause("else", ifClause))
|
||||
} else if (hasThen) {
|
||||
gen.if(schValid, validateClause("then"))
|
||||
} else {
|
||||
gen.if(not(schValid), validateClause("else"))
|
||||
}
|
||||
|
||||
cxt.pass(valid, () => cxt.error(true))
|
||||
|
||||
function validateIf(): void {
|
||||
const schCxt = cxt.subschema(
|
||||
{
|
||||
keyword: "if",
|
||||
compositeRule: true,
|
||||
createErrors: false,
|
||||
allErrors: false,
|
||||
},
|
||||
schValid
|
||||
)
|
||||
cxt.mergeEvaluated(schCxt)
|
||||
}
|
||||
|
||||
function validateClause(keyword: string, ifClause?: Name): () => void {
|
||||
return () => {
|
||||
const schCxt = cxt.subschema({keyword}, schValid)
|
||||
gen.assign(valid, schValid)
|
||||
cxt.mergeValidEvaluated(schCxt, valid)
|
||||
if (ifClause) gen.assign(ifClause, _`${keyword}`)
|
||||
else cxt.setParams({ifClause: keyword})
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
function hasSchema(it: SchemaObjCxt, keyword: string): boolean {
|
||||
const schema = it.schema[keyword]
|
||||
return schema !== undefined && !alwaysValidSchema(it, schema)
|
||||
}
|
||||
|
||||
export default def
|
53
node_modules/schema-utils/node_modules/ajv/lib/vocabularies/applicator/index.ts
generated
vendored
Normal file
53
node_modules/schema-utils/node_modules/ajv/lib/vocabularies/applicator/index.ts
generated
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
import type {ErrorNoParams, Vocabulary} from "../../types"
|
||||
import additionalItems, {AdditionalItemsError} from "./additionalItems"
|
||||
import prefixItems from "./prefixItems"
|
||||
import items from "./items"
|
||||
import items2020, {ItemsError} from "./items2020"
|
||||
import contains, {ContainsError} from "./contains"
|
||||
import dependencies, {DependenciesError} from "./dependencies"
|
||||
import propertyNames, {PropertyNamesError} from "./propertyNames"
|
||||
import additionalProperties, {AdditionalPropertiesError} from "./additionalProperties"
|
||||
import properties from "./properties"
|
||||
import patternProperties from "./patternProperties"
|
||||
import notKeyword, {NotKeywordError} from "./not"
|
||||
import anyOf, {AnyOfError} from "./anyOf"
|
||||
import oneOf, {OneOfError} from "./oneOf"
|
||||
import allOf from "./allOf"
|
||||
import ifKeyword, {IfKeywordError} from "./if"
|
||||
import thenElse from "./thenElse"
|
||||
|
||||
export default function getApplicator(draft2020 = false): Vocabulary {
|
||||
const applicator = [
|
||||
// any
|
||||
notKeyword,
|
||||
anyOf,
|
||||
oneOf,
|
||||
allOf,
|
||||
ifKeyword,
|
||||
thenElse,
|
||||
// object
|
||||
propertyNames,
|
||||
additionalProperties,
|
||||
dependencies,
|
||||
properties,
|
||||
patternProperties,
|
||||
]
|
||||
// array
|
||||
if (draft2020) applicator.push(prefixItems, items2020)
|
||||
else applicator.push(additionalItems, items)
|
||||
applicator.push(contains)
|
||||
return applicator
|
||||
}
|
||||
|
||||
export type ApplicatorKeywordError =
|
||||
| ErrorNoParams<"false schema">
|
||||
| AdditionalItemsError
|
||||
| ItemsError
|
||||
| ContainsError
|
||||
| AdditionalPropertiesError
|
||||
| DependenciesError
|
||||
| IfKeywordError
|
||||
| AnyOfError
|
||||
| OneOfError
|
||||
| NotKeywordError
|
||||
| PropertyNamesError
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user