@tb-dev/eslint-config 4.2.0 → 4.3.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/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2023 Andrew Ferreira
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2023 Andrew Ferreira
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/dist/index.cjs CHANGED
@@ -1,28 +1,8 @@
1
- "use strict";
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __copyProps = (to, from, except, desc) => {
9
- if (from && typeof from === "object" || typeof from === "function") {
10
- for (let key of __getOwnPropNames(from))
11
- if (!__hasOwnProp.call(to, key) && key !== except)
12
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
13
- }
14
- return to;
15
- };
16
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
17
- // If the importer is in node compatibility mode or this is not an ESM
18
- // file that has been converted to a CommonJS file using a Babel-
19
- // compatible transform (i.e. "__esModule" has not been set), then set
20
- // "default" to the CommonJS "module.exports" for node compatibility.
21
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
22
- mod
23
- ));
24
- const process = require("node:process");
25
- const globals = require("globals");
1
+ 'use strict';
2
+
3
+ const process = require('node:process');
4
+ const globals = require('globals');
5
+
26
6
  var Glob = /* @__PURE__ */ ((Glob2) => {
27
7
  Glob2["All"] = "**/*.?([cm])[jt]s?(x)";
28
8
  Glob2["Javascript"] = "**/*.?([cm])js?(x)";
@@ -41,13 +21,18 @@ var GlobIgnore = /* @__PURE__ */ ((GlobIgnore2) => {
41
21
  GlobIgnore2["Temp"] = "**/?(.)temp";
42
22
  return GlobIgnore2;
43
23
  })(GlobIgnore || {});
24
+
44
25
  async function interopDefault(promise) {
45
26
  const result = await promise;
46
27
  return result.default ?? result;
47
28
  }
29
+ async function json(path) {
30
+ return interopDefault(import(path));
31
+ }
48
32
  function getIgnores() {
49
33
  return Object.values(GlobIgnore);
50
34
  }
35
+
51
36
  const stylisticRules = {
52
37
  "stylistic/array-bracket-newline": ["error", "consistent"],
53
38
  "stylistic/array-bracket-spacing": ["error", "never"],
@@ -71,7 +56,11 @@ const stylisticRules = {
71
56
  "stylistic/function-call-argument-newline": ["error", "consistent"],
72
57
  "stylistic/function-call-spacing": ["error", "never"],
73
58
  "stylistic/function-paren-newline": ["error", "never"],
74
- "stylistic/generator-star-spacing": ["error", { before: false, after: true }],
59
+ "stylistic/generator-star-spacing": ["error", {
60
+ before: false,
61
+ after: true,
62
+ method: { before: true, after: false }
63
+ }],
75
64
  "stylistic/implicit-arrow-linebreak": ["error", "beside"],
76
65
  "stylistic/indent": ["error", 2, { flatTernaryExpressions: true }],
77
66
  "stylistic/indent-binary-ops": ["error", 2],
@@ -141,7 +130,13 @@ const stylisticRules = {
141
130
  "stylistic/switch-colon-spacing": ["error", { after: true, before: false }],
142
131
  "stylistic/template-curly-spacing": ["error", "never"],
143
132
  "stylistic/template-tag-spacing": ["error", "never"],
144
- "stylistic/type-annotation-spacing": ["error", { after: true, before: false }],
133
+ "stylistic/type-annotation-spacing": ["error", {
134
+ before: false,
135
+ after: true,
136
+ overrides: {
137
+ arrow: { before: true, after: true }
138
+ }
139
+ }],
145
140
  "stylistic/type-generic-spacing": "error",
146
141
  "stylistic/type-named-tuple-spacing": "error",
147
142
  "stylistic/yield-star-spacing": ["error", "after"]
@@ -149,12 +144,12 @@ const stylisticRules = {
149
144
  async function stylistic(options) {
150
145
  const { overrides, stylistic: enabled } = options;
151
146
  if (!enabled) return {};
152
- const plugin = await interopDefault(import("@stylistic/eslint-plugin"));
147
+ const plugin = await interopDefault(import('@stylistic/eslint-plugin'));
153
148
  const files = [Glob.All];
154
149
  if (options.vue) files.push(Glob.Vue);
155
150
  const rules = {
156
151
  ...stylisticRules,
157
- ...overrides == null ? void 0 : overrides.stylistic
152
+ ...overrides?.stylistic
158
153
  };
159
154
  return {
160
155
  files,
@@ -162,15 +157,17 @@ async function stylistic(options) {
162
157
  rules
163
158
  };
164
159
  }
160
+
165
161
  async function vue(options) {
166
162
  const { overrides, vue: enabled } = options;
167
163
  if (!enabled) return [];
168
164
  const [vuePlugin, vueParser, tsParser] = await Promise.all([
169
165
  // @ts-expect-error no types
170
- interopDefault(import("eslint-plugin-vue")),
171
- interopDefault(import("vue-eslint-parser")),
172
- interopDefault(import("@typescript-eslint/parser"))
166
+ interopDefault(import('eslint-plugin-vue')),
167
+ interopDefault(import('vue-eslint-parser')),
168
+ interopDefault(import('@typescript-eslint/parser'))
173
169
  ]);
170
+ const INLINE_ELEMENTS = await json("eslint-plugin-vue/lib/utils/inline-non-void-elements.json");
174
171
  const rules = {
175
172
  ...vuePlugin.configs.base.rules,
176
173
  "vue/attribute-hyphenation": ["error", "always"],
@@ -201,41 +198,17 @@ async function vue(options) {
201
198
  }],
202
199
  "vue/define-props-declaration": ["error", "type-based"],
203
200
  "vue/enforce-style-attribute": ["error", { allow: ["scoped"] }],
204
- "vue/first-attribute-linebreak": "off",
205
201
  "vue/html-button-has-type": ["error", {
206
202
  button: true,
207
203
  submit: true,
208
204
  reset: true
209
205
  }],
210
- "vue/html-closing-bracket-newline": ["error", {
211
- singleline: "never",
212
- multiline: "always",
213
- selfClosingTag: {
214
- singleline: "never",
215
- multiline: "always"
216
- }
217
- }],
218
- "vue/html-closing-bracket-spacing": ["error", {
219
- startTag: "never",
220
- endTag: "never",
221
- selfClosingTag: "always"
222
- }],
223
- "vue/html-self-closing": ["error", {
224
- html: {
225
- void: "never",
226
- normal: "always",
227
- component: "always"
228
- },
229
- svg: "always",
230
- math: "always"
231
- }],
232
206
  "vue/match-component-file-name": ["off", {
233
207
  extensions: ["tsx", "vue"],
234
208
  shouldMatchCase: false
235
209
  }],
236
210
  "vue/match-component-import-name": "error",
237
211
  "vue/multi-word-component-names": "off",
238
- "vue/mustache-interpolation-spacing": ["error", "always"],
239
212
  "vue/no-arrow-functions-in-watch": "off",
240
213
  "vue/no-async-in-computed-properties": "error",
241
214
  "vue/no-boolean-default": ["error", "no-default"],
@@ -250,7 +223,6 @@ async function vue(options) {
250
223
  "vue/no-expose-after-await": "error",
251
224
  "vue/no-lifecycle-after-await": "error",
252
225
  "vue/no-lone-template": "error",
253
- "vue/no-multi-spaces": "error",
254
226
  "vue/no-multiple-objects-in-class": "error",
255
227
  "vue/no-mutating-props": "error",
256
228
  "vue/no-parsing-error": "error",
@@ -264,7 +236,6 @@ async function vue(options) {
264
236
  "vue/no-setup-props-reactivity-loss": "error",
265
237
  "vue/no-shared-component-data": "error",
266
238
  "vue/no-side-effects-in-computed-properties": "error",
267
- "vue/no-spaces-around-equal-signs-in-attribute": "error",
268
239
  "vue/no-static-inline-styles": ["error", { allowBinding: false }],
269
240
  "vue/no-template-key": "error",
270
241
  "vue/no-template-shadow": "error",
@@ -350,9 +321,63 @@ async function vue(options) {
350
321
  "vue/valid-v-show": "error",
351
322
  "vue/valid-v-slot": "error",
352
323
  "vue/valid-v-text": "error",
353
- ...overrides == null ? void 0 : overrides.vue
324
+ ...overrides?.vue
354
325
  };
355
326
  if (options.stylistic) {
327
+ Object.assign(rules, {
328
+ "vue/first-attribute-linebreak": ["error", {
329
+ singleline: "beside",
330
+ multiline: "below"
331
+ }],
332
+ "vue/html-closing-bracket-newline": ["error", {
333
+ singleline: "never",
334
+ multiline: "always",
335
+ selfClosingTag: {
336
+ singleline: "never",
337
+ multiline: "always"
338
+ }
339
+ }],
340
+ "vue/html-closing-bracket-spacing": ["error", {
341
+ startTag: "never",
342
+ endTag: "never",
343
+ selfClosingTag: "always"
344
+ }],
345
+ "vue/html-indent": ["error", 2, {
346
+ attribute: 1,
347
+ baseIndent: 1,
348
+ closeBracket: 0,
349
+ alignAttributesVertically: true,
350
+ ignores: []
351
+ }],
352
+ "vue/html-quotes": ["error", "double", { avoidEscape: false }],
353
+ "vue/html-self-closing": ["error", {
354
+ html: {
355
+ void: "never",
356
+ normal: "always",
357
+ component: "always"
358
+ },
359
+ svg: "always",
360
+ math: "always"
361
+ }],
362
+ "vue/max-attributes-per-line": ["error", {
363
+ singleline: 1,
364
+ multiline: 1
365
+ }],
366
+ "vue/multiline-html-element-content-newline": ["error", {
367
+ ignoreWhenEmpty: true,
368
+ ignores: ["pre", "textarea", ...INLINE_ELEMENTS],
369
+ allowEmptyLines: false
370
+ }],
371
+ "vue/mustache-interpolation-spacing": ["error", "always"],
372
+ "vue/no-multi-spaces": ["error", { ignoreProperties: false }],
373
+ "vue/no-spaces-around-equal-signs-in-attribute": "error",
374
+ "vue/singleline-html-element-content-newline": ["off", {
375
+ ignoreWhenNoAttributes: true,
376
+ ignoreWhenEmpty: true,
377
+ ignores: ["pre", "textarea", ...INLINE_ELEMENTS],
378
+ externalIgnores: []
379
+ }]
380
+ });
356
381
  const vueStylistic = [
357
382
  "vue/array-bracket-newline",
358
383
  "vue/array-bracket-spacing",
@@ -403,10 +428,11 @@ async function vue(options) {
403
428
  }
404
429
  ];
405
430
  }
431
+
406
432
  async function vitest(options) {
407
433
  const { overrides, vitest: enabled } = options;
408
434
  if (!enabled) return {};
409
- const plugin = await interopDefault(import("eslint-plugin-vitest"));
435
+ const plugin = await interopDefault(import('eslint-plugin-vitest'));
410
436
  return {
411
437
  plugins: { vitest: plugin },
412
438
  files: [Glob.Vitest],
@@ -442,14 +468,15 @@ async function vitest(options) {
442
468
  "vitest/require-top-level-describe": ["error", { maxNumberOfTopLevelDescribes: 10 }],
443
469
  "vitest/valid-describe-callback": "error",
444
470
  "vitest/valid-expect": "error",
445
- ...overrides == null ? void 0 : overrides.vitest
471
+ ...overrides?.vitest
446
472
  }
447
473
  };
448
474
  }
475
+
449
476
  async function unicorn(options) {
450
477
  const { overrides, unicorn: enabled = true } = options;
451
478
  if (!enabled) return {};
452
- const plugin = await interopDefault(import("eslint-plugin-unicorn"));
479
+ const plugin = await interopDefault(import('eslint-plugin-unicorn'));
453
480
  return {
454
481
  plugins: { unicorn: plugin },
455
482
  rules: {
@@ -492,10 +519,11 @@ async function unicorn(options) {
492
519
  "unicorn/prefer-structured-clone": "error",
493
520
  "unicorn/prefer-type-error": "error",
494
521
  "unicorn/relative-url-style": ["error", "never"],
495
- ...overrides == null ? void 0 : overrides.unicorn
522
+ ...overrides?.unicorn
496
523
  }
497
524
  };
498
525
  }
526
+
499
527
  function javascript(options) {
500
528
  const { overrides } = options;
501
529
  const files = [Glob.All];
@@ -635,15 +663,16 @@ function javascript(options) {
635
663
  "use-isnan": "error",
636
664
  "valid-typeof": "error",
637
665
  yoda: ["error", "never"],
638
- ...overrides == null ? void 0 : overrides.javascript
666
+ ...overrides?.javascript
639
667
  }
640
668
  };
641
669
  }
670
+
642
671
  async function typescript(options) {
643
672
  const { project, overrides } = options;
644
673
  const [tsParser, tsPlugin] = await Promise.all([
645
- interopDefault(import("@typescript-eslint/parser")),
646
- interopDefault(import("@typescript-eslint/eslint-plugin"))
674
+ interopDefault(import('@typescript-eslint/parser')),
675
+ interopDefault(import('@typescript-eslint/eslint-plugin'))
647
676
  ]);
648
677
  const files = [Glob.Typescript];
649
678
  if (options.vue) files.push(Glob.Vue);
@@ -847,7 +876,7 @@ async function typescript(options) {
847
876
  "@typescript-eslint/unbound-method": "error",
848
877
  "@typescript-eslint/unified-signatures": ["error", { ignoreDifferentlyNamedParameters: true }],
849
878
  "@typescript-eslint/use-unknown-in-catch-callback-variable": "error",
850
- ...overrides == null ? void 0 : overrides.typescript
879
+ ...overrides?.typescript
851
880
  };
852
881
  return {
853
882
  files,
@@ -865,10 +894,11 @@ async function typescript(options) {
865
894
  rules
866
895
  };
867
896
  }
897
+
868
898
  async function perfectionist(options) {
869
899
  const { overrides, perfectionist: enabled = true } = options;
870
900
  if (!enabled) return {};
871
- const plugin = await interopDefault(import("eslint-plugin-perfectionist"));
901
+ const plugin = await interopDefault(import('eslint-plugin-perfectionist'));
872
902
  return {
873
903
  plugins: { perfectionist: plugin },
874
904
  rules: {
@@ -927,10 +957,11 @@ async function perfectionist(options) {
927
957
  order: "asc",
928
958
  ignoreCase: true
929
959
  }],
930
- ...overrides == null ? void 0 : overrides.perfectionist
960
+ ...overrides?.perfectionist
931
961
  }
932
962
  };
933
963
  }
964
+
934
965
  async function defineConfig(options) {
935
966
  const ignores = {
936
967
  ignores: [...getIgnores(), ...options.ignores ?? []]
@@ -947,4 +978,5 @@ async function defineConfig(options) {
947
978
  ]);
948
979
  return objects;
949
980
  }
981
+
950
982
  module.exports = defineConfig;
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
- import process from "node:process";
2
- import globals from "globals";
1
+ import process from 'node:process';
2
+ import globals from 'globals';
3
+
3
4
  var Glob = /* @__PURE__ */ ((Glob2) => {
4
5
  Glob2["All"] = "**/*.?([cm])[jt]s?(x)";
5
6
  Glob2["Javascript"] = "**/*.?([cm])js?(x)";
@@ -18,13 +19,18 @@ var GlobIgnore = /* @__PURE__ */ ((GlobIgnore2) => {
18
19
  GlobIgnore2["Temp"] = "**/?(.)temp";
19
20
  return GlobIgnore2;
20
21
  })(GlobIgnore || {});
22
+
21
23
  async function interopDefault(promise) {
22
24
  const result = await promise;
23
25
  return result.default ?? result;
24
26
  }
27
+ async function json(path) {
28
+ return interopDefault(import(path, { with: { type: "json" } }));
29
+ }
25
30
  function getIgnores() {
26
31
  return Object.values(GlobIgnore);
27
32
  }
33
+
28
34
  const stylisticRules = {
29
35
  "stylistic/array-bracket-newline": ["error", "consistent"],
30
36
  "stylistic/array-bracket-spacing": ["error", "never"],
@@ -48,7 +54,11 @@ const stylisticRules = {
48
54
  "stylistic/function-call-argument-newline": ["error", "consistent"],
49
55
  "stylistic/function-call-spacing": ["error", "never"],
50
56
  "stylistic/function-paren-newline": ["error", "never"],
51
- "stylistic/generator-star-spacing": ["error", { before: false, after: true }],
57
+ "stylistic/generator-star-spacing": ["error", {
58
+ before: false,
59
+ after: true,
60
+ method: { before: true, after: false }
61
+ }],
52
62
  "stylistic/implicit-arrow-linebreak": ["error", "beside"],
53
63
  "stylistic/indent": ["error", 2, { flatTernaryExpressions: true }],
54
64
  "stylistic/indent-binary-ops": ["error", 2],
@@ -118,7 +128,13 @@ const stylisticRules = {
118
128
  "stylistic/switch-colon-spacing": ["error", { after: true, before: false }],
119
129
  "stylistic/template-curly-spacing": ["error", "never"],
120
130
  "stylistic/template-tag-spacing": ["error", "never"],
121
- "stylistic/type-annotation-spacing": ["error", { after: true, before: false }],
131
+ "stylistic/type-annotation-spacing": ["error", {
132
+ before: false,
133
+ after: true,
134
+ overrides: {
135
+ arrow: { before: true, after: true }
136
+ }
137
+ }],
122
138
  "stylistic/type-generic-spacing": "error",
123
139
  "stylistic/type-named-tuple-spacing": "error",
124
140
  "stylistic/yield-star-spacing": ["error", "after"]
@@ -126,12 +142,12 @@ const stylisticRules = {
126
142
  async function stylistic(options) {
127
143
  const { overrides, stylistic: enabled } = options;
128
144
  if (!enabled) return {};
129
- const plugin = await interopDefault(import("@stylistic/eslint-plugin"));
145
+ const plugin = await interopDefault(import('@stylistic/eslint-plugin'));
130
146
  const files = [Glob.All];
131
147
  if (options.vue) files.push(Glob.Vue);
132
148
  const rules = {
133
149
  ...stylisticRules,
134
- ...overrides == null ? void 0 : overrides.stylistic
150
+ ...overrides?.stylistic
135
151
  };
136
152
  return {
137
153
  files,
@@ -139,15 +155,17 @@ async function stylistic(options) {
139
155
  rules
140
156
  };
141
157
  }
158
+
142
159
  async function vue(options) {
143
160
  const { overrides, vue: enabled } = options;
144
161
  if (!enabled) return [];
145
162
  const [vuePlugin, vueParser, tsParser] = await Promise.all([
146
163
  // @ts-expect-error no types
147
- interopDefault(import("eslint-plugin-vue")),
148
- interopDefault(import("vue-eslint-parser")),
149
- interopDefault(import("@typescript-eslint/parser"))
164
+ interopDefault(import('eslint-plugin-vue')),
165
+ interopDefault(import('vue-eslint-parser')),
166
+ interopDefault(import('@typescript-eslint/parser'))
150
167
  ]);
168
+ const INLINE_ELEMENTS = await json("eslint-plugin-vue/lib/utils/inline-non-void-elements.json");
151
169
  const rules = {
152
170
  ...vuePlugin.configs.base.rules,
153
171
  "vue/attribute-hyphenation": ["error", "always"],
@@ -178,41 +196,17 @@ async function vue(options) {
178
196
  }],
179
197
  "vue/define-props-declaration": ["error", "type-based"],
180
198
  "vue/enforce-style-attribute": ["error", { allow: ["scoped"] }],
181
- "vue/first-attribute-linebreak": "off",
182
199
  "vue/html-button-has-type": ["error", {
183
200
  button: true,
184
201
  submit: true,
185
202
  reset: true
186
203
  }],
187
- "vue/html-closing-bracket-newline": ["error", {
188
- singleline: "never",
189
- multiline: "always",
190
- selfClosingTag: {
191
- singleline: "never",
192
- multiline: "always"
193
- }
194
- }],
195
- "vue/html-closing-bracket-spacing": ["error", {
196
- startTag: "never",
197
- endTag: "never",
198
- selfClosingTag: "always"
199
- }],
200
- "vue/html-self-closing": ["error", {
201
- html: {
202
- void: "never",
203
- normal: "always",
204
- component: "always"
205
- },
206
- svg: "always",
207
- math: "always"
208
- }],
209
204
  "vue/match-component-file-name": ["off", {
210
205
  extensions: ["tsx", "vue"],
211
206
  shouldMatchCase: false
212
207
  }],
213
208
  "vue/match-component-import-name": "error",
214
209
  "vue/multi-word-component-names": "off",
215
- "vue/mustache-interpolation-spacing": ["error", "always"],
216
210
  "vue/no-arrow-functions-in-watch": "off",
217
211
  "vue/no-async-in-computed-properties": "error",
218
212
  "vue/no-boolean-default": ["error", "no-default"],
@@ -227,7 +221,6 @@ async function vue(options) {
227
221
  "vue/no-expose-after-await": "error",
228
222
  "vue/no-lifecycle-after-await": "error",
229
223
  "vue/no-lone-template": "error",
230
- "vue/no-multi-spaces": "error",
231
224
  "vue/no-multiple-objects-in-class": "error",
232
225
  "vue/no-mutating-props": "error",
233
226
  "vue/no-parsing-error": "error",
@@ -241,7 +234,6 @@ async function vue(options) {
241
234
  "vue/no-setup-props-reactivity-loss": "error",
242
235
  "vue/no-shared-component-data": "error",
243
236
  "vue/no-side-effects-in-computed-properties": "error",
244
- "vue/no-spaces-around-equal-signs-in-attribute": "error",
245
237
  "vue/no-static-inline-styles": ["error", { allowBinding: false }],
246
238
  "vue/no-template-key": "error",
247
239
  "vue/no-template-shadow": "error",
@@ -327,9 +319,63 @@ async function vue(options) {
327
319
  "vue/valid-v-show": "error",
328
320
  "vue/valid-v-slot": "error",
329
321
  "vue/valid-v-text": "error",
330
- ...overrides == null ? void 0 : overrides.vue
322
+ ...overrides?.vue
331
323
  };
332
324
  if (options.stylistic) {
325
+ Object.assign(rules, {
326
+ "vue/first-attribute-linebreak": ["error", {
327
+ singleline: "beside",
328
+ multiline: "below"
329
+ }],
330
+ "vue/html-closing-bracket-newline": ["error", {
331
+ singleline: "never",
332
+ multiline: "always",
333
+ selfClosingTag: {
334
+ singleline: "never",
335
+ multiline: "always"
336
+ }
337
+ }],
338
+ "vue/html-closing-bracket-spacing": ["error", {
339
+ startTag: "never",
340
+ endTag: "never",
341
+ selfClosingTag: "always"
342
+ }],
343
+ "vue/html-indent": ["error", 2, {
344
+ attribute: 1,
345
+ baseIndent: 1,
346
+ closeBracket: 0,
347
+ alignAttributesVertically: true,
348
+ ignores: []
349
+ }],
350
+ "vue/html-quotes": ["error", "double", { avoidEscape: false }],
351
+ "vue/html-self-closing": ["error", {
352
+ html: {
353
+ void: "never",
354
+ normal: "always",
355
+ component: "always"
356
+ },
357
+ svg: "always",
358
+ math: "always"
359
+ }],
360
+ "vue/max-attributes-per-line": ["error", {
361
+ singleline: 1,
362
+ multiline: 1
363
+ }],
364
+ "vue/multiline-html-element-content-newline": ["error", {
365
+ ignoreWhenEmpty: true,
366
+ ignores: ["pre", "textarea", ...INLINE_ELEMENTS],
367
+ allowEmptyLines: false
368
+ }],
369
+ "vue/mustache-interpolation-spacing": ["error", "always"],
370
+ "vue/no-multi-spaces": ["error", { ignoreProperties: false }],
371
+ "vue/no-spaces-around-equal-signs-in-attribute": "error",
372
+ "vue/singleline-html-element-content-newline": ["off", {
373
+ ignoreWhenNoAttributes: true,
374
+ ignoreWhenEmpty: true,
375
+ ignores: ["pre", "textarea", ...INLINE_ELEMENTS],
376
+ externalIgnores: []
377
+ }]
378
+ });
333
379
  const vueStylistic = [
334
380
  "vue/array-bracket-newline",
335
381
  "vue/array-bracket-spacing",
@@ -380,10 +426,11 @@ async function vue(options) {
380
426
  }
381
427
  ];
382
428
  }
429
+
383
430
  async function vitest(options) {
384
431
  const { overrides, vitest: enabled } = options;
385
432
  if (!enabled) return {};
386
- const plugin = await interopDefault(import("eslint-plugin-vitest"));
433
+ const plugin = await interopDefault(import('eslint-plugin-vitest'));
387
434
  return {
388
435
  plugins: { vitest: plugin },
389
436
  files: [Glob.Vitest],
@@ -419,14 +466,15 @@ async function vitest(options) {
419
466
  "vitest/require-top-level-describe": ["error", { maxNumberOfTopLevelDescribes: 10 }],
420
467
  "vitest/valid-describe-callback": "error",
421
468
  "vitest/valid-expect": "error",
422
- ...overrides == null ? void 0 : overrides.vitest
469
+ ...overrides?.vitest
423
470
  }
424
471
  };
425
472
  }
473
+
426
474
  async function unicorn(options) {
427
475
  const { overrides, unicorn: enabled = true } = options;
428
476
  if (!enabled) return {};
429
- const plugin = await interopDefault(import("eslint-plugin-unicorn"));
477
+ const plugin = await interopDefault(import('eslint-plugin-unicorn'));
430
478
  return {
431
479
  plugins: { unicorn: plugin },
432
480
  rules: {
@@ -469,10 +517,11 @@ async function unicorn(options) {
469
517
  "unicorn/prefer-structured-clone": "error",
470
518
  "unicorn/prefer-type-error": "error",
471
519
  "unicorn/relative-url-style": ["error", "never"],
472
- ...overrides == null ? void 0 : overrides.unicorn
520
+ ...overrides?.unicorn
473
521
  }
474
522
  };
475
523
  }
524
+
476
525
  function javascript(options) {
477
526
  const { overrides } = options;
478
527
  const files = [Glob.All];
@@ -612,15 +661,16 @@ function javascript(options) {
612
661
  "use-isnan": "error",
613
662
  "valid-typeof": "error",
614
663
  yoda: ["error", "never"],
615
- ...overrides == null ? void 0 : overrides.javascript
664
+ ...overrides?.javascript
616
665
  }
617
666
  };
618
667
  }
668
+
619
669
  async function typescript(options) {
620
670
  const { project, overrides } = options;
621
671
  const [tsParser, tsPlugin] = await Promise.all([
622
- interopDefault(import("@typescript-eslint/parser")),
623
- interopDefault(import("@typescript-eslint/eslint-plugin"))
672
+ interopDefault(import('@typescript-eslint/parser')),
673
+ interopDefault(import('@typescript-eslint/eslint-plugin'))
624
674
  ]);
625
675
  const files = [Glob.Typescript];
626
676
  if (options.vue) files.push(Glob.Vue);
@@ -824,7 +874,7 @@ async function typescript(options) {
824
874
  "@typescript-eslint/unbound-method": "error",
825
875
  "@typescript-eslint/unified-signatures": ["error", { ignoreDifferentlyNamedParameters: true }],
826
876
  "@typescript-eslint/use-unknown-in-catch-callback-variable": "error",
827
- ...overrides == null ? void 0 : overrides.typescript
877
+ ...overrides?.typescript
828
878
  };
829
879
  return {
830
880
  files,
@@ -842,10 +892,11 @@ async function typescript(options) {
842
892
  rules
843
893
  };
844
894
  }
895
+
845
896
  async function perfectionist(options) {
846
897
  const { overrides, perfectionist: enabled = true } = options;
847
898
  if (!enabled) return {};
848
- const plugin = await interopDefault(import("eslint-plugin-perfectionist"));
899
+ const plugin = await interopDefault(import('eslint-plugin-perfectionist'));
849
900
  return {
850
901
  plugins: { perfectionist: plugin },
851
902
  rules: {
@@ -904,10 +955,11 @@ async function perfectionist(options) {
904
955
  order: "asc",
905
956
  ignoreCase: true
906
957
  }],
907
- ...overrides == null ? void 0 : overrides.perfectionist
958
+ ...overrides?.perfectionist
908
959
  }
909
960
  };
910
961
  }
962
+
911
963
  async function defineConfig(options) {
912
964
  const ignores = {
913
965
  ignores: [...getIgnores(), ...options.ignores ?? []]
@@ -924,6 +976,5 @@ async function defineConfig(options) {
924
976
  ]);
925
977
  return objects;
926
978
  }
927
- export {
928
- defineConfig as default
929
- };
979
+
980
+ export { defineConfig as default };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tb-dev/eslint-config",
3
- "version": "4.2.0",
3
+ "version": "4.3.0",
4
4
  "description": "ESLint config",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -13,6 +13,13 @@
13
13
  "bugs": {
14
14
  "url": "https://github.com/ferreira-tb/eslint-config/issues"
15
15
  },
16
+ "keywords": [
17
+ "eslint",
18
+ "eslint-config",
19
+ "typescript",
20
+ "stylistic",
21
+ "vue"
22
+ ],
16
23
  "lint-staged": {
17
24
  "*.{?(c|m)@(j|t)s,css,vue,md,json}": "eslint --config eslint.config.js --fix"
18
25
  },
@@ -43,7 +50,7 @@
43
50
  "typescript": "^5.4.0"
44
51
  },
45
52
  "engines": {
46
- "node": ">=20"
53
+ "node": ">=22"
47
54
  },
48
55
  "files": [
49
56
  "dist/**/*"