@saasmakers/eslint 0.1.34 → 0.1.36
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/eslint.config.cjs +33 -2
- package/dist/eslint.config.mjs +29 -2
- package/dist/index.cjs +143 -332
- package/dist/index.d.cts +0 -2
- package/dist/index.d.mts +0 -2
- package/dist/index.d.ts +0 -2
- package/dist/index.mjs +143 -332
- package/package.json +6 -2
package/dist/index.cjs
CHANGED
|
@@ -4,7 +4,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
4
4
|
|
|
5
5
|
const utils = require('@typescript-eslint/utils');
|
|
6
6
|
|
|
7
|
-
const rule$
|
|
7
|
+
const rule$c = {
|
|
8
8
|
meta: {
|
|
9
9
|
docs: {
|
|
10
10
|
category: "Stylistic Issues",
|
|
@@ -67,7 +67,7 @@ const rule$e = {
|
|
|
67
67
|
}
|
|
68
68
|
};
|
|
69
69
|
|
|
70
|
-
const rule$
|
|
70
|
+
const rule$b = {
|
|
71
71
|
meta: {
|
|
72
72
|
docs: {
|
|
73
73
|
category: "Stylistic Issues",
|
|
@@ -125,7 +125,12 @@ const rule$d = {
|
|
|
125
125
|
reportAndFix(
|
|
126
126
|
node,
|
|
127
127
|
"singleLine",
|
|
128
|
-
(fixer) =>
|
|
128
|
+
(fixer) => {
|
|
129
|
+
let singleLineText = unionText.replaceAll(/[ \t\n]+/g, " ");
|
|
130
|
+
singleLineText = singleLineText.replaceAll(" |", "|").replaceAll("|", " |");
|
|
131
|
+
singleLineText = singleLineText.replaceAll(" ", " ");
|
|
132
|
+
return fixer.replaceText(node, singleLineText);
|
|
133
|
+
}
|
|
129
134
|
);
|
|
130
135
|
}
|
|
131
136
|
}
|
|
@@ -179,7 +184,7 @@ function getTestPriority(testName) {
|
|
|
179
184
|
return 1;
|
|
180
185
|
}
|
|
181
186
|
}
|
|
182
|
-
const rule$
|
|
187
|
+
const rule$a = {
|
|
183
188
|
meta: {
|
|
184
189
|
docs: {
|
|
185
190
|
category: "Best Practices",
|
|
@@ -249,6 +254,77 @@ const rule$c = {
|
|
|
249
254
|
}
|
|
250
255
|
};
|
|
251
256
|
|
|
257
|
+
function checkInvalidLocales(context, parsed, locales, startOffset, i18nContent) {
|
|
258
|
+
for (const locale of Object.keys(parsed)) {
|
|
259
|
+
if (!locales.includes(locale)) {
|
|
260
|
+
const escapedLocale = locale.replaceAll(/[.*+?^${}()|[\]\\]/g, String.raw`\$&`);
|
|
261
|
+
const localeMatch = new RegExp(String.raw`"${escapedLocale}"\s*:`, "g").exec(i18nContent);
|
|
262
|
+
if (localeMatch) {
|
|
263
|
+
const localeOffset = startOffset + localeMatch.index;
|
|
264
|
+
context.report({
|
|
265
|
+
data: {
|
|
266
|
+
allowed: locales.join(", "),
|
|
267
|
+
locale
|
|
268
|
+
},
|
|
269
|
+
loc: {
|
|
270
|
+
end: context.sourceCode.getLocFromIndex(localeOffset + locale.length + 2),
|
|
271
|
+
start: context.sourceCode.getLocFromIndex(localeOffset)
|
|
272
|
+
},
|
|
273
|
+
messageId: "invalidLocale"
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
function checkMissingLocales(context, parsed, locales, startOffset, i18nContent) {
|
|
280
|
+
for (const locale of locales) {
|
|
281
|
+
if (!parsed[locale]) {
|
|
282
|
+
context.report({
|
|
283
|
+
data: { locale },
|
|
284
|
+
loc: {
|
|
285
|
+
end: context.sourceCode.getLocFromIndex(startOffset + i18nContent.length),
|
|
286
|
+
start: context.sourceCode.getLocFromIndex(startOffset)
|
|
287
|
+
},
|
|
288
|
+
messageId: "missingLocale"
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
function checkMissingTranslations(context, parsed, locales, startOffset, i18nContent) {
|
|
294
|
+
const allKeys = /* @__PURE__ */ new Set();
|
|
295
|
+
for (const locale of locales) {
|
|
296
|
+
if (parsed[locale]) {
|
|
297
|
+
const keys = getAllKeys$1(parsed[locale]);
|
|
298
|
+
for (const key of keys) allKeys.add(key);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
for (const locale of locales) {
|
|
302
|
+
if (!parsed[locale]) {
|
|
303
|
+
continue;
|
|
304
|
+
}
|
|
305
|
+
const localeKeys = getAllKeys$1(parsed[locale]);
|
|
306
|
+
const missingKeys = [...allKeys].filter((key) => !localeKeys.includes(key));
|
|
307
|
+
if (missingKeys.length === 0) {
|
|
308
|
+
continue;
|
|
309
|
+
}
|
|
310
|
+
const escapedLocale = locale.replaceAll(/[.*+?^${}()|[\]\\]/g, String.raw`\$&`);
|
|
311
|
+
const localeMatch = new RegExp(String.raw`"${escapedLocale}"\s*:\s*\{`, "g").exec(i18nContent);
|
|
312
|
+
if (localeMatch) {
|
|
313
|
+
const localeOffset = startOffset + localeMatch.index;
|
|
314
|
+
context.report({
|
|
315
|
+
data: {
|
|
316
|
+
locale,
|
|
317
|
+
missing: missingKeys.join(", ")
|
|
318
|
+
},
|
|
319
|
+
loc: {
|
|
320
|
+
end: context.sourceCode.getLocFromIndex(localeOffset + locale.length + 2),
|
|
321
|
+
start: context.sourceCode.getLocFromIndex(localeOffset)
|
|
322
|
+
},
|
|
323
|
+
messageId: "missingTranslations"
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
252
328
|
function getAllKeys$1(object, prefix = "") {
|
|
253
329
|
let keys = [];
|
|
254
330
|
for (const key in object) {
|
|
@@ -261,7 +337,7 @@ function getAllKeys$1(object, prefix = "") {
|
|
|
261
337
|
}
|
|
262
338
|
return keys;
|
|
263
339
|
}
|
|
264
|
-
const rule$
|
|
340
|
+
const rule$9 = {
|
|
265
341
|
meta: {
|
|
266
342
|
docs: {
|
|
267
343
|
category: "Possible Errors",
|
|
@@ -296,91 +372,36 @@ const rule$b = {
|
|
|
296
372
|
return {
|
|
297
373
|
Program() {
|
|
298
374
|
const source = context.sourceCode.getText();
|
|
299
|
-
const
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
context.report({
|
|
323
|
-
data: {
|
|
324
|
-
allowed: locales.join(", "),
|
|
325
|
-
locale
|
|
326
|
-
},
|
|
327
|
-
loc: {
|
|
328
|
-
end: context.sourceCode.getLocFromIndex(localeOffset + locale.length + 2),
|
|
329
|
-
start: context.sourceCode.getLocFromIndex(localeOffset)
|
|
330
|
-
},
|
|
331
|
-
messageId: "invalidLocale"
|
|
332
|
-
});
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
const allKeys = /* @__PURE__ */ new Set();
|
|
337
|
-
for (const locale of locales) {
|
|
338
|
-
if (parsed[locale]) {
|
|
339
|
-
const keys = getAllKeys$1(parsed[locale]);
|
|
340
|
-
for (const key of keys) allKeys.add(key);
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
for (const locale of locales) {
|
|
344
|
-
if (parsed[locale]) {
|
|
345
|
-
const localeKeys = getAllKeys$1(parsed[locale]);
|
|
346
|
-
const missingKeys = [...allKeys].filter((key) => !localeKeys.includes(key));
|
|
347
|
-
if (missingKeys.length > 0) {
|
|
348
|
-
const localeMatch = new RegExp(String.raw`"${locale}"\s*:\s*{`, "g").exec(i18nContent);
|
|
349
|
-
if (localeMatch) {
|
|
350
|
-
const localeOffset = startOffset + localeMatch.index;
|
|
351
|
-
context.report({
|
|
352
|
-
data: {
|
|
353
|
-
locale,
|
|
354
|
-
missing: missingKeys.join(", ")
|
|
355
|
-
},
|
|
356
|
-
loc: {
|
|
357
|
-
end: context.sourceCode.getLocFromIndex(localeOffset + locale.length + 2),
|
|
358
|
-
start: context.sourceCode.getLocFromIndex(localeOffset)
|
|
359
|
-
},
|
|
360
|
-
messageId: "missingTranslations"
|
|
361
|
-
});
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
} catch (error) {
|
|
367
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
368
|
-
context.report({
|
|
369
|
-
data: { error: errorMessage },
|
|
370
|
-
loc: {
|
|
371
|
-
end: context.sourceCode.getLocFromIndex(startOffset + i18nContent.length),
|
|
372
|
-
start: context.sourceCode.getLocFromIndex(startOffset)
|
|
373
|
-
},
|
|
374
|
-
messageId: "invalidJson"
|
|
375
|
-
});
|
|
376
|
-
}
|
|
375
|
+
const i18nRegex = /<i18n\s+lang=["']json["']>([\s\S]*?)<\/i18n>/i;
|
|
376
|
+
const i18nMatch = i18nRegex.exec(source);
|
|
377
|
+
if (!i18nMatch) {
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
380
|
+
const tagLength = source.indexOf(">", i18nMatch.index) + 1 - i18nMatch.index;
|
|
381
|
+
const startOffset = i18nMatch.index + tagLength;
|
|
382
|
+
const i18nContent = i18nMatch[1].trim();
|
|
383
|
+
try {
|
|
384
|
+
const parsed = JSON.parse(i18nContent);
|
|
385
|
+
checkMissingLocales(context, parsed, locales, startOffset, i18nContent);
|
|
386
|
+
checkInvalidLocales(context, parsed, locales, startOffset, i18nContent);
|
|
387
|
+
checkMissingTranslations(context, parsed, locales, startOffset, i18nContent);
|
|
388
|
+
} catch (error) {
|
|
389
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
390
|
+
context.report({
|
|
391
|
+
data: { error: errorMessage },
|
|
392
|
+
loc: {
|
|
393
|
+
end: context.sourceCode.getLocFromIndex(startOffset + i18nContent.length),
|
|
394
|
+
start: context.sourceCode.getLocFromIndex(startOffset)
|
|
395
|
+
},
|
|
396
|
+
messageId: "invalidJson"
|
|
397
|
+
});
|
|
377
398
|
}
|
|
378
399
|
}
|
|
379
400
|
};
|
|
380
401
|
}
|
|
381
402
|
};
|
|
382
403
|
|
|
383
|
-
const rule$
|
|
404
|
+
const rule$8 = {
|
|
384
405
|
meta: {
|
|
385
406
|
docs: {
|
|
386
407
|
category: "Best Practices",
|
|
@@ -400,8 +421,9 @@ const rule$a = {
|
|
|
400
421
|
Program() {
|
|
401
422
|
const sourceCode = context.sourceCode;
|
|
402
423
|
const source = sourceCode.getText();
|
|
403
|
-
const
|
|
404
|
-
|
|
424
|
+
const templateRegex = /<template>([\s\S]*)<\/template>/i;
|
|
425
|
+
const templateMatch = templateRegex.exec(source);
|
|
426
|
+
if (!templateMatch) {
|
|
405
427
|
return;
|
|
406
428
|
}
|
|
407
429
|
const templateContent = templateMatch[1];
|
|
@@ -455,7 +477,7 @@ function sortObjectKeys(object) {
|
|
|
455
477
|
return object.map((item) => sortObjectKeys(item));
|
|
456
478
|
}
|
|
457
479
|
if (object && typeof object === "object") {
|
|
458
|
-
const sortedKeys = Object.keys(object).toSorted();
|
|
480
|
+
const sortedKeys = Object.keys(object).toSorted((key1, key2) => key1.localeCompare(key2));
|
|
459
481
|
const result = {};
|
|
460
482
|
const obj = object;
|
|
461
483
|
for (const key of sortedKeys) {
|
|
@@ -465,7 +487,7 @@ function sortObjectKeys(object) {
|
|
|
465
487
|
}
|
|
466
488
|
return object;
|
|
467
489
|
}
|
|
468
|
-
const rule$
|
|
490
|
+
const rule$7 = {
|
|
469
491
|
meta: {
|
|
470
492
|
docs: {
|
|
471
493
|
category: "Best Practices",
|
|
@@ -488,8 +510,9 @@ const rule$9 = {
|
|
|
488
510
|
return {
|
|
489
511
|
Program() {
|
|
490
512
|
const source = context.sourceCode.getText();
|
|
491
|
-
const
|
|
492
|
-
|
|
513
|
+
const i18nRegex = /(<i18n\s+lang=["']json["']>)([\s\S]*?)(<\/i18n>)/i;
|
|
514
|
+
const i18nMatch = i18nRegex.exec(source);
|
|
515
|
+
if (i18nMatch) {
|
|
493
516
|
const startOffset = i18nMatch.index + i18nMatch[1].length;
|
|
494
517
|
const i18nContent = i18nMatch[2];
|
|
495
518
|
try {
|
|
@@ -546,7 +569,7 @@ function getAllKeys(object, prefix = "") {
|
|
|
546
569
|
}
|
|
547
570
|
return keys;
|
|
548
571
|
}
|
|
549
|
-
const rule$
|
|
572
|
+
const rule$6 = {
|
|
550
573
|
meta: {
|
|
551
574
|
docs: {
|
|
552
575
|
category: "Best Practices",
|
|
@@ -567,8 +590,9 @@ const rule$8 = {
|
|
|
567
590
|
return {
|
|
568
591
|
Program() {
|
|
569
592
|
const source = context.sourceCode.getText();
|
|
570
|
-
const
|
|
571
|
-
|
|
593
|
+
const i18nRegex = /(<i18n\s+lang=["']json["']>)([\s\S]*?)(<\/i18n>)/i;
|
|
594
|
+
const i18nMatch = i18nRegex.exec(source);
|
|
595
|
+
if (!i18nMatch) {
|
|
572
596
|
return;
|
|
573
597
|
}
|
|
574
598
|
const startOffset = i18nMatch.index + i18nMatch[1].length;
|
|
@@ -578,9 +602,11 @@ const rule$8 = {
|
|
|
578
602
|
if (!parsed.en) {
|
|
579
603
|
return;
|
|
580
604
|
}
|
|
581
|
-
const
|
|
605
|
+
const templateRegex = /<template>([\s\S]*)<\/template>/i;
|
|
606
|
+
const templateMatch = templateRegex.exec(source);
|
|
582
607
|
const templateContent = templateMatch ? templateMatch[1] : "";
|
|
583
|
-
const
|
|
608
|
+
const scriptRegex = /<script[^>]*>([\s\S]*?)<\/script>/i;
|
|
609
|
+
const scriptMatch = scriptRegex.exec(source);
|
|
584
610
|
const scriptContent = scriptMatch ? scriptMatch[1] : "";
|
|
585
611
|
const enKeys = getAllKeys(parsed.en);
|
|
586
612
|
for (const key of enKeys) {
|
|
@@ -616,7 +642,7 @@ const rule$8 = {
|
|
|
616
642
|
}
|
|
617
643
|
};
|
|
618
644
|
|
|
619
|
-
const rule$
|
|
645
|
+
const rule$5 = {
|
|
620
646
|
defaultOptions: [],
|
|
621
647
|
meta: {
|
|
622
648
|
docs: { description: "Enforce multiline style for Vue computed properties" },
|
|
@@ -655,7 +681,7 @@ const rule$7 = {
|
|
|
655
681
|
}
|
|
656
682
|
};
|
|
657
683
|
|
|
658
|
-
const rule$
|
|
684
|
+
const rule$4 = {
|
|
659
685
|
meta: {
|
|
660
686
|
docs: {
|
|
661
687
|
category: "Best Practices",
|
|
@@ -705,165 +731,7 @@ ${typedEvents}
|
|
|
705
731
|
}
|
|
706
732
|
};
|
|
707
733
|
|
|
708
|
-
const rule$
|
|
709
|
-
meta: {
|
|
710
|
-
docs: {
|
|
711
|
-
category: "Best Practices",
|
|
712
|
-
description: "Prevent comments, empty lines, redundant required: false, enforce default: undefined for single-key props, and detect unused props inside defineProps",
|
|
713
|
-
recommended: true
|
|
714
|
-
},
|
|
715
|
-
fixable: "code",
|
|
716
|
-
messages: {
|
|
717
|
-
noCommentsInProps: "Comments are not allowed inside defineProps.",
|
|
718
|
-
noEmptyLinesInProps: "Empty lines are not allowed between props in defineProps.",
|
|
719
|
-
noRedundantRequired: "required: false is redundant in props. Props are optional by default.",
|
|
720
|
-
singleKeyProp: "Props with only one key should have default: undefined for better readability.",
|
|
721
|
-
unusedProp: 'Unused prop: "{{propName}}"'
|
|
722
|
-
},
|
|
723
|
-
schema: [],
|
|
724
|
-
type: "problem"
|
|
725
|
-
},
|
|
726
|
-
create(context) {
|
|
727
|
-
if (!context.filename.endsWith(".vue")) {
|
|
728
|
-
return {};
|
|
729
|
-
}
|
|
730
|
-
return {
|
|
731
|
-
CallExpression(node) {
|
|
732
|
-
if (node.callee.type !== "Identifier" || node.callee.name !== "defineProps") {
|
|
733
|
-
return;
|
|
734
|
-
}
|
|
735
|
-
const sourceCode = context.sourceCode;
|
|
736
|
-
const propsArg = node.arguments[0];
|
|
737
|
-
if (!propsArg?.range) {
|
|
738
|
-
return;
|
|
739
|
-
}
|
|
740
|
-
const propsArgRange = propsArg.range;
|
|
741
|
-
const commentsInProps = [
|
|
742
|
-
...sourceCode.getCommentsBefore(propsArg),
|
|
743
|
-
...sourceCode.getCommentsInside(propsArg)
|
|
744
|
-
].filter((comment) => {
|
|
745
|
-
return comment.range !== void 0 && comment.range[0] >= propsArgRange[0] && comment.range[1] <= propsArgRange[1];
|
|
746
|
-
});
|
|
747
|
-
for (const comment of commentsInProps) {
|
|
748
|
-
context.report({
|
|
749
|
-
fix: (fixer) => {
|
|
750
|
-
return fixer.removeRange(comment.range);
|
|
751
|
-
},
|
|
752
|
-
loc: comment.loc ?? node.loc ?? {
|
|
753
|
-
end: {
|
|
754
|
-
column: 0,
|
|
755
|
-
line: 0
|
|
756
|
-
},
|
|
757
|
-
start: {
|
|
758
|
-
column: 0,
|
|
759
|
-
line: 0
|
|
760
|
-
}
|
|
761
|
-
},
|
|
762
|
-
messageId: "noCommentsInProps"
|
|
763
|
-
});
|
|
764
|
-
}
|
|
765
|
-
const propsText = sourceCode.getText(propsArg);
|
|
766
|
-
const emptyLineRegex = /(?:{\s*\n\s*\n|,\s*\n\s*\n)\s*(?:([a-zA-Z])|(?:\s*}))/g;
|
|
767
|
-
let emptyLineMatch = emptyLineRegex.exec(propsText);
|
|
768
|
-
while (emptyLineMatch !== null) {
|
|
769
|
-
const matchIndex = emptyLineMatch.index;
|
|
770
|
-
const matchLength = emptyLineMatch[0].length;
|
|
771
|
-
const lastChar = emptyLineMatch[0].trim().charAt(0);
|
|
772
|
-
const isEndBrace = emptyLineMatch[0].trim().endsWith("}");
|
|
773
|
-
const firstLetter = emptyLineMatch[1];
|
|
774
|
-
const startIndex = propsArg.range[0] + matchIndex;
|
|
775
|
-
const endIndex = startIndex + matchLength;
|
|
776
|
-
context.report({
|
|
777
|
-
fix: (fixer) => {
|
|
778
|
-
const replacement = isEndBrace ? "\n}" : (lastChar === "{" ? "{\n " : ",\n ") + firstLetter;
|
|
779
|
-
return fixer.replaceTextRange([startIndex, endIndex], replacement);
|
|
780
|
-
},
|
|
781
|
-
loc: {
|
|
782
|
-
end: sourceCode.getLocFromIndex(endIndex),
|
|
783
|
-
start: sourceCode.getLocFromIndex(startIndex)
|
|
784
|
-
},
|
|
785
|
-
messageId: "noEmptyLinesInProps"
|
|
786
|
-
});
|
|
787
|
-
emptyLineMatch = emptyLineRegex.exec(propsText);
|
|
788
|
-
}
|
|
789
|
-
const redundantRequiredRegex = /required:\s*false\s*,?/g;
|
|
790
|
-
let redundantMatch = redundantRequiredRegex.exec(propsText);
|
|
791
|
-
while (redundantMatch !== null) {
|
|
792
|
-
const matchIndex = redundantMatch.index;
|
|
793
|
-
const matchLength = redundantMatch[0].length;
|
|
794
|
-
const startIndex = propsArg.range[0] + matchIndex;
|
|
795
|
-
const endIndex = startIndex + matchLength;
|
|
796
|
-
context.report({
|
|
797
|
-
fix: (fixer) => {
|
|
798
|
-
return fixer.removeRange([startIndex, endIndex]);
|
|
799
|
-
},
|
|
800
|
-
loc: {
|
|
801
|
-
end: sourceCode.getLocFromIndex(endIndex),
|
|
802
|
-
start: sourceCode.getLocFromIndex(startIndex)
|
|
803
|
-
},
|
|
804
|
-
messageId: "noRedundantRequired"
|
|
805
|
-
});
|
|
806
|
-
redundantMatch = redundantRequiredRegex.exec(propsText);
|
|
807
|
-
}
|
|
808
|
-
const source = sourceCode.getText();
|
|
809
|
-
const templateMatch = source.match(/<template>([\s\S]*)<\/template>/i);
|
|
810
|
-
const templateContent = templateMatch ? templateMatch[1] : "";
|
|
811
|
-
const scriptMatch = source.match(/<script[^>]*>([\s\S]*?)<\/script>/i);
|
|
812
|
-
const scriptContent = scriptMatch ? scriptMatch[1] : "";
|
|
813
|
-
const propDefinitions = propsText.match(/(\w+):\s*{([^}]+)}/g) ?? [];
|
|
814
|
-
for (const propDef of propDefinitions) {
|
|
815
|
-
const propNameMatch = propDef.match(/^(\w+):\s*{([^}]+)}/);
|
|
816
|
-
if (!propNameMatch) {
|
|
817
|
-
continue;
|
|
818
|
-
}
|
|
819
|
-
const propName = propNameMatch[1];
|
|
820
|
-
const propContent = propNameMatch[2].trim();
|
|
821
|
-
const hasDefault = propContent.includes("default:");
|
|
822
|
-
const hasRequired = propContent.includes("required:");
|
|
823
|
-
if (!hasDefault && !hasRequired && propContent.includes("type:")) {
|
|
824
|
-
const fullPropRegex = new RegExp(String.raw`${propName}:\s*{[^}]+}`, "g");
|
|
825
|
-
const fullMatch = propsText.match(fullPropRegex);
|
|
826
|
-
if (!fullMatch) {
|
|
827
|
-
continue;
|
|
828
|
-
}
|
|
829
|
-
const fullPropDef = fullMatch[0];
|
|
830
|
-
const matchIndex = propsText.indexOf(fullPropDef);
|
|
831
|
-
const matchLength = fullPropDef.length;
|
|
832
|
-
const startIndex = propsArg.range[0] + matchIndex;
|
|
833
|
-
const endIndex = startIndex + matchLength;
|
|
834
|
-
context.report({
|
|
835
|
-
fix: (fixer) => {
|
|
836
|
-
const newText = fullPropDef.replace(/{\s*type:/, "{\n default: undefined,\n type:").replace(/,\s*\n\s*}/, "}");
|
|
837
|
-
return fixer.replaceTextRange([startIndex, endIndex], newText);
|
|
838
|
-
},
|
|
839
|
-
loc: {
|
|
840
|
-
end: sourceCode.getLocFromIndex(endIndex),
|
|
841
|
-
start: sourceCode.getLocFromIndex(startIndex)
|
|
842
|
-
},
|
|
843
|
-
messageId: "singleKeyProp"
|
|
844
|
-
});
|
|
845
|
-
}
|
|
846
|
-
const isUsedInTemplate = templateContent.includes(propName);
|
|
847
|
-
const isUsedInScript = scriptContent.replace(propsText, "").includes(propName);
|
|
848
|
-
if (!isUsedInTemplate && !isUsedInScript) {
|
|
849
|
-
const propStartIndex = propsArg.range[0] + propsText.indexOf(propDef);
|
|
850
|
-
const propEndIndex = propStartIndex + propDef.length;
|
|
851
|
-
context.report({
|
|
852
|
-
data: { propName },
|
|
853
|
-
loc: {
|
|
854
|
-
end: sourceCode.getLocFromIndex(propEndIndex),
|
|
855
|
-
start: sourceCode.getLocFromIndex(propStartIndex)
|
|
856
|
-
},
|
|
857
|
-
messageId: "unusedProp"
|
|
858
|
-
});
|
|
859
|
-
}
|
|
860
|
-
}
|
|
861
|
-
}
|
|
862
|
-
};
|
|
863
|
-
}
|
|
864
|
-
};
|
|
865
|
-
|
|
866
|
-
const rule$4 = {
|
|
734
|
+
const rule$3 = {
|
|
867
735
|
meta: {
|
|
868
736
|
docs: {
|
|
869
737
|
category: "Best Practices",
|
|
@@ -888,64 +756,6 @@ const rule$4 = {
|
|
|
888
756
|
}
|
|
889
757
|
};
|
|
890
758
|
|
|
891
|
-
const rule$3 = {
|
|
892
|
-
meta: {
|
|
893
|
-
docs: {
|
|
894
|
-
category: "Best Practices",
|
|
895
|
-
description: 'Prevent empty lines inside :class="{ bindings in Vue template tags',
|
|
896
|
-
recommended: true
|
|
897
|
-
},
|
|
898
|
-
fixable: "code",
|
|
899
|
-
messages: { noEmptyLinesInClass: 'Empty lines are not allowed inside :class="{ bindings.' },
|
|
900
|
-
schema: [],
|
|
901
|
-
type: "problem"
|
|
902
|
-
},
|
|
903
|
-
create(context) {
|
|
904
|
-
if (!context.filename.endsWith(".vue")) {
|
|
905
|
-
return {};
|
|
906
|
-
}
|
|
907
|
-
return {
|
|
908
|
-
Program() {
|
|
909
|
-
const sourceCode = context.sourceCode;
|
|
910
|
-
const source = sourceCode.getText();
|
|
911
|
-
const templateMatch = source.match(/<template>([\s\S]*)<\/template>/i);
|
|
912
|
-
if (!templateMatch) {
|
|
913
|
-
return;
|
|
914
|
-
}
|
|
915
|
-
const templateContent = templateMatch[1];
|
|
916
|
-
const classBindingRegex = /:class="\{([\s\S]*?)\}"/g;
|
|
917
|
-
let classBindingMatch;
|
|
918
|
-
while ((classBindingMatch = classBindingRegex.exec(templateContent)) !== null) {
|
|
919
|
-
const classContent = classBindingMatch[1];
|
|
920
|
-
const emptyLineRegex = /\n\s*\n/g;
|
|
921
|
-
let emptyLineMatch;
|
|
922
|
-
while ((emptyLineMatch = emptyLineRegex.exec(classContent)) !== null) {
|
|
923
|
-
const matchIndex = emptyLineMatch.index;
|
|
924
|
-
const matchLength = emptyLineMatch[0].length;
|
|
925
|
-
const templateStartIndex = source.indexOf(templateContent);
|
|
926
|
-
const classBindingStartIndex = templateStartIndex + classBindingMatch.index;
|
|
927
|
-
const classContentStartIndex = classBindingStartIndex + 8;
|
|
928
|
-
const startIndex = classContentStartIndex + matchIndex;
|
|
929
|
-
const endIndex = startIndex + matchLength;
|
|
930
|
-
context.report({
|
|
931
|
-
// TODO: Uncomment this when we want to fix the issue
|
|
932
|
-
// fix: (fixer) => {
|
|
933
|
-
// // Replace consecutive newlines with a single newline
|
|
934
|
-
// return fixer.replaceTextRange([startIndex, endIndex], '\n')
|
|
935
|
-
// },
|
|
936
|
-
loc: {
|
|
937
|
-
end: sourceCode.getLocFromIndex(endIndex),
|
|
938
|
-
start: sourceCode.getLocFromIndex(startIndex)
|
|
939
|
-
},
|
|
940
|
-
messageId: "noEmptyLinesInClass"
|
|
941
|
-
});
|
|
942
|
-
}
|
|
943
|
-
}
|
|
944
|
-
}
|
|
945
|
-
};
|
|
946
|
-
}
|
|
947
|
-
};
|
|
948
|
-
|
|
949
759
|
const rule$2 = {
|
|
950
760
|
meta: {
|
|
951
761
|
docs: {
|
|
@@ -969,8 +779,9 @@ const rule$2 = {
|
|
|
969
779
|
}
|
|
970
780
|
const sourceCode = context.sourceCode;
|
|
971
781
|
const source = sourceCode.getText();
|
|
972
|
-
const
|
|
973
|
-
|
|
782
|
+
const templateRegex = /<template>([\s\S]*)<\/template>/i;
|
|
783
|
+
const templateMatch = templateRegex.exec(source);
|
|
784
|
+
if (!templateMatch) {
|
|
974
785
|
return;
|
|
975
786
|
}
|
|
976
787
|
const templateContent = templateMatch[1];
|
|
@@ -1020,8 +831,9 @@ const rule$1 = {
|
|
|
1020
831
|
Program() {
|
|
1021
832
|
const sourceCode = context.sourceCode;
|
|
1022
833
|
const source = sourceCode.getText();
|
|
1023
|
-
const
|
|
1024
|
-
|
|
834
|
+
const templateRegex = /<template>([\s\S]*)<\/template>/i;
|
|
835
|
+
const templateMatch = templateRegex.exec(source);
|
|
836
|
+
if (!templateMatch) {
|
|
1025
837
|
return;
|
|
1026
838
|
}
|
|
1027
839
|
const templateContent = templateMatch[1];
|
|
@@ -1097,8 +909,9 @@ const rule = {
|
|
|
1097
909
|
Program() {
|
|
1098
910
|
const sourceCode = context.sourceCode;
|
|
1099
911
|
const source = sourceCode.getText();
|
|
1100
|
-
const
|
|
1101
|
-
|
|
912
|
+
const templateRegex = /<template>([\s\S]*)<\/template>/i;
|
|
913
|
+
const templateMatch = templateRegex.exec(source);
|
|
914
|
+
if (!templateMatch) {
|
|
1102
915
|
return;
|
|
1103
916
|
}
|
|
1104
917
|
const templateContent = templateMatch[1];
|
|
@@ -1136,18 +949,16 @@ const rule = {
|
|
|
1136
949
|
|
|
1137
950
|
const saasmakers = {
|
|
1138
951
|
rules: {
|
|
1139
|
-
"ts-multiline-ternary": rule$
|
|
1140
|
-
"ts-multiline-union": rule$
|
|
1141
|
-
"ts-sort-tests": rule$
|
|
1142
|
-
"vue-i18n-consistent-locales": rule$
|
|
1143
|
-
"vue-i18n-consistent-t": rule$
|
|
1144
|
-
"vue-i18n-sort-keys": rule$
|
|
1145
|
-
"vue-i18n-unused-strings": rule$
|
|
1146
|
-
"vue-script-format-computed": rule$
|
|
1147
|
-
"vue-script-format-emits": rule$
|
|
1148
|
-
"vue-script-
|
|
1149
|
-
"vue-script-order": rule$4,
|
|
1150
|
-
"vue-template-format-classes": rule$3,
|
|
952
|
+
"ts-multiline-ternary": rule$c,
|
|
953
|
+
"ts-multiline-union": rule$b,
|
|
954
|
+
"ts-sort-tests": rule$a,
|
|
955
|
+
"vue-i18n-consistent-locales": rule$9,
|
|
956
|
+
"vue-i18n-consistent-t": rule$8,
|
|
957
|
+
"vue-i18n-sort-keys": rule$7,
|
|
958
|
+
"vue-i18n-unused-strings": rule$6,
|
|
959
|
+
"vue-script-format-computed": rule$5,
|
|
960
|
+
"vue-script-format-emits": rule$4,
|
|
961
|
+
"vue-script-order": rule$3,
|
|
1151
962
|
"vue-template-format-props": rule$2,
|
|
1152
963
|
"vue-template-remove-comments": rule$1,
|
|
1153
964
|
"vue-template-remove-true-attributes": rule
|
package/dist/index.d.cts
CHANGED
|
@@ -12,9 +12,7 @@ declare const _default: {
|
|
|
12
12
|
'vue-i18n-unused-strings': eslint.Rule.RuleModule;
|
|
13
13
|
'vue-script-format-computed': _typescript_eslint_utils_ts_eslint.RuleModule<"multilineComputed", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
14
14
|
'vue-script-format-emits': eslint.Rule.RuleModule;
|
|
15
|
-
'vue-script-format-props': eslint.Rule.RuleModule;
|
|
16
15
|
'vue-script-order': eslint.Rule.RuleModule;
|
|
17
|
-
'vue-template-format-classes': eslint.Rule.RuleModule;
|
|
18
16
|
'vue-template-format-props': eslint.Rule.RuleModule;
|
|
19
17
|
'vue-template-remove-comments': eslint.Rule.RuleModule;
|
|
20
18
|
'vue-template-remove-true-attributes': eslint.Rule.RuleModule;
|
package/dist/index.d.mts
CHANGED
|
@@ -12,9 +12,7 @@ declare const _default: {
|
|
|
12
12
|
'vue-i18n-unused-strings': eslint.Rule.RuleModule;
|
|
13
13
|
'vue-script-format-computed': _typescript_eslint_utils_ts_eslint.RuleModule<"multilineComputed", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
14
14
|
'vue-script-format-emits': eslint.Rule.RuleModule;
|
|
15
|
-
'vue-script-format-props': eslint.Rule.RuleModule;
|
|
16
15
|
'vue-script-order': eslint.Rule.RuleModule;
|
|
17
|
-
'vue-template-format-classes': eslint.Rule.RuleModule;
|
|
18
16
|
'vue-template-format-props': eslint.Rule.RuleModule;
|
|
19
17
|
'vue-template-remove-comments': eslint.Rule.RuleModule;
|
|
20
18
|
'vue-template-remove-true-attributes': eslint.Rule.RuleModule;
|
package/dist/index.d.ts
CHANGED
|
@@ -12,9 +12,7 @@ declare const _default: {
|
|
|
12
12
|
'vue-i18n-unused-strings': eslint.Rule.RuleModule;
|
|
13
13
|
'vue-script-format-computed': _typescript_eslint_utils_ts_eslint.RuleModule<"multilineComputed", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
14
14
|
'vue-script-format-emits': eslint.Rule.RuleModule;
|
|
15
|
-
'vue-script-format-props': eslint.Rule.RuleModule;
|
|
16
15
|
'vue-script-order': eslint.Rule.RuleModule;
|
|
17
|
-
'vue-template-format-classes': eslint.Rule.RuleModule;
|
|
18
16
|
'vue-template-format-props': eslint.Rule.RuleModule;
|
|
19
17
|
'vue-template-remove-comments': eslint.Rule.RuleModule;
|
|
20
18
|
'vue-template-remove-true-attributes': eslint.Rule.RuleModule;
|