@studiometa/eslint-plugin-js-toolkit 3.6.0-beta.1 → 3.6.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/README.md CHANGED
@@ -43,7 +43,16 @@ Add the plugin to your `.oxlintrc.json`:
43
43
  "js-toolkit/prefer-ref-over-query-selector": "warn",
44
44
  "js-toolkit/require-refs-declared-in-config": "error",
45
45
  "js-toolkit/no-manual-intersection-observer": "warn",
46
- "js-toolkit/no-manual-mutation-observer": "warn"
46
+ "js-toolkit/no-manual-mutation-observer": "warn",
47
+ "js-toolkit/emits-kebab-case": "error",
48
+ "js-toolkit/emits-multi-word": "error",
49
+ "js-toolkit/components-pascal-case": "error",
50
+ "js-toolkit/require-emit-declared-in-config": "error",
51
+ "js-toolkit/require-children-declared-in-config": "error",
52
+ "js-toolkit/require-options-declared-in-config": "error",
53
+ "js-toolkit/prefer-destructured-lookups": "warn",
54
+ "js-toolkit/no-dollar-prefix": "error",
55
+ "js-toolkit/require-destroyed-cleanup": "warn"
47
56
  }
48
57
  }
49
58
  ```
@@ -53,7 +62,7 @@ Add the plugin to your `.oxlintrc.json`:
53
62
  Add the recommended config to your `eslint.config.js` (ESLint v9 flat config):
54
63
 
55
64
  ```js
56
- import jsToolkit from '@studiometa/eslint-plugin-js-toolkit';
65
+ import { jsToolkit } from '@studiometa/eslint-plugin-js-toolkit';
57
66
 
