@sarj/eslint-plugin 15.6.8 → 15.6.9

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 CHANGED
@@ -4292,6 +4292,87 @@ var no_long_comment_default = createRule({
4292
4292
  }
4293
4293
  });
4294
4294
 
4295
+ // src/rules/no-vague-suppression-description.ts
4296
+ var DIRECTIVE_RE3 = /(?:eslint-(?:disable|disable-next-line|disable-line)|@ts-(?:expect-error|ignore))\b/iu;
4297
+ var DESCRIPTION_RE = /(?::|--)\s*(.+?)\s*$/u;
4298
+ var VAGUE_RE = /^(?:needed|required|intentional(?:ly)?|ignore(?:d)?|false positive|type error|typescript|to satisfy (?:the )?(?:linter|typescript|type checker))\.?$/iu;
4299
+ var noVagueSuppressionDescriptionDocumentation = {
4300
+ summary: "Require suppression descriptions to name the concrete mismatch or invariant instead of a generic non-reason.",
4301
+ rationale: "Generic phrases satisfy require-description mechanically while leaving reviewers unable to audit the risk or remove stale debt.",
4302
+ remediation: "Name the exact type/runtime mismatch, external contract, or safety invariant that makes this suppression acceptable.",
4303
+ category: "maintainability",
4304
+ limitations: [
4305
+ "Only ESLint disable comments and TypeScript expect-error/ignore directives are checked.",
4306
+ "The rule uses a small anchored vocabulary and does not score prose quality generally.",
4307
+ "Generated files and descriptions containing any concrete context are excluded."
4308
+ ],
4309
+ examples: [
4310
+ {
4311
+ id: "concrete-runtime-mismatch",
4312
+ title: "Explain the concrete runtime contract",
4313
+ outcome: "no-match",
4314
+ files: [
4315
+ {
4316
+ path: "src/adapter.ts",
4317
+ source: "// @ts-expect-error -- vendor types omit the runtime requestId field\nreturn response.requestId;"
4318
+ }
4319
+ ],
4320
+ focusPath: "src/adapter.ts",
4321
+ expectedCount: 0,
4322
+ public: true
4323
+ },
4324
+ {
4325
+ id: "generic-suppression-reason",
4326
+ title: "Reject a suppression with no auditable reason",
4327
+ outcome: "match",
4328
+ files: [
4329
+ {
4330
+ path: "src/adapter.ts",
4331
+ source: "// @ts-expect-error -- false positive\nreturn response.requestId;"
4332
+ }
4333
+ ],
4334
+ focusPath: "src/adapter.ts",
4335
+ expectedCount: 1,
4336
+ public: true
4337
+ }
4338
+ ]
4339
+ };
4340
+ var no_vague_suppression_description_default = createRule({
4341
+ name: "no-vague-suppression-description",
4342
+ documentation: noVagueSuppressionDescriptionDocumentation,
4343
+ meta: {
4344
+ type: "suggestion",
4345
+ docs: {
4346
+ description: "Require suppression descriptions to name the concrete mismatch or invariant instead of a generic non-reason."
4347
+ },
4348
+ schema: [],
4349
+ messages: {
4350
+ vagueDescription: "Suppression description `{{description}}` does not explain why the suppressed diagnostic is safe here. Name the concrete type/runtime mismatch, external contract, or invariant."
4351
+ }
4352
+ },
4353
+ defaultOptions: [],
4354
+ create(context) {
4355
+ if (isGeneratedFile(context.filename, context.sourceCode.text)) {
4356
+ return {};
4357
+ }
4358
+ return {
4359
+ Program() {
4360
+ for (const comment of context.sourceCode.getAllComments()) {
4361
+ const text = comment.value.trim();
4362
+ if (!DIRECTIVE_RE3.test(text)) continue;
4363
+ const description = DESCRIPTION_RE.exec(text)?.[1]?.trim();
4364
+ if (description === void 0 || !VAGUE_RE.test(description)) continue;
4365
+ context.report({
4366
+ loc: comment.loc,
4367
+ messageId: "vagueDescription",
4368
+ data: { description }
4369
+ });
4370
+ }
4371
+ }
4372
+ };
4373
+ }
4374
+ });
4375
+
4295
4376
  // src/rules/no-generic-single-export-module.ts
4296
4377
  var import_utils21 = require("@typescript-eslint/utils");
