@sarj/eslint-plugin 15.13.1 → 15.13.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 +387 -249
- package/dist/index.d.cts +15 -18
- package/dist/index.d.ts +15 -18
- package/dist/index.js +380 -249
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -23,16 +23,16 @@ function createRule(config) {
|
|
|
23
23
|
}
|
|
24
24
|
return rule;
|
|
25
25
|
}
|
|
26
|
-
function documentationWarnings(
|
|
27
|
-
return Object.entries(
|
|
26
|
+
function documentationWarnings(rules) {
|
|
27
|
+
return Object.entries(rules).filter(([, rule]) => rule.documentation === void 0).map(([name]) => `${name}: source-owned documentation has not been migrated`).sort();
|
|
28
28
|
}
|
|
29
|
-
function publicDocumentation(
|
|
30
|
-
const missing = documentationWarnings(
|
|
29
|
+
function publicDocumentation(rules) {
|
|
30
|
+
const missing = documentationWarnings(rules);
|
|
31
31
|
if (missing.length > 0) {
|
|
32
32
|
throw new TypeError(`cannot publish an incomplete rule catalog:
|
|
33
33
|
${missing.join("\n")}`);
|
|
34
34
|
}
|
|
35
|
-
return Object.entries(
|
|
35
|
+
return Object.entries(rules).sort(([left], [right]) => left.localeCompare(right)).map(([ruleId, rule]) => {
|
|
36
36
|
const spec = rule.documentation;
|
|
37
37
|
if (spec === void 0 || spec.ruleId !== ruleId) {
|
|
38
38
|
throw new TypeError(`${ruleId}: native documentation identity mismatch`);
|
|
@@ -291,7 +291,7 @@ function isScriptFile(filename) {
|
|
|
291
291
|
}
|
|
292
292
|
|
|
293
293
|
// src/rules/enforce-file-structure.ts
|
|
294
|
-
var
|
|
294
|
+
var ENFORCE_FILE_STRUCTURE_DOCUMENTATION = {
|
|
295
295
|
summary: "Require imports before body statements and require `use server` to be the first statement.",
|
|
296
296
|
rationale: "Interleaved imports obscure module dependencies, while a displaced `use server` string is not an active directive.",
|
|
297
297
|
remediation: "Move `use server` to the first statement when present, then place imports before declarations and executable statements.",
|
|
@@ -341,7 +341,7 @@ var isUseServerDirective = (statement) => {
|
|
|
341
341
|
};
|
|
342
342
|
var enforce_file_structure_default = createRule({
|
|
343
343
|
name: "enforce-file-structure",
|
|
344
|
-
documentation:
|
|
344
|
+
documentation: ENFORCE_FILE_STRUCTURE_DOCUMENTATION,
|
|
345
345
|
meta: {
|
|
346
346
|
type: "suggestion",
|
|
347
347
|
docs: {
|
|
@@ -416,7 +416,7 @@ var OMITTED_AST_KEYS = /* @__PURE__ */ new Set([
|
|
|
416
416
|
var MIN_STATEMENTS = 3;
|
|
417
417
|
var MAX_NORMALIZED_STRING_LENGTH = 64;
|
|
418
418
|
var TEST_MODULES = /* @__PURE__ */ new Set(["@jest/globals", "@playwright/test", "bun:test", "node:test", "vitest"]);
|
|
419
|
-
var
|
|
419
|
+
var DUPLICATE_TEST_BODY_DOCUMENTATION = {
|
|
420
420
|
summary: "Disallow substantial sibling tests with the same body shape; express their differing inputs as a parameterized case table.",
|
|
421
421
|
rationale: "Copy-pasted test bodies hide the cases that differ and allow equivalent assertions to drift independently.",
|
|
422
422
|
remediation: "Move the varying inputs and expected values into a case table consumed by `test.each(...)` or `it.each(...)`.",
|
|
@@ -614,7 +614,7 @@ function isDuplicateTestFrameworkIdentifier(identifier, sourceCode) {
|
|
|
614
614
|
}
|
|
615
615
|
var duplicate_test_body_default = createRule({
|
|
616
616
|
name: "duplicate-test-body",
|
|
617
|
-
documentation:
|
|
617
|
+
documentation: DUPLICATE_TEST_BODY_DOCUMENTATION,
|
|
618
618
|
meta: {
|
|
619
619
|
type: "suggestion",
|
|
620
620
|
docs: {
|
|
@@ -648,7 +648,7 @@ var duplicate_test_body_default = createRule({
|
|
|
648
648
|
|
|
649
649
|
// src/rules/no-client-side-data-fetching.ts
|
|
650
650
|
import { AST_NODE_TYPES as AST_NODE_TYPES3 } from "@typescript-eslint/utils";
|
|
651
|
-
var
|
|
651
|
+
var NO_CLIENT_SIDE_DATA_FETCHING_DOCUMENTATION = {
|
|
652
652
|
summary: "Disallow direct data fetching inside `useEffect` or `useLayoutEffect`.",
|
|
653
653
|
rationale: "Effect-driven reads begin after rendering and can create request waterfalls, duplicate fetches, and loading-state layout shifts.",
|
|
654
654
|
remediation: "Fetch in a React Server Component or Server Action, or use a client cache such as SWR or React Query.",
|
|
@@ -775,7 +775,7 @@ function extractUrlString(node) {
|
|
|
775
775
|
}
|
|
776
776
|
var no_client_side_data_fetching_default = createRule({
|
|
777
777
|
name: "no-client-side-data-fetching",
|
|
778
|
-
documentation:
|
|
778
|
+
documentation: NO_CLIENT_SIDE_DATA_FETCHING_DOCUMENTATION,
|
|
779
779
|
meta: {
|
|
780
780
|
type: "problem",
|
|
781
781
|
docs: {
|
|
@@ -1000,7 +1000,7 @@ function headTokens(source) {
|
|
|
1000
1000
|
}
|
|
1001
1001
|
|
|
1002
1002
|
// src/rules/no-comment-cruft.ts
|
|
1003
|
-
var
|
|
1003
|
+
var NO_COMMENT_CRUFT_DOCUMENTATION = {
|
|
1004
1004
|
summary: "Flag commented-out code, section-banner comments, and leading file-header comment preambles.",
|
|
1005
1005
|
rationale: "Decorative, narrated, or dead-code comments obscure the constraints and rationale that comments should preserve.",
|
|
1006
1006
|
remediation: "Delete dead code and narration; express boundaries with named code and retain only comments that explain constraints or intent.",
|
|
@@ -1400,7 +1400,7 @@ function hasCommentedOutCode(texts, precedingProse, allowCall) {
|
|
|
1400
1400
|
}
|
|
1401
1401
|
var no_comment_cruft_default = createRule({
|
|
1402
1402
|
name: "no-comment-cruft",
|
|
1403
|
-
documentation:
|
|
1403
|
+
documentation: NO_COMMENT_CRUFT_DOCUMENTATION,
|
|
1404
1404
|
meta: {
|
|
1405
1405
|
type: "suggestion",
|
|
1406
1406
|
docs: {
|
|
@@ -1615,7 +1615,7 @@ import {
|
|
|
1615
1615
|
AST_NODE_TYPES as AST_NODE_TYPES6,
|
|
1616
1616
|
ASTUtils as ASTUtils2
|
|
1617
1617
|
} from "@typescript-eslint/utils";
|
|
1618
|
-
var
|
|
1618
|
+
var NO_CORS_WILDCARD_WITH_CREDENTIALS_DOCUMENTATION = {
|
|
1619
1619
|
summary: "Disallow wildcard CORS origins when credentials are enabled.",
|
|
1620
1620
|
rationale: "Reflecting every origin while allowing credentials can let an untrusted site read authenticated cross-origin responses.",
|
|
1621
1621
|
remediation: "Enumerate the trusted origins that may receive credentialed responses.",
|
|
@@ -1787,7 +1787,7 @@ function enclosingScope(node) {
|
|
|
1787
1787
|
}
|
|
1788
1788
|
var no_cors_wildcard_with_credentials_default = createRule({
|
|
1789
1789
|
name: "no-cors-wildcard-with-credentials",
|
|
1790
|
-
documentation:
|
|
1790
|
+
documentation: NO_CORS_WILDCARD_WITH_CREDENTIALS_DOCUMENTATION,
|
|
1791
1791
|
meta: {
|
|
1792
1792
|
type: "problem",
|
|
1793
1793
|
docs: {
|
|
@@ -1887,7 +1887,7 @@ var no_cors_wildcard_with_credentials_default = createRule({
|
|
|
1887
1887
|
|
|
1888
1888
|
// src/rules/no-duplicate-lifecycle-refresh-listeners.ts
|
|
1889
1889
|
import { AST_NODE_TYPES as AST_NODE_TYPES7, ASTUtils as ASTUtils3 } from "@typescript-eslint/utils";
|
|
1890
|
-
var
|
|
1890
|
+
var NO_DUPLICATE_LIFECYCLE_REFRESH_LISTENERS_DOCUMENTATION = {
|
|
1891
1891
|
summary: "Do not register one Next.js route-refresh callback for both focus and visibilitychange.",
|
|
1892
1892
|
rationale: "A browser tab activation can emit both lifecycle signals and invoke the same route-wide refresh twice.",
|
|
1893
1893
|
remediation: "Choose one lifecycle signal or route both signals through an explicitly debounced refresh policy.",
|
|
@@ -1932,7 +1932,7 @@ function enclosingFunction(sourceCode, node) {
|
|
|
1932
1932
|
}
|
|
1933
1933
|
var no_duplicate_lifecycle_refresh_listeners_default = createRule({
|
|
1934
1934
|
name: "no-duplicate-lifecycle-refresh-listeners",
|
|
1935
|
-
documentation:
|
|
1935
|
+
documentation: NO_DUPLICATE_LIFECYCLE_REFRESH_LISTENERS_DOCUMENTATION,
|
|
1936
1936
|
meta: {
|
|
1937
1937
|
type: "suggestion",
|
|
1938
1938
|
docs: { description: "Do not register one Next.js route-refresh callback for both focus and visibilitychange." },
|
|
@@ -2012,7 +2012,7 @@ var no_duplicate_lifecycle_refresh_listeners_default = createRule({
|
|
|
2012
2012
|
// src/rules/no-dangerously-allow-svg.ts
|
|
2013
2013
|
import "@typescript-eslint/utils";
|
|
2014
2014
|
var NEXT_CONFIG_RE = /(?:^|\/)next\.config\.[cm]?[jt]s$/;
|
|
2015
|
-
var
|
|
2015
|
+
var NO_DANGEROUSLY_ALLOW_SVG_DOCUMENTATION = {
|
|
2016
2016
|
summary: "Next.js image configuration enables unsanitized SVG rendering",
|
|
2017
2017
|
rationale: "SVG files can contain scripts and other active content; enabling dangerouslyAllowSVG makes the image optimizer serve that content from the application origin.",
|
|
2018
2018
|
remediation: "Keep dangerouslyAllowSVG disabled. If SVG delivery is unavoidable, use a separately reviewed asset path with restrictive Content-Disposition and Content-Security-Policy headers.",
|
|
@@ -2048,10 +2048,10 @@ function propertyName(node) {
|
|
|
2048
2048
|
}
|
|
2049
2049
|
var no_dangerously_allow_svg_default = createRule({
|
|
2050
2050
|
name: "no-dangerously-allow-svg",
|
|
2051
|
-
documentation:
|
|
2051
|
+
documentation: NO_DANGEROUSLY_ALLOW_SVG_DOCUMENTATION,
|
|
2052
2052
|
meta: {
|
|
2053
2053
|
type: "problem",
|
|
2054
|
-
docs: { description:
|
|
2054
|
+
docs: { description: NO_DANGEROUSLY_ALLOW_SVG_DOCUMENTATION.summary },
|
|
2055
2055
|
schema: [],
|
|
2056
2056
|
messages: {
|
|
2057
2057
|
noDangerouslyAllowSvg: "Do not enable dangerouslyAllowSVG. SVG can carry active content served from the application origin."
|
|
@@ -2217,7 +2217,7 @@ function createSqlListener(handler) {
|
|
|
2217
2217
|
}
|
|
2218
2218
|
|
|
2219
2219
|
// src/rules/no-dynamic-sql.ts
|
|
2220
|
-
var
|
|
2220
|
+
var NO_DYNAMIC_SQL_DOCUMENTATION = {
|
|
2221
2221
|
summary: "Disallow runtime values embedded inside quoted SQL values passed to statement-execution methods.",
|
|
2222
2222
|
rationale: "Embedding runtime values in SQL bypasses driver parameterization and can introduce injection defects or unstable query plans.",
|
|
2223
2223
|
remediation: "Use SQL placeholders and pass runtime values through the driver's binding API.",
|
|
@@ -2335,11 +2335,11 @@ function statementMethodName(node, methods) {
|
|
|
2335
2335
|
}
|
|
2336
2336
|
var no_dynamic_sql_default = createRule({
|
|
2337
2337
|
name: "no-dynamic-sql",
|
|
2338
|
-
documentation:
|
|
2338
|
+
documentation: NO_DYNAMIC_SQL_DOCUMENTATION,
|
|
2339
2339
|
meta: {
|
|
2340
2340
|
type: "problem",
|
|
2341
2341
|
docs: {
|
|
2342
|
-
description:
|
|
2342
|
+
description: NO_DYNAMIC_SQL_DOCUMENTATION.summary
|
|
2343
2343
|
},
|
|
2344
2344
|
schema: [
|
|
2345
2345
|
{
|
|
@@ -2386,7 +2386,7 @@ var no_dynamic_sql_default = createRule({
|
|
|
2386
2386
|
|
|
2387
2387
|
// src/rules/no-enum.ts
|
|
2388
2388
|
import "@typescript-eslint/utils";
|
|
2389
|
-
var
|
|
2389
|
+
var NO_ENUM_DOCUMENTATION = {
|
|
2390
2390
|
summary: "Disallow TypeScript `enum`; use string-literal unions or `as const` objects instead.",
|
|
2391
2391
|
rationale: "TypeScript enums emit runtime objects and numeric enums accept values outside their declared members, adding behavior where a type-only model is sufficient.",
|
|
2392
2392
|
remediation: "Replace the enum with a string-literal union or an `as const` object and derive its value type from that object.",
|
|
@@ -2423,7 +2423,7 @@ function matchesAnyPattern(filename, patterns) {
|
|
|
2423
2423
|
}
|
|
2424
2424
|
var no_enum_default = createRule({
|
|
2425
2425
|
name: "no-enum",
|
|
2426
|
-
documentation:
|
|
2426
|
+
documentation: NO_ENUM_DOCUMENTATION,
|
|
2427
2427
|
meta: {
|
|
2428
2428
|
type: "suggestion",
|
|
2429
2429
|
docs: {
|
|
@@ -2469,7 +2469,7 @@ var no_enum_default = createRule({
|
|
|
2469
2469
|
|
|
2470
2470
|
// src/rules/no-fat-try-blocks.ts
|
|
2471
2471
|
import { AST_NODE_TYPES as AST_NODE_TYPES10 } from "@typescript-eslint/utils";
|
|
2472
|
-
var
|
|
2472
|
+
var NO_FAT_TRY_BLOCKS_DOCUMENTATION = {
|
|
2473
2473
|
summary: "Disallow `try` blocks containing more than three top-level operations that can throw.",
|
|
2474
2474
|
rationale: "A broad `try` block obscures which operation failed and encourages one catch clause to recover from unrelated errors.",
|
|
2475
2475
|
remediation: "Keep only the operations that share one recovery policy inside the `try` block and move other work outside it.",
|
|
@@ -2858,7 +2858,7 @@ var handlerReturnsSuccessShaped = (handler) => subtreeMatches(
|
|
|
2858
2858
|
);
|
|
2859
2859
|
var no_fat_try_blocks_default = createRule({
|
|
2860
2860
|
name: "no-fat-try-blocks",
|
|
2861
|
-
documentation:
|
|
2861
|
+
documentation: NO_FAT_TRY_BLOCKS_DOCUMENTATION,
|
|
2862
2862
|
meta: {
|
|
2863
2863
|
type: "problem",
|
|
2864
2864
|
docs: {
|
|
@@ -2915,7 +2915,7 @@ var no_fat_try_blocks_default = createRule({
|
|
|
2915
2915
|
|
|
2916
2916
|
// src/rules/no-hand-rolled-sleep.ts
|
|
2917
2917
|
import { AST_NODE_TYPES as AST_NODE_TYPES11 } from "@typescript-eslint/utils";
|
|
2918
|
-
var
|
|
2918
|
+
var NO_HAND_ROLLED_SLEEP_DOCUMENTATION = {
|
|
2919
2919
|
summary: "Disallow uncancellable promisified timers and timeout arms.",
|
|
2920
2920
|
rationale: "A timer that outlives an aborted operation or a lost promise race retains work and can keep the process alive until it fires.",
|
|
2921
2921
|
remediation: "Use `node:timers/promises` with an abort signal for delays, or pass `AbortSignal.timeout(...)` to the timed operation.",
|
|
@@ -3026,7 +3026,7 @@ function isRaceArm(node) {
|
|
|
3026
3026
|
}
|
|
3027
3027
|
var no_hand_rolled_sleep_default = createRule({
|
|
3028
3028
|
name: "no-hand-rolled-sleep",
|
|
3029
|
-
documentation:
|
|
3029
|
+
documentation: NO_HAND_ROLLED_SLEEP_DOCUMENTATION,
|
|
3030
3030
|
meta: {
|
|
3031
3031
|
type: "problem",
|
|
3032
3032
|
docs: {
|
|
@@ -3123,7 +3123,7 @@ var no_hand_rolled_sleep_default = createRule({
|
|
|
3123
3123
|
|
|
3124
3124
|
// src/rules/no-hand-rolled-spinner.ts
|
|
3125
3125
|
import { AST_NODE_TYPES as AST_NODE_TYPES12 } from "@typescript-eslint/utils";
|
|
3126
|
-
var
|
|
3126
|
+
var NO_HAND_ROLLED_SPINNER_DOCUMENTATION = {
|
|
3127
3127
|
summary: "Disallow intrinsic elements styled as Tailwind border-ring spinners outside the design-system implementation.",
|
|
3128
3128
|
rationale: "One-off loading indicators duplicate a shared primitive and let accessibility and styling diverge.",
|
|
3129
3129
|
remediation: "Render the design-system Spinner component instead.",
|
|
@@ -3169,7 +3169,7 @@ function staticClassName(attribute) {
|
|
|
3169
3169
|
}
|
|
3170
3170
|
var no_hand_rolled_spinner_default = createRule({
|
|
3171
3171
|
name: "no-hand-rolled-spinner",
|
|
3172
|
-
documentation:
|
|
3172
|
+
documentation: NO_HAND_ROLLED_SPINNER_DOCUMENTATION,
|
|
3173
3173
|
meta: {
|
|
3174
3174
|
type: "suggestion",
|
|
3175
3175
|
docs: {
|
|
@@ -3207,7 +3207,7 @@ var no_hand_rolled_spinner_default = createRule({
|
|
|
3207
3207
|
|
|
3208
3208
|
// src/rules/no-insecure-random-id.ts
|
|
3209
3209
|
import "@typescript-eslint/utils";
|
|
3210
|
-
var
|
|
3210
|
+
var NO_INSECURE_RANDOM_ID_DOCUMENTATION = {
|
|
3211
3211
|
summary: "Disallow using `Math.random()` to generate identifiers, tokens, or secrets; use `crypto.randomUUID()` or `crypto.getRandomValues(...)` instead.",
|
|
3212
3212
|
rationale: "Math.random is predictable and lacks the entropy required for security-sensitive values.",
|
|
3213
3213
|
remediation: "Generate the value with crypto.randomUUID or crypto.getRandomValues.",
|
|
@@ -3398,7 +3398,7 @@ function collectStaticStringParts(node, out) {
|
|
|
3398
3398
|
}
|
|
3399
3399
|
var no_insecure_random_id_default = createRule({
|
|
3400
3400
|
name: "no-insecure-random-id",
|
|
3401
|
-
documentation:
|
|
3401
|
+
documentation: NO_INSECURE_RANDOM_ID_DOCUMENTATION,
|
|
3402
3402
|
meta: {
|
|
3403
3403
|
type: "problem",
|
|
3404
3404
|
docs: {
|
|
@@ -3437,7 +3437,7 @@ var no_insecure_random_id_default = createRule({
|
|
|
3437
3437
|
|
|
3438
3438
|
// src/rules/no-json-stringify-error.ts
|
|
3439
3439
|
import "@typescript-eslint/utils";
|
|
3440
|
-
var
|
|
3440
|
+
var NO_JSON_STRINGIFY_ERROR_DOCUMENTATION = {
|
|
3441
3441
|
summary: "Disallow `JSON.stringify` on an Error value; it yields `{}` because `message`/`stack` are non-enumerable.",
|
|
3442
3442
|
rationale: "Native Error details are non-enumerable, so generic JSON serialization discards diagnostic information.",
|
|
3443
3443
|
remediation: "Serialize explicit error fields or use an error-aware serializer.",
|
|
@@ -3630,7 +3630,7 @@ function memberSuggestsError(member, scope) {
|
|
|
3630
3630
|
}
|
|
3631
3631
|
var no_json_stringify_error_default = createRule({
|
|
3632
3632
|
name: "no-json-stringify-error",
|
|
3633
|
-
documentation:
|
|
3633
|
+
documentation: NO_JSON_STRINGIFY_ERROR_DOCUMENTATION,
|
|
3634
3634
|
meta: {
|
|
3635
3635
|
type: "problem",
|
|
3636
3636
|
docs: {
|
|
@@ -3674,15 +3674,13 @@ import {
|
|
|
3674
3674
|
} from "@typescript-eslint/utils";
|
|
3675
3675
|
|
|
3676
3676
|
// src/rules/_zod.ts
|
|
3677
|
-
var ZOD_PREFIX_RE = /^Z[A-Z]/;
|
|
3678
|
-
var ZOD_SUFFIX_RE = /Schema$/;
|
|
3679
3677
|
var ZOD_SCHEMA_NAME_RE = /Schema$|^Z[A-Z]/;
|
|
3680
3678
|
function isZodModule(source) {
|
|
3681
3679
|
return /(^|[/@-])zod([/-]|$)/.test(source);
|
|
3682
3680
|
}
|
|
3683
3681
|
|
|
3684
3682
|
// src/rules/no-impossible-zod-literal-bounds.ts
|
|
3685
|
-
var
|
|
3683
|
+
var NO_IMPOSSIBLE_ZOD_LITERAL_BOUNDS_DOCUMENTATION = {
|
|
3686
3684
|
summary: "Disallow same-chain literal Zod bounds whose accepted set is mathematically empty.",
|
|
3687
3685
|
rationale: "A schema with contradictory literal bounds rejects every input, turning validation into an unreachable contract that usually reflects a typo.",
|
|
3688
3686
|
remediation: "Choose compatible lower and upper bounds, or remove the constraint that does not express the intended domain.",
|
|
@@ -3786,7 +3784,7 @@ function isOutermostCall(node) {
|
|
|
3786
3784
|
}
|
|
3787
3785
|
var no_impossible_zod_literal_bounds_default = createRule({
|
|
3788
3786
|
name: "no-impossible-zod-literal-bounds",
|
|
3789
|
-
documentation:
|
|
3787
|
+
documentation: NO_IMPOSSIBLE_ZOD_LITERAL_BOUNDS_DOCUMENTATION,
|
|
3790
3788
|
meta: {
|
|
3791
3789
|
type: "problem",
|
|
3792
3790
|
docs: {
|
|
@@ -4070,7 +4068,7 @@ function convertibleMemberName(member) {
|
|
|
4070
4068
|
}
|
|
4071
4069
|
|
|
4072
4070
|
// src/rules/interface-contract-members-private.ts
|
|
4073
|
-
var
|
|
4071
|
+
var INTERFACE_CONTRACT_MEMBERS_PRIVATE_DOCUMENTATION = {
|
|
4074
4072
|
summary: "Require methods outside an implemented interface contract to use ECMAScript private names.",
|
|
4075
4073
|
rationale: "An implementing class should expose exactly its declared interface while keeping implementation helpers runtime-private.",
|
|
4076
4074
|
remediation: "Add the method to the interface when it is public API, or make it `#private` and remove external or inherited access.",
|
|
@@ -4149,7 +4147,7 @@ function interfaceNames(services, owner) {
|
|
|
4149
4147
|
}
|
|
4150
4148
|
var interface_contract_members_private_default = createRule({
|
|
4151
4149
|
name: "interface-contract-members-private",
|
|
4152
|
-
documentation:
|
|
4150
|
+
documentation: INTERFACE_CONTRACT_MEMBERS_PRIVATE_DOCUMENTATION,
|
|
4153
4151
|
meta: {
|
|
4154
4152
|
type: "problem",
|
|
4155
4153
|
docs: { description: "Require methods outside an implemented interface contract to use ECMAScript private names." },
|
|
@@ -4281,7 +4279,7 @@ function createLogMatcher(options = {}) {
|
|
|
4281
4279
|
}
|
|
4282
4280
|
|
|
4283
4281
|
// src/rules/no-log-only-catch.ts
|
|
4284
|
-
var
|
|
4282
|
+
var NO_LOG_ONLY_CATCH_DOCUMENTATION = {
|
|
4285
4283
|
summary: "Disallow `catch` clauses that only log (or silently do nothing) and then swallow the error; rethrow or handle it instead.",
|
|
4286
4284
|
rationale: "Swallowing an exception after logging lets execution continue as if the operation succeeded.",
|
|
4287
4285
|
remediation: "Rethrow the error, return an explicit fallback, or perform concrete recovery.",
|
|
@@ -4379,7 +4377,7 @@ function isSeedValue(node) {
|
|
|
4379
4377
|
}
|
|
4380
4378
|
var no_log_only_catch_default = createRule({
|
|
4381
4379
|
name: "no-log-only-catch",
|
|
4382
|
-
documentation:
|
|
4380
|
+
documentation: NO_LOG_ONLY_CATCH_DOCUMENTATION,
|
|
4383
4381
|
meta: {
|
|
4384
4382
|
type: "problem",
|
|
4385
4383
|
docs: {
|
|
@@ -4454,7 +4452,7 @@ var no_log_only_catch_default = createRule({
|
|
|
4454
4452
|
|
|
4455
4453
|
// src/rules/no-bare-return-from-test-catch.ts
|
|
4456
4454
|
import { AST_NODE_TYPES as AST_NODE_TYPES17, ASTUtils as ASTUtils5 } from "@typescript-eslint/utils";
|
|
4457
|
-
var
|
|
4455
|
+
var NO_BARE_RETURN_FROM_TEST_CATCH_DOCUMENTATION = {
|
|
4458
4456
|
summary: "Disallow a bare return from a test catch block when it skips a later assertion.",
|
|
4459
4457
|
rationale: "The caught failure turns into a passing test without executing the assertion that follows it.",
|
|
4460
4458
|
remediation: "Rethrow the error, assert on it, or use the runner's explicit skip mechanism when the capability is optional.",
|
|
@@ -4538,7 +4536,7 @@ function isExplicitSkip(node, context) {
|
|
|
4538
4536
|
}
|
|
4539
4537
|
var no_bare_return_from_test_catch_default = createRule({
|
|
4540
4538
|
name: "no-bare-return-from-test-catch",
|
|
4541
|
-
documentation:
|
|
4539
|
+
documentation: NO_BARE_RETURN_FROM_TEST_CATCH_DOCUMENTATION,
|
|
4542
4540
|
meta: {
|
|
4543
4541
|
type: "problem",
|
|
4544
4542
|
docs: { description: "Disallow a bare return from a test catch block when it skips a later assertion." },
|
|
@@ -4682,7 +4680,7 @@ function typedFunction(node) {
|
|
|
4682
4680
|
}
|
|
4683
4681
|
|
|
4684
4682
|
// src/rules/no-long-comment.ts
|
|
4685
|
-
var
|
|
4683
|
+
var NO_LONG_COMMENT_DOCUMENTATION = {
|
|
4686
4684
|
summary: "Flag unusually large unstructured JSDoc blocks in implementation code.",
|
|
4687
4685
|
rationale: "Large narrative comments become stale and obscure the local facts that belong beside the code.",
|
|
4688
4686
|
remediation: "Keep only durable local constraints and express the remaining behavior in code.",
|
|
@@ -4755,7 +4753,7 @@ function wordUnits(text) {
|
|
|
4755
4753
|
}
|
|
4756
4754
|
var no_long_comment_default = createRule({
|
|
4757
4755
|
name: "no-long-comment",
|
|
4758
|
-
documentation:
|
|
4756
|
+
documentation: NO_LONG_COMMENT_DOCUMENTATION,
|
|
4759
4757
|
meta: {
|
|
4760
4758
|
type: "suggestion",
|
|
4761
4759
|
docs: { description: "Flag unusually large unstructured JSDoc blocks in implementation code." },
|
|
@@ -4782,7 +4780,7 @@ var no_long_comment_default = createRule({
|
|
|
4782
4780
|
// src/rules/no-vague-suppression-description.ts
|
|
4783
4781
|
var DIRECTIVE_WITH_DESCRIPTION_RE = /^(?:eslint-(?:disable|disable-next-line|disable-line)\b[^:\n]*?|@ts-expect-error\b)\s*(?::|--)\s*(.+?)\s*$/iu;
|
|
4784
4782
|
var VAGUE_RE = /^(?:needed|required|intentional(?:ly)?|ignore(?:d)?|false positive|type error|typescript|to satisfy (?:the )?(?:linter|typescript|type checker))\.?$/iu;
|
|
4785
|
-
var
|
|
4783
|
+
var NO_VAGUE_SUPPRESSION_DESCRIPTION_DOCUMENTATION = {
|
|
4786
4784
|
summary: "Require suppression descriptions to name the concrete mismatch or invariant instead of a generic non-reason.",
|
|
4787
4785
|
rationale: "Generic phrases satisfy require-description mechanically while leaving reviewers unable to audit the risk or remove stale debt.",
|
|
4788
4786
|
remediation: "Name the exact type/runtime mismatch, external contract, or safety invariant that makes this suppression acceptable.",
|
|
@@ -4825,7 +4823,7 @@ var noVagueSuppressionDescriptionDocumentation = {
|
|
|
4825
4823
|
};
|
|
4826
4824
|
var no_vague_suppression_description_default = createRule({
|
|
4827
4825
|
name: "no-vague-suppression-description",
|
|
4828
|
-
documentation:
|
|
4826
|
+
documentation: NO_VAGUE_SUPPRESSION_DESCRIPTION_DOCUMENTATION,
|
|
4829
4827
|
meta: {
|
|
4830
4828
|
type: "suggestion",
|
|
4831
4829
|
docs: {
|
|
@@ -4860,7 +4858,7 @@ var no_vague_suppression_description_default = createRule({
|
|
|
4860
4858
|
|
|
4861
4859
|
// src/rules/no-generic-single-export-module.ts
|
|
4862
4860
|
import { AST_NODE_TYPES as AST_NODE_TYPES20, ASTUtils as ASTUtils6 } from "@typescript-eslint/utils";
|
|
4863
|
-
var
|
|
4861
|
+
var NO_GENERIC_SINGLE_EXPORT_MODULE_DOCUMENTATION = {
|
|
4864
4862
|
summary: "Disallow generic module stems when one runtime export already names the responsibility.",
|
|
4865
4863
|
rationale: "A generic filename hides the sole exported responsibility and makes navigation less descriptive.",
|
|
4866
4864
|
remediation: "Choose a responsibility-bearing module name or colocate the export with its domain.",
|
|
@@ -4998,7 +4996,7 @@ function memberPropertyName(node) {
|
|
|
4998
4996
|
}
|
|
4999
4997
|
var no_generic_single_export_module_default = createRule({
|
|
5000
4998
|
name: "no-generic-single-export-module",
|
|
5001
|
-
documentation:
|
|
4999
|
+
documentation: NO_GENERIC_SINGLE_EXPORT_MODULE_DOCUMENTATION,
|
|
5002
5000
|
meta: {
|
|
5003
5001
|
type: "suggestion",
|
|
5004
5002
|
docs: { description: "Disallow generic module stems when one runtime export already names the responsibility." },
|
|
@@ -5045,7 +5043,7 @@ var no_generic_single_export_module_default = createRule({
|
|
|
5045
5043
|
|
|
5046
5044
|
// src/rules/no-offset-pagination.ts
|
|
5047
5045
|
import "@typescript-eslint/utils";
|
|
5048
|
-
var
|
|
5046
|
+
var NO_OFFSET_PAGINATION_DOCUMENTATION = {
|
|
5049
5047
|
summary: "Disallow OFFSET pagination in embedded SQL; it is O(N) per page and drops or repeats rows under concurrent writes. Use a keyset cursor.",
|
|
5050
5048
|
rationale: "Offset pagination scans skipped rows and shifts page boundaries under concurrent writes.",
|
|
5051
5049
|
remediation: "Page with a stable ordered key and a cursor predicate.",
|
|
@@ -5060,7 +5058,7 @@ var OFFSET_PAGINATION = /\bOFFSET\s+(?:%s|%\(\w+\)s|\?\d*|:\w+|@\w+|\$\d+|\d+)/i
|
|
|
5060
5058
|
var OFFSET_GATE = /offset/i;
|
|
5061
5059
|
var no_offset_pagination_default = createRule({
|
|
5062
5060
|
name: "no-offset-pagination",
|
|
5063
|
-
documentation:
|
|
5061
|
+
documentation: NO_OFFSET_PAGINATION_DOCUMENTATION,
|
|
5064
5062
|
meta: {
|
|
5065
5063
|
type: "problem",
|
|
5066
5064
|
docs: {
|
|
@@ -5087,7 +5085,7 @@ var no_offset_pagination_default = createRule({
|
|
|
5087
5085
|
|
|
5088
5086
|
// src/rules/no-positional-tuple-return.ts
|
|
5089
5087
|
import { AST_NODE_TYPES as AST_NODE_TYPES21 } from "@typescript-eslint/utils";
|
|
5090
|
-
var
|
|
5088
|
+
var NO_POSITIONAL_TUPLE_RETURN_DOCUMENTATION = {
|
|
5091
5089
|
summary: "Disallow returning a multi-field tuple from a named function; return a named object so call sites cannot mismatch slots.",
|
|
5092
5090
|
rationale: "Tuple fields are identified only by position, so reordering can preserve types while changing meaning.",
|
|
5093
5091
|
remediation: "Return an object whose property names describe each value.",
|
|
@@ -5331,7 +5329,7 @@ function isExportedInterface(node, exports) {
|
|
|
5331
5329
|
}
|
|
5332
5330
|
var no_positional_tuple_return_default = createRule({
|
|
5333
5331
|
name: "no-positional-tuple-return",
|
|
5334
|
-
documentation:
|
|
5332
|
+
documentation: NO_POSITIONAL_TUPLE_RETURN_DOCUMENTATION,
|
|
5335
5333
|
meta: {
|
|
5336
5334
|
type: "suggestion",
|
|
5337
5335
|
docs: {
|
|
@@ -5460,7 +5458,7 @@ var no_positional_tuple_return_default = createRule({
|
|
|
5460
5458
|
// src/rules/no-production-browser-source-maps.ts
|
|
5461
5459
|
import "@typescript-eslint/utils";
|
|
5462
5460
|
var NEXT_CONFIG_RE2 = /(?:^|\/)next\.config\.[cm]?[jt]s$/;
|
|
5463
|
-
var
|
|
5461
|
+
var NO_PRODUCTION_BROWSER_SOURCE_MAPS_DOCUMENTATION = {
|
|
5464
5462
|
summary: "Next.js production browser source maps expose application source",
|
|
5465
5463
|
rationale: "Next.js production browser source maps publish original client source and implementation details to every browser that can load the deployment.",
|
|
5466
5464
|
remediation: "Leave productionBrowserSourceMaps disabled and upload private source maps directly to the error-monitoring service during the build.",
|
|
@@ -5496,10 +5494,10 @@ function propertyName2(node) {
|
|
|
5496
5494
|
}
|
|
5497
5495
|
var no_production_browser_source_maps_default = createRule({
|
|
5498
5496
|
name: "no-production-browser-source-maps",
|
|
5499
|
-
documentation:
|
|
5497
|
+
documentation: NO_PRODUCTION_BROWSER_SOURCE_MAPS_DOCUMENTATION,
|
|
5500
5498
|
meta: {
|
|
5501
5499
|
type: "problem",
|
|
5502
|
-
docs: { description:
|
|
5500
|
+
docs: { description: NO_PRODUCTION_BROWSER_SOURCE_MAPS_DOCUMENTATION.summary },
|
|
5503
5501
|
schema: [],
|
|
5504
5502
|
messages: {
|
|
5505
5503
|
noProductionBrowserSourceMaps: "Do not publish production browser source maps. Upload private maps to your monitoring service instead."
|
|
@@ -5520,7 +5518,7 @@ var no_production_browser_source_maps_default = createRule({
|
|
|
5520
5518
|
|
|
5521
5519
|
// src/rules/no-raw-env.ts
|
|
5522
5520
|
import "@typescript-eslint/utils";
|
|
5523
|
-
var
|
|
5521
|
+
var NO_RAW_ENV_DOCUMENTATION = {
|
|
5524
5522
|
summary: "Disallow direct `process.env` and `import.meta.env` reads outside validated boundaries.",
|
|
5525
5523
|
rationale: "Raw environment reads are untyped and defer invalid configuration failures until use.",
|
|
5526
5524
|
remediation: "Validate environment values at startup and import the typed configuration object.",
|
|
@@ -5577,7 +5575,7 @@ function isWholeEnvSpread(node) {
|
|
|
5577
5575
|
}
|
|
5578
5576
|
var no_raw_env_default = createRule({
|
|
5579
5577
|
name: "no-raw-env",
|
|
5580
|
-
documentation:
|
|
5578
|
+
documentation: NO_RAW_ENV_DOCUMENTATION,
|
|
5581
5579
|
meta: {
|
|
5582
5580
|
type: "problem",
|
|
5583
5581
|
docs: {
|
|
@@ -5609,7 +5607,7 @@ var no_raw_env_default = createRule({
|
|
|
5609
5607
|
|
|
5610
5608
|
// src/rules/no-raw-fetch-outside-clients.ts
|
|
5611
5609
|
import { AST_NODE_TYPES as AST_NODE_TYPES22, ASTUtils as ASTUtils7 } from "@typescript-eslint/utils";
|
|
5612
|
-
var
|
|
5610
|
+
var NO_RAW_FETCH_OUTSIDE_CLIENTS_DOCUMENTATION = {
|
|
5613
5611
|
summary: "Disallow calling the global `fetch` outside the client layer; route outbound HTTP through a client module that owns retry, timeout and status handling.",
|
|
5614
5612
|
rationale: "Scattered fetch calls bypass shared transport policy and are harder to stub and observe consistently.",
|
|
5615
5613
|
remediation: "Move the request into a client module and call that abstraction from application code.",
|
|
@@ -5741,7 +5739,7 @@ function compile(patterns) {
|
|
|
5741
5739
|
}
|
|
5742
5740
|
var no_raw_fetch_outside_clients_default = createRule({
|
|
5743
5741
|
name: "no-raw-fetch-outside-clients",
|
|
5744
|
-
documentation:
|
|
5742
|
+
documentation: NO_RAW_FETCH_OUTSIDE_CLIENTS_DOCUMENTATION,
|
|
5745
5743
|
meta: {
|
|
5746
5744
|
type: "problem",
|
|
5747
5745
|
docs: {
|
|
@@ -5871,7 +5869,7 @@ var no_raw_fetch_outside_clients_default = createRule({
|
|
|
5871
5869
|
|
|
5872
5870
|
// src/rules/no-restricted-library-load.ts
|
|
5873
5871
|
import { AST_NODE_TYPES as AST_NODE_TYPES23, ASTUtils as ASTUtils8 } from "@typescript-eslint/utils";
|
|
5874
|
-
var
|
|
5872
|
+
var NO_RESTRICTED_LIBRARY_LOAD_DOCUMENTATION = {
|
|
5875
5873
|
summary: "Apply a configured library-replacement policy to literal dynamic imports, CommonJS loads, and TypeScript import-equals declarations.",
|
|
5876
5874
|
rationale: "Runtime module loads can bypass the replacement policy enforced for static imports.",
|
|
5877
5875
|
remediation: "Load the configured replacement library instead of the restricted module.",
|
|
@@ -5890,7 +5888,7 @@ function matchesModule(source, module) {
|
|
|
5890
5888
|
}
|
|
5891
5889
|
var no_restricted_library_load_default = createRule({
|
|
5892
5890
|
name: "no-restricted-library-load",
|
|
5893
|
-
documentation:
|
|
5891
|
+
documentation: NO_RESTRICTED_LIBRARY_LOAD_DOCUMENTATION,
|
|
5894
5892
|
meta: {
|
|
5895
5893
|
type: "problem",
|
|
5896
5894
|
docs: {
|
|
@@ -5976,7 +5974,7 @@ var no_restricted_library_load_default = createRule({
|
|
|
5976
5974
|
|
|
5977
5975
|
// src/rules/no-router-refresh-polling.ts
|
|
5978
5976
|
import { AST_NODE_TYPES as AST_NODE_TYPES24, ASTUtils as ASTUtils9 } from "@typescript-eslint/utils";
|
|
5979
|
-
var
|
|
5977
|
+
var NO_ROUTER_REFRESH_POLLING_DOCUMENTATION = {
|
|
5980
5978
|
summary: "Do not poll by calling a Next.js router's refresh method from a timer.",
|
|
5981
5979
|
rationale: "A route refresh refetches and rerenders the whole route on every tick instead of loading the named resource that changed.",
|
|
5982
5980
|
remediation: "Call the dedicated fetch or server action from the timer and keep the polling interval in a named constant.",
|
|
@@ -6009,7 +6007,7 @@ function isUnshadowedGlobal2(sourceCode, node) {
|
|
|
6009
6007
|
}
|
|
6010
6008
|
var no_router_refresh_polling_default = createRule({
|
|
6011
6009
|
name: "no-router-refresh-polling",
|
|
6012
|
-
documentation:
|
|
6010
|
+
documentation: NO_ROUTER_REFRESH_POLLING_DOCUMENTATION,
|
|
6013
6011
|
meta: {
|
|
6014
6012
|
type: "suggestion",
|
|
6015
6013
|
docs: { description: "Do not poll by calling a Next.js router's refresh method from a timer." },
|
|
@@ -6069,7 +6067,7 @@ var FUNCTION_TYPES4 = /* @__PURE__ */ new Set([
|
|
|
6069
6067
|
AST_NODE_TYPES25.FunctionExpression,
|
|
6070
6068
|
AST_NODE_TYPES25.ArrowFunctionExpression
|
|
6071
6069
|
]);
|
|
6072
|
-
var
|
|
6070
|
+
var NO_REPEATED_STRING_LITERAL_DOCUMENTATION = {
|
|
6073
6071
|
summary: "Disallow a long structured string literal repeated across functions; the copies drift when one is edited. Extract a module-level constant.",
|
|
6074
6072
|
rationale: "Independent copies of a query, route template, or identifier can diverge and silently change behavior.",
|
|
6075
6073
|
remediation: "Extract the repeated value to one module-level constant and reference it from each function.",
|
|
@@ -6106,7 +6104,7 @@ function isScaffolding(node) {
|
|
|
6106
6104
|
}
|
|
6107
6105
|
var no_repeated_string_literal_default = createRule({
|
|
6108
6106
|
name: "no-repeated-string-literal",
|
|
6109
|
-
documentation:
|
|
6107
|
+
documentation: NO_REPEATED_STRING_LITERAL_DOCUMENTATION,
|
|
6110
6108
|
meta: {
|
|
6111
6109
|
type: "suggestion",
|
|
6112
6110
|
docs: {
|
|
@@ -6224,7 +6222,7 @@ var NON_ASCII_LETTER_RE = /[^\p{ASCII}\p{N}\p{P}\p{Z}]/u;
|
|
|
6224
6222
|
var WALL_NARRATION_RE2 = /^(?:(?:\d+[.)]|(?:phase|step)\s+\d+\s*:?)\s*)?(?:add|build|call|check|compute|copy|count|create|fetch|filter|find|get|handle|load|map|merge|parse|process|read|remove|return|save|send|set|sort|store|update|validate|write)(?:s|es|d|ed|ing)?\b/i;
|
|
6225
6223
|
var WALL_CLUSTER_MAX_LINE_GAP = 8;
|
|
6226
6224
|
var WALL_CLUSTER_MIN_COMMENTS = 3;
|
|
6227
|
-
var
|
|
6225
|
+
var NO_RESTATED_COMMENT_DOCUMENTATION = {
|
|
6228
6226
|
summary: "Flag a single-line comment whose every word already appears on the statement below it.",
|
|
6229
6227
|
rationale: "A comment that only repeats code adds no context and can become stale independently.",
|
|
6230
6228
|
remediation: "Delete the comment or replace it with the reason, constraint, or consequence absent from the code.",
|
|
@@ -6250,7 +6248,7 @@ function headsSiblingRun(node) {
|
|
|
6250
6248
|
}
|
|
6251
6249
|
var no_restated_comment_default = createRule({
|
|
6252
6250
|
name: "no-restated-comment",
|
|
6253
|
-
documentation:
|
|
6251
|
+
documentation: NO_RESTATED_COMMENT_DOCUMENTATION,
|
|
6254
6252
|
meta: {
|
|
6255
6253
|
type: "suggestion",
|
|
6256
6254
|
hasSuggestions: true,
|
|
@@ -6348,7 +6346,7 @@ var no_restated_comment_default = createRule({
|
|
|
6348
6346
|
|
|
6349
6347
|
// src/rules/no-restated-jsdoc.ts
|
|
6350
6348
|
import { AST_NODE_TYPES as AST_NODE_TYPES27 } from "@typescript-eslint/utils";
|
|
6351
|
-
var
|
|
6349
|
+
var NO_RESTATED_JSDOC_DOCUMENTATION = {
|
|
6352
6350
|
summary: "Flag a JSDoc block whose description and tags only re-spell the signature they document.",
|
|
6353
6351
|
rationale: "Signature-only JSDoc duplicates type information and drifts without helping callers.",
|
|
6354
6352
|
remediation: "Delete the block or document behavior, constraints, failures, or context the signature cannot express.",
|
|
@@ -6460,7 +6458,7 @@ function tokensOf(names) {
|
|
|
6460
6458
|
}
|
|
6461
6459
|
var no_restated_jsdoc_default = createRule({
|
|
6462
6460
|
name: "no-restated-jsdoc",
|
|
6463
|
-
documentation:
|
|
6461
|
+
documentation: NO_RESTATED_JSDOC_DOCUMENTATION,
|
|
6464
6462
|
meta: {
|
|
6465
6463
|
type: "suggestion",
|
|
6466
6464
|
hasSuggestions: true,
|
|
@@ -6703,7 +6701,7 @@ function isAuthSecretName(identifier) {
|
|
|
6703
6701
|
}
|
|
6704
6702
|
|
|
6705
6703
|
// src/rules/no-secret-in-log.ts
|
|
6706
|
-
var
|
|
6704
|
+
var NO_SECRET_IN_LOG_DOCUMENTATION = {
|
|
6707
6705
|
summary: "Disallow passing a secret-named value or a raw request/response blob to a logging call; both leak to log sinks. Redact or omit.",
|
|
6708
6706
|
rationale: "Logs are widely retained and distributed, so credentials and raw bodies can become durable data leaks.",
|
|
6709
6707
|
remediation: "Omit the value or log an explicitly redacted, truncated, or derived non-sensitive field.",
|
|
@@ -6838,7 +6836,7 @@ function propertyKeyName2(prop) {
|
|
|
6838
6836
|
}
|
|
6839
6837
|
var no_secret_in_log_default = createRule({
|
|
6840
6838
|
name: "no-secret-in-log",
|
|
6841
|
-
documentation:
|
|
6839
|
+
documentation: NO_SECRET_IN_LOG_DOCUMENTATION,
|
|
6842
6840
|
meta: {
|
|
6843
6841
|
type: "problem",
|
|
6844
6842
|
docs: {
|
|
@@ -6914,7 +6912,7 @@ var no_secret_in_log_default = createRule({
|
|
|
6914
6912
|
// src/rules/no-server-env-in-client-component.ts
|
|
6915
6913
|
import "@typescript-eslint/utils";
|
|
6916
6914
|
var SERVER_ENV_MODULE_RE = /(?:^|\/)(?:server-env|server-settings)(?:\.[cm]?[jt]sx?)?$/;
|
|
6917
|
-
var
|
|
6915
|
+
var NO_SERVER_ENV_IN_CLIENT_COMPONENT_DOCUMENTATION = {
|
|
6918
6916
|
summary: "server-only environment settings imported by a client component",
|
|
6919
6917
|
rationale: "Next.js client modules run in the browser, where server-only environment values are unavailable; importing a server settings module can produce undefined configuration or bundle a secret-bearing module into the client graph.",
|
|
6920
6918
|
remediation: "Pass an explicitly public value from a Server Component, or import it from a separately validated client-settings module backed only by NEXT_PUBLIC_* values.",
|
|
@@ -6965,10 +6963,10 @@ function isTypeOnlyImport(node) {
|
|
|
6965
6963
|
}
|
|
6966
6964
|
var no_server_env_in_client_component_default = createRule({
|
|
6967
6965
|
name: "no-server-env-in-client-component",
|
|
6968
|
-
documentation:
|
|
6966
|
+
documentation: NO_SERVER_ENV_IN_CLIENT_COMPONENT_DOCUMENTATION,
|
|
6969
6967
|
meta: {
|
|
6970
6968
|
type: "problem",
|
|
6971
|
-
docs: { description:
|
|
6969
|
+
docs: { description: NO_SERVER_ENV_IN_CLIENT_COMPONENT_DOCUMENTATION.summary },
|
|
6972
6970
|
schema: [],
|
|
6973
6971
|
messages: {
|
|
6974
6972
|
noServerEnvInClientComponent: "A 'use client' module cannot import server-only settings. Pass public data from a Server Component or use a validated client-settings module."
|
|
@@ -6992,7 +6990,7 @@ var no_server_env_in_client_component_default = createRule({
|
|
|
6992
6990
|
|
|
6993
6991
|
// src/rules/no-select-star.ts
|
|
6994
6992
|
import "@typescript-eslint/utils";
|
|
6995
|
-
var
|
|
6993
|
+
var NO_SELECT_STAR_DOCUMENTATION = {
|
|
6996
6994
|
summary: "Disallow SELECT * in embedded SQL; it over-fetches and leaves the row contract implicit, so a schema change breaks row parsing silently.",
|
|
6997
6995
|
rationale: "Wildcard projections couple row shape and query cost to unrelated schema changes.",
|
|
6998
6996
|
remediation: "List every required column explicitly in the projection.",
|
|
@@ -7044,7 +7042,7 @@ function isProjectionStar(sql, pos) {
|
|
|
7044
7042
|
}
|
|
7045
7043
|
var no_select_star_default = createRule({
|
|
7046
7044
|
name: "no-select-star",
|
|
7047
|
-
documentation:
|
|
7045
|
+
documentation: NO_SELECT_STAR_DOCUMENTATION,
|
|
7048
7046
|
meta: {
|
|
7049
7047
|
type: "problem",
|
|
7050
7048
|
docs: {
|
|
@@ -7071,7 +7069,7 @@ var no_select_star_default = createRule({
|
|
|
7071
7069
|
|
|
7072
7070
|
// src/rules/no-sentinel-return-on-catch.ts
|
|
7073
7071
|
import { AST_NODE_TYPES as AST_NODE_TYPES28 } from "@typescript-eslint/utils";
|
|
7074
|
-
var
|
|
7072
|
+
var NO_SENTINEL_RETURN_ON_CATCH_DOCUMENTATION = {
|
|
7075
7073
|
summary: "Disallow swallowing a caught error by returning an empty sentinel unless the error is handled or the sentinel is part of the function contract.",
|
|
7076
7074
|
rationale: "An unreported fallback makes operational failure indistinguishable from a legitimate empty result.",
|
|
7077
7075
|
remediation: "Rethrow, report the error before returning, or model expected absence with an explicit predicate, safe-parse, or result contract.",
|
|
@@ -7443,7 +7441,7 @@ function isWithin(node, ancestor) {
|
|
|
7443
7441
|
}
|
|
7444
7442
|
var no_sentinel_return_on_catch_default = createRule({
|
|
7445
7443
|
name: "no-sentinel-return-on-catch",
|
|
7446
|
-
documentation:
|
|
7444
|
+
documentation: NO_SENTINEL_RETURN_ON_CATCH_DOCUMENTATION,
|
|
7447
7445
|
meta: {
|
|
7448
7446
|
type: "problem",
|
|
7449
7447
|
docs: {
|
|
@@ -7525,7 +7523,7 @@ var no_sentinel_return_on_catch_default = createRule({
|
|
|
7525
7523
|
|
|
7526
7524
|
// src/rules/no-silent-promise-catch.ts
|
|
7527
7525
|
import { AST_NODE_TYPES as AST_NODE_TYPES29 } from "@typescript-eslint/utils";
|
|
7528
|
-
var
|
|
7526
|
+
var NO_SILENT_PROMISE_CATCH_DOCUMENTATION = {
|
|
7529
7527
|
summary: "Disallow `.catch()` and second-argument `.then()` handlers that silently swallow a rejection; log, rethrow, or handle the error.",
|
|
7530
7528
|
rationale: "A swallowed rejection hides failures and gives callers an indistinguishable fallback value.",
|
|
7531
7529
|
remediation: "Log, rethrow, or explicitly recover from the rejection; explain intentional teardown suppression.",
|
|
@@ -7601,7 +7599,7 @@ function isSilentExpression(node) {
|
|
|
7601
7599
|
}
|
|
7602
7600
|
var no_silent_promise_catch_default = createRule({
|
|
7603
7601
|
name: "no-silent-promise-catch",
|
|
7604
|
-
documentation:
|
|
7602
|
+
documentation: NO_SILENT_PROMISE_CATCH_DOCUMENTATION,
|
|
7605
7603
|
meta: {
|
|
7606
7604
|
type: "problem",
|
|
7607
7605
|
docs: {
|
|
@@ -7674,7 +7672,7 @@ var no_silent_promise_catch_default = createRule({
|
|
|
7674
7672
|
|
|
7675
7673
|
// src/rules/no-sleep-in-test-body.ts
|
|
7676
7674
|
import { AST_NODE_TYPES as AST_NODE_TYPES30 } from "@typescript-eslint/utils";
|
|
7677
|
-
var
|
|
7675
|
+
var NO_SLEEP_IN_TEST_BODY_DOCUMENTATION = {
|
|
7678
7676
|
summary: "Disallow a fixed timed sleep directly in a test body; it flakes under CI load. Synchronize on the signal or use fake timers.",
|
|
7679
7677
|
rationale: "Wall-clock delays make test correctness depend on scheduler and machine speed.",
|
|
7680
7678
|
remediation: "Await the observable signal or advance deterministic fake timers.",
|
|
@@ -7768,7 +7766,7 @@ function testCallerName(callee) {
|
|
|
7768
7766
|
}
|
|
7769
7767
|
var no_sleep_in_test_body_default = createRule({
|
|
7770
7768
|
name: "no-sleep-in-test-body",
|
|
7771
|
-
documentation:
|
|
7769
|
+
documentation: NO_SLEEP_IN_TEST_BODY_DOCUMENTATION,
|
|
7772
7770
|
meta: {
|
|
7773
7771
|
type: "problem",
|
|
7774
7772
|
docs: {
|
|
@@ -7817,7 +7815,7 @@ var DEFAULT_METHODS2 = [
|
|
|
7817
7815
|
"getWithMetadata"
|
|
7818
7816
|
];
|
|
7819
7817
|
var MIN_ARGUMENTS = /* @__PURE__ */ new Map([["put", 2]]);
|
|
7820
|
-
var
|
|
7818
|
+
var NO_STORAGE_IN_STATELESS_MODULES_DOCUMENTATION = {
|
|
7821
7819
|
summary: "Disallow SQL or key/value access inside configured stateless modules; derive state from a system of record instead.",
|
|
7822
7820
|
rationale: "Private storage in a stateless workflow creates another source of truth that can silently diverge.",
|
|
7823
7821
|
remediation: "Read from the system of record or derive state from an artifact the workflow already produces.",
|
|
@@ -7880,7 +7878,7 @@ function identifierWords(name) {
|
|
|
7880
7878
|
}
|
|
7881
7879
|
var no_storage_in_stateless_modules_default = createRule({
|
|
7882
7880
|
name: "no-storage-in-stateless-modules",
|
|
7883
|
-
documentation:
|
|
7881
|
+
documentation: NO_STORAGE_IN_STATELESS_MODULES_DOCUMENTATION,
|
|
7884
7882
|
meta: {
|
|
7885
7883
|
type: "problem",
|
|
7886
7884
|
docs: {
|
|
@@ -7939,7 +7937,7 @@ var no_storage_in_stateless_modules_default = createRule({
|
|
|
7939
7937
|
|
|
7940
7938
|
// src/rules/no-string-concat-in-loop.ts
|
|
7941
7939
|
import "@typescript-eslint/utils";
|
|
7942
|
-
var
|
|
7940
|
+
var NO_STRING_CONCAT_IN_LOOP_DOCUMENTATION = {
|
|
7943
7941
|
summary: "Disallow O(n^2) string building via `+=` on a string variable inside a loop; push parts to an array and `join` instead.",
|
|
7944
7942
|
rationale: "Repeatedly rebuilding a growing string can copy all prior content on each iteration, making total work grow quadratically.",
|
|
7945
7943
|
remediation: "Collect each fragment in an array, then join the fragments after the loop.",
|
|
@@ -8108,7 +8106,7 @@ function isStringSeededReduce(node) {
|
|
|
8108
8106
|
}
|
|
8109
8107
|
var no_string_concat_in_loop_default = createRule({
|
|
8110
8108
|
name: "no-string-concat-in-loop",
|
|
8111
|
-
documentation:
|
|
8109
|
+
documentation: NO_STRING_CONCAT_IN_LOOP_DOCUMENTATION,
|
|
8112
8110
|
meta: {
|
|
8113
8111
|
type: "suggestion",
|
|
8114
8112
|
docs: {
|
|
@@ -8178,7 +8176,7 @@ var no_string_concat_in_loop_default = createRule({
|
|
|
8178
8176
|
|
|
8179
8177
|
// src/rules/no-tautological-expect.ts
|
|
8180
8178
|
import { AST_NODE_TYPES as AST_NODE_TYPES32 } from "@typescript-eslint/utils";
|
|
8181
|
-
var
|
|
8179
|
+
var NO_TAUTOLOGICAL_EXPECT_DOCUMENTATION = {
|
|
8182
8180
|
summary: "Disallow an assertion whose operands are all literals; its outcome is fixed before the code runs, so it can never fail.",
|
|
8183
8181
|
rationale: "An assertion determined entirely by literals does not observe the code under test and can keep passing after that code is removed.",
|
|
8184
8182
|
remediation: "Assert on a value produced by the behavior under test, or remove the assertion.",
|
|
@@ -8248,7 +8246,7 @@ function expectOperand(callee) {
|
|
|
8248
8246
|
}
|
|
8249
8247
|
var no_tautological_expect_default = createRule({
|
|
8250
8248
|
name: "no-tautological-expect",
|
|
8251
|
-
documentation:
|
|
8249
|
+
documentation: NO_TAUTOLOGICAL_EXPECT_DOCUMENTATION,
|
|
8252
8250
|
meta: {
|
|
8253
8251
|
type: "problem",
|
|
8254
8252
|
docs: {
|
|
@@ -8386,7 +8384,7 @@ function canonicalWord(word) {
|
|
|
8386
8384
|
if (word.endsWith("s") && word.length > 3) return word.slice(0, -1);
|
|
8387
8385
|
return word;
|
|
8388
8386
|
}
|
|
8389
|
-
var
|
|
8387
|
+
var NO_TYPED_DOC_SECTIONS_DOCUMENTATION = {
|
|
8390
8388
|
summary: "Reject typed-signature repetition while preserving behavior that types cannot express.",
|
|
8391
8389
|
rationale: "Parameter and return tags repeat typed signatures and can drift without adding runtime behavior or constraints.",
|
|
8392
8390
|
remediation: "Remove repeated parameter and return tags; retain documentation for behavior, failures, and external contracts.",
|
|
@@ -8415,7 +8413,7 @@ var noTypedDocSectionsDocumentation = {
|
|
|
8415
8413
|
};
|
|
8416
8414
|
var no_typed_doc_sections_default = createRule({
|
|
8417
8415
|
name: "no-typed-doc-sections",
|
|
8418
|
-
documentation:
|
|
8416
|
+
documentation: NO_TYPED_DOC_SECTIONS_DOCUMENTATION,
|
|
8419
8417
|
meta: {
|
|
8420
8418
|
type: "suggestion",
|
|
8421
8419
|
docs: { description: "Reject typed-signature repetition while preserving behavior that types cannot express." },
|
|
@@ -8440,7 +8438,7 @@ var no_typed_doc_sections_default = createRule({
|
|
|
8440
8438
|
|
|
8441
8439
|
// src/rules/no-trailing-value-narration.ts
|
|
8442
8440
|
import "@typescript-eslint/utils";
|
|
8443
|
-
var
|
|
8441
|
+
var NO_TRAILING_VALUE_NARRATION_DOCUMENTATION = {
|
|
8444
8442
|
summary: "Flag a trailing comment that repeats the line's numeric value only to name its unit.",
|
|
8445
8443
|
rationale: "A repeated value can disagree with the expression after either the code or comment changes.",
|
|
8446
8444
|
remediation: "Put the unit in the identifier and keep comments only when they explain a constraint or non-obvious conversion.",
|
|
@@ -8559,7 +8557,7 @@ function nameAlreadyCarriesUnit(code) {
|
|
|
8559
8557
|
}
|
|
8560
8558
|
var no_trailing_value_narration_default = createRule({
|
|
8561
8559
|
name: "no-trailing-value-narration",
|
|
8562
|
-
documentation:
|
|
8560
|
+
documentation: NO_TRAILING_VALUE_NARRATION_DOCUMENTATION,
|
|
8563
8561
|
meta: {
|
|
8564
8562
|
type: "suggestion",
|
|
8565
8563
|
hasSuggestions: true,
|
|
@@ -8753,7 +8751,7 @@ function bodyOf(member) {
|
|
|
8753
8751
|
}
|
|
8754
8752
|
|
|
8755
8753
|
// src/rules/no-declaration-comment-wall.ts
|
|
8756
|
-
var
|
|
8754
|
+
var NO_DECLARATION_COMMENT_WALL_DOCUMENTATION = {
|
|
8757
8755
|
summary: "Flag an enum body or class body whose member comments mostly re-spell the members' own names.",
|
|
8758
8756
|
rationale: "A dense block of repetitive member comments obscures the few comments that add information and drifts with renamed members.",
|
|
8759
8757
|
remediation: "Delete comments that restate member names and retain comments that explain constraints, lifecycle, or behavior.",
|
|
@@ -8795,7 +8793,7 @@ function named(node) {
|
|
|
8795
8793
|
}
|
|
8796
8794
|
var no_declaration_comment_wall_default = createRule({
|
|
8797
8795
|
name: "no-declaration-comment-wall",
|
|
8798
|
-
documentation:
|
|
8796
|
+
documentation: NO_DECLARATION_COMMENT_WALL_DOCUMENTATION,
|
|
8799
8797
|
meta: {
|
|
8800
8798
|
type: "suggestion",
|
|
8801
8799
|
docs: {
|
|
@@ -8895,7 +8893,7 @@ var no_declaration_comment_wall_default = createRule({
|
|
|
8895
8893
|
|
|
8896
8894
|
// src/rules/no-union-in-comment.ts
|
|
8897
8895
|
import { AST_NODE_TYPES as AST_NODE_TYPES35 } from "@typescript-eslint/utils";
|
|
8898
|
-
var
|
|
8896
|
+
var NO_UNION_IN_COMMENT_DOCUMENTATION = {
|
|
8899
8897
|
summary: "Flag a comment that lists a `string` field's allowed values instead of the type listing them.",
|
|
8900
8898
|
rationale: "A comment cannot prevent callers from supplying strings outside the listed set, and the list can drift from runtime behavior.",
|
|
8901
8899
|
remediation: "Move the allowed values into a string-literal union and remove the redundant comment.",
|
|
@@ -9010,7 +9008,7 @@ function unionLiterals(body2) {
|
|
|
9010
9008
|
}
|
|
9011
9009
|
var no_union_in_comment_default = createRule({
|
|
9012
9010
|
name: "no-union-in-comment",
|
|
9013
|
-
documentation:
|
|
9011
|
+
documentation: NO_UNION_IN_COMMENT_DOCUMENTATION,
|
|
9014
9012
|
meta: {
|
|
9015
9013
|
type: "suggestion",
|
|
9016
9014
|
docs: {
|
|
@@ -9071,7 +9069,7 @@ var no_union_in_comment_default = createRule({
|
|
|
9071
9069
|
|
|
9072
9070
|
// src/rules/no-type-member-comment-wall.ts
|
|
9073
9071
|
import { AST_NODE_TYPES as AST_NODE_TYPES36, AST_TOKEN_TYPES as AST_TOKEN_TYPES3 } from "@typescript-eslint/utils";
|
|
9074
|
-
var
|
|
9072
|
+
var NO_TYPE_MEMBER_COMMENT_WALL_DOCUMENTATION = {
|
|
9075
9073
|
summary: "Flag an object type whose member comments mostly re-spell the members' own names and types.",
|
|
9076
9074
|
rationale: "Repetitive member comments add scanning cost while hiding the comments that describe facts absent from the type.",
|
|
9077
9075
|
remediation: "Delete comments that restate member names or types and keep comments that add constraints or behavior.",
|
|
@@ -9103,7 +9101,7 @@ function isNamedMember(node) {
|
|
|
9103
9101
|
}
|
|
9104
9102
|
var no_type_member_comment_wall_default = createRule({
|
|
9105
9103
|
name: "no-type-member-comment-wall",
|
|
9106
|
-
documentation:
|
|
9104
|
+
documentation: NO_TYPE_MEMBER_COMMENT_WALL_DOCUMENTATION,
|
|
9107
9105
|
meta: {
|
|
9108
9106
|
type: "suggestion",
|
|
9109
9107
|
docs: {
|
|
@@ -9196,7 +9194,7 @@ var no_type_member_comment_wall_default = createRule({
|
|
|
9196
9194
|
|
|
9197
9195
|
// src/rules/no-unnecessary-use-client.ts
|
|
9198
9196
|
import { AST_NODE_TYPES as AST_NODE_TYPES37 } from "@typescript-eslint/utils";
|
|
9199
|
-
var
|
|
9197
|
+
var NO_UNNECESSARY_USE_CLIENT_DOCUMENTATION = {
|
|
9200
9198
|
summary: "Flag `'use client'` files with no hooks or event handlers \u2014 they could be RSC.",
|
|
9201
9199
|
rationale: "An unnecessary client boundary sends the component and its transitive dependencies to the browser without using client-only behavior.",
|
|
9202
9200
|
remediation: "Remove the directive, or keep it only when the module uses a supported client-side API or boundary dependency.",
|
|
@@ -9309,7 +9307,7 @@ var isGlobalReference = (node, context) => {
|
|
|
9309
9307
|
};
|
|
9310
9308
|
var no_unnecessary_use_client_default = createRule({
|
|
9311
9309
|
name: "no-unnecessary-use-client",
|
|
9312
|
-
documentation:
|
|
9310
|
+
documentation: NO_UNNECESSARY_USE_CLIENT_DOCUMENTATION,
|
|
9313
9311
|
meta: {
|
|
9314
9312
|
type: "suggestion",
|
|
9315
9313
|
docs: {
|
|
@@ -9455,7 +9453,7 @@ var MOCK_MODULES = /* @__PURE__ */ new Set([
|
|
|
9455
9453
|
"jest-mock",
|
|
9456
9454
|
"@jest/globals"
|
|
9457
9455
|
]);
|
|
9458
|
-
var
|
|
9456
|
+
var NO_UNSAFE_MOCK_CASTING_DOCUMENTATION = {
|
|
9459
9457
|
summary: "Disallow casting to mock types like `jest.Mock` or `vi.Mock`. Use `vi.mocked()` or `jest.mocked()` instead.",
|
|
9460
9458
|
rationale: "A type assertion can claim an unmocked value is a mock and bypass checking between the original callable and the mock API.",
|
|
9461
9459
|
remediation: "Use the test framework's `mocked` helper to obtain the typed mock reference.",
|
|
@@ -9484,7 +9482,7 @@ var noUnsafeMockCastingDocumentation = {
|
|
|
9484
9482
|
};
|
|
9485
9483
|
var no_unsafe_mock_casting_default = createRule({
|
|
9486
9484
|
name: "no-unsafe-mock-casting",
|
|
9487
|
-
documentation:
|
|
9485
|
+
documentation: NO_UNSAFE_MOCK_CASTING_DOCUMENTATION,
|
|
9488
9486
|
meta: {
|
|
9489
9487
|
type: "problem",
|
|
9490
9488
|
docs: {
|
|
@@ -9556,7 +9554,7 @@ import {
|
|
|
9556
9554
|
ASTUtils as ASTUtils11
|
|
9557
9555
|
} from "@typescript-eslint/utils";
|
|
9558
9556
|
import * as ts2 from "typescript";
|
|
9559
|
-
var
|
|
9557
|
+
var NO_ZOD_NATIVE_ENUM_DOCUMENTATION = {
|
|
9560
9558
|
summary: 'Disallow `z.nativeEnum()` (and `z.enum()` over a TypeScript enum); use `z.enum(["a", "b"])` with a string-literal union instead.',
|
|
9561
9559
|
rationale: "Wrapping a TypeScript enum preserves its emitted runtime object and duplicates the schema's value definition across two constructs.",
|
|
9562
9560
|
remediation: "Pass string literals directly to `z.enum` and derive the TypeScript type with `z.infer`.",
|
|
@@ -9654,7 +9652,7 @@ function resolvesToImportedEnum(node, services) {
|
|
|
9654
9652
|
}
|
|
9655
9653
|
var no_zod_native_enum_default = createRule({
|
|
9656
9654
|
name: "no-zod-native-enum",
|
|
9657
|
-
documentation:
|
|
9655
|
+
documentation: NO_ZOD_NATIVE_ENUM_DOCUMENTATION,
|
|
9658
9656
|
meta: {
|
|
9659
9657
|
type: "suggestion",
|
|
9660
9658
|
fixable: "code",
|
|
@@ -9778,7 +9776,7 @@ var no_zod_native_enum_default = createRule({
|
|
|
9778
9776
|
|
|
9779
9777
|
// src/rules/test-loops-over-literal-cases.ts
|
|
9780
9778
|
import { AST_NODE_TYPES as AST_NODE_TYPES40, ASTUtils as ASTUtils12 } from "@typescript-eslint/utils";
|
|
9781
|
-
var
|
|
9779
|
+
var TEST_LOOPS_OVER_LITERAL_CASES_DOCUMENTATION = {
|
|
9782
9780
|
summary: "Disallow assertions over an inline literal case loop in a test; parameterization reports and names every case independently.",
|
|
9783
9781
|
rationale: "A loop is reported as one test, so failures hide the individual case name and may stop later cases from running.",
|
|
9784
9782
|
remediation: "Create one named parameterized test or runner-aware subtest for each literal case.",
|
|
@@ -9923,7 +9921,7 @@ var LOOP_CARRIED_CONTROL = /* @__PURE__ */ new Set([
|
|
|
9923
9921
|
]);
|
|
9924
9922
|
var test_loops_over_literal_cases_default = createRule({
|
|
9925
9923
|
name: "test-loops-over-literal-cases",
|
|
9926
|
-
documentation:
|
|
9924
|
+
documentation: TEST_LOOPS_OVER_LITERAL_CASES_DOCUMENTATION,
|
|
9927
9925
|
meta: {
|
|
9928
9926
|
type: "suggestion",
|
|
9929
9927
|
docs: {
|
|
@@ -9988,7 +9986,7 @@ var PHASE_RE = new RegExp(
|
|
|
9988
9986
|
String.raw`^[-=~*_#.\s]{0,40}(?:${PHASE_WORD})(?:\s*(?:[/&+,|]|->|and)\s*(?:${PHASE_WORD}))*[-=~*_#.\s:;!–—]{0,40}$`,
|
|
9989
9987
|
"iu"
|
|
9990
9988
|
);
|
|
9991
|
-
var
|
|
9989
|
+
var TEST_PHASE_LABEL_COMMENT_DOCUMENTATION = {
|
|
9992
9990
|
summary: "Tests must not use bare Arrange, Act, Assert, Given, When, or Then phase comments.",
|
|
9993
9991
|
rationale: "Phase labels narrate test structure without explaining behavior and often hide unclear names or oversized tests.",
|
|
9994
9992
|
remediation: "Delete the label; if the phases remain hard to follow, extract a named helper or split the test.",
|
|
@@ -10040,11 +10038,11 @@ function continuesProseRun(comments, index) {
|
|
|
10040
10038
|
}
|
|
10041
10039
|
var test_phase_label_comment_default = createRule({
|
|
10042
10040
|
name: "test-phase-label-comment",
|
|
10043
|
-
documentation:
|
|
10041
|
+
documentation: TEST_PHASE_LABEL_COMMENT_DOCUMENTATION,
|
|
10044
10042
|
meta: {
|
|
10045
10043
|
type: "suggestion",
|
|
10046
10044
|
fixable: "code",
|
|
10047
|
-
docs: { description:
|
|
10045
|
+
docs: { description: TEST_PHASE_LABEL_COMMENT_DOCUMENTATION.summary },
|
|
10048
10046
|
schema: [],
|
|
10049
10047
|
messages: { removeLabel: "Bare test phase label \u2014 delete it and let the test names and helpers carry the structure." }
|
|
10050
10048
|
},
|
|
@@ -10073,7 +10071,7 @@ var test_phase_label_comment_default = createRule({
|
|
|
10073
10071
|
|
|
10074
10072
|
// src/rules/prefer-constant-time-secret-compare.ts
|
|
10075
10073
|
import { AST_NODE_TYPES as AST_NODE_TYPES42 } from "@typescript-eslint/utils";
|
|
10076
|
-
var
|
|
10074
|
+
var PREFER_CONSTANT_TIME_SECRET_COMPARE_DOCUMENTATION = {
|
|
10077
10075
|
summary: "Disallow `===`/`!==` on a secret-like value; short-circuiting comparison leaks the secret through timing. Use a constant-time compare.",
|
|
10078
10076
|
rationale: "Ordinary equality stops at the first differing byte, allowing repeated measurements to reveal secret material.",
|
|
10079
10077
|
remediation: "Compare equal-length cryptographic digests with a constant-time comparison primitive.",
|
|
@@ -10138,7 +10136,7 @@ function secretNameOf(node) {
|
|
|
10138
10136
|
}
|
|
10139
10137
|
var prefer_constant_time_secret_compare_default = createRule({
|
|
10140
10138
|
name: "prefer-constant-time-secret-compare",
|
|
10141
|
-
documentation:
|
|
10139
|
+
documentation: PREFER_CONSTANT_TIME_SECRET_COMPARE_DOCUMENTATION,
|
|
10142
10140
|
meta: {
|
|
10143
10141
|
type: "problem",
|
|
10144
10142
|
docs: {
|
|
@@ -10287,7 +10285,7 @@ var prefer_ecmascript_private_members_default = createRule({
|
|
|
10287
10285
|
// src/rules/prefer-discriminated-union.ts
|
|
10288
10286
|
import "@typescript-eslint/utils";
|
|
10289
10287
|
import { AST_NODE_TYPES as AST_NODE_TYPES44 } from "@typescript-eslint/utils";
|
|
10290
|
-
var
|
|
10288
|
+
var PREFER_DISCRIMINATED_UNION_DOCUMENTATION = {
|
|
10291
10289
|
summary: "Flag flat result objects with a required positive boolean status and optional success/failure payloads.",
|
|
10292
10290
|
rationale: "A boolean status plus optional branch data permits contradictory and incomplete states.",
|
|
10293
10291
|
remediation: "Represent each result branch as a discriminated union member with its required payload.",
|
|
@@ -10384,7 +10382,7 @@ function inlineReturnTypeLiteral(node) {
|
|
|
10384
10382
|
}
|
|
10385
10383
|
var prefer_discriminated_union_default = createRule({
|
|
10386
10384
|
name: "prefer-discriminated-union",
|
|
10387
|
-
documentation:
|
|
10385
|
+
documentation: PREFER_DISCRIMINATED_UNION_DOCUMENTATION,
|
|
10388
10386
|
meta: {
|
|
10389
10387
|
type: "suggestion",
|
|
10390
10388
|
docs: {
|
|
@@ -10433,7 +10431,7 @@ var prefer_discriminated_union_default = createRule({
|
|
|
10433
10431
|
|
|
10434
10432
|
// src/rules/prefer-input-group-search.ts
|
|
10435
10433
|
import { AST_NODE_TYPES as AST_NODE_TYPES45 } from "@typescript-eslint/utils";
|
|
10436
|
-
var
|
|
10434
|
+
var PREFER_INPUT_GROUP_SEARCH_DOCUMENTATION = {
|
|
10437
10435
|
summary: "Require search icons and shared Input controls in the same visual wrapper to use InputGroup.",
|
|
10438
10436
|
rationale: "The shared compound control provides consistent spacing, focus behavior, and accessible composition.",
|
|
10439
10437
|
remediation: "Compose the search icon and field with InputGroup, InputGroupAddon, and InputGroupInput.",
|
|
@@ -10498,7 +10496,7 @@ function isActionIcon(search, wrapper) {
|
|
|
10498
10496
|
}
|
|
10499
10497
|
var prefer_input_group_search_default = createRule({
|
|
10500
10498
|
name: "prefer-input-group-search",
|
|
10501
|
-
documentation:
|
|
10499
|
+
documentation: PREFER_INPUT_GROUP_SEARCH_DOCUMENTATION,
|
|
10502
10500
|
meta: {
|
|
10503
10501
|
type: "suggestion",
|
|
10504
10502
|
docs: {
|
|
@@ -10575,7 +10573,7 @@ var prefer_input_group_search_default = createRule({
|
|
|
10575
10573
|
|
|
10576
10574
|
// src/rules/prefer-immutable-module-constant.ts
|
|
10577
10575
|
import { AST_NODE_TYPES as AST_NODE_TYPES46, ASTUtils as ASTUtils13 } from "@typescript-eslint/utils";
|
|
10578
|
-
var
|
|
10576
|
+
var PREFER_IMMUTABLE_MODULE_CONSTANT_DOCUMENTATION = {
|
|
10579
10577
|
summary: "Require module-level constant collections to expose readonly state.",
|
|
10580
10578
|
rationale: "A const binding prevents reassignment but does not stop callers from mutating its array, object, Set, or Map contents.",
|
|
10581
10579
|
remediation: "Expose literals with `as const` or a readonly type, and expose Set or Map values through ReadonlySet or ReadonlyMap.",
|
|
@@ -10711,7 +10709,7 @@ function referenceMutates(identifier, isUnshadowedGlobal3) {
|
|
|
10711
10709
|
}
|
|
10712
10710
|
var prefer_immutable_module_constant_default = createRule({
|
|
10713
10711
|
name: "prefer-immutable-module-constant",
|
|
10714
|
-
documentation:
|
|
10712
|
+
documentation: PREFER_IMMUTABLE_MODULE_CONSTANT_DOCUMENTATION,
|
|
10715
10713
|
meta: {
|
|
10716
10714
|
type: "suggestion",
|
|
10717
10715
|
docs: {
|
|
@@ -10817,7 +10815,7 @@ function unwrapTransparentExport(node) {
|
|
|
10817
10815
|
|
|
10818
10816
|
// src/rules/prefer-shadcn-primitives.ts
|
|
10819
10817
|
import { AST_NODE_TYPES as AST_NODE_TYPES47 } from "@typescript-eslint/utils";
|
|
10820
|
-
var
|
|
10818
|
+
var PREFER_SHADCN_PRIMITIVES_DOCUMENTATION = {
|
|
10821
10819
|
summary: "Require visible raw JSX controls to use the corresponding shared shadcn primitive.",
|
|
10822
10820
|
rationale: "Shared primitives centralize interaction, accessibility, and visual behavior across the product.",
|
|
10823
10821
|
remediation: "Replace the raw visible control with the corresponding shared shadcn component.",
|
|
@@ -10944,7 +10942,7 @@ function replacementFor(node, element) {
|
|
|
10944
10942
|
}
|
|
10945
10943
|
var prefer_shadcn_primitives_default = createRule({
|
|
10946
10944
|
name: "prefer-shadcn-primitives",
|
|
10947
|
-
documentation:
|
|
10945
|
+
documentation: PREFER_SHADCN_PRIMITIVES_DOCUMENTATION,
|
|
10948
10946
|
meta: {
|
|
10949
10947
|
type: "suggestion",
|
|
10950
10948
|
docs: {
|
|
@@ -11001,7 +10999,7 @@ var prefer_shadcn_primitives_default = createRule({
|
|
|
11001
10999
|
|
|
11002
11000
|
// src/rules/prefer-module-level-constant.ts
|
|
11003
11001
|
import { AST_NODE_TYPES as AST_NODE_TYPES48 } from "@typescript-eslint/utils";
|
|
11004
|
-
var
|
|
11002
|
+
var PREFER_MODULE_LEVEL_CONSTANT_DOCUMENTATION = {
|
|
11005
11003
|
summary: "Hoist literal-only constant collections and regexes out of function bodies to module scope so they are allocated once.",
|
|
11006
11004
|
rationale: "Recreating immutable lookup data on every call wastes allocations and obscures its constant nature.",
|
|
11007
11005
|
remediation: "Declare immutable literal collections and non-stateful regular expressions once at module scope.",
|
|
@@ -11217,7 +11215,7 @@ function isNonRetainingBuiltinCall(node, argument) {
|
|
|
11217
11215
|
}
|
|
11218
11216
|
var prefer_module_level_constant_default = createRule({
|
|
11219
11217
|
name: "prefer-module-level-constant",
|
|
11220
|
-
documentation:
|
|
11218
|
+
documentation: PREFER_MODULE_LEVEL_CONSTANT_DOCUMENTATION,
|
|
11221
11219
|
meta: {
|
|
11222
11220
|
type: "suggestion",
|
|
11223
11221
|
docs: {
|
|
@@ -11309,7 +11307,7 @@ var prefer_module_level_constant_default = createRule({
|
|
|
11309
11307
|
|
|
11310
11308
|
// src/rules/prefer-module-level-schema.ts
|
|
11311
11309
|
import { AST_NODE_TYPES as AST_NODE_TYPES49 } from "@typescript-eslint/utils";
|
|
11312
|
-
var
|
|
11310
|
+
var PREFER_MODULE_LEVEL_SCHEMA_DOCUMENTATION = {
|
|
11313
11311
|
summary: "Declare a Zod schema at module scope when it closes over nothing in the enclosing function",
|
|
11314
11312
|
rationale: "A closed schema created inside a function is rebuilt on every call and cannot be reused or exported for inference.",
|
|
11315
11313
|
remediation: "Move the closed schema declaration to module scope and reference it from the function.",
|
|
@@ -11466,7 +11464,7 @@ function collectReferences(scope, out) {
|
|
|
11466
11464
|
}
|
|
11467
11465
|
var prefer_module_level_schema_default = createRule({
|
|
11468
11466
|
name: "prefer-module-level-schema",
|
|
11469
|
-
documentation:
|
|
11467
|
+
documentation: PREFER_MODULE_LEVEL_SCHEMA_DOCUMENTATION,
|
|
11470
11468
|
meta: {
|
|
11471
11469
|
type: "problem",
|
|
11472
11470
|
docs: {
|
|
@@ -11668,7 +11666,7 @@ var prefer_module_level_schema_default = createRule({
|
|
|
11668
11666
|
|
|
11669
11667
|
// src/rules/prefer-native-random-uuid.ts
|
|
11670
11668
|
import { AST_NODE_TYPES as AST_NODE_TYPES50, ASTUtils as ASTUtils14 } from "@typescript-eslint/utils";
|
|
11671
|
-
var
|
|
11669
|
+
var PREFER_NATIVE_RANDOM_UUID_DOCUMENTATION = {
|
|
11672
11670
|
summary: "Prefer `globalThis.crypto.randomUUID()` over resolved zero-argument UUID v4 bindings from the `uuid` package.",
|
|
11673
11671
|
rationale: "The platform implementation avoids an unnecessary dependency for standard random UUID generation.",
|
|
11674
11672
|
remediation: "Call `globalThis.crypto.randomUUID()` and remove the unused `uuid` v4 import when possible.",
|
|
@@ -11685,7 +11683,7 @@ function requireUuid(node) {
|
|
|
11685
11683
|
}
|
|
11686
11684
|
var prefer_native_random_uuid_default = createRule({
|
|
11687
11685
|
name: "prefer-native-random-uuid",
|
|
11688
|
-
documentation:
|
|
11686
|
+
documentation: PREFER_NATIVE_RANDOM_UUID_DOCUMENTATION,
|
|
11689
11687
|
meta: {
|
|
11690
11688
|
type: "suggestion",
|
|
11691
11689
|
docs: {
|
|
@@ -11767,7 +11765,7 @@ var prefer_native_random_uuid_default = createRule({
|
|
|
11767
11765
|
|
|
11768
11766
|
// src/rules/prefer-non-nullable-collection.ts
|
|
11769
11767
|
import { AST_NODE_TYPES as AST_NODE_TYPES51, ASTUtils as ASTUtils15 } from "@typescript-eslint/utils";
|
|
11770
|
-
var
|
|
11768
|
+
var PREFER_NON_NULLABLE_COLLECTION_DOCUMENTATION = {
|
|
11771
11769
|
summary: "Suggest non-null arrays only when local control flow proves the nullish state is equivalent to an empty collection.",
|
|
11772
11770
|
rationale: "A redundant nullish collection state spreads defaults and guards through consumers without carrying information.",
|
|
11773
11771
|
remediation: "Use a non-null collection type and normalize omitted input to an empty collection at the boundary.",
|
|
@@ -11915,7 +11913,7 @@ function memberIsOnlyCoalesced(context, object, property, fn) {
|
|
|
11915
11913
|
}
|
|
11916
11914
|
var prefer_non_nullable_collection_default = createRule({
|
|
11917
11915
|
name: "prefer-non-nullable-collection",
|
|
11918
|
-
documentation:
|
|
11916
|
+
documentation: PREFER_NON_NULLABLE_COLLECTION_DOCUMENTATION,
|
|
11919
11917
|
meta: {
|
|
11920
11918
|
type: "suggestion",
|
|
11921
11919
|
docs: {
|
|
@@ -12017,7 +12015,7 @@ import {
|
|
|
12017
12015
|
AST_NODE_TYPES as AST_NODE_TYPES52
|
|
12018
12016
|
} from "@typescript-eslint/utils";
|
|
12019
12017
|
import * as ts3 from "typescript";
|
|
12020
|
-
var
|
|
12018
|
+
var PREFER_AWAIT_IN_ASYNC_RETURN_DOCUMENTATION = {
|
|
12021
12019
|
summary: "Prefer explicit `await` when an async function directly returns one typed Promise `.then` transform.",
|
|
12022
12020
|
rationale: "Mixing a directly returned Promise callback into otherwise async control flow makes sequencing and failures harder to read.",
|
|
12023
12021
|
remediation: "Await the Promise, then return the transformed value with ordinary async statements.",
|
|
@@ -12104,7 +12102,7 @@ function isProvenPromiseLike(node, services) {
|
|
|
12104
12102
|
}
|
|
12105
12103
|
var prefer_await_in_async_return_default = createRule({
|
|
12106
12104
|
name: "prefer-await-in-async-return",
|
|
12107
|
-
documentation:
|
|
12105
|
+
documentation: PREFER_AWAIT_IN_ASYNC_RETURN_DOCUMENTATION,
|
|
12108
12106
|
meta: {
|
|
12109
12107
|
type: "suggestion",
|
|
12110
12108
|
docs: {
|
|
@@ -12163,7 +12161,7 @@ var prefer_await_in_async_return_default = createRule({
|
|
|
12163
12161
|
|
|
12164
12162
|
// src/rules/prefer-schema-for-api-payload.ts
|
|
12165
12163
|
import { AST_NODE_TYPES as AST_NODE_TYPES53 } from "@typescript-eslint/utils";
|
|
12166
|
-
var
|
|
12164
|
+
var PREFER_SCHEMA_FOR_API_PAYLOAD_DOCUMENTATION = {
|
|
12167
12165
|
summary: "Require Zod (or similar) schema validation on `response.json()` / `JSON.parse()` results before property access.",
|
|
12168
12166
|
rationale: "External JSON is untrusted at runtime even when its expected TypeScript shape is known statically.",
|
|
12169
12167
|
remediation: "Parse the payload through a schema or establish a recognized runtime validation guard before reading fields.",
|
|
@@ -12478,7 +12476,7 @@ var unvalidatedVariableRef = (node, scope, tracked) => {
|
|
|
12478
12476
|
};
|
|
12479
12477
|
var prefer_schema_for_api_payload_default = createRule({
|
|
12480
12478
|
name: "prefer-schema-for-api-payload",
|
|
12481
|
-
documentation:
|
|
12479
|
+
documentation: PREFER_SCHEMA_FOR_API_PAYLOAD_DOCUMENTATION,
|
|
12482
12480
|
meta: {
|
|
12483
12481
|
type: "problem",
|
|
12484
12482
|
docs: {
|
|
@@ -12688,7 +12686,7 @@ var tailwindBase = (token) => token.replace(/^(?:[a-z0-9-]+:)+/i, "").replace(/^
|
|
|
12688
12686
|
var classTokens = (value) => value.split(/\s+/).filter(Boolean);
|
|
12689
12687
|
|
|
12690
12688
|
// src/rules/prefer-semantic-colors.ts
|
|
12691
|
-
var
|
|
12689
|
+
var PREFER_SEMANTIC_COLORS_DOCUMENTATION = {
|
|
12692
12690
|
summary: "Enforce semantic color tokens over raw Tailwind palette classes, arbitrary color values, and inline color literals.",
|
|
12693
12691
|
rationale: "Semantic tokens keep themes and product meaning consistent while raw colors couple components to a palette value.",
|
|
12694
12692
|
remediation: "Replace raw palette and literal colors with the closest semantic design-system token or CSS variable.",
|
|
@@ -12767,9 +12765,9 @@ var WORKSPACE_ROOT_FILES = [
|
|
|
12767
12765
|
];
|
|
12768
12766
|
var DEFAULT_WORKSPACE_GLOBS = ["packages/*", "apps/*"];
|
|
12769
12767
|
var MAX_WORKSPACE_PACKAGES = 512;
|
|
12770
|
-
var
|
|
12771
|
-
var
|
|
12772
|
-
var
|
|
12768
|
+
var ANCESTRY_CACHE = /* @__PURE__ */ new Map();
|
|
12769
|
+
var WORKSPACE_SCAN_CACHE = /* @__PURE__ */ new Map();
|
|
12770
|
+
var WORKSPACE_ROOT_CACHE = /* @__PURE__ */ new Map();
|
|
12773
12771
|
var SVG_DEFS_CONTAINERS = /* @__PURE__ */ new Set([
|
|
12774
12772
|
"mask",
|
|
12775
12773
|
"clipPath",
|
|
@@ -12885,7 +12883,7 @@ var hasMarkerAtOrAbove = (startDir) => {
|
|
|
12885
12883
|
const visited = [];
|
|
12886
12884
|
let answer;
|
|
12887
12885
|
for (; ; ) {
|
|
12888
|
-
const cached =
|
|
12886
|
+
const cached = ANCESTRY_CACHE.get(dir);
|
|
12889
12887
|
if (cached !== void 0) {
|
|
12890
12888
|
answer = cached;
|
|
12891
12889
|
break;
|
|
@@ -12902,7 +12900,7 @@ var hasMarkerAtOrAbove = (startDir) => {
|
|
|
12902
12900
|
}
|
|
12903
12901
|
dir = parent;
|
|
12904
12902
|
}
|
|
12905
|
-
for (const seen of visited)
|
|
12903
|
+
for (const seen of visited) ANCESTRY_CACHE.set(seen, answer);
|
|
12906
12904
|
return answer;
|
|
12907
12905
|
};
|
|
12908
12906
|
var findWorkspaceRoot = (startDir) => {
|
|
@@ -12911,7 +12909,7 @@ var findWorkspaceRoot = (startDir) => {
|
|
|
12911
12909
|
const visited = [];
|
|
12912
12910
|
let answer;
|
|
12913
12911
|
for (; ; ) {
|
|
12914
|
-
const cached =
|
|
12912
|
+
const cached = WORKSPACE_ROOT_CACHE.get(dir);
|
|
12915
12913
|
if (cached !== void 0) {
|
|
12916
12914
|
answer = cached;
|
|
12917
12915
|
break;
|
|
@@ -12928,11 +12926,11 @@ var findWorkspaceRoot = (startDir) => {
|
|
|
12928
12926
|
}
|
|
12929
12927
|
dir = parent;
|
|
12930
12928
|
}
|
|
12931
|
-
for (const seen of visited)
|
|
12929
|
+
for (const seen of visited) WORKSPACE_ROOT_CACHE.set(seen, answer);
|
|
12932
12930
|
return answer;
|
|
12933
12931
|
};
|
|
12934
12932
|
var workspaceHasMarker = (root) => {
|
|
12935
|
-
const cached =
|
|
12933
|
+
const cached = WORKSPACE_SCAN_CACHE.get(root);
|
|
12936
12934
|
if (cached !== void 0) return cached;
|
|
12937
12935
|
const globs = readWorkspaceGlobs(root);
|
|
12938
12936
|
const candidates = /* @__PURE__ */ new Set();
|
|
@@ -12950,7 +12948,7 @@ var workspaceHasMarker = (root) => {
|
|
|
12950
12948
|
break;
|
|
12951
12949
|
}
|
|
12952
12950
|
}
|
|
12953
|
-
|
|
12951
|
+
WORKSPACE_SCAN_CACHE.set(root, found);
|
|
12954
12952
|
return found;
|
|
12955
12953
|
};
|
|
12956
12954
|
var expandWorkspaceGlob = (root, glob) => {
|
|
@@ -12974,7 +12972,7 @@ var staticallyImportsEmailOrPdfRenderer = (program) => program.body.some((statem
|
|
|
12974
12972
|
});
|
|
12975
12973
|
var prefer_semantic_colors_default = createRule({
|
|
12976
12974
|
name: "prefer-semantic-colors",
|
|
12977
|
-
documentation:
|
|
12975
|
+
documentation: PREFER_SEMANTIC_COLORS_DOCUMENTATION,
|
|
12978
12976
|
meta: {
|
|
12979
12977
|
type: "suggestion",
|
|
12980
12978
|
docs: {
|
|
@@ -13113,7 +13111,7 @@ var prefer_semantic_colors_default = createRule({
|
|
|
13113
13111
|
|
|
13114
13112
|
// src/rules/prefer-server-actions.ts
|
|
13115
13113
|
import "@typescript-eslint/utils";
|
|
13116
|
-
var
|
|
13114
|
+
var PREFER_SERVER_ACTIONS_DOCUMENTATION = {
|
|
13117
13115
|
summary: "Prefer Next.js Server Actions over /api/* mutations.",
|
|
13118
13116
|
rationale: "Server Actions preserve typed application calls and avoid an internal JSON request-response boundary.",
|
|
13119
13117
|
remediation: "Move the mutation into a Server Action and invoke that action from the React client.",
|
|
@@ -13222,7 +13220,7 @@ function getPropertyNode(objNode, propName2) {
|
|
|
13222
13220
|
}
|
|
13223
13221
|
var prefer_server_actions_default = createRule({
|
|
13224
13222
|
name: "prefer-server-actions",
|
|
13225
|
-
documentation:
|
|
13223
|
+
documentation: PREFER_SERVER_ACTIONS_DOCUMENTATION,
|
|
13226
13224
|
meta: {
|
|
13227
13225
|
type: "suggestion",
|
|
13228
13226
|
docs: {
|
|
@@ -13312,7 +13310,7 @@ var COLLECTION_PROPERTIES = /* @__PURE__ */ new Set(["length", "size"]);
|
|
|
13312
13310
|
var LITERAL_KEY_HAZARDS = /* @__PURE__ */ new Set(["__proto__"]);
|
|
13313
13311
|
var NUMERIC_SIGNS2 = /* @__PURE__ */ new Set(["-", "+"]);
|
|
13314
13312
|
var MIN_RUN_LENGTH = 2;
|
|
13315
|
-
var
|
|
13313
|
+
var PREFER_WHOLE_OBJECT_ASSERTION_DOCUMENTATION = {
|
|
13316
13314
|
summary: "Collapse consecutive assertions on one object into a whole-object assertion so related mismatches are reported together.",
|
|
13317
13315
|
rationale: "One whole-object assertion presents related expectations together and produces a complete structural diff.",
|
|
13318
13316
|
remediation: "Replace consecutive member assertions with one `toMatchObject` assertion.",
|
|
@@ -13371,7 +13369,7 @@ function propertyAccess(node) {
|
|
|
13371
13369
|
}
|
|
13372
13370
|
var prefer_whole_object_assertion_default = createRule({
|
|
13373
13371
|
name: "prefer-whole-object-assertion",
|
|
13374
|
-
documentation:
|
|
13372
|
+
documentation: PREFER_WHOLE_OBJECT_ASSERTION_DOCUMENTATION,
|
|
13375
13373
|
meta: {
|
|
13376
13374
|
type: "suggestion",
|
|
13377
13375
|
docs: {
|
|
@@ -13579,7 +13577,7 @@ var prefer_whole_object_assertion_default = createRule({
|
|
|
13579
13577
|
|
|
13580
13578
|
// src/rules/repeated-static-call-cases.ts
|
|
13581
13579
|
import { AST_NODE_TYPES as AST_NODE_TYPES56, ASTUtils as ASTUtils17 } from "@typescript-eslint/utils";
|
|
13582
|
-
var
|
|
13580
|
+
var REPEATED_STATIC_CALL_CASES_DOCUMENTATION = {
|
|
13583
13581
|
summary: "Report three or more consecutive literal call assertions that should be independently named test cases.",
|
|
13584
13582
|
rationale: "Copy-pasted cases obscure the input table and stop later cases from being reported after the first failure.",
|
|
13585
13583
|
remediation: "Replace the repeated assertions with a named `test.each` or `it.each` table.",
|
|
@@ -13694,7 +13692,7 @@ function expectCallFromMatcher(node) {
|
|
|
13694
13692
|
}
|
|
13695
13693
|
var repeated_static_call_cases_default = createRule({
|
|
13696
13694
|
name: "repeated-static-call-cases",
|
|
13697
|
-
documentation:
|
|
13695
|
+
documentation: REPEATED_STATIC_CALL_CASES_DOCUMENTATION,
|
|
13698
13696
|
meta: {
|
|
13699
13697
|
type: "suggestion",
|
|
13700
13698
|
docs: { description: "Report three or more consecutive literal call assertions that should be independently named test cases." },
|
|
@@ -13762,7 +13760,7 @@ var repeated_static_call_cases_default = createRule({
|
|
|
13762
13760
|
|
|
13763
13761
|
// src/rules/prefer-zod-infer.ts
|
|
13764
13762
|
import { AST_NODE_TYPES as AST_NODE_TYPES57 } from "@typescript-eslint/utils";
|
|
13765
|
-
var
|
|
13763
|
+
var PREFER_ZOD_INFER_DOCUMENTATION = {
|
|
13766
13764
|
summary: "Derive a type from its Zod schema with `z.infer` instead of hand-writing a twin declaration beside it.",
|
|
13767
13765
|
rationale: "A derived type stays synchronized when the runtime schema changes.",
|
|
13768
13766
|
remediation: "Replace the hand-written twin with `z.infer<typeof Schema>`.",
|
|
@@ -14055,7 +14053,7 @@ function endsWithTokens(candidate2, suffix) {
|
|
|
14055
14053
|
}
|
|
14056
14054
|
var prefer_zod_infer_default = createRule({
|
|
14057
14055
|
name: "prefer-zod-infer",
|
|
14058
|
-
documentation:
|
|
14056
|
+
documentation: PREFER_ZOD_INFER_DOCUMENTATION,
|
|
14059
14057
|
meta: {
|
|
14060
14058
|
type: "problem",
|
|
14061
14059
|
docs: {
|
|
@@ -14488,7 +14486,7 @@ import {
|
|
|
14488
14486
|
AST_NODE_TYPES as AST_NODE_TYPES58
|
|
14489
14487
|
} from "@typescript-eslint/utils";
|
|
14490
14488
|
import ts4 from "typescript";
|
|
14491
|
-
var
|
|
14489
|
+
var REQUIRE_ASSERT_NEVER_DOCUMENTATION = {
|
|
14492
14490
|
summary: "Require an empty switch default to call `assertNever` so discriminated unions remain exhaustive at compile time.",
|
|
14493
14491
|
rationale: "An empty default silently accepts new union members instead of making the compiler identify the missing case.",
|
|
14494
14492
|
remediation: "Call `assertNever` with the discriminant in the exhaustive switch default.",
|
|
@@ -14563,7 +14561,7 @@ function finiteTypeKey(type, checker) {
|
|
|
14563
14561
|
}
|
|
14564
14562
|
var require_assert_never_default = createRule({
|
|
14565
14563
|
name: "require-assert-never",
|
|
14566
|
-
documentation:
|
|
14564
|
+
documentation: REQUIRE_ASSERT_NEVER_DOCUMENTATION,
|
|
14567
14565
|
meta: {
|
|
14568
14566
|
type: "problem",
|
|
14569
14567
|
docs: {
|
|
@@ -14606,7 +14604,7 @@ var require_assert_never_default = createRule({
|
|
|
14606
14604
|
|
|
14607
14605
|
// src/rules/require-fetch-timeout.ts
|
|
14608
14606
|
import { AST_NODE_TYPES as AST_NODE_TYPES59, ASTUtils as ASTUtils18 } from "@typescript-eslint/utils";
|
|
14609
|
-
var
|
|
14607
|
+
var REQUIRE_FETCH_TIMEOUT_DOCUMENTATION = {
|
|
14610
14608
|
summary: "Require an abort `signal` (e.g. `AbortSignal.timeout(ms)`) on global `fetch()` calls so stalled upstreams cannot hang the caller forever.",
|
|
14611
14609
|
rationale: "An unbounded request can occupy work indefinitely when an upstream stalls.",
|
|
14612
14610
|
remediation: "Pass an abort signal, such as `AbortSignal.timeout(ms)`, in the fetch init.",
|
|
@@ -14652,7 +14650,7 @@ function isInlineUrl(node, resolvesToGlobal) {
|
|
|
14652
14650
|
}
|
|
14653
14651
|
var require_fetch_timeout_default = createRule({
|
|
14654
14652
|
name: "require-fetch-timeout",
|
|
14655
|
-
documentation:
|
|
14653
|
+
documentation: REQUIRE_FETCH_TIMEOUT_DOCUMENTATION,
|
|
14656
14654
|
meta: {
|
|
14657
14655
|
type: "problem",
|
|
14658
14656
|
docs: {
|
|
@@ -14734,7 +14732,7 @@ var require_fetch_timeout_default = createRule({
|
|
|
14734
14732
|
|
|
14735
14733
|
// src/rules/require-port-for-service.ts
|
|
14736
14734
|
import { AST_NODE_TYPES as AST_NODE_TYPES60 } from "@typescript-eslint/utils";
|
|
14737
|
-
var
|
|
14735
|
+
var REQUIRE_PORT_FOR_SERVICE_DOCUMENTATION = {
|
|
14738
14736
|
summary: "Advise when an exported service with injected collaborators has public methods not covered by its declared ports.",
|
|
14739
14737
|
rationale: "A declared port keeps consumers coupled to the service capability instead of its concrete implementation.",
|
|
14740
14738
|
remediation: "Declare and implement an interface covering the service's public methods.",
|
|
@@ -15214,7 +15212,7 @@ function hasServicePort(node, methods, classes, interfaces) {
|
|
|
15214
15212
|
}
|
|
15215
15213
|
var require_port_for_service_default = createRule({
|
|
15216
15214
|
name: "require-port-for-service",
|
|
15217
|
-
documentation:
|
|
15215
|
+
documentation: REQUIRE_PORT_FOR_SERVICE_DOCUMENTATION,
|
|
15218
15216
|
meta: {
|
|
15219
15217
|
type: "suggestion",
|
|
15220
15218
|
docs: {
|
|
@@ -15279,7 +15277,7 @@ var require_port_for_service_default = createRule({
|
|
|
15279
15277
|
|
|
15280
15278
|
// src/rules/require-static-next-matcher.ts
|
|
15281
15279
|
import { AST_NODE_TYPES as AST_NODE_TYPES61 } from "@typescript-eslint/utils";
|
|
15282
|
-
var
|
|
15280
|
+
var REQUIRE_STATIC_NEXT_MATCHER_DOCUMENTATION = {
|
|
15283
15281
|
summary: "Require Next.js middleware and proxy matcher configuration to contain only build-time literals.",
|
|
15284
15282
|
rationale: "Next.js must statically analyze matcher values at build time; computed values are ignored.",
|
|
15285
15283
|
remediation: "Write matcher strings, arrays, and object fields as literals in the exported config.",
|
|
@@ -15323,7 +15321,7 @@ function propertyName4(property) {
|
|
|
15323
15321
|
}
|
|
15324
15322
|
var require_static_next_matcher_default = createRule({
|
|
15325
15323
|
name: "require-static-next-matcher",
|
|
15326
|
-
documentation:
|
|
15324
|
+
documentation: REQUIRE_STATIC_NEXT_MATCHER_DOCUMENTATION,
|
|
15327
15325
|
meta: {
|
|
15328
15326
|
type: "problem",
|
|
15329
15327
|
docs: {
|
|
@@ -15368,7 +15366,7 @@ var require_static_next_matcher_default = createRule({
|
|
|
15368
15366
|
|
|
15369
15367
|
// src/rules/require-use-form-default-values.ts
|
|
15370
15368
|
import { ASTUtils as ASTUtils19 } from "@typescript-eslint/utils";
|
|
15371
|
-
var
|
|
15369
|
+
var REQUIRE_USE_FORM_DEFAULT_VALUES_DOCUMENTATION = {
|
|
15372
15370
|
summary: "react-hook-form useForm call without defaultValues",
|
|
15373
15371
|
rationale: "Without an explicit initial value, fields can change from uncontrolled to controlled as data arrives, reset behavior becomes ambiguous, and the form's initial shape no longer documents the values users can edit.",
|
|
15374
15372
|
remediation: "Pass an object with a defaultValues property to useForm; use empty strings, nulls, or schema-appropriate values deliberately for every controlled field.",
|
|
@@ -15404,10 +15402,10 @@ function hasDefaultValues(options) {
|
|
|
15404
15402
|
}
|
|
15405
15403
|
var require_use_form_default_values_default = createRule({
|
|
15406
15404
|
name: "require-use-form-default-values",
|
|
15407
|
-
documentation:
|
|
15405
|
+
documentation: REQUIRE_USE_FORM_DEFAULT_VALUES_DOCUMENTATION,
|
|
15408
15406
|
meta: {
|
|
15409
15407
|
type: "problem",
|
|
15410
|
-
docs: { description:
|
|
15408
|
+
docs: { description: REQUIRE_USE_FORM_DEFAULT_VALUES_DOCUMENTATION.summary },
|
|
15411
15409
|
schema: [],
|
|
15412
15410
|
messages: {
|
|
15413
15411
|
requireUseFormDefaultValues: "Pass explicit defaultValues to useForm so fields have a stable initial shape and reset behavior."
|
|
@@ -15439,7 +15437,7 @@ var require_use_form_default_values_default = createRule({
|
|
|
15439
15437
|
// src/rules/require-use-server-in-actions-file.ts
|
|
15440
15438
|
import "@typescript-eslint/utils";
|
|
15441
15439
|
var ACTION_MODULE_RE = /(?:^|\/)app\/.*\/(?:actions|[^/]+-actions)\.[cm]?[jt]s$/u;
|
|
15442
|
-
var
|
|
15440
|
+
var REQUIRE_USE_SERVER_IN_ACTIONS_FILE_DOCUMENTATION = {
|
|
15443
15441
|
summary: "route action module missing the use server directive",
|
|
15444
15442
|
rationale: "An exported async function is not callable as a Server Action merely because its file is named actions.ts. Without the module directive, a client import can fail or pull server-only implementation details across the client boundary.",
|
|
15445
15443
|
remediation: "Put 'use server' at the start of the route action module.",
|
|
@@ -15477,10 +15475,10 @@ function isExportedAsyncFunction(node) {
|
|
|
15477
15475
|
}
|
|
15478
15476
|
var require_use_server_in_actions_file_default = createRule({
|
|
15479
15477
|
name: "require-use-server-in-actions-file",
|
|
15480
|
-
documentation:
|
|
15478
|
+
documentation: REQUIRE_USE_SERVER_IN_ACTIONS_FILE_DOCUMENTATION,
|
|
15481
15479
|
meta: {
|
|
15482
15480
|
type: "problem",
|
|
15483
|
-
docs: { description:
|
|
15481
|
+
docs: { description: REQUIRE_USE_SERVER_IN_ACTIONS_FILE_DOCUMENTATION.summary },
|
|
15484
15482
|
schema: [],
|
|
15485
15483
|
messages: {
|
|
15486
15484
|
requireUseServerInActionsFile: "This route action module exports an async function but is missing a leading 'use server' directive."
|
|
@@ -15507,7 +15505,7 @@ import {
|
|
|
15507
15505
|
AST_NODE_TYPES as AST_NODE_TYPES62,
|
|
15508
15506
|
ASTUtils as ASTUtils20
|
|
15509
15507
|
} from "@typescript-eslint/utils";
|
|
15510
|
-
var
|
|
15508
|
+
var REQUIRE_ZOD_FORM_VALIDATION_DOCUMENTATION = {
|
|
15511
15509
|
summary: "Require Zod validation (`Schema.parse(...)` / `Schema.safeParse(...)`) when reading values out of a `FormData` object.",
|
|
15512
15510
|
rationale: "FormData values are untrusted strings or files and need runtime validation before use.",
|
|
15513
15511
|
remediation: "Read the value inside a Zod schema's `parse` or `safeParse` input.",
|
|
@@ -15556,7 +15554,7 @@ var isFormDataMethodCall = (node) => {
|
|
|
15556
15554
|
};
|
|
15557
15555
|
var require_zod_form_validation_default = createRule({
|
|
15558
15556
|
name: "require-zod-form-validation",
|
|
15559
|
-
documentation:
|
|
15557
|
+
documentation: REQUIRE_ZOD_FORM_VALIDATION_DOCUMENTATION,
|
|
15560
15558
|
meta: {
|
|
15561
15559
|
type: "problem",
|
|
15562
15560
|
docs: {
|
|
@@ -15807,7 +15805,7 @@ var require_zod_form_validation_default = createRule({
|
|
|
15807
15805
|
|
|
15808
15806
|
// src/rules/store-insert-requires-on-conflict.ts
|
|
15809
15807
|
import "@typescript-eslint/utils";
|
|
15810
|
-
var
|
|
15808
|
+
var STORE_INSERT_REQUIRES_ON_CONFLICT_DOCUMENTATION = {
|
|
15811
15809
|
summary: "Require embedded inserts in explicitly replayable callables to carry conflict handling.",
|
|
15812
15810
|
rationale: "A callable named as an enqueue, seed, migration, schedule, ensure, or upsert promises replay safety.",
|
|
15813
15811
|
remediation: "Add an appropriate `ON CONFLICT` action or supported replay-safe insert form.",
|
|
@@ -15840,7 +15838,7 @@ function owningCallableName(node) {
|
|
|
15840
15838
|
var INSERT_GATE = /insert/i;
|
|
15841
15839
|
var store_insert_requires_on_conflict_default = createRule({
|
|
15842
15840
|
name: "store-insert-requires-on-conflict",
|
|
15843
|
-
documentation:
|
|
15841
|
+
documentation: STORE_INSERT_REQUIRES_ON_CONFLICT_DOCUMENTATION,
|
|
15844
15842
|
meta: {
|
|
15845
15843
|
type: "problem",
|
|
15846
15844
|
docs: {
|
|
@@ -15871,7 +15869,7 @@ var store_insert_requires_on_conflict_default = createRule({
|
|
|
15871
15869
|
|
|
15872
15870
|
// src/rules/stepdown.ts
|
|
15873
15871
|
import { AST_NODE_TYPES as AST_NODE_TYPES63, ASTUtils as ASTUtils21 } from "@typescript-eslint/utils";
|
|
15874
|
-
var
|
|
15872
|
+
var STEPDOWN_DOCUMENTATION = {
|
|
15875
15873
|
summary: "Place a private helper below its sole direct same-scope caller.",
|
|
15876
15874
|
rationale: "Caller-first ordering lets a reader follow the main flow before descending into implementation details.",
|
|
15877
15875
|
remediation: "Move the private helper below its sole caller.",
|
|
@@ -16290,7 +16288,7 @@ function isClassRuntimeBarrier(member) {
|
|
|
16290
16288
|
}
|
|
16291
16289
|
var stepdown_default = createRule({
|
|
16292
16290
|
name: "stepdown",
|
|
16293
|
-
documentation:
|
|
16291
|
+
documentation: STEPDOWN_DOCUMENTATION,
|
|
16294
16292
|
meta: {
|
|
16295
16293
|
type: "suggestion",
|
|
16296
16294
|
docs: { description: "Place a private helper below its sole direct same-scope caller." },
|
|
@@ -16362,7 +16360,7 @@ var EXPECT_MATCHERS = /* @__PURE__ */ new Set([
|
|
|
16362
16360
|
]);
|
|
16363
16361
|
var EXPECT_MODIFIERS2 = /* @__PURE__ */ new Set(["not", "rejects", "resolves"]);
|
|
16364
16362
|
var ASSERT_MATCHERS = /* @__PURE__ */ new Set(["deepEqual", "doesNotMatch", "equal", "match", "notDeepEqual", "notEqual", "notStrictEqual", "ok", "strictEqual"]);
|
|
16365
|
-
var
|
|
16363
|
+
var SOURCE_COUPLED_TEST_DOCUMENTATION = {
|
|
16366
16364
|
summary: "Disallow raw repository source text as a test oracle; parse or execute the artifact instead.",
|
|
16367
16365
|
rationale: "Substring and regex checks can pass on comments or unreachable configuration and fail after behavior-preserving formatting changes.",
|
|
16368
16366
|
remediation: "Parse the artifact, execute its validator, or assert on another runtime contract.",
|
|
@@ -16620,13 +16618,13 @@ function createSourceCoupledRule(name, documentation, sourceSuffixRe) {
|
|
|
16620
16618
|
}
|
|
16621
16619
|
var source_coupled_test_default = createSourceCoupledRule(
|
|
16622
16620
|
"source-coupled-test",
|
|
16623
|
-
|
|
16621
|
+
SOURCE_COUPLED_TEST_DOCUMENTATION,
|
|
16624
16622
|
GENERAL_SOURCE_SUFFIX_RE
|
|
16625
16623
|
);
|
|
16626
16624
|
|
|
16627
16625
|
// src/rules/iac-source-coupled-test.ts
|
|
16628
16626
|
var IAC_SOURCE_SUFFIX_RE = /(?:\.tf\.json|\.tftest\.(?:hcl|json)|\.(?:hcl|tf|tfvars))$/iu;
|
|
16629
|
-
var
|
|
16627
|
+
var IAC_SOURCE_COUPLED_TEST_DOCUMENTATION = {
|
|
16630
16628
|
summary: "Disallow raw IaC source text as a test oracle; inspect a rendered plan, provider state, or runtime behavior.",
|
|
16631
16629
|
rationale: "Substring and regex checks can pass on comments, formatting, or unreachable Terraform configuration while clients fail silently.",
|
|
16632
16630
|
remediation: "Parse rendered plan JSON, query the provider, or exercise the deployed runtime contract.",
|
|
@@ -16658,31 +16656,33 @@ var iacSourceCoupledTestDocumentation = {
|
|
|
16658
16656
|
};
|
|
16659
16657
|
var iac_source_coupled_test_default = createSourceCoupledRule(
|
|
16660
16658
|
"iac-source-coupled-test",
|
|
16661
|
-
|
|
16659
|
+
IAC_SOURCE_COUPLED_TEST_DOCUMENTATION,
|
|
16662
16660
|
IAC_SOURCE_SUFFIX_RE
|
|
16663
16661
|
);
|
|
16664
16662
|
|
|
16665
|
-
// src/rules/zod-
|
|
16663
|
+
// src/rules/require-pascal-case-zod-schema-name.ts
|
|
16666
16664
|
import {
|
|
16667
16665
|
AST_NODE_TYPES as AST_NODE_TYPES65,
|
|
16668
16666
|
ASTUtils as ASTUtils22
|
|
16669
16667
|
} from "@typescript-eslint/utils";
|
|
16670
|
-
var
|
|
16671
|
-
summary: "
|
|
16672
|
-
rationale: "A
|
|
16673
|
-
remediation: "Rename the
|
|
16668
|
+
var REQUIRE_PASCAL_CASE_ZOD_SCHEMA_NAME_DOCUMENTATION = {
|
|
16669
|
+
summary: "Require confirmed module-level Zod schema contracts to use PascalCase with a `Schema` suffix.",
|
|
16670
|
+
rationale: "A reusable Zod schema is a runtime type contract. PascalCase mirrors that role; SCREAMING_SNAKE_CASE should remain reserved for scalar values and lookup tables.",
|
|
16671
|
+
remediation: "Rename the binding to PascalCase ending in `Schema` (for example, `MutationRouteBaseSchema`).",
|
|
16674
16672
|
category: "style",
|
|
16673
|
+
aliases: ["zod-naming-convention"],
|
|
16674
|
+
autofix: "none",
|
|
16675
|
+
limitations: [
|
|
16676
|
+
"Only module-level bindings proven from a Zod import or a same-file proven schema are checked.",
|
|
16677
|
+
"Tests, benchmarks, generated files, imported schemas, re-export aliases, and arbitrary wrapper-factory results are excluded.",
|
|
16678
|
+
"Cross-file and exported renames are not safely file-local, so the rule has no autofix."
|
|
16679
|
+
],
|
|
16675
16680
|
examples: [
|
|
16676
|
-
{ id: "
|
|
16677
|
-
{ id: "
|
|
16681
|
+
{ id: "runtime-type-schema-name", title: "Name a reusable schema like a runtime type contract", outcome: "no-match", files: [{ path: "src/user.ts", source: "import { z } from 'zod';\nexport const UserSchema = z.object({ id: z.string() });" }], focusPath: "src/user.ts", expectedCount: 0, public: true },
|
|
16682
|
+
{ id: "screaming-schema-name", title: "Do not name a schema like a scalar constant", outcome: "match", files: [{ path: "src/user.ts", source: "import { z } from 'zod';\nexport const USER_SCHEMA = z.object({ id: z.string() });" }], focusPath: "src/user.ts", expectedCount: 1, public: true }
|
|
16678
16683
|
]
|
|
16679
16684
|
};
|
|
16680
|
-
var
|
|
16681
|
-
prefix: { test: ZOD_PREFIX_RE, messageId: "zPrefix" },
|
|
16682
|
-
suffix: { test: ZOD_SUFFIX_RE, messageId: "schemaSuffix" },
|
|
16683
|
-
either: { test: ZOD_SCHEMA_NAME_RE, messageId: "zodSchemaName" }
|
|
16684
|
-
};
|
|
16685
|
-
var CONTAINS_SCHEMA_RE = /schema/i;
|
|
16685
|
+
var PASCAL_SCHEMA_NAME_RE = /^[A-Z][A-Za-z0-9]*Schema$/;
|
|
16686
16686
|
var BENCHMARK_PATH_RE = /(^|[\\/])(?:benchmarks?|bench)[\\/]/;
|
|
16687
16687
|
var NON_SCHEMA_TERMINALS = /* @__PURE__ */ new Set([
|
|
16688
16688
|
"parse",
|
|
@@ -16707,6 +16707,95 @@ var NON_SCHEMA_TERMINALS = /* @__PURE__ */ new Set([
|
|
|
16707
16707
|
"prettifyError",
|
|
16708
16708
|
"treeifyError"
|
|
16709
16709
|
]);
|
|
16710
|
+
var ZOD_SCHEMA_FACTORIES = /* @__PURE__ */ new Set([
|
|
16711
|
+
"any",
|
|
16712
|
+
"array",
|
|
16713
|
+
"base64",
|
|
16714
|
+
"base64url",
|
|
16715
|
+
"bigint",
|
|
16716
|
+
"boolean",
|
|
16717
|
+
"cidrv4",
|
|
16718
|
+
"cidrv6",
|
|
16719
|
+
"codec",
|
|
16720
|
+
"custom",
|
|
16721
|
+
"date",
|
|
16722
|
+
"discriminatedUnion",
|
|
16723
|
+
"email",
|
|
16724
|
+
"emoji",
|
|
16725
|
+
"enum",
|
|
16726
|
+
"file",
|
|
16727
|
+
"function",
|
|
16728
|
+
"hash",
|
|
16729
|
+
"hex",
|
|
16730
|
+
"hostname",
|
|
16731
|
+
"instanceof",
|
|
16732
|
+
"intersection",
|
|
16733
|
+
"ipv4",
|
|
16734
|
+
"ipv6",
|
|
16735
|
+
"json",
|
|
16736
|
+
"jwt",
|
|
16737
|
+
"lazy",
|
|
16738
|
+
"literal",
|
|
16739
|
+
"looseObject",
|
|
16740
|
+
"map",
|
|
16741
|
+
"nan",
|
|
16742
|
+
"nativeEnum",
|
|
16743
|
+
"never",
|
|
16744
|
+
"null",
|
|
16745
|
+
"nullable",
|
|
16746
|
+
"nullish",
|
|
16747
|
+
"number",
|
|
16748
|
+
"object",
|
|
16749
|
+
"optional",
|
|
16750
|
+
"partialRecord",
|
|
16751
|
+
"preprocess",
|
|
16752
|
+
"promise",
|
|
16753
|
+
"record",
|
|
16754
|
+
"set",
|
|
16755
|
+
"strictObject",
|
|
16756
|
+
"string",
|
|
16757
|
+
"stringbool",
|
|
16758
|
+
"symbol",
|
|
16759
|
+
"templateLiteral",
|
|
16760
|
+
"tuple",
|
|
16761
|
+
"undefined",
|
|
16762
|
+
"union",
|
|
16763
|
+
"unknown",
|
|
16764
|
+
"url",
|
|
16765
|
+
"uuid",
|
|
16766
|
+
"void"
|
|
16767
|
+
]);
|
|
16768
|
+
var ZOD_FACTORY_NAMESPACES = /* @__PURE__ */ new Set(["coerce", "iso"]);
|
|
16769
|
+
var SCHEMA_RETURNING_METHODS = /* @__PURE__ */ new Set([
|
|
16770
|
+
"and",
|
|
16771
|
+
"array",
|
|
16772
|
+
"brand",
|
|
16773
|
+
"catch",
|
|
16774
|
+
"check",
|
|
16775
|
+
"clone",
|
|
16776
|
+
"default",
|
|
16777
|
+
"describe",
|
|
16778
|
+
"extend",
|
|
16779
|
+
"keyof",
|
|
16780
|
+
"meta",
|
|
16781
|
+
"nullable",
|
|
16782
|
+
"nullish",
|
|
16783
|
+
"omit",
|
|
16784
|
+
"optional",
|
|
16785
|
+
"or",
|
|
16786
|
+
"overwrite",
|
|
16787
|
+
"partial",
|
|
16788
|
+
"pick",
|
|
16789
|
+
"pipe",
|
|
16790
|
+
"prefault",
|
|
16791
|
+
"readonly",
|
|
16792
|
+
"refine",
|
|
16793
|
+
"register",
|
|
16794
|
+
"required",
|
|
16795
|
+
"safeExtend",
|
|
16796
|
+
"superRefine",
|
|
16797
|
+
"transform"
|
|
16798
|
+
]);
|
|
16710
16799
|
var terminalMethodName = (callee) => !callee.computed && callee.property.type === AST_NODE_TYPES65.Identifier ? callee.property.name : null;
|
|
16711
16800
|
var calleeChainRoot = (node) => {
|
|
16712
16801
|
let current = node;
|
|
@@ -16725,38 +16814,55 @@ var calleeChainRoot = (node) => {
|
|
|
16725
16814
|
return null;
|
|
16726
16815
|
}
|
|
16727
16816
|
};
|
|
16728
|
-
var
|
|
16729
|
-
|
|
16730
|
-
|
|
16817
|
+
var chainMemberNames = (node) => {
|
|
16818
|
+
const names = [];
|
|
16819
|
+
let current = node;
|
|
16820
|
+
for (; ; ) {
|
|
16821
|
+
if (current.type === AST_NODE_TYPES65.MemberExpression) {
|
|
16822
|
+
if (current.computed || current.property.type !== AST_NODE_TYPES65.Identifier) return [];
|
|
16823
|
+
names.push(current.property.name);
|
|
16824
|
+
current = current.object;
|
|
16825
|
+
continue;
|
|
16826
|
+
}
|
|
16827
|
+
if (current.type === AST_NODE_TYPES65.CallExpression) {
|
|
16828
|
+
current = current.callee;
|
|
16829
|
+
continue;
|
|
16830
|
+
}
|
|
16831
|
+
break;
|
|
16832
|
+
}
|
|
16833
|
+
names.reverse();
|
|
16834
|
+
return names;
|
|
16835
|
+
};
|
|
16836
|
+
var unwrapExpression4 = (node) => {
|
|
16837
|
+
let current = node;
|
|
16838
|
+
while (current.type === AST_NODE_TYPES65.TSAsExpression || current.type === AST_NODE_TYPES65.TSSatisfiesExpression || current.type === AST_NODE_TYPES65.TSNonNullExpression || current.type === AST_NODE_TYPES65.TSTypeAssertion) {
|
|
16839
|
+
current = current.expression;
|
|
16840
|
+
}
|
|
16841
|
+
return current;
|
|
16842
|
+
};
|
|
16843
|
+
var isModuleDeclarator = (node) => {
|
|
16844
|
+
const declaration = node.parent;
|
|
16845
|
+
if (declaration.type !== AST_NODE_TYPES65.VariableDeclaration) return false;
|
|
16846
|
+
const owner = declaration.parent;
|
|
16847
|
+
return owner.type === AST_NODE_TYPES65.Program || owner.type === AST_NODE_TYPES65.ExportNamedDeclaration && owner.parent.type === AST_NODE_TYPES65.Program;
|
|
16848
|
+
};
|
|
16849
|
+
var require_pascal_case_zod_schema_name_default = createRule({
|
|
16850
|
+
name: "require-pascal-case-zod-schema-name",
|
|
16851
|
+
documentation: REQUIRE_PASCAL_CASE_ZOD_SCHEMA_NAME_DOCUMENTATION,
|
|
16731
16852
|
meta: {
|
|
16732
16853
|
type: "suggestion",
|
|
16733
16854
|
docs: {
|
|
16734
|
-
description: "
|
|
16855
|
+
description: "Require confirmed module-level Zod schema contracts to use PascalCase with a `Schema` suffix."
|
|
16735
16856
|
},
|
|
16736
|
-
schema: [
|
|
16737
|
-
{
|
|
16738
|
-
type: "object",
|
|
16739
|
-
additionalProperties: false,
|
|
16740
|
-
properties: {
|
|
16741
|
-
convention: {
|
|
16742
|
-
type: "string",
|
|
16743
|
-
enum: ["prefix", "suffix", "either"]
|
|
16744
|
-
}
|
|
16745
|
-
}
|
|
16746
|
-
}
|
|
16747
|
-
],
|
|
16857
|
+
schema: [],
|
|
16748
16858
|
messages: {
|
|
16749
|
-
|
|
16750
|
-
schemaSuffix: "Zod schema names should end with Schema (e.g. `userSchema`)",
|
|
16751
|
-
zodSchemaName: "Zod schema names should start with Z (`ZUser`) or end with Schema (`userSchema`)"
|
|
16859
|
+
requirePascalSchema: "Zod schema contracts must use PascalCase ending in Schema (for example, `MutationRouteBaseSchema`); reserve SCREAMING_SNAKE_CASE for scalar/table constants."
|
|
16752
16860
|
}
|
|
16753
16861
|
},
|
|
16754
|
-
defaultOptions: [
|
|
16755
|
-
create(context
|
|
16756
|
-
const convention = optionsArg?.convention ?? "either";
|
|
16757
|
-
const { test, messageId } = CONVENTIONS[convention];
|
|
16758
|
-
const acceptsSchemaWord = convention !== "prefix";
|
|
16862
|
+
defaultOptions: [],
|
|
16863
|
+
create(context) {
|
|
16759
16864
|
const zodBindings = /* @__PURE__ */ new Set();
|
|
16865
|
+
const schemaBindings = /* @__PURE__ */ new Set();
|
|
16760
16866
|
function resolvedBinding(identifier) {
|
|
16761
16867
|
return ASTUtils22.findVariable(
|
|
16762
16868
|
context.sourceCode.getScope(identifier),
|
|
@@ -16773,6 +16879,26 @@ var zod_naming_convention_default = createRule({
|
|
|
16773
16879
|
const binding = resolvedBinding(root);
|
|
16774
16880
|
return binding !== null && zodBindings.has(binding);
|
|
16775
16881
|
}
|
|
16882
|
+
function isSchemaBinding(identifier) {
|
|
16883
|
+
const binding = resolvedBinding(identifier);
|
|
16884
|
+
return binding !== null && schemaBindings.has(binding);
|
|
16885
|
+
}
|
|
16886
|
+
function isConfirmedSchema(expression) {
|
|
16887
|
+
const init = unwrapExpression4(expression);
|
|
16888
|
+
if (init.type === AST_NODE_TYPES65.Identifier) return isSchemaBinding(init);
|
|
16889
|
+
if (init.type !== AST_NODE_TYPES65.CallExpression || init.callee.type !== AST_NODE_TYPES65.MemberExpression) {
|
|
16890
|
+
return false;
|
|
16891
|
+
}
|
|
16892
|
+
const terminal = terminalMethodName(init.callee);
|
|
16893
|
+
if (terminal === null || NON_SCHEMA_TERMINALS.has(terminal)) return false;
|
|
16894
|
+
const names = chainMemberNames(init.callee);
|
|
16895
|
+
if (names.length === 0) return false;
|
|
16896
|
+
if (isZodChain(init.callee)) {
|
|
16897
|
+
return ZOD_SCHEMA_FACTORIES.has(names[0] ?? "") || ZOD_FACTORY_NAMESPACES.has(names[0] ?? "") && ZOD_SCHEMA_FACTORIES.has(names[1] ?? "");
|
|
16898
|
+
}
|
|
16899
|
+
const root = calleeChainRoot(init.callee);
|
|
16900
|
+
return root !== null && isSchemaBinding(root) && SCHEMA_RETURNING_METHODS.has(terminal);
|
|
16901
|
+
}
|
|
16776
16902
|
if (isTestFile(context.filename) || BENCHMARK_PATH_RE.test(context.filename.replaceAll("\\", "/")) || isGeneratedFile(context.filename, context.sourceCode.text)) {
|
|
16777
16903
|
return {};
|
|
16778
16904
|
}
|
|
@@ -16786,20 +16912,17 @@ var zod_naming_convention_default = createRule({
|
|
|
16786
16912
|
}
|
|
16787
16913
|
},
|
|
16788
16914
|
VariableDeclarator(node) {
|
|
16915
|
+
if (!isModuleDeclarator(node)) return;
|
|
16789
16916
|
const init = node.init;
|
|
16790
16917
|
if (init === null || init === void 0) return;
|
|
16791
|
-
if (init.type !== AST_NODE_TYPES65.CallExpression) return;
|
|
16792
|
-
const callee = init.callee;
|
|
16793
|
-
if (callee.type !== AST_NODE_TYPES65.MemberExpression) return;
|
|
16794
|
-
if (!isZodChain(callee)) return;
|
|
16795
|
-
const terminal = terminalMethodName(callee);
|
|
16796
|
-
if (terminal !== null && NON_SCHEMA_TERMINALS.has(terminal)) return;
|
|
16797
16918
|
if (node.id.type !== AST_NODE_TYPES65.Identifier) return;
|
|
16798
|
-
if (
|
|
16799
|
-
|
|
16919
|
+
if (!isConfirmedSchema(init)) return;
|
|
16920
|
+
const binding = resolvedBinding(node.id);
|
|
16921
|
+
if (binding !== null) schemaBindings.add(binding);
|
|
16922
|
+
if (PASCAL_SCHEMA_NAME_RE.test(node.id.name)) return;
|
|
16800
16923
|
context.report({
|
|
16801
16924
|
node: node.id,
|
|
16802
|
-
messageId
|
|
16925
|
+
messageId: "requirePascalSchema"
|
|
16803
16926
|
});
|
|
16804
16927
|
}
|
|
16805
16928
|
};
|
|
@@ -16807,15 +16930,16 @@ var zod_naming_convention_default = createRule({
|
|
|
16807
16930
|
});
|
|
16808
16931
|
|
|
16809
16932
|
// src/rules/_renames.ts
|
|
16810
|
-
var
|
|
16933
|
+
var RENAMED_RULES = {
|
|
16811
16934
|
"jsdoc-restates-signature": "no-restated-jsdoc",
|
|
16935
|
+
"zod-naming-convention": "require-pascal-case-zod-schema-name",
|
|
16812
16936
|
"require-interface-for-injected-service": "require-port-for-service",
|
|
16813
16937
|
"strict-test-assertions": "prefer-whole-object-assertion",
|
|
16814
16938
|
"trailing-value-narration": "no-trailing-value-narration"
|
|
16815
16939
|
};
|
|
16816
16940
|
|
|
16817
16941
|
// src/rules/_retired.ts
|
|
16818
|
-
var
|
|
16942
|
+
var RETIRED_RULES = {
|
|
16819
16943
|
"ban-loose-type-guards-in-tests": {
|
|
16820
16944
|
removedIn: "5.0.0",
|
|
16821
16945
|
reason: "Delete the config entry and suppressions; there is no replacement."
|
|
@@ -16887,7 +17011,7 @@ var retiredRules = {
|
|
|
16887
17011
|
};
|
|
16888
17012
|
|
|
16889
17013
|
// src/index.ts
|
|
16890
|
-
var
|
|
17014
|
+
var RULES = {
|
|
16891
17015
|
"iac-source-coupled-test": iac_source_coupled_test_default,
|
|
16892
17016
|
"duplicate-test-body": duplicate_test_body_default,
|
|
16893
17017
|
"enforce-file-structure": enforce_file_structure_default,
|
|
@@ -16966,19 +17090,19 @@ var rules = {
|
|
|
16966
17090
|
"store-insert-requires-on-conflict": store_insert_requires_on_conflict_default,
|
|
16967
17091
|
"stepdown": stepdown_default,
|
|
16968
17092
|
"source-coupled-test": source_coupled_test_default,
|
|
16969
|
-
"zod-
|
|
17093
|
+
"require-pascal-case-zod-schema-name": require_pascal_case_zod_schema_name_default
|
|
16970
17094
|
};
|
|
16971
17095
|
var meta = {
|
|
16972
17096
|
name: "@sarj/eslint-plugin",
|
|
16973
|
-
version: "15.13.
|
|
17097
|
+
version: "15.13.3"
|
|
16974
17098
|
};
|
|
16975
|
-
var
|
|
17099
|
+
var APPLICATION_ONLY_RULES = [
|
|
16976
17100
|
"no-restricted-library-load",
|
|
16977
17101
|
"prefer-native-random-uuid",
|
|
16978
17102
|
"prefer-shadcn-primitives"
|
|
16979
17103
|
];
|
|
16980
|
-
var
|
|
16981
|
-
var
|
|
17104
|
+
var ADVISORY_RULES = ["@sarj/require-pascal-case-zod-schema-name"];
|
|
17105
|
+
var RECOMMENDED_RULES = {
|
|
16982
17106
|
"@sarj/interface-contract-members-private": "error",
|
|
16983
17107
|
"@sarj/iac-source-coupled-test": "error",
|
|
16984
17108
|
"@sarj/duplicate-test-body": "error",
|
|
@@ -17050,9 +17174,9 @@ var recommendedRules = {
|
|
|
17050
17174
|
"@sarj/stepdown": "error",
|
|
17051
17175
|
"@sarj/source-coupled-test": "error",
|
|
17052
17176
|
"@sarj/test-phase-label-comment": "error",
|
|
17053
|
-
"@sarj/zod-
|
|
17177
|
+
"@sarj/require-pascal-case-zod-schema-name": "warn"
|
|
17054
17178
|
};
|
|
17055
|
-
var
|
|
17179
|
+
var STRICT_RULES = {
|
|
17056
17180
|
"@sarj/interface-contract-members-private": "error",
|
|
17057
17181
|
"@sarj/iac-source-coupled-test": "error",
|
|
17058
17182
|
"@sarj/duplicate-test-body": "error",
|
|
@@ -17128,36 +17252,43 @@ var strictRules = {
|
|
|
17128
17252
|
"@sarj/stepdown": "error",
|
|
17129
17253
|
"@sarj/source-coupled-test": "error",
|
|
17130
17254
|
"@sarj/test-phase-label-comment": "error",
|
|
17131
|
-
"@sarj/zod-
|
|
17255
|
+
"@sarj/require-pascal-case-zod-schema-name": "warn"
|
|
17132
17256
|
};
|
|
17133
|
-
var
|
|
17257
|
+
var PLUGIN = {
|
|
17134
17258
|
meta,
|
|
17135
|
-
rules,
|
|
17136
|
-
retiredRules,
|
|
17259
|
+
rules: RULES,
|
|
17260
|
+
retiredRules: RETIRED_RULES,
|
|
17137
17261
|
get configs() {
|
|
17138
17262
|
return {
|
|
17139
17263
|
recommended: {
|
|
17140
17264
|
name: "@sarj/recommended",
|
|
17141
|
-
plugins: { "@sarj":
|
|
17142
|
-
rules:
|
|
17265
|
+
plugins: { "@sarj": PLUGIN },
|
|
17266
|
+
rules: RECOMMENDED_RULES
|
|
17143
17267
|
},
|
|
17144
17268
|
strict: {
|
|
17145
17269
|
name: "@sarj/strict",
|
|
17146
|
-
plugins: { "@sarj":
|
|
17147
|
-
rules:
|
|
17270
|
+
plugins: { "@sarj": PLUGIN },
|
|
17271
|
+
rules: STRICT_RULES
|
|
17148
17272
|
}
|
|
17149
17273
|
};
|
|
17150
17274
|
}
|
|
17151
17275
|
};
|
|
17152
|
-
var index_default =
|
|
17276
|
+
var index_default = PLUGIN;
|
|
17153
17277
|
export {
|
|
17154
|
-
|
|
17155
|
-
|
|
17278
|
+
ADVISORY_RULES,
|
|
17279
|
+
APPLICATION_ONLY_RULES,
|
|
17280
|
+
RECOMMENDED_RULES,
|
|
17281
|
+
RENAMED_RULES,
|
|
17282
|
+
RETIRED_RULES,
|
|
17283
|
+
RULES,
|
|
17284
|
+
STRICT_RULES,
|
|
17285
|
+
ADVISORY_RULES as advisoryRules,
|
|
17286
|
+
APPLICATION_ONLY_RULES as applicationOnlyRules,
|
|
17156
17287
|
index_default as default,
|
|
17157
17288
|
publicDocumentation,
|
|
17158
|
-
recommendedRules,
|
|
17159
|
-
renamedRules,
|
|
17160
|
-
retiredRules,
|
|
17161
|
-
rules,
|
|
17162
|
-
strictRules
|
|
17289
|
+
RECOMMENDED_RULES as recommendedRules,
|
|
17290
|
+
RENAMED_RULES as renamedRules,
|
|
17291
|
+
RETIRED_RULES as retiredRules,
|
|
17292
|
+
RULES as rules,
|
|
17293
|
+
STRICT_RULES as strictRules
|
|
17163
17294
|
};
|