node_modules

This commit is contained in:
saeid
2019-07-15 13:07:31 +04:30
parent d3735c6d30
commit ce1a3ebf9c
35713 changed files with 3639219 additions and 1 deletions
+30
View File
@@ -0,0 +1,30 @@
## @vue/babel-helper-vue-jsx-merge-props
A package used internally by vue jsx transformer to merge props spread. It is required to merge some prop trees like this:
```js
import mergeProps from '@vue/babel-helper-vue-jsx-merge-props'
const MyComponent = {
render(h) {
// original: <button onClick={$event => console.log($event)} {...{ on: { click: $event => doSomething($event) } }} />
return h(
'button',
mergeProps([
{
on: {
click: $event => console.log($event),
},
},
{
on: {
click: $event => doSomething($event),
},
},
]),
)
},
}
```
This tool is used internally and there is no reason for you to ever use it.
+1
View File
@@ -0,0 +1 @@
"use strict";function _extends(){return _extends=Object.assign||function(a){for(var b,c=1;c<arguments.length;c++)for(var d in b=arguments[c],b)Object.prototype.hasOwnProperty.call(b,d)&&(a[d]=b[d]);return a},_extends.apply(this,arguments)}var normalMerge=["attrs","props","domProps"],toArrayMerge=["class","style","directives"],functionalMerge=["on","nativeOn"],mergeJsxProps=function(a){return a.reduce(function(c,a){for(var b in a)if(!c[b])c[b]=a[b];else if(-1!==normalMerge.indexOf(b))c[b]=_extends({},c[b],a[b]);else if(-1!==toArrayMerge.indexOf(b)){var d=c[b]instanceof Array?c[b]:[c[b]],e=a[b]instanceof Array?a[b]:[a[b]];c[b]=d.concat(e)}else if(-1!==functionalMerge.indexOf(b)){for(var f in a[b])if(c[b][f]){var g=c[b][f]instanceof Array?c[b][f]:[c[b][f]],h=a[b][f]instanceof Array?a[b][f]:[a[b][f]];c[b][f]=g.concat(h)}else c[b][f]=a[b][f];}else if("hook"==b)for(var i in a[b])c[b][i]=c[b][i]?mergeFn(c[b][i],a[b][i]):a[b][i];else c[b]=a[b];return c},{})},mergeFn=function(a,b){return function(){a&&a.apply(this,arguments),b&&b.apply(this,arguments)}};module.exports=mergeJsxProps;
+68
View File
@@ -0,0 +1,68 @@
{
"_from": "@vue/babel-helper-vue-jsx-merge-props@^1.0.0-beta.3",
"_id": "@vue/babel-helper-vue-jsx-merge-props@1.0.0-beta.3",
"_inBundle": false,
"_integrity": "sha512-cbFQnd3dDPsfWuxbWW2phynX2zsckwC4GfAkcE1QH1lZL2ZAD2V97xY3BmvTowMkjeFObRKQt1P3KKA6AoB0hQ==",
"_location": "/@vue/babel-helper-vue-jsx-merge-props",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "@vue/babel-helper-vue-jsx-merge-props@^1.0.0-beta.3",
"name": "@vue/babel-helper-vue-jsx-merge-props",
"escapedName": "@vue%2fbabel-helper-vue-jsx-merge-props",
"scope": "@vue",
"rawSpec": "^1.0.0-beta.3",
"saveSpec": null,
"fetchSpec": "^1.0.0-beta.3"
},
"_requiredBy": [
"/@vue/babel-plugin-transform-vue-jsx",
"/@vue/babel-preset-jsx",
"/@vue/babel-sugar-v-model"
],
"_resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.0.0-beta.3.tgz",
"_shasum": "e4c2e7125b3e0d2a9d493e457850b2abb0fd3cad",
"_spec": "@vue/babel-helper-vue-jsx-merge-props@^1.0.0-beta.3",
"_where": "D:\\Atom\\Git\\Laravel_CSSd\\node_modules\\@vue\\babel-preset-jsx",
"author": {
"name": "Evan You"
},
"bundleDependencies": false,
"deprecated": false,
"description": "Babel helper for Vue JSX spread",
"devDependencies": {
"@babel/core": "^7.2.0",
"@babel/preset-env": "^7.2.0",
"ava": "^0.25.0",
"nyc": "^13.1.0",
"rollup": "^0.67.4",
"rollup-plugin-babel": "4.0.3",
"rollup-plugin-babel-minify": "^6.2.0",
"rollup-plugin-istanbul": "^2.0.1"
},
"files": [],
"gitHead": "44d4d3a822fffea4c978b46975c987f445e2be23",
"license": "MIT",
"main": "dist/helper.js",
"name": "@vue/babel-helper-vue-jsx-merge-props",
"nyc": {
"exclude": [
"dist",
"test"
]
},
"private": false,
"repository": {
"type": "git",
"url": "https://github.com/vuejs/jsx/tree/master/packages/babel-helper-vue-jsx-merge-props"
},
"scripts": {
"build": "rollup -c",
"build:testing": "rollup -c rollup.config.testing.js",
"prepublish": "yarn build",
"pretest": "yarn build:testing",
"test": "nyc --reporter=html --reporter=text-summary ava -v test/test.js"
},
"version": "1.0.0-beta.3"
}
+184
View File
@@ -0,0 +1,184 @@
## @vue/babel-plugin-transform-vue-jsx
> Babel plugin for Vue 2.0 JSX
### Babel Compatibility Notes
- This repo is only compatible with Babel 7.x, for 6.x please use [vuejs/babel-plugin-transform-vue-jsx](https://github.com/vuejs/babel-plugin-transform-vue-jsx)
### Requirements
- Assumes you are using Babel with a module bundler e.g. Webpack, because the spread merge helper is imported as a module to avoid duplication.
- This is mutually exclusive with `babel-plugin-transform-react-jsx`.
### Usage
```bash
npm install @vue/babel-plugin-transform-vue-jsx --save-dev
npm install @vue/babel-helper-vue-jsx-merge-props --save
```
In your `.babelrc`:
```json
{
"plugins": ["transform-vue-jsx"]
}
```
However it is recommended to use the [configurable preset](../babel-preset-jsx/README.md) instead.
### Details
The plugin transpiles the following JSX:
```jsx
<div id="foo">{this.text}</div>
```
To the following JavaScript:
```js
h(
'div',
{
attrs: {
id: 'foo',
},
},
[this.text],
)
```
Note the `h` function, which is a shorthand for a Vue instance's `$createElement` method, must be in the scope where the JSX is. Since this method is passed to component render functions as the first argument, in most cases you'd do this:
```js
Vue.component('jsx-example', {
render(h) {
// <-- h must be in scope
return <div id="foo">bar</div>
},
})
```
### Difference from React JSX
First, Vue 2.0's vnode format is different from React's. The second argument to the `createElement` call is a "data object" that accepts nested objects. Each nested object will be then processed by corresponding modules:
```js
render (h) {
return h('div', {
// Component props
props: {
msg: 'hi'
},
// Normal HTML attributes
attrs: {
id: 'foo'
},
// DOM props
domProps: {
innerHTML: 'bar'
},
// Event handlers are nested under "on", though
// modifiers such as in v-on:keyup.enter are not
// supported. You'll have to manually check the
// keyCode in the handler instead.
on: {
click: this.clickHandler
},
// For components only. Allows you to listen to
// native events, rather than events emitted from
// the component using vm.$emit.
nativeOn: {
click: this.nativeClickHandler
},
// Class is a special module, same API as `v-bind:class`
class: {
foo: true,
bar: false
},
// Style is also same as `v-bind:style`
style: {
color: 'red',
fontSize: '14px'
},
// Other special top-level properties
key: 'key',
ref: 'ref',
// Assign the `ref` is used on elements/components with v-for
refInFor: true,
slot: 'slot'
})
}
```
The equivalent of the above in Vue 2.0 JSX is:
```jsx
render (h) {
return (
<div
// Component props
propsMsg="hi"
// Normal attributes or component props.
id="foo"
// DOM properties are prefixed with `domProps`
domPropsInnerHTML="bar"
// event listeners are prefixed with `on` or `nativeOn`
onClick={this.clickHandler}
nativeOnClick={this.nativeClickHandler}
// other special top-level properties
class={{ foo: true, bar: false }}
style={{ color: 'red', fontSize: '14px' }}
key="key"
ref="ref"
// assign the `ref` is used on elements/components with v-for
refInFor
slot="slot">
</div>
)
}
```
### Component Tip
If a custom element starts with lowercase, it will be treated as a string id and used to lookup a registered component. If it starts with uppercase, it will be treated as an identifier, which allows you to do:
```js
import Todo from './Todo.js'
export default {
render(h) {
return <Todo /> // no need to register Todo via components option
},
}
```
### JSX Spread
JSX spread is supported, and this plugin will intelligently merge nested data properties. For example:
```jsx
const data = {
class: ['b', 'c'],
}
const vnode = <div class="a" {...data} />
```
The merged data will be:
```js
{ class: ['a', 'b', 'c'] }
```
### Vue directives
Vue directives are usable the same way as in template with a few key differences:
1. You can use directives camelCased instead of kebab-cased (vMyDirective is treated as `v-my-directive`)
2. You have to use underscore sign instead of dots for modifiers because of JSXIdentifier limitation.
3. Only runtime directives work (only v-show and custom directives), compile-time directives are out of this project's scope.
A full example would be: `<MyComponent vMyDirective:argument_modifier1_modifier2={someExpression} />`
File diff suppressed because one or more lines are too long
+85
View File
@@ -0,0 +1,85 @@
{
"_from": "@vue/babel-plugin-transform-vue-jsx@^1.0.0-beta.3",
"_id": "@vue/babel-plugin-transform-vue-jsx@1.0.0-beta.3",
"_inBundle": false,
"_integrity": "sha512-yn+j2B/2aEagaxXrMSK3qcAJnlidfXg9v+qmytqrjUXc4zfi8QVC/b4zCev1FDmTip06/cs/csENA4law6Xhpg==",
"_location": "/@vue/babel-plugin-transform-vue-jsx",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "@vue/babel-plugin-transform-vue-jsx@^1.0.0-beta.3",
"name": "@vue/babel-plugin-transform-vue-jsx",
"escapedName": "@vue%2fbabel-plugin-transform-vue-jsx",
"scope": "@vue",
"rawSpec": "^1.0.0-beta.3",
"saveSpec": null,
"fetchSpec": "^1.0.0-beta.3"
},
"_requiredBy": [
"/@vue/babel-preset-jsx",
"/@vue/babel-sugar-v-model",
"/@vue/babel-sugar-v-on"
],
"_resolved": "https://registry.npmjs.org/@vue/babel-plugin-transform-vue-jsx/-/babel-plugin-transform-vue-jsx-1.0.0-beta.3.tgz",
"_shasum": "a1a44e801d8ed615e49f145ef1b3eaca2c16e2e6",
"_spec": "@vue/babel-plugin-transform-vue-jsx@^1.0.0-beta.3",
"_where": "D:\\Atom\\Git\\Laravel_CSSd\\node_modules\\@vue\\babel-preset-jsx",
"author": {
"name": "Evan You"
},
"bundleDependencies": false,
"dependencies": {
"@babel/helper-module-imports": "^7.0.0",
"@babel/plugin-syntax-jsx": "^7.2.0",
"@vue/babel-helper-vue-jsx-merge-props": "^1.0.0-beta.3",
"html-tags": "^2.0.0",
"lodash.kebabcase": "^4.1.1",
"svg-tags": "^1.0.0"
},
"deprecated": false,
"description": "Babel plugin for Vue 2.0 JSX",
"devDependencies": {
"@babel/cli": "^7.2.0",
"@babel/core": "^7.2.0",
"@babel/preset-env": "^7.2.0",
"@vue/test-utils": "^1.0.0-beta.26",
"ava": "^0.25.0",
"jsdom": "^13.0.0",
"jsdom-global": "^3.0.2",
"nyc": "^12.0.2",
"rollup": "^0.67.4",
"rollup-plugin-babel": "4.0.3",
"rollup-plugin-babel-minify": "^6.2.0",
"rollup-plugin-istanbul": "^2.0.1",
"vue": "^2.5.17",
"vue-template-compiler": "^2.5.17"
},
"files": [],
"gitHead": "44d4d3a822fffea4c978b46975c987f445e2be23",
"license": "MIT",
"main": "dist/plugin.js",
"name": "@vue/babel-plugin-transform-vue-jsx",
"nyc": {
"exclude": [
"dist",
"test"
]
},
"private": false,
"repository": {
"type": "git",
"url": "https://github.com/vuejs/jsx/tree/master/packages/babel-plugin-transform-vue-jsx"
},
"scripts": {
"build": "rollup -c",
"build:test": "rollup -c rollup.config.testing.js",
"prepublish": "yarn build",
"pretest:functional": "yarn build:test && nyc --reporter=html --reporter=text-summary babel test/functional.js --plugins ./dist/plugin.testing.js --out-file test/functional-compiled.js",
"pretest:snapshot": "yarn build:test",
"test": "rm -rf coverage* && yarn test:snapshot && mv coverage coverage-snapshot && yarn test:functional && mv coverage coverage-functional",
"test:functional": "ava -v test/functional-compiled.js",
"test:snapshot": "nyc --reporter=html --reporter=text-summary ava -v test/snapshot.js"
},
"version": "1.0.0-beta.3"
}
+21
View File
@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2017-present, Yuxi (Evan) You
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.
+103
View File
@@ -0,0 +1,103 @@
# @vue/babel-preset-app
This is the default Babel preset used in all Vue CLI projects. **Note: this preset is meant to be used exclusively in projects created via Vue CLI and does not consider external use cases.**
## Included Features
### [@babel/preset-env](https://new.babeljs.io/docs/en/next/babel-preset-env.html)
`preset-env` automatically determines the transforms and polyfills to apply based on your browser target. See [Browser Compatibility](https://cli.vuejs.org/guide/browser-compatibility.html) section in docs for more details.
- `modules: false`
- auto set to `'commonjs'` in Jest tests
- [`useBuiltIns: 'usage'`](#usebuiltins)
- `targets` is determined:
- using `browserslist` field in `package.json` when building for browsers
- set to `{ node: 'current' }` when running unit tests in Node.js
- Includes `Promise` polyfill by default so that they are usable even in non-transpiled dependencies (only for environments that need it)
### Stage 3 or Below
Only the following stage 3 or below features are supported (object rest spread is supported as part of `preset-env`):
- [Dynamic Import Syntax](https://github.com/tc39/proposal-dynamic-import)
- [Proposal Class Properties](https://babeljs.io/docs/en/next/babel-plugin-proposal-class-properties.html)
- [Proposal Decorators (legacy)](https://babeljs.io/docs/en/next/babel-plugin-proposal-decorators.html)
If you need additional stage 3 or below features, you need to install and configure it yourself.
### Vue JSX support
- [@babel/plugin-syntax-jsx](https://github.com/babel/babel/tree/master/packages/babel-plugin-syntax-jsx)
- [@vue/babel-preset-jsx](https://github.com/vuejs/jsx)
### [@babel/plugin-transform-runtime](https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-runtime)
`transform-runtime` avoids inlining helpers in every file. This is enabled for helpers only, since polyfills are handled by `babel-preset-env`.
## Options
- All options from [@babel/preset-env](https://babeljs.io/docs/en/next/babel-preset-env.html) are supported, with some of them having smarter defaults.
### modules
- Default:
- `false` when building with webpack
- `'commonjs'` when running tests in Jest.
Explicitly set `modules` option for `babel-preset-env`. See [babel-preset-env docs](https://github.com/babel/babel/tree/master/packages/babel-preset-env#modules) for more details.
### targets
- Default:
- determined from `browserslist` field in `package.json` when building for browsers
- set to `{ node: 'current' }` when running unit tests in Node.js
Explicitly set `targets` option for `babel-preset-env`. See [babel-preset-env docs](https://github.com/babel/babel/tree/master/packages/babel-preset-env#targets) for more details.
### useBuiltIns
- Default: `'usage'`
- Allowed values: `'usage' | 'entry' | false`
Explicitly set `useBuiltIns` option for `babel-preset-env`.
The default value is `'usage'`, which adds imports to polyfills based on the usage in transpiled code. For example, if you use `Object.assign` in your code, the corresponding polyfill will be auto-imported if your target environment does not supports it.
If you are building a library or web component instead of an app, you probably want to set this to `false` and let the consuming app be responsible for the polyfills.
Note that the usage detection does not apply to your dependencies (which are excluded by `cli-plugin-babel` by default). If one of your dependencies need polyfills, you have a few options:
1. **If the dependency is written in an ES version that your target environments do not support:** Add that dependency to the `transpileDependencies` option in `vue.config.js`. This would enable both syntax transforms and usage-based polyfill detection for that dependency.
2. **If the dependency ships ES5 code and explicitly lists the polyfills needed:** you can pre-include the needed polyfills using the [polyfills](#polyfills) option for this preset.
3. **If the dependency ships ES5 code, but uses ES6+ features without explicitly listing polyfill requirements (e.g. Vuetify):** Use `useBuiltIns: 'entry'` and then add `import '@babel/polyfill'` to your entry file. This will import **ALL** polyfills based on your `browserslist` targets so that you don't need to worry about dependency polyfills anymore, but will likely increase your final bundle size with some unused polyfills.
See [@babel/preset-env docs](https://new.babeljs.io/docs/en/next/babel-preset-env.html#usebuiltins-usage) for more details.
### polyfills
- Default: `['es6.array.iterator', 'es6.promise', 'es6.object.assign', 'es7.promise.finally']`
A list of [core-js](https://github.com/zloirock/core-js) polyfills to pre-include when using `useBuiltIns: 'usage'`. **These polyfills are automatically excluded if they are not needed for your target environments**.
Use this option when you have 3rd party dependencies that are not processed by Babel but have specific polyfill requirements (e.g. Axios and Vuex require Promise support).
### jsx
- Default: `true`.
Set to `false` to disable JSX support.
### loose
- Default: `false`.
Setting this to `true` will generate code that is more performant but less spec-compliant.
### entryFiles
- Default: `[]`
Multi page repo use `entryFiles` to ensure inject polyfills to all entry file.
+171
View File
@@ -0,0 +1,171 @@
const path = require('path')
const defaultPolyfills = [
// promise polyfill alone doesn't work in IE,
// needs this as well. see: #1642
'es6.array.iterator',
// this is required for webpack code splitting, vuex etc.
'es6.promise',
// this is needed for object rest spread support in templates
// as vue-template-es2015-compiler 1.8+ compiles it to Object.assign() calls.
'es6.object.assign',
// #2012 es6.promise replaces native Promise in FF and causes missing finally
'es7.promise.finally'
]
function getPolyfills (targets, includes, { ignoreBrowserslistConfig, configPath }) {
const { isPluginRequired } = require('@babel/preset-env')
const builtInsList = require('@babel/preset-env/data/built-ins.json')
const getTargets = require('@babel/preset-env/lib/targets-parser').default
const builtInTargets = getTargets(targets, {
ignoreBrowserslistConfig,
configPath
})
return includes.filter(item => {
return isPluginRequired(builtInTargets, builtInsList[item])
})
}
module.exports = (context, options = {}) => {
const presets = []
const plugins = []
const defaultEntryFiles = JSON.parse(process.env.VUE_CLI_ENTRY_FILES || '[]')
// JSX
if (options.jsx !== false) {
presets.push([require('@vue/babel-preset-jsx'), typeof options.jsx === 'object' ? options.jsx : {}])
}
const {
polyfills: userPolyfills,
loose = false,
debug = false,
useBuiltIns = 'usage',
modules = false,
targets: rawTargets,
spec,
ignoreBrowserslistConfig = !!process.env.VUE_CLI_MODERN_BUILD,
configPath,
include,
exclude,
shippedProposals,
forceAllTransforms,
decoratorsBeforeExport,
decoratorsLegacy,
// entry file list
entryFiles = defaultEntryFiles,
// Undocumented option of @babel/plugin-transform-runtime.
// When enabled, an absolute path is used when importing a runtime helper atfer tranforming.
// This ensures the transpiled file always use the runtime version required in this package.
// However, this may cause hash inconsitency if the project is moved to another directory.
// So here we allow user to explicit disable this option if hash consistency is a requirement
// and the runtime version is sure to be correct.
absoluteRuntime = path.dirname(require.resolve('@babel/runtime/package.json'))
} = options
// resolve targets
let targets
if (process.env.VUE_CLI_BABEL_TARGET_NODE) {
// running tests in Node.js
targets = { node: 'current' }
} else if (process.env.VUE_CLI_BUILD_TARGET === 'wc' || process.env.VUE_CLI_BUILD_TARGET === 'wc-async') {
// targeting browsers that at least support ES2015 classes
// https://github.com/babel/babel/blob/master/packages/babel-preset-env/data/plugins.json#L52-L61
targets = {
browsers: [
'Chrome >= 49',
'Firefox >= 45',
'Safari >= 10',
'Edge >= 13',
'iOS >= 10',
'Electron >= 0.36'
]
}
} else if (process.env.VUE_CLI_MODERN_BUILD) {
// targeting browsers that support <script type="module">
targets = { esmodules: true }
} else {
targets = rawTargets
}
// included-by-default polyfills. These are common polyfills that 3rd party
// dependencies may rely on (e.g. Vuex relies on Promise), but since with
// useBuiltIns: 'usage' we won't be running Babel on these deps, they need to
// be force-included.
let polyfills
const buildTarget = process.env.VUE_CLI_BUILD_TARGET || 'app'
if (
buildTarget === 'app' &&
useBuiltIns === 'usage' &&
!process.env.VUE_CLI_BABEL_TARGET_NODE &&
!process.env.VUE_CLI_MODERN_BUILD
) {
polyfills = getPolyfills(targets, userPolyfills || defaultPolyfills, {
ignoreBrowserslistConfig,
configPath
})
plugins.push([
require('./polyfillsPlugin'),
{ polyfills, entryFiles, useAbsolutePath: !!absoluteRuntime }
])
} else {
polyfills = []
}
const envOptions = {
spec,
loose,
debug,
modules,
targets,
useBuiltIns,
ignoreBrowserslistConfig,
configPath,
include,
exclude: polyfills.concat(exclude || []),
shippedProposals,
forceAllTransforms
}
// cli-plugin-jest sets this to true because Jest runs without bundling
if (process.env.VUE_CLI_BABEL_TRANSPILE_MODULES) {
envOptions.modules = 'commonjs'
// necessary for dynamic import to work in tests
plugins.push(require('babel-plugin-dynamic-import-node'))
}
// pass options along to babel-preset-env
presets.unshift([require('@babel/preset-env'), envOptions])
// additional <= stage-3 plugins
// Babel 7 is removing stage presets altogether because people are using
// too many unstable proposals. Let's be conservative in the defaults here.
plugins.push(
require('@babel/plugin-syntax-dynamic-import'),
[require('@babel/plugin-proposal-decorators'), {
decoratorsBeforeExport,
legacy: decoratorsLegacy !== false
}],
[require('@babel/plugin-proposal-class-properties'), { loose }],
)
// transform runtime, but only for helpers
plugins.push([require('@babel/plugin-transform-runtime'), {
regenerator: useBuiltIns !== 'usage',
// use @babel/runtime-corejs2 so that helpers that need polyfillable APIs will reference core-js instead.
// if useBuiltIns is not set to 'usage', then it means users would take care of the polyfills on their own,
// i.e., core-js 2 is no longer needed.
corejs: (useBuiltIns === 'usage' && !process.env.VUE_CLI_MODERN_BUILD) ? 2 : false,
helpers: useBuiltIns === 'usage',
useESModules: !process.env.VUE_CLI_BABEL_TRANSPILE_MODULES,
absoluteRuntime
}])
return {
presets,
plugins
}
}
+71
View File
@@ -0,0 +1,71 @@
{
"_args": [
[
"@vue/babel-preset-app@3.5.5",
"D:\\Atom\\Git\\Laravel_CSSD"
]
],
"_development": true,
"_from": "@vue/babel-preset-app@3.5.5",
"_id": "@vue/babel-preset-app@3.5.5",
"_inBundle": false,
"_integrity": "sha512-kK2DkQ+uGOjDnVjgn8A3Rczic55rI42nMESmwWfrfjssPeFQLGqiJixk9eQccHNBjyHcl3D+UOWx+EHQbpPByg==",
"_location": "/@vue/babel-preset-app",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "@vue/babel-preset-app@3.5.5",
"name": "@vue/babel-preset-app",
"escapedName": "@vue%2fbabel-preset-app",
"scope": "@vue",
"rawSpec": "3.5.5",
"saveSpec": null,
"fetchSpec": "3.5.5"
},
"_requiredBy": [
"/@vue/cli-plugin-babel"
],
"_resolved": "https://registry.npmjs.org/@vue/babel-preset-app/-/babel-preset-app-3.5.5.tgz",
"_spec": "3.5.5",
"_where": "D:\\Atom\\Git\\Laravel_CSSD",
"author": {
"name": "Evan You"
},
"bugs": {
"url": "https://github.com/vuejs/vue-cli/issues"
},
"dependencies": {
"@babel/helper-module-imports": "^7.0.0",
"@babel/plugin-proposal-class-properties": "^7.0.0",
"@babel/plugin-proposal-decorators": "^7.1.0",
"@babel/plugin-syntax-dynamic-import": "^7.0.0",
"@babel/plugin-syntax-jsx": "^7.0.0",
"@babel/plugin-transform-runtime": "^7.4.0",
"@babel/preset-env": "^7.0.0 < 7.4.0",
"@babel/runtime": "^7.0.0",
"@babel/runtime-corejs2": "^7.2.0",
"@vue/babel-preset-jsx": "^1.0.0-beta.2",
"babel-plugin-dynamic-import-node": "^2.2.0",
"core-js": "^2.6.5"
},
"description": "babel-preset-app for vue-cli",
"gitHead": "22acaf6498750f8a69ab54ccf51fa92ebe54f9d7",
"homepage": "https://github.com/vuejs/vue-cli/tree/dev/packages/@vue/babel-preset-app#readme",
"keywords": [
"vue",
"cli"
],
"license": "MIT",
"main": "index.js",
"name": "@vue/babel-preset-app",
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git",
"url": "git+https://github.com/vuejs/vue-cli.git",
"directory": "packages/@vue/babel-preset-app"
},
"version": "3.5.5"
}
+40
View File
@@ -0,0 +1,40 @@
const { addSideEffect } = require('@babel/helper-module-imports')
// slightly modifiled from @babel/preset-env/src/utils
// use an absolute path for core-js modules, to fix conflicts of different core-js versions
function getModulePath (mod, useAbsolutePath) {
const modPath =
mod === 'regenerator-runtime'
? 'regenerator-runtime/runtime'
: `core-js/modules/${mod}`
return useAbsolutePath ? require.resolve(modPath) : modPath
}
function createImport (path, mod, useAbsolutePath) {
return addSideEffect(path, getModulePath(mod, useAbsolutePath))
}
// add polyfill imports to the first file encountered.
module.exports = (
{ types },
{ polyfills, entryFiles = [], useAbsolutePath }
) => {
return {
name: 'vue-cli-inject-polyfills',
visitor: {
Program (path, state) {
if (!entryFiles.includes(state.filename)) {
return
}
// imports are injected in reverse order
polyfills
.slice()
.reverse()
.forEach(p => {
createImport(path, p, useAbsolutePath)
})
}
}
}
}
+48
View File
@@ -0,0 +1,48 @@
## @vue/babel-preset-jsx
Configurable preset for Vue JSX plugins.
### Babel Compatibility Notes
- This repo is only compatible with Babel 7.x, for 6.x please use [vuejs/babel-plugin-transform-vue-jsx](https://github.com/vuejs/babel-plugin-transform-vue-jsx)
### Usage
Install the dependencies:
```sh
# for yarn:
yarn add @vue/babel-preset-jsx @vue/babel-helper-vue-jsx-merge-props
# for npm:
npm install @vue/babel-preset-jsx @vue/babel-helper-vue-jsx-merge-props --save
```
In your `.babelrc`:
```json
{
"presets": ["@vue/babel-preset-jsx"]
}
```
You can toggle specific features, by default all features are enabled, e.g.:
```json
{
"presets": [
[
"@vue/babel-preset-jsx",
{
"vModel": false
}
]
]
}
```
Options are:
- `functional` [@vue/babel-sugar-functional-vue](../babel-sugar-functional-vue/README.md) - Functional components syntactic sugar
- `injectH` [@vue/babel-sugar-inject-h](../babel-sugar-inject-h/README.md) - Automatic `h` injection syntactic sugar
- `vModel` [@vue/babel-sugar-v-model](../babel-sugar-v-model/README.md) - `vModel` syntactic sugar
- `vOn` [@vue/babel-sugar-v-on](../babel-sugar-v-on/README.md) - `vOn` syntactic sugar
+1
View File
@@ -0,0 +1 @@
"use strict";function _interopDefault(a){return a&&"object"==typeof a&&"default"in a?a["default"]:a}var babelPluginTransformVueJsx=_interopDefault(require("@vue/babel-plugin-transform-vue-jsx")),babelSugarFunctionalVue=_interopDefault(require("@vue/babel-sugar-functional-vue")),babelSugarInjectH=_interopDefault(require("@vue/babel-sugar-inject-h")),babelSugarVModel=_interopDefault(require("@vue/babel-sugar-v-model")),babelSugarVOn=_interopDefault(require("@vue/babel-sugar-v-on")),index=(a,{functional:b=!0,injectH:c=!0,vModel:d=!0,vOn:e=!0}={})=>({plugins:[b&&babelSugarFunctionalVue,c&&babelSugarInjectH,d&&babelSugarVModel,e&&babelSugarVOn,babelPluginTransformVueJsx].filter(Boolean)});module.exports=index;
+60
View File
@@ -0,0 +1,60 @@
{
"_from": "@vue/babel-preset-jsx@^1.0.0-beta.2",
"_id": "@vue/babel-preset-jsx@1.0.0-beta.3",
"_inBundle": false,
"_integrity": "sha512-qMKGRorTI/0nE83nLEM7MyQiBZUqc62sZyjkBdVaaU7S61MHI8RKHPtbLMMZlWXb2NCJ0fQci8xJWUK5JE+TFA==",
"_location": "/@vue/babel-preset-jsx",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "@vue/babel-preset-jsx@^1.0.0-beta.2",
"name": "@vue/babel-preset-jsx",
"escapedName": "@vue%2fbabel-preset-jsx",
"scope": "@vue",
"rawSpec": "^1.0.0-beta.2",
"saveSpec": null,
"fetchSpec": "^1.0.0-beta.2"
},
"_requiredBy": [
"/@vue/babel-preset-app"
],
"_resolved": "https://registry.npmjs.org/@vue/babel-preset-jsx/-/babel-preset-jsx-1.0.0-beta.3.tgz",
"_shasum": "15c584bd62c0286a80f0196749ae38cde5cd703b",
"_spec": "@vue/babel-preset-jsx@^1.0.0-beta.2",
"_where": "D:\\Atom\\Git\\Laravel_CSSd\\node_modules\\@vue\\babel-preset-app",
"author": {
"name": "Nick Messing",
"email": "dot.nick.dot.messing@gmail.com"
},
"bundleDependencies": false,
"dependencies": {
"@vue/babel-helper-vue-jsx-merge-props": "^1.0.0-beta.3",
"@vue/babel-plugin-transform-vue-jsx": "^1.0.0-beta.3",
"@vue/babel-sugar-functional-vue": "^1.0.0-beta.3",
"@vue/babel-sugar-inject-h": "^1.0.0-beta.3",
"@vue/babel-sugar-v-model": "^1.0.0-beta.3",
"@vue/babel-sugar-v-on": "^1.0.0-beta.3"
},
"deprecated": false,
"description": "Babel preset for Vue JSX",
"devDependencies": {
"rollup": "^0.67.4",
"rollup-plugin-babel-minify": "^6.2.0"
},
"files": [],
"gitHead": "44d4d3a822fffea4c978b46975c987f445e2be23",
"license": "MIT",
"main": "dist/plugin.cjs.js",
"name": "@vue/babel-preset-jsx",
"private": false,
"repository": {
"type": "git",
"url": "https://github.com/vuejs/jsx/tree/master/packages/babel-preset-jsx"
},
"scripts": {
"build": "rollup -c",
"prerelease": "yarn build"
},
"version": "1.0.0-beta.3"
}
+56
View File
@@ -0,0 +1,56 @@
## @vue/babel-sugar-functional-vue
Syntactic sugar for functional components.
### Babel Compatibility Notes
- This repo is only compatible with Babel 7.x, for 6.x please use [vuejs/babel-plugin-transform-vue-jsx](https://github.com/vuejs/babel-plugin-transform-vue-jsx)
### Usage
Install the dependencies:
```sh
# for yarn:
yarn add @vue/babel-sugar-functional-vue
# for npm:
npm install @vue/babel-sugar-functional-vue --save
```
In your `.babelrc`:
```json
{
"plugins": ["@vue/babel-sugar-functional-vue"]
}
```
However it is recommended to use the [configurable preset](../babel-preset-jsx/README.md) instead.
### Details
This plugin transpiles arrow functions that return JSX into functional components but only if it's an uppercase variable declaration or default export:
```js
// Original:
export const A = ({ props, listeners }) => <div onClick={listeners.click}>{props.msg}</div>
export const b = ({ props, listeners }) => <div onClick={listeners.click}>{props.msg}</div>
export default ({ props, listeners }) => <div onClick={listeners.click}>{props.msg}</div>
// Result:
export const A = {
functional: true,
render: (h, {
props,
listeners
}) => <div onClick={listeners.click}>{props.msg}</div>
}
export const b = ({ props, listeners }) => <div onClick={listeners.click}>{props.msg}</div>
export default {
functional: true,
render: (h, {
props,
listeners
}) => <div onClick={listeners.click}>{props.msg}</div>
}
```
+12
View File
@@ -0,0 +1,12 @@
"use strict";function _interopDefault(a){return a&&"object"==typeof a&&"default"in a?a["default"]:a}var syntaxJsx=_interopDefault(require("@babel/plugin-syntax-jsx"));/**
* Check if expression is in method
* @param t
* @param path
* @param parentLimitPath
* @returns boolean
*/const isInMethod=(a,b,c)=>!!(b&&b!==c)&&(!!a.isObjectMethod(b)||isInMethod(a,b.parentPath,c)),hasJSX=(a,b)=>{let c=!1;return b.traverse({JSXElement(d){isInMethod(a,d,b)||(c=!0)}}),c},isFunctionalComponentDeclarator=(a,b)=>{const c=b.get("id.name").node[0];return!("A">c||"Z"<c)&&hasJSX(a,b)},convertFunctionalComponent=(a,b,c=null)=>{const d=[a.identifier("h"),...b.node.params],e=b.node.body,f=[a.objectProperty(a.identifier("functional"),a.booleanLiteral(!0)),a.objectProperty(a.identifier("render"),a.arrowFunctionExpression(d,e))];"development"===process.env.NODE_ENV&&c&&f.unshift(a.objectProperty(a.identifier("name"),a.stringLiteral(c))),b.replaceWith(a.objectExpression(f))};/**
* Check path has JSX
* @param t
* @param path
* @returns boolean
*/var index=a=>{const b=a.types;return{inherits:syntaxJsx,visitor:{Program(a){a.traverse({ExportDefaultDeclaration(a){b.isArrowFunctionExpression(a.node.declaration)&&hasJSX(b,a)&&convertFunctionalComponent(b,a.get("declaration"))},VariableDeclaration(a){if(1===a.node.declarations.length&&b.isVariableDeclarator(a.node.declarations[0])&&b.isArrowFunctionExpression(a.node.declarations[0].init)){const c=a.get("declarations")[0];if(isFunctionalComponentDeclarator(b,c)){const c=a.node.declarations[0].id.name;convertFunctionalComponent(b,a.get("declarations")[0].get("init"),c)}}}})}}}};module.exports=index;
+72
View File
@@ -0,0 +1,72 @@
{
"_from": "@vue/babel-sugar-functional-vue@^1.0.0-beta.3",
"_id": "@vue/babel-sugar-functional-vue@1.0.0-beta.3",
"_inBundle": false,
"_integrity": "sha512-CBIa0sQWn3vfBS2asfTgv0WwdyKvNTKtE/cCfulZ7MiewLBh0RlvvSmdK9BIMTiHErdeZNSGUGlU6JuSHLyYkQ==",
"_location": "/@vue/babel-sugar-functional-vue",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "@vue/babel-sugar-functional-vue@^1.0.0-beta.3",
"name": "@vue/babel-sugar-functional-vue",
"escapedName": "@vue%2fbabel-sugar-functional-vue",
"scope": "@vue",
"rawSpec": "^1.0.0-beta.3",
"saveSpec": null,
"fetchSpec": "^1.0.0-beta.3"
},
"_requiredBy": [
"/@vue/babel-preset-jsx"
],
"_resolved": "https://registry.npmjs.org/@vue/babel-sugar-functional-vue/-/babel-sugar-functional-vue-1.0.0-beta.3.tgz",
"_shasum": "41a855786971dacbbe8044858eefe98de089bf12",
"_spec": "@vue/babel-sugar-functional-vue@^1.0.0-beta.3",
"_where": "D:\\Atom\\Git\\Laravel_CSSd\\node_modules\\@vue\\babel-preset-jsx",
"author": {
"name": "Nick Messing",
"email": "dot.nick.dot.messing@gmail.com"
},
"bundleDependencies": false,
"dependencies": {
"@babel/plugin-syntax-jsx": "^7.2.0"
},
"deprecated": false,
"description": "Babel syntactic sugar for functional components",
"devDependencies": {
"@babel/cli": "^7.2.0",
"@babel/core": "^7.2.0",
"@babel/preset-env": "^7.2.0",
"ava": "^0.25.0",
"nyc": "^13.1.0",
"rollup": "^0.67.4",
"rollup-plugin-babel": "4.0.3",
"rollup-plugin-babel-minify": "^6.2.0",
"rollup-plugin-istanbul": "^2.0.1",
"vue": "^2.5.17"
},
"files": [],
"gitHead": "44d4d3a822fffea4c978b46975c987f445e2be23",
"license": "MIT",
"main": "dist/plugin.js",
"name": "@vue/babel-sugar-functional-vue",
"nyc": {
"exclude": [
"dist",
"test"
]
},
"private": false,
"repository": {
"type": "git",
"url": "https://github.com/vuejs/jsx/tree/master/packages/babel-sugar-functional-vue"
},
"scripts": {
"build": "rollup -c",
"build:test": "rollup -c rollup.config.testing.js",
"prepublish": "yarn build",
"pretest": "yarn build:test",
"test": "nyc --reporter=html --reporter=text-summary ava -v test/test.js"
},
"version": "1.0.0-beta.3"
}
+48
View File
@@ -0,0 +1,48 @@
## @vue/babel-sugar-inject-h
Syntactic sugar for automatic `h` inject in JSX.
### Babel Compatibility Notes
- This repo is only compatible with Babel 7.x, for 6.x please use [vuejs/babel-plugin-transform-vue-jsx](https://github.com/vuejs/babel-plugin-transform-vue-jsx)
### Usage
Install the dependencies:
```sh
# for yarn:
yarn add @vue/babel-sugar-inject-h
# for npm:
npm install @vue/babel-sugar-inject-h --save
```
In your `.babelrc`:
```json
{
"plugins": ["@vue/babel-sugar-inject-h"]
}
```
However it is recommended to use the [configurable preset](../babel-preset-jsx/README.md) instead.
### Details
This plugin automatically injects `h` in every method that has JSX. By using this plugin you don't have to always specifically declare `h` as first parameter in your `render()` function.
```js
// Without @vue/babel-sugar-inject-h
export default {
render (h) {
return <button />
}
}
// With @vue/babel-sugar-inject-h
export default {
render () {
return <button />
}
}
```
+1
View File
@@ -0,0 +1 @@
"use strict";function _interopDefault(e){return e&&"object"==typeof e&&"default"in e?e.default:e}var syntaxJsx=_interopDefault(require("@babel/plugin-syntax-jsx"));const firstParamIsH=(e,n)=>{const t=n.get("params");return t.length&&e.isIdentifier(t[0])&&"h"===t[0].node.name},hasJSX=(e,n)=>{const t={hasJSX:!1};n.traverse({JSXElement(){this.hasJSX=!0}},t);return t.hasJSX},isInsideJSXExpression=(e,n)=>{if(!n.parentPath)return!1;if(e.isJSXExpressionContainer(n.parentPath))return!0;return isInsideJSXExpression(e,n.parentPath)};var index=e=>{const n=e.types;return{inherits:syntaxJsx,visitor:{Program(e){e.traverse({"ObjectMethod|ClassMethod"(e){if(!firstParamIsH(n,e)&&hasJSX(n,e)&&!isInsideJSXExpression(n,e)){const t="render"===e.node.key.name;e.get("body").unshiftContainer("body",n.variableDeclaration("const",[n.variableDeclarator(n.identifier("h"),t?n.memberExpression(n.identifier("arguments"),n.numericLiteral(0),!0):n.memberExpression(n.thisExpression(),n.identifier("$createElement")))]))}}})}}}};module.exports=index;
+72
View File
@@ -0,0 +1,72 @@
{
"_from": "@vue/babel-sugar-inject-h@^1.0.0-beta.3",
"_id": "@vue/babel-sugar-inject-h@1.0.0-beta.3",
"_inBundle": false,
"_integrity": "sha512-HKMBMmFfdK9GBp3rX2bHIwILBdgc5F3ahmCB72keJxzaAQrgDAnD+ho70exUge+inAGlNF34WsQcGPElTf9QZg==",
"_location": "/@vue/babel-sugar-inject-h",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "@vue/babel-sugar-inject-h@^1.0.0-beta.3",
"name": "@vue/babel-sugar-inject-h",
"escapedName": "@vue%2fbabel-sugar-inject-h",
"scope": "@vue",
"rawSpec": "^1.0.0-beta.3",
"saveSpec": null,
"fetchSpec": "^1.0.0-beta.3"
},
"_requiredBy": [
"/@vue/babel-preset-jsx"
],
"_resolved": "https://registry.npmjs.org/@vue/babel-sugar-inject-h/-/babel-sugar-inject-h-1.0.0-beta.3.tgz",
"_shasum": "be1d00b74a1a89fed35a9b1415a738c36f125966",
"_spec": "@vue/babel-sugar-inject-h@^1.0.0-beta.3",
"_where": "D:\\Atom\\Git\\Laravel_CSSd\\node_modules\\@vue\\babel-preset-jsx",
"author": {
"name": "Nick Messing",
"email": "dot.nick.dot.messing@gmail.com"
},
"bundleDependencies": false,
"dependencies": {
"@babel/plugin-syntax-jsx": "^7.2.0"
},
"deprecated": false,
"description": "Babel syntactic sugar for h automatic injection for Vue JSX",
"devDependencies": {
"@babel/cli": "^7.2.0",
"@babel/core": "^7.2.0",
"@babel/preset-env": "^7.2.0",
"ava": "^0.25.0",
"nyc": "^13.1.0",
"rollup": "^0.67.4",
"rollup-plugin-babel": "4.0.3",
"rollup-plugin-istanbul": "^2.0.1",
"rollup-plugin-uglify-es": "^0.0.1",
"vue": "^2.5.17"
},
"files": [],
"gitHead": "44d4d3a822fffea4c978b46975c987f445e2be23",
"license": "MIT",
"main": "dist/plugin.js",
"name": "@vue/babel-sugar-inject-h",
"nyc": {
"exclude": [
"dist",
"test"
]
},
"private": false,
"repository": {
"type": "git",
"url": "https://github.com/vuejs/jsx/tree/master/packages/babel-sugar-inject-h"
},
"scripts": {
"build": "rollup -c",
"build:test": "rollup -c rollup.config.testing.js",
"prepublish": "yarn build",
"pretest": "yarn build:test",
"test": "nyc --reporter=html --reporter=text-summary ava -v test/test.js"
},
"version": "1.0.0-beta.3"
}
+51
View File
@@ -0,0 +1,51 @@
## @vue/babel-sugar-v-model
Syntactic sugar for v-model in JSX.
### Babel Compatibility Notes
- This repo is only compatible with Babel 7.x, for 6.x please use [vuejs/babel-plugin-transform-vue-jsx](https://github.com/vuejs/babel-plugin-transform-vue-jsx)
### Usage
Install the dependencies:
```sh
# for yarn:
yarn add @vue/babel-sugar-v-model
# for npm:
npm install @vue/babel-sugar-v-model --save
```
In your `.babelrc`:
```json
{
"plugins": ["@vue/babel-sugar-v-model"]
}
```
However it is recommended to use the [configurable preset](../babel-preset-jsx/README.md) instead.
### Details
This plugin adds v-model to the JSX and tries to mirror the same behaviour as in vue-template-compiler, with a few differences:
1. You should use underscore (`_`) instead of dot (`.`) for modifiers (`vModel_trim={this.test}`)
2. It is recommended to use camelCase version of it (`vModel`) in JSX, but you can use kebab-case too (`v-model`).
```js
export default {
data: () => ({
test: 'Hello World',
}),
render(h) {
return (
<div>
<input type="text" vModel_trim={this.test} />
{this.test}
</div>
)
},
}
```
File diff suppressed because one or more lines are too long
+84
View File
@@ -0,0 +1,84 @@
{
"_from": "@vue/babel-sugar-v-model@^1.0.0-beta.3",
"_id": "@vue/babel-sugar-v-model@1.0.0-beta.3",
"_inBundle": false,
"_integrity": "sha512-et39eTEh7zW4wfZoSl9Jf0/n2r9OTT8U02LtSbXsjgYcqaDQFusN0+n7tw4bnOqvnnSVjEp7bVsQCWwykC3Wgg==",
"_location": "/@vue/babel-sugar-v-model",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "@vue/babel-sugar-v-model@^1.0.0-beta.3",
"name": "@vue/babel-sugar-v-model",
"escapedName": "@vue%2fbabel-sugar-v-model",
"scope": "@vue",
"rawSpec": "^1.0.0-beta.3",
"saveSpec": null,
"fetchSpec": "^1.0.0-beta.3"
},
"_requiredBy": [
"/@vue/babel-preset-jsx"
],
"_resolved": "https://registry.npmjs.org/@vue/babel-sugar-v-model/-/babel-sugar-v-model-1.0.0-beta.3.tgz",
"_shasum": "ea935b0e08bf58c125a1349b819156059590993c",
"_spec": "@vue/babel-sugar-v-model@^1.0.0-beta.3",
"_where": "D:\\Atom\\Git\\Laravel_CSSd\\node_modules\\@vue\\babel-preset-jsx",
"author": {
"name": "Nick Messing",
"email": "dot.nick.dot.messing@gmail.com"
},
"bundleDependencies": false,
"dependencies": {
"@babel/plugin-syntax-jsx": "^7.2.0",
"@vue/babel-helper-vue-jsx-merge-props": "^1.0.0-beta.3",
"@vue/babel-plugin-transform-vue-jsx": "^1.0.0-beta.3",
"camelcase": "^5.0.0",
"html-tags": "^2.0.0",
"svg-tags": "^1.0.0"
},
"deprecated": false,
"description": "Babel syntactic sugar for v-model support in Vue JSX",
"devDependencies": {
"@babel/cli": "^7.2.0",
"@babel/core": "^7.2.0",
"@babel/preset-env": "^7.2.0",
"@vue/test-utils": "^1.0.0-beta.26",
"ava": "^0.25.0",
"jsdom": "^13.0.0",
"jsdom-global": "^3.0.2",
"nyc": "^13.1.0",
"rollup": "^0.67.4",
"rollup-plugin-babel": "4.0.3",
"rollup-plugin-istanbul": "^2.0.1",
"rollup-plugin-uglify-es": "^0.0.1",
"vue": "^2.5.17",
"vue-template-compiler": "^2.5.17"
},
"files": [],
"gitHead": "44d4d3a822fffea4c978b46975c987f445e2be23",
"license": "MIT",
"main": "dist/plugin.js",
"name": "@vue/babel-sugar-v-model",
"nyc": {
"exclude": [
"dist",
"test"
]
},
"private": false,
"repository": {
"type": "git",
"url": "https://github.com/vuejs/jsx/tree/master/packages/babel-sugar-v-model"
},
"scripts": {
"build": "rollup -c",
"build:test": "rollup -c rollup.config.testing.js",
"prepublish": "yarn build",
"pretest:functional": "yarn build:test && nyc --reporter=html --reporter=text-summary babel test/functional.js --plugins ./dist/plugin.testing.js,./node_modules/@vue/babel-plugin-transform-vue-jsx/dist/plugin.js --out-file test/functional-compiled.js",
"pretest:snapshot": "yarn build:test",
"test": "rm -rf coverage* && yarn test:snapshot && mv coverage coverage-snapshot && yarn test:functional && mv coverage coverage-functional",
"test:functional": "ava -v test/functional-compiled.js",
"test:snapshot": "nyc --reporter=html --reporter=text-summary ava -v test/snapshot.js"
},
"version": "1.0.0-beta.3"
}
+52
View File
@@ -0,0 +1,52 @@
## @vue/babel-sugar-v-on
Syntactic sugar for v-on in JSX.
### Babel Compatibility Notes
- This repo is only compatible with Babel 7.x, for 6.x please use [vuejs/babel-plugin-transform-vue-jsx](https://github.com/vuejs/babel-plugin-transform-vue-jsx)
### Usage
Install the dependencies:
```sh
# for yarn:
yarn add @vue/babel-sugar-v-on
# for npm:
npm install @vue/babel-sugar-v-on --save
```
In your `.babelrc`:
```json
{
"plugins": ["@vue/babel-sugar-v-on"]
}
```
However it is recommended to use the [configurable preset](../babel-preset-jsx/README.md) instead.
### Details
This plugin adds v-on to the JSX and tries to mirror the same behaviour as in vue-template-compiler, with a few differences:
1. You should use underscore (`_`) instead of dot (`.`) for modifiers (`vOn:click_prevent={this.test}`)
2. It is recommended to use camelCase version of it (`vOn`) in JSX, but you can use kebab-case too (`v-on`).
```js
export default {
methods: {
test() {
console.log('Hello World')
},
},
render(h) {
return (
<div>
<a href="https://vuejs.org" vOn:click={this.test}>Vue</a>
</div>
)
},
}
```
+1
View File
@@ -0,0 +1 @@
"use strict";function _interopDefault(a){return a&&"object"==typeof a&&"default"in a?a["default"]:a}var camelCase=_interopDefault(require("camelcase")),syntaxJsx=_interopDefault(require("@babel/plugin-syntax-jsx"));const cachedCamelCase=(()=>{const a=Object.create(null);return b=>(a[b]||(a[b]=camelCase(b)),a[b])})(),equalCamel=(a,b)=>a===b||a===cachedCamelCase(b),keyModifiers=["ctrl","shift","alt","meta"],keyCodes={esc:27,tab:9,enter:13,space:32,up:38,left:37,right:39,down:40,delete:[8,46]},keyNames={esc:["Esc","Escape"],tab:"Tab",enter:"Enter",space:" ",up:["Up","ArrowUp"],left:["Left","ArrowLeft"],right:["Right","ArrowRight"],down:["Down","ArrowDown"],delete:["Backspace","Delete"]};function index(a){function b(a){return p.ifStatement(a,p.returnStatement(p.nullLiteral()))}function c(a,b=[]){return p.callExpression(a,b)}function d(a){return p.memberExpression(p.identifier("$event"),p.identifier(a))}function e(a){return p.unaryExpression("!",a)}function f(a,b){return p.binaryExpression("!==",a,b)}function g(a,b){return p.logicalExpression("&&",a,b)}function h(a,b){return p.logicalExpression("||",a,b)}function i(){return p.binaryExpression("in",p.stringLiteral("button"),p.identifier("$event"))}function j(a){return p.arrowFunctionExpression([p.identifier("$event")],p.blockStatement(a instanceof Array?a:[a]))}function k(a){const b=a.get("name");let c=p.isJSXNamespacedName(b)?`${b.get("namespace.name").node}:${b.get("name.name").node}`:b.get("name").node;camelCase(c);let d,e;if([c,...d]=c.split("_"),[c,e]=c.split(":"),!equalCamel(c,"v-on")||!e)return{isInvalid:!1};if(!p.isJSXExpressionContainer(a.get("value")))throw new Error("Only expression container is allowed on v-on directive.");const f=a.get("value.expression");return{expression:f.node,modifiers:d,event:e}}function l(a){let{modifiers:e,isInvalid:f,expression:g,event:i}=k(a);"click"===i&&e.includes("right")&&(e=e.filter(a=>"right"!==a),i="contextmenu"),"click"===i&&e.includes("middle")&&(i="mouseup");let l=!1;if(f)return;if(!e||0===e.length)return{event:i,expression:g,isNative:l};const n=[],o=[],r=[];for(const c of e)if(q[c]){const a=q[c]();o.push(p.isExpression(a)?p.expressionStatement(a):a),keyCodes[c]&&r.push(c)}else"exact"===c?o.push(b(keyModifiers.filter(a=>!e.includes(a)).map(a=>d(a+"Key")).reduce((a,b)=>a?h(a,b):b))):"capture"===c?i="!"+i:"once"===c?i="~"+i:"native"===c?l=!0:r.push(c);return(r.length&&n.push(m(r)),o.length&&n.push(...o),0===n.length)?{event:i,expression:g,isNative:l}:(n.push(p.returnStatement(c(g,[p.identifier("$event")]))),{event:i,expression:j(n),isNative:l})}function m(a){return b(a.map(n).reduce((a,b)=>g(a,b),e(i())))}function n(a){const b=parseInt(a,10);if(b)return f(d("keyCode"),p.numericLiteral(b));const c=keyCodes[a],e=keyNames[a];return p.callExpression(p.memberExpression(p.thisExpression(),p.identifier("_k")),[d("keyCode"),p.stringLiteral(`${a}`),c?Array.isArray(c)?p.arrayExpression(c.map(a=>p.numericLiteral(a))):p.numericLiteral(c):p.identifier("undefined"),d("key"),e?Array.isArray(e)?p.arrayExpression(e.map(a=>p.stringLiteral(a))):p.stringLiteral(`${e}`):p.identifier("undefined")])}function o(a,b,c,d){"~"!==a[0]&&"!"!==a[0]?d.push(p.jSXAttribute(p.jSXIdentifier(`${c?"nativeOn":"on"}-${a}`),p.jSXExpressionContainer(b))):d.push(p.jSXSpreadAttribute(p.objectExpression([p.objectProperty(p.identifier("on"),p.objectExpression([p.objectProperty(p.stringLiteral(a),b)]))])))}const p=a.types,q={stop:()=>c(d("stopPropagation")),prevent:()=>c(d("preventDefault")),self:()=>b(f(d("target"),d("currentTarget"))),ctrl:()=>b(e(d("ctrlKey"))),shift:()=>b(e(d("shiftKey"))),alt:()=>b(e(d("altKey"))),meta:()=>b(e(d("metaKey"))),left:()=>b(g(i(),f(d("button"),p.numericLiteral(0)))),middle:()=>b(g(i(),f(d("button"),p.numericLiteral(1)))),right:()=>b(g(i(),f(d("button"),p.numericLiteral(2))))};return{inherits:syntaxJsx,visitor:{Program(a){a.traverse({JSXAttribute(a){const{event:b,expression:c,isNative:d}=l(a);b&&(a.remove(),o(b,c,d,a.parentPath.node.attributes))}})}}}}module.exports=index;
+82
View File
@@ -0,0 +1,82 @@
{
"_from": "@vue/babel-sugar-v-on@^1.0.0-beta.3",
"_id": "@vue/babel-sugar-v-on@1.0.0-beta.3",
"_inBundle": false,
"_integrity": "sha512-F+GapxCiy50jf2Q2B4exw+KYBzlGdeKMAMW1Dbvb0Oa59SA0CH6tsUOIAsXb0A05jwwg/of0LaVeo+4aLefVxQ==",
"_location": "/@vue/babel-sugar-v-on",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "@vue/babel-sugar-v-on@^1.0.0-beta.3",
"name": "@vue/babel-sugar-v-on",
"escapedName": "@vue%2fbabel-sugar-v-on",
"scope": "@vue",
"rawSpec": "^1.0.0-beta.3",
"saveSpec": null,
"fetchSpec": "^1.0.0-beta.3"
},
"_requiredBy": [
"/@vue/babel-preset-jsx"
],
"_resolved": "https://registry.npmjs.org/@vue/babel-sugar-v-on/-/babel-sugar-v-on-1.0.0-beta.3.tgz",
"_shasum": "2f5fedb43883f603fe76010f253b85c7465855fe",
"_spec": "@vue/babel-sugar-v-on@^1.0.0-beta.3",
"_where": "D:\\Atom\\Git\\Laravel_CSSd\\node_modules\\@vue\\babel-preset-jsx",
"author": {
"name": "Nick Messing",
"email": "dot.nick.dot.messing@gmail.com"
},
"bundleDependencies": false,
"dependencies": {
"@babel/plugin-syntax-jsx": "^7.2.0",
"@vue/babel-plugin-transform-vue-jsx": "^1.0.0-beta.3",
"camelcase": "^5.0.0"
},
"deprecated": false,
"description": "Babel syntactic sugar for v-model support in Vue JSX",
"devDependencies": {
"@babel/cli": "^7.2.0",
"@babel/core": "^7.2.0",
"@babel/preset-env": "^7.2.0",
"@vue/test-utils": "^1.0.0-beta.26",
"ava": "^0.25.0",
"jsdom": "^13.0.0",
"jsdom-global": "^3.0.2",
"ninos": "^2.0.2",
"nyc": "^13.1.0",
"rollup": "^0.67.4",
"rollup-plugin-babel": "4.0.3",
"rollup-plugin-babel-minify": "^6.2.0",
"rollup-plugin-istanbul": "^2.0.1",
"vue": "^2.5.17",
"vue-template-compiler": "^2.5.17"
},
"files": [],
"gitHead": "44d4d3a822fffea4c978b46975c987f445e2be23",
"license": "MIT",
"main": "dist/plugin.js",
"name": "@vue/babel-sugar-v-on",
"nyc": {
"exclude": [
"dist",
"test"
]
},
"private": false,
"repository": {
"type": "git",
"url": "https://github.com/vuejs/jsx/tree/master/packages/babel-sugar-v-on"
},
"scripts": {
"build": "rollup -c",
"build:test": "rollup -c rollup.config.testing.js",
"prepublish": "yarn build",
"pretest:functional": "yarn build:test && nyc --reporter=html --reporter=text-summary babel test/functional.js --plugins ./dist/plugin.testing.js,./node_modules/@vue/babel-plugin-transform-vue-jsx/dist/plugin.js --out-file test/functional-compiled.js",
"pretest:snapshot": "yarn build:test",
"test": "rm -rf coverage* && yarn test:snapshot && mv coverage coverage-snapshot && yarn test:functional && mv coverage coverage-functional",
"test:functional": "ava -v test/functional-compiled.js",
"test:snapshot": "nyc --reporter=html --reporter=text-summary ava -v test/snapshot.js"
},
"version": "1.0.0-beta.3"
}
+21
View File
@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2017-present, Yuxi (Evan) You
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.
+3
View File
@@ -0,0 +1,3 @@
# @vue/cli-overlay
> overlay for vue-cli
+61
View File
@@ -0,0 +1,61 @@
{
"_args": [
[
"@vue/cli-overlay@3.5.1",
"D:\\Atom\\Git\\Laravel_CSSD"
]
],
"_development": true,
"_from": "@vue/cli-overlay@3.5.1",
"_id": "@vue/cli-overlay@3.5.1",
"_inBundle": false,
"_integrity": "sha512-DqzfkbKJfuzcNbJouA7ZaLX77xn7FCcVUJaPYVH8qm3pNhIz2tmbfN6WVBLU8XC5FNFFWzLjHmg9rpaEBq7RCA==",
"_location": "/@vue/cli-overlay",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "@vue/cli-overlay@3.5.1",
"name": "@vue/cli-overlay",
"escapedName": "@vue%2fcli-overlay",
"scope": "@vue",
"rawSpec": "3.5.1",
"saveSpec": null,
"fetchSpec": "3.5.1"
},
"_requiredBy": [
"/@vue/cli-service"
],
"_resolved": "https://registry.npmjs.org/@vue/cli-overlay/-/cli-overlay-3.5.1.tgz",
"_spec": "3.5.1",
"_where": "D:\\Atom\\Git\\Laravel_CSSD",
"author": {
"name": "Evan You"
},
"bugs": {
"url": "https://github.com/vuejs/vue-cli/issues"
},
"description": "error overlay & dev server middleware for vue-cli",
"files": [
"dist"
],
"gitHead": "0b363bec49164c2476dac59f6aa9bf42d4eba552",
"homepage": "https://github.com/vuejs/vue-cli/tree/dev/packages/@vue/cli-overlay#readme",
"keywords": [
"vue",
"cli",
"cli-overlay"
],
"license": "MIT",
"main": "dist/client.js",
"name": "@vue/cli-overlay",
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git",
"url": "git+https://github.com/vuejs/vue-cli.git",
"directory": "packages/@vue/cli-overlay"
},
"version": "3.5.1"
}
+21
View File
@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2017-present, Yuxi (Evan) You
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.
+39
View File
@@ -0,0 +1,39 @@
# @vue/cli-plugin-babel
> babel plugin for vue-cli
## Configuration
Uses Babel 7 + `babel-loader` + [@vue/babel-preset-app](https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/babel-preset-app) by default, but can be configured via `babel.config.js` to use any other Babel presets or plugins.
By default, `babel-loader` excludes files inside `node_modules` dependencies. If you wish to explicitly transpile a dependency module, you will need to add it to the `transpileDependencies` option in `vue.config.js`:
``` js
module.exports = {
transpileDependencies: [
// can be string or regex
'my-dep',
/other-dep/
]
}
```
## Caching
[cache-loader](https://github.com/webpack-contrib/cache-loader) is enabled by default and cache is stored in `<projectRoot>/node_modules/.cache/babel-loader`.
## Parallelization
[thread-loader](https://github.com/webpack-contrib/thread-loader) is enabled by default when the machine has more than 1 CPU cores. This can be turned off by setting `parallel: false` in `vue.config.js`.
## Installing in an Already Created Project
``` sh
vue add @vue/babel
```
## Injected webpack-chain Rules
- `config.rule('js')`
- `config.rule('js').use('babel-loader')`
- `config.rule('js').use('cache-loader')`
+16
View File
@@ -0,0 +1,16 @@
module.exports = api => {
// Most likely you want to overwrite the whole config to ensure it's working
// without conflicts, e.g. for a project that used Jest without Babel.
// It should be rare for the user to have their own special babel config
// without using the Babel plugin already.
delete api.generator.files['babel.config.js']
api.extendPackage({
babel: {
presets: ['@vue/app']
},
dependencies: {
'core-js': '^2.6.5'
}
})
}
+71
View File
@@ -0,0 +1,71 @@
const path = require('path')
const { isWindows } = require('@vue/cli-shared-utils')
function genTranspileDepRegex (transpileDependencies) {
const deps = transpileDependencies.map(dep => {
if (typeof dep === 'string') {
const depPath = path.join('node_modules', dep, '/')
return isWindows
? depPath.replace(/\\/g, '\\\\') // double escape for windows style path
: depPath
} else if (dep instanceof RegExp) {
return dep.source
}
})
return deps.length ? new RegExp(deps.join('|')) : null
}
module.exports = (api, options) => {
const useThreads = process.env.NODE_ENV === 'production' && options.parallel
const cliServicePath = require('path').dirname(require.resolve('@vue/cli-service'))
const transpileDepRegex = genTranspileDepRegex(options.transpileDependencies)
api.chainWebpack(webpackConfig => {
webpackConfig.resolveLoader.modules.prepend(path.join(__dirname, 'node_modules'))
const jsRule = webpackConfig.module
.rule('js')
.test(/\.m?jsx?$/)
.exclude
.add(filepath => {
// always transpile js in vue files
if (/\.vue\.jsx?$/.test(filepath)) {
return false
}
// exclude dynamic entries from cli-service
if (filepath.startsWith(cliServicePath)) {
return true
}
// check if this is something the user explicitly wants to transpile
if (transpileDepRegex && transpileDepRegex.test(filepath)) {
return false
}
// Don't transpile node_modules
return /node_modules/.test(filepath)
})
.end()
.use('cache-loader')
.loader('cache-loader')
.options(api.genCacheConfig('babel-loader', {
'@babel/core': require('@babel/core/package.json').version,
'@vue/babel-preset-app': require('@vue/babel-preset-app/package.json').version,
'babel-loader': require('babel-loader/package.json').version,
modern: !!process.env.VUE_CLI_MODERN_BUILD,
browserslist: api.service.pkg.browserslist
}, [
'babel.config.js',
'.browserslistrc'
]))
.end()
if (useThreads) {
jsRule
.use('thread-loader')
.loader('thread-loader')
}
jsRule
.use('babel-loader')
.loader('babel-loader')
})
}
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 707 B

+65
View File
@@ -0,0 +1,65 @@
{
"_args": [
[
"@vue/cli-plugin-babel@3.5.5",
"D:\\Atom\\Git\\Laravel_CSSD"
]
],
"_development": true,
"_from": "@vue/cli-plugin-babel@3.5.5",
"_id": "@vue/cli-plugin-babel@3.5.5",
"_inBundle": false,
"_integrity": "sha512-ew+EWL2ur234wqQfI1AvWcghjWQ2PlSVpUAfnDlejplDzXSHz7455IIwN7Auhs7siEbls3EVd/bl/ieKGjwY5g==",
"_location": "/@vue/cli-plugin-babel",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "@vue/cli-plugin-babel@3.5.5",
"name": "@vue/cli-plugin-babel",
"escapedName": "@vue%2fcli-plugin-babel",
"scope": "@vue",
"rawSpec": "3.5.5",
"saveSpec": null,
"fetchSpec": "3.5.5"
},
"_requiredBy": [
"#DEV:/"
],
"_resolved": "https://registry.npmjs.org/@vue/cli-plugin-babel/-/cli-plugin-babel-3.5.5.tgz",
"_spec": "3.5.5",
"_where": "D:\\Atom\\Git\\Laravel_CSSD",
"author": {
"name": "Evan You"
},
"bugs": {
"url": "https://github.com/vuejs/vue-cli/issues"
},
"dependencies": {
"@babel/core": "^7.0.0",
"@vue/babel-preset-app": "^3.5.5",
"@vue/cli-shared-utils": "^3.5.1",
"babel-loader": "^8.0.5",
"webpack": ">=4 < 4.29"
},
"description": "babel plugin for vue-cli",
"gitHead": "22acaf6498750f8a69ab54ccf51fa92ebe54f9d7",
"homepage": "https://github.com/vuejs/vue-cli/tree/dev/packages/@vue/cli-plugin-babel#readme",
"keywords": [
"vue",
"cli",
"babel"
],
"license": "MIT",
"main": "index.js",
"name": "@vue/cli-plugin-babel",
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git",
"url": "git+https://github.com/vuejs/vue-cli.git",
"directory": "packages/@vue/cli-plugin-babel"
},
"version": "3.5.5"
}
+21
View File
@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2017-present, Yuxi (Evan) You
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.
+72
View File
@@ -0,0 +1,72 @@
# @vue/cli-plugin-eslint
> eslint plugin for vue-cli
## Injected Commands
- **`vue-cli-service lint`**
```
Usage: vue-cli-service lint [options] [...files]
Options:
--format [formatter] specify formatter (default: codeframe)
--no-fix do not fix errors
--max-errors specify number of errors to make build failed (default: 0)
--max-warnings specify number of warnings to make build failed (default: Infinity)
```
Lints and fixes files. If no specific files are given, it lints all files in `src` and `test`.
Other [ESLint CLI options](https://eslint.org/docs/user-guide/command-line-interface#options) are also supported.
## Configuration
ESLint can be configured via `.eslintrc` or the `eslintConfig` field in `package.json`.
Lint-on-save during development with `eslint-loader` is enabled by default. It can be disabled with the `lintOnSave` option in `vue.config.js`:
``` js
module.exports = {
lintOnSave: false
}
```
When set to `true`, `eslint-loader` will emit lint errors as warnings. By default, warnings are only logged to the terminal and does not fail the compilation.
To make lint errors show up in the browser overlay, you can use `lintOnSave: 'error'`. This will force `eslint-loader` to always emit errors. this also means lint errors will now cause the compilation to fail.
Alternatively, you can configure the overlay to display both warnings and errors:
``` js
// vue.config.js
module.exports = {
devServer: {
overlay: {
warnings: true,
errors: true
}
}
}
```
When `lintOnSave` is a truthy value, `eslint-loader` will be applied in both development and production. If you want to disable `eslint-loader` during production build, you can use the following config:
``` js
// vue.config.js
module.exports = {
lintOnSave: process.env.NODE_ENV !== 'production'
}
```
## Installing in an Already Created Project
``` sh
vue add @vue/eslint
```
## Injected webpack-chain Rules
- `config.module.rule('eslint')`
- `config.module.rule('eslint').use('eslint-loader')`
+30
View File
@@ -0,0 +1,30 @@
exports.config = api => {
const config = {
root: true,
env: { node: true },
extends: ['plugin:vue/essential'],
rules: {
'no-console': makeJSOnlyValue(`process.env.NODE_ENV === 'production' ? 'error' : 'off'`),
'no-debugger': makeJSOnlyValue(`process.env.NODE_ENV === 'production' ? 'error' : 'off'`)
}
}
if (!api.hasPlugin('typescript')) {
config.parserOptions = {
parser: 'babel-eslint'
}
}
return config
}
// __expression is a special flag that allows us to customize stringification
// output when extracting configs into standalone files
function makeJSOnlyValue (str) {
const fn = () => {}
fn.__expression = str
return fn
}
const baseExtensions = ['.js', '.jsx', '.vue']
exports.extensions = api => api.hasPlugin('typescript')
? baseExtensions.concat('.ts', '.tsx')
: baseExtensions
+122
View File
@@ -0,0 +1,122 @@
const fs = require('fs')
const path = require('path')
module.exports = (api, { config, lintOn = [] }, _, invoking) => {
if (typeof lintOn === 'string') {
lintOn = lintOn.split(',')
}
const eslintConfig = require('../eslintOptions').config(api)
const pkg = {
scripts: {
lint: 'vue-cli-service lint'
},
eslintConfig,
// TODO:
// Move these dependencies to package.json in v4.
// Now in v3 we have to add redundant eslint related dependencies
// in order to keep compatibility with v3.0.x users who defaults to ESlint v4.
devDependencies: {
'babel-eslint': '^10.0.1',
'eslint': '^5.8.0',
'eslint-plugin-vue': '^5.0.0'
}
}
const injectEditorConfig = (config) => {
const filePath = api.resolve('.editorconfig')
if (fs.existsSync(filePath)) {
// Append to existing .editorconfig
api.render(files => {
const configPath = path.resolve(__dirname, `./template/${config}/_editorconfig`)
const editorconfig = fs.readFileSync(configPath, 'utf-8')
files['.editorconfig'] += `\n${editorconfig}`
})
} else {
api.render(`./template/${config}`)
}
}
if (config === 'airbnb') {
eslintConfig.extends.push('@vue/airbnb')
Object.assign(pkg.devDependencies, {
'@vue/eslint-config-airbnb': '^4.0.0'
})
injectEditorConfig('airbnb')
} else if (config === 'standard') {
eslintConfig.extends.push('@vue/standard')
Object.assign(pkg.devDependencies, {
'@vue/eslint-config-standard': '^4.0.0'
})
injectEditorConfig('standard')
} else if (config === 'prettier') {
eslintConfig.extends.push('@vue/prettier')
Object.assign(pkg.devDependencies, {
'@vue/eslint-config-prettier': '^4.0.1'
})
// prettier & default config do not have any style rules
// so no need to generate an editorconfig file
} else {
// default
eslintConfig.extends.push('eslint:recommended')
}
if (!lintOn.includes('save')) {
pkg.vue = {
lintOnSave: false // eslint-loader configured in runtime plugin
}
}
if (lintOn.includes('commit')) {
Object.assign(pkg.devDependencies, {
'lint-staged': '^8.1.4'
})
pkg.gitHooks = {
'pre-commit': 'lint-staged'
}
pkg['lint-staged'] = {
'*.{js,vue}': ['vue-cli-service lint', 'git add']
}
}
api.extendPackage(pkg)
// typescript support
if (api.hasPlugin('typescript')) {
applyTS(api)
}
// invoking only
if (invoking) {
if (api.hasPlugin('unit-mocha')) {
// eslint-disable-next-line node/no-extraneous-require
require('@vue/cli-plugin-unit-mocha/generator').applyESLint(api)
} else if (api.hasPlugin('unit-jest')) {
// eslint-disable-next-line node/no-extraneous-require
require('@vue/cli-plugin-unit-jest/generator').applyESLint(api)
}
}
// lint & fix after create to ensure files adhere to chosen config
if (config && config !== 'base') {
api.onCreateComplete(() => {
require('../lint')({ silent: true }, api)
})
}
}
const applyTS = module.exports.applyTS = api => {
api.extendPackage({
eslintConfig: {
extends: ['@vue/typescript'],
parserOptions: {
parser: '@typescript-eslint/parser'
}
},
devDependencies: {
'@vue/eslint-config-typescript': '^4.0.0'
}
})
}
@@ -0,0 +1,7 @@
[*.{js,jsx,ts,tsx,vue}]
indent_style = space
indent_size = 2
end_of_line = lf
trim_trailing_whitespace = true
insert_final_newline = true
max_line_length = 100
@@ -0,0 +1,5 @@
[*.{js,jsx,ts,tsx,vue}]
indent_style = space
indent_size = 2
trim_trailing_whitespace = true
insert_final_newline = true
+73
View File
@@ -0,0 +1,73 @@
const path = require('path')
module.exports = (api, options) => {
if (options.lintOnSave) {
const extensions = require('./eslintOptions').extensions(api)
// Use loadModule to allow users to customize their ESLint dependency version.
const { resolveModule, loadModule } = require('@vue/cli-shared-utils')
const cwd = api.getCwd()
const eslintPkg =
loadModule('eslint/package.json', cwd, true) ||
require('eslint/package.json')
// eslint-loader doesn't bust cache when eslint config changes
// so we have to manually generate a cache identifier that takes the config
// into account.
const { cacheIdentifier } = api.genCacheConfig(
'eslint-loader',
{
'eslint-loader': require('eslint-loader/package.json').version,
'eslint': eslintPkg.version
},
[
'.eslintrc.js',
'.eslintrc.yaml',
'.eslintrc.yml',
'.eslintrc.json',
'.eslintrc',
'package.json'
]
)
api.chainWebpack(webpackConfig => {
webpackConfig.resolveLoader.modules.prepend(path.join(__dirname, 'node_modules'))
webpackConfig.module
.rule('eslint')
.pre()
.exclude
.add(/node_modules/)
.add(require('path').dirname(require.resolve('@vue/cli-service')))
.end()
.test(/\.(vue|(j|t)sx?)$/)
.use('eslint-loader')
.loader('eslint-loader')
.options({
extensions,
cache: true,
cacheIdentifier,
emitWarning: options.lintOnSave !== 'error',
emitError: options.lintOnSave === 'error',
eslintPath: resolveModule('eslint', cwd) || require.resolve('eslint'),
formatter:
loadModule('eslint/lib/formatters/codeframe', cwd, true) ||
require('eslint/lib/formatters/codeframe')
})
})
}
api.registerCommand('lint', {
description: 'lint and fix source files',
usage: 'vue-cli-service lint [options] [...files]',
options: {
'--format [formatter]': 'specify formatter (default: codeframe)',
'--no-fix': 'do not fix errors or warnings',
'--no-fix-warnings': 'fix errors, but do not fix warnings',
'--max-errors [limit]': 'specify number of errors to make build failed (default: 0)',
'--max-warnings [limit]': 'specify number of warnings to make build failed (default: Infinity)'
},
details: 'For more options, see https://eslint.org/docs/user-guide/command-line-interface#options'
}, args => {
require('./lint')(args, api)
})
}
+142
View File
@@ -0,0 +1,142 @@
const fs = require('fs')
const globby = require('globby')
const renamedArrayArgs = {
ext: 'extensions',
env: 'envs',
global: 'globals',
rulesdir: 'rulePaths',
plugin: 'plugins',
'ignore-pattern': 'ignorePattern'
}
const renamedArgs = {
'inline-config': 'allowInlineConfig',
rule: 'rules',
eslintrc: 'useEslintrc',
c: 'configFile',
config: 'configFile'
}
module.exports = function lint (args = {}, api) {
const path = require('path')
const cwd = api.resolve('.')
const { log, done, exit, chalk, loadModule } = require('@vue/cli-shared-utils')
const { CLIEngine } = loadModule('eslint', cwd, true) || require('eslint')
const extensions = require('./eslintOptions').extensions(api)
const argsConfig = normalizeConfig(args)
const config = Object.assign({
extensions,
fix: true,
cwd
}, argsConfig)
const noFixWarnings = (argsConfig.fixWarnings === false)
const noFixWarningsPredicate = (lintResult) => lintResult.severity === 2
config.fix = config.fix && (noFixWarnings ? noFixWarningsPredicate : true)
if (!fs.existsSync(api.resolve('.eslintignore')) && !config.ignorePattern) {
// .eslintrc.js files (ignored by default)
// However, we need to lint & fix them so as to make the default generated project's
// code style consistent with user's selected eslint config.
// Though, if users provided their own `.eslintignore` file, we don't want to
// add our own customized ignore pattern here (in eslint, ignorePattern is
// an addition to eslintignore, i.e. it can't be overriden by user),
// following the principle of least astonishment.
config.ignorePattern = [
'!.*.js',
'!{src,tests}/**/.*.js'
]
}
const engine = new CLIEngine(config)
const defaultFilesToLint = [
'src',
'tests',
// root config files
'*.js',
'.*.js'
]
.filter(pattern =>
globby
.sync(path.join(cwd, pattern))
.some(p => !engine.isPathIgnored(p))
)
const files = args._ && args._.length
? args._
: defaultFilesToLint
// mock process.cwd before executing
// See:
// https://github.com/vuejs/vue-cli/issues/2554
// https://github.com/benmosher/eslint-plugin-import/issues/602
// https://github.com/eslint/eslint/issues/11218
const processCwd = process.cwd
if (!api.invoking) {
process.cwd = () => cwd
}
const report = engine.executeOnFiles(files)
process.cwd = processCwd
const formatter = engine.getFormatter(args.format || 'codeframe')
if (config.fix) {
CLIEngine.outputFixes(report)
}
const maxErrors = argsConfig.maxErrors || 0
const maxWarnings = typeof argsConfig.maxWarnings === 'number' ? argsConfig.maxWarnings : Infinity
const isErrorsExceeded = report.errorCount > maxErrors
const isWarningsExceeded = report.warningCount > maxWarnings
if (!isErrorsExceeded && !isWarningsExceeded) {
if (!args.silent) {
const hasFixed = report.results.some(f => f.output)
if (hasFixed) {
log(`The following files have been auto-fixed:`)
log()
report.results.forEach(f => {
if (f.output) {
log(` ${chalk.blue(path.relative(cwd, f.filePath))}`)
}
})
log()
}
if (report.warningCount || report.errorCount) {
console.log(formatter(report.results))
} else {
done(hasFixed ? `All lint errors auto-fixed.` : `No lint errors found!`)
}
}
} else {
console.log(formatter(report.results))
if (isErrorsExceeded && typeof argsConfig.maxErrors === 'number') {
log(`Eslint found too many errors (maximum: ${argsConfig.maxErrors}).`)
}
if (isWarningsExceeded) {
log(`Eslint found too many warnings (maximum: ${argsConfig.maxWarnings}).`)
}
exit(1)
}
}
function normalizeConfig (args) {
const config = {}
for (const key in args) {
if (renamedArrayArgs[key]) {
config[renamedArrayArgs[key]] = args[key].split(',')
} else if (renamedArgs[key]) {
config[renamedArgs[key]] = args[key]
} else if (key !== '_') {
config[camelize(key)] = args[key]
}
}
return config
}
function camelize (str) {
return str.replace(/-(\w)/g, (_, c) => c ? c.toUpperCase() : '')
}
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 712 B

+15
View File
@@ -0,0 +1,15 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/../eslint/bin/eslint.js" "$@"
ret=$?
else
node "$basedir/../eslint/bin/eslint.js" "$@"
ret=$?
fi
exit $ret
+7
View File
@@ -0,0 +1,7 @@
@IF EXIST "%~dp0\node.exe" (
"%~dp0\node.exe" "%~dp0\..\eslint\bin\eslint.js" %*
) ELSE (
@SETLOCAL
@SET PATHEXT=%PATHEXT:;.JS;=;%
node "%~dp0\..\eslint\bin\eslint.js" %*
)
+20
View File
@@ -0,0 +1,20 @@
var Ajv = require('ajv');
var ajv = new Ajv({allErrors: true});
var schema = {
"properties": {
"foo": { "type": "string" },
"bar": { "type": "number", "maximum": 3 }
}
};
var validate = ajv.compile(schema);
test({"foo": "abc", "bar": 2});
test({"foo": 2, "bar": 4});
function test(data) {
var valid = validate(data);
if (valid) console.log('Valid!');
else console.log('Invalid: ' + ajv.errorsText(validate.errors));
}
+22
View File
@@ -0,0 +1,22 @@
The MIT License (MIT)
Copyright (c) 2015 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.
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+49
View File
@@ -0,0 +1,49 @@
'use strict';
var KEYWORDS = [
'multipleOf',
'maximum',
'exclusiveMaximum',
'minimum',
'exclusiveMinimum',
'maxLength',
'minLength',
'pattern',
'additionalItems',
'maxItems',
'minItems',
'uniqueItems',
'maxProperties',
'minProperties',
'required',
'additionalProperties',
'enum',
'format',
'const'
];
module.exports = function (metaSchema, keywordsJsonPointers) {
for (var i=0; i<keywordsJsonPointers.length; i++) {
metaSchema = JSON.parse(JSON.stringify(metaSchema));
var segments = keywordsJsonPointers[i].split('/');
var keywords = metaSchema;
var j;
for (j=1; j<segments.length; j++)
keywords = keywords[segments[j]];
for (j=0; j<KEYWORDS.length; j++) {
var key = KEYWORDS[j];
var schema = keywords[key];
if (schema) {
keywords[key] = {
anyOf: [
schema,
{ $ref: 'https://raw.githubusercontent.com/epoberezkin/ajv/master/lib/refs/$data.json#' }
]
};
}
}
}
return metaSchema;
};
+358
View File
@@ -0,0 +1,358 @@
declare var ajv: {
(options?: ajv.Options): ajv.Ajv;
new (options?: ajv.Options): ajv.Ajv;
ValidationError: ValidationError;
MissingRefError: MissingRefError;
$dataMetaSchema: object;
}
declare namespace ajv {
interface Ajv {
/**
* Validate data using schema
* Schema will be compiled and cached (using serialized JSON as key, [fast-json-stable-stringify](https://github.com/epoberezkin/fast-json-stable-stringify) is used to serialize by default).
* @param {string|object|Boolean} schemaKeyRef key, ref or schema object
* @param {Any} data to be validated
* @return {Boolean} validation result. Errors from the last validation will be available in `ajv.errors` (and also in compiled schema: `schema.errors`).
*/
validate(schemaKeyRef: object | string | boolean, data: any): boolean | Thenable<any>;
/**
* Create validating function for passed schema.
* @param {object|Boolean} schema schema object
* @return {Function} validating function
*/
compile(schema: object | boolean): ValidateFunction;
/**
* Creates validating function for passed schema with asynchronous loading of missing schemas.
* `loadSchema` option should be a function that accepts schema uri and node-style callback.
* @this Ajv
* @param {object|Boolean} schema schema object
* @param {Boolean} meta optional true to compile meta-schema; this parameter can be skipped
* @param {Function} callback optional node-style callback, it is always called with 2 parameters: error (or null) and validating function.
* @return {Thenable<ValidateFunction>} validating function
*/
compileAsync(schema: object | boolean, meta?: Boolean, callback?: (err: Error, validate: ValidateFunction) => any): Thenable<ValidateFunction>;
/**
* Adds schema to the instance.
* @param {object|Array} schema schema or array of schemas. If array is passed, `key` and other parameters will be ignored.
* @param {string} key 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`.
* @return {Ajv} this for method chaining
*/
addSchema(schema: Array<object> | object, key?: string): Ajv;
/**
* Add schema that will be used to validate other schemas
* options in META_IGNORE_OPTIONS are alway set to false
* @param {object} schema schema object
* @param {string} key optional schema key
* @return {Ajv} this for method chaining
*/
addMetaSchema(schema: object, key?: string): Ajv;
/**
* Validate schema
* @param {object|Boolean} schema schema to validate
* @return {Boolean} true if schema is valid
*/
validateSchema(schema: object | boolean): boolean;
/**
* Get compiled schema from the instance by `key` or `ref`.
* @param {string} keyRef `key` that was passed to `addSchema` or full schema reference (`schema.id` or resolved id).
* @return {Function} schema validating function (with property `schema`).
*/
getSchema(keyRef: string): ValidateFunction;
/**
* 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.
* @param {string|object|RegExp|Boolean} schemaKeyRef key, ref, pattern to match key/ref or schema object
* @return {Ajv} this for method chaining
*/
removeSchema(schemaKeyRef?: object | string | RegExp | boolean): Ajv;
/**
* Add custom format
* @param {string} name format name
* @param {string|RegExp|Function} format string is converted to RegExp; function should return boolean (true when valid)
* @return {Ajv} this for method chaining
*/
addFormat(name: string, format: FormatValidator | FormatDefinition): Ajv;
/**
* Define custom keyword
* @this Ajv
* @param {string} keyword custom keyword, should be a valid identifier, should be different from all standard, custom and macro keywords.
* @param {object} definition keyword definition object with properties `type` (type(s) which the keyword applies to), `validate` or `compile`.
* @return {Ajv} this for method chaining
*/
addKeyword(keyword: string, definition: KeywordDefinition): Ajv;
/**
* Get keyword definition
* @this Ajv
* @param {string} keyword pre-defined or custom keyword.
* @return {object|Boolean} custom keyword definition, `true` if it is a predefined keyword, `false` otherwise.
*/
getKeyword(keyword: string): object | boolean;
/**
* Remove keyword
* @this Ajv
* @param {string} keyword pre-defined or custom keyword.
* @return {Ajv} this for method chaining
*/
removeKeyword(keyword: string): Ajv;
/**
* Convert array of error message objects to string
* @param {Array<object>} errors optional array of validation errors, if not passed errors from the instance are used.
* @param {object} options optional options with properties `separator` and `dataVar`.
* @return {string} human readable string with all errors descriptions
*/
errorsText(errors?: Array<ErrorObject>, options?: ErrorsTextOptions): string;
errors?: Array<ErrorObject>;
}
interface Thenable <R> {
then <U> (onFulfilled?: (value: R) => U | Thenable<U>, onRejected?: (error: any) => U | Thenable<U>): Thenable<U>;
}
interface ValidateFunction {
(
data: any,
dataPath?: string,
parentData?: object | Array<any>,
parentDataProperty?: string | number,
rootData?: object | Array<any>
): boolean | Thenable<any>;
schema?: object | boolean;
errors?: null | Array<ErrorObject>;
refs?: object;
refVal?: Array<any>;
root?: ValidateFunction | object;
$async?: true;
source?: object;
}
interface Options {
$data?: boolean;
allErrors?: boolean;
verbose?: boolean;
jsonPointers?: boolean;
uniqueItems?: boolean;
unicode?: boolean;
format?: string;
formats?: object;
unknownFormats?: true | string[] | 'ignore';
schemas?: Array<object> | object;
schemaId?: '$id' | 'id';
missingRefs?: true | 'ignore' | 'fail';
extendRefs?: true | 'ignore' | 'fail';
loadSchema?: (uri: string, cb?: (err: Error, schema: object) => void) => Thenable<object | boolean>;
removeAdditional?: boolean | 'all' | 'failing';
useDefaults?: boolean | 'shared';
coerceTypes?: boolean | 'array';
async?: boolean | string;
transpile?: string | ((code: string) => string);
meta?: boolean | object;
validateSchema?: boolean | 'log';
addUsedSchema?: boolean;
inlineRefs?: boolean | number;
passContext?: boolean;
loopRequired?: number;
ownProperties?: boolean;
multipleOfPrecision?: boolean | number;
errorDataPath?: string,
messages?: boolean;
sourceCode?: boolean;
processCode?: (code: string) => string;
cache?: object;
}
type FormatValidator = string | RegExp | ((data: string) => boolean | Thenable<any>);
interface FormatDefinition {
validate: FormatValidator;
compare: (data1: string, data2: string) => number;
async?: boolean;
}
interface KeywordDefinition {
type?: string | Array<string>;
async?: boolean;
$data?: boolean;
errors?: boolean | string;
metaSchema?: object;
// schema: false makes validate not to expect schema (ValidateFunction)
schema?: boolean;
modifying?: boolean;
valid?: boolean;
// one and only one of the following properties should be present
validate?: SchemaValidateFunction | ValidateFunction;
compile?: (schema: any, parentSchema: object, it: CompilationContext) => ValidateFunction;
macro?: (schema: any, parentSchema: object, it: CompilationContext) => object | boolean;
inline?: (it: CompilationContext, keyword: string, schema: any, parentSchema: object) => string;
}
interface CompilationContext {
level: number;
dataLevel: number;
schema: any;
schemaPath: string;
baseId: string;
async: boolean;
opts: Options;
formats: {
[index: string]: FormatDefinition | undefined;
};
compositeRule: boolean;
validate: (schema: object) => boolean;
util: {
copy(obj: any, target?: any): any;
toHash(source: string[]): { [index: string]: true | undefined };
equal(obj: any, target: any): boolean;
getProperty(str: string): string;
schemaHasRules(schema: object, rules: any): string;
escapeQuotes(str: string): string;
toQuotedString(str: string): string;
getData(jsonPointer: string, dataLevel: number, paths: string[]): string;
escapeJsonPointer(str: string): string;
unescapeJsonPointer(str: string): string;
escapeFragment(str: string): string;
unescapeFragment(str: string): string;
};
self: Ajv;
}
interface SchemaValidateFunction {
(
schema: any,
data: any,
parentSchema?: object,
dataPath?: string,
parentData?: object | Array<any>,
parentDataProperty?: string | number,
rootData?: object | Array<any>
): boolean | Thenable<any>;
errors?: Array<ErrorObject>;
}
interface ErrorsTextOptions {
separator?: string;
dataVar?: string;
}
interface ErrorObject {
keyword: string;
dataPath: string;
schemaPath: string;
params: ErrorParameters;
// Added to validation errors of propertyNames keyword schema
propertyName?: string;
// Excluded if messages set to false.
message?: string;
// These are added with the `verbose` option.
schema?: any;
parentSchema?: object;
data?: any;
}
type ErrorParameters = RefParams | LimitParams | AdditionalPropertiesParams |
DependenciesParams | FormatParams | ComparisonParams |
MultipleOfParams | PatternParams | RequiredParams |
TypeParams | UniqueItemsParams | CustomParams |
PatternGroupsParams | PatternRequiredParams |
PropertyNamesParams | SwitchParams | NoParams | EnumParams;
interface RefParams {
ref: string;
}
interface LimitParams {
limit: number;
}
interface AdditionalPropertiesParams {
additionalProperty: string;
}
interface DependenciesParams {
property: string;
missingProperty: string;
depsCount: number;
deps: string;
}
interface FormatParams {
format: string
}
interface ComparisonParams {
comparison: string;
limit: number | string;
exclusive: boolean;
}
interface MultipleOfParams {
multipleOf: number;
}
interface PatternParams {
pattern: string;
}
interface RequiredParams {
missingProperty: string;
}
interface TypeParams {
type: string;
}
interface UniqueItemsParams {
i: number;
j: number;
}
interface CustomParams {
keyword: string;
}
interface PatternGroupsParams {
reason: string;
limit: number;
pattern: string;
}
interface PatternRequiredParams {
missingPattern: string;
}
interface PropertyNamesParams {
propertyName: string;
}
interface SwitchParams {
caseIndex: number;
}
interface NoParams {}
interface EnumParams {
allowedValues: Array<any>;
}
}
declare class ValidationError extends Error {
constructor(errors: Array<ajv.ErrorObject>);
message: string;
errors: Array<ajv.ErrorObject>;
ajv: true;
validation: true;
}
declare class MissingRefError extends Error {
constructor(baseId: string, ref: string, message?: string);
static message: (baseId: string, ref: string) => string;
message: string;
missingRef: string;
missingSchema: string;
}
export = ajv;
+502
View File
@@ -0,0 +1,502 @@
'use strict';
var compileSchema = require('./compile')
, resolve = require('./compile/resolve')
, Cache = require('./cache')
, SchemaObject = require('./compile/schema_obj')
, stableStringify = require('fast-json-stable-stringify')
, formats = require('./compile/formats')
, rules = require('./compile/rules')
, $dataMetaSchema = require('./$data')
, patternGroups = require('./patternGroups')
, util = require('./compile/util')
, co = require('co');
module.exports = Ajv;
Ajv.prototype.validate = validate;
Ajv.prototype.compile = compile;
Ajv.prototype.addSchema = addSchema;
Ajv.prototype.addMetaSchema = addMetaSchema;
Ajv.prototype.validateSchema = validateSchema;
Ajv.prototype.getSchema = getSchema;
Ajv.prototype.removeSchema = removeSchema;
Ajv.prototype.addFormat = addFormat;
Ajv.prototype.errorsText = errorsText;
Ajv.prototype._addSchema = _addSchema;
Ajv.prototype._compile = _compile;
Ajv.prototype.compileAsync = require('./compile/async');
var customKeyword = require('./keyword');
Ajv.prototype.addKeyword = customKeyword.add;
Ajv.prototype.getKeyword = customKeyword.get;
Ajv.prototype.removeKeyword = customKeyword.remove;
var errorClasses = require('./compile/error_classes');
Ajv.ValidationError = errorClasses.Validation;
Ajv.MissingRefError = errorClasses.MissingRef;
Ajv.$dataMetaSchema = $dataMetaSchema;
var META_SCHEMA_ID = 'http://json-schema.org/draft-06/schema';
var META_IGNORE_OPTIONS = [ 'removeAdditional', 'useDefaults', 'coerceTypes' ];
var META_SUPPORT_DATA = ['/properties'];
/**
* Creates validator instance.
* Usage: `Ajv(opts)`
* @param {Object} opts optional options
* @return {Object} ajv instance
*/
function Ajv(opts) {
if (!(this instanceof Ajv)) return new Ajv(opts);
opts = this._opts = util.copy(opts) || {};
setLogger(this);
this._schemas = {};
this._refs = {};
this._fragments = {};
this._formats = formats(opts.format);
var schemaUriFormat = this._schemaUriFormat = this._formats['uri-reference'];
this._schemaUriFormatFunc = function (str) { return schemaUriFormat.test(str); };
this._cache = opts.cache || new Cache;
this._loadingSchemas = {};
this._compilations = [];
this.RULES = rules();
this._getId = chooseGetId(opts);
opts.loopRequired = opts.loopRequired || Infinity;
if (opts.errorDataPath == 'property') opts._errorDataPathProperty = true;
if (opts.serialize === undefined) opts.serialize = stableStringify;
this._metaOpts = getMetaSchemaOptions(this);
if (opts.formats) addInitialFormats(this);
addDraft6MetaSchema(this);
if (typeof opts.meta == 'object') this.addMetaSchema(opts.meta);
addInitialSchemas(this);
if (opts.patternGroups) patternGroups(this);
}
/**
* Validate data using schema
* Schema will be compiled and cached (using serialized JSON as key. [fast-json-stable-stringify](https://github.com/epoberezkin/fast-json-stable-stringify) is used to serialize.
* @this Ajv
* @param {String|Object} schemaKeyRef key, ref or schema object
* @param {Any} data to be validated
* @return {Boolean} validation result. Errors from the last validation will be available in `ajv.errors` (and also in compiled schema: `schema.errors`).
*/
function validate(schemaKeyRef, data) {
var v;
if (typeof schemaKeyRef == 'string') {
v = this.getSchema(schemaKeyRef);
if (!v) throw new Error('no schema with key or ref "' + schemaKeyRef + '"');
} else {
var schemaObj = this._addSchema(schemaKeyRef);
v = schemaObj.validate || this._compile(schemaObj);
}
var valid = v(data);
if (v.$async === true)
return this._opts.async == '*' ? co(valid) : valid;
this.errors = v.errors;
return valid;
}
/**
* Create validating function for passed schema.
* @this Ajv
* @param {Object} schema schema object
* @param {Boolean} _meta true if schema is a meta-schema. Used internally to compile meta schemas of custom keywords.
* @return {Function} validating function
*/
function compile(schema, _meta) {
var schemaObj = this._addSchema(schema, undefined, _meta);
return schemaObj.validate || this._compile(schemaObj);
}
/**
* Adds schema to the instance.
* @this Ajv
* @param {Object|Array} schema schema or array of schemas. If array is passed, `key` and other parameters will be ignored.
* @param {String} key 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`.
* @param {Boolean} _skipValidation true to skip schema validation. Used internally, option validateSchema should be used instead.
* @param {Boolean} _meta true if schema is a meta-schema. Used internally, addMetaSchema should be used instead.
* @return {Ajv} this for method chaining
*/
function addSchema(schema, key, _skipValidation, _meta) {
if (Array.isArray(schema)){
for (var i=0; i<schema.length; i++) this.addSchema(schema[i], undefined, _skipValidation, _meta);
return this;
}
var id = this._getId(schema);
if (id !== undefined && typeof id != 'string')
throw new Error('schema id must be string');
key = resolve.normalizeId(key || id);
checkUnique(this, key);
this._schemas[key] = this._addSchema(schema, _skipValidation, _meta, true);
return this;
}
/**
* Add schema that will be used to validate other schemas
* options in META_IGNORE_OPTIONS are alway set to false
* @this Ajv
* @param {Object} schema schema object
* @param {String} key optional schema key
* @param {Boolean} skipValidation true to skip schema validation, can be used to override validateSchema option for meta-schema
* @return {Ajv} this for method chaining
*/
function addMetaSchema(schema, key, skipValidation) {
this.addSchema(schema, key, skipValidation, true);
return this;
}
/**
* Validate schema
* @this Ajv
* @param {Object} schema schema to validate
* @param {Boolean} throwOrLogError pass true to throw (or log) an error if invalid
* @return {Boolean} true if schema is valid
*/
function validateSchema(schema, throwOrLogError) {
var $schema = schema.$schema;
if ($schema !== undefined && typeof $schema != 'string')
throw new Error('$schema must be a string');
$schema = $schema || this._opts.defaultMeta || defaultMeta(this);
if (!$schema) {
this.logger.warn('meta-schema not available');
this.errors = null;
return true;
}
var currentUriFormat = this._formats.uri;
this._formats.uri = typeof currentUriFormat == 'function'
? this._schemaUriFormatFunc
: this._schemaUriFormat;
var valid;
try { valid = this.validate($schema, schema); }
finally { this._formats.uri = currentUriFormat; }
if (!valid && throwOrLogError) {
var message = 'schema is invalid: ' + this.errorsText();
if (this._opts.validateSchema == 'log') this.logger.error(message);
else throw new Error(message);
}
return valid;
}
function defaultMeta(self) {
var meta = self._opts.meta;
self._opts.defaultMeta = typeof meta == 'object'
? self._getId(meta) || meta
: self.getSchema(META_SCHEMA_ID)
? META_SCHEMA_ID
: undefined;
return self._opts.defaultMeta;
}
/**
* Get compiled schema from the instance by `key` or `ref`.
* @this Ajv
* @param {String} keyRef `key` that was passed to `addSchema` or full schema reference (`schema.id` or resolved id).
* @return {Function} schema validating function (with property `schema`).
*/
function getSchema(keyRef) {
var schemaObj = _getSchemaObj(this, keyRef);
switch (typeof schemaObj) {
case 'object': return schemaObj.validate || this._compile(schemaObj);
case 'string': return this.getSchema(schemaObj);
case 'undefined': return _getSchemaFragment(this, keyRef);
}
}
function _getSchemaFragment(self, ref) {
var res = resolve.schema.call(self, { schema: {} }, ref);
if (res) {
var schema = res.schema
, root = res.root
, baseId = res.baseId;
var v = compileSchema.call(self, schema, root, undefined, baseId);
self._fragments[ref] = new SchemaObject({
ref: ref,
fragment: true,
schema: schema,
root: root,
baseId: baseId,
validate: v
});
return v;
}
}
function _getSchemaObj(self, keyRef) {
keyRef = resolve.normalizeId(keyRef);
return self._schemas[keyRef] || self._refs[keyRef] || self._fragments[keyRef];
}
/**
* 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.
* @this Ajv
* @param {String|Object|RegExp} schemaKeyRef key, ref, pattern to match key/ref or schema object
* @return {Ajv} this for method chaining
*/
function removeSchema(schemaKeyRef) {
if (schemaKeyRef instanceof RegExp) {
_removeAllSchemas(this, this._schemas, schemaKeyRef);
_removeAllSchemas(this, this._refs, schemaKeyRef);
return this;
}
switch (typeof schemaKeyRef) {
case 'undefined':
_removeAllSchemas(this, this._schemas);
_removeAllSchemas(this, this._refs);
this._cache.clear();
return this;
case 'string':
var schemaObj = _getSchemaObj(this, schemaKeyRef);
if (schemaObj) this._cache.del(schemaObj.cacheKey);
delete this._schemas[schemaKeyRef];
delete this._refs[schemaKeyRef];
return this;
case 'object':
var serialize = this._opts.serialize;
var cacheKey = serialize ? serialize(schemaKeyRef) : schemaKeyRef;
this._cache.del(cacheKey);
var id = this._getId(schemaKeyRef);
if (id) {
id = resolve.normalizeId(id);
delete this._schemas[id];
delete this._refs[id];
}
}
return this;
}
function _removeAllSchemas(self, schemas, regex) {
for (var keyRef in schemas) {
var schemaObj = schemas[keyRef];
if (!schemaObj.meta && (!regex || regex.test(keyRef))) {
self._cache.del(schemaObj.cacheKey);
delete schemas[keyRef];
}
}
}
/* @this Ajv */
function _addSchema(schema, skipValidation, meta, shouldAddSchema) {
if (typeof schema != 'object' && typeof schema != 'boolean')
throw new Error('schema should be object or boolean');
var serialize = this._opts.serialize;
var cacheKey = serialize ? serialize(schema) : schema;
var cached = this._cache.get(cacheKey);
if (cached) return cached;
shouldAddSchema = shouldAddSchema || this._opts.addUsedSchema !== false;
var id = resolve.normalizeId(this._getId(schema));
if (id && shouldAddSchema) checkUnique(this, id);
var willValidate = this._opts.validateSchema !== false && !skipValidation;
var recursiveMeta;
if (willValidate && !(recursiveMeta = id && id == resolve.normalizeId(schema.$schema)))
this.validateSchema(schema, true);
var localRefs = resolve.ids.call(this, schema);
var schemaObj = new SchemaObject({
id: id,
schema: schema,
localRefs: localRefs,
cacheKey: cacheKey,
meta: meta
});
if (id[0] != '#' && shouldAddSchema) this._refs[id] = schemaObj;
this._cache.put(cacheKey, schemaObj);
if (willValidate && recursiveMeta) this.validateSchema(schema, true);
return schemaObj;
}
/* @this Ajv */
function _compile(schemaObj, root) {
if (schemaObj.compiling) {
schemaObj.validate = callValidate;
callValidate.schema = schemaObj.schema;
callValidate.errors = null;
callValidate.root = root ? root : callValidate;
if (schemaObj.schema.$async === true)
callValidate.$async = true;
return callValidate;
}
schemaObj.compiling = true;
var currentOpts;
if (schemaObj.meta) {
currentOpts = this._opts;
this._opts = this._metaOpts;
}
var v;
try { v = compileSchema.call(this, schemaObj.schema, root, schemaObj.localRefs); }
finally {
schemaObj.compiling = false;
if (schemaObj.meta) this._opts = currentOpts;
}
schemaObj.validate = v;
schemaObj.refs = v.refs;
schemaObj.refVal = v.refVal;
schemaObj.root = v.root;
return v;
function callValidate() {
var _validate = schemaObj.validate;
var result = _validate.apply(null, arguments);
callValidate.errors = _validate.errors;
return result;
}
}
function chooseGetId(opts) {
switch (opts.schemaId) {
case '$id': return _get$Id;
case 'id': return _getId;
default: return _get$IdOrId;
}
}
/* @this Ajv */
function _getId(schema) {
if (schema.$id) this.logger.warn('schema $id ignored', schema.$id);
return schema.id;
}
/* @this Ajv */
function _get$Id(schema) {
if (schema.id) this.logger.warn('schema id ignored', schema.id);
return schema.$id;
}
function _get$IdOrId(schema) {
if (schema.$id && schema.id && schema.$id != schema.id)
throw new Error('schema $id is different from id');
return schema.$id || schema.id;
}
/**
* Convert array of error message objects to string
* @this Ajv
* @param {Array<Object>} errors optional array of validation errors, if not passed errors from the instance are used.
* @param {Object} options optional options with properties `separator` and `dataVar`.
* @return {String} human readable string with all errors descriptions
*/
function errorsText(errors, options) {
errors = errors || this.errors;
if (!errors) return 'No errors';
options = options || {};
var separator = options.separator === undefined ? ', ' : options.separator;
var dataVar = options.dataVar === undefined ? 'data' : options.dataVar;
var text = '';
for (var i=0; i<errors.length; i++) {
var e = errors[i];
if (e) text += dataVar + e.dataPath + ' ' + e.message + separator;
}
return text.slice(0, -separator.length);
}
/**
* Add custom format
* @this Ajv
* @param {String} name format name
* @param {String|RegExp|Function} format string is converted to RegExp; function should return boolean (true when valid)
* @return {Ajv} this for method chaining
*/
function addFormat(name, format) {
if (typeof format == 'string') format = new RegExp(format);
this._formats[name] = format;
return this;
}
function addDraft6MetaSchema(self) {
var $dataSchema;
if (self._opts.$data) {
$dataSchema = require('./refs/$data.json');
self.addMetaSchema($dataSchema, $dataSchema.$id, true);
}
if (self._opts.meta === false) return;
var metaSchema = require('./refs/json-schema-draft-06.json');
if (self._opts.$data) metaSchema = $dataMetaSchema(metaSchema, META_SUPPORT_DATA);
self.addMetaSchema(metaSchema, META_SCHEMA_ID, true);
self._refs['http://json-schema.org/schema'] = META_SCHEMA_ID;
}
function addInitialSchemas(self) {
var optsSchemas = self._opts.schemas;
if (!optsSchemas) return;
if (Array.isArray(optsSchemas)) self.addSchema(optsSchemas);
else for (var key in optsSchemas) self.addSchema(optsSchemas[key], key);
}
function addInitialFormats(self) {
for (var name in self._opts.formats) {
var format = self._opts.formats[name];
self.addFormat(name, format);
}
}
function checkUnique(self, id) {
if (self._schemas[id] || self._refs[id])
throw new Error('schema with key or id "' + id + '" already exists');
}
function getMetaSchemaOptions(self) {
var metaOpts = util.copy(self._opts);
for (var i=0; i<META_IGNORE_OPTIONS.length; i++)
delete metaOpts[META_IGNORE_OPTIONS[i]];
return metaOpts;
}
function setLogger(self) {
var logger = self._opts.logger;
if (logger === false) {
self.logger = {log: noop, warn: noop, error: noop};
} else {
if (logger === undefined) logger = console;
if (!(typeof logger == 'object' && logger.log && logger.warn && logger.error))
throw new Error('logger must implement log, warn and error methods');
self.logger = logger;
}
}
function noop() {}
+26
View File
@@ -0,0 +1,26 @@
'use strict';
var Cache = module.exports = function Cache() {
this._cache = {};
};
Cache.prototype.put = function Cache_put(key, value) {
this._cache[key] = value;
};
Cache.prototype.get = function Cache_get(key) {
return this._cache[key];
};
Cache.prototype.del = function Cache_del(key) {
delete this._cache[key];
};
Cache.prototype.clear = function Cache_clear() {
this._cache = {};
};
@@ -0,0 +1,31 @@
'use strict';
//all requires must be explicit because browserify won't work with dynamic requires
module.exports = {
'$ref': require('../dotjs/ref'),
allOf: require('../dotjs/allOf'),
anyOf: require('../dotjs/anyOf'),
const: require('../dotjs/const'),
contains: require('../dotjs/contains'),
dependencies: require('../dotjs/dependencies'),
'enum': require('../dotjs/enum'),
format: require('../dotjs/format'),
items: require('../dotjs/items'),
maximum: require('../dotjs/_limit'),
minimum: require('../dotjs/_limit'),
maxItems: require('../dotjs/_limitItems'),
minItems: require('../dotjs/_limitItems'),
maxLength: require('../dotjs/_limitLength'),
minLength: require('../dotjs/_limitLength'),
maxProperties: require('../dotjs/_limitProperties'),
minProperties: require('../dotjs/_limitProperties'),
multipleOf: require('../dotjs/multipleOf'),
not: require('../dotjs/not'),
oneOf: require('../dotjs/oneOf'),
pattern: require('../dotjs/pattern'),
properties: require('../dotjs/properties'),
propertyNames: require('../dotjs/propertyNames'),
required: require('../dotjs/required'),
uniqueItems: require('../dotjs/uniqueItems'),
validate: require('../dotjs/validate')
};
@@ -0,0 +1,90 @@
'use strict';
var MissingRefError = require('./error_classes').MissingRef;
module.exports = compileAsync;
/**
* 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.
* @this Ajv
* @param {Object} schema schema object
* @param {Boolean} meta optional true to compile meta-schema; this parameter can be skipped
* @param {Function} callback an optional node-style callback, it is called with 2 parameters: error (or null) and validating function.
* @return {Promise} promise that resolves with a validating function.
*/
function compileAsync(schema, meta, callback) {
/* eslint no-shadow: 0 */
/* global Promise */
/* jshint validthis: true */
var self = this;
if (typeof this._opts.loadSchema != 'function')
throw new Error('options.loadSchema should be a function');
if (typeof meta == 'function') {
callback = meta;
meta = undefined;
}
var p = loadMetaSchemaOf(schema).then(function () {
var schemaObj = self._addSchema(schema, undefined, meta);
return schemaObj.validate || _compileAsync(schemaObj);
});
if (callback) {
p.then(
function(v) { callback(null, v); },
callback
);
}
return p;
function loadMetaSchemaOf(sch) {
var $schema = sch.$schema;
return $schema && !self.getSchema($schema)
? compileAsync.call(self, { $ref: $schema }, true)
: Promise.resolve();
}
function _compileAsync(schemaObj) {
try { return self._compile(schemaObj); }
catch(e) {
if (e instanceof MissingRefError) return loadMissingSchema(e);
throw e;
}
function loadMissingSchema(e) {
var ref = e.missingSchema;
if (added(ref)) throw new Error('Schema ' + ref + ' is loaded but ' + e.missingRef + ' cannot be resolved');
var schemaPromise = self._loadingSchemas[ref];
if (!schemaPromise) {
schemaPromise = self._loadingSchemas[ref] = self._opts.loadSchema(ref);
schemaPromise.then(removePromise, removePromise);
}
return schemaPromise.then(function (sch) {
if (!added(ref)) {
return loadMetaSchemaOf(sch).then(function () {
if (!added(ref)) self.addSchema(sch, ref, undefined, meta);
});
}
}).then(function() {
return _compileAsync(schemaObj);
});
function removePromise() {
delete self._loadingSchemas[ref];
}
function added(ref) {
return self._refs[ref] || self._schemas[ref];
}
}
}
}
@@ -0,0 +1,3 @@
'use strict';
module.exports = require('fast-deep-equal');
@@ -0,0 +1,34 @@
'use strict';
var resolve = require('./resolve');
module.exports = {
Validation: errorSubclass(ValidationError),
MissingRef: errorSubclass(MissingRefError)
};
function ValidationError(errors) {
this.message = 'validation failed';
this.errors = errors;
this.ajv = this.validation = true;
}
MissingRefError.message = function (baseId, ref) {
return 'can\'t resolve reference ' + ref + ' from id ' + baseId;
};
function MissingRefError(baseId, ref, message) {
this.message = message || MissingRefError.message(baseId, ref);
this.missingRef = resolve.url(baseId, ref);
this.missingSchema = resolve.normalizeId(resolve.fullPath(this.missingRef));
}
function errorSubclass(Subclass) {
Subclass.prototype = Object.create(Error.prototype);
Subclass.prototype.constructor = Subclass;
return Subclass;
}
@@ -0,0 +1,135 @@
'use strict';
var util = require('./util');
var DATE = /^\d\d\d\d-(\d\d)-(\d\d)$/;
var DAYS = [0,31,29,31,30,31,30,31,31,30,31,30,31];
var TIME = /^(\d\d):(\d\d):(\d\d)(\.\d+)?(z|[+-]\d\d:\d\d)?$/i;
var HOSTNAME = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[-0-9a-z]{0,61}[0-9a-z])?)*$/i;
var URI = /^(?:[a-z][a-z0-9+\-.]*:)(?:\/?\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:]|%[0-9a-f]{2})*@)?(?:\[(?:(?:(?:(?:[0-9a-f]{1,4}:){6}|::(?:[0-9a-f]{1,4}:){5}|(?:[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){4}|(?:(?:[0-9a-f]{1,4}:){0,1}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){3}|(?:(?:[0-9a-f]{1,4}:){0,2}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){2}|(?:(?:[0-9a-f]{1,4}:){0,3}[0-9a-f]{1,4})?::[0-9a-f]{1,4}:|(?:(?:[0-9a-f]{1,4}:){0,4}[0-9a-f]{1,4})?::)(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?))|(?:(?:[0-9a-f]{1,4}:){0,5}[0-9a-f]{1,4})?::[0-9a-f]{1,4}|(?:(?:[0-9a-f]{1,4}:){0,6}[0-9a-f]{1,4})?::)|[Vv][0-9a-f]+\.[a-z0-9\-._~!$&'()*+,;=:]+)\]|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)|(?:[a-z0-9\-._~!$&'()*+,;=]|%[0-9a-f]{2})*)(?::\d*)?(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*|\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*)?|(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*)(?:\?(?:[a-z0-9\-._~!$&'()*+,;=:@/?]|%[0-9a-f]{2})*)?(?:#(?:[a-z0-9\-._~!$&'()*+,;=:@/?]|%[0-9a-f]{2})*)?$/i;
var URIREF = /^(?:[a-z][a-z0-9+\-.]*:)?(?:\/?\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:]|%[0-9a-f]{2})*@)?(?:\[(?:(?:(?:(?:[0-9a-f]{1,4}:){6}|::(?:[0-9a-f]{1,4}:){5}|(?:[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){4}|(?:(?:[0-9a-f]{1,4}:){0,1}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){3}|(?:(?:[0-9a-f]{1,4}:){0,2}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){2}|(?:(?:[0-9a-f]{1,4}:){0,3}[0-9a-f]{1,4})?::[0-9a-f]{1,4}:|(?:(?:[0-9a-f]{1,4}:){0,4}[0-9a-f]{1,4})?::)(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?))|(?:(?:[0-9a-f]{1,4}:){0,5}[0-9a-f]{1,4})?::[0-9a-f]{1,4}|(?:(?:[0-9a-f]{1,4}:){0,6}[0-9a-f]{1,4})?::)|[Vv][0-9a-f]+\.[a-z0-9\-._~!$&'()*+,;=:]+)\]|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)|(?:[a-z0-9\-._~!$&'"()*+,;=]|%[0-9a-f]{2})*)(?::\d*)?(?:\/(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})*)*|\/(?:(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})*)*)?|(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})*)*)?(?:\?(?:[a-z0-9\-._~!$&'"()*+,;=:@/?]|%[0-9a-f]{2})*)?(?:#(?:[a-z0-9\-._~!$&'"()*+,;=:@/?]|%[0-9a-f]{2})*)?$/i;
// uri-template: https://tools.ietf.org/html/rfc6570
var URITEMPLATE = /^(?:(?:[^\x00-\x20"'<>%\\^`{|}]|%[0-9a-f]{2})|\{[+#./;?&=,!@|]?(?:[a-z0-9_]|%[0-9a-f]{2})+(?::[1-9][0-9]{0,3}|\*)?(?:,(?:[a-z0-9_]|%[0-9a-f]{2})+(?::[1-9][0-9]{0,3}|\*)?)*\})*$/i;
// For the source: https://gist.github.com/dperini/729294
// For test cases: https://mathiasbynens.be/demo/url-regex
// @todo Delete current URL in favour of the commented out URL rule when this issue is fixed https://github.com/eslint/eslint/issues/7983.
// var URL = /^(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u{00a1}-\u{ffff}0-9]+-?)*[a-z\u{00a1}-\u{ffff}0-9]+)(?:\.(?:[a-z\u{00a1}-\u{ffff}0-9]+-?)*[a-z\u{00a1}-\u{ffff}0-9]+)*(?:\.(?:[a-z\u{00a1}-\u{ffff}]{2,})))(?::\d{2,5})?(?:\/[^\s]*)?$/iu;
var URL = /^(?:(?:http[s\u017F]?|ftp):\/\/)(?:(?:[\0-\x08\x0E-\x1F!-\x9F\xA1-\u167F\u1681-\u1FFF\u200B-\u2027\u202A-\u202E\u2030-\u205E\u2060-\u2FFF\u3001-\uD7FF\uE000-\uFEFE\uFF00-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])+(?::(?:[\0-\x08\x0E-\x1F!-\x9F\xA1-\u167F\u1681-\u1FFF\u200B-\u2027\u202A-\u202E\u2030-\u205E\u2060-\u2FFF\u3001-\uD7FF\uE000-\uFEFE\uFF00-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])*)?@)?(?:(?!10(?:\.[0-9]{1,3}){3})(?!127(?:\.[0-9]{1,3}){3})(?!169\.254(?:\.[0-9]{1,3}){2})(?!192\.168(?:\.[0-9]{1,3}){2})(?!172\.(?:1[6-9]|2[0-9]|3[01])(?:\.[0-9]{1,3}){2})(?:[1-9][0-9]?|1[0-9][0-9]|2[01][0-9]|22[0-3])(?:\.(?:1?[0-9]{1,2}|2[0-4][0-9]|25[0-5])){2}(?:\.(?:[1-9][0-9]?|1[0-9][0-9]|2[0-4][0-9]|25[0-4]))|(?:(?:(?:[0-9KSa-z\xA1-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])+-?)*(?:[0-9KSa-z\xA1-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])+)(?:\.(?:(?:[0-9KSa-z\xA1-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])+-?)*(?:[0-9KSa-z\xA1-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])+)*(?:\.(?:(?:[KSa-z\xA1-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]){2,})))(?::[0-9]{2,5})?(?:\/(?:[\0-\x08\x0E-\x1F!-\x9F\xA1-\u167F\u1681-\u1FFF\u200B-\u2027\u202A-\u202E\u2030-\u205E\u2060-\u2FFF\u3001-\uD7FF\uE000-\uFEFE\uFF00-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])*)?$/i;
var UUID = /^(?:urn:uuid:)?[0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12}$/i;
var JSON_POINTER = /^(?:\/(?:[^~/]|~0|~1)*)*$|^#(?:\/(?:[a-z0-9_\-.!$&'()*+,;:=@]|%[0-9a-f]{2}|~0|~1)*)*$/i;
var RELATIVE_JSON_POINTER = /^(?:0|[1-9][0-9]*)(?:#|(?:\/(?:[^~/]|~0|~1)*)*)$/;
module.exports = formats;
function formats(mode) {
mode = mode == 'full' ? 'full' : 'fast';
return util.copy(formats[mode]);
}
formats.fast = {
// date: http://tools.ietf.org/html/rfc3339#section-5.6
date: /^\d\d\d\d-[0-1]\d-[0-3]\d$/,
// date-time: http://tools.ietf.org/html/rfc3339#section-5.6
time: /^[0-2]\d:[0-5]\d:[0-5]\d(?:\.\d+)?(?:z|[+-]\d\d:\d\d)?$/i,
'date-time': /^\d\d\d\d-[0-1]\d-[0-3]\d[t\s][0-2]\d:[0-5]\d:[0-5]\d(?:\.\d+)?(?:z|[+-]\d\d:\d\d)$/i,
// uri: https://github.com/mafintosh/is-my-json-valid/blob/master/formats.js
uri: /^(?:[a-z][a-z0-9+-.]*)(?::|\/)\/?[^\s]*$/i,
'uri-reference': /^(?:(?:[a-z][a-z0-9+-.]*:)?\/\/)?[^\s]*$/i,
'uri-template': URITEMPLATE,
url: URL,
// email (sources from jsen validator):
// http://stackoverflow.com/questions/201323/using-a-regular-expression-to-validate-an-email-address#answer-8829363
// http://www.w3.org/TR/html5/forms.html#valid-e-mail-address (search for 'willful violation')
email: /^[a-z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$/i,
hostname: HOSTNAME,
// optimized https://www.safaribooksonline.com/library/view/regular-expressions-cookbook/9780596802837/ch07s16.html
ipv4: /^(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)$/,
// optimized http://stackoverflow.com/questions/53497/regular-expression-that-matches-valid-ipv6-addresses
ipv6: /^\s*(?:(?:(?:[0-9a-f]{1,4}:){7}(?:[0-9a-f]{1,4}|:))|(?:(?:[0-9a-f]{1,4}:){6}(?::[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(?:(?:[0-9a-f]{1,4}:){5}(?:(?:(?::[0-9a-f]{1,4}){1,2})|:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(?:(?:[0-9a-f]{1,4}:){4}(?:(?:(?::[0-9a-f]{1,4}){1,3})|(?:(?::[0-9a-f]{1,4})?:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){3}(?:(?:(?::[0-9a-f]{1,4}){1,4})|(?:(?::[0-9a-f]{1,4}){0,2}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){2}(?:(?:(?::[0-9a-f]{1,4}){1,5})|(?:(?::[0-9a-f]{1,4}){0,3}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){1}(?:(?:(?::[0-9a-f]{1,4}){1,6})|(?:(?::[0-9a-f]{1,4}){0,4}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?::(?:(?:(?::[0-9a-f]{1,4}){1,7})|(?:(?::[0-9a-f]{1,4}){0,5}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(?:%.+)?\s*$/i,
regex: regex,
// uuid: http://tools.ietf.org/html/rfc4122
uuid: UUID,
// JSON-pointer: https://tools.ietf.org/html/rfc6901
// uri fragment: https://tools.ietf.org/html/rfc3986#appendix-A
'json-pointer': JSON_POINTER,
// relative JSON-pointer: http://tools.ietf.org/html/draft-luff-relative-json-pointer-00
'relative-json-pointer': RELATIVE_JSON_POINTER
};
formats.full = {
date: date,
time: time,
'date-time': date_time,
uri: uri,
'uri-reference': URIREF,
'uri-template': URITEMPLATE,
url: URL,
email: /^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&''*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/i,
hostname: hostname,
ipv4: /^(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)$/,
ipv6: /^\s*(?:(?:(?:[0-9a-f]{1,4}:){7}(?:[0-9a-f]{1,4}|:))|(?:(?:[0-9a-f]{1,4}:){6}(?::[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(?:(?:[0-9a-f]{1,4}:){5}(?:(?:(?::[0-9a-f]{1,4}){1,2})|:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(?:(?:[0-9a-f]{1,4}:){4}(?:(?:(?::[0-9a-f]{1,4}){1,3})|(?:(?::[0-9a-f]{1,4})?:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){3}(?:(?:(?::[0-9a-f]{1,4}){1,4})|(?:(?::[0-9a-f]{1,4}){0,2}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){2}(?:(?:(?::[0-9a-f]{1,4}){1,5})|(?:(?::[0-9a-f]{1,4}){0,3}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){1}(?:(?:(?::[0-9a-f]{1,4}){1,6})|(?:(?::[0-9a-f]{1,4}){0,4}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?::(?:(?:(?::[0-9a-f]{1,4}){1,7})|(?:(?::[0-9a-f]{1,4}){0,5}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(?:%.+)?\s*$/i,
regex: regex,
uuid: UUID,
'json-pointer': JSON_POINTER,
'relative-json-pointer': RELATIVE_JSON_POINTER
};
function date(str) {
// full-date from http://tools.ietf.org/html/rfc3339#section-5.6
var matches = str.match(DATE);
if (!matches) return false;
var month = +matches[1];
var day = +matches[2];
return month >= 1 && month <= 12 && day >= 1 && day <= DAYS[month];
}
function time(str, full) {
var matches = str.match(TIME);
if (!matches) return false;
var hour = matches[1];
var minute = matches[2];
var second = matches[3];
var timeZone = matches[5];
return hour <= 23 && minute <= 59 && second <= 59 && (!full || timeZone);
}
var DATE_TIME_SEPARATOR = /t|\s/i;
function date_time(str) {
// http://tools.ietf.org/html/rfc3339#section-5.6
var dateTime = str.split(DATE_TIME_SEPARATOR);
return dateTime.length == 2 && date(dateTime[0]) && time(dateTime[1], true);
}
function hostname(str) {
// https://tools.ietf.org/html/rfc1034#section-3.5
// https://tools.ietf.org/html/rfc1123#section-2
return str.length <= 255 && HOSTNAME.test(str);
}
var NOT_URI_FRAGMENT = /\/|:/;
function uri(str) {
// http://jmrware.com/articles/2009/uri_regexp/URI_regex.html + optional protocol + required "."
return NOT_URI_FRAGMENT.test(str) && URI.test(str);
}
var Z_ANCHOR = /[^\\]\\Z/;
function regex(str) {
if (Z_ANCHOR.test(str)) return false;
try {
new RegExp(str);
return true;
} catch(e) {
return false;
}
}
@@ -0,0 +1,380 @@
'use strict';
var resolve = require('./resolve')
, util = require('./util')
, errorClasses = require('./error_classes')
, stableStringify = require('fast-json-stable-stringify');
var validateGenerator = require('../dotjs/validate');
/**
* Functions below are used inside compiled validations function
*/
var co = require('co');
var ucs2length = util.ucs2length;
var equal = require('fast-deep-equal');
// this error is thrown by async schemas to return validation errors via exception
var ValidationError = errorClasses.Validation;
module.exports = compile;
/**
* Compiles schema to validation function
* @this Ajv
* @param {Object} schema schema object
* @param {Object} root object with information about the root schema for this schema
* @param {Object} localRefs the hash of local references inside the schema (created by resolve.id), used for inline resolution
* @param {String} baseId base ID for IDs in the schema
* @return {Function} validation function
*/
function compile(schema, root, localRefs, baseId) {
/* jshint validthis: true, evil: true */
/* eslint no-shadow: 0 */
var self = this
, opts = this._opts
, refVal = [ undefined ]
, refs = {}
, patterns = []
, patternsHash = {}
, defaults = []
, defaultsHash = {}
, customRules = [];
root = root || { schema: schema, refVal: refVal, refs: refs };
var c = checkCompiling.call(this, schema, root, baseId);
var compilation = this._compilations[c.index];
if (c.compiling) return (compilation.callValidate = callValidate);
var formats = this._formats;
var RULES = this.RULES;
try {
var v = localCompile(schema, root, localRefs, baseId);
compilation.validate = v;
var cv = compilation.callValidate;
if (cv) {
cv.schema = v.schema;
cv.errors = null;
cv.refs = v.refs;
cv.refVal = v.refVal;
cv.root = v.root;
cv.$async = v.$async;
if (opts.sourceCode) cv.source = v.source;
}
return v;
} finally {
endCompiling.call(this, schema, root, baseId);
}
function callValidate() {
var validate = compilation.validate;
var result = validate.apply(null, arguments);
callValidate.errors = validate.errors;
return result;
}
function localCompile(_schema, _root, localRefs, baseId) {
var isRoot = !_root || (_root && _root.schema == _schema);
if (_root.schema != root.schema)
return compile.call(self, _schema, _root, localRefs, baseId);
var $async = _schema.$async === true;
var sourceCode = validateGenerator({
isTop: true,
schema: _schema,
isRoot: isRoot,
baseId: baseId,
root: _root,
schemaPath: '',
errSchemaPath: '#',
errorPath: '""',
MissingRefError: errorClasses.MissingRef,
RULES: RULES,
validate: validateGenerator,
util: util,
resolve: resolve,
resolveRef: resolveRef,
usePattern: usePattern,
useDefault: useDefault,
useCustomRule: useCustomRule,
opts: opts,
formats: formats,
logger: self.logger,
self: self
});
sourceCode = vars(refVal, refValCode) + vars(patterns, patternCode)
+ vars(defaults, defaultCode) + vars(customRules, customRuleCode)
+ sourceCode;
if (opts.processCode) sourceCode = opts.processCode(sourceCode);
// console.log('\n\n\n *** \n', JSON.stringify(sourceCode));
var validate;
try {
var makeValidate = new Function(
'self',
'RULES',
'formats',
'root',
'refVal',
'defaults',
'customRules',
'co',
'equal',
'ucs2length',
'ValidationError',
sourceCode
);
validate = makeValidate(
self,
RULES,
formats,
root,
refVal,
defaults,
customRules,
co,
equal,
ucs2length,
ValidationError
);
refVal[0] = validate;
} catch(e) {
self.logger.error('Error compiling schema, function code:', sourceCode);
throw e;
}
validate.schema = _schema;
validate.errors = null;
validate.refs = refs;
validate.refVal = refVal;
validate.root = isRoot ? validate : _root;
if ($async) validate.$async = true;
if (opts.sourceCode === true) {
validate.source = {
code: sourceCode,
patterns: patterns,
defaults: defaults
};
}
return validate;
}
function resolveRef(baseId, ref, isRoot) {
ref = resolve.url(baseId, ref);
var refIndex = refs[ref];
var _refVal, refCode;
if (refIndex !== undefined) {
_refVal = refVal[refIndex];
refCode = 'refVal[' + refIndex + ']';
return resolvedRef(_refVal, refCode);
}
if (!isRoot && root.refs) {
var rootRefId = root.refs[ref];
if (rootRefId !== undefined) {
_refVal = root.refVal[rootRefId];
refCode = addLocalRef(ref, _refVal);
return resolvedRef(_refVal, refCode);
}
}
refCode = addLocalRef(ref);
var v = resolve.call(self, localCompile, root, ref);
if (v === undefined) {
var localSchema = localRefs && localRefs[ref];
if (localSchema) {
v = resolve.inlineRef(localSchema, opts.inlineRefs)
? localSchema
: compile.call(self, localSchema, root, localRefs, baseId);
}
}
if (v === undefined) {
removeLocalRef(ref);
} else {
replaceLocalRef(ref, v);
return resolvedRef(v, refCode);
}
}
function addLocalRef(ref, v) {
var refId = refVal.length;
refVal[refId] = v;
refs[ref] = refId;
return 'refVal' + refId;
}
function removeLocalRef(ref) {
delete refs[ref];
}
function replaceLocalRef(ref, v) {
var refId = refs[ref];
refVal[refId] = v;
}
function resolvedRef(refVal, code) {
return typeof refVal == 'object' || typeof refVal == 'boolean'
? { code: code, schema: refVal, inline: true }
: { code: code, $async: refVal && refVal.$async };
}
function usePattern(regexStr) {
var index = patternsHash[regexStr];
if (index === undefined) {
index = patternsHash[regexStr] = patterns.length;
patterns[index] = regexStr;
}
return 'pattern' + index;
}
function useDefault(value) {
switch (typeof value) {
case 'boolean':
case 'number':
return '' + value;
case 'string':
return util.toQuotedString(value);
case 'object':
if (value === null) return 'null';
var valueStr = stableStringify(value);
var index = defaultsHash[valueStr];
if (index === undefined) {
index = defaultsHash[valueStr] = defaults.length;
defaults[index] = value;
}
return 'default' + index;
}
}
function useCustomRule(rule, schema, parentSchema, it) {
var validateSchema = rule.definition.validateSchema;
if (validateSchema && self._opts.validateSchema !== false) {
var valid = validateSchema(schema);
if (!valid) {
var message = 'keyword schema is invalid: ' + self.errorsText(validateSchema.errors);
if (self._opts.validateSchema == 'log') self.logger.error(message);
else throw new Error(message);
}
}
var compile = rule.definition.compile
, inline = rule.definition.inline
, macro = rule.definition.macro;
var validate;
if (compile) {
validate = compile.call(self, schema, parentSchema, it);
} else if (macro) {
validate = macro.call(self, schema, parentSchema, it);
if (opts.validateSchema !== false) self.validateSchema(validate, true);
} else if (inline) {
validate = inline.call(self, it, rule.keyword, schema, parentSchema);
} else {
validate = rule.definition.validate;
if (!validate) return;
}
if (validate === undefined)
throw new Error('custom keyword "' + rule.keyword + '"failed to compile');
var index = customRules.length;
customRules[index] = validate;
return {
code: 'customRule' + index,
validate: validate
};
}
}
/**
* Checks if the schema is currently compiled
* @this Ajv
* @param {Object} schema schema to compile
* @param {Object} root root object
* @param {String} baseId base schema ID
* @return {Object} object with properties "index" (compilation index) and "compiling" (boolean)
*/
function checkCompiling(schema, root, baseId) {
/* jshint validthis: true */
var index = compIndex.call(this, schema, root, baseId);
if (index >= 0) return { index: index, compiling: true };
index = this._compilations.length;
this._compilations[index] = {
schema: schema,
root: root,
baseId: baseId
};
return { index: index, compiling: false };
}
/**
* Removes the schema from the currently compiled list
* @this Ajv
* @param {Object} schema schema to compile
* @param {Object} root root object
* @param {String} baseId base schema ID
*/
function endCompiling(schema, root, baseId) {
/* jshint validthis: true */
var i = compIndex.call(this, schema, root, baseId);
if (i >= 0) this._compilations.splice(i, 1);
}
/**
* Index of schema compilation in the currently compiled list
* @this Ajv
* @param {Object} schema schema to compile
* @param {Object} root root object
* @param {String} baseId base schema ID
* @return {Integer} compilation index
*/
function compIndex(schema, root, baseId) {
/* jshint validthis: true */
for (var i=0; i<this._compilations.length; i++) {
var c = this._compilations[i];
if (c.schema == schema && c.root == root && c.baseId == baseId) return i;
}
return -1;
}
function patternCode(i, patterns) {
return 'var pattern' + i + ' = new RegExp(' + util.toQuotedString(patterns[i]) + ');';
}
function defaultCode(i) {
return 'var default' + i + ' = defaults[' + i + '];';
}
function refValCode(i, refVal) {
return refVal[i] === undefined ? '' : 'var refVal' + i + ' = refVal[' + i + '];';
}
function customRuleCode(i) {
return 'var customRule' + i + ' = customRules[' + i + '];';
}
function vars(arr, statement) {
if (!arr.length) return '';
var code = '';
for (var i=0; i<arr.length; i++)
code += statement(i, arr);
return code;
}
@@ -0,0 +1,271 @@
'use strict';
var url = require('url')
, equal = require('fast-deep-equal')
, util = require('./util')
, SchemaObject = require('./schema_obj')
, traverse = require('json-schema-traverse');
module.exports = resolve;
resolve.normalizeId = normalizeId;
resolve.fullPath = getFullPath;
resolve.url = resolveUrl;
resolve.ids = resolveIds;
resolve.inlineRef = inlineRef;
resolve.schema = resolveSchema;
/**
* [resolve and compile the references ($ref)]
* @this Ajv
* @param {Function} compile reference to schema compilation funciton (localCompile)
* @param {Object} root object with information about the root schema for the current schema
* @param {String} ref reference to resolve
* @return {Object|Function} schema object (if the schema can be inlined) or validation function
*/
function resolve(compile, root, ref) {
/* jshint validthis: true */
var refVal = this._refs[ref];
if (typeof refVal == 'string') {
if (this._refs[refVal]) refVal = this._refs[refVal];
else return resolve.call(this, compile, root, refVal);
}
refVal = refVal || this._schemas[ref];
if (refVal instanceof SchemaObject) {
return inlineRef(refVal.schema, this._opts.inlineRefs)
? refVal.schema
: refVal.validate || this._compile(refVal);
}
var res = resolveSchema.call(this, root, ref);
var schema, v, baseId;
if (res) {
schema = res.schema;
root = res.root;
baseId = res.baseId;
}
if (schema instanceof SchemaObject) {
v = schema.validate || compile.call(this, schema.schema, root, undefined, baseId);
} else if (schema !== undefined) {
v = inlineRef(schema, this._opts.inlineRefs)
? schema
: compile.call(this, schema, root, undefined, baseId);
}
return v;
}
/**
* Resolve schema, its root and baseId
* @this Ajv
* @param {Object} root root object with properties schema, refVal, refs
* @param {String} ref reference to resolve
* @return {Object} object with properties schema, root, baseId
*/
function resolveSchema(root, ref) {
/* jshint validthis: true */
var p = url.parse(ref, false, true)
, refPath = _getFullPath(p)
, baseId = getFullPath(this._getId(root.schema));
if (refPath !== baseId) {
var id = normalizeId(refPath);
var refVal = this._refs[id];
if (typeof refVal == 'string') {
return resolveRecursive.call(this, root, refVal, p);
} else if (refVal instanceof SchemaObject) {
if (!refVal.validate) this._compile(refVal);
root = refVal;
} else {
refVal = this._schemas[id];
if (refVal instanceof SchemaObject) {
if (!refVal.validate) this._compile(refVal);
if (id == normalizeId(ref))
return { schema: refVal, root: root, baseId: baseId };
root = refVal;
} else {
return;
}
}
if (!root.schema) return;
baseId = getFullPath(this._getId(root.schema));
}
return getJsonPointer.call(this, p, baseId, root.schema, root);
}
/* @this Ajv */
function resolveRecursive(root, ref, parsedRef) {
/* jshint validthis: true */
var res = resolveSchema.call(this, root, ref);
if (res) {
var schema = res.schema;
var baseId = res.baseId;
root = res.root;
var id = this._getId(schema);
if (id) baseId = resolveUrl(baseId, id);
return getJsonPointer.call(this, parsedRef, baseId, schema, root);
}
}
var PREVENT_SCOPE_CHANGE = util.toHash(['properties', 'patternProperties', 'enum', 'dependencies', 'definitions']);
/* @this Ajv */
function getJsonPointer(parsedRef, baseId, schema, root) {
/* jshint validthis: true */
parsedRef.hash = parsedRef.hash || '';
if (parsedRef.hash.slice(0,2) != '#/') return;
var parts = parsedRef.hash.split('/');
for (var i = 1; i < parts.length; i++) {
var part = parts[i];
if (part) {
part = util.unescapeFragment(part);
schema = schema[part];
if (schema === undefined) break;
var id;
if (!PREVENT_SCOPE_CHANGE[part]) {
id = this._getId(schema);
if (id) baseId = resolveUrl(baseId, id);
if (schema.$ref) {
var $ref = resolveUrl(baseId, schema.$ref);
var res = resolveSchema.call(this, root, $ref);
if (res) {
schema = res.schema;
root = res.root;
baseId = res.baseId;
}
}
}
}
}
if (schema !== undefined && schema !== root.schema)
return { schema: schema, root: root, baseId: baseId };
}
var SIMPLE_INLINED = util.toHash([
'type', 'format', 'pattern',
'maxLength', 'minLength',
'maxProperties', 'minProperties',
'maxItems', 'minItems',
'maximum', 'minimum',
'uniqueItems', 'multipleOf',
'required', 'enum'
]);
function inlineRef(schema, limit) {
if (limit === false) return false;
if (limit === undefined || limit === true) return checkNoRef(schema);
else if (limit) return countKeys(schema) <= limit;
}
function checkNoRef(schema) {
var item;
if (Array.isArray(schema)) {
for (var i=0; i<schema.length; i++) {
item = schema[i];
if (typeof item == 'object' && !checkNoRef(item)) return false;
}
} else {
for (var key in schema) {
if (key == '$ref') return false;
item = schema[key];
if (typeof item == 'object' && !checkNoRef(item)) return false;
}
}
return true;
}
function countKeys(schema) {
var count = 0, item;
if (Array.isArray(schema)) {
for (var i=0; i<schema.length; i++) {
item = schema[i];
if (typeof item == 'object') count += countKeys(item);
if (count == Infinity) return Infinity;
}
} else {
for (var key in schema) {
if (key == '$ref') return Infinity;
if (SIMPLE_INLINED[key]) {
count++;
} else {
item = schema[key];
if (typeof item == 'object') count += countKeys(item) + 1;
if (count == Infinity) return Infinity;
}
}
}
return count;
}
function getFullPath(id, normalize) {
if (normalize !== false) id = normalizeId(id);
var p = url.parse(id, false, true);
return _getFullPath(p);
}
function _getFullPath(p) {
var protocolSeparator = p.protocol || p.href.slice(0,2) == '//' ? '//' : '';
return (p.protocol||'') + protocolSeparator + (p.host||'') + (p.path||'') + '#';
}
var TRAILING_SLASH_HASH = /#\/?$/;
function normalizeId(id) {
return id ? id.replace(TRAILING_SLASH_HASH, '') : '';
}
function resolveUrl(baseId, id) {
id = normalizeId(id);
return url.resolve(baseId, id);
}
/* @this Ajv */
function resolveIds(schema) {
var schemaId = normalizeId(this._getId(schema));
var baseIds = {'': schemaId};
var fullPaths = {'': getFullPath(schemaId, false)};
var localRefs = {};
var self = this;
traverse(schema, {allKeys: true}, function(sch, jsonPtr, rootSchema, parentJsonPtr, parentKeyword, parentSchema, keyIndex) {
if (jsonPtr === '') return;
var id = self._getId(sch);
var baseId = baseIds[parentJsonPtr];
var fullPath = fullPaths[parentJsonPtr] + '/' + parentKeyword;
if (keyIndex !== undefined)
fullPath += '/' + (typeof keyIndex == 'number' ? keyIndex : util.escapeFragment(keyIndex));
if (typeof id == 'string') {
id = baseId = normalizeId(baseId ? url.resolve(baseId, id) : id);
var refVal = self._refs[id];
if (typeof refVal == 'string') refVal = self._refs[refVal];
if (refVal && refVal.schema) {
if (!equal(sch, refVal.schema))
throw new Error('id "' + id + '" resolves to more than one schema');
} else if (id != normalizeId(fullPath)) {
if (id[0] == '#') {
if (localRefs[id] && !equal(sch, localRefs[id]))
throw new Error('id "' + id + '" resolves to more than one schema');
localRefs[id] = sch;
} else {
self._refs[id] = fullPath;
}
}
}
baseIds[jsonPtr] = baseId;
fullPaths[jsonPtr] = fullPath;
});
return localRefs;
}
@@ -0,0 +1,58 @@
'use strict';
var ruleModules = require('./_rules')
, toHash = require('./util').toHash;
module.exports = function rules() {
var RULES = [
{ type: 'number',
rules: [ { 'maximum': ['exclusiveMaximum'] },
{ 'minimum': ['exclusiveMinimum'] }, 'multipleOf', 'format'] },
{ type: 'string',
rules: [ 'maxLength', 'minLength', 'pattern', 'format' ] },
{ type: 'array',
rules: [ 'maxItems', 'minItems', 'uniqueItems', 'contains', 'items' ] },
{ type: 'object',
rules: [ 'maxProperties', 'minProperties', 'required', 'dependencies', 'propertyNames',
{ 'properties': ['additionalProperties', 'patternProperties'] } ] },
{ rules: [ '$ref', 'const', 'enum', 'not', 'anyOf', 'oneOf', 'allOf' ] }
];
var ALL = [ 'type' ];
var KEYWORDS = [
'additionalItems', '$schema', '$id', 'id', 'title',
'description', 'default', 'definitions'
];
var TYPES = [ 'number', 'integer', 'string', 'array', 'object', 'boolean', 'null' ];
RULES.all = toHash(ALL);
RULES.types = toHash(TYPES);
RULES.forEach(function (group) {
group.rules = group.rules.map(function (keyword) {
var implKeywords;
if (typeof keyword == 'object') {
var key = Object.keys(keyword)[0];
implKeywords = keyword[key];
keyword = key;
implKeywords.forEach(function (k) {
ALL.push(k);
RULES.all[k] = true;
});
}
ALL.push(keyword);
var rule = RULES.all[keyword] = {
keyword: keyword,
code: ruleModules[keyword],
implements: implKeywords
};
return rule;
});
if (group.type) RULES.types[group.type] = group;
});
RULES.keywords = toHash(ALL.concat(KEYWORDS));
RULES.custom = {};
return RULES;
};
@@ -0,0 +1,9 @@
'use strict';
var util = require('./util');
module.exports = SchemaObject;
function SchemaObject(obj) {
util.copy(obj, this);
}
@@ -0,0 +1,20 @@
'use strict';
// https://mathiasbynens.be/notes/javascript-encoding
// https://github.com/bestiejs/punycode.js - punycode.ucs2.decode
module.exports = function ucs2length(str) {
var length = 0
, len = str.length
, pos = 0
, value;
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;
};
@@ -0,0 +1,267 @@
'use strict';
module.exports = {
copy: copy,
checkDataType: checkDataType,
checkDataTypes: checkDataTypes,
coerceToTypes: coerceToTypes,
toHash: toHash,
getProperty: getProperty,
escapeQuotes: escapeQuotes,
equal: require('fast-deep-equal'),
ucs2length: require('./ucs2length'),
varOccurences: varOccurences,
varReplace: varReplace,
cleanUpCode: cleanUpCode,
finalCleanUpCode: finalCleanUpCode,
schemaHasRules: schemaHasRules,
schemaHasRulesExcept: schemaHasRulesExcept,
toQuotedString: toQuotedString,
getPathExpr: getPathExpr,
getPath: getPath,
getData: getData,
unescapeFragment: unescapeFragment,
unescapeJsonPointer: unescapeJsonPointer,
escapeFragment: escapeFragment,
escapeJsonPointer: escapeJsonPointer
};
function copy(o, to) {
to = to || {};
for (var key in o) to[key] = o[key];
return to;
}
function checkDataType(dataType, data, negate) {
var EQUAL = negate ? ' !== ' : ' === '
, AND = negate ? ' || ' : ' && '
, OK = negate ? '!' : ''
, NOT = negate ? '' : '!';
switch (dataType) {
case 'null': return data + EQUAL + 'null';
case 'array': return OK + 'Array.isArray(' + data + ')';
case 'object': return '(' + OK + data + AND +
'typeof ' + data + EQUAL + '"object"' + AND +
NOT + 'Array.isArray(' + data + '))';
case 'integer': return '(typeof ' + data + EQUAL + '"number"' + AND +
NOT + '(' + data + ' % 1)' +
AND + data + EQUAL + data + ')';
default: return 'typeof ' + data + EQUAL + '"' + dataType + '"';
}
}
function checkDataTypes(dataTypes, data) {
switch (dataTypes.length) {
case 1: return checkDataType(dataTypes[0], data, true);
default:
var code = '';
var types = toHash(dataTypes);
if (types.array && types.object) {
code = types.null ? '(': '(!' + data + ' || ';
code += 'typeof ' + data + ' !== "object")';
delete types.null;
delete types.array;
delete types.object;
}
if (types.number) delete types.integer;
for (var t in types)
code += (code ? ' && ' : '' ) + checkDataType(t, data, true);
return code;
}
}
var COERCE_TO_TYPES = toHash([ 'string', 'number', 'integer', 'boolean', 'null' ]);
function coerceToTypes(optionCoerceTypes, dataTypes) {
if (Array.isArray(dataTypes)) {
var types = [];
for (var i=0; i<dataTypes.length; i++) {
var t = dataTypes[i];
if (COERCE_TO_TYPES[t]) types[types.length] = t;
else if (optionCoerceTypes === 'array' && t === 'array') types[types.length] = t;
}
if (types.length) return types;
} else if (COERCE_TO_TYPES[dataTypes]) {
return [dataTypes];
} else if (optionCoerceTypes === 'array' && dataTypes === 'array') {
return ['array'];
}
}
function toHash(arr) {
var hash = {};
for (var i=0; i<arr.length; i++) hash[arr[i]] = true;
return hash;
}
var IDENTIFIER = /^[a-z$_][a-z$_0-9]*$/i;
var SINGLE_QUOTE = /'|\\/g;
function getProperty(key) {
return typeof key == 'number'
? '[' + key + ']'
: IDENTIFIER.test(key)
? '.' + key
: "['" + escapeQuotes(key) + "']";
}
function escapeQuotes(str) {
return str.replace(SINGLE_QUOTE, '\\$&')
.replace(/\n/g, '\\n')
.replace(/\r/g, '\\r')
.replace(/\f/g, '\\f')
.replace(/\t/g, '\\t');
}
function varOccurences(str, dataVar) {
dataVar += '[^0-9]';
var matches = str.match(new RegExp(dataVar, 'g'));
return matches ? matches.length : 0;
}
function varReplace(str, dataVar, expr) {
dataVar += '([^0-9])';
expr = expr.replace(/\$/g, '$$$$');
return str.replace(new RegExp(dataVar, 'g'), expr + '$1');
}
var EMPTY_ELSE = /else\s*{\s*}/g
, EMPTY_IF_NO_ELSE = /if\s*\([^)]+\)\s*\{\s*\}(?!\s*else)/g
, EMPTY_IF_WITH_ELSE = /if\s*\(([^)]+)\)\s*\{\s*\}\s*else(?!\s*if)/g;
function cleanUpCode(out) {
return out.replace(EMPTY_ELSE, '')
.replace(EMPTY_IF_NO_ELSE, '')
.replace(EMPTY_IF_WITH_ELSE, 'if (!($1))');
}
var ERRORS_REGEXP = /[^v.]errors/g
, REMOVE_ERRORS = /var errors = 0;|var vErrors = null;|validate.errors = vErrors;/g
, REMOVE_ERRORS_ASYNC = /var errors = 0;|var vErrors = null;/g
, RETURN_VALID = 'return errors === 0;'
, RETURN_TRUE = 'validate.errors = null; return true;'
, RETURN_ASYNC = /if \(errors === 0\) return data;\s*else throw new ValidationError\(vErrors\);/
, RETURN_DATA_ASYNC = 'return data;'
, ROOTDATA_REGEXP = /[^A-Za-z_$]rootData[^A-Za-z0-9_$]/g
, REMOVE_ROOTDATA = /if \(rootData === undefined\) rootData = data;/;
function finalCleanUpCode(out, async) {
var matches = out.match(ERRORS_REGEXP);
if (matches && matches.length == 2) {
out = async
? out.replace(REMOVE_ERRORS_ASYNC, '')
.replace(RETURN_ASYNC, RETURN_DATA_ASYNC)
: out.replace(REMOVE_ERRORS, '')
.replace(RETURN_VALID, RETURN_TRUE);
}
matches = out.match(ROOTDATA_REGEXP);
if (!matches || matches.length !== 3) return out;
return out.replace(REMOVE_ROOTDATA, '');
}
function schemaHasRules(schema, rules) {
if (typeof schema == 'boolean') return !schema;
for (var key in schema) if (rules[key]) return true;
}
function schemaHasRulesExcept(schema, rules, exceptKeyword) {
if (typeof schema == 'boolean') return !schema && exceptKeyword != 'not';
for (var key in schema) if (key != exceptKeyword && rules[key]) return true;
}
function toQuotedString(str) {
return '\'' + escapeQuotes(str) + '\'';
}
function getPathExpr(currentPath, expr, jsonPointers, isNumber) {
var path = jsonPointers // false by default
? '\'/\' + ' + expr + (isNumber ? '' : '.replace(/~/g, \'~0\').replace(/\\//g, \'~1\')')
: (isNumber ? '\'[\' + ' + expr + ' + \']\'' : '\'[\\\'\' + ' + expr + ' + \'\\\']\'');
return joinPaths(currentPath, path);
}
function getPath(currentPath, prop, jsonPointers) {
var path = jsonPointers // false by default
? toQuotedString('/' + escapeJsonPointer(prop))
: toQuotedString(getProperty(prop));
return joinPaths(currentPath, path);
}
var JSON_POINTER = /^\/(?:[^~]|~0|~1)*$/;
var RELATIVE_JSON_POINTER = /^([0-9]+)(#|\/(?:[^~]|~0|~1)*)?$/;
function getData($data, lvl, paths) {
var up, jsonPointer, data, matches;
if ($data === '') return 'rootData';
if ($data[0] == '/') {
if (!JSON_POINTER.test($data)) throw new Error('Invalid JSON-pointer: ' + $data);
jsonPointer = $data;
data = 'rootData';
} else {
matches = $data.match(RELATIVE_JSON_POINTER);
if (!matches) throw new Error('Invalid JSON-pointer: ' + $data);
up = +matches[1];
jsonPointer = matches[2];
if (jsonPointer == '#') {
if (up >= lvl) throw new Error('Cannot access property/index ' + up + ' levels up, current level is ' + lvl);
return paths[lvl - up];
}
if (up > lvl) throw new Error('Cannot access data ' + up + ' levels up, current level is ' + lvl);
data = 'data' + ((lvl - up) || '');
if (!jsonPointer) return data;
}
var expr = data;
var segments = jsonPointer.split('/');
for (var i=0; i<segments.length; i++) {
var segment = segments[i];
if (segment) {
data += getProperty(unescapeJsonPointer(segment));
expr += ' && ' + data;
}
}
return expr;
}
function joinPaths (a, b) {
if (a == '""') return b;
return (a + ' + ' + b).replace(/' \+ '/g, '');
}
function unescapeFragment(str) {
return unescapeJsonPointer(decodeURIComponent(str));
}
function escapeFragment(str) {
return encodeURIComponent(escapeJsonPointer(str));
}
function escapeJsonPointer(str) {
return str.replace(/~/g, '~0').replace(/\//g, '~1');
}
function unescapeJsonPointer(str) {
return str.replace(/~1/g, '/').replace(/~0/g, '~');
}
@@ -0,0 +1,96 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.setupKeyword }}
{{# def.$data }}
{{## def.setExclusiveLimit:
$exclusive = true;
$errorKeyword = $exclusiveKeyword;
$errSchemaPath = it.errSchemaPath + '/' + $exclusiveKeyword;
#}}
{{
var $isMax = $keyword == 'maximum'
, $exclusiveKeyword = $isMax ? 'exclusiveMaximum' : 'exclusiveMinimum'
, $schemaExcl = it.schema[$exclusiveKeyword]
, $isDataExcl = it.opts.$data && $schemaExcl && $schemaExcl.$data
, $op = $isMax ? '<' : '>'
, $notOp = $isMax ? '>' : '<'
, $errorKeyword = undefined;
}}
{{? $isDataExcl }}
{{
var $schemaValueExcl = it.util.getData($schemaExcl.$data, $dataLvl, it.dataPathArr)
, $exclusive = 'exclusive' + $lvl
, $exclType = 'exclType' + $lvl
, $exclIsNumber = 'exclIsNumber' + $lvl
, $opExpr = 'op' + $lvl
, $opStr = '\' + ' + $opExpr + ' + \'';
}}
var schemaExcl{{=$lvl}} = {{=$schemaValueExcl}};
{{ $schemaValueExcl = 'schemaExcl' + $lvl; }}
var {{=$exclusive}};
var {{=$exclType}} = typeof {{=$schemaValueExcl}};
if ({{=$exclType}} != 'boolean' && {{=$exclType}} != 'undefined' && {{=$exclType}} != 'number') {
{{ var $errorKeyword = $exclusiveKeyword; }}
{{# def.error:'_exclusiveLimit' }}
} else if ({{# def.$dataNotType:'number' }}
{{=$exclType}} == 'number'
? (
({{=$exclusive}} = {{=$schemaValue}} === undefined || {{=$schemaValueExcl}} {{=$op}}= {{=$schemaValue}})
? {{=$data}} {{=$notOp}}= {{=$schemaValueExcl}}
: {{=$data}} {{=$notOp}} {{=$schemaValue}}
)
: (
({{=$exclusive}} = {{=$schemaValueExcl}} === true)
? {{=$data}} {{=$notOp}}= {{=$schemaValue}}
: {{=$data}} {{=$notOp}} {{=$schemaValue}}
)
|| {{=$data}} !== {{=$data}}) {
var op{{=$lvl}} = {{=$exclusive}} ? '{{=$op}}' : '{{=$op}}=';
{{??}}
{{
var $exclIsNumber = typeof $schemaExcl == 'number'
, $opStr = $op; /*used in error*/
}}
{{? $exclIsNumber && $isData }}
{{ var $opExpr = '\'' + $opStr + '\''; /*used in error*/ }}
if ({{# def.$dataNotType:'number' }}
( {{=$schemaValue}} === undefined
|| {{=$schemaExcl}} {{=$op}}= {{=$schemaValue}}
? {{=$data}} {{=$notOp}}= {{=$schemaExcl}}
: {{=$data}} {{=$notOp}} {{=$schemaValue}} )
|| {{=$data}} !== {{=$data}}) {
{{??}}
{{
if ($exclIsNumber && $schema === undefined) {
{{# def.setExclusiveLimit }}
$schemaValue = $schemaExcl;
$notOp += '=';
} else {
if ($exclIsNumber)
$schemaValue = Math[$isMax ? 'min' : 'max']($schemaExcl, $schema);
if ($schemaExcl === ($exclIsNumber ? $schemaValue : true)) {
{{# def.setExclusiveLimit }}
$notOp += '=';
} else {
$exclusive = false;
$opStr += '=';
}
}
var $opExpr = '\'' + $opStr + '\''; /*used in error*/
}}
if ({{# def.$dataNotType:'number' }}
{{=$data}} {{=$notOp}} {{=$schemaValue}}
|| {{=$data}} !== {{=$data}}) {
{{?}}
{{?}}
{{ $errorKeyword = $errorKeyword || $keyword; }}
{{# def.error:'_limit' }}
} {{? $breakOnError }} else { {{?}}
@@ -0,0 +1,10 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.setupKeyword }}
{{# def.$data }}
{{ var $op = $keyword == 'maxItems' ? '>' : '<'; }}
if ({{# def.$dataNotType:'number' }} {{=$data}}.length {{=$op}} {{=$schemaValue}}) {
{{ var $errorKeyword = $keyword; }}
{{# def.error:'_limitItems' }}
} {{? $breakOnError }} else { {{?}}
@@ -0,0 +1,10 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.setupKeyword }}
{{# def.$data }}
{{ var $op = $keyword == 'maxLength' ? '>' : '<'; }}
if ({{# def.$dataNotType:'number' }} {{# def.strLength }} {{=$op}} {{=$schemaValue}}) {
{{ var $errorKeyword = $keyword; }}
{{# def.error:'_limitLength' }}
} {{? $breakOnError }} else { {{?}}
@@ -0,0 +1,10 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.setupKeyword }}
{{# def.$data }}
{{ var $op = $keyword == 'maxProperties' ? '>' : '<'; }}
if ({{# def.$dataNotType:'number' }} Object.keys({{=$data}}).length {{=$op}} {{=$schemaValue}}) {
{{ var $errorKeyword = $keyword; }}
{{# def.error:'_limitProperties' }}
} {{? $breakOnError }} else { {{?}}
+34
View File
@@ -0,0 +1,34 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.setupKeyword }}
{{# def.setupNextLevel }}
{{
var $currentBaseId = $it.baseId
, $allSchemasEmpty = true;
}}
{{~ $schema:$sch:$i }}
{{? {{# def.nonEmptySchema:$sch }} }}
{{
$allSchemasEmpty = false;
$it.schema = $sch;
$it.schemaPath = $schemaPath + '[' + $i + ']';
$it.errSchemaPath = $errSchemaPath + '/' + $i;
}}
{{# def.insertSubschemaCode }}
{{# def.ifResultValid }}
{{?}}
{{~}}
{{? $breakOnError }}
{{? $allSchemasEmpty }}
if (true) {
{{??}}
{{= $closingBraces.slice(0,-1) }}
{{?}}
{{?}}
{{# def.cleanUp }}
+48
View File
@@ -0,0 +1,48 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.setupKeyword }}
{{# def.setupNextLevel }}
{{
var $noEmptySchema = $schema.every(function($sch) {
return {{# def.nonEmptySchema:$sch }};
});
}}
{{? $noEmptySchema }}
{{ var $currentBaseId = $it.baseId; }}
var {{=$errs}} = errors;
var {{=$valid}} = false;
{{# def.setCompositeRule }}
{{~ $schema:$sch:$i }}
{{
$it.schema = $sch;
$it.schemaPath = $schemaPath + '[' + $i + ']';
$it.errSchemaPath = $errSchemaPath + '/' + $i;
}}
{{# def.insertSubschemaCode }}
{{=$valid}} = {{=$valid}} || {{=$nextValid}};
if (!{{=$valid}}) {
{{ $closingBraces += '}'; }}
{{~}}
{{# def.resetCompositeRule }}
{{= $closingBraces }}
if (!{{=$valid}}) {
{{# def.extraError:'anyOf' }}
} else {
{{# def.resetErrors }}
{{? it.opts.allErrors }} } {{?}}
{{# def.cleanUp }}
{{??}}
{{? $breakOnError }}
if (true) {
{{?}}
{{?}}
@@ -0,0 +1,61 @@
{{## def.coerceType:
{{
var $dataType = 'dataType' + $lvl
, $coerced = 'coerced' + $lvl;
}}
var {{=$dataType}} = typeof {{=$data}};
{{? it.opts.coerceTypes == 'array'}}
if ({{=$dataType}} == 'object' && Array.isArray({{=$data}})) {{=$dataType}} = 'array';
{{?}}
var {{=$coerced}} = undefined;
{{ var $bracesCoercion = ''; }}
{{~ $coerceToTypes:$type:$i }}
{{? $i }}
if ({{=$coerced}} === undefined) {
{{ $bracesCoercion += '}'; }}
{{?}}
{{? it.opts.coerceTypes == 'array' && $type != 'array' }}
if ({{=$dataType}} == 'array' && {{=$data}}.length == 1) {
{{=$coerced}} = {{=$data}} = {{=$data}}[0];
{{=$dataType}} = typeof {{=$data}};
/*if ({{=$dataType}} == 'object' && Array.isArray({{=$data}})) {{=$dataType}} = 'array';*/
}
{{?}}
{{? $type == 'string' }}
if ({{=$dataType}} == 'number' || {{=$dataType}} == 'boolean')
{{=$coerced}} = '' + {{=$data}};
else if ({{=$data}} === null) {{=$coerced}} = '';
{{?? $type == 'number' || $type == 'integer' }}
if ({{=$dataType}} == 'boolean' || {{=$data}} === null
|| ({{=$dataType}} == 'string' && {{=$data}} && {{=$data}} == +{{=$data}}
{{? $type == 'integer' }} && !({{=$data}} % 1){{?}}))
{{=$coerced}} = +{{=$data}};
{{?? $type == 'boolean' }}
if ({{=$data}} === 'false' || {{=$data}} === 0 || {{=$data}} === null)
{{=$coerced}} = false;
else if ({{=$data}} === 'true' || {{=$data}} === 1)
{{=$coerced}} = true;
{{?? $type == 'null' }}
if ({{=$data}} === '' || {{=$data}} === 0 || {{=$data}} === false)
{{=$coerced}} = null;
{{?? it.opts.coerceTypes == 'array' && $type == 'array' }}
if ({{=$dataType}} == 'string' || {{=$dataType}} == 'number' || {{=$dataType}} == 'boolean' || {{=$data}} == null)
{{=$coerced}} = [{{=$data}}];
{{?}}
{{~}}
{{= $bracesCoercion }}
if ({{=$coerced}} === undefined) {
{{# def.error:'type' }}
} else {
{{# def.setParentData }}
{{=$data}} = {{=$coerced}};
{{? !$dataLvl }}if ({{=$parentData}} !== undefined){{?}}
{{=$parentData}}[{{=$parentDataProperty}}] = {{=$coerced}};
}
#}}
+11
View File
@@ -0,0 +1,11 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.setupKeyword }}
{{# def.$data }}
{{? !$isData }}
var schema{{=$lvl}} = validate.schema{{=$schemaPath}};
{{?}}
var {{=$valid}} = equal({{=$data}}, schema{{=$lvl}});
{{# def.checkError:'const' }}
{{? $breakOnError }} else { {{?}}
@@ -0,0 +1,57 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.setupKeyword }}
{{# def.setupNextLevel }}
{{
var $idx = 'i' + $lvl
, $dataNxt = $it.dataLevel = it.dataLevel + 1
, $nextData = 'data' + $dataNxt
, $currentBaseId = it.baseId
, $nonEmptySchema = {{# def.nonEmptySchema:$schema }};
}}
var {{=$errs}} = errors;
var {{=$valid}};
{{? $nonEmptySchema }}
{{# def.setCompositeRule }}
{{
$it.schema = $schema;
$it.schemaPath = $schemaPath;
$it.errSchemaPath = $errSchemaPath;
}}
var {{=$nextValid}} = false;
for (var {{=$idx}} = 0; {{=$idx}} < {{=$data}}.length; {{=$idx}}++) {
{{
$it.errorPath = it.util.getPathExpr(it.errorPath, $idx, it.opts.jsonPointers, true);
var $passData = $data + '[' + $idx + ']';
$it.dataPathArr[$dataNxt] = $idx;
}}
{{# def.generateSubschemaCode }}
{{# def.optimizeValidate }}
if ({{=$nextValid}}) break;
}
{{# def.resetCompositeRule }}
{{= $closingBraces }}
if (!{{=$nextValid}}) {
{{??}}
if ({{=$data}}.length == 0) {
{{?}}
{{# def.error:'contains' }}
} else {
{{? $nonEmptySchema }}
{{# def.resetErrors }}
{{?}}
{{? it.opts.allErrors }} } {{?}}
{{# def.cleanUp }}
+191
View File
@@ -0,0 +1,191 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.setupKeyword }}
{{# def.$data }}
{{
var $rule = this
, $definition = 'definition' + $lvl
, $rDef = $rule.definition
, $closingBraces = '';
var $validate = $rDef.validate;
var $compile, $inline, $macro, $ruleValidate, $validateCode;
}}
{{? $isData && $rDef.$data }}
{{
$validateCode = 'keywordValidate' + $lvl;
var $validateSchema = $rDef.validateSchema;
}}
var {{=$definition}} = RULES.custom['{{=$keyword}}'].definition;
var {{=$validateCode}} = {{=$definition}}.validate;
{{??}}
{{
$ruleValidate = it.useCustomRule($rule, $schema, it.schema, it);
if (!$ruleValidate) return;
$schemaValue = 'validate.schema' + $schemaPath;
$validateCode = $ruleValidate.code;
$compile = $rDef.compile;
$inline = $rDef.inline;
$macro = $rDef.macro;
}}
{{?}}
{{
var $ruleErrs = $validateCode + '.errors'
, $i = 'i' + $lvl
, $ruleErr = 'ruleErr' + $lvl
, $asyncKeyword = $rDef.async;
if ($asyncKeyword && !it.async)
throw new Error('async keyword in sync schema');
}}
{{? !($inline || $macro) }}{{=$ruleErrs}} = null;{{?}}
var {{=$errs}} = errors;
var {{=$valid}};
{{## def.callRuleValidate:
{{=$validateCode}}.call(
{{? it.opts.passContext }}this{{??}}self{{?}}
{{? $compile || $rDef.schema === false }}
, {{=$data}}
{{??}}
, {{=$schemaValue}}
, {{=$data}}
, validate.schema{{=it.schemaPath}}
{{?}}
, {{# def.dataPath }}
{{# def.passParentData }}
, rootData
)
#}}
{{## def.extendErrors:_inline:
for (var {{=$i}}={{=$errs}}; {{=$i}}<errors; {{=$i}}++) {
var {{=$ruleErr}} = vErrors[{{=$i}}];
if ({{=$ruleErr}}.dataPath === undefined)
{{=$ruleErr}}.dataPath = (dataPath || '') + {{= it.errorPath }};
{{# _inline ? 'if (\{\{=$ruleErr\}\}.schemaPath === undefined) {' : '' }}
{{=$ruleErr}}.schemaPath = "{{=$errSchemaPath}}";
{{# _inline ? '}' : '' }}
{{? it.opts.verbose }}
{{=$ruleErr}}.schema = {{=$schemaValue}};
{{=$ruleErr}}.data = {{=$data}};
{{?}}
}
#}}
{{? $isData && $rDef.$data }}
{{ $closingBraces += '}'; }}
if ({{=$schemaValue}} === undefined) {
{{=$valid}} = true;
} else {
{{? $validateSchema }}
{{ $closingBraces += '}'; }}
{{=$valid}} = {{=$definition}}.validateSchema({{=$schemaValue}});
if ({{=$valid}}) {
{{?}}
{{?}}
{{? $inline }}
{{? $rDef.statements }}
{{= $ruleValidate.validate }}
{{??}}
{{=$valid}} = {{= $ruleValidate.validate }};
{{?}}
{{?? $macro }}
{{# def.setupNextLevel }}
{{
$it.schema = $ruleValidate.validate;
$it.schemaPath = '';
}}
{{# def.setCompositeRule }}
{{ var $code = it.validate($it).replace(/validate\.schema/g, $validateCode); }}
{{# def.resetCompositeRule }}
{{= $code }}
{{??}}
{{# def.beginDefOut}}
{{# def.callRuleValidate }}
{{# def.storeDefOut:def_callRuleValidate }}
{{? $rDef.errors === false }}
{{=$valid}} = {{? $asyncKeyword }}{{=it.yieldAwait}}{{?}}{{= def_callRuleValidate }};
{{??}}
{{? $asyncKeyword }}
{{ $ruleErrs = 'customErrors' + $lvl; }}
var {{=$ruleErrs}} = null;
try {
{{=$valid}} = {{=it.yieldAwait}}{{= def_callRuleValidate }};
} catch (e) {
{{=$valid}} = false;
if (e instanceof ValidationError) {{=$ruleErrs}} = e.errors;
else throw e;
}
{{??}}
{{=$ruleErrs}} = null;
{{=$valid}} = {{= def_callRuleValidate }};
{{?}}
{{?}}
{{?}}
{{? $rDef.modifying }}
if ({{=$parentData}}) {{=$data}} = {{=$parentData}}[{{=$parentDataProperty}}];
{{?}}
{{= $closingBraces }}
{{## def.notValidationResult:
{{? $rDef.valid === undefined }}
!{{? $macro }}{{=$nextValid}}{{??}}{{=$valid}}{{?}}
{{??}}
{{= !$rDef.valid }}
{{?}}
#}}
{{? $rDef.valid }}
{{? $breakOnError }} if (true) { {{?}}
{{??}}
if ({{# def.notValidationResult }}) {
{{ $errorKeyword = $rule.keyword; }}
{{# def.beginDefOut}}
{{# def.error:'custom' }}
{{# def.storeDefOut:def_customError }}
{{? $inline }}
{{? $rDef.errors }}
{{? $rDef.errors != 'full' }}
{{# def.extendErrors:true }}
{{?}}
{{??}}
{{? $rDef.errors === false}}
{{= def_customError }}
{{??}}
if ({{=$errs}} == errors) {
{{= def_customError }}
} else {
{{# def.extendErrors:true }}
}
{{?}}
{{?}}
{{?? $macro }}
{{# def.extraError:'custom' }}
{{??}}
{{? $rDef.errors === false}}
{{= def_customError }}
{{??}}
if (Array.isArray({{=$ruleErrs}})) {
if (vErrors === null) vErrors = {{=$ruleErrs}};
else vErrors = vErrors.concat({{=$ruleErrs}});
errors = vErrors.length;
{{# def.extendErrors:false }}
} else {
{{= def_customError }}
}
{{?}}
{{?}}
} {{? $breakOnError }} else { {{?}}
{{?}}
@@ -0,0 +1,32 @@
{{## def.assignDefault:
if ({{=$passData}} === undefined)
{{=$passData}} = {{? it.opts.useDefaults == 'shared' }}
{{= it.useDefault($sch.default) }}
{{??}}
{{= JSON.stringify($sch.default) }}
{{?}};
#}}
{{## def.defaultProperties:
{{
var $schema = it.schema.properties
, $schemaKeys = Object.keys($schema); }}
{{~ $schemaKeys:$propertyKey }}
{{ var $sch = $schema[$propertyKey]; }}
{{? $sch.default !== undefined }}
{{ var $passData = $data + it.util.getProperty($propertyKey); }}
{{# def.assignDefault }}
{{?}}
{{~}}
#}}
{{## def.defaultItems:
{{~ it.schema.items:$sch:$i }}
{{? $sch.default !== undefined }}
{{ var $passData = $data + '[' + $i + ']'; }}
{{# def.assignDefault }}
{{?}}
{{~}}
#}}
@@ -0,0 +1,199 @@
{{## def.setupKeyword:
{{
var $lvl = it.level;
var $dataLvl = it.dataLevel;
var $schema = it.schema[$keyword];
var $schemaPath = it.schemaPath + it.util.getProperty($keyword);
var $errSchemaPath = it.errSchemaPath + '/' + $keyword;
var $breakOnError = !it.opts.allErrors;
var $errorKeyword;
var $data = 'data' + ($dataLvl || '');
var $valid = 'valid' + $lvl;
var $errs = 'errs__' + $lvl;
}}
#}}
{{## def.setCompositeRule:
{{
var $wasComposite = it.compositeRule;
it.compositeRule = $it.compositeRule = true;
}}
#}}
{{## def.resetCompositeRule:
{{ it.compositeRule = $it.compositeRule = $wasComposite; }}
#}}
{{## def.setupNextLevel:
{{
var $it = it.util.copy(it);
var $closingBraces = '';
$it.level++;
var $nextValid = 'valid' + $it.level;
}}
#}}
{{## def.ifValid:
{{? $breakOnError }}
if ({{=$valid}}) {
{{ $closingBraces += '}'; }}
{{?}}
#}}
{{## def.ifResultValid:
{{? $breakOnError }}
if ({{=$nextValid}}) {
{{ $closingBraces += '}'; }}
{{?}}
#}}
{{## def.elseIfValid:
{{? $breakOnError }}
{{ $closingBraces += '}'; }}
else {
{{?}}
#}}
{{## def.nonEmptySchema:_schema:
it.util.schemaHasRules(_schema, it.RULES.all)
#}}
{{## def.strLength:
{{? it.opts.unicode === false }}
{{=$data}}.length
{{??}}
ucs2length({{=$data}})
{{?}}
#}}
{{## def.willOptimize:
it.util.varOccurences($code, $nextData) < 2
#}}
{{## def.generateSubschemaCode:
{{
var $code = it.validate($it);
$it.baseId = $currentBaseId;
}}
#}}
{{## def.insertSubschemaCode:
{{= it.validate($it) }}
{{ $it.baseId = $currentBaseId; }}
#}}
{{## def._optimizeValidate:
it.util.varReplace($code, $nextData, $passData)
#}}
{{## def.optimizeValidate:
{{? {{# def.willOptimize}} }}
{{= {{# def._optimizeValidate }} }}
{{??}}
var {{=$nextData}} = {{=$passData}};
{{= $code }}
{{?}}
#}}
{{## def.cleanUp: {{ out = it.util.cleanUpCode(out); }} #}}
{{## def.finalCleanUp: {{ out = it.util.finalCleanUpCode(out, $async); }} #}}
{{## def.$data:
{{
var $isData = it.opts.$data && $schema && $schema.$data
, $schemaValue;
}}
{{? $isData }}
var schema{{=$lvl}} = {{= it.util.getData($schema.$data, $dataLvl, it.dataPathArr) }};
{{ $schemaValue = 'schema' + $lvl; }}
{{??}}
{{ $schemaValue = $schema; }}
{{?}}
#}}
{{## def.$dataNotType:_type:
{{?$isData}} ({{=$schemaValue}} !== undefined && typeof {{=$schemaValue}} != _type) || {{?}}
#}}
{{## def.check$dataIsArray:
if (schema{{=$lvl}} === undefined) {{=$valid}} = true;
else if (!Array.isArray(schema{{=$lvl}})) {{=$valid}} = false;
else {
#}}
{{## def.beginDefOut:
{{
var $$outStack = $$outStack || [];
$$outStack.push(out);
out = '';
}}
#}}
{{## def.storeDefOut:_variable:
{{
var _variable = out;
out = $$outStack.pop();
}}
#}}
{{## def.dataPath:(dataPath || ''){{? it.errorPath != '""'}} + {{= it.errorPath }}{{?}}#}}
{{## def.setParentData:
{{
var $parentData = $dataLvl ? 'data' + (($dataLvl-1)||'') : 'parentData'
, $parentDataProperty = $dataLvl ? it.dataPathArr[$dataLvl] : 'parentDataProperty';
}}
#}}
{{## def.passParentData:
{{# def.setParentData }}
, {{= $parentData }}
, {{= $parentDataProperty }}
#}}
{{## def.iterateProperties:
{{? $ownProperties }}
{{=$dataProperties}} = {{=$dataProperties}} || Object.keys({{=$data}});
for (var {{=$idx}}=0; {{=$idx}}<{{=$dataProperties}}.length; {{=$idx}}++) {
var {{=$key}} = {{=$dataProperties}}[{{=$idx}}];
{{??}}
for (var {{=$key}} in {{=$data}}) {
{{?}}
#}}
{{## def.noPropertyInData:
{{=$useData}} === undefined
{{? $ownProperties }}
|| !{{# def.isOwnProperty }}
{{?}}
#}}
{{## def.isOwnProperty:
Object.prototype.hasOwnProperty.call({{=$data}}, '{{=it.util.escapeQuotes($propertyKey)}}')
#}}
@@ -0,0 +1,80 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.missing }}
{{# def.setupKeyword }}
{{# def.setupNextLevel }}
{{## def.propertyInData:
{{=$data}}{{= it.util.getProperty($property) }} !== undefined
{{? $ownProperties }}
&& Object.prototype.hasOwnProperty.call({{=$data}}, '{{=it.util.escapeQuotes($property)}}')
{{?}}
#}}
{{
var $schemaDeps = {}
, $propertyDeps = {}
, $ownProperties = it.opts.ownProperties;
for ($property in $schema) {
var $sch = $schema[$property];
var $deps = Array.isArray($sch) ? $propertyDeps : $schemaDeps;
$deps[$property] = $sch;
}
}}
var {{=$errs}} = errors;
{{ var $currentErrorPath = it.errorPath; }}
var missing{{=$lvl}};
{{ for (var $property in $propertyDeps) { }}
{{ $deps = $propertyDeps[$property]; }}
{{? $deps.length }}
if ({{# def.propertyInData }}
{{? $breakOnError }}
&& ({{# def.checkMissingProperty:$deps }})) {
{{# def.errorMissingProperty:'dependencies' }}
{{??}}
) {
{{~ $deps:$propertyKey }}
{{# def.allErrorsMissingProperty:'dependencies' }}
{{~}}
{{?}}
} {{# def.elseIfValid }}
{{?}}
{{ } }}
{{
it.errorPath = $currentErrorPath;
var $currentBaseId = $it.baseId;
}}
{{ for (var $property in $schemaDeps) { }}
{{ var $sch = $schemaDeps[$property]; }}
{{? {{# def.nonEmptySchema:$sch }} }}
{{=$nextValid}} = true;
if ({{# def.propertyInData }}) {
{{
$it.schema = $sch;
$it.schemaPath = $schemaPath + it.util.getProperty($property);
$it.errSchemaPath = $errSchemaPath + '/' + it.util.escapeFragment($property);
}}
{{# def.insertSubschemaCode }}
}
{{# def.ifResultValid }}
{{?}}
{{ } }}
{{? $breakOnError }}
{{= $closingBraces }}
if ({{=$errs}} == errors) {
{{?}}
{{# def.cleanUp }}
+30
View File
@@ -0,0 +1,30 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.setupKeyword }}
{{# def.$data }}
{{
var $i = 'i' + $lvl
, $vSchema = 'schema' + $lvl;
}}
{{? !$isData }}
var {{=$vSchema}} = validate.schema{{=$schemaPath}};
{{?}}
var {{=$valid}};
{{?$isData}}{{# def.check$dataIsArray }}{{?}}
{{=$valid}} = false;
for (var {{=$i}}=0; {{=$i}}<{{=$vSchema}}.length; {{=$i}}++)
if (equal({{=$data}}, {{=$vSchema}}[{{=$i}}])) {
{{=$valid}} = true;
break;
}
{{? $isData }} } {{?}}
{{# def.checkError:'enum' }}
{{? $breakOnError }} else { {{?}}
+194
View File
@@ -0,0 +1,194 @@
{{# def.definitions }}
{{## def._error:_rule:
{{ 'istanbul ignore else'; }}
{{? it.createErrors !== false }}
{
keyword: '{{= $errorKeyword || _rule }}'
, dataPath: (dataPath || '') + {{= it.errorPath }}
, schemaPath: {{=it.util.toQuotedString($errSchemaPath)}}
, params: {{# def._errorParams[_rule] }}
{{? it.opts.messages !== false }}
, message: {{# def._errorMessages[_rule] }}
{{?}}
{{? it.opts.verbose }}
, schema: {{# def._errorSchemas[_rule] }}
, parentSchema: validate.schema{{=it.schemaPath}}
, data: {{=$data}}
{{?}}
}
{{??}}
{}
{{?}}
#}}
{{## def._addError:_rule:
if (vErrors === null) vErrors = [err];
else vErrors.push(err);
errors++;
#}}
{{## def.addError:_rule:
var err = {{# def._error:_rule }};
{{# def._addError:_rule }}
#}}
{{## def.error:_rule:
{{# def.beginDefOut}}
{{# def._error:_rule }}
{{# def.storeDefOut:__err }}
{{? !it.compositeRule && $breakOnError }}
{{ 'istanbul ignore if'; }}
{{? it.async }}
throw new ValidationError([{{=__err}}]);
{{??}}
validate.errors = [{{=__err}}];
return false;
{{?}}
{{??}}
var err = {{=__err}};
{{# def._addError:_rule }}
{{?}}
#}}
{{## def.extraError:_rule:
{{# def.addError:_rule}}
{{? !it.compositeRule && $breakOnError }}
{{ 'istanbul ignore if'; }}
{{? it.async }}
throw new ValidationError(vErrors);
{{??}}
validate.errors = vErrors;
return false;
{{?}}
{{?}}
#}}
{{## def.checkError:_rule:
if (!{{=$valid}}) {
{{# def.error:_rule }}
}
#}}
{{## def.resetErrors:
errors = {{=$errs}};
if (vErrors !== null) {
if ({{=$errs}}) vErrors.length = {{=$errs}};
else vErrors = null;
}
#}}
{{## def.concatSchema:{{?$isData}}' + {{=$schemaValue}} + '{{??}}{{=$schema}}{{?}}#}}
{{## def.appendSchema:{{?$isData}}' + {{=$schemaValue}}{{??}}{{=$schemaValue}}'{{?}}#}}
{{## def.concatSchemaEQ:{{?$isData}}' + {{=$schemaValue}} + '{{??}}{{=it.util.escapeQuotes($schema)}}{{?}}#}}
{{## def._errorMessages = {
'false schema': "'boolean schema is false'",
$ref: "'can\\\'t resolve reference {{=it.util.escapeQuotes($schema)}}'",
additionalItems: "'should NOT have more than {{=$schema.length}} items'",
additionalProperties: "'should NOT have additional properties'",
anyOf: "'should match some schema in anyOf'",
const: "'should be equal to constant'",
contains: "'should contain a valid item'",
dependencies: "'should have {{? $deps.length == 1 }}property {{= it.util.escapeQuotes($deps[0]) }}{{??}}properties {{= it.util.escapeQuotes($deps.join(\", \")) }}{{?}} when property {{= it.util.escapeQuotes($property) }} is present'",
'enum': "'should be equal to one of the allowed values'",
format: "'should match format \"{{#def.concatSchemaEQ}}\"'",
_limit: "'should be {{=$opStr}} {{#def.appendSchema}}",
_exclusiveLimit: "'{{=$exclusiveKeyword}} should be boolean'",
_limitItems: "'should NOT have {{?$keyword=='maxItems'}}more{{??}}less{{?}} than {{#def.concatSchema}} items'",
_limitLength: "'should NOT be {{?$keyword=='maxLength'}}longer{{??}}shorter{{?}} than {{#def.concatSchema}} characters'",
_limitProperties:"'should NOT have {{?$keyword=='maxProperties'}}more{{??}}less{{?}} than {{#def.concatSchema}} properties'",
multipleOf: "'should be multiple of {{#def.appendSchema}}",
not: "'should NOT be valid'",
oneOf: "'should match exactly one schema in oneOf'",
pattern: "'should match pattern \"{{#def.concatSchemaEQ}}\"'",
patternGroups: "'should NOT have {{=$moreOrLess}} than {{=$limit}} properties matching pattern \"{{=it.util.escapeQuotes($pgProperty)}}\"'",
propertyNames: "'property name \\'{{=$invalidName}}\\' is invalid'",
required: "'{{? it.opts._errorDataPathProperty }}is a required property{{??}}should have required property \\'{{=$missingProperty}}\\'{{?}}'",
type: "'should be {{? $typeIsArray }}{{= $typeSchema.join(\",\") }}{{??}}{{=$typeSchema}}{{?}}'",
uniqueItems: "'should NOT have duplicate items (items ## ' + j + ' and ' + i + ' are identical)'",
custom: "'should pass \"{{=$rule.keyword}}\" keyword validation'",
patternRequired: "'should have property matching pattern \\'{{=$missingPattern}}\\''",
switch: "'should pass \"switch\" keyword validation'",
_formatLimit: "'should be {{=$opStr}} \"{{#def.concatSchemaEQ}}\"'",
_formatExclusiveLimit: "'{{=$exclusiveKeyword}} should be boolean'"
} #}}
{{## def.schemaRefOrVal: {{?$isData}}validate.schema{{=$schemaPath}}{{??}}{{=$schema}}{{?}} #}}
{{## def.schemaRefOrQS: {{?$isData}}validate.schema{{=$schemaPath}}{{??}}{{=it.util.toQuotedString($schema)}}{{?}} #}}
{{## def._errorSchemas = {
'false schema': "false",
$ref: "{{=it.util.toQuotedString($schema)}}",
additionalItems: "false",
additionalProperties: "false",
anyOf: "validate.schema{{=$schemaPath}}",
const: "validate.schema{{=$schemaPath}}",
contains: "validate.schema{{=$schemaPath}}",
dependencies: "validate.schema{{=$schemaPath}}",
'enum': "validate.schema{{=$schemaPath}}",
format: "{{#def.schemaRefOrQS}}",
_limit: "{{#def.schemaRefOrVal}}",
_exclusiveLimit: "validate.schema{{=$schemaPath}}",
_limitItems: "{{#def.schemaRefOrVal}}",
_limitLength: "{{#def.schemaRefOrVal}}",
_limitProperties:"{{#def.schemaRefOrVal}}",
multipleOf: "{{#def.schemaRefOrVal}}",
not: "validate.schema{{=$schemaPath}}",
oneOf: "validate.schema{{=$schemaPath}}",
pattern: "{{#def.schemaRefOrQS}}",
patternGroups: "validate.schema{{=$schemaPath}}",
propertyNames: "validate.schema{{=$schemaPath}}",
required: "validate.schema{{=$schemaPath}}",
type: "validate.schema{{=$schemaPath}}",
uniqueItems: "{{#def.schemaRefOrVal}}",
custom: "validate.schema{{=$schemaPath}}",
patternRequired: "validate.schema{{=$schemaPath}}",
switch: "validate.schema{{=$schemaPath}}",
_formatLimit: "{{#def.schemaRefOrQS}}",
_formatExclusiveLimit: "validate.schema{{=$schemaPath}}"
} #}}
{{## def.schemaValueQS: {{?$isData}}{{=$schemaValue}}{{??}}{{=it.util.toQuotedString($schema)}}{{?}} #}}
{{## def._errorParams = {
'false schema': "{}",
$ref: "{ ref: '{{=it.util.escapeQuotes($schema)}}' }",
additionalItems: "{ limit: {{=$schema.length}} }",
additionalProperties: "{ additionalProperty: '{{=$additionalProperty}}' }",
anyOf: "{}",
const: "{}",
contains: "{}",
dependencies: "{ property: '{{= it.util.escapeQuotes($property) }}', missingProperty: '{{=$missingProperty}}', depsCount: {{=$deps.length}}, deps: '{{= it.util.escapeQuotes($deps.length==1 ? $deps[0] : $deps.join(\", \")) }}' }",
'enum': "{ allowedValues: schema{{=$lvl}} }",
format: "{ format: {{#def.schemaValueQS}} }",
_limit: "{ comparison: {{=$opExpr}}, limit: {{=$schemaValue}}, exclusive: {{=$exclusive}} }",
_exclusiveLimit: "{}",
_limitItems: "{ limit: {{=$schemaValue}} }",
_limitLength: "{ limit: {{=$schemaValue}} }",
_limitProperties:"{ limit: {{=$schemaValue}} }",
multipleOf: "{ multipleOf: {{=$schemaValue}} }",
not: "{}",
oneOf: "{}",
pattern: "{ pattern: {{#def.schemaValueQS}} }",
patternGroups: "{ reason: '{{=$reason}}', limit: {{=$limit}}, pattern: '{{=it.util.escapeQuotes($pgProperty)}}' }",
propertyNames: "{ propertyName: '{{=$invalidName}}' }",
required: "{ missingProperty: '{{=$missingProperty}}' }",
type: "{ type: '{{? $typeIsArray }}{{= $typeSchema.join(\",\") }}{{??}}{{=$typeSchema}}{{?}}' }",
uniqueItems: "{ i: i, j: j }",
custom: "{ keyword: '{{=$rule.keyword}}' }",
patternRequired: "{ missingPattern: '{{=$missingPattern}}' }",
switch: "{ caseIndex: {{=$caseIndex}} }",
_formatLimit: "{ comparison: {{=$opExpr}}, limit: {{#def.schemaValueQS}}, exclusive: {{=$exclusive}} }",
_formatExclusiveLimit: "{}"
} #}}
+106
View File
@@ -0,0 +1,106 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.setupKeyword }}
{{## def.skipFormat:
{{? $breakOnError }} if (true) { {{?}}
{{ return out; }}
#}}
{{? it.opts.format === false }}{{# def.skipFormat }}{{?}}
{{# def.$data }}
{{## def.$dataCheckFormat:
{{# def.$dataNotType:'string' }}
({{? $unknownFormats != 'ignore' }}
({{=$schemaValue}} && !{{=$format}}
{{? $allowUnknown }}
&& self._opts.unknownFormats.indexOf({{=$schemaValue}}) == -1
{{?}}) ||
{{?}}
({{=$format}} && {{=$formatType}} == '{{=$ruleType}}'
&& !(typeof {{=$format}} == 'function'
? {{? it.async}}
(async{{=$lvl}} ? {{=it.yieldAwait}} {{=$format}}({{=$data}}) : {{=$format}}({{=$data}}))
{{??}}
{{=$format}}({{=$data}})
{{?}}
: {{=$format}}.test({{=$data}}))))
#}}
{{## def.checkFormat:
{{
var $formatRef = 'formats' + it.util.getProperty($schema);
if ($isObject) $formatRef += '.validate';
}}
{{? typeof $format == 'function' }}
{{=$formatRef}}({{=$data}})
{{??}}
{{=$formatRef}}.test({{=$data}})
{{?}}
#}}
{{
var $unknownFormats = it.opts.unknownFormats
, $allowUnknown = Array.isArray($unknownFormats);
}}
{{? $isData }}
{{
var $format = 'format' + $lvl
, $isObject = 'isObject' + $lvl
, $formatType = 'formatType' + $lvl;
}}
var {{=$format}} = formats[{{=$schemaValue}}];
var {{=$isObject}} = typeof {{=$format}} == 'object'
&& !({{=$format}} instanceof RegExp)
&& {{=$format}}.validate;
var {{=$formatType}} = {{=$isObject}} && {{=$format}}.type || 'string';
if ({{=$isObject}}) {
{{? it.async}}
var async{{=$lvl}} = {{=$format}}.async;
{{?}}
{{=$format}} = {{=$format}}.validate;
}
if ({{# def.$dataCheckFormat }}) {
{{??}}
{{ var $format = it.formats[$schema]; }}
{{? !$format }}
{{? $unknownFormats == 'ignore' }}
{{ it.logger.warn('unknown format "' + $schema + '" ignored in schema at path "' + it.errSchemaPath + '"'); }}
{{# def.skipFormat }}
{{?? $allowUnknown && $unknownFormats.indexOf($schema) >= 0 }}
{{# def.skipFormat }}
{{??}}
{{ throw new Error('unknown format "' + $schema + '" is used in schema at path "' + it.errSchemaPath + '"'); }}
{{?}}
{{?}}
{{
var $isObject = typeof $format == 'object'
&& !($format instanceof RegExp)
&& $format.validate;
var $formatType = $isObject && $format.type || 'string';
if ($isObject) {
var $async = $format.async === true;
$format = $format.validate;
}
}}
{{? $formatType != $ruleType }}
{{# def.skipFormat }}
{{?}}
{{? $async }}
{{
if (!it.async) throw new Error('async format in sync schema');
var $formatRef = 'formats' + it.util.getProperty($schema) + '.validate';
}}
if (!({{=it.yieldAwait}} {{=$formatRef}}({{=$data}}))) {
{{??}}
if (!{{# def.checkFormat }}) {
{{?}}
{{?}}
{{# def.error:'format' }}
} {{? $breakOnError }} else { {{?}}
+100
View File
@@ -0,0 +1,100 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.setupKeyword }}
{{# def.setupNextLevel }}
{{## def.validateItems:startFrom:
for (var {{=$idx}} = {{=startFrom}}; {{=$idx}} < {{=$data}}.length; {{=$idx}}++) {
{{
$it.errorPath = it.util.getPathExpr(it.errorPath, $idx, it.opts.jsonPointers, true);
var $passData = $data + '[' + $idx + ']';
$it.dataPathArr[$dataNxt] = $idx;
}}
{{# def.generateSubschemaCode }}
{{# def.optimizeValidate }}
{{? $breakOnError }}
if (!{{=$nextValid}}) break;
{{?}}
}
#}}
{{
var $idx = 'i' + $lvl
, $dataNxt = $it.dataLevel = it.dataLevel + 1
, $nextData = 'data' + $dataNxt
, $currentBaseId = it.baseId;
}}
var {{=$errs}} = errors;
var {{=$valid}};
{{? Array.isArray($schema) }}
{{ /* 'items' is an array of schemas */}}
{{ var $additionalItems = it.schema.additionalItems; }}
{{? $additionalItems === false }}
{{=$valid}} = {{=$data}}.length <= {{= $schema.length }};
{{
var $currErrSchemaPath = $errSchemaPath;
$errSchemaPath = it.errSchemaPath + '/additionalItems';
}}
{{# def.checkError:'additionalItems' }}
{{ $errSchemaPath = $currErrSchemaPath; }}
{{# def.elseIfValid}}
{{?}}
{{~ $schema:$sch:$i }}
{{? {{# def.nonEmptySchema:$sch }} }}
{{=$nextValid}} = true;
if ({{=$data}}.length > {{=$i}}) {
{{
var $passData = $data + '[' + $i + ']';
$it.schema = $sch;
$it.schemaPath = $schemaPath + '[' + $i + ']';
$it.errSchemaPath = $errSchemaPath + '/' + $i;
$it.errorPath = it.util.getPathExpr(it.errorPath, $i, it.opts.jsonPointers, true);
$it.dataPathArr[$dataNxt] = $i;
}}
{{# def.generateSubschemaCode }}
{{# def.optimizeValidate }}
}
{{# def.ifResultValid }}
{{?}}
{{~}}
{{? typeof $additionalItems == 'object' && {{# def.nonEmptySchema:$additionalItems }} }}
{{
$it.schema = $additionalItems;
$it.schemaPath = it.schemaPath + '.additionalItems';
$it.errSchemaPath = it.errSchemaPath + '/additionalItems';
}}
{{=$nextValid}} = true;
if ({{=$data}}.length > {{= $schema.length }}) {
{{# def.validateItems: $schema.length }}
}
{{# def.ifResultValid }}
{{?}}
{{?? {{# def.nonEmptySchema:$schema }} }}
{{ /* 'items' is a single schema */}}
{{
$it.schema = $schema;
$it.schemaPath = $schemaPath;
$it.errSchemaPath = $errSchemaPath;
}}
{{# def.validateItems: 0 }}
{{?}}
{{? $breakOnError }}
{{= $closingBraces }}
if ({{=$errs}} == errors) {
{{?}}
{{# def.cleanUp }}
@@ -0,0 +1,39 @@
{{## def.checkMissingProperty:_properties:
{{~ _properties:$propertyKey:$i }}
{{?$i}} || {{?}}
{{
var $prop = it.util.getProperty($propertyKey)
, $useData = $data + $prop;
}}
( ({{# def.noPropertyInData }}) && (missing{{=$lvl}} = {{= it.util.toQuotedString(it.opts.jsonPointers ? $propertyKey : $prop) }}) )
{{~}}
#}}
{{## def.errorMissingProperty:_error:
{{
var $propertyPath = 'missing' + $lvl
, $missingProperty = '\' + ' + $propertyPath + ' + \'';
if (it.opts._errorDataPathProperty) {
it.errorPath = it.opts.jsonPointers
? it.util.getPathExpr($currentErrorPath, $propertyPath, true)
: $currentErrorPath + ' + ' + $propertyPath;
}
}}
{{# def.error:_error }}
#}}
{{## def.allErrorsMissingProperty:_error:
{{
var $prop = it.util.getProperty($propertyKey)
, $missingProperty = it.util.escapeQuotes($propertyKey)
, $useData = $data + $prop;
if (it.opts._errorDataPathProperty) {
it.errorPath = it.util.getPath($currentErrorPath, $propertyKey, it.opts.jsonPointers);
}
}}
if ({{# def.noPropertyInData }}) {
{{# def.addError:_error }}
}
#}}
@@ -0,0 +1,20 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.setupKeyword }}
{{# def.$data }}
var division{{=$lvl}};
if ({{?$isData}}
{{=$schemaValue}} !== undefined && (
typeof {{=$schemaValue}} != 'number' ||
{{?}}
(division{{=$lvl}} = {{=$data}} / {{=$schemaValue}},
{{? it.opts.multipleOfPrecision }}
Math.abs(Math.round(division{{=$lvl}}) - division{{=$lvl}}) > 1e-{{=it.opts.multipleOfPrecision}}
{{??}}
division{{=$lvl}} !== parseInt(division{{=$lvl}})
{{?}}
)
{{?$isData}} ) {{?}} ) {
{{# def.error:'multipleOf' }}
} {{? $breakOnError }} else { {{?}}
+43
View File
@@ -0,0 +1,43 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.setupKeyword }}
{{# def.setupNextLevel }}
{{? {{# def.nonEmptySchema:$schema }} }}
{{
$it.schema = $schema;
$it.schemaPath = $schemaPath;
$it.errSchemaPath = $errSchemaPath;
}}
var {{=$errs}} = errors;
{{# def.setCompositeRule }}
{{
$it.createErrors = false;
var $allErrorsOption;
if ($it.opts.allErrors) {
$allErrorsOption = $it.opts.allErrors;
$it.opts.allErrors = false;
}
}}
{{= it.validate($it) }}
{{
$it.createErrors = true;
if ($allErrorsOption) $it.opts.allErrors = $allErrorsOption;
}}
{{# def.resetCompositeRule }}
if ({{=$nextValid}}) {
{{# def.error:'not' }}
} else {
{{# def.resetErrors }}
{{? it.opts.allErrors }} } {{?}}
{{??}}
{{# def.addError:'not' }}
{{? $breakOnError}}
if (false) {
{{?}}
{{?}}
+44
View File
@@ -0,0 +1,44 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.setupKeyword }}
{{# def.setupNextLevel }}
var {{=$errs}} = errors;
var prevValid{{=$lvl}} = false;
var {{=$valid}} = false;
{{ var $currentBaseId = $it.baseId; }}
{{# def.setCompositeRule }}
{{~ $schema:$sch:$i }}
{{? {{# def.nonEmptySchema:$sch }} }}
{{
$it.schema = $sch;
$it.schemaPath = $schemaPath + '[' + $i + ']';
$it.errSchemaPath = $errSchemaPath + '/' + $i;
}}
{{# def.insertSubschemaCode }}
{{??}}
var {{=$nextValid}} = true;
{{?}}
{{? $i }}
if ({{=$nextValid}} && prevValid{{=$lvl}})
{{=$valid}} = false;
else {
{{ $closingBraces += '}'; }}
{{?}}
if ({{=$nextValid}}) {{=$valid}} = prevValid{{=$lvl}} = true;
{{~}}
{{# def.resetCompositeRule }}
{{= $closingBraces }}
if (!{{=$valid}}) {
{{# def.extraError:'oneOf' }}
} else {
{{# def.resetErrors }}
{{? it.opts.allErrors }} } {{?}}
@@ -0,0 +1,14 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.setupKeyword }}
{{# def.$data }}
{{
var $regexp = $isData
? '(new RegExp(' + $schemaValue + '))'
: it.usePattern($schema);
}}
if ({{# def.$dataNotType:'string' }} !{{=$regexp}}.test({{=$data}}) ) {
{{# def.error:'pattern' }}
} {{? $breakOnError }} else { {{?}}
@@ -0,0 +1,327 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.setupKeyword }}
{{# def.setupNextLevel }}
{{## def.validateAdditional:
{{ /* additionalProperties is schema */
$it.schema = $aProperties;
$it.schemaPath = it.schemaPath + '.additionalProperties';
$it.errSchemaPath = it.errSchemaPath + '/additionalProperties';
$it.errorPath = it.opts._errorDataPathProperty
? it.errorPath
: it.util.getPathExpr(it.errorPath, $key, it.opts.jsonPointers);
var $passData = $data + '[' + $key + ']';
$it.dataPathArr[$dataNxt] = $key;
}}
{{# def.generateSubschemaCode }}
{{# def.optimizeValidate }}
#}}
{{
var $key = 'key' + $lvl
, $idx = 'idx' + $lvl
, $dataNxt = $it.dataLevel = it.dataLevel + 1
, $nextData = 'data' + $dataNxt
, $dataProperties = 'dataProperties' + $lvl;
var $schemaKeys = Object.keys($schema || {})
, $pProperties = it.schema.patternProperties || {}
, $pPropertyKeys = Object.keys($pProperties)
, $aProperties = it.schema.additionalProperties
, $someProperties = $schemaKeys.length || $pPropertyKeys.length
, $noAdditional = $aProperties === false
, $additionalIsSchema = typeof $aProperties == 'object'
&& Object.keys($aProperties).length
, $removeAdditional = it.opts.removeAdditional
, $checkAdditional = $noAdditional || $additionalIsSchema || $removeAdditional
, $ownProperties = it.opts.ownProperties
, $currentBaseId = it.baseId;
var $required = it.schema.required;
if ($required && !(it.opts.v5 && $required.$data) && $required.length < it.opts.loopRequired)
var $requiredHash = it.util.toHash($required);
if (it.opts.patternGroups) {
var $pgProperties = it.schema.patternGroups || {}
, $pgPropertyKeys = Object.keys($pgProperties);
}
}}
var {{=$errs}} = errors;
var {{=$nextValid}} = true;
{{? $ownProperties }}
var {{=$dataProperties}} = undefined;
{{?}}
{{? $checkAdditional }}
{{# def.iterateProperties }}
{{? $someProperties }}
var isAdditional{{=$lvl}} = !(false
{{? $schemaKeys.length }}
{{? $schemaKeys.length > 5 }}
|| validate.schema{{=$schemaPath}}[{{=$key}}]
{{??}}
{{~ $schemaKeys:$propertyKey }}
|| {{=$key}} == {{= it.util.toQuotedString($propertyKey) }}
{{~}}
{{?}}
{{?}}
{{? $pPropertyKeys.length }}
{{~ $pPropertyKeys:$pProperty:$i }}
|| {{= it.usePattern($pProperty) }}.test({{=$key}})
{{~}}
{{?}}
{{? it.opts.patternGroups && $pgPropertyKeys.length }}
{{~ $pgPropertyKeys:$pgProperty:$i }}
|| {{= it.usePattern($pgProperty) }}.test({{=$key}})
{{~}}
{{?}}
);
if (isAdditional{{=$lvl}}) {
{{?}}
{{? $removeAdditional == 'all' }}
delete {{=$data}}[{{=$key}}];
{{??}}
{{
var $currentErrorPath = it.errorPath;
var $additionalProperty = '\' + ' + $key + ' + \'';
if (it.opts._errorDataPathProperty) {
it.errorPath = it.util.getPathExpr(it.errorPath, $key, it.opts.jsonPointers);
}
}}
{{? $noAdditional }}
{{? $removeAdditional }}
delete {{=$data}}[{{=$key}}];
{{??}}
{{=$nextValid}} = false;
{{
var $currErrSchemaPath = $errSchemaPath;
$errSchemaPath = it.errSchemaPath + '/additionalProperties';
}}
{{# def.error:'additionalProperties' }}
{{ $errSchemaPath = $currErrSchemaPath; }}
{{? $breakOnError }} break; {{?}}
{{?}}
{{?? $additionalIsSchema }}
{{? $removeAdditional == 'failing' }}
var {{=$errs}} = errors;
{{# def.setCompositeRule }}
{{# def.validateAdditional }}
if (!{{=$nextValid}}) {
errors = {{=$errs}};
if (validate.errors !== null) {
if (errors) validate.errors.length = errors;
else validate.errors = null;
}
delete {{=$data}}[{{=$key}}];
}
{{# def.resetCompositeRule }}
{{??}}
{{# def.validateAdditional }}
{{? $breakOnError }} if (!{{=$nextValid}}) break; {{?}}
{{?}}
{{?}}
{{ it.errorPath = $currentErrorPath; }}
{{?}}
{{? $someProperties }}
}
{{?}}
}
{{# def.ifResultValid }}
{{?}}
{{ var $useDefaults = it.opts.useDefaults && !it.compositeRule; }}
{{? $schemaKeys.length }}
{{~ $schemaKeys:$propertyKey }}
{{ var $sch = $schema[$propertyKey]; }}
{{? {{# def.nonEmptySchema:$sch}} }}
{{
var $prop = it.util.getProperty($propertyKey)
, $passData = $data + $prop
, $hasDefault = $useDefaults && $sch.default !== undefined;
$it.schema = $sch;
$it.schemaPath = $schemaPath + $prop;
$it.errSchemaPath = $errSchemaPath + '/' + it.util.escapeFragment($propertyKey);
$it.errorPath = it.util.getPath(it.errorPath, $propertyKey, it.opts.jsonPointers);
$it.dataPathArr[$dataNxt] = it.util.toQuotedString($propertyKey);
}}
{{# def.generateSubschemaCode }}
{{? {{# def.willOptimize }} }}
{{
$code = {{# def._optimizeValidate }};
var $useData = $passData;
}}
{{??}}
{{ var $useData = $nextData; }}
var {{=$nextData}} = {{=$passData}};
{{?}}
{{? $hasDefault }}
{{= $code }}
{{??}}
{{? $requiredHash && $requiredHash[$propertyKey] }}
if ({{# def.noPropertyInData }}) {
{{=$nextValid}} = false;
{{
var $currentErrorPath = it.errorPath
, $currErrSchemaPath = $errSchemaPath
, $missingProperty = it.util.escapeQuotes($propertyKey);
if (it.opts._errorDataPathProperty) {
it.errorPath = it.util.getPath($currentErrorPath, $propertyKey, it.opts.jsonPointers);
}
$errSchemaPath = it.errSchemaPath + '/required';
}}
{{# def.error:'required' }}
{{ $errSchemaPath = $currErrSchemaPath; }}
{{ it.errorPath = $currentErrorPath; }}
} else {
{{??}}
{{? $breakOnError }}
if ({{# def.noPropertyInData }}) {
{{=$nextValid}} = true;
} else {
{{??}}
if ({{=$useData}} !== undefined
{{? $ownProperties }}
&& {{# def.isOwnProperty }}
{{?}}
) {
{{?}}
{{?}}
{{= $code }}
}
{{?}} {{ /* $hasDefault */ }}
{{?}} {{ /* def.nonEmptySchema */ }}
{{# def.ifResultValid }}
{{~}}
{{?}}
{{? $pPropertyKeys.length }}
{{~ $pPropertyKeys:$pProperty }}
{{ var $sch = $pProperties[$pProperty]; }}
{{? {{# def.nonEmptySchema:$sch}} }}
{{
$it.schema = $sch;
$it.schemaPath = it.schemaPath + '.patternProperties' + it.util.getProperty($pProperty);
$it.errSchemaPath = it.errSchemaPath + '/patternProperties/'
+ it.util.escapeFragment($pProperty);
}}
{{# def.iterateProperties }}
if ({{= it.usePattern($pProperty) }}.test({{=$key}})) {
{{
$it.errorPath = it.util.getPathExpr(it.errorPath, $key, it.opts.jsonPointers);
var $passData = $data + '[' + $key + ']';
$it.dataPathArr[$dataNxt] = $key;
}}
{{# def.generateSubschemaCode }}
{{# def.optimizeValidate }}
{{? $breakOnError }} if (!{{=$nextValid}}) break; {{?}}
}
{{? $breakOnError }} else {{=$nextValid}} = true; {{?}}
}
{{# def.ifResultValid }}
{{?}} {{ /* def.nonEmptySchema */ }}
{{~}}
{{?}}
{{? it.opts.patternGroups && $pgPropertyKeys.length }}
{{~ $pgPropertyKeys:$pgProperty }}
{{
var $pgSchema = $pgProperties[$pgProperty]
, $sch = $pgSchema.schema;
}}
{{? {{# def.nonEmptySchema:$sch}} }}
{{
$it.schema = $sch;
$it.schemaPath = it.schemaPath + '.patternGroups' + it.util.getProperty($pgProperty) + '.schema';
$it.errSchemaPath = it.errSchemaPath + '/patternGroups/'
+ it.util.escapeFragment($pgProperty)
+ '/schema';
}}
var pgPropCount{{=$lvl}} = 0;
{{# def.iterateProperties }}
if ({{= it.usePattern($pgProperty) }}.test({{=$key}})) {
pgPropCount{{=$lvl}}++;
{{
$it.errorPath = it.util.getPathExpr(it.errorPath, $key, it.opts.jsonPointers);
var $passData = $data + '[' + $key + ']';
$it.dataPathArr[$dataNxt] = $key;
}}
{{# def.generateSubschemaCode }}
{{# def.optimizeValidate }}
{{? $breakOnError }} if (!{{=$nextValid}}) break; {{?}}
}
{{? $breakOnError }} else {{=$nextValid}} = true; {{?}}
}
{{# def.ifResultValid }}
{{
var $pgMin = $pgSchema.minimum
, $pgMax = $pgSchema.maximum;
}}
{{? $pgMin !== undefined || $pgMax !== undefined }}
var {{=$valid}} = true;
{{ var $currErrSchemaPath = $errSchemaPath; }}
{{? $pgMin !== undefined }}
{{ var $limit = $pgMin, $reason = 'minimum', $moreOrLess = 'less'; }}
{{=$valid}} = pgPropCount{{=$lvl}} >= {{=$pgMin}};
{{ $errSchemaPath = it.errSchemaPath + '/patternGroups/minimum'; }}
{{# def.checkError:'patternGroups' }}
{{? $pgMax !== undefined }}
else
{{?}}
{{?}}
{{? $pgMax !== undefined }}
{{ var $limit = $pgMax, $reason = 'maximum', $moreOrLess = 'more'; }}
{{=$valid}} = pgPropCount{{=$lvl}} <= {{=$pgMax}};
{{ $errSchemaPath = it.errSchemaPath + '/patternGroups/maximum'; }}
{{# def.checkError:'patternGroups' }}
{{?}}
{{ $errSchemaPath = $currErrSchemaPath; }}
{{# def.ifValid }}
{{?}}
{{?}} {{ /* def.nonEmptySchema */ }}
{{~}}
{{?}}
{{? $breakOnError }}
{{= $closingBraces }}
if ({{=$errs}} == errors) {
{{?}}
{{# def.cleanUp }}
@@ -0,0 +1,54 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.setupKeyword }}
{{# def.setupNextLevel }}
{{? {{# def.nonEmptySchema:$schema }} }}
{{
$it.schema = $schema;
$it.schemaPath = $schemaPath;
$it.errSchemaPath = $errSchemaPath;
}}
{{
var $key = 'key' + $lvl
, $idx = 'idx' + $lvl
, $i = 'i' + $lvl
, $invalidName = '\' + ' + $key + ' + \''
, $dataNxt = $it.dataLevel = it.dataLevel + 1
, $nextData = 'data' + $dataNxt
, $dataProperties = 'dataProperties' + $lvl
, $ownProperties = it.opts.ownProperties
, $currentBaseId = it.baseId;
}}
var {{=$errs}} = errors;
{{? $ownProperties }}
var {{=$dataProperties}} = undefined;
{{?}}
{{# def.iterateProperties }}
var startErrs{{=$lvl}} = errors;
{{ var $passData = $key; }}
{{# def.setCompositeRule }}
{{# def.generateSubschemaCode }}
{{# def.optimizeValidate }}
{{# def.resetCompositeRule }}
if (!{{=$nextValid}}) {
for (var {{=$i}}=startErrs{{=$lvl}}; {{=$i}}<errors; {{=$i}}++) {
vErrors[{{=$i}}].propertyName = {{=$key}};
}
{{# def.extraError:'propertyNames' }}
{{? $breakOnError }} break; {{?}}
}
}
{{?}}
{{? $breakOnError }}
{{= $closingBraces }}
if ({{=$errs}} == errors) {
{{?}}
{{# def.cleanUp }}
+85
View File
@@ -0,0 +1,85 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.setupKeyword }}
{{## def._validateRef:_v:
{{? it.opts.passContext }}
{{=_v}}.call(this,
{{??}}
{{=_v}}(
{{?}}
{{=$data}}, {{# def.dataPath }}{{# def.passParentData }}, rootData)
#}}
{{ var $async, $refCode; }}
{{? $schema == '#' || $schema == '#/' }}
{{
if (it.isRoot) {
$async = it.async;
$refCode = 'validate';
} else {
$async = it.root.schema.$async === true;
$refCode = 'root.refVal[0]';
}
}}
{{??}}
{{ var $refVal = it.resolveRef(it.baseId, $schema, it.isRoot); }}
{{? $refVal === undefined }}
{{ var $message = it.MissingRefError.message(it.baseId, $schema); }}
{{? it.opts.missingRefs == 'fail' }}
{{ it.logger.error($message); }}
{{# def.error:'$ref' }}
{{? $breakOnError }} if (false) { {{?}}
{{?? it.opts.missingRefs == 'ignore' }}
{{ it.logger.warn($message); }}
{{? $breakOnError }} if (true) { {{?}}
{{??}}
{{ throw new it.MissingRefError(it.baseId, $schema, $message); }}
{{?}}
{{?? $refVal.inline }}
{{# def.setupNextLevel }}
{{
$it.schema = $refVal.schema;
$it.schemaPath = '';
$it.errSchemaPath = $schema;
}}
{{ var $code = it.validate($it).replace(/validate\.schema/g, $refVal.code); }}
{{= $code }}
{{? $breakOnError}}
if ({{=$nextValid}}) {
{{?}}
{{??}}
{{
$async = $refVal.$async === true;
$refCode = $refVal.code;
}}
{{?}}
{{?}}
{{? $refCode }}
{{# def.beginDefOut}}
{{# def._validateRef:$refCode }}
{{# def.storeDefOut:__callValidate }}
{{? $async }}
{{ if (!it.async) throw new Error('async schema referenced by sync schema'); }}
{{? $breakOnError }} var {{=$valid}}; {{?}}
try {
{{=it.yieldAwait}} {{=__callValidate}};
{{? $breakOnError }} {{=$valid}} = true; {{?}}
} catch (e) {
if (!(e instanceof ValidationError)) throw e;
if (vErrors === null) vErrors = e.errors;
else vErrors = vErrors.concat(e.errors);
errors = vErrors.length;
{{? $breakOnError }} {{=$valid}} = false; {{?}}
}
{{? $breakOnError }} if ({{=$valid}}) { {{?}}
{{??}}
if (!{{=__callValidate}}) {
if (vErrors === null) vErrors = {{=$refCode}}.errors;
else vErrors = vErrors.concat({{=$refCode}}.errors);
errors = vErrors.length;
} {{? $breakOnError }} else { {{?}}
{{?}}
{{?}}
@@ -0,0 +1,108 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.missing }}
{{# def.setupKeyword }}
{{# def.$data }}
{{ var $vSchema = 'schema' + $lvl; }}
{{## def.setupLoop:
{{? !$isData }}
var {{=$vSchema}} = validate.schema{{=$schemaPath}};
{{?}}
{{
var $i = 'i' + $lvl
, $propertyPath = 'schema' + $lvl + '[' + $i + ']'
, $missingProperty = '\' + ' + $propertyPath + ' + \'';
if (it.opts._errorDataPathProperty) {
it.errorPath = it.util.getPathExpr($currentErrorPath, $propertyPath, it.opts.jsonPointers);
}
}}
#}}
{{## def.isRequiredOwnProperty:
Object.prototype.hasOwnProperty.call({{=$data}}, {{=$vSchema}}[{{=$i}}])
#}}
{{? !$isData }}
{{? $schema.length < it.opts.loopRequired &&
it.schema.properties && Object.keys(it.schema.properties).length }}
{{ var $required = []; }}
{{~ $schema:$property }}
{{ var $propertySch = it.schema.properties[$property]; }}
{{? !($propertySch && {{# def.nonEmptySchema:$propertySch}}) }}
{{ $required[$required.length] = $property; }}
{{?}}
{{~}}
{{??}}
{{ var $required = $schema; }}
{{?}}
{{?}}
{{? $isData || $required.length }}
{{
var $currentErrorPath = it.errorPath
, $loopRequired = $isData || $required.length >= it.opts.loopRequired
, $ownProperties = it.opts.ownProperties;
}}
{{? $breakOnError }}
var missing{{=$lvl}};
{{? $loopRequired }}
{{# def.setupLoop }}
var {{=$valid}} = true;
{{?$isData}}{{# def.check$dataIsArray }}{{?}}
for (var {{=$i}} = 0; {{=$i}} < {{=$vSchema}}.length; {{=$i}}++) {
{{=$valid}} = {{=$data}}[{{=$vSchema}}[{{=$i}}]] !== undefined
{{? $ownProperties }}
&& {{# def.isRequiredOwnProperty }}
{{?}};
if (!{{=$valid}}) break;
}
{{? $isData }} } {{?}}
{{# def.checkError:'required' }}
else {
{{??}}
if ({{# def.checkMissingProperty:$required }}) {
{{# def.errorMissingProperty:'required' }}
} else {
{{?}}
{{??}}
{{? $loopRequired }}
{{# def.setupLoop }}
{{? $isData }}
if ({{=$vSchema}} && !Array.isArray({{=$vSchema}})) {
{{# def.addError:'required' }}
} else if ({{=$vSchema}} !== undefined) {
{{?}}
for (var {{=$i}} = 0; {{=$i}} < {{=$vSchema}}.length; {{=$i}}++) {
if ({{=$data}}[{{=$vSchema}}[{{=$i}}]] === undefined
{{? $ownProperties }}
|| !{{# def.isRequiredOwnProperty }}
{{?}}) {
{{# def.addError:'required' }}
}
}
{{? $isData }} } {{?}}
{{??}}
{{~ $required:$propertyKey }}
{{# def.allErrorsMissingProperty:'required' }}
{{~}}
{{?}}
{{?}}
{{ it.errorPath = $currentErrorPath; }}
{{?? $breakOnError }}
if (true) {
{{?}}
@@ -0,0 +1,38 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.setupKeyword }}
{{# def.$data }}
{{? ($schema || $isData) && it.opts.uniqueItems !== false }}
{{? $isData }}
var {{=$valid}};
if ({{=$schemaValue}} === false || {{=$schemaValue}} === undefined)
{{=$valid}} = true;
else if (typeof {{=$schemaValue}} != 'boolean')
{{=$valid}} = false;
else {
{{?}}
var {{=$valid}} = true;
if ({{=$data}}.length > 1) {
var i = {{=$data}}.length, j;
outer:
for (;i--;) {
for (j = i; j--;) {
if (equal({{=$data}}[i], {{=$data}}[j])) {
{{=$valid}} = false;
break outer;
}
}
}
}
{{? $isData }} } {{?}}
if (!{{=$valid}}) {
{{# def.error:'uniqueItems' }}
} {{? $breakOnError }} else { {{?}}
{{??}}
{{? $breakOnError }} if (true) { {{?}}
{{?}}
@@ -0,0 +1,272 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.defaults }}
{{# def.coerce }}
{{ /**
* schema compilation (render) time:
* it = { schema, RULES, _validate, opts }
* it.validate - this template function,
* it is used recursively to generate code for subschemas
*
* runtime:
* "validate" is a variable name to which this function will be assigned
* validateRef etc. are defined in the parent scope in index.js
*/ }}
{{
var $async = it.schema.$async === true
, $refKeywords = it.util.schemaHasRulesExcept(it.schema, it.RULES.all, '$ref')
, $id = it.self._getId(it.schema);
}}
{{? it.isTop }}
{{? $async }}
{{
it.async = true;
var $es7 = it.opts.async == 'es7';
it.yieldAwait = $es7 ? 'await' : 'yield';
}}
{{?}}
var validate =
{{? $async }}
{{? $es7 }}
(async function
{{??}}
{{? it.opts.async != '*'}}co.wrap{{?}}(function*
{{?}}
{{??}}
(function
{{?}}
(data, dataPath, parentData, parentDataProperty, rootData) {
'use strict';
{{? $id && (it.opts.sourceCode || it.opts.processCode) }}
{{= '/\*# sourceURL=' + $id + ' */' }}
{{?}}
{{?}}
{{? typeof it.schema == 'boolean' || !($refKeywords || it.schema.$ref) }}
{{ var $keyword = 'false schema'; }}
{{# def.setupKeyword }}
{{? it.schema === false}}
{{? it.isTop}}
{{ $breakOnError = true; }}
{{??}}
var {{=$valid}} = false;
{{?}}
{{# def.error:'false schema' }}
{{??}}
{{? it.isTop}}
{{? $async }}
return data;
{{??}}
validate.errors = null;
return true;
{{?}}
{{??}}
var {{=$valid}} = true;
{{?}}
{{?}}
{{? it.isTop}}
});
return validate;
{{?}}
{{ return out; }}
{{?}}
{{? it.isTop }}
{{
var $top = it.isTop
, $lvl = it.level = 0
, $dataLvl = it.dataLevel = 0
, $data = 'data';
it.rootId = it.resolve.fullPath(it.self._getId(it.root.schema));
it.baseId = it.baseId || it.rootId;
delete it.isTop;
it.dataPathArr = [undefined];
}}
var vErrors = null; {{ /* don't edit, used in replace */ }}
var errors = 0; {{ /* don't edit, used in replace */ }}
if (rootData === undefined) rootData = data; {{ /* don't edit, used in replace */ }}
{{??}}
{{
var $lvl = it.level
, $dataLvl = it.dataLevel
, $data = 'data' + ($dataLvl || '');
if ($id) it.baseId = it.resolve.url(it.baseId, $id);
if ($async && !it.async) throw new Error('async schema in sync schema');
}}
var errs_{{=$lvl}} = errors;
{{?}}
{{
var $valid = 'valid' + $lvl
, $breakOnError = !it.opts.allErrors
, $closingBraces1 = ''
, $closingBraces2 = '';
var $errorKeyword;
var $typeSchema = it.schema.type
, $typeIsArray = Array.isArray($typeSchema);
if ($typeIsArray && $typeSchema.length == 1) {
$typeSchema = $typeSchema[0];
$typeIsArray = false;
}
}}
{{## def.checkType:
{{
var $schemaPath = it.schemaPath + '.type'
, $errSchemaPath = it.errSchemaPath + '/type'
, $method = $typeIsArray ? 'checkDataTypes' : 'checkDataType';
}}
if ({{= it.util[$method]($typeSchema, $data, true) }}) {
#}}
{{? it.schema.$ref && $refKeywords }}
{{? it.opts.extendRefs == 'fail' }}
{{ throw new Error('$ref: validation keywords used in schema at path "' + it.errSchemaPath + '" (see option extendRefs)'); }}
{{?? it.opts.extendRefs !== true }}
{{
$refKeywords = false;
it.logger.warn('$ref: keywords ignored in schema at path "' + it.errSchemaPath + '"');
}}
{{?}}
{{?}}
{{? $typeSchema }}
{{? it.opts.coerceTypes }}
{{ var $coerceToTypes = it.util.coerceToTypes(it.opts.coerceTypes, $typeSchema); }}
{{?}}
{{ var $rulesGroup = it.RULES.types[$typeSchema]; }}
{{? $coerceToTypes || $typeIsArray || $rulesGroup === true ||
($rulesGroup && !$shouldUseGroup($rulesGroup)) }}
{{
var $schemaPath = it.schemaPath + '.type'
, $errSchemaPath = it.errSchemaPath + '/type';
}}
{{# def.checkType }}
{{? $coerceToTypes }}
{{# def.coerceType }}
{{??}}
{{# def.error:'type' }}
{{?}}
}
{{?}}
{{?}}
{{? it.schema.$ref && !$refKeywords }}
{{= it.RULES.all.$ref.code(it, '$ref') }}
{{? $breakOnError }}
}
if (errors === {{?$top}}0{{??}}errs_{{=$lvl}}{{?}}) {
{{ $closingBraces2 += '}'; }}
{{?}}
{{??}}
{{? it.opts.v5 && it.schema.patternGroups }}
{{ it.logger.warn('keyword "patternGroups" is deprecated and disabled. Use option patternGroups: true to enable.'); }}
{{?}}
{{~ it.RULES:$rulesGroup }}
{{? $shouldUseGroup($rulesGroup) }}
{{? $rulesGroup.type }}
if ({{= it.util.checkDataType($rulesGroup.type, $data) }}) {
{{?}}
{{? it.opts.useDefaults && !it.compositeRule }}
{{? $rulesGroup.type == 'object' && it.schema.properties }}
{{# def.defaultProperties }}
{{?? $rulesGroup.type == 'array' && Array.isArray(it.schema.items) }}
{{# def.defaultItems }}
{{?}}
{{?}}
{{~ $rulesGroup.rules:$rule }}
{{? $shouldUseRule($rule) }}
{{ var $code = $rule.code(it, $rule.keyword, $rulesGroup.type); }}
{{? $code }}
{{= $code }}
{{? $breakOnError }}
{{ $closingBraces1 += '}'; }}
{{?}}
{{?}}
{{?}}
{{~}}
{{? $breakOnError }}
{{= $closingBraces1 }}
{{ $closingBraces1 = ''; }}
{{?}}
{{? $rulesGroup.type }}
}
{{? $typeSchema && $typeSchema === $rulesGroup.type && !$coerceToTypes }}
else {
{{
var $schemaPath = it.schemaPath + '.type'
, $errSchemaPath = it.errSchemaPath + '/type';
}}
{{# def.error:'type' }}
}
{{?}}
{{?}}
{{? $breakOnError }}
if (errors === {{?$top}}0{{??}}errs_{{=$lvl}}{{?}}) {
{{ $closingBraces2 += '}'; }}
{{?}}
{{?}}
{{~}}
{{?}}
{{? $breakOnError }} {{= $closingBraces2 }} {{?}}
{{? $top }}
{{? $async }}
if (errors === 0) return data; {{ /* don't edit, used in replace */ }}
else throw new ValidationError(vErrors); {{ /* don't edit, used in replace */ }}
{{??}}
validate.errors = vErrors; {{ /* don't edit, used in replace */ }}
return errors === 0; {{ /* don't edit, used in replace */ }}
{{?}}
});
return validate;
{{??}}
var {{=$valid}} = errors === errs_{{=$lvl}};
{{?}}
{{# def.cleanUp }}
{{? $top }}
{{# def.finalCleanUp }}
{{?}}
{{
function $shouldUseGroup($rulesGroup) {
var rules = $rulesGroup.rules;
for (var i=0; i < rules.length; i++)
if ($shouldUseRule(rules[i]))
return true;
}
function $shouldUseRule($rule) {
return it.schema[$rule.keyword] !== undefined ||
($rule.implements && $ruleImplementsSomeKeyword($rule));
}
function $ruleImplementsSomeKeyword($rule) {
var impl = $rule.implements;
for (var i=0; i < impl.length; i++)
if (it.schema[impl[i]] !== undefined)
return true;
}
}}
@@ -0,0 +1,3 @@
These files are compiled dot templates from dot folder.
Do NOT edit them directly, edit the templates and run `npm run build` from main ajv folder.
@@ -0,0 +1,149 @@
'use strict';
module.exports = function generate__limit(it, $keyword, $ruleType) {
var out = ' ';
var $lvl = it.level;
var $dataLvl = it.dataLevel;
var $schema = it.schema[$keyword];
var $schemaPath = it.schemaPath + it.util.getProperty($keyword);
var $errSchemaPath = it.errSchemaPath + '/' + $keyword;
var $breakOnError = !it.opts.allErrors;
var $errorKeyword;
var $data = 'data' + ($dataLvl || '');
var $isData = it.opts.$data && $schema && $schema.$data,
$schemaValue;
if ($isData) {
out += ' var schema' + ($lvl) + ' = ' + (it.util.getData($schema.$data, $dataLvl, it.dataPathArr)) + '; ';
$schemaValue = 'schema' + $lvl;
} else {
$schemaValue = $schema;
}
var $isMax = $keyword == 'maximum',
$exclusiveKeyword = $isMax ? 'exclusiveMaximum' : 'exclusiveMinimum',
$schemaExcl = it.schema[$exclusiveKeyword],
$isDataExcl = it.opts.$data && $schemaExcl && $schemaExcl.$data,
$op = $isMax ? '<' : '>',
$notOp = $isMax ? '>' : '<',
$errorKeyword = undefined;
if ($isDataExcl) {
var $schemaValueExcl = it.util.getData($schemaExcl.$data, $dataLvl, it.dataPathArr),
$exclusive = 'exclusive' + $lvl,
$exclType = 'exclType' + $lvl,
$exclIsNumber = 'exclIsNumber' + $lvl,
$opExpr = 'op' + $lvl,
$opStr = '\' + ' + $opExpr + ' + \'';
out += ' var schemaExcl' + ($lvl) + ' = ' + ($schemaValueExcl) + '; ';
$schemaValueExcl = 'schemaExcl' + $lvl;
out += ' var ' + ($exclusive) + '; var ' + ($exclType) + ' = typeof ' + ($schemaValueExcl) + '; if (' + ($exclType) + ' != \'boolean\' && ' + ($exclType) + ' != \'undefined\' && ' + ($exclType) + ' != \'number\') { ';
var $errorKeyword = $exclusiveKeyword;
var $$outStack = $$outStack || [];
$$outStack.push(out);
out = ''; /* istanbul ignore else */
if (it.createErrors !== false) {
out += ' { keyword: \'' + ($errorKeyword || '_exclusiveLimit') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: {} ';
if (it.opts.messages !== false) {
out += ' , message: \'' + ($exclusiveKeyword) + ' should be boolean\' ';
}
if (it.opts.verbose) {
out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' ';
}
out += ' } ';
} else {
out += ' {} ';
}
var __err = out;
out = $$outStack.pop();
if (!it.compositeRule && $breakOnError) { /* istanbul ignore if */
if (it.async) {
out += ' throw new ValidationError([' + (__err) + ']); ';
} else {
out += ' validate.errors = [' + (__err) + ']; return false; ';
}
} else {
out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ';
}
out += ' } else if ( ';
if ($isData) {
out += ' (' + ($schemaValue) + ' !== undefined && typeof ' + ($schemaValue) + ' != \'number\') || ';
}
out += ' ' + ($exclType) + ' == \'number\' ? ( (' + ($exclusive) + ' = ' + ($schemaValue) + ' === undefined || ' + ($schemaValueExcl) + ' ' + ($op) + '= ' + ($schemaValue) + ') ? ' + ($data) + ' ' + ($notOp) + '= ' + ($schemaValueExcl) + ' : ' + ($data) + ' ' + ($notOp) + ' ' + ($schemaValue) + ' ) : ( (' + ($exclusive) + ' = ' + ($schemaValueExcl) + ' === true) ? ' + ($data) + ' ' + ($notOp) + '= ' + ($schemaValue) + ' : ' + ($data) + ' ' + ($notOp) + ' ' + ($schemaValue) + ' ) || ' + ($data) + ' !== ' + ($data) + ') { var op' + ($lvl) + ' = ' + ($exclusive) + ' ? \'' + ($op) + '\' : \'' + ($op) + '=\';';
} else {
var $exclIsNumber = typeof $schemaExcl == 'number',
$opStr = $op;
if ($exclIsNumber && $isData) {
var $opExpr = '\'' + $opStr + '\'';
out += ' if ( ';
if ($isData) {
out += ' (' + ($schemaValue) + ' !== undefined && typeof ' + ($schemaValue) + ' != \'number\') || ';
}
out += ' ( ' + ($schemaValue) + ' === undefined || ' + ($schemaExcl) + ' ' + ($op) + '= ' + ($schemaValue) + ' ? ' + ($data) + ' ' + ($notOp) + '= ' + ($schemaExcl) + ' : ' + ($data) + ' ' + ($notOp) + ' ' + ($schemaValue) + ' ) || ' + ($data) + ' !== ' + ($data) + ') { ';
} else {
if ($exclIsNumber && $schema === undefined) {
$exclusive = true;
$errorKeyword = $exclusiveKeyword;
$errSchemaPath = it.errSchemaPath + '/' + $exclusiveKeyword;
$schemaValue = $schemaExcl;
$notOp += '=';
} else {
if ($exclIsNumber) $schemaValue = Math[$isMax ? 'min' : 'max']($schemaExcl, $schema);
if ($schemaExcl === ($exclIsNumber ? $schemaValue : true)) {
$exclusive = true;
$errorKeyword = $exclusiveKeyword;
$errSchemaPath = it.errSchemaPath + '/' + $exclusiveKeyword;
$notOp += '=';
} else {
$exclusive = false;
$opStr += '=';
}
}
var $opExpr = '\'' + $opStr + '\'';
out += ' if ( ';
if ($isData) {
out += ' (' + ($schemaValue) + ' !== undefined && typeof ' + ($schemaValue) + ' != \'number\') || ';
}
out += ' ' + ($data) + ' ' + ($notOp) + ' ' + ($schemaValue) + ' || ' + ($data) + ' !== ' + ($data) + ') { ';
}
}
$errorKeyword = $errorKeyword || $keyword;
var $$outStack = $$outStack || [];
$$outStack.push(out);
out = ''; /* istanbul ignore else */
if (it.createErrors !== false) {
out += ' { keyword: \'' + ($errorKeyword || '_limit') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { comparison: ' + ($opExpr) + ', limit: ' + ($schemaValue) + ', exclusive: ' + ($exclusive) + ' } ';
if (it.opts.messages !== false) {
out += ' , message: \'should be ' + ($opStr) + ' ';
if ($isData) {
out += '\' + ' + ($schemaValue);
} else {
out += '' + ($schemaValue) + '\'';
}
}
if (it.opts.verbose) {
out += ' , schema: ';
if ($isData) {
out += 'validate.schema' + ($schemaPath);
} else {
out += '' + ($schema);
}
out += ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' ';
}
out += ' } ';
} else {
out += ' {} ';
}
var __err = out;
out = $$outStack.pop();
if (!it.compositeRule && $breakOnError) { /* istanbul ignore if */
if (it.async) {
out += ' throw new ValidationError([' + (__err) + ']); ';
} else {
out += ' validate.errors = [' + (__err) + ']; return false; ';
}
} else {
out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ';
}
out += ' } ';
if ($breakOnError) {
out += ' else { ';
}
return out;
}
@@ -0,0 +1,76 @@
'use strict';
module.exports = function generate__limitItems(it, $keyword, $ruleType) {
var out = ' ';
var $lvl = it.level;
var $dataLvl = it.dataLevel;
var $schema = it.schema[$keyword];
var $schemaPath = it.schemaPath + it.util.getProperty($keyword);
var $errSchemaPath = it.errSchemaPath + '/' + $keyword;
var $breakOnError = !it.opts.allErrors;
var $errorKeyword;
var $data = 'data' + ($dataLvl || '');
var $isData = it.opts.$data && $schema && $schema.$data,
$schemaValue;
if ($isData) {
out += ' var schema' + ($lvl) + ' = ' + (it.util.getData($schema.$data, $dataLvl, it.dataPathArr)) + '; ';
$schemaValue = 'schema' + $lvl;
} else {
$schemaValue = $schema;
}
var $op = $keyword == 'maxItems' ? '>' : '<';
out += 'if ( ';
if ($isData) {
out += ' (' + ($schemaValue) + ' !== undefined && typeof ' + ($schemaValue) + ' != \'number\') || ';
}
out += ' ' + ($data) + '.length ' + ($op) + ' ' + ($schemaValue) + ') { ';
var $errorKeyword = $keyword;
var $$outStack = $$outStack || [];
$$outStack.push(out);
out = ''; /* istanbul ignore else */
if (it.createErrors !== false) {
out += ' { keyword: \'' + ($errorKeyword || '_limitItems') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { limit: ' + ($schemaValue) + ' } ';
if (it.opts.messages !== false) {
out += ' , message: \'should NOT have ';
if ($keyword == 'maxItems') {
out += 'more';
} else {
out += 'less';
}
out += ' than ';
if ($isData) {
out += '\' + ' + ($schemaValue) + ' + \'';
} else {
out += '' + ($schema);
}
out += ' items\' ';
}
if (it.opts.verbose) {
out += ' , schema: ';
if ($isData) {
out += 'validate.schema' + ($schemaPath);
} else {
out += '' + ($schema);
}
out += ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' ';
}
out += ' } ';
} else {
out += ' {} ';
}
var __err = out;
out = $$outStack.pop();
if (!it.compositeRule && $breakOnError) { /* istanbul ignore if */
if (it.async) {
out += ' throw new ValidationError([' + (__err) + ']); ';
} else {
out += ' validate.errors = [' + (__err) + ']; return false; ';
}
} else {
out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ';
}
out += '} ';
if ($breakOnError) {
out += ' else { ';
}
return out;
}

Some files were not shown because too many files have changed in this diff Show More