@qstanay/eslint-config 1.0.2 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/LICENSE +21 -0
- package/README.md +12 -0
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +21 -10
- package/dist/index.mjs.map +1 -1
- package/dist/{nuxt-B6cDasrO.mjs → nuxt-jcrXAC4G.mjs} +22 -5
- package/dist/nuxt-jcrXAC4G.mjs.map +1 -0
- package/dist/nuxt.mjs +1 -1
- package/package.json +15 -5
- package/dist/nuxt-B6cDasrO.mjs.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project are documented in this file.
|
|
4
4
|
|
|
5
|
+
## [1.0.3] - 2026-07-20
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- Do not attach the TypeScript parser to `.vue` when Vue is disabled (avoids fatal parse errors)
|
|
10
|
+
- Ignore `.vue` files when Vue is disabled so `eslint .` does not crash on stray SFCs
|
|
11
|
+
- Apply shared rules and overrides to `.mjs` / `.cjs` (not only `.js`)
|
|
12
|
+
- Declare Node + ES2022 globals in the JavaScript layer so `no-undef` no longer false-positives on `console` / `process`
|
|
13
|
+
- Resolve TypeScript types for `@qstanay/eslint-config/nuxt` via package `exports`
|
|
14
|
+
- Declare `typescript` as an optional peer dependency (matches existing `peerDependenciesMeta`)
|
|
15
|
+
- Use an explicit options array for `vue/padding-line-between-tags`
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
|
|
19
|
+
- Fill `author` and `engines.node` (`>=18`) in `package.json`
|
|
20
|
+
|
|
5
21
|
## [1.0.2] - 2026-07-18
|
|
6
22
|
|
|
7
23
|
### Added
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Denis Lapshin
|
|
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
CHANGED
|
@@ -14,6 +14,18 @@ Formatting is handled by ESLint via **@stylistic** (`eslint --fix`). Do **not**
|
|
|
14
14
|
|
|
15
15
|
For Nuxt, prefer the `/nuxt` entry. It only adds opinionated rules + formatting on top of Nuxt's own TypeScript/Vue setup. It does **not** replace `@nuxt/eslint`.
|
|
16
16
|
|
|
17
|
+
## When to use this
|
|
18
|
+
|
|
19
|
+
Use this preset when you want a **small, Nuxt/Vue/TypeScript-focused** flat config with lint + format in one toolchain (`eslint --fix` via `@stylistic`), without Prettier.
|
|
20
|
+
|
|
21
|
+
How it differs from common alternatives:
|
|
22
|
+
|
|
23
|
+
- **vs `@antfu/eslint-config`** — narrower scope. No JSON/YAML/Markdown/CSS formatters, no React/Next/Svelte/Astro stack. Keeps standard rule prefixes (`@typescript-eslint/*`, `import/*`) and defaults to semicolons + single quotes + 2-space indent. Includes a dedicated Nuxt layer for `@nuxt/eslint` + `withNuxt()`.
|
|
24
|
+
- **vs Prettier (+ eslint-config-prettier)** — formatting lives in ESLint/Stylistic. Do not run both unless you set `stylistic: false`.
|
|
25
|
+
- **vs using `@nuxt/eslint` alone** — Nuxt already gives project-aware Vue/TS setup; this package adds opinionated shared rules and stylistic formatting on top.
|
|
26
|
+
|
|
27
|
+
If you need a wide multi-framework “batteries included” preset, prefer something like `@antfu/eslint-config`. If you mainly ship Nuxt/Vue/TS apps and want a predictable thin layer, use this.
|
|
28
|
+
|
|
17
29
|
## Requirements
|
|
18
30
|
|
|
19
31
|
- Node.js 18+
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"mappings":";;;iBAuBgB,aACd,UAAS,kBACN,cAAc,UAAU,sBAAsB,4BAAyB,mBAAA"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as
|
|
1
|
+
import { a as resolveEnabled, c as typescriptFiles, d as ignores, i as has, l as stylistic, n as vueRules, o as resolveStylisticOptions, r as VUE_FILES, s as sourceFiles, t as nuxt, u as sharedRules } from "./nuxt-jcrXAC4G.mjs";
|
|
2
2
|
import { FlatConfigComposer } from "eslint-flat-config-utils";
|
|
3
3
|
//#region src/configs/imports.ts
|
|
4
4
|
async function imports() {
|
|
@@ -37,12 +37,21 @@ async function imports() {
|
|
|
37
37
|
//#region src/configs/javascript.ts
|
|
38
38
|
/**
|
|
39
39
|
* Base JS quality rules from `@eslint/js` recommended.
|
|
40
|
+
* Declares Node + ES2022 globals so `no-undef` does not false-positive on
|
|
41
|
+
* `console`, `process`, and other built-ins.
|
|
40
42
|
*/
|
|
41
43
|
async function javascript() {
|
|
42
|
-
const
|
|
44
|
+
const jsMod = await import("@eslint/js");
|
|
45
|
+
const globalsMod = await import("globals");
|
|
46
|
+
const js = jsMod.default ?? jsMod;
|
|
47
|
+
const globals = globalsMod.default ?? globalsMod;
|
|
43
48
|
return [{
|
|
44
49
|
name: "qstanay/javascript",
|
|
45
|
-
|
|
50
|
+
languageOptions: { globals: {
|
|
51
|
+
...globals.es2022,
|
|
52
|
+
...globals.nodeBuiltin
|
|
53
|
+
} },
|
|
54
|
+
rules: { ...js.configs?.recommended?.rules ?? {} }
|
|
46
55
|
}];
|
|
47
56
|
}
|
|
48
57
|
//#endregion
|
|
@@ -60,21 +69,22 @@ async function nuxt$1() {
|
|
|
60
69
|
function collectRules(configs) {
|
|
61
70
|
return Object.assign({}, ...configs.filter((config) => config.rules).map((config) => config.rules));
|
|
62
71
|
}
|
|
63
|
-
async function typescript() {
|
|
72
|
+
async function typescript(options = {}) {
|
|
64
73
|
const parserMod = await import("@typescript-eslint/parser");
|
|
65
74
|
const pluginMod = await import("@typescript-eslint/eslint-plugin");
|
|
66
75
|
const parser = parserMod.default ?? parserMod;
|
|
67
76
|
const plugin = pluginMod.default ?? pluginMod;
|
|
68
77
|
const recommended = plugin.configs?.["flat/recommended"] ?? [];
|
|
78
|
+
const vueEnabled = options.vue === true;
|
|
69
79
|
return [{
|
|
70
80
|
name: "qstanay/typescript",
|
|
71
|
-
files:
|
|
81
|
+
files: typescriptFiles(vueEnabled),
|
|
72
82
|
languageOptions: {
|
|
73
83
|
parser,
|
|
74
84
|
parserOptions: {
|
|
75
85
|
sourceType: "module",
|
|
76
86
|
ecmaVersion: "latest",
|
|
77
|
-
extraFileExtensions: [".vue"]
|
|
87
|
+
...vueEnabled ? { extraFileExtensions: [".vue"] } : {}
|
|
78
88
|
}
|
|
79
89
|
},
|
|
80
90
|
plugins: { "@typescript-eslint": plugin },
|
|
@@ -117,17 +127,18 @@ function defineConfig(options = {}, ...userConfigs) {
|
|
|
117
127
|
const enableVue = resolveEnabled(options.vue, has("vue") || has("nuxt"));
|
|
118
128
|
const enableNuxt = resolveEnabled(options.nuxt, has("nuxt"));
|
|
119
129
|
const stylisticOptions = resolveStylisticOptions(options.stylistic);
|
|
130
|
+
const files = sourceFiles(enableVue);
|
|
120
131
|
const configs = [];
|
|
121
|
-
configs.push(Promise.resolve(ignores(options.ignores)));
|
|
132
|
+
configs.push(Promise.resolve(ignores([...options.ignores ?? [], ...!enableVue ? VUE_FILES : []])));
|
|
122
133
|
configs.push(javascript());
|
|
123
|
-
if (enableTs) configs.push(typescript());
|
|
134
|
+
if (enableTs) configs.push(typescript({ vue: enableVue }));
|
|
124
135
|
configs.push(imports());
|
|
125
136
|
if (stylisticOptions) configs.push(stylistic(stylisticOptions));
|
|
126
137
|
if (enableVue) configs.push(vue());
|
|
127
138
|
if (enableNuxt) configs.push(nuxt$1());
|
|
128
139
|
configs.push(Promise.resolve([{
|
|
129
140
|
name: "qstanay/shared-rules",
|
|
130
|
-
files
|
|
141
|
+
files,
|
|
131
142
|
rules: sharedRules({
|
|
132
143
|
typescript: enableTs,
|
|
133
144
|
strict: options.strict
|
|
@@ -135,7 +146,7 @@ function defineConfig(options = {}, ...userConfigs) {
|
|
|
135
146
|
}]));
|
|
136
147
|
if (options.overrides) configs.push(Promise.resolve([{
|
|
137
148
|
name: "qstanay/overrides",
|
|
138
|
-
files
|
|
149
|
+
files,
|
|
139
150
|
rules: options.overrides
|
|
140
151
|
}]));
|
|
141
152
|
const composer = new FlatConfigComposer();
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["nuxt","javascriptConfig","typescriptConfig","stylisticConfig","vueConfig","nuxtConfig"],"sources":["../src/configs/imports.ts","../src/configs/javascript.ts","../src/configs/nuxt.ts","../src/configs/typescript.ts","../src/configs/vue.ts","../src/index.ts"],"sourcesContent":["import type { TypedFlatConfigItem } from '../types';\n\nexport async function imports(): Promise<TypedFlatConfigItem[]> {\n const mod = await import('eslint-plugin-import-x');\n const plugin = (mod as any).default ?? mod;\n\n return [\n {\n name: 'qstanay/imports',\n plugins: {\n import: plugin,\n },\n rules: {\n 'import/first': 'error',\n 'import/no-duplicates': 'error',\n 'import/no-mutable-exports': 'error',\n 'import/no-named-default': 'error',\n 'import/order': [\n 'error',\n {\n 'groups': [\n 'builtin',\n 'external',\n 'internal',\n ['parent', 'sibling', 'index'],\n 'object',\n 'type',\n ],\n 'newlines-between': 'always',\n 'alphabetize': {\n order: 'asc',\n caseInsensitive: true,\n },\n },\n ],\n },\n },\n ];\n}\n","import type { TypedFlatConfigItem } from '../types';\n\n/**\n * Base JS quality rules from `@eslint/js` recommended.\n */\nexport async function javascript(): Promise<TypedFlatConfigItem[]> {\n const mod = await import('@eslint/js');\n const js = (mod as any).default ?? mod;\n\n return [\n {\n name: 'qstanay/javascript',\n rules: {\n ...(js.configs?.recommended?.rules ?? {}),\n },\n },\n ];\n}\n","import type { TypedFlatConfigItem } from '../types';\n\nexport async function nuxt(): Promise<TypedFlatConfigItem[]> {\n const mod = await import('@nuxt/eslint-plugin');\n const plugin = (mod as any).default ?? mod;\n\n return [\n {\n name: 'qstanay/nuxt',\n plugins: {\n nuxt: plugin,\n },\n rules: {\n // keep this minimal; Nuxt base config already provides most of it\n 'nuxt/prefer-import-meta': 'error',\n },\n },\n ];\n}\n","import { TYPESCRIPT_FILES } from '../utils';\n\nimport type { TypedFlatConfigItem } from '../types';\nimport type { Linter } from 'eslint';\n\nfunction collectRules(configs: TypedFlatConfigItem[]): Linter.RulesRecord {\n return Object.assign(\n {},\n ...configs\n .filter(config => config.rules)\n .map(config => config.rules),\n );\n}\n\nexport async function typescript(): Promise<TypedFlatConfigItem[]> {\n const parserMod = await import('@typescript-eslint/parser');\n const pluginMod = await import('@typescript-eslint/eslint-plugin');\n\n const parser = (parserMod as any).default ?? parserMod;\n const plugin = (pluginMod as any).default ?? pluginMod;\n\n const recommended = (plugin.configs?.['flat/recommended'] ?? []) as TypedFlatConfigItem[];\n\n return [\n {\n name: 'qstanay/typescript',\n files: [...TYPESCRIPT_FILES],\n languageOptions: {\n parser,\n parserOptions: {\n sourceType: 'module',\n ecmaVersion: 'latest',\n extraFileExtensions: ['.vue'],\n },\n },\n plugins: {\n '@typescript-eslint': plugin,\n },\n rules: collectRules(recommended),\n },\n ];\n}\n","import { VUE_FILES } from '../utils';\nimport { vueRules } from './vue-rules';\n\nimport type { TypedFlatConfigItem } from '../types';\n\n/**\n * Vue layer based on the official flat recommended preset.\n * Must spread the full array — it includes setup, processor, and rule packs.\n */\nexport async function vue(): Promise<TypedFlatConfigItem[]> {\n const vuePluginMod = await import('eslint-plugin-vue');\n const globalsMod = await import('globals');\n\n const vuePlugin = (vuePluginMod as any).default ?? vuePluginMod;\n const globals = (globalsMod as any).default ?? globalsMod;\n\n const recommended = (vuePlugin.configs?.['flat/recommended'] ?? []) as TypedFlatConfigItem[];\n\n return [\n ...recommended,\n {\n name: 'qstanay/vue/rules',\n files: [...VUE_FILES],\n languageOptions: {\n globals: {\n ...globals.browser,\n },\n parserOptions: {\n // Keep vue-eslint-parser as the root parser (from recommended),\n // and parse <script lang=\"ts\"> with the TS parser.\n parser: {\n ts: '@typescript-eslint/parser',\n js: 'espree',\n },\n ecmaVersion: 'latest',\n sourceType: 'module',\n extraFileExtensions: ['.vue'],\n },\n },\n rules: {\n ...vueRules(),\n },\n },\n ];\n}\n","import { FlatConfigComposer } from 'eslint-flat-config-utils';\n\nimport { ignores } from './configs/ignores';\nimport { imports } from './configs/imports';\nimport { javascript as javascriptConfig } from './configs/javascript';\nimport { nuxt as nuxtConfig } from './configs/nuxt';\nimport { sharedRules } from './configs/shared-rules';\nimport { stylistic as stylisticConfig } from './configs/stylistic';\nimport { typescript as typescriptConfig } from './configs/typescript';\nimport { vue as vueConfig } from './configs/vue';\nimport { has, resolveEnabled, resolveStylisticOptions, SOURCE_FILES } from './utils';\n\nimport type { Awaitable, OptionsConfig, TypedFlatConfigItem } from './types';\n\nexport { nuxt } from './nuxt';\nexport * from './types';\n\nexport function defineConfig(\n options: OptionsConfig = {},\n ...userConfigs: (Awaitable<TypedFlatConfigItem | TypedFlatConfigItem[]>)[]\n) {\n const enableTs = resolveEnabled(options.typescript, has('typescript'));\n const enableVue = resolveEnabled(options.vue, has('vue') || has('nuxt'));\n const enableNuxt = resolveEnabled(options.nuxt, has('nuxt'));\n const stylisticOptions = resolveStylisticOptions(options.stylistic);\n\n const configs: (Awaitable<TypedFlatConfigItem[]>)[] = [];\n\n configs.push(Promise.resolve(ignores(options.ignores)));\n configs.push(javascriptConfig());\n\n if (enableTs) {\n configs.push(typescriptConfig());\n }\n\n configs.push(imports());\n\n if (stylisticOptions) {\n configs.push(stylisticConfig(stylisticOptions));\n }\n\n if (enableVue) {\n configs.push(vueConfig());\n }\n\n if (enableNuxt) {\n configs.push(nuxtConfig());\n }\n\n configs.push(Promise.resolve([\n {\n name: 'qstanay/shared-rules',\n files: [...SOURCE_FILES],\n rules: sharedRules({\n typescript: enableTs,\n strict: options.strict,\n }),\n },\n ]));\n\n if (options.overrides) {\n // Trailing block so project overrides win over shared/vue/ts packs.\n configs.push(Promise.resolve([\n {\n name: 'qstanay/overrides',\n files: [...SOURCE_FILES],\n rules: options.overrides,\n },\n ]));\n }\n\n const composer = new FlatConfigComposer<TypedFlatConfigItem>();\n composer.append(...configs, ...userConfigs as any);\n return composer;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["nuxt","javascriptConfig","typescriptConfig","stylisticConfig","vueConfig","nuxtConfig"],"sources":["../src/configs/imports.ts","../src/configs/javascript.ts","../src/configs/nuxt.ts","../src/configs/typescript.ts","../src/configs/vue.ts","../src/index.ts"],"sourcesContent":["import type { TypedFlatConfigItem } from '../types';\n\nexport async function imports(): Promise<TypedFlatConfigItem[]> {\n const mod = await import('eslint-plugin-import-x');\n const plugin = (mod as any).default ?? mod;\n\n return [\n {\n name: 'qstanay/imports',\n plugins: {\n import: plugin,\n },\n rules: {\n 'import/first': 'error',\n 'import/no-duplicates': 'error',\n 'import/no-mutable-exports': 'error',\n 'import/no-named-default': 'error',\n 'import/order': [\n 'error',\n {\n 'groups': [\n 'builtin',\n 'external',\n 'internal',\n ['parent', 'sibling', 'index'],\n 'object',\n 'type',\n ],\n 'newlines-between': 'always',\n 'alphabetize': {\n order: 'asc',\n caseInsensitive: true,\n },\n },\n ],\n },\n },\n ];\n}\n","import type { TypedFlatConfigItem } from '../types';\n\n/**\n * Base JS quality rules from `@eslint/js` recommended.\n * Declares Node + ES2022 globals so `no-undef` does not false-positive on\n * `console`, `process`, and other built-ins.\n */\nexport async function javascript(): Promise<TypedFlatConfigItem[]> {\n const jsMod = await import('@eslint/js');\n const globalsMod = await import('globals');\n\n const js = (jsMod as any).default ?? jsMod;\n const globals = (globalsMod as any).default ?? globalsMod;\n\n return [\n {\n name: 'qstanay/javascript',\n languageOptions: {\n globals: {\n ...globals.es2022,\n ...globals.nodeBuiltin,\n },\n },\n rules: {\n ...(js.configs?.recommended?.rules ?? {}),\n },\n },\n ];\n}\n","import type { TypedFlatConfigItem } from '../types';\n\nexport async function nuxt(): Promise<TypedFlatConfigItem[]> {\n const mod = await import('@nuxt/eslint-plugin');\n const plugin = (mod as any).default ?? mod;\n\n return [\n {\n name: 'qstanay/nuxt',\n plugins: {\n nuxt: plugin,\n },\n rules: {\n // keep this minimal; Nuxt base config already provides most of it\n 'nuxt/prefer-import-meta': 'error',\n },\n },\n ];\n}\n","import { typescriptFiles } from '../utils';\n\nimport type { TypedFlatConfigItem } from '../types';\nimport type { Linter } from 'eslint';\n\nfunction collectRules(configs: TypedFlatConfigItem[]): Linter.RulesRecord {\n return Object.assign(\n {},\n ...configs\n .filter(config => config.rules)\n .map(config => config.rules),\n );\n}\n\nexport async function typescript(options: {\n vue?: boolean;\n} = {}): Promise<TypedFlatConfigItem[]> {\n const parserMod = await import('@typescript-eslint/parser');\n const pluginMod = await import('@typescript-eslint/eslint-plugin');\n\n const parser = (parserMod as any).default ?? parserMod;\n const plugin = (pluginMod as any).default ?? pluginMod;\n\n const recommended = (plugin.configs?.['flat/recommended'] ?? []) as TypedFlatConfigItem[];\n const vueEnabled = options.vue === true;\n\n return [\n {\n name: 'qstanay/typescript',\n files: typescriptFiles(vueEnabled),\n languageOptions: {\n parser,\n parserOptions: {\n sourceType: 'module',\n ecmaVersion: 'latest',\n ...(vueEnabled\n ? { extraFileExtensions: ['.vue'] }\n : {}),\n },\n },\n plugins: {\n '@typescript-eslint': plugin,\n },\n rules: collectRules(recommended),\n },\n ];\n}\n","import { VUE_FILES } from '../utils';\nimport { vueRules } from './vue-rules';\n\nimport type { TypedFlatConfigItem } from '../types';\n\n/**\n * Vue layer based on the official flat recommended preset.\n * Must spread the full array — it includes setup, processor, and rule packs.\n */\nexport async function vue(): Promise<TypedFlatConfigItem[]> {\n const vuePluginMod = await import('eslint-plugin-vue');\n const globalsMod = await import('globals');\n\n const vuePlugin = (vuePluginMod as any).default ?? vuePluginMod;\n const globals = (globalsMod as any).default ?? globalsMod;\n\n const recommended = (vuePlugin.configs?.['flat/recommended'] ?? []) as TypedFlatConfigItem[];\n\n return [\n ...recommended,\n {\n name: 'qstanay/vue/rules',\n files: [...VUE_FILES],\n languageOptions: {\n globals: {\n ...globals.browser,\n },\n parserOptions: {\n // Keep vue-eslint-parser as the root parser (from recommended),\n // and parse <script lang=\"ts\"> with the TS parser.\n parser: {\n ts: '@typescript-eslint/parser',\n js: 'espree',\n },\n ecmaVersion: 'latest',\n sourceType: 'module',\n extraFileExtensions: ['.vue'],\n },\n },\n rules: {\n ...vueRules(),\n },\n },\n ];\n}\n","import { FlatConfigComposer } from 'eslint-flat-config-utils';\n\nimport { ignores } from './configs/ignores';\nimport { imports } from './configs/imports';\nimport { javascript as javascriptConfig } from './configs/javascript';\nimport { nuxt as nuxtConfig } from './configs/nuxt';\nimport { sharedRules } from './configs/shared-rules';\nimport { stylistic as stylisticConfig } from './configs/stylistic';\nimport { typescript as typescriptConfig } from './configs/typescript';\nimport { vue as vueConfig } from './configs/vue';\nimport {\n has,\n resolveEnabled,\n resolveStylisticOptions,\n sourceFiles,\n VUE_FILES,\n} from './utils';\n\nimport type { Awaitable, OptionsConfig, TypedFlatConfigItem } from './types';\n\nexport { nuxt } from './nuxt';\nexport * from './types';\n\nexport function defineConfig(\n options: OptionsConfig = {},\n ...userConfigs: (Awaitable<TypedFlatConfigItem | TypedFlatConfigItem[]>)[]\n) {\n const enableTs = resolveEnabled(options.typescript, has('typescript'));\n const enableVue = resolveEnabled(options.vue, has('vue') || has('nuxt'));\n const enableNuxt = resolveEnabled(options.nuxt, has('nuxt'));\n const stylisticOptions = resolveStylisticOptions(options.stylistic);\n const files = sourceFiles(enableVue);\n\n const configs: (Awaitable<TypedFlatConfigItem[]>)[] = [];\n\n // When Vue is off, skip SFCs entirely so espree/TS do not fatal-parse them.\n configs.push(Promise.resolve(ignores([\n ...(options.ignores ?? []),\n ...(!enableVue ? VUE_FILES : []),\n ])));\n configs.push(javascriptConfig());\n\n if (enableTs) {\n configs.push(typescriptConfig({ vue: enableVue }));\n }\n\n configs.push(imports());\n\n if (stylisticOptions) {\n configs.push(stylisticConfig(stylisticOptions));\n }\n\n if (enableVue) {\n configs.push(vueConfig());\n }\n\n if (enableNuxt) {\n configs.push(nuxtConfig());\n }\n\n configs.push(Promise.resolve([\n {\n name: 'qstanay/shared-rules',\n files,\n rules: sharedRules({\n typescript: enableTs,\n strict: options.strict,\n }),\n },\n ]));\n\n if (options.overrides) {\n // Trailing block so project overrides win over shared/vue/ts packs.\n configs.push(Promise.resolve([\n {\n name: 'qstanay/overrides',\n files,\n rules: options.overrides,\n },\n ]));\n }\n\n const composer = new FlatConfigComposer<TypedFlatConfigItem>();\n composer.append(...configs, ...userConfigs as any);\n return composer;\n}\n"],"mappings":"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"}
|
|
@@ -119,9 +119,22 @@ function resolveStylisticOptions(stylistic) {
|
|
|
119
119
|
if (typeof stylistic === "object") return stylistic;
|
|
120
120
|
return {};
|
|
121
121
|
}
|
|
122
|
-
const
|
|
123
|
-
const TYPESCRIPT_FILES = ["**/*.{ts,tsx,cts,mts}", "**/*.vue"];
|
|
122
|
+
const SCRIPT_FILES = ["**/*.{js,mjs,cjs,jsx,ts,tsx,cts,mts}"];
|
|
124
123
|
const VUE_FILES = ["**/*.vue"];
|
|
124
|
+
/** TypeScript sources (`.vue` is added only when Vue is enabled). */
|
|
125
|
+
const TYPESCRIPT_FILES = ["**/*.{ts,tsx,cts,mts}"];
|
|
126
|
+
/**
|
|
127
|
+
* Files that receive shared / override rule packs.
|
|
128
|
+
* `.vue` is included only when Vue support is enabled.
|
|
129
|
+
*/
|
|
130
|
+
function sourceFiles(vueEnabled) {
|
|
131
|
+
return vueEnabled ? [...SCRIPT_FILES, ...VUE_FILES] : [...SCRIPT_FILES];
|
|
132
|
+
}
|
|
133
|
+
function typescriptFiles(vueEnabled) {
|
|
134
|
+
return vueEnabled ? [...TYPESCRIPT_FILES, ...VUE_FILES] : [...TYPESCRIPT_FILES];
|
|
135
|
+
}
|
|
136
|
+
/** Files that receive shared / override rule packs when Vue is enabled. */
|
|
137
|
+
const SOURCE_FILES = ["**/*.{js,mjs,cjs,jsx,ts,tsx,cts,mts,vue}"];
|
|
125
138
|
//#endregion
|
|
126
139
|
//#region src/configs/vue-rules.ts
|
|
127
140
|
function vueRules() {
|
|
@@ -136,7 +149,11 @@ function vueRules() {
|
|
|
136
149
|
math: "always"
|
|
137
150
|
}],
|
|
138
151
|
"vue/attributes-order": "error",
|
|
139
|
-
"vue/padding-line-between-tags": "error"
|
|
152
|
+
"vue/padding-line-between-tags": ["error", [{
|
|
153
|
+
blankLine: "always",
|
|
154
|
+
prev: "*",
|
|
155
|
+
next: "*"
|
|
156
|
+
}]]
|
|
140
157
|
};
|
|
141
158
|
}
|
|
142
159
|
//#endregion
|
|
@@ -172,6 +189,6 @@ function nuxt(options = {}) {
|
|
|
172
189
|
return configs;
|
|
173
190
|
}
|
|
174
191
|
//#endregion
|
|
175
|
-
export {
|
|
192
|
+
export { resolveEnabled as a, typescriptFiles as c, ignores as d, has as i, stylistic as l, vueRules as n, resolveStylisticOptions as o, VUE_FILES as r, sourceFiles as s, nuxt as t, sharedRules as u };
|
|
176
193
|
|
|
177
|
-
//# sourceMappingURL=nuxt-
|
|
194
|
+
//# sourceMappingURL=nuxt-jcrXAC4G.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nuxt-jcrXAC4G.mjs","names":["stylisticConfig"],"sources":["../src/configs/ignores.ts","../src/configs/shared-rules.ts","../src/configs/stylistic.ts","../src/utils.ts","../src/configs/vue-rules.ts","../src/nuxt.ts"],"sourcesContent":["import gitignore from 'eslint-config-flat-gitignore';\n\nimport type { TypedFlatConfigItem } from '../types';\n\nexport function ignores(extraIgnores: string[] = []): TypedFlatConfigItem[] {\n return [\n // Prefer project .gitignore when present; do not fail if missing.\n gitignore({ strict: false }),\n {\n name: 'qstanay/ignores',\n ignores: [\n '**/node_modules/**',\n '**/dist/**',\n '**/.output/**',\n '**/.nuxt/**',\n '**/.nitro/**',\n '**/coverage/**',\n ...extraIgnores,\n ],\n },\n ];\n}\n","import type { Linter } from 'eslint';\n\nexport function javascriptRules(): Linter.RulesRecord {\n return {\n 'no-console': ['error', { allow: ['warn', 'error'] }],\n 'no-debugger': 'error',\n 'eqeqeq': ['error', 'always'],\n 'object-shorthand': ['error', 'always'],\n 'prefer-template': 'error',\n 'curly': ['error', 'all'],\n 'arrow-body-style': ['error', 'as-needed'],\n };\n}\n\nexport function typescriptRules(options: { strict?: boolean } = {}): Linter.RulesRecord {\n const rules: Linter.RulesRecord = {\n // Disable base rules that conflict with TypeScript-aware variants.\n 'no-unused-vars': 'off',\n 'no-undef': 'off',\n\n '@typescript-eslint/no-unused-vars': [\n 'error',\n {\n argsIgnorePattern: '^_',\n varsIgnorePattern: '^_',\n caughtErrorsIgnorePattern: '^_',\n destructuredArrayIgnorePattern: '^_',\n },\n ],\n '@typescript-eslint/consistent-type-imports': [\n 'error',\n { prefer: 'type-imports', disallowTypeAnnotations: false },\n ],\n '@typescript-eslint/no-explicit-any': 'warn',\n '@typescript-eslint/no-non-null-assertion': 'error',\n '@typescript-eslint/no-empty-function': ['error', { allow: ['arrowFunctions'] }],\n };\n\n if (options.strict) {\n rules['@typescript-eslint/no-magic-numbers'] = [\n 'warn',\n {\n ignore: [-1, 0, 1, 2, 1000],\n ignoreEnums: true,\n ignoreArrayIndexes: true,\n ignoreDefaultValues: true,\n ignoreClassFieldInitialValues: true,\n ignoreReadonlyClassProperties: true,\n },\n ];\n }\n\n return rules;\n}\n\n/**\n * Shared opinionated rules.\n * TypeScript rules are included only when `typescript` is true,\n * so JS-only projects do not reference a missing plugin.\n */\nexport function sharedRules(options: {\n typescript?: boolean;\n strict?: boolean;\n} = {}): Linter.RulesRecord {\n return {\n ...javascriptRules(),\n ...(options.typescript\n ? typescriptRules({ strict: options.strict })\n : {}),\n };\n}\n","import type { TypedFlatConfigItem, StylisticOptions } from '../types';\n\nasync function loadStylistic() {\n const mod = await import('@stylistic/eslint-plugin');\n return mod.default ?? mod;\n}\n\nexport async function stylistic(\n options: StylisticOptions = {},\n): Promise<TypedFlatConfigItem[]> {\n const {\n indent = 2,\n quotes = 'single',\n semi = true,\n maxLen = 100,\n } = options;\n\n const plugin = await loadStylistic();\n\n // `customize()` gives us a coherent bundle of stylistic rules.\n // Plugin name is fixed to `style` for stable rule IDs.\n const config = plugin.configs.customize({\n indent,\n quotes,\n semi,\n jsx: false,\n pluginName: 'style',\n }) as TypedFlatConfigItem;\n\n return [\n {\n name: 'qstanay/stylistic',\n plugins: {\n style: plugin,\n },\n rules: {\n ...(config.rules ?? {}),\n // Keep max line length aligned across all projects.\n 'style/max-len': [\n 'warn',\n {\n code: maxLen,\n ignoreUrls: true,\n ignoreStrings: true,\n ignoreTemplateLiterals: true,\n ignoreComments: true,\n ignoreTrailingComments: true,\n ignoreRegExpLiterals: true,\n },\n ],\n },\n },\n ];\n}\n","import { isPackageExists } from 'local-pkg';\n\nimport type { StylisticOptions } from './types';\n\nexport function resolveEnabled(explicit: boolean | undefined, detected: boolean) {\n return explicit ?? detected;\n}\n\nexport function has(pkg: string) {\n return isPackageExists(pkg);\n}\n\nexport function resolveStylisticOptions(\n stylistic: boolean | StylisticOptions | undefined,\n): false | StylisticOptions {\n if (stylistic === false) {\n return false;\n }\n\n if (typeof stylistic === 'object') {\n return stylistic;\n }\n\n return {};\n}\n\nconst SCRIPT_FILES = [\n '**/*.{js,mjs,cjs,jsx,ts,tsx,cts,mts}',\n] as const;\n\nexport const VUE_FILES = ['**/*.vue'] as const;\n\n/** TypeScript sources (`.vue` is added only when Vue is enabled). */\nexport const TYPESCRIPT_FILES = [\n '**/*.{ts,tsx,cts,mts}',\n] as const;\n\n/**\n * Files that receive shared / override rule packs.\n * `.vue` is included only when Vue support is enabled.\n */\nexport function sourceFiles(vueEnabled: boolean): string[] {\n return vueEnabled\n ? [...SCRIPT_FILES, ...VUE_FILES]\n : [...SCRIPT_FILES];\n}\n\nexport function typescriptFiles(vueEnabled: boolean): string[] {\n return vueEnabled\n ? [...TYPESCRIPT_FILES, ...VUE_FILES]\n : [...TYPESCRIPT_FILES];\n}\n\n/** Files that receive shared / override rule packs when Vue is enabled. */\nexport const SOURCE_FILES = [\n '**/*.{js,mjs,cjs,jsx,ts,tsx,cts,mts,vue}',\n] as const;\n","import type { Linter } from 'eslint';\n\nexport function vueRules(): Linter.RulesRecord {\n return {\n 'vue/html-self-closing': [\n 'error',\n {\n html: {\n void: 'always',\n normal: 'always',\n component: 'always',\n },\n svg: 'always',\n math: 'always',\n },\n ],\n 'vue/attributes-order': 'error',\n 'vue/padding-line-between-tags': [\n 'error',\n [\n {\n blankLine: 'always',\n prev: '*',\n next: '*',\n },\n ],\n ],\n };\n}\n","import { ignores } from './configs/ignores';\nimport { sharedRules } from './configs/shared-rules';\nimport { stylistic as stylisticConfig } from './configs/stylistic';\nimport { vueRules } from './configs/vue-rules';\nimport { resolveStylisticOptions, SOURCE_FILES, VUE_FILES } from './utils';\n\nimport type { StylisticOptions, TypedFlatConfigItem } from './types';\nimport type { Linter } from 'eslint';\n\nexport interface NuxtPresetOptions {\n stylistic?: boolean | StylisticOptions;\n /**\n * Enable stricter opinionated TypeScript rules (e.g. `no-magic-numbers`).\n */\n strict?: boolean;\n overrides?: Linter.RulesRecord;\n /**\n * Extra ignores appended to defaults / `.gitignore`.\n */\n ignores?: string[];\n}\n\n/**\n * Opinionated layer for Nuxt apps.\n *\n * Intended to be used with `@nuxt/eslint` + `withNuxt()`:\n * Nuxt already provides TypeScript/Vue/import plugins, so this preset\n * only adds stylistic formatting and shared opinionated rules.\n */\nexport function nuxt(options: NuxtPresetOptions = {}) {\n const stylisticOptions = resolveStylisticOptions(options.stylistic);\n const configs: Promise<TypedFlatConfigItem[]>[] = [\n Promise.resolve(ignores(options.ignores)),\n ];\n\n if (stylisticOptions) {\n configs.push(stylisticConfig(stylisticOptions));\n }\n\n configs.push(Promise.resolve([\n {\n name: 'qstanay/nuxt/shared-rules',\n files: [...SOURCE_FILES],\n // Host (@nuxt/eslint) registers @typescript-eslint; include TS rules.\n rules: sharedRules({\n typescript: true,\n strict: options.strict,\n }),\n },\n {\n name: 'qstanay/nuxt/vue-rules',\n files: [...VUE_FILES],\n rules: {\n ...vueRules(),\n },\n },\n ]));\n\n if (options.overrides) {\n // Dedicated trailing block so overrides always win over vue/shared rules.\n configs.push(Promise.resolve([\n {\n name: 'qstanay/nuxt/overrides',\n files: [...SOURCE_FILES],\n rules: options.overrides,\n },\n ]));\n }\n\n return configs;\n}\n"],"mappings":"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"}
|
package/dist/nuxt.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as nuxt } from "./nuxt-
|
|
1
|
+
import { t as nuxt } from "./nuxt-jcrXAC4G.mjs";
|
|
2
2
|
export { nuxt };
|
package/package.json
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qstanay/eslint-config",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "Opinionated ESLint flat config for Nuxt, Vue and TypeScript",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
7
|
-
".":
|
|
8
|
-
|
|
7
|
+
".": {
|
|
8
|
+
"types": "./dist/index.d.mts",
|
|
9
|
+
"default": "./dist/index.mjs"
|
|
10
|
+
},
|
|
11
|
+
"./nuxt": {
|
|
12
|
+
"types": "./dist/nuxt.d.mts",
|
|
13
|
+
"default": "./dist/nuxt.mjs"
|
|
14
|
+
},
|
|
9
15
|
"./package.json": "./package.json"
|
|
10
16
|
},
|
|
11
17
|
"types": "./dist/index.d.mts",
|
|
@@ -32,18 +38,22 @@
|
|
|
32
38
|
"typescript",
|
|
33
39
|
"stylistic"
|
|
34
40
|
],
|
|
35
|
-
"author": "",
|
|
41
|
+
"author": "Denis Lapshin",
|
|
36
42
|
"license": "MIT",
|
|
37
43
|
"bugs": {
|
|
38
44
|
"url": "https://github.com/qstanay/eslint-config/issues"
|
|
39
45
|
},
|
|
40
46
|
"homepage": "https://github.com/qstanay/eslint-config#readme",
|
|
47
|
+
"engines": {
|
|
48
|
+
"node": ">=18"
|
|
49
|
+
},
|
|
41
50
|
"files": [
|
|
42
51
|
"dist",
|
|
43
52
|
"CHANGELOG.md"
|
|
44
53
|
],
|
|
45
54
|
"peerDependencies": {
|
|
46
|
-
"eslint": "^9.0.0 || ^10.0.0"
|
|
55
|
+
"eslint": "^9.0.0 || ^10.0.0",
|
|
56
|
+
"typescript": ">=4.9.0"
|
|
47
57
|
},
|
|
48
58
|
"peerDependenciesMeta": {
|
|
49
59
|
"typescript": {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"nuxt-B6cDasrO.mjs","names":["stylisticConfig"],"sources":["../src/configs/ignores.ts","../src/configs/shared-rules.ts","../src/configs/stylistic.ts","../src/utils.ts","../src/configs/vue-rules.ts","../src/nuxt.ts"],"sourcesContent":["import gitignore from 'eslint-config-flat-gitignore';\n\nimport type { TypedFlatConfigItem } from '../types';\n\nexport function ignores(extraIgnores: string[] = []): TypedFlatConfigItem[] {\n return [\n // Prefer project .gitignore when present; do not fail if missing.\n gitignore({ strict: false }),\n {\n name: 'qstanay/ignores',\n ignores: [\n '**/node_modules/**',\n '**/dist/**',\n '**/.output/**',\n '**/.nuxt/**',\n '**/.nitro/**',\n '**/coverage/**',\n ...extraIgnores,\n ],\n },\n ];\n}\n","import type { Linter } from 'eslint';\n\nexport function javascriptRules(): Linter.RulesRecord {\n return {\n 'no-console': ['error', { allow: ['warn', 'error'] }],\n 'no-debugger': 'error',\n 'eqeqeq': ['error', 'always'],\n 'object-shorthand': ['error', 'always'],\n 'prefer-template': 'error',\n 'curly': ['error', 'all'],\n 'arrow-body-style': ['error', 'as-needed'],\n };\n}\n\nexport function typescriptRules(options: { strict?: boolean } = {}): Linter.RulesRecord {\n const rules: Linter.RulesRecord = {\n // Disable base rules that conflict with TypeScript-aware variants.\n 'no-unused-vars': 'off',\n 'no-undef': 'off',\n\n '@typescript-eslint/no-unused-vars': [\n 'error',\n {\n argsIgnorePattern: '^_',\n varsIgnorePattern: '^_',\n caughtErrorsIgnorePattern: '^_',\n destructuredArrayIgnorePattern: '^_',\n },\n ],\n '@typescript-eslint/consistent-type-imports': [\n 'error',\n { prefer: 'type-imports', disallowTypeAnnotations: false },\n ],\n '@typescript-eslint/no-explicit-any': 'warn',\n '@typescript-eslint/no-non-null-assertion': 'error',\n '@typescript-eslint/no-empty-function': ['error', { allow: ['arrowFunctions'] }],\n };\n\n if (options.strict) {\n rules['@typescript-eslint/no-magic-numbers'] = [\n 'warn',\n {\n ignore: [-1, 0, 1, 2, 1000],\n ignoreEnums: true,\n ignoreArrayIndexes: true,\n ignoreDefaultValues: true,\n ignoreClassFieldInitialValues: true,\n ignoreReadonlyClassProperties: true,\n },\n ];\n }\n\n return rules;\n}\n\n/**\n * Shared opinionated rules.\n * TypeScript rules are included only when `typescript` is true,\n * so JS-only projects do not reference a missing plugin.\n */\nexport function sharedRules(options: {\n typescript?: boolean;\n strict?: boolean;\n} = {}): Linter.RulesRecord {\n return {\n ...javascriptRules(),\n ...(options.typescript\n ? typescriptRules({ strict: options.strict })\n : {}),\n };\n}\n","import type { TypedFlatConfigItem, StylisticOptions } from '../types';\n\nasync function loadStylistic() {\n const mod = await import('@stylistic/eslint-plugin');\n return mod.default ?? mod;\n}\n\nexport async function stylistic(\n options: StylisticOptions = {},\n): Promise<TypedFlatConfigItem[]> {\n const {\n indent = 2,\n quotes = 'single',\n semi = true,\n maxLen = 100,\n } = options;\n\n const plugin = await loadStylistic();\n\n // `customize()` gives us a coherent bundle of stylistic rules.\n // Plugin name is fixed to `style` for stable rule IDs.\n const config = plugin.configs.customize({\n indent,\n quotes,\n semi,\n jsx: false,\n pluginName: 'style',\n }) as TypedFlatConfigItem;\n\n return [\n {\n name: 'qstanay/stylistic',\n plugins: {\n style: plugin,\n },\n rules: {\n ...(config.rules ?? {}),\n // Keep max line length aligned across all projects.\n 'style/max-len': [\n 'warn',\n {\n code: maxLen,\n ignoreUrls: true,\n ignoreStrings: true,\n ignoreTemplateLiterals: true,\n ignoreComments: true,\n ignoreTrailingComments: true,\n ignoreRegExpLiterals: true,\n },\n ],\n },\n },\n ];\n}\n","import { isPackageExists } from 'local-pkg';\n\nimport type { StylisticOptions } from './types';\n\nexport function resolveEnabled(explicit: boolean | undefined, detected: boolean) {\n return explicit ?? detected;\n}\n\nexport function has(pkg: string) {\n return isPackageExists(pkg);\n}\n\nexport function resolveStylisticOptions(\n stylistic: boolean | StylisticOptions | undefined,\n): false | StylisticOptions {\n if (stylistic === false) {\n return false;\n }\n\n if (typeof stylistic === 'object') {\n return stylistic;\n }\n\n return {};\n}\n\nexport const SOURCE_FILES = ['**/*.{js,jsx,ts,tsx,cts,mts,vue}'] as const;\nexport const TYPESCRIPT_FILES = ['**/*.{ts,tsx,cts,mts}', '**/*.vue'] as const;\nexport const VUE_FILES = ['**/*.vue'] as const;\n","import type { Linter } from 'eslint';\n\nexport function vueRules(): Linter.RulesRecord {\n return {\n 'vue/html-self-closing': [\n 'error',\n {\n html: {\n void: 'always',\n normal: 'always',\n component: 'always',\n },\n svg: 'always',\n math: 'always',\n },\n ],\n 'vue/attributes-order': 'error',\n 'vue/padding-line-between-tags': 'error',\n };\n}\n","import { ignores } from './configs/ignores';\nimport { sharedRules } from './configs/shared-rules';\nimport { stylistic as stylisticConfig } from './configs/stylistic';\nimport { vueRules } from './configs/vue-rules';\nimport { resolveStylisticOptions, SOURCE_FILES, VUE_FILES } from './utils';\n\nimport type { StylisticOptions, TypedFlatConfigItem } from './types';\nimport type { Linter } from 'eslint';\n\nexport interface NuxtPresetOptions {\n stylistic?: boolean | StylisticOptions;\n /**\n * Enable stricter opinionated TypeScript rules (e.g. `no-magic-numbers`).\n */\n strict?: boolean;\n overrides?: Linter.RulesRecord;\n /**\n * Extra ignores appended to defaults / `.gitignore`.\n */\n ignores?: string[];\n}\n\n/**\n * Opinionated layer for Nuxt apps.\n *\n * Intended to be used with `@nuxt/eslint` + `withNuxt()`:\n * Nuxt already provides TypeScript/Vue/import plugins, so this preset\n * only adds stylistic formatting and shared opinionated rules.\n */\nexport function nuxt(options: NuxtPresetOptions = {}) {\n const stylisticOptions = resolveStylisticOptions(options.stylistic);\n const configs: Promise<TypedFlatConfigItem[]>[] = [\n Promise.resolve(ignores(options.ignores)),\n ];\n\n if (stylisticOptions) {\n configs.push(stylisticConfig(stylisticOptions));\n }\n\n configs.push(Promise.resolve([\n {\n name: 'qstanay/nuxt/shared-rules',\n files: [...SOURCE_FILES],\n // Host (@nuxt/eslint) registers @typescript-eslint; include TS rules.\n rules: sharedRules({\n typescript: true,\n strict: options.strict,\n }),\n },\n {\n name: 'qstanay/nuxt/vue-rules',\n files: [...VUE_FILES],\n rules: {\n ...vueRules(),\n },\n },\n ]));\n\n if (options.overrides) {\n // Dedicated trailing block so overrides always win over vue/shared rules.\n configs.push(Promise.resolve([\n {\n name: 'qstanay/nuxt/overrides',\n files: [...SOURCE_FILES],\n rules: options.overrides,\n },\n ]));\n }\n\n return configs;\n}\n"],"mappings":"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"}
|