@sarj/eslint-plugin 17.1.2 → 17.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +58 -48
- package/dist/index.js +58 -48
- package/dist/rule-examples.cjs +1 -1
- package/dist/rule-examples.js +1 -1
- package/package.json +3 -1
package/dist/index.cjs
CHANGED
|
@@ -1076,13 +1076,13 @@ var no_test_comments_default = createRule({
|
|
|
1076
1076
|
name: "no-test-comments",
|
|
1077
1077
|
documentation: NO_TEST_COMMENTS_DOCUMENTATION,
|
|
1078
1078
|
meta: {
|
|
1079
|
+
defaultOptions: [{}],
|
|
1079
1080
|
type: "suggestion",
|
|
1080
1081
|
fixable: "code",
|
|
1081
1082
|
docs: { description: NO_TEST_COMMENTS_DOCUMENTATION.summary },
|
|
1082
|
-
schema: [{ type: "object", properties: { allFiles: { type: "boolean" } }, additionalProperties: false }],
|
|
1083
|
+
schema: [{ type: "object", properties: { allFiles: { description: "Check every eligible test file without requiring frontend framework ownership.", type: "boolean" } }, additionalProperties: false }],
|
|
1083
1084
|
messages: { testComment: "Express this explanation in the test name, fixture or assertion, then remove the comment." }
|
|
1084
1085
|
},
|
|
1085
|
-
defaultOptions: [{}],
|
|
1086
1086
|
create(context, [options]) {
|
|
1087
1087
|
if (!isTestFile(context) || isGeneratedFile(context, context.sourceCode.text)) return {};
|
|
1088
1088
|
if (!ownsTestComments(context)) return {};
|
|
@@ -1171,13 +1171,13 @@ var no_frontend_comments_default = createRule({
|
|
|
1171
1171
|
name: "no-frontend-comments",
|
|
1172
1172
|
documentation: NO_FRONTEND_COMMENTS_DOCUMENTATION,
|
|
1173
1173
|
meta: {
|
|
1174
|
+
defaultOptions: [{}],
|
|
1174
1175
|
type: "suggestion",
|
|
1175
1176
|
fixable: "code",
|
|
1176
1177
|
docs: { description: NO_FRONTEND_COMMENTS_DOCUMENTATION.summary },
|
|
1177
|
-
schema: [{ type: "object", properties: { allFiles: { type: "boolean" } }, additionalProperties: false }],
|
|
1178
|
+
schema: [{ type: "object", properties: { allFiles: { description: "Check comments without requiring frontend framework ownership.", type: "boolean" } }, additionalProperties: false }],
|
|
1178
1179
|
messages: { noFrontendComments: "Frontend comments are prohibited; express the behavior in names, types or code and review any directive or legal contract before removing it." }
|
|
1179
1180
|
},
|
|
1180
|
-
defaultOptions: [{}],
|
|
1181
1181
|
create(context, [options]) {
|
|
1182
1182
|
if (isGeneratedFile(context, context.sourceCode.text) || ownsTestComments(context)) return {};
|
|
1183
1183
|
const jsxRanges = [];
|
|
@@ -4832,7 +4832,7 @@ function isSearchParamReceiver(call, services) {
|
|
|
4832
4832
|
// package.json
|
|
4833
4833
|
var package_default = {
|
|
4834
4834
|
name: "@sarj/eslint-plugin",
|
|
4835
|
-
version: "17.1.
|
|
4835
|
+
version: "17.1.3",
|
|
4836
4836
|
packageManager: "npm@12.2.1",
|
|
4837
4837
|
description: "Custom ESLint rules for hypermodern TypeScript / React / Next.js projects",
|
|
4838
4838
|
type: "module",
|
|
@@ -4906,6 +4906,7 @@ var package_default = {
|
|
|
4906
4906
|
"@vitest/eslint-plugin": "1.6.28",
|
|
4907
4907
|
eslint: "10.13.0",
|
|
4908
4908
|
"eslint-node-test": "1.0.1",
|
|
4909
|
+
"eslint-plugin-eslint-plugin": "7.6.2",
|
|
4909
4910
|
"eslint-plugin-better-tailwindcss": "^4.10.0",
|
|
4910
4911
|
"eslint-plugin-jest": "29.17.0",
|
|
4911
4912
|
"eslint-plugin-jsdoc": "65.4.2",
|
|
@@ -4926,6 +4927,7 @@ var package_default = {
|
|
|
4926
4927
|
jiti: "2.7.0",
|
|
4927
4928
|
prettier: "3.9.10",
|
|
4928
4929
|
tsup: "9.0.0",
|
|
4930
|
+
syncpack: "15.3.3",
|
|
4929
4931
|
typescript: "npm:@typescript/typescript6@6.0.2",
|
|
4930
4932
|
"typescript-eslint": "^8.72.0",
|
|
4931
4933
|
uuid: "13.0.0",
|
|
@@ -9170,6 +9172,7 @@ var require_button_accessible_name_default = createRule({
|
|
|
9170
9172
|
name: "require-button-accessible-name",
|
|
9171
9173
|
documentation: REQUIRE_BUTTON_ACCESSIBLE_NAME_DOCUMENTATION,
|
|
9172
9174
|
meta: {
|
|
9175
|
+
defaultOptions: [{}],
|
|
9173
9176
|
type: "problem",
|
|
9174
9177
|
docs: { description: REQUIRE_BUTTON_ACCESSIBLE_NAME_DOCUMENTATION.summary },
|
|
9175
9178
|
schema: [
|
|
@@ -9178,6 +9181,7 @@ var require_button_accessible_name_default = createRule({
|
|
|
9178
9181
|
properties: {
|
|
9179
9182
|
components: COMPONENT_IMPORT_SCHEMA,
|
|
9180
9183
|
iconModules: {
|
|
9184
|
+
description: "Module names whose imported components count as icons.",
|
|
9181
9185
|
type: "array",
|
|
9182
9186
|
items: { type: "string", minLength: 1 },
|
|
9183
9187
|
uniqueItems: true
|
|
@@ -9190,7 +9194,6 @@ var require_button_accessible_name_default = createRule({
|
|
|
9190
9194
|
missingName: "This button has no statically identifiable accessible name. Add action text, aria-label, or aria-labelledby."
|
|
9191
9195
|
}
|
|
9192
9196
|
},
|
|
9193
|
-
defaultOptions: [{}],
|
|
9194
9197
|
create(context, [options]) {
|
|
9195
9198
|
if (isGeneratedFile(context, context.sourceCode.text) || isTestFile(context) || isStoryFile(context))
|
|
9196
9199
|
return {};
|
|
@@ -9509,6 +9512,7 @@ var prefer_logical_tailwind_utilities_default = createRule({
|
|
|
9509
9512
|
name: "prefer-logical-tailwind-utilities",
|
|
9510
9513
|
documentation: PREFER_LOGICAL_TAILWIND_UTILITIES_DOCUMENTATION,
|
|
9511
9514
|
meta: {
|
|
9515
|
+
defaultOptions: [{ enabled: true, checkInsets: false, allowUtilities: [] }],
|
|
9512
9516
|
type: "suggestion",
|
|
9513
9517
|
docs: {
|
|
9514
9518
|
description: PREFER_LOGICAL_TAILWIND_UTILITIES_DOCUMENTATION.summary
|
|
@@ -9517,9 +9521,10 @@ var prefer_logical_tailwind_utilities_default = createRule({
|
|
|
9517
9521
|
{
|
|
9518
9522
|
type: "object",
|
|
9519
9523
|
properties: {
|
|
9520
|
-
enabled: { type: "boolean" },
|
|
9521
|
-
checkInsets: { type: "boolean" },
|
|
9524
|
+
enabled: { description: "Enable replacement of physical direction utilities with logical equivalents.", type: "boolean" },
|
|
9525
|
+
checkInsets: { description: "Include physical inset utilities in direction checks.", type: "boolean" },
|
|
9522
9526
|
allowUtilities: {
|
|
9527
|
+
description: "Physical utility names allowed without a logical replacement.",
|
|
9523
9528
|
type: "array",
|
|
9524
9529
|
items: { type: "string" },
|
|
9525
9530
|
uniqueItems: true
|
|
@@ -9532,7 +9537,6 @@ var prefer_logical_tailwind_utilities_default = createRule({
|
|
|
9532
9537
|
physicalUtility: "Use '{{replacement}}' instead of '{{utility}}' in this bidirectional UI, or explicitly allow intentional physical placement."
|
|
9533
9538
|
}
|
|
9534
9539
|
},
|
|
9535
|
-
defaultOptions: [{ enabled: true, checkInsets: false, allowUtilities: [] }],
|
|
9536
9540
|
create(context, [options]) {
|
|
9537
9541
|
if (options?.enabled === false || isGeneratedFile(context, context.sourceCode.text) || isTestFile(context) || isStoryFile(context))
|
|
9538
9542
|
return {};
|
|
@@ -9660,6 +9664,7 @@ var no_unlocalized_toast_default = createRule({
|
|
|
9660
9664
|
name: "no-unlocalized-toast",
|
|
9661
9665
|
documentation: NO_UNLOCALIZED_TOAST_DOCUMENTATION,
|
|
9662
9666
|
meta: {
|
|
9667
|
+
defaultOptions: [{ enabled: true }],
|
|
9663
9668
|
type: "suggestion",
|
|
9664
9669
|
docs: { description: NO_UNLOCALIZED_TOAST_DOCUMENTATION.summary },
|
|
9665
9670
|
schema: [
|
|
@@ -9669,6 +9674,7 @@ var no_unlocalized_toast_default = createRule({
|
|
|
9669
9674
|
...LOCALIZATION_PROPERTIES,
|
|
9670
9675
|
functions: COMPONENT_IMPORT_SCHEMA,
|
|
9671
9676
|
methods: {
|
|
9677
|
+
description: "Toast method names whose user-visible messages require localization.",
|
|
9672
9678
|
type: "array",
|
|
9673
9679
|
items: { type: "string", minLength: 1 },
|
|
9674
9680
|
uniqueItems: true
|
|
@@ -9681,7 +9687,6 @@ var no_unlocalized_toast_default = createRule({
|
|
|
9681
9687
|
unlocalized: "Translate this user-facing literal or add an explicit localization exception."
|
|
9682
9688
|
}
|
|
9683
9689
|
},
|
|
9684
|
-
defaultOptions: [{ enabled: true }],
|
|
9685
9690
|
create(context, [options]) {
|
|
9686
9691
|
if (localizationExcluded(context, context.sourceCode.text, options))
|
|
9687
9692
|
return {};
|
|
@@ -9773,6 +9778,7 @@ var no_unlocalized_jsx_attributes_default = createRule({
|
|
|
9773
9778
|
name: "no-unlocalized-jsx-attributes",
|
|
9774
9779
|
documentation: NO_UNLOCALIZED_JSX_ATTRIBUTES_DOCUMENTATION,
|
|
9775
9780
|
meta: {
|
|
9781
|
+
defaultOptions: [{ enabled: true }],
|
|
9776
9782
|
type: "suggestion",
|
|
9777
9783
|
docs: { description: NO_UNLOCALIZED_JSX_ATTRIBUTES_DOCUMENTATION.summary },
|
|
9778
9784
|
schema: [
|
|
@@ -9781,6 +9787,7 @@ var no_unlocalized_jsx_attributes_default = createRule({
|
|
|
9781
9787
|
properties: {
|
|
9782
9788
|
...LOCALIZATION_PROPERTIES,
|
|
9783
9789
|
attributes: {
|
|
9790
|
+
description: "JSX attributes whose user-visible text requires localization.",
|
|
9784
9791
|
type: "array",
|
|
9785
9792
|
items: { type: "string", minLength: 1 },
|
|
9786
9793
|
uniqueItems: true
|
|
@@ -9793,7 +9800,6 @@ var no_unlocalized_jsx_attributes_default = createRule({
|
|
|
9793
9800
|
unlocalized: "Translate this user-facing literal or add an explicit localization exception."
|
|
9794
9801
|
}
|
|
9795
9802
|
},
|
|
9796
|
-
defaultOptions: [{ enabled: true }],
|
|
9797
9803
|
create(context, [options]) {
|
|
9798
9804
|
if (localizationExcluded(context, context.sourceCode.text, options))
|
|
9799
9805
|
return {};
|
|
@@ -9858,6 +9864,7 @@ var no_unlocalized_jsx_text_default = createRule({
|
|
|
9858
9864
|
name: "no-unlocalized-jsx-text",
|
|
9859
9865
|
documentation: NO_UNLOCALIZED_JSX_TEXT_DOCUMENTATION,
|
|
9860
9866
|
meta: {
|
|
9867
|
+
defaultOptions: [{ enabled: true }],
|
|
9861
9868
|
type: "suggestion",
|
|
9862
9869
|
docs: { description: NO_UNLOCALIZED_JSX_TEXT_DOCUMENTATION.summary },
|
|
9863
9870
|
schema: [
|
|
@@ -9871,7 +9878,6 @@ var no_unlocalized_jsx_text_default = createRule({
|
|
|
9871
9878
|
unlocalized: "Translate this user-facing literal or add an explicit localization exception."
|
|
9872
9879
|
}
|
|
9873
9880
|
},
|
|
9874
|
-
defaultOptions: [{ enabled: true }],
|
|
9875
9881
|
create(context, [options]) {
|
|
9876
9882
|
if (localizationExcluded(context, context.sourceCode.text, options))
|
|
9877
9883
|
return {};
|
|
@@ -12655,6 +12661,7 @@ var no_dynamic_sql_default = createRule({
|
|
|
12655
12661
|
name: "no-dynamic-sql",
|
|
12656
12662
|
documentation: NO_DYNAMIC_SQL_DOCUMENTATION,
|
|
12657
12663
|
meta: {
|
|
12664
|
+
defaultOptions: [{}],
|
|
12658
12665
|
type: "problem",
|
|
12659
12666
|
docs: {
|
|
12660
12667
|
description: NO_DYNAMIC_SQL_DOCUMENTATION.summary
|
|
@@ -12677,7 +12684,6 @@ var no_dynamic_sql_default = createRule({
|
|
|
12677
12684
|
dynamicFragment: "Runtime fragment interpolated into SQL passed to `{{method}}()`. Bind data values; select non-bindable SQL fragments from fixed, reviewed alternatives."
|
|
12678
12685
|
}
|
|
12679
12686
|
},
|
|
12680
|
-
defaultOptions: [{}],
|
|
12681
12687
|
create(context, [options]) {
|
|
12682
12688
|
const methods = new Set(options?.methods ?? DEFAULT_METHODS);
|
|
12683
12689
|
return {
|
|
@@ -12749,6 +12755,7 @@ var no_enum_default = createRule({
|
|
|
12749
12755
|
name: "no-enum",
|
|
12750
12756
|
documentation: NO_ENUM_DOCUMENTATION,
|
|
12751
12757
|
meta: {
|
|
12758
|
+
defaultOptions: [{}],
|
|
12752
12759
|
type: "suggestion",
|
|
12753
12760
|
fixable: "code",
|
|
12754
12761
|
docs: {
|
|
@@ -12771,7 +12778,6 @@ var no_enum_default = createRule({
|
|
|
12771
12778
|
noEnum: 'Enums are discouraged. Use a string-literal union (e.g. `type Status = "active" | "inactive"`) or an `as const` object instead.'
|
|
12772
12779
|
}
|
|
12773
12780
|
},
|
|
12774
|
-
defaultOptions: [{}],
|
|
12775
12781
|
create(context, [optionsArg]) {
|
|
12776
12782
|
const options = optionsArg ?? {};
|
|
12777
12783
|
const ignoreFiles = options.ignoreFiles ?? [];
|
|
@@ -13318,6 +13324,7 @@ var no_fat_try_blocks_default = createRule({
|
|
|
13318
13324
|
name: "no-fat-try-blocks",
|
|
13319
13325
|
documentation: NO_FAT_TRY_BLOCKS_DOCUMENTATION,
|
|
13320
13326
|
meta: {
|
|
13327
|
+
defaultOptions: [{ max: MAX_TRY_BODY_STATEMENTS }],
|
|
13321
13328
|
type: "problem",
|
|
13322
13329
|
docs: {
|
|
13323
13330
|
description: "Review try blocks exceeding the configured count of syntactically selected operations."
|
|
@@ -13326,7 +13333,7 @@ var no_fat_try_blocks_default = createRule({
|
|
|
13326
13333
|
{
|
|
13327
13334
|
type: "object",
|
|
13328
13335
|
properties: {
|
|
13329
|
-
max: { type: "integer", minimum: 1 }
|
|
13336
|
+
max: { description: "Maximum number of statements allowed in one try body.", type: "integer", minimum: 1 }
|
|
13330
13337
|
},
|
|
13331
13338
|
additionalProperties: false
|
|
13332
13339
|
}
|
|
@@ -13335,7 +13342,6 @@ var no_fat_try_blocks_default = createRule({
|
|
|
13335
13342
|
fatTryBlock: "This `try` block has {{count}} syntactically selected operations (max {{max}}). Review whether they share one recovery policy; move unrelated work outside the boundary."
|
|
13336
13343
|
}
|
|
13337
13344
|
},
|
|
13338
|
-
defaultOptions: [{ max: MAX_TRY_BODY_STATEMENTS }],
|
|
13339
13345
|
create(context, [options]) {
|
|
13340
13346
|
if (isGeneratedFile(context, context.sourceCode.text)) {
|
|
13341
13347
|
return {};
|
|
@@ -13486,6 +13492,7 @@ var no_hand_rolled_sleep_default = createRule({
|
|
|
13486
13492
|
name: "no-hand-rolled-sleep",
|
|
13487
13493
|
documentation: NO_HAND_ROLLED_SLEEP_DOCUMENTATION,
|
|
13488
13494
|
meta: {
|
|
13495
|
+
defaultOptions: [{}],
|
|
13489
13496
|
type: "problem",
|
|
13490
13497
|
docs: {
|
|
13491
13498
|
description: "Disallow uncancellable promisified timers and timeout arms."
|
|
@@ -13512,7 +13519,6 @@ var no_hand_rolled_sleep_default = createRule({
|
|
|
13512
13519
|
handRolledTimeoutRace: "Hand-rolled timeout arm: when the other promise wins, this timer is never cleared and keeps the event loop alive until it fires. Use `AbortSignal.timeout(ms)` and pass the signal to the operation."
|
|
13513
13520
|
}
|
|
13514
13521
|
},
|
|
13515
|
-
defaultOptions: [{}],
|
|
13516
13522
|
create(context, [optionsArg]) {
|
|
13517
13523
|
const { filename, sourceCode } = context;
|
|
13518
13524
|
if (isTestFile(context) || isScriptFile(context) || isGeneratedFile(context, sourceCode.getText())) {
|
|
@@ -15788,6 +15794,7 @@ var no_impossible_zod_literal_bounds_default = createRule({
|
|
|
15788
15794
|
name: "no-impossible-zod-literal-bounds",
|
|
15789
15795
|
documentation: NO_IMPOSSIBLE_ZOD_LITERAL_BOUNDS_DOCUMENTATION,
|
|
15790
15796
|
meta: {
|
|
15797
|
+
defaultOptions: [{}],
|
|
15791
15798
|
type: "problem",
|
|
15792
15799
|
docs: {
|
|
15793
15800
|
description: "Disallow same-chain literal Zod bounds whose accepted set is mathematically empty."
|
|
@@ -15808,7 +15815,6 @@ var no_impossible_zod_literal_bounds_default = createRule({
|
|
|
15808
15815
|
impossibleBounds: "This Zod {{kind}} schema accepts no values: {{lower}} conflicts with {{upper}}."
|
|
15809
15816
|
}
|
|
15810
15817
|
},
|
|
15811
|
-
defaultOptions: [{}],
|
|
15812
15818
|
create(context, [options]) {
|
|
15813
15819
|
const sourceCode = context.sourceCode;
|
|
15814
15820
|
if (isTestFile(context) || isGeneratedFile(context, sourceCode.getText())) {
|
|
@@ -16851,6 +16857,7 @@ var no_log_only_catch_default = createRule({
|
|
|
16851
16857
|
name: "no-log-only-catch",
|
|
16852
16858
|
documentation: NO_LOG_ONLY_CATCH_DOCUMENTATION,
|
|
16853
16859
|
meta: {
|
|
16860
|
+
defaultOptions: [{}],
|
|
16854
16861
|
type: "problem",
|
|
16855
16862
|
docs: {
|
|
16856
16863
|
description: "Disallow `catch` clauses that only log (or silently do nothing) and then swallow the error; rethrow or handle it instead."
|
|
@@ -16867,7 +16874,6 @@ var no_log_only_catch_default = createRule({
|
|
|
16867
16874
|
emptyCatch: "Empty catch silently swallows the error. Rethrow it, handle it, or add a comment explaining why it is safe to ignore."
|
|
16868
16875
|
}
|
|
16869
16876
|
},
|
|
16870
|
-
defaultOptions: [{}],
|
|
16871
16877
|
create(context, [loggingOptions]) {
|
|
16872
16878
|
const matcher = createLogMatcher(loggingOptions);
|
|
16873
16879
|
const filename = context.filename;
|
|
@@ -18652,6 +18658,7 @@ var no_raw_fetch_outside_clients_default = createRule({
|
|
|
18652
18658
|
name: "no-raw-fetch-outside-clients",
|
|
18653
18659
|
documentation: NO_RAW_FETCH_OUTSIDE_CLIENTS_DOCUMENTATION,
|
|
18654
18660
|
meta: {
|
|
18661
|
+
defaultOptions: [{}],
|
|
18655
18662
|
type: "problem",
|
|
18656
18663
|
docs: {
|
|
18657
18664
|
description: "Disallow calling the global `fetch` outside the client layer; route outbound HTTP through a client module that owns retry, timeout and status handling."
|
|
@@ -18666,6 +18673,7 @@ var no_raw_fetch_outside_clients_default = createRule({
|
|
|
18666
18673
|
description: "Regular-expression sources matched against the filename. Replaces the defaults."
|
|
18667
18674
|
},
|
|
18668
18675
|
basePath: {
|
|
18676
|
+
description: "Static application URL base path without query strings, fragments or parent segments.",
|
|
18669
18677
|
type: "string",
|
|
18670
18678
|
pattern: "^/(?!$)(?!.*[?#])(?!(?:.*/)?\\.\\.?(?:/|$))(?:[^/]+/)*[^/]+$"
|
|
18671
18679
|
}
|
|
@@ -18677,7 +18685,6 @@ var no_raw_fetch_outside_clients_default = createRule({
|
|
|
18677
18685
|
rawFetch: "Raw `fetch()` outside a client module. Route the call through a client (e.g. `clients/*-client.ts`) so it inherits retry, timeout and status handling and stays stubbable in tests."
|
|
18678
18686
|
}
|
|
18679
18687
|
},
|
|
18680
|
-
defaultOptions: [{}],
|
|
18681
18688
|
create(context, [options]) {
|
|
18682
18689
|
const filename = context.filename;
|
|
18683
18690
|
if (isTestFile(context) || isScriptFile(context) || NON_PRODUCTION_TREE_RE.test(filename)) {
|
|
@@ -18843,6 +18850,7 @@ var no_restricted_library_load_default = createRule({
|
|
|
18843
18850
|
name: "no-restricted-library-load",
|
|
18844
18851
|
documentation: NO_RESTRICTED_LIBRARY_LOAD_DOCUMENTATION,
|
|
18845
18852
|
meta: {
|
|
18853
|
+
defaultOptions: [{ libraries: [] }],
|
|
18846
18854
|
type: "problem",
|
|
18847
18855
|
docs: {
|
|
18848
18856
|
description: NO_RESTRICTED_LIBRARY_LOAD_DOCUMENTATION.summary
|
|
@@ -18854,6 +18862,7 @@ var no_restricted_library_load_default = createRule({
|
|
|
18854
18862
|
required: ["libraries"],
|
|
18855
18863
|
properties: {
|
|
18856
18864
|
libraries: {
|
|
18865
|
+
description: "Library import and module-load restrictions.",
|
|
18857
18866
|
type: "array",
|
|
18858
18867
|
items: {
|
|
18859
18868
|
type: "object",
|
|
@@ -18874,7 +18883,6 @@ var no_restricted_library_load_default = createRule({
|
|
|
18874
18883
|
restrictedLibraryLoad: "{{id}}: Replace this runtime dependency reference to {{module}} with {{replacement}}.{{note}}"
|
|
18875
18884
|
}
|
|
18876
18885
|
},
|
|
18877
|
-
defaultOptions: [{ libraries: [] }],
|
|
18878
18886
|
create(context, [options]) {
|
|
18879
18887
|
const restrictions = options.libraries;
|
|
18880
18888
|
function report2(node, source) {
|
|
@@ -19852,6 +19860,7 @@ var no_secret_in_log_default = createRule({
|
|
|
19852
19860
|
name: "no-secret-in-log",
|
|
19853
19861
|
documentation: NO_SECRET_IN_LOG_DOCUMENTATION,
|
|
19854
19862
|
meta: {
|
|
19863
|
+
defaultOptions: [{}],
|
|
19855
19864
|
type: "problem",
|
|
19856
19865
|
docs: {
|
|
19857
19866
|
description: "Disallow passing a secret-named value or a raw request/response blob to a logging call; both leak to log sinks. Redact or omit."
|
|
@@ -19868,7 +19877,6 @@ var no_secret_in_log_default = createRule({
|
|
|
19868
19877
|
noRawBodyInLog: "Raw `{{name}}` passed to a logging call. Request/response bodies can contain personal data or credentials. Log allowlisted non-sensitive context or use an approved redactor."
|
|
19869
19878
|
}
|
|
19870
19879
|
},
|
|
19871
|
-
defaultOptions: [{}],
|
|
19872
19880
|
create(context, [loggingOptions]) {
|
|
19873
19881
|
const matcher = createLogMatcher(loggingOptions);
|
|
19874
19882
|
const blobArmApplies = !isTestFile(context);
|
|
@@ -20899,6 +20907,7 @@ var no_sentinel_return_on_catch_default = createRule({
|
|
|
20899
20907
|
name: "no-sentinel-return-on-catch",
|
|
20900
20908
|
documentation: NO_SENTINEL_RETURN_ON_CATCH_DOCUMENTATION,
|
|
20901
20909
|
meta: {
|
|
20910
|
+
defaultOptions: [{}],
|
|
20902
20911
|
type: "problem",
|
|
20903
20912
|
docs: {
|
|
20904
20913
|
description: "Disallow swallowing a caught error by returning an empty sentinel unless the error is handled or the sentinel is part of the function contract."
|
|
@@ -20914,7 +20923,6 @@ var no_sentinel_return_on_catch_default = createRule({
|
|
|
20914
20923
|
noSentinelReturn: "This `catch` block swallows the error by returning an empty sentinel without logging it. Rethrow it, log/report it, or return a typed Result."
|
|
20915
20924
|
}
|
|
20916
20925
|
},
|
|
20917
|
-
defaultOptions: [{}],
|
|
20918
20926
|
create(context, [loggingOptions]) {
|
|
20919
20927
|
if (isGeneratedFile(context, context.sourceCode.text)) {
|
|
20920
20928
|
return {};
|
|
@@ -21461,6 +21469,7 @@ var no_storage_in_stateless_modules_default = createRule({
|
|
|
21461
21469
|
name: "no-storage-in-stateless-modules",
|
|
21462
21470
|
documentation: NO_STORAGE_IN_STATELESS_MODULES_DOCUMENTATION,
|
|
21463
21471
|
meta: {
|
|
21472
|
+
defaultOptions: [{}],
|
|
21464
21473
|
type: "problem",
|
|
21465
21474
|
docs: {
|
|
21466
21475
|
description: "Disallow SQL or key/value access inside configured stateless modules; derive state from a system of record instead."
|
|
@@ -21487,7 +21496,6 @@ var no_storage_in_stateless_modules_default = createRule({
|
|
|
21487
21496
|
storageInStatelessModule: "`{{method}}()` reaches for private storage inside a module declared stateless. Derive the state from a read against the system of record, or from a marker in the artefact this feature already produces."
|
|
21488
21497
|
}
|
|
21489
21498
|
},
|
|
21490
|
-
defaultOptions: [{}],
|
|
21491
21499
|
create(context, [options]) {
|
|
21492
21500
|
if (isTestFile(context)) {
|
|
21493
21501
|
return {};
|
|
@@ -23080,6 +23088,7 @@ var no_declaration_comment_wall_default = createRule({
|
|
|
23080
23088
|
name: "no-declaration-comment-wall",
|
|
23081
23089
|
documentation: NO_DECLARATION_COMMENT_WALL_DOCUMENTATION,
|
|
23082
23090
|
meta: {
|
|
23091
|
+
defaultOptions: [WALL_DEFAULTS],
|
|
23083
23092
|
type: "suggestion",
|
|
23084
23093
|
fixable: "code",
|
|
23085
23094
|
docs: {
|
|
@@ -23090,7 +23099,6 @@ var no_declaration_comment_wall_default = createRule({
|
|
|
23090
23099
|
commentWall: "{{restated}} of this declaration's {{commented}} member comments only re-spell member names \u2014 delete them; if a row still needs narration, give the member a clearer name. Keep constraints, lifecycle, and rationale."
|
|
23091
23100
|
}
|
|
23092
23101
|
},
|
|
23093
|
-
defaultOptions: [WALL_DEFAULTS],
|
|
23094
23102
|
create(context, [provided]) {
|
|
23095
23103
|
const options = { ...WALL_DEFAULTS, ...provided };
|
|
23096
23104
|
const sourceCode = context.sourceCode;
|
|
@@ -23442,6 +23450,7 @@ var no_type_member_comment_wall_default = createRule({
|
|
|
23442
23450
|
name: "no-type-member-comment-wall",
|
|
23443
23451
|
documentation: NO_TYPE_MEMBER_COMMENT_WALL_DOCUMENTATION,
|
|
23444
23452
|
meta: {
|
|
23453
|
+
defaultOptions: [WALL_DEFAULTS],
|
|
23445
23454
|
type: "suggestion",
|
|
23446
23455
|
fixable: "code",
|
|
23447
23456
|
docs: {
|
|
@@ -23452,7 +23461,6 @@ var no_type_member_comment_wall_default = createRule({
|
|
|
23452
23461
|
commentWall: "{{restated}} of this type's {{commented}} member comments appear to repeat names and types \u2014 review them for removal or clearer naming. Keep constraints and rationale."
|
|
23453
23462
|
}
|
|
23454
23463
|
},
|
|
23455
|
-
defaultOptions: [WALL_DEFAULTS],
|
|
23456
23464
|
create(context, [provided]) {
|
|
23457
23465
|
const options = { ...WALL_DEFAULTS, ...provided };
|
|
23458
23466
|
const sourceCode = context.sourceCode;
|
|
@@ -24011,12 +24019,12 @@ var no_first_party_module_mock_default = createRule({
|
|
|
24011
24019
|
name: "no-first-party-module-mock",
|
|
24012
24020
|
documentation: NO_FIRST_PARTY_MODULE_MOCK_DOCUMENTATION,
|
|
24013
24021
|
meta: {
|
|
24022
|
+
defaultOptions: [{ additionalModulePrefixes: [] }],
|
|
24014
24023
|
type: "problem",
|
|
24015
24024
|
docs: { description: NO_FIRST_PARTY_MODULE_MOCK_DOCUMENTATION.summary },
|
|
24016
|
-
schema: [{ type: "object", additionalProperties: false, properties: { additionalModulePrefixes: { type: "array", items: { type: "string", minLength: 1 }, uniqueItems: true } } }],
|
|
24025
|
+
schema: [{ type: "object", additionalProperties: false, properties: { additionalModulePrefixes: { description: "Additional maintained module prefixes that tests must not mock.", type: "array", items: { type: "string", minLength: 1 }, uniqueItems: true } } }],
|
|
24017
24026
|
messages: { noFirstPartyModuleMock: "This test replaces the maintained module `{{module}}`. Inject a narrow collaborator or test the real module; suppress locally only when module lookup or bootstrap behavior is the contract." }
|
|
24018
24027
|
},
|
|
24019
|
-
defaultOptions: [{ additionalModulePrefixes: [] }],
|
|
24020
24028
|
create(context, [options]) {
|
|
24021
24029
|
if (!isTestFile(context) || isGeneratedFile(context, context.sourceCode.text)) return {};
|
|
24022
24030
|
return {
|
|
@@ -26227,6 +26235,7 @@ var prefer_shadcn_primitives_default = createRule({
|
|
|
26227
26235
|
name: "prefer-shadcn-primitives",
|
|
26228
26236
|
documentation: PREFER_SHADCN_PRIMITIVES_DOCUMENTATION,
|
|
26229
26237
|
meta: {
|
|
26238
|
+
defaultOptions: [{}],
|
|
26230
26239
|
type: "suggestion",
|
|
26231
26240
|
docs: {
|
|
26232
26241
|
description: "Require visible raw JSX controls to use the corresponding shared shadcn primitive."
|
|
@@ -26235,8 +26244,8 @@ var prefer_shadcn_primitives_default = createRule({
|
|
|
26235
26244
|
{
|
|
26236
26245
|
type: "object",
|
|
26237
26246
|
properties: {
|
|
26238
|
-
assumeAvailable: { type: "boolean" },
|
|
26239
|
-
detectProjectPrimitives: { type: "boolean" }
|
|
26247
|
+
assumeAvailable: { description: "Assume supported shared UI primitives are available in this project.", type: "boolean" },
|
|
26248
|
+
detectProjectPrimitives: { description: "Resolve project-owned UI primitives before recommending replacements.", type: "boolean" }
|
|
26240
26249
|
},
|
|
26241
26250
|
additionalProperties: false
|
|
26242
26251
|
}
|
|
@@ -26245,7 +26254,6 @@ var prefer_shadcn_primitives_default = createRule({
|
|
|
26245
26254
|
preferShadcnPrimitive: "Use the shared {{ replacement }} shadcn primitive instead of raw <{{ element }}> markup."
|
|
26246
26255
|
}
|
|
26247
26256
|
},
|
|
26248
|
-
defaultOptions: [{}],
|
|
26249
26257
|
create(context, [options]) {
|
|
26250
26258
|
const filename = context.filename.replaceAll("\\", "/");
|
|
26251
26259
|
if (isTestFile(context) || isStoryFile(context) || isGeneratedFile(context, context.sourceCode.text) || SHARED_PRIMITIVE_IMPLEMENTATION_RE.test(filename)) {
|
|
@@ -26622,6 +26630,7 @@ var prefer_module_level_constant_default = createRule({
|
|
|
26622
26630
|
name: "prefer-module-level-constant",
|
|
26623
26631
|
documentation: PREFER_MODULE_LEVEL_CONSTANT_DOCUMENTATION,
|
|
26624
26632
|
meta: {
|
|
26633
|
+
defaultOptions: [{}],
|
|
26625
26634
|
type: "suggestion",
|
|
26626
26635
|
fixable: "code",
|
|
26627
26636
|
docs: {
|
|
@@ -26632,9 +26641,9 @@ var prefer_module_level_constant_default = createRule({
|
|
|
26632
26641
|
type: "object",
|
|
26633
26642
|
additionalProperties: false,
|
|
26634
26643
|
properties: {
|
|
26635
|
-
minElements: { type: "number", minimum: 1 },
|
|
26636
|
-
checkRegex: { type: "boolean" },
|
|
26637
|
-
ignoreTestFiles: { type: "boolean" }
|
|
26644
|
+
minElements: { description: "Minimum collection size before recommending a module-level constant.", type: "number", minimum: 1 },
|
|
26645
|
+
checkRegex: { description: "Include reusable regular expression literals in hoisting checks.", type: "boolean" },
|
|
26646
|
+
ignoreTestFiles: { description: "Skip test files when recommending module-level constants.", type: "boolean" }
|
|
26638
26647
|
}
|
|
26639
26648
|
}
|
|
26640
26649
|
],
|
|
@@ -26643,7 +26652,6 @@ var prefer_module_level_constant_default = createRule({
|
|
|
26643
26652
|
hoistRegex: "`{{name}}` is a constant regex recompiled on every call. Hoist it to module scope."
|
|
26644
26653
|
}
|
|
26645
26654
|
},
|
|
26646
|
-
defaultOptions: [{}],
|
|
26647
26655
|
create(context, [optionsArg]) {
|
|
26648
26656
|
const options = optionsArg ?? {};
|
|
26649
26657
|
const minElements = options.minElements ?? DEFAULT_MIN_ELEMENTS;
|
|
@@ -26952,6 +26960,7 @@ var prefer_module_level_schema_default = createRule({
|
|
|
26952
26960
|
name: "prefer-module-level-schema",
|
|
26953
26961
|
documentation: PREFER_MODULE_LEVEL_SCHEMA_DOCUMENTATION,
|
|
26954
26962
|
meta: {
|
|
26963
|
+
defaultOptions: [{}],
|
|
26955
26964
|
type: "problem",
|
|
26956
26965
|
docs: {
|
|
26957
26966
|
description: "Declare a Zod schema at module scope when it closes over nothing in the enclosing function"
|
|
@@ -26987,7 +26996,6 @@ var prefer_module_level_schema_default = createRule({
|
|
|
26987
26996
|
hoistSchema: "Move this `{{factory}}` schema to module scope. It uses nothing from `{{owner}}`, so it is rebuilt on every call for no benefit and cannot be exported, reused, or `z.infer`-ed from where it is."
|
|
26988
26997
|
}
|
|
26989
26998
|
},
|
|
26990
|
-
defaultOptions: [{}],
|
|
26991
26999
|
create(context, [options]) {
|
|
26992
27000
|
const factories = new Set(options?.factories ?? DEFAULT_FACTORIES);
|
|
26993
27001
|
const ignoreTestFiles = options?.ignoreTestFiles ?? true;
|
|
@@ -27640,6 +27648,7 @@ var prefer_multi_value_zod_literal_default = createRule({
|
|
|
27640
27648
|
name: "prefer-multi-value-zod-literal",
|
|
27641
27649
|
documentation: PREFER_MULTI_VALUE_ZOD_LITERAL_DOCUMENTATION,
|
|
27642
27650
|
meta: {
|
|
27651
|
+
defaultOptions: [{}],
|
|
27643
27652
|
type: "suggestion",
|
|
27644
27653
|
docs: {
|
|
27645
27654
|
description: "Use the Zod 4 multi-value literal API instead of a union of literal schemas."
|
|
@@ -27649,7 +27658,7 @@ var prefer_multi_value_zod_literal_default = createRule({
|
|
|
27649
27658
|
type: "object",
|
|
27650
27659
|
additionalProperties: false,
|
|
27651
27660
|
properties: {
|
|
27652
|
-
zodMajorVersion: { type: "integer", minimum: 4, maximum: 4 }
|
|
27661
|
+
zodMajorVersion: { description: "Installed Zod major version used to validate multi-value literal support.", type: "integer", minimum: 4, maximum: 4 }
|
|
27653
27662
|
}
|
|
27654
27663
|
}
|
|
27655
27664
|
],
|
|
@@ -27657,7 +27666,6 @@ var prefer_multi_value_zod_literal_default = createRule({
|
|
|
27657
27666
|
useMultiValueLiteral: "Replace this literal-schema union with {{zod}}.literal([\u2026])."
|
|
27658
27667
|
}
|
|
27659
27668
|
},
|
|
27660
|
-
defaultOptions: [{}],
|
|
27661
27669
|
create(context, [options]) {
|
|
27662
27670
|
if (isTestFile(context) || isGeneratedFile(context, context.sourceCode.text))
|
|
27663
27671
|
return {};
|
|
@@ -29732,13 +29740,14 @@ var prefer_await_in_async_return_default = createRule({
|
|
|
29732
29740
|
name: "prefer-await-in-async-return",
|
|
29733
29741
|
documentation: PREFER_AWAIT_IN_ASYNC_RETURN_DOCUMENTATION,
|
|
29734
29742
|
meta: {
|
|
29743
|
+
defaultOptions: [{ scope: "async-return" }],
|
|
29735
29744
|
type: "suggestion",
|
|
29736
29745
|
docs: {
|
|
29737
29746
|
description: "Prefer explicit `await` for proven Promise `.then` calls; the default scope checks direct async returns."
|
|
29738
29747
|
},
|
|
29739
29748
|
schema: [{
|
|
29740
29749
|
type: "object",
|
|
29741
|
-
properties: { scope: { type: "string", enum: ["async-return", "all-promise-calls"] } },
|
|
29750
|
+
properties: { scope: { description: "Check async return statements or every promise-valued call.", type: "string", enum: ["async-return", "all-promise-calls"] } },
|
|
29742
29751
|
additionalProperties: false
|
|
29743
29752
|
}],
|
|
29744
29753
|
messages: {
|
|
@@ -29746,7 +29755,6 @@ var prefer_await_in_async_return_default = createRule({
|
|
|
29746
29755
|
preferAwaitCall: "This call uses built-in Promise.then(). Use async/await, preserving rejection handling and observable scheduling when rewriting."
|
|
29747
29756
|
}
|
|
29748
29757
|
},
|
|
29749
|
-
defaultOptions: [{ scope: "async-return" }],
|
|
29750
29758
|
create(context, [options]) {
|
|
29751
29759
|
let services;
|
|
29752
29760
|
try {
|
|
@@ -30960,6 +30968,7 @@ var prefer_semantic_colors_default = createRule({
|
|
|
30960
30968
|
name: "prefer-semantic-colors",
|
|
30961
30969
|
documentation: PREFER_SEMANTIC_COLORS_DOCUMENTATION,
|
|
30962
30970
|
meta: {
|
|
30971
|
+
defaultOptions: [{}],
|
|
30963
30972
|
type: "suggestion",
|
|
30964
30973
|
docs: {
|
|
30965
30974
|
description: "Enforce semantic color tokens over raw Tailwind palette classes, arbitrary color values, and inline color literals."
|
|
@@ -30969,8 +30978,8 @@ var prefer_semantic_colors_default = createRule({
|
|
|
30969
30978
|
type: "object",
|
|
30970
30979
|
additionalProperties: false,
|
|
30971
30980
|
properties: {
|
|
30972
|
-
requireSemanticTokens: { type: "boolean" },
|
|
30973
|
-
opaqueForegroundPairs: { type: "boolean" }
|
|
30981
|
+
requireSemanticTokens: { description: "Restrict checks to projects with an existing semantic token system.", type: "boolean" },
|
|
30982
|
+
opaqueForegroundPairs: { description: "Use the project semantic foreground roles to check opaque foreground and background pairs.", type: "boolean" }
|
|
30974
30983
|
}
|
|
30975
30984
|
}
|
|
30976
30985
|
],
|
|
@@ -30981,7 +30990,6 @@ var prefer_semantic_colors_default = createRule({
|
|
|
30981
30990
|
opaqueForegroundPair: "'{{class}}' bypasses the declared '{{replacement}}' token paired with '{{background}}'."
|
|
30982
30991
|
}
|
|
30983
30992
|
},
|
|
30984
|
-
defaultOptions: [{}],
|
|
30985
30993
|
create(context, [options]) {
|
|
30986
30994
|
if (STORIES_FILE_RE.test(context.filename)) return {};
|
|
30987
30995
|
if (staticallyImportsExternalRenderer(context.sourceCode.ast)) return {};
|
|
@@ -31283,6 +31291,7 @@ var prefer_server_actions_default = createRule({
|
|
|
31283
31291
|
name: "prefer-server-actions",
|
|
31284
31292
|
documentation: PREFER_SERVER_ACTIONS_DOCUMENTATION,
|
|
31285
31293
|
meta: {
|
|
31294
|
+
defaultOptions: [{}],
|
|
31286
31295
|
type: "suggestion",
|
|
31287
31296
|
docs: {
|
|
31288
31297
|
description: "Prefer Next.js Server Actions over same-origin API mutations."
|
|
@@ -31293,6 +31302,7 @@ var prefer_server_actions_default = createRule({
|
|
|
31293
31302
|
additionalProperties: false,
|
|
31294
31303
|
properties: {
|
|
31295
31304
|
basePath: {
|
|
31305
|
+
description: "Static application URL base path without query strings, fragments or parent segments.",
|
|
31296
31306
|
type: "string",
|
|
31297
31307
|
pattern: "^/(?!$)(?!.*[?#])(?!(?:.*/)?\\.\\.?(?:/|$))(?:[^/]+/)*[^/]+$"
|
|
31298
31308
|
}
|
|
@@ -31303,7 +31313,6 @@ var prefer_server_actions_default = createRule({
|
|
|
31303
31313
|
preferServerAction: "This client mutation targets a same-origin API route. Consider a Server Action to remove the hand-written API wrapper; retain authorization and validation, since the call still crosses a network boundary."
|
|
31304
31314
|
}
|
|
31305
31315
|
},
|
|
31306
|
-
defaultOptions: [{}],
|
|
31307
31316
|
create(context, [options]) {
|
|
31308
31317
|
const filename = context.filename.replaceAll("\\", "/");
|
|
31309
31318
|
if (SKIP_FILE_REGEX.test(filename)) {
|
|
@@ -32317,6 +32326,7 @@ var prefer_zod_infer_default = createRule({
|
|
|
32317
32326
|
name: "prefer-zod-infer",
|
|
32318
32327
|
documentation: PREFER_ZOD_INFER_DOCUMENTATION,
|
|
32319
32328
|
meta: {
|
|
32329
|
+
defaultOptions: [{}],
|
|
32320
32330
|
type: "problem",
|
|
32321
32331
|
fixable: "code",
|
|
32322
32332
|
docs: {
|
|
@@ -32328,10 +32338,11 @@ var prefer_zod_infer_default = createRule({
|
|
|
32328
32338
|
additionalProperties: false,
|
|
32329
32339
|
properties: {
|
|
32330
32340
|
ignoreTypeNames: {
|
|
32341
|
+
description: "Regular expression patterns for type names to leave unchanged.",
|
|
32331
32342
|
type: "array",
|
|
32332
32343
|
items: { type: "string" }
|
|
32333
32344
|
},
|
|
32334
|
-
requireIdenticalShape: { type: "boolean" }
|
|
32345
|
+
requireIdenticalShape: { description: "Require the schema output and declared type to have identical property shapes.", type: "boolean" }
|
|
32335
32346
|
}
|
|
32336
32347
|
}
|
|
32337
32348
|
],
|
|
@@ -32340,7 +32351,6 @@ var prefer_zod_infer_default = createRule({
|
|
|
32340
32351
|
repeatedEnumUnion: "`{{propertyName}}` repeats the literal domain already named by `{{typeName}}` and `{{schemaName}}` in multiple object types. Reuse `{{typeName}}` so the accepted values have one source of truth."
|
|
32341
32352
|
}
|
|
32342
32353
|
},
|
|
32343
|
-
defaultOptions: [{}],
|
|
32344
32354
|
create(context, [optionsArg]) {
|
|
32345
32355
|
const ignorePatterns = (optionsArg?.ignoreTypeNames ?? []).map(
|
|
32346
32356
|
(source) => new RegExp(source, "u")
|
|
@@ -33679,6 +33689,7 @@ var require_fetch_timeout_default = createRule({
|
|
|
33679
33689
|
name: "require-fetch-timeout",
|
|
33680
33690
|
documentation: REQUIRE_FETCH_TIMEOUT_DOCUMENTATION,
|
|
33681
33691
|
meta: {
|
|
33692
|
+
defaultOptions: [{}],
|
|
33682
33693
|
type: "problem",
|
|
33683
33694
|
docs: {
|
|
33684
33695
|
description: "Require an explicit abort signal on locally analyzable global fetch calls."
|
|
@@ -33700,7 +33711,6 @@ var require_fetch_timeout_default = createRule({
|
|
|
33700
33711
|
missingSignal: "This `fetch()` has no explicit abort signal. Pass `AbortSignal.timeout(ms)` for a deadline, or an owner-managed signal for cancellation."
|
|
33701
33712
|
}
|
|
33702
33713
|
},
|
|
33703
|
-
defaultOptions: [{}],
|
|
33704
33714
|
create(context, [optionsArg]) {
|
|
33705
33715
|
if (isTestFile(context) || isScriptFile(context)) {
|
|
33706
33716
|
return {};
|
|
@@ -35802,6 +35812,7 @@ var stepdown_default = createRule({
|
|
|
35802
35812
|
name: "stepdown",
|
|
35803
35813
|
documentation: STEPDOWN_DOCUMENTATION,
|
|
35804
35814
|
meta: {
|
|
35815
|
+
defaultOptions: [{}],
|
|
35805
35816
|
type: "suggestion",
|
|
35806
35817
|
fixable: "code",
|
|
35807
35818
|
docs: {
|
|
@@ -35823,7 +35834,6 @@ var stepdown_default = createRule({
|
|
|
35823
35834
|
helperAboveOnlyCaller: "Private helper `{{helper}}` is defined above its only caller `{{caller}}`; move it below the caller."
|
|
35824
35835
|
}
|
|
35825
35836
|
},
|
|
35826
|
-
defaultOptions: [{}],
|
|
35827
35837
|
create(context, [options]) {
|
|
35828
35838
|
if (isTestFile(context) || isGeneratedFile(context, context.sourceCode.text))
|
|
35829
35839
|
return {};
|
package/dist/index.js
CHANGED
|
@@ -1025,13 +1025,13 @@ var no_test_comments_default = createRule({
|
|
|
1025
1025
|
name: "no-test-comments",
|
|
1026
1026
|
documentation: NO_TEST_COMMENTS_DOCUMENTATION,
|
|
1027
1027
|
meta: {
|
|
1028
|
+
defaultOptions: [{}],
|
|
1028
1029
|
type: "suggestion",
|
|
1029
1030
|
fixable: "code",
|
|
1030
1031
|
docs: { description: NO_TEST_COMMENTS_DOCUMENTATION.summary },
|
|
1031
|
-
schema: [{ type: "object", properties: { allFiles: { type: "boolean" } }, additionalProperties: false }],
|
|
1032
|
+
schema: [{ type: "object", properties: { allFiles: { description: "Check every eligible test file without requiring frontend framework ownership.", type: "boolean" } }, additionalProperties: false }],
|
|
1032
1033
|
messages: { testComment: "Express this explanation in the test name, fixture or assertion, then remove the comment." }
|
|
1033
1034
|
},
|
|
1034
|
-
defaultOptions: [{}],
|
|
1035
1035
|
create(context, [options]) {
|
|
1036
1036
|
if (!isTestFile(context) || isGeneratedFile(context, context.sourceCode.text)) return {};
|
|
1037
1037
|
if (!ownsTestComments(context)) return {};
|
|
@@ -1120,13 +1120,13 @@ var no_frontend_comments_default = createRule({
|
|
|
1120
1120
|
name: "no-frontend-comments",
|
|
1121
1121
|
documentation: NO_FRONTEND_COMMENTS_DOCUMENTATION,
|
|
1122
1122
|
meta: {
|
|
1123
|
+
defaultOptions: [{}],
|
|
1123
1124
|
type: "suggestion",
|
|
1124
1125
|
fixable: "code",
|
|
1125
1126
|
docs: { description: NO_FRONTEND_COMMENTS_DOCUMENTATION.summary },
|
|
1126
|
-
schema: [{ type: "object", properties: { allFiles: { type: "boolean" } }, additionalProperties: false }],
|
|
1127
|
+
schema: [{ type: "object", properties: { allFiles: { description: "Check comments without requiring frontend framework ownership.", type: "boolean" } }, additionalProperties: false }],
|
|
1127
1128
|
messages: { noFrontendComments: "Frontend comments are prohibited; express the behavior in names, types or code and review any directive or legal contract before removing it." }
|
|
1128
1129
|
},
|
|
1129
|
-
defaultOptions: [{}],
|
|
1130
1130
|
create(context, [options]) {
|
|
1131
1131
|
if (isGeneratedFile(context, context.sourceCode.text) || ownsTestComments(context)) return {};
|
|
1132
1132
|
const jsxRanges = [];
|
|
@@ -4781,7 +4781,7 @@ function isSearchParamReceiver(call, services) {
|
|
|
4781
4781
|
// package.json
|
|
4782
4782
|
var package_default = {
|
|
4783
4783
|
name: "@sarj/eslint-plugin",
|
|
4784
|
-
version: "17.1.
|
|
4784
|
+
version: "17.1.3",
|
|
4785
4785
|
packageManager: "npm@12.2.1",
|
|
4786
4786
|
description: "Custom ESLint rules for hypermodern TypeScript / React / Next.js projects",
|
|
4787
4787
|
type: "module",
|
|
@@ -4855,6 +4855,7 @@ var package_default = {
|
|
|
4855
4855
|
"@vitest/eslint-plugin": "1.6.28",
|
|
4856
4856
|
eslint: "10.13.0",
|
|
4857
4857
|
"eslint-node-test": "1.0.1",
|
|
4858
|
+
"eslint-plugin-eslint-plugin": "7.6.2",
|
|
4858
4859
|
"eslint-plugin-better-tailwindcss": "^4.10.0",
|
|
4859
4860
|
"eslint-plugin-jest": "29.17.0",
|
|
4860
4861
|
"eslint-plugin-jsdoc": "65.4.2",
|
|
@@ -4875,6 +4876,7 @@ var package_default = {
|
|
|
4875
4876
|
jiti: "2.7.0",
|
|
4876
4877
|
prettier: "3.9.10",
|
|
4877
4878
|
tsup: "9.0.0",
|
|
4879
|
+
syncpack: "15.3.3",
|
|
4878
4880
|
typescript: "npm:@typescript/typescript6@6.0.2",
|
|
4879
4881
|
"typescript-eslint": "^8.72.0",
|
|
4880
4882
|
uuid: "13.0.0",
|
|
@@ -9122,6 +9124,7 @@ var require_button_accessible_name_default = createRule({
|
|
|
9122
9124
|
name: "require-button-accessible-name",
|
|
9123
9125
|
documentation: REQUIRE_BUTTON_ACCESSIBLE_NAME_DOCUMENTATION,
|
|
9124
9126
|
meta: {
|
|
9127
|
+
defaultOptions: [{}],
|
|
9125
9128
|
type: "problem",
|
|
9126
9129
|
docs: { description: REQUIRE_BUTTON_ACCESSIBLE_NAME_DOCUMENTATION.summary },
|
|
9127
9130
|
schema: [
|
|
@@ -9130,6 +9133,7 @@ var require_button_accessible_name_default = createRule({
|
|
|
9130
9133
|
properties: {
|
|
9131
9134
|
components: COMPONENT_IMPORT_SCHEMA,
|
|
9132
9135
|
iconModules: {
|
|
9136
|
+
description: "Module names whose imported components count as icons.",
|
|
9133
9137
|
type: "array",
|
|
9134
9138
|
items: { type: "string", minLength: 1 },
|
|
9135
9139
|
uniqueItems: true
|
|
@@ -9142,7 +9146,6 @@ var require_button_accessible_name_default = createRule({
|
|
|
9142
9146
|
missingName: "This button has no statically identifiable accessible name. Add action text, aria-label, or aria-labelledby."
|
|
9143
9147
|
}
|
|
9144
9148
|
},
|
|
9145
|
-
defaultOptions: [{}],
|
|
9146
9149
|
create(context, [options]) {
|
|
9147
9150
|
if (isGeneratedFile(context, context.sourceCode.text) || isTestFile(context) || isStoryFile(context))
|
|
9148
9151
|
return {};
|
|
@@ -9461,6 +9464,7 @@ var prefer_logical_tailwind_utilities_default = createRule({
|
|
|
9461
9464
|
name: "prefer-logical-tailwind-utilities",
|
|
9462
9465
|
documentation: PREFER_LOGICAL_TAILWIND_UTILITIES_DOCUMENTATION,
|
|
9463
9466
|
meta: {
|
|
9467
|
+
defaultOptions: [{ enabled: true, checkInsets: false, allowUtilities: [] }],
|
|
9464
9468
|
type: "suggestion",
|
|
9465
9469
|
docs: {
|
|
9466
9470
|
description: PREFER_LOGICAL_TAILWIND_UTILITIES_DOCUMENTATION.summary
|
|
@@ -9469,9 +9473,10 @@ var prefer_logical_tailwind_utilities_default = createRule({
|
|
|
9469
9473
|
{
|
|
9470
9474
|
type: "object",
|
|
9471
9475
|
properties: {
|
|
9472
|
-
enabled: { type: "boolean" },
|
|
9473
|
-
checkInsets: { type: "boolean" },
|
|
9476
|
+
enabled: { description: "Enable replacement of physical direction utilities with logical equivalents.", type: "boolean" },
|
|
9477
|
+
checkInsets: { description: "Include physical inset utilities in direction checks.", type: "boolean" },
|
|
9474
9478
|
allowUtilities: {
|
|
9479
|
+
description: "Physical utility names allowed without a logical replacement.",
|
|
9475
9480
|
type: "array",
|
|
9476
9481
|
items: { type: "string" },
|
|
9477
9482
|
uniqueItems: true
|
|
@@ -9484,7 +9489,6 @@ var prefer_logical_tailwind_utilities_default = createRule({
|
|
|
9484
9489
|
physicalUtility: "Use '{{replacement}}' instead of '{{utility}}' in this bidirectional UI, or explicitly allow intentional physical placement."
|
|
9485
9490
|
}
|
|
9486
9491
|
},
|
|
9487
|
-
defaultOptions: [{ enabled: true, checkInsets: false, allowUtilities: [] }],
|
|
9488
9492
|
create(context, [options]) {
|
|
9489
9493
|
if (options?.enabled === false || isGeneratedFile(context, context.sourceCode.text) || isTestFile(context) || isStoryFile(context))
|
|
9490
9494
|
return {};
|
|
@@ -9612,6 +9616,7 @@ var no_unlocalized_toast_default = createRule({
|
|
|
9612
9616
|
name: "no-unlocalized-toast",
|
|
9613
9617
|
documentation: NO_UNLOCALIZED_TOAST_DOCUMENTATION,
|
|
9614
9618
|
meta: {
|
|
9619
|
+
defaultOptions: [{ enabled: true }],
|
|
9615
9620
|
type: "suggestion",
|
|
9616
9621
|
docs: { description: NO_UNLOCALIZED_TOAST_DOCUMENTATION.summary },
|
|
9617
9622
|
schema: [
|
|
@@ -9621,6 +9626,7 @@ var no_unlocalized_toast_default = createRule({
|
|
|
9621
9626
|
...LOCALIZATION_PROPERTIES,
|
|
9622
9627
|
functions: COMPONENT_IMPORT_SCHEMA,
|
|
9623
9628
|
methods: {
|
|
9629
|
+
description: "Toast method names whose user-visible messages require localization.",
|
|
9624
9630
|
type: "array",
|
|
9625
9631
|
items: { type: "string", minLength: 1 },
|
|
9626
9632
|
uniqueItems: true
|
|
@@ -9633,7 +9639,6 @@ var no_unlocalized_toast_default = createRule({
|
|
|
9633
9639
|
unlocalized: "Translate this user-facing literal or add an explicit localization exception."
|
|
9634
9640
|
}
|
|
9635
9641
|
},
|
|
9636
|
-
defaultOptions: [{ enabled: true }],
|
|
9637
9642
|
create(context, [options]) {
|
|
9638
9643
|
if (localizationExcluded(context, context.sourceCode.text, options))
|
|
9639
9644
|
return {};
|
|
@@ -9725,6 +9730,7 @@ var no_unlocalized_jsx_attributes_default = createRule({
|
|
|
9725
9730
|
name: "no-unlocalized-jsx-attributes",
|
|
9726
9731
|
documentation: NO_UNLOCALIZED_JSX_ATTRIBUTES_DOCUMENTATION,
|
|
9727
9732
|
meta: {
|
|
9733
|
+
defaultOptions: [{ enabled: true }],
|
|
9728
9734
|
type: "suggestion",
|
|
9729
9735
|
docs: { description: NO_UNLOCALIZED_JSX_ATTRIBUTES_DOCUMENTATION.summary },
|
|
9730
9736
|
schema: [
|
|
@@ -9733,6 +9739,7 @@ var no_unlocalized_jsx_attributes_default = createRule({
|
|
|
9733
9739
|
properties: {
|
|
9734
9740
|
...LOCALIZATION_PROPERTIES,
|
|
9735
9741
|
attributes: {
|
|
9742
|
+
description: "JSX attributes whose user-visible text requires localization.",
|
|
9736
9743
|
type: "array",
|
|
9737
9744
|
items: { type: "string", minLength: 1 },
|
|
9738
9745
|
uniqueItems: true
|
|
@@ -9745,7 +9752,6 @@ var no_unlocalized_jsx_attributes_default = createRule({
|
|
|
9745
9752
|
unlocalized: "Translate this user-facing literal or add an explicit localization exception."
|
|
9746
9753
|
}
|
|
9747
9754
|
},
|
|
9748
|
-
defaultOptions: [{ enabled: true }],
|
|
9749
9755
|
create(context, [options]) {
|
|
9750
9756
|
if (localizationExcluded(context, context.sourceCode.text, options))
|
|
9751
9757
|
return {};
|
|
@@ -9810,6 +9816,7 @@ var no_unlocalized_jsx_text_default = createRule({
|
|
|
9810
9816
|
name: "no-unlocalized-jsx-text",
|
|
9811
9817
|
documentation: NO_UNLOCALIZED_JSX_TEXT_DOCUMENTATION,
|
|
9812
9818
|
meta: {
|
|
9819
|
+
defaultOptions: [{ enabled: true }],
|
|
9813
9820
|
type: "suggestion",
|
|
9814
9821
|
docs: { description: NO_UNLOCALIZED_JSX_TEXT_DOCUMENTATION.summary },
|
|
9815
9822
|
schema: [
|
|
@@ -9823,7 +9830,6 @@ var no_unlocalized_jsx_text_default = createRule({
|
|
|
9823
9830
|
unlocalized: "Translate this user-facing literal or add an explicit localization exception."
|
|
9824
9831
|
}
|
|
9825
9832
|
},
|
|
9826
|
-
defaultOptions: [{ enabled: true }],
|
|
9827
9833
|
create(context, [options]) {
|
|
9828
9834
|
if (localizationExcluded(context, context.sourceCode.text, options))
|
|
9829
9835
|
return {};
|
|
@@ -12607,6 +12613,7 @@ var no_dynamic_sql_default = createRule({
|
|
|
12607
12613
|
name: "no-dynamic-sql",
|
|
12608
12614
|
documentation: NO_DYNAMIC_SQL_DOCUMENTATION,
|
|
12609
12615
|
meta: {
|
|
12616
|
+
defaultOptions: [{}],
|
|
12610
12617
|
type: "problem",
|
|
12611
12618
|
docs: {
|
|
12612
12619
|
description: NO_DYNAMIC_SQL_DOCUMENTATION.summary
|
|
@@ -12629,7 +12636,6 @@ var no_dynamic_sql_default = createRule({
|
|
|
12629
12636
|
dynamicFragment: "Runtime fragment interpolated into SQL passed to `{{method}}()`. Bind data values; select non-bindable SQL fragments from fixed, reviewed alternatives."
|
|
12630
12637
|
}
|
|
12631
12638
|
},
|
|
12632
|
-
defaultOptions: [{}],
|
|
12633
12639
|
create(context, [options]) {
|
|
12634
12640
|
const methods = new Set(options?.methods ?? DEFAULT_METHODS);
|
|
12635
12641
|
return {
|
|
@@ -12701,6 +12707,7 @@ var no_enum_default = createRule({
|
|
|
12701
12707
|
name: "no-enum",
|
|
12702
12708
|
documentation: NO_ENUM_DOCUMENTATION,
|
|
12703
12709
|
meta: {
|
|
12710
|
+
defaultOptions: [{}],
|
|
12704
12711
|
type: "suggestion",
|
|
12705
12712
|
fixable: "code",
|
|
12706
12713
|
docs: {
|
|
@@ -12723,7 +12730,6 @@ var no_enum_default = createRule({
|
|
|
12723
12730
|
noEnum: 'Enums are discouraged. Use a string-literal union (e.g. `type Status = "active" | "inactive"`) or an `as const` object instead.'
|
|
12724
12731
|
}
|
|
12725
12732
|
},
|
|
12726
|
-
defaultOptions: [{}],
|
|
12727
12733
|
create(context, [optionsArg]) {
|
|
12728
12734
|
const options = optionsArg ?? {};
|
|
12729
12735
|
const ignoreFiles = options.ignoreFiles ?? [];
|
|
@@ -13270,6 +13276,7 @@ var no_fat_try_blocks_default = createRule({
|
|
|
13270
13276
|
name: "no-fat-try-blocks",
|
|
13271
13277
|
documentation: NO_FAT_TRY_BLOCKS_DOCUMENTATION,
|
|
13272
13278
|
meta: {
|
|
13279
|
+
defaultOptions: [{ max: MAX_TRY_BODY_STATEMENTS }],
|
|
13273
13280
|
type: "problem",
|
|
13274
13281
|
docs: {
|
|
13275
13282
|
description: "Review try blocks exceeding the configured count of syntactically selected operations."
|
|
@@ -13278,7 +13285,7 @@ var no_fat_try_blocks_default = createRule({
|
|
|
13278
13285
|
{
|
|
13279
13286
|
type: "object",
|
|
13280
13287
|
properties: {
|
|
13281
|
-
max: { type: "integer", minimum: 1 }
|
|
13288
|
+
max: { description: "Maximum number of statements allowed in one try body.", type: "integer", minimum: 1 }
|
|
13282
13289
|
},
|
|
13283
13290
|
additionalProperties: false
|
|
13284
13291
|
}
|
|
@@ -13287,7 +13294,6 @@ var no_fat_try_blocks_default = createRule({
|
|
|
13287
13294
|
fatTryBlock: "This `try` block has {{count}} syntactically selected operations (max {{max}}). Review whether they share one recovery policy; move unrelated work outside the boundary."
|
|
13288
13295
|
}
|
|
13289
13296
|
},
|
|
13290
|
-
defaultOptions: [{ max: MAX_TRY_BODY_STATEMENTS }],
|
|
13291
13297
|
create(context, [options]) {
|
|
13292
13298
|
if (isGeneratedFile(context, context.sourceCode.text)) {
|
|
13293
13299
|
return {};
|
|
@@ -13438,6 +13444,7 @@ var no_hand_rolled_sleep_default = createRule({
|
|
|
13438
13444
|
name: "no-hand-rolled-sleep",
|
|
13439
13445
|
documentation: NO_HAND_ROLLED_SLEEP_DOCUMENTATION,
|
|
13440
13446
|
meta: {
|
|
13447
|
+
defaultOptions: [{}],
|
|
13441
13448
|
type: "problem",
|
|
13442
13449
|
docs: {
|
|
13443
13450
|
description: "Disallow uncancellable promisified timers and timeout arms."
|
|
@@ -13464,7 +13471,6 @@ var no_hand_rolled_sleep_default = createRule({
|
|
|
13464
13471
|
handRolledTimeoutRace: "Hand-rolled timeout arm: when the other promise wins, this timer is never cleared and keeps the event loop alive until it fires. Use `AbortSignal.timeout(ms)` and pass the signal to the operation."
|
|
13465
13472
|
}
|
|
13466
13473
|
},
|
|
13467
|
-
defaultOptions: [{}],
|
|
13468
13474
|
create(context, [optionsArg]) {
|
|
13469
13475
|
const { filename, sourceCode } = context;
|
|
13470
13476
|
if (isTestFile(context) || isScriptFile(context) || isGeneratedFile(context, sourceCode.getText())) {
|
|
@@ -15746,6 +15752,7 @@ var no_impossible_zod_literal_bounds_default = createRule({
|
|
|
15746
15752
|
name: "no-impossible-zod-literal-bounds",
|
|
15747
15753
|
documentation: NO_IMPOSSIBLE_ZOD_LITERAL_BOUNDS_DOCUMENTATION,
|
|
15748
15754
|
meta: {
|
|
15755
|
+
defaultOptions: [{}],
|
|
15749
15756
|
type: "problem",
|
|
15750
15757
|
docs: {
|
|
15751
15758
|
description: "Disallow same-chain literal Zod bounds whose accepted set is mathematically empty."
|
|
@@ -15766,7 +15773,6 @@ var no_impossible_zod_literal_bounds_default = createRule({
|
|
|
15766
15773
|
impossibleBounds: "This Zod {{kind}} schema accepts no values: {{lower}} conflicts with {{upper}}."
|
|
15767
15774
|
}
|
|
15768
15775
|
},
|
|
15769
|
-
defaultOptions: [{}],
|
|
15770
15776
|
create(context, [options]) {
|
|
15771
15777
|
const sourceCode = context.sourceCode;
|
|
15772
15778
|
if (isTestFile(context) || isGeneratedFile(context, sourceCode.getText())) {
|
|
@@ -16812,6 +16818,7 @@ var no_log_only_catch_default = createRule({
|
|
|
16812
16818
|
name: "no-log-only-catch",
|
|
16813
16819
|
documentation: NO_LOG_ONLY_CATCH_DOCUMENTATION,
|
|
16814
16820
|
meta: {
|
|
16821
|
+
defaultOptions: [{}],
|
|
16815
16822
|
type: "problem",
|
|
16816
16823
|
docs: {
|
|
16817
16824
|
description: "Disallow `catch` clauses that only log (or silently do nothing) and then swallow the error; rethrow or handle it instead."
|
|
@@ -16828,7 +16835,6 @@ var no_log_only_catch_default = createRule({
|
|
|
16828
16835
|
emptyCatch: "Empty catch silently swallows the error. Rethrow it, handle it, or add a comment explaining why it is safe to ignore."
|
|
16829
16836
|
}
|
|
16830
16837
|
},
|
|
16831
|
-
defaultOptions: [{}],
|
|
16832
16838
|
create(context, [loggingOptions]) {
|
|
16833
16839
|
const matcher = createLogMatcher(loggingOptions);
|
|
16834
16840
|
const filename = context.filename;
|
|
@@ -18613,6 +18619,7 @@ var no_raw_fetch_outside_clients_default = createRule({
|
|
|
18613
18619
|
name: "no-raw-fetch-outside-clients",
|
|
18614
18620
|
documentation: NO_RAW_FETCH_OUTSIDE_CLIENTS_DOCUMENTATION,
|
|
18615
18621
|
meta: {
|
|
18622
|
+
defaultOptions: [{}],
|
|
18616
18623
|
type: "problem",
|
|
18617
18624
|
docs: {
|
|
18618
18625
|
description: "Disallow calling the global `fetch` outside the client layer; route outbound HTTP through a client module that owns retry, timeout and status handling."
|
|
@@ -18627,6 +18634,7 @@ var no_raw_fetch_outside_clients_default = createRule({
|
|
|
18627
18634
|
description: "Regular-expression sources matched against the filename. Replaces the defaults."
|
|
18628
18635
|
},
|
|
18629
18636
|
basePath: {
|
|
18637
|
+
description: "Static application URL base path without query strings, fragments or parent segments.",
|
|
18630
18638
|
type: "string",
|
|
18631
18639
|
pattern: "^/(?!$)(?!.*[?#])(?!(?:.*/)?\\.\\.?(?:/|$))(?:[^/]+/)*[^/]+$"
|
|
18632
18640
|
}
|
|
@@ -18638,7 +18646,6 @@ var no_raw_fetch_outside_clients_default = createRule({
|
|
|
18638
18646
|
rawFetch: "Raw `fetch()` outside a client module. Route the call through a client (e.g. `clients/*-client.ts`) so it inherits retry, timeout and status handling and stays stubbable in tests."
|
|
18639
18647
|
}
|
|
18640
18648
|
},
|
|
18641
|
-
defaultOptions: [{}],
|
|
18642
18649
|
create(context, [options]) {
|
|
18643
18650
|
const filename = context.filename;
|
|
18644
18651
|
if (isTestFile(context) || isScriptFile(context) || NON_PRODUCTION_TREE_RE.test(filename)) {
|
|
@@ -18804,6 +18811,7 @@ var no_restricted_library_load_default = createRule({
|
|
|
18804
18811
|
name: "no-restricted-library-load",
|
|
18805
18812
|
documentation: NO_RESTRICTED_LIBRARY_LOAD_DOCUMENTATION,
|
|
18806
18813
|
meta: {
|
|
18814
|
+
defaultOptions: [{ libraries: [] }],
|
|
18807
18815
|
type: "problem",
|
|
18808
18816
|
docs: {
|
|
18809
18817
|
description: NO_RESTRICTED_LIBRARY_LOAD_DOCUMENTATION.summary
|
|
@@ -18815,6 +18823,7 @@ var no_restricted_library_load_default = createRule({
|
|
|
18815
18823
|
required: ["libraries"],
|
|
18816
18824
|
properties: {
|
|
18817
18825
|
libraries: {
|
|
18826
|
+
description: "Library import and module-load restrictions.",
|
|
18818
18827
|
type: "array",
|
|
18819
18828
|
items: {
|
|
18820
18829
|
type: "object",
|
|
@@ -18835,7 +18844,6 @@ var no_restricted_library_load_default = createRule({
|
|
|
18835
18844
|
restrictedLibraryLoad: "{{id}}: Replace this runtime dependency reference to {{module}} with {{replacement}}.{{note}}"
|
|
18836
18845
|
}
|
|
18837
18846
|
},
|
|
18838
|
-
defaultOptions: [{ libraries: [] }],
|
|
18839
18847
|
create(context, [options]) {
|
|
18840
18848
|
const restrictions = options.libraries;
|
|
18841
18849
|
function report2(node, source) {
|
|
@@ -19816,6 +19824,7 @@ var no_secret_in_log_default = createRule({
|
|
|
19816
19824
|
name: "no-secret-in-log",
|
|
19817
19825
|
documentation: NO_SECRET_IN_LOG_DOCUMENTATION,
|
|
19818
19826
|
meta: {
|
|
19827
|
+
defaultOptions: [{}],
|
|
19819
19828
|
type: "problem",
|
|
19820
19829
|
docs: {
|
|
19821
19830
|
description: "Disallow passing a secret-named value or a raw request/response blob to a logging call; both leak to log sinks. Redact or omit."
|
|
@@ -19832,7 +19841,6 @@ var no_secret_in_log_default = createRule({
|
|
|
19832
19841
|
noRawBodyInLog: "Raw `{{name}}` passed to a logging call. Request/response bodies can contain personal data or credentials. Log allowlisted non-sensitive context or use an approved redactor."
|
|
19833
19842
|
}
|
|
19834
19843
|
},
|
|
19835
|
-
defaultOptions: [{}],
|
|
19836
19844
|
create(context, [loggingOptions]) {
|
|
19837
19845
|
const matcher = createLogMatcher(loggingOptions);
|
|
19838
19846
|
const blobArmApplies = !isTestFile(context);
|
|
@@ -20863,6 +20871,7 @@ var no_sentinel_return_on_catch_default = createRule({
|
|
|
20863
20871
|
name: "no-sentinel-return-on-catch",
|
|
20864
20872
|
documentation: NO_SENTINEL_RETURN_ON_CATCH_DOCUMENTATION,
|
|
20865
20873
|
meta: {
|
|
20874
|
+
defaultOptions: [{}],
|
|
20866
20875
|
type: "problem",
|
|
20867
20876
|
docs: {
|
|
20868
20877
|
description: "Disallow swallowing a caught error by returning an empty sentinel unless the error is handled or the sentinel is part of the function contract."
|
|
@@ -20878,7 +20887,6 @@ var no_sentinel_return_on_catch_default = createRule({
|
|
|
20878
20887
|
noSentinelReturn: "This `catch` block swallows the error by returning an empty sentinel without logging it. Rethrow it, log/report it, or return a typed Result."
|
|
20879
20888
|
}
|
|
20880
20889
|
},
|
|
20881
|
-
defaultOptions: [{}],
|
|
20882
20890
|
create(context, [loggingOptions]) {
|
|
20883
20891
|
if (isGeneratedFile(context, context.sourceCode.text)) {
|
|
20884
20892
|
return {};
|
|
@@ -21425,6 +21433,7 @@ var no_storage_in_stateless_modules_default = createRule({
|
|
|
21425
21433
|
name: "no-storage-in-stateless-modules",
|
|
21426
21434
|
documentation: NO_STORAGE_IN_STATELESS_MODULES_DOCUMENTATION,
|
|
21427
21435
|
meta: {
|
|
21436
|
+
defaultOptions: [{}],
|
|
21428
21437
|
type: "problem",
|
|
21429
21438
|
docs: {
|
|
21430
21439
|
description: "Disallow SQL or key/value access inside configured stateless modules; derive state from a system of record instead."
|
|
@@ -21451,7 +21460,6 @@ var no_storage_in_stateless_modules_default = createRule({
|
|
|
21451
21460
|
storageInStatelessModule: "`{{method}}()` reaches for private storage inside a module declared stateless. Derive the state from a read against the system of record, or from a marker in the artefact this feature already produces."
|
|
21452
21461
|
}
|
|
21453
21462
|
},
|
|
21454
|
-
defaultOptions: [{}],
|
|
21455
21463
|
create(context, [options]) {
|
|
21456
21464
|
if (isTestFile(context)) {
|
|
21457
21465
|
return {};
|
|
@@ -23044,6 +23052,7 @@ var no_declaration_comment_wall_default = createRule({
|
|
|
23044
23052
|
name: "no-declaration-comment-wall",
|
|
23045
23053
|
documentation: NO_DECLARATION_COMMENT_WALL_DOCUMENTATION,
|
|
23046
23054
|
meta: {
|
|
23055
|
+
defaultOptions: [WALL_DEFAULTS],
|
|
23047
23056
|
type: "suggestion",
|
|
23048
23057
|
fixable: "code",
|
|
23049
23058
|
docs: {
|
|
@@ -23054,7 +23063,6 @@ var no_declaration_comment_wall_default = createRule({
|
|
|
23054
23063
|
commentWall: "{{restated}} of this declaration's {{commented}} member comments only re-spell member names \u2014 delete them; if a row still needs narration, give the member a clearer name. Keep constraints, lifecycle, and rationale."
|
|
23055
23064
|
}
|
|
23056
23065
|
},
|
|
23057
|
-
defaultOptions: [WALL_DEFAULTS],
|
|
23058
23066
|
create(context, [provided]) {
|
|
23059
23067
|
const options = { ...WALL_DEFAULTS, ...provided };
|
|
23060
23068
|
const sourceCode = context.sourceCode;
|
|
@@ -23406,6 +23414,7 @@ var no_type_member_comment_wall_default = createRule({
|
|
|
23406
23414
|
name: "no-type-member-comment-wall",
|
|
23407
23415
|
documentation: NO_TYPE_MEMBER_COMMENT_WALL_DOCUMENTATION,
|
|
23408
23416
|
meta: {
|
|
23417
|
+
defaultOptions: [WALL_DEFAULTS],
|
|
23409
23418
|
type: "suggestion",
|
|
23410
23419
|
fixable: "code",
|
|
23411
23420
|
docs: {
|
|
@@ -23416,7 +23425,6 @@ var no_type_member_comment_wall_default = createRule({
|
|
|
23416
23425
|
commentWall: "{{restated}} of this type's {{commented}} member comments appear to repeat names and types \u2014 review them for removal or clearer naming. Keep constraints and rationale."
|
|
23417
23426
|
}
|
|
23418
23427
|
},
|
|
23419
|
-
defaultOptions: [WALL_DEFAULTS],
|
|
23420
23428
|
create(context, [provided]) {
|
|
23421
23429
|
const options = { ...WALL_DEFAULTS, ...provided };
|
|
23422
23430
|
const sourceCode = context.sourceCode;
|
|
@@ -23977,12 +23985,12 @@ var no_first_party_module_mock_default = createRule({
|
|
|
23977
23985
|
name: "no-first-party-module-mock",
|
|
23978
23986
|
documentation: NO_FIRST_PARTY_MODULE_MOCK_DOCUMENTATION,
|
|
23979
23987
|
meta: {
|
|
23988
|
+
defaultOptions: [{ additionalModulePrefixes: [] }],
|
|
23980
23989
|
type: "problem",
|
|
23981
23990
|
docs: { description: NO_FIRST_PARTY_MODULE_MOCK_DOCUMENTATION.summary },
|
|
23982
|
-
schema: [{ type: "object", additionalProperties: false, properties: { additionalModulePrefixes: { type: "array", items: { type: "string", minLength: 1 }, uniqueItems: true } } }],
|
|
23991
|
+
schema: [{ type: "object", additionalProperties: false, properties: { additionalModulePrefixes: { description: "Additional maintained module prefixes that tests must not mock.", type: "array", items: { type: "string", minLength: 1 }, uniqueItems: true } } }],
|
|
23983
23992
|
messages: { noFirstPartyModuleMock: "This test replaces the maintained module `{{module}}`. Inject a narrow collaborator or test the real module; suppress locally only when module lookup or bootstrap behavior is the contract." }
|
|
23984
23993
|
},
|
|
23985
|
-
defaultOptions: [{ additionalModulePrefixes: [] }],
|
|
23986
23994
|
create(context, [options]) {
|
|
23987
23995
|
if (!isTestFile(context) || isGeneratedFile(context, context.sourceCode.text)) return {};
|
|
23988
23996
|
return {
|
|
@@ -26196,6 +26204,7 @@ var prefer_shadcn_primitives_default = createRule({
|
|
|
26196
26204
|
name: "prefer-shadcn-primitives",
|
|
26197
26205
|
documentation: PREFER_SHADCN_PRIMITIVES_DOCUMENTATION,
|
|
26198
26206
|
meta: {
|
|
26207
|
+
defaultOptions: [{}],
|
|
26199
26208
|
type: "suggestion",
|
|
26200
26209
|
docs: {
|
|
26201
26210
|
description: "Require visible raw JSX controls to use the corresponding shared shadcn primitive."
|
|
@@ -26204,8 +26213,8 @@ var prefer_shadcn_primitives_default = createRule({
|
|
|
26204
26213
|
{
|
|
26205
26214
|
type: "object",
|
|
26206
26215
|
properties: {
|
|
26207
|
-
assumeAvailable: { type: "boolean" },
|
|
26208
|
-
detectProjectPrimitives: { type: "boolean" }
|
|
26216
|
+
assumeAvailable: { description: "Assume supported shared UI primitives are available in this project.", type: "boolean" },
|
|
26217
|
+
detectProjectPrimitives: { description: "Resolve project-owned UI primitives before recommending replacements.", type: "boolean" }
|
|
26209
26218
|
},
|
|
26210
26219
|
additionalProperties: false
|
|
26211
26220
|
}
|
|
@@ -26214,7 +26223,6 @@ var prefer_shadcn_primitives_default = createRule({
|
|
|
26214
26223
|
preferShadcnPrimitive: "Use the shared {{ replacement }} shadcn primitive instead of raw <{{ element }}> markup."
|
|
26215
26224
|
}
|
|
26216
26225
|
},
|
|
26217
|
-
defaultOptions: [{}],
|
|
26218
26226
|
create(context, [options]) {
|
|
26219
26227
|
const filename = context.filename.replaceAll("\\", "/");
|
|
26220
26228
|
if (isTestFile(context) || isStoryFile(context) || isGeneratedFile(context, context.sourceCode.text) || SHARED_PRIMITIVE_IMPLEMENTATION_RE.test(filename)) {
|
|
@@ -26591,6 +26599,7 @@ var prefer_module_level_constant_default = createRule({
|
|
|
26591
26599
|
name: "prefer-module-level-constant",
|
|
26592
26600
|
documentation: PREFER_MODULE_LEVEL_CONSTANT_DOCUMENTATION,
|
|
26593
26601
|
meta: {
|
|
26602
|
+
defaultOptions: [{}],
|
|
26594
26603
|
type: "suggestion",
|
|
26595
26604
|
fixable: "code",
|
|
26596
26605
|
docs: {
|
|
@@ -26601,9 +26610,9 @@ var prefer_module_level_constant_default = createRule({
|
|
|
26601
26610
|
type: "object",
|
|
26602
26611
|
additionalProperties: false,
|
|
26603
26612
|
properties: {
|
|
26604
|
-
minElements: { type: "number", minimum: 1 },
|
|
26605
|
-
checkRegex: { type: "boolean" },
|
|
26606
|
-
ignoreTestFiles: { type: "boolean" }
|
|
26613
|
+
minElements: { description: "Minimum collection size before recommending a module-level constant.", type: "number", minimum: 1 },
|
|
26614
|
+
checkRegex: { description: "Include reusable regular expression literals in hoisting checks.", type: "boolean" },
|
|
26615
|
+
ignoreTestFiles: { description: "Skip test files when recommending module-level constants.", type: "boolean" }
|
|
26607
26616
|
}
|
|
26608
26617
|
}
|
|
26609
26618
|
],
|
|
@@ -26612,7 +26621,6 @@ var prefer_module_level_constant_default = createRule({
|
|
|
26612
26621
|
hoistRegex: "`{{name}}` is a constant regex recompiled on every call. Hoist it to module scope."
|
|
26613
26622
|
}
|
|
26614
26623
|
},
|
|
26615
|
-
defaultOptions: [{}],
|
|
26616
26624
|
create(context, [optionsArg]) {
|
|
26617
26625
|
const options = optionsArg ?? {};
|
|
26618
26626
|
const minElements = options.minElements ?? DEFAULT_MIN_ELEMENTS;
|
|
@@ -26921,6 +26929,7 @@ var prefer_module_level_schema_default = createRule({
|
|
|
26921
26929
|
name: "prefer-module-level-schema",
|
|
26922
26930
|
documentation: PREFER_MODULE_LEVEL_SCHEMA_DOCUMENTATION,
|
|
26923
26931
|
meta: {
|
|
26932
|
+
defaultOptions: [{}],
|
|
26924
26933
|
type: "problem",
|
|
26925
26934
|
docs: {
|
|
26926
26935
|
description: "Declare a Zod schema at module scope when it closes over nothing in the enclosing function"
|
|
@@ -26956,7 +26965,6 @@ var prefer_module_level_schema_default = createRule({
|
|
|
26956
26965
|
hoistSchema: "Move this `{{factory}}` schema to module scope. It uses nothing from `{{owner}}`, so it is rebuilt on every call for no benefit and cannot be exported, reused, or `z.infer`-ed from where it is."
|
|
26957
26966
|
}
|
|
26958
26967
|
},
|
|
26959
|
-
defaultOptions: [{}],
|
|
26960
26968
|
create(context, [options]) {
|
|
26961
26969
|
const factories = new Set(options?.factories ?? DEFAULT_FACTORIES);
|
|
26962
26970
|
const ignoreTestFiles = options?.ignoreTestFiles ?? true;
|
|
@@ -27615,6 +27623,7 @@ var prefer_multi_value_zod_literal_default = createRule({
|
|
|
27615
27623
|
name: "prefer-multi-value-zod-literal",
|
|
27616
27624
|
documentation: PREFER_MULTI_VALUE_ZOD_LITERAL_DOCUMENTATION,
|
|
27617
27625
|
meta: {
|
|
27626
|
+
defaultOptions: [{}],
|
|
27618
27627
|
type: "suggestion",
|
|
27619
27628
|
docs: {
|
|
27620
27629
|
description: "Use the Zod 4 multi-value literal API instead of a union of literal schemas."
|
|
@@ -27624,7 +27633,7 @@ var prefer_multi_value_zod_literal_default = createRule({
|
|
|
27624
27633
|
type: "object",
|
|
27625
27634
|
additionalProperties: false,
|
|
27626
27635
|
properties: {
|
|
27627
|
-
zodMajorVersion: { type: "integer", minimum: 4, maximum: 4 }
|
|
27636
|
+
zodMajorVersion: { description: "Installed Zod major version used to validate multi-value literal support.", type: "integer", minimum: 4, maximum: 4 }
|
|
27628
27637
|
}
|
|
27629
27638
|
}
|
|
27630
27639
|
],
|
|
@@ -27632,7 +27641,6 @@ var prefer_multi_value_zod_literal_default = createRule({
|
|
|
27632
27641
|
useMultiValueLiteral: "Replace this literal-schema union with {{zod}}.literal([\u2026])."
|
|
27633
27642
|
}
|
|
27634
27643
|
},
|
|
27635
|
-
defaultOptions: [{}],
|
|
27636
27644
|
create(context, [options]) {
|
|
27637
27645
|
if (isTestFile(context) || isGeneratedFile(context, context.sourceCode.text))
|
|
27638
27646
|
return {};
|
|
@@ -29715,13 +29723,14 @@ var prefer_await_in_async_return_default = createRule({
|
|
|
29715
29723
|
name: "prefer-await-in-async-return",
|
|
29716
29724
|
documentation: PREFER_AWAIT_IN_ASYNC_RETURN_DOCUMENTATION,
|
|
29717
29725
|
meta: {
|
|
29726
|
+
defaultOptions: [{ scope: "async-return" }],
|
|
29718
29727
|
type: "suggestion",
|
|
29719
29728
|
docs: {
|
|
29720
29729
|
description: "Prefer explicit `await` for proven Promise `.then` calls; the default scope checks direct async returns."
|
|
29721
29730
|
},
|
|
29722
29731
|
schema: [{
|
|
29723
29732
|
type: "object",
|
|
29724
|
-
properties: { scope: { type: "string", enum: ["async-return", "all-promise-calls"] } },
|
|
29733
|
+
properties: { scope: { description: "Check async return statements or every promise-valued call.", type: "string", enum: ["async-return", "all-promise-calls"] } },
|
|
29725
29734
|
additionalProperties: false
|
|
29726
29735
|
}],
|
|
29727
29736
|
messages: {
|
|
@@ -29729,7 +29738,6 @@ var prefer_await_in_async_return_default = createRule({
|
|
|
29729
29738
|
preferAwaitCall: "This call uses built-in Promise.then(). Use async/await, preserving rejection handling and observable scheduling when rewriting."
|
|
29730
29739
|
}
|
|
29731
29740
|
},
|
|
29732
|
-
defaultOptions: [{ scope: "async-return" }],
|
|
29733
29741
|
create(context, [options]) {
|
|
29734
29742
|
let services;
|
|
29735
29743
|
try {
|
|
@@ -30943,6 +30951,7 @@ var prefer_semantic_colors_default = createRule({
|
|
|
30943
30951
|
name: "prefer-semantic-colors",
|
|
30944
30952
|
documentation: PREFER_SEMANTIC_COLORS_DOCUMENTATION,
|
|
30945
30953
|
meta: {
|
|
30954
|
+
defaultOptions: [{}],
|
|
30946
30955
|
type: "suggestion",
|
|
30947
30956
|
docs: {
|
|
30948
30957
|
description: "Enforce semantic color tokens over raw Tailwind palette classes, arbitrary color values, and inline color literals."
|
|
@@ -30952,8 +30961,8 @@ var prefer_semantic_colors_default = createRule({
|
|
|
30952
30961
|
type: "object",
|
|
30953
30962
|
additionalProperties: false,
|
|
30954
30963
|
properties: {
|
|
30955
|
-
requireSemanticTokens: { type: "boolean" },
|
|
30956
|
-
opaqueForegroundPairs: { type: "boolean" }
|
|
30964
|
+
requireSemanticTokens: { description: "Restrict checks to projects with an existing semantic token system.", type: "boolean" },
|
|
30965
|
+
opaqueForegroundPairs: { description: "Use the project semantic foreground roles to check opaque foreground and background pairs.", type: "boolean" }
|
|
30957
30966
|
}
|
|
30958
30967
|
}
|
|
30959
30968
|
],
|
|
@@ -30964,7 +30973,6 @@ var prefer_semantic_colors_default = createRule({
|
|
|
30964
30973
|
opaqueForegroundPair: "'{{class}}' bypasses the declared '{{replacement}}' token paired with '{{background}}'."
|
|
30965
30974
|
}
|
|
30966
30975
|
},
|
|
30967
|
-
defaultOptions: [{}],
|
|
30968
30976
|
create(context, [options]) {
|
|
30969
30977
|
if (STORIES_FILE_RE.test(context.filename)) return {};
|
|
30970
30978
|
if (staticallyImportsExternalRenderer(context.sourceCode.ast)) return {};
|
|
@@ -31266,6 +31274,7 @@ var prefer_server_actions_default = createRule({
|
|
|
31266
31274
|
name: "prefer-server-actions",
|
|
31267
31275
|
documentation: PREFER_SERVER_ACTIONS_DOCUMENTATION,
|
|
31268
31276
|
meta: {
|
|
31277
|
+
defaultOptions: [{}],
|
|
31269
31278
|
type: "suggestion",
|
|
31270
31279
|
docs: {
|
|
31271
31280
|
description: "Prefer Next.js Server Actions over same-origin API mutations."
|
|
@@ -31276,6 +31285,7 @@ var prefer_server_actions_default = createRule({
|
|
|
31276
31285
|
additionalProperties: false,
|
|
31277
31286
|
properties: {
|
|
31278
31287
|
basePath: {
|
|
31288
|
+
description: "Static application URL base path without query strings, fragments or parent segments.",
|
|
31279
31289
|
type: "string",
|
|
31280
31290
|
pattern: "^/(?!$)(?!.*[?#])(?!(?:.*/)?\\.\\.?(?:/|$))(?:[^/]+/)*[^/]+$"
|
|
31281
31291
|
}
|
|
@@ -31286,7 +31296,6 @@ var prefer_server_actions_default = createRule({
|
|
|
31286
31296
|
preferServerAction: "This client mutation targets a same-origin API route. Consider a Server Action to remove the hand-written API wrapper; retain authorization and validation, since the call still crosses a network boundary."
|
|
31287
31297
|
}
|
|
31288
31298
|
},
|
|
31289
|
-
defaultOptions: [{}],
|
|
31290
31299
|
create(context, [options]) {
|
|
31291
31300
|
const filename = context.filename.replaceAll("\\", "/");
|
|
31292
31301
|
if (SKIP_FILE_REGEX.test(filename)) {
|
|
@@ -32300,6 +32309,7 @@ var prefer_zod_infer_default = createRule({
|
|
|
32300
32309
|
name: "prefer-zod-infer",
|
|
32301
32310
|
documentation: PREFER_ZOD_INFER_DOCUMENTATION,
|
|
32302
32311
|
meta: {
|
|
32312
|
+
defaultOptions: [{}],
|
|
32303
32313
|
type: "problem",
|
|
32304
32314
|
fixable: "code",
|
|
32305
32315
|
docs: {
|
|
@@ -32311,10 +32321,11 @@ var prefer_zod_infer_default = createRule({
|
|
|
32311
32321
|
additionalProperties: false,
|
|
32312
32322
|
properties: {
|
|
32313
32323
|
ignoreTypeNames: {
|
|
32324
|
+
description: "Regular expression patterns for type names to leave unchanged.",
|
|
32314
32325
|
type: "array",
|
|
32315
32326
|
items: { type: "string" }
|
|
32316
32327
|
},
|
|
32317
|
-
requireIdenticalShape: { type: "boolean" }
|
|
32328
|
+
requireIdenticalShape: { description: "Require the schema output and declared type to have identical property shapes.", type: "boolean" }
|
|
32318
32329
|
}
|
|
32319
32330
|
}
|
|
32320
32331
|
],
|
|
@@ -32323,7 +32334,6 @@ var prefer_zod_infer_default = createRule({
|
|
|
32323
32334
|
repeatedEnumUnion: "`{{propertyName}}` repeats the literal domain already named by `{{typeName}}` and `{{schemaName}}` in multiple object types. Reuse `{{typeName}}` so the accepted values have one source of truth."
|
|
32324
32335
|
}
|
|
32325
32336
|
},
|
|
32326
|
-
defaultOptions: [{}],
|
|
32327
32337
|
create(context, [optionsArg]) {
|
|
32328
32338
|
const ignorePatterns = (optionsArg?.ignoreTypeNames ?? []).map(
|
|
32329
32339
|
(source) => new RegExp(source, "u")
|
|
@@ -33662,6 +33672,7 @@ var require_fetch_timeout_default = createRule({
|
|
|
33662
33672
|
name: "require-fetch-timeout",
|
|
33663
33673
|
documentation: REQUIRE_FETCH_TIMEOUT_DOCUMENTATION,
|
|
33664
33674
|
meta: {
|
|
33675
|
+
defaultOptions: [{}],
|
|
33665
33676
|
type: "problem",
|
|
33666
33677
|
docs: {
|
|
33667
33678
|
description: "Require an explicit abort signal on locally analyzable global fetch calls."
|
|
@@ -33683,7 +33694,6 @@ var require_fetch_timeout_default = createRule({
|
|
|
33683
33694
|
missingSignal: "This `fetch()` has no explicit abort signal. Pass `AbortSignal.timeout(ms)` for a deadline, or an owner-managed signal for cancellation."
|
|
33684
33695
|
}
|
|
33685
33696
|
},
|
|
33686
|
-
defaultOptions: [{}],
|
|
33687
33697
|
create(context, [optionsArg]) {
|
|
33688
33698
|
if (isTestFile(context) || isScriptFile(context)) {
|
|
33689
33699
|
return {};
|
|
@@ -35791,6 +35801,7 @@ var stepdown_default = createRule({
|
|
|
35791
35801
|
name: "stepdown",
|
|
35792
35802
|
documentation: STEPDOWN_DOCUMENTATION,
|
|
35793
35803
|
meta: {
|
|
35804
|
+
defaultOptions: [{}],
|
|
35794
35805
|
type: "suggestion",
|
|
35795
35806
|
fixable: "code",
|
|
35796
35807
|
docs: {
|
|
@@ -35812,7 +35823,6 @@ var stepdown_default = createRule({
|
|
|
35812
35823
|
helperAboveOnlyCaller: "Private helper `{{helper}}` is defined above its only caller `{{caller}}`; move it below the caller."
|
|
35813
35824
|
}
|
|
35814
35825
|
},
|
|
35815
|
-
defaultOptions: [{}],
|
|
35816
35826
|
create(context, [options]) {
|
|
35817
35827
|
if (isTestFile(context) || isGeneratedFile(context, context.sourceCode.text))
|
|
35818
35828
|
return {};
|
package/dist/rule-examples.cjs
CHANGED
|
@@ -199,7 +199,7 @@ async function verifyRuleExamples(rule, setup = {}) {
|
|
|
199
199
|
files: ["**/*.{ts,tsx,js,jsx,mts,cts,mjs,cjs}"],
|
|
200
200
|
languageOptions: { parser: exampleParser, parserOptions: { project: tsconfig, tsconfigRootDir: root, disallowAutomaticSingleRunInference: true } },
|
|
201
201
|
plugins: { "@sarj": { rules: { [spec.ruleId]: rule } } },
|
|
202
|
-
rules: { [ruleId]: ["error", ...example.ruleOptions ?? rule.defaultOptions ?? []] }
|
|
202
|
+
rules: { [ruleId]: ["error", ...example.ruleOptions ?? rule.meta.defaultOptions ?? rule.defaultOptions ?? []] }
|
|
203
203
|
};
|
|
204
204
|
await verifyExample(new import_eslint.Linter({ cwd: root }), config, example, root, ruleId, setup.formatFixedSource);
|
|
205
205
|
} finally {
|
package/dist/rule-examples.js
CHANGED
|
@@ -165,7 +165,7 @@ async function verifyRuleExamples(rule, setup = {}) {
|
|
|
165
165
|
files: ["**/*.{ts,tsx,js,jsx,mts,cts,mjs,cjs}"],
|
|
166
166
|
languageOptions: { parser: exampleParser, parserOptions: { project: tsconfig, tsconfigRootDir: root, disallowAutomaticSingleRunInference: true } },
|
|
167
167
|
plugins: { "@sarj": { rules: { [spec.ruleId]: rule } } },
|
|
168
|
-
rules: { [ruleId]: ["error", ...example.ruleOptions ?? rule.defaultOptions ?? []] }
|
|
168
|
+
rules: { [ruleId]: ["error", ...example.ruleOptions ?? rule.meta.defaultOptions ?? rule.defaultOptions ?? []] }
|
|
169
169
|
};
|
|
170
170
|
await verifyExample(new Linter({ cwd: root }), config, example, root, ruleId, setup.formatFixedSource);
|
|
171
171
|
} finally {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sarj/eslint-plugin",
|
|
3
|
-
"version": "17.1.
|
|
3
|
+
"version": "17.1.3",
|
|
4
4
|
"packageManager": "npm@12.2.1",
|
|
5
5
|
"description": "Custom ESLint rules for hypermodern TypeScript / React / Next.js projects",
|
|
6
6
|
"type": "module",
|
|
@@ -74,6 +74,7 @@
|
|
|
74
74
|
"@vitest/eslint-plugin": "1.6.28",
|
|
75
75
|
"eslint": "10.13.0",
|
|
76
76
|
"eslint-node-test": "1.0.1",
|
|
77
|
+
"eslint-plugin-eslint-plugin": "7.6.2",
|
|
77
78
|
"eslint-plugin-better-tailwindcss": "^4.10.0",
|
|
78
79
|
"eslint-plugin-jest": "29.17.0",
|
|
79
80
|
"eslint-plugin-jsdoc": "65.4.2",
|
|
@@ -94,6 +95,7 @@
|
|
|
94
95
|
"jiti": "2.7.0",
|
|
95
96
|
"prettier": "3.9.10",
|
|
96
97
|
"tsup": "9.0.0",
|
|
98
|
+
"syncpack": "15.3.3",
|
|
97
99
|
"typescript": "npm:@typescript/typescript6@6.0.2",
|
|
98
100
|
"typescript-eslint": "^8.72.0",
|
|
99
101
|
"uuid": "13.0.0",
|