eslint-plugin-svg 0.0.5 → 0.1.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.
Files changed (4) hide show
  1. package/README.md +31 -17
  2. package/dist/index.d.ts +44 -214
  3. package/dist/index.js +1069 -334
  4. package/package.json +17 -17
package/README.md CHANGED
@@ -35,6 +35,9 @@ import pluginSVG from 'eslint-plugin-svg'
35
35
  export default defineConfig([
36
36
  // Other configs...
37
37
  ...pluginSVG.configs.recommended,
38
+ // Optional extra layers
39
+ ...pluginSVG.configs.security,
40
+ ...pluginSVG.configs.a11y,
38
41
  ])
39
42
  ```
40
43
 
@@ -42,26 +45,37 @@ export default defineConfig([
42
45
 
43
46
  ## Rules
44
47
 
45
- 💼 Configurations enabled in.\
46
- Set in the `recommended` preset.\
48
+ 📦 Config presets enabled in.\
49
+ ✅ `recommended` preset.\
50
+ 🔒 `strict` preset.\
51
+ 🛡️ `security` preset.\
52
+ ♿ `a11y` preset.\
47
53
  🔧 Automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/user-guide/command-line-interface#--fix).\
48
54
  💡 Manually fixable by [editor suggestions](https://eslint.org/docs/developer-guide/working-with-rules#providing-suggestions).
49
55
 
50
- | Name | Description | 💼 | 🔧 | 💡 |
51
- | :--------------------------------------------------------------------------------- | :--------------------------------------- | :-: | :-: | :-: |
52
- | [no-empty-title](https://eslint-plugin-svg.ntnyq.com/rules/no-empty-title) | Disallow empty title element | ✅ | | |
53
- | [no-empty-desc](https://eslint-plugin-svg.ntnyq.com/rules/no-empty-desc) | Disallow empty desc element | ✅ | | |
54
- | [no-empty-text](https://eslint-plugin-svg.ntnyq.com/rules/no-empty-text) | Disallow empty text element | ✅ | | |
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 | ✅ | | |
61
- | [no-deprecated](https://eslint-plugin-svg.ntnyq.com/rules/no-deprecated) | Disallow deprecated elements | ✅ | | |
62
- | [no-elements](https://eslint-plugin-svg.ntnyq.com/rules/no-elements) | Disallow elements by name | | | |
63
- | [no-doctype](https://eslint-plugin-svg.ntnyq.com/rules/no-doctype) | Disallow doctype | ✅ | 🔧 | |
64
- | [no-invalid-role](https://eslint-plugin-svg.ntnyq.com/rules/no-invalid-role) | Disallow invalid value of role attribute | ✅ | | |
56
+ | Name | Description | | 🔒 | 🛡️ | ♿ | 🔧 | 💡 |
57
+ | :------------------------------------------------------------------------------------------- | :---------------------------------------- | :-: | :-: | :-: | :-: | :-: | :-: |
58
+ | [no-empty-title](https://eslint-plugin-svg.ntnyq.com/rules/no-empty-title) | Disallow empty title element | ✅ | ✅ | | ✅ | | |
59
+ | [no-empty-desc](https://eslint-plugin-svg.ntnyq.com/rules/no-empty-desc) | Disallow empty desc element | ✅ | ✅ | | ✅ | | |
60
+ | [no-empty-text](https://eslint-plugin-svg.ntnyq.com/rules/no-empty-text) | Disallow empty text element | ✅ | ✅ | | ✅ | | |
61
+ | [no-empty-container](https://eslint-plugin-svg.ntnyq.com/rules/no-empty-container) | Disallow empty container element | | ✅ | | | | |
62
+ | [no-empty-groups](https://eslint-plugin-svg.ntnyq.com/rules/no-empty-groups) | Disallow empty g element | | ✅ | | | | |
63
+ | [no-base64-data-url](https://eslint-plugin-svg.ntnyq.com/rules/no-base64-data-url) | Disallow base64 data URLs in attributes | | | ✅ | | | |
64
+ | [no-inline-styles](https://eslint-plugin-svg.ntnyq.com/rules/no-inline-styles) | Disallow inline style attribute | | ✅ | | | | |
65
+ | [no-event-handlers](https://eslint-plugin-svg.ntnyq.com/rules/no-event-handlers) | Disallow inline event handlers | | ✅ | ✅ | | | |
66
+ | [no-script-tags](https://eslint-plugin-svg.ntnyq.com/rules/no-script-tags) | Disallow script elements | ✅ | | ✅ | | | |
67
+ | [require-viewbox](https://eslint-plugin-svg.ntnyq.com/rules/require-viewbox) | Require viewBox on svg elements | ✅ | ✅ | | | | |
68
+ | [no-deprecated](https://eslint-plugin-svg.ntnyq.com/rules/no-deprecated) | Disallow deprecated elements | ✅ | | | | | |
69
+ | [no-doctype](https://eslint-plugin-svg.ntnyq.com/rules/no-doctype) | Disallow doctype | ✅ | | | | ✅ | |
70
+ | [no-duplicate-ids](https://eslint-plugin-svg.ntnyq.com/rules/no-duplicate-ids) | Disallow duplicate id attributes | | ✅ | | | | |
71
+ | [no-elements](https://eslint-plugin-svg.ntnyq.com/rules/no-elements) | Disallow elements by name | | | | | | |
72
+ | [no-comments](https://eslint-plugin-svg.ntnyq.com/rules/no-comments) | Disallow comments in SVG files | | | | | | |
73
+ | [no-invalid-role](https://eslint-plugin-svg.ntnyq.com/rules/no-invalid-role) | Disallow invalid value of role attribute | ✅ | ✅ | | ✅ | | |
74
+ | [no-discouraged-role](https://eslint-plugin-svg.ntnyq.com/rules/no-discouraged-role) | Disallow discouraged role value in SVG | | | | ✅ | | |
75
+ | [no-unsafe-href](https://eslint-plugin-svg.ntnyq.com/rules/no-unsafe-href) | Disallow unsafe href and xlink:href URLs | | | ✅ | | | |
76
+ | [require-accessible-name](https://eslint-plugin-svg.ntnyq.com/rules/require-accessible-name) | Require an accessible name for key SVGs | | | | ✅ | | |
77
+ | [no-unknown-elements](https://eslint-plugin-svg.ntnyq.com/rules/no-unknown-elements) | Disallow non-standard SVG elements | ✅ | ✅ | | | | |
78
+ | [prefer-current-color](https://eslint-plugin-svg.ntnyq.com/rules/prefer-current-color) | Prefer currentColor over hardcoded colors | | | | | | |
65
79
 
66
80
  ## License
67
81
 
package/dist/index.d.ts CHANGED
@@ -1,231 +1,49 @@
1
- import { AST } from "svg-eslint-parser";
2
- import { Linter, Rule } from "eslint";
3
- import { JSONSchema4 } from "json-schema";
1
+ import * as _$eslint from "eslint";
2
+ import { Linter } from "eslint";
4
3
 
5
- //#region src/types/sourceCode.d.ts
6
- interface SourceCode {
7
- ast: AST.Program;
8
- hasBOM: boolean;
9
- lines: string[];
10
- text: string;
11
- commentsExistBetween(left: SVGNodeOrToken, right: SVGNodeOrToken): boolean;
12
- getAllComments(): AST.CommentNode[];
13
- getCommentsAfter(nodeOrToken: SVGNodeOrToken): AST.CommentNode[];
14
- getCommentsBefore(nodeOrToken: SVGNodeOrToken): AST.CommentNode[];
15
- getCommentsInside(node: AST.AnyNode): AST.CommentNode[];
16
- getFirstToken(node: AST.AnyNode): AST.AnyToken;
17
- getIndexFromLoc(loc: AST.Position): number;
18
- getLastToken(node: AST.AnyNode): AST.AnyToken;
19
- getLastTokens(node: AST.AnyNode, options?: CursorWithCountOptions): SVGToken[];
20
- getLines(): string[];
21
- getLocFromIndex(index: number): AST.Position;
22
- getNodeByRangeIndex(index: number): AST.AnyNode | null;
23
- getTokenAfter(node: SVGNodeOrToken): AST.AnyToken | null;
24
- getTokenBefore(node: SVGNodeOrToken): AST.AnyToken | null;
25
- isSpaceBetweenTokens(first: SVGToken, second: SVGToken): boolean;
26
- visitorKeys: {
27
- [nodeType: string]: string[];
28
- };
29
- parserServices?: {
30
- isSVG?: true;
31
- parseError?: any;
32
- };
33
- getComments(node: SVGNodeOrToken): {
34
- leading: AST.CommentNode[];
35
- trailing: AST.CommentNode[];
36
- };
37
- getFirstToken(node: AST.AnyNode, options?: CursorWithSkipOptions): SVGToken | null;
38
- getFirstTokenBetween(left: SVGNodeOrToken, right: SVGNodeOrToken, options?: CursorWithSkipOptions): SVGToken | null;
39
- getFirstTokens(node: AST.AnyNode, options?: CursorWithCountOptions): SVGToken[];
40
- getFirstTokensBetween(left: SVGNodeOrToken, right: SVGNodeOrToken, options?: CursorWithCountOptions): SVGToken[];
41
- getLastToken(node: AST.AnyNode, options?: CursorWithSkipOptions): SVGToken | null;
42
- getLastTokenBetween(left: SVGNodeOrToken, right: SVGNodeOrToken, options?: CursorWithSkipOptions): SVGToken | null;
43
- getLastTokensBetween(left: SVGNodeOrToken, right: SVGNodeOrToken, options?: CursorWithCountOptions): SVGToken[];
44
- getText(node?: SVGNodeOrToken, beforeCount?: number, afterCount?: number): string;
45
- getTokenAfter(node: SVGNodeOrToken, options?: CursorWithSkipOptions): SVGToken | null;
46
- getTokenBefore(node: SVGNodeOrToken, options?: CursorWithSkipOptions): SVGToken | null;
47
- getTokenByRangeStart(offset: number, options?: {
48
- includeComments?: boolean;
49
- }): SVGToken | null;
50
- getTokens(node: AST.AnyNode, beforeCount?: number, afterCount?: number): SVGToken[];
51
- getTokens(node: AST.AnyNode, options: CursorWithCountOptions | FilterPredicate): SVGToken[];
52
- getTokensAfter(node: SVGNodeOrToken, options?: CursorWithCountOptions): SVGToken[];
53
- getTokensBefore(node: SVGNodeOrToken, options?: CursorWithCountOptions): SVGToken[];
54
- getTokensBetween(left: SVGNodeOrToken, right: SVGNodeOrToken, padding?: number | CursorWithCountOptions | FilterPredicate): SVGToken[];
55
- }
56
- type CursorWithCountOptions = number | FilterPredicate | {
57
- count?: number;
58
- filter?: FilterPredicate;
59
- includeComments?: boolean;
60
- };
61
- type CursorWithSkipOptions = number | FilterPredicate | {
62
- filter?: FilterPredicate;
63
- includeComments?: boolean;
64
- skip?: number;
65
- };
66
- type FilterPredicate = (tokenOrComment: SVGToken) => boolean;
67
- type SVGNodeOrToken = AST.AnyNode | AST.AnyToken;
68
- type SVGToken = AST.AnyToken | AST.CommentNode;
69
- //#endregion
70
- //#region src/types/eslint.d.ts
71
- /**
72
- * Rule fixer
73
- */
74
- type Fix = {
75
- range: AST.Range;
76
- text: string;
77
- };
78
- type ReportDescriptor<TMessageIds extends string> = ReportDescriptorWithSuggestion<TMessageIds> & (ReportDescriptorLocOnly | ReportDescriptorNodeOptionalLoc);
79
- type ReportDescriptorBase<TMessageIds extends string> = {
80
- readonly messageId: TMessageIds;
81
- readonly data?: ReportDescriptorMessageData;
82
- readonly fix?: ReportFixer;
83
- };
84
- type ReportDescriptorLocOnly = {
85
- loc: Readonly<AST.Position> | Readonly<AST.SourceLocation>;
86
- };
87
- type ReportDescriptorMessageData = Readonly<Record<string, unknown>>;
88
- type ReportDescriptorNodeOptionalLoc = {
89
- readonly node: AST.AnyNode;
90
- readonly loc?: Readonly<AST.Position> | Readonly<AST.SourceLocation>;
91
- };
92
- interface ReportDescriptorWithSuggestion<TMessageIds extends string> extends ReportDescriptorBase<TMessageIds> {
93
- readonly suggest?: readonly Rule.SuggestionReportDescriptor[];
94
- }
95
- type ReportFixer = (fixer: RuleFixer) => Fix | Fix[] | IterableIterator<Fix> | null;
96
- interface RuleContext<TMessageIds extends string, TOptions extends readonly unknown[] = []> {
97
- id: string;
98
- options: TOptions;
99
- parserPath: string;
100
- settings: {
101
- svg?: SVGSettings;
102
- [name: string]: any;
103
- };
104
- getFilename(): string;
105
- getSourceCode(): SourceCode;
106
- report(descriptor: ReportDescriptor<TMessageIds>): void;
107
- parserServices?: {
108
- isSVG?: true;
109
- parseError?: any;
110
- };
111
- }
112
- type RuleFixer = {
113
- insertTextAfter(nodeOrToken: AST.AnyNode | AST.AnyToken, text: string): Fix;
114
- insertTextAfterRange(range: AST.Range, text: string): Fix;
115
- insertTextBefore(nodeOrToken: AST.AnyNode | AST.AnyToken, text: string): Fix;
116
- insertTextBeforeRange(range: AST.Range, text: string): Fix;
117
- remove(nodeOrToken: AST.AnyNode | AST.AnyToken): Fix;
118
- removeRange(range: AST.Range): Fix;
119
- replaceText(nodeOrToken: AST.AnyNode | AST.AnyToken, text: string): Fix;
120
- replaceTextRange(range: AST.Range, text: string): Fix;
121
- };
122
- interface RuleListener {
123
- Attribute?: (node: AST.AttributeNode) => void;
124
- 'Attribute:exit'?: (node: AST.AttributeNode) => void;
125
- Comment?: (node: AST.CommentNode) => void;
126
- 'Comment:exit'?: (node: AST.CommentNode) => void;
127
- Doctype?: (node: AST.DoctypeNode) => void;
128
- 'Doctype:exit'?: (node: AST.DoctypeNode) => void;
129
- DoctypeAttribute?: (node: AST.DoctypeAttributeNode) => void;
130
- 'DoctypeAttribute:exit'?: (node: AST.DoctypeAttributeNode) => void;
131
- Document?: (node: AST.DocumentNode) => void;
132
- 'Document:exit'?: (node: AST.DocumentNode) => void;
133
- Program?: (node: AST.Program) => void;
134
- 'Program:exit'?: (node: AST.Program) => void;
135
- Tag?: (node: AST.TagNode) => void;
136
- 'Tag:exit'?: (node: AST.TagNode) => void;
137
- Text?: (node: AST.TextNode) => void;
138
- 'Text:exit'?: (node: AST.TextNode) => void;
139
- [key: string]: ((node: never) => void) | undefined;
140
- }
141
- interface RuleMetaData<TMessageIds extends string, TDocs = unknown, TOptions extends readonly unknown[] = []> {
142
- messages: Record<TMessageIds, string>;
143
- schema: JSONSchema4 | readonly JSONSchema4[];
144
- type: 'layout' | 'problem' | 'suggestion';
145
- defaultOptions?: TOptions;
146
- deprecated?: boolean;
147
- docs?: RuleMetaDataDocs & TDocs;
148
- fixable?: 'code' | 'whitespace';
149
- hasSuggestions?: boolean;
150
- replacedBy?: readonly string[];
151
- }
152
- interface RuleMetaDataDocs {
153
- description: string;
154
- category?: string;
155
- recommended?: boolean;
156
- url?: string;
157
- }
158
- interface RuleModule<TMessageIds extends string, TOptions extends readonly unknown[] = [], TDocs = unknown> {
159
- defaultOptions: TOptions;
160
- meta?: RuleMetaData<TMessageIds, TDocs, TOptions>;
161
- create(context: RuleContext<TMessageIds, TOptions>): RuleListener;
162
- }
163
- type SVGSettings = {
164
- indent?: number;
165
- };
166
- //#endregion
167
- //#region src/rules/no-deprecated.d.ts
168
- type Options$4 = [{
169
- allowElements?: string[];
170
- }];
171
- //#endregion
172
- //#region src/rules/no-elements.d.ts
173
- type Options$3 = [{
174
- elements?: string[];
175
- }];
176
- //#endregion
177
- //#region src/rules/no-empty-container.d.ts
178
- type Options$2 = [{
179
- elements?: string[];
180
- ignores?: string[];
181
- ignoreComments?: boolean;
182
- ignoreWhitespace?: boolean;
183
- }];
184
- //#endregion
185
- //#region src/rules/no-event-handlers.d.ts
186
- type Options$1 = [{
187
- ignores?: string[];
188
- }];
189
- //#endregion
190
- //#region src/rules/no-invalid-role.d.ts
191
- type Options = [{
192
- roles?: string[];
193
- }];
194
- //#endregion
195
4
  //#region src/rules/index.d.ts
196
5
  declare const rules: {
197
- 'no-deprecated': RuleModule<"deprecatedElement", Options$4, unknown>;
198
- 'no-doctype': RuleModule<"invalid", [], unknown>;
199
- 'no-elements': RuleModule<"invalid", Options$3, unknown>;
200
- 'no-empty-container': RuleModule<"invalid", Options$2, unknown>;
201
- 'no-empty-desc': RuleModule<"invalid", [], unknown>;
202
- 'no-empty-groups': RuleModule<"invalid", [], unknown>;
203
- 'no-empty-text': RuleModule<"invalid", [], unknown>;
204
- 'no-empty-title': RuleModule<"invalid", [], unknown>;
205
- 'no-event-handlers': RuleModule<"invalid", Options$1, unknown>;
206
- 'no-inline-styles': RuleModule<"invalid", [], unknown>;
207
- 'no-invalid-role': RuleModule<"invalid", Options, unknown>;
208
- 'no-script-tags': RuleModule<"invalid", [], unknown>;
209
- 'require-viewbox': RuleModule<"missing", [], unknown>;
6
+ 'no-base64-data-url': _$eslint.Rule.RuleModule;
7
+ 'no-comments': _$eslint.Rule.RuleModule;
8
+ 'no-deprecated': _$eslint.Rule.RuleModule;
9
+ 'no-discouraged-role': _$eslint.Rule.RuleModule;
10
+ 'no-doctype': _$eslint.Rule.RuleModule;
11
+ 'no-duplicate-ids': _$eslint.Rule.RuleModule;
12
+ 'no-elements': _$eslint.Rule.RuleModule;
13
+ 'no-empty-container': _$eslint.Rule.RuleModule;
14
+ 'no-empty-desc': _$eslint.Rule.RuleModule;
15
+ 'no-empty-groups': _$eslint.Rule.RuleModule;
16
+ 'no-empty-text': _$eslint.Rule.RuleModule;
17
+ 'no-empty-title': _$eslint.Rule.RuleModule;
18
+ 'no-event-handlers': _$eslint.Rule.RuleModule;
19
+ 'no-inline-styles': _$eslint.Rule.RuleModule;
20
+ 'no-invalid-role': _$eslint.Rule.RuleModule;
21
+ 'no-script-tags': _$eslint.Rule.RuleModule;
22
+ 'no-unknown-elements': _$eslint.Rule.RuleModule;
23
+ 'no-unsafe-href': _$eslint.Rule.RuleModule;
24
+ 'prefer-current-color': _$eslint.Rule.RuleModule;
25
+ 'require-accessible-name': _$eslint.Rule.RuleModule;
26
+ 'require-viewbox': _$eslint.Rule.RuleModule;
210
27
  };
211
28
  //#endregion
212
29
  //#region src/types/plugin.d.ts
213
30
  interface PluginSVG {
31
+ /** rule implementations exposed by the plugin */
214
32
  rules: typeof rules;
33
+ /** named config presets exposed by the plugin */
215
34
  configs: {
216
- recommended: Linter.Config<Linter.RulesRecord>[];
35
+ /** accessibility preset */a11y: Linter.Config<Linter.RulesRecord>[]; /** recommended baseline preset */
36
+ recommended: Linter.Config<Linter.RulesRecord>[]; /** security-focused preset */
37
+ security: Linter.Config<Linter.RulesRecord>[]; /** strict preset with additional stylistic checks */
38
+ strict: Linter.Config<Linter.RulesRecord>[];
217
39
  };
40
+ /** plugin package metadata */
218
41
  meta: {
219
- name: string;
42
+ /** package name */name: string; /** package version */
220
43
  version: string;
221
44
  };
222
45
  }
223
46
  //#endregion
224
- //#region src/dts.d.ts
225
- type RuleDefinitions = typeof rules;
226
- type RuleOptions = { [K in keyof RuleDefinitions]: RuleDefinitions[K]['defaultOptions'] };
227
- type Rules = { [K in keyof RuleOptions]: Linter.RuleEntry<RuleOptions[K]> };
228
- //#endregion
229
47
  //#region src/meta.d.ts
230
48
  declare const meta: {
231
49
  name: string;
@@ -237,6 +55,18 @@ declare const meta: {
237
55
  * recommended config preset
238
56
  */
239
57
  declare const recommended: Linter.Config<Linter.RulesRecord>[];
58
+ /**
59
+ * strict config preset
60
+ */
61
+ declare const strict: Linter.Config<Linter.RulesRecord>[];
62
+ /**
63
+ * security config preset
64
+ */
65
+ declare const security: Linter.Config<Linter.RulesRecord>[];
66
+ /**
67
+ * accessibility config preset
68
+ */
69
+ declare const a11y: Linter.Config<Linter.RulesRecord>[];
240
70
  declare const configs: PluginSVG['configs'];
241
71
  //#endregion
242
72
  //#region src/index.d.ts
@@ -248,4 +78,4 @@ declare const configs: PluginSVG['configs'];
248
78
  */
249
79
  declare const plugin: PluginSVG;
250
80
  //#endregion
251
- export { RuleOptions, Rules, configs, plugin as default, plugin, meta, recommended, rules };
81
+ export { a11y, configs, plugin as default, plugin, meta, recommended, rules, security, strict };