eslint-plugin-vue-setup-order 1.0.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) 2025 David KulhΓ‘nek
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,196 @@
1
+ # eslint-plugin-vue-setup-order
2
+
3
+ [![npm version](https://badge.fury.io/js/eslint-plugin-vue-setup-order.svg)](https://www.npmjs.com/package/eslint-plugin-vue-setup-order)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+
6
+ ESLint plugin to enforce consistent order of statements in Vue 3 `<script setup>`.
7
+
8
+ ## πŸ“¦ Installation
9
+
10
+ ```bash
11
+ npm install -D eslint-plugin-vue-setup-order
12
+ # or
13
+ pnpm add -D eslint-plugin-vue-setup-order
14
+ # or
15
+ yarn add -D eslint-plugin-vue-setup-order
16
+ ```
17
+
18
+ ## πŸš€ Usage
19
+
20
+ ### ESLint Flat Config (ESLint 9+)
21
+
22
+ ```javascript
23
+ // eslint.config.js
24
+ import vueSetupOrder from 'eslint-plugin-vue-setup-order';
25
+
26
+ export default [
27
+ vueSetupOrder.configs.flat.recommended,
28
+ // or manually:
29
+ {
30
+ plugins: {
31
+ 'vue-setup-order': vueSetupOrder,
32
+ },
33
+ rules: {
34
+ 'vue-setup-order/order': 'error',
35
+ },
36
+ },
37
+ ];
38
+ ```
39
+
40
+ ### Legacy Config (.eslintrc)
41
+
42
+ ```javascript
43
+ // .eslintrc.js
44
+ module.exports = {
45
+ plugins: ['vue-setup-order'],
46
+ extends: ['plugin:vue-setup-order/recommended'],
47
+ // or manually:
48
+ rules: {
49
+ 'vue-setup-order/order': 'error',
50
+ },
51
+ };
52
+ ```
53
+
54
+ ## πŸ“‹ Expected Order
55
+
56
+ The plugin enforces the following order in `<script setup>`:
57
+
58
+ 1. Imports - import statements
59
+ 2. Type declarations - type, interface, enum (TypeScript)
60
+ 3. Define macros - defineProps, defineEmits, defineOptions, defineSlots, defineExpose, defineModel
61
+ 4. Composables - useXxx() calls (useRouter, useStore, custom composables)
62
+ 5. Reactive state - ref, reactive, shallowRef, etc.
63
+ 6. Computed - computed properties
64
+ 7. Watchers - watch, watchEffect
65
+ 8. Lifecycle hooks - onMounted, onBeforeMount, etc.
66
+ 9. Functions - function declarations and arrow functions
67
+ 10. Provide - provide calls
68
+
69
+ ## βœ… Examples
70
+
71
+ ### ❌ Incorrect
72
+
73
+ ```vue
74
+ <script setup>
75
+ import { ref, computed } from 'vue';
76
+
77
+ function increment() {
78
+ // ❌ function before ref
79
+ count.value++;
80
+ }
81
+
82
+ const count = ref(0);
83
+
84
+ onMounted(() => {}); // ❌ lifecycle before computed
85
+
86
+ const doubled = computed(() => count.value * 2);
87
+ </script>
88
+ ```
89
+
90
+ ### βœ… Correct
91
+
92
+ ```vue
93
+ <script setup lang="ts">
94
+ import { ref, computed, onMounted } from 'vue';
95
+ import { useRouter } from 'vue-router';
96
+
97
+ type Props = {
98
+ title: string;
99
+ };
100
+
101
+ interface Emits {
102
+ (e: 'update', value: string): void;
103
+ }
104
+
105
+ const props = defineProps<Props>();
106
+ const emit = defineEmits<Emits>();
107
+
108
+ const router = useRouter();
109
+
110
+ const count = ref(0);
111
+
112
+ const doubled = computed(() => count.value * 2);
113
+
114
+ onMounted(() => {
115
+ console.log('mounted');
116
+ });
117
+
118
+ function increment() {
119
+ count.value++;
120
+ }
121
+ </script>
122
+ ```
123
+
124
+ ## βš™οΈ Options
125
+
126
+ ### `groupBlankLines`
127
+
128
+ Add blank lines between different categories (default: `true`).
129
+
130
+ ```javascript
131
+ {
132
+ 'vue-setup-order/order': ['error', {
133
+ groupBlankLines: true,
134
+ }]
135
+ }
136
+ ```
137
+
138
+ ### `order`
139
+
140
+ Customize the order of categories. You can specify a custom array of category names to enforce your preferred order.
141
+
142
+ **Available categories:**
143
+
144
+ - `import` - Import statements
145
+ - `types` - TypeScript type declarations (type, interface, enum)
146
+ - `defineProps`, `defineEmits`, `defineOptions`, `defineSlots`, `defineExpose`, `defineModel`, `withDefaults` - Vue define macros
147
+ - `composable` - Composable functions (useXxx)
148
+ - `ref`, `reactive`, `computed`, `watch`, `watchEffect` - Vue reactivity APIs
149
+ - `onMounted`, `onBeforeMount`, etc. - Lifecycle hooks
150
+ - `function` - Function declarations
151
+ - `provide` - Provide calls
152
+
153
+ **Example: Custom order**
154
+
155
+ ```javascript
156
+ {
157
+ 'vue-setup-order/order': ['error', {
158
+ order: [
159
+ 'import',
160
+ 'types',
161
+ 'defineProps',
162
+ 'defineEmits',
163
+ 'composable',
164
+ 'ref',
165
+ 'reactive',
166
+ 'computed',
167
+ 'watch',
168
+ 'lifecycle',
169
+ 'function',
170
+ 'provide'
171
+ ]
172
+ }]
173
+ }
174
+ ```
175
+
176
+ **Example: Functions before reactive state**
177
+
178
+ ```javascript
179
+ {
180
+ 'vue-setup-order/order': ['error', {
181
+ order: ['import', 'types', 'defineProps', 'function', 'ref', 'computed']
182
+ }]
183
+ }
184
+ ```
185
+
186
+ ## πŸ”§ Auto-fix
187
+
188
+ This rule supports auto-fix! Run ESLint with `--fix` flag:
189
+
190
+ ```bash
191
+ npx eslint --fix "src/**/*.vue"
192
+ ```
193
+
194
+ ## πŸ“„ License
195
+
196
+ MIT
package/dist/index.cjs ADDED
@@ -0,0 +1,382 @@
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
+ default: () => index_default
24
+ });
25
+ module.exports = __toCommonJS(index_exports);
26
+
27
+ // src/utils/constants.ts
28
+ var CATEGORY_IMPORT = 0;
29
+ var CATEGORY_TYPES = 1;
30
+ var CATEGORY_DEFINE = 2;
31
+ var CATEGORY_COMPOSABLE = 3;
32
+ var CATEGORY_REACTIVE = 4;
33
+ var CATEGORY_COMPUTED = 5;
34
+ var CATEGORY_WATCH = 6;
35
+ var CATEGORY_LIFECYCLE = 7;
36
+ var CATEGORY_FUNCTION = 8;
37
+ var CATEGORY_PROVIDE = 9;
38
+ var CATEGORY_UNKNOWN = 99;
39
+ var DEFAULT_ORDER = {
40
+ // Imports
41
+ import: CATEGORY_IMPORT,
42
+ // Types
43
+ types: CATEGORY_TYPES,
44
+ // Define macros
45
+ defineOptions: CATEGORY_DEFINE,
46
+ defineProps: CATEGORY_DEFINE,
47
+ defineEmits: CATEGORY_DEFINE,
48
+ defineSlots: CATEGORY_DEFINE,
49
+ defineExpose: CATEGORY_DEFINE,
50
+ defineModel: CATEGORY_DEFINE,
51
+ withDefaults: CATEGORY_DEFINE,
52
+ // Composables
53
+ composable: CATEGORY_COMPOSABLE,
54
+ // Reactive state
55
+ ref: CATEGORY_REACTIVE,
56
+ reactive: CATEGORY_REACTIVE,
57
+ shallowRef: CATEGORY_REACTIVE,
58
+ shallowReactive: CATEGORY_REACTIVE,
59
+ toRef: CATEGORY_REACTIVE,
60
+ toRefs: CATEGORY_REACTIVE,
61
+ customRef: CATEGORY_REACTIVE,
62
+ readonly: CATEGORY_REACTIVE,
63
+ shallowReadonly: CATEGORY_REACTIVE,
64
+ // Computed
65
+ computed: CATEGORY_COMPUTED,
66
+ // Watchers
67
+ watch: CATEGORY_WATCH,
68
+ watchEffect: CATEGORY_WATCH,
69
+ watchPostEffect: CATEGORY_WATCH,
70
+ watchSyncEffect: CATEGORY_WATCH,
71
+ // Lifecycle hooks
72
+ onBeforeMount: CATEGORY_LIFECYCLE,
73
+ onMounted: CATEGORY_LIFECYCLE,
74
+ onBeforeUpdate: CATEGORY_LIFECYCLE,
75
+ onUpdated: CATEGORY_LIFECYCLE,
76
+ onBeforeUnmount: CATEGORY_LIFECYCLE,
77
+ onUnmounted: CATEGORY_LIFECYCLE,
78
+ onActivated: CATEGORY_LIFECYCLE,
79
+ onDeactivated: CATEGORY_LIFECYCLE,
80
+ onErrorCaptured: CATEGORY_LIFECYCLE,
81
+ onRenderTracked: CATEGORY_LIFECYCLE,
82
+ onRenderTriggered: CATEGORY_LIFECYCLE,
83
+ onServerPrefetch: CATEGORY_LIFECYCLE,
84
+ // Functions
85
+ function: CATEGORY_FUNCTION,
86
+ // Provide
87
+ provide: CATEGORY_PROVIDE,
88
+ // Unknown
89
+ unknown: CATEGORY_UNKNOWN
90
+ };
91
+ var ORDER_NAMES = {
92
+ [CATEGORY_IMPORT]: "imports",
93
+ [CATEGORY_TYPES]: "type declarations",
94
+ [CATEGORY_DEFINE]: "define macros",
95
+ [CATEGORY_COMPOSABLE]: "composables",
96
+ [CATEGORY_REACTIVE]: "reactive state",
97
+ [CATEGORY_COMPUTED]: "computed properties",
98
+ [CATEGORY_WATCH]: "watchers",
99
+ [CATEGORY_LIFECYCLE]: "lifecycle hooks",
100
+ [CATEGORY_FUNCTION]: "functions",
101
+ [CATEGORY_PROVIDE]: "provide",
102
+ [CATEGORY_UNKNOWN]: "other"
103
+ };
104
+ var COMPOSABLE_PATTERN = /^use[A-Z]/;
105
+
106
+ // src/utils/analyze.ts
107
+ function getCalleeName(node, sourceCode) {
108
+ if (!node) return null;
109
+ if (node.type === "Identifier") {
110
+ return node.name;
111
+ }
112
+ if (node.type === "MemberExpression") {
113
+ return sourceCode.getText(node);
114
+ }
115
+ return null;
116
+ }
117
+ function isComposable(name) {
118
+ return name !== null && COMPOSABLE_PATTERN.test(name);
119
+ }
120
+ function analyzeStatement(statement, sourceCode, orderConfig) {
121
+ const result = {
122
+ node: statement,
123
+ order: orderConfig.unknown ?? CATEGORY_UNKNOWN,
124
+ name: "unknown",
125
+ category: "unknown"
126
+ };
127
+ if (statement.type === "ImportDeclaration") {
128
+ result.order = orderConfig.import;
129
+ result.name = "import";
130
+ result.category = "import";
131
+ return result;
132
+ }
133
+ const statementType = statement.type;
134
+ if (statementType === "TSTypeAliasDeclaration" || statementType === "TSInterfaceDeclaration" || statementType === "TSEnumDeclaration") {
135
+ result.order = orderConfig.types ?? CATEGORY_TYPES;
136
+ result.name = statementType === "TSTypeAliasDeclaration" ? "type" : statementType === "TSInterfaceDeclaration" ? "interface" : "enum";
137
+ result.category = "types";
138
+ return result;
139
+ }
140
+ if (statement.type === "ExportNamedDeclaration" || statement.type === "ExportDefaultDeclaration" || statement.type === "ExportAllDeclaration") {
141
+ return null;
142
+ }
143
+ if (statement.type === "VariableDeclaration") {
144
+ const declaration = statement.declarations[0];
145
+ const init = declaration?.init;
146
+ if (!init) {
147
+ result.order = orderConfig.ref ?? CATEGORY_REACTIVE;
148
+ result.name = "variable";
149
+ result.category = "reactive";
150
+ return result;
151
+ }
152
+ if (init.type === "CallExpression") {
153
+ const calleeName = getCalleeName(init.callee, sourceCode);
154
+ if (calleeName) {
155
+ if (isComposable(calleeName)) {
156
+ result.order = orderConfig.composable;
157
+ result.name = calleeName;
158
+ result.category = "composable";
159
+ return result;
160
+ }
161
+ if (orderConfig[calleeName] !== void 0) {
162
+ result.order = orderConfig[calleeName];
163
+ result.name = calleeName;
164
+ result.category = calleeName;
165
+ return result;
166
+ }
167
+ }
168
+ result.order = orderConfig.ref ?? CATEGORY_REACTIVE;
169
+ result.name = calleeName || "variable";
170
+ result.category = "reactive";
171
+ return result;
172
+ }
173
+ if (init.type === "ArrowFunctionExpression" || init.type === "FunctionExpression") {
174
+ result.order = orderConfig.function ?? CATEGORY_FUNCTION;
175
+ result.name = declaration.id?.type === "Identifier" ? declaration.id.name : "arrow function";
176
+ result.category = "function";
177
+ return result;
178
+ }
179
+ result.order = orderConfig.ref ?? CATEGORY_REACTIVE;
180
+ result.name = "variable";
181
+ result.category = "reactive";
182
+ return result;
183
+ }
184
+ if (statement.type === "FunctionDeclaration") {
185
+ result.order = orderConfig.function ?? CATEGORY_FUNCTION;
186
+ result.name = statement.id?.name || "function";
187
+ result.category = "function";
188
+ return result;
189
+ }
190
+ if (statement.type === "ExpressionStatement") {
191
+ const expr = statement.expression;
192
+ if (expr.type === "CallExpression") {
193
+ const calleeName = getCalleeName(expr.callee, sourceCode);
194
+ if (calleeName && orderConfig[calleeName] !== void 0) {
195
+ result.order = orderConfig[calleeName];
196
+ result.name = calleeName;
197
+ result.category = calleeName;
198
+ return result;
199
+ }
200
+ result.order = orderConfig.unknown ?? CATEGORY_UNKNOWN;
201
+ result.name = calleeName || "call";
202
+ result.category = "unknown";
203
+ return result;
204
+ }
205
+ result.order = orderConfig.unknown ?? CATEGORY_UNKNOWN;
206
+ result.name = "expression";
207
+ result.category = "unknown";
208
+ return result;
209
+ }
210
+ return result;
211
+ }
212
+
213
+ // src/utils/source-code.ts
214
+ function getNodeTextWithComments(node, sourceCode) {
215
+ const comments = sourceCode.getCommentsBefore(node);
216
+ let start = node.range[0];
217
+ if (comments.length > 0) {
218
+ start = comments[0].range[0];
219
+ }
220
+ return sourceCode.text.slice(start, node.range[1]);
221
+ }
222
+ function getFullRange(node, sourceCode) {
223
+ const comments = sourceCode.getCommentsBefore(node);
224
+ let start = node.range[0];
225
+ if (comments.length > 0) {
226
+ start = comments[0].range[0];
227
+ }
228
+ let end = node.range[1];
229
+ const textAfter = sourceCode.text.slice(end, end + 2);
230
+ if (textAfter.startsWith("\r\n")) {
231
+ end += 2;
232
+ } else if (textAfter.startsWith("\n")) {
233
+ end += 1;
234
+ }
235
+ return [start, end];
236
+ }
237
+ function generateSortedCode(statements, sourceCode, addBlankLines = true) {
238
+ const parts = [];
239
+ let lastOrder = -1;
240
+ for (const statement of statements) {
241
+ const text = getNodeTextWithComments(statement.node, sourceCode).trim();
242
+ if (addBlankLines && lastOrder !== -1 && statement.order !== lastOrder) {
243
+ parts.push("");
244
+ }
245
+ parts.push(text);
246
+ lastOrder = statement.order;
247
+ }
248
+ return parts.join("\n");
249
+ }
250
+
251
+ // src/rules/order.ts
252
+ var rule = {
253
+ meta: {
254
+ type: "suggestion",
255
+ docs: {
256
+ description: "Enforce consistent order of statements in Vue 3 <script setup>",
257
+ category: "Stylistic Issues",
258
+ recommended: true,
259
+ url: "https://github.com/d2a8k3u/eslint-plugin-vue-setup-order#readme"
260
+ },
261
+ fixable: "code",
262
+ schema: [
263
+ {
264
+ type: "object",
265
+ properties: {
266
+ order: {
267
+ type: "array",
268
+ items: { type: "string" },
269
+ description: "Custom order of categories"
270
+ },
271
+ groupBlankLines: {
272
+ type: "boolean",
273
+ default: true,
274
+ description: "Add blank lines between different categories"
275
+ }
276
+ },
277
+ additionalProperties: false
278
+ }
279
+ ],
280
+ messages: {
281
+ wrongOrder: "'{{current}}' ({{currentCategory}}) should come before '{{previous}}' ({{previousCategory}})"
282
+ }
283
+ },
284
+ create(context) {
285
+ const sourceCode = context.sourceCode ?? context.getSourceCode();
286
+ const options = context.options[0] || {};
287
+ const groupBlankLines = false !== options.groupBlankLines;
288
+ const orderConfig = { ...DEFAULT_ORDER };
289
+ if (options.order && Array.isArray(options.order)) {
290
+ options.order.forEach((category, index) => {
291
+ const originalOrder = DEFAULT_ORDER[category];
292
+ if (originalOrder !== void 0) {
293
+ Object.keys(DEFAULT_ORDER).forEach((key) => {
294
+ if (DEFAULT_ORDER[key] === originalOrder) {
295
+ orderConfig[key] = index;
296
+ }
297
+ });
298
+ }
299
+ orderConfig[category] = index;
300
+ });
301
+ }
302
+ return {
303
+ Program(node) {
304
+ const statements = [];
305
+ for (const statement of node.body) {
306
+ const analyzed = analyzeStatement(statement, sourceCode, orderConfig);
307
+ if (analyzed) {
308
+ statements.push(analyzed);
309
+ }
310
+ }
311
+ if (statements.length < 2) return;
312
+ let firstError = null;
313
+ for (let i = 1; i < statements.length; i++) {
314
+ const prev = statements[i - 1];
315
+ const curr = statements[i];
316
+ if (curr.order < prev.order) {
317
+ firstError = { index: i, current: curr, previous: prev };
318
+ break;
319
+ }
320
+ }
321
+ if (!firstError) return;
322
+ context.report({
323
+ node: firstError.current.node,
324
+ messageId: "wrongOrder",
325
+ data: {
326
+ current: firstError.current.name,
327
+ currentCategory: ORDER_NAMES[firstError.current.order] || "unknown",
328
+ previous: firstError.previous.name,
329
+ previousCategory: ORDER_NAMES[firstError.previous.order] || "unknown"
330
+ },
331
+ fix(fixer) {
332
+ const sorted = [...statements].sort((a, b) => {
333
+ if (a.order !== b.order) {
334
+ return a.order - b.order;
335
+ }
336
+ return statements.indexOf(a) - statements.indexOf(b);
337
+ });
338
+ const newCode = generateSortedCode(sorted, sourceCode, groupBlankLines);
339
+ const firstRange = getFullRange(statements[0].node, sourceCode);
340
+ const lastRange = getFullRange(statements[statements.length - 1].node, sourceCode);
341
+ return fixer.replaceTextRange([firstRange[0], lastRange[1]], newCode + "\n");
342
+ }
343
+ });
344
+ }
345
+ };
346
+ }
347
+ };
348
+ var order_default = rule;
349
+
350
+ // src/index.ts
351
+ var plugin = {
352
+ meta: {
353
+ name: "eslint-plugin-vue-setup-order",
354
+ version: "1.0.0"
355
+ },
356
+ rules: {
357
+ order: order_default
358
+ },
359
+ configs: {
360
+ recommended: {
361
+ plugins: ["vue-setup-order"],
362
+ rules: {
363
+ "vue-setup-order/order": "error"
364
+ }
365
+ },
366
+ // Flat config format for ESLint 9+
367
+ flat: {
368
+ recommended: {
369
+ plugins: {
370
+ get "vue-setup-order"() {
371
+ return plugin;
372
+ }
373
+ },
374
+ rules: {
375
+ "vue-setup-order/order": "error"
376
+ }
377
+ }
378
+ }
379
+ }
380
+ };
381
+ var index_default = plugin;
382
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/utils/constants.ts","../src/utils/analyze.ts","../src/utils/source-code.ts","../src/rules/order.ts"],"sourcesContent":["import orderRule from './rules/order';\n\nconst plugin = {\n meta: {\n name: 'eslint-plugin-vue-setup-order',\n version: '1.0.0',\n },\n rules: {\n order: orderRule,\n },\n configs: {\n recommended: {\n plugins: ['vue-setup-order'],\n rules: {\n 'vue-setup-order/order': 'error',\n },\n },\n // Flat config format for ESLint 9+\n flat: {\n recommended: {\n plugins: {\n get 'vue-setup-order'() {\n return plugin;\n },\n },\n rules: {\n 'vue-setup-order/order': 'error',\n },\n },\n },\n },\n};\n\nexport default plugin;\n","import type { OrderConfig } from '../types';\n\nexport const CATEGORY_IMPORT = 0;\nexport const CATEGORY_TYPES = 1;\nexport const CATEGORY_DEFINE = 2;\nexport const CATEGORY_COMPOSABLE = 3;\nexport const CATEGORY_REACTIVE = 4;\nexport const CATEGORY_COMPUTED = 5;\nexport const CATEGORY_WATCH = 6;\nexport const CATEGORY_LIFECYCLE = 7;\nexport const CATEGORY_FUNCTION = 8;\nexport const CATEGORY_PROVIDE = 9;\nexport const CATEGORY_UNKNOWN = 99;\n\nexport const DEFAULT_ORDER: OrderConfig = {\n // Imports\n import: CATEGORY_IMPORT,\n\n // Types\n types: CATEGORY_TYPES,\n\n // Define macros\n defineOptions: CATEGORY_DEFINE,\n defineProps: CATEGORY_DEFINE,\n defineEmits: CATEGORY_DEFINE,\n defineSlots: CATEGORY_DEFINE,\n defineExpose: CATEGORY_DEFINE,\n defineModel: CATEGORY_DEFINE,\n withDefaults: CATEGORY_DEFINE,\n\n // Composables\n composable: CATEGORY_COMPOSABLE,\n\n // Reactive state\n ref: CATEGORY_REACTIVE,\n reactive: CATEGORY_REACTIVE,\n shallowRef: CATEGORY_REACTIVE,\n shallowReactive: CATEGORY_REACTIVE,\n toRef: CATEGORY_REACTIVE,\n toRefs: CATEGORY_REACTIVE,\n customRef: CATEGORY_REACTIVE,\n readonly: CATEGORY_REACTIVE,\n shallowReadonly: CATEGORY_REACTIVE,\n\n // Computed\n computed: CATEGORY_COMPUTED,\n\n // Watchers\n watch: CATEGORY_WATCH,\n watchEffect: CATEGORY_WATCH,\n watchPostEffect: CATEGORY_WATCH,\n watchSyncEffect: CATEGORY_WATCH,\n\n // Lifecycle hooks\n onBeforeMount: CATEGORY_LIFECYCLE,\n onMounted: CATEGORY_LIFECYCLE,\n onBeforeUpdate: CATEGORY_LIFECYCLE,\n onUpdated: CATEGORY_LIFECYCLE,\n onBeforeUnmount: CATEGORY_LIFECYCLE,\n onUnmounted: CATEGORY_LIFECYCLE,\n onActivated: CATEGORY_LIFECYCLE,\n onDeactivated: CATEGORY_LIFECYCLE,\n onErrorCaptured: CATEGORY_LIFECYCLE,\n onRenderTracked: CATEGORY_LIFECYCLE,\n onRenderTriggered: CATEGORY_LIFECYCLE,\n onServerPrefetch: CATEGORY_LIFECYCLE,\n\n // Functions\n function: CATEGORY_FUNCTION,\n\n // Provide\n provide: CATEGORY_PROVIDE,\n\n // Unknown\n unknown: CATEGORY_UNKNOWN,\n};\n\nexport const ORDER_NAMES: Record<number, string> = {\n [CATEGORY_IMPORT]: 'imports',\n [CATEGORY_TYPES]: 'type declarations',\n [CATEGORY_DEFINE]: 'define macros',\n [CATEGORY_COMPOSABLE]: 'composables',\n [CATEGORY_REACTIVE]: 'reactive state',\n [CATEGORY_COMPUTED]: 'computed properties',\n [CATEGORY_WATCH]: 'watchers',\n [CATEGORY_LIFECYCLE]: 'lifecycle hooks',\n [CATEGORY_FUNCTION]: 'functions',\n [CATEGORY_PROVIDE]: 'provide',\n [CATEGORY_UNKNOWN]: 'other',\n};\n\nexport const COMPOSABLE_PATTERN = /^use[A-Z]/;\n","import type { Rule } from 'eslint';\nimport type { Expression, ModuleDeclaration, Statement, Super } from 'estree';\nimport type { AnalyzedStatement, OrderConfig } from '../types';\nimport {\n CATEGORY_FUNCTION,\n CATEGORY_REACTIVE,\n CATEGORY_TYPES,\n CATEGORY_UNKNOWN,\n COMPOSABLE_PATTERN,\n} from './constants';\n\n/**\n * Retrieves the name of the callee from the provided node (Expression or Super).\n *\n * @param {Expression | Super | null | undefined} node - The node representing a callee, which can be an Expression or Super. May be null or undefined.\n * @param {Rule.RuleContext['sourceCode']} sourceCode - The source code object used to extract the callee name in case it's a MemberExpression.\n * @return {string | null} The name of the callee as a string if resolved, or null if the node is null, undefined, or not resolvable.\n */\nexport function getCalleeName(\n node: Expression | Super | null | undefined,\n sourceCode: Rule.RuleContext['sourceCode'],\n): string | null {\n if (!node) return null;\n\n if (node.type === 'Identifier') {\n return node.name;\n }\n\n if (node.type === 'MemberExpression') {\n return sourceCode.getText(node);\n }\n\n return null;\n}\n\n/**\n * Determines if the provided name is composable based on a predefined pattern.\n *\n * @param {string | null} name - The name to be tested against the composable pattern. Can be null.\n * @return {boolean} Returns true if the name matches the composable pattern and is not null; otherwise, returns false.\n */\nexport function isComposable(name: string | null): boolean {\n return name !== null && COMPOSABLE_PATTERN.test(name);\n}\n\n/**\n * Analyzes a given statement or module declaration to categorize, name, and assign an order based on the specified configuration.\n *\n * @param {Statement | ModuleDeclaration} statement - The statement or module declaration to be analyzed.\n * @param {Rule.RuleContext['sourceCode']} sourceCode - The source code context to extract details about the statement.\n * @param {OrderConfig} orderConfig - Configuration object that defines ordering and categorization rules.\n * @return {AnalyzedStatement | null} An object containing analysis details of the statement, or null for certain export declarations.\n */\nexport function analyzeStatement(\n statement: Statement | ModuleDeclaration,\n sourceCode: Rule.RuleContext['sourceCode'],\n orderConfig: OrderConfig,\n): AnalyzedStatement | null {\n const result: AnalyzedStatement = {\n node: statement as Statement,\n order: orderConfig.unknown ?? CATEGORY_UNKNOWN,\n name: 'unknown',\n category: 'unknown',\n };\n\n if (statement.type === 'ImportDeclaration') {\n result.order = orderConfig.import;\n result.name = 'import';\n result.category = 'import';\n return result;\n }\n\n const statementType = (statement as { type: string }).type;\n if (\n statementType === 'TSTypeAliasDeclaration' ||\n statementType === 'TSInterfaceDeclaration' ||\n statementType === 'TSEnumDeclaration'\n ) {\n result.order = orderConfig.types ?? CATEGORY_TYPES;\n result.name =\n statementType === 'TSTypeAliasDeclaration'\n ? 'type'\n : statementType === 'TSInterfaceDeclaration'\n ? 'interface'\n : 'enum';\n result.category = 'types';\n return result;\n }\n\n if (\n statement.type === 'ExportNamedDeclaration' ||\n statement.type === 'ExportDefaultDeclaration' ||\n statement.type === 'ExportAllDeclaration'\n ) {\n return null;\n }\n\n if (statement.type === 'VariableDeclaration') {\n const declaration = statement.declarations[0];\n const init = declaration?.init;\n\n if (!init) {\n result.order = orderConfig.ref ?? CATEGORY_REACTIVE;\n result.name = 'variable';\n result.category = 'reactive';\n return result;\n }\n\n if (init.type === 'CallExpression') {\n const calleeName = getCalleeName(init.callee, sourceCode);\n\n if (calleeName) {\n if (isComposable(calleeName)) {\n result.order = orderConfig.composable;\n result.name = calleeName;\n result.category = 'composable';\n return result;\n }\n\n if (orderConfig[calleeName] !== undefined) {\n result.order = orderConfig[calleeName];\n result.name = calleeName;\n result.category = calleeName;\n return result;\n }\n }\n\n result.order = orderConfig.ref ?? CATEGORY_REACTIVE;\n result.name = calleeName || 'variable';\n result.category = 'reactive';\n return result;\n }\n\n if (init.type === 'ArrowFunctionExpression' || init.type === 'FunctionExpression') {\n result.order = orderConfig.function ?? CATEGORY_FUNCTION;\n result.name = declaration.id?.type === 'Identifier' ? declaration.id.name : 'arrow function';\n result.category = 'function';\n return result;\n }\n\n result.order = orderConfig.ref ?? CATEGORY_REACTIVE;\n result.name = 'variable';\n result.category = 'reactive';\n return result;\n }\n\n if (statement.type === 'FunctionDeclaration') {\n result.order = orderConfig.function ?? CATEGORY_FUNCTION;\n result.name = statement.id?.name || 'function';\n result.category = 'function';\n return result;\n }\n\n if (statement.type === 'ExpressionStatement') {\n const expr = statement.expression;\n\n if (expr.type === 'CallExpression') {\n const calleeName = getCalleeName(expr.callee, sourceCode);\n\n if (calleeName && orderConfig[calleeName] !== undefined) {\n result.order = orderConfig[calleeName];\n result.name = calleeName;\n result.category = calleeName;\n return result;\n }\n\n result.order = orderConfig.unknown ?? CATEGORY_UNKNOWN;\n result.name = calleeName || 'call';\n result.category = 'unknown';\n return result;\n }\n\n result.order = orderConfig.unknown ?? CATEGORY_UNKNOWN;\n result.name = 'expression';\n result.category = 'unknown';\n return result;\n }\n\n return result;\n}\n","import type { Rule } from 'eslint';\nimport type { Statement } from 'estree';\n\n/**\n * Retrieves the combined text of a given AST node and its preceding comments from the source code.\n *\n * @param {Statement} node - The AST node whose text and preceding comments are to be retrieved.\n * @param {Rule.RuleContext['sourceCode']} sourceCode - The source code object containing the text and comments.\n * @return {string} The concatenated text of the node and its preceding comments.\n */\nexport function getNodeTextWithComments(node: Statement, sourceCode: Rule.RuleContext['sourceCode']): string {\n const comments = sourceCode.getCommentsBefore(node);\n let start = node.range![0];\n\n if (comments.length > 0) {\n start = comments[0].range![0];\n }\n\n return sourceCode.text.slice(start, node.range![1]);\n}\n\n/**\n * Determines the full range of a given statement node, including its preceding comments\n * and any trailing newlines immediately following the node.\n *\n * @param {Statement} node - The statement node for which to calculate the full range.\n * @param {Rule.RuleContext['sourceCode']} sourceCode - The source code object used to retrieve comments and text.\n * @return {[number, number]} The start and end positions of the full range in the source code.\n */\nexport function getFullRange(node: Statement, sourceCode: Rule.RuleContext['sourceCode']): [number, number] {\n const comments = sourceCode.getCommentsBefore(node);\n let start = node.range![0];\n\n if (comments.length > 0) {\n start = comments[0].range![0];\n }\n\n let end = node.range![1];\n const textAfter = sourceCode.text.slice(end, end + 2);\n\n if (textAfter.startsWith('\\r\\n')) {\n end += 2;\n } else if (textAfter.startsWith('\\n')) {\n end += 1;\n }\n\n return [start, end];\n}\n\n/**\n * Generates a sorted string representation of code statements, optionally adding blank lines between different categories.\n *\n * @param {Array<{ node: Statement, order: number }>} statements - An array of objects containing a statement node and its corresponding order.\n * @param {Rule.RuleContext['sourceCode']} sourceCode - The source code object used to extract the textual representation of the statement nodes.\n * @param {boolean} [addBlankLines=true] - A flag indicating whether to add blank lines between statements of differing orders.\n * @return {string} A sorted and formatted code string based on the given statements and options.\n */\nexport function generateSortedCode(\n statements: Array<{ node: Statement; order: number }>,\n sourceCode: Rule.RuleContext['sourceCode'],\n addBlankLines: boolean = true,\n): string {\n const parts: string[] = [];\n let lastOrder = -1;\n\n for (const statement of statements) {\n const text = getNodeTextWithComments(statement.node, sourceCode).trim();\n\n if (addBlankLines && lastOrder !== -1 && statement.order !== lastOrder) {\n parts.push('');\n }\n\n parts.push(text);\n lastOrder = statement.order;\n }\n\n return parts.join('\\n');\n}\n","import type { Rule } from 'eslint';\nimport type { Program } from 'estree';\nimport type { AnalyzedStatement, OrderConfig, PluginOptions } from '../types';\nimport { analyzeStatement } from '../utils/analyze';\nimport { DEFAULT_ORDER, ORDER_NAMES } from '../utils/constants';\nimport { generateSortedCode, getFullRange } from '../utils/source-code';\n\n/**\n * Represents an ESLint rule module designed to enforce a consistent order of statements\n * in the `<script setup>` block of Vue 3 components.\n *\n * The rule provides configuration options for defining custom ordering of statement categories\n * and for including blank lines between different categories. The rule reports and optionally\n * fixes statement order violations.\n */\nconst rule: Rule.RuleModule = {\n meta: {\n type: 'suggestion',\n docs: {\n description: 'Enforce consistent order of statements in Vue 3 <script setup>',\n category: 'Stylistic Issues',\n recommended: true,\n url: 'https://github.com/d2a8k3u/eslint-plugin-vue-setup-order#readme',\n },\n fixable: 'code',\n schema: [\n {\n type: 'object',\n properties: {\n order: {\n type: 'array',\n items: { type: 'string' },\n description: 'Custom order of categories',\n },\n groupBlankLines: {\n type: 'boolean',\n default: true,\n description: 'Add blank lines between different categories',\n },\n },\n additionalProperties: false,\n },\n ],\n messages: {\n wrongOrder: \"'{{current}}' ({{currentCategory}}) should come before '{{previous}}' ({{previousCategory}})\",\n },\n },\n\n create(context: Rule.RuleContext) {\n const sourceCode = context.sourceCode ?? context.getSourceCode();\n const options: PluginOptions = context.options[0] || {};\n const groupBlankLines = false !== options.groupBlankLines;\n const orderConfig: OrderConfig = { ...DEFAULT_ORDER };\n\n if (options.order && Array.isArray(options.order)) {\n options.order.forEach((category, index) => {\n const originalOrder = DEFAULT_ORDER[category];\n if (originalOrder !== undefined) {\n Object.keys(DEFAULT_ORDER).forEach((key) => {\n if (DEFAULT_ORDER[key] === originalOrder) {\n orderConfig[key] = index;\n }\n });\n }\n orderConfig[category] = index;\n });\n }\n\n return {\n Program(node: Program) {\n const statements: AnalyzedStatement[] = [];\n\n for (const statement of node.body) {\n const analyzed = analyzeStatement(statement, sourceCode, orderConfig);\n if (analyzed) {\n statements.push(analyzed);\n }\n }\n\n if (statements.length < 2) return;\n\n let firstError: {\n index: number;\n current: AnalyzedStatement;\n previous: AnalyzedStatement;\n } | null = null;\n\n for (let i = 1; i < statements.length; i++) {\n const prev = statements[i - 1];\n const curr = statements[i];\n\n if (curr.order < prev.order) {\n firstError = { index: i, current: curr, previous: prev };\n break;\n }\n }\n\n if (!firstError) return;\n\n context.report({\n node: firstError.current.node,\n messageId: 'wrongOrder',\n data: {\n current: firstError.current.name,\n currentCategory: ORDER_NAMES[firstError.current.order] || 'unknown',\n previous: firstError.previous.name,\n previousCategory: ORDER_NAMES[firstError.previous.order] || 'unknown',\n },\n fix(fixer) {\n const sorted = [...statements].sort((a, b) => {\n if (a.order !== b.order) {\n return a.order - b.order;\n }\n\n return statements.indexOf(a) - statements.indexOf(b);\n });\n\n const newCode = generateSortedCode(sorted, sourceCode, groupBlankLines);\n const firstRange = getFullRange(statements[0].node, sourceCode);\n const lastRange = getFullRange(statements[statements.length - 1].node, sourceCode);\n\n return fixer.replaceTextRange([firstRange[0], lastRange[1]], newCode + '\\n');\n },\n });\n },\n };\n },\n};\n\nexport default rule;\n"],"mappings":"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","names":[]}
@@ -0,0 +1,31 @@
1
+ import * as eslint from 'eslint';
2
+
3
+ declare const plugin: {
4
+ meta: {
5
+ name: string;
6
+ version: string;
7
+ };
8
+ rules: {
9
+ order: eslint.Rule.RuleModule;
10
+ };
11
+ configs: {
12
+ recommended: {
13
+ plugins: string[];
14
+ rules: {
15
+ 'vue-setup-order/order': string;
16
+ };
17
+ };
18
+ flat: {
19
+ recommended: {
20
+ plugins: {
21
+ readonly 'vue-setup-order': any;
22
+ };
23
+ rules: {
24
+ 'vue-setup-order/order': string;
25
+ };
26
+ };
27
+ };
28
+ };
29
+ };
30
+
31
+ export { plugin as default };
@@ -0,0 +1,31 @@
1
+ import * as eslint from 'eslint';
2
+
3
+ declare const plugin: {
4
+ meta: {
5
+ name: string;
6
+ version: string;
7
+ };
8
+ rules: {
9
+ order: eslint.Rule.RuleModule;
10
+ };
11
+ configs: {
12
+ recommended: {
13
+ plugins: string[];
14
+ rules: {
15
+ 'vue-setup-order/order': string;
16
+ };
17
+ };
18
+ flat: {
19
+ recommended: {
20
+ plugins: {
21
+ readonly 'vue-setup-order': any;
22
+ };
23
+ rules: {
24
+ 'vue-setup-order/order': string;
25
+ };
26
+ };
27
+ };
28
+ };
29
+ };
30
+
31
+ export { plugin as default };
package/dist/index.js ADDED
@@ -0,0 +1,359 @@
1
+ // src/utils/constants.ts
2
+ var CATEGORY_IMPORT = 0;
3
+ var CATEGORY_TYPES = 1;
4
+ var CATEGORY_DEFINE = 2;
5
+ var CATEGORY_COMPOSABLE = 3;
6
+ var CATEGORY_REACTIVE = 4;
7
+ var CATEGORY_COMPUTED = 5;
8
+ var CATEGORY_WATCH = 6;
9
+ var CATEGORY_LIFECYCLE = 7;
10
+ var CATEGORY_FUNCTION = 8;
11
+ var CATEGORY_PROVIDE = 9;
12
+ var CATEGORY_UNKNOWN = 99;
13
+ var DEFAULT_ORDER = {
14
+ // Imports
15
+ import: CATEGORY_IMPORT,
16
+ // Types
17
+ types: CATEGORY_TYPES,
18
+ // Define macros
19
+ defineOptions: CATEGORY_DEFINE,
20
+ defineProps: CATEGORY_DEFINE,
21
+ defineEmits: CATEGORY_DEFINE,
22
+ defineSlots: CATEGORY_DEFINE,
23
+ defineExpose: CATEGORY_DEFINE,
24
+ defineModel: CATEGORY_DEFINE,
25
+ withDefaults: CATEGORY_DEFINE,
26
+ // Composables
27
+ composable: CATEGORY_COMPOSABLE,
28
+ // Reactive state
29
+ ref: CATEGORY_REACTIVE,
30
+ reactive: CATEGORY_REACTIVE,
31
+ shallowRef: CATEGORY_REACTIVE,
32
+ shallowReactive: CATEGORY_REACTIVE,
33
+ toRef: CATEGORY_REACTIVE,
34
+ toRefs: CATEGORY_REACTIVE,
35
+ customRef: CATEGORY_REACTIVE,
36
+ readonly: CATEGORY_REACTIVE,
37
+ shallowReadonly: CATEGORY_REACTIVE,
38
+ // Computed
39
+ computed: CATEGORY_COMPUTED,
40
+ // Watchers
41
+ watch: CATEGORY_WATCH,
42
+ watchEffect: CATEGORY_WATCH,
43
+ watchPostEffect: CATEGORY_WATCH,
44
+ watchSyncEffect: CATEGORY_WATCH,
45
+ // Lifecycle hooks
46
+ onBeforeMount: CATEGORY_LIFECYCLE,
47
+ onMounted: CATEGORY_LIFECYCLE,
48
+ onBeforeUpdate: CATEGORY_LIFECYCLE,
49
+ onUpdated: CATEGORY_LIFECYCLE,
50
+ onBeforeUnmount: CATEGORY_LIFECYCLE,
51
+ onUnmounted: CATEGORY_LIFECYCLE,
52
+ onActivated: CATEGORY_LIFECYCLE,
53
+ onDeactivated: CATEGORY_LIFECYCLE,
54
+ onErrorCaptured: CATEGORY_LIFECYCLE,
55
+ onRenderTracked: CATEGORY_LIFECYCLE,
56
+ onRenderTriggered: CATEGORY_LIFECYCLE,
57
+ onServerPrefetch: CATEGORY_LIFECYCLE,
58
+ // Functions
59
+ function: CATEGORY_FUNCTION,
60
+ // Provide
61
+ provide: CATEGORY_PROVIDE,
62
+ // Unknown
63
+ unknown: CATEGORY_UNKNOWN
64
+ };
65
+ var ORDER_NAMES = {
66
+ [CATEGORY_IMPORT]: "imports",
67
+ [CATEGORY_TYPES]: "type declarations",
68
+ [CATEGORY_DEFINE]: "define macros",
69
+ [CATEGORY_COMPOSABLE]: "composables",
70
+ [CATEGORY_REACTIVE]: "reactive state",
71
+ [CATEGORY_COMPUTED]: "computed properties",
72
+ [CATEGORY_WATCH]: "watchers",
73
+ [CATEGORY_LIFECYCLE]: "lifecycle hooks",
74
+ [CATEGORY_FUNCTION]: "functions",
75
+ [CATEGORY_PROVIDE]: "provide",
76
+ [CATEGORY_UNKNOWN]: "other"
77
+ };
78
+ var COMPOSABLE_PATTERN = /^use[A-Z]/;
79
+
80
+ // src/utils/analyze.ts
81
+ function getCalleeName(node, sourceCode) {
82
+ if (!node) return null;
83
+ if (node.type === "Identifier") {
84
+ return node.name;
85
+ }
86
+ if (node.type === "MemberExpression") {
87
+ return sourceCode.getText(node);
88
+ }
89
+ return null;
90
+ }
91
+ function isComposable(name) {
92
+ return name !== null && COMPOSABLE_PATTERN.test(name);
93
+ }
94
+ function analyzeStatement(statement, sourceCode, orderConfig) {
95
+ const result = {
96
+ node: statement,
97
+ order: orderConfig.unknown ?? CATEGORY_UNKNOWN,
98
+ name: "unknown",
99
+ category: "unknown"
100
+ };
101
+ if (statement.type === "ImportDeclaration") {
102
+ result.order = orderConfig.import;
103
+ result.name = "import";
104
+ result.category = "import";
105
+ return result;
106
+ }
107
+ const statementType = statement.type;
108
+ if (statementType === "TSTypeAliasDeclaration" || statementType === "TSInterfaceDeclaration" || statementType === "TSEnumDeclaration") {
109
+ result.order = orderConfig.types ?? CATEGORY_TYPES;
110
+ result.name = statementType === "TSTypeAliasDeclaration" ? "type" : statementType === "TSInterfaceDeclaration" ? "interface" : "enum";
111
+ result.category = "types";
112
+ return result;
113
+ }
114
+ if (statement.type === "ExportNamedDeclaration" || statement.type === "ExportDefaultDeclaration" || statement.type === "ExportAllDeclaration") {
115
+ return null;
116
+ }
117
+ if (statement.type === "VariableDeclaration") {
118
+ const declaration = statement.declarations[0];
119
+ const init = declaration?.init;
120
+ if (!init) {
121
+ result.order = orderConfig.ref ?? CATEGORY_REACTIVE;
122
+ result.name = "variable";
123
+ result.category = "reactive";
124
+ return result;
125
+ }
126
+ if (init.type === "CallExpression") {
127
+ const calleeName = getCalleeName(init.callee, sourceCode);
128
+ if (calleeName) {
129
+ if (isComposable(calleeName)) {
130
+ result.order = orderConfig.composable;
131
+ result.name = calleeName;
132
+ result.category = "composable";
133
+ return result;
134
+ }
135
+ if (orderConfig[calleeName] !== void 0) {
136
+ result.order = orderConfig[calleeName];
137
+ result.name = calleeName;
138
+ result.category = calleeName;
139
+ return result;
140
+ }
141
+ }
142
+ result.order = orderConfig.ref ?? CATEGORY_REACTIVE;
143
+ result.name = calleeName || "variable";
144
+ result.category = "reactive";
145
+ return result;
146
+ }
147
+ if (init.type === "ArrowFunctionExpression" || init.type === "FunctionExpression") {
148
+ result.order = orderConfig.function ?? CATEGORY_FUNCTION;
149
+ result.name = declaration.id?.type === "Identifier" ? declaration.id.name : "arrow function";
150
+ result.category = "function";
151
+ return result;
152
+ }
153
+ result.order = orderConfig.ref ?? CATEGORY_REACTIVE;
154
+ result.name = "variable";
155
+ result.category = "reactive";
156
+ return result;
157
+ }
158
+ if (statement.type === "FunctionDeclaration") {
159
+ result.order = orderConfig.function ?? CATEGORY_FUNCTION;
160
+ result.name = statement.id?.name || "function";
161
+ result.category = "function";
162
+ return result;
163
+ }
164
+ if (statement.type === "ExpressionStatement") {
165
+ const expr = statement.expression;
166
+ if (expr.type === "CallExpression") {
167
+ const calleeName = getCalleeName(expr.callee, sourceCode);
168
+ if (calleeName && orderConfig[calleeName] !== void 0) {
169
+ result.order = orderConfig[calleeName];
170
+ result.name = calleeName;
171
+ result.category = calleeName;
172
+ return result;
173
+ }
174
+ result.order = orderConfig.unknown ?? CATEGORY_UNKNOWN;
175
+ result.name = calleeName || "call";
176
+ result.category = "unknown";
177
+ return result;
178
+ }
179
+ result.order = orderConfig.unknown ?? CATEGORY_UNKNOWN;
180
+ result.name = "expression";
181
+ result.category = "unknown";
182
+ return result;
183
+ }
184
+ return result;
185
+ }
186
+
187
+ // src/utils/source-code.ts
188
+ function getNodeTextWithComments(node, sourceCode) {
189
+ const comments = sourceCode.getCommentsBefore(node);
190
+ let start = node.range[0];
191
+ if (comments.length > 0) {
192
+ start = comments[0].range[0];
193
+ }
194
+ return sourceCode.text.slice(start, node.range[1]);
195
+ }
196
+ function getFullRange(node, sourceCode) {
197
+ const comments = sourceCode.getCommentsBefore(node);
198
+ let start = node.range[0];
199
+ if (comments.length > 0) {
200
+ start = comments[0].range[0];
201
+ }
202
+ let end = node.range[1];
203
+ const textAfter = sourceCode.text.slice(end, end + 2);
204
+ if (textAfter.startsWith("\r\n")) {
205
+ end += 2;
206
+ } else if (textAfter.startsWith("\n")) {
207
+ end += 1;
208
+ }
209
+ return [start, end];
210
+ }
211
+ function generateSortedCode(statements, sourceCode, addBlankLines = true) {
212
+ const parts = [];
213
+ let lastOrder = -1;
214
+ for (const statement of statements) {
215
+ const text = getNodeTextWithComments(statement.node, sourceCode).trim();
216
+ if (addBlankLines && lastOrder !== -1 && statement.order !== lastOrder) {
217
+ parts.push("");
218
+ }
219
+ parts.push(text);
220
+ lastOrder = statement.order;
221
+ }
222
+ return parts.join("\n");
223
+ }
224
+
225
+ // src/rules/order.ts
226
+ var rule = {
227
+ meta: {
228
+ type: "suggestion",
229
+ docs: {
230
+ description: "Enforce consistent order of statements in Vue 3 <script setup>",
231
+ category: "Stylistic Issues",
232
+ recommended: true,
233
+ url: "https://github.com/d2a8k3u/eslint-plugin-vue-setup-order#readme"
234
+ },
235
+ fixable: "code",
236
+ schema: [
237
+ {
238
+ type: "object",
239
+ properties: {
240
+ order: {
241
+ type: "array",
242
+ items: { type: "string" },
243
+ description: "Custom order of categories"
244
+ },
245
+ groupBlankLines: {
246
+ type: "boolean",
247
+ default: true,
248
+ description: "Add blank lines between different categories"
249
+ }
250
+ },
251
+ additionalProperties: false
252
+ }
253
+ ],
254
+ messages: {
255
+ wrongOrder: "'{{current}}' ({{currentCategory}}) should come before '{{previous}}' ({{previousCategory}})"
256
+ }
257
+ },
258
+ create(context) {
259
+ const sourceCode = context.sourceCode ?? context.getSourceCode();
260
+ const options = context.options[0] || {};
261
+ const groupBlankLines = false !== options.groupBlankLines;
262
+ const orderConfig = { ...DEFAULT_ORDER };
263
+ if (options.order && Array.isArray(options.order)) {
264
+ options.order.forEach((category, index) => {
265
+ const originalOrder = DEFAULT_ORDER[category];
266
+ if (originalOrder !== void 0) {
267
+ Object.keys(DEFAULT_ORDER).forEach((key) => {
268
+ if (DEFAULT_ORDER[key] === originalOrder) {
269
+ orderConfig[key] = index;
270
+ }
271
+ });
272
+ }
273
+ orderConfig[category] = index;
274
+ });
275
+ }
276
+ return {
277
+ Program(node) {
278
+ const statements = [];
279
+ for (const statement of node.body) {
280
+ const analyzed = analyzeStatement(statement, sourceCode, orderConfig);
281
+ if (analyzed) {
282
+ statements.push(analyzed);
283
+ }
284
+ }
285
+ if (statements.length < 2) return;
286
+ let firstError = null;
287
+ for (let i = 1; i < statements.length; i++) {
288
+ const prev = statements[i - 1];
289
+ const curr = statements[i];
290
+ if (curr.order < prev.order) {
291
+ firstError = { index: i, current: curr, previous: prev };
292
+ break;
293
+ }
294
+ }
295
+ if (!firstError) return;
296
+ context.report({
297
+ node: firstError.current.node,
298
+ messageId: "wrongOrder",
299
+ data: {
300
+ current: firstError.current.name,
301
+ currentCategory: ORDER_NAMES[firstError.current.order] || "unknown",
302
+ previous: firstError.previous.name,
303
+ previousCategory: ORDER_NAMES[firstError.previous.order] || "unknown"
304
+ },
305
+ fix(fixer) {
306
+ const sorted = [...statements].sort((a, b) => {
307
+ if (a.order !== b.order) {
308
+ return a.order - b.order;
309
+ }
310
+ return statements.indexOf(a) - statements.indexOf(b);
311
+ });
312
+ const newCode = generateSortedCode(sorted, sourceCode, groupBlankLines);
313
+ const firstRange = getFullRange(statements[0].node, sourceCode);
314
+ const lastRange = getFullRange(statements[statements.length - 1].node, sourceCode);
315
+ return fixer.replaceTextRange([firstRange[0], lastRange[1]], newCode + "\n");
316
+ }
317
+ });
318
+ }
319
+ };
320
+ }
321
+ };
322
+ var order_default = rule;
323
+
324
+ // src/index.ts
325
+ var plugin = {
326
+ meta: {
327
+ name: "eslint-plugin-vue-setup-order",
328
+ version: "1.0.0"
329
+ },
330
+ rules: {
331
+ order: order_default
332
+ },
333
+ configs: {
334
+ recommended: {
335
+ plugins: ["vue-setup-order"],
336
+ rules: {
337
+ "vue-setup-order/order": "error"
338
+ }
339
+ },
340
+ // Flat config format for ESLint 9+
341
+ flat: {
342
+ recommended: {
343
+ plugins: {
344
+ get "vue-setup-order"() {
345
+ return plugin;
346
+ }
347
+ },
348
+ rules: {
349
+ "vue-setup-order/order": "error"
350
+ }
351
+ }
352
+ }
353
+ }
354
+ };
355
+ var index_default = plugin;
356
+ export {
357
+ index_default as default
358
+ };
359
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/constants.ts","../src/utils/analyze.ts","../src/utils/source-code.ts","../src/rules/order.ts","../src/index.ts"],"sourcesContent":["import type { OrderConfig } from '../types';\n\nexport const CATEGORY_IMPORT = 0;\nexport const CATEGORY_TYPES = 1;\nexport const CATEGORY_DEFINE = 2;\nexport const CATEGORY_COMPOSABLE = 3;\nexport const CATEGORY_REACTIVE = 4;\nexport const CATEGORY_COMPUTED = 5;\nexport const CATEGORY_WATCH = 6;\nexport const CATEGORY_LIFECYCLE = 7;\nexport const CATEGORY_FUNCTION = 8;\nexport const CATEGORY_PROVIDE = 9;\nexport const CATEGORY_UNKNOWN = 99;\n\nexport const DEFAULT_ORDER: OrderConfig = {\n // Imports\n import: CATEGORY_IMPORT,\n\n // Types\n types: CATEGORY_TYPES,\n\n // Define macros\n defineOptions: CATEGORY_DEFINE,\n defineProps: CATEGORY_DEFINE,\n defineEmits: CATEGORY_DEFINE,\n defineSlots: CATEGORY_DEFINE,\n defineExpose: CATEGORY_DEFINE,\n defineModel: CATEGORY_DEFINE,\n withDefaults: CATEGORY_DEFINE,\n\n // Composables\n composable: CATEGORY_COMPOSABLE,\n\n // Reactive state\n ref: CATEGORY_REACTIVE,\n reactive: CATEGORY_REACTIVE,\n shallowRef: CATEGORY_REACTIVE,\n shallowReactive: CATEGORY_REACTIVE,\n toRef: CATEGORY_REACTIVE,\n toRefs: CATEGORY_REACTIVE,\n customRef: CATEGORY_REACTIVE,\n readonly: CATEGORY_REACTIVE,\n shallowReadonly: CATEGORY_REACTIVE,\n\n // Computed\n computed: CATEGORY_COMPUTED,\n\n // Watchers\n watch: CATEGORY_WATCH,\n watchEffect: CATEGORY_WATCH,\n watchPostEffect: CATEGORY_WATCH,\n watchSyncEffect: CATEGORY_WATCH,\n\n // Lifecycle hooks\n onBeforeMount: CATEGORY_LIFECYCLE,\n onMounted: CATEGORY_LIFECYCLE,\n onBeforeUpdate: CATEGORY_LIFECYCLE,\n onUpdated: CATEGORY_LIFECYCLE,\n onBeforeUnmount: CATEGORY_LIFECYCLE,\n onUnmounted: CATEGORY_LIFECYCLE,\n onActivated: CATEGORY_LIFECYCLE,\n onDeactivated: CATEGORY_LIFECYCLE,\n onErrorCaptured: CATEGORY_LIFECYCLE,\n onRenderTracked: CATEGORY_LIFECYCLE,\n onRenderTriggered: CATEGORY_LIFECYCLE,\n onServerPrefetch: CATEGORY_LIFECYCLE,\n\n // Functions\n function: CATEGORY_FUNCTION,\n\n // Provide\n provide: CATEGORY_PROVIDE,\n\n // Unknown\n unknown: CATEGORY_UNKNOWN,\n};\n\nexport const ORDER_NAMES: Record<number, string> = {\n [CATEGORY_IMPORT]: 'imports',\n [CATEGORY_TYPES]: 'type declarations',\n [CATEGORY_DEFINE]: 'define macros',\n [CATEGORY_COMPOSABLE]: 'composables',\n [CATEGORY_REACTIVE]: 'reactive state',\n [CATEGORY_COMPUTED]: 'computed properties',\n [CATEGORY_WATCH]: 'watchers',\n [CATEGORY_LIFECYCLE]: 'lifecycle hooks',\n [CATEGORY_FUNCTION]: 'functions',\n [CATEGORY_PROVIDE]: 'provide',\n [CATEGORY_UNKNOWN]: 'other',\n};\n\nexport const COMPOSABLE_PATTERN = /^use[A-Z]/;\n","import type { Rule } from 'eslint';\nimport type { Expression, ModuleDeclaration, Statement, Super } from 'estree';\nimport type { AnalyzedStatement, OrderConfig } from '../types';\nimport {\n CATEGORY_FUNCTION,\n CATEGORY_REACTIVE,\n CATEGORY_TYPES,\n CATEGORY_UNKNOWN,\n COMPOSABLE_PATTERN,\n} from './constants';\n\n/**\n * Retrieves the name of the callee from the provided node (Expression or Super).\n *\n * @param {Expression | Super | null | undefined} node - The node representing a callee, which can be an Expression or Super. May be null or undefined.\n * @param {Rule.RuleContext['sourceCode']} sourceCode - The source code object used to extract the callee name in case it's a MemberExpression.\n * @return {string | null} The name of the callee as a string if resolved, or null if the node is null, undefined, or not resolvable.\n */\nexport function getCalleeName(\n node: Expression | Super | null | undefined,\n sourceCode: Rule.RuleContext['sourceCode'],\n): string | null {\n if (!node) return null;\n\n if (node.type === 'Identifier') {\n return node.name;\n }\n\n if (node.type === 'MemberExpression') {\n return sourceCode.getText(node);\n }\n\n return null;\n}\n\n/**\n * Determines if the provided name is composable based on a predefined pattern.\n *\n * @param {string | null} name - The name to be tested against the composable pattern. Can be null.\n * @return {boolean} Returns true if the name matches the composable pattern and is not null; otherwise, returns false.\n */\nexport function isComposable(name: string | null): boolean {\n return name !== null && COMPOSABLE_PATTERN.test(name);\n}\n\n/**\n * Analyzes a given statement or module declaration to categorize, name, and assign an order based on the specified configuration.\n *\n * @param {Statement | ModuleDeclaration} statement - The statement or module declaration to be analyzed.\n * @param {Rule.RuleContext['sourceCode']} sourceCode - The source code context to extract details about the statement.\n * @param {OrderConfig} orderConfig - Configuration object that defines ordering and categorization rules.\n * @return {AnalyzedStatement | null} An object containing analysis details of the statement, or null for certain export declarations.\n */\nexport function analyzeStatement(\n statement: Statement | ModuleDeclaration,\n sourceCode: Rule.RuleContext['sourceCode'],\n orderConfig: OrderConfig,\n): AnalyzedStatement | null {\n const result: AnalyzedStatement = {\n node: statement as Statement,\n order: orderConfig.unknown ?? CATEGORY_UNKNOWN,\n name: 'unknown',\n category: 'unknown',\n };\n\n if (statement.type === 'ImportDeclaration') {\n result.order = orderConfig.import;\n result.name = 'import';\n result.category = 'import';\n return result;\n }\n\n const statementType = (statement as { type: string }).type;\n if (\n statementType === 'TSTypeAliasDeclaration' ||\n statementType === 'TSInterfaceDeclaration' ||\n statementType === 'TSEnumDeclaration'\n ) {\n result.order = orderConfig.types ?? CATEGORY_TYPES;\n result.name =\n statementType === 'TSTypeAliasDeclaration'\n ? 'type'\n : statementType === 'TSInterfaceDeclaration'\n ? 'interface'\n : 'enum';\n result.category = 'types';\n return result;\n }\n\n if (\n statement.type === 'ExportNamedDeclaration' ||\n statement.type === 'ExportDefaultDeclaration' ||\n statement.type === 'ExportAllDeclaration'\n ) {\n return null;\n }\n\n if (statement.type === 'VariableDeclaration') {\n const declaration = statement.declarations[0];\n const init = declaration?.init;\n\n if (!init) {\n result.order = orderConfig.ref ?? CATEGORY_REACTIVE;\n result.name = 'variable';\n result.category = 'reactive';\n return result;\n }\n\n if (init.type === 'CallExpression') {\n const calleeName = getCalleeName(init.callee, sourceCode);\n\n if (calleeName) {\n if (isComposable(calleeName)) {\n result.order = orderConfig.composable;\n result.name = calleeName;\n result.category = 'composable';\n return result;\n }\n\n if (orderConfig[calleeName] !== undefined) {\n result.order = orderConfig[calleeName];\n result.name = calleeName;\n result.category = calleeName;\n return result;\n }\n }\n\n result.order = orderConfig.ref ?? CATEGORY_REACTIVE;\n result.name = calleeName || 'variable';\n result.category = 'reactive';\n return result;\n }\n\n if (init.type === 'ArrowFunctionExpression' || init.type === 'FunctionExpression') {\n result.order = orderConfig.function ?? CATEGORY_FUNCTION;\n result.name = declaration.id?.type === 'Identifier' ? declaration.id.name : 'arrow function';\n result.category = 'function';\n return result;\n }\n\n result.order = orderConfig.ref ?? CATEGORY_REACTIVE;\n result.name = 'variable';\n result.category = 'reactive';\n return result;\n }\n\n if (statement.type === 'FunctionDeclaration') {\n result.order = orderConfig.function ?? CATEGORY_FUNCTION;\n result.name = statement.id?.name || 'function';\n result.category = 'function';\n return result;\n }\n\n if (statement.type === 'ExpressionStatement') {\n const expr = statement.expression;\n\n if (expr.type === 'CallExpression') {\n const calleeName = getCalleeName(expr.callee, sourceCode);\n\n if (calleeName && orderConfig[calleeName] !== undefined) {\n result.order = orderConfig[calleeName];\n result.name = calleeName;\n result.category = calleeName;\n return result;\n }\n\n result.order = orderConfig.unknown ?? CATEGORY_UNKNOWN;\n result.name = calleeName || 'call';\n result.category = 'unknown';\n return result;\n }\n\n result.order = orderConfig.unknown ?? CATEGORY_UNKNOWN;\n result.name = 'expression';\n result.category = 'unknown';\n return result;\n }\n\n return result;\n}\n","import type { Rule } from 'eslint';\nimport type { Statement } from 'estree';\n\n/**\n * Retrieves the combined text of a given AST node and its preceding comments from the source code.\n *\n * @param {Statement} node - The AST node whose text and preceding comments are to be retrieved.\n * @param {Rule.RuleContext['sourceCode']} sourceCode - The source code object containing the text and comments.\n * @return {string} The concatenated text of the node and its preceding comments.\n */\nexport function getNodeTextWithComments(node: Statement, sourceCode: Rule.RuleContext['sourceCode']): string {\n const comments = sourceCode.getCommentsBefore(node);\n let start = node.range![0];\n\n if (comments.length > 0) {\n start = comments[0].range![0];\n }\n\n return sourceCode.text.slice(start, node.range![1]);\n}\n\n/**\n * Determines the full range of a given statement node, including its preceding comments\n * and any trailing newlines immediately following the node.\n *\n * @param {Statement} node - The statement node for which to calculate the full range.\n * @param {Rule.RuleContext['sourceCode']} sourceCode - The source code object used to retrieve comments and text.\n * @return {[number, number]} The start and end positions of the full range in the source code.\n */\nexport function getFullRange(node: Statement, sourceCode: Rule.RuleContext['sourceCode']): [number, number] {\n const comments = sourceCode.getCommentsBefore(node);\n let start = node.range![0];\n\n if (comments.length > 0) {\n start = comments[0].range![0];\n }\n\n let end = node.range![1];\n const textAfter = sourceCode.text.slice(end, end + 2);\n\n if (textAfter.startsWith('\\r\\n')) {\n end += 2;\n } else if (textAfter.startsWith('\\n')) {\n end += 1;\n }\n\n return [start, end];\n}\n\n/**\n * Generates a sorted string representation of code statements, optionally adding blank lines between different categories.\n *\n * @param {Array<{ node: Statement, order: number }>} statements - An array of objects containing a statement node and its corresponding order.\n * @param {Rule.RuleContext['sourceCode']} sourceCode - The source code object used to extract the textual representation of the statement nodes.\n * @param {boolean} [addBlankLines=true] - A flag indicating whether to add blank lines between statements of differing orders.\n * @return {string} A sorted and formatted code string based on the given statements and options.\n */\nexport function generateSortedCode(\n statements: Array<{ node: Statement; order: number }>,\n sourceCode: Rule.RuleContext['sourceCode'],\n addBlankLines: boolean = true,\n): string {\n const parts: string[] = [];\n let lastOrder = -1;\n\n for (const statement of statements) {\n const text = getNodeTextWithComments(statement.node, sourceCode).trim();\n\n if (addBlankLines && lastOrder !== -1 && statement.order !== lastOrder) {\n parts.push('');\n }\n\n parts.push(text);\n lastOrder = statement.order;\n }\n\n return parts.join('\\n');\n}\n","import type { Rule } from 'eslint';\nimport type { Program } from 'estree';\nimport type { AnalyzedStatement, OrderConfig, PluginOptions } from '../types';\nimport { analyzeStatement } from '../utils/analyze';\nimport { DEFAULT_ORDER, ORDER_NAMES } from '../utils/constants';\nimport { generateSortedCode, getFullRange } from '../utils/source-code';\n\n/**\n * Represents an ESLint rule module designed to enforce a consistent order of statements\n * in the `<script setup>` block of Vue 3 components.\n *\n * The rule provides configuration options for defining custom ordering of statement categories\n * and for including blank lines between different categories. The rule reports and optionally\n * fixes statement order violations.\n */\nconst rule: Rule.RuleModule = {\n meta: {\n type: 'suggestion',\n docs: {\n description: 'Enforce consistent order of statements in Vue 3 <script setup>',\n category: 'Stylistic Issues',\n recommended: true,\n url: 'https://github.com/d2a8k3u/eslint-plugin-vue-setup-order#readme',\n },\n fixable: 'code',\n schema: [\n {\n type: 'object',\n properties: {\n order: {\n type: 'array',\n items: { type: 'string' },\n description: 'Custom order of categories',\n },\n groupBlankLines: {\n type: 'boolean',\n default: true,\n description: 'Add blank lines between different categories',\n },\n },\n additionalProperties: false,\n },\n ],\n messages: {\n wrongOrder: \"'{{current}}' ({{currentCategory}}) should come before '{{previous}}' ({{previousCategory}})\",\n },\n },\n\n create(context: Rule.RuleContext) {\n const sourceCode = context.sourceCode ?? context.getSourceCode();\n const options: PluginOptions = context.options[0] || {};\n const groupBlankLines = false !== options.groupBlankLines;\n const orderConfig: OrderConfig = { ...DEFAULT_ORDER };\n\n if (options.order && Array.isArray(options.order)) {\n options.order.forEach((category, index) => {\n const originalOrder = DEFAULT_ORDER[category];\n if (originalOrder !== undefined) {\n Object.keys(DEFAULT_ORDER).forEach((key) => {\n if (DEFAULT_ORDER[key] === originalOrder) {\n orderConfig[key] = index;\n }\n });\n }\n orderConfig[category] = index;\n });\n }\n\n return {\n Program(node: Program) {\n const statements: AnalyzedStatement[] = [];\n\n for (const statement of node.body) {\n const analyzed = analyzeStatement(statement, sourceCode, orderConfig);\n if (analyzed) {\n statements.push(analyzed);\n }\n }\n\n if (statements.length < 2) return;\n\n let firstError: {\n index: number;\n current: AnalyzedStatement;\n previous: AnalyzedStatement;\n } | null = null;\n\n for (let i = 1; i < statements.length; i++) {\n const prev = statements[i - 1];\n const curr = statements[i];\n\n if (curr.order < prev.order) {\n firstError = { index: i, current: curr, previous: prev };\n break;\n }\n }\n\n if (!firstError) return;\n\n context.report({\n node: firstError.current.node,\n messageId: 'wrongOrder',\n data: {\n current: firstError.current.name,\n currentCategory: ORDER_NAMES[firstError.current.order] || 'unknown',\n previous: firstError.previous.name,\n previousCategory: ORDER_NAMES[firstError.previous.order] || 'unknown',\n },\n fix(fixer) {\n const sorted = [...statements].sort((a, b) => {\n if (a.order !== b.order) {\n return a.order - b.order;\n }\n\n return statements.indexOf(a) - statements.indexOf(b);\n });\n\n const newCode = generateSortedCode(sorted, sourceCode, groupBlankLines);\n const firstRange = getFullRange(statements[0].node, sourceCode);\n const lastRange = getFullRange(statements[statements.length - 1].node, sourceCode);\n\n return fixer.replaceTextRange([firstRange[0], lastRange[1]], newCode + '\\n');\n },\n });\n },\n };\n },\n};\n\nexport default rule;\n","import orderRule from './rules/order';\n\nconst plugin = {\n meta: {\n name: 'eslint-plugin-vue-setup-order',\n version: '1.0.0',\n },\n rules: {\n order: orderRule,\n },\n configs: {\n recommended: {\n plugins: ['vue-setup-order'],\n rules: {\n 'vue-setup-order/order': 'error',\n },\n },\n // Flat config format for ESLint 9+\n flat: {\n recommended: {\n plugins: {\n get 'vue-setup-order'() {\n return plugin;\n },\n },\n rules: {\n 'vue-setup-order/order': 'error',\n },\n },\n },\n },\n};\n\nexport default plugin;\n"],"mappings":"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","names":[]}
package/package.json ADDED
@@ -0,0 +1,74 @@
1
+ {
2
+ "name": "eslint-plugin-vue-setup-order",
3
+ "version": "1.0.0",
4
+ "description": "ESLint plugin to enforce consistent order of statements in Vue 3 <script setup>",
5
+ "keywords": [
6
+ "eslint",
7
+ "eslintplugin",
8
+ "eslint-plugin",
9
+ "vue",
10
+ "vue3",
11
+ "script-setup",
12
+ "order",
13
+ "formatting",
14
+ "code-style"
15
+ ],
16
+ "homepage": "https://github.com/d2a8k3u/eslint-plugin-vue-setup-order#readme",
17
+ "bugs": {
18
+ "url": "https://github.com/d2a8k3u/eslint-plugin-vue-setup-order/issues"
19
+ },
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "https://github.com/d2a8k3u/eslint-plugin-vue-setup-order.git"
23
+ },
24
+ "license": "MIT",
25
+ "author": "David Kulhanek (https://github.com/d2a8k3u)",
26
+ "type": "module",
27
+ "exports": {
28
+ ".": {
29
+ "import": "./dist/index.js",
30
+ "require": "./dist/index.cjs"
31
+ }
32
+ },
33
+ "main": "./dist/index.cjs",
34
+ "module": "./dist/index.js",
35
+ "types": "./dist/index.d.ts",
36
+ "files": [
37
+ "dist"
38
+ ],
39
+ "scripts": {
40
+ "build": "tsup",
41
+ "dev": "tsup --watch",
42
+ "lint": "eslint src tests",
43
+ "lint:fix": "eslint src tests --fix",
44
+ "prepublishOnly": "npm run build && npm run test:run",
45
+ "release": "npm run build && changeset publish",
46
+ "format": "prettier --write .",
47
+ "format:check": "prettier --check .",
48
+ "test": "vitest",
49
+ "test:coverage": "vitest run --coverage",
50
+ "test:run": "vitest run",
51
+ "typecheck": "tsc --noEmit"
52
+ },
53
+ "devDependencies": {
54
+ "@changesets/changelog-github": "^0.5.2",
55
+ "@changesets/cli": "^2.29.8",
56
+ "@types/eslint": "^8.56.2",
57
+ "@types/node": "^20.11.5",
58
+ "@typescript-eslint/eslint-plugin": "^6.19.1",
59
+ "@typescript-eslint/parser": "^6.19.1",
60
+ "@vitest/coverage-v8": "^4.0.16",
61
+ "eslint": "^8.57.1",
62
+ "prettier": "^3.2.4",
63
+ "prettier-plugin-organize-imports": "^4.1.0",
64
+ "tsup": "^8.0.1",
65
+ "typescript": "~5.3.3",
66
+ "vitest": "^4.0.16"
67
+ },
68
+ "peerDependencies": {
69
+ "eslint": ">=8.0.0"
70
+ },
71
+ "engines": {
72
+ "node": ">=18.0.0"
73
+ }
74
+ }