@quentinhsu/biome-config 0.3.2 → 0.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/dist/build.mjs +388 -0
  2. package/dist/index.jsonc +153 -0
  3. package/dist/index.mjs +358 -0
  4. package/dist/next.jsonc +170 -0
  5. package/dist/nuxt.jsonc +225 -0
  6. package/dist/react.jsonc +168 -0
  7. package/dist/types/scripts/build-presets.d.ts +1 -0
  8. package/dist/types/scripts/generate-biome-types.d.ts +1 -0
  9. package/dist/types/scripts/utils/biome-version.d.ts +12 -0
  10. package/dist/types/src/build.d.ts +1 -0
  11. package/dist/types/src/constants/biome.d.ts +1 -0
  12. package/dist/types/src/generated/biome/index.d.ts +12 -0
  13. package/dist/types/src/generated/biome/linter-configuration.d.ts +181 -0
  14. package/dist/types/src/generated/biome/no-global-object-calls-options.d.ts +321 -0
  15. package/dist/types/src/generated/biome/no-label-var-options.d.ts +1076 -0
  16. package/dist/types/src/generated/biome/no-magic-numbers-options.d.ts +291 -0
  17. package/dist/types/src/generated/biome/rule-with-no-confusing-labels-options.d.ts +1236 -0
  18. package/dist/types/src/generated/biome/rule-with-no-excessive-nested-test-suites-options.d.ts +1440 -0
  19. package/dist/types/src/generated/biome/rule-with-no-unused-expressions-options.d.ts +1337 -0
  20. package/dist/types/src/generated/biome/schema.d.ts +291 -0
  21. package/dist/types/src/generated/biome/use-consistent-object-definitions-configuration.d.ts +1304 -0
  22. package/dist/types/src/generated/biome/use-focusable-interactive-configuration.d.ts +163 -0
  23. package/dist/types/src/generated/biome/use-qwik-classlist-configuration.d.ts +241 -0
  24. package/dist/types/src/generated/biome/use-shorthand-assign-configuration.d.ts +571 -0
  25. package/dist/types/src/index.d.ts +15 -0
  26. package/dist/types/src/presets/next.d.ts +1 -0
  27. package/dist/types/src/presets/nuxt.d.ts +1 -0
  28. package/dist/types/src/presets/react.d.ts +1 -0
  29. package/dist/types/src/presets/vue.d.ts +1 -0
  30. package/dist/types/src/source/index.d.ts +2 -0
  31. package/dist/types/src/types.d.ts +1 -0
  32. package/dist/types/src/utils/merge.d.ts +2 -0
  33. package/dist/vue.jsonc +177 -0
  34. package/package.json +29 -28
