diff --git a/src/data.ts b/src/data.ts index dc6ce27..56fcdd8 100644 --- a/src/data.ts +++ b/src/data.ts @@ -83,6 +83,10 @@ export const availablePrismaDialects = [ 'cockroachdb', 'mssql' ] as const; +export const biomeDependency: AvailableDependency = { + latestVersion: '2.3.5', + value: '@biomejs/biome' +}; export const defaultDependencies: AvailableDependency[] = [ { imports: [{ isPlugin: false, packageName: 'Elysia' }], diff --git a/src/generators/configurations/generatePackageJson.ts b/src/generators/configurations/generatePackageJson.ts index 8631140..ffa2840 100644 --- a/src/generators/configurations/generatePackageJson.ts +++ b/src/generators/configurations/generatePackageJson.ts @@ -8,6 +8,7 @@ import { defaultDependencies, defaultPlugins, eslintAndPrettierDependencies, + biomeDependency, eslintReactDependencies } from '../../data'; import type { CreateConfiguration, PackageJson } from '../../types'; @@ -186,6 +187,13 @@ export const createPackageJson = async ({ ); }); } + + else if (codeQualityTool === 'biome') { + devDependencies[biomeDependency.value] = resolveVersion( + biomeDependency.value, + biomeDependency.latestVersion + ); + } if (useTailwind) { devDependencies['autoprefixer'] = resolveVersion( @@ -279,14 +287,22 @@ export const createPackageJson = async ({ if (latest) s.stop(green('Package versions resolved')); + // ---- Scripts ---- const scripts: PackageJson['scripts'] = { dev: 'absolutejs dev', - format: `absolutejs prettier --write "./**/*.{js,ts,css,json,mjs,md${flags.requiresReact ? ',jsx,tsx' : ''}${flags.requiresSvelte ? ',svelte' : ''}${flags.requiresVue ? ',vue' : ''}${flags.requiresHtml || flags.requiresHtmx ? ',html' : ''}}"`, - lint: 'absolutejs eslint', test: 'echo "Error: no test specified" && exit 1', typecheck: 'bun run tsc --noEmit' }; + if (codeQualityTool === 'biome') { + scripts.format = 'biome format . --write'; + scripts.lint = 'biome lint .'; + scripts.check = 'biome check .'; + } else { + scripts.format = `absolutejs prettier --write "./**/*.{js,ts,css,json,mjs,md${flags.requiresReact ? ',jsx,tsx' : ''}${flags.requiresSvelte ? ',svelte' : ''}${flags.requiresVue ? ',vue' : ''}${flags.requiresHtml || flags.requiresHtmx ? ',html' : ''}}"`; + scripts.lint = 'absolutejs eslint'; + } + const isLocalDb = isLocal; if ( diff --git a/src/generators/configurations/scaffoldConfigurationFiles.ts b/src/generators/configurations/scaffoldConfigurationFiles.ts index 04bf18b..7faf1ed 100644 --- a/src/generators/configurations/scaffoldConfigurationFiles.ts +++ b/src/generators/configurations/scaffoldConfigurationFiles.ts @@ -64,10 +64,20 @@ export const scaffoldConfigurationFiles = ({ const prettierrc = generatePrettierrc(frontends); writeFileSync(join(projectName, '.prettierrc.json'), prettierrc); - } else + } else if (codeQualityTool === 'biome') { + copyFileSync( + join(templatesDirectory, 'configurations', 'biome.json'), + join(projectName, 'biome.json') + ); + copyFileSync( + join(templatesDirectory, 'configurations', '.biomeignore'), + join(projectName, '.biomeignore') + ); + } else { console.warn( - `${dim('│')}\n${yellow('▲')} Biome support not implemented yet` + `${dim('│')}\n${yellow('▲')} No code-quality tool selected or unsupported tool` ); + } generateEnv({ databaseEngine, diff --git a/src/templates/configurations/.biomeignore b/src/templates/configurations/.biomeignore new file mode 100644 index 0000000..6c7cf2c --- /dev/null +++ b/src/templates/configurations/.biomeignore @@ -0,0 +1,16 @@ +node_modules +dist +build +coverage +.next +.turbo +.vercel +.cache +.output +tmp +out +pnpm-lock.yaml +yarn.lock +.DS_Store +tsconfig.json +tsconfig.*.json diff --git a/src/templates/configurations/biome.json b/src/templates/configurations/biome.json new file mode 100644 index 0000000..61c95a7 --- /dev/null +++ b/src/templates/configurations/biome.json @@ -0,0 +1,78 @@ +{ + "$schema": "https://biomejs.dev/schemas/2.3.5/schema.json", + "files": { + "includes": ["**/*"] + }, + "formatter": { + "enabled": true, + "indentStyle": "tab", + "indentWidth": 4, + "lineWidth": 80 + }, + "linter": { + "enabled": true, + "rules": { + "recommended": true, + "a11y": { + "recommended": true, + "useHtmlLang": "off", + "useButtonType": "off" + }, + "performance": { "recommended": true }, + "security": { + "recommended": true, + "noBlankTarget": "off" + }, + "correctness": { "noUnusedVariables": "warn" }, + "complexity": { "noUselessCatch": "warn" }, + "style": { + "useBlockStatements": "error", + "useConst": "error", + "noParameterAssign": "warn" + } + } + }, + "javascript": { + "formatter": { + "quoteStyle": "single", + "semicolons": "always" + } + }, + "assist": { + "enabled": true, + "actions": { + "source": { + "organizeImports": "on" + } + } + }, + "overrides": [ + { + "includes": ["**/*.md", "**/*.mdx"], + "formatter": { "lineWidth": 80 } + }, + { + "includes": ["**/*.{yml,yaml}"], + "formatter": { "indentStyle": "space", "indentWidth": 2 } + }, + { + "includes": [ + "**/*.json", + "**/*.jsonc", + "**/*.json5", + "tsconfig.json", + "tsconfig.*.json" + ], + "formatter": { + "indentStyle": "space", + "indentWidth": 2, + "enabled": false + }, + "linter": { "enabled": false } + }, + { + "includes": ["**/*.{config,cfg}.{js,ts,mjs,cjs}"], + "linter": { "rules": { "complexity": { "recommended": false } } } + } + ] +}