@wsxjs/eslint-plugin-wsx 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,387 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ configs: () => configs,
24
+ default: () => index_default,
25
+ flat: () => flat,
26
+ rules: () => rules
27
+ });
28
+ module.exports = __toCommonJS(index_exports);
29
+
30
+ // src/rules/render-method-required.ts
31
+ var renderMethodRequired = {
32
+ meta: {
33
+ type: "problem",
34
+ docs: {
35
+ description: "require WSX components to implement render method",
36
+ category: "Possible Errors",
37
+ recommended: true
38
+ },
39
+ messages: {
40
+ missingRenderMethod: "WSX component '{{componentName}}' must implement a render() method"
41
+ },
42
+ schema: []
43
+ // 无配置选项
44
+ },
45
+ create(context) {
46
+ return {
47
+ ClassDeclaration(node) {
48
+ const isWebComponent = node.superClass && node.superClass.type === "Identifier" && node.superClass.name === "WebComponent";
49
+ if (!isWebComponent) return;
50
+ const componentName = node.id?.name || "Unknown";
51
+ const hasRenderMethod = node.body.body.some(
52
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
53
+ (member) => member.type === "MethodDefinition" && member.key.type === "Identifier" && member.key.name === "render" && member.value.body !== null
54
+ );
55
+ if (!hasRenderMethod) {
56
+ context.report({
57
+ node,
58
+ messageId: "missingRenderMethod",
59
+ data: { componentName }
60
+ });
61
+ }
62
+ }
63
+ };
64
+ }
65
+ };
66
+
67
+ // src/rules/no-react-imports.ts
68
+ var noReactImports = {
69
+ meta: {
70
+ type: "problem",
71
+ docs: {
72
+ description: "disallow React imports in WSX files",
73
+ category: "Best Practices",
74
+ recommended: true
75
+ },
76
+ fixable: "code",
77
+ messages: {
78
+ noReactImport: "Do not import React in WSX files. Use 'h' function instead"
79
+ },
80
+ schema: []
81
+ // 无配置选项
82
+ },
83
+ create(context) {
84
+ const reactModules = [
85
+ "react",
86
+ "react-dom",
87
+ "react-dom/client",
88
+ "react-hooks",
89
+ "@types/react",
90
+ "@types/react-dom"
91
+ ];
92
+ return {
93
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
94
+ ImportDeclaration(node) {
95
+ const source = node.source.value;
96
+ if (typeof source === "string" && reactModules.some(
97
+ (module2) => source === module2 || source.startsWith(module2 + "/")
98
+ )) {
99
+ context.report({
100
+ node,
101
+ messageId: "noReactImport",
102
+ fix(fixer) {
103
+ return fixer.remove(node);
104
+ }
105
+ });
106
+ }
107
+ }
108
+ };
109
+ }
110
+ };
111
+
112
+ // src/rules/web-component-naming.ts
113
+ var webComponentNaming = {
114
+ meta: {
115
+ type: "suggestion",
116
+ docs: {
117
+ description: "enforce Web Component naming conventions",
118
+ category: "Stylistic Issues",
119
+ recommended: true
120
+ },
121
+ messages: {
122
+ tagNameNeedsHyphen: "Web Component tag name '{{tagName}}' must contain at least one hyphen",
123
+ tagNameReserved: "Tag name '{{tagName}}' conflicts with HTML standard elements"
124
+ },
125
+ schema: []
126
+ // 无配置选项
127
+ },
128
+ create(context) {
129
+ const htmlElements = /* @__PURE__ */ new Set([
130
+ "div",
131
+ "span",
132
+ "p",
133
+ "a",
134
+ "button",
135
+ "input",
136
+ "form",
137
+ "img",
138
+ "h1",
139
+ "h2",
140
+ "h3",
141
+ "ul",
142
+ "li",
143
+ "table",
144
+ "tr",
145
+ "td",
146
+ "th",
147
+ "section",
148
+ "article",
149
+ "header",
150
+ "footer"
151
+ ]);
152
+ return {
153
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
154
+ Decorator(node) {
155
+ if (node.expression.type === "CallExpression" && node.expression.callee.type === "Identifier" && node.expression.callee.name === "autoRegister") {
156
+ const args = node.expression.arguments;
157
+ if (args.length > 0 && args[0].type === "ObjectExpression") {
158
+ const tagNameProp = args[0].properties.find(
159
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
160
+ (prop) => prop.type === "Property" && prop.key && prop.key.type === "Identifier" && prop.key.name === "tagName"
161
+ );
162
+ if (tagNameProp && tagNameProp.type === "Property" && tagNameProp.value.type === "Literal") {
163
+ const tagName = tagNameProp.value.value;
164
+ if (typeof tagName === "string") {
165
+ if (htmlElements.has(tagName)) {
166
+ context.report({
167
+ node: tagNameProp.value,
168
+ messageId: "tagNameReserved",
169
+ data: { tagName }
170
+ });
171
+ } else if (!tagName.includes("-")) {
172
+ context.report({
173
+ node: tagNameProp.value,
174
+ messageId: "tagNameNeedsHyphen",
175
+ data: { tagName }
176
+ });
177
+ }
178
+ }
179
+ }
180
+ }
181
+ }
182
+ }
183
+ };
184
+ }
185
+ };
186
+
187
+ // src/configs/recommended.ts
188
+ var recommendedConfig = {
189
+ parser: "@typescript-eslint/parser",
190
+ parserOptions: {
191
+ ecmaVersion: "latest",
192
+ sourceType: "module",
193
+ ecmaFeatures: {
194
+ jsx: true
195
+ },
196
+ jsxPragma: "h",
197
+ jsxFragmentName: "Fragment"
198
+ },
199
+ plugins: ["wsx"],
200
+ rules: {
201
+ // WSX 特定规则(移除 valid-jsx-pragma,由 Vite 处理)
202
+ "wsx/render-method-required": "error",
203
+ "wsx/no-react-imports": "error",
204
+ "wsx/web-component-naming": "warn",
205
+ // TypeScript 规则(推荐)
206
+ "@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_" }],
207
+ "@typescript-eslint/no-explicit-any": "warn",
208
+ "@typescript-eslint/explicit-function-return-type": "off",
209
+ "@typescript-eslint/explicit-module-boundary-types": "off",
210
+ "@typescript-eslint/no-non-null-assertion": "warn",
211
+ // 通用规则
212
+ "no-console": ["warn", { allow: ["warn", "error"] }],
213
+ "no-debugger": "error",
214
+ "no-unused-vars": "off",
215
+ // 使用 TypeScript 版本
216
+ "no-undef": "off",
217
+ // TypeScript 处理
218
+ "prefer-const": "error",
219
+ "no-var": "error",
220
+ "no-duplicate-imports": "error",
221
+ "no-trailing-spaces": "error",
222
+ "eol-last": "error",
223
+ "comma-dangle": ["error", "always-multiline"],
224
+ semi: ["error", "always"],
225
+ quotes: ["error", "double", { avoidEscape: true, allowTemplateLiterals: true }],
226
+ // 禁用 React 相关规则
227
+ "react/react-in-jsx-scope": "off",
228
+ "react/prop-types": "off",
229
+ "react/jsx-uses-react": "off",
230
+ "react/jsx-uses-vars": "off",
231
+ "react/jsx-key": "off",
232
+ "react/jsx-no-duplicate-props": "off",
233
+ "react/jsx-no-undef": "off",
234
+ "react/no-array-index-key": "off",
235
+ "react/no-unescaped-entities": "off"
236
+ },
237
+ globals: {
238
+ // 浏览器环境
239
+ window: "readonly",
240
+ document: "readonly",
241
+ console: "readonly",
242
+ // Node.js 环境
243
+ process: "readonly",
244
+ Buffer: "readonly",
245
+ __dirname: "readonly",
246
+ __filename: "readonly",
247
+ global: "readonly",
248
+ module: "readonly",
249
+ require: "readonly",
250
+ exports: "readonly",
251
+ // Web Components API
252
+ HTMLElement: "readonly",
253
+ customElements: "readonly",
254
+ CustomEvent: "readonly",
255
+ ShadowRoot: "readonly",
256
+ HTMLSlotElement: "readonly",
257
+ CSSStyleSheet: "readonly",
258
+ // WSX 特定
259
+ h: "readonly",
260
+ Fragment: "readonly"
261
+ },
262
+ settings: {
263
+ // 不需要 React 设置
264
+ }
265
+ };
266
+
267
+ // src/configs/flat.ts
268
+ var flatConfig = {
269
+ name: "wsx/recommended",
270
+ files: ["**/*.wsx"],
271
+ languageOptions: {
272
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
273
+ parser: "@typescript-eslint/parser",
274
+ ecmaVersion: "latest",
275
+ sourceType: "module",
276
+ parserOptions: {
277
+ ecmaFeatures: {
278
+ jsx: true
279
+ },
280
+ jsxPragma: "h",
281
+ jsxFragmentName: "Fragment"
282
+ },
283
+ globals: {
284
+ // Browser environment
285
+ window: "readonly",
286
+ document: "readonly",
287
+ console: "readonly",
288
+ // Node.js environment
289
+ process: "readonly",
290
+ Buffer: "readonly",
291
+ __dirname: "readonly",
292
+ __filename: "readonly",
293
+ global: "readonly",
294
+ module: "readonly",
295
+ require: "readonly",
296
+ exports: "readonly",
297
+ // Web Components API
298
+ HTMLElement: "readonly",
299
+ customElements: "readonly",
300
+ CustomEvent: "readonly",
301
+ ShadowRoot: "readonly",
302
+ HTMLSlotElement: "readonly",
303
+ CSSStyleSheet: "readonly",
304
+ // WSX specific
305
+ h: "readonly",
306
+ Fragment: "readonly"
307
+ }
308
+ },
309
+ plugins: {
310
+ wsx: {
311
+ rules: {
312
+ "render-method-required": renderMethodRequired,
313
+ "no-react-imports": noReactImports,
314
+ "web-component-naming": webComponentNaming
315
+ }
316
+ }
317
+ },
318
+ rules: {
319
+ // WSX specific rules
320
+ "wsx/render-method-required": "error",
321
+ "wsx/no-react-imports": "error",
322
+ "wsx/web-component-naming": "warn",
323
+ // TypeScript rules (recommended)
324
+ "@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_" }],
325
+ "@typescript-eslint/no-explicit-any": "warn",
326
+ "@typescript-eslint/explicit-function-return-type": "off",
327
+ "@typescript-eslint/explicit-module-boundary-types": "off",
328
+ "@typescript-eslint/no-non-null-assertion": "warn",
329
+ // General rules
330
+ "no-console": ["warn", { allow: ["warn", "error"] }],
331
+ "no-debugger": "error",
332
+ "no-unused-vars": "off",
333
+ // Use TypeScript version
334
+ "no-undef": "off",
335
+ // TypeScript handles this
336
+ "prefer-const": "error",
337
+ "no-var": "error",
338
+ "no-duplicate-imports": "error",
339
+ "no-trailing-spaces": "error",
340
+ "eol-last": "error",
341
+ "comma-dangle": ["error", "always-multiline"],
342
+ semi: ["error", "always"],
343
+ quotes: ["error", "double", { avoidEscape: true, allowTemplateLiterals: true }]
344
+ },
345
+ settings: {
346
+ // No React settings needed
347
+ }
348
+ };
349
+ function createFlatConfig(plugin2) {
350
+ return {
351
+ ...flatConfig,
352
+ plugins: {
353
+ wsx: plugin2
354
+ }
355
+ };
356
+ }
357
+
358
+ // src/index.ts
359
+ var plugin = {
360
+ // 插件元信息
361
+ meta: {
362
+ name: "@wsxjs/eslint-plugin-wsx",
363
+ version: "0.0.2"
364
+ },
365
+ // 核心规则(移除 valid-jsx-pragma)
366
+ rules: {
367
+ "render-method-required": renderMethodRequired,
368
+ "no-react-imports": noReactImports,
369
+ "web-component-naming": webComponentNaming
370
+ },
371
+ // 配置预设
372
+ configs: {
373
+ recommended: recommendedConfig
374
+ }
375
+ };
376
+ var flat = {
377
+ recommended: createFlatConfig(plugin)
378
+ };
379
+ var rules = plugin.rules;
380
+ var configs = plugin.configs;
381
+ var index_default = plugin;
382
+ // Annotate the CommonJS export names for ESM import in node:
383
+ 0 && (module.exports = {
384
+ configs,
385
+ flat,
386
+ rules
387
+ });