@kazupon/eslint-plugin 0.2.2 → 0.4.0
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/README.md +5 -3
- package/lib/index.d.ts +7 -5
- package/lib/index.js +309 -10
- package/package.json +26 -24
package/README.md
CHANGED
|
@@ -61,9 +61,11 @@ The rules with the following star ⭐ are included in the configs.
|
|
|
61
61
|
|
|
62
62
|
### @kazupon/eslint-plugin Rules
|
|
63
63
|
|
|
64
|
-
| Rule ID
|
|
65
|
-
|
|
|
66
|
-
| [@kazupon/enforce-header-comment](https://eslint-plugin.kazupon.dev/rules/enforce-header-comment.html)
|
|
64
|
+
| Rule ID | Description | Category | Fixable | RECOMMENDED |
|
|
65
|
+
| :--------------------------------------------------------------------------------------------------------------- | :---------------------------------------------- | :------- | :-----: | :---------: |
|
|
66
|
+
| [@kazupon/enforce-header-comment](https://eslint-plugin.kazupon.dev/rules/enforce-header-comment.html) | Enforce heading the comment in source code file | Comment | | ⭐ |
|
|
67
|
+
| [@kazupon/no-tag-comments](https://eslint-plugin.kazupon.dev/rules/no-tag-comments.html) | disallow tag comments | Comment | | ⭐ |
|
|
68
|
+
| [@kazupon/prefer-scope-on-tag-comment](https://eslint-plugin.kazupon.dev/rules/prefer-scope-on-tag-comment.html) | enforce adding a scope to tag comments | Comment | | ⭐ |
|
|
67
69
|
|
|
68
70
|
<!--RULES_TABLE_END-->
|
|
69
71
|
|
package/lib/index.d.ts
CHANGED
|
@@ -2,17 +2,19 @@ import { ESLint, Linter } from "eslint";
|
|
|
2
2
|
|
|
3
3
|
//#region src/index.d.ts
|
|
4
4
|
type PluginConfigs = {
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
recommended: Linter.Config<Linter.RulesRecord>[];
|
|
6
|
+
comment: Linter.Config<Linter.RulesRecord>[];
|
|
7
7
|
};
|
|
8
8
|
declare const plugin: Omit<ESLint.Plugin, "configs"> & {
|
|
9
|
-
|
|
9
|
+
configs: PluginConfigs;
|
|
10
10
|
};
|
|
11
|
+
declare const recommendedConfig: Linter.Config[];
|
|
11
12
|
declare const commentConfig: Linter.Config[];
|
|
12
13
|
declare const configs: {
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
recommended: typeof recommendedConfig;
|
|
15
|
+
comment: typeof commentConfig;
|
|
15
16
|
};
|
|
17
|
+
/** @alias */
|
|
16
18
|
|
|
17
19
|
//#endregion
|
|
18
20
|
export { configs, plugin as default, plugin };
|
package/lib/index.js
CHANGED
|
@@ -1,15 +1,28 @@
|
|
|
1
1
|
import { parseComment } from "@es-joy/jsdoccomment";
|
|
2
2
|
|
|
3
3
|
//#region src/utils/constants.ts
|
|
4
|
+
/**
|
|
5
|
+
* @author kazuya kawaguchi (a.k.a. kazupon)
|
|
6
|
+
* @license MIT
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* The plugin name.
|
|
10
|
+
*/
|
|
4
11
|
const name = "@kazupon/eslint-plugin";
|
|
5
|
-
|
|
12
|
+
/**
|
|
13
|
+
* The plugin version.
|
|
14
|
+
*/
|
|
15
|
+
const version = "0.4.0";
|
|
16
|
+
/**
|
|
17
|
+
* The namespace for rules
|
|
18
|
+
*/
|
|
6
19
|
const namespace = "@kazupon";
|
|
7
20
|
|
|
8
21
|
//#endregion
|
|
9
22
|
//#region src/utils/rule.ts
|
|
10
23
|
const BLOB_URL = "https://eslint-plugin.kazupon.dev/rules";
|
|
11
24
|
function RuleCreator(urlCreator, namespace$1 = "") {
|
|
12
|
-
return function createNamedRule({ meta, name: name$1,...rule$
|
|
25
|
+
return function createNamedRule({ meta, name: name$1,...rule$3 }) {
|
|
13
26
|
const ruleId = namespace$1 ? `${namespace$1}/${name$1}` : name$1;
|
|
14
27
|
return {
|
|
15
28
|
meta: {
|
|
@@ -21,7 +34,7 @@ function RuleCreator(urlCreator, namespace$1 = "") {
|
|
|
21
34
|
ruleId
|
|
22
35
|
}
|
|
23
36
|
},
|
|
24
|
-
...rule$
|
|
37
|
+
...rule$3
|
|
25
38
|
};
|
|
26
39
|
};
|
|
27
40
|
}
|
|
@@ -40,7 +53,7 @@ function initializeTagDiagnosis(tags) {
|
|
|
40
53
|
function validTagDiagnosis(tagDiagnosis) {
|
|
41
54
|
return Object.keys(tagDiagnosis).every((tag) => tagDiagnosis[tag] === "ok");
|
|
42
55
|
}
|
|
43
|
-
const rule = createRule({
|
|
56
|
+
const rule$2 = createRule({
|
|
44
57
|
name: "enforce-header-comment",
|
|
45
58
|
meta: {
|
|
46
59
|
type: "suggestion",
|
|
@@ -168,11 +181,279 @@ const rule = createRule({
|
|
|
168
181
|
};
|
|
169
182
|
}
|
|
170
183
|
});
|
|
171
|
-
var enforce_header_comment_default = rule;
|
|
184
|
+
var enforce_header_comment_default = rule$2;
|
|
185
|
+
|
|
186
|
+
//#endregion
|
|
187
|
+
//#region src/utils/comment.ts
|
|
188
|
+
/**
|
|
189
|
+
* Remove JSDoc asterisk prefix if present
|
|
190
|
+
*/
|
|
191
|
+
function stripJSDocPrefix(line) {
|
|
192
|
+
const trimmed = line.trim();
|
|
193
|
+
return trimmed.startsWith("*") ? trimmed.slice(1).trim() : trimmed;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Check if the text starts with any of the given tags
|
|
197
|
+
* @param text The text to check
|
|
198
|
+
* @param tags Array of tags to search for
|
|
199
|
+
* @returns Tag detection result or null if no tag found
|
|
200
|
+
*/
|
|
201
|
+
function detectTag(text, tags) {
|
|
202
|
+
for (const tag of tags) {
|
|
203
|
+
const tagRegex = new RegExp(`^${tag}\\b`);
|
|
204
|
+
const match = text.match(tagRegex);
|
|
205
|
+
if (match) {
|
|
206
|
+
const afterTag = text.slice(tag.length);
|
|
207
|
+
if (afterTag.startsWith("(")) {
|
|
208
|
+
const closingParenIndex = afterTag.indexOf(")");
|
|
209
|
+
if (closingParenIndex > 0) {
|
|
210
|
+
const scope = afterTag.slice(1, closingParenIndex).trim();
|
|
211
|
+
return {
|
|
212
|
+
tag,
|
|
213
|
+
hasScope: scope.length > 0
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
return {
|
|
217
|
+
tag,
|
|
218
|
+
hasScope: false
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
if (afterTag === "" || afterTag.startsWith(":") || afterTag.startsWith(" ")) return {
|
|
222
|
+
tag,
|
|
223
|
+
hasScope: false
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
return null;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Calculate the exact location of a tag in a comment
|
|
231
|
+
* @param comment The comment containing the tag
|
|
232
|
+
* @param line The line of text containing the tag
|
|
233
|
+
* @param lineIndex The index of the line within the comment
|
|
234
|
+
* @param tag The tag to locate
|
|
235
|
+
* @returns Location with line and column, or null if not found
|
|
236
|
+
*/
|
|
237
|
+
function calculateTagLocation(comment, line, lineIndex, tag) {
|
|
238
|
+
const tagIndex = line.indexOf(tag);
|
|
239
|
+
if (tagIndex === -1) return null;
|
|
240
|
+
if (lineIndex === 0) {
|
|
241
|
+
const tagIndexInValue = comment.value.indexOf(tag);
|
|
242
|
+
return tagIndexInValue === -1 ? null : {
|
|
243
|
+
line: comment.loc.start.line,
|
|
244
|
+
column: comment.loc.start.column + 2 + tagIndexInValue
|
|
245
|
+
};
|
|
246
|
+
} else return {
|
|
247
|
+
line: comment.loc.start.line + lineIndex,
|
|
248
|
+
column: tagIndex
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
//#endregion
|
|
253
|
+
//#region src/rules/no-tag-comments.ts
|
|
254
|
+
const DEFAULT_TAGS$1 = ["FIXME", "BUG"];
|
|
255
|
+
const rule$1 = createRule({
|
|
256
|
+
name: "no-tag-comments",
|
|
257
|
+
meta: {
|
|
258
|
+
type: "problem",
|
|
259
|
+
docs: {
|
|
260
|
+
description: "disallow tag comments",
|
|
261
|
+
category: "Comment",
|
|
262
|
+
recommended: true,
|
|
263
|
+
defaultSeverity: "warn"
|
|
264
|
+
},
|
|
265
|
+
messages: { tagComment: "Exist '{{tag}}' tag comment" },
|
|
266
|
+
schema: [{
|
|
267
|
+
type: "object",
|
|
268
|
+
properties: { tags: {
|
|
269
|
+
type: "array",
|
|
270
|
+
items: { type: "string" },
|
|
271
|
+
minItems: 1,
|
|
272
|
+
uniqueItems: true
|
|
273
|
+
} },
|
|
274
|
+
additionalProperties: false
|
|
275
|
+
}]
|
|
276
|
+
},
|
|
277
|
+
create(ctx) {
|
|
278
|
+
const options = ctx.options[0] || { tags: DEFAULT_TAGS$1 };
|
|
279
|
+
const tags = options.tags || DEFAULT_TAGS$1;
|
|
280
|
+
const sourceCode = ctx.sourceCode;
|
|
281
|
+
/**
|
|
282
|
+
* Report a tag comment violation
|
|
283
|
+
*/
|
|
284
|
+
function reportTag(comment, tag, loc) {
|
|
285
|
+
if (loc && comment.loc) ctx.report({
|
|
286
|
+
messageId: "tagComment",
|
|
287
|
+
data: { tag },
|
|
288
|
+
loc: {
|
|
289
|
+
start: {
|
|
290
|
+
line: loc.line,
|
|
291
|
+
column: loc.column
|
|
292
|
+
},
|
|
293
|
+
end: {
|
|
294
|
+
line: loc.line,
|
|
295
|
+
column: loc.column + tag.length
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
});
|
|
299
|
+
else ctx.report({
|
|
300
|
+
messageId: "tagComment",
|
|
301
|
+
data: { tag },
|
|
302
|
+
loc: comment.loc
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Check a comment for tag violations
|
|
307
|
+
*/
|
|
308
|
+
function checkComment(comment) {
|
|
309
|
+
const { value, type } = comment;
|
|
310
|
+
if (type === "Line") {
|
|
311
|
+
const tagInfo = detectTag(value.trim(), tags);
|
|
312
|
+
if (tagInfo) {
|
|
313
|
+
const tagIndex = value.indexOf(tagInfo.tag);
|
|
314
|
+
if (tagIndex !== -1) reportTag(comment, tagInfo.tag, {
|
|
315
|
+
line: comment.loc.start.line,
|
|
316
|
+
column: comment.loc.start.column + 2 + tagIndex
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
const lines = value.split("\n");
|
|
322
|
+
for (const [i, line] of lines.entries()) {
|
|
323
|
+
const trimmedLine = line.trim();
|
|
324
|
+
if (!trimmedLine) continue;
|
|
325
|
+
const contentToCheck = stripJSDocPrefix(line);
|
|
326
|
+
const tagInfo = detectTag(contentToCheck, tags);
|
|
327
|
+
if (tagInfo) {
|
|
328
|
+
const location = calculateTagLocation(comment, line, i, tagInfo.tag);
|
|
329
|
+
if (location) {
|
|
330
|
+
reportTag(comment, tagInfo.tag, location);
|
|
331
|
+
break;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
return { Program() {
|
|
337
|
+
const comments = sourceCode.getAllComments();
|
|
338
|
+
for (const comment of comments) checkComment(comment);
|
|
339
|
+
} };
|
|
340
|
+
}
|
|
341
|
+
});
|
|
342
|
+
var no_tag_comments_default = rule$1;
|
|
343
|
+
|
|
344
|
+
//#endregion
|
|
345
|
+
//#region src/rules/prefer-scope-on-tag-comment.ts
|
|
346
|
+
const DEFAULT_TAGS = [
|
|
347
|
+
"TODO",
|
|
348
|
+
"FIXME",
|
|
349
|
+
"HACK",
|
|
350
|
+
"BUG",
|
|
351
|
+
"NOTE"
|
|
352
|
+
];
|
|
353
|
+
const rule = createRule({
|
|
354
|
+
name: "prefer-scope-on-tag-comment",
|
|
355
|
+
meta: {
|
|
356
|
+
type: "suggestion",
|
|
357
|
+
docs: {
|
|
358
|
+
description: "enforce adding a scope to tag comments",
|
|
359
|
+
category: "Comment",
|
|
360
|
+
recommended: true,
|
|
361
|
+
defaultSeverity: "warn"
|
|
362
|
+
},
|
|
363
|
+
messages: { missingScope: "Tag comment '{{tag}}' is missing a scope. Use format: {{tag}}(scope)" },
|
|
364
|
+
schema: [{
|
|
365
|
+
type: "object",
|
|
366
|
+
properties: { tags: {
|
|
367
|
+
type: "array",
|
|
368
|
+
items: { type: "string" },
|
|
369
|
+
minItems: 1,
|
|
370
|
+
uniqueItems: true
|
|
371
|
+
} },
|
|
372
|
+
additionalProperties: false
|
|
373
|
+
}]
|
|
374
|
+
},
|
|
375
|
+
create(ctx) {
|
|
376
|
+
const options = ctx.options[0] || { tags: DEFAULT_TAGS };
|
|
377
|
+
const tags = options.tags || DEFAULT_TAGS;
|
|
378
|
+
const sourceCode = ctx.sourceCode;
|
|
379
|
+
/**
|
|
380
|
+
* Report a missing scope violation
|
|
381
|
+
*/
|
|
382
|
+
function reportMissingScope(comment, tag, loc) {
|
|
383
|
+
if (!comment.loc) {
|
|
384
|
+
ctx.report({
|
|
385
|
+
messageId: "missingScope",
|
|
386
|
+
data: { tag },
|
|
387
|
+
node: ctx.sourceCode.ast
|
|
388
|
+
});
|
|
389
|
+
return;
|
|
390
|
+
}
|
|
391
|
+
if (loc && comment.loc) ctx.report({
|
|
392
|
+
messageId: "missingScope",
|
|
393
|
+
data: { tag },
|
|
394
|
+
loc: {
|
|
395
|
+
start: {
|
|
396
|
+
line: loc.line,
|
|
397
|
+
column: loc.column
|
|
398
|
+
},
|
|
399
|
+
end: {
|
|
400
|
+
line: loc.line,
|
|
401
|
+
column: loc.column + tag.length
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
});
|
|
405
|
+
else ctx.report({
|
|
406
|
+
messageId: "missingScope",
|
|
407
|
+
data: { tag },
|
|
408
|
+
loc: comment.loc
|
|
409
|
+
});
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Check a comment for missing scope
|
|
413
|
+
*/
|
|
414
|
+
function checkComment(comment) {
|
|
415
|
+
const { value, type } = comment;
|
|
416
|
+
if (type === "Line") {
|
|
417
|
+
const tagInfo = detectTag(value.trim(), tags);
|
|
418
|
+
if (tagInfo && !tagInfo.hasScope) {
|
|
419
|
+
const tagIndex = value.indexOf(tagInfo.tag);
|
|
420
|
+
if (tagIndex !== -1) reportMissingScope(comment, tagInfo.tag, {
|
|
421
|
+
line: comment.loc.start.line,
|
|
422
|
+
column: comment.loc.start.column + 2 + tagIndex
|
|
423
|
+
});
|
|
424
|
+
}
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
const lines = value.split("\n");
|
|
428
|
+
for (const [i, line] of lines.entries()) {
|
|
429
|
+
const trimmedLine = line.trim();
|
|
430
|
+
if (!trimmedLine) continue;
|
|
431
|
+
const contentToCheck = stripJSDocPrefix(line);
|
|
432
|
+
const tagInfo = detectTag(contentToCheck, tags);
|
|
433
|
+
if (tagInfo && !tagInfo.hasScope) {
|
|
434
|
+
const location = calculateTagLocation(comment, line, i, tagInfo.tag);
|
|
435
|
+
if (location) {
|
|
436
|
+
reportMissingScope(comment, tagInfo.tag, location);
|
|
437
|
+
break;
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
return { Program() {
|
|
443
|
+
const comments = sourceCode.getAllComments();
|
|
444
|
+
for (const comment of comments) checkComment(comment);
|
|
445
|
+
} };
|
|
446
|
+
}
|
|
447
|
+
});
|
|
448
|
+
var prefer_scope_on_tag_comment_default = rule;
|
|
172
449
|
|
|
173
450
|
//#endregion
|
|
174
451
|
//#region src/rules/index.ts
|
|
175
|
-
const rules = {
|
|
452
|
+
const rules = {
|
|
453
|
+
"enforce-header-comment": enforce_header_comment_default,
|
|
454
|
+
"no-tag-comments": no_tag_comments_default,
|
|
455
|
+
"prefer-scope-on-tag-comment": prefer_scope_on_tag_comment_default
|
|
456
|
+
};
|
|
176
457
|
|
|
177
458
|
//#endregion
|
|
178
459
|
//#region src/index.ts
|
|
@@ -184,6 +465,23 @@ const plugin = {
|
|
|
184
465
|
rules,
|
|
185
466
|
configs: {}
|
|
186
467
|
};
|
|
468
|
+
const recommendedConfig = [{
|
|
469
|
+
name: "@kazupon/eslint-plugin/recommended",
|
|
470
|
+
files: ["**/*.{js,mjs,cjs,ts,mts,cts,jsx,tsx}"],
|
|
471
|
+
ignores: [
|
|
472
|
+
"**/*.md",
|
|
473
|
+
"**/*.md/**/*.{js,mjs,cjs,ts,mts,cts,jsx,tsx}",
|
|
474
|
+
"**/*.config.{js,mjs,cjs,ts,mts,cts,jsx,tsx}"
|
|
475
|
+
],
|
|
476
|
+
plugins: { [namespace]: plugin },
|
|
477
|
+
rules: Object.entries(rules).reduce((acc, [ruleName, rule$3]) => {
|
|
478
|
+
if (rule$3.meta?.docs?.recommended) {
|
|
479
|
+
const ruleId = rule$3.meta?.docs?.ruleId || (namespace ? `${namespace}/${ruleName}` : ruleName);
|
|
480
|
+
acc[ruleId] = rule$3.meta?.docs?.defaultSeverity || "warn";
|
|
481
|
+
}
|
|
482
|
+
return acc;
|
|
483
|
+
}, Object.create(null))
|
|
484
|
+
}];
|
|
187
485
|
const commentConfig = [{
|
|
188
486
|
name: "@kazupon/eslint-plugin/comment",
|
|
189
487
|
files: ["**/*.{js,mjs,cjs,ts,mts,cts,jsx,tsx}"],
|
|
@@ -193,17 +491,18 @@ const commentConfig = [{
|
|
|
193
491
|
"**/*.config.{js,mjs,cjs,ts,mts,cts,jsx,tsx}"
|
|
194
492
|
],
|
|
195
493
|
plugins: { [namespace]: plugin },
|
|
196
|
-
rules: Object.entries(rules).reduce((rules$1, [ruleName, rule$
|
|
197
|
-
const ruleId = rule$
|
|
198
|
-
rules$1[ruleId] = rule$
|
|
494
|
+
rules: Object.entries(rules).reduce((rules$1, [ruleName, rule$3]) => {
|
|
495
|
+
const ruleId = rule$3.meta?.docs?.ruleId || (namespace ? `${namespace}/${ruleName}` : ruleName);
|
|
496
|
+
rules$1[ruleId] = rule$3.meta?.docs?.defaultSeverity || "warn";
|
|
199
497
|
return rules$1;
|
|
200
498
|
}, Object.create(null))
|
|
201
499
|
}];
|
|
202
500
|
const configs = {
|
|
203
|
-
recommended:
|
|
501
|
+
recommended: recommendedConfig,
|
|
204
502
|
comment: commentConfig
|
|
205
503
|
};
|
|
206
504
|
plugin.configs = configs;
|
|
505
|
+
/** @alias */
|
|
207
506
|
var src_default = plugin;
|
|
208
507
|
|
|
209
508
|
//#endregion
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kazupon/eslint-plugin",
|
|
3
3
|
"description": "ESLint plugin for @kazupon",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.4.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"funding": "https://github.com/sponsors/kazupon",
|
|
7
7
|
"bugs": {
|
|
@@ -47,46 +47,48 @@
|
|
|
47
47
|
}
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@es-joy/jsdoccomment": "^0.50.
|
|
51
|
-
"@eslint/core": "^0.
|
|
50
|
+
"@es-joy/jsdoccomment": "^0.50.2",
|
|
51
|
+
"@eslint/core": "^0.14.0"
|
|
52
52
|
},
|
|
53
53
|
"peerDependencies": {
|
|
54
54
|
"eslint": "^9.0.0"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
|
-
"@eslint/
|
|
58
|
-
"@
|
|
57
|
+
"@eslint/compat": "^1.2.9",
|
|
58
|
+
"@eslint/markdown": "^6.5.0",
|
|
59
|
+
"@kazupon/eslint-config": "^0.31.0",
|
|
59
60
|
"@kazupon/prettier-config": "^0.1.1",
|
|
60
|
-
"@shikijs/vitepress-twoslash": "^3.
|
|
61
|
-
"@types/node": "^22.
|
|
62
|
-
"@vitest/eslint-plugin": "^1.1
|
|
63
|
-
"bumpp": "^10.1.
|
|
64
|
-
"eslint": "^9.
|
|
65
|
-
"eslint-config-prettier": "^10.1.
|
|
66
|
-
"eslint-import-resolver-typescript": "^4.3
|
|
61
|
+
"@shikijs/vitepress-twoslash": "^3.6.0",
|
|
62
|
+
"@types/node": "^22.15.30",
|
|
63
|
+
"@vitest/eslint-plugin": "^1.2.1",
|
|
64
|
+
"bumpp": "^10.1.1",
|
|
65
|
+
"eslint": "^9.28.0",
|
|
66
|
+
"eslint-config-prettier": "^10.1.5",
|
|
67
|
+
"eslint-import-resolver-typescript": "^4.4.3",
|
|
67
68
|
"eslint-plugin-import": "^2.31.0",
|
|
68
|
-
"eslint-plugin-jsonc": "^2.20.
|
|
69
|
+
"eslint-plugin-jsonc": "^2.20.1",
|
|
69
70
|
"eslint-plugin-module-interop": "^0.3.1",
|
|
70
71
|
"eslint-plugin-promise": "^7.2.1",
|
|
71
|
-
"eslint-plugin-
|
|
72
|
+
"eslint-plugin-regexp": "^2.8.0",
|
|
73
|
+
"eslint-plugin-unicorn": "^59.0.0",
|
|
72
74
|
"eslint-plugin-unused-imports": "^4.1.4",
|
|
73
|
-
"eslint-plugin-yml": "^1.
|
|
75
|
+
"eslint-plugin-yml": "^1.18.0",
|
|
74
76
|
"eslint-vitest-rule-tester": "^2.2.0",
|
|
75
77
|
"gh-changelogen": "^0.2.8",
|
|
76
|
-
"knip": "^5.
|
|
77
|
-
"lint-staged": "^
|
|
78
|
-
"pkg-pr-new": "^0.0.
|
|
78
|
+
"knip": "^5.60.2",
|
|
79
|
+
"lint-staged": "^16.0.0",
|
|
80
|
+
"pkg-pr-new": "^0.0.51",
|
|
79
81
|
"prettier": "^3.5.3",
|
|
80
|
-
"publint": "^0.3.
|
|
81
|
-
"tsdown": "^0.
|
|
82
|
-
"tsx": "^4.19.
|
|
82
|
+
"publint": "^0.3.12",
|
|
83
|
+
"tsdown": "^0.12.7",
|
|
84
|
+
"tsx": "^4.19.4",
|
|
83
85
|
"twoslash-eslint": "^0.3.1",
|
|
84
86
|
"typescript": "^5.8.3",
|
|
85
|
-
"typescript-eslint": "^8.
|
|
87
|
+
"typescript-eslint": "^8.33.1",
|
|
86
88
|
"vite-plugin-eslint4b": "^0.5.1",
|
|
87
89
|
"vitepress": "^1.6.3",
|
|
88
|
-
"vitepress-plugin-group-icons": "^1.
|
|
89
|
-
"vitest": "^3.
|
|
90
|
+
"vitepress-plugin-group-icons": "^1.6.0",
|
|
91
|
+
"vitest": "^3.2.2"
|
|
90
92
|
},
|
|
91
93
|
"prettier": "@kazupon/prettier-config",
|
|
92
94
|
"lint-staged": {
|