| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 | 
							- /**
 
-  * @fileoverview Require default value for props
 
-  * @author Michał Sajnóg <msajnog93@gmail.com> (https://github.com/michalsnik)
 
-  */
 
- 'use strict'
 
- /**
 
-  * @typedef {import('../utils').ComponentObjectProp} ComponentObjectProp
 
-  * @typedef {ComponentObjectProp & { value: ObjectExpression} } ComponentObjectPropObject
 
-  */
 
- const utils = require('../utils')
 
- const { isDef } = require('../utils')
 
- const NATIVE_TYPES = new Set([
 
-   'String',
 
-   'Number',
 
-   'Boolean',
 
-   'Function',
 
-   'Object',
 
-   'Array',
 
-   'Symbol'
 
- ])
 
- // ------------------------------------------------------------------------------
 
- // Rule Definition
 
- // ------------------------------------------------------------------------------
 
- module.exports = {
 
-   meta: {
 
-     type: 'suggestion',
 
-     docs: {
 
-       description: 'require default value for props',
 
-       categories: ['vue3-strongly-recommended', 'strongly-recommended'],
 
-       url: 'https://eslint.vuejs.org/rules/require-default-prop.html'
 
-     },
 
-     fixable: null, // or "code" or "whitespace"
 
-     schema: []
 
-   },
 
-   /** @param {RuleContext} context */
 
-   create(context) {
 
-     // ----------------------------------------------------------------------
 
-     // Helpers
 
-     // ----------------------------------------------------------------------
 
-     /**
 
-      * Checks if the passed prop is required
 
-      * @param {ComponentObjectPropObject} prop - Property AST node for a single prop
 
-      * @return {boolean}
 
-      */
 
-     function propIsRequired(prop) {
 
-       const propRequiredNode = prop.value.properties.find(
 
-         (p) =>
 
-           p.type === 'Property' &&
 
-           utils.getStaticPropertyName(p) === 'required' &&
 
-           p.value.type === 'Literal' &&
 
-           p.value.value === true
 
-       )
 
-       return Boolean(propRequiredNode)
 
-     }
 
-     /**
 
-      * Checks if the passed prop has a default value
 
-      * @param {ComponentObjectPropObject} prop - Property AST node for a single prop
 
-      * @return {boolean}
 
-      */
 
-     function propHasDefault(prop) {
 
-       const propDefaultNode = prop.value.properties.find(
 
-         (p) =>
 
-           p.type === 'Property' && utils.getStaticPropertyName(p) === 'default'
 
-       )
 
-       return Boolean(propDefaultNode)
 
-     }
 
-     /**
 
-      * Finds all props that don't have a default value set
 
-      * @param {ComponentObjectProp[]} props - Vue component's "props" node
 
-      * @return {ComponentObjectProp[]} Array of props without "default" value
 
-      */
 
-     function findPropsWithoutDefaultValue(props) {
 
-       return props.filter((prop) => {
 
-         if (prop.value.type !== 'ObjectExpression') {
 
-           if (prop.value.type === 'Identifier') {
 
-             return NATIVE_TYPES.has(prop.value.name)
 
-           }
 
-           if (
 
-             prop.value.type === 'CallExpression' ||
 
-             prop.value.type === 'MemberExpression'
 
-           ) {
 
-             // OK
 
-             return false
 
-           }
 
-           // NG
 
-           return true
 
-         }
 
-         return (
 
-           !propIsRequired(/** @type {ComponentObjectPropObject} */ (prop)) &&
 
-           !propHasDefault(/** @type {ComponentObjectPropObject} */ (prop))
 
-         )
 
-       })
 
-     }
 
-     /**
 
-      * Detects whether given value node is a Boolean type
 
-      * @param {Expression} value
 
-      * @return {boolean}
 
-      */
 
-     function isValueNodeOfBooleanType(value) {
 
-       if (value.type === 'Identifier' && value.name === 'Boolean') {
 
-         return true
 
-       }
 
-       if (value.type === 'ArrayExpression') {
 
-         const elements = value.elements.filter(isDef)
 
-         return (
 
-           elements.length === 1 &&
 
-           elements[0].type === 'Identifier' &&
 
-           elements[0].name === 'Boolean'
 
-         )
 
-       }
 
-       return false
 
-     }
 
-     /**
 
-      * Detects whether given prop node is a Boolean
 
-      * @param {ComponentObjectProp} prop
 
-      * @return {Boolean}
 
-      */
 
-     function isBooleanProp(prop) {
 
-       const value = utils.skipTSAsExpression(prop.value)
 
-       return (
 
-         isValueNodeOfBooleanType(value) ||
 
-         (value.type === 'ObjectExpression' &&
 
-           value.properties.some(
 
-             (p) =>
 
-               p.type === 'Property' &&
 
-               p.key.type === 'Identifier' &&
 
-               p.key.name === 'type' &&
 
-               isValueNodeOfBooleanType(p.value)
 
-           ))
 
-       )
 
-     }
 
-     /**
 
-      * Excludes purely Boolean props from the Array
 
-      * @param {ComponentObjectProp[]} props - Array with props
 
-      * @return {ComponentObjectProp[]}
 
-      */
 
-     function excludeBooleanProps(props) {
 
-       return props.filter((prop) => !isBooleanProp(prop))
 
-     }
 
-     // ----------------------------------------------------------------------
 
-     // Public
 
-     // ----------------------------------------------------------------------
 
-     return utils.executeOnVue(context, (obj) => {
 
-       const props = utils
 
-         .getComponentProps(obj)
 
-         .filter(
 
-           (prop) =>
 
-             prop.value &&
 
-             !(prop.node.type === 'Property' && prop.node.shorthand)
 
-         )
 
-       const propsWithoutDefault = findPropsWithoutDefaultValue(
 
-         /** @type {ComponentObjectProp[]} */ (props)
 
-       )
 
-       const propsToReport = excludeBooleanProps(propsWithoutDefault)
 
-       for (const prop of propsToReport) {
 
-         const propName =
 
-           prop.propName != null
 
-             ? prop.propName
 
-             : `[${context.getSourceCode().getText(prop.node.key)}]`
 
-         context.report({
 
-           node: prop.node,
 
-           message: `Prop '{{propName}}' requires default value to be set.`,
 
-           data: {
 
-             propName
 
-           }
 
-         })
 
-       }
 
-     })
 
-   }
 
- }
 
 
  |