@itcase/lint 1.1.98 → 1.1.99

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.
Files changed (34) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/README.md +50 -4
  3. package/dist/eslint/plugin.d.ts +17 -0
  4. package/dist/eslint/react/dataTestIdPlugin/example.d.ts +13 -0
  5. package/dist/eslint/react/dataTestIdPlugin/extra.d.ts +8 -0
  6. package/dist/eslint/react/dataTestIdPlugin/interface.d.ts +12 -0
  7. package/dist/eslint/react/dataTestIdPlugin/plugin.d.ts +46 -0
  8. package/dist/eslint/restrictWords/config.d.ts +11 -0
  9. package/dist/eslint/restrictWords/index.d.ts +6 -0
  10. package/dist/eslint/restrictWords.js +79 -0
  11. package/dist/eslint/storybook/index.d.ts +19 -1
  12. package/dist/eslint/storybook/metaParametersDesign/constants.d.ts +12 -0
  13. package/dist/eslint/storybook/metaParametersDesign/extra.d.ts +8 -0
  14. package/dist/eslint/storybook/metaParametersDesign/interface.d.ts +6 -0
  15. package/dist/eslint/storybook/metaParametersDesign/plugin.d.ts +12 -0
  16. package/dist/eslint/storybook/metaParametersDesign/rule.d.ts +5 -0
  17. package/dist/eslint/storybook/metaParametersDesign/ruleVisitors.d.ts +3 -0
  18. package/dist/eslint/storybook/metaParametersDesign/utils.d.ts +6 -0
  19. package/dist/eslint/storybook.js +3 -10
  20. package/dist/eslint/utils/createPlugin.d.ts +14 -0
  21. package/dist/eslint/utils/createRuleCreator.d.ts +5 -0
  22. package/dist/eslint/utils/types.d.ts +4 -0
  23. package/dist/eslint.js +10 -278
  24. package/dist/index_CChA61aj.js +434 -0
  25. package/package.json +4 -3
  26. package/dist/eslint/customPlugins/dataTestIdPlugin/extra.d.ts +0 -18
  27. package/dist/eslint/customPlugins/dataTestIdPlugin/plugin.d.ts +0 -40
  28. /package/dist/eslint/{customPlugins → react}/dataTestIdPlugin/constants.d.ts +0 -0
  29. /package/dist/eslint/{customPlugins → react}/dataTestIdPlugin/rule.d.ts +0 -0
  30. /package/dist/eslint/{customPlugins → react}/dataTestIdPlugin/rule.test.d.ts +0 -0
  31. /package/dist/eslint/{customPlugins → react}/dataTestIdPlugin/ruleVisitors.d.ts +0 -0
  32. /package/dist/eslint/{customPlugins → react}/dataTestIdPlugin/utils.d.ts +0 -0
  33. /package/dist/eslint/{customPlugins/dataTestIdPlugin/example.d.ts → storybook/metaParametersDesign/rule.test.d.ts} +0 -0
  34. /package/dist/eslint/{utils.d.ts → utils/wrapArray.d.ts} +0 -0
package/dist/eslint.js CHANGED
@@ -11,288 +11,17 @@ import eslintReact from 'eslint-plugin-react';
11
11
  import eslintReactHooks from 'eslint-plugin-react-hooks';
12
12
  import globals from 'globals';
13
13
  import eslintTypeScript from 'typescript-eslint';
14
- import parser from '@typescript-eslint/parser';
15
- import { ESLintUtils, AST_NODE_TYPES } from '@typescript-eslint/utils';
16
14
  import { s as sortUnionTypes, a as sortObjectTypes, b as sortObjects, c as sortExports, d as sortNamedExports, e as sortMaps, f as sortJSXProps, g as sortIntersectionTypes, h as sortInterfaces, i as sortEnums } from './sortUnionTypes_G8w5Oj3O.js';
15
+ import parser from '@typescript-eslint/parser';
16
+ import { i as itcaseLintPlugin, p as pluginName, r as ruleName, s as storybookConfig } from './index_CChA61aj.js';
17
+ import { noRestrictedSyntaxRestrictWords } from './eslint/restrictWords.js';
17
18
  export { default as eslintFigma } from './eslint/figma.js';
