oxlint-plugin-arch 0.12.4 → 0.12.5
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 +41 -0
- package/dist/index.js +454 -274
- package/dist/types/backend.types.d.ts +1 -0
- package/dist/types/boundaries.types.d.ts +7 -0
- package/dist/types/code.types.d.ts +3 -0
- package/dist/types/comments.types.d.ts +1 -1
- package/dist/types/files.types.d.ts +6 -1
- package/dist/types/layout.types.d.ts +10 -2
- package/dist/types/react.types.d.ts +1 -0
- package/dist/types/tests.types.d.ts +7 -0
- package/dist/types/types.types.d.ts +4 -0
- package/dist/utils/source.utils.d.ts +1 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -510,14 +510,15 @@ var backendRegistry = defineRule3({
|
|
|
510
510
|
registry: { type: "string", minLength: 1 },
|
|
511
511
|
services: { type: "string", minLength: 1 },
|
|
512
512
|
skip: { type: "array", items: { type: "string" } },
|
|
513
|
-
object: { type: "string", minLength: 1 }
|
|
513
|
+
object: { type: "string", minLength: 1 },
|
|
514
|
+
file: { type: "string", minLength: 1, default: "{folder}.service.ts" }
|
|
514
515
|
},
|
|
515
516
|
required: ["registry", "services"]
|
|
516
517
|
}
|
|
517
518
|
],
|
|
518
519
|
messages: {
|
|
519
520
|
unregistered: "Register the {{folder}} service here under '{{key}}'.",
|
|
520
|
-
missing: "Domain folder '{{folder}}' needs {{
|
|
521
|
+
missing: "Domain folder '{{folder}}' needs {{file}}; add it, or list the folder in skip."
|
|
521
522
|
}
|
|
522
523
|
},
|
|
523
524
|
createOnce(context) {
|
|
@@ -559,11 +560,12 @@ var backendRegistry = defineRule3({
|
|
|
559
560
|
const domains = entries.filter((entry) => entry.isDirectory() && !(options.skip ?? []).includes(entry.name)).map((entry) => entry.name);
|
|
560
561
|
for (const folder of domains) {
|
|
561
562
|
const key = namingCamelCase(folder);
|
|
562
|
-
|
|
563
|
+
const file = (options.file ?? "{folder}.service.ts").replaceAll("{folder}", folder);
|
|
564
|
+
if (!existsSync(join(options.services, folder, file))) {
|
|
563
565
|
context.report({
|
|
564
566
|
node: program,
|
|
565
567
|
messageId: "missing",
|
|
566
|
-
data: { folder }
|
|
568
|
+
data: { folder, file }
|
|
567
569
|
});
|
|
568
570
|
} else if (![key, `${key}s`, key.replace(/y$/, "ies")].some((name) => keys.has(name))) {
|
|
569
571
|
context.report({
|
|
@@ -1136,11 +1138,14 @@ var boundariesDeny = defineRule6({
|
|
|
1136
1138
|
// src/rules/boundaries/boundaries-imports.ts
|
|
1137
1139
|
import { defineRule as defineRule7 } from "@oxlint/plugins";
|
|
1138
1140
|
import { basename, resolve as resolve2 } from "node:path";
|
|
1139
|
-
var
|
|
1141
|
+
var boundariesSurfaces = ["service", "client", "server", "rsc", "utils"];
|
|
1140
1142
|
var boundariesActionOrQuery = /\/(?:[^/]+)-(?:action|query)\./;
|
|
1141
1143
|
function boundariesContains(directory, candidate) {
|
|
1142
1144
|
return candidate === directory || candidate.startsWith(`${directory}/`);
|
|
1143
1145
|
}
|
|
1146
|
+
function boundariesIsSurface(options, stem) {
|
|
1147
|
+
return (options.surfaces ?? boundariesSurfaces).some((surface) => stem.endsWith(`.${surface}`));
|
|
1148
|
+
}
|
|
1144
1149
|
function boundariesStripExtension(path) {
|
|
1145
1150
|
return path.replace(/\.[cm]?[jt]sx?$/, "");
|
|
1146
1151
|
}
|
|
@@ -1169,12 +1174,12 @@ function boundariesPrivateDomain({ options, file, target, reExport, roots, owner
|
|
|
1169
1174
|
const targetDomain = targetOwner ? boundariesDomain(target, targetOwner, boundariesServiceFolder(options, targetOwner)) : undefined;
|
|
1170
1175
|
const sameDomain = owner && owner === targetOwner && fileDomain && fileDomain === targetDomain;
|
|
1171
1176
|
const targetStem = boundariesStripExtension(target);
|
|
1172
|
-
const publicSurface =
|
|
1177
|
+
const publicSurface = boundariesIsSurface(options, targetStem) && !boundariesActionOrQuery.test(targetStem);
|
|
1173
1178
|
const privateTarget = roles.some((role) => targetStem.endsWith(`.${role}`)) || targetDomain && !publicSurface && !/\.(?:types|constants)$/.test(targetStem);
|
|
1174
1179
|
if (!privateTarget) {
|
|
1175
1180
|
return;
|
|
1176
1181
|
}
|
|
1177
|
-
if (reExport &&
|
|
1182
|
+
if (reExport && file.endsWith(".ts") && boundariesIsSurface(options, file.slice(0, -".ts".length)) && !boundariesActionOrQuery.test(file)) {
|
|
1178
1183
|
return "public service and utility surfaces must not re-export private domain internals";
|
|
1179
1184
|
}
|
|
1180
1185
|
return sameDomain ? undefined : "private domain files stay in the same domain and application; use its service API or shared utilities";
|
|
@@ -1212,6 +1217,7 @@ var boundariesImports = defineRule7({
|
|
|
1212
1217
|
backend: { type: "array", items: { type: "string" } },
|
|
1213
1218
|
packages: { anyOf: [{ type: "string" }, { type: "array", items: { type: "string" } }] },
|
|
1214
1219
|
roles: { type: "array", items: { type: "string" } },
|
|
1220
|
+
surfaces: { type: "array", items: { type: "string", minLength: 1 }, default: boundariesSurfaces },
|
|
1215
1221
|
services: { type: "array", items: { type: "string" } },
|
|
1216
1222
|
portable: { type: "boolean" },
|
|
1217
1223
|
backendPackages: { type: "array", items: { type: "string" } },
|
|
@@ -1307,11 +1313,9 @@ var boundariesNextDefaults = {
|
|
|
1307
1313
|
serverPackages: [...boundariesServerPackages, "server-only", "next/headers", "next/cache", "next/server"],
|
|
1308
1314
|
clientPackages: ["client-only", "react-dom/client"],
|
|
1309
1315
|
hookPackages: ["react"],
|
|
1310
|
-
publicEnv: "NEXT_PUBLIC_"
|
|
1316
|
+
publicEnv: "NEXT_PUBLIC_",
|
|
1317
|
+
serverHooks: ["useId", "use"]
|
|
1311
1318
|
};
|
|
1312
|
-
function boundariesIsClientHook(name) {
|
|
1313
|
-
return /^use[A-Z]/.test(name) && name !== "useId" && name !== "use";
|
|
1314
|
-
}
|
|
1315
1319
|
var boundariesNext = defineRule8({
|
|
1316
1320
|
meta: {
|
|
1317
1321
|
type: "problem",
|
|
@@ -1319,7 +1323,11 @@ var boundariesNext = defineRule8({
|
|
|
1319
1323
|
{
|
|
1320
1324
|
type: "object",
|
|
1321
1325
|
additionalProperties: false,
|
|
1322
|
-
properties: {
|
|
1326
|
+
properties: {
|
|
1327
|
+
...boundariesRuntimeProperties,
|
|
1328
|
+
publicEnv: { type: "string" },
|
|
1329
|
+
serverHooks: { type: "array", items: { type: "string", minLength: 1 }, default: boundariesNextDefaults.serverHooks }
|
|
1330
|
+
}
|
|
1323
1331
|
}
|
|
1324
1332
|
],
|
|
1325
1333
|
messages: {
|
|
@@ -1335,6 +1343,7 @@ var boundariesNext = defineRule8({
|
|
|
1335
1343
|
let client = false;
|
|
1336
1344
|
let shared = false;
|
|
1337
1345
|
const reactNamespaces = new Set;
|
|
1346
|
+
const clientHook = (name) => /^use[A-Z]/.test(name) && !options.serverHooks.includes(name);
|
|
1338
1347
|
function check(node, source, typeOnly) {
|
|
1339
1348
|
if (typeOnly) {
|
|
1340
1349
|
return;
|
|
@@ -1398,14 +1407,14 @@ var boundariesNext = defineRule8({
|
|
|
1398
1407
|
reactNamespaces.add(specifier);
|
|
1399
1408
|
continue;
|
|
1400
1409
|
}
|
|
1401
|
-
if (specifier.importKind !== "type" && specifier.imported.type === "Identifier" &&
|
|
1410
|
+
if (specifier.importKind !== "type" && specifier.imported.type === "Identifier" && clientHook(specifier.imported.name)) {
|
|
1402
1411
|
boundariesReport(context, specifier, specifier.imported.name, boundariesClientHookReason);
|
|
1403
1412
|
}
|
|
1404
1413
|
}
|
|
1405
1414
|
},
|
|
1406
1415
|
MemberExpression(node) {
|
|
1407
1416
|
const name = boundariesMemberName(node);
|
|
1408
|
-
if (!name || !
|
|
1417
|
+
if (!name || !clientHook(name) || node.object.type !== "Identifier") {
|
|
1409
1418
|
return;
|
|
1410
1419
|
}
|
|
1411
1420
|
const binding = boundariesDeclaredVariable(context.sourceCode.getScope(node.object), node.object.name)?.defs[0]?.node;
|
|
@@ -1449,12 +1458,54 @@ var boundariesNext = defineRule8({
|
|
|
1449
1458
|
});
|
|
1450
1459
|
|
|
1451
1460
|
// src/rules/boundaries/boundaries-rpc-database.ts
|
|
1452
|
-
|
|
1453
|
-
var
|
|
1461
|
+
import { defineRule as defineRule9 } from "@oxlint/plugins";
|
|
1462
|
+
var boundariesRpcDatabaseMethods = ["selectFrom", "insertInto", "updateTable", "deleteFrom", "mergeInto", "executeQuery"];
|
|
1463
|
+
var boundariesRpcDatabase = defineRule9({
|
|
1464
|
+
meta: {
|
|
1465
|
+
type: "problem",
|
|
1466
|
+
schema: [
|
|
1467
|
+
{
|
|
1468
|
+
type: "object",
|
|
1469
|
+
additionalProperties: false,
|
|
1470
|
+
properties: {
|
|
1471
|
+
message: { type: "string" },
|
|
1472
|
+
methods: { type: "array", items: { type: "string", minLength: 1 }, default: boundariesRpcDatabaseMethods }
|
|
1473
|
+
}
|
|
1474
|
+
}
|
|
1475
|
+
],
|
|
1476
|
+
messages: { forbidden: "{{message}}" }
|
|
1477
|
+
},
|
|
1478
|
+
createOnce(context) {
|
|
1479
|
+
let message = "";
|
|
1480
|
+
let methods = new Set;
|
|
1481
|
+
return {
|
|
1482
|
+
before() {
|
|
1483
|
+
const options = optionsFirst(context, {});
|
|
1484
|
+
message = options.message ?? "RPC handlers delegate database work to services.";
|
|
1485
|
+
methods = new Set(options.methods ?? boundariesRpcDatabaseMethods);
|
|
1486
|
+
},
|
|
1487
|
+
CallExpression(node) {
|
|
1488
|
+
const callee = node.callee;
|
|
1489
|
+
if (callee.type !== "MemberExpression") {
|
|
1490
|
+
return;
|
|
1491
|
+
}
|
|
1492
|
+
const property = callee.property;
|
|
1493
|
+
const literal = property.type === "Literal" && typeof property.value === "string" ? property.value : undefined;
|
|
1494
|
+
const name = callee.computed ? literal : astMemberName(callee);
|
|
1495
|
+
if (name !== undefined && methods.has(name)) {
|
|
1496
|
+
context.report({
|
|
1497
|
+
node,
|
|
1498
|
+
messageId: "forbidden",
|
|
1499
|
+
data: { message }
|
|
1500
|
+
});
|
|
1501
|
+
}
|
|
1502
|
+
}
|
|
1503
|
+
};
|
|
1504
|
+
}
|
|
1505
|
+
});
|
|
1454
1506
|
|
|
1455
1507
|
// src/rules/boundaries/boundaries-tanstack.ts
|
|
1456
|
-
import { defineRule as
|
|
1457
|
-
var boundariesRenderers = ["renderServerComponent", "renderToReadableStream"];
|
|
1508
|
+
import { defineRule as defineRule10 } from "@oxlint/plugins";
|
|
1458
1509
|
var boundariesChainMethods = ["handler", "server", "client", "middleware", "validator", "inputValidator"];
|
|
1459
1510
|
var boundariesSplitFactories = ["createIsomorphicFn", "createMiddleware"];
|
|
1460
1511
|
var boundariesRuntimeTypeWrappers = [
|
|
@@ -1490,12 +1541,13 @@ var boundariesTanstackDefaults = {
|
|
|
1490
1541
|
clientPackages: ["react-dom/client", "@tanstack/react-start/client-only", "@tanstack/solid-start/client-only", "@tanstack/vue-start/client-only"],
|
|
1491
1542
|
hookPackages: ["react", "@tanstack/react-query", "@tanstack/react-router"],
|
|
1492
1543
|
startPackages: ["@tanstack/react-start"],
|
|
1493
|
-
rscPackages: ["@tanstack/react-start/rsc", "@tanstack/react-start-rsc"]
|
|
1544
|
+
rscPackages: ["@tanstack/react-start/rsc", "@tanstack/react-start-rsc"],
|
|
1545
|
+
renderers: ["renderServerComponent", "renderToReadableStream"]
|
|
1494
1546
|
};
|
|
1495
|
-
function
|
|
1547
|
+
function boundariesIsClientHook(name) {
|
|
1496
1548
|
return /^use[A-Z]/.test(name) && name !== "useId";
|
|
1497
1549
|
}
|
|
1498
|
-
var boundariesTanstack =
|
|
1550
|
+
var boundariesTanstack = defineRule10({
|
|
1499
1551
|
meta: {
|
|
1500
1552
|
type: "problem",
|
|
1501
1553
|
schema: [
|
|
@@ -1506,7 +1558,8 @@ var boundariesTanstack = defineRule9({
|
|
|
1506
1558
|
...boundariesRuntimeProperties,
|
|
1507
1559
|
rpc: { type: "array", items: { type: "string" } },
|
|
1508
1560
|
startPackages: { type: "array", items: { type: "string" } },
|
|
1509
|
-
rscPackages: { type: "array", items: { type: "string" } }
|
|
1561
|
+
rscPackages: { type: "array", items: { type: "string" } },
|
|
1562
|
+
renderers: { type: "array", items: { type: "string", minLength: 1 }, default: boundariesTanstackDefaults.renderers }
|
|
1510
1563
|
}
|
|
1511
1564
|
}
|
|
1512
1565
|
],
|
|
@@ -1662,7 +1715,7 @@ var boundariesTanstack = defineRule9({
|
|
|
1662
1715
|
return;
|
|
1663
1716
|
}
|
|
1664
1717
|
for (const specifier of node.specifiers) {
|
|
1665
|
-
if (options.rscPackages.includes(node.source.value) && specifier.type === "ImportSpecifier" && specifier.importKind !== "type" && specifier.imported.type === "Identifier" &&
|
|
1718
|
+
if (options.rscPackages.includes(node.source.value) && specifier.type === "ImportSpecifier" && specifier.importKind !== "type" && specifier.imported.type === "Identifier" && options.renderers.includes(specifier.imported.name)) {
|
|
1666
1719
|
check(node, node.source.value, false, false, specifier);
|
|
1667
1720
|
}
|
|
1668
1721
|
}
|
|
@@ -1670,7 +1723,7 @@ var boundariesTanstack = defineRule9({
|
|
|
1670
1723
|
return;
|
|
1671
1724
|
}
|
|
1672
1725
|
for (const specifier of node.specifiers) {
|
|
1673
|
-
if (specifier.type !== "ImportSpecifier" || specifier.importKind === "type" || specifier.imported.type !== "Identifier" || !
|
|
1726
|
+
if (specifier.type !== "ImportSpecifier" || specifier.importKind === "type" || specifier.imported.type !== "Identifier" || !boundariesIsClientHook(specifier.imported.name)) {
|
|
1674
1727
|
continue;
|
|
1675
1728
|
}
|
|
1676
1729
|
const references = runtimeReferences(node, specifier.local.name);
|
|
@@ -1689,10 +1742,10 @@ var boundariesTanstack = defineRule9({
|
|
|
1689
1742
|
return;
|
|
1690
1743
|
}
|
|
1691
1744
|
const kind = imported(node.object);
|
|
1692
|
-
if (kind === "rsc-renderers" &&
|
|
1745
|
+
if (kind === "rsc-renderers" && options.renderers.includes(name) && (shared || !serverPosition(node.start, true))) {
|
|
1693
1746
|
boundariesReport(context, node, name, "server renderers require a server execution boundary");
|
|
1694
1747
|
}
|
|
1695
|
-
if ((serverFile || rscFile) && kind === "client-hooks" &&
|
|
1748
|
+
if ((serverFile || rscFile) && kind === "client-hooks" && boundariesIsClientHook(name) && !clientSide(node.start)) {
|
|
1696
1749
|
boundariesReport(context, node, name, boundariesClientHookReason2);
|
|
1697
1750
|
}
|
|
1698
1751
|
},
|
|
@@ -1724,8 +1777,8 @@ var boundariesTanstack = defineRule9({
|
|
|
1724
1777
|
});
|
|
1725
1778
|
|
|
1726
1779
|
// src/rules/boundaries/boundaries-token-owner.ts
|
|
1727
|
-
import { defineRule as
|
|
1728
|
-
var boundariesTokenOwner =
|
|
1780
|
+
import { defineRule as defineRule11 } from "@oxlint/plugins";
|
|
1781
|
+
var boundariesTokenOwner = defineRule11({
|
|
1729
1782
|
meta: {
|
|
1730
1783
|
type: "problem",
|
|
1731
1784
|
schema: [
|
|
@@ -1820,7 +1873,7 @@ var boundariesTokenOwner = defineRule10({
|
|
|
1820
1873
|
});
|
|
1821
1874
|
|
|
1822
1875
|
// src/rules/code/code-branch-once.ts
|
|
1823
|
-
import { defineRule as
|
|
1876
|
+
import { defineRule as defineRule12 } from "@oxlint/plugins";
|
|
1824
1877
|
function codeBranchOnceSubjects(node, source) {
|
|
1825
1878
|
if (node.type === "LogicalExpression") {
|
|
1826
1879
|
return [...codeBranchOnceSubjects(node.left, source), ...codeBranchOnceSubjects(node.right, source)];
|
|
@@ -1836,18 +1889,27 @@ function codeBranchOnceSubjects(node, source) {
|
|
|
1836
1889
|
const literal = sides.some((side) => side.type === "Literal" && typeof side.value === "string");
|
|
1837
1890
|
return member && literal ? [source.getText(member)] : [];
|
|
1838
1891
|
}
|
|
1839
|
-
var codeBranchOnce =
|
|
1892
|
+
var codeBranchOnce = defineRule12({
|
|
1840
1893
|
meta: {
|
|
1841
1894
|
type: "suggestion",
|
|
1895
|
+
schema: [
|
|
1896
|
+
{
|
|
1897
|
+
type: "object",
|
|
1898
|
+
additionalProperties: false,
|
|
1899
|
+
properties: { min: { type: "integer", minimum: 2, default: 2 } }
|
|
1900
|
+
}
|
|
1901
|
+
],
|
|
1842
1902
|
messages: {
|
|
1843
1903
|
once: "{{subject}} is compared to a string in {{count}} ternaries in this file. Branch on it once and return a record."
|
|
1844
1904
|
}
|
|
1845
1905
|
},
|
|
1846
1906
|
createOnce(context) {
|
|
1847
1907
|
let groups = new Map;
|
|
1908
|
+
let min = 2;
|
|
1848
1909
|
return {
|
|
1849
1910
|
before() {
|
|
1850
1911
|
groups = new Map;
|
|
1912
|
+
min = optionsFirst(context, {}).min ?? 2;
|
|
1851
1913
|
},
|
|
1852
1914
|
ConditionalExpression(node) {
|
|
1853
1915
|
for (const subject of new Set(codeBranchOnceSubjects(node.test, context.sourceCode))) {
|
|
@@ -1856,7 +1918,7 @@ var codeBranchOnce = defineRule11({
|
|
|
1856
1918
|
},
|
|
1857
1919
|
"Program:exit"() {
|
|
1858
1920
|
for (const [subject, ternaries] of groups) {
|
|
1859
|
-
for (const node of ternaries.length
|
|
1921
|
+
for (const node of ternaries.length >= min ? ternaries : []) {
|
|
1860
1922
|
context.report({
|
|
1861
1923
|
node,
|
|
1862
1924
|
messageId: "once",
|
|
@@ -1870,8 +1932,8 @@ var codeBranchOnce = defineRule11({
|
|
|
1870
1932
|
});
|
|
1871
1933
|
|
|
1872
1934
|
// src/rules/code/code-constructor.ts
|
|
1873
|
-
import { defineRule as
|
|
1874
|
-
var codeConstructor =
|
|
1935
|
+
import { defineRule as defineRule13 } from "@oxlint/plugins";
|
|
1936
|
+
var codeConstructor = defineRule13({
|
|
1875
1937
|
meta: {
|
|
1876
1938
|
type: "problem",
|
|
1877
1939
|
schema: [
|
|
@@ -1955,8 +2017,8 @@ var codeConstructor = defineRule12({
|
|
|
1955
2017
|
var codeDoubleNegation = astSelectorRule('UnaryExpression[operator="!"] > UnaryExpression[operator="!"]', "Use Boolean(value) or an explicit comparison.");
|
|
1956
2018
|
|
|
1957
2019
|
// src/rules/code/code-function-nesting.ts
|
|
1958
|
-
import { defineRule as
|
|
1959
|
-
var codeFunctionNesting =
|
|
2020
|
+
import { defineRule as defineRule14 } from "@oxlint/plugins";
|
|
2021
|
+
var codeFunctionNesting = defineRule14({
|
|
1960
2022
|
meta: {
|
|
1961
2023
|
type: "suggestion",
|
|
1962
2024
|
schema: [
|
|
@@ -1997,7 +2059,7 @@ var codeFunctionNesting = defineRule13({
|
|
|
1997
2059
|
});
|
|
1998
2060
|
|
|
1999
2061
|
// src/rules/code/code-inline.ts
|
|
2000
|
-
import { defineRule as
|
|
2062
|
+
import { defineRule as defineRule15 } from "@oxlint/plugins";
|
|
2001
2063
|
|
|
2002
2064
|
// src/utils/source.utils.ts
|
|
2003
2065
|
var sourceDirective = /^\s*(?:\/\s*<(?:reference\b|amd-[\w-]+\b)|@ts-(?:check|ignore|expect-error|nocheck)\b|(?:#|@)__(?:PURE|NO_SIDE_EFFECTS)__\b|@jsx(?:ImportSource|Runtime|Frag)?\b|@vite-ignore\b|(?:[#@]\s*)?sourceMappingURL=|(?:es|ox)lint-(?:disable|enable)|prettier-ignore|biome-ignore|[cv]8 ignore|istanbul ignore|webpack[A-Z])/;
|
|
@@ -2038,6 +2100,9 @@ function sourceLineEnd(text, offset) {
|
|
|
2038
2100
|
`, offset);
|
|
2039
2101
|
return end === -1 ? text.length : end;
|
|
2040
2102
|
}
|
|
2103
|
+
function sourceJoinedWidth(text, start, joined, end) {
|
|
2104
|
+
return start - sourceLineStart(text, start) + joined.length + text.slice(end, sourceLineEnd(text, end)).trimEnd().length;
|
|
2105
|
+
}
|
|
2041
2106
|
function sourceItemGaps(open, items, close) {
|
|
2042
2107
|
const edges = [open, ...items.flatMap((item) => item.range), close];
|
|
2043
2108
|
return Array.from({ length: items.length + 1 }, (_, index) => [edges[index * 2] ?? open, edges[index * 2 + 1] ?? close]);
|
|
@@ -2066,7 +2131,20 @@ function codeInlineEnclosingCalls(node) {
|
|
|
2066
2131
|
return outer && astIsOneLine(outer) ? 1 + codeInlineEnclosingCalls(outer) : 0;
|
|
2067
2132
|
}
|
|
2068
2133
|
var codeInlineWrapped = new Set(["ConditionalExpression", "LogicalExpression", "BinaryExpression", "ArrowFunctionExpression"]);
|
|
2069
|
-
var
|
|
2134
|
+
var codeInlineEffects = new Set([
|
|
2135
|
+
"CallExpression",
|
|
2136
|
+
"NewExpression",
|
|
2137
|
+
"AssignmentExpression",
|
|
2138
|
+
"UpdateExpression",
|
|
2139
|
+
"AwaitExpression",
|
|
2140
|
+
"YieldExpression",
|
|
2141
|
+
"TaggedTemplateExpression",
|
|
2142
|
+
"ImportExpression"
|
|
2143
|
+
]);
|
|
2144
|
+
function codeInlineEffectBetween(program, start, end) {
|
|
2145
|
+
return astSome(program, (node) => node.range[0] >= start && node.range[1] <= end && (codeInlineEffects.has(node.type) || node.type === "UnaryExpression" && node.operator === "delete"), (node) => node.range[1] > start && node.range[0] < end && !(node.range[0] >= start && (node.type === "FunctionDeclaration" || astIsInlineFunction(node))));
|
|
2146
|
+
}
|
|
2147
|
+
var codeInline = defineRule15({
|
|
2070
2148
|
meta: {
|
|
2071
2149
|
type: "suggestion",
|
|
2072
2150
|
schema: [
|
|
@@ -2104,6 +2182,9 @@ var codeInline = defineRule14({
|
|
|
2104
2182
|
return;
|
|
2105
2183
|
}
|
|
2106
2184
|
if (uses.length === 1) {
|
|
2185
|
+
if (init && codeInlineEffectBetween(context.sourceCode.ast, node.range[1], uses[0].identifier.range[0])) {
|
|
2186
|
+
return;
|
|
2187
|
+
}
|
|
2107
2188
|
context.report({
|
|
2108
2189
|
node: id,
|
|
2109
2190
|
messageId: "once",
|
|
@@ -2141,7 +2222,7 @@ var codeInline = defineRule14({
|
|
|
2141
2222
|
deferred ||= current.type === "FunctionDeclaration" || astIsInlineFunction(current);
|
|
2142
2223
|
}
|
|
2143
2224
|
const wrapped = codeInlineWrapped.has(init.type) && use.parent.type === "MemberExpression" && use.parent.object === use;
|
|
2144
|
-
if (service || wrapped || deferred || codeInlineEnclosingCalls(use) + astCallDepth(init) > (options.nesting ?? 2) || line.length - id.name.length + context.sourceCode.getText(init).length > (options.max ?? 160)) {
|
|
2225
|
+
if (service || wrapped || deferred || codeInlineEnclosingCalls(use) + astCallDepth(init) > (options.nesting ?? 2) || line.length - id.name.length + context.sourceCode.getText(init).length > (options.max ?? 160) || codeInlineEffectBetween(context.sourceCode.ast, declarator.range[1], use.range[0])) {
|
|
2145
2226
|
return;
|
|
2146
2227
|
}
|
|
2147
2228
|
context.report({
|
|
@@ -2176,8 +2257,8 @@ var codeInline = defineRule14({
|
|
|
2176
2257
|
});
|
|
2177
2258
|
|
|
2178
2259
|
// src/rules/code/code-justified-call.ts
|
|
2179
|
-
import { defineRule as
|
|
2180
|
-
var codeJustifiedCall =
|
|
2260
|
+
import { defineRule as defineRule16 } from "@oxlint/plugins";
|
|
2261
|
+
var codeJustifiedCall = defineRule16({
|
|
2181
2262
|
meta: {
|
|
2182
2263
|
type: "problem",
|
|
2183
2264
|
schema: [
|
|
@@ -2231,8 +2312,8 @@ var codeJustifiedCall = defineRule15({
|
|
|
2231
2312
|
});
|
|
2232
2313
|
|
|
2233
2314
|
// src/rules/code/code-literal-in.ts
|
|
2234
|
-
import { defineRule as
|
|
2235
|
-
var codeLiteralIn =
|
|
2315
|
+
import { defineRule as defineRule17 } from "@oxlint/plugins";
|
|
2316
|
+
var codeLiteralIn = defineRule17({
|
|
2236
2317
|
meta: {
|
|
2237
2318
|
type: "suggestion",
|
|
2238
2319
|
schema: [
|
|
@@ -2273,7 +2354,7 @@ var codeLiteralIn = defineRule16({
|
|
|
2273
2354
|
});
|
|
2274
2355
|
|
|
2275
2356
|
// src/rules/code/code-mutable-state.ts
|
|
2276
|
-
import { defineRule as
|
|
2357
|
+
import { defineRule as defineRule18 } from "@oxlint/plugins";
|
|
2277
2358
|
var functionScopes = new Set([
|
|
2278
2359
|
"FunctionDeclaration",
|
|
2279
2360
|
"FunctionExpression",
|
|
@@ -2290,7 +2371,7 @@ function hasAncestor(node, test) {
|
|
|
2290
2371
|
}
|
|
2291
2372
|
return false;
|
|
2292
2373
|
}
|
|
2293
|
-
var codeMutableState =
|
|
2374
|
+
var codeMutableState = defineRule18({
|
|
2294
2375
|
meta: {
|
|
2295
2376
|
type: "problem",
|
|
2296
2377
|
schema: [
|
|
@@ -2348,7 +2429,7 @@ var codeMutableState = defineRule17({
|
|
|
2348
2429
|
});
|
|
2349
2430
|
|
|
2350
2431
|
// src/rules/code/code-object-params.ts
|
|
2351
|
-
import { defineRule as
|
|
2432
|
+
import { defineRule as defineRule19 } from "@oxlint/plugins";
|
|
2352
2433
|
function isObjectParam(node) {
|
|
2353
2434
|
if (node.type === "ObjectPattern") {
|
|
2354
2435
|
return true;
|
|
@@ -2362,7 +2443,7 @@ function isObjectParam(node) {
|
|
|
2362
2443
|
const annotation = node.typeAnnotation?.typeAnnotation;
|
|
2363
2444
|
return !annotation || annotation.type === "TSTypeReference" || annotation.type === "TSTypeLiteral" || annotation.type === "TSIntersectionType";
|
|
2364
2445
|
}
|
|
2365
|
-
var codeObjectParams =
|
|
2446
|
+
var codeObjectParams = defineRule19({
|
|
2366
2447
|
meta: {
|
|
2367
2448
|
type: "problem",
|
|
2368
2449
|
schema: [
|
|
@@ -2411,8 +2492,8 @@ var codeObjectParams = defineRule18({
|
|
|
2411
2492
|
});
|
|
2412
2493
|
|
|
2413
2494
|
// src/rules/code/code-paired-call.ts
|
|
2414
|
-
import { defineRule as
|
|
2415
|
-
var codePairedCall =
|
|
2495
|
+
import { defineRule as defineRule20 } from "@oxlint/plugins";
|
|
2496
|
+
var codePairedCall = defineRule20({
|
|
2416
2497
|
meta: {
|
|
2417
2498
|
type: "problem",
|
|
2418
2499
|
schema: [
|
|
@@ -2443,7 +2524,6 @@ var codePairedCall = defineRule19({
|
|
|
2443
2524
|
}
|
|
2444
2525
|
},
|
|
2445
2526
|
createOnce(context) {
|
|
2446
|
-
const aliases = new Map;
|
|
2447
2527
|
let pairs = [];
|
|
2448
2528
|
return {
|
|
2449
2529
|
before() {
|
|
@@ -2451,26 +2531,10 @@ var codePairedCall = defineRule19({
|
|
|
2451
2531
|
const all = when && require2 ? [{ when, require: require2 }, ...configured] : configured;
|
|
2452
2532
|
pairs = all.map((pair) => ({ ...pair, firstWhen: null, sawRequired: false }));
|
|
2453
2533
|
},
|
|
2454
|
-
Program(program) {
|
|
2455
|
-
aliases.clear();
|
|
2456
|
-
for (const statement of program.body) {
|
|
2457
|
-
if (statement.type !== "ImportDeclaration") {
|
|
2458
|
-
continue;
|
|
2459
|
-
}
|
|
2460
|
-
for (const specifier of statement.specifiers) {
|
|
2461
|
-
if (specifier.type !== "ImportSpecifier") {
|
|
2462
|
-
continue;
|
|
2463
|
-
}
|
|
2464
|
-
const imported = astModuleName(specifier.imported);
|
|
2465
|
-
if (imported !== specifier.local.name) {
|
|
2466
|
-
aliases.set(specifier.local.name, imported);
|
|
2467
|
-
}
|
|
2468
|
-
}
|
|
2469
|
-
}
|
|
2470
|
-
},
|
|
2471
2534
|
CallExpression(node) {
|
|
2472
|
-
const
|
|
2473
|
-
const
|
|
2535
|
+
const callee = node.callee;
|
|
2536
|
+
const binding = callee.type === "Identifier" ? boundariesDeclaredVariable(context.sourceCode.getScope(node), callee.name)?.defs.at(0)?.node : undefined;
|
|
2537
|
+
const name = binding?.type === "ImportSpecifier" ? astModuleName(binding.imported) : astCallName(node);
|
|
2474
2538
|
for (const pair of pairs) {
|
|
2475
2539
|
if (name === pair.when) {
|
|
2476
2540
|
pair.firstWhen ??= node;
|
|
@@ -2496,7 +2560,7 @@ var codePairedCall = defineRule19({
|
|
|
2496
2560
|
});
|
|
2497
2561
|
|
|
2498
2562
|
// src/rules/code/code-promise-mutation.ts
|
|
2499
|
-
import { defineRule as
|
|
2563
|
+
import { defineRule as defineRule21 } from "@oxlint/plugins";
|
|
2500
2564
|
function mutationBinding(node) {
|
|
2501
2565
|
if (node.type === "Identifier") {
|
|
2502
2566
|
return node;
|
|
@@ -2525,7 +2589,7 @@ function mutationBindings(node) {
|
|
|
2525
2589
|
const binding = mutationBinding(node);
|
|
2526
2590
|
return binding ? [binding] : [];
|
|
2527
2591
|
}
|
|
2528
|
-
var codePromiseMutation =
|
|
2592
|
+
var codePromiseMutation = defineRule21({
|
|
2529
2593
|
meta: {
|
|
2530
2594
|
type: "problem",
|
|
2531
2595
|
schema: [
|
|
@@ -2618,8 +2682,8 @@ var codePromiseMutation = defineRule20({
|
|
|
2618
2682
|
var codeSwitch = astSelectorRule("SwitchStatement", "Avoid switch statements.");
|
|
2619
2683
|
|
|
2620
2684
|
// src/rules/code/code-traced.ts
|
|
2621
|
-
import { defineRule as
|
|
2622
|
-
var codeTraced =
|
|
2685
|
+
import { defineRule as defineRule22 } from "@oxlint/plugins";
|
|
2686
|
+
var codeTraced = defineRule22({
|
|
2623
2687
|
meta: {
|
|
2624
2688
|
type: "problem",
|
|
2625
2689
|
schema: [
|
|
@@ -2668,17 +2732,17 @@ var codeTraced = defineRule21({
|
|
|
2668
2732
|
message = options.message ?? `An exported function or service method gets a span: replace ${[...untraced].join(", ")} with its traced form.`;
|
|
2669
2733
|
},
|
|
2670
2734
|
ExportNamedDeclaration(node) {
|
|
2671
|
-
if (!exported
|
|
2735
|
+
if (!exported) {
|
|
2672
2736
|
return;
|
|
2673
2737
|
}
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
}
|
|
2681
|
-
}
|
|
2738
|
+
const declarators = node.declaration?.type === "VariableDeclaration" ? node.declaration.declarations.filter((declarator) => isUntraced(declarator.init)) : [];
|
|
2739
|
+
const specifiers = node.source ? [] : node.specifiers.filter((specifier) => resolves(specifier.local));
|
|
2740
|
+
for (const surface of [...declarators, ...specifiers]) {
|
|
2741
|
+
context.report({
|
|
2742
|
+
node: surface,
|
|
2743
|
+
messageId: "surface",
|
|
2744
|
+
data: { message }
|
|
2745
|
+
});
|
|
2682
2746
|
}
|
|
2683
2747
|
},
|
|
2684
2748
|
CallExpression(node) {
|
|
@@ -2706,7 +2770,7 @@ var codeTraced = defineRule21({
|
|
|
2706
2770
|
});
|
|
2707
2771
|
|
|
2708
2772
|
// src/rules/code/code-trivial-functions.ts
|
|
2709
|
-
import { defineRule as
|
|
2773
|
+
import { defineRule as defineRule23 } from "@oxlint/plugins";
|
|
2710
2774
|
var codeTrivialFunctionsBanned = [
|
|
2711
2775
|
"isRecord",
|
|
2712
2776
|
"isPlainObject",
|
|
@@ -2836,7 +2900,7 @@ function guardStatement(node, state) {
|
|
|
2836
2900
|
return guardFallback(declaration.init);
|
|
2837
2901
|
});
|
|
2838
2902
|
}
|
|
2839
|
-
var codeTrivialFunctions =
|
|
2903
|
+
var codeTrivialFunctions = defineRule23({
|
|
2840
2904
|
meta: {
|
|
2841
2905
|
type: "problem",
|
|
2842
2906
|
schema: [
|
|
@@ -2967,8 +3031,8 @@ var codeTrivialFunctions = defineRule22({
|
|
|
2967
3031
|
});
|
|
2968
3032
|
|
|
2969
3033
|
// src/rules/code/code-yield-argument.ts
|
|
2970
|
-
import { defineRule as
|
|
2971
|
-
var codeYieldArgument =
|
|
3034
|
+
import { defineRule as defineRule24 } from "@oxlint/plugins";
|
|
3035
|
+
var codeYieldArgument = defineRule24({
|
|
2972
3036
|
meta: {
|
|
2973
3037
|
type: "suggestion",
|
|
2974
3038
|
messages: {
|
|
@@ -2990,7 +3054,7 @@ var codeYieldArgument = defineRule23({
|
|
|
2990
3054
|
});
|
|
2991
3055
|
|
|
2992
3056
|
// src/rules/comments/comments-code.ts
|
|
2993
|
-
import { defineRule as
|
|
3057
|
+
import { defineRule as defineRule25 } from "@oxlint/plugins";
|
|
2994
3058
|
var commentsLineGap = /^[\t \r\n\u2028\u2029]*$/;
|
|
2995
3059
|
var commentsLineTerminator = /\r\n|[\n\r\u2028\u2029]/;
|
|
2996
3060
|
var commentsUnicodeTerminator = /[\u2028\u2029]/;
|
|
@@ -3041,7 +3105,7 @@ function commentsFollowsOpeningBrace(text, offset) {
|
|
|
3041
3105
|
}
|
|
3042
3106
|
return false;
|
|
3043
3107
|
}
|
|
3044
|
-
var commentsCode =
|
|
3108
|
+
var commentsCode = defineRule25({
|
|
3045
3109
|
meta: {
|
|
3046
3110
|
type: "suggestion",
|
|
3047
3111
|
fixable: "code",
|
|
@@ -3050,7 +3114,7 @@ var commentsCode = defineRule24({
|
|
|
3050
3114
|
type: "object",
|
|
3051
3115
|
additionalProperties: false,
|
|
3052
3116
|
properties: {
|
|
3053
|
-
why: { type: "boolean", default: true },
|
|
3117
|
+
why: { anyOf: [{ type: "boolean" }, { type: "string", minLength: 1 }], default: true },
|
|
3054
3118
|
allow: { type: "array", items: { type: "string" } },
|
|
3055
3119
|
jsdoc: { type: "boolean", default: false },
|
|
3056
3120
|
members: { type: "string", enum: ["off", "also", "only"] }
|
|
@@ -3064,6 +3128,7 @@ var commentsCode = defineRule24({
|
|
|
3064
3128
|
},
|
|
3065
3129
|
createOnce(context) {
|
|
3066
3130
|
let allowWhy = true;
|
|
3131
|
+
let whyPrefix = "Why: ";
|
|
3067
3132
|
let allowJsdoc = false;
|
|
3068
3133
|
let allowed = [];
|
|
3069
3134
|
let members = "off";
|
|
@@ -3088,7 +3153,8 @@ var commentsCode = defineRule24({
|
|
|
3088
3153
|
return {
|
|
3089
3154
|
before() {
|
|
3090
3155
|
const options = optionsFirst(context, {});
|
|
3091
|
-
allowWhy = options.why
|
|
3156
|
+
allowWhy = options.why !== false;
|
|
3157
|
+
whyPrefix = `${typeof options.why === "string" ? options.why.trim() : "Why:"} `;
|
|
3092
3158
|
allowJsdoc = options.jsdoc ?? false;
|
|
3093
3159
|
allowed = (options.allow ?? []).map((pattern) => new RegExp(pattern));
|
|
3094
3160
|
members = options.members ?? "off";
|
|
@@ -3117,7 +3183,7 @@ var commentsCode = defineRule24({
|
|
|
3117
3183
|
mightContainJsxComment = true;
|
|
3118
3184
|
}
|
|
3119
3185
|
const followsPrevious = previous !== undefined && comment.loc.start.line === previous.loc.end.line + 1 && commentsLineGap.test(text.slice(previous.range[1], comment.range[0]));
|
|
3120
|
-
const isWhy = value.startsWith(
|
|
3186
|
+
const isWhy = value.startsWith(whyPrefix) || comment.type === "Line" && whyContinuation && followsPrevious;
|
|
3121
3187
|
if (/^(?:eslint|oxlint)-disable-next-line\b/.test(value)) {
|
|
3122
3188
|
protectedLines.push(comment.loc.end.line + 1);
|
|
3123
3189
|
}
|
|
@@ -3205,9 +3271,9 @@ var commentsCode = defineRule24({
|
|
|
3205
3271
|
});
|
|
3206
3272
|
|
|
3207
3273
|
// src/rules/comments/comments-directives.ts
|
|
3208
|
-
import { defineRule as
|
|
3274
|
+
import { defineRule as defineRule26 } from "@oxlint/plugins";
|
|
3209
3275
|
var directive = /^\s*(?:oxlint|eslint)-disable(?:-next-line|-line)?\b(.*)$/s;
|
|
3210
|
-
var commentsDirectives =
|
|
3276
|
+
var commentsDirectives = defineRule26({
|
|
3211
3277
|
meta: {
|
|
3212
3278
|
type: "problem",
|
|
3213
3279
|
schema: [],
|
|
@@ -3235,9 +3301,9 @@ var commentsDirectives = defineRule25({
|
|
|
3235
3301
|
});
|
|
3236
3302
|
|
|
3237
3303
|
// src/rules/copy/copy-dashes.ts
|
|
3238
|
-
import { defineRule as
|
|
3304
|
+
import { defineRule as defineRule27 } from "@oxlint/plugins";
|
|
3239
3305
|
var copyDashesMessage = "Use a comma, colon, period or parentheses instead.";
|
|
3240
|
-
var copyDashes =
|
|
3306
|
+
var copyDashes = defineRule27({
|
|
3241
3307
|
meta: {
|
|
3242
3308
|
type: "suggestion",
|
|
3243
3309
|
schema: [
|
|
@@ -3293,7 +3359,7 @@ var copyDashes = defineRule26({
|
|
|
3293
3359
|
});
|
|
3294
3360
|
|
|
3295
3361
|
// src/rules/files/files-components-only.ts
|
|
3296
|
-
import { defineRule as
|
|
3362
|
+
import { defineRule as defineRule28 } from "@oxlint/plugins";
|
|
3297
3363
|
|
|
3298
3364
|
// src/utils/react.utils.ts
|
|
3299
3365
|
function reactReturnsOutput(program, node) {
|
|
@@ -3365,7 +3431,7 @@ function reactIsComponent(program, candidate) {
|
|
|
3365
3431
|
function componentName(basename2) {
|
|
3366
3432
|
return basename2.replace(/\.(tsx?|jsx?)$/, "").replaceAll(/(?:^[-.]*|[-.]+)(.?)/g, (_, char) => char.toUpperCase());
|
|
3367
3433
|
}
|
|
3368
|
-
var filesComponentsOnly =
|
|
3434
|
+
var filesComponentsOnly = defineRule28({
|
|
3369
3435
|
meta: {
|
|
3370
3436
|
type: "problem",
|
|
3371
3437
|
schema: [
|
|
@@ -3373,7 +3439,7 @@ var filesComponentsOnly = defineRule27({
|
|
|
3373
3439
|
type: "object",
|
|
3374
3440
|
additionalProperties: false,
|
|
3375
3441
|
properties: {
|
|
3376
|
-
filename: { type: "boolean" },
|
|
3442
|
+
filename: { oneOf: [{ type: "boolean" }, { type: "string", enum: ["each"] }] },
|
|
3377
3443
|
roles: { type: "array", items: { type: "string" } },
|
|
3378
3444
|
types: { type: "boolean" },
|
|
3379
3445
|
deny: optionsPatternSchema
|
|
@@ -3434,10 +3500,13 @@ var filesComponentsOnly = defineRule27({
|
|
|
3434
3500
|
return;
|
|
3435
3501
|
}
|
|
3436
3502
|
const names = components.map((candidate) => candidate.name.toLowerCase());
|
|
3437
|
-
if (expectedKeys.some((key) => names.includes(key) || names.every((name) => name.startsWith(key)))) {
|
|
3503
|
+
if (matchFileName !== "each" && expectedKeys.some((key) => names.includes(key) || names.every((name) => name.startsWith(key)))) {
|
|
3438
3504
|
return;
|
|
3439
3505
|
}
|
|
3440
3506
|
for (const { name, node } of components) {
|
|
3507
|
+
if (matchFileName === "each" && expectedKeys.some((key) => name.toLowerCase().startsWith(key))) {
|
|
3508
|
+
continue;
|
|
3509
|
+
}
|
|
3441
3510
|
context.report({
|
|
3442
3511
|
node,
|
|
3443
3512
|
messageId: "nameMismatch",
|
|
@@ -3450,7 +3519,7 @@ var filesComponentsOnly = defineRule27({
|
|
|
3450
3519
|
});
|
|
3451
3520
|
|
|
3452
3521
|
// src/rules/files/files-constants-only.ts
|
|
3453
|
-
import { defineRule as
|
|
3522
|
+
import { defineRule as defineRule29 } from "@oxlint/plugins";
|
|
3454
3523
|
function unwrap(expression) {
|
|
3455
3524
|
if (expression.type === "ParenthesizedExpression" || expression.type === "TSAsExpression" || expression.type === "TSSatisfiesExpression" || expression.type === "TSTypeAssertion" || expression.type === "TSNonNullExpression" || expression.type === "TSInstantiationExpression") {
|
|
3456
3525
|
return unwrap(expression.expression);
|
|
@@ -3505,7 +3574,7 @@ function collectBindings(program) {
|
|
|
3505
3574
|
}
|
|
3506
3575
|
return bindings;
|
|
3507
3576
|
}
|
|
3508
|
-
var filesConstantsOnly =
|
|
3577
|
+
var filesConstantsOnly = defineRule29({
|
|
3509
3578
|
meta: {
|
|
3510
3579
|
type: "problem",
|
|
3511
3580
|
schema: [
|
|
@@ -3604,7 +3673,7 @@ var filesConstantsOnly = defineRule28({
|
|
|
3604
3673
|
});
|
|
3605
3674
|
|
|
3606
3675
|
// src/rules/files/files-domain-constants.ts
|
|
3607
|
-
import { defineRule as
|
|
3676
|
+
import { defineRule as defineRule30 } from "@oxlint/plugins";
|
|
3608
3677
|
import { basename as basename2, dirname as dirname2 } from "node:path";
|
|
3609
3678
|
function isData(expression) {
|
|
3610
3679
|
const value = astUnwrap(expression);
|
|
@@ -3622,14 +3691,21 @@ function isData(expression) {
|
|
|
3622
3691
|
}
|
|
3623
3692
|
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;
|
|
3624
3693
|
}
|
|
3625
|
-
var filesDomainConstants =
|
|
3694
|
+
var filesDomainConstants = defineRule30({
|
|
3626
3695
|
meta: {
|
|
3627
3696
|
type: "problem",
|
|
3628
3697
|
schema: [
|
|
3629
3698
|
{
|
|
3630
3699
|
type: "object",
|
|
3631
3700
|
additionalProperties: false,
|
|
3632
|
-
properties: {
|
|
3701
|
+
properties: {
|
|
3702
|
+
data: { type: "boolean" },
|
|
3703
|
+
services: { type: "boolean" },
|
|
3704
|
+
pattern: { ...optionsPatternSchema, default: "^[A-Z][A-Z0-9_]+$" },
|
|
3705
|
+
folders: { type: "array", items: { type: "string", minLength: 1 }, default: ["services"] },
|
|
3706
|
+
roles: { type: "array", items: { type: "string", minLength: 1 }, default: ["action", "query"] },
|
|
3707
|
+
file: { type: "string", minLength: 1, default: "{domain}.constants.ts" }
|
|
3708
|
+
}
|
|
3633
3709
|
}
|
|
3634
3710
|
],
|
|
3635
3711
|
messages: {
|
|
@@ -3638,11 +3714,19 @@ var filesDomainConstants = defineRule29({
|
|
|
3638
3714
|
},
|
|
3639
3715
|
createOnce(context) {
|
|
3640
3716
|
let includeData = false;
|
|
3717
|
+
let names = [];
|
|
3718
|
+
let folders = [];
|
|
3719
|
+
let roles = [];
|
|
3720
|
+
let target = "";
|
|
3641
3721
|
let serviceObjects = new Set;
|
|
3642
3722
|
return {
|
|
3643
3723
|
Program(program) {
|
|
3644
3724
|
const options = optionsFirst(context, {});
|
|
3645
3725
|
includeData = Boolean(options.data);
|
|
3726
|
+
names = optionsPatterns(options.pattern ?? "^[A-Z][A-Z0-9_]+$");
|
|
3727
|
+
folders = options.folders ?? ["services"];
|
|
3728
|
+
roles = options.roles ?? ["action", "query"];
|
|
3729
|
+
target = options.file ?? "{domain}.constants.ts";
|
|
3646
3730
|
serviceObjects = new Set(options.services ? declarationsPublicServiceMethods(program).map((method) => method.binding) : []);
|
|
3647
3731
|
},
|
|
3648
3732
|
VariableDeclarator(node) {
|
|
@@ -3652,15 +3736,19 @@ var filesDomainConstants = defineRule29({
|
|
|
3652
3736
|
return;
|
|
3653
3737
|
}
|
|
3654
3738
|
const name = node.id.type === "Identifier" ? node.id.name : undefined;
|
|
3655
|
-
if ((!name ||
|
|
3739
|
+
if ((!name || !optionsPatternsTest(names, name)) && (!includeData || !node.init || !isData(node.init))) {
|
|
3656
3740
|
return;
|
|
3657
3741
|
}
|
|
3658
3742
|
const file = context.filename.replaceAll("\\", "/");
|
|
3659
|
-
const
|
|
3743
|
+
const folder = basename2(dirname2(file));
|
|
3744
|
+
const stem = basename2(file).split(".")[0];
|
|
3745
|
+
const role = roles.find((candidate) => stem.endsWith(`-${candidate}`));
|
|
3746
|
+
const domain = role ? stem.slice(0, -role.length - 1) : stem;
|
|
3747
|
+
const owner = folders.some((candidate) => file.includes(`/${candidate}/`) && folder !== candidate) ? folder : domain;
|
|
3660
3748
|
context.report({
|
|
3661
3749
|
node,
|
|
3662
3750
|
messageId: "forbidden",
|
|
3663
|
-
data: { name: name ?? "<destructured binding>", file:
|
|
3751
|
+
data: { name: name ?? "<destructured binding>", file: target.replaceAll("{domain}", owner) }
|
|
3664
3752
|
});
|
|
3665
3753
|
}
|
|
3666
3754
|
};
|
|
@@ -3668,11 +3756,11 @@ var filesDomainConstants = defineRule29({
|
|
|
3668
3756
|
});
|
|
3669
3757
|
|
|
3670
3758
|
// src/rules/files/files-exports.ts
|
|
3671
|
-
import { defineRule as
|
|
3759
|
+
import { defineRule as defineRule31 } from "@oxlint/plugins";
|
|
3672
3760
|
function escapeRegExp(value) {
|
|
3673
3761
|
return value.replaceAll(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
3674
3762
|
}
|
|
3675
|
-
var filesExports =
|
|
3763
|
+
var filesExports = defineRule31({
|
|
3676
3764
|
meta: {
|
|
3677
3765
|
type: "problem",
|
|
3678
3766
|
schema: [
|
|
@@ -3753,11 +3841,12 @@ var filesExports = defineRule30({
|
|
|
3753
3841
|
});
|
|
3754
3842
|
|
|
3755
3843
|
// src/rules/files/files-externals.ts
|
|
3756
|
-
import { defineRule as
|
|
3844
|
+
import { defineRule as defineRule32 } from "@oxlint/plugins";
|
|
3757
3845
|
import { existsSync as existsSync2, readFileSync } from "node:fs";
|
|
3758
3846
|
import { builtinModules as builtinModules2 } from "node:module";
|
|
3759
3847
|
import { dirname as dirname3, join as join2 } from "node:path";
|
|
3760
|
-
var
|
|
3848
|
+
var filesExternalsConfigs = "^(?:vite|next)\\.config\\.[cm]?[jt]s$";
|
|
3849
|
+
var filesExternals = defineRule32({
|
|
3761
3850
|
meta: {
|
|
3762
3851
|
type: "problem",
|
|
3763
3852
|
schema: [
|
|
@@ -3765,7 +3854,8 @@ var filesExternals = defineRule31({
|
|
|
3765
3854
|
type: "object",
|
|
3766
3855
|
additionalProperties: false,
|
|
3767
3856
|
properties: {
|
|
3768
|
-
packages: { type: "array", items: { type: "string", minLength: 1 } }
|
|
3857
|
+
packages: { type: "array", items: { type: "string", minLength: 1 } },
|
|
3858
|
+
files: { ...optionsPatternSchema, default: filesExternalsConfigs }
|
|
3769
3859
|
}
|
|
3770
3860
|
}
|
|
3771
3861
|
],
|
|
@@ -3821,7 +3911,8 @@ var filesExternals = defineRule31({
|
|
|
3821
3911
|
}
|
|
3822
3912
|
return {
|
|
3823
3913
|
before() {
|
|
3824
|
-
|
|
3914
|
+
const files = optionsPatterns(optionsFirst(context, {}).files ?? filesExternalsConfigs);
|
|
3915
|
+
if (!optionsPatternsTest(files, namingBasename(context.filename))) {
|
|
3825
3916
|
return false;
|
|
3826
3917
|
}
|
|
3827
3918
|
},
|
|
@@ -3848,7 +3939,7 @@ var filesExternals = defineRule31({
|
|
|
3848
3939
|
});
|
|
3849
3940
|
|
|
3850
3941
|
// src/rules/files/files-factory-keys.ts
|
|
3851
|
-
import { defineRule as
|
|
3942
|
+
import { defineRule as defineRule33 } from "@oxlint/plugins";
|
|
3852
3943
|
function returnedObject(expression) {
|
|
3853
3944
|
if (expression?.type === "TSAsExpression" || expression?.type === "TSSatisfiesExpression" || expression?.type === "TSTypeAssertion" || expression?.type === "TSNonNullExpression") {
|
|
3854
3945
|
return returnedObject(expression.expression);
|
|
@@ -3859,7 +3950,7 @@ function compileKeys(pattern, keys, requireKeys) {
|
|
|
3859
3950
|
const allowedList = keys.concat(requireKeys.filter((key) => !keys.includes(key)));
|
|
3860
3951
|
return { patterns: optionsPatternsWithEmpty(pattern), allowed: new Set(allowedList), allowedList, required: requireKeys };
|
|
3861
3952
|
}
|
|
3862
|
-
var filesFactoryKeys =
|
|
3953
|
+
var filesFactoryKeys = defineRule33({
|
|
3863
3954
|
meta: {
|
|
3864
3955
|
type: "problem",
|
|
3865
3956
|
schema: [
|
|
@@ -3977,8 +4068,8 @@ var filesFactoryKeys = defineRule32({
|
|
|
3977
4068
|
});
|
|
3978
4069
|
|
|
3979
4070
|
// src/rules/files/files-helpers.ts
|
|
3980
|
-
import { defineRule as
|
|
3981
|
-
var filesHelpers =
|
|
4071
|
+
import { defineRule as defineRule34 } from "@oxlint/plugins";
|
|
4072
|
+
var filesHelpers = defineRule34({
|
|
3982
4073
|
meta: {
|
|
3983
4074
|
type: "problem",
|
|
3984
4075
|
schema: [
|
|
@@ -4026,8 +4117,8 @@ var filesHelpers = defineRule33({
|
|
|
4026
4117
|
});
|
|
4027
4118
|
|
|
4028
4119
|
// src/rules/files/files-no-functions.ts
|
|
4029
|
-
import { defineRule as
|
|
4030
|
-
var filesNoFunctions =
|
|
4120
|
+
import { defineRule as defineRule35 } from "@oxlint/plugins";
|
|
4121
|
+
var filesNoFunctions = defineRule35({
|
|
4031
4122
|
meta: {
|
|
4032
4123
|
type: "problem",
|
|
4033
4124
|
schema: [
|
|
@@ -4081,8 +4172,8 @@ var filesNoFunctions = defineRule34({
|
|
|
4081
4172
|
});
|
|
4082
4173
|
|
|
4083
4174
|
// src/rules/files/files-restricted.ts
|
|
4084
|
-
import { defineRule as
|
|
4085
|
-
var filesRestricted =
|
|
4175
|
+
import { defineRule as defineRule36 } from "@oxlint/plugins";
|
|
4176
|
+
var filesRestricted = defineRule36({
|
|
4086
4177
|
meta: {
|
|
4087
4178
|
type: "problem",
|
|
4088
4179
|
schema: [
|
|
@@ -4114,7 +4205,7 @@ var filesRestricted = defineRule35({
|
|
|
4114
4205
|
});
|
|
4115
4206
|
|
|
4116
4207
|
// src/rules/files/files-route.ts
|
|
4117
|
-
import { defineRule as
|
|
4208
|
+
import { defineRule as defineRule37 } from "@oxlint/plugins";
|
|
4118
4209
|
function inspectAdapter(context, item, bannedHooks, banIntrinsicJsx) {
|
|
4119
4210
|
astVisit(item.node.body, [item.node], (node) => {
|
|
4120
4211
|
if (banIntrinsicJsx && node.type === "JSXOpeningElement" && node.name.type === "JSXIdentifier" && /^[a-z]/.test(node.name.name)) {
|
|
@@ -4134,7 +4225,7 @@ function inspectAdapter(context, item, bannedHooks, banIntrinsicJsx) {
|
|
|
4134
4225
|
}
|
|
4135
4226
|
});
|
|
4136
4227
|
}
|
|
4137
|
-
var filesRoute =
|
|
4228
|
+
var filesRoute = defineRule37({
|
|
4138
4229
|
meta: {
|
|
4139
4230
|
type: "problem",
|
|
4140
4231
|
schema: [
|
|
@@ -4204,7 +4295,7 @@ var filesRoute = defineRule36({
|
|
|
4204
4295
|
});
|
|
4205
4296
|
|
|
4206
4297
|
// src/rules/files/files-types-only.ts
|
|
4207
|
-
import { defineRule as
|
|
4298
|
+
import { defineRule as defineRule38 } from "@oxlint/plugins";
|
|
4208
4299
|
function runtimeImportLocalNames(statement) {
|
|
4209
4300
|
return statement.specifiers.flatMap((specifier) => specifier.type !== "ImportSpecifier" || specifier.importKind !== "type" ? [specifier.local.name] : []);
|
|
4210
4301
|
}
|
|
@@ -4373,7 +4464,7 @@ function runtimeKind(node) {
|
|
|
4373
4464
|
}
|
|
4374
4465
|
return node.type === "FunctionDeclaration" ? "function" : "variable";
|
|
4375
4466
|
}
|
|
4376
|
-
var filesTypesOnly =
|
|
4467
|
+
var filesTypesOnly = defineRule38({
|
|
4377
4468
|
meta: {
|
|
4378
4469
|
type: "problem",
|
|
4379
4470
|
schema: [
|
|
@@ -4481,8 +4572,8 @@ var filesTypesOnly = defineRule37({
|
|
|
4481
4572
|
});
|
|
4482
4573
|
|
|
4483
4574
|
// src/rules/layout/layout-arrow-body.ts
|
|
4484
|
-
import { defineRule as
|
|
4485
|
-
var layoutArrowBody =
|
|
4575
|
+
import { defineRule as defineRule39 } from "@oxlint/plugins";
|
|
4576
|
+
var layoutArrowBody = defineRule39({
|
|
4486
4577
|
meta: {
|
|
4487
4578
|
type: "layout",
|
|
4488
4579
|
fixable: "whitespace",
|
|
@@ -4534,12 +4625,12 @@ var layoutArrowBody = defineRule38({
|
|
|
4534
4625
|
});
|
|
4535
4626
|
|
|
4536
4627
|
// src/rules/layout/layout-call-arguments.ts
|
|
4537
|
-
import { defineRule as
|
|
4628
|
+
import { defineRule as defineRule40 } from "@oxlint/plugins";
|
|
4538
4629
|
function layoutCallArgumentsHuggable(node) {
|
|
4539
4630
|
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);
|
|
4540
4631
|
}
|
|
4541
4632
|
var layoutCallArgumentsMax = { type: "integer", minimum: 1 };
|
|
4542
|
-
var layoutCallArguments =
|
|
4633
|
+
var layoutCallArguments = defineRule40({
|
|
4543
4634
|
meta: {
|
|
4544
4635
|
type: "layout",
|
|
4545
4636
|
fixable: "whitespace",
|
|
@@ -4553,11 +4644,7 @@ var layoutCallArguments = defineRule39({
|
|
|
4553
4644
|
minimum: 2,
|
|
4554
4645
|
default: 3
|
|
4555
4646
|
},
|
|
4556
|
-
indent: {
|
|
4557
|
-
type: "integer",
|
|
4558
|
-
minimum: 1,
|
|
4559
|
-
default: 2
|
|
4560
|
-
},
|
|
4647
|
+
indent: { ...sourceIndentSchema, default: 2 },
|
|
4561
4648
|
split: {
|
|
4562
4649
|
type: "boolean",
|
|
4563
4650
|
default: true
|
|
@@ -4575,6 +4662,7 @@ var layoutCallArguments = defineRule39({
|
|
|
4575
4662
|
properties: {
|
|
4576
4663
|
max: layoutCallArgumentsMax,
|
|
4577
4664
|
nesting: layoutCallArgumentsMax,
|
|
4665
|
+
items: layoutCallArgumentsMax,
|
|
4578
4666
|
keep: { type: "array", items: { type: "string" } }
|
|
4579
4667
|
}
|
|
4580
4668
|
}
|
|
@@ -4591,7 +4679,7 @@ var layoutCallArguments = defineRule39({
|
|
|
4591
4679
|
createOnce(context) {
|
|
4592
4680
|
let options = {};
|
|
4593
4681
|
let minArguments = 3;
|
|
4594
|
-
let
|
|
4682
|
+
let indentUnit = sourceIndentUnit();
|
|
4595
4683
|
const split = (node) => {
|
|
4596
4684
|
const args = node.arguments;
|
|
4597
4685
|
const last = args.at(-1);
|
|
@@ -4615,7 +4703,7 @@ var layoutCallArguments = defineRule39({
|
|
|
4615
4703
|
const unsafe = source.getCommentsInside(node).length > 0 || text[open] !== "(" || text[close] !== ")" || !/^\s*$/.test(between[0]) || between.slice(1, -1).some((gap) => !/^\s*,\s*$/.test(gap)) || !/^\s*,?\s*$/.test(between.at(-1) ?? "");
|
|
4616
4704
|
const baseIndent = sourceLineIndent(text, open);
|
|
4617
4705
|
const newline = sourceNewline(text);
|
|
4618
|
-
const argumentIndent = `${baseIndent}${
|
|
4706
|
+
const argumentIndent = `${baseIndent}${indentUnit}`;
|
|
4619
4707
|
context.report({
|
|
4620
4708
|
node,
|
|
4621
4709
|
messageId: "multiline",
|
|
@@ -4660,7 +4748,7 @@ var layoutCallArguments = defineRule39({
|
|
|
4660
4748
|
}
|
|
4661
4749
|
const newline = sourceNewline(text);
|
|
4662
4750
|
const base = sourceLineIndent(text, open.range[0]);
|
|
4663
|
-
const inner = `${base}${
|
|
4751
|
+
const inner = `${base}${indentUnit}`;
|
|
4664
4752
|
context.report({
|
|
4665
4753
|
node,
|
|
4666
4754
|
messageId: "hug",
|
|
@@ -4671,16 +4759,14 @@ var layoutCallArguments = defineRule39({
|
|
|
4671
4759
|
const source = context.sourceCode;
|
|
4672
4760
|
const text = source.text;
|
|
4673
4761
|
const first = items.at(0);
|
|
4674
|
-
if (!first || !open || !close || items.length > 2 || first.loc.start.line === open.loc.end.line || !items.every(astIsOneLine) || source.commentsExistBetween(open, close)) {
|
|
4762
|
+
if (!first || !open || !close || items.length > Math.min(options.join?.items ?? 2, options.split === false ? Number.POSITIVE_INFINITY : minArguments - 1) || first.loc.start.line === open.loc.end.line || !items.every(astIsOneLine) || source.commentsExistBetween(open, close)) {
|
|
4675
4763
|
return;
|
|
4676
4764
|
}
|
|
4677
|
-
const
|
|
4678
|
-
const
|
|
4679
|
-
|
|
4680
|
-
if (`${before}${inside}${after}`.length > (options.join?.max ?? 0)) {
|
|
4765
|
+
const gaps = sourceItemGaps(open.range[1], items, close.range[0]);
|
|
4766
|
+
const comma = text.slice(...gaps.at(-1) ?? [0, 0]).includes(",") ? "," : "";
|
|
4767
|
+
if (sourceJoinedWidth(text, open.range[1], `${items.map((item) => source.getText(item)).join(", ")}${comma}`, close.range[0]) > (options.join?.max ?? 0)) {
|
|
4681
4768
|
return;
|
|
4682
4769
|
}
|
|
4683
|
-
const gaps = sourceItemGaps(open.range[1], items, close.range[0]);
|
|
4684
4770
|
context.report({
|
|
4685
4771
|
node,
|
|
4686
4772
|
messageId: "join",
|
|
@@ -4712,7 +4798,7 @@ var layoutCallArguments = defineRule39({
|
|
|
4712
4798
|
before() {
|
|
4713
4799
|
options = optionsFirst(context, {});
|
|
4714
4800
|
minArguments = options.min ?? 3;
|
|
4715
|
-
|
|
4801
|
+
indentUnit = sourceIndentUnit(options.indent);
|
|
4716
4802
|
},
|
|
4717
4803
|
CallExpression: call,
|
|
4718
4804
|
NewExpression: call,
|
|
@@ -4726,12 +4812,12 @@ var layoutCallArguments = defineRule39({
|
|
|
4726
4812
|
});
|
|
4727
4813
|
|
|
4728
4814
|
// src/rules/layout/layout-call-array.ts
|
|
4729
|
-
import { defineRule as
|
|
4815
|
+
import { defineRule as defineRule41 } from "@oxlint/plugins";
|
|
4730
4816
|
var layoutCallArrayDefaultCallees = ["Promise.all", "Promise.allSettled"];
|
|
4731
4817
|
function layoutCallArrayRoot(node) {
|
|
4732
4818
|
return node.type === "MemberExpression" ? layoutCallArrayRoot(node.object) : node;
|
|
4733
4819
|
}
|
|
4734
|
-
var layoutCallArray =
|
|
4820
|
+
var layoutCallArray = defineRule41({
|
|
4735
4821
|
meta: {
|
|
4736
4822
|
type: "layout",
|
|
4737
4823
|
fixable: "whitespace",
|
|
@@ -4847,7 +4933,7 @@ var layoutCallArray = defineRule40({
|
|
|
4847
4933
|
});
|
|
4848
4934
|
|
|
4849
4935
|
// src/rules/layout/layout-call-depth.ts
|
|
4850
|
-
import { defineRule as
|
|
4936
|
+
import { defineRule as defineRule42 } from "@oxlint/plugins";
|
|
4851
4937
|
function layoutCallDepthOuter(node) {
|
|
4852
4938
|
const parent = node.parent;
|
|
4853
4939
|
if (!parent || parent.type === "ArrowFunctionExpression" || parent.type === "FunctionExpression" || parent.type.endsWith("Statement")) {
|
|
@@ -4855,7 +4941,7 @@ function layoutCallDepthOuter(node) {
|
|
|
4855
4941
|
}
|
|
4856
4942
|
return astIsCall(parent) && parent.arguments.some((argument) => argument === node) ? parent : layoutCallDepthOuter(parent);
|
|
4857
4943
|
}
|
|
4858
|
-
var layoutCallDepth =
|
|
4944
|
+
var layoutCallDepth = defineRule42({
|
|
4859
4945
|
meta: {
|
|
4860
4946
|
type: "layout",
|
|
4861
4947
|
schema: [
|
|
@@ -4894,8 +4980,8 @@ var layoutCallDepth = defineRule41({
|
|
|
4894
4980
|
});
|
|
4895
4981
|
|
|
4896
4982
|
// src/rules/layout/layout-chain.ts
|
|
4897
|
-
import { defineRule as
|
|
4898
|
-
var layoutChain =
|
|
4983
|
+
import { defineRule as defineRule43 } from "@oxlint/plugins";
|
|
4984
|
+
var layoutChain = defineRule43({
|
|
4899
4985
|
meta: {
|
|
4900
4986
|
type: "layout",
|
|
4901
4987
|
fixable: "whitespace",
|
|
@@ -5014,8 +5100,8 @@ var layoutChain = defineRule42({
|
|
|
5014
5100
|
});
|
|
5015
5101
|
|
|
5016
5102
|
// src/rules/layout/layout-items.ts
|
|
5017
|
-
import { defineRule as
|
|
5018
|
-
var layoutItems =
|
|
5103
|
+
import { defineRule as defineRule44 } from "@oxlint/plugins";
|
|
5104
|
+
var layoutItems = defineRule44({
|
|
5019
5105
|
meta: {
|
|
5020
5106
|
type: "layout",
|
|
5021
5107
|
fixable: "whitespace",
|
|
@@ -5070,8 +5156,8 @@ var layoutItems = defineRule43({
|
|
|
5070
5156
|
});
|
|
5071
5157
|
|
|
5072
5158
|
// src/rules/layout/layout-jsx-attributes.ts
|
|
5073
|
-
import { defineRule as
|
|
5074
|
-
var layoutJsxAttributes =
|
|
5159
|
+
import { defineRule as defineRule45 } from "@oxlint/plugins";
|
|
5160
|
+
var layoutJsxAttributes = defineRule45({
|
|
5075
5161
|
meta: {
|
|
5076
5162
|
type: "layout",
|
|
5077
5163
|
fixable: "whitespace",
|
|
@@ -5081,12 +5167,19 @@ var layoutJsxAttributes = defineRule44({
|
|
|
5081
5167
|
additionalProperties: false,
|
|
5082
5168
|
properties: {
|
|
5083
5169
|
min: { type: "integer", minimum: 1 },
|
|
5084
|
-
indent: sourceIndentSchema
|
|
5170
|
+
indent: sourceIndentSchema,
|
|
5171
|
+
join: {
|
|
5172
|
+
type: "object",
|
|
5173
|
+
additionalProperties: false,
|
|
5174
|
+
required: ["max"],
|
|
5175
|
+
properties: { max: { type: "integer", minimum: 1 } }
|
|
5176
|
+
}
|
|
5085
5177
|
}
|
|
5086
5178
|
}
|
|
5087
5179
|
],
|
|
5088
5180
|
messages: {
|
|
5089
|
-
multiline: "Put every JSX attribute and the closing token on its own line."
|
|
5181
|
+
multiline: "Put every JSX attribute and the closing token on its own line.",
|
|
5182
|
+
join: "This tag fits on one line, so keep it on one line."
|
|
5090
5183
|
}
|
|
5091
5184
|
},
|
|
5092
5185
|
createOnce(context) {
|
|
@@ -5094,35 +5187,52 @@ var layoutJsxAttributes = defineRule44({
|
|
|
5094
5187
|
let indentUnit = sourceIndentUnit();
|
|
5095
5188
|
let newline = `
|
|
5096
5189
|
`;
|
|
5190
|
+
let joinMax;
|
|
5097
5191
|
return {
|
|
5098
5192
|
before() {
|
|
5099
5193
|
const options = optionsFirst(context, {});
|
|
5100
5194
|
minAttributes = options.min ?? 3;
|
|
5101
5195
|
indentUnit = sourceIndentUnit(options.indent);
|
|
5102
5196
|
newline = sourceNewline(context.sourceCode.text);
|
|
5197
|
+
joinMax = options.join?.max;
|
|
5103
5198
|
},
|
|
5104
5199
|
JSXOpeningElement(node) {
|
|
5105
|
-
if (node.attributes.length < minAttributes || node.loc.start.line !== node.loc.end.line) {
|
|
5106
|
-
return;
|
|
5107
|
-
}
|
|
5108
5200
|
const source = context.sourceCode;
|
|
5109
5201
|
const text = source.text;
|
|
5202
|
+
const attributes = node.attributes;
|
|
5203
|
+
const split = attributes.length >= minAttributes;
|
|
5204
|
+
if (split ? !astIsOneLine(node) : joinMax === undefined || astIsOneLine(node)) {
|
|
5205
|
+
return;
|
|
5206
|
+
}
|
|
5207
|
+
if (!split) {
|
|
5208
|
+
const start = (node.typeArguments ?? node.name).range[1];
|
|
5209
|
+
if (attributes.length === 0 || !attributes.every(astIsOneLine) || text.slice(node.range[0], start).includes(`
|
|
5210
|
+
`) || source.getCommentsInside(node).length > 0) {
|
|
5211
|
+
return;
|
|
5212
|
+
}
|
|
5213
|
+
const end = node.range[1] - (node.selfClosing ? 2 : 1);
|
|
5214
|
+
const ranges = sourceItemGaps(start, attributes, end);
|
|
5215
|
+
const closing = node.selfClosing ? " " : "";
|
|
5216
|
+
if (sourceJoinedWidth(text, start, ` ${attributes.map((attribute) => source.getText(attribute)).join(" ")}${closing}`, end) > (joinMax ?? 0)) {
|
|
5217
|
+
return;
|
|
5218
|
+
}
|
|
5219
|
+
context.report({
|
|
5220
|
+
node,
|
|
5221
|
+
messageId: "join",
|
|
5222
|
+
fix: (fixer) => ranges.some((range) => !/^\s*$/.test(text.slice(...range))) ? null : ranges.map((range, index) => fixer.replaceTextRange(range, index === ranges.length - 1 ? closing : " "))
|
|
5223
|
+
});
|
|
5224
|
+
return;
|
|
5225
|
+
}
|
|
5110
5226
|
const baseIndent = sourceLineIndent(text, node.range[0]);
|
|
5111
5227
|
const attributeIndent = baseIndent + indentUnit;
|
|
5112
|
-
const attributes = node.attributes;
|
|
5113
5228
|
context.report({
|
|
5114
5229
|
node,
|
|
5115
5230
|
messageId: "multiline",
|
|
5116
5231
|
fix: (fixer) => {
|
|
5117
|
-
|
|
5118
|
-
if (source.getCommentsInside(node).length > 0 || !last) {
|
|
5232
|
+
if (source.getCommentsInside(node).length > 0) {
|
|
5119
5233
|
return null;
|
|
5120
5234
|
}
|
|
5121
|
-
const ranges = [
|
|
5122
|
-
[(node.typeArguments ?? node.name).range[1], attributes[0].range[0]],
|
|
5123
|
-
...attributes.slice(1).map((attribute, index) => [attributes[index].range[1], attribute.range[0]]),
|
|
5124
|
-
[last.range[1], node.range[1] - (node.selfClosing ? 2 : 1)]
|
|
5125
|
-
];
|
|
5235
|
+
const ranges = sourceItemGaps((node.typeArguments ?? node.name).range[1], attributes, node.range[1] - (node.selfClosing ? 2 : 1));
|
|
5126
5236
|
if (ranges.some((range) => !/^\s*$/.test(text.slice(...range)))) {
|
|
5127
5237
|
return null;
|
|
5128
5238
|
}
|
|
@@ -5135,8 +5245,8 @@ var layoutJsxAttributes = defineRule44({
|
|
|
5135
5245
|
});
|
|
5136
5246
|
|
|
5137
5247
|
// src/rules/layout/layout-key-value.ts
|
|
5138
|
-
import { defineRule as
|
|
5139
|
-
var layoutKeyValue =
|
|
5248
|
+
import { defineRule as defineRule46 } from "@oxlint/plugins";
|
|
5249
|
+
var layoutKeyValue = defineRule46({
|
|
5140
5250
|
meta: {
|
|
5141
5251
|
type: "layout",
|
|
5142
5252
|
fixable: "whitespace",
|
|
@@ -5172,11 +5282,15 @@ var layoutKeyValue = defineRule45({
|
|
|
5172
5282
|
});
|
|
5173
5283
|
|
|
5174
5284
|
// src/rules/layout/layout-object.ts
|
|
5175
|
-
import { defineRule as
|
|
5285
|
+
import { defineRule as defineRule47 } from "@oxlint/plugins";
|
|
5176
5286
|
function layoutObjectIsWhitespace(text) {
|
|
5177
5287
|
return /^[\t\n\r\f ]*$/.test(text);
|
|
5178
5288
|
}
|
|
5179
|
-
|
|
5289
|
+
function layoutObjectIsFlat(property) {
|
|
5290
|
+
const value = property.type === "SpreadElement" ? property.argument : property.value;
|
|
5291
|
+
return astIsOneLine(property) && (property.type === "SpreadElement" || !property.method && property.kind === "init") && value.type !== "ObjectExpression" && value.type !== "ArrayExpression" && !astIsInlineFunction(value);
|
|
5292
|
+
}
|
|
5293
|
+
var layoutObject = defineRule47({
|
|
5180
5294
|
meta: {
|
|
5181
5295
|
type: "layout",
|
|
5182
5296
|
fixable: "whitespace",
|
|
@@ -5187,13 +5301,23 @@ var layoutObject = defineRule46({
|
|
|
5187
5301
|
properties: {
|
|
5188
5302
|
min: { type: "integer", minimum: 1, default: 3 },
|
|
5189
5303
|
scope: { type: "string", enum: ["call-args", "all"], default: "call-args" },
|
|
5190
|
-
indent: { ...sourceIndentSchema, default: 2 }
|
|
5304
|
+
indent: { ...sourceIndentSchema, default: 2 },
|
|
5305
|
+
join: {
|
|
5306
|
+
type: "object",
|
|
5307
|
+
additionalProperties: false,
|
|
5308
|
+
required: ["max"],
|
|
5309
|
+
properties: {
|
|
5310
|
+
max: { type: "integer", minimum: 1 },
|
|
5311
|
+
keep: { type: "array", items: { type: "string" } }
|
|
5312
|
+
}
|
|
5313
|
+
}
|
|
5191
5314
|
}
|
|
5192
5315
|
}
|
|
5193
5316
|
],
|
|
5194
5317
|
messages: {
|
|
5195
5318
|
callArgs: "Object with {{min}}+ properties in a call should have each property on its own line.",
|
|
5196
|
-
always: "Object with {{min}}+ properties should have each property on its own line."
|
|
5319
|
+
always: "Object with {{min}}+ properties should have each property on its own line.",
|
|
5320
|
+
join: "This object fits on one line, so keep it on one line."
|
|
5197
5321
|
}
|
|
5198
5322
|
},
|
|
5199
5323
|
createOnce(context) {
|
|
@@ -5202,6 +5326,7 @@ var layoutObject = defineRule46({
|
|
|
5202
5326
|
let indentUnit = sourceIndentUnit();
|
|
5203
5327
|
let newline = `
|
|
5204
5328
|
`;
|
|
5329
|
+
let join3;
|
|
5205
5330
|
return {
|
|
5206
5331
|
before() {
|
|
5207
5332
|
const options = optionsFirst(context, {});
|
|
@@ -5209,21 +5334,43 @@ var layoutObject = defineRule46({
|
|
|
5209
5334
|
scope = options.scope ?? "call-args";
|
|
5210
5335
|
indentUnit = sourceIndentUnit(options.indent);
|
|
5211
5336
|
newline = sourceNewline(context.sourceCode.text);
|
|
5337
|
+
join3 = options.join;
|
|
5212
5338
|
},
|
|
5213
5339
|
ObjectExpression(node) {
|
|
5214
|
-
|
|
5340
|
+
const source = context.sourceCode;
|
|
5341
|
+
const text = source.text;
|
|
5342
|
+
const properties = node.properties;
|
|
5343
|
+
const split = properties.length >= minProperties;
|
|
5344
|
+
if (split ? !astIsOneLine(node) : !join3 || astIsOneLine(node)) {
|
|
5215
5345
|
return;
|
|
5216
5346
|
}
|
|
5217
5347
|
const parent = node.parent;
|
|
5218
|
-
|
|
5348
|
+
const call = (parent.type === "CallExpression" || parent.type === "NewExpression") && parent.arguments.includes(node) ? parent : undefined;
|
|
5349
|
+
if (scope === "call-args" && !call) {
|
|
5350
|
+
return;
|
|
5351
|
+
}
|
|
5352
|
+
if (!split) {
|
|
5353
|
+
const callee = call ? astDottedName(call.callee) : undefined;
|
|
5354
|
+
const kept = callee !== undefined && (join3?.keep ?? []).some((name) => callee === name || callee.endsWith(`.${name}`));
|
|
5355
|
+
if (kept || properties.length === 0 || !properties.every(layoutObjectIsFlat) || source.getCommentsInside(node).length > 0) {
|
|
5356
|
+
return;
|
|
5357
|
+
}
|
|
5358
|
+
const gaps = sourceItemGaps(node.range[0] + 1, properties, node.range[1] - 1);
|
|
5359
|
+
const comma = text.slice(...gaps.at(-1) ?? [0, 0]).includes(",") ? "," : "";
|
|
5360
|
+
const joined = ` ${properties.map((property) => source.getText(property)).join(", ")}${comma} `;
|
|
5361
|
+
if (sourceJoinedWidth(text, node.range[0] + 1, joined, node.range[1] - 1) > (join3?.max ?? 0)) {
|
|
5362
|
+
return;
|
|
5363
|
+
}
|
|
5364
|
+
context.report({
|
|
5365
|
+
node,
|
|
5366
|
+
messageId: "join",
|
|
5367
|
+
fix: (fixer) => sourceRespace(fixer, text, gaps, () => " ")
|
|
5368
|
+
});
|
|
5219
5369
|
return;
|
|
5220
5370
|
}
|
|
5221
|
-
const source = context.sourceCode;
|
|
5222
|
-
const text = source.text;
|
|
5223
5371
|
const baseIndent = sourceLineIndent(text, node.range[0]);
|
|
5224
5372
|
const propertyIndent = `${baseIndent}${indentUnit}`;
|
|
5225
5373
|
const close = node.range[1] - 1;
|
|
5226
|
-
const properties = node.properties;
|
|
5227
5374
|
context.report({
|
|
5228
5375
|
node,
|
|
5229
5376
|
messageId: scope === "all" ? "always" : "callArgs",
|
|
@@ -5260,7 +5407,7 @@ var layoutObject = defineRule46({
|
|
|
5260
5407
|
});
|
|
5261
5408
|
|
|
5262
5409
|
// src/rules/layout/layout-padding.ts
|
|
5263
|
-
import { defineRule as
|
|
5410
|
+
import { defineRule as defineRule48 } from "@oxlint/plugins";
|
|
5264
5411
|
var layoutPaddingControl = new Set([
|
|
5265
5412
|
"IfStatement",
|
|
5266
5413
|
"ForStatement",
|
|
@@ -5289,7 +5436,7 @@ function layoutPaddingKind(node) {
|
|
|
5289
5436
|
function layoutPaddingIsMultilineVariable(node, kind) {
|
|
5290
5437
|
return kind === "variable" && node.loc.start.line !== node.loc.end.line;
|
|
5291
5438
|
}
|
|
5292
|
-
var layoutPadding =
|
|
5439
|
+
var layoutPadding = defineRule48({
|
|
5293
5440
|
meta: {
|
|
5294
5441
|
type: "layout",
|
|
5295
5442
|
fixable: "whitespace",
|
|
@@ -5378,8 +5525,8 @@ var layoutPadding = defineRule47({
|
|
|
5378
5525
|
});
|
|
5379
5526
|
|
|
5380
5527
|
// src/rules/layout/layout-pipe.ts
|
|
5381
|
-
import { defineRule as
|
|
5382
|
-
var layoutPipe =
|
|
5528
|
+
import { defineRule as defineRule49 } from "@oxlint/plugins";
|
|
5529
|
+
var layoutPipe = defineRule49({
|
|
5383
5530
|
meta: {
|
|
5384
5531
|
type: "layout",
|
|
5385
5532
|
messages: {
|
|
@@ -5410,7 +5557,7 @@ var layoutPipe = defineRule48({
|
|
|
5410
5557
|
});
|
|
5411
5558
|
|
|
5412
5559
|
// src/rules/layout/layout-ternary.ts
|
|
5413
|
-
import { defineRule as
|
|
5560
|
+
import { defineRule as defineRule50 } from "@oxlint/plugins";
|
|
5414
5561
|
function layoutTernaryLines(node) {
|
|
5415
5562
|
return node.loc.end.line - node.loc.start.line + 1;
|
|
5416
5563
|
}
|
|
@@ -5418,7 +5565,7 @@ function layoutTernaryBreak(between, operator, newline) {
|
|
|
5418
5565
|
const at = between.indexOf(operator);
|
|
5419
5566
|
return `${between.slice(0, at).trimEnd()}${newline}${operator} ${between.slice(at + 1).trimStart()}`;
|
|
5420
5567
|
}
|
|
5421
|
-
var layoutTernary =
|
|
5568
|
+
var layoutTernary = defineRule50({
|
|
5422
5569
|
meta: {
|
|
5423
5570
|
type: "layout",
|
|
5424
5571
|
fixable: "whitespace",
|
|
@@ -5432,11 +5579,7 @@ var layoutTernary = defineRule49({
|
|
|
5432
5579
|
minimum: 1,
|
|
5433
5580
|
default: 160
|
|
5434
5581
|
},
|
|
5435
|
-
indent: {
|
|
5436
|
-
type: "integer",
|
|
5437
|
-
minimum: 1,
|
|
5438
|
-
default: 2
|
|
5439
|
-
},
|
|
5582
|
+
indent: { ...sourceIndentSchema, default: 2 },
|
|
5440
5583
|
fit: {
|
|
5441
5584
|
type: "boolean",
|
|
5442
5585
|
default: true
|
|
@@ -5459,7 +5602,7 @@ var layoutTernary = defineRule49({
|
|
|
5459
5602
|
},
|
|
5460
5603
|
createOnce(context) {
|
|
5461
5604
|
let maxLength = 160;
|
|
5462
|
-
let
|
|
5605
|
+
let indentUnit = sourceIndentUnit();
|
|
5463
5606
|
let fit = true;
|
|
5464
5607
|
let branchMax;
|
|
5465
5608
|
const branch = (node, max) => {
|
|
@@ -5480,7 +5623,7 @@ var layoutTernary = defineRule49({
|
|
|
5480
5623
|
before() {
|
|
5481
5624
|
const options = optionsFirst(context, {});
|
|
5482
5625
|
maxLength = options.max ?? 160;
|
|
5483
|
-
|
|
5626
|
+
indentUnit = sourceIndentUnit(options.indent);
|
|
5484
5627
|
fit = options.fit ?? true;
|
|
5485
5628
|
branchMax = options.branch?.max;
|
|
5486
5629
|
},
|
|
@@ -5520,7 +5663,7 @@ var layoutTernary = defineRule49({
|
|
|
5520
5663
|
if (!onOneLine || interpolated || length <= maxLength) {
|
|
5521
5664
|
return;
|
|
5522
5665
|
}
|
|
5523
|
-
const newline = `${sourceNewline(text)}${sourceLineIndent(text, node.range[0])}${
|
|
5666
|
+
const newline = `${sourceNewline(text)}${sourceLineIndent(text, node.range[0])}${indentUnit}`;
|
|
5524
5667
|
const question = [node.test.range[1], node.consequent.range[0]];
|
|
5525
5668
|
const colon = [node.consequent.range[1], node.alternate.range[0]];
|
|
5526
5669
|
context.report({
|
|
@@ -5538,9 +5681,9 @@ var layoutTernary = defineRule49({
|
|
|
5538
5681
|
});
|
|
5539
5682
|
|
|
5540
5683
|
// src/rules/naming/naming-declarations.ts
|
|
5541
|
-
import { defineRule as
|
|
5684
|
+
import { defineRule as defineRule51 } from "@oxlint/plugins";
|
|
5542
5685
|
var namingDeclarationsKinds = ["function", "const", "let", "var", "class", "type", "interface", "enum"];
|
|
5543
|
-
var namingDeclarations =
|
|
5686
|
+
var namingDeclarations = defineRule51({
|
|
5544
5687
|
meta: {
|
|
5545
5688
|
type: "problem",
|
|
5546
5689
|
schema: [
|
|
@@ -5572,11 +5715,9 @@ var namingDeclarations = defineRule50({
|
|
|
5572
5715
|
const declarator = node.type === "VariableDeclarator";
|
|
5573
5716
|
const kind = declarationsKindOf(node, declarator ? [node.parent] : []);
|
|
5574
5717
|
const name = declarationsIdName(node);
|
|
5575
|
-
|
|
5576
|
-
|
|
5577
|
-
|
|
5578
|
-
}
|
|
5579
|
-
if (!kind || !name || insideLoop || kinds && !kinds.has(kind) || optionsPatternsTest(allowed, name)) {
|
|
5718
|
+
const loop = declarator ? node.parent.parent : null;
|
|
5719
|
+
const loopHeader = loop?.type === "ForStatement" ? loop.init === node.parent : (loop?.type === "ForInStatement" || loop?.type === "ForOfStatement") && loop.left === node.parent;
|
|
5720
|
+
if (!kind || !name || loopHeader || kinds && !kinds.has(kind) || optionsPatternsTest(allowed, name)) {
|
|
5580
5721
|
return;
|
|
5581
5722
|
}
|
|
5582
5723
|
if (expected.length > 0) {
|
|
@@ -5619,7 +5760,7 @@ var namingDeclarations = defineRule50({
|
|
|
5619
5760
|
});
|
|
5620
5761
|
|
|
5621
5762
|
// src/rules/naming/naming-exports.ts
|
|
5622
|
-
import { defineRule as
|
|
5763
|
+
import { defineRule as defineRule52 } from "@oxlint/plugins";
|
|
5623
5764
|
var namingExportsScopeProperties = {
|
|
5624
5765
|
scope: { type: "string", enum: ["exports", "functions", "declarations"] },
|
|
5625
5766
|
types: { type: "boolean" },
|
|
@@ -5645,7 +5786,7 @@ function matchTemplate(basename3, template, placeholder = "[a-z0-9-]+") {
|
|
|
5645
5786
|
}
|
|
5646
5787
|
return new RegExp(`^${pattern}$`).exec(basename3)?.groups ?? null;
|
|
5647
5788
|
}
|
|
5648
|
-
var namingExports =
|
|
5789
|
+
var namingExports = defineRule52({
|
|
5649
5790
|
meta: {
|
|
5650
5791
|
type: "problem",
|
|
5651
5792
|
schema: {
|
|
@@ -5740,9 +5881,12 @@ var namingExports = defineRule51({
|
|
|
5740
5881
|
}
|
|
5741
5882
|
continue;
|
|
5742
5883
|
}
|
|
5743
|
-
const names = scope === "declarations" ? [...declarations ??= declarationsNamed(program)] : (bindings ??= exportsCollect(program)).flatMap((binding) =>
|
|
5884
|
+
const names = scope === "declarations" ? [...declarations ??= declarationsNamed(program)] : (bindings ??= exportsCollect(program)).flatMap((binding) => {
|
|
5885
|
+
const name = binding.default ? binding.localName ?? binding.exportedName : binding.exportedName;
|
|
5886
|
+
return options.types && binding.typeOnly ? [] : [{ name, node: binding.node }];
|
|
5887
|
+
});
|
|
5744
5888
|
if (scope === "functions") {
|
|
5745
|
-
const exported = new Set(names.map((item) => item.name));
|
|
5889
|
+
const exported = new Set([...names.map((item) => item.name), ...(bindings ?? []).flatMap((binding) => binding.localName ?? [])]);
|
|
5746
5890
|
names.push(...(declarations ??= declarationsNamed(program)).filter(({ name, node }) => !exported.has(name) && (node.type === "FunctionDeclaration" || node.type === "VariableDeclarator" && declarationsIsFunctionValue(node.init))));
|
|
5747
5891
|
}
|
|
5748
5892
|
if (options.services) {
|
|
@@ -5779,10 +5923,10 @@ var namingExports = defineRule51({
|
|
|
5779
5923
|
});
|
|
5780
5924
|
|
|
5781
5925
|
// src/rules/naming/naming-file.ts
|
|
5782
|
-
import { defineRule as
|
|
5926
|
+
import { defineRule as defineRule53 } from "@oxlint/plugins";
|
|
5783
5927
|
import { readdirSync as readdirSync2 } from "node:fs";
|
|
5784
5928
|
import { dirname as dirname4 } from "node:path";
|
|
5785
|
-
var namingFile =
|
|
5929
|
+
var namingFile = defineRule53({
|
|
5786
5930
|
meta: {
|
|
5787
5931
|
type: "problem",
|
|
5788
5932
|
schema: {
|
|
@@ -5852,9 +5996,9 @@ var namingFile = defineRule52({
|
|
|
5852
5996
|
});
|
|
5853
5997
|
|
|
5854
5998
|
// src/rules/naming/naming-folder.ts
|
|
5855
|
-
import { defineRule as
|
|
5999
|
+
import { defineRule as defineRule54 } from "@oxlint/plugins";
|
|
5856
6000
|
import { posix as posix2 } from "node:path";
|
|
5857
|
-
var namingFolder =
|
|
6001
|
+
var namingFolder = defineRule54({
|
|
5858
6002
|
meta: {
|
|
5859
6003
|
type: "problem",
|
|
5860
6004
|
schema: [
|
|
@@ -5928,9 +6072,9 @@ var reactDynamicClasses = astSelectorRule(':matches(JSXAttribute[name.name="clas
|
|
|
5928
6072
|
var reactEmptyEffect = astSelectorRule(':matches(CallExpression[callee.name=/^use(Layout)?Effect$/], CallExpression[callee.object.name="React"][callee.property.name=/^use(Layout)?Effect$/]) > :matches(ArrowFunctionExpression, FunctionExpression) > BlockStatement[body.length=0]', "Remove the empty effect.");
|
|
5929
6073
|
|
|
5930
6074
|
// src/rules/react/react-memo.ts
|
|
5931
|
-
import { defineRule as
|
|
6075
|
+
import { defineRule as defineRule55 } from "@oxlint/plugins";
|
|
5932
6076
|
var reactMemoNames = ["memo", "useMemo", "useCallback"];
|
|
5933
|
-
var reactMemo =
|
|
6077
|
+
var reactMemo = defineRule55({
|
|
5934
6078
|
meta: {
|
|
5935
6079
|
type: "problem",
|
|
5936
6080
|
schema: [],
|
|
@@ -5965,7 +6109,7 @@ var reactMemo = defineRule54({
|
|
|
5965
6109
|
});
|
|
5966
6110
|
|
|
5967
6111
|
// src/rules/react/react-props.ts
|
|
5968
|
-
import { defineRule as
|
|
6112
|
+
import { defineRule as defineRule56 } from "@oxlint/plugins";
|
|
5969
6113
|
function reactPropsTarget(node) {
|
|
5970
6114
|
if (node?.type === "FunctionDeclaration" || node?.type === "FunctionExpression" || node?.type === "ArrowFunctionExpression") {
|
|
5971
6115
|
return { fn: node };
|
|
@@ -5992,7 +6136,7 @@ function reactIsPassThrough(type) {
|
|
|
5992
6136
|
const argument = type.typeArguments?.params.length === 1 ? type.typeArguments.params[0] : undefined;
|
|
5993
6137
|
return name.type === "Identifier" && name.name === "ComponentProps" && (argument?.type === "TSTypeQuery" || argument?.type === "TSLiteralType" && argument.literal.type === "Literal" && typeof argument.literal.value === "string");
|
|
5994
6138
|
}
|
|
5995
|
-
var reactProps =
|
|
6139
|
+
var reactProps = defineRule56({
|
|
5996
6140
|
meta: {
|
|
5997
6141
|
type: "problem",
|
|
5998
6142
|
schema: [
|
|
@@ -6000,7 +6144,8 @@ var reactProps = defineRule55({
|
|
|
6000
6144
|
type: "object",
|
|
6001
6145
|
additionalProperties: false,
|
|
6002
6146
|
properties: {
|
|
6003
|
-
prefix: { type: "boolean" }
|
|
6147
|
+
prefix: { type: "boolean" },
|
|
6148
|
+
suffix: { type: "string", minLength: 1, default: "Props" }
|
|
6004
6149
|
}
|
|
6005
6150
|
}
|
|
6006
6151
|
],
|
|
@@ -6014,7 +6159,7 @@ var reactProps = defineRule55({
|
|
|
6014
6159
|
createOnce(context) {
|
|
6015
6160
|
return {
|
|
6016
6161
|
Program(program) {
|
|
6017
|
-
const { prefix: filePrefix = false } = optionsFirst(context, {});
|
|
6162
|
+
const { prefix: filePrefix = false, suffix = "Props" } = optionsFirst(context, {});
|
|
6018
6163
|
const stem = namingFileStem(namingBasename(context.filename).replace(/\.(tsx?|jsx?)$/, ""));
|
|
6019
6164
|
const prefix = namingNormalized(stem, "remove-separators");
|
|
6020
6165
|
const exported = new Set(exportsCollect(program).flatMap((binding) => binding.typeOnly ? [] : [binding.localName]));
|
|
@@ -6039,7 +6184,7 @@ var reactProps = defineRule55({
|
|
|
6039
6184
|
continue;
|
|
6040
6185
|
}
|
|
6041
6186
|
const type = target.typeArgument ?? reactParameterType(parameter);
|
|
6042
|
-
const expected = `${candidate.name}
|
|
6187
|
+
const expected = `${candidate.name}${suffix}`;
|
|
6043
6188
|
const data = { name: candidate.name, expected };
|
|
6044
6189
|
if (filePrefix && !exported.has(candidate.name) && !candidate.name.toLowerCase().startsWith(prefix)) {
|
|
6045
6190
|
context.report({
|
|
@@ -6090,7 +6235,7 @@ var reactProps = defineRule55({
|
|
|
6090
6235
|
});
|
|
6091
6236
|
|
|
6092
6237
|
// src/rules/schemas/schemas-inline.ts
|
|
6093
|
-
import { defineRule as
|
|
6238
|
+
import { defineRule as defineRule57 } from "@oxlint/plugins";
|
|
6094
6239
|
|
|
6095
6240
|
// src/utils/schemas.utils.ts
|
|
6096
6241
|
var schemasElementOptionsSchema = {
|
|
@@ -6126,7 +6271,7 @@ function schemasIsAllowedElement(node, allowScalars, namespaces, structuralMetho
|
|
|
6126
6271
|
}
|
|
6127
6272
|
|
|
6128
6273
|
// src/rules/schemas/schemas-inline.ts
|
|
6129
|
-
var schemasInline =
|
|
6274
|
+
var schemasInline = defineRule57({
|
|
6130
6275
|
meta: {
|
|
6131
6276
|
type: "problem",
|
|
6132
6277
|
schema: [schemasElementOptionsSchema],
|
|
@@ -6175,11 +6320,11 @@ var schemasInline = defineRule56({
|
|
|
6175
6320
|
});
|
|
6176
6321
|
|
|
6177
6322
|
// src/rules/schemas/schemas-local.ts
|
|
6178
|
-
import { defineRule as
|
|
6323
|
+
import { defineRule as defineRule58 } from "@oxlint/plugins";
|
|
6179
6324
|
var schemasLocalImportMessage = "Do not import runtime schema constructors from {{source}}; import a named schema instead.";
|
|
6180
6325
|
var schemasLocalConstructionMessage = "Do not construct schemas locally; import a named schema instead.";
|
|
6181
6326
|
var schemasLocalCalls = ["config", "prettifyError", "treeifyError", "flattenError", "formatError"];
|
|
6182
|
-
var schemasLocal =
|
|
6327
|
+
var schemasLocal = defineRule58({
|
|
6183
6328
|
meta: {
|
|
6184
6329
|
type: "problem",
|
|
6185
6330
|
schema: [
|
|
@@ -6209,8 +6354,6 @@ var schemasLocal = defineRule57({
|
|
|
6209
6354
|
let packages = new Set;
|
|
6210
6355
|
let calls = new Set;
|
|
6211
6356
|
let pending = [];
|
|
6212
|
-
let schemaUses = new Set;
|
|
6213
|
-
let callUses = new Set;
|
|
6214
6357
|
let importMessage = schemasLocalImportMessage;
|
|
6215
6358
|
let constructionMessage = schemasLocalConstructionMessage;
|
|
6216
6359
|
function isAllowedCall(node, member) {
|
|
@@ -6242,8 +6385,6 @@ var schemasLocal = defineRule57({
|
|
|
6242
6385
|
packages = new Set(options.packages);
|
|
6243
6386
|
calls = new Set(options.calls ?? schemasLocalCalls);
|
|
6244
6387
|
pending = [];
|
|
6245
|
-
schemaUses = new Set;
|
|
6246
|
-
callUses = new Set;
|
|
6247
6388
|
importMessage = options.importMessage ?? options.message ?? schemasLocalImportMessage;
|
|
6248
6389
|
constructionMessage = options.constructionMessage ?? options.message ?? schemasLocalConstructionMessage;
|
|
6249
6390
|
if ((options.allow ?? []).some((suffix) => filename.endsWith(suffix)) || (options.patterns ?? []).some((pattern) => new RegExp(pattern).test(filename))) {
|
|
@@ -6267,18 +6408,8 @@ var schemasLocal = defineRule57({
|
|
|
6267
6408
|
}
|
|
6268
6409
|
pending.push({ node, locals });
|
|
6269
6410
|
},
|
|
6270
|
-
Identifier(node) {
|
|
6271
|
-
if (!constructors.has(node.name) || node.parent.type.startsWith("Import")) {
|
|
6272
|
-
return;
|
|
6273
|
-
}
|
|
6274
|
-
if (isAllowedCall(node, node.parent)) {
|
|
6275
|
-
callUses.add(node.name);
|
|
6276
|
-
return;
|
|
6277
|
-
}
|
|
6278
|
-
schemaUses.add(node.name);
|
|
6279
|
-
},
|
|
6280
6411
|
"Program:exit"() {
|
|
6281
|
-
const runtime = pending.filter(({ locals }) =>
|
|
6412
|
+
const runtime = pending.filter(({ node, locals }) => context.sourceCode.getDeclaredVariables(node).filter((variable) => locals.includes(variable.name)).some((variable) => variable.references.length === 0 || variable.references.some((reference) => !isAllowedCall(reference.identifier, reference.identifier.parent))));
|
|
6282
6413
|
for (const { node } of runtime) {
|
|
6283
6414
|
reportRuntimeImport(node, node.source.value);
|
|
6284
6415
|
}
|
|
@@ -6304,8 +6435,8 @@ var schemasLocal = defineRule57({
|
|
|
6304
6435
|
});
|
|
6305
6436
|
|
|
6306
6437
|
// src/rules/schemas/schemas-rederive.ts
|
|
6307
|
-
import { defineRule as
|
|
6308
|
-
var schemasRederive =
|
|
6438
|
+
import { defineRule as defineRule59 } from "@oxlint/plugins";
|
|
6439
|
+
var schemasRederive = defineRule59({
|
|
6309
6440
|
meta: {
|
|
6310
6441
|
type: "problem",
|
|
6311
6442
|
schema: [
|
|
@@ -6351,7 +6482,7 @@ var schemasRederive = defineRule58({
|
|
|
6351
6482
|
});
|
|
6352
6483
|
|
|
6353
6484
|
// src/rules/schemas/schemas-single-use.ts
|
|
6354
|
-
import { defineRule as
|
|
6485
|
+
import { defineRule as defineRule60 } from "@oxlint/plugins";
|
|
6355
6486
|
function isScalarSchema(node, namespaces, structuralMethods) {
|
|
6356
6487
|
if (node.type !== "CallExpression" || node.callee.type !== "MemberExpression") {
|
|
6357
6488
|
return false;
|
|
@@ -6365,7 +6496,7 @@ function isScalarSchema(node, namespaces, structuralMethods) {
|
|
|
6365
6496
|
}
|
|
6366
6497
|
return node.callee.object.type === "CallExpression" && isScalarSchema(node.callee.object, namespaces, structuralMethods);
|
|
6367
6498
|
}
|
|
6368
|
-
var schemasSingleUse =
|
|
6499
|
+
var schemasSingleUse = defineRule60({
|
|
6369
6500
|
meta: {
|
|
6370
6501
|
type: "suggestion",
|
|
6371
6502
|
schema: [schemasElementOptionsSchema],
|
|
@@ -6441,7 +6572,7 @@ var schemasSingleUse = defineRule59({
|
|
|
6441
6572
|
});
|
|
6442
6573
|
|
|
6443
6574
|
// src/rules/tests/tests-assertions.ts
|
|
6444
|
-
import { defineRule as
|
|
6575
|
+
import { defineRule as defineRule61 } from "@oxlint/plugins";
|
|
6445
6576
|
var testsAssertionsModifiers = new Set(["for", "each", "concurrent", "sequential", "only", "skip"]);
|
|
6446
6577
|
var testsAssertionsFunctions = [
|
|
6447
6578
|
"expect",
|
|
@@ -6631,7 +6762,7 @@ function isAssertedTest(registration, sourceCode, state) {
|
|
|
6631
6762
|
}
|
|
6632
6763
|
return rows.length > 0 && rows.every((row) => hasAssertion(callback, row.bindings, new Set, state));
|
|
6633
6764
|
}
|
|
6634
|
-
var testsAssertions =
|
|
6765
|
+
var testsAssertions = defineRule61({
|
|
6635
6766
|
meta: {
|
|
6636
6767
|
type: "problem",
|
|
6637
6768
|
schema: [
|
|
@@ -6757,17 +6888,36 @@ var testsAssertions = defineRule60({
|
|
|
6757
6888
|
});
|
|
6758
6889
|
|
|
6759
6890
|
// src/rules/tests/tests-concurrent-db.ts
|
|
6760
|
-
import { defineRule as
|
|
6761
|
-
var testsConcurrentDb =
|
|
6891
|
+
import { defineRule as defineRule62 } from "@oxlint/plugins";
|
|
6892
|
+
var testsConcurrentDb = defineRule62({
|
|
6762
6893
|
meta: {
|
|
6763
6894
|
type: "problem",
|
|
6764
|
-
schema: [
|
|
6895
|
+
schema: [
|
|
6896
|
+
{
|
|
6897
|
+
type: "object",
|
|
6898
|
+
additionalProperties: false,
|
|
6899
|
+
properties: {
|
|
6900
|
+
message: { type: "string" },
|
|
6901
|
+
fixtures: { type: "array", items: { type: "string", minLength: 1 }, default: ["db"] },
|
|
6902
|
+
callees: { type: "array", items: { type: "string", minLength: 1 }, default: ["test.concurrent"] }
|
|
6903
|
+
}
|
|
6904
|
+
}
|
|
6905
|
+
],
|
|
6765
6906
|
messages: { forbidden: "{{message}}" }
|
|
6766
6907
|
},
|
|
6767
6908
|
createOnce(context) {
|
|
6909
|
+
let message = "";
|
|
6910
|
+
let fixtures = new Set;
|
|
6911
|
+
let callees = new Set;
|
|
6768
6912
|
return {
|
|
6913
|
+
before() {
|
|
6914
|
+
const options = optionsFirst(context, {});
|
|
6915
|
+
message = options.message ?? "Obtain an isolated database fixture for concurrent tests.";
|
|
6916
|
+
fixtures = new Set(options.fixtures ?? ["db"]);
|
|
6917
|
+
callees = new Set(options.callees ?? ["test.concurrent"]);
|
|
6918
|
+
},
|
|
6769
6919
|
CallExpression(node) {
|
|
6770
|
-
const callback = astDottedName(node.callee)
|
|
6920
|
+
const callback = callees.has(astDottedName(node.callee) ?? "") ? node.arguments.findLast(declarationsIsFunctionValue) : undefined;
|
|
6771
6921
|
const parameter = callback?.params.at(0);
|
|
6772
6922
|
const patterns = parameter?.type === "ObjectPattern" ? [parameter] : [];
|
|
6773
6923
|
if (callback && parameter?.type === "Identifier") {
|
|
@@ -6780,8 +6930,8 @@ var testsConcurrentDb = defineRule61({
|
|
|
6780
6930
|
}
|
|
6781
6931
|
}
|
|
6782
6932
|
for (const property of patterns.flatMap((pattern) => pattern.properties)) {
|
|
6783
|
-
|
|
6784
|
-
|
|
6933
|
+
const key = property.type === "Property" && !property.computed ? property.key : undefined;
|
|
6934
|
+
if (fixtures.has((key?.type === "Identifier" ? key.name : key && astStaticString(key)) ?? "")) {
|
|
6785
6935
|
context.report({
|
|
6786
6936
|
node: property,
|
|
6787
6937
|
messageId: "forbidden",
|
|
@@ -6795,10 +6945,10 @@ var testsConcurrentDb = defineRule61({
|
|
|
6795
6945
|
});
|
|
6796
6946
|
|
|
6797
6947
|
// src/rules/tests/tests-modifiers.ts
|
|
6798
|
-
import { defineRule as
|
|
6948
|
+
import { defineRule as defineRule63 } from "@oxlint/plugins";
|
|
6799
6949
|
var testsModifiersNames = ["test", "it", "describe", "suite"];
|
|
6800
6950
|
var testsModifiersPackages = new Set(["vitest", "bun:test", "@playwright/test", "@jest/globals"]);
|
|
6801
|
-
var testsModifiersBanned =
|
|
6951
|
+
var testsModifiersBanned = ["only", "skip", "todo"];
|
|
6802
6952
|
var testsModifiersBuilders = new Set(["if", "runIf", "skipIf"]);
|
|
6803
6953
|
function modifierName(node) {
|
|
6804
6954
|
if (node.type === "Identifier") {
|
|
@@ -6814,14 +6964,17 @@ function modifierName(node) {
|
|
|
6814
6964
|
const property = astMemberName(node);
|
|
6815
6965
|
return object && property ? `${object}.${property}` : undefined;
|
|
6816
6966
|
}
|
|
6817
|
-
var testsModifiers =
|
|
6967
|
+
var testsModifiers = defineRule63({
|
|
6818
6968
|
meta: {
|
|
6819
6969
|
type: "problem",
|
|
6820
6970
|
schema: [
|
|
6821
6971
|
{
|
|
6822
6972
|
type: "object",
|
|
6823
6973
|
additionalProperties: false,
|
|
6824
|
-
properties: {
|
|
6974
|
+
properties: {
|
|
6975
|
+
functions: { type: "array", items: { type: "string" } },
|
|
6976
|
+
modifiers: { type: "array", items: { type: "string", minLength: 1 }, default: testsModifiersBanned }
|
|
6977
|
+
}
|
|
6825
6978
|
}
|
|
6826
6979
|
],
|
|
6827
6980
|
messages: {
|
|
@@ -6830,12 +6983,12 @@ var testsModifiers = defineRule62({
|
|
|
6830
6983
|
},
|
|
6831
6984
|
createOnce(context) {
|
|
6832
6985
|
let names = new Set;
|
|
6986
|
+
let banned = new Set;
|
|
6833
6987
|
return {
|
|
6834
6988
|
before() {
|
|
6835
|
-
|
|
6836
|
-
|
|
6837
|
-
|
|
6838
|
-
]);
|
|
6989
|
+
const options = optionsFirst(context, {});
|
|
6990
|
+
names = new Set([...testsModifiersNames, ...options.functions ?? []]);
|
|
6991
|
+
banned = new Set(options.modifiers ?? testsModifiersBanned);
|
|
6839
6992
|
},
|
|
6840
6993
|
ImportDeclaration(node) {
|
|
6841
6994
|
if (!testsModifiersPackages.has(node.source.value)) {
|
|
@@ -6853,7 +7006,7 @@ var testsModifiers = defineRule62({
|
|
|
6853
7006
|
},
|
|
6854
7007
|
MemberExpression(node) {
|
|
6855
7008
|
const name = modifierName(node);
|
|
6856
|
-
if (!name || !
|
|
7009
|
+
if (!name || !banned.has(name.split(".").at(-1) ?? "")) {
|
|
6857
7010
|
return;
|
|
6858
7011
|
}
|
|
6859
7012
|
if ([...names].some((test) => name.startsWith(`${test}.`))) {
|
|
@@ -6865,9 +7018,9 @@ var testsModifiers = defineRule62({
|
|
|
6865
7018
|
});
|
|
6866
7019
|
|
|
6867
7020
|
// src/rules/tests/tests-titles.ts
|
|
6868
|
-
import { defineRule as
|
|
6869
|
-
var testsTitlesModifiers =
|
|
6870
|
-
var testsTitles =
|
|
7021
|
+
import { defineRule as defineRule64 } from "@oxlint/plugins";
|
|
7022
|
+
var testsTitlesModifiers = ["only", "skip", "concurrent", "sequential", "todo", "each", "for"];
|
|
7023
|
+
var testsTitles = defineRule64({
|
|
6871
7024
|
meta: {
|
|
6872
7025
|
type: "suggestion",
|
|
6873
7026
|
schema: [
|
|
@@ -6876,6 +7029,7 @@ var testsTitles = defineRule63({
|
|
|
6876
7029
|
additionalProperties: false,
|
|
6877
7030
|
properties: {
|
|
6878
7031
|
callees: { type: "array", items: { type: "string" } },
|
|
7032
|
+
modifiers: { type: "array", items: { type: "string", minLength: 1 }, default: testsTitlesModifiers },
|
|
6879
7033
|
deny: optionsPatternSchema,
|
|
6880
7034
|
require: optionsPatternSchema,
|
|
6881
7035
|
flags: { type: "string", pattern: "^[dgimsuvy]*$" }
|
|
@@ -6895,6 +7049,7 @@ var testsTitles = defineRule63({
|
|
|
6895
7049
|
},
|
|
6896
7050
|
createOnce(context) {
|
|
6897
7051
|
let callees = [];
|
|
7052
|
+
let modifiers = new Set;
|
|
6898
7053
|
let forbid = [];
|
|
6899
7054
|
let required = [];
|
|
6900
7055
|
let requiredLabel = "";
|
|
@@ -6903,6 +7058,7 @@ var testsTitles = defineRule63({
|
|
|
6903
7058
|
const options = optionsFirst(context);
|
|
6904
7059
|
const flags = options.flags ?? "";
|
|
6905
7060
|
callees = options.callees;
|
|
7061
|
+
modifiers = new Set(options.modifiers ?? testsTitlesModifiers);
|
|
6906
7062
|
forbid = options.deny === undefined ? [] : [options.deny].flat().map((source) => ({ regex: new RegExp(source, flags), pattern: source }));
|
|
6907
7063
|
required = optionsPatternsWithEmpty(options.require, flags);
|
|
6908
7064
|
requiredLabel = optionsPatternLabel(options.require);
|
|
@@ -6913,7 +7069,7 @@ var testsTitles = defineRule63({
|
|
|
6913
7069
|
CallExpression(node) {
|
|
6914
7070
|
const title = node.arguments.at(0);
|
|
6915
7071
|
const callee = node.callee;
|
|
6916
|
-
const configured = astMatchesCallee(astDottedName(callee), callees,
|
|
7072
|
+
const configured = astMatchesCallee(astDottedName(callee), callees, modifiers) || callee.type === "CallExpression" && astMatchesCallee(astDottedName(callee.callee), callees, modifiers) || callee.type === "TaggedTemplateExpression" && astMatchesCallee(astDottedName(callee.tag), callees, modifiers);
|
|
6917
7073
|
if (!title || !configured) {
|
|
6918
7074
|
return;
|
|
6919
7075
|
}
|
|
@@ -6942,11 +7098,11 @@ var testsTitles = defineRule63({
|
|
|
6942
7098
|
});
|
|
6943
7099
|
|
|
6944
7100
|
// src/rules/types/types-declarations.ts
|
|
6945
|
-
import { defineRule as
|
|
7101
|
+
import { defineRule as defineRule65 } from "@oxlint/plugins";
|
|
6946
7102
|
function isValuePattern(source) {
|
|
6947
7103
|
return /^\^?=/.test(source);
|
|
6948
7104
|
}
|
|
6949
|
-
var typesDeclarations =
|
|
7105
|
+
var typesDeclarations = defineRule65({
|
|
6950
7106
|
meta: {
|
|
6951
7107
|
type: "problem",
|
|
6952
7108
|
schema: [
|
|
@@ -6989,7 +7145,7 @@ var typesDeclarations = defineRule64({
|
|
|
6989
7145
|
});
|
|
6990
7146
|
|
|
6991
7147
|
// src/rules/types/types-imported-alias.ts
|
|
6992
|
-
import { defineRule as
|
|
7148
|
+
import { defineRule as defineRule66 } from "@oxlint/plugins";
|
|
6993
7149
|
function importedAliasTarget(declaration, imports) {
|
|
6994
7150
|
if (declaration?.type !== "TSTypeAliasDeclaration") {
|
|
6995
7151
|
return;
|
|
@@ -7001,7 +7157,7 @@ function importedAliasTarget(declaration, imports) {
|
|
|
7001
7157
|
const { name } = type.typeName;
|
|
7002
7158
|
return imports.has(name) && !declaration.typeParameters?.params.some((parameter) => parameter.name.name === name) ? name : undefined;
|
|
7003
7159
|
}
|
|
7004
|
-
var typesImportedAlias =
|
|
7160
|
+
var typesImportedAlias = defineRule66({
|
|
7005
7161
|
meta: {
|
|
7006
7162
|
type: "problem",
|
|
7007
7163
|
schema: [],
|
|
@@ -7063,7 +7219,7 @@ var typesImportedAlias = defineRule65({
|
|
|
7063
7219
|
});
|
|
7064
7220
|
|
|
7065
7221
|
// src/rules/types/types-inline.ts
|
|
7066
|
-
import { defineRule as
|
|
7222
|
+
import { defineRule as defineRule67 } from "@oxlint/plugins";
|
|
7067
7223
|
function parameterAnnotation(parameter) {
|
|
7068
7224
|
if (parameter.type === "TSParameterProperty") {
|
|
7069
7225
|
return parameterAnnotation(parameter.parameter);
|
|
@@ -7073,7 +7229,7 @@ function parameterAnnotation(parameter) {
|
|
|
7073
7229
|
}
|
|
7074
7230
|
return parameter.typeAnnotation;
|
|
7075
7231
|
}
|
|
7076
|
-
var typesInline =
|
|
7232
|
+
var typesInline = defineRule67({
|
|
7077
7233
|
meta: {
|
|
7078
7234
|
type: "problem",
|
|
7079
7235
|
schema: [
|
|
@@ -7149,8 +7305,8 @@ var typesInline = defineRule66({
|
|
|
7149
7305
|
var typesLocalAlias = astSelectorRule("TSTypeAliasDeclaration", "Local component/hook contracts use interfaces named for their owner. Derived or reusable aliases belong in domain types; do not substitute an empty interface.");
|
|
7150
7306
|
|
|
7151
7307
|
// src/rules/types/types-namespace-import.ts
|
|
7152
|
-
import { defineRule as
|
|
7153
|
-
var typesNamespaceImport =
|
|
7308
|
+
import { defineRule as defineRule68 } from "@oxlint/plugins";
|
|
7309
|
+
var typesNamespaceImport = defineRule68({
|
|
7154
7310
|
meta: {
|
|
7155
7311
|
type: "suggestion",
|
|
7156
7312
|
schema: [
|
|
@@ -7192,26 +7348,50 @@ var typesNamespaceImport = defineRule67({
|
|
|
7192
7348
|
});
|
|
7193
7349
|
|
|
7194
7350
|
// src/rules/types/types-service.ts
|
|
7195
|
-
import { defineRule as
|
|
7196
|
-
var typesService =
|
|
7351
|
+
import { defineRule as defineRule69 } from "@oxlint/plugins";
|
|
7352
|
+
var typesService = defineRule69({
|
|
7197
7353
|
meta: {
|
|
7198
7354
|
type: "problem",
|
|
7199
|
-
schema: [
|
|
7355
|
+
schema: [
|
|
7356
|
+
{
|
|
7357
|
+
type: "object",
|
|
7358
|
+
additionalProperties: false,
|
|
7359
|
+
properties: {
|
|
7360
|
+
suffix: { type: "string", minLength: 1, default: "Service" },
|
|
7361
|
+
factory: { type: "string", minLength: 1, default: "make" }
|
|
7362
|
+
}
|
|
7363
|
+
}
|
|
7364
|
+
],
|
|
7200
7365
|
messages: {
|
|
7201
|
-
domain: "Move this type to its domain types file; only the matching factory-derived
|
|
7366
|
+
domain: "Move this type to its domain types file; only the matching factory-derived {{suffix}} alias belongs here."
|
|
7202
7367
|
}
|
|
7203
7368
|
},
|
|
7204
7369
|
createOnce(context) {
|
|
7370
|
+
let suffix = "Service";
|
|
7371
|
+
let factory = "make";
|
|
7205
7372
|
return {
|
|
7373
|
+
before() {
|
|
7374
|
+
const options = optionsFirst(context, {});
|
|
7375
|
+
suffix = options.suffix ?? "Service";
|
|
7376
|
+
factory = options.factory ?? "make";
|
|
7377
|
+
},
|
|
7206
7378
|
TSInterfaceDeclaration(node) {
|
|
7207
|
-
context.report({
|
|
7379
|
+
context.report({
|
|
7380
|
+
node,
|
|
7381
|
+
messageId: "domain",
|
|
7382
|
+
data: { suffix }
|
|
7383
|
+
});
|
|
7208
7384
|
},
|
|
7209
7385
|
TSTypeAliasDeclaration(node) {
|
|
7210
7386
|
const type = node.typeAnnotation;
|
|
7211
7387
|
const argument = type.type === "TSTypeReference" && type.typeArguments?.params.length === 1 ? type.typeArguments.params[0] : undefined;
|
|
7212
|
-
const isFactoryService = node.id.name.endsWith(
|
|
7388
|
+
const isFactoryService = node.id.name.endsWith(suffix) && type.type === "TSTypeReference" && type.typeName.type === "Identifier" && type.typeName.name === "ReturnType" && argument?.type === "TSTypeQuery" && argument.exprName.type === "Identifier" && argument.exprName.name === `${factory}${node.id.name}`;
|
|
7213
7389
|
if (!isFactoryService) {
|
|
7214
|
-
context.report({
|
|
7390
|
+
context.report({
|
|
7391
|
+
node,
|
|
7392
|
+
messageId: "domain",
|
|
7393
|
+
data: { suffix }
|
|
7394
|
+
});
|
|
7215
7395
|
}
|
|
7216
7396
|
}
|
|
7217
7397
|
};
|
|
@@ -7219,12 +7399,12 @@ var typesService = defineRule68({
|
|
|
7219
7399
|
});
|
|
7220
7400
|
|
|
7221
7401
|
// src/rules/types/types-unknown.ts
|
|
7222
|
-
import { defineRule as
|
|
7402
|
+
import { defineRule as defineRule70 } from "@oxlint/plugins";
|
|
7223
7403
|
function isCatchName(node) {
|
|
7224
7404
|
const key = "key" in node && !(("computed" in node) && node.computed) ? node.key : undefined;
|
|
7225
7405
|
return key?.type === "Identifier" && key.name === "catch";
|
|
7226
7406
|
}
|
|
7227
|
-
var typesUnknown =
|
|
7407
|
+
var typesUnknown = defineRule70({
|
|
7228
7408
|
meta: { type: "problem", schema: [], messages: { forbidden: "Use an owned domain type rather than unknown." } },
|
|
7229
7409
|
createOnce(context) {
|
|
7230
7410
|
return {
|