eslint-plugin-mobx 0.0.13 → 0.1.0
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 +12 -0
- package/dist/exhaustive-make-observable.d.ts +3 -0
- package/dist/exhaustive-make-observable.js +154 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +51 -546
- package/dist/missing-make-observable.d.ts +3 -0
- package/dist/missing-make-observable.js +72 -0
- package/dist/missing-observer.d.ts +3 -0
- package/dist/missing-observer.js +85 -0
- package/dist/no-anonymous-observer.d.ts +3 -0
- package/dist/no-anonymous-observer.js +64 -0
- package/dist/unconditional-make-observable.d.ts +3 -0
- package/dist/unconditional-make-observable.js +63 -0
- package/dist/utils.d.ts +3 -0
- package/dist/utils.js +27 -0
- package/package.json +13 -14
- package/src/{exhaustive-make-observable.js → exhaustive-make-observable.ts} +8 -7
- package/src/{index.js → index.ts} +16 -11
- package/src/{missing-make-observable.js → missing-make-observable.ts} +7 -6
- package/src/{missing-observer.js → missing-observer.ts} +5 -3
- package/src/{no-anonymous-observer.js → no-anonymous-observer.ts} +5 -3
- package/src/{unconditional-make-observable.js → unconditional-make-observable.ts} +7 -5
- package/src/{utils.js → utils.ts} +3 -10
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# eslint-plugin-mobx
|
|
2
2
|
|
|
3
|
+
## 0.1.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`f7af259df425280aebeb0ccdb13350ba6d24270a`](https://github.com/mobxjs/mobx/commit/f7af259df425280aebeb0ccdb13350ba6d24270a) [#4699](https://github.com/mobxjs/mobx/pull/4699) Thanks [@rakleed](https://github.com/rakleed)! - Add TypeScript types for `configs.recommended` and `flatConfigs.recommended`, so they're typed when used from a TypeScript `eslint.config.ts`.
|
|
8
|
+
|
|
9
|
+
## 0.0.14
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [`f65bc0700461846b05294f857beb211f45eead6f`](https://github.com/mobxjs/mobx/commit/f65bc0700461846b05294f857beb211f45eead6f) [#4613](https://github.com/mobxjs/mobx/pull/4613) Thanks [@roli-lpci](https://github.com/roli-lpci)! - Replace deprecated context.getSourceCode() with context.sourceCode for ESLint 10 compatibility
|
|
14
|
+
|
|
3
15
|
## 0.0.13
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __read = (this && this.__read) || function (o, n) {
|
|
3
|
+
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
4
|
+
if (!m) return o;
|
|
5
|
+
var i = m.call(o), r, ar = [], e;
|
|
6
|
+
try {
|
|
7
|
+
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
|
8
|
+
}
|
|
9
|
+
catch (error) { e = { error: error }; }
|
|
10
|
+
finally {
|
|
11
|
+
try {
|
|
12
|
+
if (r && !r.done && (m = i["return"])) m.call(i);
|
|
13
|
+
}
|
|
14
|
+
finally { if (e) throw e.error; }
|
|
15
|
+
}
|
|
16
|
+
return ar;
|
|
17
|
+
};
|
|
18
|
+
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
19
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
20
|
+
if (ar || !(i in from)) {
|
|
21
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
22
|
+
ar[i] = from[i];
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
26
|
+
};
|
|
27
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
28
|
+
var utils_1 = require("./utils");
|
|
29
|
+
// TODO support this.foo = 5; in constructor
|
|
30
|
+
// TODO? report on field as well
|
|
31
|
+
function create(context) {
|
|
32
|
+
var _a, _b, _c;
|
|
33
|
+
var sourceCode = (_a = context.sourceCode) !== null && _a !== void 0 ? _a : context.getSourceCode();
|
|
34
|
+
var autofixAnnotation = (_c = (_b = context.options[0]) === null || _b === void 0 ? void 0 : _b.autofixAnnotation) !== null && _c !== void 0 ? _c : true;
|
|
35
|
+
function fieldToKey(field) {
|
|
36
|
+
// TODO cache on field?
|
|
37
|
+
var key = sourceCode.getText(field.key);
|
|
38
|
+
return field.computed ? "[".concat(key, "]") : key;
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
'CallExpression[callee.name="makeObservable"]': function (makeObservable) {
|
|
42
|
+
var _a;
|
|
43
|
+
// Only interested about makeObservable(this, ...) in constructor or makeObservable({}, ...)
|
|
44
|
+
// ClassDeclaration
|
|
45
|
+
// ClassBody
|
|
46
|
+
// MethodDefinition[kind="constructor"]
|
|
47
|
+
// FunctionExpression
|
|
48
|
+
// BlockStatement
|
|
49
|
+
// ExpressionStatement
|
|
50
|
+
// CallExpression[callee.name="makeObservable"]
|
|
51
|
+
var _b = __read(makeObservable.arguments, 2), firstArg = _b[0], secondArg = _b[1];
|
|
52
|
+
if (!firstArg)
|
|
53
|
+
return;
|
|
54
|
+
var members;
|
|
55
|
+
if (firstArg.type === "ThisExpression") {
|
|
56
|
+
var closestFunction = (0, utils_1.findAncestor)(makeObservable, function (node) {
|
|
57
|
+
return node.type === "FunctionExpression" || node.type === "FunctionDeclaration";
|
|
58
|
+
});
|
|
59
|
+
if (((_a = closestFunction === null || closestFunction === void 0 ? void 0 : closestFunction.parent) === null || _a === void 0 ? void 0 : _a.kind) !== "constructor")
|
|
60
|
+
return;
|
|
61
|
+
members = closestFunction.parent.parent.parent.body.body;
|
|
62
|
+
}
|
|
63
|
+
else if (firstArg.type === "ObjectExpression") {
|
|
64
|
+
members = firstArg.properties;
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
var annotationProps = (secondArg === null || secondArg === void 0 ? void 0 : secondArg.properties) || [];
|
|
70
|
+
var nonAnnotatedMembers = [];
|
|
71
|
+
var hasAnyDecorator = false;
|
|
72
|
+
members.forEach(function (member) {
|
|
73
|
+
var _a;
|
|
74
|
+
if (member.static)
|
|
75
|
+
return;
|
|
76
|
+
if (member.kind === "constructor")
|
|
77
|
+
return;
|
|
78
|
+
//if (member.type !== 'MethodDefinition' && member.type !== 'ClassProperty') return;
|
|
79
|
+
hasAnyDecorator =
|
|
80
|
+
hasAnyDecorator || ((_a = member.decorators) === null || _a === void 0 ? void 0 : _a.some(utils_1.isMobxDecorator)) || false;
|
|
81
|
+
if (!annotationProps.some(function (prop) { return fieldToKey(prop) === fieldToKey(member); })) {
|
|
82
|
+
// TODO optimize?
|
|
83
|
+
nonAnnotatedMembers.push(member);
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
/*
|
|
87
|
+
// With decorators, second arg must be null/undefined or not provided
|
|
88
|
+
if (hasAnyDecorator && secondArg && secondArg.name !== "undefined" && secondArg.value !== null) {
|
|
89
|
+
context.report({
|
|
90
|
+
node: makeObservable,
|
|
91
|
+
message: 'When using decorators, second arg must be `null`, `undefined` or not provided.',
|
|
92
|
+
})
|
|
93
|
+
}
|
|
94
|
+
// Without decorators, in constructor, second arg must be object literal
|
|
95
|
+
if (!hasAnyDecorator && firstArg.type === 'ThisExpression' && (!secondArg || secondArg.type !== 'ObjectExpression')) {
|
|
96
|
+
context.report({
|
|
97
|
+
node: makeObservable,
|
|
98
|
+
message: 'Second argument must be object in form of `{ key: annotation }`.',
|
|
99
|
+
})
|
|
100
|
+
}
|
|
101
|
+
*/
|
|
102
|
+
if (!hasAnyDecorator && nonAnnotatedMembers.length) {
|
|
103
|
+
// Set avoids reporting twice for setter+getter pair or actual duplicates
|
|
104
|
+
var keys_1 = __spreadArray([], __read(new Set(nonAnnotatedMembers.map(fieldToKey))), false);
|
|
105
|
+
var keyList = keys_1.map(function (key) { return "`".concat(key, "`"); }).join(", ");
|
|
106
|
+
var fix = function (fixer) {
|
|
107
|
+
var annotationList = keys_1.map(function (key) { return "".concat(key, ": ").concat(autofixAnnotation); }).join(", ") + ",";
|
|
108
|
+
if (!secondArg) {
|
|
109
|
+
return fixer.insertTextAfter(firstArg, ", { ".concat(annotationList, " }"));
|
|
110
|
+
}
|
|
111
|
+
else if (secondArg.type !== "ObjectExpression") {
|
|
112
|
+
return fixer.replaceText(secondArg, "{ ".concat(annotationList, " }"));
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
var openingBracket = sourceCode.getFirstToken(secondArg);
|
|
116
|
+
return fixer.insertTextAfter(openingBracket, " ".concat(annotationList, " "));
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
context.report({
|
|
120
|
+
node: makeObservable,
|
|
121
|
+
messageId: "missingAnnotation",
|
|
122
|
+
data: { keyList: keyList },
|
|
123
|
+
fix: fix
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
var rule = {
|
|
130
|
+
meta: {
|
|
131
|
+
type: "suggestion",
|
|
132
|
+
fixable: "code",
|
|
133
|
+
schema: [
|
|
134
|
+
{
|
|
135
|
+
type: "object",
|
|
136
|
+
properties: {
|
|
137
|
+
autofixAnnotation: {
|
|
138
|
+
type: "boolean"
|
|
139
|
+
}
|
|
140
|
+
},
|
|
141
|
+
additionalProperties: false
|
|
142
|
+
}
|
|
143
|
+
],
|
|
144
|
+
docs: {
|
|
145
|
+
description: "enforce all fields being listen in `makeObservable`",
|
|
146
|
+
recommended: true
|
|
147
|
+
},
|
|
148
|
+
messages: {
|
|
149
|
+
missingAnnotation: "Missing annotation for {{ keyList }}. To exclude a field, use `false` as annotation."
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
create: create
|
|
153
|
+
};
|
|
154
|
+
exports.default = rule;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ESLint, Linter } from "eslint";
|
|
2
|
+
declare const pluginMobx: ESLint.Plugin;
|
|
3
|
+
declare const plugin: typeof pluginMobx & {
|
|
4
|
+
configs: {
|
|
5
|
+
recommended: Linter.LegacyConfig;
|
|
6
|
+
};
|
|
7
|
+
flatConfigs: {
|
|
8
|
+
recommended: Linter.Config;
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
export = plugin;
|