19
+ import 'eslint-plugin-storybook';
20
+ import '@typescript-eslint/utils';
18
21
  import '@figma/eslint-plugin-figma-plugins';
19
22
 
20
- const createRule = ESLintUtils.RuleCreator(() => {
21
- return ``;
22
- });
23
- const ruleName = 'data-test-id';
24
- const pluginName = 'data-test-id-plugin';
25
- const defaultOptions = [
26
- {
27
- appendElementNamesToCheck: null,
28
- overrideElementNamesToCheck: null,
29
- overrideElementNamesToIgnore: null,
30
- },
31
- ];
32
-
33
- const MESSAGE_IDS = {
34
- missingAttribute: 'missingAttribute',
35
- missingAttributeValue: 'missingAttributeValue',
36
- };
37
- const MESSAGES = {
38
- [MESSAGE_IDS.missingAttribute]: 'JSX element is missing the required "{{propName}}" attribute.',
39
- [MESSAGE_IDS.missingAttributeValue]: 'JSX element has a "{{propName}}" attribute with a missing value.',
40
- };
41
- const ASSERT_DEFAULT_MESSAGE = 'Assert violation';
42
- /**
43
- * Property name to check for in JSX elements.
44
- */
45
- const PROP_TO_CHECK_BY_COMPONENT_TYPE = {
46
- CUSTOM: {
47
- name: 'dataTestId'},
48
- HTML: {
49
- name: 'data-test-id'},
50
- };
51
- /**
52
- * Custom element names to which the rule should apply.
53
- * If the array is empty, the rule applies to all JSX elements.
54
- */
55
- const ELEMENT_NAMES_TO_CHECK = [
56
- 'Group',
57
- 'Modal',
58
- 'Drawer',
59
- 'ModalSheetBottom',
60
- 'Grid',
61
- 'Flex',
62
- ];
63
- /**
64
- * Custom element names to ignore by the rule.
65
- */
66
- const ELEMENT_NAMES_TO_IGNORE = [
67
- // Element to ignore for testing purposes
68
- 'IgnoredElement',
69
- // Html element from Next.js
70
- 'Html',
71
- ];
72
-
73
- /** Throw an error if the condition is falsy */
74
- function assert(condition) {
75
- if (!condition) {
76
- throw new Error(ASSERT_DEFAULT_MESSAGE);
77
- }
78
- }
79
- /** Extract name from a string or Identifier node */
80
- function extractNameFromPossibleIdentifier(nodeOrName) {
81
- if (typeof nodeOrName === 'string') {
82
- return nodeOrName;
83
- }
84
- return nodeOrName.name;
85
- }
86
- /** Get name items of functions and variables that wraps the given node */
87
- const getFunctionOrVariableAncestorNameItems = (context, node) => {
88
- const ancestorNodes = context.sourceCode.getAncestors(node);
89
- const functionOrVariableNodes = ancestorNodes.filter((ancestor) => {
90
- return (ancestor.type === AST_NODE_TYPES.FunctionExpression ||
91
- ancestor.type === AST_NODE_TYPES.FunctionDeclaration ||
92
- ancestor.type === AST_NODE_TYPES.VariableDeclaration);
93
- });
94
- const nullableNameItems = functionOrVariableNodes.map((node) => {
95
- if (node.type === AST_NODE_TYPES.FunctionDeclaration ||
96
- node.type === AST_NODE_TYPES.FunctionExpression) {
97
- if (node.id !== null) {
98
- return {
99
- name: node.id.name,
100
- kind: 'function',
101
- };
102
- }
103
- }
104
- if (node.type === AST_NODE_TYPES.VariableDeclaration) {
105
- const firstDeclaration = node.declarations[0];
106
- if (firstDeclaration.id.type === AST_NODE_TYPES.Identifier) {
107
- return {
108
- name: firstDeclaration.id.name,
109
- kind: 'variable',
110
- };
111
- }
112
- }
113
- return null;
114
- });
115
- const nameItems = nullableNameItems.filter((item) => item !== null);
116
- return nameItems;
117
- };
118
-
119
- const handleReturnStatement = (context, returnStatementNode, options) => {
120
- const { elementNamesToCheck, elementNamesToIgnore } = options;
121
- // We only care about return statements that return JSX elements
122
- assert(returnStatementNode.argument);
123
- assert(returnStatementNode.argument.type === AST_NODE_TYPES.JSXElement);
124
- const openingElement = returnStatementNode.argument.openingElement;
125
- // Something is wrong if it's not a JSXIdentifier
126
- assert(openingElement.name.type === AST_NODE_TYPES.JSXIdentifier);
127
- const elementName = openingElement.name.name;
128
- const isIgnoredElement = elementNamesToIgnore.includes(elementName);
129
- // Ignore elements that are in the ignore list
130
- assert(!isIgnoredElement);
131
- const isLowerCasedName = elementName[0] === elementName[0].toLowerCase();
132
- const isElementToCheck = elementNamesToCheck.includes(elementName);
133
- const isAllElementsToCheck = elementNamesToCheck.length === 0;
134
- // We only care about lowercase elements or specific Elements
135
- assert(isLowerCasedName || isElementToCheck || isAllElementsToCheck);
136
- // Determine which prop name we are looking for
137
- const propNameWeLookingFor = isLowerCasedName
138
- ? PROP_TO_CHECK_BY_COMPONENT_TYPE.HTML
139
- : PROP_TO_CHECK_BY_COMPONENT_TYPE.CUSTOM;
140
- // Try to find the prop we are looking for
141
- const propNodeWeLookingFor = openingElement.attributes.find((attr) => {
142
- // Ignore spread attributes
143
- if (attr.type === AST_NODE_TYPES.JSXAttribute) {
144
- const attributeName = extractNameFromPossibleIdentifier(attr.name.name);
145
- return propNameWeLookingFor.name === attributeName;
146
- }
147
- });
148
- const ancestorNameItems = getFunctionOrVariableAncestorNameItems(context, returnStatementNode);
149
- // Get the nearest ancestor name as the component name
150
- const parentComponentNameItem = ancestorNameItems.at(-1);
151
- // Something is wrong if there is no component name
152
- assert(parentComponentNameItem);
153
- if (!propNodeWeLookingFor) {
154
- // If we reach here - the prop is missing - report it
155
- context.report({
156
- messageId: MESSAGE_IDS.missingAttribute,
157
- fix: (fixer) => {
158
- const propName = propNameWeLookingFor.name;
159
- const parentName = parentComponentNameItem.name;
160
- // Insert the missing prop
161
- if (parentComponentNameItem.kind === 'function') {
162
- return fixer.insertTextAfter(openingElement.name, ' ' + `${propName}={${parentName}.name}`);
163
- }
164
- if (parentComponentNameItem.kind === 'variable') {
165
- return fixer.insertTextAfter(openingElement.name, ' ' + `${propName}="${parentName}"`);
166
- }
167
- assert(false);
168
- },
169
- data: {
170
- propName: propNameWeLookingFor.name,
171
- },
172
- node: openingElement,
173
- });
174
- assert(false);
175
- }
176
- // At this moment we only care about prop without value
177
- assert(!propNodeWeLookingFor.value);
178
- // If we reach here - the prop exists but has no value - report it
179
- context.report({
180
- messageId: MESSAGE_IDS.missingAttributeValue,
181
- fix: (fixer) => {
182
- const propName = propNameWeLookingFor.name;
183
- const parentName = parentComponentNameItem.name;
184
- // Replace incomplete prop with complete one
185
- if (parentComponentNameItem.kind === 'function') {
186
- return fixer.replaceText(propNodeWeLookingFor, `${propName}={${parentName}.name}`);
187
- }
188
- if (parentComponentNameItem.kind === 'variable') {
189
- return fixer.replaceText(propNodeWeLookingFor, `${propName}="${parentName}"`);
190
- }
191
- assert(false);
192
- },
193
- data: {
194
- propName: propNameWeLookingFor.name,
195
- },
196
- node: openingElement,
197
- });
198
- };
199
- const ruleVisitors = (context, optionsWithDefault) => {
200
- const [options] = optionsWithDefault;
201
- const { appendElementNamesToCheck, overrideElementNamesToCheck, overrideElementNamesToIgnore, } = options;
202
- let elementNamesToCheck = ELEMENT_NAMES_TO_CHECK.slice();
203
- let elementNamesToIgnore = ELEMENT_NAMES_TO_IGNORE.slice();
204
- // Override default element names
205
- if (overrideElementNamesToCheck) {
206
- elementNamesToCheck = overrideElementNamesToCheck.slice();
207
- }
208
- // Override default element names
209
- if (overrideElementNamesToIgnore) {
210
- elementNamesToIgnore = overrideElementNamesToIgnore.slice();
211
- }
212
- // Append additional element names
213
- if (appendElementNamesToCheck) {
214
- elementNamesToCheck.push(...appendElementNamesToCheck);
215
- }
216
- return {
217
- // Iterate over all return statements
218
- [AST_NODE_TYPES.ReturnStatement]: (node) => {
219
- try {
220
- handleReturnStatement(context, node, {
221
- elementNamesToCheck,
222
- elementNamesToIgnore,
223
- });
224
- }
225
- catch (error) {
226
- // Only log errors that are not from assert checks.
227
- // Assert errors are used for early exit.
228
- if (error instanceof Error &&
229
- error.message === ASSERT_DEFAULT_MESSAGE) {
230
- // Ignore assert errors
231
- return;
232
- }
233
- // Log other errors
234
- console.log(`${pluginName} visitor error:`, error);
235
- }
236
- },
237
- };
238
- };
239
-
240
- const ruleMeta = {
241
- type: 'suggestion',
242
- messages: MESSAGES,
243
- docs: {
244
- description: '',
245
- },
246
- fixable: 'code',
247
- schema: [
248
- {
249
- type: 'object',
250
- additionalProperties: false,
251
- properties: {
252
- appendElementNamesToCheck: {
253
- anyOf: [
254
- { type: 'array', items: { type: 'string' } },
255
- { type: 'null' },
256
- ],
257
- default: defaultOptions[0].appendElementNamesToCheck,
258
- },
259
- overrideElementNamesToCheck: {
260
- anyOf: [
261
- { type: 'array', items: { type: 'string' } },
262
- { type: 'null' },
263
- ],
264
- default: defaultOptions[0].overrideElementNamesToCheck,
265
- },
266
- overrideElementNamesToIgnore: {
267
- anyOf: [
268
- { type: 'array', items: { type: 'string' } },
269
- { type: 'null' },
270
- ],
271
- default: defaultOptions[0].overrideElementNamesToIgnore,
272
- },
273
- },
274
- },
275
- ],
276
- };
277
- const rule = createRule({
278
- name: ruleName,
279
- create: ruleVisitors,
280
- defaultOptions: defaultOptions,
281
- meta: ruleMeta,
282
- });
283
-
284
- const plugin = {
285
- meta: {
286
- name: pluginName,
287
- version: '1.0.0',
288
- },
289
- processors: {},
290
- rules: {
291
- [ruleName]: rule,
292
- },
293
- };
294
23
  const pluginWithConfigs = {
295
- ...plugin,
24
+ ...itcaseLintPlugin,
296
25
  configs: {
297
26
  recommended: {
298
27
  languageOptions: {
@@ -300,7 +29,7 @@ const pluginWithConfigs = {
300
29
  parser: parser,
301
30
  },
302
31
  plugins: {
303
- [pluginName]: plugin,
32
+ [pluginName]: itcaseLintPlugin,
304
33
  },
305
34
  rules: {
306
35
  // By default this rule is disabled, enable only for required paths
@@ -381,6 +110,8 @@ const eslintConfig = [
381
110
  // react-hooks
382
111
  'react-hooks/exhaustive-deps': 'warn',
383
112
  'react-hooks/rules-of-hooks': 'error',
113
+ // Запрет определённых слов в качестве идентификаторов (список в restrictWords/config.ts)
114
+ 'no-restricted-syntax': noRestrictedSyntaxRestrictWords,
384
115
  // disables the requirement to format ternary operators in multiline form
385
116
  'multiline-ternary': 'off',
386
117
  // shorthand for methods and properties of objects
@@ -413,6 +144,7 @@ const eslintConfig = [
413
144
  'import/no-default-export': 'off',
414
145
  },
415
146
  },
147
+ ...storybookConfig,
416
148
  ];
417
149
 
418
150
  export { eslintConfig as default };