3
3
const getDocsUrl = require ( '../utils/getDocsUrl' )
4
4
const getSettings = require ( '../utils/getSettings' )
5
5
const getSelectorPrefix = require ( '../utils/getSelectorPrefix' )
6
+ const {
7
+ isAssignActionCreatorCall,
8
+ isWithinNode,
9
+ isFunctionExpression,
10
+ } = require ( '../utils/predicates' )
6
11
7
12
module . exports = {
8
13
meta : {
@@ -16,7 +21,8 @@ module.exports = {
16
21
fixable : 'code' ,
17
22
schema : [ ] ,
18
23
messages : {
19
- missingSystemId : 'Missing "systemId" property in "invoke" block.' ,
24
+ missingSystemId : 'Missing "systemId" property for an invoked actor.' ,
25
+ missingSystemIdSpawn : 'Missing "systemId" property for a spawned actor.' ,
20
26
invalidSystemId : 'Property "systemId" should be a non-empty string.' ,
21
27
systemIdNotAllowedBeforeVersion5 :
22
28
'Property "systemId" is not supported in xstate < 5.' ,
@@ -29,6 +35,69 @@ module.exports = {
29
35
const prefix = getSelectorPrefix ( context . sourceCode )
30
36
const systemIds = new Set ( )
31
37
38
+ function checkSpawnExpression ( node ) {
39
+ // check if this spawn call is relevant - must be within a function expression inside the assign action creator
40
+ if (
41
+ ! isWithinNode (
42
+ node ,
43
+ ( ancestor ) =>
44
+ isFunctionExpression ( ancestor ) &&
45
+ isWithinNode (
46
+ ancestor ,
47
+ ( x ) => isAssignActionCreatorCall ( x ) ,
48
+ ( ancestor ) => isFunctionExpression ( ancestor )
49
+ )
50
+ )
51
+ ) {
52
+ return
53
+ }
54
+
55
+ if ( node . arguments . length < 2 ) {
56
+ context . report ( {
57
+ node,
58
+ messageId : 'missingSystemIdSpawn' ,
59
+ } )
60
+ return
61
+ }
62
+ const arg2 = node . arguments [ 1 ]
63
+ if (
64
+ arg2 . type !== 'ObjectExpression' ||
65
+ ! arg2 . properties . some ( ( prop ) => prop . key . name === 'systemId' )
66
+ ) {
67
+ context . report ( {
68
+ node : arg2 ,
69
+ messageId : 'missingSystemIdSpawn' ,
70
+ } )
71
+ return
72
+ }
73
+ const systemIdProp = arg2 . properties . find (
74
+ ( prop ) => prop . key . name === 'systemId'
75
+ )
76
+
77
+ if (
78
+ systemIdProp . value . type !== 'Literal' ||
79
+ typeof systemIdProp . value . value !== 'string' ||
80
+ systemIdProp . value . value . trim ( ) === ''
81
+ ) {
82
+ context . report ( {
83
+ node : systemIdProp ,
84
+ messageId : 'invalidSystemId' ,
85
+ } )
86
+ }
87
+ }
88
+
89
+ function checkUniqueSystemId ( node ) {
90
+ if ( systemIds . has ( node . value . value ) ) {
91
+ context . report ( {
92
+ node,
93
+ messageId : 'duplicateSystemId' ,
94
+ data : { systemId : node . value . value } ,
95
+ } )
96
+ } else {
97
+ systemIds . add ( node . value . value )
98
+ }
99
+ }
100
+
32
101
return {
33
102
[ `${ prefix } Property[key.name='invoke'] > ObjectExpression` ] : ( node ) => {
34
103
const systemIdProp = node . properties . find (
@@ -61,40 +130,24 @@ module.exports = {
61
130
context . report ( {
62
131
node : systemIdProp ,
63
132
messageId : 'invalidSystemId' ,
64
- fix : ( fixer ) =>
65
- fixer . replaceText ( systemIdProp . value , "'myActor'" ) ,
66
133
} )
67
134
}
68
135
} else if ( version >= 5 ) {
69
- const { loc } = node . properties [ 0 ]
70
- const offset = loc . start . column
71
136
context . report ( {
72
137
node,
73
138
messageId : 'missingSystemId' ,
74
- fix : ( fixer ) => {
75
- return fixer . insertTextBefore (
76
- node . properties [ 0 ] ,
77
- `systemId: 'myActor',\n${ '' . padStart ( offset , ' ' ) } `
78
- )
79
- } ,
80
139
} )
81
140
}
82
141
} ,
83
142
84
143
[ `${ prefix } Property[key.name='invoke'] > ObjectExpression > Property[key.name="systemId"]` ] :
85
- ( node ) => {
86
- if ( systemIds . has ( node . value . value ) ) {
87
- context . report ( {
88
- node,
89
- messageId : 'duplicateSystemId' ,
90
- data : { systemId : node . value . value } ,
91
- } )
92
- } else {
93
- systemIds . add ( node . value . value )
94
- }
95
- } ,
144
+ checkUniqueSystemId ,
145
+ [ `${ prefix } CallExpression[callee.name="assign"] CallExpression[callee.name="spawn"] > ObjectExpression > Property[key.name="systemId"]` ] :
146
+ checkUniqueSystemId ,
96
147
97
- // TODO check use of systemId in spawns
148
+ [ `${ prefix } CallExpression[callee.name="spawn"]` ] : checkSpawnExpression ,
149
+ [ `${ prefix } CallExpression[callee.property.name="spawn"]` ] :
150
+ checkSpawnExpression ,
98
151
}
99
152
} ,
100
153
}
0 commit comments