@studiometa/eslint-plugin-js-toolkit 4.0.0-alpha.1 → 4.0.0-alpha.3
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
CHANGED
|
@@ -14,6 +14,16 @@ Oxlint/ESLint plugin enforcing best practices for [@studiometa/js-toolkit](https
|
|
|
14
14
|
npm install --save-dev @studiometa/eslint-plugin-js-toolkit
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
+
## Agent skills
|
|
18
|
+
|
|
19
|
+
The package ships the `studiometa-eslint-plugin-js-toolkit` [agent skill](https://agentskills.io). The skill teaches coding agents how to use the package, and it matches the installed version. Link the skills of your dependencies into your project with the [`skills` CLI](https://github.com/vercel-labs/skills):
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npx skills experimental_sync
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
The command links each skill from `node_modules` into the agent folders (`.agents/skills/`, `.claude/skills/`…). When you update the package, the linked skill updates too.
|
|
26
|
+
|
|
17
27
|
## Configuration
|
|
18
28
|
|
|
19
29
|
### Oxlint
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { eslintCompatPlugin } from "@oxlint/plugins";
|
|
2
|
-
|
|
2
|
+
// src/utils/ast.ts
|
|
3
3
|
function createRule(rule) {
|
|
4
4
|
return rule;
|
|
5
5
|
}
|
|
@@ -250,8 +250,7 @@ function getProperty(node, name) {
|
|
|
250
250
|
}
|
|
251
251
|
return null;
|
|
252
252
|
}
|
|
253
|
-
|
|
254
|
-
//#region src/rules/require-config.ts
|
|
253
|
+
// src/rules/require-config.ts
|
|
255
254
|
const requireConfig = createRule({
|
|
256
255
|
meta: {
|
|
257
256
|
type: "problem",
|
|
@@ -289,8 +288,7 @@ function check$9(node, context) {
|
|
|
289
288
|
messageId: "missingName"
|
|
290
289
|
});
|
|
291
290
|
}
|
|
292
|
-
|
|
293
|
-
//#region src/rules/require-config-name-pascal-case.ts
|
|
291
|
+
// src/rules/require-config-name-pascal-case.ts
|
|
294
292
|
const requireConfigNamePascalCase = createRule({
|
|
295
293
|
meta: {
|
|
296
294
|
type: "problem",
|
|
@@ -324,8 +322,7 @@ function check$8(node, context) {
|
|
|
324
322
|
fix: (fixer) => fixer.replaceText(nameProp.value, `'${toPascalCase(nameValue)}'`)
|
|
325
323
|
});
|
|
326
324
|
}
|
|
327
|
-
|
|
328
|
-
//#region src/rules/refs-camel-case.ts
|
|
325
|
+
// src/rules/refs-camel-case.ts
|
|
329
326
|
const refsCamelCase = createRule({
|
|
330
327
|
meta: {
|
|
331
328
|
type: "problem",
|
|
@@ -366,8 +363,7 @@ function check$7(node, context) {
|
|
|
366
363
|
}
|
|
367
364
|
}
|
|
368
365
|
}
|
|
369
|
-
|
|
370
|
-
//#region src/rules/options-camel-case.ts
|
|
366
|
+
// src/rules/options-camel-case.ts
|
|
371
367
|
const optionsCamelCase = createRule({
|
|
372
368
|
meta: {
|
|
373
369
|
type: "problem",
|
|
@@ -408,8 +404,7 @@ function check$6(node, context) {
|
|
|
408
404
|
}
|
|
409
405
|
}
|
|
410
406
|
}
|
|
411
|
-
|
|
412
|
-
//#region src/rules/async-lifecycle-methods.ts
|
|
407
|
+
// src/rules/async-lifecycle-methods.ts
|
|
413
408
|
const asyncLifecycleMethods = createRule({
|
|
414
409
|
meta: {
|
|
415
410
|
type: "problem",
|
|
@@ -433,8 +428,7 @@ const asyncLifecycleMethods = createRule({
|
|
|
433
428
|
} };
|
|
434
429
|
}
|
|
435
430
|
});
|
|
436
|
-
|
|
437
|
-
//#region src/rules/on-handler-naming.ts
|
|
431
|
+
// src/rules/on-handler-naming.ts
|
|
438
432
|
const ON_HANDLER_RE = /^on[A-Z][a-zA-Z0-9]*$/;
|
|
439
433
|
const onHandlerNaming = createRule({
|
|
440
434
|
meta: {
|
|
@@ -458,8 +452,7 @@ const onHandlerNaming = createRule({
|
|
|
458
452
|
} };
|
|
459
453
|
}
|
|
460
454
|
});
|
|
461
|
-
|
|
462
|
-
//#region src/rules/on-global-handler-prefix.ts
|
|
455
|
+
// src/rules/on-global-handler-prefix.ts
|
|
463
456
|
const GLOBAL_ONLY_EVENTS = /* @__PURE__ */ new Set(["Resize"]);
|
|
464
457
|
const onGlobalHandlerPrefix = createRule({
|
|
465
458
|
meta: {
|
|
@@ -488,8 +481,7 @@ const onGlobalHandlerPrefix = createRule({
|
|
|
488
481
|
} };
|
|
489
482
|
}
|
|
490
483
|
});
|
|
491
|
-
|
|
492
|
-
//#region src/rules/no-deprecated-properties.ts
|
|
484
|
+
// src/rules/no-deprecated-properties.ts
|
|
493
485
|
/** Deprecated in v3, still present at runtime. */
|
|
494
486
|
const V3_DEPRECATED = /* @__PURE__ */ new Map([
|
|
495
487
|
["$parent", "$closest()"],
|
|
@@ -605,8 +597,7 @@ const noDeprecatedProperties = createRule({
|
|
|
605
597
|
}
|
|
606
598
|
}
|
|
607
599
|
});
|
|
608
|
-
|
|
609
|
-
//#region src/rules/no-dispatch-event.ts
|
|
600
|
+
// src/rules/no-dispatch-event.ts
|
|
610
601
|
const noDispatchEvent = createRule({
|
|
611
602
|
meta: {
|
|
612
603
|
type: "suggestion",
|
|
@@ -626,8 +617,7 @@ const noDispatchEvent = createRule({
|
|
|
626
617
|
} };
|
|
627
618
|
}
|
|
628
619
|
});
|
|
629
|
-
|
|
630
|
-
//#region src/rules/no-shadow-dom.ts
|
|
620
|
+
// src/rules/no-shadow-dom.ts
|
|
631
621
|
const noShadowDom = createRule({
|
|
632
622
|
meta: {
|
|
633
623
|
type: "problem",
|
|
@@ -647,8 +637,7 @@ const noShadowDom = createRule({
|
|
|
647
637
|
} };
|
|
648
638
|
}
|
|
649
639
|
});
|
|
650
|
-
|
|
651
|
-
//#region src/rules/no-create-app.ts
|
|
640
|
+
// src/rules/no-create-app.ts
|
|
652
641
|
const noCreateApp = createRule({
|
|
653
642
|
meta: {
|
|
654
643
|
type: "suggestion",
|
|
@@ -665,8 +654,7 @@ const noCreateApp = createRule({
|
|
|
665
654
|
} };
|
|
666
655
|
}
|
|
667
656
|
});
|
|
668
|
-
|
|
669
|
-
//#region src/rules/no-event-listener-methods.ts
|
|
657
|
+
// src/rules/no-event-listener-methods.ts
|
|
670
658
|
const FORBIDDEN = /* @__PURE__ */ new Set(["addEventListener", "removeEventListener"]);
|
|
671
659
|
const noEventListenerMethods = createRule({
|
|
672
660
|
meta: {
|
|
@@ -695,8 +683,7 @@ const noEventListenerMethods = createRule({
|
|
|
695
683
|
} };
|
|
696
684
|
}
|
|
697
685
|
});
|
|
698
|
-
|
|
699
|
-
//#region src/rules/refs-plural-multiple.ts
|
|
686
|
+
// src/rules/refs-plural-multiple.ts
|
|
700
687
|
const refsPluralMultiple = createRule({
|
|
701
688
|
meta: {
|
|
702
689
|
type: "problem",
|
|
@@ -733,8 +720,7 @@ function check$5(node, context) {
|
|
|
733
720
|
});
|
|
734
721
|
}
|
|
735
722
|
}
|
|
736
|
-
|
|
737
|
-
//#region src/rules/no-deep-utils-import.ts
|
|
723
|
+
// src/rules/no-deep-utils-import.ts
|
|
738
724
|
const UTILS_PREFIX = "@studiometa/js-toolkit/utils/";
|
|
739
725
|
/**
|
|
740
726
|
* A published per-symbol subpath: exactly one segment after `utils/`, and no dot in it.
|
|
@@ -768,8 +754,7 @@ const noDeepUtilsImport = createRule({
|
|
|
768
754
|
} };
|
|
769
755
|
}
|
|
770
756
|
});
|
|
771
|
-
|
|
772
|
-
//#region src/rules/no-internal-barrel-import.ts
|
|
757
|
+
// src/rules/no-internal-barrel-import.ts
|
|
773
758
|
/** A relative import of a barrel: `'./utils/index.js'`, `'../Base/index.js'`. */
|
|
774
759
|
const RELATIVE_BARREL_RE = /^\.{1,2}\/.*\/index\.js$/;
|
|
775
760
|
const noInternalBarrelImport = createRule({
|
|
@@ -790,8 +775,7 @@ const noInternalBarrelImport = createRule({
|
|
|
790
775
|
} };
|
|
791
776
|
}
|
|
792
777
|
});
|
|
793
|
-
|
|
794
|
-
//#region src/rules/refs-no-bracket-access.ts
|
|
778
|
+
// src/rules/refs-no-bracket-access.ts
|
|
795
779
|
function isThisRefs$1(node) {
|
|
796
780
|
return node.type === "MemberExpression" && node.object?.type === "ThisExpression" && node.property?.name === "$refs";
|
|
797
781
|
}
|
|
@@ -826,8 +810,7 @@ const refsNoBracketAccess = createRule({
|
|
|
826
810
|
} };
|
|
827
811
|
}
|
|
828
812
|
});
|
|
829
|
-
|
|
830
|
-
//#region src/rules/no-redundant-with-mount-when-in-view.ts
|
|
813
|
+
// src/rules/no-redundant-with-mount-when-in-view.ts
|
|
831
814
|
const noRedundantWithMountWhenInView = createRule({
|
|
832
815
|
meta: {
|
|
833
816
|
type: "suggestion",
|
|
@@ -852,8 +835,7 @@ function check$4(node, context) {
|
|
|
852
835
|
messageId: "redundant"
|
|
853
836
|
});
|
|
854
837
|
}
|
|
855
|
-
|
|
856
|
-
//#region src/rules/prefer-ref-over-query-selector.ts
|
|
838
|
+
// src/rules/prefer-ref-over-query-selector.ts
|
|
857
839
|
const QUERY_METHODS = /* @__PURE__ */ new Set(["querySelector", "querySelectorAll"]);
|
|
858
840
|
function isThisEl(node) {
|
|
859
841
|
return node.type === "MemberExpression" && node.object?.type === "ThisExpression" && node.property?.name === "$el";
|
|
@@ -881,8 +863,7 @@ const preferRefOverQuerySelector = createRule({
|
|
|
881
863
|
} };
|
|
882
864
|
}
|
|
883
865
|
});
|
|
884
|
-
|
|
885
|
-
//#region src/rules/require-refs-declared-in-config.ts
|
|
866
|
+
// src/rules/require-refs-declared-in-config.ts
|
|
886
867
|
function collectDeclaredRefs(classNode) {
|
|
887
868
|
const configProp = (classNode.body?.body ?? []).find((m) => m.type === "PropertyDefinition" && m.static === true && m.key?.name === "config");
|
|
888
869
|
if (!configProp?.value || configProp.value.type !== "ObjectExpression") return /* @__PURE__ */ new Set();
|
|
@@ -938,8 +919,7 @@ function walkNode$3(node, visit) {
|
|
|
938
919
|
else if (child && typeof child === "object" && child.type) walkNode$3(child, visit);
|
|
939
920
|
}
|
|
940
921
|
}
|
|
941
|
-
|
|
942
|
-
//#region src/rules/no-manual-intersection-observer.ts
|
|
922
|
+
// src/rules/no-manual-intersection-observer.ts
|
|
943
923
|
const noManualIntersectionObserver = createRule({
|
|
944
924
|
meta: {
|
|
945
925
|
type: "suggestion",
|
|
@@ -958,8 +938,7 @@ const noManualIntersectionObserver = createRule({
|
|
|
958
938
|
} };
|
|
959
939
|
}
|
|
960
940
|
});
|
|
961
|
-
|
|
962
|
-
//#region src/rules/no-manual-mutation-observer.ts
|
|
941
|
+
// src/rules/no-manual-mutation-observer.ts
|
|
963
942
|
const noManualMutationObserver = createRule({
|
|
964
943
|
meta: {
|
|
965
944
|
type: "suggestion",
|
|
@@ -978,8 +957,7 @@ const noManualMutationObserver = createRule({
|
|
|
978
957
|
} };
|
|
979
958
|
}
|
|
980
959
|
});
|
|
981
|
-
|
|
982
|
-
//#region src/rules/emits-kebab-case.ts
|
|
960
|
+
// src/rules/emits-kebab-case.ts
|
|
983
961
|
/**
|
|
984
962
|
* Returns true if the string is kebab-case:
|
|
985
963
|
* all lowercase letters, digits and hyphens, no underscores or uppercase.
|
|
@@ -1032,8 +1010,7 @@ const emitsKebabCase = createRule({
|
|
|
1032
1010
|
};
|
|
1033
1011
|
}
|
|
1034
1012
|
});
|
|
1035
|
-
|
|
1036
|
-
//#region src/rules/emits-multi-word.ts
|
|
1013
|
+
// src/rules/emits-multi-word.ts
|
|
1037
1014
|
function check$2(node, context) {
|
|
1038
1015
|
if (!isBaseSubclass(node, context)) return;
|
|
1039
1016
|
const configProp = (node.body?.body ?? []).find((member) => member.type === "PropertyDefinition" && member.static === true && member.key?.name === "config");
|
|
@@ -1068,8 +1045,7 @@ const emitsMultiWord = createRule({
|
|
|
1068
1045
|
};
|
|
1069
1046
|
}
|
|
1070
1047
|
});
|
|
1071
|
-
|
|
1072
|
-
//#region src/rules/components-pascal-case.ts
|
|
1048
|
+
// src/rules/components-pascal-case.ts
|
|
1073
1049
|
function check$1(node, context) {
|
|
1074
1050
|
if (!isBaseSubclass(node, context)) return;
|
|
1075
1051
|
const configProp = (node.body?.body ?? []).find((member) => member.type === "PropertyDefinition" && member.static === true && member.key?.name === "config");
|
|
@@ -1110,8 +1086,7 @@ const componentsPascalCase = createRule({
|
|
|
1110
1086
|
};
|
|
1111
1087
|
}
|
|
1112
1088
|
});
|
|
1113
|
-
|
|
1114
|
-
//#region src/rules/require-emit-declared-in-config.ts
|
|
1089
|
+
// src/rules/require-emit-declared-in-config.ts
|
|
1115
1090
|
function collectDeclaredEmits(classNode) {
|
|
1116
1091
|
const configProp = (classNode.body?.body ?? []).find((m) => m.type === "PropertyDefinition" && m.static === true && m.key?.name === "config");
|
|
1117
1092
|
if (!configProp?.value || configProp.value.type !== "ObjectExpression") return /* @__PURE__ */ new Set();
|
|
@@ -1163,8 +1138,7 @@ function walkNode$2(node, visit) {
|
|
|
1163
1138
|
else if (child && typeof child === "object" && child.type) walkNode$2(child, visit);
|
|
1164
1139
|
}
|
|
1165
1140
|
}
|
|
1166
|
-
|
|
1167
|
-
//#region src/rules/require-children-declared-in-config.ts
|
|
1141
|
+
// src/rules/require-children-declared-in-config.ts
|
|
1168
1142
|
function collectDeclaredComponents(classNode) {
|
|
1169
1143
|
const configProp = (classNode.body?.body ?? []).find((m) => m.type === "PropertyDefinition" && m.static === true && m.key?.name === "config");
|
|
1170
1144
|
if (!configProp?.value || configProp.value.type !== "ObjectExpression") return /* @__PURE__ */ new Set();
|
|
@@ -1219,8 +1193,7 @@ function walkNode$1(node, visit) {
|
|
|
1219
1193
|
else if (child && typeof child === "object" && child.type) walkNode$1(child, visit);
|
|
1220
1194
|
}
|
|
1221
1195
|
}
|
|
1222
|
-
|
|
1223
|
-
//#region src/rules/require-options-declared-in-config.ts
|
|
1196
|
+
// src/rules/require-options-declared-in-config.ts
|
|
1224
1197
|
function collectDeclaredOptions(classNode) {
|
|
1225
1198
|
const configProp = (classNode.body?.body ?? []).find((m) => m.type === "PropertyDefinition" && m.static === true && m.key?.name === "config");
|
|
1226
1199
|
if (!configProp?.value || configProp.value.type !== "ObjectExpression") return /* @__PURE__ */ new Set();
|
|
@@ -1275,8 +1248,7 @@ function walkNode(node, visit) {
|
|
|
1275
1248
|
else if (child && typeof child === "object" && child.type) walkNode(child, visit);
|
|
1276
1249
|
}
|
|
1277
1250
|
}
|
|
1278
|
-
|
|
1279
|
-
//#region src/rules/prefer-destructured-lookups.ts
|
|
1251
|
+
// src/rules/prefer-destructured-lookups.ts
|
|
1280
1252
|
const TRACKED_PROPERTIES = /* @__PURE__ */ new Set([
|
|
1281
1253
|
"$refs",
|
|
1282
1254
|
"$options",
|
|
@@ -1341,8 +1313,7 @@ const preferDestructuredLookups = createRule({
|
|
|
1341
1313
|
};
|
|
1342
1314
|
}
|
|
1343
1315
|
});
|
|
1344
|
-
|
|
1345
|
-
//#region src/rules/no-dollar-prefix.ts
|
|
1316
|
+
// src/rules/no-dollar-prefix.ts
|
|
1346
1317
|
const noDollarPrefix = createRule({
|
|
1347
1318
|
meta: {
|
|
1348
1319
|
type: "problem",
|
|
@@ -1373,8 +1344,7 @@ function check(node, context) {
|
|
|
1373
1344
|
});
|
|
1374
1345
|
}
|
|
1375
1346
|
}
|
|
1376
|
-
|
|
1377
|
-
//#region src/rules/require-destroyed-cleanup.ts
|
|
1347
|
+
// src/rules/require-destroyed-cleanup.ts
|
|
1378
1348
|
const SETUP_CALLS = /* @__PURE__ */ new Set([
|
|
1379
1349
|
"setTimeout",
|
|
1380
1350
|
"setInterval",
|
|
@@ -1447,8 +1417,7 @@ function reportIfNeeded(node, context, classTimers, classHasDestroyed) {
|
|
|
1447
1417
|
data: { calls: [...timers].join(", ") }
|
|
1448
1418
|
});
|
|
1449
1419
|
}
|
|
1450
|
-
|
|
1451
|
-
//#region src/rules/no-write-in-read-phase.ts
|
|
1420
|
+
// src/rules/no-write-in-read-phase.ts
|
|
1452
1421
|
/**
|
|
1453
1422
|
* Hooks whose service fans its subscribers out inside `defaultScheduler.read()`.
|
|
1454
1423
|
*
|
|
@@ -1754,8 +1723,7 @@ const noWriteInReadPhase = createRule({
|
|
|
1754
1723
|
};
|
|
1755
1724
|
}
|
|
1756
1725
|
});
|
|
1757
|
-
|
|
1758
|
-
//#region src/rules/no-options-assignment.ts
|
|
1726
|
+
// src/rules/no-options-assignment.ts
|
|
1759
1727
|
/**
|
|
1760
1728
|
* Returns true if an expression is `this.$options`, or a path reaching into it.
|
|
1761
1729
|
*/
|
|
@@ -1811,8 +1779,7 @@ const noOptionsAssignment = createRule({
|
|
|
1811
1779
|
};
|
|
1812
1780
|
}
|
|
1813
1781
|
});
|
|
1814
|
-
|
|
1815
|
-
//#region src/rules/prefer-instance-scheduler.ts
|
|
1782
|
+
// src/rules/prefer-instance-scheduler.ts
|
|
1816
1783
|
/** The phases a component owns an instance-scoped equivalent of. */
|
|
1817
1784
|
const PHASES = /* @__PURE__ */ new Map([["read", "$read"], ["write", "$write"]]);
|
|
1818
1785
|
const preferInstanceScheduler = createRule({
|
|
@@ -1842,8 +1809,7 @@ const preferInstanceScheduler = createRule({
|
|
|
1842
1809
|
} };
|
|
1843
1810
|
}
|
|
1844
1811
|
});
|
|
1845
|
-
|
|
1846
|
-
//#region src/rules/option-default-factory.ts
|
|
1812
|
+
// src/rules/option-default-factory.ts
|
|
1847
1813
|
const optionDefaultFactory = createRule({
|
|
1848
1814
|
meta: {
|
|
1849
1815
|
type: "problem",
|
|
@@ -1886,8 +1852,7 @@ const optionDefaultFactory = createRule({
|
|
|
1886
1852
|
};
|
|
1887
1853
|
}
|
|
1888
1854
|
});
|
|
1889
|
-
|
|
1890
|
-
//#region src/rules/no-conflicting-negated-option.ts
|
|
1855
|
+
// src/rules/no-conflicting-negated-option.ts
|
|
1891
1856
|
/**
|
|
1892
1857
|
* Returns true if an option declaration can hold a boolean, in any of the
|
|
1893
1858
|
* spellings v4 accepts: the shorthand `Boolean`, a union `[Boolean, String]`,
|
|
@@ -1938,8 +1903,7 @@ const noConflictingNegatedOption = createRule({
|
|
|
1938
1903
|
};
|
|
1939
1904
|
}
|
|
1940
1905
|
});
|
|
1941
|
-
|
|
1942
|
-
//#region src/rules/no-destroy-lifecycle.ts
|
|
1906
|
+
// src/rules/no-destroy-lifecycle.ts
|
|
1943
1907
|
/**
|
|
1944
1908
|
* v4 renamed `$destroy()` to `$unmount()` and `destroyed()` to `unmounted()`.
|
|
1945
1909
|
*
|
|
@@ -2040,8 +2004,7 @@ const noDestroyLifecycle = createRule({
|
|
|
2040
2004
|
};
|
|
2041
2005
|
}
|
|
2042
2006
|
});
|
|
2043
|
-
|
|
2044
|
-
//#region src/index.ts
|
|
2007
|
+
// src/index.ts
|
|
2045
2008
|
const PLUGIN_NAME = "js-toolkit";
|
|
2046
2009
|
const rules = {
|
|
2047
2010
|
"require-config": requireConfig,
|
|
@@ -2149,7 +2112,6 @@ plugin.configs["v4"] = {
|
|
|
2149
2112
|
plugins: { [PLUGIN_NAME]: plugin },
|
|
2150
2113
|
rules: v4Rules
|
|
2151
2114
|
};
|
|
2152
|
-
//#endregion
|
|
2153
2115
|
export { plugin as default, plugin as jsToolkit };
|
|
2154
2116
|
|
|
2155
2117
|
//# sourceMappingURL=index.js.map
|