eslint-plugin-xstate
Advanced tools
Comparing version 0.10.1 to 0.11.0
@@ -28,2 +28,3 @@ /** | ||
'no-invalid-transition-props': require('./rules/no-invalid-transition-props'), | ||
'no-async-guard': require('./rules/no-async-guard'), | ||
}, | ||
@@ -44,2 +45,3 @@ configs: { | ||
'xstate/no-invalid-transition-props': 'error', | ||
'xstate/no-async-guard': 'error', | ||
}, | ||
@@ -64,2 +66,3 @@ }, | ||
'xstate/no-invalid-transition-props': 'error', | ||
'xstate/no-async-guard': 'error', | ||
}, | ||
@@ -66,0 +69,0 @@ }, |
@@ -24,2 +24,14 @@ 'use strict' | ||
const entryActionDeclaration = | ||
'CallExpression[callee.name=/^createMachine$|^Machine$/] Property[key.name!="states"] > ObjectExpression > Property[key.name="entry"]' | ||
const rootEntryActionDeclaration = | ||
'CallExpression[callee.name=/^createMachine$|^Machine$/] > ObjectExpression:nth-child(1) > Property[key.name="entry"]' | ||
const exitActionDeclaration = | ||
'CallExpression[callee.name=/^createMachine$|^Machine$/] Property[key.name!="states"] > ObjectExpression > Property[key.name="exit"]' | ||
const rootExitActionDeclaration = | ||
'CallExpression[callee.name=/^createMachine$|^Machine$/] > ObjectExpression:nth-child(1) > Property[key.name="exit"]' | ||
module.exports = { | ||
@@ -93,8 +105,8 @@ meta: { | ||
return { | ||
'CallExpression[callee.name=/^createMachine$|^Machine$/] Property[key.name="entry"]': | ||
validateAction('entry'), | ||
'CallExpression[callee.name=/^createMachine$|^Machine$/] Property[key.name="exit"]': | ||
validateAction('exit'), | ||
[entryActionDeclaration]: validateAction('entry'), | ||
[rootEntryActionDeclaration]: validateAction('entry'), | ||
[exitActionDeclaration]: validateAction('exit'), | ||
[rootExitActionDeclaration]: validateAction('exit'), | ||
} | ||
}, | ||
} |
@@ -10,5 +10,2 @@ 'use strict' | ||
// const isMacroCase = (string) => | ||
// /^\*$|^[A-Z](_?[A-Z0-9])*(\.[A-Z](_?[A-Z0-9])*)*(\.\*)?$/.test(string) | ||
const toMacroCase = (string) => { | ||
@@ -58,2 +55,7 @@ const words = string.split('.').filter(Boolean) | ||
function isPropertyOfStateNode(property) { | ||
const grandParent = property.parent.parent.parent.parent | ||
return grandParent.type === 'Property' && grandParent.key.name === 'states' | ||
} | ||
const wildcardOrDot = /[.*]/ | ||
@@ -124,2 +126,7 @@ function containsWildcardOrDot(name) { | ||
} | ||
// make sure this is not a property of a "on" state node | ||
if (isPropertyOfStateNode(node)) { | ||
return | ||
} | ||
const eventName = | ||
@@ -126,0 +133,0 @@ node.key.type === 'Identifier' ? node.key.name : node.key.value |
@@ -63,2 +63,8 @@ 'use strict' | ||
const propertyOfChoosableActionObject = | ||
'CallExpression[callee.name=/^createMachine$|^Machine$/] CallExpression[callee.name="choose"] > ArrayExpression > ObjectExpression > Property' | ||
const propertyOfChoosableActionObjectAlt = | ||
'CallExpression[callee.name=/^createMachine$|^Machine$/] CallExpression[callee.type="MemberExpression"][callee.object.name="actions"][callee.property.name="choose"] > ArrayExpression > ObjectExpression > Property' | ||
const defaultOptions = { | ||
@@ -165,2 +171,4 @@ allowKnownActionCreators: false, | ||
[propertyOfOnDoneOnErrorTransitionInArray]: checkTransitionProperty, | ||
[propertyOfChoosableActionObject]: checkTransitionProperty, | ||
[propertyOfChoosableActionObjectAlt]: checkTransitionProperty, | ||
@@ -167,0 +175,0 @@ [activitiesProperty]: function (node) { |
'use strict' | ||
const getDocsUrl = require('../utils/getDocsUrl') | ||
const { isReservedXStateWord } = require('../utils/predicates') | ||
const snakeCase = require('lodash.snakecase') | ||
@@ -39,3 +40,4 @@ const camelCase = require('lodash.camelcase') | ||
docs: { | ||
description: 'suggest consistent formatting of state names', | ||
description: | ||
'suggest consistent formatting of state names and warn about confusing names', | ||
category: 'Stylistic Issues', | ||
@@ -66,2 +68,4 @@ url: getDocsUrl('state-names'), | ||
'State name "{{name}}" violates regular expression /{{regex}}/', | ||
stateNameIsReservedWord: | ||
'"{{name}}" has a special meaning to XState in some contexts. Using it as a state name is confusing.', | ||
}, | ||
@@ -88,2 +92,11 @@ }, | ||
if (isReservedXStateWord(name)) { | ||
context.report({ | ||
node, | ||
data: { name }, | ||
messageId: 'stateNameIsReservedWord', | ||
}) | ||
return | ||
} | ||
if (regex && !regex.test(name)) { | ||
@@ -90,0 +103,0 @@ context.report({ |
@@ -102,2 +102,30 @@ const { allPass, complement } = require('./combinators') | ||
// list of property names which have special meaning to XState in some contexts (they are | ||
// part of the XState's API) | ||
const reservedWords = [ | ||
'on', | ||
'src', | ||
'onDone', | ||
'onError', | ||
'id', | ||
'after', | ||
'type', | ||
'cond', | ||
'actions', | ||
'activities', | ||
'in', | ||
'invoke', | ||
'meta', | ||
'always', | ||
'initial', | ||
'entry', | ||
'exit', | ||
'context', | ||
'states', | ||
'tags', | ||
] | ||
function isReservedXStateWord(string) { | ||
return reservedWords.includes(string) | ||
} | ||
module.exports = { | ||
@@ -118,2 +146,3 @@ isFirstArrayItem, | ||
isWithinInvoke, | ||
isReservedXStateWord, | ||
} |
{ | ||
"name": "eslint-plugin-xstate", | ||
"version": "0.10.1", | ||
"version": "0.11.0", | ||
"description": "ESLint rules for XState", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
@@ -48,2 +48,3 @@ # eslint-plugin-xstate | ||
"xstate/no-invalid-transition-props": "error", | ||
"xstate/no-async-guard": "error", | ||
"xstate/event-names": ["warn", "macroCase"], | ||
@@ -90,2 +91,3 @@ "xstate/state-names": ["warn", "camelCase"], | ||
| [no-invalid-transition-props](docs/rules/no-invalid-transition-props.md) | Forbid invalid properties in transition declarations | :heavy_check_mark: | | ||
| [no-async-guard](docs/rules/no-async-guard.md) | Forbid asynchronous guard functions | :heavy_check_mark: | | ||
@@ -102,5 +104,5 @@ ### Best Practices | ||
| Rule | Description | Recommended | | ||
| ---------------------------------------- | -------------------------------------------- | ----------- | | ||
| [event-names](docs/rules/event-names.md) | Suggest consistent formatting of event names | | | ||
| [state-names](docs/rules/state-names.md) | Suggest consistent formatting of state names | | | ||
| Rule | Description | Recommended | | ||
| ---------------------------------------- | ------------------------------------------------------------------------ | ----------- | | ||
| [event-names](docs/rules/event-names.md) | Suggest consistent formatting of event names | | | ||
| [state-names](docs/rules/state-names.md) | Suggest consistent formatting of state names and prevent confusing names | | |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
67277
31
1707
106