@quentinhsu/biome-config 0.3.1 → 0.3.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.
Files changed (33) 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 +11 -0
  13. package/dist/types/src/generated/biome/no-assign-in-expressions-configuration.d.ts +1002 -0
  14. package/dist/types/src/generated/biome/no-empty-source-configuration.d.ts +241 -0
  15. package/dist/types/src/generated/biome/no-global-object-calls-options.d.ts +320 -0
  16. package/dist/types/src/generated/biome/no-misrefactored-shorthand-assign-options.d.ts +1116 -0
  17. package/dist/types/src/generated/biome/no-non-null-assertion-options.d.ts +291 -0
  18. package/dist/types/src/generated/biome/nursery.d.ts +1023 -0
  19. package/dist/types/src/generated/biome/rule-with-no-document-import-in-page-options.d.ts +1148 -0
  20. package/dist/types/src/generated/biome/rule-with-no-implicit-coercions-options.d.ts +1440 -0
  21. package/dist/types/src/generated/biome/schema.d.ts +291 -0
  22. package/dist/types/src/generated/biome/use-consistent-arrow-return-options.d.ts +1341 -0
  23. package/dist/types/src/generated/biome/use-semantic-elements-configuration.d.ts +163 -0
  24. package/dist/types/src/index.d.ts +15 -0
  25. package/dist/types/src/presets/next.d.ts +1 -0
  26. package/dist/types/src/presets/nuxt.d.ts +1 -0
  27. package/dist/types/src/presets/react.d.ts +1 -0
  28. package/dist/types/src/presets/vue.d.ts +1 -0
  29. package/dist/types/src/source/index.d.ts +2 -0
  30. package/dist/types/src/types.d.ts +1 -0
  31. package/dist/types/src/utils/merge.d.ts +2 -0
  32. package/dist/vue.jsonc +177 -0
  33. package/package.json +12 -11
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.2/schema.json';
48
+ const indexConfig = {
49
+ $schema: BIOME_SCHEMA_URL,
50
+ root: true,
51
+ vcs: {
52
+ enabled: true,
53
+ clientKind: 'git',
54
+ useIgnoreFile: true,
55
+ defaultBranch: 'main'
56
+ },
57
+ files: {
58
+ ignoreUnknown: true,
59
+ includes: [
60
+ '**',
61
+ '!**/build',
62
+ '!**/dist',
63
+ '!**/.next'
64
+ ]
65
+ },
66
+ formatter: {
67
+ enabled: true,
68
+ indentStyle: 'space',
69
+ lineWidth: 140,
70
+ formatWithErrors: true
71
+ },
72
+ assist: {
73
+ actions: {
74
+ source: {
75
+ organizeImports: {
76
+ level: 'on',
77
+ options: {
78
+ groups: [
79
+ [
80
+ ':NODE:',
81
+ ':BUN:',
82
+ ':PACKAGE_WITH_PROTOCOL:',
83
+ ':PACKAGE:'
84
+ ],
85
+ ':BLANK_LINE:',
86
+ ':ALIAS:',
87
+ ':BLANK_LINE:',
88
+ ':PATH:'
89
+ ]
90
+ }
91
+ },
92
+ useSortedKeys: 'on',
93
+ useSortedAttributes: {
94
+ level: 'on',
95
+ options: {
96
+ sortOrder: 'natural'
97
+ }
98
+ }
99
+ }
100
+ }
101
+ },
102
+ linter: {
103
+ enabled: true,
104
+ rules: {
105
+ recommended: true,
106
+ complexity: {
107
+ noUselessStringConcat: 'error',
108
+ noUselessUndefinedInitialization: 'error',
109
+ noVoid: 'error',
110
+ useDateNow: 'error'
111
+ },
112
+ correctness: {
113
+ noConstantMathMinMaxClamp: 'error',
114
+ noUndeclaredVariables: 'error',
115
+ noUnusedImports: 'error',
116
+ noUnusedFunctionParameters: 'error',
117
+ noUnusedPrivateClassMembers: 'error',
118
+ useExhaustiveDependencies: {
119
+ level: 'error',
120
+ options: {
121
+ reportUnnecessaryDependencies: false
122
+ }
123
+ },
124
+ noUnusedVariables: 'error'
125
+ },
126
+ style: {
127
+ noParameterProperties: 'error',
128
+ noYodaExpression: 'error',
129
+ useConsistentBuiltinInstantiation: 'error',
130
+ useFragmentSyntax: 'error',
131
+ useImportType: {
132
+ level: 'error',
133
+ fix: 'safe',
134
+ options: {
135
+ style: 'separatedType'
136
+ }
137
+ },
138
+ useSelfClosingElements: {
139
+ level: 'error',
140
+ fix: 'safe',
141
+ options: {}
142
+ },
143
+ useShorthandAssign: 'error',
144
+ useArrayLiterals: 'error'
145
+ },
146
+ nursery: {
147
+ useSortedClasses: {
148
+ level: 'error',
149
+ fix: 'safe',
150
+ options: {
151
+ functions: [
152
+ 'clsx',
153
+ 'cn'
154
+ ]
155
+ }
156
+ }
157
+ },
158
+ suspicious: {
159
+ useAwait: 'error',
160
+ noEvolvingTypes: 'error'
161
+ }
162
+ }
163
+ },
164
+ javascript: {
165
+ formatter: {
166
+ quoteStyle: 'single',
167
+ jsxQuoteStyle: 'single',
168
+ arrowParentheses: 'asNeeded',
169
+ trailingCommas: 'all'
170
+ }
171
+ },
172
+ overrides: [
173
+ {
174
+ includes: [
175
+ '**/*.jsx',
176
+ '**/*.tsx'
177
+ ],
178
+ linter: {
179
+ rules: {
180
+ style: {
181
+ noParameterAssign: 'error'
182
+ }
183
+ }
184
+ }
185
+ },
186
+ {
187
+ includes: [
188
+ '**/*.ts',
189
+ '**/*.tsx'
190
+ ],
191
+ linter: {
192
+ rules: {
193
+ correctness: {
194
+ noUnusedVariables: 'off'
195
+ }
196
+ }
197
+ }
198
+ }
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
+ react: reactConfig,
357
+ next: nextConfig,
358
+ vue: vueConfig,
359
+ nuxt: nuxtConfig
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.2/schema.json",
3
+ "root": true,
4
+ "vcs": {
5
+ "enabled": true,
6
+ "clientKind": "git",
7
+ "useIgnoreFile": true,
8
+ "defaultBranch": "main"
9
+ },
10
+ "files": {
11
+ "ignoreUnknown": true,
12
+ "includes": [
13
+ "**",
14
+ "!**/build",
15
+ "!**/dist",
16
+ "!**/.next"
17
+ ]
18
+ },
19
+ "formatter": {
20
+ "enabled": true,
21
+ "indentStyle": "space",
22
+ "lineWidth": 140,
23
+ "formatWithErrors": true
24
+ },
25
+ "assist": {
26
+ "actions": {
27
+ "source": {
28
+ "organizeImports": {
29
+ "level": "on",
30
+ "options": {
31
+ "groups": [
32
+ [
33
+ ":NODE:",
34
+ ":BUN:",
35
+ ":PACKAGE_WITH_PROTOCOL:",
36
+ ":PACKAGE:"
37
+ ],
38
+ ":BLANK_LINE:",
39
+ ":ALIAS:",
40
+ ":BLANK_LINE:",
41
+ ":PATH:"
42
+ ]
43
+ }
44
+ },
45
+ "useSortedKeys": "on",
46
+ "useSortedAttributes": {
47
+ "level": "on",
48
+ "options": {
49
+ "sortOrder": "natural"
50
+ }
51
+ }
52
+ }
53
+ }
54
+ },
55
+ "linter": {
56
+ "enabled": true,
57
+ "rules": {
58
+ "recommended": true,
59
+ "complexity": {
60
+ "noUselessStringConcat": "error",
61
+ "noUselessUndefinedInitialization": "error",
62
+ "noVoid": "error",
63
+ "useDateNow": "error"
64
+ },
65
+ "correctness": {
66
+ "noConstantMathMinMaxClamp": "error",
67
+ "noUndeclaredVariables": "error",
68
+ "noUnusedImports": "error",
69
+ "noUnusedFunctionParameters": "error",
70
+ "noUnusedPrivateClassMembers": "error",
71
+ "useExhaustiveDependencies": {
72
+ "level": "error",
73
+ "options": {
74
+ "reportUnnecessaryDependencies": false
75
+ }
76
+ },
77
+ "noUnusedVariables": "error"
78
+ },
79
+ "style": {
80
+ "noParameterProperties": "error",
81
+ "noYodaExpression": "error",
82
+ "useConsistentBuiltinInstantiation": "error",
83
+ "useFragmentSyntax": "error",
84
+ "useImportType": {
85
+ "level": "error",
86
+ "fix": "safe",
87
+ "options": {
88
+ "style": "separatedType"
89
+ }
90
+ },
91
+ "useSelfClosingElements": {
92
+ "level": "error",
93
+ "fix": "safe",
94
+ "options": {}
95
+ },
96
+ "useShorthandAssign": "error",
97
+ "useArrayLiterals": "error"
98
+ },
99
+ "nursery": {
100
+ "useSortedClasses": {
101
+ "level": "error",
102
+ "fix": "safe",
103
+ "options": {
104
+ "functions": [
105
+ "clsx",
106
+ "cn"
107
+ ]
108
+ }
109
+ }
110
+ },
111
+ "suspicious": {
112
+ "useAwait": "error",
113
+ "noEvolvingTypes": "error"
114
+ }
115
+ }
116
+ },
117
+ "javascript": {
118
+ "formatter": {
119
+ "quoteStyle": "single",
120
+ "jsxQuoteStyle": "single",
121
+ "arrowParentheses": "asNeeded",
122
+ "trailingCommas": "all"
123
+ }
124
+ },
125
+ "overrides": [
126
+ {
127
+ "includes": [
128
+ "**/*.jsx",
129
+ "**/*.tsx"
130
+ ],
131
+ "linter": {
132
+ "rules": {
133
+ "style": {
134
+ "noParameterAssign": "error"
135
+ }
136
+ }
137
+ }
138
+ },
139
+ {
140
+ "includes": [
141
+ "**/*.ts",
142
+ "**/*.tsx"
143
+ ],
144
+ "linter": {
145
+ "rules": {
146
+ "correctness": {
147
+ "noUnusedVariables": "off"
148
+ }
149
+ }
150
+ }
151
+ }
152
+ ]
153
+ }