4297
4378
  var noGenericSingleExportModuleDocumentation = {
@@ -5431,7 +5512,7 @@ var no_repeated_string_literal_default = createRule({
5431
5512
  var import_utils28 = require("@typescript-eslint/utils");
5432
5513
  var MAX_WORDS = 8;
5433
5514
  var MIN_CONTENT_TOKENS = 2;
5434
- var DIRECTIVE_RE3 = /^(eslint\b|eslint-|sarj-noqa\b|@ts-|prettier-ignore|prettier\b|biome-|c8\b|v8\b|istanbul\b|@type\b|@vite|webpack|<reference|<amd|global\b|noinspection|todo\b|fixme\b|hack\b|xxx\b)/i;
5515
+ var DIRECTIVE_RE4 = /^(eslint\b|eslint-|sarj-noqa\b|@ts-|prettier-ignore|prettier\b|biome-|c8\b|v8\b|istanbul\b|@type\b|@vite|webpack|<reference|<amd|global\b|noinspection|todo\b|fixme\b|hack\b|xxx\b)/i;
5435
5516
  var CODEY_RE = /^[\w.$[\]'"]+\s*[:=]\s*\S|^[\w.$]+\s*\(|^(?:return|throw|await|import|export|const|let|var)\b.*[=()[\]{}]/;
5436
5517
  var BANNERISH_RE = /[=\-─-╿*#~_.]{3,}|^[A-Z0-9 _:-]+$/;
5437
5518
  var MODALITY_RE = /\b(?:can|could|should|shall|may|might|must|will|would|cannot)\b/i;
@@ -5530,7 +5611,7 @@ var no_restated_comment_default = createRule({
5530
5611
  }
5531
5612
  const body2 = comment.value.replace(/^\/*/, "").trim();
5532
5613
  if (body2.length === 0 || body2.endsWith("?")) continue;
5533
- if (DIRECTIVE_RE3.test(body2) || CODEY_RE.test(body2) || BANNERISH_RE.test(body2)) continue;
5614
+ if (DIRECTIVE_RE4.test(body2) || CODEY_RE.test(body2) || BANNERISH_RE.test(body2)) continue;
5534
5615
  if (NON_ASCII_LETTER_RE.test(body2) || isProtected(body2)) continue;
5535
5616
  if (MODALITY_RE.test(body2) || LEAD_IN_RE.test(body2) || EMPHASIS_RE.test(body2)) continue;
5536
5617
  if (NEGATION_WORD_RE.test(body2)) continue;
@@ -5578,7 +5659,7 @@ var MODELLED_TAGS = /* @__PURE__ */ new Set([
5578
5659
  ]);
5579
5660
  var PARAM_TAGS = /* @__PURE__ */ new Set(["arg", "argument", "param"]);
5580
5661
  var RETURN_TAGS = /* @__PURE__ */ new Set(["return", "returns"]);
5581
- var DIRECTIVE_RE4 = /^\s*(?:eslint\b|eslint-|@ts-|prettier|biome-|c8\b|v8\b|istanbul\b|@vite|webpack|@jsx|@jest-environment|@vitest-environment|#__)/i;
5662
+ var DIRECTIVE_RE5 = /^\s*(?:eslint\b|eslint-|@ts-|prettier|biome-|c8\b|v8\b|istanbul\b|@vite|webpack|@jsx|@jest-environment|@vitest-environment|#__)/i;
5582
5663
  var STOPWORDS2 = new Set(
5583
5664
  `the a an of to for in on with and or as at by is are was be been being
5584
5665
  this that it its if whether when where which what will would can could should
@@ -5694,7 +5775,7 @@ var no_restated_jsdoc_default = createRule({
5694
5775
  description,
5695
5776
  ...tags.filter((tag) => tag.name === "description").map((tag) => tag.text)
5696
5777
  ].filter((text) => text.length > 0).join("\n");
5697
- if (DIRECTIVE_RE4.test(describedText)) continue;
5778
+ if (DIRECTIVE_RE5.test(describedText)) continue;
5698
5779
  const tagNames = new Set(tags.map((tag) => tag.name));
5699
5780
  if ([...tagNames].some((name) => !MODELLED_TAGS.has(name))) continue;
5700
5781
  if (isProtected(describedText)) continue;
@@ -7656,10 +7737,10 @@ var STOPWORDS3 = /* @__PURE__ */ new Set([
7656
7737
  "we",
7657
7738
  "with"
7658
7739
  ]);
7659
- var DIRECTIVE_RE5 = /^\s*(?:eslint\b|eslint-|sarj-noqa\b|@ts-|prettier|biome-|c8\b|v8\b|istanbul\b|todo\b|fixme\b|hack\b|xxx\b)/i;
7740
+ var DIRECTIVE_RE6 = /^\s*(?:eslint\b|eslint-|sarj-noqa\b|@ts-|prettier|biome-|c8\b|v8\b|istanbul\b|todo\b|fixme\b|hack\b|xxx\b)/i;
7660
7741
  var UNIT_NAME_SUFFIX_RE = /(?:_(?:NS|US|MS|S|SEC|SECS|SECOND|SECONDS|MIN|MINS|MINUTE|MINUTES|HOUR|HOURS|DAY|DAYS|BYTE|BYTES|KB|MB|GB|HZ|KHZ|MHZ|PX)|(?:Ns|Us|Ms|Sec|Secs|Second|Seconds|Min|Mins|Minute|Minutes|Hour|Hours|Day|Days|Byte|Bytes|Kb|Mb|Gb|Hz|Khz|Mhz|Px))$/u;
7661
7742
  function narratesValue(body2, code) {
7662
- if (body2.length === 0 || DIRECTIVE_RE5.test(body2) || hasExternalReference(body2)) return false;
7743
+ if (body2.length === 0 || DIRECTIVE_RE6.test(body2) || hasExternalReference(body2)) return false;
7663
7744
  const codeNumbers = numbersIn(code);
7664
7745
  if (codeNumbers.size === 0) return false;
7665
7746
  const words2 = (body2.match(WORD_RE3) ?? []).map((word) => word.toLowerCase());
@@ -15305,6 +15386,7 @@ var rules = {
15305
15386
  "no-impossible-zod-literal-bounds": no_impossible_zod_literal_bounds_default,
15306
15387
  "no-log-only-catch": no_log_only_catch_default,
15307
15388
  "no-long-comment": no_long_comment_default,
15389
+ "no-vague-suppression-description": no_vague_suppression_description_default,
15308
15390
  "no-generic-single-export-module": no_generic_single_export_module_default,
15309
15391
  "no-offset-pagination": no_offset_pagination_default,
15310
15392
  "no-positional-tuple-return": no_positional_tuple_return_default,
@@ -15358,14 +15440,14 @@ var rules = {
15358
15440
  };
15359
15441
  var meta = {
15360
15442
  name: "@sarj/eslint-plugin",
15361
- version: "15.6.8"
15443
+ version: "15.6.9"
15362
15444
  };
15363
15445
  var applicationOnlyRules = [
15364
15446
  "no-restricted-library-load",
15365
15447
  "prefer-native-random-uuid",
15366
15448
  "prefer-shadcn-primitives"
15367
15449
  ];
15368
- var advisoryRules = ["source-coupled-test"];
15450
+ var advisoryRules = ["no-vague-suppression-description", "source-coupled-test"];
15369
15451
  var recommendedRules = {
15370
15452
  "@sarj/duplicate-test-body": "error",
15371
15453
  "@sarj/enforce-file-structure": "error",
@@ -15381,6 +15463,7 @@ var recommendedRules = {
15381
15463
  "@sarj/no-impossible-zod-literal-bounds": "error",
15382
15464
  "@sarj/no-log-only-catch": "error",
15383
15465
  "@sarj/no-long-comment": "error",
15466
+ "@sarj/no-vague-suppression-description": "warn",
15384
15467
  "@sarj/no-generic-single-export-module": "error",
15385
15468
  "@sarj/no-offset-pagination": "error",
15386
15469
  "@sarj/no-positional-tuple-return": "error",
@@ -15442,6 +15525,7 @@ var strictRules = {
15442
15525
  "@sarj/no-impossible-zod-literal-bounds": "error",
15443
15526
  "@sarj/no-log-only-catch": "error",
15444
15527
  "@sarj/no-long-comment": "error",
15528
+ "@sarj/no-vague-suppression-description": "warn",
15445
15529
  "@sarj/no-generic-single-export-module": "error",
15446
15530
  "@sarj/no-offset-pagination": "error",
15447
15531
  "@sarj/no-positional-tuple-return": "error",
package/dist/index.d.cts CHANGED
@@ -208,6 +208,7 @@ declare const rules: {
208
208
  readonly "no-impossible-zod-literal-bounds": DocumentedRule<readonly [], "impossibleBounds">;
209
209
  readonly "no-log-only-catch": DocumentedRule<readonly [LoggingOptions?], "noLogOnlyCatch" | "emptyCatch">;
210
210
  readonly "no-long-comment": DocumentedRule<readonly [], "tooLong">;
211
+ readonly "no-vague-suppression-description": DocumentedRule<readonly [], "vagueDescription">;
211
212
  readonly "no-generic-single-export-module": DocumentedRule<[], "genericSingleExport">;
212
213
  readonly "no-offset-pagination": DocumentedRule<readonly [], "noOffsetPagination">;
213
214
  readonly "no-positional-tuple-return": DocumentedRule<readonly [], "noPositionalTupleReturn">;
@@ -282,7 +283,7 @@ declare const rules: {
282
283
  /** Rules registered for application-profile configs but intentionally absent from general presets. */
283
284
  declare const applicationOnlyRules: readonly ["no-restricted-library-load", "prefer-native-random-uuid", "prefer-shadcn-primitives"];
284
285
  /** Calibrated rules that intentionally remain warnings until consumer-corpus precision is proven. */
285
- declare const advisoryRules: readonly ["source-coupled-test"];
286
+ declare const advisoryRules: readonly ["no-vague-suppression-description", "source-coupled-test"];
286
287
  declare const recommendedRules: {
287
288
  readonly "@sarj/duplicate-test-body": "error";
288
289
  readonly "@sarj/enforce-file-structure": "error";
@@ -300,6 +301,7 @@ declare const recommendedRules: {
300
301
  readonly "@sarj/no-impossible-zod-literal-bounds": "error";
301
302
  readonly "@sarj/no-log-only-catch": "error";
302
303
  readonly "@sarj/no-long-comment": "error";
304
+ readonly "@sarj/no-vague-suppression-description": "warn";
303
305
  readonly "@sarj/no-generic-single-export-module": "error";
304
306
  readonly "@sarj/no-offset-pagination": "error";
305
307
  readonly "@sarj/no-positional-tuple-return": "error";
@@ -365,6 +367,7 @@ declare const strictRules: {
365
367
  readonly "@sarj/no-impossible-zod-literal-bounds": "error";
366
368
  readonly "@sarj/no-log-only-catch": "error";
367
369
  readonly "@sarj/no-long-comment": "error";
370
+ readonly "@sarj/no-vague-suppression-description": "warn";
368
371
  readonly "@sarj/no-generic-single-export-module": "error";
369
372
  readonly "@sarj/no-offset-pagination": "error";
370
373
  readonly "@sarj/no-positional-tuple-return": "error";
@@ -423,7 +426,7 @@ type FlatPreset = {
423
426
  declare const plugin: {
424
427
  readonly meta: {
425
428
  readonly name: "@sarj/eslint-plugin";
426
- readonly version: "15.6.8";
429
+ readonly version: "15.6.9";
427
430
  };
428
431
  readonly rules: {
429
432
  readonly "duplicate-test-body": DocumentedRule<readonly [], "duplicateTestBody">;
@@ -446,6 +449,7 @@ declare const plugin: {
446
449
  readonly "no-impossible-zod-literal-bounds": DocumentedRule<readonly [], "impossibleBounds">;
447
450
  readonly "no-log-only-catch": DocumentedRule<readonly [LoggingOptions?], "noLogOnlyCatch" | "emptyCatch">;
448
451
  readonly "no-long-comment": DocumentedRule<readonly [], "tooLong">;
452
+ readonly "no-vague-suppression-description": DocumentedRule<readonly [], "vagueDescription">;
449
453
  readonly "no-generic-single-export-module": DocumentedRule<[], "genericSingleExport">;
450
454
  readonly "no-offset-pagination": DocumentedRule<readonly [], "noOffsetPagination">;
451
455
  readonly "no-positional-tuple-return": DocumentedRule<readonly [], "noPositionalTupleReturn">;
package/dist/index.d.ts CHANGED
@@ -208,6 +208,7 @@ declare const rules: {
208
208
  readonly "no-impossible-zod-literal-bounds": DocumentedRule<readonly [], "impossibleBounds">;
209
209
  readonly "no-log-only-catch": DocumentedRule<readonly [LoggingOptions?], "noLogOnlyCatch" | "emptyCatch">;
210
210
  readonly "no-long-comment": DocumentedRule<readonly [], "tooLong">;
211
+ readonly "no-vague-suppression-description": DocumentedRule<readonly [], "vagueDescription">;
211
212
  readonly "no-generic-single-export-module": DocumentedRule<[], "genericSingleExport">;
212
213
  readonly "no-offset-pagination": DocumentedRule<readonly [], "noOffsetPagination">;
213
214
  readonly "no-positional-tuple-return": DocumentedRule<readonly [], "noPositionalTupleReturn">;
@@ -282,7 +283,7 @@ declare const rules: {
282
283
  /** Rules registered for application-profile configs but intentionally absent from general presets. */
283
284
  declare const applicationOnlyRules: readonly ["no-restricted-library-load", "prefer-native-random-uuid", "prefer-shadcn-primitives"];
284
285
  /** Calibrated rules that intentionally remain warnings until consumer-corpus precision is proven. */
285
- declare const advisoryRules: readonly ["source-coupled-test"];
286
+ declare const advisoryRules: readonly ["no-vague-suppression-description", "source-coupled-test"];
286
287
  declare const recommendedRules: {
287
288
  readonly "@sarj/duplicate-test-body": "error";
288
289
  readonly "@sarj/enforce-file-structure": "error";
@@ -300,6 +301,7 @@ declare const recommendedRules: {
300
301
  readonly "@sarj/no-impossible-zod-literal-bounds": "error";
301
302
  readonly "@sarj/no-log-only-catch": "error";
302
303
  readonly "@sarj/no-long-comment": "error";
304
+ readonly "@sarj/no-vague-suppression-description": "warn";
303
305
  readonly "@sarj/no-generic-single-export-module": "error";
304
306
  readonly "@sarj/no-offset-pagination": "error";
305
307
  readonly "@sarj/no-positional-tuple-return": "error";
@@ -365,6 +367,7 @@ declare const strictRules: {
365
367
  readonly "@sarj/no-impossible-zod-literal-bounds": "error";
366
368
  readonly "@sarj/no-log-only-catch": "error";
367
369
  readonly "@sarj/no-long-comment": "error";
370
+ readonly "@sarj/no-vague-suppression-description": "warn";
368
371
  readonly "@sarj/no-generic-single-export-module": "error";
369
372
  readonly "@sarj/no-offset-pagination": "error";
370
373
  readonly "@sarj/no-positional-tuple-return": "error";
@@ -423,7 +426,7 @@ type FlatPreset = {
423
426
  declare const plugin: {
424
427
  readonly meta: {
425
428
  readonly name: "@sarj/eslint-plugin";
426
- readonly version: "15.6.8";
429
+ readonly version: "15.6.9";
427
430
  };
428
431
  readonly rules: {
429
432
  readonly "duplicate-test-body": DocumentedRule<readonly [], "duplicateTestBody">;
@@ -446,6 +449,7 @@ declare const plugin: {
446
449
  readonly "no-impossible-zod-literal-bounds": DocumentedRule<readonly [], "impossibleBounds">;
447
450
  readonly "no-log-only-catch": DocumentedRule<readonly [LoggingOptions?], "noLogOnlyCatch" | "emptyCatch">;
448
451
  readonly "no-long-comment": DocumentedRule<readonly [], "tooLong">;
452
+ readonly "no-vague-suppression-description": DocumentedRule<readonly [], "vagueDescription">;
449
453
  readonly "no-generic-single-export-module": DocumentedRule<[], "genericSingleExport">;
450
454
  readonly "no-offset-pagination": DocumentedRule<readonly [], "noOffsetPagination">;
451
455
  readonly "no-positional-tuple-return": DocumentedRule<readonly [], "noPositionalTupleReturn">;
package/dist/index.js CHANGED
@@ -4253,6 +4253,87 @@ var no_long_comment_default = createRule({
4253
4253
  }
4254
4254
  });
4255
4255
 
4256
+ // src/rules/no-vague-suppression-description.ts
4257
+ var DIRECTIVE_RE3 = /(?:eslint-(?:disable|disable-next-line|disable-line)|@ts-(?:expect-error|ignore))\b/iu;
4258
+ var DESCRIPTION_RE = /(?::|--)\s*(.+?)\s*$/u;
4259
+ var VAGUE_RE = /^(?:needed|required|intentional(?:ly)?|ignore(?:d)?|false positive|type error|typescript|to satisfy (?:the )?(?:linter|typescript|type checker))\.?$/iu;
4260
+ var noVagueSuppressionDescriptionDocumentation = {
4261
+ summary: "Require suppression descriptions to name the concrete mismatch or invariant instead of a generic non-reason.",
4262
+ rationale: "Generic phrases satisfy require-description mechanically while leaving reviewers unable to audit the risk or remove stale debt.",
4263
+ remediation: "Name the exact type/runtime mismatch, external contract, or safety invariant that makes this suppression acceptable.",
4264
+ category: "maintainability",
4265
+ limitations: [
4266
+ "Only ESLint disable comments and TypeScript expect-error/ignore directives are checked.",
4267
+ "The rule uses a small anchored vocabulary and does not score prose quality generally.",
4268
+ "Generated files and descriptions containing any concrete context are excluded."
4269
+ ],
4270
+ examples: [
4271
+ {
4272
+ id: "concrete-runtime-mismatch",
4273
+ title: "Explain the concrete runtime contract",
4274
+ outcome: "no-match",
4275
+ files: [
4276
+ {
4277
+ path: "src/adapter.ts",
4278
+ source: "// @ts-expect-error -- vendor types omit the runtime requestId field\nreturn response.requestId;"
4279
+ }
4280
+ ],
4281
+ focusPath: "src/adapter.ts",
4282
+ expectedCount: 0,
4283
+ public: true
4284
+ },
4285
+ {
4286
+ id: "generic-suppression-reason",
4287
+ title: "Reject a suppression with no auditable reason",
4288
+ outcome: "match",
4289
+ files: [
4290
+ {
4291
+ path: "src/adapter.ts",
4292
+ source: "// @ts-expect-error -- false positive\nreturn response.requestId;"
4293
+ }
4294
+ ],
4295
+ focusPath: "src/adapter.ts",
4296
+ expectedCount: 1,
4297
+ public: true
4298
+ }
4299
+ ]
4300
+ };
4301
+ var no_vague_suppression_description_default = createRule({
4302
+ name: "no-vague-suppression-description",
4303
+ documentation: noVagueSuppressionDescriptionDocumentation,
4304
+ meta: {
4305
+ type: "suggestion",
4306
+ docs: {
4307
+ description: "Require suppression descriptions to name the concrete mismatch or invariant instead of a generic non-reason."
4308
+ },
4309
+ schema: [],
4310
+ messages: {
4311
+ vagueDescription: "Suppression description `{{description}}` does not explain why the suppressed diagnostic is safe here. Name the concrete type/runtime mismatch, external contract, or invariant."
4312
+ }
4313
+ },
4314
+ defaultOptions: [],
4315
+ create(context) {
4316
+ if (isGeneratedFile(context.filename, context.sourceCode.text)) {
4317
+ return {};
4318
+ }
4319
+ return {
4320
+ Program() {
4321
+ for (const comment of context.sourceCode.getAllComments()) {
4322
+ const text = comment.value.trim();
4323
+ if (!DIRECTIVE_RE3.test(text)) continue;
4324
+ const description = DESCRIPTION_RE.exec(text)?.[1]?.trim();
4325
+ if (description === void 0 || !VAGUE_RE.test(description)) continue;
4326
+ context.report({
4327
+ loc: comment.loc,
4328
+ messageId: "vagueDescription",
4329
+ data: { description }
4330
+ });
4331
+ }
4332
+ }
4333
+ };
4334
+ }
4335
+ });
4336
+
4256
4337
  // src/rules/no-generic-single-export-module.ts
4257
4338
  import { AST_NODE_TYPES as AST_NODE_TYPES16, ASTUtils as ASTUtils4 } from "@typescript-eslint/utils";
4258
4339
  var noGenericSingleExportModuleDocumentation = {
@@ -5392,7 +5473,7 @@ var no_repeated_string_literal_default = createRule({
5392
5473
  import { AST_NODE_TYPES as AST_NODE_TYPES21 } from "@typescript-eslint/utils";
5393
5474
  var MAX_WORDS = 8;
5394
5475
  var MIN_CONTENT_TOKENS = 2;
5395
- var DIRECTIVE_RE3 = /^(eslint\b|eslint-|sarj-noqa\b|@ts-|prettier-ignore|prettier\b|biome-|c8\b|v8\b|istanbul\b|@type\b|@vite|webpack|<reference|<amd|global\b|noinspection|todo\b|fixme\b|hack\b|xxx\b)/i;
5476
+ var DIRECTIVE_RE4 = /^(eslint\b|eslint-|sarj-noqa\b|@ts-|prettier-ignore|prettier\b|biome-|c8\b|v8\b|istanbul\b|@type\b|@vite|webpack|<reference|<amd|global\b|noinspection|todo\b|fixme\b|hack\b|xxx\b)/i;
5396
5477
  var CODEY_RE = /^[\w.$[\]'"]+\s*[:=]\s*\S|^[\w.$]+\s*\(|^(?:return|throw|await|import|export|const|let|var)\b.*[=()[\]{}]/;
5397
5478
  var BANNERISH_RE = /[=\-─-╿*#~_.]{3,}|^[A-Z0-9 _:-]+$/;
5398
5479
  var MODALITY_RE = /\b(?:can|could|should|shall|may|might|must|will|would|cannot)\b/i;
@@ -5491,7 +5572,7 @@ var no_restated_comment_default = createRule({
5491
5572
  }
5492
5573
  const body2 = comment.value.replace(/^\/*/, "").trim();
5493
5574
  if (body2.length === 0 || body2.endsWith("?")) continue;
5494
- if (DIRECTIVE_RE3.test(body2) || CODEY_RE.test(body2) || BANNERISH_RE.test(body2)) continue;
5575
+ if (DIRECTIVE_RE4.test(body2) || CODEY_RE.test(body2) || BANNERISH_RE.test(body2)) continue;
5495
5576
  if (NON_ASCII_LETTER_RE.test(body2) || isProtected(body2)) continue;
5496
5577
  if (MODALITY_RE.test(body2) || LEAD_IN_RE.test(body2) || EMPHASIS_RE.test(body2)) continue;
5497
5578
  if (NEGATION_WORD_RE.test(body2)) continue;
@@ -5539,7 +5620,7 @@ var MODELLED_TAGS = /* @__PURE__ */ new Set([
5539
5620
  ]);
5540
5621
  var PARAM_TAGS = /* @__PURE__ */ new Set(["arg", "argument", "param"]);
5541
5622
  var RETURN_TAGS = /* @__PURE__ */ new Set(["return", "returns"]);
5542
- var DIRECTIVE_RE4 = /^\s*(?:eslint\b|eslint-|@ts-|prettier|biome-|c8\b|v8\b|istanbul\b|@vite|webpack|@jsx|@jest-environment|@vitest-environment|#__)/i;
5623
+ var DIRECTIVE_RE5 = /^\s*(?:eslint\b|eslint-|@ts-|prettier|biome-|c8\b|v8\b|istanbul\b|@vite|webpack|@jsx|@jest-environment|@vitest-environment|#__)/i;
5543
5624
  var STOPWORDS2 = new Set(
5544
5625
  `the a an of to for in on with and or as at by is are was be been being
5545
5626
  this that it its if whether when where which what will would can could should
@@ -5655,7 +5736,7 @@ var no_restated_jsdoc_default = createRule({
5655
5736
  description,
5656
5737
  ...tags.filter((tag) => tag.name === "description").map((tag) => tag.text)
5657
5738
  ].filter((text) => text.length > 0).join("\n");
5658
- if (DIRECTIVE_RE4.test(describedText)) continue;
5739
+ if (DIRECTIVE_RE5.test(describedText)) continue;
5659
5740
  const tagNames = new Set(tags.map((tag) => tag.name));
5660
5741
  if ([...tagNames].some((name) => !MODELLED_TAGS.has(name))) continue;
5661
5742
  if (isProtected(describedText)) continue;
@@ -7617,10 +7698,10 @@ var STOPWORDS3 = /* @__PURE__ */ new Set([
7617
7698
  "we",
7618
7699
  "with"
7619
7700
  ]);
7620
- var DIRECTIVE_RE5 = /^\s*(?:eslint\b|eslint-|sarj-noqa\b|@ts-|prettier|biome-|c8\b|v8\b|istanbul\b|todo\b|fixme\b|hack\b|xxx\b)/i;
7701
+ var DIRECTIVE_RE6 = /^\s*(?:eslint\b|eslint-|sarj-noqa\b|@ts-|prettier|biome-|c8\b|v8\b|istanbul\b|todo\b|fixme\b|hack\b|xxx\b)/i;
7621
7702
  var UNIT_NAME_SUFFIX_RE = /(?:_(?:NS|US|MS|S|SEC|SECS|SECOND|SECONDS|MIN|MINS|MINUTE|MINUTES|HOUR|HOURS|DAY|DAYS|BYTE|BYTES|KB|MB|GB|HZ|KHZ|MHZ|PX)|(?:Ns|Us|Ms|Sec|Secs|Second|Seconds|Min|Mins|Minute|Minutes|Hour|Hours|Day|Days|Byte|Bytes|Kb|Mb|Gb|Hz|Khz|Mhz|Px))$/u;
7622
7703
  function narratesValue(body2, code) {
7623
- if (body2.length === 0 || DIRECTIVE_RE5.test(body2) || hasExternalReference(body2)) return false;
7704
+ if (body2.length === 0 || DIRECTIVE_RE6.test(body2) || hasExternalReference(body2)) return false;
7624
7705
  const codeNumbers = numbersIn(code);
7625
7706
  if (codeNumbers.size === 0) return false;
7626
7707
  const words2 = (body2.match(WORD_RE3) ?? []).map((word) => word.toLowerCase());
@@ -15285,6 +15366,7 @@ var rules = {
15285
15366
  "no-impossible-zod-literal-bounds": no_impossible_zod_literal_bounds_default,
15286
15367
  "no-log-only-catch": no_log_only_catch_default,
15287
15368
  "no-long-comment": no_long_comment_default,
15369
+ "no-vague-suppression-description": no_vague_suppression_description_default,
15288
15370
  "no-generic-single-export-module": no_generic_single_export_module_default,
15289
15371
  "no-offset-pagination": no_offset_pagination_default,
15290
15372
  "no-positional-tuple-return": no_positional_tuple_return_default,
@@ -15338,14 +15420,14 @@ var rules = {
15338
15420
  };
15339
15421
  var meta = {
15340
15422
  name: "@sarj/eslint-plugin",
15341
- version: "15.6.8"
15423
+ version: "15.6.9"
15342
15424
  };
15343
15425
  var applicationOnlyRules = [
15344
15426
  "no-restricted-library-load",
15345
15427
  "prefer-native-random-uuid",
15346
15428
  "prefer-shadcn-primitives"
15347
15429
  ];
15348
- var advisoryRules = ["source-coupled-test"];
15430
+ var advisoryRules = ["no-vague-suppression-description", "source-coupled-test"];
15349
15431
  var recommendedRules = {
15350
15432
  "@sarj/duplicate-test-body": "error",
15351
15433
  "@sarj/enforce-file-structure": "error",
@@ -15361,6 +15443,7 @@ var recommendedRules = {
15361
15443
  "@sarj/no-impossible-zod-literal-bounds": "error",
15362
15444
  "@sarj/no-log-only-catch": "error",
15363
15445
  "@sarj/no-long-comment": "error",
15446
+ "@sarj/no-vague-suppression-description": "warn",
15364
15447
  "@sarj/no-generic-single-export-module": "error",
15365
15448
  "@sarj/no-offset-pagination": "error",
15366
15449
  "@sarj/no-positional-tuple-return": "error",
@@ -15422,6 +15505,7 @@ var strictRules = {
15422
15505
  "@sarj/no-impossible-zod-literal-bounds": "error",
15423
15506
  "@sarj/no-log-only-catch": "error",
15424
15507
  "@sarj/no-long-comment": "error",
15508
+ "@sarj/no-vague-suppression-description": "warn",
15425
15509
  "@sarj/no-generic-single-export-module": "error",
15426
15510
  "@sarj/no-offset-pagination": "error",
15427
15511
  "@sarj/no-positional-tuple-return": "error",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sarj/eslint-plugin",
3
- "version": "15.6.8",
3
+ "version": "15.6.9",
4
4
  "packageManager": "npm@12.0.2",
5
5
  "description": "Custom ESLint rules for hypermodern TypeScript / React / Next.js projects",
6
6
  "type": "module",