eslint-plugin-formatjs 4.11.2 → 4.12.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/LICENSE.md +1 -1
- package/index.d.ts +3 -23
- package/index.js +36 -37
- package/package.json +5 -5
- package/rules/blocklist-elements.d.ts +17 -3
- package/rules/blocklist-elements.js +50 -46
- package/rules/enforce-default-message.d.ts +10 -3
- package/rules/enforce-default-message.js +21 -9
- package/rules/enforce-description.d.ts +10 -3
- package/rules/enforce-description.js +19 -6
- package/rules/enforce-id.d.ts +10 -3
- package/rules/enforce-id.js +53 -24
- package/rules/enforce-placeholders.d.ts +8 -3
- package/rules/enforce-placeholders.js +18 -7
- package/rules/enforce-plural-rules.d.ts +17 -3
- package/rules/enforce-plural-rules.js +20 -20
- package/rules/no-camel-case.d.ts +6 -3
- package/rules/no-camel-case.js +20 -20
- package/rules/no-complex-selectors.d.ts +9 -3
- package/rules/no-complex-selectors.js +18 -16
- package/rules/no-emoji.d.ts +9 -3
- package/rules/no-emoji.js +6 -4
- package/rules/no-id.d.ts +6 -3
- package/rules/no-id.js +11 -4
- package/rules/no-invalid-icu.d.ts +6 -3
- package/rules/no-invalid-icu.js +12 -5
- package/rules/no-literal-string-in-jsx.d.ts +13 -3
- package/rules/no-literal-string-in-jsx.js +10 -7
- package/rules/no-multiple-plurals.d.ts +6 -3
- package/rules/no-multiple-plurals.js +20 -20
- package/rules/no-multiple-whitespaces.d.ts +6 -3
- package/rules/no-multiple-whitespaces.js +10 -5
- package/rules/no-offset.d.ts +6 -3
- package/rules/no-offset.js +19 -19
- package/rules/no-useless-message.d.ts +6 -3
- package/rules/no-useless-message.js +23 -39
- package/rules/prefer-formatted-message.d.ts +6 -3
- package/rules/prefer-formatted-message.js +5 -3
- package/rules/prefer-pound-in-plural.d.ts +6 -3
- package/rules/prefer-pound-in-plural.js +10 -4
- package/util.d.ts +2 -2
package/rules/enforce-id.js
CHANGED
|
@@ -1,27 +1,28 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.rule = exports.name = void 0;
|
|
3
4
|
const ts_transformer_1 = require("@formatjs/ts-transformer");
|
|
4
5
|
const util_1 = require("../util");
|
|
5
|
-
function checkNode(context, node, { idInterpolationPattern, idWhitelistRegexps }) {
|
|
6
|
+
function checkNode(context, node, { idInterpolationPattern, idWhitelistRegexps, }) {
|
|
6
7
|
const msgs = (0, util_1.extractMessages)(node, (0, util_1.getSettings)(context));
|
|
7
8
|
for (const [{ message: { defaultMessage, description, id }, idPropNode, descriptionNode, messagePropNode, },] of msgs) {
|
|
8
9
|
if (!idInterpolationPattern && !idPropNode) {
|
|
9
10
|
context.report({
|
|
10
|
-
node
|
|
11
|
-
|
|
11
|
+
node,
|
|
12
|
+
messageId: 'enforceId',
|
|
12
13
|
});
|
|
13
14
|
}
|
|
14
15
|
else if (idInterpolationPattern) {
|
|
15
16
|
if (!defaultMessage) {
|
|
16
17
|
context.report({
|
|
17
|
-
node
|
|
18
|
-
|
|
18
|
+
node,
|
|
19
|
+
messageId: 'enforceIdDefaultMessage',
|
|
19
20
|
});
|
|
20
21
|
}
|
|
21
22
|
else if (!description && descriptionNode) {
|
|
22
23
|
context.report({
|
|
23
|
-
node
|
|
24
|
-
|
|
24
|
+
node,
|
|
25
|
+
messageId: 'enforceIdDescription',
|
|
25
26
|
});
|
|
26
27
|
}
|
|
27
28
|
else {
|
|
@@ -39,17 +40,25 @@ function checkNode(context, node, { idInterpolationPattern, idWhitelistRegexps }
|
|
|
39
40
|
: defaultMessage,
|
|
40
41
|
});
|
|
41
42
|
if (id !== correctId) {
|
|
42
|
-
let
|
|
43
|
+
let messageId = 'enforceIdMatching';
|
|
44
|
+
let messageData = {
|
|
45
|
+
idInterpolationPattern,
|
|
46
|
+
expected: correctId,
|
|
47
|
+
actual: id,
|
|
48
|
+
};
|
|
43
49
|
if (idWhitelistRegexps) {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
50
|
+
messageId = 'enforceIdMatchingAllowlisted';
|
|
51
|
+
messageData = {
|
|
52
|
+
...messageData,
|
|
53
|
+
idWhitelist: idWhitelistRegexps
|
|
54
|
+
.map(r => `"${r.toString()}"`)
|
|
55
|
+
.join(', '),
|
|
56
|
+
};
|
|
47
57
|
}
|
|
48
58
|
context.report({
|
|
49
|
-
node
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
Actual: ${id}`,
|
|
59
|
+
node,
|
|
60
|
+
messageId,
|
|
61
|
+
data: messageData,
|
|
53
62
|
fix(fixer) {
|
|
54
63
|
if (idPropNode) {
|
|
55
64
|
if (idPropNode.type === 'JSXAttribute') {
|
|
@@ -57,11 +66,14 @@ Actual: ${id}`,
|
|
|
57
66
|
}
|
|
58
67
|
return fixer.replaceText(idPropNode, `id: '${correctId}'`);
|
|
59
68
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
69
|
+
if (messagePropNode) {
|
|
70
|
+
// Insert after default message node
|
|
71
|
+
if (messagePropNode.type === 'JSXAttribute') {
|
|
72
|
+
return fixer.insertTextAfter(messagePropNode, ` id="${correctId}"`);
|
|
73
|
+
}
|
|
74
|
+
return fixer.insertTextAfter(messagePropNode, `, id: '${correctId}'`);
|
|
63
75
|
}
|
|
64
|
-
return
|
|
76
|
+
return null;
|
|
65
77
|
},
|
|
66
78
|
});
|
|
67
79
|
}
|
|
@@ -69,13 +81,12 @@ Actual: ${id}`,
|
|
|
69
81
|
}
|
|
70
82
|
}
|
|
71
83
|
}
|
|
72
|
-
exports.
|
|
84
|
+
exports.name = 'enforce-id';
|
|
85
|
+
exports.rule = {
|
|
73
86
|
meta: {
|
|
74
87
|
type: 'problem',
|
|
75
88
|
docs: {
|
|
76
89
|
description: 'Enforce (generated) ID in message descriptor',
|
|
77
|
-
category: 'Errors',
|
|
78
|
-
recommended: false,
|
|
79
90
|
url: 'https://formatjs.io/docs/tooling/linter#enforce-id',
|
|
80
91
|
},
|
|
81
92
|
fixable: 'code',
|
|
@@ -99,10 +110,26 @@ exports.default = {
|
|
|
99
110
|
additionalProperties: false,
|
|
100
111
|
},
|
|
101
112
|
],
|
|
113
|
+
messages: {
|
|
114
|
+
enforceId: `id must be specified`,
|
|
115
|
+
enforceIdDefaultMessage: `defaultMessage must be a string literal to calculate generated IDs`,
|
|
116
|
+
enforceIdDescription: `description must be a string literal to calculate generated IDs`,
|
|
117
|
+
enforceIdMatching: `"id" does not match with hash pattern {{idInterpolationPattern}}.
|
|
118
|
+
Expected: {{expected}}
|
|
119
|
+
Actual: {{actual}}`,
|
|
120
|
+
enforceIdMatchingAllowlisted: `"id" does not match with hash pattern {{idInterpolationPattern}} or allowlisted patterns {{idWhitelist}}.
|
|
121
|
+
Expected: {{expected}}
|
|
122
|
+
Actual: {{actual}}`,
|
|
123
|
+
},
|
|
102
124
|
},
|
|
125
|
+
defaultOptions: [
|
|
126
|
+
{
|
|
127
|
+
idInterpolationPattern: '[sha512:contenthash:base64:6]',
|
|
128
|
+
},
|
|
129
|
+
],
|
|
103
130
|
create(context) {
|
|
104
|
-
const tmp = context
|
|
105
|
-
|
|
131
|
+
const tmp = context.options[0];
|
|
132
|
+
let opts = {
|
|
106
133
|
idInterpolationPattern: tmp?.idInterpolationPattern,
|
|
107
134
|
};
|
|
108
135
|
if (Array.isArray(tmp?.idWhitelist)) {
|
|
@@ -110,7 +137,9 @@ exports.default = {
|
|
|
110
137
|
opts.idWhitelistRegexps = idWhitelist.map((str) => new RegExp(str, 'i'));
|
|
111
138
|
}
|
|
112
139
|
const callExpressionVisitor = (node) => checkNode(context, node, opts);
|
|
140
|
+
//@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
|
|
113
141
|
if (context.parserServices.defineTemplateBodyVisitor) {
|
|
142
|
+
//@ts-expect-error
|
|
114
143
|
return context.parserServices.defineTemplateBodyVisitor({
|
|
115
144
|
CallExpression: callExpressionVisitor,
|
|
116
145
|
}, {
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { RuleModule, RuleListener } from '@typescript-eslint/utils/ts-eslint';
|
|
2
|
+
type MessageIds = 'parserError' | 'missingValue' | 'unusedValue';
|
|
3
|
+
type Options = [{
|
|
4
|
+
ignoreList: string[];
|
|
5
|
+
}?];
|
|
6
|
+
export declare const name = "enforce-placeholders";
|
|
7
|
+
export declare const rule: RuleModule<MessageIds, Options, RuleListener>;
|
|
8
|
+
export {};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.rule = exports.name = void 0;
|
|
3
4
|
const icu_messageformat_parser_1 = require("@formatjs/icu-messageformat-parser");
|
|
4
5
|
const util_1 = require("../util");
|
|
5
6
|
function collectPlaceholderNames(ast) {
|
|
@@ -68,7 +69,8 @@ function checkNode(context, node) {
|
|
|
68
69
|
catch (e) {
|
|
69
70
|
context.report({
|
|
70
71
|
node: messageNode,
|
|
71
|
-
|
|
72
|
+
messageId: 'parserError',
|
|
73
|
+
data: { message: e instanceof Error ? e.message : String(e) },
|
|
72
74
|
});
|
|
73
75
|
continue;
|
|
74
76
|
}
|
|
@@ -82,26 +84,28 @@ function checkNode(context, node) {
|
|
|
82
84
|
if (missingPlaceholders.length > 0) {
|
|
83
85
|
context.report({
|
|
84
86
|
node: messageNode,
|
|
85
|
-
|
|
87
|
+
messageId: 'missingValue',
|
|
88
|
+
data: {
|
|
89
|
+
list: missingPlaceholders.join(', '),
|
|
90
|
+
},
|
|
86
91
|
});
|
|
87
92
|
}
|
|
88
93
|
literalElementByLiteralKey.forEach((element, key) => {
|
|
89
94
|
if (!ignoreList.has(key) && !placeholderNames.has(key)) {
|
|
90
95
|
context.report({
|
|
91
96
|
node: element,
|
|
92
|
-
|
|
97
|
+
messageId: 'unusedValue',
|
|
93
98
|
});
|
|
94
99
|
}
|
|
95
100
|
});
|
|
96
101
|
}
|
|
97
102
|
}
|
|
98
|
-
|
|
103
|
+
exports.name = 'enforce-placeholders';
|
|
104
|
+
exports.rule = {
|
|
99
105
|
meta: {
|
|
100
106
|
type: 'problem',
|
|
101
107
|
docs: {
|
|
102
108
|
description: 'Enforce that all messages with placeholders have enough passed-in values',
|
|
103
|
-
category: 'Errors',
|
|
104
|
-
recommended: true,
|
|
105
109
|
url: 'https://formatjs.io/docs/tooling/linter#enforce-placeholders',
|
|
106
110
|
},
|
|
107
111
|
schema: [
|
|
@@ -118,10 +122,18 @@ const rule = {
|
|
|
118
122
|
additionalProperties: false,
|
|
119
123
|
},
|
|
120
124
|
],
|
|
125
|
+
messages: {
|
|
126
|
+
parserError: '{{message}}',
|
|
127
|
+
missingValue: 'Missing value(s) for the following placeholder(s): {{list}}.',
|
|
128
|
+
unusedValue: 'Value not used by the message.',
|
|
129
|
+
},
|
|
121
130
|
},
|
|
131
|
+
defaultOptions: [],
|
|
122
132
|
create(context) {
|
|
123
133
|
const callExpressionVisitor = (node) => checkNode(context, node);
|
|
134
|
+
//@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
|
|
124
135
|
if (context.parserServices.defineTemplateBodyVisitor) {
|
|
136
|
+
//@ts-expect-error
|
|
125
137
|
return context.parserServices.defineTemplateBodyVisitor({
|
|
126
138
|
CallExpression: callExpressionVisitor,
|
|
127
139
|
}, {
|
|
@@ -134,4 +146,3 @@ const rule = {
|
|
|
134
146
|
};
|
|
135
147
|
},
|
|
136
148
|
};
|
|
137
|
-
exports.default = rule;
|
|
@@ -1,3 +1,17 @@
|
|
|
1
|
-
import {
|
|
2
|
-
declare
|
|
3
|
-
|
|
1
|
+
import { RuleModule, RuleListener } from '@typescript-eslint/utils/ts-eslint';
|
|
2
|
+
declare enum LDML {
|
|
3
|
+
zero = "zero",
|
|
4
|
+
one = "one",
|
|
5
|
+
two = "two",
|
|
6
|
+
few = "few",
|
|
7
|
+
many = "many",
|
|
8
|
+
other = "other"
|
|
9
|
+
}
|
|
10
|
+
type PluralConfig = {
|
|
11
|
+
[key in LDML]?: boolean;
|
|
12
|
+
};
|
|
13
|
+
export type Options = [PluralConfig?];
|
|
14
|
+
type MessageIds = 'missingPlural' | 'forbidden';
|
|
15
|
+
export declare const name = "enforce-plural-rules";
|
|
16
|
+
export declare const rule: RuleModule<MessageIds, Options, RuleListener>;
|
|
17
|
+
export {};
|
|
@@ -1,13 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.rule = exports.name = void 0;
|
|
3
4
|
const icu_messageformat_parser_1 = require("@formatjs/icu-messageformat-parser");
|
|
4
5
|
const util_1 = require("../util");
|
|
5
|
-
class PluralRulesEnforcement extends Error {
|
|
6
|
-
constructor(message) {
|
|
7
|
-
super();
|
|
8
|
-
this.message = message;
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
6
|
var LDML;
|
|
12
7
|
(function (LDML) {
|
|
13
8
|
LDML["zero"] = "zero";
|
|
@@ -18,23 +13,25 @@ var LDML;
|
|
|
18
13
|
LDML["other"] = "other";
|
|
19
14
|
})(LDML || (LDML = {}));
|
|
20
15
|
function verifyAst(plConfig, ast) {
|
|
16
|
+
const errors = [];
|
|
21
17
|
for (const el of ast) {
|
|
22
18
|
if ((0, icu_messageformat_parser_1.isPluralElement)(el)) {
|
|
23
19
|
const rules = Object.keys(plConfig);
|
|
24
20
|
for (const rule of rules) {
|
|
25
21
|
if (plConfig[rule] && !el.options[rule]) {
|
|
26
|
-
|
|
22
|
+
errors.push({ messageId: 'missingPlural', data: { rule } });
|
|
27
23
|
}
|
|
28
24
|
if (!plConfig[rule] && el.options[rule]) {
|
|
29
|
-
|
|
25
|
+
errors.push({ messageId: 'forbidden', data: { rule } });
|
|
30
26
|
}
|
|
31
27
|
}
|
|
32
28
|
const { options } = el;
|
|
33
29
|
for (const selector of Object.keys(options)) {
|
|
34
|
-
verifyAst(plConfig, options[selector].value);
|
|
30
|
+
errors.push(...verifyAst(plConfig, options[selector].value));
|
|
35
31
|
}
|
|
36
32
|
}
|
|
37
33
|
}
|
|
34
|
+
return errors;
|
|
38
35
|
}
|
|
39
36
|
function checkNode(context, node) {
|
|
40
37
|
const settings = (0, util_1.getSettings)(context);
|
|
@@ -50,26 +47,23 @@ function checkNode(context, node) {
|
|
|
50
47
|
if (!defaultMessage || !messageNode) {
|
|
51
48
|
continue;
|
|
52
49
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
58
|
-
catch (e) {
|
|
50
|
+
const errors = verifyAst(plConfig, (0, icu_messageformat_parser_1.parse)(defaultMessage, {
|
|
51
|
+
ignoreTag: settings.ignoreTag,
|
|
52
|
+
}));
|
|
53
|
+
for (const error of errors) {
|
|
59
54
|
context.report({
|
|
60
55
|
node: messageNode,
|
|
61
|
-
|
|
56
|
+
...error,
|
|
62
57
|
});
|
|
63
58
|
}
|
|
64
59
|
}
|
|
65
60
|
}
|
|
66
|
-
|
|
61
|
+
exports.name = 'enforce-plural-rules';
|
|
62
|
+
exports.rule = {
|
|
67
63
|
meta: {
|
|
68
64
|
type: 'problem',
|
|
69
65
|
docs: {
|
|
70
66
|
description: 'Enforce plural rules to always specify certain categories like `one`/`other`',
|
|
71
|
-
category: 'Errors',
|
|
72
|
-
recommended: false,
|
|
73
67
|
url: 'https://formatjs.io/docs/tooling/linter#enforce-plural-rules',
|
|
74
68
|
},
|
|
75
69
|
fixable: 'code',
|
|
@@ -85,10 +79,17 @@ const rule = {
|
|
|
85
79
|
additionalProperties: false,
|
|
86
80
|
},
|
|
87
81
|
],
|
|
82
|
+
messages: {
|
|
83
|
+
missingPlural: `Missing plural rule "{{rule}}"`,
|
|
84
|
+
forbidden: `Plural rule "{{rule}}" is forbidden`,
|
|
85
|
+
},
|
|
88
86
|
},
|
|
87
|
+
defaultOptions: [],
|
|
89
88
|
create(context) {
|
|
90
89
|
const callExpressionVisitor = (node) => checkNode(context, node);
|
|
90
|
+
//@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
|
|
91
91
|
if (context.parserServices.defineTemplateBodyVisitor) {
|
|
92
|
+
//@ts-expect-error
|
|
92
93
|
return context.parserServices.defineTemplateBodyVisitor({
|
|
93
94
|
CallExpression: callExpressionVisitor,
|
|
94
95
|
}, {
|
|
@@ -101,4 +102,3 @@ const rule = {
|
|
|
101
102
|
};
|
|
102
103
|
},
|
|
103
104
|
};
|
|
104
|
-
exports.default = rule;
|
package/rules/no-camel-case.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { RuleModule, RuleListener } from '@typescript-eslint/utils/ts-eslint';
|
|
2
|
+
type MessageIds = 'camelcase';
|
|
3
|
+
type Options = [Element[]?];
|
|
4
|
+
export declare const name = "no-camel-case";
|
|
5
|
+
export declare const rule: RuleModule<MessageIds, Options, RuleListener>;
|
|
6
|
+
export {};
|
package/rules/no-camel-case.js
CHANGED
|
@@ -1,32 +1,30 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.rule = exports.name = void 0;
|
|
3
4
|
const icu_messageformat_parser_1 = require("@formatjs/icu-messageformat-parser");
|
|
4
5
|
const util_1 = require("../util");
|
|
6
|
+
exports.name = 'no-camel-case';
|
|
5
7
|
const CAMEL_CASE_REGEX = /[A-Z]/;
|
|
6
|
-
class CamelCase extends Error {
|
|
7
|
-
constructor() {
|
|
8
|
-
super(...arguments);
|
|
9
|
-
this.message = 'Camel case arguments are not allowed';
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
8
|
function verifyAst(ast) {
|
|
9
|
+
const errors = [];
|
|
13
10
|
for (const el of ast) {
|
|
14
11
|
if ((0, icu_messageformat_parser_1.isArgumentElement)(el)) {
|
|
15
12
|
if (CAMEL_CASE_REGEX.test(el.value)) {
|
|
16
|
-
|
|
13
|
+
errors.push({ messageId: 'camelcase', data: {} });
|
|
17
14
|
}
|
|
18
15
|
continue;
|
|
19
16
|
}
|
|
20
17
|
if ((0, icu_messageformat_parser_1.isPluralElement)(el)) {
|
|
21
18
|
if (CAMEL_CASE_REGEX.test(el.value)) {
|
|
22
|
-
|
|
19
|
+
errors.push({ messageId: 'camelcase', data: {} });
|
|
23
20
|
}
|
|
24
21
|
const { options } = el;
|
|
25
22
|
for (const selector of Object.keys(options)) {
|
|
26
|
-
verifyAst(options[selector].value);
|
|
23
|
+
errors.push(...verifyAst(options[selector].value));
|
|
27
24
|
}
|
|
28
25
|
}
|
|
29
26
|
}
|
|
27
|
+
return errors;
|
|
30
28
|
}
|
|
31
29
|
function checkNode(context, node) {
|
|
32
30
|
const settings = (0, util_1.getSettings)(context);
|
|
@@ -35,33 +33,36 @@ function checkNode(context, node) {
|
|
|
35
33
|
if (!defaultMessage || !messageNode) {
|
|
36
34
|
continue;
|
|
37
35
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
43
|
-
catch (e) {
|
|
36
|
+
const errors = verifyAst((0, icu_messageformat_parser_1.parse)(defaultMessage, {
|
|
37
|
+
ignoreTag: settings.ignoreTag,
|
|
38
|
+
}));
|
|
39
|
+
for (const error of errors) {
|
|
44
40
|
context.report({
|
|
45
41
|
node: messageNode,
|
|
46
|
-
|
|
42
|
+
...error,
|
|
47
43
|
});
|
|
48
44
|
}
|
|
49
45
|
}
|
|
50
46
|
}
|
|
51
|
-
|
|
47
|
+
exports.rule = {
|
|
52
48
|
meta: {
|
|
53
49
|
type: 'problem',
|
|
54
50
|
docs: {
|
|
55
51
|
description: 'Disallow camel case placeholders in message',
|
|
56
|
-
category: 'Errors',
|
|
57
|
-
recommended: false,
|
|
58
52
|
url: 'https://formatjs.io/docs/tooling/linter#no-camel-case',
|
|
59
53
|
},
|
|
60
54
|
fixable: 'code',
|
|
55
|
+
schema: [],
|
|
56
|
+
messages: {
|
|
57
|
+
camelcase: 'Camel case arguments are not allowed',
|
|
58
|
+
},
|
|
61
59
|
},
|
|
60
|
+
defaultOptions: [],
|
|
62
61
|
create(context) {
|
|
63
62
|
const callExpressionVisitor = (node) => checkNode(context, node);
|
|
63
|
+
//@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
|
|
64
64
|
if (context.parserServices.defineTemplateBodyVisitor) {
|
|
65
|
+
//@ts-expect-error
|
|
65
66
|
return context.parserServices.defineTemplateBodyVisitor({
|
|
66
67
|
CallExpression: callExpressionVisitor,
|
|
67
68
|
}, {
|
|
@@ -74,4 +75,3 @@ const rule = {
|
|
|
74
75
|
};
|
|
75
76
|
},
|
|
76
77
|
};
|
|
77
|
-
exports.default = rule;
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { RuleModule, RuleListener } from '@typescript-eslint/utils/ts-eslint';
|
|
2
|
+
interface Config {
|
|
3
|
+
limit: number;
|
|
4
|
+
}
|
|
5
|
+
type MessageIds = 'tooComplex' | 'parserError';
|
|
6
|
+
type Options = [Config?];
|
|
7
|
+
export declare const name = "no-complex-selectors";
|
|
8
|
+
export declare const rule: RuleModule<MessageIds, Options, RuleListener>;
|
|
9
|
+
export {};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.rule = exports.name = void 0;
|
|
3
4
|
const icu_messageformat_parser_1 = require("@formatjs/icu-messageformat-parser");
|
|
4
5
|
const util_1 = require("../util");
|
|
5
6
|
function calculateComplexity(ast) {
|
|
@@ -65,29 +66,26 @@ function checkNode(context, node) {
|
|
|
65
66
|
catch (e) {
|
|
66
67
|
context.report({
|
|
67
68
|
node: messageNode,
|
|
68
|
-
|
|
69
|
+
messageId: 'parserError',
|
|
70
|
+
data: { message: e instanceof Error ? e.message : String(e) },
|
|
69
71
|
});
|
|
70
72
|
return;
|
|
71
73
|
}
|
|
72
|
-
|
|
73
|
-
try {
|
|
74
|
-
complexity = calculateComplexity(ast);
|
|
75
|
-
}
|
|
76
|
-
catch (e) {
|
|
77
|
-
context.report({
|
|
78
|
-
node: messageNode,
|
|
79
|
-
message: e instanceof Error ? e.message : e,
|
|
80
|
-
});
|
|
81
|
-
}
|
|
74
|
+
const complexity = calculateComplexity(ast);
|
|
82
75
|
if (complexity > config.limit) {
|
|
83
76
|
context.report({
|
|
84
77
|
node: messageNode,
|
|
85
|
-
|
|
78
|
+
messageId: 'tooComplex',
|
|
79
|
+
data: {
|
|
80
|
+
complexity,
|
|
81
|
+
limit: config.limit,
|
|
82
|
+
},
|
|
86
83
|
});
|
|
87
84
|
}
|
|
88
85
|
}
|
|
89
86
|
}
|
|
90
|
-
|
|
87
|
+
exports.name = 'no-complex-selectors';
|
|
88
|
+
exports.rule = {
|
|
91
89
|
meta: {
|
|
92
90
|
type: 'problem',
|
|
93
91
|
docs: {
|
|
@@ -100,8 +98,6 @@ results in 2 sentences: "I have a dog" & "I have many dogs".
|
|
|
100
98
|
Default complexity limit is 20
|
|
101
99
|
(using Smartling as a reference: https://help.smartling.com/hc/en-us/articles/360008030994-ICU-MessageFormat)
|
|
102
100
|
`,
|
|
103
|
-
category: 'Errors',
|
|
104
|
-
recommended: false,
|
|
105
101
|
url: 'https://formatjs.io/docs/tooling/linter#no-complex-selectors',
|
|
106
102
|
},
|
|
107
103
|
schema: [
|
|
@@ -116,10 +112,17 @@ Default complexity limit is 20
|
|
|
116
112
|
},
|
|
117
113
|
],
|
|
118
114
|
fixable: 'code',
|
|
115
|
+
messages: {
|
|
116
|
+
tooComplex: `Message complexity is too high ({{complexity}} vs limit at {{limit}})`,
|
|
117
|
+
parserError: '{{meesage}}',
|
|
118
|
+
},
|
|
119
119
|
},
|
|
120
|
+
defaultOptions: [{ limit: 20 }],
|
|
120
121
|
create(context) {
|
|
121
122
|
const callExpressionVisitor = (node) => checkNode(context, node);
|
|
123
|
+
//@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
|
|
122
124
|
if (context.parserServices.defineTemplateBodyVisitor) {
|
|
125
|
+
//@ts-expect-error
|
|
123
126
|
return context.parserServices.defineTemplateBodyVisitor({
|
|
124
127
|
CallExpression: callExpressionVisitor,
|
|
125
128
|
}, {
|
|
@@ -132,4 +135,3 @@ Default complexity limit is 20
|
|
|
132
135
|
};
|
|
133
136
|
},
|
|
134
137
|
};
|
|
135
|
-
exports.default = rule;
|
package/rules/no-emoji.d.ts
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
declare const
|
|
3
|
-
|
|
1
|
+
import { RuleModule, RuleListener } from '@typescript-eslint/utils/ts-eslint';
|
|
2
|
+
export declare const name = "no-emoji";
|
|
3
|
+
type MessageIds = 'notAllowed' | 'notAllowedAboveVersion';
|
|
4
|
+
type NoEmojiConfig = {
|
|
5
|
+
versionAbove: string;
|
|
6
|
+
};
|
|
7
|
+
export type Options = [NoEmojiConfig?];
|
|
8
|
+
export declare const rule: RuleModule<MessageIds, Options, RuleListener>;
|
|
9
|
+
export {};
|
package/rules/no-emoji.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.rule = exports.name = void 0;
|
|
3
4
|
const unicode_emoji_utils_1 = require("unicode-emoji-utils");
|
|
4
5
|
const util_1 = require("../util");
|
|
6
|
+
exports.name = 'no-emoji';
|
|
5
7
|
function checkNode(context, node) {
|
|
6
8
|
const msgs = (0, util_1.extractMessages)(node, (0, util_1.getSettings)(context));
|
|
7
9
|
let allowedEmojis = [];
|
|
@@ -58,13 +60,11 @@ const versionAboveEnums = [
|
|
|
58
60
|
'14.0',
|
|
59
61
|
'15.0',
|
|
60
62
|
];
|
|
61
|
-
|
|
63
|
+
exports.rule = {
|
|
62
64
|
meta: {
|
|
63
65
|
type: 'problem',
|
|
64
66
|
docs: {
|
|
65
67
|
description: 'Disallow emojis in message',
|
|
66
|
-
category: 'Errors',
|
|
67
|
-
recommended: false,
|
|
68
68
|
url: 'https://formatjs.io/docs/tooling/linter#no-emoji',
|
|
69
69
|
},
|
|
70
70
|
fixable: 'code',
|
|
@@ -80,9 +80,12 @@ const rule = {
|
|
|
80
80
|
notAllowedAboveVersion: 'Emojis above version {{versionAbove}} are not allowed - Emoji: {{emoji}}',
|
|
81
81
|
},
|
|
82
82
|
},
|
|
83
|
+
defaultOptions: [],
|
|
83
84
|
create(context) {
|
|
84
85
|
const callExpressionVisitor = (node) => checkNode(context, node);
|
|
86
|
+
//@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
|
|
85
87
|
if (context.parserServices.defineTemplateBodyVisitor) {
|
|
88
|
+
//@ts-expect-error
|
|
86
89
|
return context.parserServices.defineTemplateBodyVisitor({
|
|
87
90
|
CallExpression: callExpressionVisitor,
|
|
88
91
|
}, {
|
|
@@ -95,4 +98,3 @@ const rule = {
|
|
|
95
98
|
};
|
|
96
99
|
},
|
|
97
100
|
};
|
|
98
|
-
exports.default = rule;
|
package/rules/no-id.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { RuleModule, RuleListener } from '@typescript-eslint/utils/ts-eslint';
|
|
2
|
+
type MessageIds = 'noId';
|
|
3
|
+
type Options = [];
|
|
4
|
+
export declare const name = "no-id";
|
|
5
|
+
export declare const rule: RuleModule<MessageIds, Options, RuleListener>;
|
|
6
|
+
export {};
|
package/rules/no-id.js
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.rule = exports.name = void 0;
|
|
3
4
|
const util_1 = require("../util");
|
|
4
5
|
function isComment(token) {
|
|
5
6
|
return !!token && (token.type === 'Block' || token.type === 'Line');
|
|
6
7
|
}
|
|
8
|
+
exports.name = 'no-id';
|
|
7
9
|
function checkNode(context, node) {
|
|
8
10
|
const msgs = (0, util_1.extractMessages)(node, (0, util_1.getSettings)(context));
|
|
9
11
|
for (const [{ idPropNode }] of msgs) {
|
|
10
12
|
if (idPropNode) {
|
|
11
13
|
context.report({
|
|
12
14
|
node: idPropNode,
|
|
13
|
-
|
|
15
|
+
messageId: 'noId',
|
|
14
16
|
fix(fixer) {
|
|
15
17
|
const src = context.getSourceCode();
|
|
16
18
|
const token = src.getTokenAfter(idPropNode);
|
|
@@ -24,20 +26,25 @@ function checkNode(context, node) {
|
|
|
24
26
|
}
|
|
25
27
|
}
|
|
26
28
|
}
|
|
27
|
-
exports.
|
|
29
|
+
exports.rule = {
|
|
28
30
|
meta: {
|
|
29
31
|
type: 'problem',
|
|
30
32
|
docs: {
|
|
31
33
|
description: 'Ban explicit ID from MessageDescriptor',
|
|
32
|
-
category: 'Errors',
|
|
33
|
-
recommended: false,
|
|
34
34
|
url: 'https://formatjs.io/docs/tooling/linter#no-id',
|
|
35
35
|
},
|
|
36
36
|
fixable: 'code',
|
|
37
|
+
schema: [],
|
|
38
|
+
messages: {
|
|
39
|
+
noId: 'Manual `id` are not allowed in message descriptor',
|
|
40
|
+
},
|
|
37
41
|
},
|
|
42
|
+
defaultOptions: [],
|
|
38
43
|
create(context) {
|
|
39
44
|
const callExpressionVisitor = (node) => checkNode(context, node);
|
|
45
|
+
//@ts-expect-error defineTemplateBodyVisitor exists in Vue parser
|
|
40
46
|
if (context.parserServices.defineTemplateBodyVisitor) {
|
|
47
|
+
//@ts-expect-error
|
|
41
48
|
return context.parserServices.defineTemplateBodyVisitor({
|
|
42
49
|
CallExpression: callExpressionVisitor,
|
|
43
50
|
}, {
|