Add components
This commit is contained in:
21
slider/node_modules/eslint-plugin-vue/LICENSE
generated
vendored
Normal file
21
slider/node_modules/eslint-plugin-vue/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017 Toru Nagashima
|
||||
|
||||
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.
|
56
slider/node_modules/eslint-plugin-vue/README.md
generated
vendored
Normal file
56
slider/node_modules/eslint-plugin-vue/README.md
generated
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
# eslint-plugin-vue
|
||||
|
||||
[](https://npmjs.org/package/eslint-plugin-vue)
|
||||
[](https://npmjs.org/package/eslint-plugin-vue)
|
||||
[](https://github.com/vuejs/eslint-plugin-vue/actions/workflows/CI.yml)
|
||||
[](https://github.com/vuejs/eslint-plugin-vue/blob/master/LICENSE)
|
||||
|
||||
> Official ESLint plugin for Vue.js
|
||||
|
||||
## :book: Documentation
|
||||
|
||||
Please refer to the [official website](https://eslint.vuejs.org).
|
||||
|
||||
## :anchor: Versioning Policy
|
||||
|
||||
This plugin follows [Semantic Versioning].
|
||||
However, please note that we do not follow [ESLint's Semantic Versioning Policy].
|
||||
In minor version releases, this plugin may change the sharable configs provided by the plugin or the default behavior of the plugin's rules in order to add features to the plugin. Because we want to add many features to the plugin soon, so that users can easily take advantage of new features in Vue and Nuxt.
|
||||
|
||||
According to our policy, any minor update may report more linting errors than the previous release. As such, we recommend using the [tilde (`~`)](https://semver.npmjs.com/#syntax-examples) in `package.json` to guarantee the results of your builds.
|
||||
|
||||
[Semantic Versioning]: https://semver.org/
|
||||
[ESLint's Semantic Versioning Policy]: https://github.com/eslint/eslint#semantic-versioning-policy
|
||||
|
||||
## :newspaper: Releases
|
||||
|
||||
This project uses [GitHub Releases](https://github.com/vuejs/eslint-plugin-vue/releases).
|
||||
|
||||
## :beers: Contribution Guide
|
||||
|
||||
Contributing is welcome! See the [ESLint Vue Plugin Developer Guide](https://eslint.vuejs.org/developer-guide).
|
||||
|
||||
### Working With Rules
|
||||
|
||||
Be sure to read the [official ESLint guide](https://eslint.org/docs/developer-guide/working-with-rules) before you start writing a new rule.
|
||||
|
||||
To see what an abstract syntax tree (AST) of your code looks like, you may use [AST Explorer](https://astexplorer.net). After opening [AST Explorer](https://astexplorer.net), select `Vue` as the syntax and [`vue-eslint-parser`](https://github.com/vuejs/vue-eslint-parser) as the parser.
|
||||
|
||||
The default JavaScript parser must be replaced because [Vue.js single file components](https://vuejs.org/guide/scaling-up/sfc.html) are not plain JavaScript, but a custom file format. [`vue-eslint-parser`](https://github.com/vuejs/vue-eslint-parser) is a replacement parser that generates an enhanced AST with nodes that represent specific parts of the template syntax, as well as the contents of the `<script>` tag.
|
||||
|
||||
To learn more about certain nodes in a produced AST, see the [ESTree project page](https://github.com/estree/estree) and the [vue-eslint-parser AST documentation](https://github.com/vuejs/vue-eslint-parser/blob/master/docs/ast.md).
|
||||
|
||||
[`vue-eslint-parser`](https://github.com/vuejs/vue-eslint-parser) provides a few useful parser services to help traverse the produced AST and access template tokens:
|
||||
|
||||
- `context.parserServices.defineTemplateBodyVisitor(visitor, scriptVisitor)`
|
||||
- `context.parserServices.getTemplateBodyTokenStore()`
|
||||
|
||||
Check out an [example rule](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/mustache-interpolation-spacing.js) to see usage of these services.
|
||||
|
||||
Be aware that depending on the code samples you write in tests, the `RuleTester` parser property must be set accordingly (this can be done on a test by test basis). See an [example here](https://github.com/vuejs/eslint-plugin-vue/blob/master/tests/lib/rules/attribute-hyphenation.js#L19).
|
||||
|
||||
If you're stuck, remember there are many rules available for reference. If you can't find the right solution, don't hesitate to reach out in [issues](https://github.com/vuejs/eslint-plugin-vue/issues) – we're happy to help!
|
||||
|
||||
## :lock: License
|
||||
|
||||
See the [LICENSE](LICENSE) file for license rights and limitations (MIT).
|
22
slider/node_modules/eslint-plugin-vue/lib/configs/base.js
generated
vendored
Normal file
22
slider/node_modules/eslint-plugin-vue/lib/configs/base.js
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* IMPORTANT!
|
||||
* This file has been automatically generated,
|
||||
* in order to update its content execute "npm run update"
|
||||
*/
|
||||
module.exports = {
|
||||
parserOptions: {
|
||||
ecmaVersion: 'latest',
|
||||
sourceType: 'module'
|
||||
},
|
||||
plugins: ['vue'],
|
||||
rules: {
|
||||
'vue/comment-directive': 'error',
|
||||
'vue/jsx-uses-vars': 'error'
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
files: '*.vue',
|
||||
parser: require.resolve('vue-eslint-parser')
|
||||
}
|
||||
]
|
||||
}
|
36
slider/node_modules/eslint-plugin-vue/lib/configs/flat/base.js
generated
vendored
Normal file
36
slider/node_modules/eslint-plugin-vue/lib/configs/flat/base.js
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* IMPORTANT!
|
||||
* This file has been automatically generated,
|
||||
* in order to update its content execute "npm run update"
|
||||
*/
|
||||
module.exports = [
|
||||
{
|
||||
name: 'vue/base/setup',
|
||||
plugins: {
|
||||
get vue() {
|
||||
return require('../../index')
|
||||
}
|
||||
},
|
||||
languageOptions: {
|
||||
sourceType: 'module'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'vue/base/setup-for-vue',
|
||||
files: ['*.vue', '**/*.vue'],
|
||||
plugins: {
|
||||
get vue() {
|
||||
return require('../../index')
|
||||
}
|
||||
},
|
||||
languageOptions: {
|
||||
parser: require('vue-eslint-parser'),
|
||||
sourceType: 'module'
|
||||
},
|
||||
rules: {
|
||||
'vue/comment-directive': 'error',
|
||||
'vue/jsx-uses-vars': 'error'
|
||||
},
|
||||
processor: 'vue/vue'
|
||||
}
|
||||
]
|
79
slider/node_modules/eslint-plugin-vue/lib/configs/flat/vue2-essential.js
generated
vendored
Normal file
79
slider/node_modules/eslint-plugin-vue/lib/configs/flat/vue2-essential.js
generated
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* IMPORTANT!
|
||||
* This file has been automatically generated,
|
||||
* in order to update its content execute "npm run update"
|
||||
*/
|
||||
'use strict'
|
||||
const config = require('./base.js')
|
||||
|
||||
module.exports = [
|
||||
...config,
|
||||
{
|
||||
name: 'vue/vue2-essential/rules',
|
||||
rules: {
|
||||
'vue/multi-word-component-names': 'error',
|
||||
'vue/no-arrow-functions-in-watch': 'error',
|
||||
'vue/no-async-in-computed-properties': 'error',
|
||||
'vue/no-child-content': 'error',
|
||||
'vue/no-computed-properties-in-data': 'error',
|
||||
'vue/no-custom-modifiers-on-v-model': 'error',
|
||||
'vue/no-dupe-keys': 'error',
|
||||
'vue/no-dupe-v-else-if': 'error',
|
||||
'vue/no-duplicate-attributes': 'error',
|
||||
'vue/no-export-in-script-setup': 'error',
|
||||
'vue/no-multiple-template-root': 'error',
|
||||
'vue/no-mutating-props': 'error',
|
||||
'vue/no-parsing-error': 'error',
|
||||
'vue/no-ref-as-operand': 'error',
|
||||
'vue/no-reserved-component-names': 'error',
|
||||
'vue/no-reserved-keys': 'error',
|
||||
'vue/no-reserved-props': [
|
||||
'error',
|
||||
{
|
||||
vueVersion: 2
|
||||
}
|
||||
],
|
||||
'vue/no-shared-component-data': 'error',
|
||||
'vue/no-side-effects-in-computed-properties': 'error',
|
||||
'vue/no-template-key': 'error',
|
||||
'vue/no-textarea-mustache': 'error',
|
||||
'vue/no-unused-components': 'error',
|
||||
'vue/no-unused-vars': 'error',
|
||||
'vue/no-use-computed-property-like-method': 'error',
|
||||
'vue/no-use-v-if-with-v-for': 'error',
|
||||
'vue/no-useless-template-attributes': 'error',
|
||||
'vue/no-v-for-template-key': 'error',
|
||||
'vue/no-v-model-argument': 'error',
|
||||
'vue/no-v-text-v-html-on-component': 'error',
|
||||
'vue/require-component-is': 'error',
|
||||
'vue/require-prop-type-constructor': 'error',
|
||||
'vue/require-render-return': 'error',
|
||||
'vue/require-v-for-key': 'error',
|
||||
'vue/require-valid-default-prop': 'error',
|
||||
'vue/return-in-computed-property': 'error',
|
||||
'vue/return-in-emits-validator': 'error',
|
||||
'vue/use-v-on-exact': 'error',
|
||||
'vue/valid-attribute-name': 'error',
|
||||
'vue/valid-define-emits': 'error',
|
||||
'vue/valid-define-props': 'error',
|
||||
'vue/valid-model-definition': 'error',
|
||||
'vue/valid-next-tick': 'error',
|
||||
'vue/valid-template-root': 'error',
|
||||
'vue/valid-v-bind-sync': 'error',
|
||||
'vue/valid-v-bind': 'error',
|
||||
'vue/valid-v-cloak': 'error',
|
||||
'vue/valid-v-else-if': 'error',
|
||||
'vue/valid-v-else': 'error',
|
||||
'vue/valid-v-for': 'error',
|
||||
'vue/valid-v-html': 'error',
|
||||
'vue/valid-v-if': 'error',
|
||||
'vue/valid-v-model': 'error',
|
||||
'vue/valid-v-on': 'error',
|
||||
'vue/valid-v-once': 'error',
|
||||
'vue/valid-v-pre': 'error',
|
||||
'vue/valid-v-show': 'error',
|
||||
'vue/valid-v-slot': 'error',
|
||||
'vue/valid-v-text': 'error'
|
||||
}
|
||||
}
|
||||
]
|
24
slider/node_modules/eslint-plugin-vue/lib/configs/flat/vue2-recommended.js
generated
vendored
Normal file
24
slider/node_modules/eslint-plugin-vue/lib/configs/flat/vue2-recommended.js
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* IMPORTANT!
|
||||
* This file has been automatically generated,
|
||||
* in order to update its content execute "npm run update"
|
||||
*/
|
||||
'use strict'
|
||||
const config = require('./vue2-strongly-recommended.js')
|
||||
|
||||
module.exports = [
|
||||
...config,
|
||||
{
|
||||
name: 'vue/vue2-recommended/rules',
|
||||
rules: {
|
||||
'vue/attributes-order': 'warn',
|
||||
'vue/block-order': 'warn',
|
||||
'vue/no-lone-template': 'warn',
|
||||
'vue/no-multiple-slot-args': 'warn',
|
||||
'vue/no-required-prop-with-default': 'warn',
|
||||
'vue/no-v-html': 'warn',
|
||||
'vue/order-in-components': 'warn',
|
||||
'vue/this-in-template': 'warn'
|
||||
}
|
||||
}
|
||||
]
|
39
slider/node_modules/eslint-plugin-vue/lib/configs/flat/vue2-strongly-recommended.js
generated
vendored
Normal file
39
slider/node_modules/eslint-plugin-vue/lib/configs/flat/vue2-strongly-recommended.js
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* IMPORTANT!
|
||||
* This file has been automatically generated,
|
||||
* in order to update its content execute "npm run update"
|
||||
*/
|
||||
'use strict'
|
||||
const config = require('./vue2-essential.js')
|
||||
|
||||
module.exports = [
|
||||
...config,
|
||||
{
|
||||
name: 'vue/vue2-strongly-recommended/rules',
|
||||
rules: {
|
||||
'vue/attribute-hyphenation': 'warn',
|
||||
'vue/component-definition-name-casing': 'warn',
|
||||
'vue/first-attribute-linebreak': 'warn',
|
||||
'vue/html-closing-bracket-newline': 'warn',
|
||||
'vue/html-closing-bracket-spacing': 'warn',
|
||||
'vue/html-end-tags': 'warn',
|
||||
'vue/html-indent': 'warn',
|
||||
'vue/html-quotes': 'warn',
|
||||
'vue/html-self-closing': 'warn',
|
||||
'vue/max-attributes-per-line': 'warn',
|
||||
'vue/multiline-html-element-content-newline': 'warn',
|
||||
'vue/mustache-interpolation-spacing': 'warn',
|
||||
'vue/no-multi-spaces': 'warn',
|
||||
'vue/no-spaces-around-equal-signs-in-attribute': 'warn',
|
||||
'vue/no-template-shadow': 'warn',
|
||||
'vue/one-component-per-file': 'warn',
|
||||
'vue/prop-name-casing': 'warn',
|
||||
'vue/require-default-prop': 'warn',
|
||||
'vue/require-prop-types': 'warn',
|
||||
'vue/singleline-html-element-content-newline': 'warn',
|
||||
'vue/v-bind-style': 'warn',
|
||||
'vue/v-on-style': 'warn',
|
||||
'vue/v-slot-style': 'warn'
|
||||
}
|
||||
}
|
||||
]
|
99
slider/node_modules/eslint-plugin-vue/lib/configs/flat/vue3-essential.js
generated
vendored
Normal file
99
slider/node_modules/eslint-plugin-vue/lib/configs/flat/vue3-essential.js
generated
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* IMPORTANT!
|
||||
* This file has been automatically generated,
|
||||
* in order to update its content execute "npm run update"
|
||||
*/
|
||||
'use strict'
|
||||
const config = require('./base.js')
|
||||
|
||||
module.exports = [
|
||||
...config,
|
||||
{
|
||||
name: 'vue/essential/rules',
|
||||
rules: {
|
||||
'vue/multi-word-component-names': 'error',
|
||||
'vue/no-arrow-functions-in-watch': 'error',
|
||||
'vue/no-async-in-computed-properties': 'error',
|
||||
'vue/no-child-content': 'error',
|
||||
'vue/no-computed-properties-in-data': 'error',
|
||||
'vue/no-deprecated-data-object-declaration': 'error',
|
||||
'vue/no-deprecated-delete-set': 'error',
|
||||
'vue/no-deprecated-destroyed-lifecycle': 'error',
|
||||
'vue/no-deprecated-dollar-listeners-api': 'error',
|
||||
'vue/no-deprecated-dollar-scopedslots-api': 'error',
|
||||
'vue/no-deprecated-events-api': 'error',
|
||||
'vue/no-deprecated-filter': 'error',
|
||||
'vue/no-deprecated-functional-template': 'error',
|
||||
'vue/no-deprecated-html-element-is': 'error',
|
||||
'vue/no-deprecated-inline-template': 'error',
|
||||
'vue/no-deprecated-model-definition': 'error',
|
||||
'vue/no-deprecated-props-default-this': 'error',
|
||||
'vue/no-deprecated-router-link-tag-prop': 'error',
|
||||
'vue/no-deprecated-scope-attribute': 'error',
|
||||
'vue/no-deprecated-slot-attribute': 'error',
|
||||
'vue/no-deprecated-slot-scope-attribute': 'error',
|
||||
'vue/no-deprecated-v-bind-sync': 'error',
|
||||
'vue/no-deprecated-v-is': 'error',
|
||||
'vue/no-deprecated-v-on-native-modifier': 'error',
|
||||
'vue/no-deprecated-v-on-number-modifiers': 'error',
|
||||
'vue/no-deprecated-vue-config-keycodes': 'error',
|
||||
'vue/no-dupe-keys': 'error',
|
||||
'vue/no-dupe-v-else-if': 'error',
|
||||
'vue/no-duplicate-attributes': 'error',
|
||||
'vue/no-export-in-script-setup': 'error',
|
||||
'vue/no-expose-after-await': 'error',
|
||||
'vue/no-lifecycle-after-await': 'error',
|
||||
'vue/no-mutating-props': 'error',
|
||||
'vue/no-parsing-error': 'error',
|
||||
'vue/no-ref-as-operand': 'error',
|
||||
'vue/no-reserved-component-names': 'error',
|
||||
'vue/no-reserved-keys': 'error',
|
||||
'vue/no-reserved-props': 'error',
|
||||
'vue/no-shared-component-data': 'error',
|
||||
'vue/no-side-effects-in-computed-properties': 'error',
|
||||
'vue/no-template-key': 'error',
|
||||
'vue/no-textarea-mustache': 'error',
|
||||
'vue/no-unused-components': 'error',
|
||||
'vue/no-unused-vars': 'error',
|
||||
'vue/no-use-computed-property-like-method': 'error',
|
||||
'vue/no-use-v-if-with-v-for': 'error',
|
||||
'vue/no-useless-template-attributes': 'error',
|
||||
'vue/no-v-for-template-key-on-child': 'error',
|
||||
'vue/no-v-text-v-html-on-component': 'error',
|
||||
'vue/no-watch-after-await': 'error',
|
||||
'vue/prefer-import-from-vue': 'error',
|
||||
'vue/require-component-is': 'error',
|
||||
'vue/require-prop-type-constructor': 'error',
|
||||
'vue/require-render-return': 'error',
|
||||
'vue/require-slots-as-functions': 'error',
|
||||
'vue/require-toggle-inside-transition': 'error',
|
||||
'vue/require-v-for-key': 'error',
|
||||
'vue/require-valid-default-prop': 'error',
|
||||
'vue/return-in-computed-property': 'error',
|
||||
'vue/return-in-emits-validator': 'error',
|
||||
'vue/use-v-on-exact': 'error',
|
||||
'vue/valid-attribute-name': 'error',
|
||||
'vue/valid-define-emits': 'error',
|
||||
'vue/valid-define-options': 'error',
|
||||
'vue/valid-define-props': 'error',
|
||||
'vue/valid-next-tick': 'error',
|
||||
'vue/valid-template-root': 'error',
|
||||
'vue/valid-v-bind': 'error',
|
||||
'vue/valid-v-cloak': 'error',
|
||||
'vue/valid-v-else-if': 'error',
|
||||
'vue/valid-v-else': 'error',
|
||||
'vue/valid-v-for': 'error',
|
||||
'vue/valid-v-html': 'error',
|
||||
'vue/valid-v-if': 'error',
|
||||
'vue/valid-v-is': 'error',
|
||||
'vue/valid-v-memo': 'error',
|
||||
'vue/valid-v-model': 'error',
|
||||
'vue/valid-v-on': 'error',
|
||||
'vue/valid-v-once': 'error',
|
||||
'vue/valid-v-pre': 'error',
|
||||
'vue/valid-v-show': 'error',
|
||||
'vue/valid-v-slot': 'error',
|
||||
'vue/valid-v-text': 'error'
|
||||
}
|
||||
}
|
||||
]
|
24
slider/node_modules/eslint-plugin-vue/lib/configs/flat/vue3-recommended.js
generated
vendored
Normal file
24
slider/node_modules/eslint-plugin-vue/lib/configs/flat/vue3-recommended.js
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* IMPORTANT!
|
||||
* This file has been automatically generated,
|
||||
* in order to update its content execute "npm run update"
|
||||
*/
|
||||
'use strict'
|
||||
const config = require('./vue3-strongly-recommended.js')
|
||||
|
||||
module.exports = [
|
||||
...config,
|
||||
{
|
||||
name: 'vue/recommended/rules',
|
||||
rules: {
|
||||
'vue/attributes-order': 'warn',
|
||||
'vue/block-order': 'warn',
|
||||
'vue/no-lone-template': 'warn',
|
||||
'vue/no-multiple-slot-args': 'warn',
|
||||
'vue/no-required-prop-with-default': 'warn',
|
||||
'vue/no-v-html': 'warn',
|
||||
'vue/order-in-components': 'warn',
|
||||
'vue/this-in-template': 'warn'
|
||||
}
|
||||
}
|
||||
]
|
47
slider/node_modules/eslint-plugin-vue/lib/configs/flat/vue3-strongly-recommended.js
generated
vendored
Normal file
47
slider/node_modules/eslint-plugin-vue/lib/configs/flat/vue3-strongly-recommended.js
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* IMPORTANT!
|
||||
* This file has been automatically generated,
|
||||
* in order to update its content execute "npm run update"
|
||||
*/
|
||||
'use strict'
|
||||
const config = require('./vue3-essential.js')
|
||||
|
||||
module.exports = [
|
||||
...config,
|
||||
{
|
||||
name: 'vue/strongly-recommended/rules',
|
||||
rules: {
|
||||
'vue/attribute-hyphenation': 'warn',
|
||||
'vue/component-definition-name-casing': 'warn',
|
||||
'vue/first-attribute-linebreak': 'warn',
|
||||
'vue/html-closing-bracket-newline': 'warn',
|
||||
'vue/html-closing-bracket-spacing': 'warn',
|
||||
'vue/html-end-tags': 'warn',
|
||||
'vue/html-indent': 'warn',
|
||||
'vue/html-quotes': 'warn',
|
||||
'vue/html-self-closing': 'warn',
|
||||
'vue/max-attributes-per-line': 'warn',
|
||||
'vue/multiline-html-element-content-newline': 'warn',
|
||||
'vue/mustache-interpolation-spacing': 'warn',
|
||||
'vue/no-multi-spaces': 'warn',
|
||||
'vue/no-spaces-around-equal-signs-in-attribute': 'warn',
|
||||
'vue/no-template-shadow': 'warn',
|
||||
'vue/one-component-per-file': 'warn',
|
||||
'vue/prop-name-casing': 'warn',
|
||||
'vue/require-default-prop': 'warn',
|
||||
'vue/require-explicit-emits': 'warn',
|
||||
'vue/require-prop-types': 'warn',
|
||||
'vue/singleline-html-element-content-newline': 'warn',
|
||||
'vue/v-bind-style': 'warn',
|
||||
'vue/v-on-event-hyphenation': [
|
||||
'warn',
|
||||
'always',
|
||||
{
|
||||
autofix: true
|
||||
}
|
||||
],
|
||||
'vue/v-on-style': 'warn',
|
||||
'vue/v-slot-style': 'warn'
|
||||
}
|
||||
}
|
||||
]
|
57
slider/node_modules/eslint-plugin-vue/lib/configs/no-layout-rules.js
generated
vendored
Normal file
57
slider/node_modules/eslint-plugin-vue/lib/configs/no-layout-rules.js
generated
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* IMPORTANT!
|
||||
* This file has been automatically generated,
|
||||
* in order to update its content execute "npm run update"
|
||||
*/
|
||||
module.exports = {
|
||||
rules: {
|
||||
'vue/array-bracket-newline': 'off',
|
||||
'vue/array-bracket-spacing': 'off',
|
||||
'vue/array-element-newline': 'off',
|
||||
'vue/arrow-spacing': 'off',
|
||||
'vue/block-spacing': 'off',
|
||||
'vue/block-tag-newline': 'off',
|
||||
'vue/brace-style': 'off',
|
||||
'vue/comma-dangle': 'off',
|
||||
'vue/comma-spacing': 'off',
|
||||
'vue/comma-style': 'off',
|
||||
'vue/define-macros-order': 'off',
|
||||
'vue/dot-location': 'off',
|
||||
'vue/first-attribute-linebreak': 'off',
|
||||
'vue/func-call-spacing': 'off',
|
||||
'vue/html-closing-bracket-newline': 'off',
|
||||
'vue/html-closing-bracket-spacing': 'off',
|
||||
'vue/html-comment-content-newline': 'off',
|
||||
'vue/html-comment-content-spacing': 'off',
|
||||
'vue/html-comment-indent': 'off',
|
||||
'vue/html-indent': 'off',
|
||||
'vue/html-quotes': 'off',
|
||||
'vue/html-self-closing': 'off',
|
||||
'vue/key-spacing': 'off',
|
||||
'vue/keyword-spacing': 'off',
|
||||
'vue/max-attributes-per-line': 'off',
|
||||
'vue/max-len': 'off',
|
||||
'vue/multiline-html-element-content-newline': 'off',
|
||||
'vue/multiline-ternary': 'off',
|
||||
'vue/mustache-interpolation-spacing': 'off',
|
||||
'vue/new-line-between-multi-line-property': 'off',
|
||||
'vue/no-extra-parens': 'off',
|
||||
'vue/no-multi-spaces': 'off',
|
||||
'vue/no-spaces-around-equal-signs-in-attribute': 'off',
|
||||
'vue/object-curly-newline': 'off',
|
||||
'vue/object-curly-spacing': 'off',
|
||||
'vue/object-property-newline': 'off',
|
||||
'vue/operator-linebreak': 'off',
|
||||
'vue/padding-line-between-blocks': 'off',
|
||||
'vue/padding-line-between-tags': 'off',
|
||||
'vue/padding-lines-in-component-definition': 'off',
|
||||
'vue/quote-props': 'off',
|
||||
'vue/script-indent': 'off',
|
||||
'vue/singleline-html-element-content-newline': 'off',
|
||||
'vue/space-in-parens': 'off',
|
||||
'vue/space-infix-ops': 'off',
|
||||
'vue/space-unary-ops': 'off',
|
||||
'vue/template-curly-spacing': 'off',
|
||||
'vue/v-for-delimiter-style': 'off'
|
||||
}
|
||||
}
|
73
slider/node_modules/eslint-plugin-vue/lib/configs/vue2-essential.js
generated
vendored
Normal file
73
slider/node_modules/eslint-plugin-vue/lib/configs/vue2-essential.js
generated
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* IMPORTANT!
|
||||
* This file has been automatically generated,
|
||||
* in order to update its content execute "npm run update"
|
||||
*/
|
||||
module.exports = {
|
||||
extends: require.resolve('./base'),
|
||||
rules: {
|
||||
'vue/multi-word-component-names': 'error',
|
||||
'vue/no-arrow-functions-in-watch': 'error',
|
||||
'vue/no-async-in-computed-properties': 'error',
|
||||
'vue/no-child-content': 'error',
|
||||
'vue/no-computed-properties-in-data': 'error',
|
||||
'vue/no-custom-modifiers-on-v-model': 'error',
|
||||
'vue/no-dupe-keys': 'error',
|
||||
'vue/no-dupe-v-else-if': 'error',
|
||||
'vue/no-duplicate-attributes': 'error',
|
||||
'vue/no-export-in-script-setup': 'error',
|
||||
'vue/no-multiple-template-root': 'error',
|
||||
'vue/no-mutating-props': 'error',
|
||||
'vue/no-parsing-error': 'error',
|
||||
'vue/no-ref-as-operand': 'error',
|
||||
'vue/no-reserved-component-names': 'error',
|
||||
'vue/no-reserved-keys': 'error',
|
||||
'vue/no-reserved-props': [
|
||||
'error',
|
||||
{
|
||||
vueVersion: 2
|
||||
}
|
||||
],
|
||||
'vue/no-shared-component-data': 'error',
|
||||
'vue/no-side-effects-in-computed-properties': 'error',
|
||||
'vue/no-template-key': 'error',
|
||||
'vue/no-textarea-mustache': 'error',
|
||||
'vue/no-unused-components': 'error',
|
||||
'vue/no-unused-vars': 'error',
|
||||
'vue/no-use-computed-property-like-method': 'error',
|
||||
'vue/no-use-v-if-with-v-for': 'error',
|
||||
'vue/no-useless-template-attributes': 'error',
|
||||
'vue/no-v-for-template-key': 'error',
|
||||
'vue/no-v-model-argument': 'error',
|
||||
'vue/no-v-text-v-html-on-component': 'error',
|
||||
'vue/require-component-is': 'error',
|
||||
'vue/require-prop-type-constructor': 'error',
|
||||
'vue/require-render-return': 'error',
|
||||
'vue/require-v-for-key': 'error',
|
||||
'vue/require-valid-default-prop': 'error',
|
||||
'vue/return-in-computed-property': 'error',
|
||||
'vue/return-in-emits-validator': 'error',
|
||||
'vue/use-v-on-exact': 'error',
|
||||
'vue/valid-attribute-name': 'error',
|
||||
'vue/valid-define-emits': 'error',
|
||||
'vue/valid-define-props': 'error',
|
||||
'vue/valid-model-definition': 'error',
|
||||
'vue/valid-next-tick': 'error',
|
||||
'vue/valid-template-root': 'error',
|
||||
'vue/valid-v-bind-sync': 'error',
|
||||
'vue/valid-v-bind': 'error',
|
||||
'vue/valid-v-cloak': 'error',
|
||||
'vue/valid-v-else-if': 'error',
|
||||
'vue/valid-v-else': 'error',
|
||||
'vue/valid-v-for': 'error',
|
||||
'vue/valid-v-html': 'error',
|
||||
'vue/valid-v-if': 'error',
|
||||
'vue/valid-v-model': 'error',
|
||||
'vue/valid-v-on': 'error',
|
||||
'vue/valid-v-once': 'error',
|
||||
'vue/valid-v-pre': 'error',
|
||||
'vue/valid-v-show': 'error',
|
||||
'vue/valid-v-slot': 'error',
|
||||
'vue/valid-v-text': 'error'
|
||||
}
|
||||
}
|
18
slider/node_modules/eslint-plugin-vue/lib/configs/vue2-recommended.js
generated
vendored
Normal file
18
slider/node_modules/eslint-plugin-vue/lib/configs/vue2-recommended.js
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* IMPORTANT!
|
||||
* This file has been automatically generated,
|
||||
* in order to update its content execute "npm run update"
|
||||
*/
|
||||
module.exports = {
|
||||
extends: require.resolve('./vue2-strongly-recommended'),
|
||||
rules: {
|
||||
'vue/attributes-order': 'warn',
|
||||
'vue/block-order': 'warn',
|
||||
'vue/no-lone-template': 'warn',
|
||||
'vue/no-multiple-slot-args': 'warn',
|
||||
'vue/no-required-prop-with-default': 'warn',
|
||||
'vue/no-v-html': 'warn',
|
||||
'vue/order-in-components': 'warn',
|
||||
'vue/this-in-template': 'warn'
|
||||
}
|
||||
}
|
33
slider/node_modules/eslint-plugin-vue/lib/configs/vue2-strongly-recommended.js
generated
vendored
Normal file
33
slider/node_modules/eslint-plugin-vue/lib/configs/vue2-strongly-recommended.js
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* IMPORTANT!
|
||||
* This file has been automatically generated,
|
||||
* in order to update its content execute "npm run update"
|
||||
*/
|
||||
module.exports = {
|
||||
extends: require.resolve('./vue2-essential'),
|
||||
rules: {
|
||||
'vue/attribute-hyphenation': 'warn',
|
||||
'vue/component-definition-name-casing': 'warn',
|
||||
'vue/first-attribute-linebreak': 'warn',
|
||||
'vue/html-closing-bracket-newline': 'warn',
|
||||
'vue/html-closing-bracket-spacing': 'warn',
|
||||
'vue/html-end-tags': 'warn',
|
||||
'vue/html-indent': 'warn',
|
||||
'vue/html-quotes': 'warn',
|
||||
'vue/html-self-closing': 'warn',
|
||||
'vue/max-attributes-per-line': 'warn',
|
||||
'vue/multiline-html-element-content-newline': 'warn',
|
||||
'vue/mustache-interpolation-spacing': 'warn',
|
||||
'vue/no-multi-spaces': 'warn',
|
||||
'vue/no-spaces-around-equal-signs-in-attribute': 'warn',
|
||||
'vue/no-template-shadow': 'warn',
|
||||
'vue/one-component-per-file': 'warn',
|
||||
'vue/prop-name-casing': 'warn',
|
||||
'vue/require-default-prop': 'warn',
|
||||
'vue/require-prop-types': 'warn',
|
||||
'vue/singleline-html-element-content-newline': 'warn',
|
||||
'vue/v-bind-style': 'warn',
|
||||
'vue/v-on-style': 'warn',
|
||||
'vue/v-slot-style': 'warn'
|
||||
}
|
||||
}
|
93
slider/node_modules/eslint-plugin-vue/lib/configs/vue3-essential.js
generated
vendored
Normal file
93
slider/node_modules/eslint-plugin-vue/lib/configs/vue3-essential.js
generated
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* IMPORTANT!
|
||||
* This file has been automatically generated,
|
||||
* in order to update its content execute "npm run update"
|
||||
*/
|
||||
module.exports = {
|
||||
extends: require.resolve('./base'),
|
||||
rules: {
|
||||
'vue/multi-word-component-names': 'error',
|
||||
'vue/no-arrow-functions-in-watch': 'error',
|
||||
'vue/no-async-in-computed-properties': 'error',
|
||||
'vue/no-child-content': 'error',
|
||||
'vue/no-computed-properties-in-data': 'error',
|
||||
'vue/no-deprecated-data-object-declaration': 'error',
|
||||
'vue/no-deprecated-delete-set': 'error',
|
||||
'vue/no-deprecated-destroyed-lifecycle': 'error',
|
||||
'vue/no-deprecated-dollar-listeners-api': 'error',
|
||||
'vue/no-deprecated-dollar-scopedslots-api': 'error',
|
||||
'vue/no-deprecated-events-api': 'error',
|
||||
'vue/no-deprecated-filter': 'error',
|
||||
'vue/no-deprecated-functional-template': 'error',
|
||||
'vue/no-deprecated-html-element-is': 'error',
|
||||
'vue/no-deprecated-inline-template': 'error',
|
||||
'vue/no-deprecated-model-definition': 'error',
|
||||
'vue/no-deprecated-props-default-this': 'error',
|
||||
'vue/no-deprecated-router-link-tag-prop': 'error',
|
||||
'vue/no-deprecated-scope-attribute': 'error',
|
||||
'vue/no-deprecated-slot-attribute': 'error',
|
||||
'vue/no-deprecated-slot-scope-attribute': 'error',
|
||||
'vue/no-deprecated-v-bind-sync': 'error',
|
||||
'vue/no-deprecated-v-is': 'error',
|
||||
'vue/no-deprecated-v-on-native-modifier': 'error',
|
||||
'vue/no-deprecated-v-on-number-modifiers': 'error',
|
||||
'vue/no-deprecated-vue-config-keycodes': 'error',
|
||||
'vue/no-dupe-keys': 'error',
|
||||
'vue/no-dupe-v-else-if': 'error',
|
||||
'vue/no-duplicate-attributes': 'error',
|
||||
'vue/no-export-in-script-setup': 'error',
|
||||
'vue/no-expose-after-await': 'error',
|
||||
'vue/no-lifecycle-after-await': 'error',
|
||||
'vue/no-mutating-props': 'error',
|
||||
'vue/no-parsing-error': 'error',
|
||||
'vue/no-ref-as-operand': 'error',
|
||||
'vue/no-reserved-component-names': 'error',
|
||||
'vue/no-reserved-keys': 'error',
|
||||
'vue/no-reserved-props': 'error',
|
||||
'vue/no-shared-component-data': 'error',
|
||||
'vue/no-side-effects-in-computed-properties': 'error',
|
||||
'vue/no-template-key': 'error',
|
||||
'vue/no-textarea-mustache': 'error',
|
||||
'vue/no-unused-components': 'error',
|
||||
'vue/no-unused-vars': 'error',
|
||||
'vue/no-use-computed-property-like-method': 'error',
|
||||
'vue/no-use-v-if-with-v-for': 'error',
|
||||
'vue/no-useless-template-attributes': 'error',
|
||||
'vue/no-v-for-template-key-on-child': 'error',
|
||||
'vue/no-v-text-v-html-on-component': 'error',
|
||||
'vue/no-watch-after-await': 'error',
|
||||
'vue/prefer-import-from-vue': 'error',
|
||||
'vue/require-component-is': 'error',
|
||||
'vue/require-prop-type-constructor': 'error',
|
||||
'vue/require-render-return': 'error',
|
||||
'vue/require-slots-as-functions': 'error',
|
||||
'vue/require-toggle-inside-transition': 'error',
|
||||
'vue/require-v-for-key': 'error',
|
||||
'vue/require-valid-default-prop': 'error',
|
||||
'vue/return-in-computed-property': 'error',
|
||||
'vue/return-in-emits-validator': 'error',
|
||||
'vue/use-v-on-exact': 'error',
|
||||
'vue/valid-attribute-name': 'error',
|
||||
'vue/valid-define-emits': 'error',
|
||||
'vue/valid-define-options': 'error',
|
||||
'vue/valid-define-props': 'error',
|
||||
'vue/valid-next-tick': 'error',
|
||||
'vue/valid-template-root': 'error',
|
||||
'vue/valid-v-bind': 'error',
|
||||
'vue/valid-v-cloak': 'error',
|
||||
'vue/valid-v-else-if': 'error',
|
||||
'vue/valid-v-else': 'error',
|
||||
'vue/valid-v-for': 'error',
|
||||
'vue/valid-v-html': 'error',
|
||||
'vue/valid-v-if': 'error',
|
||||
'vue/valid-v-is': 'error',
|
||||
'vue/valid-v-memo': 'error',
|
||||
'vue/valid-v-model': 'error',
|
||||
'vue/valid-v-on': 'error',
|
||||
'vue/valid-v-once': 'error',
|
||||
'vue/valid-v-pre': 'error',
|
||||
'vue/valid-v-show': 'error',
|
||||
'vue/valid-v-slot': 'error',
|
||||
'vue/valid-v-text': 'error'
|
||||
}
|
||||
}
|
18
slider/node_modules/eslint-plugin-vue/lib/configs/vue3-recommended.js
generated
vendored
Normal file
18
slider/node_modules/eslint-plugin-vue/lib/configs/vue3-recommended.js
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* IMPORTANT!
|
||||
* This file has been automatically generated,
|
||||
* in order to update its content execute "npm run update"
|
||||
*/
|
||||
module.exports = {
|
||||
extends: require.resolve('./vue3-strongly-recommended'),
|
||||
rules: {
|
||||
'vue/attributes-order': 'warn',
|
||||
'vue/block-order': 'warn',
|
||||
'vue/no-lone-template': 'warn',
|
||||
'vue/no-multiple-slot-args': 'warn',
|
||||
'vue/no-required-prop-with-default': 'warn',
|
||||
'vue/no-v-html': 'warn',
|
||||
'vue/order-in-components': 'warn',
|
||||
'vue/this-in-template': 'warn'
|
||||
}
|
||||
}
|
41
slider/node_modules/eslint-plugin-vue/lib/configs/vue3-strongly-recommended.js
generated
vendored
Normal file
41
slider/node_modules/eslint-plugin-vue/lib/configs/vue3-strongly-recommended.js
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* IMPORTANT!
|
||||
* This file has been automatically generated,
|
||||
* in order to update its content execute "npm run update"
|
||||
*/
|
||||
module.exports = {
|
||||
extends: require.resolve('./vue3-essential'),
|
||||
rules: {
|
||||
'vue/attribute-hyphenation': 'warn',
|
||||
'vue/component-definition-name-casing': 'warn',
|
||||
'vue/first-attribute-linebreak': 'warn',
|
||||
'vue/html-closing-bracket-newline': 'warn',
|
||||
'vue/html-closing-bracket-spacing': 'warn',
|
||||
'vue/html-end-tags': 'warn',
|
||||
'vue/html-indent': 'warn',
|
||||
'vue/html-quotes': 'warn',
|
||||
'vue/html-self-closing': 'warn',
|
||||
'vue/max-attributes-per-line': 'warn',
|
||||
'vue/multiline-html-element-content-newline': 'warn',
|
||||
'vue/mustache-interpolation-spacing': 'warn',
|
||||
'vue/no-multi-spaces': 'warn',
|
||||
'vue/no-spaces-around-equal-signs-in-attribute': 'warn',
|
||||
'vue/no-template-shadow': 'warn',
|
||||
'vue/one-component-per-file': 'warn',
|
||||
'vue/prop-name-casing': 'warn',
|
||||
'vue/require-default-prop': 'warn',
|
||||
'vue/require-explicit-emits': 'warn',
|
||||
'vue/require-prop-types': 'warn',
|
||||
'vue/singleline-html-element-content-newline': 'warn',
|
||||
'vue/v-bind-style': 'warn',
|
||||
'vue/v-on-event-hyphenation': [
|
||||
'warn',
|
||||
'always',
|
||||
{
|
||||
autofix: true
|
||||
}
|
||||
],
|
||||
'vue/v-on-style': 'warn',
|
||||
'vue/v-slot-style': 'warn'
|
||||
}
|
||||
}
|
2512
slider/node_modules/eslint-plugin-vue/lib/eslint-typegen.d.ts
generated
vendored
Normal file
2512
slider/node_modules/eslint-plugin-vue/lib/eslint-typegen.d.ts
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
36
slider/node_modules/eslint-plugin-vue/lib/index.d.ts
generated
vendored
Normal file
36
slider/node_modules/eslint-plugin-vue/lib/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
/// <reference path="./eslint-typegen.d.ts" />
|
||||
import type { Linter } from 'eslint'
|
||||
|
||||
declare const vue: {
|
||||
meta: any
|
||||
configs: {
|
||||
base: Linter.LegacyConfig
|
||||
|
||||
'vue2-essential': Linter.LegacyConfig
|
||||
'vue2-strongly-recommended': Linter.LegacyConfig
|
||||
'vue2-recommended': Linter.LegacyConfig
|
||||
|
||||
essential: Linter.LegacyConfig
|
||||
'strongly-recommended': Linter.LegacyConfig
|
||||
recommended: Linter.LegacyConfig
|
||||
|
||||
'flat/base': Linter.FlatConfig[]
|
||||
|
||||
'flat/vue2-essential': Linter.FlatConfig[]
|
||||
'flat/vue2-strongly-recommended': Linter.FlatConfig[]
|
||||
'flat/vue2-recommended': Linter.FlatConfig[]
|
||||
|
||||
'flat/essential': Linter.FlatConfig[]
|
||||
'flat/strongly-recommended': Linter.FlatConfig[]
|
||||
'flat/recommended': Linter.FlatConfig[]
|
||||
|
||||
'no-layout-rules': Linter.LegacyConfig
|
||||
}
|
||||
rules: Record<string, any>
|
||||
processors: {
|
||||
'.vue': any
|
||||
vue: any
|
||||
}
|
||||
}
|
||||
|
||||
export = vue
|
291
slider/node_modules/eslint-plugin-vue/lib/index.js
generated
vendored
Normal file
291
slider/node_modules/eslint-plugin-vue/lib/index.js
generated
vendored
Normal file
@@ -0,0 +1,291 @@
|
||||
/*
|
||||
* IMPORTANT!
|
||||
* This file has been automatically generated,
|
||||
* in order to update its content execute "npm run update"
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const plugin = {
|
||||
meta: require('./meta'),
|
||||
configs: {
|
||||
// eslintrc configs
|
||||
base: require('./configs/base'),
|
||||
|
||||
'vue2-essential': require('./configs/vue2-essential'),
|
||||
'vue2-strongly-recommended': require('./configs/vue2-strongly-recommended'),
|
||||
'vue2-recommended': require('./configs/vue2-recommended'),
|
||||
|
||||
essential: require('./configs/vue3-essential'),
|
||||
'strongly-recommended': require('./configs/vue3-strongly-recommended'),
|
||||
recommended: require('./configs/vue3-recommended'),
|
||||
|
||||
// flat configs
|
||||
'flat/base': require('./configs/flat/base.js'),
|
||||
|
||||
'flat/vue2-essential': require('./configs/flat/vue2-essential.js'),
|
||||
'flat/vue2-strongly-recommended': require('./configs/flat/vue2-strongly-recommended.js'),
|
||||
'flat/vue2-recommended': require('./configs/flat/vue2-recommended.js'),
|
||||
|
||||
'flat/essential': require('./configs/flat/vue3-essential.js'),
|
||||
'flat/strongly-recommended': require('./configs/flat/vue3-strongly-recommended.js'),
|
||||
'flat/recommended': require('./configs/flat/vue3-recommended.js'),
|
||||
|
||||
// config-format-agnostic configs
|
||||
'no-layout-rules': require('./configs/no-layout-rules')
|
||||
},
|
||||
rules: {
|
||||
'array-bracket-newline': require('./rules/array-bracket-newline'),
|
||||
'array-bracket-spacing': require('./rules/array-bracket-spacing'),
|
||||
'array-element-newline': require('./rules/array-element-newline'),
|
||||
'arrow-spacing': require('./rules/arrow-spacing'),
|
||||
'attribute-hyphenation': require('./rules/attribute-hyphenation'),
|
||||
'attributes-order': require('./rules/attributes-order'),
|
||||
'block-lang': require('./rules/block-lang'),
|
||||
'block-order': require('./rules/block-order'),
|
||||
'block-spacing': require('./rules/block-spacing'),
|
||||
'block-tag-newline': require('./rules/block-tag-newline'),
|
||||
'brace-style': require('./rules/brace-style'),
|
||||
camelcase: require('./rules/camelcase'),
|
||||
'comma-dangle': require('./rules/comma-dangle'),
|
||||
'comma-spacing': require('./rules/comma-spacing'),
|
||||
'comma-style': require('./rules/comma-style'),
|
||||
'comment-directive': require('./rules/comment-directive'),
|
||||
'component-api-style': require('./rules/component-api-style'),
|
||||
'component-definition-name-casing': require('./rules/component-definition-name-casing'),
|
||||
'component-name-in-template-casing': require('./rules/component-name-in-template-casing'),
|
||||
'component-options-name-casing': require('./rules/component-options-name-casing'),
|
||||
'custom-event-name-casing': require('./rules/custom-event-name-casing'),
|
||||
'define-emits-declaration': require('./rules/define-emits-declaration'),
|
||||
'define-macros-order': require('./rules/define-macros-order'),
|
||||
'define-props-declaration': require('./rules/define-props-declaration'),
|
||||
'define-props-destructuring': require('./rules/define-props-destructuring'),
|
||||
'dot-location': require('./rules/dot-location'),
|
||||
'dot-notation': require('./rules/dot-notation'),
|
||||
'enforce-style-attribute': require('./rules/enforce-style-attribute'),
|
||||
eqeqeq: require('./rules/eqeqeq'),
|
||||
'first-attribute-linebreak': require('./rules/first-attribute-linebreak'),
|
||||
'func-call-spacing': require('./rules/func-call-spacing'),
|
||||
'html-button-has-type': require('./rules/html-button-has-type'),
|
||||
'html-closing-bracket-newline': require('./rules/html-closing-bracket-newline'),
|
||||
'html-closing-bracket-spacing': require('./rules/html-closing-bracket-spacing'),
|
||||
'html-comment-content-newline': require('./rules/html-comment-content-newline'),
|
||||
'html-comment-content-spacing': require('./rules/html-comment-content-spacing'),
|
||||
'html-comment-indent': require('./rules/html-comment-indent'),
|
||||
'html-end-tags': require('./rules/html-end-tags'),
|
||||
'html-indent': require('./rules/html-indent'),
|
||||
'html-quotes': require('./rules/html-quotes'),
|
||||
'html-self-closing': require('./rules/html-self-closing'),
|
||||
'jsx-uses-vars': require('./rules/jsx-uses-vars'),
|
||||
'key-spacing': require('./rules/key-spacing'),
|
||||
'keyword-spacing': require('./rules/keyword-spacing'),
|
||||
'match-component-file-name': require('./rules/match-component-file-name'),
|
||||
'match-component-import-name': require('./rules/match-component-import-name'),
|
||||
'max-attributes-per-line': require('./rules/max-attributes-per-line'),
|
||||
'max-len': require('./rules/max-len'),
|
||||
'max-lines-per-block': require('./rules/max-lines-per-block'),
|
||||
'max-props': require('./rules/max-props'),
|
||||
'max-template-depth': require('./rules/max-template-depth'),
|
||||
'multi-word-component-names': require('./rules/multi-word-component-names'),
|
||||
'multiline-html-element-content-newline': require('./rules/multiline-html-element-content-newline'),
|
||||
'multiline-ternary': require('./rules/multiline-ternary'),
|
||||
'mustache-interpolation-spacing': require('./rules/mustache-interpolation-spacing'),
|
||||
'new-line-between-multi-line-property': require('./rules/new-line-between-multi-line-property'),
|
||||
'next-tick-style': require('./rules/next-tick-style'),
|
||||
'no-arrow-functions-in-watch': require('./rules/no-arrow-functions-in-watch'),
|
||||
'no-async-in-computed-properties': require('./rules/no-async-in-computed-properties'),
|
||||
'no-bare-strings-in-template': require('./rules/no-bare-strings-in-template'),
|
||||
'no-boolean-default': require('./rules/no-boolean-default'),
|
||||
'no-child-content': require('./rules/no-child-content'),
|
||||
'no-computed-properties-in-data': require('./rules/no-computed-properties-in-data'),
|
||||
'no-console': require('./rules/no-console'),
|
||||
'no-constant-condition': require('./rules/no-constant-condition'),
|
||||
'no-custom-modifiers-on-v-model': require('./rules/no-custom-modifiers-on-v-model'),
|
||||
'no-deprecated-data-object-declaration': require('./rules/no-deprecated-data-object-declaration'),
|
||||
'no-deprecated-delete-set': require('./rules/no-deprecated-delete-set'),
|
||||
'no-deprecated-destroyed-lifecycle': require('./rules/no-deprecated-destroyed-lifecycle'),
|
||||
'no-deprecated-dollar-listeners-api': require('./rules/no-deprecated-dollar-listeners-api'),
|
||||
'no-deprecated-dollar-scopedslots-api': require('./rules/no-deprecated-dollar-scopedslots-api'),
|
||||
'no-deprecated-events-api': require('./rules/no-deprecated-events-api'),
|
||||
'no-deprecated-filter': require('./rules/no-deprecated-filter'),
|
||||
'no-deprecated-functional-template': require('./rules/no-deprecated-functional-template'),
|
||||
'no-deprecated-html-element-is': require('./rules/no-deprecated-html-element-is'),
|
||||
'no-deprecated-inline-template': require('./rules/no-deprecated-inline-template'),
|
||||
'no-deprecated-model-definition': require('./rules/no-deprecated-model-definition'),
|
||||
'no-deprecated-props-default-this': require('./rules/no-deprecated-props-default-this'),
|
||||
'no-deprecated-router-link-tag-prop': require('./rules/no-deprecated-router-link-tag-prop'),
|
||||
'no-deprecated-scope-attribute': require('./rules/no-deprecated-scope-attribute'),
|
||||
'no-deprecated-slot-attribute': require('./rules/no-deprecated-slot-attribute'),
|
||||
'no-deprecated-slot-scope-attribute': require('./rules/no-deprecated-slot-scope-attribute'),
|
||||
'no-deprecated-v-bind-sync': require('./rules/no-deprecated-v-bind-sync'),
|
||||
'no-deprecated-v-is': require('./rules/no-deprecated-v-is'),
|
||||
'no-deprecated-v-on-native-modifier': require('./rules/no-deprecated-v-on-native-modifier'),
|
||||
'no-deprecated-v-on-number-modifiers': require('./rules/no-deprecated-v-on-number-modifiers'),
|
||||
'no-deprecated-vue-config-keycodes': require('./rules/no-deprecated-vue-config-keycodes'),
|
||||
'no-dupe-keys': require('./rules/no-dupe-keys'),
|
||||
'no-dupe-v-else-if': require('./rules/no-dupe-v-else-if'),
|
||||
'no-duplicate-attr-inheritance': require('./rules/no-duplicate-attr-inheritance'),
|
||||
'no-duplicate-attributes': require('./rules/no-duplicate-attributes'),
|
||||
'no-empty-component-block': require('./rules/no-empty-component-block'),
|
||||
'no-empty-pattern': require('./rules/no-empty-pattern'),
|
||||
'no-export-in-script-setup': require('./rules/no-export-in-script-setup'),
|
||||
'no-expose-after-await': require('./rules/no-expose-after-await'),
|
||||
'no-extra-parens': require('./rules/no-extra-parens'),
|
||||
'no-implicit-coercion': require('./rules/no-implicit-coercion'),
|
||||
'no-import-compiler-macros': require('./rules/no-import-compiler-macros'),
|
||||
'no-irregular-whitespace': require('./rules/no-irregular-whitespace'),
|
||||
'no-lifecycle-after-await': require('./rules/no-lifecycle-after-await'),
|
||||
'no-lone-template': require('./rules/no-lone-template'),
|
||||
'no-loss-of-precision': require('./rules/no-loss-of-precision'),
|
||||
'no-multi-spaces': require('./rules/no-multi-spaces'),
|
||||
'no-multiple-objects-in-class': require('./rules/no-multiple-objects-in-class'),
|
||||
'no-multiple-slot-args': require('./rules/no-multiple-slot-args'),
|
||||
'no-multiple-template-root': require('./rules/no-multiple-template-root'),
|
||||
'no-mutating-props': require('./rules/no-mutating-props'),
|
||||
'no-negated-condition': require('./rules/no-negated-condition'),
|
||||
'no-negated-v-if-condition': require('./rules/no-negated-v-if-condition'),
|
||||
'no-parsing-error': require('./rules/no-parsing-error'),
|
||||
'no-potential-component-option-typo': require('./rules/no-potential-component-option-typo'),
|
||||
'no-ref-as-operand': require('./rules/no-ref-as-operand'),
|
||||
'no-ref-object-reactivity-loss': require('./rules/no-ref-object-reactivity-loss'),
|
||||
'no-required-prop-with-default': require('./rules/no-required-prop-with-default'),
|
||||
'no-reserved-component-names': require('./rules/no-reserved-component-names'),
|
||||
'no-reserved-keys': require('./rules/no-reserved-keys'),
|
||||
'no-reserved-props': require('./rules/no-reserved-props'),
|
||||
'no-restricted-block': require('./rules/no-restricted-block'),
|
||||
'no-restricted-call-after-await': require('./rules/no-restricted-call-after-await'),
|
||||
'no-restricted-class': require('./rules/no-restricted-class'),
|
||||
'no-restricted-component-names': require('./rules/no-restricted-component-names'),
|
||||
'no-restricted-component-options': require('./rules/no-restricted-component-options'),
|
||||
'no-restricted-custom-event': require('./rules/no-restricted-custom-event'),
|
||||
'no-restricted-html-elements': require('./rules/no-restricted-html-elements'),
|
||||
'no-restricted-props': require('./rules/no-restricted-props'),
|
||||
'no-restricted-static-attribute': require('./rules/no-restricted-static-attribute'),
|
||||
'no-restricted-syntax': require('./rules/no-restricted-syntax'),
|
||||
'no-restricted-v-bind': require('./rules/no-restricted-v-bind'),
|
||||
'no-restricted-v-on': require('./rules/no-restricted-v-on'),
|
||||
'no-root-v-if': require('./rules/no-root-v-if'),
|
||||
'no-setup-props-reactivity-loss': require('./rules/no-setup-props-reactivity-loss'),
|
||||
'no-shared-component-data': require('./rules/no-shared-component-data'),
|
||||
'no-side-effects-in-computed-properties': require('./rules/no-side-effects-in-computed-properties'),
|
||||
'no-spaces-around-equal-signs-in-attribute': require('./rules/no-spaces-around-equal-signs-in-attribute'),
|
||||
'no-sparse-arrays': require('./rules/no-sparse-arrays'),
|
||||
'no-static-inline-styles': require('./rules/no-static-inline-styles'),
|
||||
'no-template-key': require('./rules/no-template-key'),
|
||||
'no-template-shadow': require('./rules/no-template-shadow'),
|
||||
'no-template-target-blank': require('./rules/no-template-target-blank'),
|
||||
'no-textarea-mustache': require('./rules/no-textarea-mustache'),
|
||||
'no-this-in-before-route-enter': require('./rules/no-this-in-before-route-enter'),
|
||||
'no-undef-components': require('./rules/no-undef-components'),
|
||||
'no-undef-properties': require('./rules/no-undef-properties'),
|
||||
'no-unsupported-features': require('./rules/no-unsupported-features'),
|
||||
'no-unused-components': require('./rules/no-unused-components'),
|
||||
'no-unused-emit-declarations': require('./rules/no-unused-emit-declarations'),
|
||||
'no-unused-properties': require('./rules/no-unused-properties'),
|
||||
'no-unused-refs': require('./rules/no-unused-refs'),
|
||||
'no-unused-vars': require('./rules/no-unused-vars'),
|
||||
'no-use-computed-property-like-method': require('./rules/no-use-computed-property-like-method'),
|
||||
'no-use-v-else-with-v-for': require('./rules/no-use-v-else-with-v-for'),
|
||||
'no-use-v-if-with-v-for': require('./rules/no-use-v-if-with-v-for'),
|
||||
'no-useless-concat': require('./rules/no-useless-concat'),
|
||||
'no-useless-mustaches': require('./rules/no-useless-mustaches'),
|
||||
'no-useless-template-attributes': require('./rules/no-useless-template-attributes'),
|
||||
'no-useless-v-bind': require('./rules/no-useless-v-bind'),
|
||||
'no-v-for-template-key-on-child': require('./rules/no-v-for-template-key-on-child'),
|
||||
'no-v-for-template-key': require('./rules/no-v-for-template-key'),
|
||||
'no-v-html': require('./rules/no-v-html'),
|
||||
'no-v-model-argument': require('./rules/no-v-model-argument'),
|
||||
'no-v-text-v-html-on-component': require('./rules/no-v-text-v-html-on-component'),
|
||||
'no-v-text': require('./rules/no-v-text'),
|
||||
'no-watch-after-await': require('./rules/no-watch-after-await'),
|
||||
'object-curly-newline': require('./rules/object-curly-newline'),
|
||||
'object-curly-spacing': require('./rules/object-curly-spacing'),
|
||||
'object-property-newline': require('./rules/object-property-newline'),
|
||||
'object-shorthand': require('./rules/object-shorthand'),
|
||||
'one-component-per-file': require('./rules/one-component-per-file'),
|
||||
'operator-linebreak': require('./rules/operator-linebreak'),
|
||||
'order-in-components': require('./rules/order-in-components'),
|
||||
'padding-line-between-blocks': require('./rules/padding-line-between-blocks'),
|
||||
'padding-line-between-tags': require('./rules/padding-line-between-tags'),
|
||||
'padding-lines-in-component-definition': require('./rules/padding-lines-in-component-definition'),
|
||||
'prefer-define-options': require('./rules/prefer-define-options'),
|
||||
'prefer-import-from-vue': require('./rules/prefer-import-from-vue'),
|
||||
'prefer-prop-type-boolean-first': require('./rules/prefer-prop-type-boolean-first'),
|
||||
'prefer-separate-static-class': require('./rules/prefer-separate-static-class'),
|
||||
'prefer-template': require('./rules/prefer-template'),
|
||||
'prefer-true-attribute-shorthand': require('./rules/prefer-true-attribute-shorthand'),
|
||||
'prefer-use-template-ref': require('./rules/prefer-use-template-ref'),
|
||||
'prop-name-casing': require('./rules/prop-name-casing'),
|
||||
'quote-props': require('./rules/quote-props'),
|
||||
'require-component-is': require('./rules/require-component-is'),
|
||||
'require-default-export': require('./rules/require-default-export'),
|
||||
'require-default-prop': require('./rules/require-default-prop'),
|
||||
'require-direct-export': require('./rules/require-direct-export'),
|
||||
'require-emit-validator': require('./rules/require-emit-validator'),
|
||||
'require-explicit-emits': require('./rules/require-explicit-emits'),
|
||||
'require-explicit-slots': require('./rules/require-explicit-slots'),
|
||||
'require-expose': require('./rules/require-expose'),
|
||||
'require-macro-variable-name': require('./rules/require-macro-variable-name'),
|
||||
'require-name-property': require('./rules/require-name-property'),
|
||||
'require-prop-comment': require('./rules/require-prop-comment'),
|
||||
'require-prop-type-constructor': require('./rules/require-prop-type-constructor'),
|
||||
'require-prop-types': require('./rules/require-prop-types'),
|
||||
'require-render-return': require('./rules/require-render-return'),
|
||||
'require-slots-as-functions': require('./rules/require-slots-as-functions'),
|
||||
'require-toggle-inside-transition': require('./rules/require-toggle-inside-transition'),
|
||||
'require-typed-object-prop': require('./rules/require-typed-object-prop'),
|
||||
'require-typed-ref': require('./rules/require-typed-ref'),
|
||||
'require-v-for-key': require('./rules/require-v-for-key'),
|
||||
'require-valid-default-prop': require('./rules/require-valid-default-prop'),
|
||||
'restricted-component-names': require('./rules/restricted-component-names'),
|
||||
'return-in-computed-property': require('./rules/return-in-computed-property'),
|
||||
'return-in-emits-validator': require('./rules/return-in-emits-validator'),
|
||||
'script-indent': require('./rules/script-indent'),
|
||||
'singleline-html-element-content-newline': require('./rules/singleline-html-element-content-newline'),
|
||||
'slot-name-casing': require('./rules/slot-name-casing'),
|
||||
'sort-keys': require('./rules/sort-keys'),
|
||||
'space-in-parens': require('./rules/space-in-parens'),
|
||||
'space-infix-ops': require('./rules/space-infix-ops'),
|
||||
'space-unary-ops': require('./rules/space-unary-ops'),
|
||||
'static-class-names-order': require('./rules/static-class-names-order'),
|
||||
'template-curly-spacing': require('./rules/template-curly-spacing'),
|
||||
'this-in-template': require('./rules/this-in-template'),
|
||||
'use-v-on-exact': require('./rules/use-v-on-exact'),
|
||||
'v-bind-style': require('./rules/v-bind-style'),
|
||||
'v-for-delimiter-style': require('./rules/v-for-delimiter-style'),
|
||||
'v-if-else-key': require('./rules/v-if-else-key'),
|
||||
'v-on-event-hyphenation': require('./rules/v-on-event-hyphenation'),
|
||||
'v-on-handler-style': require('./rules/v-on-handler-style'),
|
||||
'v-on-style': require('./rules/v-on-style'),
|
||||
'v-slot-style': require('./rules/v-slot-style'),
|
||||
'valid-attribute-name': require('./rules/valid-attribute-name'),
|
||||
'valid-define-emits': require('./rules/valid-define-emits'),
|
||||
'valid-define-options': require('./rules/valid-define-options'),
|
||||
'valid-define-props': require('./rules/valid-define-props'),
|
||||
'valid-model-definition': require('./rules/valid-model-definition'),
|
||||
'valid-next-tick': require('./rules/valid-next-tick'),
|
||||
'valid-template-root': require('./rules/valid-template-root'),
|
||||
'valid-v-bind-sync': require('./rules/valid-v-bind-sync'),
|
||||
'valid-v-bind': require('./rules/valid-v-bind'),
|
||||
'valid-v-cloak': require('./rules/valid-v-cloak'),
|
||||
'valid-v-else-if': require('./rules/valid-v-else-if'),
|
||||
'valid-v-else': require('./rules/valid-v-else'),
|
||||
'valid-v-for': require('./rules/valid-v-for'),
|
||||
'valid-v-html': require('./rules/valid-v-html'),
|
||||
'valid-v-if': require('./rules/valid-v-if'),
|
||||
'valid-v-is': require('./rules/valid-v-is'),
|
||||
'valid-v-memo': require('./rules/valid-v-memo'),
|
||||
'valid-v-model': require('./rules/valid-v-model'),
|
||||
'valid-v-on': require('./rules/valid-v-on'),
|
||||
'valid-v-once': require('./rules/valid-v-once'),
|
||||
'valid-v-pre': require('./rules/valid-v-pre'),
|
||||
'valid-v-show': require('./rules/valid-v-show'),
|
||||
'valid-v-slot': require('./rules/valid-v-slot'),
|
||||
'valid-v-text': require('./rules/valid-v-text')
|
||||
},
|
||||
processors: {
|
||||
'.vue': require('./processor'),
|
||||
vue: require('./processor')
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = plugin
|
3
slider/node_modules/eslint-plugin-vue/lib/meta.js
generated
vendored
Normal file
3
slider/node_modules/eslint-plugin-vue/lib/meta.js
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
'use strict'
|
||||
const { name, version } = require('../package.json')
|
||||
module.exports = { name, version }
|
177
slider/node_modules/eslint-plugin-vue/lib/processor.js
generated
vendored
Normal file
177
slider/node_modules/eslint-plugin-vue/lib/processor.js
generated
vendored
Normal file
@@ -0,0 +1,177 @@
|
||||
/**
|
||||
* @author Toru Nagashima <https://github.com/mysticatea>
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* @typedef {import('eslint').Linter.LintMessage} LintMessage
|
||||
*/
|
||||
/**
|
||||
* @typedef {object} GroupState
|
||||
* @property {Set<string>} GroupState.disableAllKeys
|
||||
* @property {Map<string, string[]>} GroupState.disableRuleKeys
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
/** @param {string} code */
|
||||
preprocess(code) {
|
||||
return [code]
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {LintMessage[][]} messages
|
||||
* @returns {LintMessage[]}
|
||||
*/
|
||||
postprocess(messages) {
|
||||
const state = {
|
||||
/** @type {GroupState} */
|
||||
block: {
|
||||
disableAllKeys: new Set(),
|
||||
disableRuleKeys: new Map()
|
||||
},
|
||||
/** @type {GroupState} */
|
||||
line: {
|
||||
disableAllKeys: new Set(),
|
||||
disableRuleKeys: new Map()
|
||||
}
|
||||
}
|
||||
/** @type {string[]} */
|
||||
const usedDisableDirectiveKeys = []
|
||||
/** @type {Map<string,LintMessage>} */
|
||||
const unusedDisableDirectiveReports = new Map()
|
||||
|
||||
// Filter messages which are in disabled area.
|
||||
const filteredMessages = messages[0].filter((message) => {
|
||||
if (message.ruleId === 'vue/comment-directive') {
|
||||
const directiveType = message.messageId
|
||||
const data = message.message.split(' ')
|
||||
switch (directiveType) {
|
||||
case 'disableBlock': {
|
||||
state.block.disableAllKeys.add(data[1])
|
||||
break
|
||||
}
|
||||
case 'disableLine': {
|
||||
state.line.disableAllKeys.add(data[1])
|
||||
break
|
||||
}
|
||||
case 'enableBlock': {
|
||||
state.block.disableAllKeys.clear()
|
||||
break
|
||||
}
|
||||
case 'enableLine': {
|
||||
state.line.disableAllKeys.clear()
|
||||
break
|
||||
}
|
||||
case 'disableBlockRule': {
|
||||
addDisableRule(state.block.disableRuleKeys, data[1], data[2])
|
||||
break
|
||||
}
|
||||
case 'disableLineRule': {
|
||||
addDisableRule(state.line.disableRuleKeys, data[1], data[2])
|
||||
break
|
||||
}
|
||||
case 'enableBlockRule': {
|
||||
state.block.disableRuleKeys.delete(data[1])
|
||||
break
|
||||
}
|
||||
case 'enableLineRule': {
|
||||
state.line.disableRuleKeys.delete(data[1])
|
||||
break
|
||||
}
|
||||
case 'clear': {
|
||||
state.block.disableAllKeys.clear()
|
||||
state.block.disableRuleKeys.clear()
|
||||
state.line.disableAllKeys.clear()
|
||||
state.line.disableRuleKeys.clear()
|
||||
break
|
||||
}
|
||||
default: {
|
||||
// unused eslint-disable comments report
|
||||
unusedDisableDirectiveReports.set(messageToKey(message), message)
|
||||
break
|
||||
}
|
||||
}
|
||||
return false
|
||||
} else {
|
||||
const disableDirectiveKeys = []
|
||||
if (state.block.disableAllKeys.size > 0) {
|
||||
disableDirectiveKeys.push(...state.block.disableAllKeys)
|
||||
}
|
||||
if (state.line.disableAllKeys.size > 0) {
|
||||
disableDirectiveKeys.push(...state.line.disableAllKeys)
|
||||
}
|
||||
if (message.ruleId) {
|
||||
const block = state.block.disableRuleKeys.get(message.ruleId)
|
||||
if (block) {
|
||||
disableDirectiveKeys.push(...block)
|
||||
}
|
||||
const line = state.line.disableRuleKeys.get(message.ruleId)
|
||||
if (line) {
|
||||
disableDirectiveKeys.push(...line)
|
||||
}
|
||||
}
|
||||
|
||||
if (disableDirectiveKeys.length > 0) {
|
||||
// Store used eslint-disable comment key
|
||||
usedDisableDirectiveKeys.push(...disableDirectiveKeys)
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
if (unusedDisableDirectiveReports.size > 0) {
|
||||
for (const key of usedDisableDirectiveKeys) {
|
||||
// Remove used eslint-disable comments
|
||||
unusedDisableDirectiveReports.delete(key)
|
||||
}
|
||||
// Reports unused eslint-disable comments
|
||||
filteredMessages.push(...unusedDisableDirectiveReports.values())
|
||||
filteredMessages.sort(compareLocations)
|
||||
}
|
||||
|
||||
return filteredMessages
|
||||
},
|
||||
|
||||
supportsAutofix: true,
|
||||
|
||||
meta: require('./meta')
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Map<string, string[]>} disableRuleKeys
|
||||
* @param {string} rule
|
||||
* @param {string} key
|
||||
*/
|
||||
function addDisableRule(disableRuleKeys, rule, key) {
|
||||
let keys = disableRuleKeys.get(rule)
|
||||
if (keys) {
|
||||
keys.push(key)
|
||||
} else {
|
||||
keys = [key]
|
||||
disableRuleKeys.set(rule, keys)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {LintMessage} message
|
||||
* @returns {string} message key
|
||||
*/
|
||||
function messageToKey(message) {
|
||||
return `line:${message.line},column${
|
||||
// -1 because +1 by ESLint's `report-translator`.
|
||||
message.column - 1
|
||||
}`
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the locations of two objects in a source file
|
||||
* @param {Position} itemA The first object
|
||||
* @param {Position} itemB The second object
|
||||
* @returns {number} A value less than 1 if itemA appears before itemB in the source file, greater than 1 if
|
||||
* itemA appears after itemB in the source file, or 0 if itemA and itemB have the same location.
|
||||
*/
|
||||
function compareLocations(itemA, itemB) {
|
||||
return itemA.line - itemB.line || itemA.column - itemB.column
|
||||
}
|
73
slider/node_modules/eslint-plugin-vue/lib/removed-rules.js
generated
vendored
Normal file
73
slider/node_modules/eslint-plugin-vue/lib/removed-rules.js
generated
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* @typedef {object} RemovedRule
|
||||
* @property {string} ruleName
|
||||
* @property {string[]} replacedBy
|
||||
* @property {string} deprecatedInVersion
|
||||
* @property {string} removedInVersion
|
||||
*/
|
||||
|
||||
/** @type {RemovedRule[]} */
|
||||
module.exports = [
|
||||
{
|
||||
ruleName: 'component-tags-order',
|
||||
replacedBy: ['block-order'],
|
||||
deprecatedInVersion: 'v9.16.0',
|
||||
removedInVersion: 'v10.0.0'
|
||||
},
|
||||
{
|
||||
ruleName: 'experimental-script-setup-vars',
|
||||
replacedBy: [],
|
||||
deprecatedInVersion: 'v7.13.0',
|
||||
removedInVersion: 'v9.0.0'
|
||||
},
|
||||
{
|
||||
ruleName: 'name-property-casing',
|
||||
replacedBy: ['component-definition-name-casing'],
|
||||
deprecatedInVersion: 'v7.0.0',
|
||||
removedInVersion: 'v9.0.0'
|
||||
},
|
||||
{
|
||||
ruleName: 'no-confusing-v-for-v-if',
|
||||
replacedBy: ['no-use-v-if-with-v-for'],
|
||||
deprecatedInVersion: 'v5.0.0',
|
||||
removedInVersion: 'v9.0.0'
|
||||
},
|
||||
{
|
||||
ruleName: 'no-invalid-model-keys',
|
||||
replacedBy: ['valid-model-definition'],
|
||||
deprecatedInVersion: 'v9.0.0',
|
||||
removedInVersion: 'v10.0.0'
|
||||
},
|
||||
{
|
||||
ruleName: 'no-ref-object-destructure',
|
||||
replacedBy: ['no-ref-object-reactivity-loss'],
|
||||
deprecatedInVersion: 'v9.17.0',
|
||||
removedInVersion: 'v10.0.0'
|
||||
},
|
||||
{
|
||||
ruleName: 'no-setup-props-destructure',
|
||||
replacedBy: ['no-setup-props-reactivity-loss'],
|
||||
deprecatedInVersion: 'v9.17.0',
|
||||
removedInVersion: 'v10.0.0'
|
||||
},
|
||||
{
|
||||
ruleName: 'no-unregistered-components',
|
||||
replacedBy: ['no-undef-components'],
|
||||
deprecatedInVersion: 'v8.4.0',
|
||||
removedInVersion: 'v9.0.0'
|
||||
},
|
||||
{
|
||||
ruleName: 'script-setup-uses-vars',
|
||||
replacedBy: [],
|
||||
deprecatedInVersion: 'v9.0.0',
|
||||
removedInVersion: 'v10.0.0'
|
||||
},
|
||||
{
|
||||
ruleName: 'v-on-function-call',
|
||||
replacedBy: ['v-on-handler-style'],
|
||||
deprecatedInVersion: 'v9.7.0',
|
||||
removedInVersion: 'v10.0.0'
|
||||
}
|
||||
]
|
11
slider/node_modules/eslint-plugin-vue/lib/rules/array-bracket-newline.js
generated
vendored
Normal file
11
slider/node_modules/eslint-plugin-vue/lib/rules/array-bracket-newline.js
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* @author Yosuke Ota
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const { wrapStylisticOrCoreRule } = require('../utils')
|
||||
|
||||
// eslint-disable-next-line internal/no-invalid-meta
|
||||
module.exports = wrapStylisticOrCoreRule('array-bracket-newline', {
|
||||
skipDynamicArguments: true
|
||||
})
|
11
slider/node_modules/eslint-plugin-vue/lib/rules/array-bracket-spacing.js
generated
vendored
Normal file
11
slider/node_modules/eslint-plugin-vue/lib/rules/array-bracket-spacing.js
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* @author Toru Nagashima
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const { wrapStylisticOrCoreRule } = require('../utils')
|
||||
|
||||
// eslint-disable-next-line internal/no-invalid-meta
|
||||
module.exports = wrapStylisticOrCoreRule('array-bracket-spacing', {
|
||||
skipDynamicArguments: true
|
||||
})
|
11
slider/node_modules/eslint-plugin-vue/lib/rules/array-element-newline.js
generated
vendored
Normal file
11
slider/node_modules/eslint-plugin-vue/lib/rules/array-element-newline.js
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* @author alshyra
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const { wrapStylisticOrCoreRule } = require('../utils')
|
||||
|
||||
// eslint-disable-next-line internal/no-invalid-meta
|
||||
module.exports = wrapStylisticOrCoreRule('array-element-newline', {
|
||||
skipDynamicArguments: true
|
||||
})
|
9
slider/node_modules/eslint-plugin-vue/lib/rules/arrow-spacing.js
generated
vendored
Normal file
9
slider/node_modules/eslint-plugin-vue/lib/rules/arrow-spacing.js
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
/**
|
||||
* @author Yosuke Ota
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const { wrapStylisticOrCoreRule } = require('../utils')
|
||||
|
||||
// eslint-disable-next-line internal/no-invalid-meta
|
||||
module.exports = wrapStylisticOrCoreRule('arrow-spacing')
|
157
slider/node_modules/eslint-plugin-vue/lib/rules/attribute-hyphenation.js
generated
vendored
Normal file
157
slider/node_modules/eslint-plugin-vue/lib/rules/attribute-hyphenation.js
generated
vendored
Normal file
@@ -0,0 +1,157 @@
|
||||
/**
|
||||
* @fileoverview Define a style for the props casing in templates.
|
||||
* @author Armano
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const utils = require('../utils')
|
||||
const casing = require('../utils/casing')
|
||||
const { toRegExpGroupMatcher } = require('../utils/regexp')
|
||||
const svgAttributes = require('../utils/svg-attributes-weird-case.json')
|
||||
|
||||
/**
|
||||
* @param {VDirective | VAttribute} node
|
||||
* @returns {string | null}
|
||||
*/
|
||||
function getAttributeName(node) {
|
||||
if (!node.directive) {
|
||||
return node.key.rawName
|
||||
}
|
||||
|
||||
if (
|
||||
(node.key.name.name === 'bind' || node.key.name.name === 'model') &&
|
||||
node.key.argument &&
|
||||
node.key.argument.type === 'VIdentifier'
|
||||
) {
|
||||
return node.key.argument.rawName
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'suggestion',
|
||||
docs: {
|
||||
description:
|
||||
'enforce attribute naming style on custom components in template',
|
||||
categories: ['vue3-strongly-recommended', 'vue2-strongly-recommended'],
|
||||
url: 'https://eslint.vuejs.org/rules/attribute-hyphenation.html'
|
||||
},
|
||||
fixable: 'code',
|
||||
schema: [
|
||||
{
|
||||
enum: ['always', 'never']
|
||||
},
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
ignore: {
|
||||
type: 'array',
|
||||
items: {
|
||||
allOf: [
|
||||
{ type: 'string' },
|
||||
{ not: { type: 'string', pattern: ':exit$' } },
|
||||
{ not: { type: 'string', pattern: String.raw`^\s*$` } }
|
||||
]
|
||||
},
|
||||
uniqueItems: true,
|
||||
additionalItems: false
|
||||
},
|
||||
ignoreTags: {
|
||||
type: 'array',
|
||||
items: { type: 'string' },
|
||||
uniqueItems: true,
|
||||
additionalItems: false
|
||||
}
|
||||
},
|
||||
additionalProperties: false
|
||||
}
|
||||
],
|
||||
messages: {
|
||||
mustBeHyphenated: "Attribute '{{text}}' must be hyphenated.",
|
||||
cannotBeHyphenated: "Attribute '{{text}}' can't be hyphenated."
|
||||
}
|
||||
},
|
||||
/** @param {RuleContext} context */
|
||||
create(context) {
|
||||
const sourceCode = context.getSourceCode()
|
||||
const option = context.options[0]
|
||||
const optionsPayload = context.options[1]
|
||||
const useHyphenated = option !== 'never'
|
||||
const isIgnoredTagName = toRegExpGroupMatcher(optionsPayload?.ignoreTags)
|
||||
const ignoredAttributes = ['data-', 'aria-', 'slot-scope', ...svgAttributes]
|
||||
|
||||
if (optionsPayload && optionsPayload.ignore) {
|
||||
ignoredAttributes.push(...optionsPayload.ignore)
|
||||
}
|
||||
|
||||
const caseConverter = casing.getExactConverter(
|
||||
useHyphenated ? 'kebab-case' : 'camelCase'
|
||||
)
|
||||
|
||||
/**
|
||||
* @param {VDirective | VAttribute} node
|
||||
* @param {string} name
|
||||
*/
|
||||
function reportIssue(node, name) {
|
||||
const text = sourceCode.getText(node.key)
|
||||
|
||||
context.report({
|
||||
node: node.key,
|
||||
loc: node.loc,
|
||||
messageId: useHyphenated ? 'mustBeHyphenated' : 'cannotBeHyphenated',
|
||||
data: {
|
||||
text
|
||||
},
|
||||
fix: (fixer) => {
|
||||
if (text.includes('_')) {
|
||||
return null
|
||||
}
|
||||
|
||||
if (text.endsWith('.sync')) {
|
||||
return null
|
||||
}
|
||||
|
||||
if (/^[A-Z]/.test(name)) {
|
||||
return null
|
||||
}
|
||||
|
||||
return fixer.replaceText(
|
||||
node.key,
|
||||
text.replace(name, caseConverter(name))
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} value
|
||||
*/
|
||||
function isIgnoredAttribute(value) {
|
||||
const isIgnored = ignoredAttributes.some((attr) => value.includes(attr))
|
||||
|
||||
if (isIgnored) {
|
||||
return true
|
||||
}
|
||||
|
||||
return useHyphenated ? value.toLowerCase() === value : !/-/.test(value)
|
||||
}
|
||||
|
||||
return utils.defineTemplateBodyVisitor(context, {
|
||||
VAttribute(node) {
|
||||
const element = node.parent.parent
|
||||
if (
|
||||
(!utils.isCustomComponent(element) && element.name !== 'slot') ||
|
||||
isIgnoredTagName(element.rawName)
|
||||
)
|
||||
return
|
||||
|
||||
const name = getAttributeName(node)
|
||||
if (name === null || isIgnoredAttribute(name)) return
|
||||
|
||||
reportIssue(node, name)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
481
slider/node_modules/eslint-plugin-vue/lib/rules/attributes-order.js
generated
vendored
Normal file
481
slider/node_modules/eslint-plugin-vue/lib/rules/attributes-order.js
generated
vendored
Normal file
@@ -0,0 +1,481 @@
|
||||
/**
|
||||
* @fileoverview enforce ordering of attributes
|
||||
* @author Erin Depew
|
||||
*/
|
||||
'use strict'
|
||||
const utils = require('../utils')
|
||||
|
||||
/**
|
||||
* @typedef { VDirective & { key: VDirectiveKey & { name: VIdentifier & { name: 'bind' } } } } VBindDirective
|
||||
*/
|
||||
|
||||
const ATTRS = {
|
||||
DEFINITION: 'DEFINITION',
|
||||
LIST_RENDERING: 'LIST_RENDERING',
|
||||
CONDITIONALS: 'CONDITIONALS',
|
||||
RENDER_MODIFIERS: 'RENDER_MODIFIERS',
|
||||
GLOBAL: 'GLOBAL',
|
||||
UNIQUE: 'UNIQUE',
|
||||
SLOT: 'SLOT',
|
||||
TWO_WAY_BINDING: 'TWO_WAY_BINDING',
|
||||
OTHER_DIRECTIVES: 'OTHER_DIRECTIVES',
|
||||
OTHER_ATTR: 'OTHER_ATTR',
|
||||
ATTR_STATIC: 'ATTR_STATIC',
|
||||
ATTR_DYNAMIC: 'ATTR_DYNAMIC',
|
||||
ATTR_SHORTHAND_BOOL: 'ATTR_SHORTHAND_BOOL',
|
||||
EVENTS: 'EVENTS',
|
||||
CONTENT: 'CONTENT'
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the given attribute is `v-bind` directive.
|
||||
* @param {VAttribute | VDirective | undefined | null} node
|
||||
* @returns { node is VBindDirective }
|
||||
*/
|
||||
function isVBind(node) {
|
||||
return Boolean(node && node.directive && node.key.name.name === 'bind')
|
||||
}
|
||||
/**
|
||||
* Check whether the given attribute is `v-model` directive.
|
||||
* @param {VAttribute | VDirective | undefined | null} node
|
||||
* @returns { node is VDirective }
|
||||
*/
|
||||
function isVModel(node) {
|
||||
return Boolean(node && node.directive && node.key.name.name === 'model')
|
||||
}
|
||||
/**
|
||||
* Check whether the given attribute is plain attribute.
|
||||
* @param {VAttribute | VDirective | undefined | null} node
|
||||
* @returns { node is VAttribute }
|
||||
*/
|
||||
function isVAttribute(node) {
|
||||
return Boolean(node && !node.directive)
|
||||
}
|
||||
/**
|
||||
* Check whether the given attribute is plain attribute, `v-bind` directive or `v-model` directive.
|
||||
* @param {VAttribute | VDirective | undefined | null} node
|
||||
* @returns { node is VAttribute }
|
||||
*/
|
||||
function isVAttributeOrVBindOrVModel(node) {
|
||||
return isVAttribute(node) || isVBind(node) || isVModel(node)
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the given attribute is `v-bind="..."` directive.
|
||||
* @param {VAttribute | VDirective | undefined | null} node
|
||||
* @returns { node is VBindDirective }
|
||||
*/
|
||||
function isVBindObject(node) {
|
||||
return isVBind(node) && node.key.argument == null
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the given attribute is a shorthand boolean like `selected`.
|
||||
* @param {VAttribute | VDirective | undefined | null} node
|
||||
* @returns { node is VAttribute }
|
||||
*/
|
||||
function isVShorthandBoolean(node) {
|
||||
return isVAttribute(node) && !node.value
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {VAttribute | VDirective} attribute
|
||||
* @param {SourceCode} sourceCode
|
||||
*/
|
||||
function getAttributeName(attribute, sourceCode) {
|
||||
if (attribute.directive) {
|
||||
if (isVBind(attribute)) {
|
||||
return attribute.key.argument
|
||||
? sourceCode.getText(attribute.key.argument)
|
||||
: ''
|
||||
} else {
|
||||
return getDirectiveKeyName(attribute.key, sourceCode)
|
||||
}
|
||||
} else {
|
||||
return attribute.key.name
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {VDirectiveKey} directiveKey
|
||||
* @param {SourceCode} sourceCode
|
||||
*/
|
||||
function getDirectiveKeyName(directiveKey, sourceCode) {
|
||||
let text = `v-${directiveKey.name.name}`
|
||||
if (directiveKey.argument) {
|
||||
text += `:${sourceCode.getText(directiveKey.argument)}`
|
||||
}
|
||||
for (const modifier of directiveKey.modifiers) {
|
||||
text += `.${modifier.name}`
|
||||
}
|
||||
return text
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {VAttribute | VDirective} attribute
|
||||
*/
|
||||
function getAttributeType(attribute) {
|
||||
let propName
|
||||
if (attribute.directive) {
|
||||
if (!isVBind(attribute)) {
|
||||
const name = attribute.key.name.name
|
||||
switch (name) {
|
||||
case 'for': {
|
||||
return ATTRS.LIST_RENDERING
|
||||
}
|
||||
case 'if':
|
||||
case 'else-if':
|
||||
case 'else':
|
||||
case 'show':
|
||||
case 'cloak': {
|
||||
return ATTRS.CONDITIONALS
|
||||
}
|
||||
case 'pre':
|
||||
case 'once': {
|
||||
return ATTRS.RENDER_MODIFIERS
|
||||
}
|
||||
case 'model': {
|
||||
return ATTRS.TWO_WAY_BINDING
|
||||
}
|
||||
case 'on': {
|
||||
return ATTRS.EVENTS
|
||||
}
|
||||
case 'html':
|
||||
case 'text': {
|
||||
return ATTRS.CONTENT
|
||||
}
|
||||
case 'slot': {
|
||||
return ATTRS.SLOT
|
||||
}
|
||||
case 'is': {
|
||||
return ATTRS.DEFINITION
|
||||
}
|
||||
default: {
|
||||
return ATTRS.OTHER_DIRECTIVES
|
||||
}
|
||||
}
|
||||
}
|
||||
propName =
|
||||
attribute.key.argument && attribute.key.argument.type === 'VIdentifier'
|
||||
? attribute.key.argument.rawName
|
||||
: ''
|
||||
} else {
|
||||
propName = attribute.key.name
|
||||
}
|
||||
switch (propName) {
|
||||
case 'is': {
|
||||
return ATTRS.DEFINITION
|
||||
}
|
||||
case 'id': {
|
||||
return ATTRS.GLOBAL
|
||||
}
|
||||
case 'ref':
|
||||
case 'key': {
|
||||
return ATTRS.UNIQUE
|
||||
}
|
||||
case 'slot':
|
||||
case 'slot-scope': {
|
||||
return ATTRS.SLOT
|
||||
}
|
||||
default: {
|
||||
if (isVBind(attribute)) {
|
||||
return ATTRS.ATTR_DYNAMIC
|
||||
}
|
||||
if (isVShorthandBoolean(attribute)) {
|
||||
return ATTRS.ATTR_SHORTHAND_BOOL
|
||||
}
|
||||
return ATTRS.ATTR_STATIC
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {VAttribute | VDirective} attribute
|
||||
* @param { { [key: string]: number } } attributePosition
|
||||
* @returns {number | null} If the value is null, the order is omitted. Do not force the order.
|
||||
*/
|
||||
function getPosition(attribute, attributePosition) {
|
||||
const attributeType = getAttributeType(attribute)
|
||||
return attributePosition[attributeType] == null
|
||||
? null
|
||||
: attributePosition[attributeType]
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {VAttribute | VDirective} prevNode
|
||||
* @param {VAttribute | VDirective} currNode
|
||||
* @param {SourceCode} sourceCode
|
||||
*/
|
||||
function isAlphabetical(prevNode, currNode, sourceCode) {
|
||||
const prevName = getAttributeName(prevNode, sourceCode)
|
||||
const currName = getAttributeName(currNode, sourceCode)
|
||||
if (prevName === currName) {
|
||||
const prevIsBind = isVBind(prevNode)
|
||||
const currIsBind = isVBind(currNode)
|
||||
return prevIsBind <= currIsBind
|
||||
}
|
||||
return prevName < currName
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {RuleContext} context - The rule context.
|
||||
* @returns {RuleListener} AST event handlers.
|
||||
*/
|
||||
function create(context) {
|
||||
const sourceCode = context.getSourceCode()
|
||||
const otherAttrs = [
|
||||
ATTRS.ATTR_DYNAMIC,
|
||||
ATTRS.ATTR_STATIC,
|
||||
ATTRS.ATTR_SHORTHAND_BOOL
|
||||
]
|
||||
let attributeOrder = [
|
||||
ATTRS.DEFINITION,
|
||||
ATTRS.LIST_RENDERING,
|
||||
ATTRS.CONDITIONALS,
|
||||
ATTRS.RENDER_MODIFIERS,
|
||||
ATTRS.GLOBAL,
|
||||
[ATTRS.UNIQUE, ATTRS.SLOT],
|
||||
ATTRS.TWO_WAY_BINDING,
|
||||
ATTRS.OTHER_DIRECTIVES,
|
||||
otherAttrs,
|
||||
ATTRS.EVENTS,
|
||||
ATTRS.CONTENT
|
||||
]
|
||||
if (context.options[0] && context.options[0].order) {
|
||||
attributeOrder = [...context.options[0].order]
|
||||
|
||||
// check if `OTHER_ATTR` is valid
|
||||
for (const item of attributeOrder.flat()) {
|
||||
if (item === ATTRS.OTHER_ATTR) {
|
||||
for (const attribute of attributeOrder.flat()) {
|
||||
if (otherAttrs.includes(attribute)) {
|
||||
throw new Error(
|
||||
`Value "${ATTRS.OTHER_ATTR}" is not allowed with "${attribute}".`
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// expand `OTHER_ATTR` alias
|
||||
for (const [index, item] of attributeOrder.entries()) {
|
||||
if (item === ATTRS.OTHER_ATTR) {
|
||||
attributeOrder[index] = otherAttrs
|
||||
} else if (Array.isArray(item) && item.includes(ATTRS.OTHER_ATTR)) {
|
||||
const attributes = item.filter((i) => i !== ATTRS.OTHER_ATTR)
|
||||
attributes.push(...otherAttrs)
|
||||
attributeOrder[index] = attributes
|
||||
}
|
||||
}
|
||||
}
|
||||
const alphabetical = Boolean(
|
||||
context.options[0] && context.options[0].alphabetical
|
||||
)
|
||||
const sortLineLength = Boolean(
|
||||
context.options[0] && context.options[0].sortLineLength
|
||||
)
|
||||
|
||||
/** @type { { [key: string]: number } } */
|
||||
const attributePosition = {}
|
||||
for (const [i, item] of attributeOrder.entries()) {
|
||||
if (Array.isArray(item)) {
|
||||
for (const attr of item) {
|
||||
attributePosition[attr] = i
|
||||
}
|
||||
} else attributePosition[item] = i
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {VAttribute | VDirective} node
|
||||
* @param {VAttribute | VDirective} previousNode
|
||||
*/
|
||||
function reportIssue(node, previousNode) {
|
||||
const currentNode = sourceCode.getText(node.key)
|
||||
const prevNode = sourceCode.getText(previousNode.key)
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'expectedOrder',
|
||||
data: {
|
||||
currentNode,
|
||||
prevNode
|
||||
},
|
||||
|
||||
fix(fixer) {
|
||||
const attributes = node.parent.attributes
|
||||
|
||||
/** @type { (node: VAttribute | VDirective | undefined) => boolean } */
|
||||
let isMoveUp
|
||||
|
||||
if (isVBindObject(node)) {
|
||||
// prev, v-bind:foo, v-bind -> v-bind:foo, v-bind, prev
|
||||
isMoveUp = isVAttributeOrVBindOrVModel
|
||||
} else if (isVAttributeOrVBindOrVModel(node)) {
|
||||
// prev, v-bind, v-bind:foo -> v-bind, v-bind:foo, prev
|
||||
isMoveUp = isVBindObject
|
||||
} else {
|
||||
isMoveUp = () => false
|
||||
}
|
||||
|
||||
const previousNodes = attributes.slice(
|
||||
attributes.indexOf(previousNode),
|
||||
attributes.indexOf(node)
|
||||
)
|
||||
const moveNodes = [node]
|
||||
for (const node of previousNodes) {
|
||||
if (isMoveUp(node)) {
|
||||
moveNodes.unshift(node)
|
||||
} else {
|
||||
moveNodes.push(node)
|
||||
}
|
||||
}
|
||||
|
||||
return moveNodes.map((moveNode, index) => {
|
||||
const text = sourceCode.getText(moveNode)
|
||||
return fixer.replaceText(previousNodes[index] || node, text)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return utils.defineTemplateBodyVisitor(context, {
|
||||
VStartTag(node) {
|
||||
const attributeAndPositions = getAttributeAndPositionList(node)
|
||||
if (attributeAndPositions.length <= 1) {
|
||||
return
|
||||
}
|
||||
|
||||
let { attr: previousNode, position: previousPosition } =
|
||||
attributeAndPositions[0]
|
||||
for (let index = 1; index < attributeAndPositions.length; index++) {
|
||||
const { attr, position } = attributeAndPositions[index]
|
||||
|
||||
let valid = previousPosition <= position
|
||||
if (valid && previousPosition === position) {
|
||||
let sortedByLength = false
|
||||
if (sortLineLength) {
|
||||
const prevText = sourceCode.getText(previousNode)
|
||||
const currText = sourceCode.getText(attr)
|
||||
|
||||
if (prevText.length !== currText.length) {
|
||||
valid = prevText.length < currText.length
|
||||
sortedByLength = true
|
||||
}
|
||||
}
|
||||
|
||||
if (alphabetical && !sortedByLength) {
|
||||
valid = isAlphabetical(previousNode, attr, sourceCode)
|
||||
}
|
||||
}
|
||||
|
||||
if (valid) {
|
||||
previousNode = attr
|
||||
previousPosition = position
|
||||
} else {
|
||||
reportIssue(attr, previousNode)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* @param {VStartTag} node
|
||||
* @returns { { attr: ( VAttribute | VDirective ), position: number }[] }
|
||||
*/
|
||||
function getAttributeAndPositionList(node) {
|
||||
const attributes = node.attributes.filter((node, index, attributes) => {
|
||||
if (
|
||||
isVBindObject(node) &&
|
||||
(isVAttributeOrVBindOrVModel(attributes[index - 1]) ||
|
||||
isVAttributeOrVBindOrVModel(attributes[index + 1]))
|
||||
) {
|
||||
// In Vue 3, ignore `v-bind="object"`, which is
|
||||
// a pair of `v-bind:foo="..."` and `v-bind="object"` and
|
||||
// a pair of `v-model="..."` and `v-bind="object"`,
|
||||
// because changing the order behaves differently.
|
||||
return false
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
||||
const results = []
|
||||
for (const [index, attr] of attributes.entries()) {
|
||||
const position = getPositionFromAttrIndex(index)
|
||||
if (position == null) {
|
||||
// The omitted order is skipped.
|
||||
continue
|
||||
}
|
||||
results.push({ attr, position })
|
||||
}
|
||||
|
||||
return results
|
||||
|
||||
/**
|
||||
* @param {number} index
|
||||
* @returns {number | null}
|
||||
*/
|
||||
function getPositionFromAttrIndex(index) {
|
||||
const node = attributes[index]
|
||||
if (isVBindObject(node)) {
|
||||
// node is `v-bind ="object"` syntax
|
||||
|
||||
// In Vue 3, if change the order of `v-bind:foo="..."`, `v-model="..."` and `v-bind="object"`,
|
||||
// the behavior will be different, so adjust so that there is no change in behavior.
|
||||
|
||||
const len = attributes.length
|
||||
for (let nextIndex = index + 1; nextIndex < len; nextIndex++) {
|
||||
const next = attributes[nextIndex]
|
||||
|
||||
if (isVAttributeOrVBindOrVModel(next) && !isVBindObject(next)) {
|
||||
// It is considered to be in the same order as the next bind prop node.
|
||||
return getPositionFromAttrIndex(nextIndex)
|
||||
}
|
||||
}
|
||||
}
|
||||
return getPosition(node, attributePosition)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'suggestion',
|
||||
docs: {
|
||||
description: 'enforce order of attributes',
|
||||
categories: ['vue3-recommended', 'vue2-recommended'],
|
||||
url: 'https://eslint.vuejs.org/rules/attributes-order.html'
|
||||
},
|
||||
fixable: 'code',
|
||||
schema: [
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
order: {
|
||||
type: 'array',
|
||||
items: {
|
||||
oneOf: [
|
||||
{ enum: Object.values(ATTRS) },
|
||||
{
|
||||
type: 'array',
|
||||
items: {
|
||||
enum: Object.values(ATTRS),
|
||||
uniqueItems: true,
|
||||
additionalItems: false
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
uniqueItems: true,
|
||||
additionalItems: false
|
||||
},
|
||||
alphabetical: { type: 'boolean' },
|
||||
sortLineLength: { type: 'boolean' }
|
||||
},
|
||||
additionalProperties: false
|
||||
}
|
||||
],
|
||||
messages: {
|
||||
expectedOrder: `Attribute "{{currentNode}}" should go before "{{prevNode}}".`
|
||||
}
|
||||
},
|
||||
create
|
||||
}
|
227
slider/node_modules/eslint-plugin-vue/lib/rules/block-lang.js
generated
vendored
Normal file
227
slider/node_modules/eslint-plugin-vue/lib/rules/block-lang.js
generated
vendored
Normal file
@@ -0,0 +1,227 @@
|
||||
/**
|
||||
* @fileoverview Disallow use other than available `lang`
|
||||
* @author Yosuke Ota
|
||||
*/
|
||||
'use strict'
|
||||
const utils = require('../utils')
|
||||
|
||||
/**
|
||||
* @typedef {object} BlockOptions
|
||||
* @property {Set<string>} lang
|
||||
* @property {boolean} allowNoLang
|
||||
*/
|
||||
/**
|
||||
* @typedef { { [element: string]: BlockOptions | undefined } } Options
|
||||
*/
|
||||
/**
|
||||
* @typedef {object} UserBlockOptions
|
||||
* @property {string[] | string} [lang]
|
||||
* @property {boolean} [allowNoLang]
|
||||
*/
|
||||
/**
|
||||
* @typedef { { [element: string]: UserBlockOptions | undefined } } UserOptions
|
||||
*/
|
||||
|
||||
/**
|
||||
* https://vuejs.github.io/vetur/guide/highlighting.html
|
||||
* <template lang="html"></template>
|
||||
* <style lang="css"></style>
|
||||
* <script lang="js"></script>
|
||||
* <script lang="javascript"></script>
|
||||
* @type {Record<string, string[] | undefined>}
|
||||
*/
|
||||
const DEFAULT_LANGUAGES = {
|
||||
template: ['html'],
|
||||
style: ['css'],
|
||||
script: ['js', 'javascript']
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {NonNullable<BlockOptions['lang']>} lang
|
||||
*/
|
||||
function getAllowsLangPhrase(lang) {
|
||||
const langs = [...lang].map((s) => `'${s}'`)
|
||||
switch (langs.length) {
|
||||
case 1: {
|
||||
return langs[0]
|
||||
}
|
||||
default: {
|
||||
return `${langs.slice(0, -1).join(', ')}, and ${langs[langs.length - 1]}`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes a given option.
|
||||
* @param {string} blockName The block name.
|
||||
* @param {UserBlockOptions} option An option to parse.
|
||||
* @returns {BlockOptions} Normalized option.
|
||||
*/
|
||||
function normalizeOption(blockName, option) {
|
||||
/** @type {Set<string>} */
|
||||
let lang
|
||||
|
||||
if (Array.isArray(option.lang)) {
|
||||
lang = new Set(option.lang)
|
||||
} else if (typeof option.lang === 'string') {
|
||||
lang = new Set([option.lang])
|
||||
} else {
|
||||
lang = new Set()
|
||||
}
|
||||
|
||||
let hasDefault = false
|
||||
for (const def of DEFAULT_LANGUAGES[blockName] || []) {
|
||||
if (lang.has(def)) {
|
||||
lang.delete(def)
|
||||
hasDefault = true
|
||||
}
|
||||
}
|
||||
if (lang.size === 0) {
|
||||
return {
|
||||
lang,
|
||||
allowNoLang: true
|
||||
}
|
||||
}
|
||||
return {
|
||||
lang,
|
||||
allowNoLang: hasDefault || Boolean(option.allowNoLang)
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Normalizes a given options.
|
||||
* @param { UserOptions } options An option to parse.
|
||||
* @returns {Options} Normalized option.
|
||||
*/
|
||||
function normalizeOptions(options) {
|
||||
if (!options) {
|
||||
return {}
|
||||
}
|
||||
|
||||
/** @type {Options} */
|
||||
const normalized = {}
|
||||
|
||||
for (const blockName of Object.keys(options)) {
|
||||
const value = options[blockName]
|
||||
if (value) {
|
||||
normalized[blockName] = normalizeOption(blockName, value)
|
||||
}
|
||||
}
|
||||
|
||||
return normalized
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'suggestion',
|
||||
docs: {
|
||||
description: 'disallow use other than available `lang`',
|
||||
categories: undefined,
|
||||
url: 'https://eslint.vuejs.org/rules/block-lang.html'
|
||||
},
|
||||
schema: [
|
||||
{
|
||||
type: 'object',
|
||||
patternProperties: {
|
||||
'^(?:\\S+)$': {
|
||||
oneOf: [
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
lang: {
|
||||
oneOf: [
|
||||
{ type: 'string' },
|
||||
{
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'string'
|
||||
},
|
||||
uniqueItems: true,
|
||||
additionalItems: false
|
||||
}
|
||||
]
|
||||
},
|
||||
allowNoLang: { type: 'boolean' }
|
||||
},
|
||||
additionalProperties: false
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
minProperties: 1,
|
||||
additionalProperties: false
|
||||
}
|
||||
],
|
||||
messages: {
|
||||
expected:
|
||||
"Only {{allows}} can be used for the 'lang' attribute of '<{{tag}}>'.",
|
||||
missing: "The 'lang' attribute of '<{{tag}}>' is missing.",
|
||||
unexpected: "Do not specify the 'lang' attribute of '<{{tag}}>'.",
|
||||
useOrNot:
|
||||
"Only {{allows}} can be used for the 'lang' attribute of '<{{tag}}>'. Or, not specifying the 'lang' attribute is allowed.",
|
||||
unexpectedDefault:
|
||||
"Do not explicitly specify the default language for the 'lang' attribute of '<{{tag}}>'."
|
||||
}
|
||||
},
|
||||
/** @param {RuleContext} context */
|
||||
create(context) {
|
||||
const options = normalizeOptions(
|
||||
context.options[0] || {
|
||||
script: { allowNoLang: true },
|
||||
template: { allowNoLang: true },
|
||||
style: { allowNoLang: true }
|
||||
}
|
||||
)
|
||||
if (Object.keys(options).length === 0) {
|
||||
return {}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {VElement} element
|
||||
* @returns {void}
|
||||
*/
|
||||
function verify(element) {
|
||||
const tag = element.name
|
||||
const option = options[tag]
|
||||
if (!option) {
|
||||
return
|
||||
}
|
||||
const lang = utils.getAttribute(element, 'lang')
|
||||
if (lang == null || lang.value == null) {
|
||||
if (!option.allowNoLang) {
|
||||
context.report({
|
||||
node: element.startTag,
|
||||
messageId: 'missing',
|
||||
data: {
|
||||
tag
|
||||
}
|
||||
})
|
||||
}
|
||||
return
|
||||
}
|
||||
if (!option.lang.has(lang.value.value)) {
|
||||
let messageId
|
||||
if (!option.allowNoLang) {
|
||||
messageId = 'expected'
|
||||
} else if (option.lang.size === 0) {
|
||||
messageId = (DEFAULT_LANGUAGES[tag] || []).includes(lang.value.value)
|
||||
? 'unexpectedDefault'
|
||||
: 'unexpected'
|
||||
} else {
|
||||
messageId = 'useOrNot'
|
||||
}
|
||||
context.report({
|
||||
node: lang,
|
||||
messageId,
|
||||
data: {
|
||||
tag,
|
||||
allows: getAllowsLangPhrase(option.lang)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return utils.defineDocumentVisitor(context, {
|
||||
'VDocumentFragment > VElement': verify
|
||||
})
|
||||
}
|
||||
}
|
185
slider/node_modules/eslint-plugin-vue/lib/rules/block-order.js
generated
vendored
Normal file
185
slider/node_modules/eslint-plugin-vue/lib/rules/block-order.js
generated
vendored
Normal file
@@ -0,0 +1,185 @@
|
||||
/**
|
||||
* @author Yosuke Ota
|
||||
* issue https://github.com/vuejs/eslint-plugin-vue/issues/140
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const utils = require('../utils')
|
||||
const { parseSelector } = require('../utils/selector')
|
||||
|
||||
/**
|
||||
* @typedef {import('../utils/selector').VElementSelector} VElementSelector
|
||||
*/
|
||||
|
||||
const DEFAULT_ORDER = Object.freeze([['script', 'template'], 'style'])
|
||||
|
||||
/**
|
||||
* @param {VElement} element
|
||||
* @return {string}
|
||||
*/
|
||||
function getAttributeString(element) {
|
||||
return element.startTag.attributes
|
||||
.map((attribute) => {
|
||||
if (attribute.value && attribute.value.type !== 'VLiteral') {
|
||||
return ''
|
||||
}
|
||||
|
||||
return `${attribute.key.name}${
|
||||
attribute.value && attribute.value.value
|
||||
? `=${attribute.value.value}`
|
||||
: ''
|
||||
}`
|
||||
})
|
||||
.join(' ')
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'suggestion',
|
||||
docs: {
|
||||
description: 'enforce order of component top-level elements',
|
||||
categories: ['vue3-recommended', 'vue2-recommended'],
|
||||
url: 'https://eslint.vuejs.org/rules/block-order.html'
|
||||
},
|
||||
fixable: 'code',
|
||||
schema: [
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
order: {
|
||||
type: 'array',
|
||||
items: {
|
||||
oneOf: [
|
||||
{ type: 'string' },
|
||||
{ type: 'array', items: { type: 'string' }, uniqueItems: true }
|
||||
]
|
||||
},
|
||||
uniqueItems: true,
|
||||
additionalItems: false
|
||||
}
|
||||
},
|
||||
additionalProperties: false
|
||||
}
|
||||
],
|
||||
messages: {
|
||||
unexpected:
|
||||
"'<{{elementName}}{{elementAttributes}}>' should be above '<{{firstUnorderedName}}{{firstUnorderedAttributes}}>' on line {{line}}."
|
||||
}
|
||||
},
|
||||
/**
|
||||
* @param {RuleContext} context - The rule context.
|
||||
* @returns {RuleListener} AST event handlers.
|
||||
*/
|
||||
create(context) {
|
||||
/**
|
||||
* @typedef {object} OrderElement
|
||||
* @property {string} selectorText
|
||||
* @property {VElementSelector} selector
|
||||
* @property {number} index
|
||||
*/
|
||||
/** @type {OrderElement[]} */
|
||||
const orders = []
|
||||
/** @type {(string|string[])[]} */
|
||||
const orderOptions =
|
||||
(context.options[0] && context.options[0].order) || DEFAULT_ORDER
|
||||
for (const [index, selectorOrSelectors] of orderOptions.entries()) {
|
||||
if (Array.isArray(selectorOrSelectors)) {
|
||||
for (const selector of selectorOrSelectors) {
|
||||
orders.push({
|
||||
selectorText: selector,
|
||||
selector: parseSelector(selector, context),
|
||||
index
|
||||
})
|
||||
}
|
||||
} else {
|
||||
orders.push({
|
||||
selectorText: selectorOrSelectors,
|
||||
selector: parseSelector(selectorOrSelectors, context),
|
||||
index
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {VElement} element
|
||||
*/
|
||||
function getOrderElement(element) {
|
||||
return orders.find((o) => o.selector.test(element))
|
||||
}
|
||||
const sourceCode = context.getSourceCode()
|
||||
const documentFragment =
|
||||
sourceCode.parserServices.getDocumentFragment &&
|
||||
sourceCode.parserServices.getDocumentFragment()
|
||||
|
||||
function getTopLevelHTMLElements() {
|
||||
if (documentFragment) {
|
||||
return documentFragment.children.filter(utils.isVElement)
|
||||
}
|
||||
return []
|
||||
}
|
||||
|
||||
return {
|
||||
Program(node) {
|
||||
if (utils.hasInvalidEOF(node)) {
|
||||
return
|
||||
}
|
||||
const elements = getTopLevelHTMLElements()
|
||||
|
||||
const elementsWithOrder = elements.flatMap((element) => {
|
||||
const order = getOrderElement(element)
|
||||
return order ? [{ order, element }] : []
|
||||
})
|
||||
const sourceCode = context.getSourceCode()
|
||||
for (const [index, elementWithOrders] of elementsWithOrder.entries()) {
|
||||
const { order: expected, element } = elementWithOrders
|
||||
const firstUnordered = elementsWithOrder
|
||||
.slice(0, index)
|
||||
.filter(({ order }) => expected.index < order.index)
|
||||
.sort((e1, e2) => e1.order.index - e2.order.index)[0]
|
||||
if (firstUnordered) {
|
||||
const firstUnorderedAttributes = getAttributeString(
|
||||
firstUnordered.element
|
||||
)
|
||||
const elementAttributes = getAttributeString(element)
|
||||
|
||||
context.report({
|
||||
node: element,
|
||||
loc: element.loc,
|
||||
messageId: 'unexpected',
|
||||
data: {
|
||||
elementName: element.name,
|
||||
elementAttributes: elementAttributes
|
||||
? ` ${elementAttributes}`
|
||||
: '',
|
||||
firstUnorderedName: firstUnordered.element.name,
|
||||
firstUnorderedAttributes: firstUnorderedAttributes
|
||||
? ` ${firstUnorderedAttributes}`
|
||||
: '',
|
||||
line: firstUnordered.element.loc.start.line
|
||||
},
|
||||
*fix(fixer) {
|
||||
// insert element before firstUnordered
|
||||
const fixedElements = elements.flatMap((it) => {
|
||||
if (it === firstUnordered.element) {
|
||||
return [element, it]
|
||||
} else if (it === element) {
|
||||
return []
|
||||
}
|
||||
return [it]
|
||||
})
|
||||
for (let i = elements.length - 1; i >= 0; i--) {
|
||||
if (elements[i] !== fixedElements[i]) {
|
||||
yield fixer.replaceTextRange(
|
||||
elements[i].range,
|
||||
sourceCode.text.slice(...fixedElements[i].range)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
11
slider/node_modules/eslint-plugin-vue/lib/rules/block-spacing.js
generated
vendored
Normal file
11
slider/node_modules/eslint-plugin-vue/lib/rules/block-spacing.js
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* @author Yosuke Ota
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const { wrapStylisticOrCoreRule } = require('../utils')
|
||||
|
||||
// eslint-disable-next-line internal/no-invalid-meta
|
||||
module.exports = wrapStylisticOrCoreRule('block-spacing', {
|
||||
skipDynamicArguments: true
|
||||
})
|
364
slider/node_modules/eslint-plugin-vue/lib/rules/block-tag-newline.js
generated
vendored
Normal file
364
slider/node_modules/eslint-plugin-vue/lib/rules/block-tag-newline.js
generated
vendored
Normal file
@@ -0,0 +1,364 @@
|
||||
/**
|
||||
* @fileoverview Enforce line breaks style after opening and before closing block-level tags.
|
||||
* @author Yosuke Ota
|
||||
*/
|
||||
'use strict'
|
||||
const utils = require('../utils')
|
||||
|
||||
/**
|
||||
* @typedef { 'always' | 'never' | 'consistent' | 'ignore' } OptionType
|
||||
* @typedef { { singleline?: OptionType, multiline?: OptionType, maxEmptyLines?: number } } ContentsOptions
|
||||
* @typedef { ContentsOptions & { blocks?: { [element: string]: ContentsOptions } } } Options
|
||||
* @typedef { Required<ContentsOptions> } ArgsOptions
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {string} text Source code as a string.
|
||||
* @returns {number}
|
||||
*/
|
||||
function getLinebreakCount(text) {
|
||||
return text.split(/\r\n|[\r\n\u2028\u2029]/gu).length - 1
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} lineBreaks
|
||||
*/
|
||||
function getPhrase(lineBreaks) {
|
||||
switch (lineBreaks) {
|
||||
case 1: {
|
||||
return '1 line break'
|
||||
}
|
||||
default: {
|
||||
return `${lineBreaks} line breaks`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const ENUM_OPTIONS = { enum: ['always', 'never', 'consistent', 'ignore'] }
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'layout',
|
||||
docs: {
|
||||
description:
|
||||
'enforce line breaks after opening and before closing block-level tags',
|
||||
categories: undefined,
|
||||
url: 'https://eslint.vuejs.org/rules/block-tag-newline.html'
|
||||
},
|
||||
fixable: 'whitespace',
|
||||
schema: [
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
singleline: ENUM_OPTIONS,
|
||||
multiline: ENUM_OPTIONS,
|
||||
maxEmptyLines: { type: 'number', minimum: 0 },
|
||||
blocks: {
|
||||
type: 'object',
|
||||
patternProperties: {
|
||||
'^(?:\\S+)$': {
|
||||
type: 'object',
|
||||
properties: {
|
||||
singleline: ENUM_OPTIONS,
|
||||
multiline: ENUM_OPTIONS,
|
||||
maxEmptyLines: { type: 'number', minimum: 0 }
|
||||
},
|
||||
additionalProperties: false
|
||||
}
|
||||
},
|
||||
additionalProperties: false
|
||||
}
|
||||
},
|
||||
additionalProperties: false
|
||||
}
|
||||
],
|
||||
messages: {
|
||||
unexpectedOpeningLinebreak:
|
||||
"There should be no line break after '<{{tag}}>'.",
|
||||
expectedOpeningLinebreak:
|
||||
"Expected {{expected}} after '<{{tag}}>', but {{actual}} found.",
|
||||
expectedClosingLinebreak:
|
||||
"Expected {{expected}} before '</{{tag}}>', but {{actual}} found.",
|
||||
missingOpeningLinebreak: "A line break is required after '<{{tag}}>'.",
|
||||
missingClosingLinebreak: "A line break is required before '</{{tag}}>'."
|
||||
}
|
||||
},
|
||||
/** @param {RuleContext} context */
|
||||
create(context) {
|
||||
const sourceCode = context.getSourceCode()
|
||||
const df =
|
||||
sourceCode.parserServices.getDocumentFragment &&
|
||||
sourceCode.parserServices.getDocumentFragment()
|
||||
if (!df) {
|
||||
return {}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {VStartTag} startTag
|
||||
* @param {string} beforeText
|
||||
* @param {number} beforeLinebreakCount
|
||||
* @param {'always' | 'never'} beforeOption
|
||||
* @param {number} maxEmptyLines
|
||||
* @returns {void}
|
||||
*/
|
||||
function verifyBeforeSpaces(
|
||||
startTag,
|
||||
beforeText,
|
||||
beforeLinebreakCount,
|
||||
beforeOption,
|
||||
maxEmptyLines
|
||||
) {
|
||||
if (beforeOption === 'always') {
|
||||
if (beforeLinebreakCount === 0) {
|
||||
context.report({
|
||||
loc: {
|
||||
start: startTag.loc.end,
|
||||
end: startTag.loc.end
|
||||
},
|
||||
messageId: 'missingOpeningLinebreak',
|
||||
data: { tag: startTag.parent.name },
|
||||
fix(fixer) {
|
||||
return fixer.insertTextAfter(startTag, '\n')
|
||||
}
|
||||
})
|
||||
} else if (maxEmptyLines < beforeLinebreakCount - 1) {
|
||||
context.report({
|
||||
loc: {
|
||||
start: startTag.loc.end,
|
||||
end: sourceCode.getLocFromIndex(
|
||||
startTag.range[1] + beforeText.length
|
||||
)
|
||||
},
|
||||
messageId: 'expectedOpeningLinebreak',
|
||||
data: {
|
||||
tag: startTag.parent.name,
|
||||
expected: getPhrase(maxEmptyLines + 1),
|
||||
actual: getPhrase(beforeLinebreakCount)
|
||||
},
|
||||
fix(fixer) {
|
||||
return fixer.replaceTextRange(
|
||||
[startTag.range[1], startTag.range[1] + beforeText.length],
|
||||
'\n'.repeat(maxEmptyLines + 1)
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
} else {
|
||||
if (beforeLinebreakCount > 0) {
|
||||
context.report({
|
||||
loc: {
|
||||
start: startTag.loc.end,
|
||||
end: sourceCode.getLocFromIndex(
|
||||
startTag.range[1] + beforeText.length
|
||||
)
|
||||
},
|
||||
messageId: 'unexpectedOpeningLinebreak',
|
||||
data: { tag: startTag.parent.name },
|
||||
fix(fixer) {
|
||||
return fixer.removeRange([
|
||||
startTag.range[1],
|
||||
startTag.range[1] + beforeText.length
|
||||
])
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param {VEndTag} endTag
|
||||
* @param {string} afterText
|
||||
* @param {number} afterLinebreakCount
|
||||
* @param {'always' | 'never'} afterOption
|
||||
* @param {number} maxEmptyLines
|
||||
* @returns {void}
|
||||
*/
|
||||
function verifyAfterSpaces(
|
||||
endTag,
|
||||
afterText,
|
||||
afterLinebreakCount,
|
||||
afterOption,
|
||||
maxEmptyLines
|
||||
) {
|
||||
if (afterOption === 'always') {
|
||||
if (afterLinebreakCount === 0) {
|
||||
context.report({
|
||||
loc: {
|
||||
start: endTag.loc.start,
|
||||
end: endTag.loc.start
|
||||
},
|
||||
messageId: 'missingClosingLinebreak',
|
||||
data: { tag: endTag.parent.name },
|
||||
fix(fixer) {
|
||||
return fixer.insertTextBefore(endTag, '\n')
|
||||
}
|
||||
})
|
||||
} else if (maxEmptyLines < afterLinebreakCount - 1) {
|
||||
context.report({
|
||||
loc: {
|
||||
start: sourceCode.getLocFromIndex(
|
||||
endTag.range[0] - afterText.length
|
||||
),
|
||||
end: endTag.loc.start
|
||||
},
|
||||
messageId: 'expectedClosingLinebreak',
|
||||
data: {
|
||||
tag: endTag.parent.name,
|
||||
expected: getPhrase(maxEmptyLines + 1),
|
||||
actual: getPhrase(afterLinebreakCount)
|
||||
},
|
||||
fix(fixer) {
|
||||
return fixer.replaceTextRange(
|
||||
[endTag.range[0] - afterText.length, endTag.range[0]],
|
||||
'\n'.repeat(maxEmptyLines + 1)
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
} else {
|
||||
if (afterLinebreakCount > 0) {
|
||||
context.report({
|
||||
loc: {
|
||||
start: sourceCode.getLocFromIndex(
|
||||
endTag.range[0] - afterText.length
|
||||
),
|
||||
end: endTag.loc.start
|
||||
},
|
||||
messageId: 'unexpectedOpeningLinebreak',
|
||||
data: { tag: endTag.parent.name },
|
||||
fix(fixer) {
|
||||
return fixer.removeRange([
|
||||
endTag.range[0] - afterText.length,
|
||||
endTag.range[0]
|
||||
])
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param {VElement} element
|
||||
* @param {ArgsOptions} options
|
||||
* @returns {void}
|
||||
*/
|
||||
function verifyElement(element, options) {
|
||||
const { startTag, endTag } = element
|
||||
if (startTag.selfClosing || endTag == null) {
|
||||
return
|
||||
}
|
||||
const text = sourceCode.text.slice(startTag.range[1], endTag.range[0])
|
||||
|
||||
const trimText = text.trim()
|
||||
if (!trimText) {
|
||||
return
|
||||
}
|
||||
|
||||
const option =
|
||||
options.multiline !== options.singleline &&
|
||||
/[\n\r\u2028\u2029]/u.test(text.trim())
|
||||
? options.multiline
|
||||
: options.singleline
|
||||
if (option === 'ignore') {
|
||||
return
|
||||
}
|
||||
const beforeText = /** @type {RegExpExecArray} */ (/^\s*/u.exec(text))[0]
|
||||
const afterText = /** @type {RegExpExecArray} */ (/\s*$/u.exec(text))[0]
|
||||
const beforeLinebreakCount = getLinebreakCount(beforeText)
|
||||
const afterLinebreakCount = getLinebreakCount(afterText)
|
||||
|
||||
/** @type {'always' | 'never'} */
|
||||
let beforeOption
|
||||
/** @type {'always' | 'never'} */
|
||||
let afterOption
|
||||
if (option === 'always' || option === 'never') {
|
||||
beforeOption = option
|
||||
afterOption = option
|
||||
} else {
|
||||
// consistent
|
||||
if (beforeLinebreakCount > 0 === afterLinebreakCount > 0) {
|
||||
return
|
||||
}
|
||||
beforeOption = 'always'
|
||||
afterOption = 'always'
|
||||
}
|
||||
|
||||
verifyBeforeSpaces(
|
||||
startTag,
|
||||
beforeText,
|
||||
beforeLinebreakCount,
|
||||
beforeOption,
|
||||
options.maxEmptyLines
|
||||
)
|
||||
|
||||
verifyAfterSpaces(
|
||||
endTag,
|
||||
afterText,
|
||||
afterLinebreakCount,
|
||||
afterOption,
|
||||
options.maxEmptyLines
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes a given option value.
|
||||
* @param { Options | undefined } option An option value to parse.
|
||||
* @returns { (element: VElement) => void } Verify function.
|
||||
*/
|
||||
function normalizeOptionValue(option) {
|
||||
if (!option) {
|
||||
return normalizeOptionValue({})
|
||||
}
|
||||
|
||||
/** @type {ContentsOptions} */
|
||||
const contentsOptions = option
|
||||
/** @type {ArgsOptions} */
|
||||
const options = {
|
||||
singleline: contentsOptions.singleline || 'consistent',
|
||||
multiline: contentsOptions.multiline || 'always',
|
||||
maxEmptyLines: contentsOptions.maxEmptyLines || 0
|
||||
}
|
||||
const { blocks } = option
|
||||
if (!blocks) {
|
||||
return (element) => verifyElement(element, options)
|
||||
}
|
||||
|
||||
return (element) => {
|
||||
const { name } = element
|
||||
const elementsOptions = blocks[name]
|
||||
if (elementsOptions) {
|
||||
normalizeOptionValue({
|
||||
singleline: elementsOptions.singleline || options.singleline,
|
||||
multiline: elementsOptions.multiline || options.multiline,
|
||||
maxEmptyLines:
|
||||
elementsOptions.maxEmptyLines == null
|
||||
? options.maxEmptyLines
|
||||
: elementsOptions.maxEmptyLines
|
||||
})(element)
|
||||
} else {
|
||||
verifyElement(element, options)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const documentFragment = df
|
||||
|
||||
const verify = normalizeOptionValue(context.options[0])
|
||||
|
||||
return utils.defineTemplateBodyVisitor(
|
||||
context,
|
||||
{},
|
||||
{
|
||||
/** @param {Program} node */
|
||||
Program(node) {
|
||||
if (utils.hasInvalidEOF(node)) {
|
||||
return
|
||||
}
|
||||
|
||||
for (const element of documentFragment.children) {
|
||||
if (utils.isVElement(element)) {
|
||||
verify(element)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
11
slider/node_modules/eslint-plugin-vue/lib/rules/brace-style.js
generated
vendored
Normal file
11
slider/node_modules/eslint-plugin-vue/lib/rules/brace-style.js
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* @author Yosuke Ota
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const { wrapStylisticOrCoreRule } = require('../utils')
|
||||
|
||||
// eslint-disable-next-line internal/no-invalid-meta
|
||||
module.exports = wrapStylisticOrCoreRule('brace-style', {
|
||||
skipDynamicArguments: true
|
||||
})
|
9
slider/node_modules/eslint-plugin-vue/lib/rules/camelcase.js
generated
vendored
Normal file
9
slider/node_modules/eslint-plugin-vue/lib/rules/camelcase.js
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
/**
|
||||
* @author Yosuke Ota
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const { wrapCoreRule } = require('../utils')
|
||||
|
||||
// eslint-disable-next-line internal/no-invalid-meta
|
||||
module.exports = wrapCoreRule('camelcase')
|
9
slider/node_modules/eslint-plugin-vue/lib/rules/comma-dangle.js
generated
vendored
Normal file
9
slider/node_modules/eslint-plugin-vue/lib/rules/comma-dangle.js
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
/**
|
||||
* @author Yosuke Ota
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const { wrapStylisticOrCoreRule } = require('../utils')
|
||||
|
||||
// eslint-disable-next-line internal/no-invalid-meta
|
||||
module.exports = wrapStylisticOrCoreRule('comma-dangle')
|
13
slider/node_modules/eslint-plugin-vue/lib/rules/comma-spacing.js
generated
vendored
Normal file
13
slider/node_modules/eslint-plugin-vue/lib/rules/comma-spacing.js
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* @author Yosuke Ota
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const { wrapStylisticOrCoreRule } = require('../utils')
|
||||
|
||||
// eslint-disable-next-line internal/no-invalid-meta
|
||||
module.exports = wrapStylisticOrCoreRule('comma-spacing', {
|
||||
skipDynamicArguments: true,
|
||||
skipDynamicArgumentsReport: true,
|
||||
applyDocument: true
|
||||
})
|
20
slider/node_modules/eslint-plugin-vue/lib/rules/comma-style.js
generated
vendored
Normal file
20
slider/node_modules/eslint-plugin-vue/lib/rules/comma-style.js
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* @author Yosuke Ota
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const { wrapStylisticOrCoreRule } = require('../utils')
|
||||
|
||||
// eslint-disable-next-line internal/no-invalid-meta
|
||||
module.exports = wrapStylisticOrCoreRule('comma-style', {
|
||||
create(_context, { baseHandlers }) {
|
||||
return {
|
||||
VSlotScopeExpression(node) {
|
||||
if (baseHandlers.FunctionExpression) {
|
||||
// @ts-expect-error -- Process params of VSlotScopeExpression as FunctionExpression.
|
||||
baseHandlers.FunctionExpression(node)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
356
slider/node_modules/eslint-plugin-vue/lib/rules/comment-directive.js
generated
vendored
Normal file
356
slider/node_modules/eslint-plugin-vue/lib/rules/comment-directive.js
generated
vendored
Normal file
@@ -0,0 +1,356 @@
|
||||
/**
|
||||
* @author Toru Nagashima <https://github.com/mysticatea>
|
||||
*/
|
||||
/* eslint-disable eslint-plugin/report-message-format */
|
||||
|
||||
'use strict'
|
||||
|
||||
const utils = require('../utils')
|
||||
|
||||
/**
|
||||
* @typedef {object} RuleAndLocation
|
||||
* @property {string} RuleAndLocation.ruleId
|
||||
* @property {number} RuleAndLocation.index
|
||||
* @property {string} [RuleAndLocation.key]
|
||||
*/
|
||||
|
||||
const COMMENT_DIRECTIVE_B = /^\s*(eslint-(?:en|dis)able)(?:\s+|$)/
|
||||
const COMMENT_DIRECTIVE_L = /^\s*(eslint-disable(?:-next)?-line)(?:\s+|$)/
|
||||
|
||||
/**
|
||||
* Remove the ignored part from a given directive comment and trim it.
|
||||
* @param {string} value The comment text to strip.
|
||||
* @returns {string} The stripped text.
|
||||
*/
|
||||
function stripDirectiveComment(value) {
|
||||
return value.split(/\s-{2,}\s/u)[0]
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a given comment.
|
||||
* @param {RegExp} pattern The RegExp pattern to parse.
|
||||
* @param {string} comment The comment value to parse.
|
||||
* @returns {({type:string,rules:RuleAndLocation[]})|null} The parsing result.
|
||||
*/
|
||||
function parse(pattern, comment) {
|
||||
const text = stripDirectiveComment(comment)
|
||||
const match = pattern.exec(text)
|
||||
if (match == null) {
|
||||
return null
|
||||
}
|
||||
|
||||
const type = match[1]
|
||||
|
||||
/** @type {RuleAndLocation[]} */
|
||||
const rules = []
|
||||
|
||||
const rulesRe = /([^\s,]+)[\s,]*/g
|
||||
let startIndex = match[0].length
|
||||
rulesRe.lastIndex = startIndex
|
||||
|
||||
let res
|
||||
while ((res = rulesRe.exec(text))) {
|
||||
const ruleId = res[1].trim()
|
||||
rules.push({
|
||||
ruleId,
|
||||
index: startIndex
|
||||
})
|
||||
startIndex = rulesRe.lastIndex
|
||||
}
|
||||
|
||||
return { type, rules }
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable rules.
|
||||
* @param {RuleContext} context The rule context.
|
||||
* @param {{line:number,column:number}} loc The location information to enable.
|
||||
* @param { 'block' | 'line' } group The group to enable.
|
||||
* @param {string | null} rule The rule ID to enable.
|
||||
* @returns {void}
|
||||
*/
|
||||
function enable(context, loc, group, rule) {
|
||||
if (rule) {
|
||||
context.report({
|
||||
loc,
|
||||
messageId: group === 'block' ? 'enableBlockRule' : 'enableLineRule',
|
||||
data: { rule }
|
||||
})
|
||||
} else {
|
||||
context.report({
|
||||
loc,
|
||||
messageId: group === 'block' ? 'enableBlock' : 'enableLine'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable rules.
|
||||
* @param {RuleContext} context The rule context.
|
||||
* @param {{line:number,column:number}} loc The location information to disable.
|
||||
* @param { 'block' | 'line' } group The group to disable.
|
||||
* @param {string | null} rule The rule ID to disable.
|
||||
* @param {string} key The disable directive key.
|
||||
* @returns {void}
|
||||
*/
|
||||
function disable(context, loc, group, rule, key) {
|
||||
if (rule) {
|
||||
context.report({
|
||||
loc,
|
||||
messageId: group === 'block' ? 'disableBlockRule' : 'disableLineRule',
|
||||
data: { rule, key }
|
||||
})
|
||||
} else {
|
||||
context.report({
|
||||
loc,
|
||||
messageId: group === 'block' ? 'disableBlock' : 'disableLine',
|
||||
data: { key }
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a given comment token.
|
||||
* If the comment is `eslint-disable` or `eslint-enable` then it reports the comment.
|
||||
* @param {RuleContext} context The rule context.
|
||||
* @param {Token} comment The comment token to process.
|
||||
* @param {boolean} reportUnusedDisableDirectives To report unused eslint-disable comments.
|
||||
* @returns {void}
|
||||
*/
|
||||
function processBlock(context, comment, reportUnusedDisableDirectives) {
|
||||
const parsed = parse(COMMENT_DIRECTIVE_B, comment.value)
|
||||
if (parsed === null) return
|
||||
|
||||
if (parsed.type === 'eslint-disable') {
|
||||
if (parsed.rules.length > 0) {
|
||||
const rules = reportUnusedDisableDirectives
|
||||
? reportUnusedRules(context, comment, parsed.type, parsed.rules)
|
||||
: parsed.rules
|
||||
for (const rule of rules) {
|
||||
disable(
|
||||
context,
|
||||
comment.loc.start,
|
||||
'block',
|
||||
rule.ruleId,
|
||||
rule.key || '*'
|
||||
)
|
||||
}
|
||||
} else {
|
||||
const key = reportUnusedDisableDirectives
|
||||
? reportUnused(context, comment, parsed.type)
|
||||
: ''
|
||||
disable(context, comment.loc.start, 'block', null, key)
|
||||
}
|
||||
} else {
|
||||
if (parsed.rules.length > 0) {
|
||||
for (const rule of parsed.rules) {
|
||||
enable(context, comment.loc.start, 'block', rule.ruleId)
|
||||
}
|
||||
} else {
|
||||
enable(context, comment.loc.start, 'block', null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a given comment token.
|
||||
* If the comment is `eslint-disable-line` or `eslint-disable-next-line` then it reports the comment.
|
||||
* @param {RuleContext} context The rule context.
|
||||
* @param {Token} comment The comment token to process.
|
||||
* @param {boolean} reportUnusedDisableDirectives To report unused eslint-disable comments.
|
||||
* @returns {void}
|
||||
*/
|
||||
function processLine(context, comment, reportUnusedDisableDirectives) {
|
||||
const parsed = parse(COMMENT_DIRECTIVE_L, comment.value)
|
||||
if (parsed != null && comment.loc.start.line === comment.loc.end.line) {
|
||||
const line =
|
||||
comment.loc.start.line + (parsed.type === 'eslint-disable-line' ? 0 : 1)
|
||||
const column = -1
|
||||
if (parsed.rules.length > 0) {
|
||||
const rules = reportUnusedDisableDirectives
|
||||
? reportUnusedRules(context, comment, parsed.type, parsed.rules)
|
||||
: parsed.rules
|
||||
for (const rule of rules) {
|
||||
disable(context, { line, column }, 'line', rule.ruleId, rule.key || '')
|
||||
enable(context, { line: line + 1, column }, 'line', rule.ruleId)
|
||||
}
|
||||
} else {
|
||||
const key = reportUnusedDisableDirectives
|
||||
? reportUnused(context, comment, parsed.type)
|
||||
: ''
|
||||
disable(context, { line, column }, 'line', null, key)
|
||||
enable(context, { line: line + 1, column }, 'line', null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports unused disable directive.
|
||||
* Do not check the use of directives here. Filter the directives used with postprocess.
|
||||
* @param {RuleContext} context The rule context.
|
||||
* @param {Token} comment The comment token to report.
|
||||
* @param {string} kind The comment directive kind.
|
||||
* @returns {string} The report key
|
||||
*/
|
||||
function reportUnused(context, comment, kind) {
|
||||
const loc = comment.loc
|
||||
|
||||
context.report({
|
||||
loc,
|
||||
messageId: 'unused',
|
||||
data: { kind }
|
||||
})
|
||||
|
||||
return locToKey(loc.start)
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports unused disable directive rules.
|
||||
* Do not check the use of directives here. Filter the directives used with postprocess.
|
||||
* @param {RuleContext} context The rule context.
|
||||
* @param {Token} comment The comment token to report.
|
||||
* @param {string} kind The comment directive kind.
|
||||
* @param {RuleAndLocation[]} rules To report rule.
|
||||
* @returns { { ruleId: string, key: string }[] }
|
||||
*/
|
||||
function reportUnusedRules(context, comment, kind, rules) {
|
||||
const sourceCode = context.getSourceCode()
|
||||
const commentStart = comment.range[0] + 4 /* <!-- */
|
||||
|
||||
return rules.map((rule) => {
|
||||
const start = sourceCode.getLocFromIndex(commentStart + rule.index)
|
||||
const end = sourceCode.getLocFromIndex(
|
||||
commentStart + rule.index + rule.ruleId.length
|
||||
)
|
||||
|
||||
context.report({
|
||||
loc: { start, end },
|
||||
messageId: 'unusedRule',
|
||||
data: { rule: rule.ruleId, kind }
|
||||
})
|
||||
|
||||
return {
|
||||
ruleId: rule.ruleId,
|
||||
key: locToKey(start)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the key of location
|
||||
* @param {Position} location The location
|
||||
* @returns {string} The key
|
||||
*/
|
||||
function locToKey(location) {
|
||||
return `line:${location.line},column${location.column}`
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the top-level elements in document fragment.
|
||||
* @param {VDocumentFragment} documentFragment The document fragment.
|
||||
* @returns {VElement[]} The top-level elements
|
||||
*/
|
||||
function extractTopLevelHTMLElements(documentFragment) {
|
||||
return documentFragment.children.filter(utils.isVElement)
|
||||
}
|
||||
/**
|
||||
* Extracts the top-level comments in document fragment.
|
||||
* @param {VDocumentFragment} documentFragment The document fragment.
|
||||
* @returns {Token[]} The top-level comments
|
||||
*/
|
||||
function extractTopLevelDocumentFragmentComments(documentFragment) {
|
||||
const elements = extractTopLevelHTMLElements(documentFragment)
|
||||
|
||||
return documentFragment.comments.filter((comment) =>
|
||||
elements.every(
|
||||
(element) =>
|
||||
comment.range[1] <= element.range[0] ||
|
||||
element.range[1] <= comment.range[0]
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description: 'support comment-directives in `<template>`', // eslint-disable-line eslint-plugin/require-meta-docs-description
|
||||
categories: ['base'],
|
||||
url: 'https://eslint.vuejs.org/rules/comment-directive.html'
|
||||
},
|
||||
schema: [
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
reportUnusedDisableDirectives: {
|
||||
type: 'boolean'
|
||||
}
|
||||
},
|
||||
additionalProperties: false
|
||||
}
|
||||
],
|
||||
messages: {
|
||||
disableBlock: '--block {{key}}',
|
||||
enableBlock: '++block',
|
||||
disableLine: '--line {{key}}',
|
||||
enableLine: '++line',
|
||||
disableBlockRule: '-block {{rule}} {{key}}',
|
||||
enableBlockRule: '+block {{rule}}',
|
||||
disableLineRule: '-line {{rule}} {{key}}',
|
||||
enableLineRule: '+line {{rule}}',
|
||||
clear: 'clear',
|
||||
|
||||
unused: 'Unused {{kind}} directive (no problems were reported).',
|
||||
unusedRule:
|
||||
"Unused {{kind}} directive (no problems were reported from '{{rule}}')."
|
||||
}
|
||||
},
|
||||
/**
|
||||
* @param {RuleContext} context - The rule context.
|
||||
* @returns {RuleListener} AST event handlers.
|
||||
*/
|
||||
create(context) {
|
||||
const options = context.options[0] || {}
|
||||
/** @type {boolean} */
|
||||
const reportUnusedDisableDirectives = options.reportUnusedDisableDirectives
|
||||
const sourceCode = context.getSourceCode()
|
||||
const documentFragment =
|
||||
sourceCode.parserServices.getDocumentFragment &&
|
||||
sourceCode.parserServices.getDocumentFragment()
|
||||
|
||||
return {
|
||||
Program(node) {
|
||||
if (node.templateBody) {
|
||||
// Send directives to the post-process.
|
||||
for (const comment of node.templateBody.comments) {
|
||||
processBlock(context, comment, reportUnusedDisableDirectives)
|
||||
processLine(context, comment, reportUnusedDisableDirectives)
|
||||
}
|
||||
|
||||
// Send a clear mark to the post-process.
|
||||
context.report({
|
||||
loc: node.templateBody.loc.end,
|
||||
messageId: 'clear'
|
||||
})
|
||||
}
|
||||
if (documentFragment) {
|
||||
// Send directives to the post-process.
|
||||
for (const comment of extractTopLevelDocumentFragmentComments(
|
||||
documentFragment
|
||||
)) {
|
||||
processBlock(context, comment, reportUnusedDisableDirectives)
|
||||
processLine(context, comment, reportUnusedDisableDirectives)
|
||||
}
|
||||
|
||||
// Send a clear mark to the post-process.
|
||||
for (const element of extractTopLevelHTMLElements(documentFragment)) {
|
||||
context.report({
|
||||
loc: element.loc.end,
|
||||
messageId: 'clear'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
308
slider/node_modules/eslint-plugin-vue/lib/rules/component-api-style.js
generated
vendored
Normal file
308
slider/node_modules/eslint-plugin-vue/lib/rules/component-api-style.js
generated
vendored
Normal file
@@ -0,0 +1,308 @@
|
||||
/**
|
||||
* @author Yosuke Ota <https://github.com/ota-meshi>
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const utils = require('../utils')
|
||||
|
||||
/**
|
||||
* @typedef { 'script-setup' | 'composition' | 'composition-vue2' | 'options' } PreferOption
|
||||
*
|
||||
* @typedef {PreferOption[]} UserPreferOption
|
||||
*
|
||||
* @typedef {object} NormalizeOptions
|
||||
* @property {object} allowsSFC
|
||||
* @property {boolean} [allowsSFC.scriptSetup]
|
||||
* @property {boolean} [allowsSFC.composition]
|
||||
* @property {boolean} [allowsSFC.compositionVue2]
|
||||
* @property {boolean} [allowsSFC.options]
|
||||
* @property {object} allowsOther
|
||||
* @property {boolean} [allowsOther.composition]
|
||||
* @property {boolean} [allowsOther.compositionVue2]
|
||||
* @property {boolean} [allowsOther.options]
|
||||
*/
|
||||
|
||||
/** @type {PreferOption[]} */
|
||||
const STYLE_OPTIONS = [
|
||||
'script-setup',
|
||||
'composition',
|
||||
'composition-vue2',
|
||||
'options'
|
||||
]
|
||||
|
||||
/**
|
||||
* Normalize options.
|
||||
* @param {any[]} options The options user configured.
|
||||
* @returns {NormalizeOptions} The normalized options.
|
||||
*/
|
||||
function parseOptions(options) {
|
||||
/** @type {NormalizeOptions} */
|
||||
const opts = { allowsSFC: {}, allowsOther: {} }
|
||||
|
||||
/** @type {UserPreferOption} */
|
||||
const preferOptions = options[0] || ['script-setup', 'composition']
|
||||
for (const prefer of preferOptions) {
|
||||
switch (prefer) {
|
||||
case 'script-setup': {
|
||||
opts.allowsSFC.scriptSetup = true
|
||||
break
|
||||
}
|
||||
case 'composition': {
|
||||
opts.allowsSFC.composition = true
|
||||
opts.allowsOther.composition = true
|
||||
break
|
||||
}
|
||||
case 'composition-vue2': {
|
||||
opts.allowsSFC.compositionVue2 = true
|
||||
opts.allowsOther.compositionVue2 = true
|
||||
break
|
||||
}
|
||||
case 'options': {
|
||||
opts.allowsSFC.options = true
|
||||
opts.allowsOther.options = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
!opts.allowsOther.composition &&
|
||||
!opts.allowsOther.compositionVue2 &&
|
||||
!opts.allowsOther.options
|
||||
) {
|
||||
opts.allowsOther.composition = true
|
||||
opts.allowsOther.compositionVue2 = true
|
||||
opts.allowsOther.options = true
|
||||
}
|
||||
|
||||
return opts
|
||||
}
|
||||
|
||||
const OPTIONS_API_OPTIONS = new Set([
|
||||
'mixins',
|
||||
'extends',
|
||||
// state
|
||||
'data',
|
||||
'computed',
|
||||
'methods',
|
||||
'watch',
|
||||
'provide',
|
||||
'inject',
|
||||
// lifecycle
|
||||
'beforeCreate',
|
||||
'created',
|
||||
'beforeMount',
|
||||
'mounted',
|
||||
'beforeUpdate',
|
||||
'updated',
|
||||
'activated',
|
||||
'deactivated',
|
||||
'beforeDestroy',
|
||||
'beforeUnmount',
|
||||
'destroyed',
|
||||
'unmounted',
|
||||
'render',
|
||||
'renderTracked',
|
||||
'renderTriggered',
|
||||
'errorCaptured',
|
||||
// public API
|
||||
'expose'
|
||||
])
|
||||
const COMPOSITION_API_OPTIONS = new Set(['setup'])
|
||||
|
||||
const COMPOSITION_API_VUE2_OPTIONS = new Set([
|
||||
'setup',
|
||||
'render', // https://github.com/vuejs/composition-api#template-refs
|
||||
'renderTracked', // https://github.com/vuejs/composition-api#missing-apis
|
||||
'renderTriggered' // https://github.com/vuejs/composition-api#missing-apis
|
||||
])
|
||||
|
||||
const LIFECYCLE_HOOK_OPTIONS = new Set([
|
||||
'beforeCreate',
|
||||
'created',
|
||||
'beforeMount',
|
||||
'mounted',
|
||||
'beforeUpdate',
|
||||
'updated',
|
||||
'activated',
|
||||
'deactivated',
|
||||
'beforeDestroy',
|
||||
'beforeUnmount',
|
||||
'destroyed',
|
||||
'unmounted',
|
||||
'renderTracked',
|
||||
'renderTriggered',
|
||||
'errorCaptured'
|
||||
])
|
||||
|
||||
/**
|
||||
* @typedef { 'script-setup' | 'composition' | 'options' } ApiStyle
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {object} allowsOpt
|
||||
* @param {boolean} [allowsOpt.scriptSetup]
|
||||
* @param {boolean} [allowsOpt.composition]
|
||||
* @param {boolean} [allowsOpt.compositionVue2]
|
||||
* @param {boolean} [allowsOpt.options]
|
||||
*/
|
||||
function buildAllowedPhrase(allowsOpt) {
|
||||
const phrases = []
|
||||
if (allowsOpt.scriptSetup) {
|
||||
phrases.push('`<script setup>`')
|
||||
}
|
||||
if (allowsOpt.composition) {
|
||||
phrases.push('Composition API')
|
||||
}
|
||||
if (allowsOpt.compositionVue2) {
|
||||
phrases.push('Composition API (Vue 2)')
|
||||
}
|
||||
if (allowsOpt.options) {
|
||||
phrases.push('Options API')
|
||||
}
|
||||
return phrases.length > 2
|
||||
? `${phrases.slice(0, -1).join(', ')} or ${phrases.slice(-1)[0]}`
|
||||
: phrases.join(' or ')
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {object} allowsOpt
|
||||
* @param {boolean} [allowsOpt.scriptSetup]
|
||||
* @param {boolean} [allowsOpt.composition]
|
||||
* @param {boolean} [allowsOpt.compositionVue2]
|
||||
* @param {boolean} [allowsOpt.options]
|
||||
*/
|
||||
function isPreferScriptSetup(allowsOpt) {
|
||||
if (
|
||||
!allowsOpt.scriptSetup ||
|
||||
allowsOpt.composition ||
|
||||
allowsOpt.compositionVue2 ||
|
||||
allowsOpt.options
|
||||
) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} name
|
||||
*/
|
||||
function buildOptionPhrase(name) {
|
||||
if (LIFECYCLE_HOOK_OPTIONS.has(name)) return `\`${name}\` lifecycle hook`
|
||||
|
||||
return name === 'setup' || name === 'render'
|
||||
? `\`${name}\` function`
|
||||
: `\`${name}\` option`
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'suggestion',
|
||||
docs: {
|
||||
description: 'enforce component API style',
|
||||
categories: undefined,
|
||||
url: 'https://eslint.vuejs.org/rules/component-api-style.html'
|
||||
},
|
||||
fixable: null,
|
||||
schema: [
|
||||
{
|
||||
type: 'array',
|
||||
items: {
|
||||
enum: STYLE_OPTIONS,
|
||||
uniqueItems: true,
|
||||
additionalItems: false
|
||||
},
|
||||
minItems: 1
|
||||
}
|
||||
],
|
||||
messages: {
|
||||
disallowScriptSetup:
|
||||
'`<script setup>` is not allowed in your project. Use {{allowedApis}} instead.',
|
||||
disallowComponentOption:
|
||||
'{{disallowedApi}} is not allowed in your project. {{optionPhrase}} is part of the {{disallowedApi}}. Use {{allowedApis}} instead.',
|
||||
disallowComponentOptionPreferScriptSetup:
|
||||
'{{disallowedApi}} is not allowed in your project. Use `<script setup>` instead.'
|
||||
}
|
||||
},
|
||||
/** @param {RuleContext} context */
|
||||
create(context) {
|
||||
const options = parseOptions(context.options)
|
||||
|
||||
return utils.compositingVisitors(
|
||||
{
|
||||
Program() {
|
||||
if (options.allowsSFC.scriptSetup) {
|
||||
return
|
||||
}
|
||||
const scriptSetup = utils.getScriptSetupElement(context)
|
||||
if (scriptSetup) {
|
||||
context.report({
|
||||
node: scriptSetup.startTag,
|
||||
messageId: 'disallowScriptSetup',
|
||||
data: {
|
||||
allowedApis: buildAllowedPhrase(options.allowsSFC)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
utils.defineVueVisitor(context, {
|
||||
onVueObjectEnter(node) {
|
||||
const allows = utils.isSFCObject(context, node)
|
||||
? options.allowsSFC
|
||||
: options.allowsOther
|
||||
if (
|
||||
(allows.composition || allows.compositionVue2) &&
|
||||
allows.options
|
||||
) {
|
||||
return
|
||||
}
|
||||
const apis = [
|
||||
{
|
||||
allow: allows.composition,
|
||||
options: COMPOSITION_API_OPTIONS,
|
||||
apiName: 'Composition API'
|
||||
},
|
||||
{
|
||||
allow: allows.options,
|
||||
options: OPTIONS_API_OPTIONS,
|
||||
apiName: 'Options API'
|
||||
},
|
||||
{
|
||||
allow: allows.compositionVue2,
|
||||
options: COMPOSITION_API_VUE2_OPTIONS,
|
||||
apiName: 'Composition API (Vue 2)'
|
||||
}
|
||||
]
|
||||
for (const prop of node.properties) {
|
||||
if (prop.type !== 'Property') {
|
||||
continue
|
||||
}
|
||||
const name = utils.getStaticPropertyName(prop)
|
||||
if (!name) {
|
||||
continue
|
||||
}
|
||||
const disallowApi =
|
||||
!apis.some((api) => api.allow && api.options.has(name)) &&
|
||||
apis.find((api) => !api.allow && api.options.has(name))
|
||||
|
||||
if (disallowApi) {
|
||||
context.report({
|
||||
node: prop.key,
|
||||
messageId: isPreferScriptSetup(allows)
|
||||
? 'disallowComponentOptionPreferScriptSetup'
|
||||
: 'disallowComponentOption',
|
||||
data: {
|
||||
disallowedApi: disallowApi.apiName,
|
||||
optionPhrase: buildOptionPhrase(name),
|
||||
allowedApis: buildAllowedPhrase(allows)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
113
slider/node_modules/eslint-plugin-vue/lib/rules/component-definition-name-casing.js
generated
vendored
Normal file
113
slider/node_modules/eslint-plugin-vue/lib/rules/component-definition-name-casing.js
generated
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
/**
|
||||
* @fileoverview enforce specific casing for component definition name
|
||||
* @author Armano
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const utils = require('../utils')
|
||||
const casing = require('../utils/casing')
|
||||
const allowedCaseOptions = ['PascalCase', 'kebab-case']
|
||||
|
||||
/**
|
||||
* @param {Expression | SpreadElement} node
|
||||
* @returns {node is (Literal | TemplateLiteral)}
|
||||
*/
|
||||
function canConvert(node) {
|
||||
return (
|
||||
node.type === 'Literal' ||
|
||||
(node.type === 'TemplateLiteral' &&
|
||||
node.expressions.length === 0 &&
|
||||
node.quasis.length === 1)
|
||||
)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'suggestion',
|
||||
docs: {
|
||||
description: 'enforce specific casing for component definition name',
|
||||
categories: ['vue3-strongly-recommended', 'vue2-strongly-recommended'],
|
||||
url: 'https://eslint.vuejs.org/rules/component-definition-name-casing.html'
|
||||
},
|
||||
fixable: 'code',
|
||||
schema: [
|
||||
{
|
||||
enum: allowedCaseOptions
|
||||
}
|
||||
],
|
||||
messages: {
|
||||
incorrectCase: 'Property name "{{value}}" is not {{caseType}}.'
|
||||
}
|
||||
},
|
||||
/** @param {RuleContext} context */
|
||||
create(context) {
|
||||
const options = context.options[0]
|
||||
const caseType = allowedCaseOptions.includes(options)
|
||||
? options
|
||||
: 'PascalCase'
|
||||
|
||||
/**
|
||||
* @param {Literal | TemplateLiteral} node
|
||||
*/
|
||||
function convertName(node) {
|
||||
/** @type {string} */
|
||||
let nodeValue
|
||||
/** @type {Range} */
|
||||
let range
|
||||
if (node.type === 'TemplateLiteral') {
|
||||
const quasis = node.quasis[0]
|
||||
nodeValue = quasis.value.cooked
|
||||
range = quasis.range
|
||||
} else {
|
||||
nodeValue = `${node.value}`
|
||||
range = node.range
|
||||
}
|
||||
|
||||
if (!casing.getChecker(caseType)(nodeValue)) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'incorrectCase',
|
||||
data: {
|
||||
value: nodeValue,
|
||||
caseType
|
||||
},
|
||||
fix: (fixer) =>
|
||||
fixer.replaceTextRange(
|
||||
[range[0] + 1, range[1] - 1],
|
||||
casing.getExactConverter(caseType)(nodeValue)
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return utils.compositingVisitors(
|
||||
utils.executeOnCallVueComponent(context, (node) => {
|
||||
if (node.arguments.length === 2) {
|
||||
const argument = node.arguments[0]
|
||||
|
||||
if (canConvert(argument)) {
|
||||
convertName(argument)
|
||||
}
|
||||
}
|
||||
}),
|
||||
utils.executeOnVue(context, (obj) => {
|
||||
const node = utils.findProperty(obj, 'name')
|
||||
|
||||
if (!node) return
|
||||
if (!canConvert(node.value)) return
|
||||
convertName(node.value)
|
||||
}),
|
||||
utils.defineScriptSetupVisitor(context, {
|
||||
onDefineOptionsEnter(node) {
|
||||
if (node.arguments.length === 0) return
|
||||
const define = node.arguments[0]
|
||||
if (define.type !== 'ObjectExpression') return
|
||||
const nameNode = utils.findProperty(define, 'name')
|
||||
if (!nameNode) return
|
||||
if (!canConvert(nameNode.value)) return
|
||||
convertName(nameNode.value)
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
209
slider/node_modules/eslint-plugin-vue/lib/rules/component-name-in-template-casing.js
generated
vendored
Normal file
209
slider/node_modules/eslint-plugin-vue/lib/rules/component-name-in-template-casing.js
generated
vendored
Normal file
@@ -0,0 +1,209 @@
|
||||
/**
|
||||
* @author Yosuke Ota
|
||||
* issue https://github.com/vuejs/eslint-plugin-vue/issues/250
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const utils = require('../utils')
|
||||
const casing = require('../utils/casing')
|
||||
const { toRegExpGroupMatcher, isRegExp } = require('../utils/regexp')
|
||||
|
||||
const allowedCaseOptions = ['PascalCase', 'kebab-case']
|
||||
const defaultCase = 'PascalCase'
|
||||
|
||||
/**
|
||||
* Checks whether the given variable is the type-only import object.
|
||||
* @param {Variable} variable
|
||||
* @returns {boolean} `true` if the given variable is the type-only import.
|
||||
*/
|
||||
function isTypeOnlyImport(variable) {
|
||||
if (variable.defs.length === 0) return false
|
||||
|
||||
return variable.defs.every((def) => {
|
||||
if (def.type !== 'ImportBinding') {
|
||||
return false
|
||||
}
|
||||
if (def.parent.importKind === 'type') {
|
||||
// check for `import type Foo from './xxx'`
|
||||
return true
|
||||
}
|
||||
if (def.node.type === 'ImportSpecifier' && def.node.importKind === 'type') {
|
||||
// check for `import { type Foo } from './xxx'`
|
||||
return true
|
||||
}
|
||||
return false
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'suggestion',
|
||||
docs: {
|
||||
description:
|
||||
'enforce specific casing for the component naming style in template',
|
||||
categories: undefined,
|
||||
url: 'https://eslint.vuejs.org/rules/component-name-in-template-casing.html'
|
||||
},
|
||||
fixable: 'code',
|
||||
schema: [
|
||||
{
|
||||
enum: allowedCaseOptions
|
||||
},
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
globals: {
|
||||
type: 'array',
|
||||
items: { type: 'string' },
|
||||
uniqueItems: true
|
||||
},
|
||||
ignores: {
|
||||
type: 'array',
|
||||
items: { type: 'string' },
|
||||
uniqueItems: true,
|
||||
additionalItems: false
|
||||
},
|
||||
registeredComponentsOnly: {
|
||||
type: 'boolean'
|
||||
}
|
||||
},
|
||||
additionalProperties: false
|
||||
}
|
||||
],
|
||||
messages: {
|
||||
incorrectCase: 'Component name "{{name}}" is not {{caseType}}.'
|
||||
}
|
||||
},
|
||||
/** @param {RuleContext} context */
|
||||
create(context) {
|
||||
const caseOption = context.options[0]
|
||||
const options = context.options[1] || {}
|
||||
const caseType = allowedCaseOptions.includes(caseOption)
|
||||
? caseOption
|
||||
: defaultCase
|
||||
const isIgnored = toRegExpGroupMatcher(options.ignores)
|
||||
|
||||
const globalStrings = []
|
||||
const globalPatterns = []
|
||||
for (const global of options.globals || []) {
|
||||
if (isRegExp(global)) {
|
||||
globalPatterns.push(global)
|
||||
} else {
|
||||
globalStrings.push(global)
|
||||
}
|
||||
}
|
||||
|
||||
const isGlobalPattern = toRegExpGroupMatcher(globalPatterns)
|
||||
const registeredComponentsOnly = options.registeredComponentsOnly !== false
|
||||
const sourceCode = context.getSourceCode()
|
||||
const tokens =
|
||||
sourceCode.parserServices.getTemplateBodyTokenStore &&
|
||||
sourceCode.parserServices.getTemplateBodyTokenStore()
|
||||
|
||||
/** @type { Set<string> } */
|
||||
const registeredComponents = new Set(globalStrings.map(casing.pascalCase))
|
||||
|
||||
if (utils.isScriptSetup(context)) {
|
||||
// For <script setup>
|
||||
const globalScope = context.getSourceCode().scopeManager.globalScope
|
||||
if (globalScope) {
|
||||
// Only check find the import module
|
||||
const moduleScope = globalScope.childScopes.find(
|
||||
(scope) => scope.type === 'module'
|
||||
)
|
||||
for (const variable of (moduleScope && moduleScope.variables) || []) {
|
||||
if (!isTypeOnlyImport(variable)) {
|
||||
registeredComponents.add(variable.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given node is the verification target node.
|
||||
* @param {VElement} node element node
|
||||
* @returns {boolean} `true` if the given node is the verification target node.
|
||||
*/
|
||||
function isVerifyTarget(node) {
|
||||
if (isIgnored(node.rawName)) {
|
||||
// ignore
|
||||
return false
|
||||
}
|
||||
|
||||
if (
|
||||
(!utils.isHtmlElementNode(node) &&
|
||||
!utils.isSvgElementNode(node) &&
|
||||
!utils.isMathElementNode(node)) ||
|
||||
utils.isHtmlWellKnownElementName(node.rawName) ||
|
||||
utils.isSvgWellKnownElementName(node.rawName) ||
|
||||
utils.isMathWellKnownElementName(node.rawName) ||
|
||||
utils.isVueBuiltInElementName(node.rawName)
|
||||
) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (!registeredComponentsOnly) {
|
||||
// If the user specifies registeredComponentsOnly as false, it checks all component tags.
|
||||
return true
|
||||
}
|
||||
|
||||
return (
|
||||
registeredComponents.has(casing.pascalCase(node.rawName)) ||
|
||||
isGlobalPattern(node.rawName)
|
||||
)
|
||||
}
|
||||
|
||||
let hasInvalidEOF = false
|
||||
|
||||
return utils.defineTemplateBodyVisitor(
|
||||
context,
|
||||
{
|
||||
VElement(node) {
|
||||
if (hasInvalidEOF) {
|
||||
return
|
||||
}
|
||||
|
||||
if (!isVerifyTarget(node)) {
|
||||
return
|
||||
}
|
||||
|
||||
const name = node.rawName
|
||||
if (!casing.getChecker(caseType)(name)) {
|
||||
const startTag = node.startTag
|
||||
const open = tokens.getFirstToken(startTag)
|
||||
const casingName = casing.getExactConverter(caseType)(name)
|
||||
context.report({
|
||||
node: open,
|
||||
loc: open.loc,
|
||||
messageId: 'incorrectCase',
|
||||
data: {
|
||||
name,
|
||||
caseType
|
||||
},
|
||||
*fix(fixer) {
|
||||
yield fixer.replaceText(open, `<${casingName}`)
|
||||
const endTag = node.endTag
|
||||
if (endTag) {
|
||||
const endTagOpen = tokens.getFirstToken(endTag)
|
||||
yield fixer.replaceText(endTagOpen, `</${casingName}`)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
Program(node) {
|
||||
hasInvalidEOF = utils.hasInvalidEOF(node)
|
||||
},
|
||||
...(registeredComponentsOnly
|
||||
? utils.executeOnVue(context, (obj) => {
|
||||
for (const n of utils.getRegisteredComponents(obj)) {
|
||||
registeredComponents.add(n.name)
|
||||
}
|
||||
})
|
||||
: {})
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
103
slider/node_modules/eslint-plugin-vue/lib/rules/component-options-name-casing.js
generated
vendored
Normal file
103
slider/node_modules/eslint-plugin-vue/lib/rules/component-options-name-casing.js
generated
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
/**
|
||||
* @author Pig Fang
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const utils = require('../utils')
|
||||
const casing = require('../utils/casing')
|
||||
|
||||
/**
|
||||
* @param {import('../../typings/eslint-plugin-vue/util-types/ast').Expression} node
|
||||
* @returns {string | null}
|
||||
*/
|
||||
function getOptionsComponentName(node) {
|
||||
if (node.type === 'Identifier') {
|
||||
return node.name
|
||||
}
|
||||
if (node.type === 'Literal') {
|
||||
return typeof node.value === 'string' ? node.value : null
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'suggestion',
|
||||
docs: {
|
||||
description:
|
||||
'enforce the casing of component name in `components` options',
|
||||
categories: undefined,
|
||||
url: 'https://eslint.vuejs.org/rules/component-options-name-casing.html'
|
||||
},
|
||||
fixable: 'code',
|
||||
hasSuggestions: true,
|
||||
schema: [{ enum: casing.allowedCaseOptions }],
|
||||
messages: {
|
||||
caseNotMatched: 'Component name "{{component}}" is not {{caseType}}.',
|
||||
possibleRenaming: 'Rename component name to be in {{caseType}}.'
|
||||
}
|
||||
},
|
||||
/** @param {RuleContext} context */
|
||||
create(context) {
|
||||
const caseType = context.options[0] || 'PascalCase'
|
||||
|
||||
const canAutoFix = caseType === 'PascalCase'
|
||||
const checkCase = casing.getChecker(caseType)
|
||||
const convert = casing.getConverter(caseType)
|
||||
|
||||
return utils.executeOnVue(context, (obj) => {
|
||||
const node = utils.findProperty(obj, 'components')
|
||||
if (!node || node.value.type !== 'ObjectExpression') {
|
||||
return
|
||||
}
|
||||
|
||||
for (const property of node.value.properties) {
|
||||
if (property.type !== 'Property') {
|
||||
continue
|
||||
}
|
||||
|
||||
const name = getOptionsComponentName(property.key)
|
||||
if (!name || checkCase(name)) {
|
||||
continue
|
||||
}
|
||||
|
||||
context.report({
|
||||
node: property.key,
|
||||
messageId: 'caseNotMatched',
|
||||
data: {
|
||||
component: name,
|
||||
caseType
|
||||
},
|
||||
fix: canAutoFix
|
||||
? (fixer) => {
|
||||
const converted = convert(name)
|
||||
return property.shorthand
|
||||
? fixer.replaceText(property, `${converted}: ${name}`)
|
||||
: fixer.replaceText(property.key, converted)
|
||||
}
|
||||
: undefined,
|
||||
suggest: canAutoFix
|
||||
? undefined
|
||||
: [
|
||||
{
|
||||
messageId: 'possibleRenaming',
|
||||
data: { caseType },
|
||||
fix: (fixer) => {
|
||||
const converted = convert(name)
|
||||
if (caseType === 'kebab-case') {
|
||||
return property.shorthand
|
||||
? fixer.replaceText(property, `'${converted}': ${name}`)
|
||||
: fixer.replaceText(property.key, `'${converted}'`)
|
||||
}
|
||||
return property.shorthand
|
||||
? fixer.replaceText(property, `${converted}: ${name}`)
|
||||
: fixer.replaceText(property.key, converted)
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
296
slider/node_modules/eslint-plugin-vue/lib/rules/custom-event-name-casing.js
generated
vendored
Normal file
296
slider/node_modules/eslint-plugin-vue/lib/rules/custom-event-name-casing.js
generated
vendored
Normal file
@@ -0,0 +1,296 @@
|
||||
/**
|
||||
* @author Yosuke Ota
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const { findVariable } = require('@eslint-community/eslint-utils')
|
||||
const utils = require('../utils')
|
||||
const casing = require('../utils/casing')
|
||||
const { toRegExpGroupMatcher } = require('../utils/regexp')
|
||||
|
||||
/**
|
||||
* @typedef {import('../utils').VueObjectData} VueObjectData
|
||||
*/
|
||||
|
||||
const ALLOWED_CASE_OPTIONS = ['kebab-case', 'camelCase']
|
||||
const DEFAULT_CASE = 'camelCase'
|
||||
|
||||
/**
|
||||
* @typedef {object} NameWithLoc
|
||||
* @property {string} name
|
||||
* @property {SourceLocation} loc
|
||||
*/
|
||||
/**
|
||||
* Get the name param node from the given CallExpression
|
||||
* @param {CallExpression} node CallExpression
|
||||
* @returns { NameWithLoc | null }
|
||||
*/
|
||||
function getNameParamNode(node) {
|
||||
const nameLiteralNode = node.arguments[0]
|
||||
if (nameLiteralNode && utils.isStringLiteral(nameLiteralNode)) {
|
||||
const name = utils.getStringLiteralValue(nameLiteralNode)
|
||||
if (name != null) {
|
||||
return { name, loc: nameLiteralNode.loc }
|
||||
}
|
||||
}
|
||||
|
||||
// cannot check
|
||||
return null
|
||||
}
|
||||
/**
|
||||
* Get the callee member node from the given CallExpression
|
||||
* @param {CallExpression} node CallExpression
|
||||
*/
|
||||
function getCalleeMemberNode(node) {
|
||||
const callee = utils.skipChainExpression(node.callee)
|
||||
|
||||
if (callee.type === 'MemberExpression') {
|
||||
const name = utils.getStaticPropertyName(callee)
|
||||
if (name) {
|
||||
return { name, member: callee }
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'suggestion',
|
||||
docs: {
|
||||
description: 'enforce specific casing for custom event name',
|
||||
categories: undefined,
|
||||
url: 'https://eslint.vuejs.org/rules/custom-event-name-casing.html'
|
||||
},
|
||||
fixable: null,
|
||||
schema: [
|
||||
{
|
||||
enum: ALLOWED_CASE_OPTIONS
|
||||
},
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
ignores: {
|
||||
type: 'array',
|
||||
items: { type: 'string' },
|
||||
uniqueItems: true,
|
||||
additionalItems: false
|
||||
}
|
||||
},
|
||||
additionalProperties: false
|
||||
}
|
||||
],
|
||||
messages: {
|
||||
unexpected: "Custom event name '{{name}}' must be {{caseType}}."
|
||||
}
|
||||
},
|
||||
/** @param {RuleContext} context */
|
||||
create(context) {
|
||||
/** @type {Map<ObjectExpression|Program, {contextReferenceIds:Set<Identifier>,emitReferenceIds:Set<Identifier>}>} */
|
||||
const setupContexts = new Map()
|
||||
let emitParamName = ''
|
||||
const caseType = context.options[0] || DEFAULT_CASE
|
||||
const objectOption = context.options[1] || {}
|
||||
const caseChecker = casing.getChecker(caseType)
|
||||
const isIgnored = toRegExpGroupMatcher(objectOption.ignores)
|
||||
|
||||
/**
|
||||
* Check whether the given event name is valid.
|
||||
* @param {string} name The name to check.
|
||||
* @returns {boolean} `true` if the given event name is valid.
|
||||
*/
|
||||
function isValidEventName(name) {
|
||||
return caseChecker(name) || name.startsWith('update:')
|
||||
}
|
||||
|
||||
/**
|
||||
* @param { NameWithLoc } nameWithLoc
|
||||
*/
|
||||
function verify(nameWithLoc) {
|
||||
const name = nameWithLoc.name
|
||||
if (isValidEventName(name) || isIgnored(name)) {
|
||||
return
|
||||
}
|
||||
context.report({
|
||||
loc: nameWithLoc.loc,
|
||||
messageId: 'unexpected',
|
||||
data: {
|
||||
name,
|
||||
caseType
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const programNode = context.getSourceCode().ast
|
||||
|
||||
const callVisitor = {
|
||||
/**
|
||||
* @param {CallExpression} node
|
||||
* @param {VueObjectData} [info]
|
||||
*/
|
||||
CallExpression(node, info) {
|
||||
const nameWithLoc = getNameParamNode(node)
|
||||
if (!nameWithLoc) {
|
||||
// cannot check
|
||||
return
|
||||
}
|
||||
|
||||
// verify setup context
|
||||
const setupContext = setupContexts.get(info ? info.node : programNode)
|
||||
if (setupContext) {
|
||||
const { contextReferenceIds, emitReferenceIds } = setupContext
|
||||
if (
|
||||
node.callee.type === 'Identifier' &&
|
||||
emitReferenceIds.has(node.callee)
|
||||
) {
|
||||
// verify setup(props,{emit}) {emit()}
|
||||
verify(nameWithLoc)
|
||||
} else {
|
||||
const emit = getCalleeMemberNode(node)
|
||||
if (
|
||||
emit &&
|
||||
emit.name === 'emit' &&
|
||||
emit.member.object.type === 'Identifier' &&
|
||||
contextReferenceIds.has(emit.member.object)
|
||||
) {
|
||||
// verify setup(props,context) {context.emit()}
|
||||
verify(nameWithLoc)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return utils.defineTemplateBodyVisitor(
|
||||
context,
|
||||
{
|
||||
CallExpression(node) {
|
||||
const callee = node.callee
|
||||
const nameWithLoc = getNameParamNode(node)
|
||||
if (!nameWithLoc) {
|
||||
// cannot check
|
||||
return
|
||||
}
|
||||
|
||||
if (
|
||||
callee.type === 'Identifier' &&
|
||||
(callee.name === '$emit' || callee.name === emitParamName)
|
||||
) {
|
||||
verify(nameWithLoc)
|
||||
}
|
||||
}
|
||||
},
|
||||
utils.compositingVisitors(
|
||||
utils.defineScriptSetupVisitor(context, {
|
||||
onDefineEmitsEnter(node) {
|
||||
if (
|
||||
!node.parent ||
|
||||
node.parent.type !== 'VariableDeclarator' ||
|
||||
node.parent.init !== node
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
||||
const emitParam = node.parent.id
|
||||
if (emitParam.type !== 'Identifier') {
|
||||
return
|
||||
}
|
||||
emitParamName = emitParam.name
|
||||
|
||||
// const emit = defineEmits()
|
||||
const variable = findVariable(
|
||||
utils.getScope(context, emitParam),
|
||||
emitParam
|
||||
)
|
||||
if (!variable) {
|
||||
return
|
||||
}
|
||||
const emitReferenceIds = new Set()
|
||||
for (const reference of variable.references) {
|
||||
emitReferenceIds.add(reference.identifier)
|
||||
}
|
||||
setupContexts.set(programNode, {
|
||||
contextReferenceIds: new Set(),
|
||||
emitReferenceIds
|
||||
})
|
||||
},
|
||||
...callVisitor
|
||||
}),
|
||||
utils.defineVueVisitor(context, {
|
||||
onSetupFunctionEnter(node, { node: vueNode }) {
|
||||
const contextParam = utils.skipDefaultParamValue(node.params[1])
|
||||
if (!contextParam) {
|
||||
// no arguments
|
||||
return
|
||||
}
|
||||
if (
|
||||
contextParam.type === 'RestElement' ||
|
||||
contextParam.type === 'ArrayPattern'
|
||||
) {
|
||||
// cannot check
|
||||
return
|
||||
}
|
||||
const contextReferenceIds = new Set()
|
||||
const emitReferenceIds = new Set()
|
||||
if (contextParam.type === 'ObjectPattern') {
|
||||
const emitProperty = utils.findAssignmentProperty(
|
||||
contextParam,
|
||||
'emit'
|
||||
)
|
||||
if (!emitProperty || emitProperty.value.type !== 'Identifier') {
|
||||
return
|
||||
}
|
||||
const emitParam = emitProperty.value
|
||||
// `setup(props, {emit})`
|
||||
const variable = findVariable(
|
||||
utils.getScope(context, emitParam),
|
||||
emitParam
|
||||
)
|
||||
if (!variable) {
|
||||
return
|
||||
}
|
||||
for (const reference of variable.references) {
|
||||
emitReferenceIds.add(reference.identifier)
|
||||
}
|
||||
} else {
|
||||
// `setup(props, context)`
|
||||
const variable = findVariable(
|
||||
utils.getScope(context, contextParam),
|
||||
contextParam
|
||||
)
|
||||
if (!variable) {
|
||||
return
|
||||
}
|
||||
for (const reference of variable.references) {
|
||||
contextReferenceIds.add(reference.identifier)
|
||||
}
|
||||
}
|
||||
setupContexts.set(vueNode, {
|
||||
contextReferenceIds,
|
||||
emitReferenceIds
|
||||
})
|
||||
},
|
||||
...callVisitor,
|
||||
onVueObjectExit(node) {
|
||||
setupContexts.delete(node)
|
||||
}
|
||||
}),
|
||||
{
|
||||
CallExpression(node) {
|
||||
const nameLiteralNode = getNameParamNode(node)
|
||||
if (!nameLiteralNode) {
|
||||
// cannot check
|
||||
return
|
||||
}
|
||||
const emit = getCalleeMemberNode(node)
|
||||
// verify $emit
|
||||
if (emit && emit.name === '$emit') {
|
||||
// verify this.$emit()
|
||||
verify(nameLiteralNode)
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
106
slider/node_modules/eslint-plugin-vue/lib/rules/define-emits-declaration.js
generated
vendored
Normal file
106
slider/node_modules/eslint-plugin-vue/lib/rules/define-emits-declaration.js
generated
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
/**
|
||||
* @author Amorites
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const utils = require('../utils')
|
||||
|
||||
/**
|
||||
* @typedef {import('@typescript-eslint/types').TSESTree.TypeNode} TypeNode
|
||||
*
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'suggestion',
|
||||
docs: {
|
||||
description: 'enforce declaration style of `defineEmits`',
|
||||
categories: undefined,
|
||||
url: 'https://eslint.vuejs.org/rules/define-emits-declaration.html'
|
||||
},
|
||||
fixable: null,
|
||||
schema: [
|
||||
{
|
||||
enum: ['type-based', 'type-literal', 'runtime']
|
||||
}
|
||||
],
|
||||
messages: {
|
||||
hasArg: 'Use type based declaration instead of runtime declaration.',
|
||||
hasTypeArg: 'Use runtime declaration instead of type based declaration.',
|
||||
hasTypeCallArg:
|
||||
'Use new type literal declaration instead of the old call signature declaration.'
|
||||
}
|
||||
},
|
||||
/** @param {RuleContext} context */
|
||||
create(context) {
|
||||
const scriptSetup = utils.getScriptSetupElement(context)
|
||||
if (!scriptSetup || !utils.hasAttribute(scriptSetup, 'lang', 'ts')) {
|
||||
return {}
|
||||
}
|
||||
|
||||
const defineType = context.options[0] || 'type-based'
|
||||
return utils.defineScriptSetupVisitor(context, {
|
||||
onDefineEmitsEnter(node) {
|
||||
switch (defineType) {
|
||||
case 'type-based': {
|
||||
if (node.arguments.length > 0) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'hasArg'
|
||||
})
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
case 'type-literal': {
|
||||
verifyTypeLiteral(node)
|
||||
break
|
||||
}
|
||||
|
||||
case 'runtime': {
|
||||
const typeArguments =
|
||||
'typeArguments' in node ? node.typeArguments : node.typeParameters
|
||||
if (typeArguments && typeArguments.params.length > 0) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'hasTypeArg'
|
||||
})
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
/** @param {CallExpression} node */
|
||||
function verifyTypeLiteral(node) {
|
||||
if (node.arguments.length > 0) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'hasArg'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
const typeArguments = node.typeArguments || node.typeParameters
|
||||
const param = /** @type {TypeNode|undefined} */ (typeArguments?.params[0])
|
||||
if (!param) return
|
||||
if (param.type === 'TSTypeLiteral') {
|
||||
for (const memberNode of param.members) {
|
||||
if (memberNode.type !== 'TSPropertySignature') {
|
||||
context.report({
|
||||
node: memberNode,
|
||||
messageId: 'hasTypeCallArg'
|
||||
})
|
||||
}
|
||||
}
|
||||
} else if (param.type === 'TSFunctionType') {
|
||||
context.report({
|
||||
node: param,
|
||||
messageId: 'hasTypeCallArg'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
404
slider/node_modules/eslint-plugin-vue/lib/rules/define-macros-order.js
generated
vendored
Normal file
404
slider/node_modules/eslint-plugin-vue/lib/rules/define-macros-order.js
generated
vendored
Normal file
@@ -0,0 +1,404 @@
|
||||
/**
|
||||
* @author Eduard Deisling
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const utils = require('../utils')
|
||||
|
||||
const MACROS_EMITS = 'defineEmits'
|
||||
const MACROS_PROPS = 'defineProps'
|
||||
const MACROS_OPTIONS = 'defineOptions'
|
||||
const MACROS_SLOTS = 'defineSlots'
|
||||
const MACROS_MODEL = 'defineModel'
|
||||
const MACROS_EXPOSE = 'defineExpose'
|
||||
const KNOWN_MACROS = new Set([
|
||||
MACROS_EMITS,
|
||||
MACROS_PROPS,
|
||||
MACROS_OPTIONS,
|
||||
MACROS_SLOTS,
|
||||
MACROS_MODEL,
|
||||
MACROS_EXPOSE
|
||||
])
|
||||
const DEFAULT_ORDER = [MACROS_PROPS, MACROS_EMITS]
|
||||
|
||||
/**
|
||||
* @param {VElement} scriptSetup
|
||||
* @param {ASTNode} node
|
||||
*/
|
||||
function inScriptSetup(scriptSetup, node) {
|
||||
return (
|
||||
scriptSetup.range[0] <= node.range[0] &&
|
||||
node.range[1] <= scriptSetup.range[1]
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ASTNode} node
|
||||
*/
|
||||
function isDeclareStatement(node) {
|
||||
return 'declare' in node && node.declare === true
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ASTNode} node
|
||||
*/
|
||||
function isUseStrictStatement(node) {
|
||||
return (
|
||||
node.type === 'ExpressionStatement' &&
|
||||
node.expression.type === 'Literal' &&
|
||||
node.expression.value === 'use strict'
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an index of the first statement after imports and interfaces in order
|
||||
* to place defineEmits and defineProps before this statement
|
||||
* @param {VElement} scriptSetup
|
||||
* @param {Program} program
|
||||
*/
|
||||
function getTargetStatementPosition(scriptSetup, program) {
|
||||
const skipStatements = new Set([
|
||||
'ImportDeclaration',
|
||||
'TSEnumDeclaration',
|
||||
'TSModuleDeclaration',
|
||||
'TSInterfaceDeclaration',
|
||||
'TSTypeAliasDeclaration',
|
||||
'DebuggerStatement',
|
||||
'EmptyStatement',
|
||||
'ExportNamedDeclaration'
|
||||
])
|
||||
|
||||
for (const [index, item] of program.body.entries()) {
|
||||
if (
|
||||
inScriptSetup(scriptSetup, item) &&
|
||||
!skipStatements.has(item.type) &&
|
||||
!isDeclareStatement(item) &&
|
||||
!isUseStrictStatement(item)
|
||||
) {
|
||||
return index
|
||||
}
|
||||
}
|
||||
|
||||
return -1
|
||||
}
|
||||
|
||||
/**
|
||||
* We need to handle cases like "const props = defineProps(...)"
|
||||
* Define macros must be used only on top, so we can look for "Program" type
|
||||
* inside node.parent.type
|
||||
* @param {CallExpression|ASTNode} node
|
||||
* @return {ASTNode}
|
||||
*/
|
||||
function getDefineMacrosStatement(node) {
|
||||
if (!node.parent) {
|
||||
throw new Error('Node has no parent')
|
||||
}
|
||||
|
||||
if (node.parent.type === 'Program') {
|
||||
return node
|
||||
}
|
||||
|
||||
return getDefineMacrosStatement(node.parent)
|
||||
}
|
||||
|
||||
/** @param {RuleContext} context */
|
||||
function create(context) {
|
||||
const scriptSetup = utils.getScriptSetupElement(context)
|
||||
|
||||
if (!scriptSetup) {
|
||||
return {}
|
||||
}
|
||||
|
||||
const sourceCode = context.getSourceCode()
|
||||
const options = context.options
|
||||
/** @type {[string, string]} */
|
||||
const order = (options[0] && options[0].order) || DEFAULT_ORDER
|
||||
/** @type {boolean} */
|
||||
const defineExposeLast = (options[0] && options[0].defineExposeLast) || false
|
||||
/** @type {Map<string, ASTNode[]>} */
|
||||
const macrosNodes = new Map()
|
||||
/** @type {ASTNode} */
|
||||
let defineExposeNode
|
||||
|
||||
if (order.includes(MACROS_EXPOSE) && defineExposeLast) {
|
||||
throw new Error(
|
||||
"`defineExpose` macro can't be in the `order` array if `defineExposeLast` is true."
|
||||
)
|
||||
}
|
||||
|
||||
return utils.compositingVisitors(
|
||||
utils.defineScriptSetupVisitor(context, {
|
||||
onDefinePropsExit(node) {
|
||||
macrosNodes.set(MACROS_PROPS, [getDefineMacrosStatement(node)])
|
||||
},
|
||||
onDefineEmitsExit(node) {
|
||||
macrosNodes.set(MACROS_EMITS, [getDefineMacrosStatement(node)])
|
||||
},
|
||||
onDefineOptionsExit(node) {
|
||||
macrosNodes.set(MACROS_OPTIONS, [getDefineMacrosStatement(node)])
|
||||
},
|
||||
onDefineSlotsExit(node) {
|
||||
macrosNodes.set(MACROS_SLOTS, [getDefineMacrosStatement(node)])
|
||||
},
|
||||
onDefineModelExit(node) {
|
||||
const currentModelMacros = macrosNodes.get(MACROS_MODEL) ?? []
|
||||
currentModelMacros.push(getDefineMacrosStatement(node))
|
||||
macrosNodes.set(MACROS_MODEL, currentModelMacros)
|
||||
},
|
||||
onDefineExposeExit(node) {
|
||||
defineExposeNode = getDefineMacrosStatement(node)
|
||||
},
|
||||
|
||||
/** @param {CallExpression} node */
|
||||
'Program > ExpressionStatement > CallExpression, Program > VariableDeclaration > VariableDeclarator > CallExpression'(
|
||||
node
|
||||
) {
|
||||
if (
|
||||
node.callee &&
|
||||
node.callee.type === 'Identifier' &&
|
||||
order.includes(node.callee.name) &&
|
||||
!KNOWN_MACROS.has(node.callee.name)
|
||||
) {
|
||||
macrosNodes.set(node.callee.name, [getDefineMacrosStatement(node)])
|
||||
}
|
||||
}
|
||||
}),
|
||||
{
|
||||
'Program:exit'(program) {
|
||||
/**
|
||||
* @typedef {object} OrderedData
|
||||
* @property {string} name
|
||||
* @property {ASTNode} node
|
||||
*/
|
||||
const firstStatementIndex = getTargetStatementPosition(
|
||||
scriptSetup,
|
||||
program
|
||||
)
|
||||
const orderedList = order
|
||||
.flatMap((name) => {
|
||||
const nodes = macrosNodes.get(name) ?? []
|
||||
return nodes.map((node) => ({ name, node }))
|
||||
})
|
||||
.filter(
|
||||
/** @returns {data is OrderedData} */
|
||||
(data) => utils.isDef(data.node)
|
||||
)
|
||||
|
||||
// check last node
|
||||
if (defineExposeLast) {
|
||||
const lastNode = program.body[program.body.length - 1]
|
||||
if (defineExposeNode && lastNode !== defineExposeNode) {
|
||||
reportExposeNotOnBottom(defineExposeNode, lastNode)
|
||||
}
|
||||
}
|
||||
|
||||
for (const [index, should] of orderedList.entries()) {
|
||||
const targetStatement = program.body[firstStatementIndex + index]
|
||||
|
||||
if (should.node !== targetStatement) {
|
||||
let moveTargetNodes = orderedList
|
||||
.slice(index)
|
||||
.map(({ node }) => node)
|
||||
const targetStatementIndex =
|
||||
moveTargetNodes.indexOf(targetStatement)
|
||||
|
||||
if (targetStatementIndex !== -1) {
|
||||
moveTargetNodes = moveTargetNodes.slice(0, targetStatementIndex)
|
||||
}
|
||||
reportNotOnTop(should.name, moveTargetNodes, targetStatement)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
/**
|
||||
* @param {string} macro
|
||||
* @param {ASTNode[]} nodes
|
||||
* @param {ASTNode} before
|
||||
*/
|
||||
function reportNotOnTop(macro, nodes, before) {
|
||||
context.report({
|
||||
node: nodes[0],
|
||||
loc: nodes[0].loc,
|
||||
messageId: 'macrosNotOnTop',
|
||||
data: {
|
||||
macro
|
||||
},
|
||||
*fix(fixer) {
|
||||
for (const node of nodes) {
|
||||
yield* moveNodeBefore(fixer, node, before)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ASTNode} node
|
||||
* @param {ASTNode} lastNode
|
||||
*/
|
||||
function reportExposeNotOnBottom(node, lastNode) {
|
||||
context.report({
|
||||
node,
|
||||
loc: node.loc,
|
||||
messageId: 'defineExposeNotTheLast',
|
||||
suggest: [
|
||||
{
|
||||
messageId: 'putExposeAtTheLast',
|
||||
fix(fixer) {
|
||||
return moveNodeToLast(fixer, node, lastNode)
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Move all lines of "node" with its comments to after the "target"
|
||||
* @param {RuleFixer} fixer
|
||||
* @param {ASTNode} node
|
||||
* @param {ASTNode} target
|
||||
*/
|
||||
function moveNodeToLast(fixer, node, target) {
|
||||
// get comments under tokens(if any)
|
||||
const beforeNodeToken = sourceCode.getTokenBefore(node)
|
||||
const nodeComment = sourceCode.getTokenAfter(beforeNodeToken, {
|
||||
includeComments: true
|
||||
})
|
||||
const nextNodeComment = sourceCode.getTokenAfter(node, {
|
||||
includeComments: true
|
||||
})
|
||||
|
||||
// remove position: node (and comments) to next node (and comments)
|
||||
const cutStart = getLineStartIndex(nodeComment, beforeNodeToken)
|
||||
const cutEnd = getLineStartIndex(nextNodeComment, node)
|
||||
|
||||
// insert text: comment + node
|
||||
const textNode = sourceCode.getText(
|
||||
node,
|
||||
node.range[0] - beforeNodeToken.range[1]
|
||||
)
|
||||
|
||||
return [
|
||||
fixer.insertTextAfter(target, textNode),
|
||||
fixer.removeRange([cutStart, cutEnd])
|
||||
]
|
||||
}
|
||||
|
||||
/**
|
||||
* Move all lines of "node" with its comments to before the "target"
|
||||
* @param {RuleFixer} fixer
|
||||
* @param {ASTNode} node
|
||||
* @param {ASTNode} target
|
||||
*/
|
||||
function moveNodeBefore(fixer, node, target) {
|
||||
// get comments under tokens(if any)
|
||||
const beforeNodeToken = sourceCode.getTokenBefore(node)
|
||||
const nodeComment = sourceCode.getTokenAfter(beforeNodeToken, {
|
||||
includeComments: true
|
||||
})
|
||||
const nextNodeComment = sourceCode.getTokenAfter(node, {
|
||||
includeComments: true
|
||||
})
|
||||
// get positions of what we need to remove
|
||||
const cutStart = getLineStartIndex(nodeComment, beforeNodeToken)
|
||||
const cutEnd = getLineStartIndex(nextNodeComment, node)
|
||||
// get space before target
|
||||
const beforeTargetToken = sourceCode.getTokenBefore(target)
|
||||
const targetComment = sourceCode.getTokenAfter(beforeTargetToken, {
|
||||
includeComments: true
|
||||
})
|
||||
// make insert text: comments + node + space before target
|
||||
const textNode = sourceCode.getText(
|
||||
node,
|
||||
node.range[0] - nodeComment.range[0]
|
||||
)
|
||||
const insertText = getInsertText(textNode, target)
|
||||
|
||||
return [
|
||||
fixer.insertTextBefore(targetComment, insertText),
|
||||
fixer.removeRange([cutStart, cutEnd])
|
||||
]
|
||||
}
|
||||
|
||||
/**
|
||||
* Get result text to insert
|
||||
* @param {string} textNode
|
||||
* @param {ASTNode} target
|
||||
*/
|
||||
function getInsertText(textNode, target) {
|
||||
const afterTargetComment = sourceCode.getTokenAfter(target, {
|
||||
includeComments: true
|
||||
})
|
||||
const afterText = sourceCode.text.slice(
|
||||
target.range[1],
|
||||
afterTargetComment.range[0]
|
||||
)
|
||||
// handle case when a();b() -> b()a();
|
||||
const invalidResult = !textNode.endsWith(';') && !afterText.includes('\n')
|
||||
|
||||
return textNode + afterText + (invalidResult ? ';' : '')
|
||||
}
|
||||
|
||||
/**
|
||||
* Get position of the beginning of the token's line(or prevToken end if no line)
|
||||
* @param {ASTNode|Token} token
|
||||
* @param {ASTNode|Token} prevToken
|
||||
*/
|
||||
function getLineStartIndex(token, prevToken) {
|
||||
// if we have next token on the same line - get index right before that token
|
||||
if (token.loc.start.line === prevToken.loc.end.line) {
|
||||
return prevToken.range[1]
|
||||
}
|
||||
|
||||
return sourceCode.getIndexFromLoc({
|
||||
line: token.loc.start.line,
|
||||
column: 0
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'layout',
|
||||
docs: {
|
||||
description:
|
||||
'enforce order of compiler macros (`defineProps`, `defineEmits`, etc.)',
|
||||
categories: undefined,
|
||||
url: 'https://eslint.vuejs.org/rules/define-macros-order.html'
|
||||
},
|
||||
fixable: 'code',
|
||||
hasSuggestions: true,
|
||||
schema: [
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
order: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'string',
|
||||
minLength: 1
|
||||
},
|
||||
uniqueItems: true,
|
||||
additionalItems: false
|
||||
},
|
||||
defineExposeLast: {
|
||||
type: 'boolean'
|
||||
}
|
||||
},
|
||||
additionalProperties: false
|
||||
}
|
||||
],
|
||||
messages: {
|
||||
macrosNotOnTop:
|
||||
'{{macro}} should be the first statement in `<script setup>` (after any potential import statements or type definitions).',
|
||||
defineExposeNotTheLast:
|
||||
'`defineExpose` should be the last statement in `<script setup>`.',
|
||||
putExposeAtTheLast:
|
||||
'Put `defineExpose` as the last statement in `<script setup>`.'
|
||||
}
|
||||
},
|
||||
create
|
||||
}
|
64
slider/node_modules/eslint-plugin-vue/lib/rules/define-props-declaration.js
generated
vendored
Normal file
64
slider/node_modules/eslint-plugin-vue/lib/rules/define-props-declaration.js
generated
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* @author Amorites
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const utils = require('../utils')
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'suggestion',
|
||||
docs: {
|
||||
description: 'enforce declaration style of `defineProps`',
|
||||
categories: undefined,
|
||||
url: 'https://eslint.vuejs.org/rules/define-props-declaration.html'
|
||||
},
|
||||
fixable: null,
|
||||
schema: [
|
||||
{
|
||||
enum: ['type-based', 'runtime']
|
||||
}
|
||||
],
|
||||
messages: {
|
||||
hasArg: 'Use type-based declaration instead of runtime declaration.',
|
||||
hasTypeArg: 'Use runtime declaration instead of type-based declaration.'
|
||||
}
|
||||
},
|
||||
/** @param {RuleContext} context */
|
||||
create(context) {
|
||||
const scriptSetup = utils.getScriptSetupElement(context)
|
||||
if (!scriptSetup || !utils.hasAttribute(scriptSetup, 'lang', 'ts')) {
|
||||
return {}
|
||||
}
|
||||
|
||||
const defineType = context.options[0] || 'type-based'
|
||||
return utils.defineScriptSetupVisitor(context, {
|
||||
onDefinePropsEnter(node) {
|
||||
switch (defineType) {
|
||||
case 'type-based': {
|
||||
if (node.arguments.length > 0) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'hasArg'
|
||||
})
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
case 'runtime': {
|
||||
const typeArguments =
|
||||
'typeArguments' in node ? node.typeArguments : node.typeParameters
|
||||
if (typeArguments && typeArguments.params.length > 0) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'hasTypeArg'
|
||||
})
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
79
slider/node_modules/eslint-plugin-vue/lib/rules/define-props-destructuring.js
generated
vendored
Normal file
79
slider/node_modules/eslint-plugin-vue/lib/rules/define-props-destructuring.js
generated
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* @author Wayne Zhang
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const utils = require('../utils')
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'suggestion',
|
||||
docs: {
|
||||
description: 'enforce consistent style for props destructuring',
|
||||
categories: undefined,
|
||||
url: 'https://eslint.vuejs.org/rules/define-props-destructuring.html'
|
||||
},
|
||||
fixable: null,
|
||||
schema: [
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
destructure: {
|
||||
enum: ['always', 'never']
|
||||
}
|
||||
},
|
||||
additionalProperties: false
|
||||
}
|
||||
],
|
||||
messages: {
|
||||
preferDestructuring: 'Prefer destructuring from `defineProps` directly.',
|
||||
avoidDestructuring: 'Avoid destructuring from `defineProps`.',
|
||||
avoidWithDefaults: 'Avoid using `withDefaults` with destructuring.'
|
||||
}
|
||||
},
|
||||
/** @param {RuleContext} context */
|
||||
create(context) {
|
||||
const options = context.options[0] || {}
|
||||
const destructurePreference = options.destructure || 'always'
|
||||
|
||||
return utils.compositingVisitors(
|
||||
utils.defineScriptSetupVisitor(context, {
|
||||
onDefinePropsEnter(node, props) {
|
||||
const hasNoArgs = props.filter((prop) => prop.propName).length === 0
|
||||
if (hasNoArgs) {
|
||||
return
|
||||
}
|
||||
|
||||
const hasDestructure = utils.isUsingPropsDestructure(node)
|
||||
const hasWithDefaults = utils.hasWithDefaults(node)
|
||||
|
||||
if (destructurePreference === 'never') {
|
||||
if (hasDestructure) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'avoidDestructuring'
|
||||
})
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if (!hasDestructure) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'preferDestructuring'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if (hasWithDefaults) {
|
||||
context.report({
|
||||
node: node.parent.callee,
|
||||
messageId: 'avoidWithDefaults'
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
9
slider/node_modules/eslint-plugin-vue/lib/rules/dot-location.js
generated
vendored
Normal file
9
slider/node_modules/eslint-plugin-vue/lib/rules/dot-location.js
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
/**
|
||||
* @author Yosuke Ota
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const { wrapStylisticOrCoreRule } = require('../utils')
|
||||
|
||||
// eslint-disable-next-line internal/no-invalid-meta
|
||||
module.exports = wrapStylisticOrCoreRule('dot-location')
|
11
slider/node_modules/eslint-plugin-vue/lib/rules/dot-notation.js
generated
vendored
Normal file
11
slider/node_modules/eslint-plugin-vue/lib/rules/dot-notation.js
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* @author Yosuke Ota
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const { wrapStylisticOrCoreRule } = require('../utils')
|
||||
|
||||
// eslint-disable-next-line internal/no-invalid-meta
|
||||
module.exports = wrapStylisticOrCoreRule('dot-notation', {
|
||||
applyDocument: true
|
||||
})
|
154
slider/node_modules/eslint-plugin-vue/lib/rules/enforce-style-attribute.js
generated
vendored
Normal file
154
slider/node_modules/eslint-plugin-vue/lib/rules/enforce-style-attribute.js
generated
vendored
Normal file
@@ -0,0 +1,154 @@
|
||||
/**
|
||||
* @author Mussin Benarbia
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const { isVElement } = require('../utils')
|
||||
|
||||
/**
|
||||
* check whether a tag has the `scoped` attribute
|
||||
* @param {VElement} componentBlock
|
||||
*/
|
||||
function isScoped(componentBlock) {
|
||||
return componentBlock.startTag.attributes.some(
|
||||
(attribute) => !attribute.directive && attribute.key.name === 'scoped'
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* check whether a tag has the `module` attribute
|
||||
* @param {VElement} componentBlock
|
||||
*/
|
||||
function isModule(componentBlock) {
|
||||
return componentBlock.startTag.attributes.some(
|
||||
(attribute) => !attribute.directive && attribute.key.name === 'module'
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* check if a tag doesn't have either the `scoped` nor `module` attribute
|
||||
* @param {VElement} componentBlock
|
||||
*/
|
||||
function isPlain(componentBlock) {
|
||||
return !isScoped(componentBlock) && !isModule(componentBlock)
|
||||
}
|
||||
|
||||
/** @param {RuleContext} context */
|
||||
function getUserDefinedAllowedAttrs(context) {
|
||||
if (context.options[0] && context.options[0].allow) {
|
||||
return context.options[0].allow
|
||||
}
|
||||
return []
|
||||
}
|
||||
|
||||
const defaultAllowedAttrs = ['scoped']
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'suggestion',
|
||||
docs: {
|
||||
description:
|
||||
'enforce or forbid the use of the `scoped` and `module` attributes in SFC top level style tags',
|
||||
categories: undefined,
|
||||
url: 'https://eslint.vuejs.org/rules/enforce-style-attribute.html'
|
||||
},
|
||||
fixable: null,
|
||||
schema: [
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
allow: {
|
||||
type: 'array',
|
||||
minItems: 1,
|
||||
uniqueItems: true,
|
||||
items: {
|
||||
type: 'string',
|
||||
enum: ['plain', 'scoped', 'module']
|
||||
}
|
||||
}
|
||||
},
|
||||
additionalProperties: false
|
||||
}
|
||||
],
|
||||
messages: {
|
||||
notAllowedScoped:
|
||||
'The scoped attribute is not allowed. Allowed: {{ allowedAttrsString }}.',
|
||||
notAllowedModule:
|
||||
'The module attribute is not allowed. Allowed: {{ allowedAttrsString }}.',
|
||||
notAllowedPlain:
|
||||
'Plain <style> tags are not allowed. Allowed: {{ allowedAttrsString }}.'
|
||||
}
|
||||
},
|
||||
|
||||
/** @param {RuleContext} context */
|
||||
create(context) {
|
||||
const sourceCode = context.getSourceCode()
|
||||
if (!sourceCode.parserServices.getDocumentFragment) {
|
||||
return {}
|
||||
}
|
||||
const documentFragment = sourceCode.parserServices.getDocumentFragment()
|
||||
if (!documentFragment) {
|
||||
return {}
|
||||
}
|
||||
|
||||
const topLevelStyleTags = documentFragment.children.filter(
|
||||
/** @returns {element is VElement} */
|
||||
(element) => isVElement(element) && element.rawName === 'style'
|
||||
)
|
||||
|
||||
if (topLevelStyleTags.length === 0) {
|
||||
return {}
|
||||
}
|
||||
|
||||
const userDefinedAllowedAttrs = getUserDefinedAllowedAttrs(context)
|
||||
const allowedAttrs =
|
||||
userDefinedAllowedAttrs.length > 0
|
||||
? userDefinedAllowedAttrs
|
||||
: defaultAllowedAttrs
|
||||
|
||||
const allowsPlain = allowedAttrs.includes('plain')
|
||||
const allowsScoped = allowedAttrs.includes('scoped')
|
||||
const allowsModule = allowedAttrs.includes('module')
|
||||
const allowedAttrsString = [...allowedAttrs].sort().join(', ')
|
||||
|
||||
return {
|
||||
Program() {
|
||||
for (const styleTag of topLevelStyleTags) {
|
||||
if (!allowsPlain && isPlain(styleTag)) {
|
||||
context.report({
|
||||
node: styleTag,
|
||||
messageId: 'notAllowedPlain',
|
||||
data: {
|
||||
allowedAttrsString
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if (!allowsScoped && isScoped(styleTag)) {
|
||||
context.report({
|
||||
node: styleTag,
|
||||
messageId: 'notAllowedScoped',
|
||||
data: {
|
||||
allowedAttrsString
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if (!allowsModule && isModule(styleTag)) {
|
||||
context.report({
|
||||
node: styleTag,
|
||||
messageId: 'notAllowedModule',
|
||||
data: {
|
||||
allowedAttrsString
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
11
slider/node_modules/eslint-plugin-vue/lib/rules/eqeqeq.js
generated
vendored
Normal file
11
slider/node_modules/eslint-plugin-vue/lib/rules/eqeqeq.js
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* @author Toru Nagashima
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const { wrapCoreRule } = require('../utils')
|
||||
|
||||
// eslint-disable-next-line internal/no-invalid-meta
|
||||
module.exports = wrapCoreRule('eqeqeq', {
|
||||
applyDocument: true
|
||||
})
|
96
slider/node_modules/eslint-plugin-vue/lib/rules/first-attribute-linebreak.js
generated
vendored
Normal file
96
slider/node_modules/eslint-plugin-vue/lib/rules/first-attribute-linebreak.js
generated
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
/**
|
||||
* @fileoverview Enforce the location of first attribute
|
||||
* @author Yosuke Ota
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const utils = require('../utils')
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'layout',
|
||||
docs: {
|
||||
description: 'enforce the location of first attribute',
|
||||
categories: ['vue3-strongly-recommended', 'vue2-strongly-recommended'],
|
||||
url: 'https://eslint.vuejs.org/rules/first-attribute-linebreak.html'
|
||||
},
|
||||
fixable: 'whitespace',
|
||||
schema: [
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
multiline: { enum: ['below', 'beside', 'ignore'] },
|
||||
singleline: { enum: ['below', 'beside', 'ignore'] }
|
||||
},
|
||||
additionalProperties: false
|
||||
}
|
||||
],
|
||||
messages: {
|
||||
expected: 'Expected a linebreak before this attribute.',
|
||||
unexpected: 'Expected no linebreak before this attribute.'
|
||||
}
|
||||
},
|
||||
/** @param {RuleContext} context */
|
||||
create(context) {
|
||||
/** @type {"below" | "beside" | "ignore"} */
|
||||
const singleline =
|
||||
(context.options[0] && context.options[0].singleline) || 'ignore'
|
||||
/** @type {"below" | "beside" | "ignore"} */
|
||||
const multiline =
|
||||
(context.options[0] && context.options[0].multiline) || 'below'
|
||||
|
||||
const sourceCode = context.getSourceCode()
|
||||
const template =
|
||||
sourceCode.parserServices.getTemplateBodyTokenStore &&
|
||||
sourceCode.parserServices.getTemplateBodyTokenStore()
|
||||
|
||||
/**
|
||||
* Report attribute
|
||||
* @param {VAttribute | VDirective} firstAttribute
|
||||
* @param { "below" | "beside"} location
|
||||
*/
|
||||
function report(firstAttribute, location) {
|
||||
context.report({
|
||||
node: firstAttribute,
|
||||
messageId: location === 'beside' ? 'unexpected' : 'expected',
|
||||
fix(fixer) {
|
||||
const prevToken = template.getTokenBefore(firstAttribute, {
|
||||
includeComments: true
|
||||
})
|
||||
return fixer.replaceTextRange(
|
||||
[prevToken.range[1], firstAttribute.range[0]],
|
||||
location === 'beside' ? ' ' : '\n'
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return utils.defineTemplateBodyVisitor(context, {
|
||||
VStartTag(node) {
|
||||
const firstAttribute = node.attributes[0]
|
||||
if (!firstAttribute) return
|
||||
|
||||
const lastAttribute = node.attributes[node.attributes.length - 1]
|
||||
|
||||
const location =
|
||||
firstAttribute.loc.start.line === lastAttribute.loc.end.line
|
||||
? singleline
|
||||
: multiline
|
||||
if (location === 'ignore') {
|
||||
return
|
||||
}
|
||||
|
||||
if (location === 'beside') {
|
||||
if (node.loc.start.line === firstAttribute.loc.start.line) {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if (node.loc.start.line < firstAttribute.loc.start.line) {
|
||||
return
|
||||
}
|
||||
}
|
||||
report(firstAttribute, location)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
19
slider/node_modules/eslint-plugin-vue/lib/rules/func-call-spacing.js
generated
vendored
Normal file
19
slider/node_modules/eslint-plugin-vue/lib/rules/func-call-spacing.js
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* @author Yosuke Ota
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const { wrapStylisticOrCoreRule } = require('../utils')
|
||||
|
||||
// eslint-disable-next-line internal/no-invalid-meta
|
||||
module.exports = wrapStylisticOrCoreRule(
|
||||
{
|
||||
core: 'func-call-spacing',
|
||||
stylistic: 'function-call-spacing',
|
||||
vue: 'func-call-spacing'
|
||||
},
|
||||
{
|
||||
skipDynamicArguments: true,
|
||||
applyDocument: true
|
||||
}
|
||||
)
|
130
slider/node_modules/eslint-plugin-vue/lib/rules/html-button-has-type.js
generated
vendored
Normal file
130
slider/node_modules/eslint-plugin-vue/lib/rules/html-button-has-type.js
generated
vendored
Normal file
@@ -0,0 +1,130 @@
|
||||
/**
|
||||
* @fileoverview Disallow usage of button without an explicit type attribute
|
||||
* @author Jonathan Santerre <jonathan@santerre.dev>
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const utils = require('../utils')
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} type
|
||||
* @returns {type is 'button' | 'submit' | 'reset'}
|
||||
*/
|
||||
function isButtonType(type) {
|
||||
return type === 'button' || type === 'submit' || type === 'reset'
|
||||
}
|
||||
|
||||
const optionDefaults = {
|
||||
button: true,
|
||||
submit: true,
|
||||
reset: true
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'suggestion',
|
||||
docs: {
|
||||
description:
|
||||
'disallow usage of button without an explicit type attribute',
|
||||
categories: null,
|
||||
url: 'https://eslint.vuejs.org/rules/html-button-has-type.html'
|
||||
},
|
||||
fixable: null,
|
||||
schema: [
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
button: { type: 'boolean' },
|
||||
submit: { type: 'boolean' },
|
||||
reset: { type: 'boolean' }
|
||||
},
|
||||
additionalProperties: false
|
||||
}
|
||||
],
|
||||
messages: {
|
||||
missingTypeAttribute: 'Missing an explicit type attribute for button.',
|
||||
invalidTypeAttribute:
|
||||
'{{value}} is an invalid value for button type attribute.',
|
||||
forbiddenTypeAttribute:
|
||||
'{{value}} is a forbidden value for button type attribute.',
|
||||
emptyTypeAttribute: 'A value must be set for button type attribute.'
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {RuleContext} context - The rule context.
|
||||
* @returns {RuleListener} AST event handlers.
|
||||
*/
|
||||
create(context) {
|
||||
/**
|
||||
* @typedef {object} Configuration
|
||||
* @property {boolean} button
|
||||
* @property {boolean} submit
|
||||
* @property {boolean} reset
|
||||
*/
|
||||
/** @type {Configuration} */
|
||||
const configuration = Object.assign({}, optionDefaults, context.options[0])
|
||||
|
||||
/**
|
||||
* @param {ASTNode} node
|
||||
* @param {string} messageId
|
||||
* @param {any} [data]
|
||||
*/
|
||||
function report(node, messageId, data) {
|
||||
context.report({
|
||||
node,
|
||||
messageId,
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {VAttribute} attribute
|
||||
*/
|
||||
function validateAttribute(attribute) {
|
||||
const value = attribute.value
|
||||
if (!value || !value.value) {
|
||||
report(value || attribute, 'emptyTypeAttribute')
|
||||
return
|
||||
}
|
||||
|
||||
const strValue = value.value
|
||||
if (!isButtonType(strValue)) {
|
||||
report(value, 'invalidTypeAttribute', { value: strValue })
|
||||
} else if (!configuration[strValue]) {
|
||||
report(value, 'forbiddenTypeAttribute', { value: strValue })
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {VDirective} directive
|
||||
*/
|
||||
function validateDirective(directive) {
|
||||
const value = directive.value
|
||||
if (!value || !value.expression) {
|
||||
report(value || directive, 'emptyTypeAttribute')
|
||||
}
|
||||
}
|
||||
|
||||
return utils.defineTemplateBodyVisitor(context, {
|
||||
/**
|
||||
* @param {VElement} node
|
||||
*/
|
||||
"VElement[rawName='button']"(node) {
|
||||
const typeAttr = utils.getAttribute(node, 'type')
|
||||
if (typeAttr) {
|
||||
validateAttribute(typeAttr)
|
||||
return
|
||||
}
|
||||
const typeDir = utils.getDirective(node, 'bind', 'type')
|
||||
if (typeDir) {
|
||||
validateDirective(typeDir)
|
||||
return
|
||||
}
|
||||
|
||||
report(node.startTag, 'missingTypeAttribute')
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
160
slider/node_modules/eslint-plugin-vue/lib/rules/html-closing-bracket-newline.js
generated
vendored
Normal file
160
slider/node_modules/eslint-plugin-vue/lib/rules/html-closing-bracket-newline.js
generated
vendored
Normal file
@@ -0,0 +1,160 @@
|
||||
/**
|
||||
* @author Toru Nagashima
|
||||
* @copyright 2016 Toru Nagashima. All rights reserved.
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const utils = require('../utils')
|
||||
|
||||
/**
|
||||
* @param {number} lineBreaks
|
||||
*/
|
||||
function getPhrase(lineBreaks) {
|
||||
switch (lineBreaks) {
|
||||
case 0: {
|
||||
return 'no line breaks'
|
||||
}
|
||||
case 1: {
|
||||
return '1 line break'
|
||||
}
|
||||
default: {
|
||||
return `${lineBreaks} line breaks`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef LineBreakBehavior
|
||||
* @type {('always'|'never')}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef LineType
|
||||
* @type {('singleline'|'multiline')}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef RuleOptions
|
||||
* @type {object}
|
||||
* @property {LineBreakBehavior} singleline - The behavior for single line tags.
|
||||
* @property {LineBreakBehavior} multiline - The behavior for multiline tags.
|
||||
* @property {object} selfClosingTag
|
||||
* @property {LineBreakBehavior} selfClosingTag.singleline - The behavior for single line self closing tags.
|
||||
* @property {LineBreakBehavior} selfClosingTag.multiline - The behavior for multiline self closing tags.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {VStartTag | VEndTag} node - The node representing a start or end tag.
|
||||
* @param {RuleOptions} options - The options for line breaks.
|
||||
* @param {LineType} type - The type of line break.
|
||||
* @returns {number} - The expected line breaks.
|
||||
*/
|
||||
function getExpectedLineBreaks(node, options, type) {
|
||||
const isSelfClosingTag = node.type === 'VStartTag' && node.selfClosing
|
||||
if (
|
||||
isSelfClosingTag &&
|
||||
options.selfClosingTag &&
|
||||
options.selfClosingTag[type]
|
||||
) {
|
||||
return options.selfClosingTag[type] === 'always' ? 1 : 0
|
||||
}
|
||||
|
||||
return options[type] === 'always' ? 1 : 0
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'layout',
|
||||
docs: {
|
||||
description:
|
||||
"require or disallow a line break before tag's closing brackets",
|
||||
categories: ['vue3-strongly-recommended', 'vue2-strongly-recommended'],
|
||||
url: 'https://eslint.vuejs.org/rules/html-closing-bracket-newline.html'
|
||||
},
|
||||
fixable: 'whitespace',
|
||||
schema: [
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
singleline: { enum: ['always', 'never'] },
|
||||
multiline: { enum: ['always', 'never'] },
|
||||
selfClosingTag: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
singleline: { enum: ['always', 'never'] },
|
||||
multiline: { enum: ['always', 'never'] }
|
||||
},
|
||||
additionalProperties: false,
|
||||
minProperties: 1
|
||||
}
|
||||
},
|
||||
additionalProperties: false
|
||||
}
|
||||
],
|
||||
messages: {
|
||||
expectedBeforeClosingBracket:
|
||||
'Expected {{expected}} before closing bracket, but {{actual}} found.'
|
||||
}
|
||||
},
|
||||
/** @param {RuleContext} context */
|
||||
create(context) {
|
||||
const options = Object.assign(
|
||||
{},
|
||||
{
|
||||
singleline: 'never',
|
||||
multiline: 'always'
|
||||
},
|
||||
context.options[0] || {}
|
||||
)
|
||||
const sourceCode = context.getSourceCode()
|
||||
const template =
|
||||
sourceCode.parserServices.getTemplateBodyTokenStore &&
|
||||
sourceCode.parserServices.getTemplateBodyTokenStore()
|
||||
|
||||
return utils.defineDocumentVisitor(context, {
|
||||
/** @param {VStartTag | VEndTag} node */
|
||||
'VStartTag, VEndTag'(node) {
|
||||
const closingBracketToken = template.getLastToken(node)
|
||||
if (
|
||||
closingBracketToken.type !== 'HTMLSelfClosingTagClose' &&
|
||||
closingBracketToken.type !== 'HTMLTagClose'
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
||||
const prevToken = template.getTokenBefore(closingBracketToken)
|
||||
const type =
|
||||
node.loc.start.line === prevToken.loc.end.line
|
||||
? 'singleline'
|
||||
: 'multiline'
|
||||
|
||||
const expectedLineBreaks = getExpectedLineBreaks(node, options, type)
|
||||
|
||||
const actualLineBreaks =
|
||||
closingBracketToken.loc.start.line - prevToken.loc.end.line
|
||||
|
||||
if (actualLineBreaks !== expectedLineBreaks) {
|
||||
context.report({
|
||||
node,
|
||||
loc: {
|
||||
start: prevToken.loc.end,
|
||||
end: closingBracketToken.loc.start
|
||||
},
|
||||
messageId: 'expectedBeforeClosingBracket',
|
||||
data: {
|
||||
expected: getPhrase(expectedLineBreaks),
|
||||
actual: getPhrase(actualLineBreaks)
|
||||
},
|
||||
fix(fixer) {
|
||||
/** @type {Range} */
|
||||
const range = [prevToken.range[1], closingBracketToken.range[0]]
|
||||
const text = '\n'.repeat(expectedLineBreaks)
|
||||
return fixer.replaceTextRange(range, text)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
129
slider/node_modules/eslint-plugin-vue/lib/rules/html-closing-bracket-spacing.js
generated
vendored
Normal file
129
slider/node_modules/eslint-plugin-vue/lib/rules/html-closing-bracket-spacing.js
generated
vendored
Normal file
@@ -0,0 +1,129 @@
|
||||
/**
|
||||
* @author Toru Nagashima <https://github.com/mysticatea>
|
||||
*/
|
||||
|
||||
'use strict'
|
||||
|
||||
const utils = require('../utils')
|
||||
|
||||
/**
|
||||
* @typedef { {startTag?:"always"|"never",endTag?:"always"|"never",selfClosingTag?:"always"|"never"} } Options
|
||||
*/
|
||||
|
||||
/**
|
||||
* Normalize options.
|
||||
* @param {Options} options The options user configured.
|
||||
* @param {ParserServices.TokenStore} tokens The token store of template body.
|
||||
* @returns {Options & { detectType: (node: VStartTag | VEndTag) => 'never' | 'always' | null }} The normalized options.
|
||||
*/
|
||||
function parseOptions(options, tokens) {
|
||||
const opts = Object.assign(
|
||||
{
|
||||
startTag: 'never',
|
||||
endTag: 'never',
|
||||
selfClosingTag: 'always'
|
||||
},
|
||||
options
|
||||
)
|
||||
return Object.assign(opts, {
|
||||
/**
|
||||
* @param {VStartTag | VEndTag} node
|
||||
* @returns {'never' | 'always' | null}
|
||||
*/
|
||||
detectType(node) {
|
||||
const openType = tokens.getFirstToken(node).type
|
||||
const closeType = tokens.getLastToken(node).type
|
||||
|
||||
if (openType === 'HTMLEndTagOpen' && closeType === 'HTMLTagClose') {
|
||||
return opts.endTag
|
||||
}
|
||||
if (openType === 'HTMLTagOpen' && closeType === 'HTMLTagClose') {
|
||||
return opts.startTag
|
||||
}
|
||||
if (
|
||||
openType === 'HTMLTagOpen' &&
|
||||
closeType === 'HTMLSelfClosingTagClose'
|
||||
) {
|
||||
return opts.selfClosingTag
|
||||
}
|
||||
return null
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'layout',
|
||||
docs: {
|
||||
description: "require or disallow a space before tag's closing brackets",
|
||||
categories: ['vue3-strongly-recommended', 'vue2-strongly-recommended'],
|
||||
url: 'https://eslint.vuejs.org/rules/html-closing-bracket-spacing.html'
|
||||
},
|
||||
fixable: 'whitespace',
|
||||
schema: [
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
startTag: { enum: ['always', 'never'] },
|
||||
endTag: { enum: ['always', 'never'] },
|
||||
selfClosingTag: { enum: ['always', 'never'] }
|
||||
},
|
||||
additionalProperties: false
|
||||
}
|
||||
],
|
||||
messages: {
|
||||
missing: "Expected a space before '{{bracket}}', but not found.",
|
||||
unexpected: "Expected no space before '{{bracket}}', but found."
|
||||
}
|
||||
},
|
||||
/** @param {RuleContext} context */
|
||||
create(context) {
|
||||
const sourceCode = context.getSourceCode()
|
||||
const tokens =
|
||||
sourceCode.parserServices.getTemplateBodyTokenStore &&
|
||||
sourceCode.parserServices.getTemplateBodyTokenStore()
|
||||
const options = parseOptions(context.options[0], tokens)
|
||||
|
||||
return utils.defineDocumentVisitor(context, {
|
||||
/** @param {VStartTag | VEndTag} node */
|
||||
'VStartTag, VEndTag'(node) {
|
||||
const type = options.detectType(node)
|
||||
const lastToken = tokens.getLastToken(node)
|
||||
const prevToken = tokens.getLastToken(node, 1)
|
||||
|
||||
// Skip if EOF exists in the tag or linebreak exists before `>`.
|
||||
if (
|
||||
type == null ||
|
||||
prevToken == null ||
|
||||
prevToken.loc.end.line !== lastToken.loc.start.line
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
||||
// Check and report.
|
||||
const hasSpace = prevToken.range[1] !== lastToken.range[0]
|
||||
if (type === 'always' && !hasSpace) {
|
||||
context.report({
|
||||
node,
|
||||
loc: lastToken.loc,
|
||||
messageId: 'missing',
|
||||
data: { bracket: sourceCode.getText(lastToken) },
|
||||
fix: (fixer) => fixer.insertTextBefore(lastToken, ' ')
|
||||
})
|
||||
} else if (type === 'never' && hasSpace) {
|
||||
context.report({
|
||||
node,
|
||||
loc: {
|
||||
start: prevToken.loc.end,
|
||||
end: lastToken.loc.end
|
||||
},
|
||||
messageId: 'unexpected',
|
||||
data: { bracket: sourceCode.getText(lastToken) },
|
||||
fix: (fixer) =>
|
||||
fixer.removeRange([prevToken.range[1], lastToken.range[0]])
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
203
slider/node_modules/eslint-plugin-vue/lib/rules/html-comment-content-newline.js
generated
vendored
Normal file
203
slider/node_modules/eslint-plugin-vue/lib/rules/html-comment-content-newline.js
generated
vendored
Normal file
@@ -0,0 +1,203 @@
|
||||
/**
|
||||
* @author Yosuke ota
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const htmlComments = require('../utils/html-comments')
|
||||
|
||||
/**
|
||||
* @typedef { import('../utils/html-comments').ParsedHTMLComment } ParsedHTMLComment
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {any} param
|
||||
*/
|
||||
function parseOption(param) {
|
||||
if (param && typeof param === 'string') {
|
||||
return {
|
||||
singleline: param,
|
||||
multiline: param
|
||||
}
|
||||
}
|
||||
return Object.assign(
|
||||
{
|
||||
singleline: 'never',
|
||||
multiline: 'always'
|
||||
},
|
||||
param
|
||||
)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'layout',
|
||||
|
||||
docs: {
|
||||
description: 'enforce unified line break in HTML comments',
|
||||
categories: undefined,
|
||||
url: 'https://eslint.vuejs.org/rules/html-comment-content-newline.html'
|
||||
},
|
||||
fixable: 'whitespace',
|
||||
schema: [
|
||||
{
|
||||
oneOf: [
|
||||
{
|
||||
enum: ['always', 'never']
|
||||
},
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
singleline: { enum: ['always', 'never', 'ignore'] },
|
||||
multiline: { enum: ['always', 'never', 'ignore'] }
|
||||
},
|
||||
additionalProperties: false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
exceptions: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'string'
|
||||
}
|
||||
}
|
||||
},
|
||||
additionalProperties: false
|
||||
}
|
||||
],
|
||||
messages: {
|
||||
expectedAfterHTMLCommentOpen: "Expected line break after '<!--'.",
|
||||
expectedBeforeHTMLCommentOpen: "Expected line break before '-->'.",
|
||||
expectedAfterExceptionBlock: 'Expected line break after exception block.',
|
||||
expectedBeforeExceptionBlock:
|
||||
'Expected line break before exception block.',
|
||||
unexpectedAfterHTMLCommentOpen: "Unexpected line breaks after '<!--'.",
|
||||
unexpectedBeforeHTMLCommentOpen: "Unexpected line breaks before '-->'."
|
||||
}
|
||||
},
|
||||
/** @param {RuleContext} context */
|
||||
create(context) {
|
||||
const option = parseOption(context.options[0])
|
||||
return htmlComments.defineVisitor(
|
||||
context,
|
||||
context.options[1],
|
||||
(comment) => {
|
||||
const { value, openDecoration, closeDecoration } = comment
|
||||
if (!value) {
|
||||
return
|
||||
}
|
||||
|
||||
const startLine = openDecoration
|
||||
? openDecoration.loc.end.line
|
||||
: value.loc.start.line
|
||||
const endLine = closeDecoration
|
||||
? closeDecoration.loc.start.line
|
||||
: value.loc.end.line
|
||||
const newlineType =
|
||||
startLine === endLine ? option.singleline : option.multiline
|
||||
if (newlineType === 'ignore') {
|
||||
return
|
||||
}
|
||||
checkCommentOpen(comment, newlineType !== 'never')
|
||||
checkCommentClose(comment, newlineType !== 'never')
|
||||
}
|
||||
)
|
||||
|
||||
/**
|
||||
* Reports the newline before the contents of a given comment if it's invalid.
|
||||
* @param {ParsedHTMLComment} comment - comment data.
|
||||
* @param {boolean} requireNewline - `true` if line breaks are required.
|
||||
* @returns {void}
|
||||
*/
|
||||
function checkCommentOpen(comment, requireNewline) {
|
||||
const { value, openDecoration, open } = comment
|
||||
if (!value) {
|
||||
return
|
||||
}
|
||||
const beforeToken = openDecoration || open
|
||||
|
||||
if (requireNewline) {
|
||||
if (beforeToken.loc.end.line < value.loc.start.line) {
|
||||
// Is valid
|
||||
return
|
||||
}
|
||||
context.report({
|
||||
loc: {
|
||||
start: beforeToken.loc.end,
|
||||
end: value.loc.start
|
||||
},
|
||||
messageId: openDecoration
|
||||
? 'expectedAfterExceptionBlock'
|
||||
: 'expectedAfterHTMLCommentOpen',
|
||||
fix: openDecoration
|
||||
? undefined
|
||||
: (fixer) => fixer.insertTextAfter(beforeToken, '\n')
|
||||
})
|
||||
} else {
|
||||
if (beforeToken.loc.end.line === value.loc.start.line) {
|
||||
// Is valid
|
||||
return
|
||||
}
|
||||
context.report({
|
||||
loc: {
|
||||
start: beforeToken.loc.end,
|
||||
end: value.loc.start
|
||||
},
|
||||
messageId: 'unexpectedAfterHTMLCommentOpen',
|
||||
fix: (fixer) =>
|
||||
fixer.replaceTextRange([beforeToken.range[1], value.range[0]], ' ')
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports the space after the contents of a given comment if it's invalid.
|
||||
* @param {ParsedHTMLComment} comment - comment data.
|
||||
* @param {boolean} requireNewline - `true` if line breaks are required.
|
||||
* @returns {void}
|
||||
*/
|
||||
function checkCommentClose(comment, requireNewline) {
|
||||
const { value, closeDecoration, close } = comment
|
||||
if (!value) {
|
||||
return
|
||||
}
|
||||
const afterToken = closeDecoration || close
|
||||
|
||||
if (requireNewline) {
|
||||
if (value.loc.end.line < afterToken.loc.start.line) {
|
||||
// Is valid
|
||||
return
|
||||
}
|
||||
context.report({
|
||||
loc: {
|
||||
start: value.loc.end,
|
||||
end: afterToken.loc.start
|
||||
},
|
||||
messageId: closeDecoration
|
||||
? 'expectedBeforeExceptionBlock'
|
||||
: 'expectedBeforeHTMLCommentOpen',
|
||||
fix: closeDecoration
|
||||
? undefined
|
||||
: (fixer) => fixer.insertTextBefore(afterToken, '\n')
|
||||
})
|
||||
} else {
|
||||
if (value.loc.end.line === afterToken.loc.start.line) {
|
||||
// Is valid
|
||||
return
|
||||
}
|
||||
context.report({
|
||||
loc: {
|
||||
start: value.loc.end,
|
||||
end: afterToken.loc.start
|
||||
},
|
||||
messageId: 'unexpectedBeforeHTMLCommentOpen',
|
||||
fix: (fixer) =>
|
||||
fixer.replaceTextRange([value.range[1], afterToken.range[0]], ' ')
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
171
slider/node_modules/eslint-plugin-vue/lib/rules/html-comment-content-spacing.js
generated
vendored
Normal file
171
slider/node_modules/eslint-plugin-vue/lib/rules/html-comment-content-spacing.js
generated
vendored
Normal file
@@ -0,0 +1,171 @@
|
||||
/**
|
||||
* @author Yosuke ota
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const htmlComments = require('../utils/html-comments')
|
||||
|
||||
/**
|
||||
* @typedef { import('../utils/html-comments').ParsedHTMLComment } ParsedHTMLComment
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'layout',
|
||||
|
||||
docs: {
|
||||
description: 'enforce unified spacing in HTML comments',
|
||||
categories: undefined,
|
||||
url: 'https://eslint.vuejs.org/rules/html-comment-content-spacing.html'
|
||||
},
|
||||
fixable: 'whitespace',
|
||||
schema: [
|
||||
{
|
||||
enum: ['always', 'never']
|
||||
},
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
exceptions: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'string'
|
||||
}
|
||||
}
|
||||
},
|
||||
additionalProperties: false
|
||||
}
|
||||
],
|
||||
messages: {
|
||||
expectedAfterHTMLCommentOpen: "Expected space after '<!--'.",
|
||||
expectedBeforeHTMLCommentOpen: "Expected space before '-->'.",
|
||||
expectedAfterExceptionBlock: 'Expected space after exception block.',
|
||||
expectedBeforeExceptionBlock: 'Expected space before exception block.',
|
||||
unexpectedAfterHTMLCommentOpen: "Unexpected space after '<!--'.",
|
||||
unexpectedBeforeHTMLCommentOpen: "Unexpected space before '-->'."
|
||||
}
|
||||
},
|
||||
/** @param {RuleContext} context */
|
||||
create(context) {
|
||||
// Unless the first option is never, require a space
|
||||
const requireSpace = context.options[0] !== 'never'
|
||||
return htmlComments.defineVisitor(
|
||||
context,
|
||||
context.options[1],
|
||||
(comment) => {
|
||||
checkCommentOpen(comment)
|
||||
checkCommentClose(comment)
|
||||
},
|
||||
{ includeDirectives: true }
|
||||
)
|
||||
|
||||
/**
|
||||
* Reports the space before the contents of a given comment if it's invalid.
|
||||
* @param {ParsedHTMLComment} comment - comment data.
|
||||
* @returns {void}
|
||||
*/
|
||||
function checkCommentOpen(comment) {
|
||||
const { value, openDecoration, open } = comment
|
||||
if (!value) {
|
||||
return
|
||||
}
|
||||
const beforeToken = openDecoration || open
|
||||
if (beforeToken.loc.end.line !== value.loc.start.line) {
|
||||
// Ignore newline
|
||||
return
|
||||
}
|
||||
|
||||
if (requireSpace) {
|
||||
if (beforeToken.range[1] < value.range[0]) {
|
||||
// Is valid
|
||||
return
|
||||
}
|
||||
context.report({
|
||||
loc: {
|
||||
start: beforeToken.loc.end,
|
||||
end: value.loc.start
|
||||
},
|
||||
messageId: openDecoration
|
||||
? 'expectedAfterExceptionBlock'
|
||||
: 'expectedAfterHTMLCommentOpen',
|
||||
fix: openDecoration
|
||||
? undefined
|
||||
: (fixer) => fixer.insertTextAfter(beforeToken, ' ')
|
||||
})
|
||||
} else {
|
||||
if (openDecoration) {
|
||||
// Ignore expection block
|
||||
return
|
||||
}
|
||||
if (beforeToken.range[1] === value.range[0]) {
|
||||
// Is valid
|
||||
return
|
||||
}
|
||||
context.report({
|
||||
loc: {
|
||||
start: beforeToken.loc.end,
|
||||
end: value.loc.start
|
||||
},
|
||||
messageId: 'unexpectedAfterHTMLCommentOpen',
|
||||
fix: (fixer) =>
|
||||
fixer.removeRange([beforeToken.range[1], value.range[0]])
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports the space after the contents of a given comment if it's invalid.
|
||||
* @param {ParsedHTMLComment} comment - comment data.
|
||||
* @returns {void}
|
||||
*/
|
||||
function checkCommentClose(comment) {
|
||||
const { value, closeDecoration, close } = comment
|
||||
if (!value) {
|
||||
return
|
||||
}
|
||||
const afterToken = closeDecoration || close
|
||||
if (value.loc.end.line !== afterToken.loc.start.line) {
|
||||
// Ignore newline
|
||||
return
|
||||
}
|
||||
|
||||
if (requireSpace) {
|
||||
if (value.range[1] < afterToken.range[0]) {
|
||||
// Is valid
|
||||
return
|
||||
}
|
||||
context.report({
|
||||
loc: {
|
||||
start: value.loc.end,
|
||||
end: afterToken.loc.start
|
||||
},
|
||||
messageId: closeDecoration
|
||||
? 'expectedBeforeExceptionBlock'
|
||||
: 'expectedBeforeHTMLCommentOpen',
|
||||
fix: closeDecoration
|
||||
? undefined
|
||||
: (fixer) => fixer.insertTextBefore(afterToken, ' ')
|
||||
})
|
||||
} else {
|
||||
if (closeDecoration) {
|
||||
// Ignore expection block
|
||||
return
|
||||
}
|
||||
if (value.range[1] === afterToken.range[0]) {
|
||||
// Is valid
|
||||
return
|
||||
}
|
||||
context.report({
|
||||
loc: {
|
||||
start: value.loc.end,
|
||||
end: afterToken.loc.start
|
||||
},
|
||||
messageId: 'unexpectedBeforeHTMLCommentOpen',
|
||||
fix: (fixer) =>
|
||||
fixer.removeRange([value.range[1], afterToken.range[0]])
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
244
slider/node_modules/eslint-plugin-vue/lib/rules/html-comment-indent.js
generated
vendored
Normal file
244
slider/node_modules/eslint-plugin-vue/lib/rules/html-comment-indent.js
generated
vendored
Normal file
@@ -0,0 +1,244 @@
|
||||
/**
|
||||
* @author Yosuke ota
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const htmlComments = require('../utils/html-comments')
|
||||
|
||||
/**
|
||||
* Normalize options.
|
||||
* @param {number|"tab"|undefined} type The type of indentation.
|
||||
* @returns { { indentChar: string, indentSize: number, indentText: string } } Normalized options.
|
||||
*/
|
||||
function parseOptions(type) {
|
||||
const ret = {
|
||||
indentChar: ' ',
|
||||
indentSize: 2,
|
||||
indentText: ''
|
||||
}
|
||||
|
||||
if (Number.isSafeInteger(type)) {
|
||||
ret.indentSize = Number(type)
|
||||
} else if (type === 'tab') {
|
||||
ret.indentChar = '\t'
|
||||
ret.indentSize = 1
|
||||
}
|
||||
ret.indentText = ret.indentChar.repeat(ret.indentSize)
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} s
|
||||
* @param {string} [unitChar]
|
||||
*/
|
||||
function toDisplay(s, unitChar) {
|
||||
if (s.length === 0 && unitChar) {
|
||||
return `0 ${toUnit(unitChar)}s`
|
||||
}
|
||||
const char = s[0]
|
||||
if ((char === ' ' || char === '\t') && [...s].every((c) => c === char)) {
|
||||
return `${s.length} ${toUnit(char)}${s.length === 1 ? '' : 's'}`
|
||||
}
|
||||
|
||||
return JSON.stringify(s)
|
||||
}
|
||||
|
||||
/** @param {string} char */
|
||||
function toUnit(char) {
|
||||
if (char === '\t') {
|
||||
return 'tab'
|
||||
}
|
||||
if (char === ' ') {
|
||||
return 'space'
|
||||
}
|
||||
return JSON.stringify(char)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'layout',
|
||||
|
||||
docs: {
|
||||
description: 'enforce consistent indentation in HTML comments',
|
||||
categories: undefined,
|
||||
url: 'https://eslint.vuejs.org/rules/html-comment-indent.html'
|
||||
},
|
||||
fixable: 'whitespace',
|
||||
schema: [
|
||||
{
|
||||
oneOf: [{ type: 'integer', minimum: 0 }, { enum: ['tab'] }]
|
||||
}
|
||||
],
|
||||
messages: {
|
||||
unexpectedBaseIndentation:
|
||||
'Expected base point indentation of {{expected}}, but found {{actual}}.',
|
||||
missingBaseIndentation:
|
||||
'Expected base point indentation of {{expected}}, but not found.',
|
||||
unexpectedIndentationCharacter:
|
||||
'Expected {{expected}} character, but found {{actual}} character.',
|
||||
unexpectedIndentation:
|
||||
'Expected indentation of {{expected}} but found {{actual}}.',
|
||||
unexpectedRelativeIndentation:
|
||||
'Expected relative indentation of {{expected}} but found {{actual}}.'
|
||||
}
|
||||
},
|
||||
/** @param {RuleContext} context */
|
||||
create(context) {
|
||||
const options = parseOptions(context.options[0])
|
||||
const sourceCode = context.getSourceCode()
|
||||
return htmlComments.defineVisitor(
|
||||
context,
|
||||
null,
|
||||
(comment) => {
|
||||
const baseIndentText = getLineIndentText(comment.open.loc.start.line)
|
||||
let endLine
|
||||
if (comment.value) {
|
||||
const startLine = comment.value.loc.start.line
|
||||
endLine = comment.value.loc.end.line
|
||||
|
||||
const checkStartLine =
|
||||
comment.open.loc.end.line === startLine ? startLine + 1 : startLine
|
||||
|
||||
for (let line = checkStartLine; line <= endLine; line++) {
|
||||
validateIndentForLine(line, baseIndentText, 1)
|
||||
}
|
||||
} else {
|
||||
endLine = comment.open.loc.end.line
|
||||
}
|
||||
|
||||
if (endLine < comment.close.loc.start.line) {
|
||||
// `-->`
|
||||
validateIndentForLine(comment.close.loc.start.line, baseIndentText, 0)
|
||||
}
|
||||
},
|
||||
{ includeDirectives: true }
|
||||
)
|
||||
|
||||
/**
|
||||
* Checks whether the given line is a blank line.
|
||||
* @param {number} line The number of line. Begins with 1.
|
||||
* @returns {boolean} `true` if the given line is a blank line
|
||||
*/
|
||||
function isEmptyLine(line) {
|
||||
const lineText = sourceCode.getLines()[line - 1]
|
||||
return !lineText.trim()
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the actual indentation of the given line.
|
||||
* @param {number} line The number of line. Begins with 1.
|
||||
* @returns {string} The actual indentation text
|
||||
*/
|
||||
function getLineIndentText(line) {
|
||||
const lineText = sourceCode.getLines()[line - 1]
|
||||
const charIndex = lineText.search(/\S/)
|
||||
// already checked
|
||||
// if (charIndex < 0) {
|
||||
// return lineText
|
||||
// }
|
||||
return lineText.slice(0, charIndex)
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the function which fixes the problem.
|
||||
* @param {number} line The number of line.
|
||||
* @param {string} actualIndentText The actual indentation text.
|
||||
* @param {string} expectedIndentText The expected indentation text.
|
||||
* @returns { (fixer: RuleFixer) => Fix } The defined function.
|
||||
*/
|
||||
function defineFix(line, actualIndentText, expectedIndentText) {
|
||||
return (fixer) => {
|
||||
const start = sourceCode.getIndexFromLoc({
|
||||
line,
|
||||
column: 0
|
||||
})
|
||||
return fixer.replaceTextRange(
|
||||
[start, start + actualIndentText.length],
|
||||
expectedIndentText
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the indentation of a line.
|
||||
* @param {number} line The number of line. Begins with 1.
|
||||
* @param {string} baseIndentText The expected base indentation text.
|
||||
* @param {number} offset The number of the indentation offset.
|
||||
*/
|
||||
function validateIndentForLine(line, baseIndentText, offset) {
|
||||
if (isEmptyLine(line)) {
|
||||
return
|
||||
}
|
||||
const actualIndentText = getLineIndentText(line)
|
||||
|
||||
const expectedOffsetIndentText = options.indentText.repeat(offset)
|
||||
const expectedIndentText = baseIndentText + expectedOffsetIndentText
|
||||
|
||||
// validate base indent
|
||||
if (
|
||||
baseIndentText &&
|
||||
(actualIndentText.length < baseIndentText.length ||
|
||||
!actualIndentText.startsWith(baseIndentText))
|
||||
) {
|
||||
context.report({
|
||||
loc: {
|
||||
start: { line, column: 0 },
|
||||
end: { line, column: actualIndentText.length }
|
||||
},
|
||||
messageId: actualIndentText
|
||||
? 'unexpectedBaseIndentation'
|
||||
: 'missingBaseIndentation',
|
||||
data: {
|
||||
expected: toDisplay(baseIndentText),
|
||||
actual: toDisplay(actualIndentText.slice(0, baseIndentText.length))
|
||||
},
|
||||
fix: defineFix(line, actualIndentText, expectedIndentText)
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
const actualOffsetIndentText = actualIndentText.slice(
|
||||
baseIndentText.length
|
||||
)
|
||||
|
||||
// validate indent charctor
|
||||
for (const [i, char] of [...actualOffsetIndentText].entries()) {
|
||||
if (char !== options.indentChar) {
|
||||
context.report({
|
||||
loc: {
|
||||
start: { line, column: baseIndentText.length + i },
|
||||
end: { line, column: baseIndentText.length + i + 1 }
|
||||
},
|
||||
messageId: 'unexpectedIndentationCharacter',
|
||||
data: {
|
||||
expected: toUnit(options.indentChar),
|
||||
actual: toUnit(char)
|
||||
},
|
||||
fix: defineFix(line, actualIndentText, expectedIndentText)
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// validate indent length
|
||||
if (actualOffsetIndentText.length !== expectedOffsetIndentText.length) {
|
||||
context.report({
|
||||
loc: {
|
||||
start: { line, column: baseIndentText.length },
|
||||
end: { line, column: actualIndentText.length }
|
||||
},
|
||||
messageId: baseIndentText
|
||||
? 'unexpectedRelativeIndentation'
|
||||
: 'unexpectedIndentation',
|
||||
data: {
|
||||
expected: toDisplay(expectedOffsetIndentText, options.indentChar),
|
||||
actual: toDisplay(actualOffsetIndentText, options.indentChar)
|
||||
},
|
||||
fix: defineFix(line, actualIndentText, expectedIndentText)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
59
slider/node_modules/eslint-plugin-vue/lib/rules/html-end-tags.js
generated
vendored
Normal file
59
slider/node_modules/eslint-plugin-vue/lib/rules/html-end-tags.js
generated
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* @author Toru Nagashima
|
||||
* @copyright 2017 Toru Nagashima. All rights reserved.
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const utils = require('../utils')
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'suggestion',
|
||||
docs: {
|
||||
description: 'enforce end tag style',
|
||||
categories: ['vue3-strongly-recommended', 'vue2-strongly-recommended'],
|
||||
url: 'https://eslint.vuejs.org/rules/html-end-tags.html'
|
||||
},
|
||||
fixable: 'code',
|
||||
schema: [],
|
||||
messages: {
|
||||
missingEndTag: "'<{{name}}>' should have end tag."
|
||||
}
|
||||
},
|
||||
/** @param {RuleContext} context */
|
||||
create(context) {
|
||||
let hasInvalidEOF = false
|
||||
|
||||
return utils.defineTemplateBodyVisitor(
|
||||
context,
|
||||
{
|
||||
VElement(node) {
|
||||
if (hasInvalidEOF) {
|
||||
return
|
||||
}
|
||||
|
||||
const name = node.name
|
||||
const isVoid = utils.isHtmlVoidElementName(name)
|
||||
const isSelfClosing = node.startTag.selfClosing
|
||||
const hasEndTag = node.endTag != null
|
||||
|
||||
if (!isVoid && !hasEndTag && !isSelfClosing) {
|
||||
context.report({
|
||||
node: node.startTag,
|
||||
loc: node.startTag.loc,
|
||||
messageId: 'missingEndTag',
|
||||
data: { name },
|
||||
fix: (fixer) => fixer.insertTextAfter(node, `</${name}>`)
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
Program(node) {
|
||||
hasInvalidEOF = utils.hasInvalidEOF(node)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
76
slider/node_modules/eslint-plugin-vue/lib/rules/html-indent.js
generated
vendored
Normal file
76
slider/node_modules/eslint-plugin-vue/lib/rules/html-indent.js
generated
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* @author Toru Nagashima
|
||||
* @copyright 2016 Toru Nagashima. All rights reserved.
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const indentCommon = require('../utils/indent-common')
|
||||
const utils = require('../utils')
|
||||
|
||||
module.exports = {
|
||||
/** @param {RuleContext} context */
|
||||
create(context) {
|
||||
const sourceCode = context.getSourceCode()
|
||||
const tokenStore =
|
||||
sourceCode.parserServices.getTemplateBodyTokenStore &&
|
||||
sourceCode.parserServices.getTemplateBodyTokenStore()
|
||||
const visitor = indentCommon.defineVisitor(context, tokenStore, {
|
||||
baseIndent: 1
|
||||
})
|
||||
|
||||
return utils.defineTemplateBodyVisitor(context, visitor)
|
||||
},
|
||||
// eslint-disable-next-line eslint-plugin/prefer-message-ids
|
||||
meta: {
|
||||
type: 'layout',
|
||||
docs: {
|
||||
description: 'enforce consistent indentation in `<template>`',
|
||||
categories: ['vue3-strongly-recommended', 'vue2-strongly-recommended'],
|
||||
url: 'https://eslint.vuejs.org/rules/html-indent.html'
|
||||
},
|
||||
// eslint-disable-next-line eslint-plugin/require-meta-fixable -- fixer is not recognized
|
||||
fixable: 'whitespace',
|
||||
schema: [
|
||||
{
|
||||
oneOf: [{ type: 'integer', minimum: 1 }, { enum: ['tab'] }]
|
||||
},
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
attribute: { type: 'integer', minimum: 0 },
|
||||
baseIndent: { type: 'integer', minimum: 0 },
|
||||
closeBracket: {
|
||||
oneOf: [
|
||||
{ type: 'integer', minimum: 0 },
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
startTag: { type: 'integer', minimum: 0 },
|
||||
endTag: { type: 'integer', minimum: 0 },
|
||||
selfClosingTag: { type: 'integer', minimum: 0 }
|
||||
},
|
||||
additionalProperties: false
|
||||
}
|
||||
]
|
||||
},
|
||||
switchCase: { type: 'integer', minimum: 0 },
|
||||
alignAttributesVertically: { type: 'boolean' },
|
||||
ignores: {
|
||||
type: 'array',
|
||||
items: {
|
||||
allOf: [
|
||||
{ type: 'string' },
|
||||
{ not: { type: 'string', pattern: ':exit$' } },
|
||||
{ not: { type: 'string', pattern: String.raw`^\s*$` } }
|
||||
]
|
||||
},
|
||||
uniqueItems: true,
|
||||
additionalItems: false
|
||||
}
|
||||
},
|
||||
additionalProperties: false
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
107
slider/node_modules/eslint-plugin-vue/lib/rules/html-quotes.js
generated
vendored
Normal file
107
slider/node_modules/eslint-plugin-vue/lib/rules/html-quotes.js
generated
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
/**
|
||||
* @author Toru Nagashima
|
||||
* @copyright 2017 Toru Nagashima. All rights reserved.
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const utils = require('../utils')
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'layout',
|
||||
docs: {
|
||||
description: 'enforce quotes style of HTML attributes',
|
||||
categories: ['vue3-strongly-recommended', 'vue2-strongly-recommended'],
|
||||
url: 'https://eslint.vuejs.org/rules/html-quotes.html'
|
||||
},
|
||||
fixable: 'code',
|
||||
schema: [
|
||||
{ enum: ['double', 'single'] },
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
avoidEscape: {
|
||||
type: 'boolean'
|
||||
}
|
||||
},
|
||||
additionalProperties: false
|
||||
}
|
||||
],
|
||||
messages: {
|
||||
expected: 'Expected to be enclosed by {{kind}}.'
|
||||
}
|
||||
},
|
||||
/** @param {RuleContext} context */
|
||||
create(context) {
|
||||
const sourceCode = context.getSourceCode()
|
||||
const double = context.options[0] !== 'single'
|
||||
const avoidEscape =
|
||||
context.options[1] && context.options[1].avoidEscape === true
|
||||
const quoteChar = double ? '"' : "'"
|
||||
const quoteName = double ? 'double quotes' : 'single quotes'
|
||||
/** @type {boolean} */
|
||||
let hasInvalidEOF
|
||||
|
||||
return utils.defineTemplateBodyVisitor(
|
||||
context,
|
||||
{
|
||||
'VAttribute[value!=null]'(node) {
|
||||
if (hasInvalidEOF) {
|
||||
return
|
||||
}
|
||||
|
||||
if (utils.isVBindSameNameShorthand(node)) {
|
||||
// v-bind same-name shorthand (Vue 3.4+)
|
||||
return
|
||||
}
|
||||
|
||||
const text = sourceCode.getText(node.value)
|
||||
const firstChar = text[0]
|
||||
|
||||
if (firstChar !== quoteChar) {
|
||||
const quoted = firstChar === "'" || firstChar === '"'
|
||||
if (avoidEscape && quoted) {
|
||||
const contentText = text.slice(1, -1)
|
||||
if (contentText.includes(quoteChar)) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
context.report({
|
||||
node: node.value,
|
||||
loc: node.value.loc,
|
||||
messageId: 'expected',
|
||||
data: { kind: quoteName },
|
||||
fix(fixer) {
|
||||
const contentText = quoted ? text.slice(1, -1) : text
|
||||
|
||||
let fixToDouble = double
|
||||
if (avoidEscape && !quoted && contentText.includes(quoteChar)) {
|
||||
fixToDouble = double
|
||||
? contentText.includes("'")
|
||||
: !contentText.includes('"')
|
||||
}
|
||||
|
||||
const quotePattern = fixToDouble ? /"/g : /'/g
|
||||
const quoteEscaped = fixToDouble ? '"' : '''
|
||||
const fixQuoteChar = fixToDouble ? '"' : "'"
|
||||
|
||||
const replacement =
|
||||
fixQuoteChar +
|
||||
contentText.replace(quotePattern, quoteEscaped) +
|
||||
fixQuoteChar
|
||||
return fixer.replaceText(node.value, replacement)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
Program(node) {
|
||||
hasInvalidEOF = utils.hasInvalidEOF(node)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
222
slider/node_modules/eslint-plugin-vue/lib/rules/html-self-closing.js
generated
vendored
Normal file
222
slider/node_modules/eslint-plugin-vue/lib/rules/html-self-closing.js
generated
vendored
Normal file
@@ -0,0 +1,222 @@
|
||||
/**
|
||||
* @author Toru Nagashima
|
||||
* @copyright 2016 Toru Nagashima. All rights reserved.
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const utils = require('../utils')
|
||||
|
||||
/**
|
||||
* These strings wil be displayed in error messages.
|
||||
*/
|
||||
const ELEMENT_TYPE_MESSAGES = Object.freeze({
|
||||
NORMAL: 'HTML elements',
|
||||
VOID: 'HTML void elements',
|
||||
COMPONENT: 'Vue.js custom components',
|
||||
SVG: 'SVG elements',
|
||||
MATH: 'MathML elements',
|
||||
UNKNOWN: 'unknown elements'
|
||||
})
|
||||
|
||||
/**
|
||||
* @typedef {object} Options
|
||||
* @property {'always' | 'never'} NORMAL
|
||||
* @property {'always' | 'never'} VOID
|
||||
* @property {'always' | 'never'} COMPONENT
|
||||
* @property {'always' | 'never'} SVG
|
||||
* @property {'always' | 'never'} MATH
|
||||
* @property {null} UNKNOWN
|
||||
*/
|
||||
|
||||
/**
|
||||
* Normalize the given options.
|
||||
* @param {any} options The raw options object.
|
||||
* @returns {Options} Normalized options.
|
||||
*/
|
||||
function parseOptions(options) {
|
||||
return {
|
||||
NORMAL: (options && options.html && options.html.normal) || 'always',
|
||||
VOID: (options && options.html && options.html.void) || 'never',
|
||||
COMPONENT: (options && options.html && options.html.component) || 'always',
|
||||
SVG: (options && options.svg) || 'always',
|
||||
MATH: (options && options.math) || 'always',
|
||||
UNKNOWN: null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the elementType of the given element.
|
||||
* @param {VElement} node The element node to get.
|
||||
* @returns {keyof Options} The elementType of the element.
|
||||
*/
|
||||
function getElementType(node) {
|
||||
if (utils.isCustomComponent(node)) {
|
||||
return 'COMPONENT'
|
||||
}
|
||||
if (utils.isHtmlElementNode(node)) {
|
||||
if (utils.isHtmlVoidElementName(node.name)) {
|
||||
return 'VOID'
|
||||
}
|
||||
return 'NORMAL'
|
||||
}
|
||||
if (utils.isSvgElementNode(node)) {
|
||||
return 'SVG'
|
||||
}
|
||||
if (utils.isMathElementNode(node)) {
|
||||
return 'MATH'
|
||||
}
|
||||
return 'UNKNOWN'
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the given element is empty or not.
|
||||
* This ignores whitespaces, doesn't ignore comments.
|
||||
* @param {VElement} node The element node to check.
|
||||
* @param {SourceCode} sourceCode The source code object of the current context.
|
||||
* @returns {boolean} `true` if the element is empty.
|
||||
*/
|
||||
function isEmpty(node, sourceCode) {
|
||||
const start = node.startTag.range[1]
|
||||
const end = node.endTag == null ? node.range[1] : node.endTag.range[0]
|
||||
|
||||
return sourceCode.text.slice(start, end).trim() === ''
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'layout',
|
||||
docs: {
|
||||
description: 'enforce self-closing style',
|
||||
categories: ['vue3-strongly-recommended', 'vue2-strongly-recommended'],
|
||||
url: 'https://eslint.vuejs.org/rules/html-self-closing.html'
|
||||
},
|
||||
fixable: 'code',
|
||||
schema: {
|
||||
definitions: {
|
||||
optionValue: {
|
||||
enum: ['always', 'never', 'any']
|
||||
}
|
||||
},
|
||||
type: 'array',
|
||||
items: [
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
html: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
normal: { $ref: '#/definitions/optionValue' },
|
||||
void: { $ref: '#/definitions/optionValue' },
|
||||
component: { $ref: '#/definitions/optionValue' }
|
||||
},
|
||||
additionalProperties: false
|
||||
},
|
||||
svg: { $ref: '#/definitions/optionValue' },
|
||||
math: { $ref: '#/definitions/optionValue' }
|
||||
},
|
||||
additionalProperties: false
|
||||
}
|
||||
],
|
||||
maxItems: 1
|
||||
},
|
||||
messages: {
|
||||
requireSelfClosing:
|
||||
'Require self-closing on {{elementType}} (<{{name}}>).',
|
||||
disallowSelfClosing:
|
||||
'Disallow self-closing on {{elementType}} (<{{name}}/>).'
|
||||
}
|
||||
},
|
||||
/** @param {RuleContext} context */
|
||||
create(context) {
|
||||
const sourceCode = context.getSourceCode()
|
||||
const options = parseOptions(context.options[0])
|
||||
let hasInvalidEOF = false
|
||||
|
||||
return utils.defineTemplateBodyVisitor(
|
||||
context,
|
||||
{
|
||||
VElement(node) {
|
||||
if (hasInvalidEOF || node.parent.type === 'VDocumentFragment') {
|
||||
return
|
||||
}
|
||||
|
||||
const elementType = getElementType(node)
|
||||
const mode = options[elementType]
|
||||
|
||||
if (
|
||||
mode === 'always' &&
|
||||
!node.startTag.selfClosing &&
|
||||
isEmpty(node, sourceCode)
|
||||
) {
|
||||
context.report({
|
||||
node: node.endTag || node,
|
||||
messageId: 'requireSelfClosing',
|
||||
data: {
|
||||
elementType: ELEMENT_TYPE_MESSAGES[elementType],
|
||||
name: node.rawName
|
||||
},
|
||||
fix(fixer) {
|
||||
const tokens =
|
||||
sourceCode.parserServices.getTemplateBodyTokenStore()
|
||||
const close = tokens.getLastToken(node.startTag)
|
||||
if (close.type !== 'HTMLTagClose') {
|
||||
return null
|
||||
}
|
||||
return fixer.replaceTextRange(
|
||||
[close.range[0], node.range[1]],
|
||||
'/>'
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (mode === 'never' && node.startTag.selfClosing) {
|
||||
context.report({
|
||||
node,
|
||||
loc: {
|
||||
start: {
|
||||
line: node.loc.end.line,
|
||||
column: node.loc.end.column - 2
|
||||
},
|
||||
end: node.loc.end
|
||||
},
|
||||
messageId: 'disallowSelfClosing',
|
||||
data: {
|
||||
elementType: ELEMENT_TYPE_MESSAGES[elementType],
|
||||
name: node.rawName
|
||||
},
|
||||
fix(fixer) {
|
||||
const tokens =
|
||||
sourceCode.parserServices.getTemplateBodyTokenStore()
|
||||
const close = tokens.getLastToken(node.startTag)
|
||||
if (close.type !== 'HTMLSelfClosingTagClose') {
|
||||
return null
|
||||
}
|
||||
if (elementType === 'VOID') {
|
||||
return fixer.replaceText(close, '>')
|
||||
}
|
||||
// If only `close` is targeted for replacement, it conflicts with `component-name-in-template-casing`,
|
||||
// so replace the entire element.
|
||||
// return fixer.replaceText(close, `></${node.rawName}>`)
|
||||
const elementPart = sourceCode.text.slice(
|
||||
node.range[0],
|
||||
close.range[0]
|
||||
)
|
||||
return fixer.replaceText(
|
||||
node,
|
||||
`${elementPart}></${node.rawName}>`
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
Program(node) {
|
||||
hasInvalidEOF = utils.hasInvalidEOF(node)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
72
slider/node_modules/eslint-plugin-vue/lib/rules/jsx-uses-vars.js
generated
vendored
Normal file
72
slider/node_modules/eslint-plugin-vue/lib/rules/jsx-uses-vars.js
generated
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
// the following rule is based on yannickcr/eslint-plugin-react
|
||||
|
||||
/**
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Yannick Croissant
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Prevent variables used in JSX to be marked as unused
|
||||
* @author Yannick Croissant
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const utils = require('../utils')
|
||||
|
||||
module.exports = {
|
||||
// eslint-disable-next-line eslint-plugin/prefer-message-ids
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description: 'prevent variables used in JSX to be marked as unused', // eslint-disable-line eslint-plugin/require-meta-docs-description
|
||||
categories: ['base'],
|
||||
url: 'https://eslint.vuejs.org/rules/jsx-uses-vars.html'
|
||||
},
|
||||
schema: []
|
||||
},
|
||||
/**
|
||||
* @param {RuleContext} context - The rule context.
|
||||
* @returns {RuleListener} AST event handlers.
|
||||
*/
|
||||
create(context) {
|
||||
return {
|
||||
JSXOpeningElement(node) {
|
||||
let name
|
||||
if (node.name.type === 'JSXIdentifier') {
|
||||
// <Foo>
|
||||
name = node.name.name
|
||||
} else if (node.name.type === 'JSXMemberExpression') {
|
||||
// <Foo...Bar>
|
||||
let parent = node.name.object
|
||||
while (parent.type === 'JSXMemberExpression') {
|
||||
parent = parent.object
|
||||
}
|
||||
name = parent.name
|
||||
} else {
|
||||
return
|
||||
}
|
||||
|
||||
utils.markVariableAsUsed(context, name, node)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
11
slider/node_modules/eslint-plugin-vue/lib/rules/key-spacing.js
generated
vendored
Normal file
11
slider/node_modules/eslint-plugin-vue/lib/rules/key-spacing.js
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* @author Toru Nagashima
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const { wrapStylisticOrCoreRule } = require('../utils')
|
||||
|
||||
// eslint-disable-next-line internal/no-invalid-meta
|
||||
module.exports = wrapStylisticOrCoreRule('key-spacing', {
|
||||
skipDynamicArguments: true
|
||||
})
|
11
slider/node_modules/eslint-plugin-vue/lib/rules/keyword-spacing.js
generated
vendored
Normal file
11
slider/node_modules/eslint-plugin-vue/lib/rules/keyword-spacing.js
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* @author Yosuke Ota
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const { wrapStylisticOrCoreRule } = require('../utils')
|
||||
|
||||
// eslint-disable-next-line internal/no-invalid-meta
|
||||
module.exports = wrapStylisticOrCoreRule('keyword-spacing', {
|
||||
skipDynamicArguments: true
|
||||
})
|
164
slider/node_modules/eslint-plugin-vue/lib/rules/match-component-file-name.js
generated
vendored
Normal file
164
slider/node_modules/eslint-plugin-vue/lib/rules/match-component-file-name.js
generated
vendored
Normal file
@@ -0,0 +1,164 @@
|
||||
/**
|
||||
* @fileoverview Require component name property to match its file name
|
||||
* @author Rodrigo Pedra Brum <rodrigo.pedra@gmail.com>
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const utils = require('../utils')
|
||||
const casing = require('../utils/casing')
|
||||
const path = require('path')
|
||||
|
||||
/**
|
||||
* @param {Expression | SpreadElement} node
|
||||
* @returns {node is (Literal | TemplateLiteral)}
|
||||
*/
|
||||
function canVerify(node) {
|
||||
return (
|
||||
node.type === 'Literal' ||
|
||||
(node.type === 'TemplateLiteral' &&
|
||||
node.expressions.length === 0 &&
|
||||
node.quasis.length === 1)
|
||||
)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'suggestion',
|
||||
docs: {
|
||||
description: 'require component name property to match its file name',
|
||||
categories: undefined,
|
||||
url: 'https://eslint.vuejs.org/rules/match-component-file-name.html'
|
||||
},
|
||||
fixable: null,
|
||||
hasSuggestions: true,
|
||||
schema: [
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
extensions: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'string'
|
||||
},
|
||||
uniqueItems: true,
|
||||
additionalItems: false
|
||||
},
|
||||
shouldMatchCase: {
|
||||
type: 'boolean'
|
||||
}
|
||||
},
|
||||
additionalProperties: false
|
||||
}
|
||||
],
|
||||
messages: {
|
||||
shouldMatchFileName:
|
||||
'Component name `{{name}}` should match file name `{{filename}}`.'
|
||||
}
|
||||
},
|
||||
/** @param {RuleContext} context */
|
||||
create(context) {
|
||||
const options = context.options[0]
|
||||
const shouldMatchCase = (options && options.shouldMatchCase) || false
|
||||
const extensionsArray = options && options.extensions
|
||||
const allowedExtensions = Array.isArray(extensionsArray)
|
||||
? extensionsArray
|
||||
: ['jsx']
|
||||
|
||||
const extension = path.extname(context.getFilename())
|
||||
const filename = path.basename(context.getFilename(), extension)
|
||||
|
||||
/** @type {Rule.ReportDescriptor[]} */
|
||||
const errors = []
|
||||
let componentCount = 0
|
||||
|
||||
if (!allowedExtensions.includes(extension.replace(/^\./, ''))) {
|
||||
return {}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} name
|
||||
* @param {string} filename
|
||||
*/
|
||||
function compareNames(name, filename) {
|
||||
if (shouldMatchCase) {
|
||||
return name === filename
|
||||
}
|
||||
|
||||
return (
|
||||
casing.pascalCase(name) === filename ||
|
||||
casing.kebabCase(name) === filename
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Literal | TemplateLiteral} node
|
||||
*/
|
||||
function verifyName(node) {
|
||||
let name
|
||||
if (node.type === 'TemplateLiteral') {
|
||||
const quasis = node.quasis[0]
|
||||
name = quasis.value.cooked
|
||||
} else {
|
||||
name = `${node.value}`
|
||||
}
|
||||
|
||||
if (!compareNames(name, filename)) {
|
||||
errors.push({
|
||||
node,
|
||||
messageId: 'shouldMatchFileName',
|
||||
data: { filename, name },
|
||||
suggest: [
|
||||
{
|
||||
desc: 'Rename component to match file name.',
|
||||
fix(fixer) {
|
||||
const quote =
|
||||
node.type === 'TemplateLiteral' ? '`' : node.raw[0]
|
||||
return fixer.replaceText(node, `${quote}${filename}${quote}`)
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return utils.compositingVisitors(
|
||||
utils.executeOnCallVueComponent(context, (node) => {
|
||||
if (node.arguments.length === 2) {
|
||||
const argument = node.arguments[0]
|
||||
|
||||
if (canVerify(argument)) {
|
||||
verifyName(argument)
|
||||
}
|
||||
}
|
||||
}),
|
||||
utils.executeOnVue(context, (object) => {
|
||||
const node = utils.findProperty(object, 'name')
|
||||
|
||||
componentCount++
|
||||
|
||||
if (!node) return
|
||||
if (!canVerify(node.value)) return
|
||||
verifyName(node.value)
|
||||
}),
|
||||
utils.defineScriptSetupVisitor(context, {
|
||||
onDefineOptionsEnter(node) {
|
||||
componentCount++
|
||||
if (node.arguments.length === 0) return
|
||||
const define = node.arguments[0]
|
||||
if (define.type !== 'ObjectExpression') return
|
||||
const nameNode = utils.findProperty(define, 'name')
|
||||
if (!nameNode) return
|
||||
if (!canVerify(nameNode.value)) return
|
||||
verifyName(nameNode.value)
|
||||
}
|
||||
}),
|
||||
{
|
||||
'Program:exit'() {
|
||||
if (componentCount > 1) return
|
||||
|
||||
for (const error of errors) context.report(error)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
73
slider/node_modules/eslint-plugin-vue/lib/rules/match-component-import-name.js
generated
vendored
Normal file
73
slider/node_modules/eslint-plugin-vue/lib/rules/match-component-import-name.js
generated
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
* @author Doug Wade <douglas.b.wade@gmail.com>
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const utils = require('../utils')
|
||||
const casing = require('../utils/casing')
|
||||
|
||||
/**
|
||||
* @param {Identifier} identifier
|
||||
* @return {Array<String>}
|
||||
*/
|
||||
function getExpectedNames(identifier) {
|
||||
return [casing.pascalCase(identifier.name), casing.kebabCase(identifier.name)]
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description:
|
||||
'require the registered component name to match the imported component name',
|
||||
categories: undefined,
|
||||
url: 'https://eslint.vuejs.org/rules/match-component-import-name.html'
|
||||
},
|
||||
fixable: null,
|
||||
schema: [],
|
||||
messages: {
|
||||
unexpected:
|
||||
'Component alias {{importedName}} should be one of: {{expectedName}}.'
|
||||
}
|
||||
},
|
||||
/**
|
||||
* @param {RuleContext} context
|
||||
* @returns {RuleListener}
|
||||
*/
|
||||
create(context) {
|
||||
return utils.executeOnVueComponent(context, (obj) => {
|
||||
const components = utils.findProperty(obj, 'components')
|
||||
if (
|
||||
!components ||
|
||||
!components.value ||
|
||||
components.value.type !== 'ObjectExpression'
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
||||
for (const property of components.value.properties) {
|
||||
if (
|
||||
property.type === 'SpreadElement' ||
|
||||
property.value.type !== 'Identifier' ||
|
||||
property.computed === true
|
||||
) {
|
||||
continue
|
||||
}
|
||||
|
||||
const importedName = utils.getStaticPropertyName(property) || ''
|
||||
const expectedNames = getExpectedNames(property.value)
|
||||
if (!expectedNames.includes(importedName)) {
|
||||
context.report({
|
||||
node: property,
|
||||
messageId: 'unexpected',
|
||||
data: {
|
||||
importedName,
|
||||
expectedName: expectedNames.join(', ')
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
183
slider/node_modules/eslint-plugin-vue/lib/rules/max-attributes-per-line.js
generated
vendored
Normal file
183
slider/node_modules/eslint-plugin-vue/lib/rules/max-attributes-per-line.js
generated
vendored
Normal file
@@ -0,0 +1,183 @@
|
||||
/**
|
||||
* @fileoverview Define the number of attributes allows per line
|
||||
* @author Filipa Lacerda
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const utils = require('../utils')
|
||||
|
||||
/**
|
||||
* @param {any} options
|
||||
*/
|
||||
function parseOptions(options) {
|
||||
const defaults = {
|
||||
singleline: 1,
|
||||
multiline: 1
|
||||
}
|
||||
|
||||
if (options) {
|
||||
if (typeof options.singleline === 'number') {
|
||||
defaults.singleline = options.singleline
|
||||
} else if (
|
||||
typeof options.singleline === 'object' &&
|
||||
typeof options.singleline.max === 'number'
|
||||
) {
|
||||
defaults.singleline = options.singleline.max
|
||||
}
|
||||
|
||||
if (options.multiline) {
|
||||
if (typeof options.multiline === 'number') {
|
||||
defaults.multiline = options.multiline
|
||||
} else if (
|
||||
typeof options.multiline === 'object' &&
|
||||
typeof options.multiline.max === 'number'
|
||||
) {
|
||||
defaults.multiline = options.multiline.max
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return defaults
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {(VDirective | VAttribute)[]} attributes
|
||||
*/
|
||||
function groupAttrsByLine(attributes) {
|
||||
const propsPerLine = [[attributes[0]]]
|
||||
|
||||
for (let index = 1; index < attributes.length; index++) {
|
||||
const previous = attributes[index - 1]
|
||||
const current = attributes[index]
|
||||
|
||||
if (previous.loc.end.line === current.loc.start.line) {
|
||||
propsPerLine[propsPerLine.length - 1].push(current)
|
||||
} else {
|
||||
propsPerLine.push([current])
|
||||
}
|
||||
}
|
||||
|
||||
return propsPerLine
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'layout',
|
||||
docs: {
|
||||
description: 'enforce the maximum number of attributes per line',
|
||||
categories: ['vue3-strongly-recommended', 'vue2-strongly-recommended'],
|
||||
url: 'https://eslint.vuejs.org/rules/max-attributes-per-line.html'
|
||||
},
|
||||
fixable: 'whitespace',
|
||||
schema: [
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
singleline: {
|
||||
oneOf: [
|
||||
{
|
||||
type: 'number',
|
||||
minimum: 1
|
||||
},
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
max: {
|
||||
type: 'number',
|
||||
minimum: 1
|
||||
}
|
||||
},
|
||||
additionalProperties: false
|
||||
}
|
||||
]
|
||||
},
|
||||
multiline: {
|
||||
oneOf: [
|
||||
{
|
||||
type: 'number',
|
||||
minimum: 1
|
||||
},
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
max: {
|
||||
type: 'number',
|
||||
minimum: 1
|
||||
}
|
||||
},
|
||||
additionalProperties: false
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
additionalProperties: false
|
||||
}
|
||||
],
|
||||
messages: {
|
||||
shouldBeOnNewLine: "'{{name}}' should be on a new line."
|
||||
}
|
||||
},
|
||||
/** @param {RuleContext} context */
|
||||
create(context) {
|
||||
const sourceCode = context.getSourceCode()
|
||||
const configuration = parseOptions(context.options[0])
|
||||
const multilineMaximum = configuration.multiline
|
||||
const singlelinemMaximum = configuration.singleline
|
||||
const template =
|
||||
sourceCode.parserServices.getTemplateBodyTokenStore &&
|
||||
sourceCode.parserServices.getTemplateBodyTokenStore()
|
||||
|
||||
return utils.defineTemplateBodyVisitor(context, {
|
||||
VStartTag(node) {
|
||||
const numberOfAttributes = node.attributes.length
|
||||
|
||||
if (!numberOfAttributes) return
|
||||
|
||||
if (
|
||||
utils.isSingleLine(node) &&
|
||||
numberOfAttributes > singlelinemMaximum
|
||||
) {
|
||||
showErrors(node.attributes.slice(singlelinemMaximum))
|
||||
}
|
||||
|
||||
if (!utils.isSingleLine(node)) {
|
||||
for (const attrs of groupAttrsByLine(node.attributes)) {
|
||||
if (attrs.length > multilineMaximum) {
|
||||
showErrors(attrs.splice(multilineMaximum))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* @param {(VDirective | VAttribute)[]} attributes
|
||||
*/
|
||||
function showErrors(attributes) {
|
||||
for (const [i, prop] of attributes.entries()) {
|
||||
context.report({
|
||||
node: prop,
|
||||
loc: prop.loc,
|
||||
messageId: 'shouldBeOnNewLine',
|
||||
data: { name: sourceCode.getText(prop.key) },
|
||||
fix(fixer) {
|
||||
if (i !== 0) return null
|
||||
|
||||
// Find the closest token before the current prop
|
||||
// that is not a white space
|
||||
const prevToken = /** @type {Token} */ (
|
||||
template.getTokenBefore(prop, {
|
||||
filter: (token) => token.type !== 'HTMLWhitespace'
|
||||
})
|
||||
)
|
||||
|
||||
/** @type {Range} */
|
||||
const range = [prevToken.range[1], prop.range[0]]
|
||||
|
||||
return fixer.replaceTextRange(range, '\n')
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
516
slider/node_modules/eslint-plugin-vue/lib/rules/max-len.js
generated
vendored
Normal file
516
slider/node_modules/eslint-plugin-vue/lib/rules/max-len.js
generated
vendored
Normal file
@@ -0,0 +1,516 @@
|
||||
/**
|
||||
* @author Yosuke Ota
|
||||
* @fileoverview Rule to check for max length on a line of Vue file.
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const utils = require('../utils')
|
||||
|
||||
const OPTIONS_SCHEMA = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
code: {
|
||||
type: 'integer',
|
||||
minimum: 0
|
||||
},
|
||||
template: {
|
||||
type: 'integer',
|
||||
minimum: 0
|
||||
},
|
||||
comments: {
|
||||
type: 'integer',
|
||||
minimum: 0
|
||||
},
|
||||
tabWidth: {
|
||||
type: 'integer',
|
||||
minimum: 0
|
||||
},
|
||||
ignorePattern: {
|
||||
type: 'string'
|
||||
},
|
||||
ignoreComments: {
|
||||
type: 'boolean'
|
||||
},
|
||||
ignoreTrailingComments: {
|
||||
type: 'boolean'
|
||||
},
|
||||
ignoreUrls: {
|
||||
type: 'boolean'
|
||||
},
|
||||
ignoreStrings: {
|
||||
type: 'boolean'
|
||||
},
|
||||
ignoreTemplateLiterals: {
|
||||
type: 'boolean'
|
||||
},
|
||||
ignoreRegExpLiterals: {
|
||||
type: 'boolean'
|
||||
},
|
||||
ignoreHTMLAttributeValues: {
|
||||
type: 'boolean'
|
||||
},
|
||||
ignoreHTMLTextContents: {
|
||||
type: 'boolean'
|
||||
}
|
||||
},
|
||||
additionalProperties: false
|
||||
}
|
||||
|
||||
const OPTIONS_OR_INTEGER_SCHEMA = {
|
||||
oneOf: [
|
||||
OPTIONS_SCHEMA,
|
||||
{
|
||||
type: 'integer',
|
||||
minimum: 0
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the length of a line that may contain tabs. The width of each
|
||||
* tab will be the number of spaces to the next tab stop.
|
||||
* @param {string} line The line.
|
||||
* @param {number} tabWidth The width of each tab stop in spaces.
|
||||
* @returns {number} The computed line length.
|
||||
* @private
|
||||
*/
|
||||
function computeLineLength(line, tabWidth) {
|
||||
let extraCharacterCount = 0
|
||||
|
||||
const re = /\t/gu
|
||||
let ret
|
||||
while ((ret = re.exec(line))) {
|
||||
const offset = ret.index
|
||||
const totalOffset = offset + extraCharacterCount
|
||||
const previousTabStopOffset = tabWidth ? totalOffset % tabWidth : 0
|
||||
const spaceCount = tabWidth - previousTabStopOffset
|
||||
extraCharacterCount += spaceCount - 1 // -1 for the replaced tab
|
||||
}
|
||||
|
||||
return [...line].length + extraCharacterCount
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells if a given comment is trailing: it starts on the current line and
|
||||
* extends to or past the end of the current line.
|
||||
* @param {string} line The source line we want to check for a trailing comment on
|
||||
* @param {number} lineNumber The one-indexed line number for line
|
||||
* @param {Token | null} comment The comment to inspect
|
||||
* @returns {comment is Token} If the comment is trailing on the given line
|
||||
*/
|
||||
function isTrailingComment(line, lineNumber, comment) {
|
||||
return Boolean(
|
||||
comment &&
|
||||
comment.loc.start.line === lineNumber &&
|
||||
lineNumber <= comment.loc.end.line &&
|
||||
(comment.loc.end.line > lineNumber ||
|
||||
comment.loc.end.column === line.length)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells if a comment encompasses the entire line.
|
||||
* @param {string} line The source line with a trailing comment
|
||||
* @param {number} lineNumber The one-indexed line number this is on
|
||||
* @param {Token | null} comment The comment to remove
|
||||
* @returns {boolean} If the comment covers the entire line
|
||||
*/
|
||||
function isFullLineComment(line, lineNumber, comment) {
|
||||
if (!comment) {
|
||||
return false
|
||||
}
|
||||
const start = comment.loc.start
|
||||
const end = comment.loc.end
|
||||
const isFirstTokenOnLine = !line.slice(0, comment.loc.start.column).trim()
|
||||
|
||||
return (
|
||||
comment &&
|
||||
(start.line < lineNumber ||
|
||||
(start.line === lineNumber && isFirstTokenOnLine)) &&
|
||||
(end.line > lineNumber ||
|
||||
(end.line === lineNumber && end.column === line.length))
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the line after the comment and any remaining trailing whitespace is
|
||||
* stripped.
|
||||
* @param {string} line The source line with a trailing comment
|
||||
* @param {Token} comment The comment to remove
|
||||
* @returns {string} Line without comment and trailing whitepace
|
||||
*/
|
||||
function stripTrailingComment(line, comment) {
|
||||
// loc.column is zero-indexed
|
||||
return line.slice(0, comment.loc.start.column).replace(/\s+$/u, '')
|
||||
}
|
||||
|
||||
/**
|
||||
* Group AST nodes by line number, both start and end.
|
||||
*
|
||||
* @param {Token[]} nodes the AST nodes in question
|
||||
* @returns { { [key: number]: Token[] } } the grouped nodes
|
||||
* @private
|
||||
*/
|
||||
function groupByLineNumber(nodes) {
|
||||
/** @type { { [key: number]: Token[] } } */
|
||||
const grouped = {}
|
||||
for (const node of nodes) {
|
||||
for (let i = node.loc.start.line; i <= node.loc.end.line; ++i) {
|
||||
if (!Array.isArray(grouped[i])) {
|
||||
grouped[i] = []
|
||||
}
|
||||
grouped[i].push(node)
|
||||
}
|
||||
}
|
||||
return grouped
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'layout',
|
||||
|
||||
docs: {
|
||||
description: 'enforce a maximum line length in `.vue` files',
|
||||
categories: undefined,
|
||||
url: 'https://eslint.vuejs.org/rules/max-len.html',
|
||||
extensionSource: {
|
||||
url: 'https://eslint.org/docs/rules/max-len',
|
||||
name: 'ESLint core'
|
||||
}
|
||||
},
|
||||
|
||||
schema: [
|
||||
OPTIONS_OR_INTEGER_SCHEMA,
|
||||
OPTIONS_OR_INTEGER_SCHEMA,
|
||||
OPTIONS_SCHEMA
|
||||
],
|
||||
messages: {
|
||||
max: 'This line has a length of {{lineLength}}. Maximum allowed is {{maxLength}}.',
|
||||
maxComment:
|
||||
'This line has a comment length of {{lineLength}}. Maximum allowed is {{maxCommentLength}}.'
|
||||
}
|
||||
},
|
||||
/**
|
||||
* @param {RuleContext} context - The rule context.
|
||||
* @returns {RuleListener} AST event handlers.
|
||||
*/
|
||||
create(context) {
|
||||
/*
|
||||
* Inspired by http://tools.ietf.org/html/rfc3986#appendix-B, however:
|
||||
* - They're matching an entire string that we know is a URI
|
||||
* - We're matching part of a string where we think there *might* be a URL
|
||||
* - We're only concerned about URLs, as picking out any URI would cause
|
||||
* too many false positives
|
||||
* - We don't care about matching the entire URL, any small segment is fine
|
||||
*/
|
||||
const URL_REGEXP = /[^:/?#]:\/\/[^?#]/u
|
||||
|
||||
const sourceCode = context.getSourceCode()
|
||||
/** @type {Token[]} */
|
||||
const tokens = []
|
||||
/** @type {(HTMLComment | HTMLBogusComment | Comment)[]} */
|
||||
const comments = []
|
||||
/** @type {VLiteral[]} */
|
||||
const htmlAttributeValues = []
|
||||
|
||||
// The options object must be the last option specified…
|
||||
const options = Object.assign(
|
||||
{},
|
||||
context.options[context.options.length - 1]
|
||||
)
|
||||
|
||||
// …but max code length…
|
||||
if (typeof context.options[0] === 'number') {
|
||||
options.code = context.options[0]
|
||||
}
|
||||
|
||||
// …and tabWidth can be optionally specified directly as integers.
|
||||
if (typeof context.options[1] === 'number') {
|
||||
options.tabWidth = context.options[1]
|
||||
}
|
||||
/** @type {number} */
|
||||
const scriptMaxLength = typeof options.code === 'number' ? options.code : 80
|
||||
/** @type {number} */
|
||||
const tabWidth = typeof options.tabWidth === 'number' ? options.tabWidth : 2 // default value of `vue/html-indent`
|
||||
/** @type {number} */
|
||||
const templateMaxLength =
|
||||
typeof options.template === 'number' ? options.template : scriptMaxLength
|
||||
const ignoreComments = !!options.ignoreComments
|
||||
const ignoreStrings = !!options.ignoreStrings
|
||||
const ignoreTemplateLiterals = !!options.ignoreTemplateLiterals
|
||||
const ignoreRegExpLiterals = !!options.ignoreRegExpLiterals
|
||||
const ignoreTrailingComments =
|
||||
!!options.ignoreTrailingComments || !!options.ignoreComments
|
||||
const ignoreUrls = !!options.ignoreUrls
|
||||
const ignoreHTMLAttributeValues = !!options.ignoreHTMLAttributeValues
|
||||
const ignoreHTMLTextContents = !!options.ignoreHTMLTextContents
|
||||
/** @type {number} */
|
||||
const maxCommentLength = options.comments
|
||||
/** @type {RegExp} */
|
||||
let ignorePattern = options.ignorePattern || null
|
||||
|
||||
if (ignorePattern) {
|
||||
ignorePattern = new RegExp(ignorePattern, 'u')
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves an array containing all strings (" or ') in the source code.
|
||||
*
|
||||
* @returns {Token[]} An array of string nodes.
|
||||
*/
|
||||
function getAllStrings() {
|
||||
return tokens.filter(
|
||||
(token) =>
|
||||
token.type === 'String' ||
|
||||
(token.type === 'JSXText' &&
|
||||
sourceCode.getNodeByRangeIndex(token.range[0] - 1).type ===
|
||||
'JSXAttribute')
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves an array containing all template literals in the source code.
|
||||
*
|
||||
* @returns {Token[]} An array of template literal nodes.
|
||||
*/
|
||||
function getAllTemplateLiterals() {
|
||||
return tokens.filter((token) => token.type === 'Template')
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves an array containing all RegExp literals in the source code.
|
||||
*
|
||||
* @returns {Token[]} An array of RegExp literal nodes.
|
||||
*/
|
||||
function getAllRegExpLiterals() {
|
||||
return tokens.filter((token) => token.type === 'RegularExpression')
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves an array containing all HTML texts in the source code.
|
||||
*
|
||||
* @returns {Token[]} An array of HTML text nodes.
|
||||
*/
|
||||
function getAllHTMLTextContents() {
|
||||
return tokens.filter((token) => token.type === 'HTMLText')
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the program for max length
|
||||
* @param {Program} node Node to examine
|
||||
* @returns {void}
|
||||
* @private
|
||||
*/
|
||||
function checkProgramForMaxLength(node) {
|
||||
const programNode = node
|
||||
const templateBody = node.templateBody
|
||||
|
||||
// setup tokens
|
||||
const scriptTokens = sourceCode.ast.tokens
|
||||
const scriptComments = sourceCode.getAllComments()
|
||||
|
||||
if (sourceCode.parserServices.getTemplateBodyTokenStore && templateBody) {
|
||||
const tokenStore = sourceCode.parserServices.getTemplateBodyTokenStore()
|
||||
|
||||
const templateTokens = tokenStore.getTokens(templateBody, {
|
||||
includeComments: true
|
||||
})
|
||||
|
||||
if (templateBody.range[0] < programNode.range[0]) {
|
||||
tokens.push(...templateTokens, ...scriptTokens)
|
||||
} else {
|
||||
tokens.push(...scriptTokens, ...templateTokens)
|
||||
}
|
||||
} else {
|
||||
tokens.push(...scriptTokens)
|
||||
}
|
||||
|
||||
if (ignoreComments || maxCommentLength || ignoreTrailingComments) {
|
||||
// list of comments to ignore
|
||||
if (templateBody) {
|
||||
if (templateBody.range[0] < programNode.range[0]) {
|
||||
comments.push(...templateBody.comments, ...scriptComments)
|
||||
} else {
|
||||
comments.push(...scriptComments, ...templateBody.comments)
|
||||
}
|
||||
} else {
|
||||
comments.push(...scriptComments)
|
||||
}
|
||||
}
|
||||
|
||||
/** @type {Range | undefined} */
|
||||
let scriptLinesRange
|
||||
if (scriptTokens.length > 0) {
|
||||
scriptLinesRange =
|
||||
scriptComments.length > 0
|
||||
? [
|
||||
Math.min(
|
||||
scriptTokens[0].loc.start.line,
|
||||
scriptComments[0].loc.start.line
|
||||
),
|
||||
Math.max(
|
||||
scriptTokens[scriptTokens.length - 1].loc.end.line,
|
||||
scriptComments[scriptComments.length - 1].loc.end.line
|
||||
)
|
||||
]
|
||||
: [
|
||||
scriptTokens[0].loc.start.line,
|
||||
scriptTokens[scriptTokens.length - 1].loc.end.line
|
||||
]
|
||||
} else if (scriptComments.length > 0) {
|
||||
scriptLinesRange = [
|
||||
scriptComments[0].loc.start.line,
|
||||
scriptComments[scriptComments.length - 1].loc.end.line
|
||||
]
|
||||
}
|
||||
const templateLinesRange = templateBody && [
|
||||
templateBody.loc.start.line,
|
||||
templateBody.loc.end.line
|
||||
]
|
||||
|
||||
// split (honors line-ending)
|
||||
const lines = sourceCode.lines
|
||||
|
||||
const strings = getAllStrings()
|
||||
const stringsByLine = groupByLineNumber(strings)
|
||||
|
||||
const templateLiterals = getAllTemplateLiterals()
|
||||
const templateLiteralsByLine = groupByLineNumber(templateLiterals)
|
||||
|
||||
const regExpLiterals = getAllRegExpLiterals()
|
||||
const regExpLiteralsByLine = groupByLineNumber(regExpLiterals)
|
||||
|
||||
const htmlAttributeValuesByLine = groupByLineNumber(htmlAttributeValues)
|
||||
|
||||
const htmlTextContents = getAllHTMLTextContents()
|
||||
const htmlTextContentsByLine = groupByLineNumber(htmlTextContents)
|
||||
|
||||
const commentsByLine = groupByLineNumber(comments)
|
||||
|
||||
for (const [i, line] of lines.entries()) {
|
||||
// i is zero-indexed, line numbers are one-indexed
|
||||
const lineNumber = i + 1
|
||||
|
||||
const inScript =
|
||||
scriptLinesRange &&
|
||||
scriptLinesRange[0] <= lineNumber &&
|
||||
lineNumber <= scriptLinesRange[1]
|
||||
const inTemplate =
|
||||
templateLinesRange &&
|
||||
templateLinesRange[0] <= lineNumber &&
|
||||
lineNumber <= templateLinesRange[1]
|
||||
// check if line is inside a script or template.
|
||||
if (!inScript && !inTemplate) {
|
||||
// out of range.
|
||||
continue
|
||||
}
|
||||
const maxLength = Math.max(
|
||||
inScript ? scriptMaxLength : 0,
|
||||
inTemplate ? templateMaxLength : 0
|
||||
)
|
||||
|
||||
if (
|
||||
(ignoreStrings && stringsByLine[lineNumber]) ||
|
||||
(ignoreTemplateLiterals && templateLiteralsByLine[lineNumber]) ||
|
||||
(ignoreRegExpLiterals && regExpLiteralsByLine[lineNumber]) ||
|
||||
(ignoreHTMLAttributeValues &&
|
||||
htmlAttributeValuesByLine[lineNumber]) ||
|
||||
(ignoreHTMLTextContents && htmlTextContentsByLine[lineNumber])
|
||||
) {
|
||||
// ignore this line
|
||||
continue
|
||||
}
|
||||
|
||||
/*
|
||||
* if we're checking comment length; we need to know whether this
|
||||
* line is a comment
|
||||
*/
|
||||
let lineIsComment = false
|
||||
let textToMeasure
|
||||
|
||||
/*
|
||||
* comments to check.
|
||||
*/
|
||||
if (commentsByLine[lineNumber]) {
|
||||
const commentList = [...commentsByLine[lineNumber]]
|
||||
|
||||
let comment = commentList.pop() || null
|
||||
|
||||
if (isFullLineComment(line, lineNumber, comment)) {
|
||||
lineIsComment = true
|
||||
textToMeasure = line
|
||||
} else if (
|
||||
ignoreTrailingComments &&
|
||||
isTrailingComment(line, lineNumber, comment)
|
||||
) {
|
||||
textToMeasure = stripTrailingComment(line, comment)
|
||||
|
||||
// ignore multiple trailing comments in the same line
|
||||
comment = commentList.pop() || null
|
||||
|
||||
while (isTrailingComment(textToMeasure, lineNumber, comment)) {
|
||||
textToMeasure = stripTrailingComment(textToMeasure, comment)
|
||||
}
|
||||
} else {
|
||||
textToMeasure = line
|
||||
}
|
||||
} else {
|
||||
textToMeasure = line
|
||||
}
|
||||
|
||||
if (
|
||||
(ignorePattern && ignorePattern.test(textToMeasure)) ||
|
||||
(ignoreUrls && URL_REGEXP.test(textToMeasure))
|
||||
) {
|
||||
// ignore this line
|
||||
continue
|
||||
}
|
||||
|
||||
const lineLength = computeLineLength(textToMeasure, tabWidth)
|
||||
const commentLengthApplies = lineIsComment && maxCommentLength
|
||||
|
||||
if (lineIsComment && ignoreComments) {
|
||||
continue
|
||||
}
|
||||
|
||||
if (commentLengthApplies) {
|
||||
if (lineLength > maxCommentLength) {
|
||||
context.report({
|
||||
node,
|
||||
loc: { line: lineNumber, column: 0 },
|
||||
messageId: 'maxComment',
|
||||
data: {
|
||||
lineLength,
|
||||
maxCommentLength
|
||||
}
|
||||
})
|
||||
}
|
||||
} else if (lineLength > maxLength) {
|
||||
context.report({
|
||||
node,
|
||||
loc: { line: lineNumber, column: 0 },
|
||||
messageId: 'max',
|
||||
data: {
|
||||
lineLength,
|
||||
maxLength
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return utils.compositingVisitors(
|
||||
utils.defineTemplateBodyVisitor(context, {
|
||||
/** @param {VLiteral} node */
|
||||
'VAttribute[directive=false] > VLiteral'(node) {
|
||||
htmlAttributeValues.push(node)
|
||||
}
|
||||
}),
|
||||
{
|
||||
'Program:exit'(node) {
|
||||
checkProgramForMaxLength(node)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
111
slider/node_modules/eslint-plugin-vue/lib/rules/max-lines-per-block.js
generated
vendored
Normal file
111
slider/node_modules/eslint-plugin-vue/lib/rules/max-lines-per-block.js
generated
vendored
Normal file
@@ -0,0 +1,111 @@
|
||||
/**
|
||||
* @author lsdsjy
|
||||
* @fileoverview Rule for checking the maximum number of lines in Vue SFC blocks.
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const { SourceCode } = require('eslint')
|
||||
const utils = require('../utils')
|
||||
|
||||
/**
|
||||
* @param {string} text
|
||||
*/
|
||||
function isEmptyLine(text) {
|
||||
return !text.trim()
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description: 'enforce maximum number of lines in Vue SFC blocks',
|
||||
categories: undefined,
|
||||
url: 'https://eslint.vuejs.org/rules/max-lines-per-block.html'
|
||||
},
|
||||
fixable: null,
|
||||
schema: [
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
style: {
|
||||
type: 'integer',
|
||||
minimum: 1
|
||||
},
|
||||
template: {
|
||||
type: 'integer',
|
||||
minimum: 1
|
||||
},
|
||||
script: {
|
||||
type: 'integer',
|
||||
minimum: 1
|
||||
},
|
||||
skipBlankLines: {
|
||||
type: 'boolean',
|
||||
minimum: 0
|
||||
}
|
||||
},
|
||||
additionalProperties: false
|
||||
}
|
||||
],
|
||||
messages: {
|
||||
tooManyLines:
|
||||
'Block has too many lines ({{lineCount}}). Maximum allowed is {{limit}}.'
|
||||
}
|
||||
},
|
||||
/** @param {RuleContext} context */
|
||||
create(context) {
|
||||
const option = context.options[0] || {}
|
||||
/**
|
||||
* @type {Record<string, number>}
|
||||
*/
|
||||
const limits = {
|
||||
template: option.template,
|
||||
script: option.script,
|
||||
style: option.style
|
||||
}
|
||||
|
||||
const code = context.getSourceCode()
|
||||
const sourceCode = context.getSourceCode()
|
||||
const documentFragment =
|
||||
sourceCode.parserServices.getDocumentFragment &&
|
||||
sourceCode.parserServices.getDocumentFragment()
|
||||
|
||||
function getTopLevelHTMLElements() {
|
||||
if (documentFragment) {
|
||||
return documentFragment.children.filter(utils.isVElement)
|
||||
}
|
||||
return []
|
||||
}
|
||||
|
||||
return {
|
||||
/** @param {Program} node */
|
||||
Program(node) {
|
||||
if (utils.hasInvalidEOF(node)) {
|
||||
return
|
||||
}
|
||||
for (const block of getTopLevelHTMLElements()) {
|
||||
if (limits[block.name]) {
|
||||
// We suppose the start tag and end tag occupy one single line respectively
|
||||
let lineCount = block.loc.end.line - block.loc.start.line - 1
|
||||
|
||||
if (option.skipBlankLines) {
|
||||
const lines = SourceCode.splitLines(code.getText(block))
|
||||
lineCount -= lines.filter(isEmptyLine).length
|
||||
}
|
||||
|
||||
if (lineCount > limits[block.name]) {
|
||||
context.report({
|
||||
node: block,
|
||||
messageId: 'tooManyLines',
|
||||
data: {
|
||||
limit: limits[block.name],
|
||||
lineCount
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
81
slider/node_modules/eslint-plugin-vue/lib/rules/max-props.js
generated
vendored
Normal file
81
slider/node_modules/eslint-plugin-vue/lib/rules/max-props.js
generated
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
/**
|
||||
* @author kevsommer Kevin Sommer
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
'use strict'
|
||||
const utils = require('../utils')
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description: 'enforce maximum number of props in Vue component',
|
||||
categories: undefined,
|
||||
url: 'https://eslint.vuejs.org/rules/max-props.html'
|
||||
},
|
||||
fixable: null,
|
||||
schema: [
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
maxProps: {
|
||||
type: 'integer',
|
||||
minimum: 1
|
||||
}
|
||||
},
|
||||
additionalProperties: false,
|
||||
minProperties: 1
|
||||
}
|
||||
],
|
||||
messages: {
|
||||
tooManyProps:
|
||||
'Component has too many props ({{propCount}}). Maximum allowed is {{limit}}.'
|
||||
}
|
||||
},
|
||||
/** @param {RuleContext} context */
|
||||
create(context) {
|
||||
/** @type {Record<string, number>} */
|
||||
const option = context.options[0] || {}
|
||||
|
||||
/**
|
||||
* @param {import('../utils').ComponentProp[]} props
|
||||
* @param {CallExpression | Property} node
|
||||
*/
|
||||
function checkMaxNumberOfProps(props, node) {
|
||||
const uniqueProps = new Set(props.map((prop) => prop.propName))
|
||||
const propCount = uniqueProps.size
|
||||
if (propCount > option.maxProps && props[0].node) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'tooManyProps',
|
||||
data: {
|
||||
propCount,
|
||||
limit: option.maxProps
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return utils.compositingVisitors(
|
||||
utils.executeOnVue(context, (node) => {
|
||||
const propsNode = node.properties.find(
|
||||
/** @returns {p is Property} */
|
||||
(p) =>
|
||||
p.type === 'Property' && utils.getStaticPropertyName(p) === 'props'
|
||||
)
|
||||
|
||||
if (!propsNode) return
|
||||
|
||||
checkMaxNumberOfProps(
|
||||
utils.getComponentPropsFromOptions(node),
|
||||
propsNode
|
||||
)
|
||||
}),
|
||||
utils.defineScriptSetupVisitor(context, {
|
||||
onDefinePropsEnter(node, props) {
|
||||
checkMaxNumberOfProps(props, node)
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
82
slider/node_modules/eslint-plugin-vue/lib/rules/max-template-depth.js
generated
vendored
Normal file
82
slider/node_modules/eslint-plugin-vue/lib/rules/max-template-depth.js
generated
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
/**
|
||||
* @author kevsommer Kevin Sommer
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description: 'enforce maximum depth of template',
|
||||
categories: undefined,
|
||||
url: 'https://eslint.vuejs.org/rules/max-template-depth.html'
|
||||
},
|
||||
fixable: null,
|
||||
schema: [
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
maxDepth: {
|
||||
type: 'integer',
|
||||
minimum: 1
|
||||
}
|
||||
},
|
||||
additionalProperties: false,
|
||||
minProperties: 1
|
||||
}
|
||||
],
|
||||
messages: {
|
||||
templateTooDeep:
|
||||
'Element is nested too deeply (depth of {{depth}}, maximum allowed is {{limit}}).'
|
||||
}
|
||||
},
|
||||
/** @param {RuleContext} context */
|
||||
create(context) {
|
||||
const option = context.options[0] || {}
|
||||
|
||||
/**
|
||||
* @param {VElement} element
|
||||
* @param {number} curDepth
|
||||
*/
|
||||
function checkMaxDepth(element, curDepth) {
|
||||
if (curDepth > option.maxDepth) {
|
||||
context.report({
|
||||
node: element,
|
||||
messageId: 'templateTooDeep',
|
||||
data: {
|
||||
depth: curDepth,
|
||||
limit: option.maxDepth
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (!element.children) {
|
||||
return
|
||||
}
|
||||
|
||||
for (const child of element.children) {
|
||||
if (child.type === 'VElement') {
|
||||
checkMaxDepth(child, curDepth + 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
/** @param {Program} program */
|
||||
Program(program) {
|
||||
const element = program.templateBody
|
||||
|
||||
if (element == null) {
|
||||
return
|
||||
}
|
||||
|
||||
if (element.type !== 'VElement') {
|
||||
return
|
||||
}
|
||||
|
||||
checkMaxDepth(element, 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
135
slider/node_modules/eslint-plugin-vue/lib/rules/multi-word-component-names.js
generated
vendored
Normal file
135
slider/node_modules/eslint-plugin-vue/lib/rules/multi-word-component-names.js
generated
vendored
Normal file
@@ -0,0 +1,135 @@
|
||||
/**
|
||||
* @author Marton Csordas
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const path = require('path')
|
||||
const casing = require('../utils/casing')
|
||||
const utils = require('../utils')
|
||||
|
||||
const RESERVED_NAMES_IN_VUE3 = new Set(
|
||||
require('../utils/vue3-builtin-components')
|
||||
)
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'suggestion',
|
||||
docs: {
|
||||
description: 'require component names to be always multi-word',
|
||||
categories: ['vue3-essential', 'vue2-essential'],
|
||||
url: 'https://eslint.vuejs.org/rules/multi-word-component-names.html'
|
||||
},
|
||||
schema: [
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
ignores: {
|
||||
type: 'array',
|
||||
items: { type: 'string' },
|
||||
uniqueItems: true,
|
||||
additionalItems: false
|
||||
}
|
||||
},
|
||||
additionalProperties: false
|
||||
}
|
||||
],
|
||||
messages: {
|
||||
unexpected: 'Component name "{{value}}" should always be multi-word.'
|
||||
}
|
||||
},
|
||||
/** @param {RuleContext} context */
|
||||
create(context) {
|
||||
/** @type {Set<string>} */
|
||||
const ignores = new Set()
|
||||
ignores.add('App')
|
||||
ignores.add('app')
|
||||
for (const ignore of (context.options[0] && context.options[0].ignores) ||
|
||||
[]) {
|
||||
ignores.add(ignore)
|
||||
if (casing.isPascalCase(ignore)) {
|
||||
// PascalCase
|
||||
ignores.add(casing.kebabCase(ignore))
|
||||
}
|
||||
}
|
||||
let hasVue = utils.isScriptSetup(context)
|
||||
let hasName = false
|
||||
|
||||
/**
|
||||
* Returns true if the given component name is valid, otherwise false.
|
||||
* @param {string} name
|
||||
* */
|
||||
function isValidComponentName(name) {
|
||||
if (ignores.has(name) || RESERVED_NAMES_IN_VUE3.has(name)) {
|
||||
return true
|
||||
}
|
||||
const elements = casing.kebabCase(name).split('-')
|
||||
return elements.length > 1
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Expression | SpreadElement} nameNode
|
||||
*/
|
||||
function validateName(nameNode) {
|
||||
if (nameNode.type !== 'Literal') return
|
||||
const componentName = `${nameNode.value}`
|
||||
if (!isValidComponentName(componentName)) {
|
||||
context.report({
|
||||
node: nameNode,
|
||||
messageId: 'unexpected',
|
||||
data: {
|
||||
value: componentName
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return utils.compositingVisitors(
|
||||
utils.executeOnCallVueComponent(context, (node) => {
|
||||
hasVue = true
|
||||
if (node.arguments.length !== 2) return
|
||||
hasName = true
|
||||
validateName(node.arguments[0])
|
||||
}),
|
||||
utils.executeOnVue(context, (obj) => {
|
||||
hasVue = true
|
||||
const node = utils.findProperty(obj, 'name')
|
||||
if (!node) return
|
||||
hasName = true
|
||||
validateName(node.value)
|
||||
}),
|
||||
utils.defineScriptSetupVisitor(context, {
|
||||
onDefineOptionsEnter(node) {
|
||||
if (node.arguments.length === 0) return
|
||||
const define = node.arguments[0]
|
||||
if (define.type !== 'ObjectExpression') return
|
||||
const nameNode = utils.findProperty(define, 'name')
|
||||
if (!nameNode) return
|
||||
hasName = true
|
||||
validateName(nameNode.value)
|
||||
}
|
||||
}),
|
||||
{
|
||||
/** @param {Program} node */
|
||||
'Program:exit'(node) {
|
||||
if (hasName) return
|
||||
if (!hasVue && node.body.length > 0) return
|
||||
const fileName = context.getFilename()
|
||||
const componentName = path.basename(fileName, path.extname(fileName))
|
||||
if (
|
||||
utils.isVueFile(fileName) &&
|
||||
!isValidComponentName(componentName)
|
||||
) {
|
||||
context.report({
|
||||
messageId: 'unexpected',
|
||||
data: {
|
||||
value: componentName
|
||||
},
|
||||
loc: { line: 1, column: 0 }
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
229
slider/node_modules/eslint-plugin-vue/lib/rules/multiline-html-element-content-newline.js
generated
vendored
Normal file
229
slider/node_modules/eslint-plugin-vue/lib/rules/multiline-html-element-content-newline.js
generated
vendored
Normal file
@@ -0,0 +1,229 @@
|
||||
/**
|
||||
* @author Yosuke Ota
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const utils = require('../utils')
|
||||
const casing = require('../utils/casing')
|
||||
const INLINE_ELEMENTS = require('../utils/inline-non-void-elements.json')
|
||||
|
||||
/**
|
||||
* @param {VElement & { endTag: VEndTag }} element
|
||||
*/
|
||||
function isMultilineElement(element) {
|
||||
return element.loc.start.line < element.endTag.loc.start.line
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {any} options
|
||||
*/
|
||||
function parseOptions(options) {
|
||||
return Object.assign(
|
||||
{
|
||||
ignores: ['pre', 'textarea', ...INLINE_ELEMENTS],
|
||||
ignoreWhenEmpty: true,
|
||||
allowEmptyLines: false
|
||||
},
|
||||
options
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} lineBreaks
|
||||
*/
|
||||
function getPhrase(lineBreaks) {
|
||||
switch (lineBreaks) {
|
||||
case 0: {
|
||||
return 'no'
|
||||
}
|
||||
default: {
|
||||
return `${lineBreaks}`
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Check whether the given element is empty or not.
|
||||
* This ignores whitespaces, doesn't ignore comments.
|
||||
* @param {VElement & { endTag: VEndTag }} node The element node to check.
|
||||
* @param {SourceCode} sourceCode The source code object of the current context.
|
||||
* @returns {boolean} `true` if the element is empty.
|
||||
*/
|
||||
function isEmpty(node, sourceCode) {
|
||||
const start = node.startTag.range[1]
|
||||
const end = node.endTag.range[0]
|
||||
return sourceCode.text.slice(start, end).trim() === ''
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'layout',
|
||||
docs: {
|
||||
description:
|
||||
'require a line break before and after the contents of a multiline element',
|
||||
categories: ['vue3-strongly-recommended', 'vue2-strongly-recommended'],
|
||||
url: 'https://eslint.vuejs.org/rules/multiline-html-element-content-newline.html'
|
||||
},
|
||||
fixable: 'whitespace',
|
||||
schema: [
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
ignoreWhenEmpty: {
|
||||
type: 'boolean'
|
||||
},
|
||||
ignores: {
|
||||
type: 'array',
|
||||
items: { type: 'string' },
|
||||
uniqueItems: true,
|
||||
additionalItems: false
|
||||
},
|
||||
allowEmptyLines: {
|
||||
type: 'boolean'
|
||||
}
|
||||
},
|
||||
additionalProperties: false
|
||||
}
|
||||
],
|
||||
messages: {
|
||||
unexpectedAfterClosingBracket:
|
||||
'Expected 1 line break after opening tag (`<{{name}}>`), but {{actual}} line breaks found.',
|
||||
unexpectedBeforeOpeningBracket:
|
||||
'Expected 1 line break before closing tag (`</{{name}}>`), but {{actual}} line breaks found.'
|
||||
}
|
||||
},
|
||||
/** @param {RuleContext} context */
|
||||
create(context) {
|
||||
const options = parseOptions(context.options[0])
|
||||
const ignores = options.ignores
|
||||
const ignoreWhenEmpty = options.ignoreWhenEmpty
|
||||
const allowEmptyLines = options.allowEmptyLines
|
||||
const sourceCode = context.getSourceCode()
|
||||
const template =
|
||||
sourceCode.parserServices.getTemplateBodyTokenStore &&
|
||||
sourceCode.parserServices.getTemplateBodyTokenStore()
|
||||
|
||||
/** @type {VElement | null} */
|
||||
let inIgnoreElement = null
|
||||
|
||||
/**
|
||||
* @param {VElement} node
|
||||
*/
|
||||
function isIgnoredElement(node) {
|
||||
return (
|
||||
ignores.includes(node.name) ||
|
||||
ignores.includes(casing.pascalCase(node.rawName)) ||
|
||||
ignores.includes(casing.kebabCase(node.rawName))
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} lineBreaks
|
||||
*/
|
||||
function isInvalidLineBreaks(lineBreaks) {
|
||||
return allowEmptyLines ? lineBreaks === 0 : lineBreaks !== 1
|
||||
}
|
||||
|
||||
return utils.defineTemplateBodyVisitor(context, {
|
||||
VElement(node) {
|
||||
if (inIgnoreElement) {
|
||||
return
|
||||
}
|
||||
if (isIgnoredElement(node)) {
|
||||
// ignore element name
|
||||
inIgnoreElement = node
|
||||
return
|
||||
}
|
||||
if (node.startTag.selfClosing || !node.endTag) {
|
||||
// self closing
|
||||
return
|
||||
}
|
||||
|
||||
const element = /** @type {VElement & { endTag: VEndTag }} */ (node)
|
||||
|
||||
if (!isMultilineElement(element)) {
|
||||
return
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {SourceCode.CursorWithCountOptions}
|
||||
*/
|
||||
const getTokenOption = {
|
||||
includeComments: true,
|
||||
filter: (token) => token.type !== 'HTMLWhitespace'
|
||||
}
|
||||
if (
|
||||
ignoreWhenEmpty &&
|
||||
element.children.length === 0 &&
|
||||
template.getFirstTokensBetween(
|
||||
element.startTag,
|
||||
element.endTag,
|
||||
getTokenOption
|
||||
).length === 0
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
||||
const contentFirst = /** @type {Token} */ (
|
||||
template.getTokenAfter(element.startTag, getTokenOption)
|
||||
)
|
||||
const contentLast = /** @type {Token} */ (
|
||||
template.getTokenBefore(element.endTag, getTokenOption)
|
||||
)
|
||||
|
||||
const beforeLineBreaks =
|
||||
contentFirst.loc.start.line - element.startTag.loc.end.line
|
||||
const afterLineBreaks =
|
||||
element.endTag.loc.start.line - contentLast.loc.end.line
|
||||
if (isInvalidLineBreaks(beforeLineBreaks)) {
|
||||
context.report({
|
||||
node: template.getLastToken(element.startTag),
|
||||
loc: {
|
||||
start: element.startTag.loc.end,
|
||||
end: contentFirst.loc.start
|
||||
},
|
||||
messageId: 'unexpectedAfterClosingBracket',
|
||||
data: {
|
||||
name: element.rawName,
|
||||
actual: getPhrase(beforeLineBreaks)
|
||||
},
|
||||
fix(fixer) {
|
||||
/** @type {Range} */
|
||||
const range = [element.startTag.range[1], contentFirst.range[0]]
|
||||
return fixer.replaceTextRange(range, '\n')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (isEmpty(element, sourceCode)) {
|
||||
return
|
||||
}
|
||||
|
||||
if (isInvalidLineBreaks(afterLineBreaks)) {
|
||||
context.report({
|
||||
node: template.getFirstToken(element.endTag),
|
||||
loc: {
|
||||
start: contentLast.loc.end,
|
||||
end: element.endTag.loc.start
|
||||
},
|
||||
messageId: 'unexpectedBeforeOpeningBracket',
|
||||
data: {
|
||||
name: element.name,
|
||||
actual: getPhrase(afterLineBreaks)
|
||||
},
|
||||
fix(fixer) {
|
||||
/** @type {Range} */
|
||||
const range = [contentLast.range[1], element.endTag.range[0]]
|
||||
return fixer.replaceTextRange(range, '\n')
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
'VElement:exit'(node) {
|
||||
if (inIgnoreElement === node) {
|
||||
inIgnoreElement = null
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
13
slider/node_modules/eslint-plugin-vue/lib/rules/multiline-ternary.js
generated
vendored
Normal file
13
slider/node_modules/eslint-plugin-vue/lib/rules/multiline-ternary.js
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* @author dev1437
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const { wrapStylisticOrCoreRule } = require('../utils')
|
||||
|
||||
// eslint-disable-next-line internal/no-invalid-meta
|
||||
module.exports = wrapStylisticOrCoreRule('multiline-ternary', {
|
||||
skipDynamicArguments: true,
|
||||
applyDocument: true
|
||||
})
|
102
slider/node_modules/eslint-plugin-vue/lib/rules/mustache-interpolation-spacing.js
generated
vendored
Normal file
102
slider/node_modules/eslint-plugin-vue/lib/rules/mustache-interpolation-spacing.js
generated
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
/**
|
||||
* @fileoverview enforce unified spacing in mustache interpolations.
|
||||
* @author Armano
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const utils = require('../utils')
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'layout',
|
||||
docs: {
|
||||
description: 'enforce unified spacing in mustache interpolations',
|
||||
categories: ['vue3-strongly-recommended', 'vue2-strongly-recommended'],
|
||||
url: 'https://eslint.vuejs.org/rules/mustache-interpolation-spacing.html'
|
||||
},
|
||||
fixable: 'whitespace',
|
||||
schema: [
|
||||
{
|
||||
enum: ['always', 'never']
|
||||
}
|
||||
],
|
||||
messages: {
|
||||
expectedSpaceAfter: "Expected 1 space after '{{', but not found.",
|
||||
expectedSpaceBefore: "Expected 1 space before '}}', but not found.",
|
||||
unexpectedSpaceAfter: "Expected no space after '{{', but found.",
|
||||
unexpectedSpaceBefore: "Expected no space before '}}', but found."
|
||||
}
|
||||
},
|
||||
/** @param {RuleContext} context */
|
||||
create(context) {
|
||||
const options = context.options[0] || 'always'
|
||||
const sourceCode = context.getSourceCode()
|
||||
const template =
|
||||
sourceCode.parserServices.getTemplateBodyTokenStore &&
|
||||
sourceCode.parserServices.getTemplateBodyTokenStore()
|
||||
|
||||
return utils.defineTemplateBodyVisitor(context, {
|
||||
/** @param {VExpressionContainer} node */
|
||||
'VExpressionContainer[expression!=null]'(node) {
|
||||
const openBrace = template.getFirstToken(node)
|
||||
const closeBrace = template.getLastToken(node)
|
||||
|
||||
if (
|
||||
!openBrace ||
|
||||
!closeBrace ||
|
||||
openBrace.type !== 'VExpressionStart' ||
|
||||
closeBrace.type !== 'VExpressionEnd'
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
||||
const firstToken = template.getTokenAfter(openBrace, {
|
||||
includeComments: true
|
||||
})
|
||||
const lastToken = template.getTokenBefore(closeBrace, {
|
||||
includeComments: true
|
||||
})
|
||||
|
||||
if (options === 'always') {
|
||||
if (openBrace.range[1] === firstToken.range[0]) {
|
||||
context.report({
|
||||
node: openBrace,
|
||||
messageId: 'expectedSpaceAfter',
|
||||
fix: (fixer) => fixer.insertTextAfter(openBrace, ' ')
|
||||
})
|
||||
}
|
||||
if (closeBrace.range[0] === lastToken.range[1]) {
|
||||
context.report({
|
||||
node: closeBrace,
|
||||
messageId: 'expectedSpaceBefore',
|
||||
fix: (fixer) => fixer.insertTextBefore(closeBrace, ' ')
|
||||
})
|
||||
}
|
||||
} else {
|
||||
if (openBrace.range[1] !== firstToken.range[0]) {
|
||||
context.report({
|
||||
loc: {
|
||||
start: openBrace.loc.start,
|
||||
end: firstToken.loc.start
|
||||
},
|
||||
messageId: 'unexpectedSpaceAfter',
|
||||
fix: (fixer) =>
|
||||
fixer.removeRange([openBrace.range[1], firstToken.range[0]])
|
||||
})
|
||||
}
|
||||
if (closeBrace.range[0] !== lastToken.range[1]) {
|
||||
context.report({
|
||||
loc: {
|
||||
start: lastToken.loc.end,
|
||||
end: closeBrace.loc.end
|
||||
},
|
||||
messageId: 'unexpectedSpaceBefore',
|
||||
fix: (fixer) =>
|
||||
fixer.removeRange([lastToken.range[1], closeBrace.range[0]])
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
154
slider/node_modules/eslint-plugin-vue/lib/rules/new-line-between-multi-line-property.js
generated
vendored
Normal file
154
slider/node_modules/eslint-plugin-vue/lib/rules/new-line-between-multi-line-property.js
generated
vendored
Normal file
@@ -0,0 +1,154 @@
|
||||
/**
|
||||
* @fileoverview Enforce new lines between multi-line properties in Vue components.
|
||||
* @author IWANABETHATGUY
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const utils = require('../utils')
|
||||
|
||||
/**
|
||||
* @param {Token} node
|
||||
*/
|
||||
function isComma(node) {
|
||||
return node.type === 'Punctuator' && node.value === ','
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the between given nodes has empty line.
|
||||
* @param {SourceCode} sourceCode
|
||||
* @param {ASTNode} pre
|
||||
* @param {ASTNode} cur
|
||||
*/
|
||||
function* iterateBetweenTokens(sourceCode, pre, cur) {
|
||||
yield sourceCode.getLastToken(pre)
|
||||
yield* sourceCode.getTokensBetween(pre, cur, {
|
||||
includeComments: true
|
||||
})
|
||||
yield sourceCode.getFirstToken(cur)
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the between given nodes has empty line.
|
||||
* @param {SourceCode} sourceCode
|
||||
* @param {ASTNode} pre
|
||||
* @param {ASTNode} cur
|
||||
*/
|
||||
function hasEmptyLine(sourceCode, pre, cur) {
|
||||
/** @type {Token|null} */
|
||||
let preToken = null
|
||||
for (const token of iterateBetweenTokens(sourceCode, pre, cur)) {
|
||||
if (preToken && token.loc.start.line - preToken.loc.end.line >= 2) {
|
||||
return true
|
||||
}
|
||||
preToken = token
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'layout',
|
||||
docs: {
|
||||
description:
|
||||
'enforce new lines between multi-line properties in Vue components',
|
||||
categories: undefined,
|
||||
url: 'https://eslint.vuejs.org/rules/new-line-between-multi-line-property.html'
|
||||
},
|
||||
fixable: 'whitespace',
|
||||
schema: [
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
// number of line you want to insert after multi-line property
|
||||
minLineOfMultilineProperty: {
|
||||
type: 'number',
|
||||
minimum: 2
|
||||
}
|
||||
},
|
||||
additionalProperties: false
|
||||
}
|
||||
],
|
||||
messages: {
|
||||
missingEmptyLine:
|
||||
'Enforce new lines between multi-line properties in Vue components.'
|
||||
}
|
||||
},
|
||||
|
||||
/** @param {RuleContext} context */
|
||||
create(context) {
|
||||
let minLineOfMultilineProperty = 2
|
||||
if (
|
||||
context.options &&
|
||||
context.options[0] &&
|
||||
context.options[0].minLineOfMultilineProperty
|
||||
) {
|
||||
minLineOfMultilineProperty = context.options[0].minLineOfMultilineProperty
|
||||
}
|
||||
|
||||
/** @type {CallExpression[]} */
|
||||
const callStack = []
|
||||
const sourceCode = context.getSourceCode()
|
||||
return Object.assign(
|
||||
utils.defineVueVisitor(context, {
|
||||
CallExpression(node) {
|
||||
callStack.push(node)
|
||||
},
|
||||
'CallExpression:exit'() {
|
||||
callStack.pop()
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {ObjectExpression} node
|
||||
*/
|
||||
ObjectExpression(node) {
|
||||
if (callStack.length > 0) {
|
||||
return
|
||||
}
|
||||
const properties = node.properties
|
||||
for (let i = 1; i < properties.length; i++) {
|
||||
const cur = properties[i]
|
||||
const pre = properties[i - 1]
|
||||
|
||||
const lineCountOfPreProperty =
|
||||
pre.loc.end.line - pre.loc.start.line + 1
|
||||
if (lineCountOfPreProperty < minLineOfMultilineProperty) {
|
||||
continue
|
||||
}
|
||||
|
||||
if (hasEmptyLine(sourceCode, pre, cur)) {
|
||||
continue
|
||||
}
|
||||
|
||||
context.report({
|
||||
node: pre,
|
||||
loc: {
|
||||
start: pre.loc.end,
|
||||
end: cur.loc.start
|
||||
},
|
||||
messageId: 'missingEmptyLine',
|
||||
fix(fixer) {
|
||||
/** @type {Token|null} */
|
||||
let preToken = null
|
||||
for (const token of iterateBetweenTokens(
|
||||
sourceCode,
|
||||
pre,
|
||||
cur
|
||||
)) {
|
||||
if (
|
||||
preToken &&
|
||||
preToken.loc.end.line < token.loc.start.line
|
||||
) {
|
||||
return fixer.insertTextAfter(preToken, '\n')
|
||||
}
|
||||
preToken = token
|
||||
}
|
||||
const commaToken = sourceCode.getTokenAfter(pre, isComma)
|
||||
return fixer.insertTextAfter(commaToken || pre, '\n\n')
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
141
slider/node_modules/eslint-plugin-vue/lib/rules/next-tick-style.js
generated
vendored
Normal file
141
slider/node_modules/eslint-plugin-vue/lib/rules/next-tick-style.js
generated
vendored
Normal file
@@ -0,0 +1,141 @@
|
||||
/**
|
||||
* @fileoverview enforce Promise or callback style in `nextTick`
|
||||
* @author Flo Edelmann
|
||||
* @copyright 2020 Flo Edelmann. All rights reserved.
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const utils = require('../utils')
|
||||
const { findVariable } = require('@eslint-community/eslint-utils')
|
||||
|
||||
/**
|
||||
* @param {Identifier} identifier
|
||||
* @param {RuleContext} context
|
||||
* @returns {CallExpression|undefined}
|
||||
*/
|
||||
function getVueNextTickCallExpression(identifier, context) {
|
||||
// Instance API: this.$nextTick()
|
||||
if (
|
||||
identifier.name === '$nextTick' &&
|
||||
identifier.parent.type === 'MemberExpression' &&
|
||||
utils.isThis(identifier.parent.object, context) &&
|
||||
identifier.parent.parent.type === 'CallExpression' &&
|
||||
identifier.parent.parent.callee === identifier.parent
|
||||
) {
|
||||
return identifier.parent.parent
|
||||
}
|
||||
|
||||
// Vue 2 Global API: Vue.nextTick()
|
||||
if (
|
||||
identifier.name === 'nextTick' &&
|
||||
identifier.parent.type === 'MemberExpression' &&
|
||||
identifier.parent.object.type === 'Identifier' &&
|
||||
identifier.parent.object.name === 'Vue' &&
|
||||
identifier.parent.parent.type === 'CallExpression' &&
|
||||
identifier.parent.parent.callee === identifier.parent
|
||||
) {
|
||||
return identifier.parent.parent
|
||||
}
|
||||
|
||||
// Vue 3 Global API: import { nextTick as nt } from 'vue'; nt()
|
||||
if (
|
||||
identifier.parent.type === 'CallExpression' &&
|
||||
identifier.parent.callee === identifier
|
||||
) {
|
||||
const variable = findVariable(
|
||||
utils.getScope(context, identifier),
|
||||
identifier
|
||||
)
|
||||
|
||||
if (variable != null && variable.defs.length === 1) {
|
||||
const def = variable.defs[0]
|
||||
if (
|
||||
def.type === 'ImportBinding' &&
|
||||
def.node.type === 'ImportSpecifier' &&
|
||||
def.node.imported.type === 'Identifier' &&
|
||||
def.node.imported.name === 'nextTick' &&
|
||||
def.node.parent.type === 'ImportDeclaration' &&
|
||||
def.node.parent.source.value === 'vue'
|
||||
) {
|
||||
return identifier.parent
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return undefined
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {CallExpression} callExpression
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isAwaitedPromise(callExpression) {
|
||||
return (
|
||||
callExpression.parent.type === 'AwaitExpression' ||
|
||||
(callExpression.parent.type === 'MemberExpression' &&
|
||||
callExpression.parent.property.type === 'Identifier' &&
|
||||
callExpression.parent.property.name === 'then')
|
||||
)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'suggestion',
|
||||
docs: {
|
||||
description: 'enforce Promise or callback style in `nextTick`',
|
||||
categories: undefined,
|
||||
url: 'https://eslint.vuejs.org/rules/next-tick-style.html'
|
||||
},
|
||||
fixable: 'code',
|
||||
schema: [{ enum: ['promise', 'callback'] }],
|
||||
messages: {
|
||||
usePromise:
|
||||
'Use the Promise returned by `nextTick` instead of passing a callback function.',
|
||||
useCallback:
|
||||
'Pass a callback function to `nextTick` instead of using the returned Promise.'
|
||||
}
|
||||
},
|
||||
/** @param {RuleContext} context */
|
||||
create(context) {
|
||||
const preferredStyle =
|
||||
/** @type {string|undefined} */ (context.options[0]) || 'promise'
|
||||
|
||||
return utils.defineVueVisitor(context, {
|
||||
/** @param {Identifier} node */
|
||||
Identifier(node) {
|
||||
const callExpression = getVueNextTickCallExpression(node, context)
|
||||
if (!callExpression) {
|
||||
return
|
||||
}
|
||||
|
||||
if (preferredStyle === 'callback') {
|
||||
if (
|
||||
callExpression.arguments.length !== 1 ||
|
||||
isAwaitedPromise(callExpression)
|
||||
) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'useCallback'
|
||||
})
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if (
|
||||
callExpression.arguments.length > 0 ||
|
||||
!isAwaitedPromise(callExpression)
|
||||
) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'usePromise',
|
||||
fix(fixer) {
|
||||
return fixer.insertTextAfter(node, '().then')
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
50
slider/node_modules/eslint-plugin-vue/lib/rules/no-arrow-functions-in-watch.js
generated
vendored
Normal file
50
slider/node_modules/eslint-plugin-vue/lib/rules/no-arrow-functions-in-watch.js
generated
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* @author Sosuke Suzuki
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const utils = require('../utils')
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description: 'disallow using arrow functions to define watcher',
|
||||
categories: ['vue3-essential', 'vue2-essential'],
|
||||
url: 'https://eslint.vuejs.org/rules/no-arrow-functions-in-watch.html'
|
||||
},
|
||||
fixable: null,
|
||||
schema: [],
|
||||
messages: {
|
||||
noArrowFunctionsInWatch:
|
||||
'You should not use an arrow function to define a watcher.'
|
||||
}
|
||||
},
|
||||
/** @param {RuleContext} context */
|
||||
create(context) {
|
||||
return utils.executeOnVue(context, (obj) => {
|
||||
const watchNode = utils.findProperty(obj, 'watch')
|
||||
if (watchNode == null) {
|
||||
return
|
||||
}
|
||||
const watchValue = watchNode.value
|
||||
if (watchValue.type !== 'ObjectExpression') {
|
||||
return
|
||||
}
|
||||
for (const property of watchValue.properties) {
|
||||
if (property.type !== 'Property') {
|
||||
continue
|
||||
}
|
||||
|
||||
for (const handler of utils.iterateWatchHandlerValues(property)) {
|
||||
if (handler.type === 'ArrowFunctionExpression') {
|
||||
context.report({
|
||||
node: handler,
|
||||
messageId: 'noArrowFunctionsInWatch'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
374
slider/node_modules/eslint-plugin-vue/lib/rules/no-async-in-computed-properties.js
generated
vendored
Normal file
374
slider/node_modules/eslint-plugin-vue/lib/rules/no-async-in-computed-properties.js
generated
vendored
Normal file
@@ -0,0 +1,374 @@
|
||||
/**
|
||||
* @fileoverview Check if there are no asynchronous actions inside computed properties.
|
||||
* @author Armano
|
||||
*/
|
||||
'use strict'
|
||||
const { ReferenceTracker } = require('@eslint-community/eslint-utils')
|
||||
const utils = require('../utils')
|
||||
|
||||
/**
|
||||
* @typedef {import('../utils').VueObjectData} VueObjectData
|
||||
* @typedef {import('../utils').VueVisitor} VueVisitor
|
||||
* @typedef {import('../utils').ComponentComputedProperty} ComponentComputedProperty
|
||||
*/
|
||||
|
||||
const PROMISE_FUNCTIONS = new Set(['then', 'catch', 'finally'])
|
||||
|
||||
const PROMISE_METHODS = new Set(['all', 'race', 'reject', 'resolve'])
|
||||
|
||||
const TIMED_FUNCTIONS = new Set([
|
||||
'setTimeout',
|
||||
'setInterval',
|
||||
'setImmediate',
|
||||
'requestAnimationFrame'
|
||||
])
|
||||
|
||||
/**
|
||||
* @param {CallExpression} node
|
||||
*/
|
||||
function isTimedFunction(node) {
|
||||
const callee = utils.skipChainExpression(node.callee)
|
||||
return (
|
||||
((callee.type === 'Identifier' && TIMED_FUNCTIONS.has(callee.name)) ||
|
||||
(callee.type === 'MemberExpression' &&
|
||||
callee.object.type === 'Identifier' &&
|
||||
callee.object.name === 'window' &&
|
||||
TIMED_FUNCTIONS.has(utils.getStaticPropertyName(callee) || ''))) &&
|
||||
node.arguments.length > 0
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {*} node
|
||||
* @returns {*}
|
||||
*/
|
||||
function skipWrapper(node) {
|
||||
while (node && node.expression) {
|
||||
node = node.expression
|
||||
}
|
||||
return node
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the root object name from a member expression chain
|
||||
* @param {MemberExpression} memberExpr
|
||||
* @returns {string|null}
|
||||
*/
|
||||
function getRootObjectName(memberExpr) {
|
||||
let current = skipWrapper(memberExpr.object)
|
||||
|
||||
while (current) {
|
||||
switch (current.type) {
|
||||
case 'MemberExpression': {
|
||||
current = skipWrapper(current.object)
|
||||
break
|
||||
}
|
||||
case 'CallExpression': {
|
||||
const calleeExpr = skipWrapper(current.callee)
|
||||
if (calleeExpr.type === 'MemberExpression') {
|
||||
current = skipWrapper(calleeExpr.object)
|
||||
} else if (calleeExpr.type === 'Identifier') {
|
||||
return calleeExpr.name
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
break
|
||||
}
|
||||
case 'Identifier': {
|
||||
return current.name
|
||||
}
|
||||
default: {
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} name
|
||||
* @param {*} callee
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isPromiseMethod(name, callee) {
|
||||
return (
|
||||
// hello.PROMISE_FUNCTION()
|
||||
PROMISE_FUNCTIONS.has(name) ||
|
||||
// Promise.PROMISE_METHOD()
|
||||
(callee.object.type === 'Identifier' &&
|
||||
callee.object.name === 'Promise' &&
|
||||
PROMISE_METHODS.has(name))
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {CallExpression} node
|
||||
* @param {Set<string>} ignoredObjectNames
|
||||
*/
|
||||
function isPromise(node, ignoredObjectNames) {
|
||||
const callee = utils.skipChainExpression(node.callee)
|
||||
if (callee.type === 'MemberExpression') {
|
||||
const name = utils.getStaticPropertyName(callee)
|
||||
if (!name || !isPromiseMethod(name, callee)) {
|
||||
return false
|
||||
}
|
||||
|
||||
const rootObjectName = getRootObjectName(callee)
|
||||
if (rootObjectName && ignoredObjectNames.has(rootObjectName)) {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {CallExpression} node
|
||||
* @param {RuleContext} context
|
||||
*/
|
||||
function isNextTick(node, context) {
|
||||
const callee = utils.skipChainExpression(node.callee)
|
||||
if (callee.type === 'MemberExpression') {
|
||||
const name = utils.getStaticPropertyName(callee)
|
||||
return (
|
||||
(utils.isThis(callee.object, context) && name === '$nextTick') ||
|
||||
(callee.object.type === 'Identifier' &&
|
||||
callee.object.name === 'Vue' &&
|
||||
name === 'nextTick')
|
||||
)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description: 'disallow asynchronous actions in computed properties',
|
||||
categories: ['vue3-essential', 'vue2-essential'],
|
||||
url: 'https://eslint.vuejs.org/rules/no-async-in-computed-properties.html'
|
||||
},
|
||||
fixable: null,
|
||||
schema: [
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
ignoredObjectNames: {
|
||||
type: 'array',
|
||||
items: { type: 'string' },
|
||||
uniqueItems: true,
|
||||
additionalItems: false
|
||||
}
|
||||
},
|
||||
additionalProperties: false
|
||||
}
|
||||
],
|
||||
messages: {
|
||||
unexpectedInFunction:
|
||||
'Unexpected {{expressionName}} in computed function.',
|
||||
unexpectedInProperty:
|
||||
'Unexpected {{expressionName}} in "{{propertyName}}" computed property.'
|
||||
}
|
||||
},
|
||||
/** @param {RuleContext} context */
|
||||
create(context) {
|
||||
const options = context.options[0] || {}
|
||||
const ignoredObjectNames = new Set(options.ignoredObjectNames || [])
|
||||
|
||||
/** @type {Map<ObjectExpression, ComponentComputedProperty[]>} */
|
||||
const computedPropertiesMap = new Map()
|
||||
/** @type {(FunctionExpression | ArrowFunctionExpression)[]} */
|
||||
const computedFunctionNodes = []
|
||||
|
||||
/**
|
||||
* @typedef {object} ScopeStack
|
||||
* @property {ScopeStack | null} upper
|
||||
* @property {BlockStatement | Expression} body
|
||||
*/
|
||||
/** @type {ScopeStack | null} */
|
||||
let scopeStack = null
|
||||
|
||||
const expressionTypes = {
|
||||
promise: 'asynchronous action',
|
||||
nextTick: 'asynchronous action',
|
||||
await: 'await operator',
|
||||
async: 'async function declaration',
|
||||
new: 'Promise object',
|
||||
timed: 'timed function'
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {FunctionExpression | FunctionDeclaration | ArrowFunctionExpression} node
|
||||
* @param {VueObjectData|undefined} [info]
|
||||
*/
|
||||
function onFunctionEnter(node, info) {
|
||||
if (node.async) {
|
||||
verify(
|
||||
node,
|
||||
node.body,
|
||||
'async',
|
||||
info ? computedPropertiesMap.get(info.node) : null
|
||||
)
|
||||
}
|
||||
|
||||
scopeStack = {
|
||||
upper: scopeStack,
|
||||
body: node.body
|
||||
}
|
||||
}
|
||||
|
||||
function onFunctionExit() {
|
||||
scopeStack = scopeStack && scopeStack.upper
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ESNode} node
|
||||
* @param {BlockStatement | Expression} targetBody
|
||||
* @param {keyof expressionTypes} type
|
||||
* @param {ComponentComputedProperty[]|undefined|null} computedProperties
|
||||
*/
|
||||
function verify(node, targetBody, type, computedProperties) {
|
||||
for (const cp of computedProperties || []) {
|
||||
if (
|
||||
cp.value &&
|
||||
node.loc.start.line >= cp.value.loc.start.line &&
|
||||
node.loc.end.line <= cp.value.loc.end.line &&
|
||||
targetBody === cp.value
|
||||
) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'unexpectedInProperty',
|
||||
data: {
|
||||
expressionName: expressionTypes[type],
|
||||
propertyName: cp.key || 'unknown'
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
for (const cf of computedFunctionNodes) {
|
||||
if (
|
||||
node.loc.start.line >= cf.body.loc.start.line &&
|
||||
node.loc.end.line <= cf.body.loc.end.line &&
|
||||
targetBody === cf.body
|
||||
) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'unexpectedInFunction',
|
||||
data: {
|
||||
expressionName: expressionTypes[type]
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
const nodeVisitor = {
|
||||
':function': onFunctionEnter,
|
||||
':function:exit': onFunctionExit,
|
||||
|
||||
/**
|
||||
* @param {NewExpression} node
|
||||
* @param {VueObjectData|undefined} [info]
|
||||
*/
|
||||
NewExpression(node, info) {
|
||||
if (!scopeStack) {
|
||||
return
|
||||
}
|
||||
if (
|
||||
node.callee.type === 'Identifier' &&
|
||||
node.callee.name === 'Promise'
|
||||
) {
|
||||
verify(
|
||||
node,
|
||||
scopeStack.body,
|
||||
'new',
|
||||
info ? computedPropertiesMap.get(info.node) : null
|
||||
)
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {CallExpression} node
|
||||
* @param {VueObjectData|undefined} [info]
|
||||
*/
|
||||
CallExpression(node, info) {
|
||||
if (!scopeStack) {
|
||||
return
|
||||
}
|
||||
if (isPromise(node, ignoredObjectNames)) {
|
||||
verify(
|
||||
node,
|
||||
scopeStack.body,
|
||||
'promise',
|
||||
info ? computedPropertiesMap.get(info.node) : null
|
||||
)
|
||||
} else if (isTimedFunction(node)) {
|
||||
verify(
|
||||
node,
|
||||
scopeStack.body,
|
||||
'timed',
|
||||
info ? computedPropertiesMap.get(info.node) : null
|
||||
)
|
||||
} else if (isNextTick(node, context)) {
|
||||
verify(
|
||||
node,
|
||||
scopeStack.body,
|
||||
'nextTick',
|
||||
info ? computedPropertiesMap.get(info.node) : null
|
||||
)
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {AwaitExpression} node
|
||||
* @param {VueObjectData|undefined} [info]
|
||||
*/
|
||||
AwaitExpression(node, info) {
|
||||
if (!scopeStack) {
|
||||
return
|
||||
}
|
||||
verify(
|
||||
node,
|
||||
scopeStack.body,
|
||||
'await',
|
||||
info ? computedPropertiesMap.get(info.node) : null
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return utils.compositingVisitors(
|
||||
{
|
||||
/** @param {Program} program */
|
||||
Program(program) {
|
||||
const tracker = new ReferenceTracker(utils.getScope(context, program))
|
||||
for (const { node } of utils.iterateReferencesTraceMap(tracker, {
|
||||
computed: {
|
||||
[ReferenceTracker.CALL]: true
|
||||
}
|
||||
})) {
|
||||
if (node.type !== 'CallExpression') {
|
||||
continue
|
||||
}
|
||||
|
||||
const getter = utils.getGetterBodyFromComputedFunction(node)
|
||||
if (getter) {
|
||||
computedFunctionNodes.push(getter)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
utils.isScriptSetup(context)
|
||||
? utils.defineScriptSetupVisitor(context, nodeVisitor)
|
||||
: utils.defineVueVisitor(context, {
|
||||
onVueObjectEnter(node) {
|
||||
computedPropertiesMap.set(node, utils.getComputedProperties(node))
|
||||
},
|
||||
...nodeVisitor
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
293
slider/node_modules/eslint-plugin-vue/lib/rules/no-bare-strings-in-template.js
generated
vendored
Normal file
293
slider/node_modules/eslint-plugin-vue/lib/rules/no-bare-strings-in-template.js
generated
vendored
Normal file
@@ -0,0 +1,293 @@
|
||||
/**
|
||||
* @author Yosuke Ota
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const utils = require('../utils')
|
||||
const regexp = require('../utils/regexp')
|
||||
const casing = require('../utils/casing')
|
||||
|
||||
/**
|
||||
* @typedef { { names: { [tagName in string]: Set<string> }, regexps: { name: RegExp, attrs: Set<string> }[], cache: { [tagName in string]: Set<string> } } } TargetAttrs
|
||||
*/
|
||||
|
||||
// https://dev.w3.org/html5/html-author/charref
|
||||
const DEFAULT_ALLOWLIST = [
|
||||
'(',
|
||||
')',
|
||||
',',
|
||||
'.',
|
||||
'&',
|
||||
'+',
|
||||
'-',
|
||||
'=',
|
||||
'*',
|
||||
'/',
|
||||
'#',
|
||||
'%',
|
||||
'!',
|
||||
'?',
|
||||
':',
|
||||
'[',
|
||||
']',
|
||||
'{',
|
||||
'}',
|
||||
'<',
|
||||
'>',
|
||||
'\u00B7', // "·"
|
||||
'\u2022', // "•"
|
||||
'\u2010', // "‐"
|
||||
'\u2013', // "–"
|
||||
'\u2014', // "—"
|
||||
'\u2212', // "−"
|
||||
'|'
|
||||
]
|
||||
|
||||
const DEFAULT_ATTRIBUTES = {
|
||||
'/.+/': [
|
||||
'title',
|
||||
'aria-label',
|
||||
'aria-placeholder',
|
||||
'aria-roledescription',
|
||||
'aria-valuetext'
|
||||
],
|
||||
input: ['placeholder'],
|
||||
img: ['alt']
|
||||
}
|
||||
|
||||
const DEFAULT_DIRECTIVES = ['v-text']
|
||||
|
||||
/**
|
||||
* Parse attributes option
|
||||
* @param {any} options
|
||||
* @returns {TargetAttrs}
|
||||
*/
|
||||
function parseTargetAttrs(options) {
|
||||
/** @type {TargetAttrs} */
|
||||
const result = { names: {}, regexps: [], cache: {} }
|
||||
for (const tagName of Object.keys(options)) {
|
||||
/** @type { Set<string> } */
|
||||
const attrs = new Set(options[tagName])
|
||||
if (regexp.isRegExp(tagName)) {
|
||||
result.regexps.push({
|
||||
name: regexp.toRegExp(tagName),
|
||||
attrs
|
||||
})
|
||||
} else {
|
||||
result.names[tagName] = attrs
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a string from given expression container node
|
||||
* @param {VExpressionContainer} value
|
||||
* @returns { string | null }
|
||||
*/
|
||||
function getStringValue(value) {
|
||||
const expression = value.expression
|
||||
if (!expression) {
|
||||
return null
|
||||
}
|
||||
if (expression.type !== 'Literal') {
|
||||
return null
|
||||
}
|
||||
if (typeof expression.value === 'string') {
|
||||
return expression.value
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'suggestion',
|
||||
docs: {
|
||||
description: 'disallow the use of bare strings in `<template>`',
|
||||
categories: undefined,
|
||||
url: 'https://eslint.vuejs.org/rules/no-bare-strings-in-template.html'
|
||||
},
|
||||
schema: [
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
allowlist: {
|
||||
type: 'array',
|
||||
items: { type: 'string' },
|
||||
uniqueItems: true
|
||||
},
|
||||
attributes: {
|
||||
type: 'object',
|
||||
patternProperties: {
|
||||
'^(?:\\S+|/.*/[a-z]*)$': {
|
||||
type: 'array',
|
||||
items: { type: 'string' },
|
||||
uniqueItems: true
|
||||
}
|
||||
},
|
||||
additionalProperties: false
|
||||
},
|
||||
directives: {
|
||||
type: 'array',
|
||||
items: { type: 'string', pattern: '^v-' },
|
||||
uniqueItems: true
|
||||
}
|
||||
},
|
||||
additionalProperties: false
|
||||
}
|
||||
],
|
||||
messages: {
|
||||
unexpected: 'Unexpected non-translated string used.',
|
||||
unexpectedInAttr: 'Unexpected non-translated string used in `{{attr}}`.'
|
||||
}
|
||||
},
|
||||
/** @param {RuleContext} context */
|
||||
create(context) {
|
||||
/**
|
||||
* @typedef { { upper: ElementStack | null, name: string, attrs: Set<string> } } ElementStack
|
||||
*/
|
||||
const opts = context.options[0] || {}
|
||||
/** @type {string[]} */
|
||||
const rawAllowlist = opts.allowlist || DEFAULT_ALLOWLIST
|
||||
const attributes = parseTargetAttrs(opts.attributes || DEFAULT_ATTRIBUTES)
|
||||
const directives = opts.directives || DEFAULT_DIRECTIVES
|
||||
|
||||
/** @type {string[]} */
|
||||
const stringAllowlist = []
|
||||
/** @type {RegExp[]} */
|
||||
const regexAllowlist = []
|
||||
|
||||
for (const item of rawAllowlist) {
|
||||
if (regexp.isRegExp(item)) {
|
||||
regexAllowlist.push(regexp.toRegExp(item))
|
||||
} else {
|
||||
stringAllowlist.push(item)
|
||||
}
|
||||
}
|
||||
|
||||
const allowlistRe =
|
||||
stringAllowlist.length > 0
|
||||
? new RegExp(
|
||||
stringAllowlist
|
||||
.map((w) => regexp.escape(w))
|
||||
.sort((a, b) => b.length - a.length)
|
||||
.join('|'),
|
||||
'gu'
|
||||
)
|
||||
: null
|
||||
|
||||
/** @type {ElementStack | null} */
|
||||
let elementStack = null
|
||||
/**
|
||||
* Gets the bare string from given string
|
||||
* @param {string} str
|
||||
*/
|
||||
function getBareString(str) {
|
||||
let result = str.trim()
|
||||
|
||||
if (allowlistRe) {
|
||||
result = result.replace(allowlistRe, '')
|
||||
}
|
||||
|
||||
for (const regex of regexAllowlist) {
|
||||
const flags = regex.flags.includes('g')
|
||||
? regex.flags
|
||||
: `${regex.flags}g`
|
||||
const globalRegex = new RegExp(regex.source, flags)
|
||||
result = result.replace(globalRegex, '')
|
||||
}
|
||||
|
||||
return result.trim()
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attribute to be verified from the element name.
|
||||
* @param {string} tagName
|
||||
* @returns {Set<string>}
|
||||
*/
|
||||
function getTargetAttrs(tagName) {
|
||||
if (attributes.cache[tagName]) {
|
||||
return attributes.cache[tagName]
|
||||
}
|
||||
/** @type {string[]} */
|
||||
const result = []
|
||||
if (attributes.names[tagName]) {
|
||||
result.push(...attributes.names[tagName])
|
||||
}
|
||||
for (const { name, attrs } of attributes.regexps) {
|
||||
name.lastIndex = 0
|
||||
if (name.test(tagName)) {
|
||||
result.push(...attrs)
|
||||
}
|
||||
}
|
||||
if (casing.isKebabCase(tagName)) {
|
||||
result.push(...getTargetAttrs(casing.pascalCase(tagName)))
|
||||
}
|
||||
|
||||
return (attributes.cache[tagName] = new Set(result))
|
||||
}
|
||||
|
||||
return utils.defineTemplateBodyVisitor(context, {
|
||||
/** @param {VText} node */
|
||||
VText(node) {
|
||||
if (getBareString(node.value)) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'unexpected'
|
||||
})
|
||||
}
|
||||
},
|
||||
/**
|
||||
* @param {VElement} node
|
||||
*/
|
||||
VElement(node) {
|
||||
elementStack = {
|
||||
upper: elementStack,
|
||||
name: node.rawName,
|
||||
attrs: getTargetAttrs(node.rawName)
|
||||
}
|
||||
},
|
||||
'VElement:exit'() {
|
||||
elementStack = elementStack && elementStack.upper
|
||||
},
|
||||
/** @param {VAttribute|VDirective} node */
|
||||
VAttribute(node) {
|
||||
if (!node.value || !elementStack) {
|
||||
return
|
||||
}
|
||||
if (node.directive === false) {
|
||||
const attrs = elementStack.attrs
|
||||
if (!attrs.has(node.key.rawName)) {
|
||||
return
|
||||
}
|
||||
|
||||
if (getBareString(node.value.value)) {
|
||||
context.report({
|
||||
node: node.value,
|
||||
messageId: 'unexpectedInAttr',
|
||||
data: {
|
||||
attr: node.key.rawName
|
||||
}
|
||||
})
|
||||
}
|
||||
} else {
|
||||
const directive = `v-${node.key.name.name}`
|
||||
if (!directives.includes(directive)) {
|
||||
return
|
||||
}
|
||||
const str = getStringValue(node.value)
|
||||
if (str && getBareString(str)) {
|
||||
context.report({
|
||||
node: node.value,
|
||||
messageId: 'unexpectedInAttr',
|
||||
data: {
|
||||
attr: directive
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
148
slider/node_modules/eslint-plugin-vue/lib/rules/no-boolean-default.js
generated
vendored
Normal file
148
slider/node_modules/eslint-plugin-vue/lib/rules/no-boolean-default.js
generated
vendored
Normal file
@@ -0,0 +1,148 @@
|
||||
/**
|
||||
* @fileoverview Prevents boolean defaults from being set
|
||||
* @author Hiroki Osame
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const utils = require('../utils')
|
||||
|
||||
/**
|
||||
* @typedef {import('../utils').ComponentProp} ComponentProp
|
||||
* @typedef {import('../utils').ComponentObjectProp} ComponentObjectProp
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {Expression|undefined} node
|
||||
*/
|
||||
function isBooleanIdentifier(node) {
|
||||
return Boolean(node && node.type === 'Identifier' && node.name === 'Boolean')
|
||||
}
|
||||
|
||||
/**
|
||||
* Detects whether given prop node is a Boolean
|
||||
* @param {ComponentObjectProp} prop
|
||||
* @return {Boolean}
|
||||
*/
|
||||
function isBooleanProp(prop) {
|
||||
const value = utils.skipTSAsExpression(prop.value)
|
||||
return (
|
||||
isBooleanIdentifier(value) ||
|
||||
(value.type === 'ObjectExpression' &&
|
||||
isBooleanIdentifier(utils.findProperty(value, 'type')?.value))
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ObjectExpression} propDefValue
|
||||
*/
|
||||
function getDefaultNode(propDefValue) {
|
||||
return utils.findProperty(propDefValue, 'default')
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'suggestion',
|
||||
docs: {
|
||||
description: 'disallow boolean defaults',
|
||||
categories: undefined,
|
||||
url: 'https://eslint.vuejs.org/rules/no-boolean-default.html'
|
||||
},
|
||||
fixable: null,
|
||||
schema: [
|
||||
{
|
||||
enum: ['default-false', 'no-default']
|
||||
}
|
||||
],
|
||||
messages: {
|
||||
noBooleanDefault:
|
||||
'Boolean prop should not set a default (Vue defaults it to false).',
|
||||
defaultFalse: 'Boolean prop should only be defaulted to false.'
|
||||
}
|
||||
},
|
||||
/** @param {RuleContext} context */
|
||||
create(context) {
|
||||
const booleanType = context.options[0] || 'no-default'
|
||||
/**
|
||||
* @param {ComponentProp} prop
|
||||
* @param {(propName: string) => Expression[]} otherDefaultProvider
|
||||
*/
|
||||
function processProp(prop, otherDefaultProvider) {
|
||||
if (prop.type === 'object') {
|
||||
if (!isBooleanProp(prop)) {
|
||||
return
|
||||
}
|
||||
if (prop.value.type === 'ObjectExpression') {
|
||||
const defaultNode = getDefaultNode(prop.value)
|
||||
if (defaultNode) {
|
||||
verifyDefaultExpression(defaultNode.value)
|
||||
}
|
||||
}
|
||||
if (prop.propName != null) {
|
||||
for (const defaultNode of otherDefaultProvider(prop.propName)) {
|
||||
verifyDefaultExpression(defaultNode)
|
||||
}
|
||||
}
|
||||
} else if (prop.type === 'type') {
|
||||
if (prop.types.length !== 1 || prop.types[0] !== 'Boolean') {
|
||||
return
|
||||
}
|
||||
for (const defaultNode of otherDefaultProvider(prop.propName)) {
|
||||
verifyDefaultExpression(defaultNode)
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param {ComponentProp[]} props
|
||||
* @param {(propName: string) => Expression[]} otherDefaultProvider
|
||||
*/
|
||||
function processProps(props, otherDefaultProvider) {
|
||||
for (const prop of props) {
|
||||
processProp(prop, otherDefaultProvider)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Expression} defaultNode
|
||||
*/
|
||||
function verifyDefaultExpression(defaultNode) {
|
||||
switch (booleanType) {
|
||||
case 'no-default': {
|
||||
context.report({
|
||||
node: defaultNode,
|
||||
messageId: 'noBooleanDefault'
|
||||
})
|
||||
break
|
||||
}
|
||||
|
||||
case 'default-false': {
|
||||
if (defaultNode.type !== 'Literal' || defaultNode.value !== false) {
|
||||
context.report({
|
||||
node: defaultNode,
|
||||
messageId: 'defaultFalse'
|
||||
})
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return utils.compositingVisitors(
|
||||
utils.executeOnVueComponent(context, (obj) => {
|
||||
processProps(utils.getComponentPropsFromOptions(obj), () => [])
|
||||
}),
|
||||
utils.defineScriptSetupVisitor(context, {
|
||||
onDefinePropsEnter(node, props) {
|
||||
const defaultsByWithDefaults =
|
||||
utils.getWithDefaultsPropExpressions(node)
|
||||
const defaultsByAssignmentPatterns =
|
||||
utils.getDefaultPropExpressionsForPropsDestructure(node)
|
||||
processProps(props, (propName) =>
|
||||
[
|
||||
defaultsByWithDefaults[propName],
|
||||
defaultsByAssignmentPatterns[propName]?.expression
|
||||
].filter(utils.isDef)
|
||||
)
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
163
slider/node_modules/eslint-plugin-vue/lib/rules/no-child-content.js
generated
vendored
Normal file
163
slider/node_modules/eslint-plugin-vue/lib/rules/no-child-content.js
generated
vendored
Normal file
@@ -0,0 +1,163 @@
|
||||
/**
|
||||
* @author Flo Edelmann
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
'use strict'
|
||||
const { defineTemplateBodyVisitor } = require('../utils')
|
||||
|
||||
/**
|
||||
* @typedef {object} RuleOption
|
||||
* @property {string[]} additionalDirectives
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {VNode | Token} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isWhiteSpaceTextNode(node) {
|
||||
return node.type === 'VText' && node.value.trim() === ''
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Position} pos1
|
||||
* @param {Position} pos2
|
||||
* @returns {'less' | 'equal' | 'greater'}
|
||||
*/
|
||||
function comparePositions(pos1, pos2) {
|
||||
if (
|
||||
pos1.line < pos2.line ||
|
||||
(pos1.line === pos2.line && pos1.column < pos2.column)
|
||||
) {
|
||||
return 'less'
|
||||
}
|
||||
|
||||
if (
|
||||
pos1.line > pos2.line ||
|
||||
(pos1.line === pos2.line && pos1.column > pos2.column)
|
||||
) {
|
||||
return 'greater'
|
||||
}
|
||||
|
||||
return 'equal'
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {(VNode | Token)[]} nodes
|
||||
* @returns {SourceLocation | undefined}
|
||||
*/
|
||||
function getLocationRange(nodes) {
|
||||
/** @type {Position | undefined} */
|
||||
let start
|
||||
/** @type {Position | undefined} */
|
||||
let end
|
||||
|
||||
for (const node of nodes) {
|
||||
if (!start || comparePositions(node.loc.start, start) === 'less') {
|
||||
start = node.loc.start
|
||||
}
|
||||
|
||||
if (!end || comparePositions(node.loc.end, end) === 'greater') {
|
||||
end = node.loc.end
|
||||
}
|
||||
}
|
||||
|
||||
if (start === undefined || end === undefined) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
return { start, end }
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description:
|
||||
"disallow element's child contents which would be overwritten by a directive like `v-html` or `v-text`",
|
||||
categories: ['vue3-essential', 'vue2-essential'],
|
||||
url: 'https://eslint.vuejs.org/rules/no-child-content.html'
|
||||
},
|
||||
fixable: null,
|
||||
hasSuggestions: true,
|
||||
schema: [
|
||||
{
|
||||
type: 'object',
|
||||
additionalProperties: false,
|
||||
properties: {
|
||||
additionalDirectives: {
|
||||
type: 'array',
|
||||
uniqueItems: true,
|
||||
minItems: 1,
|
||||
items: {
|
||||
type: 'string'
|
||||
}
|
||||
}
|
||||
},
|
||||
required: ['additionalDirectives']
|
||||
}
|
||||
],
|
||||
messages: {
|
||||
disallowedChildContent:
|
||||
'Child content is disallowed because it will be overwritten by the v-{{ directiveName }} directive.',
|
||||
removeChildContent: 'Remove child content.'
|
||||
}
|
||||
},
|
||||
/** @param {RuleContext} context */
|
||||
create(context) {
|
||||
const directives = new Set(['html', 'text'])
|
||||
|
||||
/** @type {RuleOption | undefined} */
|
||||
const option = context.options[0]
|
||||
if (option !== undefined) {
|
||||
for (const directive of option.additionalDirectives) {
|
||||
directives.add(directive)
|
||||
}
|
||||
}
|
||||
|
||||
return defineTemplateBodyVisitor(context, {
|
||||
/** @param {VDirective} directiveNode */
|
||||
'VAttribute[directive=true]'(directiveNode) {
|
||||
const directiveName = directiveNode.key.name.name
|
||||
const elementNode = directiveNode.parent.parent
|
||||
|
||||
if (elementNode.endTag === null) {
|
||||
return
|
||||
}
|
||||
const sourceCode = context.getSourceCode()
|
||||
const tokenStore = sourceCode.parserServices.getTemplateBodyTokenStore()
|
||||
const elementComments = tokenStore.getTokensBetween(
|
||||
elementNode.startTag,
|
||||
elementNode.endTag,
|
||||
{
|
||||
includeComments: true,
|
||||
filter: (token) => token.type === 'HTMLComment'
|
||||
}
|
||||
)
|
||||
|
||||
const childNodes = [...elementNode.children, ...elementComments]
|
||||
|
||||
if (
|
||||
directives.has(directiveName) &&
|
||||
childNodes.some((childNode) => !isWhiteSpaceTextNode(childNode))
|
||||
) {
|
||||
context.report({
|
||||
node: elementNode,
|
||||
loc: getLocationRange(childNodes),
|
||||
messageId: 'disallowedChildContent',
|
||||
data: { directiveName },
|
||||
suggest: [
|
||||
{
|
||||
messageId: 'removeChildContent',
|
||||
*fix(fixer) {
|
||||
for (const childNode of childNodes) {
|
||||
yield fixer.remove(childNode)
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
100
slider/node_modules/eslint-plugin-vue/lib/rules/no-computed-properties-in-data.js
generated
vendored
Normal file
100
slider/node_modules/eslint-plugin-vue/lib/rules/no-computed-properties-in-data.js
generated
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
/**
|
||||
* @author Yosuke Ota
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const utils = require('../utils')
|
||||
|
||||
/**
|
||||
* @typedef {import('../utils').VueObjectData} VueObjectData
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description: 'disallow accessing computed properties in `data`',
|
||||
categories: ['vue3-essential', 'vue2-essential'],
|
||||
url: 'https://eslint.vuejs.org/rules/no-computed-properties-in-data.html'
|
||||
},
|
||||
fixable: null,
|
||||
schema: [],
|
||||
messages: {
|
||||
cannotBeUsed:
|
||||
'The computed property cannot be used in `data()` because it is before initialization.'
|
||||
}
|
||||
},
|
||||
/** @param {RuleContext} context */
|
||||
create(context) {
|
||||
/** @type {Map<ObjectExpression, {data: FunctionExpression | ArrowFunctionExpression, computedNames:Set<string>}>} */
|
||||
const contextMap = new Map()
|
||||
|
||||
/**
|
||||
* @typedef {object} ScopeStack
|
||||
* @property {ScopeStack | null} upper
|
||||
* @property {FunctionExpression | FunctionDeclaration | ArrowFunctionExpression} node
|
||||
*/
|
||||
/** @type {ScopeStack | null} */
|
||||
let scopeStack = null
|
||||
|
||||
return utils.compositingVisitors(
|
||||
{
|
||||
/**
|
||||
* @param {FunctionExpression | FunctionDeclaration | ArrowFunctionExpression} node
|
||||
*/
|
||||
':function'(node) {
|
||||
scopeStack = {
|
||||
upper: scopeStack,
|
||||
node
|
||||
}
|
||||
},
|
||||
':function:exit'() {
|
||||
scopeStack = scopeStack && scopeStack.upper
|
||||
}
|
||||
},
|
||||
utils.defineVueVisitor(context, {
|
||||
onVueObjectEnter(node) {
|
||||
const dataProperty = utils.findProperty(node, 'data')
|
||||
if (
|
||||
!dataProperty ||
|
||||
(dataProperty.value.type !== 'FunctionExpression' &&
|
||||
dataProperty.value.type !== 'ArrowFunctionExpression')
|
||||
) {
|
||||
return
|
||||
}
|
||||
const computedNames = new Set()
|
||||
for (const computed of utils.iterateProperties(
|
||||
node,
|
||||
new Set(['computed'])
|
||||
)) {
|
||||
computedNames.add(computed.name)
|
||||
}
|
||||
|
||||
contextMap.set(node, { data: dataProperty.value, computedNames })
|
||||
},
|
||||
/**
|
||||
* @param {MemberExpression} node
|
||||
* @param {VueObjectData} vueData
|
||||
*/
|
||||
MemberExpression(node, vueData) {
|
||||
if (!scopeStack || !utils.isThis(node.object, context)) {
|
||||
return
|
||||
}
|
||||
const ctx = contextMap.get(vueData.node)
|
||||
if (!ctx || ctx.data !== scopeStack.node) {
|
||||
return
|
||||
}
|
||||
const name = utils.getStaticPropertyName(node)
|
||||
if (!name || !ctx.computedNames.has(name)) {
|
||||
return
|
||||
}
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'cannotBeUsed'
|
||||
})
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
45
slider/node_modules/eslint-plugin-vue/lib/rules/no-console.js
generated
vendored
Normal file
45
slider/node_modules/eslint-plugin-vue/lib/rules/no-console.js
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* @author ItMaga <https://github.com/ItMaga>
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const utils = require('../utils')
|
||||
|
||||
// eslint-disable-next-line internal/no-invalid-meta
|
||||
module.exports = utils.wrapCoreRule('no-console', {
|
||||
skipBaseHandlers: true,
|
||||
create(context) {
|
||||
const options = context.options[0] || {}
|
||||
const allowed = options.allow || []
|
||||
|
||||
/**
|
||||
* Copied from the core rule `no-console`.
|
||||
* Checks whether the property name of the given MemberExpression node
|
||||
* is allowed by options or not.
|
||||
* @param {MemberExpression} node The MemberExpression node to check.
|
||||
* @returns {boolean} `true` if the property name of the node is allowed.
|
||||
*/
|
||||
function isAllowed(node) {
|
||||
const propertyName = utils.getStaticPropertyName(node)
|
||||
|
||||
return propertyName && allowed.includes(propertyName)
|
||||
}
|
||||
|
||||
return {
|
||||
MemberExpression(node) {
|
||||
if (
|
||||
node.object.type === 'Identifier' &&
|
||||
node.object.name === 'console' &&
|
||||
!isAllowed(node)
|
||||
) {
|
||||
context.report({
|
||||
node: node.object,
|
||||
loc: node.object.loc,
|
||||
messageId: 'unexpected'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
29
slider/node_modules/eslint-plugin-vue/lib/rules/no-constant-condition.js
generated
vendored
Normal file
29
slider/node_modules/eslint-plugin-vue/lib/rules/no-constant-condition.js
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* @author Flo Edelmann
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const { wrapCoreRule } = require('../utils')
|
||||
|
||||
const conditionalDirectiveNames = new Set(['v-show', 'v-if', 'v-else-if'])
|
||||
|
||||
// eslint-disable-next-line internal/no-invalid-meta
|
||||
module.exports = wrapCoreRule('no-constant-condition', {
|
||||
create(_context, { baseHandlers }) {
|
||||
return {
|
||||
VDirectiveKey(node) {
|
||||
if (
|
||||
conditionalDirectiveNames.has(`v-${node.name.name}`) &&
|
||||
node.parent.value &&
|
||||
node.parent.value.expression &&
|
||||
baseHandlers.IfStatement
|
||||
) {
|
||||
baseHandlers.IfStatement({
|
||||
// @ts-expect-error -- Process expression of VExpressionContainer as IfStatement.
|
||||
test: node.parent.value.expression
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
47
slider/node_modules/eslint-plugin-vue/lib/rules/no-custom-modifiers-on-v-model.js
generated
vendored
Normal file
47
slider/node_modules/eslint-plugin-vue/lib/rules/no-custom-modifiers-on-v-model.js
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* @author Przemyslaw Falowski (@przemkow)
|
||||
* @fileoverview This rule checks whether v-model used on the component do not have custom modifiers
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const utils = require('../utils')
|
||||
|
||||
const VALID_MODIFIERS = new Set(['lazy', 'number', 'trim'])
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description: 'disallow custom modifiers on v-model used on the component',
|
||||
categories: ['vue2-essential'],
|
||||
url: 'https://eslint.vuejs.org/rules/no-custom-modifiers-on-v-model.html'
|
||||
},
|
||||
fixable: null,
|
||||
schema: [],
|
||||
messages: {
|
||||
notSupportedModifier:
|
||||
"'v-model' directives don't support the modifier '{{name}}'."
|
||||
}
|
||||
},
|
||||
/** @param {RuleContext} context */
|
||||
create(context) {
|
||||
return utils.defineTemplateBodyVisitor(context, {
|
||||
"VAttribute[directive=true][key.name.name='model']"(node) {
|
||||
const element = node.parent.parent
|
||||
|
||||
if (utils.isCustomComponent(element)) {
|
||||
for (const modifier of node.key.modifiers) {
|
||||
if (!VALID_MODIFIERS.has(modifier.name)) {
|
||||
context.report({
|
||||
node,
|
||||
loc: node.loc,
|
||||
messageId: 'notSupportedModifier',
|
||||
data: { name: modifier.name }
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
86
slider/node_modules/eslint-plugin-vue/lib/rules/no-deprecated-data-object-declaration.js
generated
vendored
Normal file
86
slider/node_modules/eslint-plugin-vue/lib/rules/no-deprecated-data-object-declaration.js
generated
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
/**
|
||||
* @fileoverview disallow using deprecated object declaration on data
|
||||
* @author yoyo930021
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const utils = require('../utils')
|
||||
|
||||
/** @param {Token} token */
|
||||
function isOpenParen(token) {
|
||||
return token.type === 'Punctuator' && token.value === '('
|
||||
}
|
||||
|
||||
/** @param {Token} token */
|
||||
function isCloseParen(token) {
|
||||
return token.type === 'Punctuator' && token.value === ')'
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Expression} node
|
||||
* @param {SourceCode} sourceCode
|
||||
*/
|
||||
function getFirstAndLastTokens(node, sourceCode) {
|
||||
let first = sourceCode.getFirstToken(node)
|
||||
let last = sourceCode.getLastToken(node)
|
||||
|
||||
// If the value enclosed by parentheses, update the 'first' and 'last' by the parentheses.
|
||||
while (true) {
|
||||
const prev = sourceCode.getTokenBefore(first)
|
||||
const next = sourceCode.getTokenAfter(last)
|
||||
if (isOpenParen(prev) && isCloseParen(next)) {
|
||||
first = prev
|
||||
last = next
|
||||
} else {
|
||||
return { first, last }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description:
|
||||
'disallow using deprecated object declaration on data (in Vue.js 3.0.0+)',
|
||||
categories: ['vue3-essential'],
|
||||
url: 'https://eslint.vuejs.org/rules/no-deprecated-data-object-declaration.html'
|
||||
},
|
||||
fixable: 'code',
|
||||
schema: [],
|
||||
messages: {
|
||||
objectDeclarationIsDeprecated:
|
||||
"Object declaration on 'data' property is deprecated. Using function declaration instead."
|
||||
}
|
||||
},
|
||||
/** @param {RuleContext} context */
|
||||
create(context) {
|
||||
const sourceCode = context.getSourceCode()
|
||||
|
||||
return utils.executeOnVue(context, (obj) => {
|
||||
const invalidData = utils.findProperty(
|
||||
obj,
|
||||
'data',
|
||||
(p) =>
|
||||
p.value.type !== 'FunctionExpression' &&
|
||||
p.value.type !== 'ArrowFunctionExpression' &&
|
||||
p.value.type !== 'Identifier'
|
||||
)
|
||||
|
||||
if (invalidData) {
|
||||
context.report({
|
||||
node: invalidData,
|
||||
messageId: 'objectDeclarationIsDeprecated',
|
||||
fix(fixer) {
|
||||
const tokens = getFirstAndLastTokens(invalidData.value, sourceCode)
|
||||
|
||||
return [
|
||||
fixer.insertTextBefore(tokens.first, 'function() {\nreturn '),
|
||||
fixer.insertTextAfter(tokens.last, ';\n}')
|
||||
]
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
132
slider/node_modules/eslint-plugin-vue/lib/rules/no-deprecated-delete-set.js
generated
vendored
Normal file
132
slider/node_modules/eslint-plugin-vue/lib/rules/no-deprecated-delete-set.js
generated
vendored
Normal file
@@ -0,0 +1,132 @@
|
||||
/**
|
||||
* @author Wayne Zhang
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const utils = require('../utils')
|
||||
const { ReferenceTracker } = require('@eslint-community/eslint-utils')
|
||||
|
||||
/**
|
||||
* @typedef {import('@eslint-community/eslint-utils').TYPES.TraceMap} TraceMap
|
||||
*/
|
||||
|
||||
/** @type {TraceMap} */
|
||||
const deletedImportApisMap = {
|
||||
set: {
|
||||
[ReferenceTracker.CALL]: true
|
||||
},
|
||||
del: {
|
||||
[ReferenceTracker.CALL]: true
|
||||
}
|
||||
}
|
||||
const deprecatedApis = new Set(['set', 'delete'])
|
||||
const deprecatedDollarApis = new Set(['$set', '$delete'])
|
||||
|
||||
/**
|
||||
* @param {Expression|Super} node
|
||||
*/
|
||||
function isVue(node) {
|
||||
return node.type === 'Identifier' && node.name === 'Vue'
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description:
|
||||
'disallow using deprecated `$delete` and `$set` (in Vue.js 3.0.0+)',
|
||||
categories: ['vue3-essential'],
|
||||
url: 'https://eslint.vuejs.org/rules/no-deprecated-delete-set.html'
|
||||
},
|
||||
fixable: null,
|
||||
schema: [],
|
||||
messages: {
|
||||
deprecated: 'The `$delete`, `$set` is deprecated.'
|
||||
}
|
||||
},
|
||||
/** @param {RuleContext} context */
|
||||
create(context) {
|
||||
/**
|
||||
* @param {Identifier} identifier
|
||||
* @param {RuleContext} context
|
||||
* @returns {CallExpression|undefined}
|
||||
*/
|
||||
function getVueDeprecatedCallExpression(identifier, context) {
|
||||
// Instance API: this.$set()
|
||||
if (
|
||||
deprecatedDollarApis.has(identifier.name) &&
|
||||
identifier.parent.type === 'MemberExpression' &&
|
||||
utils.isThis(identifier.parent.object, context) &&
|
||||
identifier.parent.parent.type === 'CallExpression' &&
|
||||
identifier.parent.parent.callee === identifier.parent
|
||||
) {
|
||||
return identifier.parent.parent
|
||||
}
|
||||
|
||||
// Vue 2 Global API: Vue.set()
|
||||
if (
|
||||
deprecatedApis.has(identifier.name) &&
|
||||
identifier.parent.type === 'MemberExpression' &&
|
||||
isVue(identifier.parent.object) &&
|
||||
identifier.parent.parent.type === 'CallExpression' &&
|
||||
identifier.parent.parent.callee === identifier.parent
|
||||
) {
|
||||
return identifier.parent.parent
|
||||
}
|
||||
|
||||
return undefined
|
||||
}
|
||||
|
||||
const nodeVisitor = {
|
||||
/** @param {Identifier} node */
|
||||
Identifier(node) {
|
||||
const callExpression = getVueDeprecatedCallExpression(node, context)
|
||||
if (!callExpression) {
|
||||
return
|
||||
}
|
||||
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'deprecated'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return utils.compositingVisitors(
|
||||
utils.defineVueVisitor(context, nodeVisitor),
|
||||
utils.defineScriptSetupVisitor(context, nodeVisitor),
|
||||
{
|
||||
/** @param {Program} node */
|
||||
Program(node) {
|
||||
const tracker = new ReferenceTracker(utils.getScope(context, node))
|
||||
|
||||
// import { set } from 'vue'; set()
|
||||
const esmTraceMap = {
|
||||
vue: {
|
||||
[ReferenceTracker.ESM]: true,
|
||||
...deletedImportApisMap
|
||||
}
|
||||
}
|
||||
// const { set } = require('vue'); set()
|
||||
const cjsTraceMap = {
|
||||
vue: {
|
||||
...deletedImportApisMap
|
||||
}
|
||||
}
|
||||
|
||||
for (const { node } of [
|
||||
...tracker.iterateEsmReferences(esmTraceMap),
|
||||
...tracker.iterateCjsReferences(cjsTraceMap)
|
||||
]) {
|
||||
const refNode = /** @type {CallExpression} */ (node)
|
||||
context.report({
|
||||
node: refNode.callee,
|
||||
messageId: 'deprecated'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
78
slider/node_modules/eslint-plugin-vue/lib/rules/no-deprecated-destroyed-lifecycle.js
generated
vendored
Normal file
78
slider/node_modules/eslint-plugin-vue/lib/rules/no-deprecated-destroyed-lifecycle.js
generated
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
* @author Yosuke Ota
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const utils = require('../utils')
|
||||
|
||||
/**
|
||||
* @param {RuleFixer} fixer
|
||||
* @param {Property} property
|
||||
* @param {string} newName
|
||||
*/
|
||||
function fix(fixer, property, newName) {
|
||||
if (property.computed) {
|
||||
if (
|
||||
property.key.type === 'Literal' ||
|
||||
property.key.type === 'TemplateLiteral'
|
||||
) {
|
||||
return fixer.replaceTextRange(
|
||||
[property.key.range[0] + 1, property.key.range[1] - 1],
|
||||
newName
|
||||
)
|
||||
}
|
||||
return null
|
||||
}
|
||||
if (property.shorthand) {
|
||||
return fixer.insertTextBefore(property.key, `${newName}:`)
|
||||
}
|
||||
return fixer.replaceText(property.key, newName)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description:
|
||||
'disallow using deprecated `destroyed` and `beforeDestroy` lifecycle hooks (in Vue.js 3.0.0+)',
|
||||
categories: ['vue3-essential'],
|
||||
url: 'https://eslint.vuejs.org/rules/no-deprecated-destroyed-lifecycle.html'
|
||||
},
|
||||
fixable: 'code',
|
||||
schema: [],
|
||||
messages: {
|
||||
deprecatedDestroyed:
|
||||
'The `destroyed` lifecycle hook is deprecated. Use `unmounted` instead.',
|
||||
deprecatedBeforeDestroy:
|
||||
'The `beforeDestroy` lifecycle hook is deprecated. Use `beforeUnmount` instead.'
|
||||
}
|
||||
},
|
||||
/** @param {RuleContext} context */
|
||||
create(context) {
|
||||
return utils.executeOnVue(context, (obj) => {
|
||||
const destroyed = utils.findProperty(obj, 'destroyed')
|
||||
|
||||
if (destroyed) {
|
||||
context.report({
|
||||
node: destroyed.key,
|
||||
messageId: 'deprecatedDestroyed',
|
||||
fix(fixer) {
|
||||
return fix(fixer, destroyed, 'unmounted')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const beforeDestroy = utils.findProperty(obj, 'beforeDestroy')
|
||||
if (beforeDestroy) {
|
||||
context.report({
|
||||
node: beforeDestroy.key,
|
||||
messageId: 'deprecatedBeforeDestroy',
|
||||
fix(fixer) {
|
||||
return fix(fixer, beforeDestroy, 'beforeUnmount')
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
63
slider/node_modules/eslint-plugin-vue/lib/rules/no-deprecated-dollar-listeners-api.js
generated
vendored
Normal file
63
slider/node_modules/eslint-plugin-vue/lib/rules/no-deprecated-dollar-listeners-api.js
generated
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
* @author Yosuke Ota
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const utils = require('../utils')
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description: 'disallow using deprecated `$listeners` (in Vue.js 3.0.0+)',
|
||||
categories: ['vue3-essential'],
|
||||
url: 'https://eslint.vuejs.org/rules/no-deprecated-dollar-listeners-api.html'
|
||||
},
|
||||
fixable: null,
|
||||
schema: [],
|
||||
messages: {
|
||||
deprecated: 'The `$listeners` is deprecated.'
|
||||
}
|
||||
},
|
||||
/** @param {RuleContext} context */
|
||||
create(context) {
|
||||
return utils.defineTemplateBodyVisitor(
|
||||
context,
|
||||
{
|
||||
VExpressionContainer(node) {
|
||||
for (const reference of node.references) {
|
||||
if (reference.variable != null) {
|
||||
// Not vm reference
|
||||
continue
|
||||
}
|
||||
if (reference.id.name === '$listeners') {
|
||||
context.report({
|
||||
node: reference.id,
|
||||
messageId: 'deprecated'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
utils.defineVueVisitor(context, {
|
||||
MemberExpression(node) {
|
||||
if (
|
||||
node.property.type !== 'Identifier' ||
|
||||
node.property.name !== '$listeners'
|
||||
) {
|
||||
return
|
||||
}
|
||||
if (!utils.isThis(node.object, context)) {
|
||||
return
|
||||
}
|
||||
|
||||
context.report({
|
||||
node: node.property,
|
||||
messageId: 'deprecated'
|
||||
})
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
70
slider/node_modules/eslint-plugin-vue/lib/rules/no-deprecated-dollar-scopedslots-api.js
generated
vendored
Normal file
70
slider/node_modules/eslint-plugin-vue/lib/rules/no-deprecated-dollar-scopedslots-api.js
generated
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* @author Yosuke Ota
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const utils = require('../utils')
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description:
|
||||
'disallow using deprecated `$scopedSlots` (in Vue.js 3.0.0+)',
|
||||
categories: ['vue3-essential'],
|
||||
url: 'https://eslint.vuejs.org/rules/no-deprecated-dollar-scopedslots-api.html'
|
||||
},
|
||||
fixable: 'code',
|
||||
schema: [],
|
||||
messages: {
|
||||
deprecated: 'The `$scopedSlots` is deprecated.'
|
||||
}
|
||||
},
|
||||
/** @param {RuleContext} context */
|
||||
create(context) {
|
||||
return utils.defineTemplateBodyVisitor(
|
||||
context,
|
||||
{
|
||||
VExpressionContainer(node) {
|
||||
for (const reference of node.references) {
|
||||
if (reference.variable != null) {
|
||||
// Not vm reference
|
||||
continue
|
||||
}
|
||||
if (reference.id.name === '$scopedSlots') {
|
||||
context.report({
|
||||
node: reference.id,
|
||||
messageId: 'deprecated',
|
||||
fix(fixer) {
|
||||
return fixer.replaceText(reference.id, '$slots')
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
utils.defineVueVisitor(context, {
|
||||
MemberExpression(node) {
|
||||
if (
|
||||
node.property.type !== 'Identifier' ||
|
||||
node.property.name !== '$scopedSlots'
|
||||
) {
|
||||
return
|
||||
}
|
||||
if (!utils.isThis(node.object, context)) {
|
||||
return
|
||||
}
|
||||
|
||||
context.report({
|
||||
node: node.property,
|
||||
messageId: 'deprecated',
|
||||
fix(fixer) {
|
||||
return fixer.replaceText(node.property, '$slots')
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
61
slider/node_modules/eslint-plugin-vue/lib/rules/no-deprecated-events-api.js
generated
vendored
Normal file
61
slider/node_modules/eslint-plugin-vue/lib/rules/no-deprecated-events-api.js
generated
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
* @fileoverview disallow using deprecated events api
|
||||
* @author yoyo930021
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const utils = require('../utils')
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description: 'disallow using deprecated events api (in Vue.js 3.0.0+)',
|
||||
categories: ['vue3-essential'],
|
||||
url: 'https://eslint.vuejs.org/rules/no-deprecated-events-api.html'
|
||||
},
|
||||
fixable: null,
|
||||
schema: [],
|
||||
messages: {
|
||||
noDeprecatedEventsApi:
|
||||
'The Events api `$on`, `$off` `$once` is deprecated. Using external library instead, for example mitt.'
|
||||
}
|
||||
},
|
||||
/** @param {RuleContext} context */
|
||||
create(context) {
|
||||
return utils.defineVueVisitor(context, {
|
||||
/** @param {MemberExpression & ({parent: CallExpression} | {parent: ChainExpression & {parent: CallExpression}})} node */
|
||||
'CallExpression > MemberExpression, CallExpression > ChainExpression > MemberExpression'(
|
||||
node
|
||||
) {
|
||||
const call =
|
||||
node.parent.type === 'ChainExpression'
|
||||
? node.parent.parent
|
||||
: node.parent
|
||||
|
||||
if (call.optional) {
|
||||
// It is OK because checking whether it is deprecated.
|
||||
// e.g. `this.$on?.()`
|
||||
return
|
||||
}
|
||||
|
||||
if (
|
||||
utils.skipChainExpression(call.callee) !== node ||
|
||||
!['$on', '$off', '$once'].includes(
|
||||
utils.getStaticPropertyName(node) || ''
|
||||
)
|
||||
) {
|
||||
return
|
||||
}
|
||||
if (!utils.isThis(node.object, context)) {
|
||||
return
|
||||
}
|
||||
|
||||
context.report({
|
||||
node: node.property,
|
||||
messageId: 'noDeprecatedEventsApi'
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
36
slider/node_modules/eslint-plugin-vue/lib/rules/no-deprecated-filter.js
generated
vendored
Normal file
36
slider/node_modules/eslint-plugin-vue/lib/rules/no-deprecated-filter.js
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* @author Przemyslaw Falowski (@przemkow)
|
||||
* @fileoverview disallow using deprecated filters syntax
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const utils = require('../utils')
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description:
|
||||
'disallow using deprecated filters syntax (in Vue.js 3.0.0+)',
|
||||
categories: ['vue3-essential'],
|
||||
url: 'https://eslint.vuejs.org/rules/no-deprecated-filter.html'
|
||||
},
|
||||
fixable: null,
|
||||
schema: [],
|
||||
messages: {
|
||||
noDeprecatedFilter: 'Filters are deprecated.'
|
||||
}
|
||||
},
|
||||
/** @param {RuleContext} context */
|
||||
create(context) {
|
||||
return utils.defineTemplateBodyVisitor(context, {
|
||||
VFilterSequenceExpression(node) {
|
||||
context.report({
|
||||
node,
|
||||
loc: node.loc,
|
||||
messageId: 'noDeprecatedFilter'
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
47
slider/node_modules/eslint-plugin-vue/lib/rules/no-deprecated-functional-template.js
generated
vendored
Normal file
47
slider/node_modules/eslint-plugin-vue/lib/rules/no-deprecated-functional-template.js
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* @author Yosuke Ota
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const utils = require('../utils')
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description:
|
||||
'disallow using deprecated the `functional` template (in Vue.js 3.0.0+)',
|
||||
categories: ['vue3-essential'],
|
||||
url: 'https://eslint.vuejs.org/rules/no-deprecated-functional-template.html'
|
||||
},
|
||||
fixable: null,
|
||||
schema: [],
|
||||
messages: {
|
||||
unexpected: 'The `functional` template are deprecated.'
|
||||
}
|
||||
},
|
||||
/**
|
||||
* @param {RuleContext} context - The rule context.
|
||||
* @returns {RuleListener} AST event handlers.
|
||||
*/
|
||||
create(context) {
|
||||
return {
|
||||
Program(program) {
|
||||
const element = program.templateBody
|
||||
if (element == null) {
|
||||
return
|
||||
}
|
||||
|
||||
const functional = utils.getAttribute(element, 'functional')
|
||||
|
||||
if (functional) {
|
||||
context.report({
|
||||
node: functional,
|
||||
messageId: 'unexpected'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
65
slider/node_modules/eslint-plugin-vue/lib/rules/no-deprecated-html-element-is.js
generated
vendored
Normal file
65
slider/node_modules/eslint-plugin-vue/lib/rules/no-deprecated-html-element-is.js
generated
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* @author Yosuke Ota
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const utils = require('../utils')
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description:
|
||||
'disallow using deprecated the `is` attribute on HTML elements (in Vue.js 3.0.0+)',
|
||||
categories: ['vue3-essential'],
|
||||
url: 'https://eslint.vuejs.org/rules/no-deprecated-html-element-is.html'
|
||||
},
|
||||
fixable: null,
|
||||
schema: [],
|
||||
messages: {
|
||||
unexpected: 'The `is` attribute on HTML element are deprecated.'
|
||||
}
|
||||
},
|
||||
/** @param {RuleContext} context */
|
||||
create(context) {
|
||||
/** @param {VElement} node */
|
||||
function isValidElement(node) {
|
||||
return (
|
||||
!utils.isHtmlWellKnownElementName(node.rawName) &&
|
||||
!utils.isSvgWellKnownElementName(node.rawName) &&
|
||||
!utils.isMathWellKnownElementName(node.rawName)
|
||||
)
|
||||
}
|
||||
return utils.defineTemplateBodyVisitor(context, {
|
||||
/** @param {VDirective} node */
|
||||
"VAttribute[directive=true][key.name.name='bind'][key.argument.name='is']"(
|
||||
node
|
||||
) {
|
||||
if (isValidElement(node.parent.parent)) {
|
||||
return
|
||||
}
|
||||
context.report({
|
||||
node,
|
||||
loc: node.loc,
|
||||
messageId: 'unexpected'
|
||||
})
|
||||
},
|
||||
/** @param {VAttribute} node */
|
||||
"VAttribute[directive=false][key.name='is']"(node) {
|
||||
if (isValidElement(node.parent.parent)) {
|
||||
return
|
||||
}
|
||||
if (node.value && node.value.value.startsWith('vue:')) {
|
||||
// Usage on native elements 3.1+
|
||||
return
|
||||
}
|
||||
context.report({
|
||||
node,
|
||||
loc: node.loc,
|
||||
messageId: 'unexpected'
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
39
slider/node_modules/eslint-plugin-vue/lib/rules/no-deprecated-inline-template.js
generated
vendored
Normal file
39
slider/node_modules/eslint-plugin-vue/lib/rules/no-deprecated-inline-template.js
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* @author Yosuke Ota
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const utils = require('../utils')
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description:
|
||||
'disallow using deprecated `inline-template` attribute (in Vue.js 3.0.0+)',
|
||||
categories: ['vue3-essential'],
|
||||
url: 'https://eslint.vuejs.org/rules/no-deprecated-inline-template.html'
|
||||
},
|
||||
fixable: null,
|
||||
schema: [],
|
||||
messages: {
|
||||
unexpected: '`inline-template` are deprecated.'
|
||||
}
|
||||
},
|
||||
/** @param {RuleContext} context */
|
||||
create(context) {
|
||||
return utils.defineTemplateBodyVisitor(context, {
|
||||
/** @param {VIdentifier} node */
|
||||
"VAttribute[directive=false] > VIdentifier[rawName='inline-template']"(
|
||||
node
|
||||
) {
|
||||
context.report({
|
||||
node,
|
||||
loc: node.loc,
|
||||
messageId: 'unexpected'
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
133
slider/node_modules/eslint-plugin-vue/lib/rules/no-deprecated-model-definition.js
generated
vendored
Normal file
133
slider/node_modules/eslint-plugin-vue/lib/rules/no-deprecated-model-definition.js
generated
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
/**
|
||||
* @author Flo Edelmann
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const utils = require('../utils')
|
||||
|
||||
const allowedPropNames = new Set(['modelValue', 'model-value'])
|
||||
const allowedEventNames = new Set(['update:modelValue', 'update:model-value'])
|
||||
|
||||
/**
|
||||
* @param {ObjectExpression} node
|
||||
* @param {string} key
|
||||
* @returns {Literal | TemplateLiteral | undefined}
|
||||
*/
|
||||
function findPropertyValue(node, key) {
|
||||
const property = node.properties.find(
|
||||
(property) =>
|
||||
property.type === 'Property' &&
|
||||
property.key.type === 'Identifier' &&
|
||||
property.key.name === key
|
||||
)
|
||||
if (
|
||||
!property ||
|
||||
property.type !== 'Property' ||
|
||||
!utils.isStringLiteral(property.value)
|
||||
) {
|
||||
return undefined
|
||||
}
|
||||
return property.value
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {RuleFixer} fixer
|
||||
* @param {Literal | TemplateLiteral} node
|
||||
* @param {string} text
|
||||
*/
|
||||
function replaceLiteral(fixer, node, text) {
|
||||
return fixer.replaceTextRange([node.range[0] + 1, node.range[1] - 1], text)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description: 'disallow deprecated `model` definition (in Vue.js 3.0.0+)',
|
||||
categories: ['vue3-essential'],
|
||||
url: 'https://eslint.vuejs.org/rules/no-deprecated-model-definition.html'
|
||||
},
|
||||
fixable: null,
|
||||
hasSuggestions: true,
|
||||
schema: [
|
||||
{
|
||||
type: 'object',
|
||||
additionalProperties: false,
|
||||
properties: {
|
||||
allowVue3Compat: {
|
||||
type: 'boolean'
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
messages: {
|
||||
deprecatedModel: '`model` definition is deprecated.',
|
||||
vue3Compat:
|
||||
'`model` definition is deprecated. You may use the Vue 3-compatible `modelValue`/`update:modelValue` though.',
|
||||
changeToModelValue: 'Change to `modelValue`/`update:modelValue`.',
|
||||
changeToKebabModelValue: 'Change to `model-value`/`update:model-value`.'
|
||||
}
|
||||
},
|
||||
/** @param {RuleContext} context */
|
||||
create(context) {
|
||||
const allowVue3Compat = Boolean(context.options[0]?.allowVue3Compat)
|
||||
|
||||
return utils.executeOnVue(context, (obj) => {
|
||||
const modelProperty = utils.findProperty(obj, 'model')
|
||||
if (!modelProperty || modelProperty.value.type !== 'ObjectExpression') {
|
||||
return
|
||||
}
|
||||
|
||||
if (!allowVue3Compat) {
|
||||
context.report({
|
||||
node: modelProperty,
|
||||
messageId: 'deprecatedModel'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
const propName = findPropertyValue(modelProperty.value, 'prop')
|
||||
const eventName = findPropertyValue(modelProperty.value, 'event')
|
||||
|
||||
if (
|
||||
!propName ||
|
||||
!eventName ||
|
||||
!allowedPropNames.has(
|
||||
utils.getStringLiteralValue(propName, true) ?? ''
|
||||
) ||
|
||||
!allowedEventNames.has(
|
||||
utils.getStringLiteralValue(eventName, true) ?? ''
|
||||
)
|
||||
) {
|
||||
context.report({
|
||||
node: modelProperty,
|
||||
messageId: 'vue3Compat',
|
||||
suggest:
|
||||
propName && eventName
|
||||
? [
|
||||
{
|
||||
messageId: 'changeToModelValue',
|
||||
*fix(fixer) {
|
||||
const newPropName = 'modelValue'
|
||||
const newEventName = 'update:modelValue'
|
||||
yield replaceLiteral(fixer, propName, newPropName)
|
||||
yield replaceLiteral(fixer, eventName, newEventName)
|
||||
}
|
||||
},
|
||||
{
|
||||
messageId: 'changeToKebabModelValue',
|
||||
*fix(fixer) {
|
||||
const newPropName = 'model-value'
|
||||
const newEventName = 'update:model-value'
|
||||
yield replaceLiteral(fixer, propName, newPropName)
|
||||
yield replaceLiteral(fixer, eventName, newEventName)
|
||||
}
|
||||
}
|
||||
]
|
||||
: []
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user