package/dist/build.mjs ADDED
@@ -0,0 +1,388 @@
1
+ import { mkdir, writeFile } from "node:fs/promises";
2
+ import { dirname, join } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ const isPlainObject = (value)=>null !== value && 'object' == typeof value && !Array.isArray(value);
5
+ const mergeArrays = (a, b)=>{
6
+ const result = [
7
+ ...a
8
+ ];
9
+ for (const item of b)if (!result.some((existing)=>deepEqual(existing, item))) result.push(item);
10
+ return result;
11
+ };
12
+ const deepEqual = (a, b)=>{
13
+ if (a === b) return true;
14
+ if (Array.isArray(a) && Array.isArray(b)) return a.length === b.length && a.every((item, index)=>deepEqual(item, b[index]));
15
+ if (isPlainObject(a) && isPlainObject(b)) {
16
+ const keysA = Object.keys(a);
17
+ const keysB = Object.keys(b);
18
+ return keysA.length === keysB.length && keysA.every((key)=>deepEqual(a[key], b[key]));
19
+ }
20
+ return false;
21
+ };
22
+ const deepMerge = (target, source)=>{
23
+ for (const [key, value] of Object.entries(source)){
24
+ const current = target[key];
25
+ if (Array.isArray(value)) {
26
+ if (Array.isArray(current)) target[key] = mergeArrays(current, value);
27
+ else target[key] = [
28
+ ...value
29
+ ];
30
+ continue;
31
+ }
32
+ if (isPlainObject(value)) {
33
+ const nextTarget = isPlainObject(current) ? {
34
+ ...current
35
+ } : {};
36
+ target[key] = deepMerge(nextTarget, value);
37
+ continue;
38
+ }
39
+ target[key] = value;
40
+ }
41
+ return target;
42
+ };
43
+ const mergeConfigs = (...configs)=>{
44
+ const merged = configs.reduce((accumulator, config)=>deepMerge(accumulator, config), {});
45
+ return merged;
46
+ };
47
+ const BIOME_SCHEMA_URL = 'https://biomejs.dev/schemas/2.3.5/schema.json';
48
+ const indexConfig = {
49
+ $schema: BIOME_SCHEMA_URL,
50
+ assist: {
51
+ actions: {
52
+ source: {
53
+ organizeImports: {
54
+ level: 'on',
55
+ options: {
56
+ groups: [
57
+ [
58
+ ':NODE:',
59
+ ':BUN:',
60
+ ':PACKAGE_WITH_PROTOCOL:',
61
+ ':PACKAGE:'
62
+ ],
63
+ ':BLANK_LINE:',
64
+ ':ALIAS:',
65
+ ':BLANK_LINE:',
66
+ ':PATH:'
67
+ ]
68
+ }
69
+ },
70
+ useSortedAttributes: {
71
+ level: 'on',
72
+ options: {
73
+ sortOrder: 'natural'
74
+ }
75
+ },
76
+ useSortedKeys: 'on'
77
+ }
78
+ }
79
+ },
80
+ files: {
81
+ ignoreUnknown: true,
82
+ includes: [
83
+ '**',
84
+ '!**/build',
85
+ '!**/dist',
86
+ '!**/.next'
87
+ ]
88
+ },
89
+ formatter: {
90
+ enabled: true,
91
+ formatWithErrors: true,
92
+ indentStyle: 'space',
93
+ lineWidth: 140
94
+ },
95
+ javascript: {
96
+ formatter: {
97
+ arrowParentheses: 'asNeeded',
98
+ jsxQuoteStyle: 'single',
99
+ quoteStyle: 'single',
100
+ trailingCommas: 'all'
101
+ }
102
+ },
103
+ linter: {
104
+ enabled: true,
105
+ rules: {
106
+ complexity: {
107
+ noUselessStringConcat: 'error',
108
+ noUselessUndefinedInitialization: 'error',
109
+ noVoid: 'error',
110
+ useDateNow: 'error'
111
+ },
112
+ correctness: {
113
+ noConstantMathMinMaxClamp: 'error',
114
+ noUndeclaredVariables: 'error',
115
+ noUnusedFunctionParameters: 'error',
116
+ noUnusedImports: 'error',
117
+ noUnusedPrivateClassMembers: 'error',
118
+ noUnusedVariables: 'error',
119
+ useExhaustiveDependencies: {
120
+ level: 'error',
121
+ options: {
122
+ reportUnnecessaryDependencies: false
123
+ }
124
+ }
125
+ },
126
+ nursery: {
127
+ useSortedClasses: {
128
+ fix: 'safe',
129
+ level: 'error',
130
+ options: {
131
+ functions: [
132
+ 'clsx',
133
+ 'cn'
134
+ ]
135
+ }
136
+ }
137
+ },
138
+ recommended: true,
139
+ style: {
140
+ noParameterProperties: 'error',
141
+ noYodaExpression: 'error',
142
+ useArrayLiterals: 'error',
143
+ useConsistentBuiltinInstantiation: 'error',
144
+ useFragmentSyntax: 'error',
145
+ useImportType: {
146
+ fix: 'safe',
147
+ level: 'error',
148
+ options: {
149
+ style: 'separatedType'
150
+ }
151
+ },
152
+ useSelfClosingElements: {
153
+ fix: 'safe',
154
+ level: 'error',
155
+ options: {}
156
+ },
157
+ useShorthandAssign: 'error'
158
+ },
159
+ suspicious: {
160
+ noEvolvingTypes: 'error',
161
+ useAwait: 'error'
162
+ }
163
+ }
164
+ },
165
+ overrides: [
166
+ {
167
+ includes: [
168
+ '**/*.jsx',
169
+ '**/*.tsx'
170
+ ],
171
+ linter: {
172
+ rules: {
173
+ style: {
174
+ noParameterAssign: 'error'
175
+ }
176
+ }
177
+ }
178
+ },
179
+ {
180
+ includes: [
181
+ '**/*.ts',
182
+ '**/*.tsx'
183
+ ],
184
+ linter: {
185
+ rules: {
186
+ correctness: {
187
+ noUnusedVariables: 'off'
188
+ }
189
+ }
190
+ }
191
+ }
192
+ ],
193
+ root: true,
194
+ vcs: {
195
+ clientKind: 'git',
196
+ defaultBranch: 'main',
197
+ enabled: true,
198
+ useIgnoreFile: true
199
+ }
200
+ };
201
+ const reactOverlay = {
202
+ files: {
203
+ includes: [
204
+ '!**/.storybook'
205
+ ]
206
+ },
207
+ javascript: {
208
+ jsxRuntime: 'reactClassic'
209
+ },
210
+ linter: {
211
+ rules: {
212
+ style: {
213
+ useFragmentSyntax: 'error'
214
+ }
215
+ }
216
+ },
217
+ overrides: [
218
+ {
219
+ includes: [
220
+ '**/__tests__/**',
221
+ '**/*.{test,spec}.{ts,tsx,js,jsx}'
222
+ ],
223
+ linter: {
224
+ rules: {
225
+ correctness: {
226
+ noUnusedVariables: 'off'
227
+ }
228
+ }
229
+ }
230
+ }
231
+ ]
232
+ };
233
+ const reactConfig = mergeConfigs(indexConfig, reactOverlay);
234
+ const nextOverlay = {
235
+ files: {
236
+ includes: [
237
+ '!**/.next',
238
+ '!**/.vercel',
239
+ '!**/out'
240
+ ]
241
+ },
242
+ javascript: {
243
+ jsxRuntime: 'transparent'
244
+ },
245
+ linter: {
246
+ rules: {
247
+ correctness: {
248
+ useExhaustiveDependencies: {
249
+ level: 'error',
250
+ options: {
251
+ reportUnnecessaryDependencies: true
252
+ }
253
+ }
254
+ }
255
+ }
256
+ }
257
+ };
258
+ const nextConfig = mergeConfigs(reactConfig, nextOverlay);
259
+ const vueOverlay = {
260
+ files: {
261
+ includes: [
262
+ '!**/.vitepress',
263
+ '!**/.output'
264
+ ]
265
+ },
266
+ javascript: {
267
+ parser: {
268
+ jsxEverywhere: false
269
+ }
270
+ },
271
+ html: {
272
+ formatter: {
273
+ indentScriptAndStyle: true,
274
+ selfCloseVoidElements: 'always'
275
+ }
276
+ },
277
+ overrides: [
278
+ {
279
+ includes: [
280
+ '**/*.vue'
281
+ ],
282
+ formatter: {
283
+ lineWidth: 120
284
+ },
285
+ javascript: {
286
+ formatter: {
287
+ quoteStyle: 'single'
288
+ }
289
+ }
290
+ }
291
+ ]
292
+ };
293
+ const vueConfig = mergeConfigs(indexConfig, vueOverlay);
294
+ const nuxtOverlay = {
295
+ files: {
296
+ includes: [
297
+ '!**/.nuxt',
298
+ '!**/.nitro',
299
+ '!**/.output'
300
+ ]
301
+ },
302
+ javascript: {
303
+ globals: [
304
+ 'defineNuxtConfig',
305
+ 'defineAppConfig',
306
+ 'defineNuxtPlugin',
307
+ 'defineNuxtRouteMiddleware',
308
+ 'defineNuxtServerPlugin',
309
+ 'defineNitroPlugin',
310
+ 'defineEventHandler',
311
+ 'defineLazyEventHandler',
312
+ 'definePayloadPlugin',
313
+ 'defineRouteRules',
314
+ 'definePageMeta',
315
+ 'useRuntimeConfig',
316
+ 'useNuxtApp',
317
+ 'useAsyncData',
318
+ 'useLazyAsyncData',
319
+ 'useFetch',
320
+ 'useLazyFetch',
321
+ 'useState',
322
+ 'useCookie',
323
+ 'useHead',
324
+ 'useSeoMeta',
325
+ 'useError',
326
+ 'clearError',
327
+ 'showError',
328
+ 'navigateTo',
329
+ 'abortNavigation',
330
+ 'refreshNuxtData',
331
+ 'onNuxtReady',
332
+ 'useRouter',
333
+ 'useRoute',
334
+ 'useRequestEvent',
335
+ 'useRequestHeaders'
336
+ ]
337
+ },
338
+ overrides: [
339
+ {
340
+ includes: [
341
+ '**/*.ts'
342
+ ],
343
+ linter: {
344
+ rules: {
345
+ correctness: {
346
+ noUndeclaredVariables: 'error'
347
+ }
348
+ }
349
+ }
350
+ }
351
+ ]
352
+ };
353
+ const nuxtConfig = mergeConfigs(vueConfig, nuxtOverlay);
354
+ const allPresets = Object.freeze({
355
+ index: indexConfig,
356
+ next: nextConfig,
357
+ nuxt: nuxtConfig,
358
+ react: reactConfig,
359
+ vue: vueConfig
360
+ });
361
+ const currentDir = dirname(fileURLToPath(import.meta.url));
362
+ const outputDir = currentDir;
363
+ const serialize = (config)=>`${JSON.stringify(config, null, 2)}\n`;
364
+ async function ensureDir(path) {
365
+ await mkdir(path, {
366
+ recursive: true
367
+ });
368
+ }
369
+ async function buildJsonPresets() {
370
+ await ensureDir(outputDir);
371
+ const tasks = Object.entries(allPresets).map(async ([name, config])=>{
372
+ const filePath = join(outputDir, `${name}.jsonc`);
373
+ const data = serialize(config);
374
+ await writeFile(filePath, data, 'utf8');
375
+ return filePath;
376
+ });
377
+ const writtenFiles = await Promise.all(tasks);
378
+ return writtenFiles;
379
+ }
380
+ (async ()=>{
381
+ try {
382
+ const files = await buildJsonPresets();
383
+ console.log(`Generated presets: ${files.join(', ')}`);
384
+ } catch (error) {
385
+ console.error('Failed to generate Biome presets', error);
386
+ process.exitCode = 1;
387
+ }
388
+ })();
@@ -0,0 +1,153 @@
1
+ {
2
+ "$schema": "https://biomejs.dev/schemas/2.3.5/schema.json",
3
+ "assist": {
4
+ "actions": {
5
+ "source": {
6
+ "organizeImports": {
7
+ "level": "on",
8
+ "options": {
9
+ "groups": [
10
+ [
11
+ ":NODE:",
12
+ ":BUN:",
13
+ ":PACKAGE_WITH_PROTOCOL:",
14
+ ":PACKAGE:"
15
+ ],
16
+ ":BLANK_LINE:",
17
+ ":ALIAS:",
18
+ ":BLANK_LINE:",
19
+ ":PATH:"
20
+ ]
21
+ }
22
+ },
23
+ "useSortedAttributes": {
24
+ "level": "on",
25
+ "options": {
26
+ "sortOrder": "natural"
27
+ }
28
+ },
29
+ "useSortedKeys": "on"
30
+ }
31
+ }
32
+ },
33
+ "files": {
34
+ "ignoreUnknown": true,
35
+ "includes": [
36
+ "**",
37
+ "!**/build",
38
+ "!**/dist",
39
+ "!**/.next"
40
+ ]
41
+ },
42
+ "formatter": {
43
+ "enabled": true,
44
+ "formatWithErrors": true,
45
+ "indentStyle": "space",
46
+ "lineWidth": 140
47
+ },
48
+ "javascript": {
49
+ "formatter": {
50
+ "arrowParentheses": "asNeeded",
51
+ "jsxQuoteStyle": "single",
52
+ "quoteStyle": "single",
53
+ "trailingCommas": "all"
54
+ }
55
+ },
56
+ "linter": {
57
+ "enabled": true,
58
+ "rules": {
59
+ "complexity": {
60
+ "noUselessStringConcat": "error",
61
+ "noUselessUndefinedInitialization": "error",
62
+ "noVoid": "error",
63
+ "useDateNow": "error"
64
+ },
65
+ "correctness": {
66
+ "noConstantMathMinMaxClamp": "error",
67
+ "noUndeclaredVariables": "error",
68
+ "noUnusedFunctionParameters": "error",
69
+ "noUnusedImports": "error",
70
+ "noUnusedPrivateClassMembers": "error",
71
+ "noUnusedVariables": "error",
72
+ "useExhaustiveDependencies": {
73
+ "level": "error",
74
+ "options": {
75
+ "reportUnnecessaryDependencies": false
76
+ }
77
+ }
78
+ },
79
+ "nursery": {
80
+ "useSortedClasses": {
81
+ "fix": "safe",
82
+ "level": "error",
83
+ "options": {
84
+ "functions": [
85
+ "clsx",
86
+ "cn"
87
+ ]
88
+ }
89
+ }
90
+ },
91
+ "recommended": true,
92
+ "style": {
93
+ "noParameterProperties": "error",
94
+ "noYodaExpression": "error",
95
+ "useArrayLiterals": "error",
96
+ "useConsistentBuiltinInstantiation": "error",
97
+ "useFragmentSyntax": "error",
98
+ "useImportType": {
99
+ "fix": "safe",
100
+ "level": "error",
101
+ "options": {
102
+ "style": "separatedType"
103
+ }
104
+ },
105
+ "useSelfClosingElements": {
106
+ "fix": "safe",
107
+ "level": "error",
108
+ "options": {}
109
+ },
110
+ "useShorthandAssign": "error"
111
+ },
112
+ "suspicious": {
113
+ "noEvolvingTypes": "error",
114
+ "useAwait": "error"
115
+ }
116
+ }
117
+ },
118
+ "overrides": [
119
+ {
120
+ "includes": [
121
+ "**/*.jsx",
122
+ "**/*.tsx"
123
+ ],
124
+ "linter": {
125
+ "rules": {
126
+ "style": {
127
+ "noParameterAssign": "error"
128
+ }
129
+ }
130
+ }
131
+ },
132
+ {
133
+ "includes": [
134
+ "**/*.ts",
135
+ "**/*.tsx"
136
+ ],
137
+ "linter": {
138
+ "rules": {
139
+ "correctness": {
140
+ "noUnusedVariables": "off"
141
+ }
142
+ }
143
+ }
144
+ }
145
+ ],
146
+ "root": true,
147
+ "vcs": {
148
+ "clientKind": "git",
149
+ "defaultBranch": "main",
150
+ "enabled": true,
151
+ "useIgnoreFile": true
152
+ }
153
+ }