@sarj/eslint-plugin 15.10.0 → 15.10.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 CHANGED
@@ -1456,7 +1456,7 @@ var no_comment_cruft_default = createRule({
1456
1456
  sectionBanner: "Section-banner / region comment \u2014 remove the decoration or replace it with a named code boundary.",
1457
1457
  fileHeaderPreamble: "File-header comment preamble \u2014 use a brief doc comment for the why, not a block of `//` lines.",
1458
1458
  commentWall: "Statement comment wall ({{count}} narrated steps) \u2014 delete the walkthrough and name the operations in code; keep only constraints or rationale.",
1459
- redundantNarration: "Comment narrates the code \u2014 delete it or say *why*, not *what*. Code is self-documenting.",
1459
+ redundantNarration: "Comment narrates the code \u2014 delete it; if the code still needs explanation, use clearer names or extract a named helper. Keep only constraints or rationale.",
1460
1460
  placeholderImplementation: "Placeholder implementation comment \u2014 implement the behavior or use an explicit unsupported path.",
1461
1461
  untrackedTodo: "Untracked TODO/FIXME marker \u2014 add an issue ticket or context link."
1462
1462
  }
@@ -4212,6 +4212,7 @@ var DIRECTIVE_RE2 = /^(?:!|eslint\b|eslint-|@ts-|prettier|biome-|c8\b|v8\b|istan
4212
4212
  var LICENSE_RE2 = /\b(?:copyright|spdx-license-identifier|licensed under)\b/i;
4213
4213
  var TYPED_TAG_RE = /@(arg|argument|param|return|returns|yield|yields)\b/i;
4214
4214
  var VALUE_TAG_RE = /@(example|deprecated|see|remarks|throws|internal|public|alpha|beta|since|template|fileoverview)\b/i;
4215
+ var ANY_TAG_RE = /(?:^|\s)@[A-Za-z][\w-]*\b/u;
4215
4216
  var BOUNDARY_RE = /(?<=[.!?])["'`)\]]*\s+(?=[A-Z0-9`])/;
4216
4217
  var BULLET_RE = /^\s*(?:[-*+] |\d+[.)] )/;
4217
4218
  var HEADING_RE = /^[A-Za-z][A-Za-z ]+:$/;
@@ -4219,8 +4220,8 @@ var TECHNICAL_ANCHOR_RE = /https?:\/\/|`[^`\n]+`|:[a-z][a-z0-9_-]*:|(["'])[^"'\n
4219
4220
  function body(comment) {
4220
4221
  return comment.value.replace(/^\*/, "").split("\n").map((line) => line.replace(/^\s*\*?\s?/, "")).join("\n").trim();
4221
4222
  }
4222
- function eligible(text, includeValueTags) {
4223
- return text.length > 0 && !DIRECTIVE_RE2.test(text) && !LICENSE_RE2.test(text) && (includeValueTags || !VALUE_TAG_RE.test(text));
4223
+ function eligible(text, includeValueTags, jsDoc = false) {
4224
+ return text.length > 0 && !DIRECTIVE_RE2.test(text) && !LICENSE_RE2.test(text) && (includeValueTags || !VALUE_TAG_RE.test(text) && (!jsDoc || !ANY_TAG_RE.test(text)));
4224
4225
  }
4225
4226
  function sentenceUnits(text) {
4226
4227
  const cleaned = text.replace(/https?:\/\/\S+/g, "URL").replace(/`[^`\n]+`/g, "CODE").replace(/\b\d+\.\d+\b/g, "NUMBER").replace(/\b(?:e\.g\.|i\.e\.|vs\.|etc\.)/gi, "ABBREVIATION");
@@ -4260,7 +4261,9 @@ function proseGroups(filename, sourceCode, includeValueTags = false) {
4260
4261
  const text = body(comment);
4261
4262
  if (comment.type === "Block") {
4262
4263
  flush();
4263
- if (eligible(text, includeValueTags)) groups.push({ comment, text, hasTypedTags: TYPED_TAG_RE.test(text) });
4264
+ if (eligible(text, includeValueTags, comment.value.startsWith("*"))) {
4265
+ groups.push({ comment, text, hasTypedTags: TYPED_TAG_RE.test(text) });
4266
+ }
4264
4267
  continue;
4265
4268
  }
4266
4269
  const ownLine = sourceCode.lines[comment.loc.start.line - 1]?.slice(0, comment.loc.start.column).trim() === "";
@@ -5956,7 +5959,7 @@ var no_restated_jsdoc_default = createRule({
5956
5959
  },
5957
5960
  schema: [],
5958
5961
  messages: {
5959
- restatesSignature: "JSDoc only re-spells the signature \u2014 delete it, or say what the caller cannot read off the name (what it throws, what it assumes, why it exists).",
5962
+ restatesSignature: "JSDoc only re-spells the signature \u2014 delete it; if the signature still needs explanation, improve its names or types. Keep constraints, failures, and rationale.",
5960
5963
  deleteBlock: "Delete the JSDoc block."
5961
5964
  }
5962
5965
  },
@@ -7829,7 +7832,7 @@ var no_typed_doc_sections_default = createRule({
7829
7832
  docs: { description: "Reject typed-signature repetition while preserving behavior that types cannot express." },
7830
7833
  schema: [],
7831
7834
  messages: {
7832
- typedSection: "Typed JSDoc repeats parameters or returns \u2014 delete the tags and improve names or types instead."
7835
+ typedSection: "Typed JSDoc repeats parameters or returns \u2014 delete the repeated tags; if the signature still needs explanation, improve its names or types. Keep constraints and rationale."
7833
7836
  }
7834
7837
  },
7835
7838
  defaultOptions: [],
@@ -8098,6 +8101,9 @@ function labelStems(body2) {
8098
8101
  function commentBody(comment) {
8099
8102
  return comment.value.replace(/^\*+/, "").replace(/^[ \t]*\*[ \t]?/gm, "").trim();
8100
8103
  }
8104
+ function hasJsDocTag(comment) {
8105
+ return comment.type === import_utils41.AST_TOKEN_TYPES.Block && comment.value.startsWith("*") && /(?:^|\s)@[A-Za-z][\w-]*\b/u.test(commentBody(comment));
8106
+ }
8101
8107
  function carriesValue(body2) {
8102
8108
  return isProtected(body2) || VALUE_TAG_RE2.test(body2) || DEFAULT_RE.test(body2) || DIGIT_RE.test(body2) || UNIT_WORD_RE.test(body2) || EXAMPLE_RE.test(body2) || BANNER_RE.test(body2) || NON_ASCII_LETTER_RE2.test(body2);
8103
8109
  }
@@ -8208,7 +8214,7 @@ var no_declaration_comment_wall_default = createRule({
8208
8214
  },
8209
8215
  schema: [WALL_SCHEMA],
8210
8216
  messages: {
8211
- commentWall: "{{restated}} of this declaration's {{commented}} member comments only re-spell the member's own name \u2014 delete them, and keep the rows that say what the name cannot."
8217
+ commentWall: "{{restated}} of this declaration's {{commented}} member comments only re-spell member names \u2014 delete them; if a row still needs narration, give the member a clearer name. Keep constraints, lifecycle, and rationale."
8212
8218
  }
8213
8219
  },
8214
8220
  defaultOptions: [WALL_DEFAULTS],
@@ -8268,7 +8274,7 @@ var no_declaration_comment_wall_default = createRule({
8268
8274
  claimed.add(comment);
8269
8275
  commented += 1;
8270
8276
  const body2 = commentBody(comment);
8271
- if (body2.length === 0 || carriesValue(body2) || isTagsOnly(body2) || isLabel(body2)) {
8277
+ if (body2.length === 0 || hasJsDocTag(comment) || carriesValue(body2) || isTagsOnly(body2) || isLabel(body2)) {
8272
8278
  continue;
8273
8279
  }
8274
8280
  const { end, start } = declarationRange(member.node);
@@ -8516,7 +8522,7 @@ var no_type_member_comment_wall_default = createRule({
8516
8522
  },
8517
8523
  schema: [WALL_SCHEMA],
8518
8524
  messages: {
8519
- commentWall: "{{restated}} of this type's {{commented}} member comments only re-spell the member's own name and type \u2014 delete them, and keep the rows that say what the name cannot."
8525
+ commentWall: "{{restated}} of this type's {{commented}} member comments only re-spell names and types \u2014 delete them; if a row still needs narration, improve its name or type. Keep constraints and rationale."
8520
8526
  }
8521
8527
  },
8522
8528
  defaultOptions: [WALL_DEFAULTS],
@@ -8574,7 +8580,9 @@ var no_type_member_comment_wall_default = createRule({
8574
8580
  claimed.add(comment);
8575
8581
  commented += 1;
8576
8582
  const body2 = commentBody(comment);
8577
- if (body2.length === 0 || carriesValue(body2) || isTagsOnly(body2)) continue;
8583
+ if (body2.length === 0 || hasJsDocTag(comment) || carriesValue(body2) || isTagsOnly(body2)) {
8584
+ continue;
8585
+ }
8578
8586
  if (novelWords(body2, knownTokens(sourceCode.getText(member))) <= options.maxNovelWords) {
8579
8587
  restated += 1;
8580
8588
  }
@@ -16048,7 +16056,7 @@ var rules = {
16048
16056
  };
16049
16057
  var meta = {
16050
16058
  name: "@sarj/eslint-plugin",
16051
- version: "15.10.0"
16059
+ version: "15.10.3"
16052
16060
  };
16053
16061
  var applicationOnlyRules = [
16054
16062
  "no-restricted-library-load",
package/dist/index.d.cts CHANGED
@@ -438,7 +438,7 @@ type FlatPreset = {
438
438
  declare const plugin: {
439
439
  readonly meta: {
440
440
  readonly name: "@sarj/eslint-plugin";
441
- readonly version: "15.10.0";
441
+ readonly version: "15.10.3";
442
442
  };
443
443
  readonly rules: {
444
444
  readonly "iac-source-coupled-test": DocumentedRule<readonly [], "rawSourceOracle">;
package/dist/index.d.ts CHANGED
@@ -438,7 +438,7 @@ type FlatPreset = {
438
438
  declare const plugin: {
439
439
  readonly meta: {
440
440
  readonly name: "@sarj/eslint-plugin";
441
- readonly version: "15.10.0";
441
+ readonly version: "15.10.3";
442
442
  };
443
443
  readonly rules: {
444
444
  readonly "iac-source-coupled-test": DocumentedRule<readonly [], "rawSourceOracle">;
package/dist/index.js CHANGED
@@ -1412,7 +1412,7 @@ var no_comment_cruft_default = createRule({
1412
1412
  sectionBanner: "Section-banner / region comment \u2014 remove the decoration or replace it with a named code boundary.",
1413
1413
  fileHeaderPreamble: "File-header comment preamble \u2014 use a brief doc comment for the why, not a block of `//` lines.",
1414
1414
  commentWall: "Statement comment wall ({{count}} narrated steps) \u2014 delete the walkthrough and name the operations in code; keep only constraints or rationale.",
1415
- redundantNarration: "Comment narrates the code \u2014 delete it or say *why*, not *what*. Code is self-documenting.",
1415
+ redundantNarration: "Comment narrates the code \u2014 delete it; if the code still needs explanation, use clearer names or extract a named helper. Keep only constraints or rationale.",
1416
1416
  placeholderImplementation: "Placeholder implementation comment \u2014 implement the behavior or use an explicit unsupported path.",
1417
1417
  untrackedTodo: "Untracked TODO/FIXME marker \u2014 add an issue ticket or context link."
1418
1418
  }
@@ -4173,6 +4173,7 @@ var DIRECTIVE_RE2 = /^(?:!|eslint\b|eslint-|@ts-|prettier|biome-|c8\b|v8\b|istan
4173
4173
  var LICENSE_RE2 = /\b(?:copyright|spdx-license-identifier|licensed under)\b/i;
4174
4174
  var TYPED_TAG_RE = /@(arg|argument|param|return|returns|yield|yields)\b/i;
4175
4175
  var VALUE_TAG_RE = /@(example|deprecated|see|remarks|throws|internal|public|alpha|beta|since|template|fileoverview)\b/i;
4176
+ var ANY_TAG_RE = /(?:^|\s)@[A-Za-z][\w-]*\b/u;
4176
4177
  var BOUNDARY_RE = /(?<=[.!?])["'`)\]]*\s+(?=[A-Z0-9`])/;
4177
4178
  var BULLET_RE = /^\s*(?:[-*+] |\d+[.)] )/;
4178
4179
  var HEADING_RE = /^[A-Za-z][A-Za-z ]+:$/;
@@ -4180,8 +4181,8 @@ var TECHNICAL_ANCHOR_RE = /https?:\/\/|`[^`\n]+`|:[a-z][a-z0-9_-]*:|(["'])[^"'\n
4180
4181
  function body(comment) {
4181
4182
  return comment.value.replace(/^\*/, "").split("\n").map((line) => line.replace(/^\s*\*?\s?/, "")).join("\n").trim();
4182
4183
  }
4183
- function eligible(text, includeValueTags) {
4184
- return text.length > 0 && !DIRECTIVE_RE2.test(text) && !LICENSE_RE2.test(text) && (includeValueTags || !VALUE_TAG_RE.test(text));
4184
+ function eligible(text, includeValueTags, jsDoc = false) {
4185
+ return text.length > 0 && !DIRECTIVE_RE2.test(text) && !LICENSE_RE2.test(text) && (includeValueTags || !VALUE_TAG_RE.test(text) && (!jsDoc || !ANY_TAG_RE.test(text)));
4185
4186
  }
4186
4187
  function sentenceUnits(text) {
4187
4188
  const cleaned = text.replace(/https?:\/\/\S+/g, "URL").replace(/`[^`\n]+`/g, "CODE").replace(/\b\d+\.\d+\b/g, "NUMBER").replace(/\b(?:e\.g\.|i\.e\.|vs\.|etc\.)/gi, "ABBREVIATION");
@@ -4221,7 +4222,9 @@ function proseGroups(filename, sourceCode, includeValueTags = false) {
4221
4222
  const text = body(comment);
4222
4223
  if (comment.type === "Block") {
4223
4224
  flush();
4224
- if (eligible(text, includeValueTags)) groups.push({ comment, text, hasTypedTags: TYPED_TAG_RE.test(text) });
4225
+ if (eligible(text, includeValueTags, comment.value.startsWith("*"))) {
4226
+ groups.push({ comment, text, hasTypedTags: TYPED_TAG_RE.test(text) });
4227
+ }
4225
4228
  continue;
4226
4229
  }
4227
4230
  const ownLine = sourceCode.lines[comment.loc.start.line - 1]?.slice(0, comment.loc.start.column).trim() === "";
@@ -5917,7 +5920,7 @@ var no_restated_jsdoc_default = createRule({
5917
5920
  },
5918
5921
  schema: [],
5919
5922
  messages: {
5920
- restatesSignature: "JSDoc only re-spells the signature \u2014 delete it, or say what the caller cannot read off the name (what it throws, what it assumes, why it exists).",
5923
+ restatesSignature: "JSDoc only re-spells the signature \u2014 delete it; if the signature still needs explanation, improve its names or types. Keep constraints, failures, and rationale.",
5921
5924
  deleteBlock: "Delete the JSDoc block."
5922
5925
  }
5923
5926
  },
@@ -7790,7 +7793,7 @@ var no_typed_doc_sections_default = createRule({
7790
7793
  docs: { description: "Reject typed-signature repetition while preserving behavior that types cannot express." },
7791
7794
  schema: [],
7792
7795
  messages: {
7793
- typedSection: "Typed JSDoc repeats parameters or returns \u2014 delete the tags and improve names or types instead."
7796
+ typedSection: "Typed JSDoc repeats parameters or returns \u2014 delete the repeated tags; if the signature still needs explanation, improve its names or types. Keep constraints and rationale."
7794
7797
  }
7795
7798
  },
7796
7799
  defaultOptions: [],
@@ -7991,10 +7994,10 @@ var no_trailing_value_narration_default = createRule({
7991
7994
  });
7992
7995
 
7993
7996
  // src/rules/no-declaration-comment-wall.ts
7994
- import { AST_NODE_TYPES as AST_NODE_TYPES30, AST_TOKEN_TYPES } from "@typescript-eslint/utils";
7997
+ import { AST_NODE_TYPES as AST_NODE_TYPES30, AST_TOKEN_TYPES as AST_TOKEN_TYPES2 } from "@typescript-eslint/utils";
7995
7998
 
7996
7999
  // src/rules/_comment-wall.ts
7997
- import { AST_NODE_TYPES as AST_NODE_TYPES29 } from "@typescript-eslint/utils";
8000
+ import { AST_NODE_TYPES as AST_NODE_TYPES29, AST_TOKEN_TYPES } from "@typescript-eslint/utils";
7998
8001
  var WALL_DEFAULTS = {
7999
8002
  // Below three rows "a wall" is not a fair description of what the reader sees.
8000
8003
  minCommentedMembers: 3,
@@ -8059,6 +8062,9 @@ function labelStems(body2) {
8059
8062
  function commentBody(comment) {
8060
8063
  return comment.value.replace(/^\*+/, "").replace(/^[ \t]*\*[ \t]?/gm, "").trim();
8061
8064
  }
8065
+ function hasJsDocTag(comment) {
8066
+ return comment.type === AST_TOKEN_TYPES.Block && comment.value.startsWith("*") && /(?:^|\s)@[A-Za-z][\w-]*\b/u.test(commentBody(comment));
8067
+ }
8062
8068
  function carriesValue(body2) {
8063
8069
  return isProtected(body2) || VALUE_TAG_RE2.test(body2) || DEFAULT_RE.test(body2) || DIGIT_RE.test(body2) || UNIT_WORD_RE.test(body2) || EXAMPLE_RE.test(body2) || BANNER_RE.test(body2) || NON_ASCII_LETTER_RE2.test(body2);
8064
8070
  }
@@ -8169,7 +8175,7 @@ var no_declaration_comment_wall_default = createRule({
8169
8175
  },
8170
8176
  schema: [WALL_SCHEMA],
8171
8177
  messages: {
8172
- commentWall: "{{restated}} of this declaration's {{commented}} member comments only re-spell the member's own name \u2014 delete them, and keep the rows that say what the name cannot."
8178
+ commentWall: "{{restated}} of this declaration's {{commented}} member comments only re-spell member names \u2014 delete them; if a row still needs narration, give the member a clearer name. Keep constraints, lifecycle, and rationale."
8173
8179
  }
8174
8180
  },
8175
8181
  defaultOptions: [WALL_DEFAULTS],
@@ -8193,7 +8199,7 @@ var no_declaration_comment_wall_default = createRule({
8193
8199
  const before = sourceCode.getTokenBefore(lead, { includeComments: false });
8194
8200
  if (before === null || before.loc.end.line < lead.loc.start.line) {
8195
8201
  const previousLine = endingOn.get(lead.loc.start.line - 1);
8196
- if (lead.type === AST_TOKEN_TYPES.Line && previousLine?.type === AST_TOKEN_TYPES.Line && previousLine.loc.start.column === lead.loc.start.column) {
8202
+ if (lead.type === AST_TOKEN_TYPES2.Line && previousLine?.type === AST_TOKEN_TYPES2.Line && previousLine.loc.start.column === lead.loc.start.column) {
8197
8203
  return void 0;
8198
8204
  }
8199
8205
  return lead;
@@ -8229,7 +8235,7 @@ var no_declaration_comment_wall_default = createRule({
8229
8235
  claimed.add(comment);
8230
8236
  commented += 1;
8231
8237
  const body2 = commentBody(comment);
8232
- if (body2.length === 0 || carriesValue(body2) || isTagsOnly(body2) || isLabel(body2)) {
8238
+ if (body2.length === 0 || hasJsDocTag(comment) || carriesValue(body2) || isTagsOnly(body2) || isLabel(body2)) {
8233
8239
  continue;
8234
8240
  }
8235
8241
  const { end, start } = declarationRange(member.node);
@@ -8436,7 +8442,7 @@ var no_union_in_comment_default = createRule({
8436
8442
  });
8437
8443
 
8438
8444
  // src/rules/no-type-member-comment-wall.ts
8439
- import { AST_NODE_TYPES as AST_NODE_TYPES32, AST_TOKEN_TYPES as AST_TOKEN_TYPES2 } from "@typescript-eslint/utils";
8445
+ import { AST_NODE_TYPES as AST_NODE_TYPES32, AST_TOKEN_TYPES as AST_TOKEN_TYPES3 } from "@typescript-eslint/utils";
8440
8446
  var noTypeMemberCommentWallDocumentation = {
8441
8447
  summary: "Flag an object type whose member comments mostly re-spell the members' own names and types.",
8442
8448
  rationale: "Repetitive member comments add scanning cost while hiding the comments that describe facts absent from the type.",
@@ -8477,7 +8483,7 @@ var no_type_member_comment_wall_default = createRule({
8477
8483
  },
8478
8484
  schema: [WALL_SCHEMA],
8479
8485
  messages: {
8480
- commentWall: "{{restated}} of this type's {{commented}} member comments only re-spell the member's own name and type \u2014 delete them, and keep the rows that say what the name cannot."
8486
+ commentWall: "{{restated}} of this type's {{commented}} member comments only re-spell names and types \u2014 delete them; if a row still needs narration, improve its name or type. Keep constraints and rationale."
8481
8487
  }
8482
8488
  },
8483
8489
  defaultOptions: [WALL_DEFAULTS],
@@ -8501,7 +8507,7 @@ var no_type_member_comment_wall_default = createRule({
8501
8507
  const before = sourceCode.getTokenBefore(lead, { includeComments: false });
8502
8508
  if (before === null || before.loc.end.line < lead.loc.start.line) {
8503
8509
  const previousLine = endingOn.get(lead.loc.start.line - 1);
8504
- if (lead.type === AST_TOKEN_TYPES2.Line && previousLine?.type === AST_TOKEN_TYPES2.Line && previousLine.loc.start.column === lead.loc.start.column) {
8510
+ if (lead.type === AST_TOKEN_TYPES3.Line && previousLine?.type === AST_TOKEN_TYPES3.Line && previousLine.loc.start.column === lead.loc.start.column) {
8505
8511
  return void 0;
8506
8512
  }
8507
8513
  return lead;
@@ -8535,7 +8541,9 @@ var no_type_member_comment_wall_default = createRule({
8535
8541
  claimed.add(comment);
8536
8542
  commented += 1;
8537
8543
  const body2 = commentBody(comment);
8538
- if (body2.length === 0 || carriesValue(body2) || isTagsOnly(body2)) continue;
8544
+ if (body2.length === 0 || hasJsDocTag(comment) || carriesValue(body2) || isTagsOnly(body2)) {
8545
+ continue;
8546
+ }
8539
8547
  if (novelWords(body2, knownTokens(sourceCode.getText(member))) <= options.maxNovelWords) {
8540
8548
  restated += 1;
8541
8549
  }
@@ -16029,7 +16037,7 @@ var rules = {
16029
16037
  };
16030
16038
  var meta = {
16031
16039
  name: "@sarj/eslint-plugin",
16032
- version: "15.10.0"
16040
+ version: "15.10.3"
16033
16041
  };
16034
16042
  var applicationOnlyRules = [
16035
16043
  "no-restricted-library-load",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sarj/eslint-plugin",
3
- "version": "15.10.0",
3
+ "version": "15.10.3",
4
4
  "packageManager": "npm@12.0.2",
5
5
  "description": "Custom ESLint rules for hypermodern TypeScript / React / Next.js projects",
6
6
  "type": "module",
@@ -59,10 +59,10 @@
59
59
  "@eslint-community/eslint-plugin-eslint-comments": "^4.7.2",
60
60
  "@eslint/compat": "^2.1.0",
61
61
  "@eslint/js": "10.0.1",
62
- "@types/node": "latest",
63
- "@typescript-eslint/parser": "latest",
64
- "@typescript-eslint/rule-tester": "latest",
65
- "@typescript-eslint/utils": "latest",
62
+ "@types/node": "26.2.0",
63
+ "@typescript-eslint/parser": "8.67.0",
64
+ "@typescript-eslint/rule-tester": "8.67.0",
65
+ "@typescript-eslint/utils": "8.67.0",
66
66
  "eslint": "^10.8.1",
67
67
  "eslint-plugin-better-tailwindcss": "^4.7.0",
68
68
  "eslint-plugin-perfectionist": "^5.10.1",
@@ -73,9 +73,9 @@
73
73
  "eslint-plugin-unicorn": "^73.0.0",
74
74
  "eslint-plugin-zod": "^4.9.1",
75
75
  "tsup": "latest",
76
- "typescript": "latest",
76
+ "typescript": "6.0.3",
77
77
  "typescript-eslint": "^8.67.0",
78
- "vitest": "latest"
78
+ "vitest": "4.1.11"
79
79
  },
80
80
  "peerDependencies": {
81
81
  "eslint": ">=9.39.4",
@@ -85,7 +85,7 @@
85
85
  "node": ">=22.13.0"
86
86
  },
87
87
  "allowScripts": {
88
- "esbuild@0.28.1": true,
88
+ "esbuild@0.28.2": true,
89
89
  "fsevents@2.3.3": true
90
90
  },
91
91
  "peerDependenciesMeta": {
@@ -95,8 +95,8 @@
95
95
  },
96
96
  "overrides": {
97
97
  "brace-expansion@^5.0.0": "5.0.9",
98
- "esbuild": "^0.28.1",
99
- "nanoid@<3.3.17": "3.3.17",
98
+ "esbuild": "0.28.2",
99
+ "nanoid@<3.3.18": "3.3.18",
100
100
  "eslint-plugin-react": {
101
101
  "eslint": "$eslint"
102
102
  }