@weapp-vite/eslint 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 ice breaker
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,47 @@
1
+ # @weapp-vite/eslint
2
+
3
+ `@weapp-vite/eslint` 提供 Wevu 项目的兼容性静态检查规则,帮助在源码阶段发现不能直接迁移到小程序运行时的 Vue、Pinia 和 Vue Router API。
4
+
5
+ ## 安装
6
+
7
+ ```bash
8
+ pnpm add -D @weapp-vite/eslint eslint
9
+ ```
10
+
11
+ ## 配置
12
+
13
+ ```js
14
+ import {
15
+ wevuCompatibilityPlugin,
16
+ wevuCompatibilityRecommended,
17
+ } from '@weapp-vite/eslint'
18
+ import { defineConfig } from 'eslint/config'
19
+
20
+ export default defineConfig([
21
+ wevuCompatibilityRecommended,
22
+ {
23
+ plugins: {
24
+ wevu: wevuCompatibilityPlugin,
25
+ },
26
+ },
27
+ ])
28
+ ```
29
+
30
+ 推荐配置包含三条规则:
31
+
32
+ - `wevu/no-unsupported-api`:禁止静态可确定的不支持导入,并给出替代 API。
33
+ - `wevu/no-risky-api`:警告同名但参数、时序或宿主语义不同的 API。
34
+ - `wevu/no-unsupported-template-feature`:只对能追溯到 `vue-router` 导入的 `RouterLink` 模板能力报错。
35
+
36
+ 规则只检查项目源码,不扫描 `node_modules`、构建产物或 `.weapp-vite` 生成文件。动态属性访问、第三方依赖内部代码和宿主运行时能力不在静态判定范围内。
37
+
38
+ 兼容矩阵也从根入口导出:
39
+
40
+ ```ts
41
+ import {
42
+ findWevuCompatibilityEntry,
43
+ wevuCompatibilityCatalog,
44
+ } from '@weapp-vite/eslint'
45
+ ```
46
+
47
+ 旧项目可以继续从 `weapp-vite/eslint` 和 `weapp-vite/compatibility` 导入兼容转出入口。
@@ -0,0 +1,44 @@
1
+ import { Linter, Rule } from "eslint";
2
+ //#region src/compatibility.d.ts
3
+ type WevuCompatibilityLevel = 'supported' | 'supported-with-differences' | 'experimental' | 'unsupported';
4
+ type WevuCompatibilityDiagnostic = 'off' | 'warn' | 'error';
5
+ type WevuCompatibilitySurface = 'runtime' | 'template' | 'sfc-style' | 'type';
6
+ type WevuCompatibilityUpstream = 'vue' | 'pinia' | 'vue-router';
7
+ interface WevuCompatibilityEntry {
8
+ upstream: WevuCompatibilityUpstream;
9
+ api: string;
10
+ wevuEntry: 'wevu' | 'wevu/router' | 'wevu/store' | 'weapp-vite';
11
+ compatibility: WevuCompatibilityLevel;
12
+ diagnostic: WevuCompatibilityDiagnostic;
13
+ replacement?: string;
14
+ summary: string;
15
+ docs: string;
16
+ surfaces: WevuCompatibilitySurface[];
17
+ platforms?: {
18
+ weapp: 'stable' | 'experimental' | 'unsupported';
19
+ other: 'stable' | 'experimental' | 'unsupported';
20
+ };
21
+ }
22
+ /**
23
+ * Wevu 与 Vue 生态的公开兼容真值。
24
+ *
25
+ * Website、ESLint 规则和兼容审计应消费此清单,避免各自维护状态。
26
+ */
27
+ declare const wevuCompatibilityCatalog: readonly WevuCompatibilityEntry[];
28
+ declare function findWevuCompatibilityEntry(upstream: WevuCompatibilityUpstream, api: string, surface?: WevuCompatibilitySurface): WevuCompatibilityEntry | undefined;
29
+ //#endregion
30
+ //#region src/index.d.ts
31
+ declare const wevuCompatibilityPlugin: {
32
+ meta: {
33
+ name: string;
34
+ version: string;
35
+ };
36
+ rules: {
37
+ 'no-unsupported-api': Rule.RuleModule;
38
+ 'no-risky-api': Rule.RuleModule;
39
+ 'no-unsupported-template-feature': Rule.RuleModule;
40
+ };
41
+ };
42
+ declare const wevuCompatibilityRecommended: Linter.Config;
43
+ //#endregion
44
+ export { type WevuCompatibilityDiagnostic, type WevuCompatibilityEntry, type WevuCompatibilityLevel, type WevuCompatibilitySurface, type WevuCompatibilityUpstream, findWevuCompatibilityEntry, wevuCompatibilityCatalog, wevuCompatibilityPlugin, wevuCompatibilityRecommended };
package/dist/index.mjs ADDED
@@ -0,0 +1,382 @@
1
+ //#region src/compatibility.ts
2
+ const entry = (value) => value;
3
+ /**
4
+ * Wevu 与 Vue 生态的公开兼容真值。
5
+ *
6
+ * Website、ESLint 规则和兼容审计应消费此清单,避免各自维护状态。
7
+ */
8
+ const wevuCompatibilityCatalog = [
9
+ ...[
10
+ [
11
+ "vue",
12
+ "createSSRApp",
13
+ "createApp()"
14
+ ],
15
+ [
16
+ "vue",
17
+ "defineAsyncComponent",
18
+ "静态组件导入或自动组件注册"
19
+ ],
20
+ [
21
+ "vue",
22
+ "onWatcherCleanup",
23
+ "watch() 回调提供的清理函数"
24
+ ],
25
+ [
26
+ "vue",
27
+ "useId",
28
+ "自行生成稳定的小程序实例 id"
29
+ ],
30
+ [
31
+ "vue",
32
+ "h",
33
+ "Wevu JSX/TSX"
34
+ ],
35
+ [
36
+ "vue",
37
+ "createRenderer",
38
+ "Wevu 小程序编译运行时"
39
+ ],
40
+ [
41
+ "vue",
42
+ "render",
43
+ "Wevu 模板或 JSX/TSX"
44
+ ],
45
+ [
46
+ "vue-router",
47
+ "RouterView",
48
+ "页面路由与 layout"
49
+ ],
50
+ [
51
+ "vue-router",
52
+ "createWebHistory",
53
+ "createRouter()"
54
+ ],
55
+ [
56
+ "vue-router",
57
+ "createWebHashHistory",
58
+ "createRouter()"
59
+ ]
60
+ ].map(([upstream, api, replacement]) => entry({
61
+ upstream,
62
+ api,
63
+ wevuEntry: upstream === "vue-router" ? "wevu/router" : "wevu",
64
+ compatibility: "unsupported",
65
+ diagnostic: "error",
66
+ replacement,
67
+ summary: "该 Web/renderer 能力不能在 Wevu 小程序运行时使用。",
68
+ docs: "/wevu/compatibility",
69
+ surfaces: ["runtime"]
70
+ })),
71
+ entry({
72
+ upstream: "vue",
73
+ api: "hasInjectionContext",
74
+ wevuEntry: "wevu",
75
+ compatibility: "supported",
76
+ diagnostic: "off",
77
+ summary: "与 Wevu 的同步 setup 注入上下文对齐。",
78
+ docs: "/wevu/api/setup-context#hasinjectioncontext",
79
+ surfaces: ["runtime"]
80
+ }),
81
+ entry({
82
+ upstream: "pinia",
83
+ api: "createPinia",
84
+ wevuEntry: "wevu/store",
85
+ compatibility: "unsupported",
86
+ diagnostic: "error",
87
+ replacement: "createStore();单例场景也可直接 defineStore()",
88
+ summary: "Wevu Store 不创建 Pinia 根实例。",
89
+ docs: "/wevu/api/store#createpinia",
90
+ surfaces: ["runtime"]
91
+ }),
92
+ entry({
93
+ upstream: "vue-router",
94
+ api: "RouterLink",
95
+ wevuEntry: "wevu/router",
96
+ compatibility: "unsupported",
97
+ diagnostic: "error",
98
+ replacement: "router.push() 或原生 <navigator>",
99
+ summary: "小程序模板没有 Web RouterLink 组件。",
100
+ docs: "/wevu/api/router#routerlink",
101
+ surfaces: ["runtime", "template"]
102
+ }),
103
+ entry({
104
+ upstream: "vue-router",
105
+ api: "<router-link>",
106
+ wevuEntry: "wevu/router",
107
+ compatibility: "unsupported",
108
+ diagnostic: "error",
109
+ replacement: "router.push() 或原生 <navigator>",
110
+ summary: "仅禁止可追溯到 vue-router 的模板组件。",
111
+ docs: "/wevu/api/router#routerlink",
112
+ surfaces: ["template"]
113
+ }),
114
+ ...[
115
+ ["createRouter", "创建时必须处于同步 setup;默认实例按首次创建时序确定。"],
116
+ ["useRouter", "读取 Wevu Router,而非 Web history router。"],
117
+ ["useRoute", "只能在同步 setup 阶段读取。"],
118
+ ["currentRoute", "是 readonly 响应式对象,不是 Ref。"],
119
+ ["isReady", "小程序没有初始异步 history 导航,Promise 立即完成。"],
120
+ ["install", "只建立默认实例,不注册 RouterView 或 RouterLink。"],
121
+ ["push", "映射宿主导航;正向历史、hash、tabBar query 均受宿主限制。"],
122
+ ["replace", "映射宿主 redirect/reLaunch/switchTab,而非 Web history replace。"],
123
+ ["go", "仅支持负数回退;正数历史导航不可用。"],
124
+ ["forward", "小程序没有正向历史栈。"]
125
+ ].map(([api, summary]) => entry({
126
+ upstream: "vue-router",
127
+ api,
128
+ wevuEntry: "wevu/router",
129
+ compatibility: "supported-with-differences",
130
+ diagnostic: "warn",
131
+ summary,
132
+ docs: `/wevu/api/router#router-${api.toLowerCase()}`,
133
+ surfaces: ["runtime"]
134
+ })),
135
+ ...[
136
+ ["defineStore", "API 形状相近,但没有 Pinia SSR、HMR 和 devtools 生态。"],
137
+ ["storeToRefs", "当前结果包含函数;Pinia 会过滤方法。"],
138
+ ["$reset", "Options Store 与 Setup Store 均可重置。"],
139
+ ["$subscribe", "订阅批次和错误传播遵循 Wevu 的同步 Store 契约。"],
140
+ ["$onAction", "插件和 action 错误处理不提供完整 Pinia 上下文。"],
141
+ ["install", "Store manager 的 install() 是 no-op。"],
142
+ ["use", "插件上下文是 Wevu Store manager 契约,不等同 PiniaPluginContext。"]
143
+ ].map(([api, summary]) => entry({
144
+ upstream: "pinia",
145
+ api,
146
+ wevuEntry: "wevu/store",
147
+ compatibility: "supported-with-differences",
148
+ diagnostic: "warn",
149
+ summary,
150
+ docs: `/wevu/api/store#${api.replace(/^\$/, "store-").toLowerCase()}`,
151
+ surfaces: ["runtime"]
152
+ })),
153
+ ...[
154
+ ["CSS v-bind()", "CSS 表达式经 compiler-sfc 重写并由 Wevu 响应式桥接到模板根节点。"],
155
+ ["scoped CSS", "使用稳定 scope 属性隔离当前 SFC 拥有的节点。"],
156
+ [":deep()", "支持可映射到小程序选择器的常见 deep 形式。"],
157
+ [":global()", "支持显式移除局部 scope 的常见 global 形式。"],
158
+ [":slotted()", "为 slot 投影节点生成独立 slotted scope 属性。"],
159
+ ["CSS Modules", "支持默认 $style 和命名 module。"],
160
+ ["useCssModule()", "只能在同步 setup 中读取当前 SFC 的 module 映射。"]
161
+ ].map(([api, summary]) => entry({
162
+ upstream: "vue",
163
+ api,
164
+ wevuEntry: api === "useCssModule()" ? "wevu" : "weapp-vite",
165
+ compatibility: "supported-with-differences",
166
+ diagnostic: "off",
167
+ summary,
168
+ docs: "/wevu/vue-sfc/class-style",
169
+ surfaces: api === "useCssModule()" ? ["runtime", "sfc-style"] : ["sfc-style"],
170
+ platforms: {
171
+ weapp: "stable",
172
+ other: "experimental"
173
+ }
174
+ })),
175
+ ...[
176
+ ["AppConfig", "Wevu 配置面向小程序 RuntimeApp,不含 Vue DOM renderer 配置。"],
177
+ ["ComponentPublicInstance", "实例暴露宿主桥接与 Wevu setup 状态,不是 Vue DOM 组件代理。"],
178
+ ["SetupContext", "attrs、slots、emit、expose 遵循小程序桥接约束。"],
179
+ ["PropType", "用于小程序 properties 推导,运行时构造器能力受宿主限制。"],
180
+ ["VNode", "仅描述 Wevu JSX island 节点,不等同 Vue renderer VNode。"],
181
+ ["ObjectDirective", "只覆盖 Wevu 可编译或可桥接的指令钩子。"],
182
+ ["ExtractPropTypes", "推导结果包含小程序 properties 归一化规则。"],
183
+ ["ExtractPublicPropTypes", "公开 props 推导遵循 Wevu 组件构造类型。"]
184
+ ].map(([api, summary]) => entry({
185
+ upstream: "vue",
186
+ api,
187
+ wevuEntry: "wevu",
188
+ compatibility: "supported-with-differences",
189
+ diagnostic: "warn",
190
+ summary,
191
+ docs: `/wevu/api/types#${api.toLowerCase()}`,
192
+ surfaces: ["type"]
193
+ })),
194
+ ...[
195
+ "ComputedGetter",
196
+ "ComputedRef",
197
+ "ComputedSetter",
198
+ "CustomRefFactory",
199
+ "EffectScope",
200
+ "MaybeRef",
201
+ "MaybeRefOrGetter",
202
+ "Ref",
203
+ "ShallowRef",
204
+ "ToRefs",
205
+ "WritableComputedOptions",
206
+ "WritableComputedRef"
207
+ ].map((api) => entry({
208
+ upstream: "vue",
209
+ api,
210
+ wevuEntry: "wevu",
211
+ compatibility: "supported",
212
+ diagnostic: "off",
213
+ summary: "类型形状与 Vue 响应式类型兼容,由 Wevu 响应式实现承载。",
214
+ docs: `/wevu/api/types#${api.toLowerCase()}`,
215
+ surfaces: ["type"]
216
+ })),
217
+ ...[
218
+ "AllowedComponentProps",
219
+ "ComponentCustomProps",
220
+ "ComponentOptionsMixin",
221
+ "ComponentPropsOptions",
222
+ "ComponentTypeEmits",
223
+ "DefineComponent",
224
+ "EmitFn",
225
+ "EmitsOptions",
226
+ "ExtractDefaultPropTypes",
227
+ "GlobalComponents",
228
+ "GlobalDirectives",
229
+ "ModelRef",
230
+ "PublicProps",
231
+ "ShallowUnwrapRef",
232
+ "TemplateRef",
233
+ "VNodeProps"
234
+ ].map((api) => entry({
235
+ upstream: "vue",
236
+ api,
237
+ wevuEntry: "wevu",
238
+ compatibility: "supported-with-differences",
239
+ diagnostic: "warn",
240
+ summary: "同名类型按 Wevu 小程序组件、事件、模板或宿主实例契约收窄。",
241
+ docs: `/wevu/api/types#${api.toLowerCase()}`,
242
+ surfaces: ["type"]
243
+ })),
244
+ ...[
245
+ "MultiWatchSources",
246
+ "WatchCallback",
247
+ "WatchEffect",
248
+ "WatchEffectOptions",
249
+ "WatchOptions",
250
+ "WatchSource",
251
+ "WatchStopHandle"
252
+ ].map((api) => entry({
253
+ upstream: "vue",
254
+ api,
255
+ wevuEntry: "wevu",
256
+ compatibility: "supported-with-differences",
257
+ diagnostic: "warn",
258
+ summary: "类型形状接近 Vue,但 flush 时序和渲染批次遵循 Wevu setData 调度。",
259
+ docs: `/wevu/api/types#${api.toLowerCase()}`,
260
+ surfaces: ["type"]
261
+ }))
262
+ ];
263
+ function findWevuCompatibilityEntry(upstream, api, surface) {
264
+ return wevuCompatibilityCatalog.find((item) => item.upstream === upstream && item.api === api && (!surface || item.surfaces.includes(surface)));
265
+ }
266
+ //#endregion
267
+ //#region src/index.ts
268
+ const SOURCE_TO_UPSTREAM = {
269
+ "vue": "vue",
270
+ "pinia": "pinia",
271
+ "vue-router": "vue-router"
272
+ };
273
+ function findEntry(upstream, api, diagnostic) {
274
+ return wevuCompatibilityCatalog.find((item) => item.upstream === upstream && item.api === api && item.diagnostic === diagnostic);
275
+ }
276
+ function importedName(specifier) {
277
+ if (specifier.type !== "ImportSpecifier") return;
278
+ return specifier.imported.type === "Identifier" ? specifier.imported.name : specifier.imported.value;
279
+ }
280
+ function reportCompatibility(context, node, entry) {
281
+ context.report({
282
+ node,
283
+ message: entry.replacement ? `{{api}} 不能在 Wevu 中使用;请改用 {{replacement}}。` : `{{api}} 在 Wevu 中的语义不同:{{summary}}`,
284
+ data: {
285
+ api: entry.api,
286
+ replacement: entry.replacement,
287
+ summary: entry.summary
288
+ }
289
+ });
290
+ }
291
+ function createImportCompatibilityRule(diagnostic) {
292
+ return {
293
+ meta: {
294
+ type: "problem",
295
+ docs: { description: diagnostic === "error" ? "禁止 Wevu 不支持的上游 API" : "提示 Wevu 同名 API 的语义差异" },
296
+ schema: [],
297
+ messages: {}
298
+ },
299
+ create(context) {
300
+ const namespaces = /* @__PURE__ */ new Map();
301
+ return {
302
+ ImportDeclaration(node) {
303
+ const upstream = SOURCE_TO_UPSTREAM[node.source.value];
304
+ if (!upstream || node.importKind === "type" && diagnostic === "error") return;
305
+ for (const specifier of node.specifiers) {
306
+ if (specifier.type === "ImportNamespaceSpecifier") {
307
+ namespaces.set(specifier.local.name, upstream);
308
+ continue;
309
+ }
310
+ if (specifier.importKind === "type" && diagnostic === "error") continue;
311
+ const name = importedName(specifier);
312
+ const compatibility = name && findEntry(upstream, name, diagnostic);
313
+ if (compatibility) reportCompatibility(context, specifier, compatibility);
314
+ }
315
+ },
316
+ MemberExpression(node) {
317
+ if (node.object.type !== "Identifier" || node.computed && node.property.type !== "Literal") return;
318
+ const upstream = namespaces.get(node.object.name);
319
+ const name = node.computed ? node.property.value : node.property.name;
320
+ const compatibility = upstream && typeof name === "string" && findEntry(upstream, name, diagnostic);
321
+ if (compatibility) reportCompatibility(context, node, compatibility);
322
+ },
323
+ TSQualifiedName(node) {
324
+ if (node.left.type !== "Identifier" || node.right.type !== "Identifier") return;
325
+ const upstream = namespaces.get(node.left.name);
326
+ const compatibility = upstream && findEntry(upstream, node.right.name, diagnostic);
327
+ if (compatibility) reportCompatibility(context, node, compatibility);
328
+ }
329
+ };
330
+ }
331
+ };
332
+ }
333
+ const wevuCompatibilityPlugin = {
334
+ meta: {
335
+ name: "weapp-vite-wevu-compatibility",
336
+ version: "1.0.0"
337
+ },
338
+ rules: {
339
+ "no-unsupported-api": createImportCompatibilityRule("error"),
340
+ "no-risky-api": createImportCompatibilityRule("warn"),
341
+ "no-unsupported-template-feature": {
342
+ meta: {
343
+ type: "problem",
344
+ docs: { description: "禁止可追溯到上游包的不支持模板能力" },
345
+ schema: [],
346
+ messages: {}
347
+ },
348
+ create(context) {
349
+ const routerLinkAliases = /* @__PURE__ */ new Set();
350
+ const scriptVisitor = { ImportDeclaration(node) {
351
+ if (node.source.value !== "vue-router" || node.importKind === "type") return;
352
+ for (const specifier of node.specifiers) if (importedName(specifier) === "RouterLink") routerLinkAliases.add(specifier.local.name);
353
+ } };
354
+ const parserServices = context.sourceCode.parserServices;
355
+ if (typeof parserServices?.defineTemplateBodyVisitor !== "function") return scriptVisitor;
356
+ return parserServices.defineTemplateBodyVisitor({ VElement(node) {
357
+ const rawName = node.rawName || node.name;
358
+ const normalized = String(rawName).replace(/-/g, "").toLowerCase();
359
+ if (![...routerLinkAliases].some((alias) => alias.toLowerCase() === normalized)) return;
360
+ const compatibility = findEntry("vue-router", "<router-link>", "error") ?? findEntry("vue-router", "RouterLink", "error");
361
+ if (compatibility) reportCompatibility(context, node, compatibility);
362
+ } }, scriptVisitor);
363
+ }
364
+ }
365
+ }
366
+ };
367
+ const wevuCompatibilityRecommended = {
368
+ files: ["**/*.{js,mjs,cjs,jsx,ts,mts,cts,tsx,vue}"],
369
+ ignores: [
370
+ "**/node_modules/**",
371
+ "**/dist/**",
372
+ "**/.weapp-vite/**"
373
+ ],
374
+ plugins: { wevu: wevuCompatibilityPlugin },
375
+ rules: {
376
+ "wevu/no-unsupported-api": "error",
377
+ "wevu/no-risky-api": "warn",
378
+ "wevu/no-unsupported-template-feature": "error"
379
+ }
380
+ };
381
+ //#endregion
382
+ export { findWevuCompatibilityEntry, wevuCompatibilityCatalog, wevuCompatibilityPlugin, wevuCompatibilityRecommended };
package/package.json ADDED
@@ -0,0 +1,72 @@
1
+ {
2
+ "name": "@weapp-vite/eslint",
3
+ "type": "module",
4
+ "version": "0.1.0",
5
+ "description": "Wevu compatibility ESLint plugin and recommended configuration",
6
+ "author": "ice breaker <1324318532@qq.com>",
7
+ "license": "MIT",
8
+ "homepage": "https://vite.icebreaker.top/",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/weapp-vite/weapp-vite.git",
12
+ "directory": "packages/eslint"
13
+ },
14
+ "bugs": {
15
+ "url": "https://github.com/weapp-vite/weapp-vite/issues"
16
+ },
17
+ "keywords": [
18
+ "eslint",
19
+ "wevu",
20
+ "vue",
21
+ "pinia",
22
+ "vue-router",
23
+ "weapp-vite"
24
+ ],
25
+ "sideEffects": false,
26
+ "exports": {
27
+ ".": {
28
+ "types": "./dist/index.d.mts",
29
+ "import": "./dist/index.mjs"
30
+ },
31
+ "./package.json": "./package.json"
32
+ },
33
+ "main": "./dist/index.mjs",
34
+ "module": "./dist/index.mjs",
35
+ "types": "./dist/index.d.mts",
36
+ "files": [
37
+ "dist"
38
+ ],
39
+ "engines": {
40
+ "node": "^20.19.0 || >=22.12.0"
41
+ },
42
+ "publishConfig": {
43
+ "access": "public",
44
+ "registry": "https://registry.npmjs.org"
45
+ },
46
+ "peerDependencies": {
47
+ "eslint": ">=9"
48
+ },
49
+ "peerDependenciesMeta": {
50
+ "eslint": {
51
+ "optional": true
52
+ }
53
+ },
54
+ "dependencies": {},
55
+ "devDependencies": {
56
+ "@typescript-eslint/parser": "^8.67.0",
57
+ "eslint": "^10.9.0",
58
+ "typescript": "^6.0.3",
59
+ "vitest": "^4.1.11",
60
+ "vue-eslint-parser": "^10.4.1"
61
+ },
62
+ "scripts": {
63
+ "dev": "tsdown -w --sourcemap",
64
+ "build": "tsdown",
65
+ "test": "vitest run --config ./vitest.config.ts",
66
+ "test:types": "cd test-d/compatibility-eslint-public-types && tsd",
67
+ "typecheck": "tsc -p tsconfig.json --noEmit",
68
+ "release": "pnpm publish",
69
+ "lint": "eslint .",
70
+ "lint:fix": "eslint . --fix"
71
+ }
72
+ }