oxlint-plugin-arch 0.13.0 → 0.13.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +71 -0
- package/README.md +7 -7
- package/dist/index.js +2154 -504
- package/dist/preset/groups/top.d.ts +2 -0
- package/dist/preset/preset-sets.d.ts +2 -0
- package/dist/preset/preset.constants.d.ts +4 -1
- package/dist/preset/preset.js +299 -57
- package/dist/preset/preset.utils.d.ts +2 -0
- package/dist/rules/code/code-inside.d.ts +1 -0
- package/dist/rules/effect/effect-layer-keys.d.ts +1 -0
- package/dist/rules/effect/effect-service-params.d.ts +1 -0
- package/dist/rules/effect/effect-yield-name.d.ts +1 -0
- package/dist/rules/effect/effect-yields-first.d.ts +1 -0
- package/dist/rules/files/files-siblings.d.ts +1 -0
- package/dist/rules/files/files-top-level.d.ts +1 -0
- package/dist/rules/layout/layout-type-arguments.d.ts +1 -0
- package/dist/rules/naming/naming-imports.d.ts +1 -0
- package/dist/rules/naming/naming-keys.d.ts +1 -0
- package/dist/rules/naming/naming-labels.d.ts +1 -0
- package/dist/rules/naming/naming-pairs.d.ts +1 -0
- package/dist/types/boundaries.types.d.ts +33 -1
- package/dist/types/code.types.d.ts +12 -0
- package/dist/types/comments.types.d.ts +1 -0
- package/dist/types/dillon-anti-slop.types.d.ts +6 -0
- package/dist/types/effect.types.d.ts +21 -0
- package/dist/types/files.types.d.ts +33 -3
- package/dist/types/layout.types.d.ts +16 -0
- package/dist/types/naming.types.d.ts +74 -2
- package/dist/types/preset.types.d.ts +26 -0
- package/dist/types/react.types.d.ts +13 -0
- package/dist/types/types.types.d.ts +4 -0
- package/dist/utils/ast.utils.d.ts +1 -2
- package/dist/utils/boundaries.utils.d.ts +72 -4
- package/dist/utils/naming.utils.d.ts +4 -1
- package/dist/utils/options.utils.d.ts +2 -0
- package/dist/vendor/dillon-anti-slop/index.js +40 -15
- package/package.json +1 -1
- package/src/vendor/dillon-anti-slop/UPSTREAM.md +3 -0
|
@@ -152,6 +152,12 @@ function optionsAssertMockingApis(patterns) {
|
|
|
152
152
|
throw new OptionsError("Test mocking APIs must be `*` or `<vi|jest|*>.<method|*>`.");
|
|
153
153
|
}
|
|
154
154
|
}
|
|
155
|
+
function optionsEscape(value) {
|
|
156
|
+
return value.replaceAll(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
157
|
+
}
|
|
158
|
+
function optionsWildcards(names) {
|
|
159
|
+
return [names ?? []].flat().map((name) => new RegExp(`^${name.split("*").map(optionsEscape).join(".*")}$`));
|
|
160
|
+
}
|
|
155
161
|
|
|
156
162
|
// src/utils/ast.utils.ts
|
|
157
163
|
var astSkippedKeys = new Set(["parent", "type", "start", "end", "range", "loc", "tokens", "comments"]);
|
|
@@ -339,9 +345,6 @@ function astIsInlineFunction(node) {
|
|
|
339
345
|
function astIsCall(node) {
|
|
340
346
|
return node.type === "CallExpression" || node.type === "NewExpression";
|
|
341
347
|
}
|
|
342
|
-
function astIsPipe(node) {
|
|
343
|
-
return node.callee.type === "MemberExpression" && astMemberName(node.callee) === "pipe";
|
|
344
|
-
}
|
|
345
348
|
function astChildren(node) {
|
|
346
349
|
return Object.entries(node).filter(([key]) => !astSkippedKeys.has(key)).map(([, child]) => child);
|
|
347
350
|
}
|
|
@@ -351,17 +354,20 @@ function astSome(value, test, enter = () => true) {
|
|
|
351
354
|
}
|
|
352
355
|
return astIsNode(value) && (test(value) || enter(value) && astChildren(value).some((child) => astSome(child, test, enter)));
|
|
353
356
|
}
|
|
354
|
-
function astCallDepth(value) {
|
|
357
|
+
function astCallDepth(value, callbacks = false) {
|
|
355
358
|
if (Array.isArray(value)) {
|
|
356
|
-
return Math.max(0, ...value.map(astCallDepth));
|
|
359
|
+
return Math.max(0, ...value.map((item) => astCallDepth(item, callbacks)));
|
|
357
360
|
}
|
|
358
|
-
if (!astIsNode(value)
|
|
361
|
+
if (!astIsNode(value)) {
|
|
359
362
|
return 0;
|
|
360
363
|
}
|
|
364
|
+
if (astIsInlineFunction(value)) {
|
|
365
|
+
return callbacks ? astCallDepth(value.body, callbacks) : 0;
|
|
366
|
+
}
|
|
361
367
|
if (astIsCall(value)) {
|
|
362
|
-
return Math.max(value.arguments.length === 0 ? 0 : 1 + astCallDepth(value.arguments), astCallDepth(value.callee));
|
|
368
|
+
return Math.max(value.arguments.length === 0 ? 0 : 1 + astCallDepth(value.arguments, callbacks), astCallDepth(value.callee, callbacks));
|
|
363
369
|
}
|
|
364
|
-
return astCallDepth(astChildren(value));
|
|
370
|
+
return astCallDepth(astChildren(value), callbacks);
|
|
365
371
|
}
|
|
366
372
|
|
|
367
373
|
// src/vendor/dillon-anti-slop/shared/type-reference-name.ts
|
|
@@ -1247,7 +1253,6 @@ var noRuntimeTypeofRule = defineRule8({
|
|
|
1247
1253
|
|
|
1248
1254
|
// src/vendor/dillon-anti-slop/rules/no-shape-in-symbol-names.ts
|
|
1249
1255
|
import { defineRule as defineRule9 } from "@oxlint/plugins";
|
|
1250
|
-
var FORBIDDEN_SYMBOL_NAME = "shape";
|
|
1251
1256
|
function namesForeignApi(node) {
|
|
1252
1257
|
const parent = node.parent;
|
|
1253
1258
|
if (!parent) {
|
|
@@ -1279,22 +1284,29 @@ var noForbiddenTermInSymbolNamesRule = defineRule9({
|
|
|
1279
1284
|
docs: {
|
|
1280
1285
|
description: 'Disallow the case-insensitive substring "shape" in JavaScript, TypeScript, private, and JSX symbol names.'
|
|
1281
1286
|
},
|
|
1287
|
+
schema: [{ type: "object", additionalProperties: false, properties: { terms: { type: "array", items: { type: "string", minLength: 1 }, minItems: 1 } } }],
|
|
1282
1288
|
messages: {
|
|
1283
|
-
forbiddenSymbolName: 'Rename symbol "{{name}}" for its domain role; "
|
|
1289
|
+
forbiddenSymbolName: 'Rename symbol "{{name}}" for its domain role; "{{term}}" describes structure rather than ownership.'
|
|
1284
1290
|
}
|
|
1285
1291
|
},
|
|
1286
1292
|
createOnce(context) {
|
|
1293
|
+
let terms = [];
|
|
1287
1294
|
const reportForbiddenSymbolName = (node) => {
|
|
1288
|
-
|
|
1295
|
+
const lower = node.name.toLowerCase();
|
|
1296
|
+
const term = terms.find((candidate) => lower.includes(candidate));
|
|
1297
|
+
if (term === undefined || namesForeignApi(node)) {
|
|
1289
1298
|
return;
|
|
1290
1299
|
}
|
|
1291
1300
|
context.report({
|
|
1292
1301
|
node,
|
|
1293
1302
|
messageId: "forbiddenSymbolName",
|
|
1294
|
-
data: { name: node.name }
|
|
1303
|
+
data: { name: node.name, term }
|
|
1295
1304
|
});
|
|
1296
1305
|
};
|
|
1297
1306
|
return {
|
|
1307
|
+
before() {
|
|
1308
|
+
terms = (optionsFirst(context, {}).terms ?? ["shape"]).map((term) => term.toLowerCase());
|
|
1309
|
+
},
|
|
1298
1310
|
Identifier: reportForbiddenSymbolName,
|
|
1299
1311
|
PrivateIdentifier: reportForbiddenSymbolName,
|
|
1300
1312
|
JSXIdentifier: reportForbiddenSymbolName
|
|
@@ -1750,18 +1762,22 @@ var requireSafetyCommentForTypeAssertionRule = defineRule15({
|
|
|
1750
1762
|
docs: {
|
|
1751
1763
|
description: "Require a nearby SAFETY comment for every TypeScript type assertion except const assertions."
|
|
1752
1764
|
},
|
|
1765
|
+
schema: [{ type: "object", additionalProperties: false, properties: { comment: { type: "string", minLength: 1 } } }],
|
|
1753
1766
|
messages: {
|
|
1754
|
-
missingSafetyComment: "This type assertion has no `
|
|
1767
|
+
missingSafetyComment: "This type assertion has no `{{comment}}` justification. State the checked invariant immediately before the assertion or its containing statement."
|
|
1755
1768
|
}
|
|
1756
1769
|
},
|
|
1757
1770
|
createOnce(context) {
|
|
1771
|
+
let comment = "SAFETY:";
|
|
1772
|
+
let marker = /(?<![\p{L}\p{N}_])SAFETY\s*:/u;
|
|
1758
1773
|
const checkAssertion = (node) => {
|
|
1759
1774
|
if (expressionsIsConstAssertion(node)) {
|
|
1760
1775
|
return;
|
|
1761
1776
|
}
|
|
1762
1777
|
let current = node;
|
|
1778
|
+
const justified = (candidate) => candidate.end <= node.start && marker.test(candidate.value);
|
|
1763
1779
|
for (;; ) {
|
|
1764
|
-
if (context.sourceCode.getCommentsBefore(current).some(
|
|
1780
|
+
if (context.sourceCode.getCommentsBefore(current).some(justified)) {
|
|
1765
1781
|
return;
|
|
1766
1782
|
}
|
|
1767
1783
|
const parent = current.parent;
|
|
@@ -1770,9 +1786,18 @@ var requireSafetyCommentForTypeAssertionRule = defineRule15({
|
|
|
1770
1786
|
}
|
|
1771
1787
|
current = parent;
|
|
1772
1788
|
}
|
|
1773
|
-
context.report({
|
|
1789
|
+
context.report({
|
|
1790
|
+
node,
|
|
1791
|
+
messageId: "missingSafetyComment",
|
|
1792
|
+
data: { comment }
|
|
1793
|
+
});
|
|
1774
1794
|
};
|
|
1775
1795
|
return {
|
|
1796
|
+
before() {
|
|
1797
|
+
comment = optionsFirst(context, {}).comment ?? "SAFETY:";
|
|
1798
|
+
const word = optionsEscape(comment.replace(/:\s*$/, ""));
|
|
1799
|
+
marker = new RegExp(`(?<![\\p{L}\\p{N}_])${word}\\s*:`, "u");
|
|
1800
|
+
},
|
|
1776
1801
|
TSAsExpression: checkAssertion,
|
|
1777
1802
|
TSTypeAssertion: checkAssertion
|
|
1778
1803
|
};
|
package/package.json
CHANGED
|
@@ -14,6 +14,9 @@ The TanStack preset selects the enabled rules; this directory implements them
|
|
|
14
14
|
and is not a separate preset. Upstream intentionally distributes source for
|
|
15
15
|
vendoring and does not publish an official npm package.
|
|
16
16
|
|
|
17
|
+
Local options: `terms` on `no-shape-in-symbol-names` and `comment` on
|
|
18
|
+
`require-safety-comment-for-type-assertion`; their defaults keep upstream behavior.
|
|
19
|
+
|
|
17
20
|
Local behavior fixes recognize `SAFETY:` comments on exported declarations and
|
|
18
21
|
export-default assertions, while retaining statement boundaries for other
|
|
19
22
|
assertions.
|