58
67
  export default [
59
68
  jsToolkit.configs.recommended,
@@ -64,7 +73,7 @@ export default [
64
73
  To customise individual rule severities, add an override entry after the recommended config:
65
74
 
66
75
  ```js
67
- import jsToolkit from '@studiometa/eslint-plugin-js-toolkit';
76
+ import { jsToolkit } from '@studiometa/eslint-plugin-js-toolkit';
68
77
 
69
78
  export default [
70
79
  jsToolkit.configs.recommended,
@@ -115,6 +124,22 @@ export default [
115
124
  | `js-toolkit/no-manual-intersection-observer` | Disallows `new IntersectionObserver()` inside `Base` subclasses. Use `withIntersectionObserver` or `withMountWhenInView` decorators instead. | warn | |
116
125
  | `js-toolkit/no-manual-mutation-observer` | Disallows `new MutationObserver()` inside `Base` subclasses. Use the `withMutation` decorator instead. | warn | |
117
126
 
127
+ ### Emits
128
+
129
+ | Rule | Description | Recommended | Fixable |
130
+ | -------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | ----------- | ------- |
131
+ | `js-toolkit/emits-kebab-case` | Requires emit names in `config.emits` to be kebab-case (e.g. `content-change`). | error | 🔧 |
132
+ | `js-toolkit/emits-multi-word` | Requires emit names in `config.emits` to be multi-word to avoid collisions with native DOM events (e.g. `item-click` not `click`). | error | |
133
+ | `js-toolkit/require-emit-declared-in-config` | Requires all `this.$emit('name')` calls to use event names declared in `static config.emits`. | error | |
134
+
135
+ ### Components
136
+
137
+ | Rule | Description | Recommended | Fixable |
138
+ | ------------------------------------------------ | ------------------------------------------------------------------------------------------- | ----------- | ------- |
139
+ | `js-toolkit/components-pascal-case` | Requires component keys in `config.components` to be PascalCase. | error | 🔧 |
140
+ | `js-toolkit/require-children-declared-in-config` | Requires all `this.$children.<Name>` accesses to be declared in `static config.components`. | error | |
141
+ | `js-toolkit/require-options-declared-in-config` | Requires all `this.$options.<name>` accesses to be declared in `static config.options`. | error | |
142
+
118
143
  ### Refs
119
144
 
120
145
  | Rule | Description | Recommended | Fixable |
@@ -122,3 +147,11 @@ export default [
122
147
  | `js-toolkit/refs-no-bracket-access` | Disallows bracket access with a `[]` suffix on `this.$refs` (e.g. `this.$refs['items[]']`). Rewrites to dot notation camelCase. | error | 🔧 |
123
148
  | `js-toolkit/prefer-ref-over-query-selector` | Warns when `this.$el.querySelector()` or `this.$el.querySelectorAll()` is used inside a `Base` subclass. Declare a ref in `static config` and use `this.$refs` instead. | warn | |
124
149
  | `js-toolkit/require-refs-declared-in-config` | Requires all `this.$refs.<name>` accesses to be declared in `static config.refs`. | error | |
150
+
151
+ ### Best practices
152
+
153
+ | Rule | Description | Recommended | Fixable |
154
+ | ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | ------- |
155
+ | `js-toolkit/prefer-destructured-lookups` | Warns when `this.$refs`, `this.$options` or `this.$children` members are accessed more than once in the same method. Destructure into a local variable instead. | warn | |
156
+ | `js-toolkit/no-dollar-prefix` | Disallows user-defined instance methods and properties prefixed with `$` in `Base` subclasses. The `$` prefix is reserved for framework-provided members. | error | |
157
+ | `js-toolkit/require-destroyed-cleanup` | Requires a `destroyed()` method in `Base` subclasses that call `setTimeout`, `setInterval` or `requestAnimationFrame`, to clear timers and prevent memory leaks. | warn | |
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  declare const plugin: import("@oxlint/plugins").Plugin & {
2
2
  configs: Record<string, object>;
3
3
  };
4
+ export { plugin as jsToolkit };
4
5
  export default plugin;
package/dist/index.js CHANGED
@@ -1000,6 +1000,551 @@ var noManualMutationObserver = createRule({
1000
1000
  }
1001
1001
  });
1002
1002
 
1003
+ // src/rules/emits-kebab-case.ts
1004
+ function isKebabCase(value) {
1005
+ return /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/.test(value);
1006
+ }
1007
+ function toKebabCase(value) {
1008
+ return value.replace(/([A-Z])/g, (_, c) => `-${c.toLowerCase()}`).replace(/_/g, "-").replace(/^-/, "").toLowerCase();
1009
+ }
1010
+ function check7(node, context) {
1011
+ if (!isBaseSubclass(node, context)) return;
1012
+ const body = node.body?.body ?? [];
1013
+ const configProp = body.find(
1014
+ (member) => member.type === "PropertyDefinition" && member.static === true && member.key?.name === "config"
1015
+ );
1016
+ if (!configProp?.value || configProp.value.type !== "ObjectExpression") return;
1017
+ const emitsProp = configProp.value.properties?.find(
1018
+ (prop) => prop.type === "Property" && prop.key?.name === "emits"
1019
+ );
1020
+ if (!emitsProp?.value || emitsProp.value.type !== "ArrayExpression") return;
1021
+ for (const element of emitsProp.value.elements ?? []) {
1022
+ if (!element || element.type !== "Literal") continue;
1023
+ const name = element.value;
1024
+ if (typeof name !== "string") continue;
1025
+ if (!isKebabCase(name)) {
1026
+ const fixed = toKebabCase(name);
1027
+ context.report({
1028
+ node: element,
1029
+ messageId: "notKebabCase",
1030
+ data: { name },
1031
+ fix: (fixer) => fixer.replaceText(element, `'${fixed}'`)
1032
+ });
1033
+ }
1034
+ }
1035
+ }
1036
+ var emitsKebabCase = createRule({
1037
+ meta: {
1038
+ type: "problem",
1039
+ fixable: "code",
1040
+ docs: {
1041
+ description: "Require emit names in static config to be kebab-case"
1042
+ },
1043
+ messages: {
1044
+ notKebabCase: 'Emit name "{{name}}" must be kebab-case (e.g. "content-change").'
1045
+ }
1046
+ },
1047
+ createOnce(context) {
1048
+ return {
1049
+ ClassDeclaration(node) {
1050
+ check7(node, context);
1051
+ },
1052
+ ClassExpression(node) {
1053
+ check7(node, context);
1054
+ }
1055
+ };
1056
+ }
1057
+ });
1058
+
1059
+ // src/rules/emits-multi-word.ts
1060
+ function check8(node, context) {
1061
+ if (!isBaseSubclass(node, context)) return;
1062
+ const body = node.body?.body ?? [];
1063
+ const configProp = body.find(
1064
+ (member) => member.type === "PropertyDefinition" && member.static === true && member.key?.name === "config"
1065
+ );
1066
+ if (!configProp?.value || configProp.value.type !== "ObjectExpression") return;
1067
+ const emitsProp = configProp.value.properties?.find(
1068
+ (prop) => prop.type === "Property" && prop.key?.name === "emits"
1069
+ );
1070
+ if (!emitsProp?.value || emitsProp.value.type !== "ArrayExpression") return;
1071
+ for (const element of emitsProp.value.elements ?? []) {
1072
+ if (!element || element.type !== "Literal") continue;
1073
+ const name = element.value;
1074
+ if (typeof name !== "string") continue;
1075
+ if (!name.includes("-")) {
1076
+ context.report({
1077
+ node: element,
1078
+ messageId: "singleWord",
1079
+ data: { name }
1080
+ });
1081
+ }
1082
+ }
1083
+ }
1084
+ var emitsMultiWord = createRule({
1085
+ meta: {
1086
+ type: "problem",
1087
+ docs: {
1088
+ description: "Require emit names in static config to be multi-word to avoid collision with native DOM events"
1089
+ },
1090
+ messages: {
1091
+ singleWord: 'Emit name "{{name}}" must be multi-word (e.g. "item-click" instead of "click") to avoid collisions with native DOM events.'
1092
+ }
1093
+ },
1094
+ createOnce(context) {
1095
+ return {
1096
+ ClassDeclaration(node) {
1097
+ check8(node, context);
1098
+ },
1099
+ ClassExpression(node) {
1100
+ check8(node, context);
1101
+ }
1102
+ };
1103
+ }
1104
+ });
1105
+
1106
+ // src/rules/components-pascal-case.ts
1107
+ function check9(node, context) {
1108
+ if (!isBaseSubclass(node, context)) return;
1109
+ const body = node.body?.body ?? [];
1110
+ const configProp = body.find(
1111
+ (member) => member.type === "PropertyDefinition" && member.static === true && member.key?.name === "config"
1112
+ );
1113
+ if (!configProp?.value || configProp.value.type !== "ObjectExpression") return;
1114
+ const componentsProp = configProp.value.properties?.find(
1115
+ (prop) => prop.type === "Property" && prop.key?.name === "components"
1116
+ );
1117
+ if (!componentsProp?.value || componentsProp.value.type !== "ObjectExpression") return;
1118
+ for (const prop of componentsProp.value.properties ?? []) {
1119
+ if (prop.type !== "Property") continue;
1120
+ const name = prop.key?.name ?? prop.key?.value;
1121
+ if (typeof name !== "string") continue;
1122
+ if (!isPascalCase(name)) {
1123
+ const fixed = toPascalCase(name);
1124
+ const fixedText = prop.key.type === "Literal" ? `'${fixed}'` : fixed;
1125
+ context.report({
1126
+ node: prop.key,
1127
+ messageId: "notPascalCase",
1128
+ data: { name },
1129
+ fix: (fixer) => fixer.replaceText(prop.key, fixedText)
1130
+ });
1131
+ }
1132
+ }
1133
+ }
1134
+ var componentsPascalCase = createRule({
1135
+ meta: {
1136
+ type: "problem",
1137
+ fixable: "code",
1138
+ docs: {
1139
+ description: "Require component keys in static config to be PascalCase"
1140
+ },
1141
+ messages: {
1142
+ notPascalCase: 'Component key "{{name}}" must be PascalCase (e.g. "MyComponent").'
1143
+ }
1144
+ },
1145
+ createOnce(context) {
1146
+ return {
1147
+ ClassDeclaration(node) {
1148
+ check9(node, context);
1149
+ },
1150
+ ClassExpression(node) {
1151
+ check9(node, context);
1152
+ }
1153
+ };
1154
+ }
1155
+ });
1156
+
1157
+ // src/rules/require-emit-declared-in-config.ts
1158
+ function collectDeclaredEmits(classNode) {
1159
+ const body = classNode.body?.body ?? [];
1160
+ const configProp = body.find(
1161
+ (m) => m.type === "PropertyDefinition" && m.static === true && m.key?.name === "config"
1162
+ );
1163
+ if (!configProp?.value || configProp.value.type !== "ObjectExpression") return /* @__PURE__ */ new Set();
1164
+ const emitsProp = configProp.value.properties?.find(
1165
+ (p) => p.type === "Property" && p.key?.name === "emits"
1166
+ );
1167
+ if (!emitsProp?.value || emitsProp.value.type !== "ArrayExpression") return /* @__PURE__ */ new Set();
1168
+ const names = /* @__PURE__ */ new Set();
1169
+ for (const el of emitsProp.value.elements ?? []) {
1170
+ if (el?.type === "Literal" && typeof el.value === "string") {
1171
+ names.add(el.value);
1172
+ }
1173
+ }
1174
+ return names;
1175
+ }
1176
+ function isThisEmit(node) {
1177
+ return node.type === "MemberExpression" && node.object?.type === "ThisExpression" && node.property?.name === "$emit";
1178
+ }
1179
+ var requireEmitDeclaredInConfig = createRule({
1180
+ meta: {
1181
+ type: "problem",
1182
+ docs: {
1183
+ description: "Require all this.$emit() calls to use event names declared in static config.emits"
1184
+ },
1185
+ messages: {
1186
+ undeclared: 'Emit "{{name}}" is not declared in static config.emits.'
1187
+ }
1188
+ },
1189
+ createOnce(context) {
1190
+ return {
1191
+ "ClassDeclaration, ClassExpression"(classNode) {
1192
+ if (!isBaseSubclass(classNode, context)) return;
1193
+ const declared = collectDeclaredEmits(classNode);
1194
+ walkNode2(classNode.body, (node) => {
1195
+ if (node.type !== "CallExpression") return;
1196
+ if (!isThisEmit(node.callee)) return;
1197
+ const firstArg = node.arguments?.[0];
1198
+ if (!firstArg || firstArg.type !== "Literal") return;
1199
+ const name = firstArg.value;
1200
+ if (typeof name !== "string") return;
1201
+ if (!declared.has(name)) {
1202
+ context.report({
1203
+ node: firstArg,
1204
+ messageId: "undeclared",
1205
+ data: { name }
1206
+ });
1207
+ }
1208
+ });
1209
+ }
1210
+ };
1211
+ }
1212
+ });
1213
+ function walkNode2(node, visit) {
1214
+ if (!node || typeof node !== "object") return;
1215
+ visit(node);
1216
+ for (const key of Object.keys(node)) {
1217
+ if (key === "parent") continue;
1218
+ const child = node[key];
1219
+ if (Array.isArray(child)) {
1220
+ for (const item of child) walkNode2(item, visit);
1221
+ } else if (child && typeof child === "object" && child.type) {
1222
+ walkNode2(child, visit);
1223
+ }
1224
+ }
1225
+ }
1226
+
1227
+ // src/rules/require-children-declared-in-config.ts
1228
+ function collectDeclaredComponents(classNode) {
1229
+ const body = classNode.body?.body ?? [];
1230
+ const configProp = body.find(
1231
+ (m) => m.type === "PropertyDefinition" && m.static === true && m.key?.name === "config"
1232
+ );
1233
+ if (!configProp?.value || configProp.value.type !== "ObjectExpression") return /* @__PURE__ */ new Set();
1234
+ const componentsProp = configProp.value.properties?.find(
1235
+ (p) => p.type === "Property" && p.key?.name === "components"
1236
+ );
1237
+ if (!componentsProp?.value || componentsProp.value.type !== "ObjectExpression") return /* @__PURE__ */ new Set();
1238
+ const names = /* @__PURE__ */ new Set();
1239
+ for (const prop of componentsProp.value.properties ?? []) {
1240
+ if (prop.type !== "Property") continue;
1241
+ const name = prop.key?.name ?? prop.key?.value;
1242
+ if (typeof name === "string") {
1243
+ names.add(name);
1244
+ }
1245
+ }
1246
+ return names;
1247
+ }
1248
+ function isThisChildren(node) {
1249
+ return node.type === "MemberExpression" && node.object?.type === "ThisExpression" && node.property?.name === "$children";
1250
+ }
1251
+ var requireChildrenDeclaredInConfig = createRule({
1252
+ meta: {
1253
+ type: "problem",
1254
+ docs: {
1255
+ description: "Require all this.$children accesses to use component names declared in static config.components"
1256
+ },
1257
+ messages: {
1258
+ undeclared: 'Component "{{name}}" is not declared in static config.components.'
1259
+ }
1260
+ },
1261
+ createOnce(context) {
1262
+ return {
1263
+ "ClassDeclaration, ClassExpression"(classNode) {
1264
+ if (!isBaseSubclass(classNode, context)) return;
1265
+ const declared = collectDeclaredComponents(classNode);
1266
+ walkNode3(classNode.body, (node) => {
1267
+ if (node.type !== "MemberExpression") return;
1268
+ if (!isThisChildren(node.object)) return;
1269
+ let name = null;
1270
+ if (!node.computed && node.property?.type === "Identifier") {
1271
+ name = node.property.name;
1272
+ } else if (node.computed && node.property?.type === "Literal" && typeof node.property.value === "string") {
1273
+ name = node.property.value;
1274
+ }
1275
+ if (name && !declared.has(name)) {
1276
+ context.report({
1277
+ node,
1278
+ messageId: "undeclared",
1279
+ data: { name }
1280
+ });
1281
+ }
1282
+ });
1283
+ }
1284
+ };
1285
+ }
1286
+ });
1287
+ function walkNode3(node, visit) {
1288
+ if (!node || typeof node !== "object") return;
1289
+ visit(node);
1290
+ for (const key of Object.keys(node)) {
1291
+ if (key === "parent") continue;
1292
+ const child = node[key];
1293
+ if (Array.isArray(child)) {
1294
+ for (const item of child) walkNode3(item, visit);
1295
+ } else if (child && typeof child === "object" && child.type) {
1296
+ walkNode3(child, visit);
1297
+ }
1298
+ }
1299
+ }
1300
+
1301
+ // src/rules/require-options-declared-in-config.ts
1302
+ function collectDeclaredOptions(classNode) {
1303
+ const body = classNode.body?.body ?? [];
1304
+ const configProp = body.find(
1305
+ (m) => m.type === "PropertyDefinition" && m.static === true && m.key?.name === "config"
1306
+ );
1307
+ if (!configProp?.value || configProp.value.type !== "ObjectExpression") return /* @__PURE__ */ new Set();
1308
+ const optionsProp = configProp.value.properties?.find(
1309
+ (p) => p.type === "Property" && p.key?.name === "options"
1310
+ );
1311
+ if (!optionsProp?.value || optionsProp.value.type !== "ObjectExpression") return /* @__PURE__ */ new Set();
1312
+ const names = /* @__PURE__ */ new Set();
1313
+ for (const prop of optionsProp.value.properties ?? []) {
1314
+ if (prop.type !== "Property") continue;
1315
+ const name = prop.key?.name ?? prop.key?.value;
1316
+ if (typeof name === "string") {
1317
+ names.add(toCamelCase(name));
1318
+ }
1319
+ }
1320
+ return names;
1321
+ }
1322
+ function isThisOptions(node) {
1323
+ return node.type === "MemberExpression" && node.object?.type === "ThisExpression" && node.property?.name === "$options";
1324
+ }
1325
+ var requireOptionsDeclaredInConfig = createRule({
1326
+ meta: {
1327
+ type: "problem",
1328
+ docs: {
1329
+ description: "Require all this.$options accesses to use option names declared in static config.options"
1330
+ },
1331
+ messages: {
1332
+ undeclared: 'Option "{{name}}" is not declared in static config.options.'
1333
+ }
1334
+ },
1335
+ createOnce(context) {
1336
+ return {
1337
+ "ClassDeclaration, ClassExpression"(classNode) {
1338
+ if (!isBaseSubclass(classNode, context)) return;
1339
+ const declared = collectDeclaredOptions(classNode);
1340
+ walkNode4(classNode.body, (node) => {
1341
+ if (node.type !== "MemberExpression") return;
1342
+ if (!isThisOptions(node.object)) return;
1343
+ let name = null;
1344
+ if (!node.computed && node.property?.type === "Identifier") {
1345
+ name = node.property.name;
1346
+ } else if (node.computed && node.property?.type === "Literal" && typeof node.property.value === "string") {
1347
+ name = toCamelCase(node.property.value);
1348
+ }
1349
+ if (name && !declared.has(name)) {
1350
+ context.report({
1351
+ node,
1352
+ messageId: "undeclared",
1353
+ data: { name }
1354
+ });
1355
+ }
1356
+ });
1357
+ }
1358
+ };
1359
+ }
1360
+ });
1361
+ function walkNode4(node, visit) {
1362
+ if (!node || typeof node !== "object") return;
1363
+ visit(node);
1364
+ for (const key of Object.keys(node)) {
1365
+ if (key === "parent") continue;
1366
+ const child = node[key];
1367
+ if (Array.isArray(child)) {
1368
+ for (const item of child) walkNode4(item, visit);
1369
+ } else if (child && typeof child === "object" && child.type) {
1370
+ walkNode4(child, visit);
1371
+ }
1372
+ }
1373
+ }
1374
+
1375
+ // src/rules/prefer-destructured-lookups.ts
1376
+ var TRACKED_PROPERTIES = /* @__PURE__ */ new Set(["$refs", "$options", "$children"]);
1377
+ function isTrackedLookup(node) {
1378
+ if (node.type === "MemberExpression" && node.object?.type === "MemberExpression" && node.object.object?.type === "ThisExpression" && node.object.property?.type === "Identifier" && TRACKED_PROPERTIES.has(node.object.property.name) && node.property?.type === "Identifier" && !node.computed) {
1379
+ return { prop: node.object.property.name, name: node.property.name };
1380
+ }
1381
+ return null;
1382
+ }
1383
+ function findEnclosingMethod(ancestors) {
1384
+ for (let i = ancestors.length - 1; i >= 0; i--) {
1385
+ const node = ancestors[i];
1386
+ if (node.type === "MethodDefinition") return node;
1387
+ }
1388
+ return null;
1389
+ }
1390
+ var preferDestructuredLookups = createRule({
1391
+ meta: {
1392
+ type: "suggestion",
1393
+ docs: {
1394
+ description: "Prefer destructuring this.$refs, this.$options and this.$children into local variables when accessed multiple times in the same method"
1395
+ },
1396
+ messages: {
1397
+ preferDestructured: '"this.{{prop}}.{{name}}" is accessed {{count}} times. Destructure it into a local variable to avoid repeated lookups.'
1398
+ }
1399
+ },
1400
+ createOnce(context) {
1401
+ const methodLookups = /* @__PURE__ */ new Map();
1402
+ return {
1403
+ MemberExpression(node) {
1404
+ const match = isTrackedLookup(node);
1405
+ if (!match) return;
1406
+ const ancestors = context.getAncestors?.() ?? context.sourceCode?.getAncestors?.(node) ?? [];
1407
+ const method = findEnclosingMethod(ancestors);
1408
+ if (!method) return;
1409
+ const cls = findEnclosingClass(ancestors);
1410
+ if (!cls || !isBaseSubclass(cls, context)) return;
1411
+ if (!methodLookups.has(method)) methodLookups.set(method, /* @__PURE__ */ new Map());
1412
+ const map = methodLookups.get(method);
1413
+ const key = `${match.prop}.${match.name}`;
1414
+ const list = map.get(key) ?? [];
1415
+ list.push(node);
1416
+ map.set(key, list);
1417
+ },
1418
+ "MethodDefinition:exit"(node) {
1419
+ const map = methodLookups.get(node);
1420
+ if (!map) return;
1421
+ methodLookups.delete(node);
1422
+ for (const [key, nodes] of map) {
1423
+ if (nodes.length < 2) continue;
1424
+ const [prop, name] = key.split(".");
1425
+ context.report({
1426
+ node: nodes[0],
1427
+ messageId: "preferDestructured",
1428
+ data: { prop, name, count: String(nodes.length) }
1429
+ });
1430
+ }
1431
+ }
1432
+ };
1433
+ }
1434
+ });
1435
+
1436
+ // src/rules/no-dollar-prefix.ts
1437
+ var noDollarPrefix = createRule({
1438
+ meta: {
1439
+ type: "problem",
1440
+ docs: {
1441
+ description: 'Disallow user-defined methods and properties prefixed with "$" in Base subclasses \u2014 "$" is reserved for js-toolkit framework members'
1442
+ },
1443
+ messages: {
1444
+ noDollarPrefix: '"${{name}}" uses the "$" prefix, which is reserved for js-toolkit framework members. Rename it without the "$" prefix.'
1445
+ }
1446
+ },
1447
+ createOnce(context) {
1448
+ return {
1449
+ ClassDeclaration(node) {
1450
+ check10(node, context);
1451
+ },
1452
+ ClassExpression(node) {
1453
+ check10(node, context);
1454
+ }
1455
+ };
1456
+ }
1457
+ });
1458
+ function check10(node, context) {
1459
+ if (!isBaseSubclass(node, context)) return;
1460
+ for (const member of node.body?.body ?? []) {
1461
+ if (member.static) continue;
1462
+ if (member.type !== "MethodDefinition" && member.type !== "PropertyDefinition") continue;
1463
+ const name = member.key?.name ?? "";
1464
+ if (name.startsWith("$")) {
1465
+ context.report({
1466
+ node: member.key,
1467
+ messageId: "noDollarPrefix",
1468
+ data: { name: name.slice(1) }
1469
+ });
1470
+ }
1471
+ }
1472
+ }
1473
+
1474
+ // src/rules/require-destroyed-cleanup.ts
1475
+ var SETUP_CALLS = /* @__PURE__ */ new Set(["setTimeout", "setInterval", "requestAnimationFrame"]);
1476
+ var requireDestroyedCleanup = createRule({
1477
+ meta: {
1478
+ type: "suggestion",
1479
+ docs: {
1480
+ description: "Require a destroyed() method in Base subclasses that use setTimeout, setInterval or requestAnimationFrame"
1481
+ },
1482
+ messages: {
1483
+ requireDestroyed: "This component uses {{calls}} but has no destroyed() method. Add destroyed() to clear timers and avoid memory leaks."
1484
+ }
1485
+ },
1486
+ createOnce(context) {
1487
+ const classTimers = /* @__PURE__ */ new Map();
1488
+ const classHasDestroyed = /* @__PURE__ */ new Map();
1489
+ return {
1490
+ ClassDeclaration(node) {
1491
+ classTimers.set(node, /* @__PURE__ */ new Set());
1492
+ classHasDestroyed.set(node, false);
1493
+ },
1494
+ ClassExpression(node) {
1495
+ classTimers.set(node, /* @__PURE__ */ new Set());
1496
+ classHasDestroyed.set(node, false);
1497
+ },
1498
+ MethodDefinition(node) {
1499
+ if (node.key?.name === "destroyed") {
1500
+ const sourceCode = context.sourceCode ?? context.getSourceCode?.();
1501
+ const ancestors = context.getAncestors?.() ?? sourceCode?.getAncestors?.(node) ?? [];
1502
+ for (let i = ancestors.length - 1; i >= 0; i--) {
1503
+ const a = ancestors[i];
1504
+ if (a.type === "ClassDeclaration" || a.type === "ClassExpression") {
1505
+ classHasDestroyed.set(a, true);
1506
+ break;
1507
+ }
1508
+ }
1509
+ }
1510
+ },
1511
+ CallExpression(node) {
1512
+ if (node.callee?.type !== "Identifier") return;
1513
+ if (!SETUP_CALLS.has(node.callee.name)) return;
1514
+ const sourceCode = context.sourceCode ?? context.getSourceCode?.();
1515
+ const ancestors = context.getAncestors?.() ?? sourceCode?.getAncestors?.(node) ?? [];
1516
+ for (let i = ancestors.length - 1; i >= 0; i--) {
1517
+ const a = ancestors[i];
1518
+ if (a.type === "ClassDeclaration" || a.type === "ClassExpression") {
1519
+ if (!isBaseSubclass(a, context)) break;
1520
+ classTimers.get(a)?.add(node.callee.name);
1521
+ break;
1522
+ }
1523
+ }
1524
+ },
1525
+ "ClassDeclaration:exit"(node) {
1526
+ reportIfNeeded(node, context, classTimers, classHasDestroyed);
1527
+ },
1528
+ "ClassExpression:exit"(node) {
1529
+ reportIfNeeded(node, context, classTimers, classHasDestroyed);
1530
+ }
1531
+ };
1532
+ }
1533
+ });
1534
+ function reportIfNeeded(node, context, classTimers, classHasDestroyed) {
1535
+ const timers = classTimers.get(node);
1536
+ const hasDestroyed = classHasDestroyed.get(node);
1537
+ classTimers.delete(node);
1538
+ classHasDestroyed.delete(node);
1539
+ if (!timers || timers.size === 0) return;
1540
+ if (hasDestroyed) return;
1541
+ context.report({
1542
+ node: node.id ?? node,
1543
+ messageId: "requireDestroyed",
1544
+ data: { calls: [...timers].join(", ") }
1545
+ });
1546
+ }
1547
+
1003
1548
  // src/index.ts
1004
1549
  var PLUGIN_NAME = "js-toolkit";
1005
1550
  var rules = {
@@ -1022,7 +1567,16 @@ var rules = {
1022
1567
  "prefer-ref-over-query-selector": preferRefOverQuerySelector,
1023
1568
  "require-refs-declared-in-config": requireRefsDeclaredInConfig,
1024
1569
  "no-manual-intersection-observer": noManualIntersectionObserver,
1025
- "no-manual-mutation-observer": noManualMutationObserver
1570
+ "no-manual-mutation-observer": noManualMutationObserver,
1571
+ "emits-kebab-case": emitsKebabCase,
1572
+ "emits-multi-word": emitsMultiWord,
1573
+ "components-pascal-case": componentsPascalCase,
1574
+ "require-emit-declared-in-config": requireEmitDeclaredInConfig,
1575
+ "require-children-declared-in-config": requireChildrenDeclaredInConfig,
1576
+ "require-options-declared-in-config": requireOptionsDeclaredInConfig,
1577
+ "prefer-destructured-lookups": preferDestructuredLookups,
1578
+ "no-dollar-prefix": noDollarPrefix,
1579
+ "require-destroyed-cleanup": requireDestroyedCleanup
1026
1580
  };
1027
1581
  var recommendedRules = {
1028
1582
  [`${PLUGIN_NAME}/require-config`]: "error",
@@ -1044,7 +1598,16 @@ var recommendedRules = {
1044
1598
  [`${PLUGIN_NAME}/prefer-ref-over-query-selector`]: "warn",
1045
1599
  [`${PLUGIN_NAME}/require-refs-declared-in-config`]: "error",
1046
1600
  [`${PLUGIN_NAME}/no-manual-intersection-observer`]: "warn",
1047
- [`${PLUGIN_NAME}/no-manual-mutation-observer`]: "warn"
1601
+ [`${PLUGIN_NAME}/no-manual-mutation-observer`]: "warn",
1602
+ [`${PLUGIN_NAME}/emits-kebab-case`]: "error",
1603
+ [`${PLUGIN_NAME}/emits-multi-word`]: "error",
1604
+ [`${PLUGIN_NAME}/components-pascal-case`]: "error",
1605
+ [`${PLUGIN_NAME}/require-emit-declared-in-config`]: "error",
1606
+ [`${PLUGIN_NAME}/require-children-declared-in-config`]: "error",
1607
+ [`${PLUGIN_NAME}/require-options-declared-in-config`]: "error",
1608
+ [`${PLUGIN_NAME}/prefer-destructured-lookups`]: "warn",
1609
+ [`${PLUGIN_NAME}/no-dollar-prefix`]: "error",
1610
+ [`${PLUGIN_NAME}/require-destroyed-cleanup`]: "warn"
1048
1611
  };
1049
1612
  var base = eslintCompatPlugin({
1050
1613
  meta: {
@@ -1059,6 +1622,7 @@ plugin.configs["recommended"] = {
1059
1622
  };
1060
1623
  var index_default = plugin;
1061
1624
  export {
1062
- index_default as default
1625
+ index_default as default,
1626
+ plugin as jsToolkit
1063
1627
  };
1064
1628
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../../node_modules/@oxlint/plugins/index.js", "../src/utils/ast.ts", "../src/rules/require-config.ts", "../src/rules/require-config-name-pascal-case.ts", "../src/rules/refs-camel-case.ts", "../src/rules/options-camel-case.ts", "../src/rules/async-lifecycle-methods.ts", "../src/rules/on-handler-naming.ts", "../src/rules/on-global-handler-prefix.ts", "../src/rules/no-deprecated-properties.ts", "../src/rules/no-dispatch-event.ts", "../src/rules/no-shadow-dom.ts", "../src/rules/no-create-app.ts", "../src/rules/no-event-listener-methods.ts", "../src/rules/refs-plural-multiple.ts", "../src/rules/no-deep-utils-import.ts", "../src/rules/refs-no-bracket-access.ts", "../src/rules/no-redundant-with-mount-when-in-view.ts", "../src/rules/prefer-ref-over-query-selector.ts", "../src/rules/require-refs-declared-in-config.ts", "../src/rules/no-manual-intersection-observer.ts", "../src/rules/no-manual-mutation-observer.ts", "../src/index.ts"],
4
- "sourcesContent": ["//#region src-js/package/define.ts\n/**\n* Define a plugin.\n*\n* No-op function, just to provide type safety. Input is passed through unchanged.\n*\n* @param plugin - Plugin to define\n* @returns Same plugin as passed in\n*/\nfunction definePlugin(plugin) {\n\treturn plugin;\n}\n/**\n* Define a rule.\n*\n* No-op function, just to provide type safety. Input is passed through unchanged.\n*\n* @param rule - Rule to define\n* @returns Same rule as passed in\n*/\nfunction defineRule(rule) {\n\treturn rule;\n}\n//#endregion\n//#region src-js/package/compat.ts\nconst EMPTY_VISITOR = {};\n/**\n* Convert a plugin which used Oxlint's `createOnce` API to also work with ESLint.\n*\n* If any of the plugin's rules use the Oxlint alternative `createOnce` API,\n* add ESLint-compatible `create` methods to those rules, which delegate to `createOnce`.\n* This makes the plugin compatible with ESLint.\n*\n* The `plugin` object passed in is mutated in-place.\n*\n* @param plugin - Plugin to convert\n* @returns Plugin with all rules having `create` method\n* @throws {Error} If `plugin` is not an object, or `plugin.rules` is not an object\n*/\nfunction eslintCompatPlugin(plugin) {\n\tif (typeof plugin != \"object\" || !plugin) throw Error(\"Plugin must be an object\");\n\tlet { rules } = plugin;\n\tif (typeof rules != \"object\" || !rules) throw Error(\"Plugin must have an object as `rules` property\");\n\tlet afterHooksState = new AfterHooksState();\n\tfor (let ruleName in rules) Object.hasOwn(rules, ruleName) && convertRule(rules[ruleName], afterHooksState);\n\treturn plugin;\n}\n/**\n* Class containing state for tracking if any `after` hooks for a plugin's rules need to be called.\n*\n* # Aims\n*\n* Aims are:\n* 1. `after` hook of each rule runs after all other AST visit functions, and CFG event handlers.\n* 2. `after` hooks for *all* a plugin's rules run after *all* that plugin's rules have completed visiting AST.\n* 3. `after` hooks for *all* a plugin's rules run before *any* of plugin's rules begin linting another file.\n* 4. In the case of an error during AST traversal, `after` hooks are always still run.\n*\n* The above exactly matches the behavior when running a `createOnce` rule in Oxlint.\n*\n* # Why this is important\n*\n* All the complication comes from ensuring `after` hooks run even after an error during AST traversal.\n*\n* In ESLint CLI, an error will crash the process, so it doesn't particularly matter if `after` hooks run or not,\n* but language servers will typically swallow errors, and keep the process running.\n*\n* Rules using `before` and `after` hooks will often rely on both hooks running in a predictable order,\n* to maintain some internal state. For example, they may use `before` and `after` hooks to maintain a per-file\n* cache of data which is shared between rules. The cache use case is why rule (2) above is important.\n*\n* Below is an example of using `before` and `after` hooks to maintain a per-file cache, shared between rules.\n* It relies on all `before` hooks running before any rule starts visiting the AST,\n* and all `after` hooks running after all rules have finished visiting the AST.\n*\n* ```ts\n* let cache: Data | null = null;\n*\n* let numRunningRules = 0;\n*\n* const setupCache = (context) => {\n* if (cache === null) cache = new Data(context);\n* numRunningRules++;\n* };\n*\n* const teardownCache = () => {\n* numRunningRules--;\n* if (numRunningRules === 0) cache = null;\n* };\n*\n* const rule1 = {\n* createOnce(context) {\n* return {\n* before() {\n* setupCache(context);\n* },\n* Identifier(node) {\n* // Use `cache`\n* },\n* after: teardownCache,\n* };\n* },\n* };\n*\n* const rule2 = {\n* // Same as above\n* };\n*\n* const rule3 = {\n* // Same as above\n* };\n* ```\n*\n* If `after` hooks did not always run, the next lint run could get stale state, and malfunction.\n* If `after` hooks ran in the wrong order (e.g. after some `before` hooks for next file),\n* `numRunningRules` would never get to 0, and cache would never be cleared.\n*\n* Note that because all rules run together in a single AST traversal, if a rule from plugin X throws an error,\n* it can disrupt rules from plugin Y. This would make it hard to debug.\n*\n* # Mechanism\n*\n* ## Initialization\n*\n* Rules with an `after` hook register themselves by:\n*\n* 1. Calling `registerResetFunction` to register a function to run `after` hook and clean up internal state.\n* This call adds the reset fn to `resetFunctions`, and adds `AFTER_HOOK_INACTIVE` to `pendingStates`.\n* 2. Adding an `onCodePathEnd` CFG event handler to the visitor which calls `ruleFinished` at end of AST traversal.\n*\n* ## Per-file setup\n*\n* Before linting a file, `create` will call `setupAfterHook` which is created by `createContextAndVisitor`.\n* This registers that the `after` hook for the rule needs to run, by setting `pendingStates[ruleIndex]`\n* to `AFTER_HOOK_PENDING`, and incrementing `pendingCount`.\n*\n* If a cleanup microtask has not been scheduled yet, one is scheduled now (see reason below).\n*\n* ## Normal operation\n*\n* AST traversal for each rule ends with `ruleFinished` hook being called from `onCodePathEnd` CFG event handler.\n* It increments `lintFinishedCount`. If `lintFinishedCount` equals `pendingCount`, all rules have finished linting\n* the file, and `reset` is called, which calls all the pending `after` hooks.\n*\n* ## Error handling\n*\n* If an error is thrown during AST traversal, we ensure that `after` hooks are still run by 2 mechanisms:\n*\n* ### 1. Next microtick\n*\n* Before any rules began linting files, a microtask was scheduled, which runs on next micro-tick.\n* All language servers we're aware of run each lint task in a separate tick, so this microtask will run in next tick\n* after a linting run, before the next lint task starts.\n*\n* If the linting run completed successfully, the microtask does nothing.\n*\n* But if an error was thrown during AST traversal, this will be visible from the state of `pendingCount`.\n* The microtask will run any `after` hooks which need to be run, and reset state to reflect that there are\n* no more pending `after` hooks.\n*\n* ### 2. Fallback: Next lint run\n*\n* Before linting any file, the state of `pendingCount` is checked.\n* If any `after` hooks are still pending, they are run immediately.\n* They're run before the `context` objects in `createOnce` closures are updated to the next file,\n* so they run with access to the old `context` object from the last file.\n*\n* This fallback should not be required, but it's included as \"belt and braces\", to handle if any language server\n* or other environment running ESLint programmatically, does not pause a tick between linting runs.\n*/\nvar AfterHooksState = class {\n\tresetFunctions = [];\n\tpendingStates = [];\n\tpendingCount = 0;\n\tlintFinishedCount = 0;\n\tresetIsScheduled = !1;\n\tsourceCode = null;\n\tresetMicrotask = this.resetMicrotaskImpl.bind(this);\n\t/**\n\t* Register a function to run `after` hook for a rule, and reset state.\n\t* @param reset - Function to run `after` hook and reset state\n\t* @returns Index of rule\n\t*/\n\tregisterResetFunction(reset) {\n\t\tlet { pendingStates } = this, index = pendingStates.length;\n\t\treturn pendingStates.push(0), this.resetFunctions.push(reset), index;\n\t}\n\t/**\n\t* Register that a rule with `after` hook has completed linting a file.\n\t* Called by `onCodePathEnd` CFG event handler which is added to visitor for rules with `after` hooks.\n\t*\n\t* If all rules with an `after` hook which needs to be run have completed linting the file, run all `after` hooks.\n\t*/\n\truleFinished() {\n\t\tthis.lintFinishedCount++, this.lintFinishedCount === this.pendingCount && this.reset(!1);\n\t}\n\t/**\n\t* Call all reset functions where corresponding entry in `pendingStates` is `AFTER_HOOK_PENDING`.\n\t* Should only be called when some `after` hooks are pending.\n\t*\n\t* @param ignoreErrors - `true` to catch and silently ignore any errors which occur in `after` hooks.\n\t* `false` to throw them,\n\t* @throws {unknown} If `ignoreErrors` is `false` and an error occurs in any `after` hooks.\n\t*/\n\treset(ignoreErrors) {\n\t\tthis.pendingCount;\n\t\tlet { resetFunctions, pendingStates } = this, hooksLen = pendingStates.length, hasError = !1, error;\n\t\tfor (let i = 0; i < hooksLen; i++) if (pendingStates[i] !== 0) {\n\t\t\tpendingStates[i] = 0;\n\t\t\ttry {\n\t\t\t\tresetFunctions[i]();\n\t\t\t} catch (e) {\n\t\t\t\thasError === !1 && (hasError = !0, error = e);\n\t\t\t}\n\t\t}\n\t\tif (this.pendingCount = 0, this.lintFinishedCount = 0, this.sourceCode = null, hasError === !0 && ignoreErrors === !1) throw error;\n\t}\n\t/**\n\t* Schedule a microtask to run `reset` functions.\n\t*/\n\tscheduleReset() {\n\t\tqueueMicrotask(this.resetMicrotask), this.resetIsScheduled = !0;\n\t}\n\t/**\n\t* Function which is scheduled as the cleanup microtask.\n\t* `scheduleReset` uses `resetMicrotask` which is this method bound to `this`.\n\t*/\n\tresetMicrotaskImpl() {\n\t\tthis.resetIsScheduled = !1, this.pendingCount !== 0 && this.reset(!0);\n\t}\n};\n/**\n* Convert a rule.\n*\n* The `rule` object passed in is mutated in-place.\n*\n* @param rule - Rule to convert\n* @param afterHooksState - State of `after` hooks\n* @throws {Error} If `rule` is not an object\n*/\nfunction convertRule(rule, afterHooksState) {\n\tif (typeof rule != \"object\" || !rule) throw Error(\"Rule must be an object\");\n\tif (\"create\" in rule) return;\n\tlet context = null, visitor, beforeHook, setupAfterHook;\n\trule.create = (eslintContext) => {\n\t\tcontext === null && ({context, visitor, beforeHook, setupAfterHook} = createContextAndVisitor(rule, afterHooksState));\n\t\tlet eslintFileContext = Object.getPrototypeOf(eslintContext);\n\t\tif (setupAfterHook !== null) {\n\t\t\tlet { sourceCode } = eslintFileContext;\n\t\t\tafterHooksState.sourceCode !== sourceCode && (afterHooksState.sourceCode = sourceCode, afterHooksState.pendingCount !== 0 && afterHooksState.reset(!0));\n\t\t}\n\t\treturn Object.defineProperties(context, {\n\t\t\tid: { value: eslintContext.id },\n\t\t\toptions: { value: eslintContext.options },\n\t\t\treport: { value: eslintContext.report }\n\t\t}), Object.setPrototypeOf(context, eslintFileContext), beforeHook !== null && beforeHook() === !1 ? EMPTY_VISITOR : (setupAfterHook !== null && (setupAfterHook(eslintFileContext.sourceCode.ast), afterHooksState.resetIsScheduled === !1 && afterHooksState.scheduleReset()), visitor);\n\t};\n}\nconst FILE_CONTEXT = Object.freeze({\n\tget filename() {\n\t\tthrow Error(\"Cannot access `context.filename` in `createOnce`\");\n\t},\n\tgetFilename() {\n\t\tthrow Error(\"Cannot call `context.getFilename` in `createOnce`\");\n\t},\n\tget physicalFilename() {\n\t\tthrow Error(\"Cannot access `context.physicalFilename` in `createOnce`\");\n\t},\n\tgetPhysicalFilename() {\n\t\tthrow Error(\"Cannot call `context.getPhysicalFilename` in `createOnce`\");\n\t},\n\tget cwd() {\n\t\tthrow Error(\"Cannot access `context.cwd` in `createOnce`\");\n\t},\n\tgetCwd() {\n\t\tthrow Error(\"Cannot call `context.getCwd` in `createOnce`\");\n\t},\n\tget sourceCode() {\n\t\tthrow Error(\"Cannot access `context.sourceCode` in `createOnce`\");\n\t},\n\tgetSourceCode() {\n\t\tthrow Error(\"Cannot call `context.getSourceCode` in `createOnce`\");\n\t},\n\tget languageOptions() {\n\t\tthrow Error(\"Cannot access `context.languageOptions` in `createOnce`\");\n\t},\n\tget settings() {\n\t\tthrow Error(\"Cannot access `context.settings` in `createOnce`\");\n\t},\n\textend(extension) {\n\t\treturn Object.freeze(Object.assign(Object.create(this), extension));\n\t},\n\tget parserOptions() {\n\t\tthrow Error(\"Cannot access `context.parserOptions` in `createOnce`\");\n\t},\n\tget parserPath() {\n\t\tthrow Error(\"Cannot access `context.parserPath` in `createOnce`\");\n\t}\n});\n/**\n* Call `createOnce` method of rule, and return `Context`, `Visitor`, and `beforeHook` (if any).\n*\n* @param rule - Rule with `createOnce` method\n* @param afterHooksState - State of `after` hooks\n* @returns Object with `context`, `visitor`, and `beforeHook` properties,\n* and `setupAfterHook` function if visitor has an `after` hook\n*/\nfunction createContextAndVisitor(rule, afterHooksState) {\n\tlet { createOnce } = rule;\n\tif (createOnce == null) throw Error(\"Rules must define either a `create` or `createOnce` method\");\n\tif (typeof createOnce != \"function\") throw Error(\"Rule `createOnce` property must be a function\");\n\tlet context = Object.create(FILE_CONTEXT, {\n\t\tid: {\n\t\t\tvalue: null,\n\t\t\tenumerable: !0,\n\t\t\tconfigurable: !0\n\t\t},\n\t\toptions: {\n\t\t\tvalue: null,\n\t\t\tenumerable: !0,\n\t\t\tconfigurable: !0\n\t\t},\n\t\treport: {\n\t\t\tvalue() {\n\t\t\t\tthrow Error(\"Cannot report errors in `createOnce`\");\n\t\t\t},\n\t\t\tenumerable: !0,\n\t\t\tconfigurable: !0\n\t\t}\n\t}), { before: beforeHook, after: afterHook, ...visitor } = createOnce.call(rule, context);\n\tif (beforeHook === void 0) beforeHook = null;\n\telse if (beforeHook !== null && typeof beforeHook != \"function\") throw Error(\"`before` property of visitor must be a function if defined\");\n\tlet setupAfterHook = null;\n\tif (afterHook != null) {\n\t\tif (typeof afterHook != \"function\") throw Error(\"`after` property of visitor must be a function if defined\");\n\t\tlet program = null, ruleIndex = afterHooksState.registerResetFunction(() => {\n\t\t\tprogram = null, afterHook();\n\t\t});\n\t\tsetupAfterHook = (ast) => {\n\t\t\tprogram = ast, afterHooksState.pendingStates[ruleIndex] = 1, afterHooksState.pendingCount++;\n\t\t};\n\t\tlet onCodePathEnd = visitor.onCodePathEnd;\n\t\tvisitor.onCodePathEnd = onCodePathEnd == null ? function(_codePath, node) {\n\t\t\tnode === program && afterHooksState.ruleFinished();\n\t\t} : function(codePath, node) {\n\t\t\tonCodePathEnd.call(this, codePath, node), node === program && afterHooksState.ruleFinished();\n\t\t};\n\t}\n\treturn {\n\t\tcontext,\n\t\tvisitor,\n\t\tbeforeHook,\n\t\tsetupAfterHook\n\t};\n}\n//#endregion\nexport { definePlugin, defineRule, eslintCompatPlugin };\n", "/**\n * ESLint v9 compatible AST node types used across rules.\n * We use loose typings here since oxlint/eslint expose their own node types.\n */\n\nexport type Node = Record<string, any>;\nexport type RuleContext = Record<string, any>;\n\nexport type RuleMeta = {\n type?: 'problem' | 'suggestion' | 'layout';\n fixable?: 'code' | 'whitespace';\n hasSuggestions?: boolean;\n docs?: { description?: string };\n messages?: Record<string, string>;\n};\n\nexport function createRule<V extends Record<string, (node: Node) => unknown>>(rule: {\n meta?: RuleMeta;\n createOnce(context: RuleContext): V;\n}): { meta?: RuleMeta; createOnce(context: RuleContext): V } {\n return rule;\n}\n\nexport const LIFECYCLE_METHODS = new Set([\n 'mounted',\n 'destroyed',\n 'updated',\n 'terminated',\n 'ticked',\n 'scrolled',\n 'resized',\n 'moved',\n 'loaded',\n 'keyed',\n]);\n\nexport const TOOLKIT_PACKAGE = '@studiometa/js-toolkit';\n\n/**\n * Returns true if a class declaration extends an identifier imported from\n * @studiometa/js-toolkit, or extends a bare identifier named `Base`.\n *\n * This is a heuristic \u2014 we cannot do full type resolution in a lint rule.\n */\nexport function isBaseSubclass(node: Node, context: RuleContext): boolean {\n if (node.type !== 'ClassDeclaration' && node.type !== 'ClassExpression') {\n return false;\n }\n\n if (!node.superClass) {\n return false;\n }\n\n const superName = node.superClass.type === 'Identifier' ? node.superClass.name : null;\n\n if (!superName) {\n return false;\n }\n\n // Fast path: class extends Base\n if (superName === 'Base') {\n return true;\n }\n\n // Check if the superclass identifier is imported from @studiometa/js-toolkit\n const sourceCode = context.sourceCode ?? context.getSourceCode?.();\n const ast = sourceCode?.ast;\n\n if (!ast) {\n return false;\n }\n\n for (const node of ast.body) {\n if (node.type !== 'ImportDeclaration') continue;\n if (node.source.value !== TOOLKIT_PACKAGE) continue;\n\n for (const specifier of node.specifiers) {\n if (specifier.type === 'ImportSpecifier' && specifier.local.name === superName) {\n return true;\n }\n }\n }\n\n return false;\n}\n\n/**\n * Returns true if the string is camelCase (starts lowercase, no separators).\n */\nexport function isCamelCase(value: string): boolean {\n return /^[a-z][a-zA-Z0-9]*$/.test(value);\n}\n\n/**\n * Returns true if the string is PascalCase.\n */\nexport function isPascalCase(value: string): boolean {\n return /^[A-Z][a-zA-Z0-9]*$/.test(value);\n}\n\n/**\n * Converts a kebab-case, snake_case or PascalCase string to camelCase.\n */\nexport function toCamelCase(value: string): string {\n return value\n .replace(/[-_](.)/g, (_, c: string) => c.toUpperCase())\n .replace(/^[A-Z]/, (c) => c.toLowerCase());\n}\n\n/**\n * Converts a kebab-case, snake_case or camelCase string to PascalCase.\n */\nexport function toPascalCase(value: string): string {\n return value\n .replace(/[-_](.)/g, (_, c: string) => c.toUpperCase())\n .replace(/^[a-z]/, (c) => c.toUpperCase());\n}\n\n/**\n * Walks up ancestor nodes to find the nearest class declaration/expression.\n */\nexport function findEnclosingClass(ancestors: Node[]): Node | null {\n for (let i = ancestors.length - 1; i >= 0; i--) {\n const node = ancestors[i];\n if (node.type === 'ClassDeclaration' || node.type === 'ClassExpression') {\n return node;\n }\n }\n return null;\n}\n", "import { isBaseSubclass, type Node, type RuleContext, createRule } from '../utils/ast.ts';\n\nexport const requireConfig = createRule({\n meta: {\n type: 'problem',\n docs: {\n description: 'Require a static config property on classes extending Base',\n },\n messages: {\n missingConfig: 'Classes extending Base must define a static config property.',\n missingName: 'The static config must include a name property.',\n },\n },\n createOnce(context: RuleContext) {\n return {\n ClassDeclaration(node: Node) {\n check(node, context);\n },\n ClassExpression(node: Node) {\n check(node, context);\n },\n };\n },\n});\n\nfunction check(node: Node, context: RuleContext) {\n if (!isBaseSubclass(node, context)) return;\n\n const body: Node[] = node.body?.body ?? [];\n\n const configProp = body.find(\n (member: Node) =>\n member.type === 'PropertyDefinition' &&\n member.static === true &&\n member.key?.name === 'config',\n );\n\n if (!configProp) {\n context.report({ node, messageId: 'missingConfig' });\n return;\n }\n\n // Check that config has a `name` property\n const value = configProp.value;\n if (!value || value.type !== 'ObjectExpression') return;\n\n const hasName = value.properties?.some(\n (prop: Node) => prop.type === 'Property' && prop.key?.name === 'name' && prop.value?.value,\n );\n\n if (!hasName) {\n context.report({ node: configProp, messageId: 'missingName' });\n }\n}\n", "import {\n isBaseSubclass,\n isPascalCase,\n toPascalCase,\n type Node,\n type RuleContext,\n createRule,\n} from '../utils/ast.ts';\n\nexport const requireConfigNamePascalCase = createRule({\n meta: {\n type: 'problem',\n fixable: 'code',\n docs: {\n description: 'Require config.name to be PascalCase on classes extending Base',\n },\n messages: {\n notPascalCase: 'config.name \"{{name}}\" must be PascalCase.',\n },\n },\n createOnce(context: RuleContext) {\n return {\n ClassDeclaration(node: Node) {\n check(node, context);\n },\n ClassExpression(node: Node) {\n check(node, context);\n },\n };\n },\n});\n\nfunction check(node: Node, context: RuleContext) {\n if (!isBaseSubclass(node, context)) return;\n\n const body: Node[] = node.body?.body ?? [];\n\n const configProp = body.find(\n (member: Node) =>\n member.type === 'PropertyDefinition' &&\n member.static === true &&\n member.key?.name === 'config',\n );\n\n if (!configProp?.value || configProp.value.type !== 'ObjectExpression') return;\n\n const nameProp = configProp.value.properties?.find(\n (prop: Node) => prop.type === 'Property' && prop.key?.name === 'name',\n );\n\n if (!nameProp) return;\n\n const nameValue = nameProp.value?.value;\n if (typeof nameValue !== 'string') return;\n\n if (!isPascalCase(nameValue)) {\n context.report({\n node: nameProp.value,\n messageId: 'notPascalCase',\n data: { name: nameValue },\n fix: (fixer: any) => fixer.replaceText(nameProp.value, `'${toPascalCase(nameValue)}'`),\n });\n }\n}\n", "import {\n isBaseSubclass,\n isCamelCase,\n toCamelCase,\n type Node,\n type RuleContext,\n createRule,\n} from '../utils/ast.ts';\n\nexport const refsCamelCase = createRule({\n meta: {\n type: 'problem',\n fixable: 'code',\n docs: {\n description: 'Require ref names in static config to be camelCase',\n },\n messages: {\n notCamelCase: 'Ref name \"{{name}}\" must be camelCase.',\n },\n },\n createOnce(context: RuleContext) {\n return {\n ClassDeclaration(node: Node) {\n check(node, context);\n },\n ClassExpression(node: Node) {\n check(node, context);\n },\n };\n },\n});\n\nfunction check(node: Node, context: RuleContext) {\n if (!isBaseSubclass(node, context)) return;\n\n const body: Node[] = node.body?.body ?? [];\n\n const configProp = body.find(\n (member: Node) =>\n member.type === 'PropertyDefinition' &&\n member.static === true &&\n member.key?.name === 'config',\n );\n\n if (!configProp?.value || configProp.value.type !== 'ObjectExpression') return;\n\n const refsProp = configProp.value.properties?.find(\n (prop: Node) => prop.type === 'Property' && prop.key?.name === 'refs',\n );\n\n if (!refsProp?.value || refsProp.value.type !== 'ArrayExpression') return;\n\n for (const element of refsProp.value.elements ?? []) {\n if (!element || element.type !== 'Literal') continue;\n const raw = element.value;\n if (typeof raw !== 'string') continue;\n // Strip the multiple-ref suffix before checking casing\n const name = raw.endsWith('[]') ? raw.slice(0, -2) : raw;\n if (!isCamelCase(name)) {\n const fixed = toCamelCase(name) + (raw.endsWith('[]') ? '[]' : '');\n context.report({\n node: element,\n messageId: 'notCamelCase',\n data: { name },\n fix: (fixer: any) => fixer.replaceText(element, `'${fixed}'`),\n });\n }\n }\n}\n", "import {\n isBaseSubclass,\n isCamelCase,\n toCamelCase,\n type Node,\n type RuleContext,\n createRule,\n} from '../utils/ast.ts';\n\nexport const optionsCamelCase = createRule({\n meta: {\n type: 'problem',\n fixable: 'code',\n docs: {\n description: 'Require option keys in static config to be camelCase',\n },\n messages: {\n notCamelCase: 'Option key \"{{name}}\" must be camelCase.',\n },\n },\n createOnce(context: RuleContext) {\n return {\n ClassDeclaration(node: Node) {\n check(node, context);\n },\n ClassExpression(node: Node) {\n check(node, context);\n },\n };\n },\n});\n\nfunction check(node: Node, context: RuleContext) {\n if (!isBaseSubclass(node, context)) return;\n\n const body: Node[] = node.body?.body ?? [];\n\n const configProp = body.find(\n (member: Node) =>\n member.type === 'PropertyDefinition' &&\n member.static === true &&\n member.key?.name === 'config',\n );\n\n if (!configProp?.value || configProp.value.type !== 'ObjectExpression') return;\n\n const optionsProp = configProp.value.properties?.find(\n (prop: Node) => prop.type === 'Property' && prop.key?.name === 'options',\n );\n\n if (!optionsProp?.value || optionsProp.value.type !== 'ObjectExpression') return;\n\n for (const prop of optionsProp.value.properties ?? []) {\n if (prop.type !== 'Property') continue;\n const name = prop.key?.name ?? prop.key?.value;\n if (typeof name !== 'string') continue;\n if (!isCamelCase(name)) {\n const fixed = toCamelCase(name);\n // Quoted key ('slides-to-show') vs identifier key (SlidesToShow)\n const fixedText = prop.key.type === 'Literal' ? `'${fixed}'` : fixed;\n context.report({\n node: prop.key,\n messageId: 'notCamelCase',\n data: { name },\n fix: (fixer: any) => fixer.replaceText(prop.key, fixedText),\n });\n }\n }\n}\n", "import {\n isBaseSubclass,\n LIFECYCLE_METHODS,\n findEnclosingClass,\n type Node,\n type RuleContext,\n createRule,\n} from '../utils/ast.ts';\n\nexport const asyncLifecycleMethods = createRule({\n meta: {\n type: 'problem',\n fixable: 'code',\n docs: {\n description: 'Require lifecycle methods on Base subclasses to be async',\n },\n messages: {\n notAsync: 'Lifecycle method \"{{name}}\" must be declared as async.',\n },\n },\n createOnce(context: RuleContext) {\n return {\n MethodDefinition(node: Node) {\n const name = node.key?.name;\n if (!name || !LIFECYCLE_METHODS.has(name)) return;\n if (node.value?.async) return;\n\n const ancestors = context.getAncestors\n ? context.getAncestors()\n : (context.sourceCode?.getAncestors?.(node) ?? []);\n\n const enclosingClass = findEnclosingClass(ancestors);\n if (!enclosingClass || !isBaseSubclass(enclosingClass, context)) return;\n\n context.report({\n node,\n messageId: 'notAsync',\n data: { name },\n fix: (fixer: any) => fixer.insertTextBefore(node.key, 'async '),\n });\n },\n };\n },\n});\n", "import {\n isBaseSubclass,\n findEnclosingClass,\n type Node,\n type RuleContext,\n createRule,\n} from '../utils/ast.ts';\n\n// onXxxYyy \u2014 the part after \"on\" must start with an uppercase letter\nconst ON_HANDLER_RE = /^on[A-Z][a-zA-Z0-9]*$/;\n\nexport const onHandlerNaming = createRule({\n meta: {\n type: 'problem',\n docs: {\n description: 'Require event handler methods to follow the onXxxYyy naming convention',\n },\n messages: {\n invalidName:\n 'Event handler \"{{name}}\" must follow the onXxxYyy camelCase convention (e.g. onClickButton).',\n },\n },\n createOnce(context: RuleContext) {\n return {\n MethodDefinition(node: Node) {\n // Skip getters, setters \u2014 those are not event handlers\n if (node.kind === 'get' || node.kind === 'set') return;\n\n const name = node.key?.name;\n // Only lint methods that start with \"on\" followed by an uppercase letter \u2014\n // that's the unambiguous signal of an intended event handler.\n if (!name || !/^on[A-Z]/.test(name)) return;\n if (ON_HANDLER_RE.test(name)) return;\n\n const ancestors = context.getAncestors\n ? context.getAncestors()\n : (context.sourceCode?.getAncestors?.(node) ?? []);\n\n const enclosingClass = findEnclosingClass(ancestors);\n if (!enclosingClass || !isBaseSubclass(enclosingClass, context)) return;\n\n context.report({ node, messageId: 'invalidName', data: { name } });\n },\n };\n },\n});\n", "import {\n isBaseSubclass,\n findEnclosingClass,\n type Node,\n type RuleContext,\n createRule,\n} from '../utils/ast.ts';\n\n// Events that only make sense on window/document, never on a DOM element.\n// Pointer, keyboard, and form events are intentionally excluded \u2014 they can all\n// fire on elements too, so onResize/onScroll without a prefix is the only\n// unambiguous mistake worth flagging automatically.\nconst GLOBAL_ONLY_EVENTS = new Set(['Resize']);\n\nexport const onGlobalHandlerPrefix = createRule({\n meta: {\n type: 'suggestion',\n docs: {\n description:\n 'Require global event handlers (resize, scroll, etc.) to be prefixed with onWindow or onDocument',\n },\n messages: {\n missingPrefix:\n '\"{{name}}\" looks like a global event handler. Use \"onWindow{{event}}\" or \"onDocument{{event}}\" to bind to window/document events.',\n },\n },\n createOnce(context: RuleContext) {\n return {\n MethodDefinition(node: Node) {\n const name = node.key?.name;\n if (!name || !name.startsWith('on')) return;\n\n const suffix = name.slice(2); // strip \"on\"\n const event = GLOBAL_ONLY_EVENTS.has(suffix) ? suffix : null;\n if (!event) return;\n\n // Allow onWindow* and onDocument* \u2014 those are correct\n if (name.startsWith('onWindow') || name.startsWith('onDocument')) return;\n\n const ancestors = context.getAncestors\n ? context.getAncestors()\n : (context.sourceCode?.getAncestors?.(node) ?? []);\n\n const enclosingClass = findEnclosingClass(ancestors);\n if (!enclosingClass || !isBaseSubclass(enclosingClass, context)) return;\n\n context.report({\n node,\n messageId: 'missingPrefix',\n data: { name, event },\n });\n },\n };\n },\n});\n", "import {\n isBaseSubclass,\n findEnclosingClass,\n type Node,\n type RuleContext,\n createRule,\n} from '../utils/ast.ts';\n\nconst DEPRECATED = new Map([\n ['$parent', '$closest()'],\n ['$root', '$closest()'],\n ['$children', '$query()'],\n]);\n\nexport const noDeprecatedProperties = createRule({\n meta: {\n type: 'problem',\n docs: {\n description: 'Disallow deprecated Base properties ($parent, $children, $root)',\n },\n messages: {\n deprecated: '\"{{name}}\" is deprecated. Use {{replacement}} instead.',\n },\n },\n createOnce(context: RuleContext) {\n return {\n MemberExpression(node: Node) {\n const prop = node.property?.name;\n if (!prop || !DEPRECATED.has(prop)) return;\n\n // Only flag `this.$parent` etc. \u2014 not arbitrary object access\n if (node.object?.type !== 'ThisExpression') return;\n\n const ancestors = context.getAncestors\n ? context.getAncestors()\n : (context.sourceCode?.getAncestors?.(node) ?? []);\n\n const enclosingClass = findEnclosingClass(ancestors);\n if (!enclosingClass || !isBaseSubclass(enclosingClass, context)) return;\n\n const replacement = DEPRECATED.get(prop);\n context.report({\n node,\n messageId: 'deprecated',\n data: { name: prop, replacement },\n });\n },\n };\n },\n});\n", "import {\n findEnclosingClass,\n isBaseSubclass,\n type Node,\n type RuleContext,\n createRule,\n} from '../utils/ast.ts';\n\nexport const noDispatchEvent = createRule({\n meta: {\n type: 'suggestion',\n docs: {\n description: 'Disallow dispatchEvent() in Base subclasses \u2014 use this.$emit() instead',\n },\n messages: {\n useEmit: 'Use this.$emit() instead of dispatchEvent() to emit events in a Base component.',\n },\n },\n createOnce(context: RuleContext) {\n return {\n CallExpression(node: Node) {\n const callee = node.callee;\n\n const isDispatchEvent =\n // this.dispatchEvent(...)\n (callee.type === 'MemberExpression' &&\n callee.object?.type === 'ThisExpression' &&\n callee.property?.name === 'dispatchEvent') ||\n // this.$el.dispatchEvent(...) or el.dispatchEvent(...)\n (callee.type === 'MemberExpression' && callee.property?.name === 'dispatchEvent');\n\n if (!isDispatchEvent) return;\n\n const ancestors = context.getAncestors\n ? context.getAncestors()\n : (context.sourceCode?.getAncestors?.(node) ?? []);\n\n const enclosingClass = findEnclosingClass(ancestors);\n if (!enclosingClass || !isBaseSubclass(enclosingClass, context)) return;\n\n context.report({ node, messageId: 'useEmit' });\n },\n };\n },\n});\n", "import {\n findEnclosingClass,\n isBaseSubclass,\n type Node,\n type RuleContext,\n createRule,\n} from '../utils/ast.ts';\n\nexport const noShadowDom = createRule({\n meta: {\n type: 'problem',\n docs: {\n description: 'Disallow attachShadow() in Base subclasses \u2014 js-toolkit uses Light DOM only',\n },\n messages: {\n noShadow:\n 'Do not use attachShadow() in a Base component. @studiometa/js-toolkit uses Light DOM only.',\n },\n },\n createOnce(context: RuleContext) {\n return {\n CallExpression(node: Node) {\n const callee = node.callee;\n if (callee.type !== 'MemberExpression' || callee.property?.name !== 'attachShadow') {\n return;\n }\n\n const ancestors = context.getAncestors\n ? context.getAncestors()\n : (context.sourceCode?.getAncestors?.(node) ?? []);\n\n const enclosingClass = findEnclosingClass(ancestors);\n if (!enclosingClass || !isBaseSubclass(enclosingClass, context)) return;\n\n context.report({ node, messageId: 'noShadow' });\n },\n };\n },\n});\n", "import { type Node, type RuleContext, createRule } from '../utils/ast.ts';\n\nexport const noCreateApp = createRule({\n meta: {\n type: 'suggestion',\n docs: {\n description: 'Disallow createApp() \u2014 use registerComponent() instead',\n },\n messages: {\n useRegister:\n 'createApp() is deprecated. Use registerComponent() from @studiometa/js-toolkit instead.',\n },\n },\n createOnce(context: RuleContext) {\n return {\n CallExpression(node: Node) {\n const callee = node.callee;\n if (callee.type === 'Identifier' && callee.name === 'createApp') {\n context.report({ node, messageId: 'useRegister' });\n }\n },\n };\n },\n});\n", "import {\n findEnclosingClass,\n isBaseSubclass,\n type Node,\n type RuleContext,\n createRule,\n} from '../utils/ast.ts';\n\nconst FORBIDDEN = new Set(['addEventListener', 'removeEventListener']);\n\nexport const noEventListenerMethods = createRule({\n meta: {\n type: 'problem',\n docs: {\n description:\n 'Disallow addEventListener/removeEventListener in Base subclasses \u2014 use on* methods instead',\n },\n messages: {\n useOnMethod:\n '\"{{method}}()\" should not be used in a Base component. ' +\n 'Define an \"on<Target><Event>()\" method instead \u2014 the framework handles binding and cleanup automatically.',\n },\n },\n createOnce(context: RuleContext) {\n return {\n CallExpression(node: Node) {\n const callee = node.callee;\n if (callee.type !== 'MemberExpression') return;\n\n const method = callee.property?.name;\n if (!method || !FORBIDDEN.has(method)) return;\n\n // Only flag calls on `this.*`, `document`, or `window`\n let root = callee.object;\n while (root?.type === 'MemberExpression') root = root.object;\n const isThis = root?.type === 'ThisExpression';\n const isGlobal =\n root?.type === 'Identifier' && (root.name === 'document' || root.name === 'window');\n if (!isThis && !isGlobal) return;\n\n const ancestors = context.getAncestors\n ? context.getAncestors()\n : (context.sourceCode?.getAncestors?.(node) ?? []);\n\n const enclosingClass = findEnclosingClass(ancestors);\n if (!enclosingClass || !isBaseSubclass(enclosingClass, context)) return;\n\n context.report({ node, messageId: 'useOnMethod', data: { method } });\n },\n };\n },\n});\n", "import { isBaseSubclass, type Node, type RuleContext, createRule } from '../utils/ast.ts';\n\nexport const refsPluralMultiple = createRule({\n meta: {\n type: 'problem',\n docs: {\n description: 'Require multiple-ref names (using [] suffix) to be pluralized',\n },\n messages: {\n notPlural: 'Multiple ref \"{{name}}\" must be pluralized (e.g. \"{{name}}s[]\").',\n },\n },\n createOnce(context: RuleContext) {\n return {\n ClassDeclaration(node: Node) {\n check(node, context);\n },\n ClassExpression(node: Node) {\n check(node, context);\n },\n };\n },\n});\n\nfunction check(node: Node, context: RuleContext) {\n if (!isBaseSubclass(node, context)) return;\n\n const body: Node[] = node.body?.body ?? [];\n\n const configProp = body.find(\n (member: Node) =>\n member.type === 'PropertyDefinition' &&\n member.static === true &&\n member.key?.name === 'config',\n );\n\n if (!configProp?.value || configProp.value.type !== 'ObjectExpression') return;\n\n const refsProp = configProp.value.properties?.find(\n (prop: Node) => prop.type === 'Property' && prop.key?.name === 'refs',\n );\n\n if (!refsProp?.value || refsProp.value.type !== 'ArrayExpression') return;\n\n for (const element of refsProp.value.elements ?? []) {\n if (!element || element.type !== 'Literal') continue;\n const raw = element.value;\n if (typeof raw !== 'string') continue;\n if (!raw.endsWith('[]')) continue;\n\n const name = raw.slice(0, -2);\n if (!name.endsWith('s')) {\n context.report({\n node: element,\n messageId: 'notPlural',\n data: { name },\n });\n }\n }\n}\n", "import { type Node, type RuleContext, createRule } from '../utils/ast.ts';\n\nconst DEEP_UTILS_RE = /^@studiometa\\/js-toolkit\\/utils\\/.+/;\n\nexport const noDeepUtilsImport = createRule({\n meta: {\n type: 'problem',\n fixable: 'code',\n docs: {\n description: 'Disallow deep imports from @studiometa/js-toolkit/utils/*',\n },\n messages: {\n noDeepImport:\n 'Import from \"{{source}}\" should use the public entrypoint \"@studiometa/js-toolkit/utils\".',\n },\n },\n createOnce(context: RuleContext) {\n return {\n ImportDeclaration(node: Node) {\n const source: string = node.source.value;\n if (!DEEP_UTILS_RE.test(source)) return;\n\n context.report({\n node,\n messageId: 'noDeepImport',\n data: { source },\n fix(fixer: any) {\n const specifiers: Node[] = node.specifiers ?? [];\n const parts: string[] = [];\n\n for (const s of specifiers) {\n if (s.type === 'ImportDefaultSpecifier') {\n parts.push(s.local.name);\n } else if (s.type === 'ImportSpecifier') {\n const imported = s.imported.name;\n const local = s.local.name;\n parts.push(imported === local ? imported : `${imported} as ${local}`);\n }\n }\n\n const named = parts.join(', ');\n return fixer.replaceText(\n node,\n `import { ${named} } from '@studiometa/js-toolkit/utils';`,\n );\n },\n });\n },\n };\n },\n});\n", "import { toCamelCase, type Node, type RuleContext, createRule } from '../utils/ast.ts';\n\nfunction isThisRefs(node: Node): boolean {\n return (\n node.type === 'MemberExpression' &&\n node.object?.type === 'ThisExpression' &&\n node.property?.name === '$refs'\n );\n}\n\nexport const refsNoBracketAccess = createRule({\n meta: {\n type: 'problem',\n fixable: 'code',\n docs: {\n description: 'Disallow bracket access with [] suffix on this.$refs',\n },\n messages: {\n noBracketAccess: 'Use \"this.$refs.{{fixed}}\" instead of \"this.$refs[\\'{{raw}}\\']\".',\n },\n },\n createOnce(context: RuleContext) {\n return {\n MemberExpression(node: Node) {\n if (!isThisRefs(node.object)) return;\n if (!node.computed) return;\n const prop = node.property;\n if (prop.type !== 'Literal' || typeof prop.value !== 'string') return;\n const raw: string = prop.value;\n if (!raw.endsWith('[]')) return;\n\n const stripped = raw.slice(0, -2);\n const fixed = toCamelCase(stripped);\n\n context.report({\n node,\n messageId: 'noBracketAccess',\n data: { raw, fixed },\n fix(fixer: any) {\n const src = context.sourceCode ?? context.getSourceCode?.();\n const objText = src.getText(node.object);\n return fixer.replaceText(node, `${objText}.${fixed}`);\n },\n });\n },\n };\n },\n});\n", "import { type Node, type RuleContext, createRule } from '../utils/ast.ts';\n\nexport const noRedundantWithMountWhenInView = createRule({\n meta: {\n type: 'suggestion',\n docs: {\n description: 'Disallow wrapping withMountWhenInView inside withScrolledInView (redundant)',\n },\n messages: {\n redundant:\n 'withScrolledInView already includes withMountWhenInView internally. Remove the inner withMountWhenInView call.',\n },\n },\n createOnce(context: RuleContext) {\n return {\n 'ClassDeclaration, ClassExpression'(node: Node) {\n check(node, context);\n },\n };\n },\n});\n\nfunction check(node: Node, context: RuleContext) {\n const superClass = node.superClass;\n if (!superClass || superClass.type !== 'CallExpression') return;\n if (superClass.callee?.name !== 'withScrolledInView') return;\n\n const arg = superClass.arguments?.[0];\n if (!arg || arg.type !== 'CallExpression') return;\n if (arg.callee?.name !== 'withMountWhenInView') return;\n\n context.report({ node: superClass, messageId: 'redundant' });\n}\n", "import {\n findEnclosingClass,\n isBaseSubclass,\n type Node,\n type RuleContext,\n createRule,\n} from '../utils/ast.ts';\n\nconst QUERY_METHODS = new Set(['querySelector', 'querySelectorAll']);\n\nfunction isThisEl(node: Node): boolean {\n return (\n node.type === 'MemberExpression' &&\n node.object?.type === 'ThisExpression' &&\n node.property?.name === '$el'\n );\n}\n\nexport const preferRefOverQuerySelector = createRule({\n meta: {\n type: 'suggestion',\n docs: {\n description: 'Prefer this.$refs over this.$el.querySelector() in Base subclasses',\n },\n messages: {\n preferRef:\n 'Avoid \"this.$el.{{method}}()\". Declare a ref in static config and use \"this.$refs\" instead.',\n },\n },\n createOnce(context: RuleContext) {\n return {\n CallExpression(node: Node) {\n const callee = node.callee;\n if (callee?.type !== 'MemberExpression') return;\n if (!isThisEl(callee.object)) return;\n const method = callee.property?.name;\n if (!QUERY_METHODS.has(method)) return;\n\n const ancestors =\n context.getAncestors?.() ?? context.sourceCode?.getAncestors?.(node) ?? [];\n const cls = findEnclosingClass(ancestors);\n if (!cls || !isBaseSubclass(cls, context)) return;\n\n context.report({ node, messageId: 'preferRef', data: { method } });\n },\n };\n },\n});\n", "import {\n isBaseSubclass,\n toCamelCase,\n type Node,\n type RuleContext,\n createRule,\n} from '../utils/ast.ts';\n\nfunction collectDeclaredRefs(classNode: Node): Set<string> {\n const body: Node[] = classNode.body?.body ?? [];\n const configProp = body.find(\n (m: Node) => m.type === 'PropertyDefinition' && m.static === true && m.key?.name === 'config',\n );\n\n if (!configProp?.value || configProp.value.type !== 'ObjectExpression') return new Set();\n\n const refsProp = configProp.value.properties?.find(\n (p: Node) => p.type === 'Property' && p.key?.name === 'refs',\n );\n\n if (!refsProp?.value || refsProp.value.type !== 'ArrayExpression') return new Set();\n\n const names = new Set<string>();\n for (const el of refsProp.value.elements ?? []) {\n if (!el || el.type !== 'Literal' || typeof el.value !== 'string') continue;\n const raw: string = el.value;\n const stripped = raw.endsWith('[]') ? raw.slice(0, -2) : raw;\n names.add(toCamelCase(stripped));\n }\n return names;\n}\n\nfunction isThisRefs(node: Node): boolean {\n return (\n node.type === 'MemberExpression' &&\n node.object?.type === 'ThisExpression' &&\n node.property?.name === '$refs'\n );\n}\n\nexport const requireRefsDeclaredInConfig = createRule({\n meta: {\n type: 'problem',\n docs: {\n description: 'Require all this.$refs accesses to be declared in static config.refs',\n },\n messages: {\n undeclared: 'Ref \"{{name}}\" is not declared in static config.refs.',\n },\n },\n createOnce(context: RuleContext) {\n return {\n 'ClassDeclaration, ClassExpression'(classNode: Node) {\n if (!isBaseSubclass(classNode, context)) return;\n\n const declared = collectDeclaredRefs(classNode);\n\n // Walk the class body looking for this.$refs.<name> accesses\n walkNode(classNode.body, (node: Node) => {\n if (node.type !== 'MemberExpression') return;\n if (!isThisRefs(node.object)) return;\n\n let refName: string | null = null;\n\n if (!node.computed && node.property?.type === 'Identifier') {\n refName = node.property.name;\n } else if (\n node.computed &&\n node.property?.type === 'Literal' &&\n typeof node.property.value === 'string'\n ) {\n const raw: string = node.property.value;\n const stripped = raw.endsWith('[]') ? raw.slice(0, -2) : raw;\n refName = toCamelCase(stripped);\n }\n\n if (refName && !declared.has(refName)) {\n context.report({\n node,\n messageId: 'undeclared',\n data: { name: refName },\n });\n }\n });\n },\n };\n },\n});\n\nfunction walkNode(node: Node, visit: (n: Node) => void) {\n if (!node || typeof node !== 'object') return;\n visit(node);\n for (const key of Object.keys(node)) {\n if (key === 'parent') continue;\n const child = node[key];\n if (Array.isArray(child)) {\n for (const item of child) walkNode(item, visit);\n } else if (child && typeof child === 'object' && child.type) {\n walkNode(child, visit);\n }\n }\n}\n", "import {\n findEnclosingClass,\n isBaseSubclass,\n type Node,\n type RuleContext,\n createRule,\n} from '../utils/ast.ts';\n\nexport const noManualIntersectionObserver = createRule({\n meta: {\n type: 'suggestion',\n docs: {\n description:\n 'Disallow manual IntersectionObserver inside Base subclasses; use withIntersectionObserver or withMountWhenInView instead',\n },\n messages: {\n noManual:\n 'Avoid manual \"new IntersectionObserver()\". Use \"withIntersectionObserver\" or \"withMountWhenInView\" decorators instead.',\n },\n },\n createOnce(context: RuleContext) {\n return {\n NewExpression(node: Node) {\n if (node.callee?.name !== 'IntersectionObserver') return;\n\n const ancestors =\n context.getAncestors?.() ?? context.sourceCode?.getAncestors?.(node) ?? [];\n const cls = findEnclosingClass(ancestors);\n if (!cls || !isBaseSubclass(cls, context)) return;\n\n context.report({ node, messageId: 'noManual' });\n },\n };\n },\n});\n", "import {\n findEnclosingClass,\n isBaseSubclass,\n type Node,\n type RuleContext,\n createRule,\n} from '../utils/ast.ts';\n\nexport const noManualMutationObserver = createRule({\n meta: {\n type: 'suggestion',\n docs: {\n description:\n 'Disallow manual MutationObserver inside Base subclasses; use withMutation decorator instead',\n },\n messages: {\n noManual: 'Avoid manual \"new MutationObserver()\". Use the \"withMutation\" decorator instead.',\n },\n },\n createOnce(context: RuleContext) {\n return {\n NewExpression(node: Node) {\n if (node.callee?.name !== 'MutationObserver') return;\n\n const ancestors =\n context.getAncestors?.() ?? context.sourceCode?.getAncestors?.(node) ?? [];\n const cls = findEnclosingClass(ancestors);\n if (!cls || !isBaseSubclass(cls, context)) return;\n\n context.report({ node, messageId: 'noManual' });\n },\n };\n },\n});\n", "import { eslintCompatPlugin } from '@oxlint/plugins';\nimport {\n requireConfig,\n requireConfigNamePascalCase,\n refsCamelCase,\n optionsCamelCase,\n asyncLifecycleMethods,\n onHandlerNaming,\n onGlobalHandlerPrefix,\n noDeprecatedProperties,\n noDispatchEvent,\n noShadowDom,\n noCreateApp,\n noEventListenerMethods,\n refsPluralMultiple,\n noDeepUtilsImport,\n refsNoBracketAccess,\n noRedundantWithMountWhenInView,\n preferRefOverQuerySelector,\n requireRefsDeclaredInConfig,\n noManualIntersectionObserver,\n noManualMutationObserver,\n} from './rules/index.ts';\n\nconst PLUGIN_NAME = 'js-toolkit';\n\nconst rules = {\n 'require-config': requireConfig,\n 'require-config-name-pascal-case': requireConfigNamePascalCase,\n 'refs-camel-case': refsCamelCase,\n 'refs-plural-multiple': refsPluralMultiple,\n 'options-camel-case': optionsCamelCase,\n 'async-lifecycle-methods': asyncLifecycleMethods,\n 'on-handler-naming': onHandlerNaming,\n 'on-global-handler-prefix': onGlobalHandlerPrefix,\n 'no-deprecated-properties': noDeprecatedProperties,\n 'no-dispatch-event': noDispatchEvent,\n 'no-shadow-dom': noShadowDom,\n 'no-create-app': noCreateApp,\n 'no-event-listener-methods': noEventListenerMethods,\n 'no-deep-utils-import': noDeepUtilsImport,\n 'refs-no-bracket-access': refsNoBracketAccess,\n 'no-redundant-with-mount-when-in-view': noRedundantWithMountWhenInView,\n 'prefer-ref-over-query-selector': preferRefOverQuerySelector,\n 'require-refs-declared-in-config': requireRefsDeclaredInConfig,\n 'no-manual-intersection-observer': noManualIntersectionObserver,\n 'no-manual-mutation-observer': noManualMutationObserver,\n};\n\nconst recommendedRules: Record<string, string> = {\n [`${PLUGIN_NAME}/require-config`]: 'error',\n [`${PLUGIN_NAME}/require-config-name-pascal-case`]: 'error',\n [`${PLUGIN_NAME}/refs-camel-case`]: 'error',\n [`${PLUGIN_NAME}/refs-plural-multiple`]: 'error',\n [`${PLUGIN_NAME}/options-camel-case`]: 'error',\n [`${PLUGIN_NAME}/async-lifecycle-methods`]: 'error',\n [`${PLUGIN_NAME}/on-handler-naming`]: 'error',\n [`${PLUGIN_NAME}/on-global-handler-prefix`]: 'warn',\n [`${PLUGIN_NAME}/no-deprecated-properties`]: 'warn',\n [`${PLUGIN_NAME}/no-dispatch-event`]: 'warn',\n [`${PLUGIN_NAME}/no-shadow-dom`]: 'error',\n [`${PLUGIN_NAME}/no-create-app`]: 'warn',\n [`${PLUGIN_NAME}/no-event-listener-methods`]: 'error',\n [`${PLUGIN_NAME}/no-deep-utils-import`]: 'error',\n [`${PLUGIN_NAME}/refs-no-bracket-access`]: 'error',\n [`${PLUGIN_NAME}/no-redundant-with-mount-when-in-view`]: 'warn',\n [`${PLUGIN_NAME}/prefer-ref-over-query-selector`]: 'warn',\n [`${PLUGIN_NAME}/require-refs-declared-in-config`]: 'error',\n [`${PLUGIN_NAME}/no-manual-intersection-observer`]: 'warn',\n [`${PLUGIN_NAME}/no-manual-mutation-observer`]: 'warn',\n};\n\nconst base = eslintCompatPlugin({\n meta: {\n name: '@studiometa/eslint-plugin-js-toolkit',\n },\n rules,\n});\n\nconst plugin = Object.assign(base, { configs: {} as Record<string, object> });\n\nplugin.configs['recommended'] = {\n plugins: { [PLUGIN_NAME]: plugin },\n rules: recommendedRules,\n};\n\nexport default plugin;\n"],
5
- "mappings": "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",
6
- "names": ["plugin", "rules", "node", "check", "check", "check", "check", "check", "isThisRefs"]
3
+ "sources": ["../../../node_modules/@oxlint/plugins/index.js", "../src/utils/ast.ts", "../src/rules/require-config.ts", "../src/rules/require-config-name-pascal-case.ts", "../src/rules/refs-camel-case.ts", "../src/rules/options-camel-case.ts", "../src/rules/async-lifecycle-methods.ts", "../src/rules/on-handler-naming.ts", "../src/rules/on-global-handler-prefix.ts", "../src/rules/no-deprecated-properties.ts", "../src/rules/no-dispatch-event.ts", "../src/rules/no-shadow-dom.ts", "../src/rules/no-create-app.ts", "../src/rules/no-event-listener-methods.ts", "../src/rules/refs-plural-multiple.ts", "../src/rules/no-deep-utils-import.ts", "../src/rules/refs-no-bracket-access.ts", "../src/rules/no-redundant-with-mount-when-in-view.ts", "../src/rules/prefer-ref-over-query-selector.ts", "../src/rules/require-refs-declared-in-config.ts", "../src/rules/no-manual-intersection-observer.ts", "../src/rules/no-manual-mutation-observer.ts", "../src/rules/emits-kebab-case.ts", "../src/rules/emits-multi-word.ts", "../src/rules/components-pascal-case.ts", "../src/rules/require-emit-declared-in-config.ts", "../src/rules/require-children-declared-in-config.ts", "../src/rules/require-options-declared-in-config.ts", "../src/rules/prefer-destructured-lookups.ts", "../src/rules/no-dollar-prefix.ts", "../src/rules/require-destroyed-cleanup.ts", "../src/index.ts"],
4
+ "sourcesContent": ["//#region src-js/package/define.ts\n/**\n* Define a plugin.\n*\n* No-op function, just to provide type safety. Input is passed through unchanged.\n*\n* @param plugin - Plugin to define\n* @returns Same plugin as passed in\n*/\nfunction definePlugin(plugin) {\n\treturn plugin;\n}\n/**\n* Define a rule.\n*\n* No-op function, just to provide type safety. Input is passed through unchanged.\n*\n* @param rule - Rule to define\n* @returns Same rule as passed in\n*/\nfunction defineRule(rule) {\n\treturn rule;\n}\n//#endregion\n//#region src-js/package/compat.ts\nconst EMPTY_VISITOR = {};\n/**\n* Convert a plugin which used Oxlint's `createOnce` API to also work with ESLint.\n*\n* If any of the plugin's rules use the Oxlint alternative `createOnce` API,\n* add ESLint-compatible `create` methods to those rules, which delegate to `createOnce`.\n* This makes the plugin compatible with ESLint.\n*\n* The `plugin` object passed in is mutated in-place.\n*\n* @param plugin - Plugin to convert\n* @returns Plugin with all rules having `create` method\n* @throws {Error} If `plugin` is not an object, or `plugin.rules` is not an object\n*/\nfunction eslintCompatPlugin(plugin) {\n\tif (typeof plugin != \"object\" || !plugin) throw Error(\"Plugin must be an object\");\n\tlet { rules } = plugin;\n\tif (typeof rules != \"object\" || !rules) throw Error(\"Plugin must have an object as `rules` property\");\n\tlet afterHooksState = new AfterHooksState();\n\tfor (let ruleName in rules) Object.hasOwn(rules, ruleName) && convertRule(rules[ruleName], afterHooksState);\n\treturn plugin;\n}\n/**\n* Class containing state for tracking if any `after` hooks for a plugin's rules need to be called.\n*\n* # Aims\n*\n* Aims are:\n* 1. `after` hook of each rule runs after all other AST visit functions, and CFG event handlers.\n* 2. `after` hooks for *all* a plugin's rules run after *all* that plugin's rules have completed visiting AST.\n* 3. `after` hooks for *all* a plugin's rules run before *any* of plugin's rules begin linting another file.\n* 4. In the case of an error during AST traversal, `after` hooks are always still run.\n*\n* The above exactly matches the behavior when running a `createOnce` rule in Oxlint.\n*\n* # Why this is important\n*\n* All the complication comes from ensuring `after` hooks run even after an error during AST traversal.\n*\n* In ESLint CLI, an error will crash the process, so it doesn't particularly matter if `after` hooks run or not,\n* but language servers will typically swallow errors, and keep the process running.\n*\n* Rules using `before` and `after` hooks will often rely on both hooks running in a predictable order,\n* to maintain some internal state. For example, they may use `before` and `after` hooks to maintain a per-file\n* cache of data which is shared between rules. The cache use case is why rule (2) above is important.\n*\n* Below is an example of using `before` and `after` hooks to maintain a per-file cache, shared between rules.\n* It relies on all `before` hooks running before any rule starts visiting the AST,\n* and all `after` hooks running after all rules have finished visiting the AST.\n*\n* ```ts\n* let cache: Data | null = null;\n*\n* let numRunningRules = 0;\n*\n* const setupCache = (context) => {\n* if (cache === null) cache = new Data(context);\n* numRunningRules++;\n* };\n*\n* const teardownCache = () => {\n* numRunningRules--;\n* if (numRunningRules === 0) cache = null;\n* };\n*\n* const rule1 = {\n* createOnce(context) {\n* return {\n* before() {\n* setupCache(context);\n* },\n* Identifier(node) {\n* // Use `cache`\n* },\n* after: teardownCache,\n* };\n* },\n* };\n*\n* const rule2 = {\n* // Same as above\n* };\n*\n* const rule3 = {\n* // Same as above\n* };\n* ```\n*\n* If `after` hooks did not always run, the next lint run could get stale state, and malfunction.\n* If `after` hooks ran in the wrong order (e.g. after some `before` hooks for next file),\n* `numRunningRules` would never get to 0, and cache would never be cleared.\n*\n* Note that because all rules run together in a single AST traversal, if a rule from plugin X throws an error,\n* it can disrupt rules from plugin Y. This would make it hard to debug.\n*\n* # Mechanism\n*\n* ## Initialization\n*\n* Rules with an `after` hook register themselves by:\n*\n* 1. Calling `registerResetFunction` to register a function to run `after` hook and clean up internal state.\n* This call adds the reset fn to `resetFunctions`, and adds `AFTER_HOOK_INACTIVE` to `pendingStates`.\n* 2. Adding an `onCodePathEnd` CFG event handler to the visitor which calls `ruleFinished` at end of AST traversal.\n*\n* ## Per-file setup\n*\n* Before linting a file, `create` will call `setupAfterHook` which is created by `createContextAndVisitor`.\n* This registers that the `after` hook for the rule needs to run, by setting `pendingStates[ruleIndex]`\n* to `AFTER_HOOK_PENDING`, and incrementing `pendingCount`.\n*\n* If a cleanup microtask has not been scheduled yet, one is scheduled now (see reason below).\n*\n* ## Normal operation\n*\n* AST traversal for each rule ends with `ruleFinished` hook being called from `onCodePathEnd` CFG event handler.\n* It increments `lintFinishedCount`. If `lintFinishedCount` equals `pendingCount`, all rules have finished linting\n* the file, and `reset` is called, which calls all the pending `after` hooks.\n*\n* ## Error handling\n*\n* If an error is thrown during AST traversal, we ensure that `after` hooks are still run by 2 mechanisms:\n*\n* ### 1. Next microtick\n*\n* Before any rules began linting files, a microtask was scheduled, which runs on next micro-tick.\n* All language servers we're aware of run each lint task in a separate tick, so this microtask will run in next tick\n* after a linting run, before the next lint task starts.\n*\n* If the linting run completed successfully, the microtask does nothing.\n*\n* But if an error was thrown during AST traversal, this will be visible from the state of `pendingCount`.\n* The microtask will run any `after` hooks which need to be run, and reset state to reflect that there are\n* no more pending `after` hooks.\n*\n* ### 2. Fallback: Next lint run\n*\n* Before linting any file, the state of `pendingCount` is checked.\n* If any `after` hooks are still pending, they are run immediately.\n* They're run before the `context` objects in `createOnce` closures are updated to the next file,\n* so they run with access to the old `context` object from the last file.\n*\n* This fallback should not be required, but it's included as \"belt and braces\", to handle if any language server\n* or other environment running ESLint programmatically, does not pause a tick between linting runs.\n*/\nvar AfterHooksState = class {\n\tresetFunctions = [];\n\tpendingStates = [];\n\tpendingCount = 0;\n\tlintFinishedCount = 0;\n\tresetIsScheduled = !1;\n\tsourceCode = null;\n\tresetMicrotask = this.resetMicrotaskImpl.bind(this);\n\t/**\n\t* Register a function to run `after` hook for a rule, and reset state.\n\t* @param reset - Function to run `after` hook and reset state\n\t* @returns Index of rule\n\t*/\n\tregisterResetFunction(reset) {\n\t\tlet { pendingStates } = this, index = pendingStates.length;\n\t\treturn pendingStates.push(0), this.resetFunctions.push(reset), index;\n\t}\n\t/**\n\t* Register that a rule with `after` hook has completed linting a file.\n\t* Called by `onCodePathEnd` CFG event handler which is added to visitor for rules with `after` hooks.\n\t*\n\t* If all rules with an `after` hook which needs to be run have completed linting the file, run all `after` hooks.\n\t*/\n\truleFinished() {\n\t\tthis.lintFinishedCount++, this.lintFinishedCount === this.pendingCount && this.reset(!1);\n\t}\n\t/**\n\t* Call all reset functions where corresponding entry in `pendingStates` is `AFTER_HOOK_PENDING`.\n\t* Should only be called when some `after` hooks are pending.\n\t*\n\t* @param ignoreErrors - `true` to catch and silently ignore any errors which occur in `after` hooks.\n\t* `false` to throw them,\n\t* @throws {unknown} If `ignoreErrors` is `false` and an error occurs in any `after` hooks.\n\t*/\n\treset(ignoreErrors) {\n\t\tthis.pendingCount;\n\t\tlet { resetFunctions, pendingStates } = this, hooksLen = pendingStates.length, hasError = !1, error;\n\t\tfor (let i = 0; i < hooksLen; i++) if (pendingStates[i] !== 0) {\n\t\t\tpendingStates[i] = 0;\n\t\t\ttry {\n\t\t\t\tresetFunctions[i]();\n\t\t\t} catch (e) {\n\t\t\t\thasError === !1 && (hasError = !0, error = e);\n\t\t\t}\n\t\t}\n\t\tif (this.pendingCount = 0, this.lintFinishedCount = 0, this.sourceCode = null, hasError === !0 && ignoreErrors === !1) throw error;\n\t}\n\t/**\n\t* Schedule a microtask to run `reset` functions.\n\t*/\n\tscheduleReset() {\n\t\tqueueMicrotask(this.resetMicrotask), this.resetIsScheduled = !0;\n\t}\n\t/**\n\t* Function which is scheduled as the cleanup microtask.\n\t* `scheduleReset` uses `resetMicrotask` which is this method bound to `this`.\n\t*/\n\tresetMicrotaskImpl() {\n\t\tthis.resetIsScheduled = !1, this.pendingCount !== 0 && this.reset(!0);\n\t}\n};\n/**\n* Convert a rule.\n*\n* The `rule` object passed in is mutated in-place.\n*\n* @param rule - Rule to convert\n* @param afterHooksState - State of `after` hooks\n* @throws {Error} If `rule` is not an object\n*/\nfunction convertRule(rule, afterHooksState) {\n\tif (typeof rule != \"object\" || !rule) throw Error(\"Rule must be an object\");\n\tif (\"create\" in rule) return;\n\tlet context = null, visitor, beforeHook, setupAfterHook;\n\trule.create = (eslintContext) => {\n\t\tcontext === null && ({context, visitor, beforeHook, setupAfterHook} = createContextAndVisitor(rule, afterHooksState));\n\t\tlet eslintFileContext = Object.getPrototypeOf(eslintContext);\n\t\tif (setupAfterHook !== null) {\n\t\t\tlet { sourceCode } = eslintFileContext;\n\t\t\tafterHooksState.sourceCode !== sourceCode && (afterHooksState.sourceCode = sourceCode, afterHooksState.pendingCount !== 0 && afterHooksState.reset(!0));\n\t\t}\n\t\treturn Object.defineProperties(context, {\n\t\t\tid: { value: eslintContext.id },\n\t\t\toptions: { value: eslintContext.options },\n\t\t\treport: { value: eslintContext.report }\n\t\t}), Object.setPrototypeOf(context, eslintFileContext), beforeHook !== null && beforeHook() === !1 ? EMPTY_VISITOR : (setupAfterHook !== null && (setupAfterHook(eslintFileContext.sourceCode.ast), afterHooksState.resetIsScheduled === !1 && afterHooksState.scheduleReset()), visitor);\n\t};\n}\nconst FILE_CONTEXT = Object.freeze({\n\tget filename() {\n\t\tthrow Error(\"Cannot access `context.filename` in `createOnce`\");\n\t},\n\tgetFilename() {\n\t\tthrow Error(\"Cannot call `context.getFilename` in `createOnce`\");\n\t},\n\tget physicalFilename() {\n\t\tthrow Error(\"Cannot access `context.physicalFilename` in `createOnce`\");\n\t},\n\tgetPhysicalFilename() {\n\t\tthrow Error(\"Cannot call `context.getPhysicalFilename` in `createOnce`\");\n\t},\n\tget cwd() {\n\t\tthrow Error(\"Cannot access `context.cwd` in `createOnce`\");\n\t},\n\tgetCwd() {\n\t\tthrow Error(\"Cannot call `context.getCwd` in `createOnce`\");\n\t},\n\tget sourceCode() {\n\t\tthrow Error(\"Cannot access `context.sourceCode` in `createOnce`\");\n\t},\n\tgetSourceCode() {\n\t\tthrow Error(\"Cannot call `context.getSourceCode` in `createOnce`\");\n\t},\n\tget languageOptions() {\n\t\tthrow Error(\"Cannot access `context.languageOptions` in `createOnce`\");\n\t},\n\tget settings() {\n\t\tthrow Error(\"Cannot access `context.settings` in `createOnce`\");\n\t},\n\textend(extension) {\n\t\treturn Object.freeze(Object.assign(Object.create(this), extension));\n\t},\n\tget parserOptions() {\n\t\tthrow Error(\"Cannot access `context.parserOptions` in `createOnce`\");\n\t},\n\tget parserPath() {\n\t\tthrow Error(\"Cannot access `context.parserPath` in `createOnce`\");\n\t}\n});\n/**\n* Call `createOnce` method of rule, and return `Context`, `Visitor`, and `beforeHook` (if any).\n*\n* @param rule - Rule with `createOnce` method\n* @param afterHooksState - State of `after` hooks\n* @returns Object with `context`, `visitor`, and `beforeHook` properties,\n* and `setupAfterHook` function if visitor has an `after` hook\n*/\nfunction createContextAndVisitor(rule, afterHooksState) {\n\tlet { createOnce } = rule;\n\tif (createOnce == null) throw Error(\"Rules must define either a `create` or `createOnce` method\");\n\tif (typeof createOnce != \"function\") throw Error(\"Rule `createOnce` property must be a function\");\n\tlet context = Object.create(FILE_CONTEXT, {\n\t\tid: {\n\t\t\tvalue: null,\n\t\t\tenumerable: !0,\n\t\t\tconfigurable: !0\n\t\t},\n\t\toptions: {\n\t\t\tvalue: null,\n\t\t\tenumerable: !0,\n\t\t\tconfigurable: !0\n\t\t},\n\t\treport: {\n\t\t\tvalue() {\n\t\t\t\tthrow Error(\"Cannot report errors in `createOnce`\");\n\t\t\t},\n\t\t\tenumerable: !0,\n\t\t\tconfigurable: !0\n\t\t}\n\t}), { before: beforeHook, after: afterHook, ...visitor } = createOnce.call(rule, context);\n\tif (beforeHook === void 0) beforeHook = null;\n\telse if (beforeHook !== null && typeof beforeHook != \"function\") throw Error(\"`before` property of visitor must be a function if defined\");\n\tlet setupAfterHook = null;\n\tif (afterHook != null) {\n\t\tif (typeof afterHook != \"function\") throw Error(\"`after` property of visitor must be a function if defined\");\n\t\tlet program = null, ruleIndex = afterHooksState.registerResetFunction(() => {\n\t\t\tprogram = null, afterHook();\n\t\t});\n\t\tsetupAfterHook = (ast) => {\n\t\t\tprogram = ast, afterHooksState.pendingStates[ruleIndex] = 1, afterHooksState.pendingCount++;\n\t\t};\n\t\tlet onCodePathEnd = visitor.onCodePathEnd;\n\t\tvisitor.onCodePathEnd = onCodePathEnd == null ? function(_codePath, node) {\n\t\t\tnode === program && afterHooksState.ruleFinished();\n\t\t} : function(codePath, node) {\n\t\t\tonCodePathEnd.call(this, codePath, node), node === program && afterHooksState.ruleFinished();\n\t\t};\n\t}\n\treturn {\n\t\tcontext,\n\t\tvisitor,\n\t\tbeforeHook,\n\t\tsetupAfterHook\n\t};\n}\n//#endregion\nexport { definePlugin, defineRule, eslintCompatPlugin };\n", "/**\n * ESLint v9 compatible AST node types used across rules.\n * We use loose typings here since oxlint/eslint expose their own node types.\n */\n\nexport type Node = Record<string, any>;\nexport type RuleContext = Record<string, any>;\n\nexport type RuleMeta = {\n type?: 'problem' | 'suggestion' | 'layout';\n fixable?: 'code' | 'whitespace';\n hasSuggestions?: boolean;\n docs?: { description?: string };\n messages?: Record<string, string>;\n};\n\nexport function createRule<V extends Record<string, (node: Node) => unknown>>(rule: {\n meta?: RuleMeta;\n createOnce(context: RuleContext): V;\n}): { meta?: RuleMeta; createOnce(context: RuleContext): V } {\n return rule;\n}\n\nexport const LIFECYCLE_METHODS = new Set([\n 'mounted',\n 'destroyed',\n 'updated',\n 'terminated',\n 'ticked',\n 'scrolled',\n 'resized',\n 'moved',\n 'loaded',\n 'keyed',\n]);\n\nexport const TOOLKIT_PACKAGE = '@studiometa/js-toolkit';\n\n/**\n * Returns true if a class declaration extends an identifier imported from\n * @studiometa/js-toolkit, or extends a bare identifier named `Base`.\n *\n * This is a heuristic \u2014 we cannot do full type resolution in a lint rule.\n */\nexport function isBaseSubclass(node: Node, context: RuleContext): boolean {\n if (node.type !== 'ClassDeclaration' && node.type !== 'ClassExpression') {\n return false;\n }\n\n if (!node.superClass) {\n return false;\n }\n\n const superName = node.superClass.type === 'Identifier' ? node.superClass.name : null;\n\n if (!superName) {\n return false;\n }\n\n // Fast path: class extends Base\n if (superName === 'Base') {\n return true;\n }\n\n // Check if the superclass identifier is imported from @studiometa/js-toolkit\n const sourceCode = context.sourceCode ?? context.getSourceCode?.();\n const ast = sourceCode?.ast;\n\n if (!ast) {\n return false;\n }\n\n for (const node of ast.body) {\n if (node.type !== 'ImportDeclaration') continue;\n if (node.source.value !== TOOLKIT_PACKAGE) continue;\n\n for (const specifier of node.specifiers) {\n if (specifier.type === 'ImportSpecifier' && specifier.local.name === superName) {\n return true;\n }\n }\n }\n\n return false;\n}\n\n/**\n * Returns true if the string is camelCase (starts lowercase, no separators).\n */\nexport function isCamelCase(value: string): boolean {\n return /^[a-z][a-zA-Z0-9]*$/.test(value);\n}\n\n/**\n * Returns true if the string is PascalCase.\n */\nexport function isPascalCase(value: string): boolean {\n return /^[A-Z][a-zA-Z0-9]*$/.test(value);\n}\n\n/**\n * Converts a kebab-case, snake_case or PascalCase string to camelCase.\n */\nexport function toCamelCase(value: string): string {\n return value\n .replace(/[-_](.)/g, (_, c: string) => c.toUpperCase())\n .replace(/^[A-Z]/, (c) => c.toLowerCase());\n}\n\n/**\n * Converts a kebab-case, snake_case or camelCase string to PascalCase.\n */\nexport function toPascalCase(value: string): string {\n return value\n .replace(/[-_](.)/g, (_, c: string) => c.toUpperCase())\n .replace(/^[a-z]/, (c) => c.toUpperCase());\n}\n\n/**\n * Walks up ancestor nodes to find the nearest class declaration/expression.\n */\nexport function findEnclosingClass(ancestors: Node[]): Node | null {\n for (let i = ancestors.length - 1; i >= 0; i--) {\n const node = ancestors[i];\n if (node.type === 'ClassDeclaration' || node.type === 'ClassExpression') {\n return node;\n }\n }\n return null;\n}\n", "import { isBaseSubclass, type Node, type RuleContext, createRule } from '../utils/ast.ts';\n\nexport const requireConfig = createRule({\n meta: {\n type: 'problem',\n docs: {\n description: 'Require a static config property on classes extending Base',\n },\n messages: {\n missingConfig: 'Classes extending Base must define a static config property.',\n missingName: 'The static config must include a name property.',\n },\n },\n createOnce(context: RuleContext) {\n return {\n ClassDeclaration(node: Node) {\n check(node, context);\n },\n ClassExpression(node: Node) {\n check(node, context);\n },\n };\n },\n});\n\nfunction check(node: Node, context: RuleContext) {\n if (!isBaseSubclass(node, context)) return;\n\n const body: Node[] = node.body?.body ?? [];\n\n const configProp = body.find(\n (member: Node) =>\n member.type === 'PropertyDefinition' &&\n member.static === true &&\n member.key?.name === 'config',\n );\n\n if (!configProp) {\n context.report({ node, messageId: 'missingConfig' });\n return;\n }\n\n // Check that config has a `name` property\n const value = configProp.value;\n if (!value || value.type !== 'ObjectExpression') return;\n\n const hasName = value.properties?.some(\n (prop: Node) => prop.type === 'Property' && prop.key?.name === 'name' && prop.value?.value,\n );\n\n if (!hasName) {\n context.report({ node: configProp, messageId: 'missingName' });\n }\n}\n", "import {\n isBaseSubclass,\n isPascalCase,\n toPascalCase,\n type Node,\n type RuleContext,\n createRule,\n} from '../utils/ast.ts';\n\nexport const requireConfigNamePascalCase = createRule({\n meta: {\n type: 'problem',\n fixable: 'code',\n docs: {\n description: 'Require config.name to be PascalCase on classes extending Base',\n },\n messages: {\n notPascalCase: 'config.name \"{{name}}\" must be PascalCase.',\n },\n },\n createOnce(context: RuleContext) {\n return {\n ClassDeclaration(node: Node) {\n check(node, context);\n },\n ClassExpression(node: Node) {\n check(node, context);\n },\n };\n },\n});\n\nfunction check(node: Node, context: RuleContext) {\n if (!isBaseSubclass(node, context)) return;\n\n const body: Node[] = node.body?.body ?? [];\n\n const configProp = body.find(\n (member: Node) =>\n member.type === 'PropertyDefinition' &&\n member.static === true &&\n member.key?.name === 'config',\n );\n\n if (!configProp?.value || configProp.value.type !== 'ObjectExpression') return;\n\n const nameProp = configProp.value.properties?.find(\n (prop: Node) => prop.type === 'Property' && prop.key?.name === 'name',\n );\n\n if (!nameProp) return;\n\n const nameValue = nameProp.value?.value;\n if (typeof nameValue !== 'string') return;\n\n if (!isPascalCase(nameValue)) {\n context.report({\n node: nameProp.value,\n messageId: 'notPascalCase',\n data: { name: nameValue },\n fix: (fixer: any) => fixer.replaceText(nameProp.value, `'${toPascalCase(nameValue)}'`),\n });\n }\n}\n", "import {\n isBaseSubclass,\n isCamelCase,\n toCamelCase,\n type Node,\n type RuleContext,\n createRule,\n} from '../utils/ast.ts';\n\nexport const refsCamelCase = createRule({\n meta: {\n type: 'problem',\n fixable: 'code',\n docs: {\n description: 'Require ref names in static config to be camelCase',\n },\n messages: {\n notCamelCase: 'Ref name \"{{name}}\" must be camelCase.',\n },\n },\n createOnce(context: RuleContext) {\n return {\n ClassDeclaration(node: Node) {\n check(node, context);\n },\n ClassExpression(node: Node) {\n check(node, context);\n },\n };\n },\n});\n\nfunction check(node: Node, context: RuleContext) {\n if (!isBaseSubclass(node, context)) return;\n\n const body: Node[] = node.body?.body ?? [];\n\n const configProp = body.find(\n (member: Node) =>\n member.type === 'PropertyDefinition' &&\n member.static === true &&\n member.key?.name === 'config',\n );\n\n if (!configProp?.value || configProp.value.type !== 'ObjectExpression') return;\n\n const refsProp = configProp.value.properties?.find(\n (prop: Node) => prop.type === 'Property' && prop.key?.name === 'refs',\n );\n\n if (!refsProp?.value || refsProp.value.type !== 'ArrayExpression') return;\n\n for (const element of refsProp.value.elements ?? []) {\n if (!element || element.type !== 'Literal') continue;\n const raw = element.value;\n if (typeof raw !== 'string') continue;\n // Strip the multiple-ref suffix before checking casing\n const name = raw.endsWith('[]') ? raw.slice(0, -2) : raw;\n if (!isCamelCase(name)) {\n const fixed = toCamelCase(name) + (raw.endsWith('[]') ? '[]' : '');\n context.report({\n node: element,\n messageId: 'notCamelCase',\n data: { name },\n fix: (fixer: any) => fixer.replaceText(element, `'${fixed}'`),\n });\n }\n }\n}\n", "import {\n isBaseSubclass,\n isCamelCase,\n toCamelCase,\n type Node,\n type RuleContext,\n createRule,\n} from '../utils/ast.ts';\n\nexport const optionsCamelCase = createRule({\n meta: {\n type: 'problem',\n fixable: 'code',\n docs: {\n description: 'Require option keys in static config to be camelCase',\n },\n messages: {\n notCamelCase: 'Option key \"{{name}}\" must be camelCase.',\n },\n },\n createOnce(context: RuleContext) {\n return {\n ClassDeclaration(node: Node) {\n check(node, context);\n },\n ClassExpression(node: Node) {\n check(node, context);\n },\n };\n },\n});\n\nfunction check(node: Node, context: RuleContext) {\n if (!isBaseSubclass(node, context)) return;\n\n const body: Node[] = node.body?.body ?? [];\n\n const configProp = body.find(\n (member: Node) =>\n member.type === 'PropertyDefinition' &&\n member.static === true &&\n member.key?.name === 'config',\n );\n\n if (!configProp?.value || configProp.value.type !== 'ObjectExpression') return;\n\n const optionsProp = configProp.value.properties?.find(\n (prop: Node) => prop.type === 'Property' && prop.key?.name === 'options',\n );\n\n if (!optionsProp?.value || optionsProp.value.type !== 'ObjectExpression') return;\n\n for (const prop of optionsProp.value.properties ?? []) {\n if (prop.type !== 'Property') continue;\n const name = prop.key?.name ?? prop.key?.value;\n if (typeof name !== 'string') continue;\n if (!isCamelCase(name)) {\n const fixed = toCamelCase(name);\n // Quoted key ('slides-to-show') vs identifier key (SlidesToShow)\n const fixedText = prop.key.type === 'Literal' ? `'${fixed}'` : fixed;\n context.report({\n node: prop.key,\n messageId: 'notCamelCase',\n data: { name },\n fix: (fixer: any) => fixer.replaceText(prop.key, fixedText),\n });\n }\n }\n}\n", "import {\n isBaseSubclass,\n LIFECYCLE_METHODS,\n findEnclosingClass,\n type Node,\n type RuleContext,\n createRule,\n} from '../utils/ast.ts';\n\nexport const asyncLifecycleMethods = createRule({\n meta: {\n type: 'problem',\n fixable: 'code',\n docs: {\n description: 'Require lifecycle methods on Base subclasses to be async',\n },\n messages: {\n notAsync: 'Lifecycle method \"{{name}}\" must be declared as async.',\n },\n },\n createOnce(context: RuleContext) {\n return {\n MethodDefinition(node: Node) {\n const name = node.key?.name;\n if (!name || !LIFECYCLE_METHODS.has(name)) return;\n if (node.value?.async) return;\n\n const ancestors = context.getAncestors\n ? context.getAncestors()\n : (context.sourceCode?.getAncestors?.(node) ?? []);\n\n const enclosingClass = findEnclosingClass(ancestors);\n if (!enclosingClass || !isBaseSubclass(enclosingClass, context)) return;\n\n context.report({\n node,\n messageId: 'notAsync',\n data: { name },\n fix: (fixer: any) => fixer.insertTextBefore(node.key, 'async '),\n });\n },\n };\n },\n});\n", "import {\n isBaseSubclass,\n findEnclosingClass,\n type Node,\n type RuleContext,\n createRule,\n} from '../utils/ast.ts';\n\n// onXxxYyy \u2014 the part after \"on\" must start with an uppercase letter\nconst ON_HANDLER_RE = /^on[A-Z][a-zA-Z0-9]*$/;\n\nexport const onHandlerNaming = createRule({\n meta: {\n type: 'problem',\n docs: {\n description: 'Require event handler methods to follow the onXxxYyy naming convention',\n },\n messages: {\n invalidName:\n 'Event handler \"{{name}}\" must follow the onXxxYyy camelCase convention (e.g. onClickButton).',\n },\n },\n createOnce(context: RuleContext) {\n return {\n MethodDefinition(node: Node) {\n // Skip getters, setters \u2014 those are not event handlers\n if (node.kind === 'get' || node.kind === 'set') return;\n\n const name = node.key?.name;\n // Only lint methods that start with \"on\" followed by an uppercase letter \u2014\n // that's the unambiguous signal of an intended event handler.\n if (!name || !/^on[A-Z]/.test(name)) return;\n if (ON_HANDLER_RE.test(name)) return;\n\n const ancestors = context.getAncestors\n ? context.getAncestors()\n : (context.sourceCode?.getAncestors?.(node) ?? []);\n\n const enclosingClass = findEnclosingClass(ancestors);\n if (!enclosingClass || !isBaseSubclass(enclosingClass, context)) return;\n\n context.report({ node, messageId: 'invalidName', data: { name } });\n },\n };\n },\n});\n", "import {\n isBaseSubclass,\n findEnclosingClass,\n type Node,\n type RuleContext,\n createRule,\n} from '../utils/ast.ts';\n\n// Events that only make sense on window/document, never on a DOM element.\n// Pointer, keyboard, and form events are intentionally excluded \u2014 they can all\n// fire on elements too, so onResize/onScroll without a prefix is the only\n// unambiguous mistake worth flagging automatically.\nconst GLOBAL_ONLY_EVENTS = new Set(['Resize']);\n\nexport const onGlobalHandlerPrefix = createRule({\n meta: {\n type: 'suggestion',\n docs: {\n description:\n 'Require global event handlers (resize, scroll, etc.) to be prefixed with onWindow or onDocument',\n },\n messages: {\n missingPrefix:\n '\"{{name}}\" looks like a global event handler. Use \"onWindow{{event}}\" or \"onDocument{{event}}\" to bind to window/document events.',\n },\n },\n createOnce(context: RuleContext) {\n return {\n MethodDefinition(node: Node) {\n const name = node.key?.name;\n if (!name || !name.startsWith('on')) return;\n\n const suffix = name.slice(2); // strip \"on\"\n const event = GLOBAL_ONLY_EVENTS.has(suffix) ? suffix : null;\n if (!event) return;\n\n // Allow onWindow* and onDocument* \u2014 those are correct\n if (name.startsWith('onWindow') || name.startsWith('onDocument')) return;\n\n const ancestors = context.getAncestors\n ? context.getAncestors()\n : (context.sourceCode?.getAncestors?.(node) ?? []);\n\n const enclosingClass = findEnclosingClass(ancestors);\n if (!enclosingClass || !isBaseSubclass(enclosingClass, context)) return;\n\n context.report({\n node,\n messageId: 'missingPrefix',\n data: { name, event },\n });\n },\n };\n },\n});\n", "import {\n isBaseSubclass,\n findEnclosingClass,\n type Node,\n type RuleContext,\n createRule,\n} from '../utils/ast.ts';\n\nconst DEPRECATED = new Map([\n ['$parent', '$closest()'],\n ['$root', '$closest()'],\n ['$children', '$query()'],\n]);\n\nexport const noDeprecatedProperties = createRule({\n meta: {\n type: 'problem',\n docs: {\n description: 'Disallow deprecated Base properties ($parent, $children, $root)',\n },\n messages: {\n deprecated: '\"{{name}}\" is deprecated. Use {{replacement}} instead.',\n },\n },\n createOnce(context: RuleContext) {\n return {\n MemberExpression(node: Node) {\n const prop = node.property?.name;\n if (!prop || !DEPRECATED.has(prop)) return;\n\n // Only flag `this.$parent` etc. \u2014 not arbitrary object access\n if (node.object?.type !== 'ThisExpression') return;\n\n const ancestors = context.getAncestors\n ? context.getAncestors()\n : (context.sourceCode?.getAncestors?.(node) ?? []);\n\n const enclosingClass = findEnclosingClass(ancestors);\n if (!enclosingClass || !isBaseSubclass(enclosingClass, context)) return;\n\n const replacement = DEPRECATED.get(prop);\n context.report({\n node,\n messageId: 'deprecated',\n data: { name: prop, replacement },\n });\n },\n };\n },\n});\n", "import {\n findEnclosingClass,\n isBaseSubclass,\n type Node,\n type RuleContext,\n createRule,\n} from '../utils/ast.ts';\n\nexport const noDispatchEvent = createRule({\n meta: {\n type: 'suggestion',\n docs: {\n description: 'Disallow dispatchEvent() in Base subclasses \u2014 use this.$emit() instead',\n },\n messages: {\n useEmit: 'Use this.$emit() instead of dispatchEvent() to emit events in a Base component.',\n },\n },\n createOnce(context: RuleContext) {\n return {\n CallExpression(node: Node) {\n const callee = node.callee;\n\n const isDispatchEvent =\n // this.dispatchEvent(...)\n (callee.type === 'MemberExpression' &&\n callee.object?.type === 'ThisExpression' &&\n callee.property?.name === 'dispatchEvent') ||\n // this.$el.dispatchEvent(...) or el.dispatchEvent(...)\n (callee.type === 'MemberExpression' && callee.property?.name === 'dispatchEvent');\n\n if (!isDispatchEvent) return;\n\n const ancestors = context.getAncestors\n ? context.getAncestors()\n : (context.sourceCode?.getAncestors?.(node) ?? []);\n\n const enclosingClass = findEnclosingClass(ancestors);\n if (!enclosingClass || !isBaseSubclass(enclosingClass, context)) return;\n\n context.report({ node, messageId: 'useEmit' });\n },\n };\n },\n});\n", "import {\n findEnclosingClass,\n isBaseSubclass,\n type Node,\n type RuleContext,\n createRule,\n} from '../utils/ast.ts';\n\nexport const noShadowDom = createRule({\n meta: {\n type: 'problem',\n docs: {\n description: 'Disallow attachShadow() in Base subclasses \u2014 js-toolkit uses Light DOM only',\n },\n messages: {\n noShadow:\n 'Do not use attachShadow() in a Base component. @studiometa/js-toolkit uses Light DOM only.',\n },\n },\n createOnce(context: RuleContext) {\n return {\n CallExpression(node: Node) {\n const callee = node.callee;\n if (callee.type !== 'MemberExpression' || callee.property?.name !== 'attachShadow') {\n return;\n }\n\n const ancestors = context.getAncestors\n ? context.getAncestors()\n : (context.sourceCode?.getAncestors?.(node) ?? []);\n\n const enclosingClass = findEnclosingClass(ancestors);\n if (!enclosingClass || !isBaseSubclass(enclosingClass, context)) return;\n\n context.report({ node, messageId: 'noShadow' });\n },\n };\n },\n});\n", "import { type Node, type RuleContext, createRule } from '../utils/ast.ts';\n\nexport const noCreateApp = createRule({\n meta: {\n type: 'suggestion',\n docs: {\n description: 'Disallow createApp() \u2014 use registerComponent() instead',\n },\n messages: {\n useRegister:\n 'createApp() is deprecated. Use registerComponent() from @studiometa/js-toolkit instead.',\n },\n },\n createOnce(context: RuleContext) {\n return {\n CallExpression(node: Node) {\n const callee = node.callee;\n if (callee.type === 'Identifier' && callee.name === 'createApp') {\n context.report({ node, messageId: 'useRegister' });\n }\n },\n };\n },\n});\n", "import {\n findEnclosingClass,\n isBaseSubclass,\n type Node,\n type RuleContext,\n createRule,\n} from '../utils/ast.ts';\n\nconst FORBIDDEN = new Set(['addEventListener', 'removeEventListener']);\n\nexport const noEventListenerMethods = createRule({\n meta: {\n type: 'problem',\n docs: {\n description:\n 'Disallow addEventListener/removeEventListener in Base subclasses \u2014 use on* methods instead',\n },\n messages: {\n useOnMethod:\n '\"{{method}}()\" should not be used in a Base component. ' +\n 'Define an \"on<Target><Event>()\" method instead \u2014 the framework handles binding and cleanup automatically.',\n },\n },\n createOnce(context: RuleContext) {\n return {\n CallExpression(node: Node) {\n const callee = node.callee;\n if (callee.type !== 'MemberExpression') return;\n\n const method = callee.property?.name;\n if (!method || !FORBIDDEN.has(method)) return;\n\n // Only flag calls on `this.*`, `document`, or `window`\n let root = callee.object;\n while (root?.type === 'MemberExpression') root = root.object;\n const isThis = root?.type === 'ThisExpression';\n const isGlobal =\n root?.type === 'Identifier' && (root.name === 'document' || root.name === 'window');\n if (!isThis && !isGlobal) return;\n\n const ancestors = context.getAncestors\n ? context.getAncestors()\n : (context.sourceCode?.getAncestors?.(node) ?? []);\n\n const enclosingClass = findEnclosingClass(ancestors);\n if (!enclosingClass || !isBaseSubclass(enclosingClass, context)) return;\n\n context.report({ node, messageId: 'useOnMethod', data: { method } });\n },\n };\n },\n});\n", "import { isBaseSubclass, type Node, type RuleContext, createRule } from '../utils/ast.ts';\n\nexport const refsPluralMultiple = createRule({\n meta: {\n type: 'problem',\n docs: {\n description: 'Require multiple-ref names (using [] suffix) to be pluralized',\n },\n messages: {\n notPlural: 'Multiple ref \"{{name}}\" must be pluralized (e.g. \"{{name}}s[]\").',\n },\n },\n createOnce(context: RuleContext) {\n return {\n ClassDeclaration(node: Node) {\n check(node, context);\n },\n ClassExpression(node: Node) {\n check(node, context);\n },\n };\n },\n});\n\nfunction check(node: Node, context: RuleContext) {\n if (!isBaseSubclass(node, context)) return;\n\n const body: Node[] = node.body?.body ?? [];\n\n const configProp = body.find(\n (member: Node) =>\n member.type === 'PropertyDefinition' &&\n member.static === true &&\n member.key?.name === 'config',\n );\n\n if (!configProp?.value || configProp.value.type !== 'ObjectExpression') return;\n\n const refsProp = configProp.value.properties?.find(\n (prop: Node) => prop.type === 'Property' && prop.key?.name === 'refs',\n );\n\n if (!refsProp?.value || refsProp.value.type !== 'ArrayExpression') return;\n\n for (const element of refsProp.value.elements ?? []) {\n if (!element || element.type !== 'Literal') continue;\n const raw = element.value;\n if (typeof raw !== 'string') continue;\n if (!raw.endsWith('[]')) continue;\n\n const name = raw.slice(0, -2);\n if (!name.endsWith('s')) {\n context.report({\n node: element,\n messageId: 'notPlural',\n data: { name },\n });\n }\n }\n}\n", "import { type Node, type RuleContext, createRule } from '../utils/ast.ts';\n\nconst DEEP_UTILS_RE = /^@studiometa\\/js-toolkit\\/utils\\/.+/;\n\nexport const noDeepUtilsImport = createRule({\n meta: {\n type: 'problem',\n fixable: 'code',\n docs: {\n description: 'Disallow deep imports from @studiometa/js-toolkit/utils/*',\n },\n messages: {\n noDeepImport:\n 'Import from \"{{source}}\" should use the public entrypoint \"@studiometa/js-toolkit/utils\".',\n },\n },\n createOnce(context: RuleContext) {\n return {\n ImportDeclaration(node: Node) {\n const source: string = node.source.value;\n if (!DEEP_UTILS_RE.test(source)) return;\n\n context.report({\n node,\n messageId: 'noDeepImport',\n data: { source },\n fix(fixer: any) {\n const specifiers: Node[] = node.specifiers ?? [];\n const parts: string[] = [];\n\n for (const s of specifiers) {\n if (s.type === 'ImportDefaultSpecifier') {\n parts.push(s.local.name);\n } else if (s.type === 'ImportSpecifier') {\n const imported = s.imported.name;\n const local = s.local.name;\n parts.push(imported === local ? imported : `${imported} as ${local}`);\n }\n }\n\n const named = parts.join(', ');\n return fixer.replaceText(\n node,\n `import { ${named} } from '@studiometa/js-toolkit/utils';`,\n );\n },\n });\n },\n };\n },\n});\n", "import { toCamelCase, type Node, type RuleContext, createRule } from '../utils/ast.ts';\n\nfunction isThisRefs(node: Node): boolean {\n return (\n node.type === 'MemberExpression' &&\n node.object?.type === 'ThisExpression' &&\n node.property?.name === '$refs'\n );\n}\n\nexport const refsNoBracketAccess = createRule({\n meta: {\n type: 'problem',\n fixable: 'code',\n docs: {\n description: 'Disallow bracket access with [] suffix on this.$refs',\n },\n messages: {\n noBracketAccess: 'Use \"this.$refs.{{fixed}}\" instead of \"this.$refs[\\'{{raw}}\\']\".',\n },\n },\n createOnce(context: RuleContext) {\n return {\n MemberExpression(node: Node) {\n if (!isThisRefs(node.object)) return;\n if (!node.computed) return;\n const prop = node.property;\n if (prop.type !== 'Literal' || typeof prop.value !== 'string') return;\n const raw: string = prop.value;\n if (!raw.endsWith('[]')) return;\n\n const stripped = raw.slice(0, -2);\n const fixed = toCamelCase(stripped);\n\n context.report({\n node,\n messageId: 'noBracketAccess',\n data: { raw, fixed },\n fix(fixer: any) {\n const src = context.sourceCode ?? context.getSourceCode?.();\n const objText = src.getText(node.object);\n return fixer.replaceText(node, `${objText}.${fixed}`);\n },\n });\n },\n };\n },\n});\n", "import { type Node, type RuleContext, createRule } from '../utils/ast.ts';\n\nexport const noRedundantWithMountWhenInView = createRule({\n meta: {\n type: 'suggestion',\n docs: {\n description: 'Disallow wrapping withMountWhenInView inside withScrolledInView (redundant)',\n },\n messages: {\n redundant:\n 'withScrolledInView already includes withMountWhenInView internally. Remove the inner withMountWhenInView call.',\n },\n },\n createOnce(context: RuleContext) {\n return {\n 'ClassDeclaration, ClassExpression'(node: Node) {\n check(node, context);\n },\n };\n },\n});\n\nfunction check(node: Node, context: RuleContext) {\n const superClass = node.superClass;\n if (!superClass || superClass.type !== 'CallExpression') return;\n if (superClass.callee?.name !== 'withScrolledInView') return;\n\n const arg = superClass.arguments?.[0];\n if (!arg || arg.type !== 'CallExpression') return;\n if (arg.callee?.name !== 'withMountWhenInView') return;\n\n context.report({ node: superClass, messageId: 'redundant' });\n}\n", "import {\n findEnclosingClass,\n isBaseSubclass,\n type Node,\n type RuleContext,\n createRule,\n} from '../utils/ast.ts';\n\nconst QUERY_METHODS = new Set(['querySelector', 'querySelectorAll']);\n\nfunction isThisEl(node: Node): boolean {\n return (\n node.type === 'MemberExpression' &&\n node.object?.type === 'ThisExpression' &&\n node.property?.name === '$el'\n );\n}\n\nexport const preferRefOverQuerySelector = createRule({\n meta: {\n type: 'suggestion',\n docs: {\n description: 'Prefer this.$refs over this.$el.querySelector() in Base subclasses',\n },\n messages: {\n preferRef:\n 'Avoid \"this.$el.{{method}}()\". Declare a ref in static config and use \"this.$refs\" instead.',\n },\n },\n createOnce(context: RuleContext) {\n return {\n CallExpression(node: Node) {\n const callee = node.callee;\n if (callee?.type !== 'MemberExpression') return;\n if (!isThisEl(callee.object)) return;\n const method = callee.property?.name;\n if (!QUERY_METHODS.has(method)) return;\n\n const ancestors =\n context.getAncestors?.() ?? context.sourceCode?.getAncestors?.(node) ?? [];\n const cls = findEnclosingClass(ancestors);\n if (!cls || !isBaseSubclass(cls, context)) return;\n\n context.report({ node, messageId: 'preferRef', data: { method } });\n },\n };\n },\n});\n", "import {\n isBaseSubclass,\n toCamelCase,\n type Node,\n type RuleContext,\n createRule,\n} from '../utils/ast.ts';\n\nfunction collectDeclaredRefs(classNode: Node): Set<string> {\n const body: Node[] = classNode.body?.body ?? [];\n const configProp = body.find(\n (m: Node) => m.type === 'PropertyDefinition' && m.static === true && m.key?.name === 'config',\n );\n\n if (!configProp?.value || configProp.value.type !== 'ObjectExpression') return new Set();\n\n const refsProp = configProp.value.properties?.find(\n (p: Node) => p.type === 'Property' && p.key?.name === 'refs',\n );\n\n if (!refsProp?.value || refsProp.value.type !== 'ArrayExpression') return new Set();\n\n const names = new Set<string>();\n for (const el of refsProp.value.elements ?? []) {\n if (!el || el.type !== 'Literal' || typeof el.value !== 'string') continue;\n const raw: string = el.value;\n const stripped = raw.endsWith('[]') ? raw.slice(0, -2) : raw;\n names.add(toCamelCase(stripped));\n }\n return names;\n}\n\nfunction isThisRefs(node: Node): boolean {\n return (\n node.type === 'MemberExpression' &&\n node.object?.type === 'ThisExpression' &&\n node.property?.name === '$refs'\n );\n}\n\nexport const requireRefsDeclaredInConfig = createRule({\n meta: {\n type: 'problem',\n docs: {\n description: 'Require all this.$refs accesses to be declared in static config.refs',\n },\n messages: {\n undeclared: 'Ref \"{{name}}\" is not declared in static config.refs.',\n },\n },\n createOnce(context: RuleContext) {\n return {\n 'ClassDeclaration, ClassExpression'(classNode: Node) {\n if (!isBaseSubclass(classNode, context)) return;\n\n const declared = collectDeclaredRefs(classNode);\n\n // Walk the class body looking for this.$refs.<name> accesses\n walkNode(classNode.body, (node: Node) => {\n if (node.type !== 'MemberExpression') return;\n if (!isThisRefs(node.object)) return;\n\n let refName: string | null = null;\n\n if (!node.computed && node.property?.type === 'Identifier') {\n refName = node.property.name;\n } else if (\n node.computed &&\n node.property?.type === 'Literal' &&\n typeof node.property.value === 'string'\n ) {\n const raw: string = node.property.value;\n const stripped = raw.endsWith('[]') ? raw.slice(0, -2) : raw;\n refName = toCamelCase(stripped);\n }\n\n if (refName && !declared.has(refName)) {\n context.report({\n node,\n messageId: 'undeclared',\n data: { name: refName },\n });\n }\n });\n },\n };\n },\n});\n\nfunction walkNode(node: Node, visit: (n: Node) => void) {\n if (!node || typeof node !== 'object') return;\n visit(node);\n for (const key of Object.keys(node)) {\n if (key === 'parent') continue;\n const child = node[key];\n if (Array.isArray(child)) {\n for (const item of child) walkNode(item, visit);\n } else if (child && typeof child === 'object' && child.type) {\n walkNode(child, visit);\n }\n }\n}\n", "import {\n findEnclosingClass,\n isBaseSubclass,\n type Node,\n type RuleContext,\n createRule,\n} from '../utils/ast.ts';\n\nexport const noManualIntersectionObserver = createRule({\n meta: {\n type: 'suggestion',\n docs: {\n description:\n 'Disallow manual IntersectionObserver inside Base subclasses; use withIntersectionObserver or withMountWhenInView instead',\n },\n messages: {\n noManual:\n 'Avoid manual \"new IntersectionObserver()\". Use \"withIntersectionObserver\" or \"withMountWhenInView\" decorators instead.',\n },\n },\n createOnce(context: RuleContext) {\n return {\n NewExpression(node: Node) {\n if (node.callee?.name !== 'IntersectionObserver') return;\n\n const ancestors =\n context.getAncestors?.() ?? context.sourceCode?.getAncestors?.(node) ?? [];\n const cls = findEnclosingClass(ancestors);\n if (!cls || !isBaseSubclass(cls, context)) return;\n\n context.report({ node, messageId: 'noManual' });\n },\n };\n },\n});\n", "import {\n findEnclosingClass,\n isBaseSubclass,\n type Node,\n type RuleContext,\n createRule,\n} from '../utils/ast.ts';\n\nexport const noManualMutationObserver = createRule({\n meta: {\n type: 'suggestion',\n docs: {\n description:\n 'Disallow manual MutationObserver inside Base subclasses; use withMutation decorator instead',\n },\n messages: {\n noManual: 'Avoid manual \"new MutationObserver()\". Use the \"withMutation\" decorator instead.',\n },\n },\n createOnce(context: RuleContext) {\n return {\n NewExpression(node: Node) {\n if (node.callee?.name !== 'MutationObserver') return;\n\n const ancestors =\n context.getAncestors?.() ?? context.sourceCode?.getAncestors?.(node) ?? [];\n const cls = findEnclosingClass(ancestors);\n if (!cls || !isBaseSubclass(cls, context)) return;\n\n context.report({ node, messageId: 'noManual' });\n },\n };\n },\n});\n", "import { isBaseSubclass, type Node, type RuleContext, createRule } from '../utils/ast.ts';\n\n/**\n * Returns true if the string is kebab-case:\n * all lowercase letters, digits and hyphens, no underscores or uppercase.\n */\nfunction isKebabCase(value: string): boolean {\n return /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/.test(value);\n}\n\n/**\n * Converts a camelCase, PascalCase or snake_case string to kebab-case.\n */\nfunction toKebabCase(value: string): string {\n return value\n .replace(/([A-Z])/g, (_, c: string) => `-${c.toLowerCase()}`)\n .replace(/_/g, '-')\n .replace(/^-/, '')\n .toLowerCase();\n}\n\nfunction check(node: Node, context: RuleContext) {\n if (!isBaseSubclass(node, context)) return;\n\n const body: Node[] = node.body?.body ?? [];\n\n const configProp = body.find(\n (member: Node) =>\n member.type === 'PropertyDefinition' &&\n member.static === true &&\n member.key?.name === 'config',\n );\n\n if (!configProp?.value || configProp.value.type !== 'ObjectExpression') return;\n\n const emitsProp = configProp.value.properties?.find(\n (prop: Node) => prop.type === 'Property' && prop.key?.name === 'emits',\n );\n\n if (!emitsProp?.value || emitsProp.value.type !== 'ArrayExpression') return;\n\n for (const element of emitsProp.value.elements ?? []) {\n if (!element || element.type !== 'Literal') continue;\n const name = element.value;\n if (typeof name !== 'string') continue;\n if (!isKebabCase(name)) {\n const fixed = toKebabCase(name);\n context.report({\n node: element,\n messageId: 'notKebabCase',\n data: { name },\n fix: (fixer: any) => fixer.replaceText(element, `'${fixed}'`),\n });\n }\n }\n}\n\nexport const emitsKebabCase = createRule({\n meta: {\n type: 'problem',\n fixable: 'code',\n docs: {\n description: 'Require emit names in static config to be kebab-case',\n },\n messages: {\n notKebabCase: 'Emit name \"{{name}}\" must be kebab-case (e.g. \"content-change\").',\n },\n },\n createOnce(context: RuleContext) {\n return {\n ClassDeclaration(node: Node) {\n check(node, context);\n },\n ClassExpression(node: Node) {\n check(node, context);\n },\n };\n },\n});\n", "import { isBaseSubclass, type Node, type RuleContext, createRule } from '../utils/ast.ts';\n\nfunction check(node: Node, context: RuleContext) {\n if (!isBaseSubclass(node, context)) return;\n\n const body: Node[] = node.body?.body ?? [];\n\n const configProp = body.find(\n (member: Node) =>\n member.type === 'PropertyDefinition' &&\n member.static === true &&\n member.key?.name === 'config',\n );\n\n if (!configProp?.value || configProp.value.type !== 'ObjectExpression') return;\n\n const emitsProp = configProp.value.properties?.find(\n (prop: Node) => prop.type === 'Property' && prop.key?.name === 'emits',\n );\n\n if (!emitsProp?.value || emitsProp.value.type !== 'ArrayExpression') return;\n\n for (const element of emitsProp.value.elements ?? []) {\n if (!element || element.type !== 'Literal') continue;\n const name = element.value;\n if (typeof name !== 'string') continue;\n if (!name.includes('-')) {\n context.report({\n node: element,\n messageId: 'singleWord',\n data: { name },\n });\n }\n }\n}\n\nexport const emitsMultiWord = createRule({\n meta: {\n type: 'problem',\n docs: {\n description:\n 'Require emit names in static config to be multi-word to avoid collision with native DOM events',\n },\n messages: {\n singleWord:\n 'Emit name \"{{name}}\" must be multi-word (e.g. \"item-click\" instead of \"click\") to avoid collisions with native DOM events.',\n },\n },\n createOnce(context: RuleContext) {\n return {\n ClassDeclaration(node: Node) {\n check(node, context);\n },\n ClassExpression(node: Node) {\n check(node, context);\n },\n };\n },\n});\n", "import {\n isBaseSubclass,\n isPascalCase,\n toPascalCase,\n type Node,\n type RuleContext,\n createRule,\n} from '../utils/ast.ts';\n\nfunction check(node: Node, context: RuleContext) {\n if (!isBaseSubclass(node, context)) return;\n\n const body: Node[] = node.body?.body ?? [];\n\n const configProp = body.find(\n (member: Node) =>\n member.type === 'PropertyDefinition' &&\n member.static === true &&\n member.key?.name === 'config',\n );\n\n if (!configProp?.value || configProp.value.type !== 'ObjectExpression') return;\n\n const componentsProp = configProp.value.properties?.find(\n (prop: Node) => prop.type === 'Property' && prop.key?.name === 'components',\n );\n\n if (!componentsProp?.value || componentsProp.value.type !== 'ObjectExpression') return;\n\n for (const prop of componentsProp.value.properties ?? []) {\n if (prop.type !== 'Property') continue;\n const name = prop.key?.name ?? prop.key?.value;\n if (typeof name !== 'string') continue;\n if (!isPascalCase(name)) {\n const fixed = toPascalCase(name);\n const fixedText = prop.key.type === 'Literal' ? `'${fixed}'` : fixed;\n context.report({\n node: prop.key,\n messageId: 'notPascalCase',\n data: { name },\n fix: (fixer: any) => fixer.replaceText(prop.key, fixedText),\n });\n }\n }\n}\n\nexport const componentsPascalCase = createRule({\n meta: {\n type: 'problem',\n fixable: 'code',\n docs: {\n description: 'Require component keys in static config to be PascalCase',\n },\n messages: {\n notPascalCase: 'Component key \"{{name}}\" must be PascalCase (e.g. \"MyComponent\").',\n },\n },\n createOnce(context: RuleContext) {\n return {\n ClassDeclaration(node: Node) {\n check(node, context);\n },\n ClassExpression(node: Node) {\n check(node, context);\n },\n };\n },\n});\n", "import { isBaseSubclass, type Node, type RuleContext, createRule } from '../utils/ast.ts';\n\nfunction collectDeclaredEmits(classNode: Node): Set<string> {\n const body: Node[] = classNode.body?.body ?? [];\n const configProp = body.find(\n (m: Node) => m.type === 'PropertyDefinition' && m.static === true && m.key?.name === 'config',\n );\n\n if (!configProp?.value || configProp.value.type !== 'ObjectExpression') return new Set();\n\n const emitsProp = configProp.value.properties?.find(\n (p: Node) => p.type === 'Property' && p.key?.name === 'emits',\n );\n\n if (!emitsProp?.value || emitsProp.value.type !== 'ArrayExpression') return new Set();\n\n const names = new Set<string>();\n for (const el of emitsProp.value.elements ?? []) {\n if (el?.type === 'Literal' && typeof el.value === 'string') {\n names.add(el.value);\n }\n }\n return names;\n}\n\n/**\n * Returns true if `node` looks like `this.$emit`.\n */\nfunction isThisEmit(node: Node): boolean {\n return (\n node.type === 'MemberExpression' &&\n node.object?.type === 'ThisExpression' &&\n node.property?.name === '$emit'\n );\n}\n\nexport const requireEmitDeclaredInConfig = createRule({\n meta: {\n type: 'problem',\n docs: {\n description:\n 'Require all this.$emit() calls to use event names declared in static config.emits',\n },\n messages: {\n undeclared: 'Emit \"{{name}}\" is not declared in static config.emits.',\n },\n },\n createOnce(context: RuleContext) {\n return {\n 'ClassDeclaration, ClassExpression'(classNode: Node) {\n if (!isBaseSubclass(classNode, context)) return;\n\n const declared = collectDeclaredEmits(classNode);\n\n walkNode(classNode.body, (node: Node) => {\n // Match: this.$emit('event-name', ...)\n if (node.type !== 'CallExpression') return;\n if (!isThisEmit(node.callee)) return;\n\n const firstArg = node.arguments?.[0];\n if (!firstArg || firstArg.type !== 'Literal') return;\n const name = firstArg.value;\n if (typeof name !== 'string') return;\n\n if (!declared.has(name)) {\n context.report({\n node: firstArg,\n messageId: 'undeclared',\n data: { name },\n });\n }\n });\n },\n };\n },\n});\n\nfunction walkNode(node: Node, visit: (n: Node) => void) {\n if (!node || typeof node !== 'object') return;\n visit(node);\n for (const key of Object.keys(node)) {\n if (key === 'parent') continue;\n const child = node[key];\n if (Array.isArray(child)) {\n for (const item of child) walkNode(item, visit);\n } else if (child && typeof child === 'object' && child.type) {\n walkNode(child, visit);\n }\n }\n}\n", "import { isBaseSubclass, type Node, type RuleContext, createRule } from '../utils/ast.ts';\n\nfunction collectDeclaredComponents(classNode: Node): Set<string> {\n const body: Node[] = classNode.body?.body ?? [];\n const configProp = body.find(\n (m: Node) => m.type === 'PropertyDefinition' && m.static === true && m.key?.name === 'config',\n );\n\n if (!configProp?.value || configProp.value.type !== 'ObjectExpression') return new Set();\n\n const componentsProp = configProp.value.properties?.find(\n (p: Node) => p.type === 'Property' && p.key?.name === 'components',\n );\n\n if (!componentsProp?.value || componentsProp.value.type !== 'ObjectExpression') return new Set();\n\n const names = new Set<string>();\n for (const prop of componentsProp.value.properties ?? []) {\n if (prop.type !== 'Property') continue;\n const name = prop.key?.name ?? prop.key?.value;\n if (typeof name === 'string') {\n names.add(name);\n }\n }\n return names;\n}\n\n/**\n * Returns true if `node` looks like `this.$children`.\n */\nfunction isThisChildren(node: Node): boolean {\n return (\n node.type === 'MemberExpression' &&\n node.object?.type === 'ThisExpression' &&\n node.property?.name === '$children'\n );\n}\n\nexport const requireChildrenDeclaredInConfig = createRule({\n meta: {\n type: 'problem',\n docs: {\n description:\n 'Require all this.$children accesses to use component names declared in static config.components',\n },\n messages: {\n undeclared: 'Component \"{{name}}\" is not declared in static config.components.',\n },\n },\n createOnce(context: RuleContext) {\n return {\n 'ClassDeclaration, ClassExpression'(classNode: Node) {\n if (!isBaseSubclass(classNode, context)) return;\n\n const declared = collectDeclaredComponents(classNode);\n\n walkNode(classNode.body, (node: Node) => {\n if (node.type !== 'MemberExpression') return;\n if (!isThisChildren(node.object)) return;\n\n let name: string | null = null;\n\n if (!node.computed && node.property?.type === 'Identifier') {\n name = node.property.name;\n } else if (\n node.computed &&\n node.property?.type === 'Literal' &&\n typeof node.property.value === 'string'\n ) {\n name = node.property.value;\n }\n\n if (name && !declared.has(name)) {\n context.report({\n node,\n messageId: 'undeclared',\n data: { name },\n });\n }\n });\n },\n };\n },\n});\n\nfunction walkNode(node: Node, visit: (n: Node) => void) {\n if (!node || typeof node !== 'object') return;\n visit(node);\n for (const key of Object.keys(node)) {\n if (key === 'parent') continue;\n const child = node[key];\n if (Array.isArray(child)) {\n for (const item of child) walkNode(item, visit);\n } else if (child && typeof child === 'object' && child.type) {\n walkNode(child, visit);\n }\n }\n}\n", "import {\n isBaseSubclass,\n toCamelCase,\n type Node,\n type RuleContext,\n createRule,\n} from '../utils/ast.ts';\n\nfunction collectDeclaredOptions(classNode: Node): Set<string> {\n const body: Node[] = classNode.body?.body ?? [];\n const configProp = body.find(\n (m: Node) => m.type === 'PropertyDefinition' && m.static === true && m.key?.name === 'config',\n );\n\n if (!configProp?.value || configProp.value.type !== 'ObjectExpression') return new Set();\n\n const optionsProp = configProp.value.properties?.find(\n (p: Node) => p.type === 'Property' && p.key?.name === 'options',\n );\n\n if (!optionsProp?.value || optionsProp.value.type !== 'ObjectExpression') return new Set();\n\n const names = new Set<string>();\n for (const prop of optionsProp.value.properties ?? []) {\n if (prop.type !== 'Property') continue;\n const name = prop.key?.name ?? prop.key?.value;\n if (typeof name === 'string') {\n names.add(toCamelCase(name));\n }\n }\n return names;\n}\n\n/**\n * Returns true if `node` looks like `this.$options`.\n */\nfunction isThisOptions(node: Node): boolean {\n return (\n node.type === 'MemberExpression' &&\n node.object?.type === 'ThisExpression' &&\n node.property?.name === '$options'\n );\n}\n\nexport const requireOptionsDeclaredInConfig = createRule({\n meta: {\n type: 'problem',\n docs: {\n description:\n 'Require all this.$options accesses to use option names declared in static config.options',\n },\n messages: {\n undeclared: 'Option \"{{name}}\" is not declared in static config.options.',\n },\n },\n createOnce(context: RuleContext) {\n return {\n 'ClassDeclaration, ClassExpression'(classNode: Node) {\n if (!isBaseSubclass(classNode, context)) return;\n\n const declared = collectDeclaredOptions(classNode);\n\n walkNode(classNode.body, (node: Node) => {\n if (node.type !== 'MemberExpression') return;\n if (!isThisOptions(node.object)) return;\n\n let name: string | null = null;\n\n if (!node.computed && node.property?.type === 'Identifier') {\n name = node.property.name;\n } else if (\n node.computed &&\n node.property?.type === 'Literal' &&\n typeof node.property.value === 'string'\n ) {\n name = toCamelCase(node.property.value);\n }\n\n if (name && !declared.has(name)) {\n context.report({\n node,\n messageId: 'undeclared',\n data: { name },\n });\n }\n });\n },\n };\n },\n});\n\nfunction walkNode(node: Node, visit: (n: Node) => void) {\n if (!node || typeof node !== 'object') return;\n visit(node);\n for (const key of Object.keys(node)) {\n if (key === 'parent') continue;\n const child = node[key];\n if (Array.isArray(child)) {\n for (const item of child) walkNode(item, visit);\n } else if (child && typeof child === 'object' && child.type) {\n walkNode(child, visit);\n }\n }\n}\n", "import {\n findEnclosingClass,\n isBaseSubclass,\n type Node,\n type RuleContext,\n createRule,\n} from '../utils/ast.ts';\n\nconst TRACKED_PROPERTIES = new Set(['$refs', '$options', '$children']);\n\nfunction isTrackedLookup(node: Node): { prop: string; name: string } | null {\n if (\n node.type === 'MemberExpression' &&\n node.object?.type === 'MemberExpression' &&\n node.object.object?.type === 'ThisExpression' &&\n node.object.property?.type === 'Identifier' &&\n TRACKED_PROPERTIES.has(node.object.property.name) &&\n node.property?.type === 'Identifier' &&\n !node.computed\n ) {\n return { prop: node.object.property.name, name: node.property.name };\n }\n return null;\n}\n\nfunction findEnclosingMethod(ancestors: Node[]): Node | null {\n for (let i = ancestors.length - 1; i >= 0; i--) {\n const node = ancestors[i];\n if (node.type === 'MethodDefinition') return node;\n }\n return null;\n}\n\nexport const preferDestructuredLookups = createRule({\n meta: {\n type: 'suggestion',\n docs: {\n description:\n 'Prefer destructuring this.$refs, this.$options and this.$children into local variables when accessed multiple times in the same method',\n },\n messages: {\n preferDestructured:\n '\"this.{{prop}}.{{name}}\" is accessed {{count}} times. Destructure it into a local variable to avoid repeated lookups.',\n },\n },\n createOnce(context: RuleContext) {\n // methodKey -> lookup key -> list of nodes\n const methodLookups = new Map<Node, Map<string, Node[]>>();\n\n return {\n MemberExpression(node: Node) {\n const match = isTrackedLookup(node);\n if (!match) return;\n\n const ancestors =\n context.getAncestors?.() ?? context.sourceCode?.getAncestors?.(node) ?? [];\n const method = findEnclosingMethod(ancestors);\n if (!method) return;\n\n const cls = findEnclosingClass(ancestors);\n if (!cls || !isBaseSubclass(cls, context)) return;\n\n if (!methodLookups.has(method)) methodLookups.set(method, new Map());\n const map = methodLookups.get(method)!;\n const key = `${match.prop}.${match.name}`;\n const list = map.get(key) ?? [];\n list.push(node);\n map.set(key, list);\n },\n\n 'MethodDefinition:exit'(node: Node) {\n const map = methodLookups.get(node);\n if (!map) return;\n methodLookups.delete(node);\n\n for (const [key, nodes] of map) {\n if (nodes.length < 2) continue;\n const [prop, name] = key.split('.');\n context.report({\n node: nodes[0],\n messageId: 'preferDestructured',\n data: { prop, name, count: String(nodes.length) },\n });\n }\n },\n };\n },\n});\n", "import { isBaseSubclass, type Node, type RuleContext, createRule } from '../utils/ast.ts';\n\nexport const noDollarPrefix = createRule({\n meta: {\n type: 'problem',\n docs: {\n description:\n 'Disallow user-defined methods and properties prefixed with \"$\" in Base subclasses \u2014 \"$\" is reserved for js-toolkit framework members',\n },\n messages: {\n noDollarPrefix:\n '\"${{name}}\" uses the \"$\" prefix, which is reserved for js-toolkit framework members. Rename it without the \"$\" prefix.',\n },\n },\n createOnce(context: RuleContext) {\n return {\n ClassDeclaration(node: Node) {\n check(node, context);\n },\n ClassExpression(node: Node) {\n check(node, context);\n },\n };\n },\n});\n\nfunction check(node: Node, context: RuleContext) {\n if (!isBaseSubclass(node, context)) return;\n\n for (const member of node.body?.body ?? []) {\n if (member.static) continue;\n if (member.type !== 'MethodDefinition' && member.type !== 'PropertyDefinition') continue;\n const name: string = member.key?.name ?? '';\n if (name.startsWith('$')) {\n context.report({\n node: member.key,\n messageId: 'noDollarPrefix',\n data: { name: name.slice(1) },\n });\n }\n }\n}\n", "import { isBaseSubclass, type Node, type RuleContext, createRule } from '../utils/ast.ts';\n\nconst SETUP_CALLS = new Set(['setTimeout', 'setInterval', 'requestAnimationFrame']);\n\nexport const requireDestroyedCleanup = createRule({\n meta: {\n type: 'suggestion',\n docs: {\n description:\n 'Require a destroyed() method in Base subclasses that use setTimeout, setInterval or requestAnimationFrame',\n },\n messages: {\n requireDestroyed:\n 'This component uses {{calls}} but has no destroyed() method. Add destroyed() to clear timers and avoid memory leaks.',\n },\n },\n createOnce(context: RuleContext) {\n // class node -> set of timer call names found\n const classTimers = new Map<Node, Set<string>>();\n // class node -> whether destroyed() exists\n const classHasDestroyed = new Map<Node, boolean>();\n\n return {\n ClassDeclaration(node: Node) {\n classTimers.set(node, new Set());\n classHasDestroyed.set(node, false);\n },\n\n ClassExpression(node: Node) {\n classTimers.set(node, new Set());\n classHasDestroyed.set(node, false);\n },\n\n MethodDefinition(node: Node) {\n if (node.key?.name === 'destroyed') {\n // Find the enclosing class\n const sourceCode = context.sourceCode ?? context.getSourceCode?.();\n const ancestors = context.getAncestors?.() ?? sourceCode?.getAncestors?.(node) ?? [];\n for (let i = ancestors.length - 1; i >= 0; i--) {\n const a = ancestors[i];\n if (a.type === 'ClassDeclaration' || a.type === 'ClassExpression') {\n classHasDestroyed.set(a, true);\n break;\n }\n }\n }\n },\n\n CallExpression(node: Node) {\n if (node.callee?.type !== 'Identifier') return;\n if (!SETUP_CALLS.has(node.callee.name)) return;\n\n const sourceCode = context.sourceCode ?? context.getSourceCode?.();\n const ancestors = context.getAncestors?.() ?? sourceCode?.getAncestors?.(node) ?? [];\n\n for (let i = ancestors.length - 1; i >= 0; i--) {\n const a = ancestors[i];\n if (a.type === 'ClassDeclaration' || a.type === 'ClassExpression') {\n if (!isBaseSubclass(a, context)) break;\n classTimers.get(a)?.add(node.callee.name);\n break;\n }\n }\n },\n\n 'ClassDeclaration:exit'(node: Node) {\n reportIfNeeded(node, context, classTimers, classHasDestroyed);\n },\n\n 'ClassExpression:exit'(node: Node) {\n reportIfNeeded(node, context, classTimers, classHasDestroyed);\n },\n };\n },\n});\n\nfunction reportIfNeeded(\n node: Node,\n context: RuleContext,\n classTimers: Map<Node, Set<string>>,\n classHasDestroyed: Map<Node, boolean>,\n) {\n const timers = classTimers.get(node);\n const hasDestroyed = classHasDestroyed.get(node);\n classTimers.delete(node);\n classHasDestroyed.delete(node);\n\n if (!timers || timers.size === 0) return;\n if (hasDestroyed) return;\n\n context.report({\n node: node.id ?? node,\n messageId: 'requireDestroyed',\n data: { calls: [...timers].join(', ') },\n });\n}\n", "import { eslintCompatPlugin } from '@oxlint/plugins';\nimport {\n requireConfig,\n requireConfigNamePascalCase,\n refsCamelCase,\n optionsCamelCase,\n asyncLifecycleMethods,\n onHandlerNaming,\n onGlobalHandlerPrefix,\n noDeprecatedProperties,\n noDispatchEvent,\n noShadowDom,\n noCreateApp,\n noEventListenerMethods,\n refsPluralMultiple,\n noDeepUtilsImport,\n refsNoBracketAccess,\n noRedundantWithMountWhenInView,\n preferRefOverQuerySelector,\n requireRefsDeclaredInConfig,\n noManualIntersectionObserver,\n noManualMutationObserver,\n emitsKebabCase,\n emitsMultiWord,\n componentsPascalCase,\n requireEmitDeclaredInConfig,\n requireChildrenDeclaredInConfig,\n requireOptionsDeclaredInConfig,\n preferDestructuredLookups,\n noDollarPrefix,\n requireDestroyedCleanup,\n} from './rules/index.ts';\n\nconst PLUGIN_NAME = 'js-toolkit';\n\nconst rules = {\n 'require-config': requireConfig,\n 'require-config-name-pascal-case': requireConfigNamePascalCase,\n 'refs-camel-case': refsCamelCase,\n 'refs-plural-multiple': refsPluralMultiple,\n 'options-camel-case': optionsCamelCase,\n 'async-lifecycle-methods': asyncLifecycleMethods,\n 'on-handler-naming': onHandlerNaming,\n 'on-global-handler-prefix': onGlobalHandlerPrefix,\n 'no-deprecated-properties': noDeprecatedProperties,\n 'no-dispatch-event': noDispatchEvent,\n 'no-shadow-dom': noShadowDom,\n 'no-create-app': noCreateApp,\n 'no-event-listener-methods': noEventListenerMethods,\n 'no-deep-utils-import': noDeepUtilsImport,\n 'refs-no-bracket-access': refsNoBracketAccess,\n 'no-redundant-with-mount-when-in-view': noRedundantWithMountWhenInView,\n 'prefer-ref-over-query-selector': preferRefOverQuerySelector,\n 'require-refs-declared-in-config': requireRefsDeclaredInConfig,\n 'no-manual-intersection-observer': noManualIntersectionObserver,\n 'no-manual-mutation-observer': noManualMutationObserver,\n 'emits-kebab-case': emitsKebabCase,\n 'emits-multi-word': emitsMultiWord,\n 'components-pascal-case': componentsPascalCase,\n 'require-emit-declared-in-config': requireEmitDeclaredInConfig,\n 'require-children-declared-in-config': requireChildrenDeclaredInConfig,\n 'require-options-declared-in-config': requireOptionsDeclaredInConfig,\n 'prefer-destructured-lookups': preferDestructuredLookups,\n 'no-dollar-prefix': noDollarPrefix,\n 'require-destroyed-cleanup': requireDestroyedCleanup,\n};\n\nconst recommendedRules: Record<string, string> = {\n [`${PLUGIN_NAME}/require-config`]: 'error',\n [`${PLUGIN_NAME}/require-config-name-pascal-case`]: 'error',\n [`${PLUGIN_NAME}/refs-camel-case`]: 'error',\n [`${PLUGIN_NAME}/refs-plural-multiple`]: 'error',\n [`${PLUGIN_NAME}/options-camel-case`]: 'error',\n [`${PLUGIN_NAME}/async-lifecycle-methods`]: 'error',\n [`${PLUGIN_NAME}/on-handler-naming`]: 'error',\n [`${PLUGIN_NAME}/on-global-handler-prefix`]: 'warn',\n [`${PLUGIN_NAME}/no-deprecated-properties`]: 'warn',\n [`${PLUGIN_NAME}/no-dispatch-event`]: 'warn',\n [`${PLUGIN_NAME}/no-shadow-dom`]: 'error',\n [`${PLUGIN_NAME}/no-create-app`]: 'warn',\n [`${PLUGIN_NAME}/no-event-listener-methods`]: 'error',\n [`${PLUGIN_NAME}/no-deep-utils-import`]: 'error',\n [`${PLUGIN_NAME}/refs-no-bracket-access`]: 'error',\n [`${PLUGIN_NAME}/no-redundant-with-mount-when-in-view`]: 'warn',\n [`${PLUGIN_NAME}/prefer-ref-over-query-selector`]: 'warn',\n [`${PLUGIN_NAME}/require-refs-declared-in-config`]: 'error',\n [`${PLUGIN_NAME}/no-manual-intersection-observer`]: 'warn',\n [`${PLUGIN_NAME}/no-manual-mutation-observer`]: 'warn',\n [`${PLUGIN_NAME}/emits-kebab-case`]: 'error',\n [`${PLUGIN_NAME}/emits-multi-word`]: 'error',\n [`${PLUGIN_NAME}/components-pascal-case`]: 'error',\n [`${PLUGIN_NAME}/require-emit-declared-in-config`]: 'error',\n [`${PLUGIN_NAME}/require-children-declared-in-config`]: 'error',\n [`${PLUGIN_NAME}/require-options-declared-in-config`]: 'error',\n [`${PLUGIN_NAME}/prefer-destructured-lookups`]: 'warn',\n [`${PLUGIN_NAME}/no-dollar-prefix`]: 'error',\n [`${PLUGIN_NAME}/require-destroyed-cleanup`]: 'warn',\n};\n\nconst base = eslintCompatPlugin({\n meta: {\n name: '@studiometa/eslint-plugin-js-toolkit',\n },\n rules,\n});\n\nconst plugin = Object.assign(base, { configs: {} as Record<string, object> });\n\nplugin.configs['recommended'] = {\n plugins: { [PLUGIN_NAME]: plugin },\n rules: recommendedRules,\n};\n\nexport { plugin as jsToolkit };\nexport default plugin;\n"],
5
+ "mappings": "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",
6
+ "names": ["plugin", "rules", "node", "check", "check", "check", "check", "check", "isThisRefs", "check", "check", "check", "walkNode", "walkNode", "walkNode", "check"]
7
7
  }
@@ -0,0 +1,8 @@
1
+ import { type Node, type RuleContext } from '../utils/ast.ts';
2
+ export declare const componentsPascalCase: {
3
+ meta?: import("../utils/ast.ts").RuleMeta;
4
+ createOnce(context: RuleContext): {
5
+ ClassDeclaration(node: Node): void;
6
+ ClassExpression(node: Node): void;
7
+ };
8
+ };
@@ -0,0 +1,8 @@
1
+ import { type Node, type RuleContext } from '../utils/ast.ts';
2
+ export declare const emitsKebabCase: {
3
+ meta?: import("../utils/ast.ts").RuleMeta;
4
+ createOnce(context: RuleContext): {
5
+ ClassDeclaration(node: Node): void;
6
+ ClassExpression(node: Node): void;
7
+ };
8
+ };
@@ -0,0 +1,8 @@
1
+ import { type Node, type RuleContext } from '../utils/ast.ts';
2
+ export declare const emitsMultiWord: {
3
+ meta?: import("../utils/ast.ts").RuleMeta;
4
+ createOnce(context: RuleContext): {
5
+ ClassDeclaration(node: Node): void;
6
+ ClassExpression(node: Node): void;
7
+ };
8
+ };
@@ -18,3 +18,12 @@ export { preferRefOverQuerySelector } from './prefer-ref-over-query-selector.ts'
18
18
  export { requireRefsDeclaredInConfig } from './require-refs-declared-in-config.ts';
19
19
  export { noManualIntersectionObserver } from './no-manual-intersection-observer.ts';
20
20
  export { noManualMutationObserver } from './no-manual-mutation-observer.ts';
21
+ export { emitsKebabCase } from './emits-kebab-case.ts';
22
+ export { emitsMultiWord } from './emits-multi-word.ts';
23
+ export { componentsPascalCase } from './components-pascal-case.ts';
24
+ export { requireEmitDeclaredInConfig } from './require-emit-declared-in-config.ts';
25
+ export { requireChildrenDeclaredInConfig } from './require-children-declared-in-config.ts';
26
+ export { requireOptionsDeclaredInConfig } from './require-options-declared-in-config.ts';
27
+ export { preferDestructuredLookups } from './prefer-destructured-lookups.ts';
28
+ export { noDollarPrefix } from './no-dollar-prefix.ts';
29
+ export { requireDestroyedCleanup } from './require-destroyed-cleanup.ts';
@@ -0,0 +1,8 @@
1
+ import { type Node, type RuleContext } from '../utils/ast.ts';
2
+ export declare const noDollarPrefix: {
3
+ meta?: import("../utils/ast.ts").RuleMeta;
4
+ createOnce(context: RuleContext): {
5
+ ClassDeclaration(node: Node): void;
6
+ ClassExpression(node: Node): void;
7
+ };
8
+ };
@@ -0,0 +1,8 @@
1
+ import { type Node, type RuleContext } from '../utils/ast.ts';
2
+ export declare const preferDestructuredLookups: {
3
+ meta?: import("../utils/ast.ts").RuleMeta;
4
+ createOnce(context: RuleContext): {
5
+ MemberExpression(node: Node): void;
6
+ 'MethodDefinition:exit'(node: Node): void;
7
+ };
8
+ };
@@ -0,0 +1,7 @@
1
+ import { type Node, type RuleContext } from '../utils/ast.ts';
2
+ export declare const requireChildrenDeclaredInConfig: {
3
+ meta?: import("../utils/ast.ts").RuleMeta;
4
+ createOnce(context: RuleContext): {
5
+ 'ClassDeclaration, ClassExpression'(classNode: Node): void;
6
+ };
7
+ };
@@ -0,0 +1,12 @@
1
+ import { type Node, type RuleContext } from '../utils/ast.ts';
2
+ export declare const requireDestroyedCleanup: {
3
+ meta?: import("../utils/ast.ts").RuleMeta;
4
+ createOnce(context: RuleContext): {
5
+ ClassDeclaration(node: Node): void;
6
+ ClassExpression(node: Node): void;
7
+ MethodDefinition(node: Node): void;
8
+ CallExpression(node: Node): void;
9
+ 'ClassDeclaration:exit'(node: Node): void;
10
+ 'ClassExpression:exit'(node: Node): void;
11
+ };
12
+ };
@@ -0,0 +1,7 @@
1
+ import { type Node, type RuleContext } from '../utils/ast.ts';
2
+ export declare const requireEmitDeclaredInConfig: {
3
+ meta?: import("../utils/ast.ts").RuleMeta;
4
+ createOnce(context: RuleContext): {
5
+ 'ClassDeclaration, ClassExpression'(classNode: Node): void;
6
+ };
7
+ };
@@ -0,0 +1,7 @@
1
+ import { type Node, type RuleContext } from '../utils/ast.ts';
2
+ export declare const requireOptionsDeclaredInConfig: {
3
+ meta?: import("../utils/ast.ts").RuleMeta;
4
+ createOnce(context: RuleContext): {
5
+ 'ClassDeclaration, ClassExpression'(classNode: Node): void;
6
+ };
7
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@studiometa/eslint-plugin-js-toolkit",
3
- "version": "3.6.0-beta.1",
3
+ "version": "3.6.0",
4
4
  "description": "Oxlint/ESLint plugin for @studiometa/js-toolkit best practices",
5
5
  "publishConfig": {
6
6
  "access": "public"