oxlint-plugin-arch 0.13.1 → 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 +40 -0
- package/README.md +6 -6
- package/dist/index.js +1411 -267
- 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 +0 -1
- package/dist/preset/preset.js +251 -41
- package/dist/preset/preset.utils.d.ts +1 -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/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 +7 -0
- package/dist/types/code.types.d.ts +11 -0
- package/dist/types/effect.types.d.ts +20 -0
- package/dist/types/files.types.d.ts +33 -3
- package/dist/types/naming.types.d.ts +70 -2
- package/dist/types/preset.types.d.ts +26 -0
- package/dist/utils/naming.utils.d.ts +4 -1
- package/dist/utils/options.utils.d.ts +1 -0
- package/dist/vendor/dillon-anti-slop/index.js +3 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -53,6 +53,9 @@ function optionsAssertMockingApis(patterns) {
|
|
|
53
53
|
function optionsEscape(value) {
|
|
54
54
|
return value.replaceAll(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
55
55
|
}
|
|
56
|
+
function optionsWildcards(names) {
|
|
57
|
+
return [names ?? []].flat().map((name) => new RegExp(`^${name.split("*").map(optionsEscape).join(".*")}$`));
|
|
58
|
+
}
|
|
56
59
|
|
|
57
60
|
// src/utils/ast.utils.ts
|
|
58
61
|
var astSkippedKeys = new Set(["parent", "type", "start", "end", "range", "loc", "tokens", "comments"]);
|
|
@@ -458,7 +461,8 @@ var namingStemSchemaProperties = {
|
|
|
458
461
|
roles: { type: "array", items: { type: "string" } },
|
|
459
462
|
separators: { type: "array", items: { type: "string" } },
|
|
460
463
|
normalize: { type: "string", enum: ["remove-separators", "none"] },
|
|
461
|
-
singularize: { type: "string", enum: ["none", "trailing-s"] }
|
|
464
|
+
singularize: { type: "string", enum: ["none", "trailing-s"] },
|
|
465
|
+
prefix: { type: "array", items: { type: "string", enum: ["file", "folder", "parent"] }, minItems: 1 }
|
|
462
466
|
};
|
|
463
467
|
function namingBasename(filePath) {
|
|
464
468
|
return posix.basename(filePath.replaceAll("\\", "/"));
|
|
@@ -485,17 +489,73 @@ function namingFileStem(basename, mode = "before-first-dot", trailingRoles = [],
|
|
|
485
489
|
}
|
|
486
490
|
return stem;
|
|
487
491
|
}
|
|
492
|
+
function namingSingular(value) {
|
|
493
|
+
const parts = value.split(/[-_]+/).filter(Boolean);
|
|
494
|
+
const last = parts.at(-1) ?? "";
|
|
495
|
+
return last.endsWith("s") && last.length > 1 ? [...parts.slice(0, -1), last.slice(0, -1)].join("-") : value;
|
|
496
|
+
}
|
|
497
|
+
function namingFolders(filename) {
|
|
498
|
+
return filename.replaceAll("\\", "/").split("/").slice(0, -1).toReversed();
|
|
499
|
+
}
|
|
488
500
|
function namingFilePrefixesFor(filename, options) {
|
|
489
501
|
const basename = namingBasename(filename).replace(/\.(tsx?|jsx?)$/, "");
|
|
490
|
-
const
|
|
502
|
+
const [folder = "", parent = ""] = namingFolders(filename);
|
|
491
503
|
const normalize = options.normalize ?? "remove-separators";
|
|
492
|
-
const
|
|
493
|
-
const
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
504
|
+
const sources = { file: namingFileStem(basename, options.stem, options.roles, options.separators), folder, parent };
|
|
505
|
+
const prefixes = (options.prefix ?? ["file"]).flatMap((source) => {
|
|
506
|
+
const stem = sources[source];
|
|
507
|
+
return options.singularize === "trailing-s" ? [stem, namingSingular(stem)] : [stem];
|
|
508
|
+
});
|
|
509
|
+
return [...new Set(prefixes.map((stem) => namingNormalized(stem, normalize)).filter(Boolean))];
|
|
510
|
+
}
|
|
511
|
+
function namingTemplatePattern(template, placeholder = "[a-z0-9-]+") {
|
|
512
|
+
const seen = new Set;
|
|
513
|
+
const source = template.split(/(\{[^{}]+\})/).map((part) => {
|
|
514
|
+
const name = /^\{[^{}]+\}$/.test(part) ? part.slice(1, -1) : undefined;
|
|
515
|
+
if (name === undefined) {
|
|
516
|
+
return part.replaceAll(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
517
|
+
}
|
|
518
|
+
const again = seen.has(name);
|
|
519
|
+
seen.add(name);
|
|
520
|
+
return again ? `\\k<${name}>` : `(?<${name}>${placeholder})`;
|
|
521
|
+
}).join("");
|
|
522
|
+
try {
|
|
523
|
+
return new RegExp(`^${source}$`);
|
|
524
|
+
} catch {
|
|
525
|
+
return null;
|
|
497
526
|
}
|
|
498
|
-
|
|
527
|
+
}
|
|
528
|
+
function namingCaptures(filename, options = {}) {
|
|
529
|
+
const path = filename.replaceAll("\\", "/");
|
|
530
|
+
const file = namingBasename(path).replace(/\.(tsx?|jsx?)$/, "");
|
|
531
|
+
const [folder = "", parent = ""] = namingFolders(path);
|
|
532
|
+
const stem = namingFileStem(file, options.stem === "folder" ? undefined : options.stem, options.roles, options.separators);
|
|
533
|
+
const read = options.stem === "folder" ? folder : stem;
|
|
534
|
+
const last = read.split(/[-_]+/).at(-1) ?? "";
|
|
535
|
+
const domain = options.singularize === "trailing-s" && last.length > 1 && last.endsWith("s") ? read.slice(0, -1) : read;
|
|
536
|
+
const builtIn = { file, stem, folder, parent, domain };
|
|
537
|
+
if (options.file === undefined) {
|
|
538
|
+
return builtIn;
|
|
539
|
+
}
|
|
540
|
+
const depth = options.file.split("/").length;
|
|
541
|
+
const match = namingTemplatePattern(options.file, options.placeholder)?.exec(path.split("/").slice(-depth).join("/"));
|
|
542
|
+
return match ? { ...builtIn, ...match.groups } : null;
|
|
543
|
+
}
|
|
544
|
+
function namingExpand(template, captures, camelCase, escape = (value) => value) {
|
|
545
|
+
return template.replaceAll(/\{([A-Za-z][A-Za-z0-9]*)\}/g, (placeholder, key) => {
|
|
546
|
+
const name = key.toLowerCase();
|
|
547
|
+
if (!Object.hasOwn(captures, name)) {
|
|
548
|
+
return placeholder;
|
|
549
|
+
}
|
|
550
|
+
const value = captures[name];
|
|
551
|
+
if (key.length > 1 && key === key.toUpperCase()) {
|
|
552
|
+
return escape(value.split(/[-_\s.]+/).filter(Boolean).join("_").toUpperCase());
|
|
553
|
+
}
|
|
554
|
+
if (/^[A-Z]/.test(key)) {
|
|
555
|
+
return escape(namingPascalCase(value));
|
|
556
|
+
}
|
|
557
|
+
return escape(camelCase ? namingCamelCase(value) : value);
|
|
558
|
+
});
|
|
499
559
|
}
|
|
500
560
|
function namingHasFilePrefix(name, prefixes, normalize) {
|
|
501
561
|
const comparable = normalize === "none" ? name : name.replaceAll("_", "").toLowerCase();
|
|
@@ -1123,7 +1183,17 @@ var boundariesDeny = defineRule6({
|
|
|
1123
1183
|
additionalProperties: false,
|
|
1124
1184
|
properties: {
|
|
1125
1185
|
imports: { type: "object", additionalProperties: { type: "string" } },
|
|
1126
|
-
calls: { type: "object", additionalProperties: { type: "string" } }
|
|
1186
|
+
calls: { type: "object", additionalProperties: { type: "string" } },
|
|
1187
|
+
only: {
|
|
1188
|
+
type: "array",
|
|
1189
|
+
items: {
|
|
1190
|
+
type: "object",
|
|
1191
|
+
additionalProperties: false,
|
|
1192
|
+
properties: { imports: optionsPatternSchema, calls: optionsPatternSchema, in: optionsPatternSchema, message: { type: "string" } },
|
|
1193
|
+
required: ["in"],
|
|
1194
|
+
anyOf: [{ required: ["imports"] }, { required: ["calls"] }]
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1127
1197
|
}
|
|
1128
1198
|
}
|
|
1129
1199
|
],
|
|
@@ -1148,8 +1218,17 @@ var boundariesDeny = defineRule6({
|
|
|
1148
1218
|
return {
|
|
1149
1219
|
before() {
|
|
1150
1220
|
const options = optionsFirst(context, {});
|
|
1151
|
-
|
|
1152
|
-
|
|
1221
|
+
const filename = context.filename.replaceAll("\\", "/");
|
|
1222
|
+
const elsewhere = (options.only ?? []).filter((entry) => ![entry.in].flat().some((place) => optionsGlob(`**/${place}{,/**}`).test(filename)));
|
|
1223
|
+
const owned = (entry) => ` ${entry.message ?? `Only ${[entry.in].flat().join(", ")} may use it.`}`;
|
|
1224
|
+
imports = [
|
|
1225
|
+
...Object.entries(options.imports ?? {}).map(([pattern, message]) => [optionsGlob(pattern), message && ` ${message}`]),
|
|
1226
|
+
...elsewhere.flatMap((entry) => [entry.imports ?? []].flat().map((pattern) => [optionsGlob(pattern), owned(entry)]))
|
|
1227
|
+
];
|
|
1228
|
+
calls = new Map([
|
|
1229
|
+
...elsewhere.flatMap((entry) => [entry.calls ?? []].flat().map((name) => [name, owned(entry)])),
|
|
1230
|
+
...Object.entries(options.calls ?? {}).map(([name, message]) => [name, message && ` ${message}`])
|
|
1231
|
+
]);
|
|
1153
1232
|
if (imports.length === 0 && calls.size === 0) {
|
|
1154
1233
|
return false;
|
|
1155
1234
|
}
|
|
@@ -2432,9 +2511,85 @@ var codeInline = defineRule16({
|
|
|
2432
2511
|
}
|
|
2433
2512
|
});
|
|
2434
2513
|
|
|
2435
|
-
// src/rules/code/code-
|
|
2514
|
+
// src/rules/code/code-inside.ts
|
|
2436
2515
|
import { defineRule as defineRule17 } from "@oxlint/plugins";
|
|
2437
|
-
|
|
2516
|
+
function codeInsideOwners(node) {
|
|
2517
|
+
const parent = node.parent;
|
|
2518
|
+
if (!parent) {
|
|
2519
|
+
return [];
|
|
2520
|
+
}
|
|
2521
|
+
const callback = node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression";
|
|
2522
|
+
const owner = callback && astIsCall(parent) && parent.arguments.some((item) => item === node) ? astDottedName(parent.callee) : undefined;
|
|
2523
|
+
return [...owner === undefined ? [] : [owner], ...codeInsideOwners(parent)];
|
|
2524
|
+
}
|
|
2525
|
+
var codeInside = defineRule17({
|
|
2526
|
+
meta: {
|
|
2527
|
+
type: "problem",
|
|
2528
|
+
schema: [
|
|
2529
|
+
{
|
|
2530
|
+
type: "object",
|
|
2531
|
+
additionalProperties: false,
|
|
2532
|
+
properties: {
|
|
2533
|
+
inside: {
|
|
2534
|
+
type: "array",
|
|
2535
|
+
items: {
|
|
2536
|
+
type: "object",
|
|
2537
|
+
additionalProperties: false,
|
|
2538
|
+
properties: {
|
|
2539
|
+
callee: optionsPatternSchema,
|
|
2540
|
+
calls: { type: "object", additionalProperties: { type: "string" } }
|
|
2541
|
+
},
|
|
2542
|
+
required: ["callee", "calls"]
|
|
2543
|
+
}
|
|
2544
|
+
}
|
|
2545
|
+
},
|
|
2546
|
+
required: ["inside"]
|
|
2547
|
+
}
|
|
2548
|
+
],
|
|
2549
|
+
messages: {
|
|
2550
|
+
inside: "Do not call '{{name}}' inside {{owner}}.{{message}}"
|
|
2551
|
+
}
|
|
2552
|
+
},
|
|
2553
|
+
createOnce(context) {
|
|
2554
|
+
let entries = [];
|
|
2555
|
+
return {
|
|
2556
|
+
before() {
|
|
2557
|
+
entries = optionsFirst(context, { inside: [] }).inside.map((entry) => ({
|
|
2558
|
+
callees: optionsWildcards(entry.callee),
|
|
2559
|
+
calls: Object.entries(entry.calls).map(([name, message]) => [optionsWildcards(name)[0], message && ` ${message}`])
|
|
2560
|
+
}));
|
|
2561
|
+
if (entries.length === 0) {
|
|
2562
|
+
return false;
|
|
2563
|
+
}
|
|
2564
|
+
},
|
|
2565
|
+
CallExpression(node) {
|
|
2566
|
+
const name = astDottedName(node.callee);
|
|
2567
|
+
if (name === undefined) {
|
|
2568
|
+
return;
|
|
2569
|
+
}
|
|
2570
|
+
const banned = entries.flatMap(({ callees, calls }) => calls.flatMap(([pattern, message]) => pattern.test(name) ? [{ callees, message }] : []));
|
|
2571
|
+
if (banned.length === 0) {
|
|
2572
|
+
return;
|
|
2573
|
+
}
|
|
2574
|
+
const owners = codeInsideOwners(node);
|
|
2575
|
+
for (const { callees, message } of banned) {
|
|
2576
|
+
const owner = owners.find((item) => optionsPatternsTest(callees, item));
|
|
2577
|
+
if (owner !== undefined) {
|
|
2578
|
+
context.report({
|
|
2579
|
+
node: node.callee,
|
|
2580
|
+
messageId: "inside",
|
|
2581
|
+
data: { name, owner, message }
|
|
2582
|
+
});
|
|
2583
|
+
}
|
|
2584
|
+
}
|
|
2585
|
+
}
|
|
2586
|
+
};
|
|
2587
|
+
}
|
|
2588
|
+
});
|
|
2589
|
+
|
|
2590
|
+
// src/rules/code/code-justified-call.ts
|
|
2591
|
+
import { defineRule as defineRule18 } from "@oxlint/plugins";
|
|
2592
|
+
var codeJustifiedCall = defineRule18({
|
|
2438
2593
|
meta: {
|
|
2439
2594
|
type: "problem",
|
|
2440
2595
|
schema: [
|
|
@@ -2488,8 +2643,8 @@ var codeJustifiedCall = defineRule17({
|
|
|
2488
2643
|
});
|
|
2489
2644
|
|
|
2490
2645
|
// src/rules/code/code-literal-in.ts
|
|
2491
|
-
import { defineRule as
|
|
2492
|
-
var codeLiteralIn =
|
|
2646
|
+
import { defineRule as defineRule19 } from "@oxlint/plugins";
|
|
2647
|
+
var codeLiteralIn = defineRule19({
|
|
2493
2648
|
meta: {
|
|
2494
2649
|
type: "suggestion",
|
|
2495
2650
|
schema: [
|
|
@@ -2530,7 +2685,7 @@ var codeLiteralIn = defineRule18({
|
|
|
2530
2685
|
});
|
|
2531
2686
|
|
|
2532
2687
|
// src/rules/code/code-mutable-state.ts
|
|
2533
|
-
import { defineRule as
|
|
2688
|
+
import { defineRule as defineRule20 } from "@oxlint/plugins";
|
|
2534
2689
|
var functionScopes = new Set([
|
|
2535
2690
|
"FunctionDeclaration",
|
|
2536
2691
|
"FunctionExpression",
|
|
@@ -2547,7 +2702,7 @@ function hasAncestor(node, test) {
|
|
|
2547
2702
|
}
|
|
2548
2703
|
return false;
|
|
2549
2704
|
}
|
|
2550
|
-
var codeMutableState =
|
|
2705
|
+
var codeMutableState = defineRule20({
|
|
2551
2706
|
meta: {
|
|
2552
2707
|
type: "problem",
|
|
2553
2708
|
schema: [
|
|
@@ -2605,7 +2760,7 @@ var codeMutableState = defineRule19({
|
|
|
2605
2760
|
});
|
|
2606
2761
|
|
|
2607
2762
|
// src/rules/code/code-object-params.ts
|
|
2608
|
-
import { defineRule as
|
|
2763
|
+
import { defineRule as defineRule21 } from "@oxlint/plugins";
|
|
2609
2764
|
function isObjectParam(node) {
|
|
2610
2765
|
if (node.type === "ObjectPattern") {
|
|
2611
2766
|
return true;
|
|
@@ -2619,7 +2774,7 @@ function isObjectParam(node) {
|
|
|
2619
2774
|
const annotation = node.typeAnnotation?.typeAnnotation;
|
|
2620
2775
|
return !annotation || annotation.type === "TSTypeReference" || annotation.type === "TSTypeLiteral" || annotation.type === "TSIntersectionType";
|
|
2621
2776
|
}
|
|
2622
|
-
var codeObjectParams =
|
|
2777
|
+
var codeObjectParams = defineRule21({
|
|
2623
2778
|
meta: {
|
|
2624
2779
|
type: "problem",
|
|
2625
2780
|
schema: [
|
|
@@ -2668,8 +2823,8 @@ var codeObjectParams = defineRule20({
|
|
|
2668
2823
|
});
|
|
2669
2824
|
|
|
2670
2825
|
// src/rules/code/code-paired-call.ts
|
|
2671
|
-
import { defineRule as
|
|
2672
|
-
var codePairedCall =
|
|
2826
|
+
import { defineRule as defineRule22 } from "@oxlint/plugins";
|
|
2827
|
+
var codePairedCall = defineRule22({
|
|
2673
2828
|
meta: {
|
|
2674
2829
|
type: "problem",
|
|
2675
2830
|
schema: [
|
|
@@ -2736,7 +2891,7 @@ var codePairedCall = defineRule21({
|
|
|
2736
2891
|
});
|
|
2737
2892
|
|
|
2738
2893
|
// src/rules/code/code-promise-mutation.ts
|
|
2739
|
-
import { defineRule as
|
|
2894
|
+
import { defineRule as defineRule23 } from "@oxlint/plugins";
|
|
2740
2895
|
function mutationBinding(node) {
|
|
2741
2896
|
if (node.type === "Identifier") {
|
|
2742
2897
|
return node;
|
|
@@ -2765,7 +2920,7 @@ function mutationBindings(node) {
|
|
|
2765
2920
|
const binding = mutationBinding(node);
|
|
2766
2921
|
return binding ? [binding] : [];
|
|
2767
2922
|
}
|
|
2768
|
-
var codePromiseMutation =
|
|
2923
|
+
var codePromiseMutation = defineRule23({
|
|
2769
2924
|
meta: {
|
|
2770
2925
|
type: "problem",
|
|
2771
2926
|
schema: [
|
|
@@ -2858,8 +3013,8 @@ var codePromiseMutation = defineRule22({
|
|
|
2858
3013
|
var codeSwitch = astSelectorRule("SwitchStatement", "Avoid switch statements.");
|
|
2859
3014
|
|
|
2860
3015
|
// src/rules/code/code-traced.ts
|
|
2861
|
-
import { defineRule as
|
|
2862
|
-
var codeTraced =
|
|
3016
|
+
import { defineRule as defineRule24 } from "@oxlint/plugins";
|
|
3017
|
+
var codeTraced = defineRule24({
|
|
2863
3018
|
meta: {
|
|
2864
3019
|
type: "problem",
|
|
2865
3020
|
schema: [
|
|
@@ -2946,7 +3101,7 @@ var codeTraced = defineRule23({
|
|
|
2946
3101
|
});
|
|
2947
3102
|
|
|
2948
3103
|
// src/rules/code/code-trivial-functions.ts
|
|
2949
|
-
import { defineRule as
|
|
3104
|
+
import { defineRule as defineRule25 } from "@oxlint/plugins";
|
|
2950
3105
|
var codeTrivialFunctionsBanned = [
|
|
2951
3106
|
"isRecord",
|
|
2952
3107
|
"isPlainObject",
|
|
@@ -3104,7 +3259,7 @@ function codeTrivialFunctionsDefaults(program) {
|
|
|
3104
3259
|
}
|
|
3105
3260
|
return starts;
|
|
3106
3261
|
}
|
|
3107
|
-
var codeTrivialFunctions =
|
|
3262
|
+
var codeTrivialFunctions = defineRule25({
|
|
3108
3263
|
meta: {
|
|
3109
3264
|
type: "problem",
|
|
3110
3265
|
schema: [
|
|
@@ -3246,8 +3401,8 @@ var codeTrivialFunctions = defineRule24({
|
|
|
3246
3401
|
});
|
|
3247
3402
|
|
|
3248
3403
|
// src/rules/code/code-yield-argument.ts
|
|
3249
|
-
import { defineRule as
|
|
3250
|
-
var codeYieldArgument =
|
|
3404
|
+
import { defineRule as defineRule26 } from "@oxlint/plugins";
|
|
3405
|
+
var codeYieldArgument = defineRule26({
|
|
3251
3406
|
meta: {
|
|
3252
3407
|
type: "suggestion",
|
|
3253
3408
|
messages: {
|
|
@@ -3269,7 +3424,7 @@ var codeYieldArgument = defineRule25({
|
|
|
3269
3424
|
});
|
|
3270
3425
|
|
|
3271
3426
|
// src/rules/comments/comments-code.ts
|
|
3272
|
-
import { defineRule as
|
|
3427
|
+
import { defineRule as defineRule27 } from "@oxlint/plugins";
|
|
3273
3428
|
var commentsLineGap = /^[\t \r\n\u2028\u2029]*$/;
|
|
3274
3429
|
var commentsLineTerminator = /\r\n|[\n\r\u2028\u2029]/;
|
|
3275
3430
|
var commentsUnicodeTerminator = /[\u2028\u2029]/;
|
|
@@ -3320,7 +3475,7 @@ function commentsFollowsOpeningBrace(text, offset) {
|
|
|
3320
3475
|
}
|
|
3321
3476
|
return false;
|
|
3322
3477
|
}
|
|
3323
|
-
var commentsCode =
|
|
3478
|
+
var commentsCode = defineRule27({
|
|
3324
3479
|
meta: {
|
|
3325
3480
|
type: "suggestion",
|
|
3326
3481
|
fixable: "code",
|
|
@@ -3523,9 +3678,9 @@ var commentsCode = defineRule26({
|
|
|
3523
3678
|
});
|
|
3524
3679
|
|
|
3525
3680
|
// src/rules/comments/comments-directives.ts
|
|
3526
|
-
import { defineRule as
|
|
3681
|
+
import { defineRule as defineRule28 } from "@oxlint/plugins";
|
|
3527
3682
|
var directive = /^\s*(?:oxlint|eslint)-disable(?:-next-line|-line)?\b(.*)$/s;
|
|
3528
|
-
var commentsDirectives =
|
|
3683
|
+
var commentsDirectives = defineRule28({
|
|
3529
3684
|
meta: {
|
|
3530
3685
|
type: "problem",
|
|
3531
3686
|
schema: [],
|
|
@@ -3553,9 +3708,9 @@ var commentsDirectives = defineRule27({
|
|
|
3553
3708
|
});
|
|
3554
3709
|
|
|
3555
3710
|
// src/rules/copy/copy-dashes.ts
|
|
3556
|
-
import { defineRule as
|
|
3711
|
+
import { defineRule as defineRule29 } from "@oxlint/plugins";
|
|
3557
3712
|
var copyDashesMessage = "Use a comma, colon, period or parentheses instead.";
|
|
3558
|
-
var copyDashes =
|
|
3713
|
+
var copyDashes = defineRule29({
|
|
3559
3714
|
meta: {
|
|
3560
3715
|
type: "suggestion",
|
|
3561
3716
|
schema: [
|
|
@@ -3611,7 +3766,7 @@ var copyDashes = defineRule28({
|
|
|
3611
3766
|
});
|
|
3612
3767
|
|
|
3613
3768
|
// src/rules/effect/effect-layer-file.ts
|
|
3614
|
-
import { defineRule as
|
|
3769
|
+
import { defineRule as defineRule30 } from "@oxlint/plugins";
|
|
3615
3770
|
|
|
3616
3771
|
// src/utils/effect.utils.ts
|
|
3617
3772
|
var effectBuilders = ["Effect.gen", "Effect.fn", "Effect.fnUntraced"];
|
|
@@ -3653,7 +3808,7 @@ var effectLayerFileDefaultConstructors = [
|
|
|
3653
3808
|
"Layer.sync",
|
|
3654
3809
|
"Layer.unwrap"
|
|
3655
3810
|
];
|
|
3656
|
-
var effectLayerFile =
|
|
3811
|
+
var effectLayerFile = defineRule30({
|
|
3657
3812
|
meta: {
|
|
3658
3813
|
type: "problem",
|
|
3659
3814
|
schema: [
|
|
@@ -3819,8 +3974,138 @@ var effectLayerFile = defineRule29({
|
|
|
3819
3974
|
}
|
|
3820
3975
|
});
|
|
3821
3976
|
|
|
3977
|
+
// src/rules/effect/effect-layer-keys.ts
|
|
3978
|
+
import { defineRule as defineRule31 } from "@oxlint/plugins";
|
|
3979
|
+
import { readFileSync } from "node:fs";
|
|
3980
|
+
var effectLayerKeysPairs = new Map([["{", "}"], ["(", ")"], ["[", "]"], ["<", ">"]]);
|
|
3981
|
+
function effectLayerKeysDeclared(text, declaration) {
|
|
3982
|
+
const code = text.replaceAll(/\/\*[\s\S]*?\*\/|\/\/[^\n]*|'(?:[^'\\\n]|\\.)*'|"(?:[^"\\\n]|\\.)*"/g, " ");
|
|
3983
|
+
const start = code.indexOf(`${declaration}<`);
|
|
3984
|
+
const open = start === -1 ? -1 : code.indexOf("{", start);
|
|
3985
|
+
if (open === -1) {
|
|
3986
|
+
return null;
|
|
3987
|
+
}
|
|
3988
|
+
const paths = [];
|
|
3989
|
+
const frames = [{ open: "{", members: 0 }];
|
|
3990
|
+
const key = /\s*(?:readonly\s+)?([A-Za-z_$][\w$]*)\??\s*(?=[:(<])/y;
|
|
3991
|
+
let fresh = true;
|
|
3992
|
+
for (let index = open + 1;index < code.length && frames.length > 0; index += 1) {
|
|
3993
|
+
const char = code[index];
|
|
3994
|
+
const members = frames.every((frame) => frame.open === "{");
|
|
3995
|
+
key.lastIndex = index;
|
|
3996
|
+
const match = fresh && members ? key.exec(code) : null;
|
|
3997
|
+
if (match) {
|
|
3998
|
+
const rest = code.slice(key.lastIndex).replace(/^:\s*/, "");
|
|
3999
|
+
const path = [...frames.flatMap((frame) => frame.key ?? []), match[1]].join(".");
|
|
4000
|
+
const parent = frames.at(-1);
|
|
4001
|
+
if (parent) {
|
|
4002
|
+
parent.members += 1;
|
|
4003
|
+
}
|
|
4004
|
+
if (rest.startsWith("{")) {
|
|
4005
|
+
frames.push({
|
|
4006
|
+
open: "{",
|
|
4007
|
+
key: match[1],
|
|
4008
|
+
members: 0
|
|
4009
|
+
});
|
|
4010
|
+
index = code.length - rest.length;
|
|
4011
|
+
} else {
|
|
4012
|
+
paths.push(path);
|
|
4013
|
+
fresh = false;
|
|
4014
|
+
index = key.lastIndex - 1;
|
|
4015
|
+
}
|
|
4016
|
+
continue;
|
|
4017
|
+
}
|
|
4018
|
+
if (effectLayerKeysPairs.has(char)) {
|
|
4019
|
+
frames.push({ open: char, members: 0 });
|
|
4020
|
+
} else if (char === effectLayerKeysPairs.get(frames.at(-1)?.open ?? "") && !(char === ">" && code[index - 1] === "=")) {
|
|
4021
|
+
const closed = frames.pop();
|
|
4022
|
+
if (closed?.key !== undefined && closed.members === 0) {
|
|
4023
|
+
paths.push([...frames.flatMap((frame) => frame.key ?? []), closed.key].join("."));
|
|
4024
|
+
}
|
|
4025
|
+
}
|
|
4026
|
+
fresh = members && (char === "{" || char === ";" || char === "," || char === "}" || fresh && /\s/.test(char));
|
|
4027
|
+
}
|
|
4028
|
+
return paths;
|
|
4029
|
+
}
|
|
4030
|
+
function effectLayerKeysBound(object, path) {
|
|
4031
|
+
return object.properties.flatMap((property) => {
|
|
4032
|
+
const key = declarationsPropertyName(property);
|
|
4033
|
+
if (property.type !== "Property" || key === undefined) {
|
|
4034
|
+
return [];
|
|
4035
|
+
}
|
|
4036
|
+
return property.value.type === "ObjectExpression" ? effectLayerKeysBound(property.value, [...path, key]) : [[[...path, key].join("."), property]];
|
|
4037
|
+
});
|
|
4038
|
+
}
|
|
4039
|
+
var effectLayerKeys = defineRule31({
|
|
4040
|
+
meta: {
|
|
4041
|
+
type: "problem",
|
|
4042
|
+
schema: [
|
|
4043
|
+
{
|
|
4044
|
+
type: "object",
|
|
4045
|
+
additionalProperties: false,
|
|
4046
|
+
properties: {
|
|
4047
|
+
service: { type: "string", minLength: 1 },
|
|
4048
|
+
callees: { type: "array", items: { type: "string" }, minItems: 1 },
|
|
4049
|
+
declaration: { type: "string", minLength: 1 }
|
|
4050
|
+
},
|
|
4051
|
+
required: ["service"]
|
|
4052
|
+
}
|
|
4053
|
+
],
|
|
4054
|
+
messages: {
|
|
4055
|
+
extra: "'{{path}}' is not a method of the service declared in {{file}}.",
|
|
4056
|
+
missing: "The service in {{file}} declares {{paths}}, which this layer does not bind."
|
|
4057
|
+
}
|
|
4058
|
+
},
|
|
4059
|
+
createOnce(context) {
|
|
4060
|
+
let declared = null;
|
|
4061
|
+
let callees = [];
|
|
4062
|
+
let file = "";
|
|
4063
|
+
return {
|
|
4064
|
+
before() {
|
|
4065
|
+
const options = optionsFirst(context, { service: "" });
|
|
4066
|
+
file = namingExpand(options.service, namingCaptures(context.filename) ?? {}, false);
|
|
4067
|
+
callees = optionsWildcards(options.callees ?? ["*.of", "*.bind"]);
|
|
4068
|
+
try {
|
|
4069
|
+
declared = effectLayerKeysDeclared(readFileSync(file, "utf8"), options.declaration ?? "Context.Service");
|
|
4070
|
+
} catch {
|
|
4071
|
+
declared = null;
|
|
4072
|
+
}
|
|
4073
|
+
if (!declared) {
|
|
4074
|
+
return false;
|
|
4075
|
+
}
|
|
4076
|
+
},
|
|
4077
|
+
CallExpression(node) {
|
|
4078
|
+
const first = node.arguments.at(0);
|
|
4079
|
+
if (!declared || first?.type !== "ObjectExpression" || !optionsPatternsTest(callees, astDottedName(node.callee) ?? "")) {
|
|
4080
|
+
return;
|
|
4081
|
+
}
|
|
4082
|
+
const bound = effectLayerKeysBound(first, []);
|
|
4083
|
+
const names = new Set(bound.map(([path]) => path));
|
|
4084
|
+
const short = file.split("/").slice(-2).join("/");
|
|
4085
|
+
const missing = declared.filter((path) => !names.has(path) && !bound.some(([name]) => name.startsWith(`${path}.`)));
|
|
4086
|
+
for (const [path, property] of bound) {
|
|
4087
|
+
if (!declared.some((name) => name === path || path.startsWith(`${name}.`))) {
|
|
4088
|
+
context.report({
|
|
4089
|
+
node: property,
|
|
4090
|
+
messageId: "extra",
|
|
4091
|
+
data: { path, file: short }
|
|
4092
|
+
});
|
|
4093
|
+
}
|
|
4094
|
+
}
|
|
4095
|
+
if (missing.length > 0) {
|
|
4096
|
+
context.report({
|
|
4097
|
+
node: first,
|
|
4098
|
+
messageId: "missing",
|
|
4099
|
+
data: { paths: missing.map((path) => `'${path}'`).join(", "), file: short }
|
|
4100
|
+
});
|
|
4101
|
+
}
|
|
4102
|
+
}
|
|
4103
|
+
};
|
|
4104
|
+
}
|
|
4105
|
+
});
|
|
4106
|
+
|
|
3822
4107
|
// src/rules/effect/effect-layers.ts
|
|
3823
|
-
import { defineRule as
|
|
4108
|
+
import { defineRule as defineRule32 } from "@oxlint/plugins";
|
|
3824
4109
|
var effectLayersDefaultMerge = ["Layer.mergeAll"];
|
|
3825
4110
|
var effectLayersDefaultProvide = ["Effect.provide", "Layer.provide", "Layer.provideMerge"];
|
|
3826
4111
|
var effectLayersDefaultMin = 2;
|
|
@@ -3832,7 +4117,7 @@ var effectLayersGroupSchema = {
|
|
|
3832
4117
|
min: { type: "integer", minimum: 1 }
|
|
3833
4118
|
}
|
|
3834
4119
|
};
|
|
3835
|
-
var effectLayers =
|
|
4120
|
+
var effectLayers = defineRule32({
|
|
3836
4121
|
meta: {
|
|
3837
4122
|
type: "layout",
|
|
3838
4123
|
fixable: "whitespace",
|
|
@@ -3914,11 +4199,11 @@ var effectLayers = defineRule30({
|
|
|
3914
4199
|
});
|
|
3915
4200
|
|
|
3916
4201
|
// src/rules/effect/effect-merge-pipe.ts
|
|
3917
|
-
import { defineRule as
|
|
4202
|
+
import { defineRule as defineRule33 } from "@oxlint/plugins";
|
|
3918
4203
|
var effectMergePipeDefaultMerge = ["Layer.mergeAll"];
|
|
3919
4204
|
var effectMergePipeDefaultPipe = ["pipe", "Function.pipe"];
|
|
3920
4205
|
var effectMergePipeDefaultMethods = ["pipe"];
|
|
3921
|
-
var effectMergePipe =
|
|
4206
|
+
var effectMergePipe = defineRule33({
|
|
3922
4207
|
meta: {
|
|
3923
4208
|
type: "layout",
|
|
3924
4209
|
schema: [
|
|
@@ -3963,7 +4248,7 @@ var effectMergePipe = defineRule31({
|
|
|
3963
4248
|
});
|
|
3964
4249
|
|
|
3965
4250
|
// src/rules/effect/effect-schema-first.ts
|
|
3966
|
-
import { defineRule as
|
|
4251
|
+
import { defineRule as defineRule34 } from "@oxlint/plugins";
|
|
3967
4252
|
var effectSchemaFirstDefaultRuntime = [
|
|
3968
4253
|
"Effect",
|
|
3969
4254
|
"Layer",
|
|
@@ -4025,7 +4310,7 @@ function effectSchemaFirstReference(node) {
|
|
|
4025
4310
|
}
|
|
4026
4311
|
return node.type === "TSInterfaceHeritage" ? astDottedName(node.expression) : undefined;
|
|
4027
4312
|
}
|
|
4028
|
-
var effectSchemaFirst =
|
|
4313
|
+
var effectSchemaFirst = defineRule34({
|
|
4029
4314
|
meta: {
|
|
4030
4315
|
type: "suggestion",
|
|
4031
4316
|
schema: [
|
|
@@ -4035,6 +4320,7 @@ var effectSchemaFirst = defineRule32({
|
|
|
4035
4320
|
properties: {
|
|
4036
4321
|
member: { type: "string" },
|
|
4037
4322
|
keep: optionsPatternSchema,
|
|
4323
|
+
allow: optionsPatternSchema,
|
|
4038
4324
|
runtime: { type: "array", items: { type: "string" } },
|
|
4039
4325
|
rows: {
|
|
4040
4326
|
type: "object",
|
|
@@ -4064,6 +4350,7 @@ var effectSchemaFirst = defineRule32({
|
|
|
4064
4350
|
createOnce(context) {
|
|
4065
4351
|
let member = "Type";
|
|
4066
4352
|
let keep = [];
|
|
4353
|
+
let allow = [];
|
|
4067
4354
|
let runtime = new Set(effectSchemaFirstDefaultRuntime);
|
|
4068
4355
|
let rows;
|
|
4069
4356
|
let suffix = "Record";
|
|
@@ -4128,6 +4415,7 @@ var effectSchemaFirst = defineRule32({
|
|
|
4128
4415
|
const options = optionsFirst(context, {});
|
|
4129
4416
|
member = options.member ?? "Type";
|
|
4130
4417
|
keep = optionsPatterns(options.keep);
|
|
4418
|
+
allow = optionsPatterns(options.allow);
|
|
4131
4419
|
runtime = new Set(options.runtime ?? effectSchemaFirstDefaultRuntime);
|
|
4132
4420
|
rows = options.rows ? new Set(options.rows.types ?? ["Kysely.Selectable"]) : undefined;
|
|
4133
4421
|
suffix = options.rows?.suffix ?? "Record";
|
|
@@ -4147,7 +4435,7 @@ var effectSchemaFirst = defineRule32({
|
|
|
4147
4435
|
const typed = new Set(exported.flatMap((node) => node.type === "TSTypeAliasDeclaration" && derives(node) ? [node.id.name] : []));
|
|
4148
4436
|
for (const node of exported.flatMap((declaration) => declaration.type === "VariableDeclaration" ? declaration.declarations : [])) {
|
|
4149
4437
|
const isSchema = node.init?.type === "CallExpression" || node.init?.type === "MemberExpression";
|
|
4150
|
-
if (isSchema && node.id.type === "Identifier" && !typed.has(node.id.name)) {
|
|
4438
|
+
if (isSchema && node.id.type === "Identifier" && !typed.has(node.id.name) && !optionsPatternsTest(allow, node.id.name)) {
|
|
4151
4439
|
context.report({
|
|
4152
4440
|
node,
|
|
4153
4441
|
messageId: "schemaType",
|
|
@@ -4197,8 +4485,104 @@ var effectSchemaFirst = defineRule32({
|
|
|
4197
4485
|
}
|
|
4198
4486
|
});
|
|
4199
4487
|
|
|
4488
|
+
// src/rules/effect/effect-service-params.ts
|
|
4489
|
+
import { defineRule as defineRule35 } from "@oxlint/plugins";
|
|
4490
|
+
function effectServiceParamsKey(member) {
|
|
4491
|
+
if (member.type !== "TSPropertySignature" && member.type !== "TSMethodSignature" || member.computed) {
|
|
4492
|
+
return;
|
|
4493
|
+
}
|
|
4494
|
+
return member.key.type === "Identifier" ? member.key.name : undefined;
|
|
4495
|
+
}
|
|
4496
|
+
function effectServiceParamsTypeName(name) {
|
|
4497
|
+
if (name.type === "TSQualifiedName") {
|
|
4498
|
+
return `${effectServiceParamsTypeName(name.left)}.${name.right.name}`;
|
|
4499
|
+
}
|
|
4500
|
+
return name.type === "Identifier" ? name.name : "this";
|
|
4501
|
+
}
|
|
4502
|
+
var effectServiceParams = defineRule35({
|
|
4503
|
+
meta: {
|
|
4504
|
+
type: "problem",
|
|
4505
|
+
schema: [
|
|
4506
|
+
{
|
|
4507
|
+
type: "object",
|
|
4508
|
+
additionalProperties: false,
|
|
4509
|
+
properties: {
|
|
4510
|
+
name: optionsPatternSchema,
|
|
4511
|
+
allow: optionsPatternSchema,
|
|
4512
|
+
declaration: { type: "string", minLength: 1 }
|
|
4513
|
+
}
|
|
4514
|
+
}
|
|
4515
|
+
],
|
|
4516
|
+
messages: {
|
|
4517
|
+
name: "'{{path}}' takes '{{type}}'; a service method takes a params type that matches {{pattern}}.",
|
|
4518
|
+
inline: "'{{path}}' takes an unnamed type; a service method takes a params type that matches {{pattern}}."
|
|
4519
|
+
}
|
|
4520
|
+
},
|
|
4521
|
+
createOnce(context) {
|
|
4522
|
+
let options = {};
|
|
4523
|
+
let captures = {};
|
|
4524
|
+
let allowed = [];
|
|
4525
|
+
function checkParams(params, keys) {
|
|
4526
|
+
const first = params.at(0);
|
|
4527
|
+
const annotation = first && "typeAnnotation" in first ? first.typeAnnotation?.typeAnnotation : undefined;
|
|
4528
|
+
if (!first || !annotation) {
|
|
4529
|
+
return;
|
|
4530
|
+
}
|
|
4531
|
+
const values = { ...captures, path: keys.join("-"), key: keys.at(-1) ?? "" };
|
|
4532
|
+
const sources = [options.name ?? "^{Folder}\\w*Params$"].flat().map((source) => namingExpand(source, values, true, optionsEscape));
|
|
4533
|
+
const data = { path: keys.join("."), pattern: optionsPatternLabel(sources) };
|
|
4534
|
+
if (annotation.type !== "TSTypeReference") {
|
|
4535
|
+
context.report({
|
|
4536
|
+
node: first,
|
|
4537
|
+
messageId: "inline",
|
|
4538
|
+
data
|
|
4539
|
+
});
|
|
4540
|
+
return;
|
|
4541
|
+
}
|
|
4542
|
+
const type = effectServiceParamsTypeName(annotation.typeName);
|
|
4543
|
+
const last = type.split(".").at(-1) ?? type;
|
|
4544
|
+
if (!optionsPatternsTest(allowed, type) && !optionsPatternsTest(optionsPatterns(sources), last)) {
|
|
4545
|
+
context.report({
|
|
4546
|
+
node: first,
|
|
4547
|
+
messageId: "name",
|
|
4548
|
+
data: { ...data, type }
|
|
4549
|
+
});
|
|
4550
|
+
}
|
|
4551
|
+
}
|
|
4552
|
+
function check(literal, path) {
|
|
4553
|
+
for (const member of literal.members) {
|
|
4554
|
+
const key = effectServiceParamsKey(member);
|
|
4555
|
+
const type = member.type === "TSPropertySignature" ? member.typeAnnotation?.typeAnnotation : undefined;
|
|
4556
|
+
if (key === undefined) {
|
|
4557
|
+
continue;
|
|
4558
|
+
}
|
|
4559
|
+
if (member.type === "TSMethodSignature") {
|
|
4560
|
+
checkParams(member.params, [...path, key]);
|
|
4561
|
+
} else if (type?.type === "TSFunctionType") {
|
|
4562
|
+
checkParams(type.params, [...path, key]);
|
|
4563
|
+
} else if (type?.type === "TSTypeLiteral") {
|
|
4564
|
+
check(type, [...path, key]);
|
|
4565
|
+
}
|
|
4566
|
+
}
|
|
4567
|
+
}
|
|
4568
|
+
return {
|
|
4569
|
+
before() {
|
|
4570
|
+
options = optionsFirst(context, {});
|
|
4571
|
+
captures = namingCaptures(context.filename) ?? {};
|
|
4572
|
+
allowed = optionsPatterns(options.allow);
|
|
4573
|
+
},
|
|
4574
|
+
TSTypeLiteral(node) {
|
|
4575
|
+
const call = node.parent.type === "TSTypeParameterInstantiation" ? node.parent.parent : undefined;
|
|
4576
|
+
if (call?.type === "CallExpression" && astDottedName(call.callee) === (options.declaration ?? "Context.Service")) {
|
|
4577
|
+
check(node, []);
|
|
4578
|
+
}
|
|
4579
|
+
}
|
|
4580
|
+
};
|
|
4581
|
+
}
|
|
4582
|
+
});
|
|
4583
|
+
|
|
4200
4584
|
// src/rules/effect/effect-values-first.ts
|
|
4201
|
-
import { defineRule as
|
|
4585
|
+
import { defineRule as defineRule36 } from "@oxlint/plugins";
|
|
4202
4586
|
var effectValuesFirstDefaultPinned = [
|
|
4203
4587
|
"^Layer\\.",
|
|
4204
4588
|
"^Context\\.",
|
|
@@ -4207,7 +4591,7 @@ var effectValuesFirstDefaultPinned = [
|
|
|
4207
4591
|
"(?:^|\\.)layer[^.]*$",
|
|
4208
4592
|
"^Schema\\.(?:asserts|decode\\w*|encode\\w*|is|isSchema|isSchemaError|resolveAnnotations)$"
|
|
4209
4593
|
];
|
|
4210
|
-
var effectValuesFirst =
|
|
4594
|
+
var effectValuesFirst = defineRule36({
|
|
4211
4595
|
meta: {
|
|
4212
4596
|
type: "suggestion",
|
|
4213
4597
|
schema: [
|
|
@@ -4289,32 +4673,116 @@ var effectValuesFirst = defineRule33({
|
|
|
4289
4673
|
}
|
|
4290
4674
|
});
|
|
4291
4675
|
|
|
4292
|
-
// src/rules/
|
|
4293
|
-
import { defineRule as
|
|
4294
|
-
|
|
4295
|
-
|
|
4296
|
-
|
|
4297
|
-
|
|
4298
|
-
|
|
4299
|
-
|
|
4300
|
-
|
|
4301
|
-
|
|
4302
|
-
|
|
4303
|
-
|
|
4304
|
-
|
|
4305
|
-
|
|
4306
|
-
|
|
4676
|
+
// src/rules/effect/effect-yield-name.ts
|
|
4677
|
+
import { defineRule as defineRule37 } from "@oxlint/plugins";
|
|
4678
|
+
var effectYieldName = defineRule37({
|
|
4679
|
+
meta: {
|
|
4680
|
+
type: "suggestion",
|
|
4681
|
+
schema: [
|
|
4682
|
+
{
|
|
4683
|
+
type: "object",
|
|
4684
|
+
additionalProperties: false,
|
|
4685
|
+
properties: {
|
|
4686
|
+
names: { type: "object", additionalProperties: optionsPatternSchema },
|
|
4687
|
+
allow: optionsPatternSchema
|
|
4688
|
+
}
|
|
4689
|
+
}
|
|
4690
|
+
],
|
|
4691
|
+
messages: {
|
|
4692
|
+
name: "Name this '{{expected}}', not '{{actual}}': it holds {{source}}."
|
|
4307
4693
|
}
|
|
4308
|
-
|
|
4309
|
-
|
|
4310
|
-
|
|
4311
|
-
|
|
4694
|
+
},
|
|
4695
|
+
createOnce(context) {
|
|
4696
|
+
return {
|
|
4697
|
+
VariableDeclarator(node) {
|
|
4698
|
+
const { id, init } = node;
|
|
4699
|
+
if (id.type !== "Identifier" || init?.type !== "YieldExpression" || !init.delegate || init.argument?.type !== "MemberExpression") {
|
|
4700
|
+
return;
|
|
4701
|
+
}
|
|
4702
|
+
const service = astMemberName(init.argument);
|
|
4703
|
+
const source = astDottedName(init.argument);
|
|
4704
|
+
if (!service || !source || !/^[A-Z]/.test(service)) {
|
|
4705
|
+
return;
|
|
4706
|
+
}
|
|
4707
|
+
const options = optionsFirst(context, {});
|
|
4708
|
+
const named = options.names?.[source] ?? options.names?.[`*.${service}`];
|
|
4709
|
+
const expected = named === undefined ? [`${service.charAt(0).toLowerCase()}${service.slice(1)}`] : [named].flat();
|
|
4710
|
+
if (!expected.includes(id.name) && !optionsPatternsTest(optionsPatterns(options.allow), id.name)) {
|
|
4711
|
+
context.report({
|
|
4712
|
+
node: id,
|
|
4713
|
+
messageId: "name",
|
|
4714
|
+
data: { expected: expected.join(" or "), actual: id.name, source }
|
|
4715
|
+
});
|
|
4716
|
+
}
|
|
4312
4717
|
}
|
|
4313
|
-
}
|
|
4314
|
-
|
|
4315
|
-
|
|
4316
|
-
|
|
4317
|
-
|
|
4718
|
+
};
|
|
4719
|
+
}
|
|
4720
|
+
});
|
|
4721
|
+
|
|
4722
|
+
// src/rules/effect/effect-yields-first.ts
|
|
4723
|
+
import { defineRule as defineRule38 } from "@oxlint/plugins";
|
|
4724
|
+
function effectYieldsFirstService(statement) {
|
|
4725
|
+
const init = statement.type === "VariableDeclaration" && statement.declarations.length === 1 ? statement.declarations[0].init : null;
|
|
4726
|
+
const argument = init?.type === "YieldExpression" && init.delegate ? init.argument : null;
|
|
4727
|
+
return argument?.type === "MemberExpression" && /^[A-Z]/.test(astMemberName(argument) ?? "") ? astDottedName(argument) : undefined;
|
|
4728
|
+
}
|
|
4729
|
+
var effectYieldsFirst = defineRule38({
|
|
4730
|
+
meta: {
|
|
4731
|
+
type: "suggestion",
|
|
4732
|
+
messages: {
|
|
4733
|
+
first: "Yield {{source}} with the other dependencies, at the top of the function."
|
|
4734
|
+
}
|
|
4735
|
+
},
|
|
4736
|
+
createOnce(context) {
|
|
4737
|
+
return {
|
|
4738
|
+
FunctionExpression(node) {
|
|
4739
|
+
if (!node.generator || !node.body) {
|
|
4740
|
+
return;
|
|
4741
|
+
}
|
|
4742
|
+
let started = false;
|
|
4743
|
+
for (const statement of node.body.body) {
|
|
4744
|
+
const source = effectYieldsFirstService(statement);
|
|
4745
|
+
if (source === undefined) {
|
|
4746
|
+
started = true;
|
|
4747
|
+
} else if (started) {
|
|
4748
|
+
context.report({
|
|
4749
|
+
node: statement,
|
|
4750
|
+
messageId: "first",
|
|
4751
|
+
data: { source }
|
|
4752
|
+
});
|
|
4753
|
+
}
|
|
4754
|
+
}
|
|
4755
|
+
}
|
|
4756
|
+
};
|
|
4757
|
+
}
|
|
4758
|
+
});
|
|
4759
|
+
|
|
4760
|
+
// src/rules/files/files-components-only.ts
|
|
4761
|
+
import { defineRule as defineRule39 } from "@oxlint/plugins";
|
|
4762
|
+
|
|
4763
|
+
// src/utils/react.utils.ts
|
|
4764
|
+
function reactReturnsOutput(program, node) {
|
|
4765
|
+
const expressions = astReturnExpressions(node);
|
|
4766
|
+
if (expressions.some((expression) => astContainsJsx(expression) || expression.type === "Literal" && expression.value === null)) {
|
|
4767
|
+
return true;
|
|
4768
|
+
}
|
|
4769
|
+
const returned = new Set(expressions.flatMap((expression) => expression.type === "Identifier" ? [expression.name] : []));
|
|
4770
|
+
const propsWithChildren = new Set(program.body.flatMap((statement) => statement.type === "ImportDeclaration" && statement.source.value === "react" ? statement.specifiers.flatMap((specifier) => specifier.type === "ImportSpecifier" && astModuleName(specifier.imported) === "PropsWithChildren" ? [specifier.local.name] : []) : []));
|
|
4771
|
+
return node.params.some((param) => {
|
|
4772
|
+
const returnsProp = param.type === "ObjectPattern" && param.properties.some((property) => property.type === "Property" && property.value.type === "Identifier" && returned.has(property.value.name));
|
|
4773
|
+
if (!returnsProp) {
|
|
4774
|
+
return false;
|
|
4775
|
+
}
|
|
4776
|
+
let found = false;
|
|
4777
|
+
astVisit(param.typeAnnotation, [], (candidate) => {
|
|
4778
|
+
if (candidate.type === "TSTypeReference" && candidate.typeName.type === "Identifier" && propsWithChildren.has(candidate.typeName.name)) {
|
|
4779
|
+
found = true;
|
|
4780
|
+
}
|
|
4781
|
+
});
|
|
4782
|
+
return found;
|
|
4783
|
+
});
|
|
4784
|
+
}
|
|
4785
|
+
function reactIsComponentValue(program, initializer) {
|
|
4318
4786
|
if (!initializer) {
|
|
4319
4787
|
return false;
|
|
4320
4788
|
}
|
|
@@ -4362,7 +4830,7 @@ function reactIsComponent(program, candidate) {
|
|
|
4362
4830
|
function componentName(basename2) {
|
|
4363
4831
|
return basename2.replace(/\.(tsx?|jsx?)$/, "").replaceAll(/(?:^[-.]*|[-.]+)(.?)/g, (_, char) => char.toUpperCase());
|
|
4364
4832
|
}
|
|
4365
|
-
var filesComponentsOnly =
|
|
4833
|
+
var filesComponentsOnly = defineRule39({
|
|
4366
4834
|
meta: {
|
|
4367
4835
|
type: "problem",
|
|
4368
4836
|
schema: [
|
|
@@ -4450,7 +4918,7 @@ var filesComponentsOnly = defineRule34({
|
|
|
4450
4918
|
});
|
|
4451
4919
|
|
|
4452
4920
|
// src/rules/files/files-constants-only.ts
|
|
4453
|
-
import { defineRule as
|
|
4921
|
+
import { defineRule as defineRule40 } from "@oxlint/plugins";
|
|
4454
4922
|
function unwrap(expression) {
|
|
4455
4923
|
if (expression.type === "ParenthesizedExpression" || expression.type === "TSAsExpression" || expression.type === "TSSatisfiesExpression" || expression.type === "TSTypeAssertion" || expression.type === "TSNonNullExpression" || expression.type === "TSInstantiationExpression") {
|
|
4456
4924
|
return unwrap(expression.expression);
|
|
@@ -4505,7 +4973,7 @@ function collectBindings(program) {
|
|
|
4505
4973
|
}
|
|
4506
4974
|
return bindings;
|
|
4507
4975
|
}
|
|
4508
|
-
var filesConstantsOnly =
|
|
4976
|
+
var filesConstantsOnly = defineRule40({
|
|
4509
4977
|
meta: {
|
|
4510
4978
|
type: "problem",
|
|
4511
4979
|
schema: [
|
|
@@ -4604,7 +5072,7 @@ var filesConstantsOnly = defineRule35({
|
|
|
4604
5072
|
});
|
|
4605
5073
|
|
|
4606
5074
|
// src/rules/files/files-domain-constants.ts
|
|
4607
|
-
import { defineRule as
|
|
5075
|
+
import { defineRule as defineRule41 } from "@oxlint/plugins";
|
|
4608
5076
|
import { basename as basename2, dirname as dirname2 } from "node:path";
|
|
4609
5077
|
function isData(expression) {
|
|
4610
5078
|
const value = astUnwrap(expression);
|
|
@@ -4622,7 +5090,7 @@ function isData(expression) {
|
|
|
4622
5090
|
}
|
|
4623
5091
|
return value.type === "NewExpression" && value.callee.type === "Identifier" && ["Map", "Set"].includes(value.callee.name) && value.arguments[0]?.type === "ArrayExpression" && value.arguments[0].elements.length > 0;
|
|
4624
5092
|
}
|
|
4625
|
-
var filesDomainConstants =
|
|
5093
|
+
var filesDomainConstants = defineRule41({
|
|
4626
5094
|
meta: {
|
|
4627
5095
|
type: "problem",
|
|
4628
5096
|
schema: [
|
|
@@ -4687,9 +5155,8 @@ var filesDomainConstants = defineRule36({
|
|
|
4687
5155
|
});
|
|
4688
5156
|
|
|
4689
5157
|
// src/rules/files/files-exports.ts
|
|
4690
|
-
import { defineRule as
|
|
4691
|
-
|
|
4692
|
-
var filesExports = defineRule37({
|
|
5158
|
+
import { defineRule as defineRule42 } from "@oxlint/plugins";
|
|
5159
|
+
var filesExports = defineRule42({
|
|
4693
5160
|
meta: {
|
|
4694
5161
|
type: "problem",
|
|
4695
5162
|
schema: [
|
|
@@ -4705,6 +5172,8 @@ var filesExports = defineRule37({
|
|
|
4705
5172
|
separators: { type: "array", items: { type: "string" } },
|
|
4706
5173
|
types: { type: "boolean" },
|
|
4707
5174
|
factory: { type: "string" },
|
|
5175
|
+
file: { type: "string" },
|
|
5176
|
+
placeholder: { type: "string" },
|
|
4708
5177
|
scope: { type: "string", enum: ["exports", "declarations"] }
|
|
4709
5178
|
},
|
|
4710
5179
|
anyOf: [{ required: ["names"] }, { required: ["patterns"] }, { required: ["factory"] }]
|
|
@@ -4743,16 +5212,12 @@ var filesExports = defineRule37({
|
|
|
4743
5212
|
if (options.names === undefined && options.patterns === undefined) {
|
|
4744
5213
|
return;
|
|
4745
5214
|
}
|
|
4746
|
-
const
|
|
4747
|
-
|
|
4748
|
-
|
|
4749
|
-
|
|
4750
|
-
const
|
|
4751
|
-
const
|
|
4752
|
-
const patterns = (options.patterns ?? []).map((template) => {
|
|
4753
|
-
const source = template.replaceAll("{Domain}", optionsEscape(pascalDomain)).replaceAll("{domain}", optionsEscape(camelDomain));
|
|
4754
|
-
return new RegExp(`^(?:${source})$`);
|
|
4755
|
-
});
|
|
5215
|
+
const captures = namingCaptures(context.filename, options);
|
|
5216
|
+
if (!captures) {
|
|
5217
|
+
return;
|
|
5218
|
+
}
|
|
5219
|
+
const allowed = (options.names ?? []).map((template) => namingExpand(template, captures, true));
|
|
5220
|
+
const patterns = (options.patterns ?? []).map((template) => new RegExp(`^(?:${namingExpand(template, captures, true, optionsEscape)})$`));
|
|
4756
5221
|
const allowedLabel = [...allowed, ...patterns.map((pattern) => pattern.toString())].join(", ");
|
|
4757
5222
|
for (const binding of exportsCollect(program)) {
|
|
4758
5223
|
if (options.types && binding.typeOnly) {
|
|
@@ -4773,12 +5238,12 @@ var filesExports = defineRule37({
|
|
|
4773
5238
|
});
|
|
4774
5239
|
|
|
4775
5240
|
// src/rules/files/files-externals.ts
|
|
4776
|
-
import { defineRule as
|
|
4777
|
-
import { existsSync as existsSync2, readFileSync } from "node:fs";
|
|
5241
|
+
import { defineRule as defineRule43 } from "@oxlint/plugins";
|
|
5242
|
+
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
|
|
4778
5243
|
import { builtinModules as builtinModules2 } from "node:module";
|
|
4779
5244
|
import { dirname as dirname3, join as join2 } from "node:path";
|
|
4780
5245
|
var filesExternalsConfigs = "^(?:vite|next)\\.config\\.[cm]?[jt]s$";
|
|
4781
|
-
var filesExternals =
|
|
5246
|
+
var filesExternals = defineRule43({
|
|
4782
5247
|
meta: {
|
|
4783
5248
|
type: "problem",
|
|
4784
5249
|
schema: [
|
|
@@ -4804,7 +5269,7 @@ var filesExternals = defineRule38({
|
|
|
4804
5269
|
}
|
|
4805
5270
|
let dependencies;
|
|
4806
5271
|
try {
|
|
4807
|
-
const manifest = JSON.parse(
|
|
5272
|
+
const manifest = JSON.parse(readFileSync2(join2(folder, "package.json"), "utf8"));
|
|
4808
5273
|
dependencies = [...Object.keys(manifest.dependencies ?? {}), ...Object.keys(manifest.optionalDependencies ?? {})];
|
|
4809
5274
|
} catch {
|
|
4810
5275
|
return;
|
|
@@ -4871,7 +5336,7 @@ var filesExternals = defineRule38({
|
|
|
4871
5336
|
});
|
|
4872
5337
|
|
|
4873
5338
|
// src/rules/files/files-factory-keys.ts
|
|
4874
|
-
import { defineRule as
|
|
5339
|
+
import { defineRule as defineRule44 } from "@oxlint/plugins";
|
|
4875
5340
|
function returnedObject(expression) {
|
|
4876
5341
|
if (expression?.type === "TSAsExpression" || expression?.type === "TSSatisfiesExpression" || expression?.type === "TSTypeAssertion" || expression?.type === "TSNonNullExpression") {
|
|
4877
5342
|
return returnedObject(expression.expression);
|
|
@@ -4882,7 +5347,7 @@ function compileKeys(pattern, keys, requireKeys) {
|
|
|
4882
5347
|
const allowedList = keys.concat(requireKeys.filter((key) => !keys.includes(key)));
|
|
4883
5348
|
return { patterns: optionsPatternsWithEmpty(pattern), allowed: new Set(allowedList), allowedList, required: requireKeys };
|
|
4884
5349
|
}
|
|
4885
|
-
var filesFactoryKeys =
|
|
5350
|
+
var filesFactoryKeys = defineRule44({
|
|
4886
5351
|
meta: {
|
|
4887
5352
|
type: "problem",
|
|
4888
5353
|
schema: [
|
|
@@ -5000,8 +5465,8 @@ var filesFactoryKeys = defineRule39({
|
|
|
5000
5465
|
});
|
|
5001
5466
|
|
|
5002
5467
|
// src/rules/files/files-helpers.ts
|
|
5003
|
-
import { defineRule as
|
|
5004
|
-
var filesHelpers =
|
|
5468
|
+
import { defineRule as defineRule45 } from "@oxlint/plugins";
|
|
5469
|
+
var filesHelpers = defineRule45({
|
|
5005
5470
|
meta: {
|
|
5006
5471
|
type: "problem",
|
|
5007
5472
|
schema: [
|
|
@@ -5049,8 +5514,8 @@ var filesHelpers = defineRule40({
|
|
|
5049
5514
|
});
|
|
5050
5515
|
|
|
5051
5516
|
// src/rules/files/files-no-functions.ts
|
|
5052
|
-
import { defineRule as
|
|
5053
|
-
var filesNoFunctions =
|
|
5517
|
+
import { defineRule as defineRule46 } from "@oxlint/plugins";
|
|
5518
|
+
var filesNoFunctions = defineRule46({
|
|
5054
5519
|
meta: {
|
|
5055
5520
|
type: "problem",
|
|
5056
5521
|
schema: [
|
|
@@ -5104,8 +5569,8 @@ var filesNoFunctions = defineRule41({
|
|
|
5104
5569
|
});
|
|
5105
5570
|
|
|
5106
5571
|
// src/rules/files/files-restricted.ts
|
|
5107
|
-
import { defineRule as
|
|
5108
|
-
var filesRestricted =
|
|
5572
|
+
import { defineRule as defineRule47 } from "@oxlint/plugins";
|
|
5573
|
+
var filesRestricted = defineRule47({
|
|
5109
5574
|
meta: {
|
|
5110
5575
|
type: "problem",
|
|
5111
5576
|
schema: [
|
|
@@ -5137,7 +5602,7 @@ var filesRestricted = defineRule42({
|
|
|
5137
5602
|
});
|
|
5138
5603
|
|
|
5139
5604
|
// src/rules/files/files-route.ts
|
|
5140
|
-
import { defineRule as
|
|
5605
|
+
import { defineRule as defineRule48 } from "@oxlint/plugins";
|
|
5141
5606
|
function inspectAdapter(context, item, bannedHooks, banIntrinsicJsx) {
|
|
5142
5607
|
astVisit(item.node.body, [item.node], (node) => {
|
|
5143
5608
|
if (banIntrinsicJsx && node.type === "JSXOpeningElement" && node.name.type === "JSXIdentifier" && /^[a-z]/.test(node.name.name)) {
|
|
@@ -5157,7 +5622,7 @@ function inspectAdapter(context, item, bannedHooks, banIntrinsicJsx) {
|
|
|
5157
5622
|
}
|
|
5158
5623
|
});
|
|
5159
5624
|
}
|
|
5160
|
-
var filesRoute =
|
|
5625
|
+
var filesRoute = defineRule48({
|
|
5161
5626
|
meta: {
|
|
5162
5627
|
type: "problem",
|
|
5163
5628
|
schema: [
|
|
@@ -5226,8 +5691,247 @@ var filesRoute = defineRule43({
|
|
|
5226
5691
|
}
|
|
5227
5692
|
});
|
|
5228
5693
|
|
|
5694
|
+
// src/rules/files/files-siblings.ts
|
|
5695
|
+
import { defineRule as defineRule49 } from "@oxlint/plugins";
|
|
5696
|
+
import { existsSync as existsSync3 } from "node:fs";
|
|
5697
|
+
import { dirname as dirname4, join as join3 } from "node:path";
|
|
5698
|
+
var filesSiblings = defineRule49({
|
|
5699
|
+
meta: {
|
|
5700
|
+
type: "problem",
|
|
5701
|
+
schema: [
|
|
5702
|
+
{
|
|
5703
|
+
type: "object",
|
|
5704
|
+
additionalProperties: false,
|
|
5705
|
+
properties: {
|
|
5706
|
+
require: optionsPatternSchema,
|
|
5707
|
+
message: { type: "string" }
|
|
5708
|
+
},
|
|
5709
|
+
required: ["require"]
|
|
5710
|
+
}
|
|
5711
|
+
],
|
|
5712
|
+
messages: {
|
|
5713
|
+
missing: "This file needs '{{file}}' beside it.{{message}}"
|
|
5714
|
+
}
|
|
5715
|
+
},
|
|
5716
|
+
createOnce(context) {
|
|
5717
|
+
return {
|
|
5718
|
+
Program(program) {
|
|
5719
|
+
const options = optionsFirst(context, { require: [] });
|
|
5720
|
+
const captures = namingCaptures(context.filename) ?? {};
|
|
5721
|
+
for (const template of [options.require].flat()) {
|
|
5722
|
+
const file = namingExpand(template, captures, false);
|
|
5723
|
+
if (!existsSync3(join3(dirname4(context.filename), file))) {
|
|
5724
|
+
context.report({
|
|
5725
|
+
node: program,
|
|
5726
|
+
messageId: "missing",
|
|
5727
|
+
data: { file, message: options.message ? ` ${options.message}` : "" }
|
|
5728
|
+
});
|
|
5729
|
+
}
|
|
5730
|
+
}
|
|
5731
|
+
}
|
|
5732
|
+
};
|
|
5733
|
+
}
|
|
5734
|
+
});
|
|
5735
|
+
|
|
5736
|
+
// src/rules/files/files-top-level.ts
|
|
5737
|
+
import { defineRule as defineRule50 } from "@oxlint/plugins";
|
|
5738
|
+
var filesTopLevelKinds = [
|
|
5739
|
+
"import",
|
|
5740
|
+
"export",
|
|
5741
|
+
"reexport",
|
|
5742
|
+
"default",
|
|
5743
|
+
"type",
|
|
5744
|
+
"interface",
|
|
5745
|
+
"enum",
|
|
5746
|
+
"class",
|
|
5747
|
+
"namespace",
|
|
5748
|
+
"const",
|
|
5749
|
+
"let",
|
|
5750
|
+
"var",
|
|
5751
|
+
"function",
|
|
5752
|
+
"function-const",
|
|
5753
|
+
"call",
|
|
5754
|
+
"statement"
|
|
5755
|
+
];
|
|
5756
|
+
var filesTopLevelDeclared = new Map([
|
|
5757
|
+
["FunctionDeclaration", "function"],
|
|
5758
|
+
["TSDeclareFunction", "function"],
|
|
5759
|
+
["ClassDeclaration", "class"],
|
|
5760
|
+
["TSTypeAliasDeclaration", "type"],
|
|
5761
|
+
["TSInterfaceDeclaration", "interface"],
|
|
5762
|
+
["TSEnumDeclaration", "enum"],
|
|
5763
|
+
["TSModuleDeclaration", "namespace"]
|
|
5764
|
+
]);
|
|
5765
|
+
var filesTopLevelEntries = {
|
|
5766
|
+
type: "array",
|
|
5767
|
+
items: {
|
|
5768
|
+
anyOf: [
|
|
5769
|
+
{ type: "string" },
|
|
5770
|
+
{
|
|
5771
|
+
type: "object",
|
|
5772
|
+
additionalProperties: false,
|
|
5773
|
+
properties: {
|
|
5774
|
+
kind: { anyOf: [{ type: "string", enum: [...filesTopLevelKinds] }, { type: "array", items: { type: "string", enum: [...filesTopLevelKinds] }, minItems: 1 }] },
|
|
5775
|
+
names: optionsPatternSchema,
|
|
5776
|
+
from: optionsPatternSchema,
|
|
5777
|
+
exported: { type: "boolean" },
|
|
5778
|
+
message: { type: "string" }
|
|
5779
|
+
},
|
|
5780
|
+
required: ["kind"]
|
|
5781
|
+
}
|
|
5782
|
+
]
|
|
5783
|
+
}
|
|
5784
|
+
};
|
|
5785
|
+
var filesTopLevelValues = new Map([
|
|
5786
|
+
["Literal", "<literal>"],
|
|
5787
|
+
["TemplateLiteral", "<literal>"],
|
|
5788
|
+
["ObjectExpression", "<object>"],
|
|
5789
|
+
["ArrayExpression", "<array>"],
|
|
5790
|
+
["FunctionExpression", "<function>"],
|
|
5791
|
+
["ArrowFunctionExpression", "<function>"]
|
|
5792
|
+
]);
|
|
5793
|
+
function filesTopLevelHead(node) {
|
|
5794
|
+
if (!node) {
|
|
5795
|
+
return "<none>";
|
|
5796
|
+
}
|
|
5797
|
+
if (node.type === "AwaitExpression") {
|
|
5798
|
+
return filesTopLevelHead(node.argument);
|
|
5799
|
+
}
|
|
5800
|
+
if (node.type === "ParenthesizedExpression" || node.type === "TSAsExpression" || node.type === "TSSatisfiesExpression" || node.type === "TSTypeAssertion" || node.type === "TSNonNullExpression" || node.type === "ChainExpression") {
|
|
5801
|
+
return filesTopLevelHead(node.expression);
|
|
5802
|
+
}
|
|
5803
|
+
if (node.type === "CallExpression" || node.type === "NewExpression") {
|
|
5804
|
+
return filesTopLevelHead(node.callee);
|
|
5805
|
+
}
|
|
5806
|
+
if (node.type === "TaggedTemplateExpression") {
|
|
5807
|
+
return filesTopLevelHead(node.tag);
|
|
5808
|
+
}
|
|
5809
|
+
if (node.type === "MemberExpression") {
|
|
5810
|
+
return astDottedName(node) ?? filesTopLevelHead(node.object);
|
|
5811
|
+
}
|
|
5812
|
+
return node.type === "Identifier" ? node.name : filesTopLevelValues.get(node.type) ?? "<other>";
|
|
5813
|
+
}
|
|
5814
|
+
function filesTopLevelItems(statement) {
|
|
5815
|
+
const item = (kind, name, node2, from = "", exported2 = false) => ({ kind, name, from, exported: exported2, node: node2 });
|
|
5816
|
+
if (statement.type === "ExpressionStatement" && statement.directive) {
|
|
5817
|
+
return [];
|
|
5818
|
+
}
|
|
5819
|
+
if (statement.type === "ImportDeclaration") {
|
|
5820
|
+
return [item("import", statement.source.value, statement)];
|
|
5821
|
+
}
|
|
5822
|
+
if (statement.type === "ExportAllDeclaration") {
|
|
5823
|
+
return [item("reexport", statement.source.value, statement, "", true)];
|
|
5824
|
+
}
|
|
5825
|
+
if (statement.type === "ExportNamedDeclaration" && !statement.declaration) {
|
|
5826
|
+
const kind = statement.source ? "reexport" : "export";
|
|
5827
|
+
const names = statement.specifiers.map((specifier) => item(kind, astModuleName(specifier.exported), specifier, statement.source?.value ?? "", true));
|
|
5828
|
+
return names.length > 0 ? names : [item(kind, "", statement, statement.source?.value ?? "", true)];
|
|
5829
|
+
}
|
|
5830
|
+
const exported = statement.type === "ExportNamedDeclaration" || statement.type === "ExportDefaultDeclaration";
|
|
5831
|
+
const node = exported ? statement.declaration : statement;
|
|
5832
|
+
if (!node) {
|
|
5833
|
+
return [];
|
|
5834
|
+
}
|
|
5835
|
+
if (node.type === "VariableDeclaration") {
|
|
5836
|
+
return node.declarations.flatMap((declarator) => {
|
|
5837
|
+
const variable = node.kind === "using" || node.kind === "await using" ? "statement" : node.kind;
|
|
5838
|
+
const kind = declarationsIsFunctionValue(declarator.init) ? "function-const" : variable;
|
|
5839
|
+
return astBindings(declarator.id).map((binding) => item(kind, binding.name, declarator, filesTopLevelHead(declarator.init), exported));
|
|
5840
|
+
});
|
|
5841
|
+
}
|
|
5842
|
+
const declared = filesTopLevelDeclared.get(node.type);
|
|
5843
|
+
if (declared) {
|
|
5844
|
+
const id = "id" in node ? node.id : null;
|
|
5845
|
+
return [item(declared, id && "name" in id ? id.name : "", node, "", exported)];
|
|
5846
|
+
}
|
|
5847
|
+
if (statement.type === "ExportDefaultDeclaration") {
|
|
5848
|
+
return [item("default", filesTopLevelHead(node), statement, filesTopLevelHead(node), true)];
|
|
5849
|
+
}
|
|
5850
|
+
if (statement.type === "ExpressionStatement") {
|
|
5851
|
+
const expression = astUnwrap(statement.expression);
|
|
5852
|
+
if (expression.type === "CallExpression" || expression.type === "TaggedTemplateExpression") {
|
|
5853
|
+
return [item("call", filesTopLevelHead(expression), statement)];
|
|
5854
|
+
}
|
|
5855
|
+
}
|
|
5856
|
+
return [item("statement", statement.type, statement)];
|
|
5857
|
+
}
|
|
5858
|
+
var filesTopLevel = defineRule50({
|
|
5859
|
+
meta: {
|
|
5860
|
+
type: "problem",
|
|
5861
|
+
schema: [
|
|
5862
|
+
{
|
|
5863
|
+
type: "object",
|
|
5864
|
+
additionalProperties: false,
|
|
5865
|
+
properties: {
|
|
5866
|
+
allow: filesTopLevelEntries,
|
|
5867
|
+
deny: filesTopLevelEntries,
|
|
5868
|
+
message: { type: "string" },
|
|
5869
|
+
stem: { type: "string", enum: [...namingStemModes, "folder"] },
|
|
5870
|
+
singularize: { type: "string", enum: ["none", "trailing-s"] },
|
|
5871
|
+
roles: { type: "array", items: { type: "string" } },
|
|
5872
|
+
separators: { type: "array", items: { type: "string" } },
|
|
5873
|
+
file: { type: "string" },
|
|
5874
|
+
placeholder: { type: "string" }
|
|
5875
|
+
},
|
|
5876
|
+
anyOf: [{ required: ["allow"] }, { required: ["deny"] }]
|
|
5877
|
+
}
|
|
5878
|
+
],
|
|
5879
|
+
messages: {
|
|
5880
|
+
denied: "Top-level {{what}} is not allowed in this file.{{message}}",
|
|
5881
|
+
unlisted: "Top-level {{what}} is not allowed in this file; allowed: {{allowed}}.{{message}}"
|
|
5882
|
+
}
|
|
5883
|
+
},
|
|
5884
|
+
createOnce(context) {
|
|
5885
|
+
return {
|
|
5886
|
+
Program(program) {
|
|
5887
|
+
const options = optionsFirst(context, {});
|
|
5888
|
+
const captures = namingCaptures(context.filename, options);
|
|
5889
|
+
if (!captures) {
|
|
5890
|
+
return;
|
|
5891
|
+
}
|
|
5892
|
+
const patterns = (pattern) => pattern === undefined ? null : optionsPatterns([pattern].flat().map((source) => namingExpand(source, captures, true, optionsEscape)));
|
|
5893
|
+
const matcher = (entry) => {
|
|
5894
|
+
if (typeof entry !== "string") {
|
|
5895
|
+
return { kinds: [entry.kind].flat(), names: patterns(entry.names), from: patterns(entry.from), exported: entry.exported, message: entry.message ?? "" };
|
|
5896
|
+
}
|
|
5897
|
+
const kind = filesTopLevelKinds.find((name) => name === entry);
|
|
5898
|
+
return kind ? { kinds: [kind], names: null, from: null, message: "" } : { kinds: ["call"], names: optionsWildcards(entry), from: null, message: "" };
|
|
5899
|
+
};
|
|
5900
|
+
const matches = (item) => (entry) => entry.kinds.includes(item.kind) && (entry.names === null || optionsPatternsTest(entry.names, item.name)) && (entry.from === null || optionsPatternsTest(entry.from, item.from)) && (entry.exported === undefined || entry.exported === item.exported);
|
|
5901
|
+
const allow = options.allow?.map(matcher);
|
|
5902
|
+
const deny = (options.deny ?? []).map(matcher);
|
|
5903
|
+
const label = (entry) => [
|
|
5904
|
+
entry.exported === undefined ? [] : [entry.exported ? "exported" : "unexported"],
|
|
5905
|
+
[entry.kind].flat().join("/"),
|
|
5906
|
+
entry.names === undefined ? [] : ["named", [entry.names].flat().join(" | ")],
|
|
5907
|
+
entry.from === undefined ? [] : ["from", [entry.from].flat().join(" | ")]
|
|
5908
|
+
].flat().join(" ");
|
|
5909
|
+
const allowed = (options.allow ?? []).map((entry) => typeof entry === "string" ? entry : label(entry)).join(", ");
|
|
5910
|
+
const hint = options.message ? ` ${options.message}` : "";
|
|
5911
|
+
for (const item of program.body.flatMap(filesTopLevelItems)) {
|
|
5912
|
+
const what = item.name && item.kind !== "statement" ? `${item.kind} '${item.name}'` : item.kind;
|
|
5913
|
+
const denied = deny.find(matches(item));
|
|
5914
|
+
if (denied) {
|
|
5915
|
+
context.report({
|
|
5916
|
+
node: item.node,
|
|
5917
|
+
messageId: "denied",
|
|
5918
|
+
data: { what, message: denied.message ? ` ${denied.message}` : hint }
|
|
5919
|
+
});
|
|
5920
|
+
} else if (allow && !allow.some(matches(item))) {
|
|
5921
|
+
context.report({
|
|
5922
|
+
node: item.node,
|
|
5923
|
+
messageId: "unlisted",
|
|
5924
|
+
data: { what, allowed, message: hint }
|
|
5925
|
+
});
|
|
5926
|
+
}
|
|
5927
|
+
}
|
|
5928
|
+
}
|
|
5929
|
+
};
|
|
5930
|
+
}
|
|
5931
|
+
});
|
|
5932
|
+
|
|
5229
5933
|
// src/rules/files/files-types-only.ts
|
|
5230
|
-
import { defineRule as
|
|
5934
|
+
import { defineRule as defineRule51 } from "@oxlint/plugins";
|
|
5231
5935
|
function runtimeImportLocalNames(statement) {
|
|
5232
5936
|
return statement.specifiers.flatMap((specifier) => specifier.type !== "ImportSpecifier" || specifier.importKind !== "type" ? [specifier.local.name] : []);
|
|
5233
5937
|
}
|
|
@@ -5396,7 +6100,7 @@ function runtimeKind(node) {
|
|
|
5396
6100
|
}
|
|
5397
6101
|
return node.type === "FunctionDeclaration" ? "function" : "variable";
|
|
5398
6102
|
}
|
|
5399
|
-
var filesTypesOnly =
|
|
6103
|
+
var filesTypesOnly = defineRule51({
|
|
5400
6104
|
meta: {
|
|
5401
6105
|
type: "problem",
|
|
5402
6106
|
schema: [
|
|
@@ -5504,8 +6208,8 @@ var filesTypesOnly = defineRule44({
|
|
|
5504
6208
|
});
|
|
5505
6209
|
|
|
5506
6210
|
// src/rules/layout/layout-arrow-body.ts
|
|
5507
|
-
import { defineRule as
|
|
5508
|
-
var layoutArrowBody =
|
|
6211
|
+
import { defineRule as defineRule52 } from "@oxlint/plugins";
|
|
6212
|
+
var layoutArrowBody = defineRule52({
|
|
5509
6213
|
meta: {
|
|
5510
6214
|
type: "layout",
|
|
5511
6215
|
fixable: "whitespace",
|
|
@@ -5557,12 +6261,12 @@ var layoutArrowBody = defineRule45({
|
|
|
5557
6261
|
});
|
|
5558
6262
|
|
|
5559
6263
|
// src/rules/layout/layout-call-arguments.ts
|
|
5560
|
-
import { defineRule as
|
|
6264
|
+
import { defineRule as defineRule53 } from "@oxlint/plugins";
|
|
5561
6265
|
function layoutCallArgumentsHuggable(node) {
|
|
5562
6266
|
return astIsInlineFunction(node) || node.type === "ObjectExpression" || node.type === "ArrayExpression" || astIsCall(node) && node.arguments.length === 1 && (node.callee.type !== "MemberExpression" || astIsOneLine(node.callee)) && node.arguments.every(layoutCallArgumentsHuggable);
|
|
5563
6267
|
}
|
|
5564
6268
|
var layoutCallArgumentsMax = { type: "integer", minimum: 1 };
|
|
5565
|
-
var layoutCallArguments =
|
|
6269
|
+
var layoutCallArguments = defineRule53({
|
|
5566
6270
|
meta: {
|
|
5567
6271
|
type: "layout",
|
|
5568
6272
|
fixable: "whitespace",
|
|
@@ -5708,7 +6412,7 @@ var layoutCallArguments = defineRule46({
|
|
|
5708
6412
|
fix: (fixer) => sourceRespace(fixer, text, gaps, (_, end) => `${newline}${end ? base : inner}`)
|
|
5709
6413
|
});
|
|
5710
6414
|
};
|
|
5711
|
-
const
|
|
6415
|
+
const join4 = (node, items, open, close) => {
|
|
5712
6416
|
const source = context.sourceCode;
|
|
5713
6417
|
const text = source.text;
|
|
5714
6418
|
const first = items.at(0);
|
|
@@ -5737,7 +6441,7 @@ var layoutCallArguments = defineRule46({
|
|
|
5737
6441
|
hug(node, options.hug.max);
|
|
5738
6442
|
}
|
|
5739
6443
|
if (options.join && !(options.join.keep ?? []).includes(source.getText(node.callee)) && !(isPipe(node) && (node.arguments.length > 1 || options.pipe)) && astCallDepth(node) <= (options.join.nesting ?? Number.POSITIVE_INFINITY)) {
|
|
5740
|
-
|
|
6444
|
+
join4(node, node.arguments, source.getTokenAfter(node.typeArguments ?? node.callee), source.getLastToken(node));
|
|
5741
6445
|
}
|
|
5742
6446
|
};
|
|
5743
6447
|
const parameters = (node) => {
|
|
@@ -5747,7 +6451,7 @@ var layoutCallArguments = defineRule46({
|
|
|
5747
6451
|
if (!options.join || !first || !last) {
|
|
5748
6452
|
return;
|
|
5749
6453
|
}
|
|
5750
|
-
|
|
6454
|
+
join4(node, node.params, source.getTokenBefore(first, { filter: (token) => token.value === "(" }), source.getTokenAfter(last, { filter: (token) => token.value === ")" }));
|
|
5751
6455
|
};
|
|
5752
6456
|
return {
|
|
5753
6457
|
before() {
|
|
@@ -5768,12 +6472,12 @@ var layoutCallArguments = defineRule46({
|
|
|
5768
6472
|
});
|
|
5769
6473
|
|
|
5770
6474
|
// src/rules/layout/layout-call-array.ts
|
|
5771
|
-
import { defineRule as
|
|
6475
|
+
import { defineRule as defineRule54 } from "@oxlint/plugins";
|
|
5772
6476
|
var layoutCallArrayDefaultCallees = ["Promise.all", "Promise.allSettled"];
|
|
5773
6477
|
function layoutCallArrayRoot(node) {
|
|
5774
6478
|
return node.type === "MemberExpression" ? layoutCallArrayRoot(node.object) : node;
|
|
5775
6479
|
}
|
|
5776
|
-
var layoutCallArray =
|
|
6480
|
+
var layoutCallArray = defineRule54({
|
|
5777
6481
|
meta: {
|
|
5778
6482
|
type: "layout",
|
|
5779
6483
|
fixable: "whitespace",
|
|
@@ -5889,7 +6593,7 @@ var layoutCallArray = defineRule47({
|
|
|
5889
6593
|
});
|
|
5890
6594
|
|
|
5891
6595
|
// src/rules/layout/layout-call-depth.ts
|
|
5892
|
-
import { defineRule as
|
|
6596
|
+
import { defineRule as defineRule55 } from "@oxlint/plugins";
|
|
5893
6597
|
function layoutCallDepthOuter(node, callbacks) {
|
|
5894
6598
|
const parent = node.parent;
|
|
5895
6599
|
if (!parent || !callbacks && (parent.type === "ArrowFunctionExpression" || parent.type === "FunctionExpression")) {
|
|
@@ -5904,7 +6608,7 @@ function layoutCallDepthOuter(node, callbacks) {
|
|
|
5904
6608
|
}
|
|
5905
6609
|
return astIsCall(parent) && parent.arguments.some((argument) => argument === node) ? parent : layoutCallDepthOuter(parent, callbacks);
|
|
5906
6610
|
}
|
|
5907
|
-
var layoutCallDepth =
|
|
6611
|
+
var layoutCallDepth = defineRule55({
|
|
5908
6612
|
meta: {
|
|
5909
6613
|
type: "layout",
|
|
5910
6614
|
schema: [
|
|
@@ -5946,8 +6650,8 @@ var layoutCallDepth = defineRule48({
|
|
|
5946
6650
|
});
|
|
5947
6651
|
|
|
5948
6652
|
// src/rules/layout/layout-chain.ts
|
|
5949
|
-
import { defineRule as
|
|
5950
|
-
var layoutChain =
|
|
6653
|
+
import { defineRule as defineRule56 } from "@oxlint/plugins";
|
|
6654
|
+
var layoutChain = defineRule56({
|
|
5951
6655
|
meta: {
|
|
5952
6656
|
type: "layout",
|
|
5953
6657
|
fixable: "whitespace",
|
|
@@ -6066,8 +6770,8 @@ var layoutChain = defineRule49({
|
|
|
6066
6770
|
});
|
|
6067
6771
|
|
|
6068
6772
|
// src/rules/layout/layout-items.ts
|
|
6069
|
-
import { defineRule as
|
|
6070
|
-
var layoutItems =
|
|
6773
|
+
import { defineRule as defineRule57 } from "@oxlint/plugins";
|
|
6774
|
+
var layoutItems = defineRule57({
|
|
6071
6775
|
meta: {
|
|
6072
6776
|
type: "layout",
|
|
6073
6777
|
fixable: "whitespace",
|
|
@@ -6122,8 +6826,8 @@ var layoutItems = defineRule50({
|
|
|
6122
6826
|
});
|
|
6123
6827
|
|
|
6124
6828
|
// src/rules/layout/layout-jsx-attributes.ts
|
|
6125
|
-
import { defineRule as
|
|
6126
|
-
var layoutJsxAttributes =
|
|
6829
|
+
import { defineRule as defineRule58 } from "@oxlint/plugins";
|
|
6830
|
+
var layoutJsxAttributes = defineRule58({
|
|
6127
6831
|
meta: {
|
|
6128
6832
|
type: "layout",
|
|
6129
6833
|
fixable: "whitespace",
|
|
@@ -6211,8 +6915,8 @@ var layoutJsxAttributes = defineRule51({
|
|
|
6211
6915
|
});
|
|
6212
6916
|
|
|
6213
6917
|
// src/rules/layout/layout-key-value.ts
|
|
6214
|
-
import { defineRule as
|
|
6215
|
-
var layoutKeyValue =
|
|
6918
|
+
import { defineRule as defineRule59 } from "@oxlint/plugins";
|
|
6919
|
+
var layoutKeyValue = defineRule59({
|
|
6216
6920
|
meta: {
|
|
6217
6921
|
type: "layout",
|
|
6218
6922
|
fixable: "whitespace",
|
|
@@ -6248,7 +6952,7 @@ var layoutKeyValue = defineRule52({
|
|
|
6248
6952
|
});
|
|
6249
6953
|
|
|
6250
6954
|
// src/rules/layout/layout-object.ts
|
|
6251
|
-
import { defineRule as
|
|
6955
|
+
import { defineRule as defineRule60 } from "@oxlint/plugins";
|
|
6252
6956
|
function layoutObjectIsWhitespace(text) {
|
|
6253
6957
|
return /^[\t\n\r\f ]*$/.test(text);
|
|
6254
6958
|
}
|
|
@@ -6256,7 +6960,7 @@ function layoutObjectIsFlat(property) {
|
|
|
6256
6960
|
const value = property.type === "SpreadElement" ? property.argument : property.value;
|
|
6257
6961
|
return astIsOneLine(property) && (property.type === "SpreadElement" || !property.method && property.kind === "init") && value.type !== "ObjectExpression" && value.type !== "ArrayExpression" && !astIsInlineFunction(value);
|
|
6258
6962
|
}
|
|
6259
|
-
var layoutObject =
|
|
6963
|
+
var layoutObject = defineRule60({
|
|
6260
6964
|
meta: {
|
|
6261
6965
|
type: "layout",
|
|
6262
6966
|
fixable: "whitespace",
|
|
@@ -6301,7 +7005,7 @@ var layoutObject = defineRule53({
|
|
|
6301
7005
|
let indentUnit = sourceIndentUnit();
|
|
6302
7006
|
let newline = `
|
|
6303
7007
|
`;
|
|
6304
|
-
let
|
|
7008
|
+
let join4;
|
|
6305
7009
|
let params = false;
|
|
6306
7010
|
let nested = false;
|
|
6307
7011
|
let siblings = false;
|
|
@@ -6359,7 +7063,7 @@ var layoutObject = defineRule53({
|
|
|
6359
7063
|
}
|
|
6360
7064
|
function joinBlocked(node, call) {
|
|
6361
7065
|
const callee = call && astIsCall(call) ? astDottedName(call.callee) : undefined;
|
|
6362
|
-
const kept = callee !== undefined && (
|
|
7066
|
+
const kept = callee !== undefined && (join4?.keep ?? []).some((name) => callee === name || callee.endsWith(`.${name}`));
|
|
6363
7067
|
return kept || keptByInner(node) || splitSiblings(node) > 1 || node.properties.length === 0 || !node.properties.every(layoutObjectIsFlat) || context.sourceCode.getCommentsInside(node).length > 0;
|
|
6364
7068
|
}
|
|
6365
7069
|
function reportSplit(node, properties, open, close, messageId) {
|
|
@@ -6422,7 +7126,7 @@ var layoutObject = defineRule53({
|
|
|
6422
7126
|
scope = options.scope ?? "call-args";
|
|
6423
7127
|
indentUnit = sourceIndentUnit(options.indent);
|
|
6424
7128
|
newline = sourceNewline(context.sourceCode.text);
|
|
6425
|
-
|
|
7129
|
+
join4 = options.join;
|
|
6426
7130
|
params = options.params ?? false;
|
|
6427
7131
|
nested = options.nested ?? false;
|
|
6428
7132
|
siblings = options.siblings ?? false;
|
|
@@ -6447,7 +7151,7 @@ var layoutObject = defineRule53({
|
|
|
6447
7151
|
return;
|
|
6448
7152
|
}
|
|
6449
7153
|
const split = full || holds;
|
|
6450
|
-
if (split ? !astIsOneLine(node) : !
|
|
7154
|
+
if (split ? !astIsOneLine(node) : !join4 || astIsOneLine(node)) {
|
|
6451
7155
|
return;
|
|
6452
7156
|
}
|
|
6453
7157
|
const call = (parent.type === "CallExpression" || parent.type === "NewExpression") && parent.arguments.includes(node) ? parent : undefined;
|
|
@@ -6461,7 +7165,7 @@ var layoutObject = defineRule53({
|
|
|
6461
7165
|
const gaps = sourceItemGaps(node.range[0] + 1, properties, node.range[1] - 1);
|
|
6462
7166
|
const comma = text.slice(...gaps.at(-1) ?? [0, 0]).includes(",") ? "," : "";
|
|
6463
7167
|
const joined = ` ${properties.map((property) => source.getText(property)).join(", ")}${comma} `;
|
|
6464
|
-
if (sourceJoinedWidth(text, node.range[0] + 1, joined, node.range[1] - 1) > (
|
|
7168
|
+
if (sourceJoinedWidth(text, node.range[0] + 1, joined, node.range[1] - 1) > (join4?.max ?? 0)) {
|
|
6465
7169
|
return;
|
|
6466
7170
|
}
|
|
6467
7171
|
context.report({
|
|
@@ -6480,7 +7184,7 @@ var layoutObject = defineRule53({
|
|
|
6480
7184
|
});
|
|
6481
7185
|
|
|
6482
7186
|
// src/rules/layout/layout-padding.ts
|
|
6483
|
-
import { defineRule as
|
|
7187
|
+
import { defineRule as defineRule61 } from "@oxlint/plugins";
|
|
6484
7188
|
var layoutPaddingControl = new Set([
|
|
6485
7189
|
"IfStatement",
|
|
6486
7190
|
"ForStatement",
|
|
@@ -6509,7 +7213,7 @@ function layoutPaddingKind(node) {
|
|
|
6509
7213
|
function layoutPaddingIsMultilineVariable(node, kind) {
|
|
6510
7214
|
return kind === "variable" && node.loc.start.line !== node.loc.end.line;
|
|
6511
7215
|
}
|
|
6512
|
-
var layoutPadding =
|
|
7216
|
+
var layoutPadding = defineRule61({
|
|
6513
7217
|
meta: {
|
|
6514
7218
|
type: "layout",
|
|
6515
7219
|
fixable: "whitespace",
|
|
@@ -6598,8 +7302,8 @@ var layoutPadding = defineRule54({
|
|
|
6598
7302
|
});
|
|
6599
7303
|
|
|
6600
7304
|
// src/rules/layout/layout-pipe.ts
|
|
6601
|
-
import { defineRule as
|
|
6602
|
-
var layoutPipe =
|
|
7305
|
+
import { defineRule as defineRule62 } from "@oxlint/plugins";
|
|
7306
|
+
var layoutPipe = defineRule62({
|
|
6603
7307
|
meta: {
|
|
6604
7308
|
type: "layout",
|
|
6605
7309
|
schema: [{ type: "object", additionalProperties: false, properties: { methods: { type: "array", items: { type: "string" } } } }],
|
|
@@ -6640,7 +7344,7 @@ var layoutPipe = defineRule55({
|
|
|
6640
7344
|
});
|
|
6641
7345
|
|
|
6642
7346
|
// src/rules/layout/layout-ternary.ts
|
|
6643
|
-
import { defineRule as
|
|
7347
|
+
import { defineRule as defineRule63 } from "@oxlint/plugins";
|
|
6644
7348
|
function layoutTernaryLines(node) {
|
|
6645
7349
|
return node.loc.end.line - node.loc.start.line + 1;
|
|
6646
7350
|
}
|
|
@@ -6648,7 +7352,7 @@ function layoutTernaryBreak(between, operator, newline) {
|
|
|
6648
7352
|
const at = between.indexOf(operator);
|
|
6649
7353
|
return `${between.slice(0, at).trimEnd()}${newline}${operator} ${between.slice(at + 1).trimStart()}`;
|
|
6650
7354
|
}
|
|
6651
|
-
var layoutTernary =
|
|
7355
|
+
var layoutTernary = defineRule63({
|
|
6652
7356
|
meta: {
|
|
6653
7357
|
type: "layout",
|
|
6654
7358
|
fixable: "whitespace",
|
|
@@ -6764,8 +7468,8 @@ var layoutTernary = defineRule56({
|
|
|
6764
7468
|
});
|
|
6765
7469
|
|
|
6766
7470
|
// src/rules/layout/layout-type-arguments.ts
|
|
6767
|
-
import { defineRule as
|
|
6768
|
-
var layoutTypeArguments =
|
|
7471
|
+
import { defineRule as defineRule64 } from "@oxlint/plugins";
|
|
7472
|
+
var layoutTypeArguments = defineRule64({
|
|
6769
7473
|
meta: {
|
|
6770
7474
|
type: "layout",
|
|
6771
7475
|
fixable: "code",
|
|
@@ -6824,13 +7528,14 @@ var layoutTypeArguments = defineRule57({
|
|
|
6824
7528
|
});
|
|
6825
7529
|
|
|
6826
7530
|
// src/rules/naming/naming-declarations.ts
|
|
6827
|
-
import { defineRule as
|
|
7531
|
+
import { defineRule as defineRule65 } from "@oxlint/plugins";
|
|
6828
7532
|
var namingDeclarationsKinds = ["function", "const", "let", "var", "class", "type", "interface", "enum"];
|
|
6829
|
-
var namingDeclarations =
|
|
7533
|
+
var namingDeclarations = defineRule65({
|
|
6830
7534
|
meta: {
|
|
6831
7535
|
type: "problem",
|
|
6832
|
-
schema:
|
|
6833
|
-
|
|
7536
|
+
schema: {
|
|
7537
|
+
type: "array",
|
|
7538
|
+
items: {
|
|
6834
7539
|
type: "object",
|
|
6835
7540
|
additionalProperties: false,
|
|
6836
7541
|
properties: {
|
|
@@ -6841,56 +7546,61 @@ var namingDeclarations = defineRule58({
|
|
|
6841
7546
|
allow: optionsPatternSchema
|
|
6842
7547
|
}
|
|
6843
7548
|
}
|
|
6844
|
-
|
|
7549
|
+
},
|
|
6845
7550
|
messages: {
|
|
6846
7551
|
prefix: "'{{name}}' must start with file prefix '{{prefix}}'.",
|
|
6847
7552
|
pattern: "'{{name}}' must match {{pattern}}."
|
|
6848
7553
|
}
|
|
6849
7554
|
},
|
|
6850
7555
|
createOnce(context) {
|
|
6851
|
-
let
|
|
6852
|
-
let kinds = null;
|
|
6853
|
-
let allowed = [];
|
|
6854
|
-
let expected = [];
|
|
6855
|
-
let prefixes = [];
|
|
6856
|
-
let label = "";
|
|
7556
|
+
let checks = [];
|
|
6857
7557
|
function check(node) {
|
|
6858
7558
|
const declarator = node.type === "VariableDeclarator";
|
|
6859
7559
|
const kind = declarationsKindOf(node, declarator ? [node.parent] : []);
|
|
6860
7560
|
const name = declarationsIdName(node);
|
|
6861
7561
|
const loop = declarator ? node.parent.parent : null;
|
|
6862
7562
|
const loopHeader = loop?.type === "ForStatement" ? loop.init === node.parent : (loop?.type === "ForInStatement" || loop?.type === "ForOfStatement") && loop.left === node.parent;
|
|
6863
|
-
if (!kind || !name || loopHeader
|
|
7563
|
+
if (!kind || !name || loopHeader) {
|
|
6864
7564
|
return;
|
|
6865
7565
|
}
|
|
6866
|
-
|
|
6867
|
-
if (optionsPatternsTest(
|
|
6868
|
-
|
|
7566
|
+
for (const { kinds, allowed, expected, prefixes, label, normalize } of checks) {
|
|
7567
|
+
if (kinds && !kinds.has(kind) || optionsPatternsTest(allowed, name)) {
|
|
7568
|
+
continue;
|
|
7569
|
+
}
|
|
7570
|
+
if (expected.length > 0) {
|
|
7571
|
+
if (!optionsPatternsTest(expected, name)) {
|
|
7572
|
+
context.report({
|
|
7573
|
+
node,
|
|
7574
|
+
messageId: "pattern",
|
|
7575
|
+
data: { name, pattern: label }
|
|
7576
|
+
});
|
|
7577
|
+
}
|
|
7578
|
+
continue;
|
|
7579
|
+
}
|
|
7580
|
+
if (!namingHasFilePrefix(name, prefixes, normalize)) {
|
|
7581
|
+
context.report({
|
|
7582
|
+
node,
|
|
7583
|
+
messageId: "prefix",
|
|
7584
|
+
data: { name, prefix: prefixes.join(" or ") }
|
|
7585
|
+
});
|
|
6869
7586
|
}
|
|
6870
|
-
context.report({
|
|
6871
|
-
node,
|
|
6872
|
-
messageId: "pattern",
|
|
6873
|
-
data: { name, pattern: label }
|
|
6874
|
-
});
|
|
6875
|
-
return;
|
|
6876
|
-
}
|
|
6877
|
-
if (namingHasFilePrefix(name, prefixes, options.normalize)) {
|
|
6878
|
-
return;
|
|
6879
7587
|
}
|
|
6880
|
-
context.report({
|
|
6881
|
-
node,
|
|
6882
|
-
messageId: "prefix",
|
|
6883
|
-
data: { name, prefix: prefixes.join(" or ") }
|
|
6884
|
-
});
|
|
6885
7588
|
}
|
|
6886
7589
|
return {
|
|
6887
7590
|
before() {
|
|
6888
|
-
|
|
6889
|
-
|
|
6890
|
-
|
|
6891
|
-
|
|
6892
|
-
|
|
6893
|
-
|
|
7591
|
+
const given = optionsAll(context);
|
|
7592
|
+
const captures = namingCaptures(context.filename) ?? {};
|
|
7593
|
+
checks = (given.length > 0 ? given : [{}]).map((options) => {
|
|
7594
|
+
const sources = options.pattern === undefined ? [] : [options.pattern].flat().map((source) => namingExpand(source, captures, true, optionsEscape));
|
|
7595
|
+
return {
|
|
7596
|
+
kinds: options.kinds?.length ? new Set(options.kinds) : null,
|
|
7597
|
+
allowed: optionsPatterns(options.allow),
|
|
7598
|
+
expected: optionsPatterns(sources, options.flags),
|
|
7599
|
+
prefixes: namingFilePrefixesFor(context.filename, options),
|
|
7600
|
+
label: optionsPatternLabel(sources),
|
|
7601
|
+
normalize: options.normalize
|
|
7602
|
+
};
|
|
7603
|
+
});
|
|
6894
7604
|
},
|
|
6895
7605
|
FunctionDeclaration: check,
|
|
6896
7606
|
ClassDeclaration: check,
|
|
@@ -6903,33 +7613,14 @@ var namingDeclarations = defineRule58({
|
|
|
6903
7613
|
});
|
|
6904
7614
|
|
|
6905
7615
|
// src/rules/naming/naming-exports.ts
|
|
6906
|
-
import { defineRule as
|
|
7616
|
+
import { defineRule as defineRule66 } from "@oxlint/plugins";
|
|
6907
7617
|
var namingExportsScopeProperties = {
|
|
6908
7618
|
scope: { type: "string", enum: ["exports", "functions", "declarations"] },
|
|
6909
7619
|
types: { type: "boolean" },
|
|
6910
7620
|
services: { type: "boolean" },
|
|
6911
7621
|
allow: optionsPatternSchema
|
|
6912
7622
|
};
|
|
6913
|
-
|
|
6914
|
-
let pattern = "";
|
|
6915
|
-
let index = 0;
|
|
6916
|
-
while (index < template.length) {
|
|
6917
|
-
const char = template[index];
|
|
6918
|
-
if (char === "{") {
|
|
6919
|
-
const end = template.indexOf("}", index);
|
|
6920
|
-
if (end === -1) {
|
|
6921
|
-
return null;
|
|
6922
|
-
}
|
|
6923
|
-
pattern += `(?<${template.slice(index + 1, end)}>${placeholder})`;
|
|
6924
|
-
index = end + 1;
|
|
6925
|
-
continue;
|
|
6926
|
-
}
|
|
6927
|
-
pattern += /[.+^${}()|[\]\\]/.test(char) ? `\\${char}` : char;
|
|
6928
|
-
index += 1;
|
|
6929
|
-
}
|
|
6930
|
-
return new RegExp(`^${pattern}$`).exec(basename3)?.groups ?? null;
|
|
6931
|
-
}
|
|
6932
|
-
var namingExports = defineRule59({
|
|
7623
|
+
var namingExports = defineRule66({
|
|
6933
7624
|
meta: {
|
|
6934
7625
|
type: "problem",
|
|
6935
7626
|
schema: {
|
|
@@ -6959,7 +7650,7 @@ var namingExports = defineRule59({
|
|
|
6959
7650
|
mode: { type: "string", enum: ["template"] },
|
|
6960
7651
|
...namingExportsScopeProperties,
|
|
6961
7652
|
file: { type: "string" },
|
|
6962
|
-
export:
|
|
7653
|
+
export: optionsPatternSchema,
|
|
6963
7654
|
match: { type: "string", enum: ["all", "some"] },
|
|
6964
7655
|
placeholder: { type: "string" },
|
|
6965
7656
|
camelCase: { type: "boolean" }
|
|
@@ -6986,23 +7677,15 @@ var namingExports = defineRule59({
|
|
|
6986
7677
|
const allowed = optionsPatterns(options.allow);
|
|
6987
7678
|
if (options.mode === "template") {
|
|
6988
7679
|
const file = namingBasename(context.filename);
|
|
6989
|
-
const
|
|
6990
|
-
if (!
|
|
7680
|
+
const captures2 = namingCaptures(context.filename, { file: options.file, placeholder: options.placeholder });
|
|
7681
|
+
if (!captures2) {
|
|
6991
7682
|
continue;
|
|
6992
7683
|
}
|
|
6993
|
-
const
|
|
6994
|
-
|
|
6995
|
-
if (!group) {
|
|
6996
|
-
return placeholder;
|
|
6997
|
-
}
|
|
6998
|
-
if (/^[A-Z]/.test(key)) {
|
|
6999
|
-
return namingPascalCase(group);
|
|
7000
|
-
}
|
|
7001
|
-
return options.camelCase ? namingCamelCase(group) : group;
|
|
7002
|
-
});
|
|
7684
|
+
const names2 = [options.export].flat().map((template) => namingExpand(template, captures2, options.camelCase ?? false));
|
|
7685
|
+
const expected2 = names2.join(" or ");
|
|
7003
7686
|
const functions = (scope === "exports" ? exportsFunctions(program, true) : declarationsFunctions(program)).filter(({ name }) => !optionsPatternsTest(allowed, name));
|
|
7004
7687
|
if (options.match === "some") {
|
|
7005
|
-
if (functions.some((item) => item.name
|
|
7688
|
+
if (functions.some((item) => names2.includes(item.name))) {
|
|
7006
7689
|
continue;
|
|
7007
7690
|
}
|
|
7008
7691
|
const first = functions.at(0);
|
|
@@ -7014,7 +7697,7 @@ var namingExports = defineRule59({
|
|
|
7014
7697
|
continue;
|
|
7015
7698
|
}
|
|
7016
7699
|
for (const item of functions) {
|
|
7017
|
-
if (item.name
|
|
7700
|
+
if (!names2.includes(item.name)) {
|
|
7018
7701
|
context.report({
|
|
7019
7702
|
node: item.node,
|
|
7020
7703
|
messageId: "mismatch",
|
|
@@ -7036,7 +7719,9 @@ var namingExports = defineRule59({
|
|
|
7036
7719
|
names.push(...declarationsPublicServiceMethods(program));
|
|
7037
7720
|
}
|
|
7038
7721
|
const prefixes = options.mode === "pattern" ? [] : namingFilePrefixesFor(context.filename, options);
|
|
7039
|
-
const
|
|
7722
|
+
const captures = namingCaptures(context.filename) ?? {};
|
|
7723
|
+
const sources = options.mode === "pattern" ? [options.pattern].flat().map((source) => namingExpand(source, captures, true, optionsEscape)) : [];
|
|
7724
|
+
const expected = optionsPatternsWithEmpty(sources, options.mode === "pattern" ? options.flags : undefined);
|
|
7040
7725
|
for (const item of declarationsUnique(names)) {
|
|
7041
7726
|
if (optionsPatternsTest(allowed, item.name)) {
|
|
7042
7727
|
continue;
|
|
@@ -7046,7 +7731,7 @@ var namingExports = defineRule59({
|
|
|
7046
7731
|
context.report({
|
|
7047
7732
|
node: item.node,
|
|
7048
7733
|
messageId: "pattern",
|
|
7049
|
-
data: { name: item.name, pattern: optionsPatternLabel(
|
|
7734
|
+
data: { name: item.name, pattern: optionsPatternLabel(sources) }
|
|
7050
7735
|
});
|
|
7051
7736
|
}
|
|
7052
7737
|
continue;
|
|
@@ -7066,10 +7751,10 @@ var namingExports = defineRule59({
|
|
|
7066
7751
|
});
|
|
7067
7752
|
|
|
7068
7753
|
// src/rules/naming/naming-file.ts
|
|
7069
|
-
import { defineRule as
|
|
7754
|
+
import { defineRule as defineRule67 } from "@oxlint/plugins";
|
|
7070
7755
|
import { readdirSync as readdirSync2 } from "node:fs";
|
|
7071
|
-
import { dirname as
|
|
7072
|
-
var namingFile =
|
|
7756
|
+
import { dirname as dirname5 } from "node:path";
|
|
7757
|
+
var namingFile = defineRule67({
|
|
7073
7758
|
meta: {
|
|
7074
7759
|
type: "problem",
|
|
7075
7760
|
schema: {
|
|
@@ -7081,9 +7766,12 @@ var namingFile = defineRule60({
|
|
|
7081
7766
|
pattern: optionsPatternSchema,
|
|
7082
7767
|
message: { type: "string" },
|
|
7083
7768
|
flags: { type: "string" },
|
|
7084
|
-
unique: { type: "string", minLength: 1 }
|
|
7769
|
+
unique: { type: "string", minLength: 1 },
|
|
7770
|
+
template: optionsPatternSchema,
|
|
7771
|
+
placeholder: { type: "string" }
|
|
7085
7772
|
},
|
|
7086
|
-
required: ["
|
|
7773
|
+
required: ["message"],
|
|
7774
|
+
anyOf: [{ required: ["pattern"] }, { required: ["template"] }]
|
|
7087
7775
|
}
|
|
7088
7776
|
},
|
|
7089
7777
|
messages: {
|
|
@@ -7096,9 +7784,12 @@ var namingFile = defineRule60({
|
|
|
7096
7784
|
Program(program) {
|
|
7097
7785
|
const basename3 = namingBasename(context.filename);
|
|
7098
7786
|
let siblings;
|
|
7099
|
-
for (const { pattern, message, flags, unique } of optionsAll(context)) {
|
|
7787
|
+
for (const { pattern, message, flags, unique, template, placeholder } of optionsAll(context)) {
|
|
7100
7788
|
const patterns = optionsPatternsWithEmpty(pattern, flags);
|
|
7101
|
-
|
|
7789
|
+
const path = context.filename.replaceAll("\\", "/").split("/");
|
|
7790
|
+
const templates = [template ?? []].flat();
|
|
7791
|
+
const fits = templates.some((item) => namingTemplatePattern(item, placeholder)?.test(path.slice(-item.split("/").length).join("/")));
|
|
7792
|
+
if (pattern !== undefined && !optionsPatternsTest(patterns, basename3) || templates.length > 0 && !fits) {
|
|
7102
7793
|
context.report({
|
|
7103
7794
|
node: program,
|
|
7104
7795
|
messageId: "mismatch",
|
|
@@ -7119,7 +7810,7 @@ var namingFile = defineRule60({
|
|
|
7119
7810
|
}
|
|
7120
7811
|
if (!siblings) {
|
|
7121
7812
|
try {
|
|
7122
|
-
siblings = readdirSync2(
|
|
7813
|
+
siblings = readdirSync2(dirname5(context.filename), { withFileTypes: true }).flatMap((entry) => entry.isFile() ? [entry.name] : []);
|
|
7123
7814
|
} catch {
|
|
7124
7815
|
siblings = [];
|
|
7125
7816
|
}
|
|
@@ -7139,9 +7830,9 @@ var namingFile = defineRule60({
|
|
|
7139
7830
|
});
|
|
7140
7831
|
|
|
7141
7832
|
// src/rules/naming/naming-folder.ts
|
|
7142
|
-
import { defineRule as
|
|
7143
|
-
import { posix as
|
|
7144
|
-
var namingFolder =
|
|
7833
|
+
import { defineRule as defineRule68 } from "@oxlint/plugins";
|
|
7834
|
+
import { posix as posix2 } from "node:path";
|
|
7835
|
+
var namingFolder = defineRule68({
|
|
7145
7836
|
meta: {
|
|
7146
7837
|
type: "problem",
|
|
7147
7838
|
schema: [
|
|
@@ -7164,7 +7855,7 @@ var namingFolder = defineRule61({
|
|
|
7164
7855
|
return {
|
|
7165
7856
|
Program(program) {
|
|
7166
7857
|
const { singularize = "trailing-s", separators = ["-"], after, prefixes: stripPrefixes = [] } = optionsFirst(context, {});
|
|
7167
|
-
const all =
|
|
7858
|
+
const all = posix2.dirname(context.filename.replaceAll("\\", "/")).split("/").filter((part) => part && part !== ".");
|
|
7168
7859
|
const parent = [all.at(-1) ?? ""];
|
|
7169
7860
|
let folders = after ? undefined : parent;
|
|
7170
7861
|
const marker = (after ?? "").split("/").filter(Boolean);
|
|
@@ -7205,9 +7896,451 @@ var namingFolder = defineRule61({
|
|
|
7205
7896
|
}
|
|
7206
7897
|
});
|
|
7207
7898
|
|
|
7899
|
+
// src/rules/naming/naming-imports.ts
|
|
7900
|
+
import { defineRule as defineRule69 } from "@oxlint/plugins";
|
|
7901
|
+
var namingImports = defineRule69({
|
|
7902
|
+
meta: {
|
|
7903
|
+
type: "problem",
|
|
7904
|
+
schema: [
|
|
7905
|
+
{
|
|
7906
|
+
type: "object",
|
|
7907
|
+
additionalProperties: false,
|
|
7908
|
+
properties: {
|
|
7909
|
+
imports: {
|
|
7910
|
+
type: "array",
|
|
7911
|
+
items: {
|
|
7912
|
+
type: "object",
|
|
7913
|
+
additionalProperties: false,
|
|
7914
|
+
properties: {
|
|
7915
|
+
source: { type: "string" },
|
|
7916
|
+
name: optionsPatternSchema,
|
|
7917
|
+
namespace: { type: "boolean" },
|
|
7918
|
+
placeholder: { type: "string" }
|
|
7919
|
+
},
|
|
7920
|
+
required: ["source", "name"]
|
|
7921
|
+
}
|
|
7922
|
+
}
|
|
7923
|
+
},
|
|
7924
|
+
required: ["imports"]
|
|
7925
|
+
}
|
|
7926
|
+
],
|
|
7927
|
+
messages: {
|
|
7928
|
+
name: "Import '{{source}}' as '{{expected}}', not '{{actual}}'.",
|
|
7929
|
+
namespace: "Import '{{source}}' as a namespace: import * as {{expected}}."
|
|
7930
|
+
}
|
|
7931
|
+
},
|
|
7932
|
+
createOnce(context) {
|
|
7933
|
+
let entries = [];
|
|
7934
|
+
return {
|
|
7935
|
+
before() {
|
|
7936
|
+
entries = optionsFirst(context, { imports: [] }).imports.flatMap((entry) => {
|
|
7937
|
+
const pattern = namingTemplatePattern(entry.source, entry.placeholder ?? "[^/]+");
|
|
7938
|
+
return pattern ? [{ pattern, names: [entry.name].flat(), namespace: entry.namespace !== false }] : [];
|
|
7939
|
+
});
|
|
7940
|
+
if (entries.length === 0) {
|
|
7941
|
+
return false;
|
|
7942
|
+
}
|
|
7943
|
+
},
|
|
7944
|
+
ImportDeclaration(node) {
|
|
7945
|
+
const source = node.source.value;
|
|
7946
|
+
for (const entry of entries) {
|
|
7947
|
+
const match = entry.pattern.exec(source);
|
|
7948
|
+
if (!match) {
|
|
7949
|
+
continue;
|
|
7950
|
+
}
|
|
7951
|
+
const names = entry.names.map((template) => namingExpand(template, { ...match.groups }, true));
|
|
7952
|
+
const expected = names.join(" or ");
|
|
7953
|
+
for (const specifier of node.specifiers) {
|
|
7954
|
+
if (specifier.type !== "ImportNamespaceSpecifier" && entry.namespace) {
|
|
7955
|
+
context.report({
|
|
7956
|
+
node: specifier,
|
|
7957
|
+
messageId: "namespace",
|
|
7958
|
+
data: { source, expected }
|
|
7959
|
+
});
|
|
7960
|
+
} else if (specifier.type !== "ImportSpecifier" && !names.includes(specifier.local.name)) {
|
|
7961
|
+
context.report({
|
|
7962
|
+
node: specifier,
|
|
7963
|
+
messageId: "name",
|
|
7964
|
+
data: { source, expected, actual: specifier.local.name }
|
|
7965
|
+
});
|
|
7966
|
+
}
|
|
7967
|
+
}
|
|
7968
|
+
return;
|
|
7969
|
+
}
|
|
7970
|
+
}
|
|
7971
|
+
};
|
|
7972
|
+
}
|
|
7973
|
+
});
|
|
7974
|
+
|
|
7975
|
+
// src/rules/naming/naming-keys.ts
|
|
7976
|
+
import { defineRule as defineRule70 } from "@oxlint/plugins";
|
|
7977
|
+
function namingKeysNames(value) {
|
|
7978
|
+
const dotted = astDottedName(value);
|
|
7979
|
+
return dotted === undefined ? [] : [...new Set([dotted.split(".").at(-1) ?? dotted, dotted.split(".")[0]])];
|
|
7980
|
+
}
|
|
7981
|
+
function namingKeysSingular(key, options) {
|
|
7982
|
+
return options.singularize === "trailing-s" && key.length > 1 && key.endsWith("s") ? [key, key.slice(0, -1)] : [key];
|
|
7983
|
+
}
|
|
7984
|
+
function namingKeysSources(options, captures, keys) {
|
|
7985
|
+
const last = keys.at(-1) ?? "";
|
|
7986
|
+
return [options.name ?? []].flat().flatMap((source) => namingKeysSingular(last, options).map((key) => {
|
|
7987
|
+
const values = { ...captures, path: keys.join("-"), key };
|
|
7988
|
+
return namingExpand(source, values, true, optionsEscape);
|
|
7989
|
+
}));
|
|
7990
|
+
}
|
|
7991
|
+
function namingKeysFunction(value) {
|
|
7992
|
+
if (astIsInlineFunction(value)) {
|
|
7993
|
+
return value;
|
|
7994
|
+
}
|
|
7995
|
+
return value.type === "CallExpression" ? value.arguments.find(astIsInlineFunction) ?? namingKeysFunction(value.callee) : undefined;
|
|
7996
|
+
}
|
|
7997
|
+
function namingKeysYielded(node) {
|
|
7998
|
+
let found;
|
|
7999
|
+
astSome(node, (candidate) => {
|
|
8000
|
+
const call = candidate.type === "YieldExpression" && candidate.delegate && candidate.argument ? astUnwrap(candidate.argument) : undefined;
|
|
8001
|
+
found ??= call?.type === "CallExpression" ? call : undefined;
|
|
8002
|
+
return found !== undefined;
|
|
8003
|
+
});
|
|
8004
|
+
return found;
|
|
8005
|
+
}
|
|
8006
|
+
function namingKeysAssigned(fn, returned) {
|
|
8007
|
+
let found;
|
|
8008
|
+
astSome(fn.body, (candidate) => {
|
|
8009
|
+
const local = candidate.type === "VariableDeclarator" && candidate.id.type === "Identifier" && candidate.init ? candidate.id.name : undefined;
|
|
8010
|
+
const used = local !== undefined && astSome(returned, (node) => node.type === "Identifier" && node.name === local);
|
|
8011
|
+
found ??= used && candidate.type === "VariableDeclarator" && candidate.init ? namingKeysYielded(candidate.init) : undefined;
|
|
8012
|
+
return found !== undefined;
|
|
8013
|
+
});
|
|
8014
|
+
return found;
|
|
8015
|
+
}
|
|
8016
|
+
function namingKeysCalled(fn) {
|
|
8017
|
+
const returned = astReturnExpressions(fn).at(-1);
|
|
8018
|
+
if (!returned) {
|
|
8019
|
+
return;
|
|
8020
|
+
}
|
|
8021
|
+
const plain = astUnwrap(returned);
|
|
8022
|
+
const direct = !fn.generator && plain.type === "CallExpression" ? plain : undefined;
|
|
8023
|
+
const call = namingKeysYielded(returned) ?? namingKeysAssigned(fn, returned) ?? direct;
|
|
8024
|
+
return call ? astDottedName(call.callee) : undefined;
|
|
8025
|
+
}
|
|
8026
|
+
var namingKeys = defineRule70({
|
|
8027
|
+
meta: {
|
|
8028
|
+
type: "problem",
|
|
8029
|
+
schema: [
|
|
8030
|
+
{
|
|
8031
|
+
type: "object",
|
|
8032
|
+
additionalProperties: false,
|
|
8033
|
+
properties: {
|
|
8034
|
+
callees: { type: "array", items: { type: "string" }, minItems: 1 },
|
|
8035
|
+
exports: optionsPatternSchema,
|
|
8036
|
+
name: optionsPatternSchema,
|
|
8037
|
+
keys: optionsPatternSchema,
|
|
8038
|
+
inline: { type: "boolean" },
|
|
8039
|
+
delegate: { type: "boolean" },
|
|
8040
|
+
allow: optionsPatternSchema,
|
|
8041
|
+
singularize: { type: "string", enum: ["none", "trailing-s"] }
|
|
8042
|
+
},
|
|
8043
|
+
anyOf: [{ required: ["callees"] }, { required: ["exports"] }]
|
|
8044
|
+
}
|
|
8045
|
+
],
|
|
8046
|
+
messages: {
|
|
8047
|
+
name: "'{{name}}' under key '{{path}}' must match {{pattern}}.",
|
|
8048
|
+
key: "Key '{{key}}' in '{{path}}' must match {{pattern}}.",
|
|
8049
|
+
inline: "Bind a named function under '{{path}}', not an inline one.",
|
|
8050
|
+
delegate: "'{{path}}' must return a call to '{{path}}' on its service, not '{{called}}'."
|
|
8051
|
+
}
|
|
8052
|
+
},
|
|
8053
|
+
createOnce(context) {
|
|
8054
|
+
let options = {};
|
|
8055
|
+
let captures = {};
|
|
8056
|
+
let callees = [];
|
|
8057
|
+
let exported = [];
|
|
8058
|
+
let allowed = [];
|
|
8059
|
+
let keyPatterns = [];
|
|
8060
|
+
function checkValue(value, keys) {
|
|
8061
|
+
const path = keys.join(".");
|
|
8062
|
+
const fn = namingKeysFunction(value);
|
|
8063
|
+
const names = namingKeysNames(value);
|
|
8064
|
+
const sources = namingKeysSources(options, captures, keys);
|
|
8065
|
+
const called = options.delegate && fn ? namingKeysCalled(fn) : undefined;
|
|
8066
|
+
if (fn && astIsInlineFunction(value) && options.inline === false) {
|
|
8067
|
+
context.report({
|
|
8068
|
+
node: value,
|
|
8069
|
+
messageId: "inline",
|
|
8070
|
+
data: { path }
|
|
8071
|
+
});
|
|
8072
|
+
}
|
|
8073
|
+
if (called !== undefined && called.split(".").slice(1).join(".") !== path) {
|
|
8074
|
+
context.report({
|
|
8075
|
+
node: value,
|
|
8076
|
+
messageId: "delegate",
|
|
8077
|
+
data: { path, called }
|
|
8078
|
+
});
|
|
8079
|
+
}
|
|
8080
|
+
if (sources.length > 0 && names.length > 0 && !names.some((name) => optionsPatternsTest(optionsPatterns(sources), name))) {
|
|
8081
|
+
context.report({
|
|
8082
|
+
node: value,
|
|
8083
|
+
messageId: "name",
|
|
8084
|
+
data: { name: names[0], path, pattern: optionsPatternLabel(sources) }
|
|
8085
|
+
});
|
|
8086
|
+
}
|
|
8087
|
+
}
|
|
8088
|
+
function check(object, path) {
|
|
8089
|
+
for (const property of object.properties) {
|
|
8090
|
+
const key = declarationsPropertyName(property);
|
|
8091
|
+
const keys = key === undefined ? path : [...path, key];
|
|
8092
|
+
if (property.type !== "Property" || key === undefined || optionsPatternsTest(allowed, keys.join("."))) {
|
|
8093
|
+
continue;
|
|
8094
|
+
}
|
|
8095
|
+
if (keyPatterns.length > 0 && !optionsPatternsTest(keyPatterns, key)) {
|
|
8096
|
+
context.report({
|
|
8097
|
+
node: property.key,
|
|
8098
|
+
messageId: "key",
|
|
8099
|
+
data: { key, path: keys.join("."), pattern: optionsPatternLabel(options.keys) }
|
|
8100
|
+
});
|
|
8101
|
+
}
|
|
8102
|
+
if (property.value.type === "ObjectExpression") {
|
|
8103
|
+
check(property.value, keys);
|
|
8104
|
+
} else {
|
|
8105
|
+
checkValue(property.value, keys);
|
|
8106
|
+
}
|
|
8107
|
+
}
|
|
8108
|
+
}
|
|
8109
|
+
return {
|
|
8110
|
+
before() {
|
|
8111
|
+
options = optionsFirst(context, {});
|
|
8112
|
+
captures = namingCaptures(context.filename) ?? {};
|
|
8113
|
+
callees = optionsWildcards(options.callees);
|
|
8114
|
+
exported = optionsPatterns(options.exports);
|
|
8115
|
+
allowed = optionsPatterns(options.allow);
|
|
8116
|
+
keyPatterns = optionsPatterns(options.keys);
|
|
8117
|
+
if (callees.length === 0 && exported.length === 0) {
|
|
8118
|
+
return false;
|
|
8119
|
+
}
|
|
8120
|
+
},
|
|
8121
|
+
CallExpression(node) {
|
|
8122
|
+
const first = node.arguments.at(0);
|
|
8123
|
+
if (first?.type === "ObjectExpression" && optionsPatternsTest(callees, astDottedName(node.callee) ?? "")) {
|
|
8124
|
+
check(first, []);
|
|
8125
|
+
}
|
|
8126
|
+
},
|
|
8127
|
+
VariableDeclarator(node) {
|
|
8128
|
+
const statement = node.parent.parent;
|
|
8129
|
+
const top = statement?.type === "ExportNamedDeclaration" && statement.parent.type === "Program";
|
|
8130
|
+
const value = node.init ? astUnwrap(node.init) : null;
|
|
8131
|
+
if (top && node.id.type === "Identifier" && value?.type === "ObjectExpression" && optionsPatternsTest(exported, node.id.name)) {
|
|
8132
|
+
check(value, []);
|
|
8133
|
+
}
|
|
8134
|
+
}
|
|
8135
|
+
};
|
|
8136
|
+
}
|
|
8137
|
+
});
|
|
8138
|
+
|
|
8139
|
+
// src/rules/naming/naming-labels.ts
|
|
8140
|
+
import { defineRule as defineRule71 } from "@oxlint/plugins";
|
|
8141
|
+
function namingLabelsRoot(node) {
|
|
8142
|
+
return node.type === "CallExpression" ? namingLabelsRoot(node.callee) : astDottedName(node);
|
|
8143
|
+
}
|
|
8144
|
+
function namingLabelsBinding(node, within) {
|
|
8145
|
+
const parent = node.parent;
|
|
8146
|
+
if (!parent) {
|
|
8147
|
+
return;
|
|
8148
|
+
}
|
|
8149
|
+
if (parent.type === "VariableDeclarator" && parent.init === node) {
|
|
8150
|
+
return parent.id.type === "Identifier" ? parent.id.name : undefined;
|
|
8151
|
+
}
|
|
8152
|
+
if ((parent.type === "ClassDeclaration" || parent.type === "ClassExpression") && parent.superClass === node) {
|
|
8153
|
+
return parent.id?.name;
|
|
8154
|
+
}
|
|
8155
|
+
if (parent.type === "CallExpression" && parent.callee === node || parent.type === "MemberExpression" && parent.object === node) {
|
|
8156
|
+
return namingLabelsBinding(parent, within);
|
|
8157
|
+
}
|
|
8158
|
+
const owner = parent.type === "CallExpression" && parent.callee.type === "MemberExpression" ? astDottedName(parent.callee) : undefined;
|
|
8159
|
+
return owner !== undefined && optionsPatternsTest(within, owner) ? owner.split(".").at(-2) : undefined;
|
|
8160
|
+
}
|
|
8161
|
+
function namingLabelsTarget(first, property) {
|
|
8162
|
+
if (property === undefined) {
|
|
8163
|
+
return first;
|
|
8164
|
+
}
|
|
8165
|
+
const held = first.type === "ObjectExpression" ? first.properties.find((item) => declarationsPropertyName(item) === property) : undefined;
|
|
8166
|
+
return held?.type === "Property" ? held.value : undefined;
|
|
8167
|
+
}
|
|
8168
|
+
function namingLabelsPlain(text, loose) {
|
|
8169
|
+
return loose ? text.replaceAll(/[._\-/\s]/g, "").toLowerCase() : text;
|
|
8170
|
+
}
|
|
8171
|
+
function namingLabelsExpected({ entry, drop }, captures, binding) {
|
|
8172
|
+
const name = drop.reduce((text, pattern) => text.replace(pattern, ""), binding);
|
|
8173
|
+
return [entry.name ?? []].flat().map((template) => namingExpand(template, { ...captures, name }, false));
|
|
8174
|
+
}
|
|
8175
|
+
var namingLabels = defineRule71({
|
|
8176
|
+
meta: {
|
|
8177
|
+
type: "problem",
|
|
8178
|
+
schema: [
|
|
8179
|
+
{
|
|
8180
|
+
type: "object",
|
|
8181
|
+
additionalProperties: false,
|
|
8182
|
+
properties: {
|
|
8183
|
+
labels: {
|
|
8184
|
+
type: "array",
|
|
8185
|
+
items: {
|
|
8186
|
+
type: "object",
|
|
8187
|
+
additionalProperties: false,
|
|
8188
|
+
properties: {
|
|
8189
|
+
callee: optionsPatternSchema,
|
|
8190
|
+
property: { type: "string" },
|
|
8191
|
+
name: optionsPatternSchema,
|
|
8192
|
+
pattern: optionsPatternSchema,
|
|
8193
|
+
drop: optionsPatternSchema,
|
|
8194
|
+
loose: { type: "boolean" },
|
|
8195
|
+
within: optionsPatternSchema
|
|
8196
|
+
},
|
|
8197
|
+
required: ["callee"],
|
|
8198
|
+
anyOf: [{ required: ["name"] }, { required: ["pattern"] }]
|
|
8199
|
+
}
|
|
8200
|
+
}
|
|
8201
|
+
},
|
|
8202
|
+
required: ["labels"]
|
|
8203
|
+
}
|
|
8204
|
+
],
|
|
8205
|
+
messages: {
|
|
8206
|
+
name: "'{{label}}' must be '{{expected}}', after the name '{{name}}'.",
|
|
8207
|
+
pattern: "'{{label}}' must match {{pattern}}."
|
|
8208
|
+
}
|
|
8209
|
+
},
|
|
8210
|
+
createOnce(context) {
|
|
8211
|
+
let entries = [];
|
|
8212
|
+
let captures = {};
|
|
8213
|
+
return {
|
|
8214
|
+
before() {
|
|
8215
|
+
const paths = namingCaptures(context.filename) ?? {};
|
|
8216
|
+
captures = paths;
|
|
8217
|
+
entries = optionsFirst(context, { labels: [] }).labels.map((entry) => ({
|
|
8218
|
+
callees: optionsWildcards(entry.callee),
|
|
8219
|
+
entry,
|
|
8220
|
+
drop: optionsPatterns(entry.drop),
|
|
8221
|
+
within: optionsWildcards(entry.within),
|
|
8222
|
+
patterns: [entry.pattern ?? []].flat().map((source) => namingExpand(source, paths, true, optionsEscape))
|
|
8223
|
+
}));
|
|
8224
|
+
if (entries.length === 0) {
|
|
8225
|
+
return false;
|
|
8226
|
+
}
|
|
8227
|
+
},
|
|
8228
|
+
CallExpression(node) {
|
|
8229
|
+
const root = namingLabelsRoot(node.callee);
|
|
8230
|
+
const first = node.arguments.at(0);
|
|
8231
|
+
if (root === undefined || !first) {
|
|
8232
|
+
return;
|
|
8233
|
+
}
|
|
8234
|
+
for (const compiled of entries) {
|
|
8235
|
+
const target = optionsPatternsTest(compiled.callees, root) ? namingLabelsTarget(first, compiled.entry.property) : undefined;
|
|
8236
|
+
const label = target ? astStaticString(target) : undefined;
|
|
8237
|
+
if (!target || label === undefined) {
|
|
8238
|
+
continue;
|
|
8239
|
+
}
|
|
8240
|
+
if (compiled.patterns.length > 0 && !optionsPatternsTest(optionsPatterns(compiled.patterns), label)) {
|
|
8241
|
+
context.report({
|
|
8242
|
+
node: target,
|
|
8243
|
+
messageId: "pattern",
|
|
8244
|
+
data: { label, pattern: optionsPatternLabel(compiled.patterns) }
|
|
8245
|
+
});
|
|
8246
|
+
}
|
|
8247
|
+
const binding = namingLabelsBinding(node, compiled.within);
|
|
8248
|
+
const expected = binding === undefined ? [] : namingLabelsExpected(compiled, captures, binding);
|
|
8249
|
+
const plain = expected.map((item) => namingLabelsPlain(item, compiled.entry.loose));
|
|
8250
|
+
if (binding !== undefined && expected.length > 0 && !plain.includes(namingLabelsPlain(label, compiled.entry.loose))) {
|
|
8251
|
+
context.report({
|
|
8252
|
+
node: target,
|
|
8253
|
+
messageId: "name",
|
|
8254
|
+
data: { label, expected: expected.join(" or "), name: binding }
|
|
8255
|
+
});
|
|
8256
|
+
}
|
|
8257
|
+
}
|
|
8258
|
+
}
|
|
8259
|
+
};
|
|
8260
|
+
}
|
|
8261
|
+
});
|
|
8262
|
+
|
|
8263
|
+
// src/rules/naming/naming-pairs.ts
|
|
8264
|
+
import { defineRule as defineRule72 } from "@oxlint/plugins";
|
|
8265
|
+
function namingPairsArguments(node, found) {
|
|
8266
|
+
if (node.type === "MemberExpression") {
|
|
8267
|
+
return namingPairsArguments(node.object, found);
|
|
8268
|
+
}
|
|
8269
|
+
if (node.type !== "CallExpression") {
|
|
8270
|
+
return found;
|
|
8271
|
+
}
|
|
8272
|
+
const method = node.callee.type === "MemberExpression" ? astMemberName(node.callee) : undefined;
|
|
8273
|
+
const first = node.arguments.at(0);
|
|
8274
|
+
if (method !== undefined && first && !found.has(method)) {
|
|
8275
|
+
found.set(method, first);
|
|
8276
|
+
}
|
|
8277
|
+
return namingPairsArguments(node.callee, found);
|
|
8278
|
+
}
|
|
8279
|
+
var namingPairs = defineRule72({
|
|
8280
|
+
meta: {
|
|
8281
|
+
type: "problem",
|
|
8282
|
+
schema: [
|
|
8283
|
+
{
|
|
8284
|
+
type: "object",
|
|
8285
|
+
additionalProperties: false,
|
|
8286
|
+
properties: {
|
|
8287
|
+
pairs: {
|
|
8288
|
+
type: "array",
|
|
8289
|
+
items: {
|
|
8290
|
+
type: "object",
|
|
8291
|
+
additionalProperties: false,
|
|
8292
|
+
properties: {
|
|
8293
|
+
methods: { type: "array", items: { type: "string" }, minItems: 2, maxItems: 2 },
|
|
8294
|
+
strip: optionsPatternSchema,
|
|
8295
|
+
allow: optionsPatternSchema
|
|
8296
|
+
},
|
|
8297
|
+
required: ["methods"]
|
|
8298
|
+
}
|
|
8299
|
+
}
|
|
8300
|
+
},
|
|
8301
|
+
required: ["pairs"]
|
|
8302
|
+
}
|
|
8303
|
+
],
|
|
8304
|
+
messages: {
|
|
8305
|
+
pair: "'{{second}}' in .{{secondMethod}}() must share its name with '{{first}}' in .{{firstMethod}}()."
|
|
8306
|
+
}
|
|
8307
|
+
},
|
|
8308
|
+
createOnce(context) {
|
|
8309
|
+
return {
|
|
8310
|
+
CallExpression(node) {
|
|
8311
|
+
const parent = node.parent;
|
|
8312
|
+
const chained = parent.type === "MemberExpression" && parent.object === node || parent.type === "CallExpression" && parent.callee === node;
|
|
8313
|
+
const { pairs } = optionsFirst(context, { pairs: [] });
|
|
8314
|
+
if (chained || pairs.length === 0) {
|
|
8315
|
+
return;
|
|
8316
|
+
}
|
|
8317
|
+
const found = namingPairsArguments(node, new Map);
|
|
8318
|
+
for (const { methods: [firstMethod, secondMethod], strip, allow } of pairs) {
|
|
8319
|
+
const firstNode = found.get(firstMethod);
|
|
8320
|
+
const secondNode = found.get(secondMethod);
|
|
8321
|
+
const first = firstNode ? astDottedName(firstNode)?.split(".").at(-1) : undefined;
|
|
8322
|
+
const second = secondNode ? astDottedName(secondNode)?.split(".").at(-1) : undefined;
|
|
8323
|
+
const skipped = optionsPatterns(allow);
|
|
8324
|
+
const stem = (name) => optionsPatterns(strip).reduce((text, pattern) => text.replace(pattern, ""), name);
|
|
8325
|
+
if (!secondNode || first === undefined || second === undefined || optionsPatternsTest(skipped, first) || optionsPatternsTest(skipped, second)) {
|
|
8326
|
+
continue;
|
|
8327
|
+
}
|
|
8328
|
+
if (stem(first) !== stem(second)) {
|
|
8329
|
+
context.report({
|
|
8330
|
+
node: secondNode,
|
|
8331
|
+
messageId: "pair",
|
|
8332
|
+
data: { first, second, firstMethod, secondMethod }
|
|
8333
|
+
});
|
|
8334
|
+
}
|
|
8335
|
+
}
|
|
8336
|
+
}
|
|
8337
|
+
};
|
|
8338
|
+
}
|
|
8339
|
+
});
|
|
8340
|
+
|
|
7208
8341
|
// src/rules/naming/naming-types.ts
|
|
7209
|
-
import { defineRule as
|
|
7210
|
-
var namingTypes =
|
|
8342
|
+
import { defineRule as defineRule73 } from "@oxlint/plugins";
|
|
8343
|
+
var namingTypes = defineRule73({
|
|
7211
8344
|
meta: {
|
|
7212
8345
|
type: "problem",
|
|
7213
8346
|
schema: [{ type: "object", additionalProperties: false, properties: { pattern: optionsPatternSchema, message: { type: "string" } } }],
|
|
@@ -7236,8 +8369,8 @@ var namingTypes = defineRule62({
|
|
|
7236
8369
|
});
|
|
7237
8370
|
|
|
7238
8371
|
// src/rules/react/react-dynamic-classes.ts
|
|
7239
|
-
import { defineRule as
|
|
7240
|
-
var reactDynamicClasses =
|
|
8372
|
+
import { defineRule as defineRule74 } from "@oxlint/plugins";
|
|
8373
|
+
var reactDynamicClasses = defineRule74({
|
|
7241
8374
|
meta: {
|
|
7242
8375
|
type: "problem",
|
|
7243
8376
|
schema: [
|
|
@@ -7277,8 +8410,8 @@ var reactDynamicClasses = defineRule63({
|
|
|
7277
8410
|
});
|
|
7278
8411
|
|
|
7279
8412
|
// src/rules/react/react-empty-effect.ts
|
|
7280
|
-
import { defineRule as
|
|
7281
|
-
var reactEmptyEffect =
|
|
8413
|
+
import { defineRule as defineRule75 } from "@oxlint/plugins";
|
|
8414
|
+
var reactEmptyEffect = defineRule75({
|
|
7282
8415
|
meta: {
|
|
7283
8416
|
type: "problem",
|
|
7284
8417
|
schema: [
|
|
@@ -7318,8 +8451,8 @@ var reactEmptyEffect = defineRule64({
|
|
|
7318
8451
|
});
|
|
7319
8452
|
|
|
7320
8453
|
// src/rules/react/react-memo.ts
|
|
7321
|
-
import { defineRule as
|
|
7322
|
-
var reactMemo =
|
|
8454
|
+
import { defineRule as defineRule76 } from "@oxlint/plugins";
|
|
8455
|
+
var reactMemo = defineRule76({
|
|
7323
8456
|
meta: {
|
|
7324
8457
|
type: "problem",
|
|
7325
8458
|
schema: [
|
|
@@ -7381,7 +8514,7 @@ var reactMemo = defineRule65({
|
|
|
7381
8514
|
});
|
|
7382
8515
|
|
|
7383
8516
|
// src/rules/react/react-props.ts
|
|
7384
|
-
import { defineRule as
|
|
8517
|
+
import { defineRule as defineRule77 } from "@oxlint/plugins";
|
|
7385
8518
|
function reactPropsTarget(node) {
|
|
7386
8519
|
if (node?.type === "FunctionDeclaration" || node?.type === "FunctionExpression" || node?.type === "ArrowFunctionExpression") {
|
|
7387
8520
|
return { fn: node };
|
|
@@ -7408,7 +8541,7 @@ function reactIsPassThrough(type) {
|
|
|
7408
8541
|
const argument = type.typeArguments?.params.length === 1 ? type.typeArguments.params[0] : undefined;
|
|
7409
8542
|
return name.type === "Identifier" && name.name === "ComponentProps" && (argument?.type === "TSTypeQuery" || argument?.type === "TSLiteralType" && argument.literal.type === "Literal" && typeof argument.literal.value === "string");
|
|
7410
8543
|
}
|
|
7411
|
-
var reactProps =
|
|
8544
|
+
var reactProps = defineRule77({
|
|
7412
8545
|
meta: {
|
|
7413
8546
|
type: "problem",
|
|
7414
8547
|
schema: [
|
|
@@ -7507,8 +8640,8 @@ var reactProps = defineRule66({
|
|
|
7507
8640
|
});
|
|
7508
8641
|
|
|
7509
8642
|
// src/rules/react/react-query-props.ts
|
|
7510
|
-
import { defineRule as
|
|
7511
|
-
var reactQueryProps =
|
|
8643
|
+
import { defineRule as defineRule78 } from "@oxlint/plugins";
|
|
8644
|
+
var reactQueryProps = defineRule78({
|
|
7512
8645
|
meta: {
|
|
7513
8646
|
type: "problem",
|
|
7514
8647
|
schema: [
|
|
@@ -7589,7 +8722,7 @@ var reactQueryProps = defineRule67({
|
|
|
7589
8722
|
});
|
|
7590
8723
|
|
|
7591
8724
|
// src/rules/schemas/schemas-inline.ts
|
|
7592
|
-
import { defineRule as
|
|
8725
|
+
import { defineRule as defineRule79 } from "@oxlint/plugins";
|
|
7593
8726
|
|
|
7594
8727
|
// src/utils/schemas.utils.ts
|
|
7595
8728
|
var schemasElementOptionsSchema = {
|
|
@@ -7625,7 +8758,7 @@ function schemasIsAllowedElement(node, allowScalars, namespaces, structuralMetho
|
|
|
7625
8758
|
}
|
|
7626
8759
|
|
|
7627
8760
|
// src/rules/schemas/schemas-inline.ts
|
|
7628
|
-
var schemasInline =
|
|
8761
|
+
var schemasInline = defineRule79({
|
|
7629
8762
|
meta: {
|
|
7630
8763
|
type: "problem",
|
|
7631
8764
|
schema: [schemasElementOptionsSchema],
|
|
@@ -7674,11 +8807,11 @@ var schemasInline = defineRule68({
|
|
|
7674
8807
|
});
|
|
7675
8808
|
|
|
7676
8809
|
// src/rules/schemas/schemas-local.ts
|
|
7677
|
-
import { defineRule as
|
|
8810
|
+
import { defineRule as defineRule80 } from "@oxlint/plugins";
|
|
7678
8811
|
var schemasLocalImportMessage = "Do not import runtime schema constructors from {{source}}; import a named schema instead.";
|
|
7679
8812
|
var schemasLocalConstructionMessage = "Do not construct schemas locally; import a named schema instead.";
|
|
7680
8813
|
var schemasLocalCalls = ["config", "prettifyError", "treeifyError", "flattenError", "formatError"];
|
|
7681
|
-
var schemasLocal =
|
|
8814
|
+
var schemasLocal = defineRule80({
|
|
7682
8815
|
meta: {
|
|
7683
8816
|
type: "problem",
|
|
7684
8817
|
schema: [
|
|
@@ -7827,8 +8960,8 @@ var schemasLocal = defineRule69({
|
|
|
7827
8960
|
});
|
|
7828
8961
|
|
|
7829
8962
|
// src/rules/schemas/schemas-rederive.ts
|
|
7830
|
-
import { defineRule as
|
|
7831
|
-
var schemasRederive =
|
|
8963
|
+
import { defineRule as defineRule81 } from "@oxlint/plugins";
|
|
8964
|
+
var schemasRederive = defineRule81({
|
|
7832
8965
|
meta: {
|
|
7833
8966
|
type: "problem",
|
|
7834
8967
|
schema: [
|
|
@@ -7874,7 +9007,7 @@ var schemasRederive = defineRule70({
|
|
|
7874
9007
|
});
|
|
7875
9008
|
|
|
7876
9009
|
// src/rules/schemas/schemas-single-use.ts
|
|
7877
|
-
import { defineRule as
|
|
9010
|
+
import { defineRule as defineRule82 } from "@oxlint/plugins";
|
|
7878
9011
|
function isScalarSchema(node, namespaces, structuralMethods) {
|
|
7879
9012
|
if (node.type !== "CallExpression" || node.callee.type !== "MemberExpression") {
|
|
7880
9013
|
return false;
|
|
@@ -7888,7 +9021,7 @@ function isScalarSchema(node, namespaces, structuralMethods) {
|
|
|
7888
9021
|
}
|
|
7889
9022
|
return node.callee.object.type === "CallExpression" && isScalarSchema(node.callee.object, namespaces, structuralMethods);
|
|
7890
9023
|
}
|
|
7891
|
-
var schemasSingleUse =
|
|
9024
|
+
var schemasSingleUse = defineRule82({
|
|
7892
9025
|
meta: {
|
|
7893
9026
|
type: "suggestion",
|
|
7894
9027
|
schema: [schemasElementOptionsSchema],
|
|
@@ -7964,7 +9097,7 @@ var schemasSingleUse = defineRule71({
|
|
|
7964
9097
|
});
|
|
7965
9098
|
|
|
7966
9099
|
// src/rules/tests/tests-assertions.ts
|
|
7967
|
-
import { defineRule as
|
|
9100
|
+
import { defineRule as defineRule83 } from "@oxlint/plugins";
|
|
7968
9101
|
var testsAssertionsModifiers = new Set(["for", "each", "concurrent", "sequential", "only", "skip"]);
|
|
7969
9102
|
var testsAssertionsFunctions = [
|
|
7970
9103
|
"expect",
|
|
@@ -8154,7 +9287,7 @@ function isAssertedTest(registration, sourceCode, state) {
|
|
|
8154
9287
|
}
|
|
8155
9288
|
return rows.length > 0 && rows.every((row) => hasAssertion(callback, row.bindings, new Set, state));
|
|
8156
9289
|
}
|
|
8157
|
-
var testsAssertions =
|
|
9290
|
+
var testsAssertions = defineRule83({
|
|
8158
9291
|
meta: {
|
|
8159
9292
|
type: "problem",
|
|
8160
9293
|
schema: [
|
|
@@ -8280,8 +9413,8 @@ var testsAssertions = defineRule72({
|
|
|
8280
9413
|
});
|
|
8281
9414
|
|
|
8282
9415
|
// src/rules/tests/tests-concurrent-db.ts
|
|
8283
|
-
import { defineRule as
|
|
8284
|
-
var testsConcurrentDb =
|
|
9416
|
+
import { defineRule as defineRule84 } from "@oxlint/plugins";
|
|
9417
|
+
var testsConcurrentDb = defineRule84({
|
|
8285
9418
|
meta: {
|
|
8286
9419
|
type: "problem",
|
|
8287
9420
|
schema: [
|
|
@@ -8337,7 +9470,7 @@ var testsConcurrentDb = defineRule73({
|
|
|
8337
9470
|
});
|
|
8338
9471
|
|
|
8339
9472
|
// src/rules/tests/tests-modifiers.ts
|
|
8340
|
-
import { defineRule as
|
|
9473
|
+
import { defineRule as defineRule85 } from "@oxlint/plugins";
|
|
8341
9474
|
var testsModifiersNames = ["test", "it", "describe", "suite"];
|
|
8342
9475
|
var testsModifiersPackages = new Set(["vitest", "bun:test", "@playwright/test", "@jest/globals"]);
|
|
8343
9476
|
var testsModifiersBanned = ["only", "skip", "todo"];
|
|
@@ -8356,7 +9489,7 @@ function modifierName(node) {
|
|
|
8356
9489
|
const property = astMemberName(node);
|
|
8357
9490
|
return object && property ? `${object}.${property}` : undefined;
|
|
8358
9491
|
}
|
|
8359
|
-
var testsModifiers =
|
|
9492
|
+
var testsModifiers = defineRule85({
|
|
8360
9493
|
meta: {
|
|
8361
9494
|
type: "problem",
|
|
8362
9495
|
schema: [
|
|
@@ -8410,9 +9543,9 @@ var testsModifiers = defineRule74({
|
|
|
8410
9543
|
});
|
|
8411
9544
|
|
|
8412
9545
|
// src/rules/tests/tests-titles.ts
|
|
8413
|
-
import { defineRule as
|
|
9546
|
+
import { defineRule as defineRule86 } from "@oxlint/plugins";
|
|
8414
9547
|
var testsTitlesModifiers = ["only", "skip", "concurrent", "sequential", "todo", "each", "for"];
|
|
8415
|
-
var testsTitles =
|
|
9548
|
+
var testsTitles = defineRule86({
|
|
8416
9549
|
meta: {
|
|
8417
9550
|
type: "suggestion",
|
|
8418
9551
|
schema: [
|
|
@@ -8490,11 +9623,11 @@ var testsTitles = defineRule75({
|
|
|
8490
9623
|
});
|
|
8491
9624
|
|
|
8492
9625
|
// src/rules/types/types-declarations.ts
|
|
8493
|
-
import { defineRule as
|
|
9626
|
+
import { defineRule as defineRule87 } from "@oxlint/plugins";
|
|
8494
9627
|
function isValuePattern(source) {
|
|
8495
9628
|
return /^\^?=/.test(source);
|
|
8496
9629
|
}
|
|
8497
|
-
var typesDeclarations =
|
|
9630
|
+
var typesDeclarations = defineRule87({
|
|
8498
9631
|
meta: {
|
|
8499
9632
|
type: "problem",
|
|
8500
9633
|
schema: [
|
|
@@ -8545,8 +9678,8 @@ var typesDeclarations = defineRule76({
|
|
|
8545
9678
|
});
|
|
8546
9679
|
|
|
8547
9680
|
// src/rules/types/types-duplicate.ts
|
|
8548
|
-
import { defineRule as
|
|
8549
|
-
var typesDuplicate =
|
|
9681
|
+
import { defineRule as defineRule88 } from "@oxlint/plugins";
|
|
9682
|
+
var typesDuplicate = defineRule88({
|
|
8550
9683
|
meta: {
|
|
8551
9684
|
type: "suggestion",
|
|
8552
9685
|
schema: [
|
|
@@ -8610,7 +9743,7 @@ var typesDuplicate = defineRule77({
|
|
|
8610
9743
|
});
|
|
8611
9744
|
|
|
8612
9745
|
// src/rules/types/types-imported-alias.ts
|
|
8613
|
-
import { defineRule as
|
|
9746
|
+
import { defineRule as defineRule89 } from "@oxlint/plugins";
|
|
8614
9747
|
function importedAliasTarget(declaration, imports) {
|
|
8615
9748
|
if (declaration?.type !== "TSTypeAliasDeclaration") {
|
|
8616
9749
|
return;
|
|
@@ -8622,7 +9755,7 @@ function importedAliasTarget(declaration, imports) {
|
|
|
8622
9755
|
const { name } = type.typeName;
|
|
8623
9756
|
return imports.has(name) && !declaration.typeParameters?.params.some((parameter) => parameter.name.name === name) ? name : undefined;
|
|
8624
9757
|
}
|
|
8625
|
-
var typesImportedAlias =
|
|
9758
|
+
var typesImportedAlias = defineRule89({
|
|
8626
9759
|
meta: {
|
|
8627
9760
|
type: "problem",
|
|
8628
9761
|
schema: [],
|
|
@@ -8684,7 +9817,7 @@ var typesImportedAlias = defineRule78({
|
|
|
8684
9817
|
});
|
|
8685
9818
|
|
|
8686
9819
|
// src/rules/types/types-inline.ts
|
|
8687
|
-
import { defineRule as
|
|
9820
|
+
import { defineRule as defineRule90 } from "@oxlint/plugins";
|
|
8688
9821
|
function parameterAnnotation(parameter) {
|
|
8689
9822
|
if (parameter.type === "TSParameterProperty") {
|
|
8690
9823
|
return parameterAnnotation(parameter.parameter);
|
|
@@ -8694,7 +9827,7 @@ function parameterAnnotation(parameter) {
|
|
|
8694
9827
|
}
|
|
8695
9828
|
return parameter.typeAnnotation;
|
|
8696
9829
|
}
|
|
8697
|
-
var typesInline =
|
|
9830
|
+
var typesInline = defineRule90({
|
|
8698
9831
|
meta: {
|
|
8699
9832
|
type: "problem",
|
|
8700
9833
|
schema: [
|
|
@@ -8806,8 +9939,8 @@ var typesInline = defineRule79({
|
|
|
8806
9939
|
});
|
|
8807
9940
|
|
|
8808
9941
|
// src/rules/types/types-local-alias.ts
|
|
8809
|
-
import { defineRule as
|
|
8810
|
-
var typesLocalAlias =
|
|
9942
|
+
import { defineRule as defineRule91 } from "@oxlint/plugins";
|
|
9943
|
+
var typesLocalAlias = defineRule91({
|
|
8811
9944
|
meta: {
|
|
8812
9945
|
type: "problem",
|
|
8813
9946
|
schema: [{ type: "object", additionalProperties: false, properties: { allow: optionsPatternSchema, message: { type: "string" } } }],
|
|
@@ -8836,8 +9969,8 @@ var typesLocalAlias = defineRule80({
|
|
|
8836
9969
|
});
|
|
8837
9970
|
|
|
8838
9971
|
// src/rules/types/types-namespace-import.ts
|
|
8839
|
-
import { defineRule as
|
|
8840
|
-
var typesNamespaceImport =
|
|
9972
|
+
import { defineRule as defineRule92 } from "@oxlint/plugins";
|
|
9973
|
+
var typesNamespaceImport = defineRule92({
|
|
8841
9974
|
meta: {
|
|
8842
9975
|
type: "suggestion",
|
|
8843
9976
|
schema: [
|
|
@@ -8879,8 +10012,8 @@ var typesNamespaceImport = defineRule81({
|
|
|
8879
10012
|
});
|
|
8880
10013
|
|
|
8881
10014
|
// src/rules/types/types-service.ts
|
|
8882
|
-
import { defineRule as
|
|
8883
|
-
var typesService =
|
|
10015
|
+
import { defineRule as defineRule93 } from "@oxlint/plugins";
|
|
10016
|
+
var typesService = defineRule93({
|
|
8884
10017
|
meta: {
|
|
8885
10018
|
type: "problem",
|
|
8886
10019
|
schema: [
|
|
@@ -8930,12 +10063,12 @@ var typesService = defineRule82({
|
|
|
8930
10063
|
});
|
|
8931
10064
|
|
|
8932
10065
|
// src/rules/types/types-unknown.ts
|
|
8933
|
-
import { defineRule as
|
|
10066
|
+
import { defineRule as defineRule94 } from "@oxlint/plugins";
|
|
8934
10067
|
function isCatchName(node) {
|
|
8935
10068
|
const key = "key" in node && !(("computed" in node) && node.computed) ? node.key : undefined;
|
|
8936
10069
|
return key?.type === "Identifier" && key.name === "catch";
|
|
8937
10070
|
}
|
|
8938
|
-
var typesUnknown =
|
|
10071
|
+
var typesUnknown = defineRule94({
|
|
8939
10072
|
meta: { type: "problem", schema: [], messages: { forbidden: "Use an owned domain type rather than unknown." } },
|
|
8940
10073
|
createOnce(context) {
|
|
8941
10074
|
return {
|
|
@@ -8978,6 +10111,7 @@ var src_default = eslintCompatPlugin({
|
|
|
8978
10111
|
"code-double-negation": codeDoubleNegation,
|
|
8979
10112
|
"code-function-nesting": codeFunctionNesting,
|
|
8980
10113
|
"code-inline": codeInline,
|
|
10114
|
+
"code-inside": codeInside,
|
|
8981
10115
|
"code-justified-call": codeJustifiedCall,
|
|
8982
10116
|
"code-literal-in": codeLiteralIn,
|
|
8983
10117
|
"code-mutable-state": codeMutableState,
|
|
@@ -8992,10 +10126,14 @@ var src_default = eslintCompatPlugin({
|
|
|
8992
10126
|
"comments-directives": commentsDirectives,
|
|
8993
10127
|
"copy-dashes": copyDashes,
|
|
8994
10128
|
"effect-layer-file": effectLayerFile,
|
|
10129
|
+
"effect-layer-keys": effectLayerKeys,
|
|
8995
10130
|
"effect-layers": effectLayers,
|
|
8996
10131
|
"effect-merge-pipe": effectMergePipe,
|
|
8997
10132
|
"effect-schema-first": effectSchemaFirst,
|
|
10133
|
+
"effect-service-params": effectServiceParams,
|
|
8998
10134
|
"effect-values-first": effectValuesFirst,
|
|
10135
|
+
"effect-yield-name": effectYieldName,
|
|
10136
|
+
"effect-yields-first": effectYieldsFirst,
|
|
8999
10137
|
"files-components-only": filesComponentsOnly,
|
|
9000
10138
|
"files-constants-only": filesConstantsOnly,
|
|
9001
10139
|
"files-domain-constants": filesDomainConstants,
|
|
@@ -9006,6 +10144,8 @@ var src_default = eslintCompatPlugin({
|
|
|
9006
10144
|
"files-no-functions": filesNoFunctions,
|
|
9007
10145
|
"files-restricted": filesRestricted,
|
|
9008
10146
|
"files-route": filesRoute,
|
|
10147
|
+
"files-siblings": filesSiblings,
|
|
10148
|
+
"files-top-level": filesTopLevel,
|
|
9009
10149
|
"files-types-only": filesTypesOnly,
|
|
9010
10150
|
"layout-arrow-body": layoutArrowBody,
|
|
9011
10151
|
"layout-call-arguments": layoutCallArguments,
|
|
@@ -9024,6 +10164,10 @@ var src_default = eslintCompatPlugin({
|
|
|
9024
10164
|
"naming-exports": namingExports,
|
|
9025
10165
|
"naming-file": namingFile,
|
|
9026
10166
|
"naming-folder": namingFolder,
|
|
10167
|
+
"naming-imports": namingImports,
|
|
10168
|
+
"naming-keys": namingKeys,
|
|
10169
|
+
"naming-labels": namingLabels,
|
|
10170
|
+
"naming-pairs": namingPairs,
|
|
9027
10171
|
"naming-types": namingTypes,
|
|
9028
10172
|
"react-dynamic-classes": reactDynamicClasses,
|
|
9029
10173
|
"react-empty-effect": reactEmptyEffect,
|