@pobammer-ts/small-rules 2.2.1 → 2.4.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/dist/index.d.ts +7 -1
- package/dist/index.js +278 -258
- package/package.json +2 -1
package/dist/index.d.ts
CHANGED
|
@@ -379,9 +379,15 @@ declare const smallRules: import("oxlint-plugin-utilities").Plugin<{
|
|
|
379
379
|
}], "noRecursive", undefined>;
|
|
380
380
|
"no-redundant-aspect-ratio-constraint": import("oxlint-plugin-utilities").CreateRule<readonly [], "redundantAspectRatioConstraint", undefined>;
|
|
381
381
|
"no-render-helper-functions": import("oxlint-plugin-utilities").CreateRule<readonly [], "noRenderHelper", undefined>;
|
|
382
|
-
"no-restricted-property-assignment": import("oxlint-plugin-utilities").
|
|
382
|
+
"no-restricted-property-assignment": import("oxlint-plugin-utilities").CreateRule<readonly [{
|
|
383
383
|
readonly additionalProperties: false;
|
|
384
384
|
readonly properties: {
|
|
385
|
+
readonly allowFiles: {
|
|
386
|
+
readonly items: {
|
|
387
|
+
readonly type: "string";
|
|
388
|
+
};
|
|
389
|
+
readonly type: "array";
|
|
390
|
+
};
|
|
385
391
|
readonly checkComputed: {
|
|
386
392
|
readonly default: true;
|
|
387
393
|
readonly type: "boolean";
|
package/dist/index.js
CHANGED
|
@@ -5,6 +5,7 @@ import { parseSync } from "oxc-parser";
|
|
|
5
5
|
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
6
6
|
import { ResolverFactory } from "oxc-resolver";
|
|
7
7
|
import { type } from "arktype";
|
|
8
|
+
import { Minimatch, minimatch } from "minimatch";
|
|
8
9
|
//#region src/rules/array-type-generic.ts
|
|
9
10
|
function toGenericArrayType(typeNode, sourceCode) {
|
|
10
11
|
if (typeNode.type === "TSParenthesizedType") return toGenericArrayType(typeNode.typeAnnotation, sourceCode);
|
|
@@ -112,6 +113,197 @@ function hasShadowedBinding(sourceCode, node, name) {
|
|
|
112
113
|
return false;
|
|
113
114
|
}
|
|
114
115
|
//#endregion
|
|
116
|
+
//#region src/utilities/oxc-utilities.ts
|
|
117
|
+
const COMPONENT_NAME_PATTERN = /^[A-Z]/v;
|
|
118
|
+
const KEY_OF_NODE = new Set([
|
|
119
|
+
"end",
|
|
120
|
+
"loc",
|
|
121
|
+
"parent",
|
|
122
|
+
"range",
|
|
123
|
+
"start",
|
|
124
|
+
"type"
|
|
125
|
+
]);
|
|
126
|
+
function isNode$1(value) {
|
|
127
|
+
return isRecord(value) && isStringRaw(value.type);
|
|
128
|
+
}
|
|
129
|
+
function isKeyOfNode(key) {
|
|
130
|
+
return KEY_OF_NODE.has(key);
|
|
131
|
+
}
|
|
132
|
+
function isComponentName(name) {
|
|
133
|
+
return COMPONENT_NAME_PATTERN.test(name);
|
|
134
|
+
}
|
|
135
|
+
function isVariableDeclarator(node) {
|
|
136
|
+
return node.type === "VariableDeclarator";
|
|
137
|
+
}
|
|
138
|
+
function getTypeAnnotationFromBinding(binding) {
|
|
139
|
+
return isTsTypeAnnotation(binding.typeAnnotation) ? binding.typeAnnotation : void 0;
|
|
140
|
+
}
|
|
141
|
+
function isTsTypeAnnotation(value) {
|
|
142
|
+
return isRecord(value) && "type" in value && value.type === "TSTypeAnnotation";
|
|
143
|
+
}
|
|
144
|
+
function isIdentifierNamed$1(node, name) {
|
|
145
|
+
return node.type === "Identifier" && node.name === name;
|
|
146
|
+
}
|
|
147
|
+
function isReactNamedCall(node, identifiers, reactNamespaces, name) {
|
|
148
|
+
if (node.callee.type === "Identifier") return identifiers.has(node.callee.name);
|
|
149
|
+
if (node.callee.type !== "MemberExpression" || node.callee.object.type !== "Identifier") return false;
|
|
150
|
+
return reactNamespaces.has(node.callee.object.name) && getMemberPropertyName(node.callee) === name;
|
|
151
|
+
}
|
|
152
|
+
function isUseMemoCall(node, memoIdentifiers, reactNamespaces) {
|
|
153
|
+
return isReactNamedCall(node, memoIdentifiers, reactNamespaces, "useMemo");
|
|
154
|
+
}
|
|
155
|
+
function getImportedName({ imported }) {
|
|
156
|
+
return imported.type === "Identifier" ? imported.name : imported.value;
|
|
157
|
+
}
|
|
158
|
+
function hasName(node) {
|
|
159
|
+
return node.type === "Identifier" && isStringRaw(node.name);
|
|
160
|
+
}
|
|
161
|
+
function isIdentifierName(node) {
|
|
162
|
+
return node.type === "Identifier";
|
|
163
|
+
}
|
|
164
|
+
function isJsxIdentifier$1(node) {
|
|
165
|
+
return node.type === "JSXIdentifier" && "name" in node;
|
|
166
|
+
}
|
|
167
|
+
function isJsxOpeningExpression(node) {
|
|
168
|
+
return node.type === "JSXOpeningElement";
|
|
169
|
+
}
|
|
170
|
+
function isImportDeclaration(node) {
|
|
171
|
+
return node.type === "ImportDeclaration";
|
|
172
|
+
}
|
|
173
|
+
function isStringLiteral(node) {
|
|
174
|
+
return node.type === "Literal" && isStringRaw(node.value);
|
|
175
|
+
}
|
|
176
|
+
function isCallExpression$1(node) {
|
|
177
|
+
return node.type === "CallExpression";
|
|
178
|
+
}
|
|
179
|
+
function isImportSpecifier$1(node) {
|
|
180
|
+
return node.type === "ImportSpecifier";
|
|
181
|
+
}
|
|
182
|
+
function isExportSpecifier(node) {
|
|
183
|
+
return node.type === "ExportSpecifier";
|
|
184
|
+
}
|
|
185
|
+
function isProperty(node) {
|
|
186
|
+
return node.type === "Property";
|
|
187
|
+
}
|
|
188
|
+
function isMemberExpression(node) {
|
|
189
|
+
return node.type === "MemberExpression";
|
|
190
|
+
}
|
|
191
|
+
function isAssignmentExpression(node) {
|
|
192
|
+
return node.type === "AssignmentExpression";
|
|
193
|
+
}
|
|
194
|
+
function isUnaryExpression(node) {
|
|
195
|
+
return node.type === "UnaryExpression";
|
|
196
|
+
}
|
|
197
|
+
function isBinaryExpression(node) {
|
|
198
|
+
return node.type === "BinaryExpression";
|
|
199
|
+
}
|
|
200
|
+
function isLogicalExpression(node) {
|
|
201
|
+
return node.type === "LogicalExpression";
|
|
202
|
+
}
|
|
203
|
+
function isConditionalExpression(node) {
|
|
204
|
+
return node.type === "ConditionalExpression";
|
|
205
|
+
}
|
|
206
|
+
function isSequenceExpression(node) {
|
|
207
|
+
return node.type === "SequenceExpression";
|
|
208
|
+
}
|
|
209
|
+
function isMethodDefinition(node) {
|
|
210
|
+
return node.type === "MethodDefinition" || node.type === "TSAbstractMethodDefinition";
|
|
211
|
+
}
|
|
212
|
+
function isPropertyDefinition(node) {
|
|
213
|
+
return node.type === "PropertyDefinition" || node.type === "TSAbstractPropertyDefinition";
|
|
214
|
+
}
|
|
215
|
+
function isImportDefaultSpecifier(node) {
|
|
216
|
+
return node.type === "ImportDefaultSpecifier";
|
|
217
|
+
}
|
|
218
|
+
function isImportNamespaceSpecifier(node) {
|
|
219
|
+
return node.type === "ImportNamespaceSpecifier";
|
|
220
|
+
}
|
|
221
|
+
function isVariableDeclaration(node) {
|
|
222
|
+
return node.type === "VariableDeclaration";
|
|
223
|
+
}
|
|
224
|
+
function isExportNamedDeclaration(node) {
|
|
225
|
+
return node.type === "ExportNamedDeclaration";
|
|
226
|
+
}
|
|
227
|
+
function isFunctionDeclaration(node) {
|
|
228
|
+
return node.type === "FunctionDeclaration" || node.type === "FunctionExpression";
|
|
229
|
+
}
|
|
230
|
+
function isCallbackFunction(node) {
|
|
231
|
+
return node.type === "ArrowFunctionExpression" || node.type === "FunctionExpression";
|
|
232
|
+
}
|
|
233
|
+
function isAnyFunction(node) {
|
|
234
|
+
return node.type === "ArrowFunctionExpression" || node.type === "FunctionDeclaration" || node.type === "FunctionExpression";
|
|
235
|
+
}
|
|
236
|
+
function isNamedGlobalCall(node, name) {
|
|
237
|
+
return isIdentifierNamed$1(node.callee, name);
|
|
238
|
+
}
|
|
239
|
+
function isClass(node) {
|
|
240
|
+
return node.type === "ClassDeclaration" || node.type === "ClassExpression";
|
|
241
|
+
}
|
|
242
|
+
function isTsTypeAliasDeclaration(node) {
|
|
243
|
+
return node.type === "TSTypeAliasDeclaration";
|
|
244
|
+
}
|
|
245
|
+
function isTsPropertySignature(node) {
|
|
246
|
+
return node.type === "TSPropertySignature";
|
|
247
|
+
}
|
|
248
|
+
function isLiteral(node) {
|
|
249
|
+
return node.type === "Literal";
|
|
250
|
+
}
|
|
251
|
+
function isArrowFunctionExpression(node) {
|
|
252
|
+
return node.type === "ArrowFunctionExpression";
|
|
253
|
+
}
|
|
254
|
+
function isFunction(node) {
|
|
255
|
+
return isFunctionDeclaration(node) || isArrowFunctionExpression(node);
|
|
256
|
+
}
|
|
257
|
+
function isTsQualifiedName(node) {
|
|
258
|
+
return node.type === "TSQualifiedName";
|
|
259
|
+
}
|
|
260
|
+
function isNumericLiteral(node) {
|
|
261
|
+
return node.type === "Literal" && isNumberRaw(node.value);
|
|
262
|
+
}
|
|
263
|
+
function isNewExpression(node) {
|
|
264
|
+
return node.type === "NewExpression";
|
|
265
|
+
}
|
|
266
|
+
function isArrayExpression(node) {
|
|
267
|
+
return node.type === "ArrayExpression";
|
|
268
|
+
}
|
|
269
|
+
function isObjectExpression(node) {
|
|
270
|
+
return node.type === "ObjectExpression";
|
|
271
|
+
}
|
|
272
|
+
function isObjectPattern(node) {
|
|
273
|
+
return node.type === "ObjectPattern";
|
|
274
|
+
}
|
|
275
|
+
function isTemplateLiteral(node) {
|
|
276
|
+
return node.type === "TemplateLiteral";
|
|
277
|
+
}
|
|
278
|
+
function isExpressionStatement(node) {
|
|
279
|
+
return node.type === "ExpressionStatement";
|
|
280
|
+
}
|
|
281
|
+
function isTsTypeAssertion(node) {
|
|
282
|
+
return node.type === "TSTypeAssertion";
|
|
283
|
+
}
|
|
284
|
+
function isTsAsExpression(node) {
|
|
285
|
+
return node.type === "TSAsExpression";
|
|
286
|
+
}
|
|
287
|
+
function isAssignmentPattern(node) {
|
|
288
|
+
return node.type === "AssignmentPattern";
|
|
289
|
+
}
|
|
290
|
+
function isThisExpression(node) {
|
|
291
|
+
return node.type === "ThisExpression";
|
|
292
|
+
}
|
|
293
|
+
function isStaticRequire(node) {
|
|
294
|
+
if (!isCallExpression$1(node) || node.optional) return false;
|
|
295
|
+
const { callee } = node;
|
|
296
|
+
if (!isIdentifierName(callee) || callee.name !== "require" || node.arguments.length !== 1) return false;
|
|
297
|
+
const [argument] = node.arguments;
|
|
298
|
+
return argument !== void 0 && isStringLiteral(argument);
|
|
299
|
+
}
|
|
300
|
+
function isBindingIdentifier(node) {
|
|
301
|
+
return node.type === "Identifier";
|
|
302
|
+
}
|
|
303
|
+
function isExpressionNode(node) {
|
|
304
|
+
return node.type !== "PrivateIdentifier";
|
|
305
|
+
}
|
|
306
|
+
//#endregion
|
|
115
307
|
//#region src/rules/ban-instances.ts
|
|
116
308
|
function getJsxAttributeName$2(name) {
|
|
117
309
|
return name.type === "JSXIdentifier" ? name.name : name.name.name;
|
|
@@ -162,7 +354,7 @@ function getEnclosingFunctionScope(scope) {
|
|
|
162
354
|
return currentScope;
|
|
163
355
|
}
|
|
164
356
|
function getInstanceClassName(node) {
|
|
165
|
-
if (node
|
|
357
|
+
if (!isNamedGlobalCall(node, "Instance")) return void 0;
|
|
166
358
|
const [firstArgument] = node.arguments;
|
|
167
359
|
if (firstArgument?.type !== "Literal" || !isStringRaw(firstArgument.value)) return void 0;
|
|
168
360
|
return firstArgument.value;
|
|
@@ -326,191 +518,6 @@ const banInstances = defineRule({
|
|
|
326
518
|
}
|
|
327
519
|
});
|
|
328
520
|
//#endregion
|
|
329
|
-
//#region src/utilities/oxc-utilities.ts
|
|
330
|
-
const COMPONENT_NAME_PATTERN = /^[A-Z]/v;
|
|
331
|
-
const KEY_OF_NODE = new Set([
|
|
332
|
-
"end",
|
|
333
|
-
"loc",
|
|
334
|
-
"parent",
|
|
335
|
-
"range",
|
|
336
|
-
"start",
|
|
337
|
-
"type"
|
|
338
|
-
]);
|
|
339
|
-
function isNode$1(value) {
|
|
340
|
-
return isRecord(value) && isStringRaw(value.type);
|
|
341
|
-
}
|
|
342
|
-
function isKeyOfNode(key) {
|
|
343
|
-
return KEY_OF_NODE.has(key);
|
|
344
|
-
}
|
|
345
|
-
function isComponentName(name) {
|
|
346
|
-
return COMPONENT_NAME_PATTERN.test(name);
|
|
347
|
-
}
|
|
348
|
-
function isVariableDeclarator(node) {
|
|
349
|
-
return node.type === "VariableDeclarator";
|
|
350
|
-
}
|
|
351
|
-
function getTypeAnnotationFromBinding(binding) {
|
|
352
|
-
return isTsTypeAnnotation(binding.typeAnnotation) ? binding.typeAnnotation : void 0;
|
|
353
|
-
}
|
|
354
|
-
function isTsTypeAnnotation(value) {
|
|
355
|
-
return isRecord(value) && "type" in value && value.type === "TSTypeAnnotation";
|
|
356
|
-
}
|
|
357
|
-
function isIdentifierNamed$1(node, name) {
|
|
358
|
-
return node.type === "Identifier" && node.name === name;
|
|
359
|
-
}
|
|
360
|
-
function isReactNamedCall(node, identifiers, reactNamespaces, name) {
|
|
361
|
-
if (node.callee.type === "Identifier") return identifiers.has(node.callee.name);
|
|
362
|
-
if (node.callee.type !== "MemberExpression" || node.callee.object.type !== "Identifier") return false;
|
|
363
|
-
return reactNamespaces.has(node.callee.object.name) && getMemberPropertyName(node.callee) === name;
|
|
364
|
-
}
|
|
365
|
-
function isUseMemoCall(node, memoIdentifiers, reactNamespaces) {
|
|
366
|
-
return isReactNamedCall(node, memoIdentifiers, reactNamespaces, "useMemo");
|
|
367
|
-
}
|
|
368
|
-
function getImportedName({ imported }) {
|
|
369
|
-
return imported.type === "Identifier" ? imported.name : imported.value;
|
|
370
|
-
}
|
|
371
|
-
function hasName(node) {
|
|
372
|
-
return node.type === "Identifier" && isStringRaw(node.name);
|
|
373
|
-
}
|
|
374
|
-
function isIdentifierName(node) {
|
|
375
|
-
return node.type === "Identifier";
|
|
376
|
-
}
|
|
377
|
-
function isJsxIdentifier$1(node) {
|
|
378
|
-
return node.type === "JSXIdentifier" && "name" in node;
|
|
379
|
-
}
|
|
380
|
-
function isJsxOpeningExpression(node) {
|
|
381
|
-
return node.type === "JSXOpeningElement";
|
|
382
|
-
}
|
|
383
|
-
function isImportDeclaration(node) {
|
|
384
|
-
return node.type === "ImportDeclaration";
|
|
385
|
-
}
|
|
386
|
-
function isStringLiteral(node) {
|
|
387
|
-
return node.type === "Literal" && isStringRaw(node.value);
|
|
388
|
-
}
|
|
389
|
-
function isCallExpression$1(node) {
|
|
390
|
-
return node.type === "CallExpression";
|
|
391
|
-
}
|
|
392
|
-
function isImportSpecifier$1(node) {
|
|
393
|
-
return node.type === "ImportSpecifier";
|
|
394
|
-
}
|
|
395
|
-
function isExportSpecifier(node) {
|
|
396
|
-
return node.type === "ExportSpecifier";
|
|
397
|
-
}
|
|
398
|
-
function isProperty(node) {
|
|
399
|
-
return node.type === "Property";
|
|
400
|
-
}
|
|
401
|
-
function isMemberExpression(node) {
|
|
402
|
-
return node.type === "MemberExpression";
|
|
403
|
-
}
|
|
404
|
-
function isAssignmentExpression(node) {
|
|
405
|
-
return node.type === "AssignmentExpression";
|
|
406
|
-
}
|
|
407
|
-
function isUnaryExpression(node) {
|
|
408
|
-
return node.type === "UnaryExpression";
|
|
409
|
-
}
|
|
410
|
-
function isBinaryExpression(node) {
|
|
411
|
-
return node.type === "BinaryExpression";
|
|
412
|
-
}
|
|
413
|
-
function isLogicalExpression(node) {
|
|
414
|
-
return node.type === "LogicalExpression";
|
|
415
|
-
}
|
|
416
|
-
function isConditionalExpression(node) {
|
|
417
|
-
return node.type === "ConditionalExpression";
|
|
418
|
-
}
|
|
419
|
-
function isSequenceExpression(node) {
|
|
420
|
-
return node.type === "SequenceExpression";
|
|
421
|
-
}
|
|
422
|
-
function isMethodDefinition(node) {
|
|
423
|
-
return node.type === "MethodDefinition" || node.type === "TSAbstractMethodDefinition";
|
|
424
|
-
}
|
|
425
|
-
function isPropertyDefinition(node) {
|
|
426
|
-
return node.type === "PropertyDefinition" || node.type === "TSAbstractPropertyDefinition";
|
|
427
|
-
}
|
|
428
|
-
function isImportDefaultSpecifier(node) {
|
|
429
|
-
return node.type === "ImportDefaultSpecifier";
|
|
430
|
-
}
|
|
431
|
-
function isImportNamespaceSpecifier(node) {
|
|
432
|
-
return node.type === "ImportNamespaceSpecifier";
|
|
433
|
-
}
|
|
434
|
-
function isVariableDeclaration(node) {
|
|
435
|
-
return node.type === "VariableDeclaration";
|
|
436
|
-
}
|
|
437
|
-
function isExportNamedDeclaration(node) {
|
|
438
|
-
return node.type === "ExportNamedDeclaration";
|
|
439
|
-
}
|
|
440
|
-
function isFunctionDeclaration(node) {
|
|
441
|
-
return node.type === "FunctionDeclaration" || node.type === "FunctionExpression";
|
|
442
|
-
}
|
|
443
|
-
function isCallbackFunction(node) {
|
|
444
|
-
return node.type === "ArrowFunctionExpression" || node.type === "FunctionExpression";
|
|
445
|
-
}
|
|
446
|
-
function isClass(node) {
|
|
447
|
-
return node.type === "ClassDeclaration" || node.type === "ClassExpression";
|
|
448
|
-
}
|
|
449
|
-
function isTsTypeAliasDeclaration(node) {
|
|
450
|
-
return node.type === "TSTypeAliasDeclaration";
|
|
451
|
-
}
|
|
452
|
-
function isTsPropertySignature(node) {
|
|
453
|
-
return node.type === "TSPropertySignature";
|
|
454
|
-
}
|
|
455
|
-
function isLiteral(node) {
|
|
456
|
-
return node.type === "Literal";
|
|
457
|
-
}
|
|
458
|
-
function isArrowFunctionExpression(node) {
|
|
459
|
-
return node.type === "ArrowFunctionExpression";
|
|
460
|
-
}
|
|
461
|
-
function isFunction(node) {
|
|
462
|
-
return isFunctionDeclaration(node) || isArrowFunctionExpression(node);
|
|
463
|
-
}
|
|
464
|
-
function isTsQualifiedName(node) {
|
|
465
|
-
return node.type === "TSQualifiedName";
|
|
466
|
-
}
|
|
467
|
-
function isNumericLiteral(node) {
|
|
468
|
-
return node.type === "Literal" && isNumberRaw(node.value);
|
|
469
|
-
}
|
|
470
|
-
function isNewExpression(node) {
|
|
471
|
-
return node.type === "NewExpression";
|
|
472
|
-
}
|
|
473
|
-
function isArrayExpression(node) {
|
|
474
|
-
return node.type === "ArrayExpression";
|
|
475
|
-
}
|
|
476
|
-
function isObjectExpression(node) {
|
|
477
|
-
return node.type === "ObjectExpression";
|
|
478
|
-
}
|
|
479
|
-
function isObjectPattern(node) {
|
|
480
|
-
return node.type === "ObjectPattern";
|
|
481
|
-
}
|
|
482
|
-
function isTemplateLiteral(node) {
|
|
483
|
-
return node.type === "TemplateLiteral";
|
|
484
|
-
}
|
|
485
|
-
function isExpressionStatement(node) {
|
|
486
|
-
return node.type === "ExpressionStatement";
|
|
487
|
-
}
|
|
488
|
-
function isTsTypeAssertion(node) {
|
|
489
|
-
return node.type === "TSTypeAssertion";
|
|
490
|
-
}
|
|
491
|
-
function isTsAsExpression(node) {
|
|
492
|
-
return node.type === "TSAsExpression";
|
|
493
|
-
}
|
|
494
|
-
function isAssignmentPattern(node) {
|
|
495
|
-
return node.type === "AssignmentPattern";
|
|
496
|
-
}
|
|
497
|
-
function isThisExpression(node) {
|
|
498
|
-
return node.type === "ThisExpression";
|
|
499
|
-
}
|
|
500
|
-
function isStaticRequire(node) {
|
|
501
|
-
if (!isCallExpression$1(node) || node.optional) return false;
|
|
502
|
-
const { callee } = node;
|
|
503
|
-
if (!isIdentifierName(callee) || callee.name !== "require" || node.arguments.length !== 1) return false;
|
|
504
|
-
const [argument] = node.arguments;
|
|
505
|
-
return argument !== void 0 && isStringLiteral(argument);
|
|
506
|
-
}
|
|
507
|
-
function isBindingIdentifier(node) {
|
|
508
|
-
return node.type === "Identifier";
|
|
509
|
-
}
|
|
510
|
-
function isExpressionNode(node) {
|
|
511
|
-
return node.type !== "PrivateIdentifier";
|
|
512
|
-
}
|
|
513
|
-
//#endregion
|
|
514
521
|
//#region src/rules/ban-react-fc.ts
|
|
515
522
|
const BANNED_FC_NAMES = new Set([
|
|
516
523
|
"FC",
|
|
@@ -2597,7 +2604,7 @@ function isPromiseChainCall(node) {
|
|
|
2597
2604
|
}
|
|
2598
2605
|
function isAsyncIife({ callee }) {
|
|
2599
2606
|
const unwrapped = unwrapExpression(callee);
|
|
2600
|
-
return (unwrapped
|
|
2607
|
+
return isCallbackFunction(unwrapped) && unwrapped.async;
|
|
2601
2608
|
}
|
|
2602
2609
|
function getThisAsyncMethodName({ callee }, asyncMethods) {
|
|
2603
2610
|
if (callee.type !== "MemberExpression" || callee.object.type !== "ThisExpression" || callee.property.type !== "Identifier") return;
|
|
@@ -2614,7 +2621,7 @@ function getLocalVariableAssignment(node) {
|
|
|
2614
2621
|
return parent.id.type === "Identifier" ? parent.id.name : void 0;
|
|
2615
2622
|
}
|
|
2616
2623
|
function isNonIifeFunction(node) {
|
|
2617
|
-
if (node
|
|
2624
|
+
if (!isCallbackFunction(node)) return false;
|
|
2618
2625
|
if (node.parent.type === "ParenthesizedExpression" && node.parent.parent.type === "CallExpression" && node.parent.parent.callee === node.parent) return false;
|
|
2619
2626
|
return node.parent.type !== "CallExpression" || node.parent.callee !== node;
|
|
2620
2627
|
}
|
|
@@ -2765,7 +2772,7 @@ const noColor3Constructor = defineRule({
|
|
|
2765
2772
|
create(context) {
|
|
2766
2773
|
const options = normalizeOptions$4(context.options[0]);
|
|
2767
2774
|
return { NewExpression(node) {
|
|
2768
|
-
if (node
|
|
2775
|
+
if (!isNamedGlobalCall(node, "Color3")) return;
|
|
2769
2776
|
const parameters = node.arguments;
|
|
2770
2777
|
if (parameters.length === 0) return;
|
|
2771
2778
|
const collected = collectNumericComponents(parameters);
|
|
@@ -3445,14 +3452,6 @@ const LOOP_TYPES = new Set([
|
|
|
3445
3452
|
function isLoopNode(node) {
|
|
3446
3453
|
return LOOP_TYPES.has(node.type);
|
|
3447
3454
|
}
|
|
3448
|
-
const FUNCTION_BOUNDARY_TYPES$1 = new Set([
|
|
3449
|
-
"ArrowFunctionExpression",
|
|
3450
|
-
"FunctionDeclaration",
|
|
3451
|
-
"FunctionExpression"
|
|
3452
|
-
]);
|
|
3453
|
-
function isFunctionBoundary(node) {
|
|
3454
|
-
return FUNCTION_BOUNDARY_TYPES$1.has(node.type);
|
|
3455
|
-
}
|
|
3456
3455
|
function findLabeledStatementBody$1(labelName, startingNode) {
|
|
3457
3456
|
let current = startingNode;
|
|
3458
3457
|
while (current !== null) {
|
|
@@ -3466,7 +3465,7 @@ function breaksTargetLoop(statement, loopNode) {
|
|
|
3466
3465
|
if (statement.label) return findLabeledStatementBody$1(statement.label.name, statement.parent) === loopNode;
|
|
3467
3466
|
let current = statement.parent;
|
|
3468
3467
|
while (current !== null) {
|
|
3469
|
-
if (current.type === "Program" ||
|
|
3468
|
+
if (current.type === "Program" || isAnyFunction(current) || current.type === "SwitchStatement") return false;
|
|
3470
3469
|
if (isLoopNode(current)) return current === loopNode;
|
|
3471
3470
|
current = current.parent;
|
|
3472
3471
|
}
|
|
@@ -5533,7 +5532,7 @@ function hasAspectRatioConstraintInSubtree(node) {
|
|
|
5533
5532
|
function getFunctionComponentName(node) {
|
|
5534
5533
|
if (node.type === "FunctionDeclaration") return node.id?.name;
|
|
5535
5534
|
/* v8 ignore next -- @preserve only named declarations and assigned function expressions are inspected as components. */
|
|
5536
|
-
if (node
|
|
5535
|
+
if (isCallbackFunction(node)) {
|
|
5537
5536
|
const { parent } = node;
|
|
5538
5537
|
/* v8 ignore next -- @preserve assigned function components have identifier variable declarator parents. */
|
|
5539
5538
|
if (parent.type === "VariableDeclarator" && parent.id.type === "Identifier") return parent.id.name;
|
|
@@ -5804,35 +5803,72 @@ const noRenderHelperFunctions = defineRule({
|
|
|
5804
5803
|
});
|
|
5805
5804
|
//#endregion
|
|
5806
5805
|
//#region src/rules/no-restricted-property-assignment.ts
|
|
5807
|
-
|
|
5808
|
-
|
|
5809
|
-
|
|
5810
|
-
|
|
5811
|
-
|
|
5812
|
-
|
|
5813
|
-
|
|
5814
|
-
|
|
5815
|
-
|
|
5816
|
-
|
|
5817
|
-
|
|
5818
|
-
|
|
5819
|
-
|
|
5820
|
-
|
|
5821
|
-
|
|
5806
|
+
const isRestriction = type({
|
|
5807
|
+
"message?": "string | undefined",
|
|
5808
|
+
object: "string",
|
|
5809
|
+
properties: type("string[]").readonly()
|
|
5810
|
+
}).readonly();
|
|
5811
|
+
const isRuleOptions = type({
|
|
5812
|
+
"allowFiles?": type("string[]").readonly().or("undefined"),
|
|
5813
|
+
"checkComputed?": "boolean | undefined",
|
|
5814
|
+
restrictions: isRestriction.array().readonly()
|
|
5815
|
+
}).readonly();
|
|
5816
|
+
const FILE_MATCH_OPTIONS = { matchBase: true };
|
|
5817
|
+
const NAME_MATCH_OPTIONS = {
|
|
5818
|
+
dot: true,
|
|
5819
|
+
magicalBraces: true
|
|
5820
|
+
};
|
|
5821
|
+
function compileMatcher(pattern, options) {
|
|
5822
|
+
const matcher = new Minimatch(pattern, options);
|
|
5823
|
+
const hasMagic = matcher.hasMagic();
|
|
5824
|
+
return {
|
|
5825
|
+
hasMagic,
|
|
5826
|
+
matches: hasMagic ? (value) => matcher.match(value) : (value) => value === pattern
|
|
5827
|
+
};
|
|
5828
|
+
}
|
|
5829
|
+
function createPropertyMatcher(patterns) {
|
|
5830
|
+
const literalPatterns = /* @__PURE__ */ new Set();
|
|
5831
|
+
const globMatchers = [];
|
|
5832
|
+
for (const pattern of patterns) {
|
|
5833
|
+
const matcher = compileMatcher(pattern, NAME_MATCH_OPTIONS);
|
|
5834
|
+
if (matcher.hasMagic) globMatchers.push(matcher.matches);
|
|
5835
|
+
else literalPatterns.add(pattern);
|
|
5836
|
+
}
|
|
5837
|
+
return (property) => literalPatterns.has(property) || globMatchers.some((matcher) => matcher(property));
|
|
5838
|
+
}
|
|
5839
|
+
function compileRestriction(restriction) {
|
|
5840
|
+
return {
|
|
5841
|
+
matchesObject: compileMatcher(restriction.object, NAME_MATCH_OPTIONS).matches,
|
|
5842
|
+
matchesProperty: createPropertyMatcher(restriction.properties),
|
|
5843
|
+
message: restriction.message
|
|
5844
|
+
};
|
|
5845
|
+
}
|
|
5846
|
+
function getEffectiveOptions(context) {
|
|
5847
|
+
const [options] = context.options;
|
|
5848
|
+
if (!isRuleOptions.allows(options)) return {
|
|
5849
|
+
checkComputed: true,
|
|
5850
|
+
isAllowedFile: false,
|
|
5851
|
+
restrictions: []
|
|
5852
|
+
};
|
|
5853
|
+
const { allowFiles, checkComputed, restrictions } = options;
|
|
5854
|
+
const isAllowedFile = allowFiles?.some((pattern) => minimatch(context.filename, pattern, FILE_MATCH_OPTIONS)) ?? false;
|
|
5855
|
+
return {
|
|
5856
|
+
checkComputed: checkComputed ?? true,
|
|
5857
|
+
isAllowedFile,
|
|
5858
|
+
restrictions: restrictions.map(compileRestriction)
|
|
5859
|
+
};
|
|
5822
5860
|
}
|
|
5823
5861
|
const noRestrictedPropertyAssignment = defineRule({
|
|
5824
|
-
|
|
5825
|
-
|
|
5826
|
-
let checkComputed = true;
|
|
5862
|
+
create(context) {
|
|
5863
|
+
const { checkComputed, isAllowedFile, restrictions } = getEffectiveOptions(context);
|
|
5827
5864
|
function reportIfRestricted(node, reportNode) {
|
|
5828
|
-
if (!
|
|
5829
|
-
if (node.computed && !checkComputed) return;
|
|
5830
|
-
if (node.object.type !== "Identifier") return;
|
|
5865
|
+
if (isAllowedFile || !isMemberExpression(node)) return;
|
|
5866
|
+
if (node.computed && !checkComputed || node.object.type !== "Identifier") return;
|
|
5831
5867
|
const property = getMemberPropertyName(node);
|
|
5832
5868
|
if (property === void 0) return;
|
|
5833
5869
|
for (const restriction of restrictions) {
|
|
5834
|
-
if (restriction.
|
|
5835
|
-
if (restriction.
|
|
5870
|
+
if (!restriction.matchesObject(node.object.name)) continue;
|
|
5871
|
+
if (restriction.matchesProperty(property)) {
|
|
5836
5872
|
if (restriction.message === void 0) context.report({
|
|
5837
5873
|
data: {
|
|
5838
5874
|
object: node.object.name,
|
|
@@ -5854,17 +5890,6 @@ const noRestrictedPropertyAssignment = defineRule({
|
|
|
5854
5890
|
AssignmentExpression(node) {
|
|
5855
5891
|
reportIfRestricted(node.left, node);
|
|
5856
5892
|
},
|
|
5857
|
-
before() {
|
|
5858
|
-
const [options] = context.options;
|
|
5859
|
-
if (!isRuleOptions(options)) {
|
|
5860
|
-
restrictions = [];
|
|
5861
|
-
checkComputed = true;
|
|
5862
|
-
return;
|
|
5863
|
-
}
|
|
5864
|
-
const { checkComputed: nextCheckComputed, restrictions: nextRestrictions } = options;
|
|
5865
|
-
restrictions = nextRestrictions;
|
|
5866
|
-
checkComputed = nextCheckComputed ?? true;
|
|
5867
|
-
},
|
|
5868
5893
|
UpdateExpression(node) {
|
|
5869
5894
|
reportIfRestricted(node.argument, node);
|
|
5870
5895
|
}
|
|
@@ -5882,6 +5907,10 @@ const noRestrictedPropertyAssignment = defineRule({
|
|
|
5882
5907
|
schema: [{
|
|
5883
5908
|
additionalProperties: false,
|
|
5884
5909
|
properties: {
|
|
5910
|
+
allowFiles: {
|
|
5911
|
+
items: { type: "string" },
|
|
5912
|
+
type: "array"
|
|
5913
|
+
},
|
|
5885
5914
|
checkComputed: {
|
|
5886
5915
|
default: true,
|
|
5887
5916
|
type: "boolean"
|
|
@@ -5990,7 +6019,7 @@ function isStaticComponentVariable(variable, name) {
|
|
|
5990
6019
|
if (definition.node.type !== "VariableDeclarator") continue;
|
|
5991
6020
|
const initializer = definition.node.init ?? void 0;
|
|
5992
6021
|
if (initializer === void 0) continue;
|
|
5993
|
-
if (initializer
|
|
6022
|
+
if (isCallbackFunction(initializer) || initializer.type === "ClassExpression") return true;
|
|
5994
6023
|
}
|
|
5995
6024
|
return false;
|
|
5996
6025
|
}
|
|
@@ -6383,9 +6412,14 @@ function collectAllScopes(root) {
|
|
|
6383
6412
|
function isFunctionLikeInitializer(node) {
|
|
6384
6413
|
return isCallbackFunction(node) || node.type === "ClassExpression";
|
|
6385
6414
|
}
|
|
6415
|
+
const OBJECT_LIKE_INITIALIZER_TYPES = new Set([
|
|
6416
|
+
"ArrayExpression",
|
|
6417
|
+
"ObjectExpression",
|
|
6418
|
+
"JSXElement",
|
|
6419
|
+
"JSXFragment"
|
|
6420
|
+
]);
|
|
6386
6421
|
function isObjectLikeInitializer(initializer, patterns, sourceCode) {
|
|
6387
|
-
if (
|
|
6388
|
-
if (initializer.type === "JSXElement" || initializer.type === "JSXFragment") return true;
|
|
6422
|
+
if (OBJECT_LIKE_INITIALIZER_TYPES.has(initializer.type)) return true;
|
|
6389
6423
|
if (initializer.type !== "CallExpression" && initializer.type !== "NewExpression") return false;
|
|
6390
6424
|
const candidateText = sourceCode.getText(initializer.callee);
|
|
6391
6425
|
for (const pattern of patterns) if (pattern.test(candidateText)) return true;
|
|
@@ -22043,7 +22077,7 @@ function getSequenceKeypointName(sequenceName) {
|
|
|
22043
22077
|
}
|
|
22044
22078
|
function getKeypointValue(node, keypointName, time) {
|
|
22045
22079
|
if (node.type !== "NewExpression") return void 0;
|
|
22046
|
-
if (node
|
|
22080
|
+
if (!isNamedGlobalCall(node, keypointName)) return void 0;
|
|
22047
22081
|
if (node.arguments.length !== 2) return void 0;
|
|
22048
22082
|
const [timeArgument, valueArgument] = node.arguments;
|
|
22049
22083
|
/* v8 ignore next -- @preserve length was checked above; this only guards malformed AST tuples. */
|
|
@@ -22702,7 +22736,7 @@ function collectArguments(parameters) {
|
|
|
22702
22736
|
const preferUDim2Shorthand = defineRule({
|
|
22703
22737
|
create(context) {
|
|
22704
22738
|
return { NewExpression(node) {
|
|
22705
|
-
if (node
|
|
22739
|
+
if (!isNamedGlobalCall(node, "UDim2")) return;
|
|
22706
22740
|
const collected = collectArguments(node.arguments);
|
|
22707
22741
|
if (collected === void 0) return;
|
|
22708
22742
|
const [scaleXNode, offsetXNode, scaleYNode, offsetYNode] = node.arguments;
|
|
@@ -25198,7 +25232,6 @@ const EMPTY_CALLBACK_USAGE = {
|
|
|
25198
25232
|
memoization: false
|
|
25199
25233
|
};
|
|
25200
25234
|
const SHOULD_ASCEND_TYPES = new Set(["ConditionalExpression", "LogicalExpression"]);
|
|
25201
|
-
const IS_FUNCTION_EXPRESSION = new Set(["ArrowFunctionExpression", "FunctionExpression"]);
|
|
25202
25235
|
const CONTROL_FLOW_TYPES = new Set([
|
|
25203
25236
|
"BlockStatement",
|
|
25204
25237
|
"CatchClause",
|
|
@@ -25223,13 +25256,10 @@ function ascendPastWrappers(node) {
|
|
|
25223
25256
|
while (current !== void 0 && WRAPPER_PARENT_TYPES.has(current.type)) current = getParent(current);
|
|
25224
25257
|
return current;
|
|
25225
25258
|
}
|
|
25226
|
-
function isFunctionLikeNode(node) {
|
|
25227
|
-
return node.type === "ArrowFunctionExpression" || node.type === "FunctionExpression" || node.type === "FunctionDeclaration";
|
|
25228
|
-
}
|
|
25229
25259
|
function getEnclosingFunctionLike(node) {
|
|
25230
25260
|
let current = getParent(node);
|
|
25231
25261
|
while (current !== void 0) {
|
|
25232
|
-
if (
|
|
25262
|
+
if (isAnyFunction(current)) return current;
|
|
25233
25263
|
current = getParent(current);
|
|
25234
25264
|
}
|
|
25235
25265
|
}
|
|
@@ -25336,7 +25366,7 @@ function isFunctionReturnStatement(parent) {
|
|
|
25336
25366
|
while (currentNode !== void 0 && CONTROL_FLOW_TYPES.has(currentNode.type)) currentNode = ascendPastWrappers(getParent(currentNode));
|
|
25337
25367
|
/* v8 ignore next -- @preserve return statements that contain JSX are parser-nested inside a function body. */
|
|
25338
25368
|
if (currentNode === void 0) return false;
|
|
25339
|
-
return
|
|
25369
|
+
return isAnyFunction(currentNode);
|
|
25340
25370
|
}
|
|
25341
25371
|
function isTopLevelReturn(node) {
|
|
25342
25372
|
if (!isTopLevelFunctionReturn(node)) return false;
|
|
@@ -26116,11 +26146,6 @@ const strictComponentBoundaries = defineRule({
|
|
|
26116
26146
|
});
|
|
26117
26147
|
//#endregion
|
|
26118
26148
|
//#region src/rules/use-exhaustive-dependencies.ts
|
|
26119
|
-
const FUNCTION_DECLARATIONS = new Set([
|
|
26120
|
-
"ArrowFunctionExpression",
|
|
26121
|
-
"FunctionDeclaration",
|
|
26122
|
-
"FunctionExpression"
|
|
26123
|
-
]);
|
|
26124
26149
|
const UNSTABLE_VALUES = new Set([
|
|
26125
26150
|
"ArrayExpression",
|
|
26126
26151
|
"ArrowFunctionExpression",
|
|
@@ -26429,7 +26454,7 @@ function isDeclaredInComponentBody(variable, closureNode) {
|
|
|
26429
26454
|
/* v8 ignore next -- @preserve hook closure nodes are nested inside their containing component function. */
|
|
26430
26455
|
let parent = closureNode.parent ?? void 0;
|
|
26431
26456
|
while (parent) {
|
|
26432
|
-
if (
|
|
26457
|
+
if (isAnyFunction(parent)) {
|
|
26433
26458
|
const functionParent = parent;
|
|
26434
26459
|
if (variable.defs.some((definition) => {
|
|
26435
26460
|
if (definition.type !== "Parameter") return false;
|
|
@@ -26625,7 +26650,7 @@ function reportUnnecessaryDependency(context, dependencies, dependency, dependen
|
|
|
26625
26650
|
});
|
|
26626
26651
|
}
|
|
26627
26652
|
function isCallbackFunctionNode(node) {
|
|
26628
|
-
return node
|
|
26653
|
+
return node !== void 0 && isAnyFunction(node);
|
|
26629
26654
|
}
|
|
26630
26655
|
function getRequiredCaptures(captures, stableHooks) {
|
|
26631
26656
|
return captures.filter((capture) => capture.forceDependency || !isStableValue(capture.variable, capture.name, stableHooks));
|
|
@@ -26792,7 +26817,7 @@ const useExhaustiveDependencies = defineRule({
|
|
|
26792
26817
|
}
|
|
26793
26818
|
function resolveClosureFunction(closureArgument, callExpression) {
|
|
26794
26819
|
if (closureArgument.type === "ArrowFunctionExpression") return closureArgument;
|
|
26795
|
-
if (!(
|
|
26820
|
+
if (!(isAnyFunction(closureArgument) || closureArgument.type === "Identifier")) return void 0;
|
|
26796
26821
|
const resolved = resolveFunctionReference(closureArgument, getScope(callExpression));
|
|
26797
26822
|
return isCallbackFunctionNode(resolved) ? resolved : void 0;
|
|
26798
26823
|
}
|
|
@@ -26925,17 +26950,12 @@ function isHookCall(node) {
|
|
|
26925
26950
|
const hookName = getHookName$1(node);
|
|
26926
26951
|
return hookName !== void 0 && isReactHookName(hookName);
|
|
26927
26952
|
}
|
|
26928
|
-
const FUNCTION_BOUNDARIES = new Set([
|
|
26929
|
-
"ArrowFunctionExpression",
|
|
26930
|
-
"FunctionDeclaration",
|
|
26931
|
-
"FunctionExpression"
|
|
26932
|
-
]);
|
|
26933
26953
|
function isInFinallyBlock(node) {
|
|
26934
26954
|
let current = node.parent;
|
|
26935
26955
|
const maxDepth = 20;
|
|
26936
26956
|
let inFinallyBlock = false;
|
|
26937
26957
|
for (let depth = 0; depth < maxDepth && current !== null; depth += 1) {
|
|
26938
|
-
if (
|
|
26958
|
+
if (isAnyFunction(current)) break;
|
|
26939
26959
|
if (current.type === "TryStatement") {
|
|
26940
26960
|
let checkNode = node;
|
|
26941
26961
|
while (checkNode !== null && checkNode !== current) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pobammer-ts/small-rules",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.0",
|
|
4
4
|
"description": "Various Oxlint-native rules for linting roblox-ts projects.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"lint",
|
|
@@ -70,6 +70,7 @@
|
|
|
70
70
|
"dependencies": {
|
|
71
71
|
"arktype": "2.2.1",
|
|
72
72
|
"ignore": "7.0.5",
|
|
73
|
+
"minimatch": "10.2.5",
|
|
73
74
|
"oxc-parser": "0.138.0",
|
|
74
75
|
"oxc-resolver": "11.21.3",
|
|
75
76
|
"oxlint-plugin-utilities": "1.1.0"
|