eslint-plugin-mobx 0.0.10 → 0.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/dist/index.js +87 -72
- package/package.json +1 -1
- package/src/missing-observer.js +86 -55
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# eslint-plugin-mobx
|
|
2
2
|
|
|
3
|
+
## 0.0.11
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`638533e592f4fda7663fa351447380f9d0917d14`](https://github.com/mobxjs/mobx/commit/638533e592f4fda7663fa351447380f9d0917d14) [#3909](https://github.com/mobxjs/mobx/pull/3909) Thanks [@urugator](https://github.com/urugator)! - mobx/missing-observer rule false positive with forwardRef #3908
|
|
8
|
+
|
|
3
9
|
## 0.0.10
|
|
4
10
|
|
|
5
11
|
### Patch Changes
|
package/dist/index.js
CHANGED
|
@@ -1,65 +1,64 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
function
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
3
|
+
function _arrayLikeToArray(r, a) {
|
|
4
|
+
(null == a || a > r.length) && (a = r.length);
|
|
5
|
+
for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
|
|
6
|
+
return n;
|
|
7
|
+
}
|
|
8
|
+
function _arrayWithHoles(r) {
|
|
9
|
+
if (Array.isArray(r)) return r;
|
|
10
|
+
}
|
|
11
|
+
function _arrayWithoutHoles(r) {
|
|
12
|
+
if (Array.isArray(r)) return _arrayLikeToArray(r);
|
|
13
|
+
}
|
|
14
|
+
function _iterableToArray(r) {
|
|
15
|
+
if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r);
|
|
16
|
+
}
|
|
17
|
+
function _iterableToArrayLimit(r, l) {
|
|
18
|
+
var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
|
|
19
|
+
if (null != t) {
|
|
20
|
+
var e,
|
|
21
|
+
n,
|
|
22
|
+
i,
|
|
23
|
+
u,
|
|
24
|
+
a = [],
|
|
25
|
+
f = !0,
|
|
26
|
+
o = !1;
|
|
13
27
|
try {
|
|
14
|
-
if (
|
|
15
|
-
if (Object(
|
|
16
|
-
|
|
17
|
-
} else for (; !(
|
|
18
|
-
} catch (
|
|
19
|
-
|
|
28
|
+
if (i = (t = t.call(r)).next, 0 === l) {
|
|
29
|
+
if (Object(t) !== t) return;
|
|
30
|
+
f = !1;
|
|
31
|
+
} else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);
|
|
32
|
+
} catch (r) {
|
|
33
|
+
o = !0, n = r;
|
|
20
34
|
} finally {
|
|
21
35
|
try {
|
|
22
|
-
if (!
|
|
36
|
+
if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;
|
|
23
37
|
} finally {
|
|
24
|
-
if (
|
|
38
|
+
if (o) throw n;
|
|
25
39
|
}
|
|
26
40
|
}
|
|
27
|
-
return
|
|
41
|
+
return a;
|
|
28
42
|
}
|
|
29
43
|
}
|
|
30
|
-
function
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
function _toConsumableArray(arr) {
|
|
34
|
-
return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
|
|
35
|
-
}
|
|
36
|
-
function _arrayWithoutHoles(arr) {
|
|
37
|
-
if (Array.isArray(arr)) return _arrayLikeToArray(arr);
|
|
38
|
-
}
|
|
39
|
-
function _arrayWithHoles(arr) {
|
|
40
|
-
if (Array.isArray(arr)) return arr;
|
|
41
|
-
}
|
|
42
|
-
function _iterableToArray(iter) {
|
|
43
|
-
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
|
|
44
|
-
}
|
|
45
|
-
function _unsupportedIterableToArray(o, minLen) {
|
|
46
|
-
if (!o) return;
|
|
47
|
-
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
|
|
48
|
-
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
49
|
-
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
50
|
-
if (n === "Map" || n === "Set") return Array.from(o);
|
|
51
|
-
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
|
|
52
|
-
}
|
|
53
|
-
function _arrayLikeToArray(arr, len) {
|
|
54
|
-
if (len == null || len > arr.length) len = arr.length;
|
|
55
|
-
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
|
|
56
|
-
return arr2;
|
|
44
|
+
function _nonIterableRest() {
|
|
45
|
+
throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
57
46
|
}
|
|
58
47
|
function _nonIterableSpread() {
|
|
59
48
|
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
60
49
|
}
|
|
61
|
-
function
|
|
62
|
-
|
|
50
|
+
function _slicedToArray(r, e) {
|
|
51
|
+
return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();
|
|
52
|
+
}
|
|
53
|
+
function _toConsumableArray(r) {
|
|
54
|
+
return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread();
|
|
55
|
+
}
|
|
56
|
+
function _unsupportedIterableToArray(r, a) {
|
|
57
|
+
if (r) {
|
|
58
|
+
if ("string" == typeof r) return _arrayLikeToArray(r, a);
|
|
59
|
+
var t = {}.toString.call(r).slice(8, -1);
|
|
60
|
+
return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
|
|
61
|
+
}
|
|
63
62
|
}
|
|
64
63
|
|
|
65
64
|
var mobxDecorators = new Set(['observable', 'computed', 'action', 'flow', 'override']);
|
|
@@ -69,7 +68,6 @@ function isMobxDecorator$2(decorator) {
|
|
|
69
68
|
|| mobxDecorators.has((_decorator$expression = decorator.expression.callee) === null || _decorator$expression === void 0 ? void 0 : _decorator$expression.name) // @foo()
|
|
70
69
|
|| mobxDecorators.has((_decorator$expression2 = decorator.expression.object) === null || _decorator$expression2 === void 0 ? void 0 : _decorator$expression2.name); // @foo.bar
|
|
71
70
|
}
|
|
72
|
-
|
|
73
71
|
function findAncestor$3(node, match) {
|
|
74
72
|
var parent = node.parent;
|
|
75
73
|
if (!parent) return;
|
|
@@ -115,7 +113,7 @@ function create$4(context) {
|
|
|
115
113
|
var closestFunction = findAncestor$2(makeObservable, function (node) {
|
|
116
114
|
return node.type === "FunctionExpression" || node.type === "FunctionDeclaration";
|
|
117
115
|
});
|
|
118
|
-
if ((closestFunction === null || closestFunction === void 0
|
|
116
|
+
if ((closestFunction === null || closestFunction === void 0 || (_closestFunction$pare = closestFunction.parent) === null || _closestFunction$pare === void 0 ? void 0 : _closestFunction$pare.kind) !== "constructor") return;
|
|
119
117
|
members = closestFunction.parent.parent.parent.body.body;
|
|
120
118
|
} else if (firstArg.type === "ObjectExpression") {
|
|
121
119
|
members = firstArg.properties;
|
|
@@ -229,7 +227,7 @@ function create$3(context) {
|
|
|
229
227
|
var closestFunction = findAncestor$1(makeObservable, function (node) {
|
|
230
228
|
return node.type === 'FunctionExpression' || node.type === 'FunctionDeclaration';
|
|
231
229
|
});
|
|
232
|
-
if ((closestFunction === null || closestFunction === void 0
|
|
230
|
+
if ((closestFunction === null || closestFunction === void 0 || (_closestFunction$pare = closestFunction.parent) === null || _closestFunction$pare === void 0 ? void 0 : _closestFunction$pare.kind) !== 'constructor') return;
|
|
233
231
|
if (makeObservable.parent.parent.parent !== closestFunction) {
|
|
234
232
|
context.report({
|
|
235
233
|
node: makeObservable,
|
|
@@ -262,7 +260,7 @@ function create$2(context) {
|
|
|
262
260
|
var sourceCode = context.getSourceCode();
|
|
263
261
|
return {
|
|
264
262
|
'Decorator': function Decorator(decorator) {
|
|
265
|
-
var _clazz$body$body$find, _constructor$value$bo
|
|
263
|
+
var _clazz$body$body$find, _constructor$value$bo;
|
|
266
264
|
if (!isMobxDecorator(decorator)) return;
|
|
267
265
|
var clazz = findAncestor(decorator, function (node) {
|
|
268
266
|
return node.type === 'ClassDeclaration' || node.type === 'ClassExpression';
|
|
@@ -276,10 +274,10 @@ function create$2(context) {
|
|
|
276
274
|
});
|
|
277
275
|
// MethodDefinition > FunctionExpression > BlockStatement > []
|
|
278
276
|
var isMakeObservable = function isMakeObservable(node) {
|
|
279
|
-
var _node$expression, _node$
|
|
280
|
-
return ((_node$expression = node.expression) === null || _node$expression === void 0
|
|
277
|
+
var _node$expression, _node$expression2;
|
|
278
|
+
return ((_node$expression = node.expression) === null || _node$expression === void 0 || (_node$expression = _node$expression.callee) === null || _node$expression === void 0 ? void 0 : _node$expression.name) === 'makeObservable' && ((_node$expression2 = node.expression) === null || _node$expression2 === void 0 || (_node$expression2 = _node$expression2.arguments[0]) === null || _node$expression2 === void 0 ? void 0 : _node$expression2.type) === 'ThisExpression';
|
|
281
279
|
};
|
|
282
|
-
var makeObservable = constructor === null || constructor === void 0
|
|
280
|
+
var makeObservable = constructor === null || constructor === void 0 || (_constructor$value$bo = constructor.value.body) === null || _constructor$value$bo === void 0 || (_constructor$value$bo = _constructor$value$bo.body.find(isMakeObservable)) === null || _constructor$value$bo === void 0 ? void 0 : _constructor$value$bo.expression;
|
|
283
281
|
if (makeObservable) {
|
|
284
282
|
// make sure second arg is nullish
|
|
285
283
|
var secondArg = makeObservable.arguments[1];
|
|
@@ -334,34 +332,51 @@ var missingMakeObservable$1 = {
|
|
|
334
332
|
function create$1(context) {
|
|
335
333
|
var sourceCode = context.getSourceCode();
|
|
336
334
|
return {
|
|
337
|
-
|
|
338
|
-
var _cmp$id,
|
|
339
|
-
|
|
340
|
-
|
|
335
|
+
"FunctionDeclaration,FunctionExpression,ArrowFunctionExpression,ClassDeclaration,ClassExpression": function FunctionDeclarationFunctionExpressionArrowFunctionExpressionClassDeclarationClassExpression(cmp) {
|
|
336
|
+
var _cmp$id, _cmpOrForwardRef$pare;
|
|
337
|
+
if (cmp.parent && cmp.parent.type === "CallExpression" && cmp.parent.callee.name === "observer") {
|
|
338
|
+
// observer(...)
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
var forwardRef = cmp.parent && cmp.parent.type === "CallExpression" && cmp.parent.callee.name === "forwardRef" ? cmp.parent : undefined;
|
|
342
|
+
if (forwardRef && forwardRef.parent && forwardRef.parent.type === "CallExpression" && forwardRef.parent.callee.name === "observer") {
|
|
343
|
+
// forwardRef(observer(...))
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
346
|
+
var cmpOrForwardRef = forwardRef || cmp;
|
|
341
347
|
var name = (_cmp$id = cmp.id) === null || _cmp$id === void 0 ? void 0 : _cmp$id.name;
|
|
342
|
-
// If anonymous try to infer name from variable declaration
|
|
343
|
-
if (!name && ((
|
|
344
|
-
name =
|
|
348
|
+
// If anonymous try to infer name from variable declaration
|
|
349
|
+
if (!name && ((_cmpOrForwardRef$pare = cmpOrForwardRef.parent) === null || _cmpOrForwardRef$pare === void 0 ? void 0 : _cmpOrForwardRef$pare.type) === "VariableDeclarator") {
|
|
350
|
+
name = cmpOrForwardRef.parent.id.name;
|
|
345
351
|
}
|
|
346
|
-
if (cmp.type.startsWith(
|
|
352
|
+
if (cmp.type.startsWith("Class")) {
|
|
347
353
|
// Must extend Component or React.Component
|
|
348
354
|
var superClass = cmp.superClass;
|
|
349
|
-
if (!superClass)
|
|
355
|
+
if (!superClass) {
|
|
356
|
+
// not a component
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
350
359
|
var superClassText = sourceCode.getText(superClass);
|
|
351
|
-
if (superClassText !==
|
|
360
|
+
if (superClassText !== "Component" && superClassText !== "React.Component") {
|
|
361
|
+
// not a component
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
352
364
|
} else {
|
|
353
365
|
var _name;
|
|
354
366
|
// Name must start with uppercase letter
|
|
355
|
-
if (!((_name = name) !== null && _name !== void 0 && _name.charAt(0).match(/^[A-Z]$/)))
|
|
367
|
+
if (!((_name = name) !== null && _name !== void 0 && _name.charAt(0).match(/^[A-Z]$/))) {
|
|
368
|
+
// not a component
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
356
371
|
}
|
|
357
372
|
var fix = function fix(fixer) {
|
|
358
|
-
return [fixer.insertTextBefore(sourceCode.getFirstToken(
|
|
373
|
+
return [fixer.insertTextBefore(sourceCode.getFirstToken(cmpOrForwardRef), (name && cmp.type.endsWith("Declaration") ? "const ".concat(name, " = ") : "") + "observer("), fixer.insertTextAfter(sourceCode.getLastToken(cmpOrForwardRef), ")")];
|
|
359
374
|
};
|
|
360
375
|
context.report({
|
|
361
376
|
node: cmp,
|
|
362
|
-
messageId:
|
|
377
|
+
messageId: "missingObserver",
|
|
363
378
|
data: {
|
|
364
|
-
name: name ||
|
|
379
|
+
name: name || "<anonymous>"
|
|
365
380
|
},
|
|
366
381
|
fix: fix
|
|
367
382
|
});
|
|
@@ -370,10 +385,10 @@ function create$1(context) {
|
|
|
370
385
|
}
|
|
371
386
|
var missingObserver$1 = {
|
|
372
387
|
meta: {
|
|
373
|
-
type:
|
|
374
|
-
fixable:
|
|
388
|
+
type: "problem",
|
|
389
|
+
fixable: "code",
|
|
375
390
|
docs: {
|
|
376
|
-
description:
|
|
391
|
+
description: "prevents missing `observer` on react component",
|
|
377
392
|
recommended: true
|
|
378
393
|
},
|
|
379
394
|
messages: {
|
package/package.json
CHANGED
package/src/missing-observer.js
CHANGED
|
@@ -1,63 +1,94 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict"
|
|
2
2
|
|
|
3
3
|
function create(context) {
|
|
4
|
-
|
|
4
|
+
const sourceCode = context.getSourceCode()
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
6
|
+
return {
|
|
7
|
+
"FunctionDeclaration,FunctionExpression,ArrowFunctionExpression,ClassDeclaration,ClassExpression":
|
|
8
|
+
cmp => {
|
|
9
|
+
if (
|
|
10
|
+
cmp.parent &&
|
|
11
|
+
cmp.parent.type === "CallExpression" &&
|
|
12
|
+
cmp.parent.callee.name === "observer"
|
|
13
|
+
) {
|
|
14
|
+
// observer(...)
|
|
15
|
+
return
|
|
16
|
+
}
|
|
17
|
+
let forwardRef =
|
|
18
|
+
cmp.parent &&
|
|
19
|
+
cmp.parent.type === "CallExpression" &&
|
|
20
|
+
cmp.parent.callee.name === "forwardRef"
|
|
21
|
+
? cmp.parent
|
|
22
|
+
: undefined
|
|
23
|
+
if (
|
|
24
|
+
forwardRef &&
|
|
25
|
+
forwardRef.parent &&
|
|
26
|
+
forwardRef.parent.type === "CallExpression" &&
|
|
27
|
+
forwardRef.parent.callee.name === "observer"
|
|
28
|
+
) {
|
|
29
|
+
// forwardRef(observer(...))
|
|
30
|
+
return
|
|
31
|
+
}
|
|
25
32
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
33
|
+
const cmpOrForwardRef = forwardRef || cmp
|
|
34
|
+
let name = cmp.id?.name
|
|
35
|
+
// If anonymous try to infer name from variable declaration
|
|
36
|
+
if (!name && cmpOrForwardRef.parent?.type === "VariableDeclarator") {
|
|
37
|
+
name = cmpOrForwardRef.parent.id.name
|
|
38
|
+
}
|
|
39
|
+
if (cmp.type.startsWith("Class")) {
|
|
40
|
+
// Must extend Component or React.Component
|
|
41
|
+
const { superClass } = cmp
|
|
42
|
+
if (!superClass) {
|
|
43
|
+
// not a component
|
|
44
|
+
return
|
|
45
|
+
}
|
|
46
|
+
const superClassText = sourceCode.getText(superClass)
|
|
47
|
+
if (superClassText !== "Component" && superClassText !== "React.Component") {
|
|
48
|
+
// not a component
|
|
49
|
+
return
|
|
50
|
+
}
|
|
51
|
+
} else {
|
|
52
|
+
// Name must start with uppercase letter
|
|
53
|
+
if (!name?.charAt(0).match(/^[A-Z]$/)) {
|
|
54
|
+
// not a component
|
|
55
|
+
return
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const fix = fixer => {
|
|
60
|
+
return [
|
|
61
|
+
fixer.insertTextBefore(
|
|
62
|
+
sourceCode.getFirstToken(cmpOrForwardRef),
|
|
63
|
+
(name && cmp.type.endsWith("Declaration") ? `const ${name} = ` : "") +
|
|
64
|
+
"observer("
|
|
65
|
+
),
|
|
66
|
+
fixer.insertTextAfter(sourceCode.getLastToken(cmpOrForwardRef), ")")
|
|
67
|
+
]
|
|
68
|
+
}
|
|
69
|
+
context.report({
|
|
70
|
+
node: cmp,
|
|
71
|
+
messageId: "missingObserver",
|
|
72
|
+
data: {
|
|
73
|
+
name: name || "<anonymous>"
|
|
74
|
+
},
|
|
75
|
+
fix
|
|
76
|
+
})
|
|
77
|
+
}
|
|
78
|
+
}
|
|
48
79
|
}
|
|
49
80
|
|
|
50
81
|
module.exports = {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
82
|
+
meta: {
|
|
83
|
+
type: "problem",
|
|
84
|
+
fixable: "code",
|
|
85
|
+
docs: {
|
|
86
|
+
description: "prevents missing `observer` on react component",
|
|
87
|
+
recommended: true
|
|
88
|
+
},
|
|
89
|
+
messages: {
|
|
90
|
+
missingObserver: "Component `{{ name }}` is missing `observer`."
|
|
91
|
+
}
|
|
60
92
|
},
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
};
|
|
93
|
+
create
|
|
94
|
+
}
|