@octohash/eslint-config 0.1.3 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -58
- package/dist/index.d.mts +1601 -0
- package/dist/index.mjs +269 -0
- package/package.json +31 -25
- package/dist/index.d.ts +0 -15
- package/dist/index.js +0 -52
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
import antfu, { GLOB_HTML, GLOB_SRC, GLOB_VUE, ensurePackages, interopDefault } from "@antfu/eslint-config";
|
|
2
|
+
import catalogsSort, { configs } from "eslint-plugin-catalogs-sort";
|
|
3
|
+
import { readFile } from "node:fs/promises";
|
|
4
|
+
import { getPackageInfo } from "local-pkg";
|
|
5
|
+
import { basename, dirname, resolve } from "pathe";
|
|
6
|
+
import { glob } from "tinyglobby";
|
|
7
|
+
import process from "node:process";
|
|
8
|
+
import { findUp } from "find-up-simple";
|
|
9
|
+
|
|
10
|
+
//#region src/configs/octohash.ts
|
|
11
|
+
async function octohash() {
|
|
12
|
+
return [{
|
|
13
|
+
name: "octohash/octohash/rules",
|
|
14
|
+
rules: { "pnpm/yaml-enforce-settings": "off" }
|
|
15
|
+
}];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
//#endregion
|
|
19
|
+
//#region src/configs/sort.ts
|
|
20
|
+
async function sortPackageJson() {
|
|
21
|
+
return [
|
|
22
|
+
{
|
|
23
|
+
name: "octohash/sort/setup",
|
|
24
|
+
plugins: { "catalogs-sort": catalogsSort }
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
name: "octohash/sort/package-json",
|
|
28
|
+
files: ["**/package.json"],
|
|
29
|
+
rules: { "jsonc/sort-keys": [
|
|
30
|
+
"error",
|
|
31
|
+
{
|
|
32
|
+
order: [
|
|
33
|
+
"publisher",
|
|
34
|
+
"name",
|
|
35
|
+
"displayName",
|
|
36
|
+
"type",
|
|
37
|
+
"version",
|
|
38
|
+
"private",
|
|
39
|
+
"packageManager",
|
|
40
|
+
"description",
|
|
41
|
+
"author",
|
|
42
|
+
"contributors",
|
|
43
|
+
"license",
|
|
44
|
+
"funding",
|
|
45
|
+
"homepage",
|
|
46
|
+
"repository",
|
|
47
|
+
"bugs",
|
|
48
|
+
"keywords",
|
|
49
|
+
"categories",
|
|
50
|
+
"sideEffects",
|
|
51
|
+
"imports",
|
|
52
|
+
"exports",
|
|
53
|
+
"main",
|
|
54
|
+
"module",
|
|
55
|
+
"unpkg",
|
|
56
|
+
"jsdelivr",
|
|
57
|
+
"types",
|
|
58
|
+
"typesVersions",
|
|
59
|
+
"bin",
|
|
60
|
+
"icon",
|
|
61
|
+
"files",
|
|
62
|
+
"engines",
|
|
63
|
+
"activationEvents",
|
|
64
|
+
"contributes",
|
|
65
|
+
"scripts",
|
|
66
|
+
"peerDependencies",
|
|
67
|
+
"peerDependenciesMeta",
|
|
68
|
+
"dependencies",
|
|
69
|
+
"optionalDependencies",
|
|
70
|
+
"devDependencies",
|
|
71
|
+
"pnpm",
|
|
72
|
+
"overrides",
|
|
73
|
+
"resolutions",
|
|
74
|
+
"husky",
|
|
75
|
+
"simple-git-hooks",
|
|
76
|
+
"lint-staged",
|
|
77
|
+
"eslintConfig"
|
|
78
|
+
],
|
|
79
|
+
pathPattern: "^$"
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
order: { type: "asc" },
|
|
83
|
+
pathPattern: "^workspaces\\.catalog$"
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
order: { type: "asc" },
|
|
87
|
+
pathPattern: "^workspaces\\.catalogs\\.[^.]+$"
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
order: [
|
|
91
|
+
"types",
|
|
92
|
+
"import",
|
|
93
|
+
"require",
|
|
94
|
+
"default"
|
|
95
|
+
],
|
|
96
|
+
pathPattern: "^exports.*$"
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
order: [
|
|
100
|
+
"pre-commit",
|
|
101
|
+
"prepare-commit-msg",
|
|
102
|
+
"commit-msg",
|
|
103
|
+
"post-commit",
|
|
104
|
+
"pre-rebase",
|
|
105
|
+
"post-rewrite",
|
|
106
|
+
"post-checkout",
|
|
107
|
+
"post-merge",
|
|
108
|
+
"pre-push",
|
|
109
|
+
"pre-auto-gc"
|
|
110
|
+
],
|
|
111
|
+
pathPattern: "^(?:gitHooks|husky|simple-git-hooks)$"
|
|
112
|
+
}
|
|
113
|
+
] }
|
|
114
|
+
},
|
|
115
|
+
...configs.recommended
|
|
116
|
+
];
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
//#endregion
|
|
120
|
+
//#region src/constants.ts
|
|
121
|
+
const DEFAULT_IGNORE_PATHS = [
|
|
122
|
+
"**/.git/**",
|
|
123
|
+
"**/.next/**",
|
|
124
|
+
"**/.nuxt/**",
|
|
125
|
+
"**/.output/**",
|
|
126
|
+
"**/.vercel/**",
|
|
127
|
+
"**/.vscode/**",
|
|
128
|
+
"**/.idea/**",
|
|
129
|
+
"**/coverage/**",
|
|
130
|
+
"**/dist/**",
|
|
131
|
+
"**/build/**",
|
|
132
|
+
"**/node_modules/**",
|
|
133
|
+
"**/dist/**",
|
|
134
|
+
"**/public/**",
|
|
135
|
+
"**/fixture/**",
|
|
136
|
+
"**/fixtures/**"
|
|
137
|
+
];
|
|
138
|
+
const REPOSITORY_ROOT_FILES = [
|
|
139
|
+
".git",
|
|
140
|
+
"package-lock.json",
|
|
141
|
+
"npm-shrinkwrap.json",
|
|
142
|
+
"pnpm-lock.yaml",
|
|
143
|
+
"pnpm-workspace.yaml",
|
|
144
|
+
"yarn.lock",
|
|
145
|
+
"bun.lock",
|
|
146
|
+
"bun.lockb",
|
|
147
|
+
"deno.lock"
|
|
148
|
+
];
|
|
149
|
+
const TAILWIND_V3_CONFIG_PATTERNS = [
|
|
150
|
+
"**/tailwind.config.ts",
|
|
151
|
+
"**/tailwind.config.mjs",
|
|
152
|
+
"**/tailwind.config.cjs",
|
|
153
|
+
"**/tailwind.config.js"
|
|
154
|
+
];
|
|
155
|
+
const TAILWIND_V4_IMPORT_RE = /@import\s+['"]tailwindcss(?:\/[^'"]*)?['"]/;
|
|
156
|
+
|
|
157
|
+
//#endregion
|
|
158
|
+
//#region src/utils.ts
|
|
159
|
+
async function findRepositoryRoot() {
|
|
160
|
+
for (const file of REPOSITORY_ROOT_FILES) {
|
|
161
|
+
const filepath = await findUp(file, file === ".git" ? { type: "directory" } : void 0);
|
|
162
|
+
if (filepath) return dirname(filepath);
|
|
163
|
+
}
|
|
164
|
+
return process.cwd();
|
|
165
|
+
}
|
|
166
|
+
function pathDepth(filepath) {
|
|
167
|
+
return filepath.split("/").length;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
//#endregion
|
|
171
|
+
//#region src/configs/tailwindcss.ts
|
|
172
|
+
async function tailwindcss(options = {}) {
|
|
173
|
+
const pkg = await getPackageInfo("tailwindcss");
|
|
174
|
+
if (!pkg || !pkg.version) return [];
|
|
175
|
+
await ensurePackages(["eslint-plugin-better-tailwindcss"]);
|
|
176
|
+
const version = pkg.version;
|
|
177
|
+
const { files = [
|
|
178
|
+
GLOB_HTML,
|
|
179
|
+
GLOB_SRC,
|
|
180
|
+
GLOB_VUE
|
|
181
|
+
], overrides = {}, settings = {} } = options;
|
|
182
|
+
const resolvedSettings = await resolveTailwindSettings(settings, version);
|
|
183
|
+
return [{
|
|
184
|
+
name: "octohash/tailwindcss/setup",
|
|
185
|
+
plugins: { tailwindcss: await interopDefault(import("eslint-plugin-better-tailwindcss")) }
|
|
186
|
+
}, {
|
|
187
|
+
files,
|
|
188
|
+
name: "octohash/tailwindcss/rules",
|
|
189
|
+
rules: {
|
|
190
|
+
"tailwindcss/enforce-consistent-line-wrapping": "error",
|
|
191
|
+
"tailwindcss/enforce-consistent-class-order": "error",
|
|
192
|
+
"tailwindcss/enforce-consistent-variable-syntax": "error",
|
|
193
|
+
"tailwindcss/enforce-consistent-important-position": "error",
|
|
194
|
+
"tailwindcss/enforce-shorthand-classes": "error",
|
|
195
|
+
"tailwindcss/enforce-canonical-classes": "error",
|
|
196
|
+
"tailwindcss/no-duplicate-classes": "error",
|
|
197
|
+
"tailwindcss/no-deprecated-classes": "error",
|
|
198
|
+
"tailwindcss/no-unnecessary-whitespace": "error",
|
|
199
|
+
"tailwindcss/no-conflicting-classes": "error",
|
|
200
|
+
...overrides
|
|
201
|
+
},
|
|
202
|
+
settings: { "better-tailwindcss": resolvedSettings }
|
|
203
|
+
}];
|
|
204
|
+
}
|
|
205
|
+
async function resolveTailwindSettings(settings, version) {
|
|
206
|
+
const resolvedSettings = { ...settings ?? {} };
|
|
207
|
+
const major = Number.parseInt(version, 10);
|
|
208
|
+
const cwd = await findRepositoryRoot();
|
|
209
|
+
if (major === 4 && !resolvedSettings.entryPoint) resolvedSettings.entryPoint = await findTailwindV4ImportCSS(cwd) ?? void 0;
|
|
210
|
+
if (major === 3 && !resolvedSettings.tailwindConfig) resolvedSettings.tailwindConfig = await findTailwindV3Config(cwd) ?? void 0;
|
|
211
|
+
return resolvedSettings;
|
|
212
|
+
}
|
|
213
|
+
async function findTailwindV3Config(cwd) {
|
|
214
|
+
const files = await glob(TAILWIND_V3_CONFIG_PATTERNS, {
|
|
215
|
+
cwd,
|
|
216
|
+
ignore: DEFAULT_IGNORE_PATHS,
|
|
217
|
+
onlyFiles: true
|
|
218
|
+
});
|
|
219
|
+
if (files.length === 0) return void 0;
|
|
220
|
+
const extensionPriority = new Map(TAILWIND_V3_CONFIG_PATTERNS.map((pattern, index) => [basename(pattern), index]));
|
|
221
|
+
files.sort((a, b) => {
|
|
222
|
+
const depthDiff = pathDepth(a) - pathDepth(b);
|
|
223
|
+
if (depthDiff !== 0) return depthDiff;
|
|
224
|
+
return (extensionPriority.get(basename(a)) ?? Number.POSITIVE_INFINITY) - (extensionPriority.get(basename(b)) ?? Number.POSITIVE_INFINITY);
|
|
225
|
+
});
|
|
226
|
+
return resolve(cwd, files[0]);
|
|
227
|
+
}
|
|
228
|
+
async function findTailwindV4ImportCSS(cwd) {
|
|
229
|
+
const files = await glob("**/*.css", {
|
|
230
|
+
cwd,
|
|
231
|
+
ignore: DEFAULT_IGNORE_PATHS,
|
|
232
|
+
onlyFiles: true
|
|
233
|
+
});
|
|
234
|
+
files.sort((a, b) => pathDepth(a) - pathDepth(b));
|
|
235
|
+
for (const file of files) {
|
|
236
|
+
const fullPath = resolve(cwd, file);
|
|
237
|
+
if (await hasTailwindV4Import(fullPath)) return fullPath;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
async function hasTailwindV4Import(filePath) {
|
|
241
|
+
try {
|
|
242
|
+
const content = await readFile(filePath, "utf-8");
|
|
243
|
+
return TAILWIND_V4_IMPORT_RE.test(content);
|
|
244
|
+
} catch {
|
|
245
|
+
return false;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
//#endregion
|
|
250
|
+
//#region src/index.ts
|
|
251
|
+
function defineConfig(options, ...userConfigs) {
|
|
252
|
+
const { formatters } = options || {};
|
|
253
|
+
const config = antfu(mergeOptions(options), ...userConfigs);
|
|
254
|
+
if (formatters === false) return config;
|
|
255
|
+
const enableTailwindCSS = typeof options?.formatters === "boolean" || options?.formatters?.tailwindcss;
|
|
256
|
+
if (enableTailwindCSS) config.append(tailwindcss(typeof enableTailwindCSS === "boolean" ? {} : enableTailwindCSS)).renamePlugins({ "better-tailwindcss": "tailwindcss" });
|
|
257
|
+
config.append(sortPackageJson());
|
|
258
|
+
config.append(octohash());
|
|
259
|
+
return config;
|
|
260
|
+
}
|
|
261
|
+
function mergeOptions(options) {
|
|
262
|
+
return {
|
|
263
|
+
...options,
|
|
264
|
+
formatters: { ...typeof options?.formatters === "object" ? options.formatters : {} }
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
//#endregion
|
|
269
|
+
export { defineConfig };
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@octohash/eslint-config",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.1
|
|
5
|
-
"description": "ESLint
|
|
4
|
+
"version": "0.2.1",
|
|
5
|
+
"description": "Personal ESLint config based on @antfu/eslint-config with opinionated extensions.",
|
|
6
6
|
"author": "jinghaihan",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"homepage": "https://github.com/jinghaihan/eslint-config#readme",
|
|
@@ -19,11 +19,9 @@
|
|
|
19
19
|
"linter"
|
|
20
20
|
],
|
|
21
21
|
"exports": {
|
|
22
|
-
".": "./dist/index.
|
|
22
|
+
".": "./dist/index.mjs",
|
|
23
23
|
"./package.json": "./package.json"
|
|
24
24
|
},
|
|
25
|
-
"main": "./dist/index.js",
|
|
26
|
-
"module": "./dist/index.js",
|
|
27
25
|
"types": "./dist/index.d.ts",
|
|
28
26
|
"publishConfig": {
|
|
29
27
|
"access": "public"
|
|
@@ -31,28 +29,37 @@
|
|
|
31
29
|
"files": [
|
|
32
30
|
"dist"
|
|
33
31
|
],
|
|
32
|
+
"peerDependencies": {
|
|
33
|
+
"eslint-plugin-better-tailwindcss": ">=4.2.0"
|
|
34
|
+
},
|
|
35
|
+
"peerDependenciesMeta": {
|
|
36
|
+
"eslint-plugin-better-tailwindcss": {
|
|
37
|
+
"optional": true
|
|
38
|
+
}
|
|
39
|
+
},
|
|
34
40
|
"dependencies": {
|
|
35
|
-
"@antfu/eslint-config": "^
|
|
36
|
-
"eslint-plugin-
|
|
37
|
-
"
|
|
41
|
+
"@antfu/eslint-config": "^7.4.3",
|
|
42
|
+
"eslint-plugin-catalogs-sort": "^0.0.0-alpha.0",
|
|
43
|
+
"find-up-simple": "^1.0.1",
|
|
38
44
|
"local-pkg": "^1.1.2",
|
|
39
|
-
"pathe": "^2.0.3"
|
|
45
|
+
"pathe": "^2.0.3",
|
|
46
|
+
"tinyglobby": "^0.2.15"
|
|
40
47
|
},
|
|
41
48
|
"devDependencies": {
|
|
49
|
+
"tsdown": "^0.20.3",
|
|
42
50
|
"@octohash/tsconfig": "^0.2.0",
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
"bumpp": "^10.2.3",
|
|
46
|
-
"eslint": "^9.34.0",
|
|
47
|
-
"eslint-flat-config-utils": "^2.1.1",
|
|
48
|
-
"lint-staged": "^16.1.5",
|
|
49
|
-
"pncat": "^0.5.0",
|
|
51
|
+
"bumpp": "^10.4.1",
|
|
52
|
+
"pncat": "^0.10.2",
|
|
50
53
|
"simple-git-hooks": "^2.13.1",
|
|
51
|
-
"taze": "^19.
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
"
|
|
54
|
+
"taze": "^19.9.2",
|
|
55
|
+
"typescript": "^5.9.3",
|
|
56
|
+
"eslint": "^10.0.0",
|
|
57
|
+
"eslint-flat-config-utils": "^3.0.1",
|
|
58
|
+
"eslint-plugin-better-tailwindcss": "^4.2.0",
|
|
59
|
+
"lint-staged": "^16.2.7",
|
|
60
|
+
"vitest": "^4.0.18",
|
|
61
|
+
"@types/node": "^24.10.13",
|
|
62
|
+
"@octohash/eslint-config": "0.2.1"
|
|
56
63
|
},
|
|
57
64
|
"simple-git-hooks": {
|
|
58
65
|
"pre-commit": "pnpm lint-staged"
|
|
@@ -61,14 +68,13 @@
|
|
|
61
68
|
"*": "eslint --fix"
|
|
62
69
|
},
|
|
63
70
|
"scripts": {
|
|
64
|
-
"build": "tsdown
|
|
71
|
+
"build": "tsdown",
|
|
65
72
|
"typecheck": "tsc",
|
|
66
73
|
"test": "vitest",
|
|
67
74
|
"lint": "eslint",
|
|
68
75
|
"deps": "taze major -I",
|
|
69
|
-
"release": "bumpp
|
|
76
|
+
"release": "bumpp",
|
|
70
77
|
"catalog": "pncat",
|
|
71
|
-
"bootstrap": "pnpm install"
|
|
72
|
-
"preinstall": "npx only-allow pnpm"
|
|
78
|
+
"bootstrap": "pnpm install"
|
|
73
79
|
}
|
|
74
80
|
}
|
package/dist/index.d.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import * as _antfu_eslint_config0 from "@antfu/eslint-config";
|
|
2
|
-
import { Awaitable, OptionsConfig, TypedFlatConfigItem } from "@antfu/eslint-config";
|
|
3
|
-
import * as eslint_flat_config_utils0 from "eslint-flat-config-utils";
|
|
4
|
-
import { FlatConfigComposer } from "eslint-flat-config-utils";
|
|
5
|
-
import { Linter } from "eslint";
|
|
6
|
-
|
|
7
|
-
//#region src/types.d.ts
|
|
8
|
-
type Options = AntfuOptions & {};
|
|
9
|
-
type AntfuOptions = OptionsConfig & Omit<TypedFlatConfigItem, 'files'>;
|
|
10
|
-
type UserConfig = Awaitable<TypedFlatConfigItem | TypedFlatConfigItem[] | FlatConfigComposer<any, any> | Linter.Config[]>[];
|
|
11
|
-
//#endregion
|
|
12
|
-
//#region src/index.d.ts
|
|
13
|
-
declare function defineConfig(options?: Options, ...userConfigs: UserConfig): eslint_flat_config_utils0.FlatConfigComposer<_antfu_eslint_config0.TypedFlatConfigItem, _antfu_eslint_config0.ConfigNames>;
|
|
14
|
-
//#endregion
|
|
15
|
-
export { defineConfig };
|
package/dist/index.js
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import antfu from "@antfu/eslint-config";
|
|
2
|
-
import { readFileSync, readdirSync } from "node:fs";
|
|
3
|
-
import process from "node:process";
|
|
4
|
-
import tailwindPlugin from "eslint-plugin-tailwindcss";
|
|
5
|
-
import { isPackageExists } from "local-pkg";
|
|
6
|
-
import { join } from "pathe";
|
|
7
|
-
|
|
8
|
-
//#region src/tailwindcss.ts
|
|
9
|
-
function tailwindCSS(dir) {
|
|
10
|
-
const installed = isPackageExists("tailwindcss");
|
|
11
|
-
if (!installed) return [];
|
|
12
|
-
const config = findTailwindImportCSS(dir ?? process.cwd());
|
|
13
|
-
if (!config) return [];
|
|
14
|
-
return {
|
|
15
|
-
...tailwindPlugin.configs["flat/recommended"],
|
|
16
|
-
settings: { tailwindcss: { config } }
|
|
17
|
-
};
|
|
18
|
-
}
|
|
19
|
-
function findTailwindImportCSS(dir) {
|
|
20
|
-
const entries = readdirSync(dir, { withFileTypes: true });
|
|
21
|
-
for (const entry of entries) {
|
|
22
|
-
const fullPath = join(dir, entry.name);
|
|
23
|
-
if (entry.isDirectory()) {
|
|
24
|
-
const found = findTailwindImportCSS(fullPath);
|
|
25
|
-
if (found) return found;
|
|
26
|
-
} else if (entry.isFile() && entry.name.endsWith(".css")) {
|
|
27
|
-
const lines = readFileSync(fullPath, "utf8").split(/\r?\n/);
|
|
28
|
-
for (const line of lines) if (line.trim().startsWith("@import \"tailwindcss")) return fullPath;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
return null;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
//#endregion
|
|
35
|
-
//#region src/index.ts
|
|
36
|
-
function defineConfig(options, ...userConfigs) {
|
|
37
|
-
return antfu(mergeOptions(options), tailwindCSS(), ...userConfigs);
|
|
38
|
-
}
|
|
39
|
-
function mergeOptions(options) {
|
|
40
|
-
return {
|
|
41
|
-
...options,
|
|
42
|
-
stylistic: true,
|
|
43
|
-
formatters: {
|
|
44
|
-
css: true,
|
|
45
|
-
html: true,
|
|
46
|
-
...typeof options?.formatters === "object" ? options.formatters : {}
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
//#endregion
|
|
52
|
-
export { defineConfig };
|