eslint-plugin-svg 0.0.4 → 0.0.5
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 -0
- package/dist/index.d.ts +16 -6
- package/dist/index.js +207 -58
- package/package.json +10 -10
package/README.md
CHANGED
|
@@ -53,6 +53,11 @@ export default defineConfig([
|
|
|
53
53
|
| [no-empty-desc](https://eslint-plugin-svg.ntnyq.com/rules/no-empty-desc) | Disallow empty desc element | ✅ | | |
|
|
54
54
|
| [no-empty-text](https://eslint-plugin-svg.ntnyq.com/rules/no-empty-text) | Disallow empty text element | ✅ | | |
|
|
55
55
|
| [no-empty-container](https://eslint-plugin-svg.ntnyq.com/rules/no-empty-container) | Disallow empty container element | ✅ | | |
|
|
56
|
+
| [no-empty-groups](https://eslint-plugin-svg.ntnyq.com/rules/no-empty-groups) | Disallow empty g element | ✅ | | |
|
|
57
|
+
| [no-inline-styles](https://eslint-plugin-svg.ntnyq.com/rules/no-inline-styles) | Disallow inline style attribute | ✅ | | |
|
|
58
|
+
| [no-event-handlers](https://eslint-plugin-svg.ntnyq.com/rules/no-event-handlers) | Disallow inline event handlers | ✅ | | |
|
|
59
|
+
| [no-script-tags](https://eslint-plugin-svg.ntnyq.com/rules/no-script-tags) | Disallow script elements | ✅ | | |
|
|
60
|
+
| [require-viewbox](https://eslint-plugin-svg.ntnyq.com/rules/require-viewbox) | Require viewBox on svg elements | ✅ | | |
|
|
56
61
|
| [no-deprecated](https://eslint-plugin-svg.ntnyq.com/rules/no-deprecated) | Disallow deprecated elements | ✅ | | |
|
|
57
62
|
| [no-elements](https://eslint-plugin-svg.ntnyq.com/rules/no-elements) | Disallow elements by name | | | |
|
|
58
63
|
| [no-doctype](https://eslint-plugin-svg.ntnyq.com/rules/no-doctype) | Disallow doctype | ✅ | 🔧 | |
|
package/dist/index.d.ts
CHANGED
|
@@ -165,23 +165,28 @@ type SVGSettings = {
|
|
|
165
165
|
};
|
|
166
166
|
//#endregion
|
|
167
167
|
//#region src/rules/no-deprecated.d.ts
|
|
168
|
-
type Options$
|
|
168
|
+
type Options$4 = [{
|
|
169
169
|
allowElements?: string[];
|
|
170
170
|
}];
|
|
171
171
|
//#endregion
|
|
172
172
|
//#region src/rules/no-elements.d.ts
|
|
173
|
-
type Options$
|
|
173
|
+
type Options$3 = [{
|
|
174
174
|
elements?: string[];
|
|
175
175
|
}];
|
|
176
176
|
//#endregion
|
|
177
177
|
//#region src/rules/no-empty-container.d.ts
|
|
178
|
-
type Options$
|
|
178
|
+
type Options$2 = [{
|
|
179
179
|
elements?: string[];
|
|
180
180
|
ignores?: string[];
|
|
181
181
|
ignoreComments?: boolean;
|
|
182
182
|
ignoreWhitespace?: boolean;
|
|
183
183
|
}];
|
|
184
184
|
//#endregion
|
|
185
|
+
//#region src/rules/no-event-handlers.d.ts
|
|
186
|
+
type Options$1 = [{
|
|
187
|
+
ignores?: string[];
|
|
188
|
+
}];
|
|
189
|
+
//#endregion
|
|
185
190
|
//#region src/rules/no-invalid-role.d.ts
|
|
186
191
|
type Options = [{
|
|
187
192
|
roles?: string[];
|
|
@@ -189,14 +194,19 @@ type Options = [{
|
|
|
189
194
|
//#endregion
|
|
190
195
|
//#region src/rules/index.d.ts
|
|
191
196
|
declare const rules: {
|
|
192
|
-
'no-deprecated': RuleModule<"deprecatedElement", Options$
|
|
197
|
+
'no-deprecated': RuleModule<"deprecatedElement", Options$4, unknown>;
|
|
193
198
|
'no-doctype': RuleModule<"invalid", [], unknown>;
|
|
194
|
-
'no-elements': RuleModule<"invalid", Options$
|
|
195
|
-
'no-empty-container': RuleModule<"invalid", Options$
|
|
199
|
+
'no-elements': RuleModule<"invalid", Options$3, unknown>;
|
|
200
|
+
'no-empty-container': RuleModule<"invalid", Options$2, unknown>;
|
|
196
201
|
'no-empty-desc': RuleModule<"invalid", [], unknown>;
|
|
202
|
+
'no-empty-groups': RuleModule<"invalid", [], unknown>;
|
|
197
203
|
'no-empty-text': RuleModule<"invalid", [], unknown>;
|
|
198
204
|
'no-empty-title': RuleModule<"invalid", [], unknown>;
|
|
205
|
+
'no-event-handlers': RuleModule<"invalid", Options$1, unknown>;
|
|
206
|
+
'no-inline-styles': RuleModule<"invalid", [], unknown>;
|
|
199
207
|
'no-invalid-role': RuleModule<"invalid", Options, unknown>;
|
|
208
|
+
'no-script-tags': RuleModule<"invalid", [], unknown>;
|
|
209
|
+
'require-viewbox': RuleModule<"missing", [], unknown>;
|
|
200
210
|
};
|
|
201
211
|
//#endregion
|
|
202
212
|
//#region src/types/plugin.d.ts
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as parserSVG from "svg-eslint-parser";
|
|
2
2
|
import "uncase";
|
|
3
|
-
import { isNonEmptyString } from "@ntnyq/utils";
|
|
3
|
+
import { isNonEmptyString, toArray } from "@ntnyq/utils";
|
|
4
4
|
|
|
5
5
|
//#region src/configs/index.ts
|
|
6
6
|
/**
|
|
@@ -18,9 +18,14 @@ const recommended = [{
|
|
|
18
18
|
"svg/no-doctype": "error",
|
|
19
19
|
"svg/no-empty-container": "error",
|
|
20
20
|
"svg/no-empty-desc": "error",
|
|
21
|
+
"svg/no-empty-groups": "error",
|
|
21
22
|
"svg/no-empty-text": "error",
|
|
22
23
|
"svg/no-empty-title": "error",
|
|
23
|
-
"svg/no-
|
|
24
|
+
"svg/no-event-handlers": "error",
|
|
25
|
+
"svg/no-inline-styles": "error",
|
|
26
|
+
"svg/no-invalid-role": "error",
|
|
27
|
+
"svg/no-script-tags": "error",
|
|
28
|
+
"svg/require-viewbox": "error"
|
|
24
29
|
}
|
|
25
30
|
}];
|
|
26
31
|
const configs = { recommended };
|
|
@@ -28,7 +33,7 @@ const configs = { recommended };
|
|
|
28
33
|
//#endregion
|
|
29
34
|
//#region package.json
|
|
30
35
|
var name = "eslint-plugin-svg";
|
|
31
|
-
var version = "0.0.
|
|
36
|
+
var version = "0.0.5";
|
|
32
37
|
|
|
33
38
|
//#endregion
|
|
34
39
|
//#region src/meta.ts
|
|
@@ -264,21 +269,21 @@ function deepMerge(first = {}, second = {}) {
|
|
|
264
269
|
|
|
265
270
|
//#endregion
|
|
266
271
|
//#region src/utils/createRule.ts
|
|
267
|
-
function createRule({ create, defaultOptions: defaultOptions$
|
|
272
|
+
function createRule({ create, defaultOptions: defaultOptions$5, meta: meta$1 }) {
|
|
268
273
|
return {
|
|
269
274
|
create: ((context) => {
|
|
270
|
-
const optionsCount = Math.max(context.options.length, defaultOptions$
|
|
275
|
+
const optionsCount = Math.max(context.options.length, defaultOptions$5.length);
|
|
271
276
|
return create(context, Array.from({ length: optionsCount }, (_, i) => {
|
|
272
277
|
/* v8 ignore start */
|
|
273
|
-
if (isObjectNotArray(context.options[i]) && isObjectNotArray(defaultOptions$
|
|
274
|
-
return context.options[i] ?? defaultOptions$
|
|
278
|
+
if (isObjectNotArray(context.options[i]) && isObjectNotArray(defaultOptions$5[i])) return deepMerge(defaultOptions$5[i], context.options[i]);
|
|
279
|
+
return context.options[i] ?? defaultOptions$5[i];
|
|
275
280
|
/* v8 ignore stop */
|
|
276
281
|
}));
|
|
277
282
|
}),
|
|
278
|
-
defaultOptions: defaultOptions$
|
|
283
|
+
defaultOptions: defaultOptions$5,
|
|
279
284
|
meta: {
|
|
280
285
|
...meta$1,
|
|
281
|
-
defaultOptions: defaultOptions$
|
|
286
|
+
defaultOptions: defaultOptions$5
|
|
282
287
|
}
|
|
283
288
|
};
|
|
284
289
|
}
|
|
@@ -307,17 +312,17 @@ const createESLintRule = RuleCreator((ruleName) => `https://eslint-plugin-svg.nt
|
|
|
307
312
|
* @param defaultOptions - default options
|
|
308
313
|
* @returns - resolved options
|
|
309
314
|
*/
|
|
310
|
-
function resolveOptions(options, defaultOptions$
|
|
315
|
+
function resolveOptions(options, defaultOptions$5) {
|
|
311
316
|
/* v8 ignore next guard by eslint */
|
|
312
|
-
return options?.[0] || defaultOptions$
|
|
317
|
+
return options?.[0] || defaultOptions$5;
|
|
313
318
|
}
|
|
314
319
|
|
|
315
320
|
//#endregion
|
|
316
321
|
//#region src/rules/no-deprecated.ts
|
|
317
|
-
const RULE_NAME$
|
|
318
|
-
const defaultOptions$
|
|
322
|
+
const RULE_NAME$12 = "no-deprecated";
|
|
323
|
+
const defaultOptions$4 = {};
|
|
319
324
|
var no_deprecated_default = createESLintRule({
|
|
320
|
-
name: RULE_NAME$
|
|
325
|
+
name: RULE_NAME$12,
|
|
321
326
|
meta: {
|
|
322
327
|
type: "suggestion",
|
|
323
328
|
docs: {
|
|
@@ -335,9 +340,9 @@ var no_deprecated_default = createESLintRule({
|
|
|
335
340
|
}],
|
|
336
341
|
messages: { deprecatedElement: `Element '{{name}}' is deprecated` }
|
|
337
342
|
},
|
|
338
|
-
defaultOptions: [defaultOptions$
|
|
343
|
+
defaultOptions: [defaultOptions$4],
|
|
339
344
|
create(context) {
|
|
340
|
-
const { allowElements = [] } = resolveOptions(context.options, defaultOptions$
|
|
345
|
+
const { allowElements = [] } = resolveOptions(context.options, defaultOptions$4);
|
|
341
346
|
const deprecatedElements = new Set(DEPRECATED_ELEMENTS.filter((element) => !allowElements.includes(element)));
|
|
342
347
|
return { Tag(node) {
|
|
343
348
|
if (deprecatedElements.has(node.name)) context.report({
|
|
@@ -351,9 +356,9 @@ var no_deprecated_default = createESLintRule({
|
|
|
351
356
|
|
|
352
357
|
//#endregion
|
|
353
358
|
//#region src/rules/no-doctype.ts
|
|
354
|
-
const RULE_NAME$
|
|
359
|
+
const RULE_NAME$11 = "no-doctype";
|
|
355
360
|
var no_doctype_default = createESLintRule({
|
|
356
|
-
name: RULE_NAME$
|
|
361
|
+
name: RULE_NAME$11,
|
|
357
362
|
meta: {
|
|
358
363
|
type: "suggestion",
|
|
359
364
|
docs: {
|
|
@@ -378,10 +383,10 @@ var no_doctype_default = createESLintRule({
|
|
|
378
383
|
|
|
379
384
|
//#endregion
|
|
380
385
|
//#region src/rules/no-elements.ts
|
|
381
|
-
const RULE_NAME$
|
|
382
|
-
const defaultOptions$
|
|
386
|
+
const RULE_NAME$10 = "no-elements";
|
|
387
|
+
const defaultOptions$3 = {};
|
|
383
388
|
var no_elements_default = createESLintRule({
|
|
384
|
-
name: RULE_NAME$
|
|
389
|
+
name: RULE_NAME$10,
|
|
385
390
|
meta: {
|
|
386
391
|
type: "suggestion",
|
|
387
392
|
docs: {
|
|
@@ -399,9 +404,9 @@ var no_elements_default = createESLintRule({
|
|
|
399
404
|
}],
|
|
400
405
|
messages: { invalid: `Element '{{name}}' is not allowed` }
|
|
401
406
|
},
|
|
402
|
-
defaultOptions: [defaultOptions$
|
|
407
|
+
defaultOptions: [defaultOptions$3],
|
|
403
408
|
create(context) {
|
|
404
|
-
const { elements = [] } = resolveOptions(context.options, defaultOptions$
|
|
409
|
+
const { elements = [] } = resolveOptions(context.options, defaultOptions$3);
|
|
405
410
|
if (!elements.length) return {};
|
|
406
411
|
return { Tag(node) {
|
|
407
412
|
if (elements.includes(node.name)) context.report({
|
|
@@ -415,10 +420,10 @@ var no_elements_default = createESLintRule({
|
|
|
415
420
|
|
|
416
421
|
//#endregion
|
|
417
422
|
//#region src/rules/no-empty-container.ts
|
|
418
|
-
const RULE_NAME$
|
|
419
|
-
const defaultOptions$
|
|
423
|
+
const RULE_NAME$9 = "no-empty-container";
|
|
424
|
+
const defaultOptions$2 = {};
|
|
420
425
|
var no_empty_container_default = createESLintRule({
|
|
421
|
-
name: RULE_NAME$
|
|
426
|
+
name: RULE_NAME$9,
|
|
422
427
|
meta: {
|
|
423
428
|
type: "suggestion",
|
|
424
429
|
docs: {
|
|
@@ -453,9 +458,9 @@ var no_empty_container_default = createESLintRule({
|
|
|
453
458
|
}],
|
|
454
459
|
messages: { invalid: `Container element '{{name}}' must not be empty` }
|
|
455
460
|
},
|
|
456
|
-
defaultOptions: [defaultOptions$
|
|
461
|
+
defaultOptions: [defaultOptions$2],
|
|
457
462
|
create(context) {
|
|
458
|
-
const { elements = [], ignores = [], ignoreComments = true, ignoreWhitespace = true } = resolveOptions(context.options, defaultOptions$
|
|
463
|
+
const { elements = [], ignores = [], ignoreComments = true, ignoreWhitespace = true } = resolveOptions(context.options, defaultOptions$2);
|
|
459
464
|
const containerElements = new Set([...CONTAINER_ELEMENTS, ...elements].filter((v) => !ignores.includes(v)));
|
|
460
465
|
return { Tag(node) {
|
|
461
466
|
if (!containerElements.has(node.name)) return;
|
|
@@ -470,9 +475,9 @@ var no_empty_container_default = createESLintRule({
|
|
|
470
475
|
|
|
471
476
|
//#endregion
|
|
472
477
|
//#region src/rules/no-empty-desc.ts
|
|
473
|
-
const RULE_NAME$
|
|
478
|
+
const RULE_NAME$8 = "no-empty-desc";
|
|
474
479
|
var no_empty_desc_default = createESLintRule({
|
|
475
|
-
name: RULE_NAME$
|
|
480
|
+
name: RULE_NAME$8,
|
|
476
481
|
meta: {
|
|
477
482
|
type: "suggestion",
|
|
478
483
|
docs: {
|
|
@@ -486,13 +491,36 @@ var no_empty_desc_default = createESLintRule({
|
|
|
486
491
|
create(context) {
|
|
487
492
|
return { Tag(node) {
|
|
488
493
|
if (node.name !== "desc") return;
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
494
|
+
if (!node.children || node.children.length === 0 || node.children.every((child) => child.type === "Text" && !child.value.trim())) return context.report({
|
|
495
|
+
node,
|
|
496
|
+
messageId: "invalid"
|
|
497
|
+
});
|
|
498
|
+
} };
|
|
499
|
+
}
|
|
500
|
+
});
|
|
501
|
+
|
|
502
|
+
//#endregion
|
|
503
|
+
//#region src/rules/no-empty-groups.ts
|
|
504
|
+
const RULE_NAME$7 = "no-empty-groups";
|
|
505
|
+
var no_empty_groups_default = createESLintRule({
|
|
506
|
+
name: RULE_NAME$7,
|
|
507
|
+
meta: {
|
|
508
|
+
type: "suggestion",
|
|
509
|
+
docs: {
|
|
510
|
+
description: "disallow empty group element",
|
|
511
|
+
recommended: true
|
|
512
|
+
},
|
|
513
|
+
schema: [],
|
|
514
|
+
messages: { invalid: `Group element 'g' must not be empty` }
|
|
515
|
+
},
|
|
516
|
+
defaultOptions: [],
|
|
517
|
+
create(context) {
|
|
518
|
+
return { Tag(node) {
|
|
519
|
+
if (node.name !== "g") return;
|
|
520
|
+
if ((node.children ?? []).filter((child) => child.type !== "Comment").filter((child) => {
|
|
521
|
+
if (child.type !== "Text") return true;
|
|
522
|
+
return isNonEmptyString((child.value ?? "").trim());
|
|
523
|
+
}).length === 0) context.report({
|
|
496
524
|
node,
|
|
497
525
|
messageId: "invalid"
|
|
498
526
|
});
|
|
@@ -502,9 +530,9 @@ var no_empty_desc_default = createESLintRule({
|
|
|
502
530
|
|
|
503
531
|
//#endregion
|
|
504
532
|
//#region src/rules/no-empty-text.ts
|
|
505
|
-
const RULE_NAME$
|
|
533
|
+
const RULE_NAME$6 = "no-empty-text";
|
|
506
534
|
var no_empty_text_default = createESLintRule({
|
|
507
|
-
name: RULE_NAME$
|
|
535
|
+
name: RULE_NAME$6,
|
|
508
536
|
meta: {
|
|
509
537
|
type: "suggestion",
|
|
510
538
|
docs: {
|
|
@@ -518,13 +546,7 @@ var no_empty_text_default = createESLintRule({
|
|
|
518
546
|
create(context) {
|
|
519
547
|
return { Tag(node) {
|
|
520
548
|
if (node.name !== "text") return;
|
|
521
|
-
|
|
522
|
-
if (textNode) {
|
|
523
|
-
if (!textNode.value.trim()) return context.report({
|
|
524
|
-
node,
|
|
525
|
-
messageId: "invalid"
|
|
526
|
-
});
|
|
527
|
-
} else return context.report({
|
|
549
|
+
if (!node.children || node.children.length === 0 || node.children.every((child) => child.type === "Text" && !child.value.trim())) return context.report({
|
|
528
550
|
node,
|
|
529
551
|
messageId: "invalid"
|
|
530
552
|
});
|
|
@@ -534,9 +556,9 @@ var no_empty_text_default = createESLintRule({
|
|
|
534
556
|
|
|
535
557
|
//#endregion
|
|
536
558
|
//#region src/rules/no-empty-title.ts
|
|
537
|
-
const RULE_NAME$
|
|
559
|
+
const RULE_NAME$5 = "no-empty-title";
|
|
538
560
|
var no_empty_title_default = createESLintRule({
|
|
539
|
-
name: RULE_NAME$
|
|
561
|
+
name: RULE_NAME$5,
|
|
540
562
|
meta: {
|
|
541
563
|
type: "suggestion",
|
|
542
564
|
docs: {
|
|
@@ -550,13 +572,7 @@ var no_empty_title_default = createESLintRule({
|
|
|
550
572
|
create(context) {
|
|
551
573
|
return { Tag(node) {
|
|
552
574
|
if (node.name !== "title") return;
|
|
553
|
-
|
|
554
|
-
if (textNode) {
|
|
555
|
-
if (!textNode.value.trim()) return context.report({
|
|
556
|
-
node,
|
|
557
|
-
messageId: "invalid"
|
|
558
|
-
});
|
|
559
|
-
} else return context.report({
|
|
575
|
+
if (!node.children || node.children.length === 0 || node.children.every((child) => child.type === "Text" && !child.value.trim())) return context.report({
|
|
560
576
|
node,
|
|
561
577
|
messageId: "invalid"
|
|
562
578
|
});
|
|
@@ -564,12 +580,80 @@ var no_empty_title_default = createESLintRule({
|
|
|
564
580
|
}
|
|
565
581
|
});
|
|
566
582
|
|
|
583
|
+
//#endregion
|
|
584
|
+
//#region src/rules/no-event-handlers.ts
|
|
585
|
+
const RULE_NAME$4 = "no-event-handlers";
|
|
586
|
+
const defaultOptions$1 = {};
|
|
587
|
+
var no_event_handlers_default = createESLintRule({
|
|
588
|
+
name: RULE_NAME$4,
|
|
589
|
+
meta: {
|
|
590
|
+
type: "suggestion",
|
|
591
|
+
docs: {
|
|
592
|
+
description: "disallow inline event handler attributes (e.g. onclick)",
|
|
593
|
+
recommended: true
|
|
594
|
+
},
|
|
595
|
+
schema: [{
|
|
596
|
+
type: "object",
|
|
597
|
+
properties: { ignores: {
|
|
598
|
+
type: "array",
|
|
599
|
+
description: "Event handler attribute names to ignore",
|
|
600
|
+
items: { type: "string" },
|
|
601
|
+
uniqueItems: true
|
|
602
|
+
} },
|
|
603
|
+
additionalProperties: false
|
|
604
|
+
}],
|
|
605
|
+
messages: { invalid: `Inline event handler '{{name}}' is not allowed` }
|
|
606
|
+
},
|
|
607
|
+
defaultOptions: [defaultOptions$1],
|
|
608
|
+
create(context) {
|
|
609
|
+
const { ignores = [] } = resolveOptions(context.options, defaultOptions$1);
|
|
610
|
+
const ignorePatterns = ignores.map((pattern) => new RegExp(pattern));
|
|
611
|
+
const isIgnored = (name$1) => ignorePatterns.some((pattern) => pattern.test(name$1));
|
|
612
|
+
return { Attribute(node) {
|
|
613
|
+
const name$1 = node.key.value;
|
|
614
|
+
if (!name$1 || !name$1.toLowerCase().startsWith("on")) return;
|
|
615
|
+
if (isIgnored(name$1)) return;
|
|
616
|
+
context.report({
|
|
617
|
+
node: node.value ?? node.key,
|
|
618
|
+
messageId: "invalid",
|
|
619
|
+
data: { name: name$1 }
|
|
620
|
+
});
|
|
621
|
+
} };
|
|
622
|
+
}
|
|
623
|
+
});
|
|
624
|
+
|
|
625
|
+
//#endregion
|
|
626
|
+
//#region src/rules/no-inline-styles.ts
|
|
627
|
+
const RULE_NAME$3 = "no-inline-styles";
|
|
628
|
+
var no_inline_styles_default = createESLintRule({
|
|
629
|
+
name: RULE_NAME$3,
|
|
630
|
+
meta: {
|
|
631
|
+
type: "suggestion",
|
|
632
|
+
docs: {
|
|
633
|
+
description: "disallow inline style attribute usage",
|
|
634
|
+
recommended: true
|
|
635
|
+
},
|
|
636
|
+
schema: [],
|
|
637
|
+
messages: { invalid: "Inline style attributes are not allowed" }
|
|
638
|
+
},
|
|
639
|
+
defaultOptions: [],
|
|
640
|
+
create(context) {
|
|
641
|
+
return { Attribute(node) {
|
|
642
|
+
if (node.key.value !== "style") return;
|
|
643
|
+
context.report({
|
|
644
|
+
node: node.value ?? node.key,
|
|
645
|
+
messageId: "invalid"
|
|
646
|
+
});
|
|
647
|
+
} };
|
|
648
|
+
}
|
|
649
|
+
});
|
|
650
|
+
|
|
567
651
|
//#endregion
|
|
568
652
|
//#region src/rules/no-invalid-role.ts
|
|
569
|
-
const RULE_NAME = "no-invalid-role";
|
|
653
|
+
const RULE_NAME$2 = "no-invalid-role";
|
|
570
654
|
const defaultOptions = {};
|
|
571
655
|
var no_invalid_role_default = createESLintRule({
|
|
572
|
-
name: RULE_NAME,
|
|
656
|
+
name: RULE_NAME$2,
|
|
573
657
|
meta: {
|
|
574
658
|
type: "suggestion",
|
|
575
659
|
docs: {
|
|
@@ -606,6 +690,66 @@ var no_invalid_role_default = createESLintRule({
|
|
|
606
690
|
}
|
|
607
691
|
});
|
|
608
692
|
|
|
693
|
+
//#endregion
|
|
694
|
+
//#region src/rules/no-script-tags.ts
|
|
695
|
+
const RULE_NAME$1 = "no-script-tags";
|
|
696
|
+
var no_script_tags_default = createESLintRule({
|
|
697
|
+
name: RULE_NAME$1,
|
|
698
|
+
meta: {
|
|
699
|
+
type: "suggestion",
|
|
700
|
+
docs: {
|
|
701
|
+
description: "disallow usage of script elements",
|
|
702
|
+
recommended: true
|
|
703
|
+
},
|
|
704
|
+
schema: [],
|
|
705
|
+
messages: { invalid: `Script elements are not allowed in SVG` }
|
|
706
|
+
},
|
|
707
|
+
defaultOptions: [],
|
|
708
|
+
create(context) {
|
|
709
|
+
return { Tag(node) {
|
|
710
|
+
if (node.name !== "script") return;
|
|
711
|
+
context.report({
|
|
712
|
+
node,
|
|
713
|
+
messageId: "invalid"
|
|
714
|
+
});
|
|
715
|
+
} };
|
|
716
|
+
}
|
|
717
|
+
});
|
|
718
|
+
|
|
719
|
+
//#endregion
|
|
720
|
+
//#region src/rules/require-viewbox.ts
|
|
721
|
+
const RULE_NAME = "require-viewbox";
|
|
722
|
+
var require_viewbox_default = createESLintRule({
|
|
723
|
+
name: RULE_NAME,
|
|
724
|
+
meta: {
|
|
725
|
+
type: "suggestion",
|
|
726
|
+
docs: {
|
|
727
|
+
description: "require svg elements to include a non-empty viewBox attribute",
|
|
728
|
+
recommended: true
|
|
729
|
+
},
|
|
730
|
+
schema: [],
|
|
731
|
+
messages: { missing: `SVG element must include a non-empty viewBox attribute` }
|
|
732
|
+
},
|
|
733
|
+
defaultOptions: [],
|
|
734
|
+
create(context) {
|
|
735
|
+
return { Tag(node) {
|
|
736
|
+
if (node.name !== "svg") return;
|
|
737
|
+
const viewBoxAttr = toArray(node.attributes).find((attr) => attr.key.value === "viewBox");
|
|
738
|
+
if (!viewBoxAttr) {
|
|
739
|
+
context.report({
|
|
740
|
+
node,
|
|
741
|
+
messageId: "missing"
|
|
742
|
+
});
|
|
743
|
+
return;
|
|
744
|
+
}
|
|
745
|
+
if (!isNonEmptyString((viewBoxAttr.value?.value ?? "").trim())) context.report({
|
|
746
|
+
node: viewBoxAttr.value ?? viewBoxAttr.key,
|
|
747
|
+
messageId: "missing"
|
|
748
|
+
});
|
|
749
|
+
} };
|
|
750
|
+
}
|
|
751
|
+
});
|
|
752
|
+
|
|
609
753
|
//#endregion
|
|
610
754
|
//#region src/rules/index.ts
|
|
611
755
|
const rules = {
|
|
@@ -614,9 +758,14 @@ const rules = {
|
|
|
614
758
|
"no-elements": no_elements_default,
|
|
615
759
|
"no-empty-container": no_empty_container_default,
|
|
616
760
|
"no-empty-desc": no_empty_desc_default,
|
|
761
|
+
"no-empty-groups": no_empty_groups_default,
|
|
617
762
|
"no-empty-text": no_empty_text_default,
|
|
618
763
|
"no-empty-title": no_empty_title_default,
|
|
619
|
-
"no-
|
|
764
|
+
"no-event-handlers": no_event_handlers_default,
|
|
765
|
+
"no-inline-styles": no_inline_styles_default,
|
|
766
|
+
"no-invalid-role": no_invalid_role_default,
|
|
767
|
+
"no-script-tags": no_script_tags_default,
|
|
768
|
+
"require-viewbox": require_viewbox_default
|
|
620
769
|
};
|
|
621
770
|
|
|
622
771
|
//#endregion
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-svg",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.5",
|
|
5
5
|
"description": "Rules for consistent, readable and valid SVG files.",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"eslint",
|
|
@@ -34,27 +34,27 @@
|
|
|
34
34
|
"eslint": "^9.5.0"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@ntnyq/utils": "^0.
|
|
37
|
+
"@ntnyq/utils": "^0.11.0",
|
|
38
38
|
"@types/json-schema": "^7.0.15",
|
|
39
|
-
"svg-eslint-parser": "^0.0.
|
|
39
|
+
"svg-eslint-parser": "^0.0.7",
|
|
40
40
|
"uncase": "^0.2.0"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
|
-
"@ntnyq/eslint-config": "^
|
|
43
|
+
"@ntnyq/eslint-config": "^6.0.0-beta.2",
|
|
44
44
|
"@ntnyq/prettier-config": "^3.0.1",
|
|
45
|
-
"@types/node": "^25.0.
|
|
46
|
-
"bumpp": "^10.
|
|
45
|
+
"@types/node": "^25.0.10",
|
|
46
|
+
"bumpp": "^10.4.0",
|
|
47
47
|
"eslint": "^9.39.2",
|
|
48
|
-
"eslint-plugin-eslint-plugin": "^7.
|
|
48
|
+
"eslint-plugin-eslint-plugin": "^7.3.0",
|
|
49
49
|
"eslint-vitest-rule-tester": "^3.0.1",
|
|
50
50
|
"husky": "^9.1.7",
|
|
51
51
|
"nano-staged": "^0.9.0",
|
|
52
52
|
"npm-run-all2": "^8.0.4",
|
|
53
|
-
"prettier": "^3.
|
|
53
|
+
"prettier": "^3.8.1",
|
|
54
54
|
"tinyglobby": "^0.2.15",
|
|
55
|
-
"tsdown": "^0.
|
|
55
|
+
"tsdown": "^0.20.0-beta.4",
|
|
56
56
|
"typescript": "^5.9.3",
|
|
57
|
-
"vitest": "^4.0.
|
|
57
|
+
"vitest": "^4.0.17"
|
|
58
58
|
},
|
|
59
59
|
"engines": {
|
|
60
60
|
"node": "^20.19.0 || ^22.13.0 || >=24"
|