eslint-plugin-absolute 0.2.0 → 0.2.1
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/.absolutejs/eslint.cache.json +49 -0
- package/.absolutejs/prettier.cache.json +49 -0
- package/.absolutejs/tsconfig.tsbuildinfo +1 -0
- package/.claude/settings.local.json +8 -3
- package/dist/index.js +1321 -1419
- package/eslint.config.mjs +107 -0
- package/package.json +10 -8
- package/src/index.ts +15 -15
- package/src/rules/explicit-object-types.ts +42 -40
- package/src/rules/inline-style-limit.ts +56 -54
- package/src/rules/localize-react-props.ts +261 -266
- package/src/rules/max-depth-extended.ts +55 -66
- package/src/rules/max-jsx-nesting.ts +28 -36
- package/src/rules/min-var-length.ts +238 -208
- package/src/rules/no-button-navigation.ts +114 -156
- package/src/rules/no-explicit-return-types.ts +32 -36
- package/src/rules/no-inline-prop-types.ts +30 -30
- package/src/rules/no-multi-style-objects.ts +35 -42
- package/src/rules/no-nested-jsx-return.ts +100 -105
- package/src/rules/no-or-none-component.ts +17 -19
- package/src/rules/no-transition-cssproperties.ts +76 -70
- package/src/rules/no-unnecessary-div.ts +26 -34
- package/src/rules/no-unnecessary-key.ts +41 -75
- package/src/rules/no-useless-function.ts +18 -20
- package/src/rules/seperate-style-files.ts +19 -21
- package/src/rules/sort-exports.ts +252 -248
- package/src/rules/sort-keys-fixable.ts +354 -328
- package/src/rules/spring-naming-convention.ts +104 -89
- package/tsconfig.json +2 -0
|
@@ -8,45 +8,69 @@ type MinVarLengthOption = {
|
|
|
8
8
|
type Options = [MinVarLengthOption?];
|
|
9
9
|
type MessageIds = "variableNameTooShort";
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Recursively extract identifier names from a pattern (for destructuring)
|
|
13
|
+
*/
|
|
14
|
+
const extractIdentifiersFromPattern = (
|
|
15
|
+
pattern: TSESTree.Node | null,
|
|
16
|
+
identifiers: string[] = []
|
|
17
|
+
) => {
|
|
18
|
+
if (!pattern) return identifiers;
|
|
19
|
+
switch (pattern.type) {
|
|
20
|
+
case "Identifier":
|
|
21
|
+
identifiers.push(pattern.name);
|
|
22
|
+
break;
|
|
23
|
+
case "ObjectPattern":
|
|
24
|
+
pattern.properties.forEach((prop) => {
|
|
25
|
+
if (prop.type === "Property") {
|
|
26
|
+
extractIdentifiersFromPattern(prop.value, identifiers);
|
|
27
|
+
} else if (prop.type === "RestElement") {
|
|
28
|
+
extractIdentifiersFromPattern(prop.argument, identifiers);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
break;
|
|
32
|
+
case "ArrayPattern":
|
|
33
|
+
pattern.elements
|
|
34
|
+
.filter(
|
|
35
|
+
(element): element is TSESTree.DestructuringPattern =>
|
|
36
|
+
element !== null
|
|
37
|
+
)
|
|
38
|
+
.forEach((element) => {
|
|
39
|
+
extractIdentifiersFromPattern(element, identifiers);
|
|
40
|
+
});
|
|
41
|
+
break;
|
|
42
|
+
case "AssignmentPattern":
|
|
43
|
+
extractIdentifiersFromPattern(pattern.left, identifiers);
|
|
44
|
+
break;
|
|
45
|
+
default:
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
return identifiers;
|
|
49
|
+
};
|
|
44
50
|
|
|
45
|
-
|
|
51
|
+
const getDeclaratorNames = (declarations: TSESTree.VariableDeclarator[]) =>
|
|
52
|
+
declarations
|
|
53
|
+
.filter(
|
|
54
|
+
(
|
|
55
|
+
decl
|
|
56
|
+
): decl is TSESTree.VariableDeclarator & {
|
|
57
|
+
id: TSESTree.Identifier;
|
|
58
|
+
} => decl.id.type === "Identifier"
|
|
59
|
+
)
|
|
60
|
+
.map((decl) => decl.id.name);
|
|
46
61
|
|
|
62
|
+
const collectParamNames = (params: TSESTree.Parameter[]) => {
|
|
63
|
+
const names: string[] = [];
|
|
64
|
+
params.forEach((param) => {
|
|
65
|
+
extractIdentifiersFromPattern(param, names);
|
|
66
|
+
});
|
|
67
|
+
return names;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export const minVarLength: TSESLint.RuleModule<MessageIds, Options> = {
|
|
47
71
|
create(context) {
|
|
48
|
-
const sourceCode = context
|
|
49
|
-
const options = context.options
|
|
72
|
+
const { sourceCode } = context;
|
|
73
|
+
const [options] = context.options;
|
|
50
74
|
const configuredMinLength =
|
|
51
75
|
options && typeof options.minLength === "number"
|
|
52
76
|
? options.minLength
|
|
@@ -60,7 +84,7 @@ export const minVarLength: TSESLint.RuleModule<MessageIds, Options> = {
|
|
|
60
84
|
const allowedVars = configuredAllowedVars;
|
|
61
85
|
|
|
62
86
|
// Helper: walk up the node.parent chain to get ancestors.
|
|
63
|
-
|
|
87
|
+
const getAncestors = (node: TSESTree.Node) => {
|
|
64
88
|
const ancestors: TSESTree.Node[] = [];
|
|
65
89
|
let current: TSESTree.Node | null | undefined = node.parent;
|
|
66
90
|
while (current) {
|
|
@@ -68,11 +92,11 @@ export const minVarLength: TSESLint.RuleModule<MessageIds, Options> = {
|
|
|
68
92
|
current = current.parent;
|
|
69
93
|
}
|
|
70
94
|
return ancestors;
|
|
71
|
-
}
|
|
95
|
+
};
|
|
72
96
|
|
|
73
97
|
// Helper: retrieve the scope for a given node using the scopeManager.
|
|
74
|
-
|
|
75
|
-
const scopeManager = sourceCode
|
|
98
|
+
const getScope = (node: TSESTree.Node) => {
|
|
99
|
+
const { scopeManager } = sourceCode;
|
|
76
100
|
if (!scopeManager) {
|
|
77
101
|
return null;
|
|
78
102
|
}
|
|
@@ -81,220 +105,193 @@ export const minVarLength: TSESLint.RuleModule<MessageIds, Options> = {
|
|
|
81
105
|
return acquired;
|
|
82
106
|
}
|
|
83
107
|
return scopeManager.globalScope ?? null;
|
|
84
|
-
}
|
|
108
|
+
};
|
|
85
109
|
|
|
86
110
|
// Fallback: get declared variable names in the nearest BlockStatement.
|
|
87
|
-
|
|
111
|
+
const getVariablesInNearestBlock = (node: TSESTree.Node) => {
|
|
88
112
|
let current: TSESTree.Node | null | undefined = node.parent;
|
|
89
113
|
while (current && current.type !== "BlockStatement") {
|
|
90
114
|
current = current.parent;
|
|
91
115
|
}
|
|
92
|
-
const names: string[] = [];
|
|
93
116
|
if (
|
|
94
|
-
current
|
|
95
|
-
current.type
|
|
96
|
-
Array.isArray(current.body)
|
|
117
|
+
!current ||
|
|
118
|
+
current.type !== "BlockStatement" ||
|
|
119
|
+
!Array.isArray(current.body)
|
|
97
120
|
) {
|
|
98
|
-
|
|
99
|
-
if (stmt.type === "VariableDeclaration") {
|
|
100
|
-
for (const decl of stmt.declarations) {
|
|
101
|
-
if (decl.id && decl.id.type === "Identifier") {
|
|
102
|
-
names.push(decl.id.name);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
}
|
|
121
|
+
return [];
|
|
107
122
|
}
|
|
108
|
-
return names;
|
|
109
|
-
}
|
|
110
123
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
identifiers: string[] = []
|
|
120
|
-
): string[] {
|
|
121
|
-
if (!pattern) return identifiers;
|
|
122
|
-
switch (pattern.type) {
|
|
123
|
-
case "Identifier":
|
|
124
|
-
identifiers.push(pattern.name);
|
|
125
|
-
break;
|
|
126
|
-
case "ObjectPattern":
|
|
127
|
-
for (const prop of pattern.properties) {
|
|
128
|
-
if (prop.type === "Property") {
|
|
129
|
-
extractIdentifiersFromPattern(
|
|
130
|
-
prop.value,
|
|
131
|
-
identifiers
|
|
132
|
-
);
|
|
133
|
-
} else if (prop.type === "RestElement") {
|
|
134
|
-
extractIdentifiersFromPattern(
|
|
135
|
-
prop.argument,
|
|
136
|
-
identifiers
|
|
137
|
-
);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
break;
|
|
141
|
-
case "ArrayPattern":
|
|
142
|
-
for (const element of pattern.elements) {
|
|
143
|
-
if (element) {
|
|
144
|
-
extractIdentifiersFromPattern(element, identifiers);
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
break;
|
|
148
|
-
case "AssignmentPattern":
|
|
149
|
-
extractIdentifiersFromPattern(pattern.left, identifiers);
|
|
150
|
-
break;
|
|
151
|
-
default:
|
|
152
|
-
break;
|
|
153
|
-
}
|
|
154
|
-
return identifiers;
|
|
155
|
-
}
|
|
124
|
+
const varDeclarations = current.body.filter(
|
|
125
|
+
(stmt): stmt is TSESTree.VariableDeclaration =>
|
|
126
|
+
stmt.type === "VariableDeclaration"
|
|
127
|
+
);
|
|
128
|
+
return varDeclarations.flatMap((stmt) =>
|
|
129
|
+
getDeclaratorNames(stmt.declarations)
|
|
130
|
+
);
|
|
131
|
+
};
|
|
156
132
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
* @param {ASTNode} node The current identifier node.
|
|
164
|
-
* @returns {boolean} True if an outer variable is found.
|
|
165
|
-
*/
|
|
166
|
-
function hasOuterCorrespondingIdentifier(
|
|
133
|
+
const isLongerMatchInScope = (shortName: string, varName: string) =>
|
|
134
|
+
varName.length >= minLength &&
|
|
135
|
+
varName.length > shortName.length &&
|
|
136
|
+
varName.startsWith(shortName);
|
|
137
|
+
|
|
138
|
+
const checkScopeVariables = (
|
|
167
139
|
shortName: string,
|
|
168
140
|
node: TSESTree.Identifier
|
|
169
|
-
) {
|
|
170
|
-
// First, try using the scope manager.
|
|
141
|
+
) => {
|
|
171
142
|
const startingScope = getScope(node);
|
|
172
143
|
let outer =
|
|
173
144
|
startingScope && startingScope.upper
|
|
174
145
|
? startingScope.upper
|
|
175
146
|
: null;
|
|
176
147
|
while (outer) {
|
|
177
|
-
for (const variable of outer.variables) {
|
|
178
|
-
if (
|
|
179
|
-
variable.name.length >= minLength &&
|
|
180
|
-
variable.name.length > shortName.length &&
|
|
181
|
-
variable.name.startsWith(shortName)
|
|
182
|
-
) {
|
|
183
|
-
return true;
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
outer = outer.upper;
|
|
187
|
-
}
|
|
188
|
-
// Fallback: scan the nearest BlockStatement.
|
|
189
|
-
const blockVars = getVariablesInNearestBlock(node);
|
|
190
|
-
for (const name of blockVars) {
|
|
191
148
|
if (
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
149
|
+
outer.variables.some((variable) =>
|
|
150
|
+
isLongerMatchInScope(shortName, variable.name)
|
|
151
|
+
)
|
|
195
152
|
) {
|
|
196
153
|
return true;
|
|
197
154
|
}
|
|
155
|
+
outer = outer.upper;
|
|
198
156
|
}
|
|
199
|
-
|
|
157
|
+
return false;
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
const checkBlockVariables = (
|
|
161
|
+
shortName: string,
|
|
162
|
+
node: TSESTree.Identifier
|
|
163
|
+
) => {
|
|
164
|
+
const blockVars = getVariablesInNearestBlock(node);
|
|
165
|
+
return blockVars.some((varName) =>
|
|
166
|
+
isLongerMatchInScope(shortName, varName)
|
|
167
|
+
);
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
const checkAncestorDeclarators = (
|
|
171
|
+
shortName: string,
|
|
172
|
+
node: TSESTree.Identifier
|
|
173
|
+
) => {
|
|
200
174
|
const ancestors = getAncestors(node);
|
|
201
|
-
|
|
202
|
-
|
|
175
|
+
return ancestors.some(
|
|
176
|
+
(anc) =>
|
|
203
177
|
anc.type === "VariableDeclarator" &&
|
|
204
178
|
anc.id &&
|
|
205
|
-
anc.id.type === "Identifier"
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
179
|
+
anc.id.type === "Identifier" &&
|
|
180
|
+
isLongerMatchInScope(shortName, anc.id.name)
|
|
181
|
+
);
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
const checkFunctionAncestor = (
|
|
185
|
+
shortName: string,
|
|
186
|
+
anc:
|
|
187
|
+
| TSESTree.FunctionDeclaration
|
|
188
|
+
| TSESTree.FunctionExpression
|
|
189
|
+
| TSESTree.ArrowFunctionExpression
|
|
190
|
+
) => {
|
|
191
|
+
const names = collectParamNames(anc.params);
|
|
192
|
+
return names.some((paramName) =>
|
|
193
|
+
isLongerMatchInScope(shortName, paramName)
|
|
194
|
+
);
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
const checkCatchAncestor = (
|
|
198
|
+
shortName: string,
|
|
199
|
+
anc: TSESTree.CatchClause
|
|
200
|
+
) => {
|
|
201
|
+
if (!anc.param) {
|
|
202
|
+
return false;
|
|
203
|
+
}
|
|
204
|
+
const names = extractIdentifiersFromPattern(anc.param, []);
|
|
205
|
+
return names.some((paramName) =>
|
|
206
|
+
isLongerMatchInScope(shortName, paramName)
|
|
207
|
+
);
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
const checkAncestorParams = (
|
|
211
|
+
shortName: string,
|
|
212
|
+
node: TSESTree.Identifier
|
|
213
|
+
) => {
|
|
214
|
+
const ancestors = getAncestors(node);
|
|
215
|
+
return ancestors.some((anc) => {
|
|
216
216
|
if (
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
Array.isArray(anc.params)
|
|
217
|
+
anc.type === "FunctionDeclaration" ||
|
|
218
|
+
anc.type === "FunctionExpression" ||
|
|
219
|
+
anc.type === "ArrowFunctionExpression"
|
|
221
220
|
) {
|
|
222
|
-
|
|
223
|
-
const names = extractIdentifiersFromPattern(param, []);
|
|
224
|
-
for (const n of names) {
|
|
225
|
-
if (
|
|
226
|
-
n.length >= minLength &&
|
|
227
|
-
n.length > shortName.length &&
|
|
228
|
-
n.startsWith(shortName)
|
|
229
|
-
) {
|
|
230
|
-
return true;
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
}
|
|
221
|
+
return checkFunctionAncestor(shortName, anc);
|
|
234
222
|
}
|
|
235
|
-
if (anc.type === "CatchClause"
|
|
236
|
-
|
|
237
|
-
for (const n of names) {
|
|
238
|
-
if (
|
|
239
|
-
n.length >= minLength &&
|
|
240
|
-
n.length > shortName.length &&
|
|
241
|
-
n.startsWith(shortName)
|
|
242
|
-
) {
|
|
243
|
-
return true;
|
|
244
|
-
}
|
|
245
|
-
}
|
|
223
|
+
if (anc.type === "CatchClause") {
|
|
224
|
+
return checkCatchAncestor(shortName, anc);
|
|
246
225
|
}
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
}
|
|
226
|
+
return false;
|
|
227
|
+
});
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Checks if there is an outer variable whose name is longer than the current short name
|
|
232
|
+
* and starts with the same characters.
|
|
233
|
+
*/
|
|
234
|
+
const hasOuterCorrespondingIdentifier = (
|
|
235
|
+
shortName: string,
|
|
236
|
+
node: TSESTree.Identifier
|
|
237
|
+
) =>
|
|
238
|
+
checkScopeVariables(shortName, node) ||
|
|
239
|
+
checkBlockVariables(shortName, node) ||
|
|
240
|
+
checkAncestorDeclarators(shortName, node) ||
|
|
241
|
+
checkAncestorParams(shortName, node);
|
|
250
242
|
|
|
251
243
|
/**
|
|
252
244
|
* Checks an Identifier node. If its name is shorter than minLength (and not in the allowed list)
|
|
253
245
|
* and no outer variable with a longer name starting with the short name is found, it reports an error.
|
|
254
|
-
* @param {ASTNode} node The Identifier node.
|
|
255
246
|
*/
|
|
256
|
-
|
|
257
|
-
const name = node
|
|
258
|
-
if (name.length
|
|
259
|
-
|
|
260
|
-
if (allowedVars.includes(name)) {
|
|
261
|
-
return;
|
|
262
|
-
}
|
|
263
|
-
if (!hasOuterCorrespondingIdentifier(name, node)) {
|
|
264
|
-
context.report({
|
|
265
|
-
node,
|
|
266
|
-
messageId: "variableNameTooShort",
|
|
267
|
-
data: { name, minLength }
|
|
268
|
-
});
|
|
269
|
-
}
|
|
247
|
+
const checkIdentifier = (node: TSESTree.Identifier) => {
|
|
248
|
+
const { name } = node;
|
|
249
|
+
if (name.length >= minLength) {
|
|
250
|
+
return;
|
|
270
251
|
}
|
|
271
|
-
|
|
252
|
+
|
|
253
|
+
// If the name is in the allowed list, skip.
|
|
254
|
+
if (allowedVars.includes(name)) {
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
if (!hasOuterCorrespondingIdentifier(name, node)) {
|
|
258
|
+
context.report({
|
|
259
|
+
data: { minLength, name },
|
|
260
|
+
messageId: "variableNameTooShort",
|
|
261
|
+
node
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
};
|
|
272
265
|
|
|
273
266
|
/**
|
|
274
267
|
* Recursively checks a pattern node for identifiers.
|
|
275
|
-
* @param {ASTNode} pattern The pattern node.
|
|
276
268
|
*/
|
|
277
|
-
|
|
269
|
+
const checkPattern = (pattern: TSESTree.Node | null) => {
|
|
278
270
|
if (!pattern) return;
|
|
279
271
|
switch (pattern.type) {
|
|
280
272
|
case "Identifier":
|
|
281
273
|
checkIdentifier(pattern);
|
|
282
274
|
break;
|
|
283
275
|
case "ObjectPattern":
|
|
284
|
-
|
|
276
|
+
pattern.properties.forEach((prop) => {
|
|
285
277
|
if (prop.type === "Property") {
|
|
286
278
|
checkPattern(prop.value);
|
|
287
279
|
} else if (prop.type === "RestElement") {
|
|
288
280
|
checkPattern(prop.argument);
|
|
289
281
|
}
|
|
290
|
-
}
|
|
282
|
+
});
|
|
291
283
|
break;
|
|
292
284
|
case "ArrayPattern":
|
|
293
|
-
|
|
294
|
-
|
|
285
|
+
pattern.elements
|
|
286
|
+
.filter(
|
|
287
|
+
(
|
|
288
|
+
element
|
|
289
|
+
): element is TSESTree.DestructuringPattern =>
|
|
290
|
+
element !== null
|
|
291
|
+
)
|
|
292
|
+
.forEach((element) => {
|
|
295
293
|
checkPattern(element);
|
|
296
|
-
}
|
|
297
|
-
}
|
|
294
|
+
});
|
|
298
295
|
break;
|
|
299
296
|
case "AssignmentPattern":
|
|
300
297
|
checkPattern(pattern.left);
|
|
@@ -302,12 +299,12 @@ export const minVarLength: TSESLint.RuleModule<MessageIds, Options> = {
|
|
|
302
299
|
default:
|
|
303
300
|
break;
|
|
304
301
|
}
|
|
305
|
-
}
|
|
302
|
+
};
|
|
306
303
|
|
|
307
304
|
return {
|
|
308
|
-
|
|
309
|
-
if (node.
|
|
310
|
-
checkPattern(node.
|
|
305
|
+
CatchClause(node: TSESTree.CatchClause) {
|
|
306
|
+
if (node.param) {
|
|
307
|
+
checkPattern(node.param);
|
|
311
308
|
}
|
|
312
309
|
},
|
|
313
310
|
"FunctionDeclaration, FunctionExpression, ArrowFunctionExpression"(
|
|
@@ -316,15 +313,48 @@ export const minVarLength: TSESLint.RuleModule<MessageIds, Options> = {
|
|
|
316
313
|
| TSESTree.FunctionExpression
|
|
317
314
|
| TSESTree.ArrowFunctionExpression
|
|
318
315
|
) {
|
|
319
|
-
|
|
316
|
+
node.params.forEach((param) => {
|
|
320
317
|
checkPattern(param);
|
|
321
|
-
}
|
|
318
|
+
});
|
|
322
319
|
},
|
|
323
|
-
|
|
324
|
-
if (node.
|
|
325
|
-
checkPattern(node.
|
|
320
|
+
VariableDeclarator(node: TSESTree.VariableDeclarator) {
|
|
321
|
+
if (node.id) {
|
|
322
|
+
checkPattern(node.id);
|
|
326
323
|
}
|
|
327
324
|
}
|
|
328
325
|
};
|
|
326
|
+
},
|
|
327
|
+
defaultOptions: [{}],
|
|
328
|
+
meta: {
|
|
329
|
+
docs: {
|
|
330
|
+
description:
|
|
331
|
+
"Disallow variable names shorter than the configured minimum length unless an outer variable with a longer name starting with the same characters exists. You can exempt specific variable names using the allowedVars option."
|
|
332
|
+
},
|
|
333
|
+
messages: {
|
|
334
|
+
variableNameTooShort:
|
|
335
|
+
"Variable '{{name}}' is too short. Minimum allowed length is {{minLength}} characters unless an outer variable with a longer name starting with '{{name}}' exists."
|
|
336
|
+
},
|
|
337
|
+
schema: [
|
|
338
|
+
{
|
|
339
|
+
additionalProperties: false,
|
|
340
|
+
properties: {
|
|
341
|
+
allowedVars: {
|
|
342
|
+
default: [],
|
|
343
|
+
items: {
|
|
344
|
+
minLength: 1,
|
|
345
|
+
type: "string"
|
|
346
|
+
// Note: The maxLength for each string should be at most the configured minLength.
|
|
347
|
+
},
|
|
348
|
+
type: "array"
|
|
349
|
+
},
|
|
350
|
+
minLength: {
|
|
351
|
+
default: 1,
|
|
352
|
+
type: "number"
|
|
353
|
+
}
|
|
354
|
+
},
|
|
355
|
+
type: "object"
|
|
356
|
+
}
|
|
357
|
+
],
|
|
358
|
+
type: "problem"
|
|
329
359
|
}
|
|
330
360
|
};
|