diff --git a/index.d.ts b/index.d.ts index d5204bf..56639d7 100644 --- a/index.d.ts +++ b/index.d.ts @@ -20,8 +20,11 @@ export default function createConfig(options: { devDependencies: Record } files: { - 'eslint.config.js': string + 'eslint.config.js'?: string + 'eslint.config.ts'?: string '.editorconfig': string + '.gitattributes': string + '.oxfmtrc.jsonc'?: string '.prettierrc.json'?: string } } diff --git a/index.js b/index.js index 4696f06..428a58e 100644 --- a/index.js +++ b/index.js @@ -4,13 +4,26 @@ import renderEjsFile from './renderEjsFile.js' import thisPackage from './package.json' with { type: 'json' } const versionMap = thisPackage.devDependencies -// This is also used in `create-vue` +/** + * Creates an ESLint configuration for Vue.js projects. + * This is also used in `create-vue`. + * + * @param {object} options - Configuration options + * @param {string} [options.styleGuide='default'] - The style guide to use (only 'default' is supported for now) + * @param {boolean} [options.hasTypeScript=false] - Whether the project uses TypeScript + * @param {boolean} [options.needsPrettier=false] - Whether to include Prettier integration + * @param {boolean} [options.needsOxlint=false] - Whether to include Oxlint (faster linter to complement ESLint) + * @param {boolean} [options.needsOxfmt=false] - Whether to include Oxfmt (faster formatter to complement Prettier, experimental) + * @param {Array<{devDependencies?: object, beforeVuePlugin?: Array<{importer: string, content: string}>, afterVuePlugin?: Array<{importer: string, content: string}>}>} [options.additionalConfigs=[]] - Additional configurations to merge + * @returns {{pkg: {devDependencies: object, scripts: object}, files: object}} An object containing package.json modifications and generated config files + */ export default function createConfig({ styleGuide = 'default', // only the default is supported for now hasTypeScript = false, needsPrettier = false, needsOxlint = false, + needsOxfmt = false, additionalConfigs = [], }) { @@ -20,6 +33,7 @@ export default function createConfig({ const pkg = { devDependencies: pickDependencies(['eslint', 'eslint-plugin-vue']), + /** @type Record */ scripts: {}, } @@ -79,9 +93,22 @@ export default function createConfig({ // Users can still append any paths they'd like to format to the command, // e.g. `npm run format cypress/`. pkg.scripts.format = 'prettier --write src/' + + // For now, oxfmt's feature isn't complete enough to fully replace prettier + if (needsOxfmt) { + additionalConfigs.push({ + devDependencies: pickDependencies(['oxfmt']), + }) + pkg.scripts['format:oxfmt'] = 'oxfmt src/' + pkg.scripts['format:prettier'] = `prettier --write src/ '!**/*.{js,jsx,ts,tsx}'` + pkg.scripts.format = 'run-p format:oxfmt format:prettier' + } } - if (needsOxlint && needsPrettier) { + // TBH they don't share dependencies so the plugin can be added with or without oxlint/oxfmt. + // But I don't feel like pushing this as the default option right now. + // If the user shows interest in oxlint/oxfmt, we can safely assume they wants this plugin too. + if (needsPrettier && (needsOxlint || needsOxfmt)) { additionalConfigs.push({ devDependencies: pickDependencies(['@prettier/plugin-oxc']), }) @@ -104,6 +131,7 @@ export default function createConfig({ configsAfterVuePlugin, } + /** @type Record */ const files = { '.editorconfig': renderEjsFile( './templates/_editorconfig.ejs', @@ -164,9 +192,9 @@ const isObject = val => val && typeof val === 'object' const mergeArrayWithDedupe = (a, b) => Array.from(new Set([...a, ...b])) /** - * Recursively merge the content of the new object to the existing one - * @param {object} target the existing object - * @param {object} obj the new object + * Recursively merge the content of the new object to the existing one. + * @param {object} target - The existing object + * @param {object} obj - The new object */ export function deepMerge(target, obj) { for (const key of Object.keys(obj)) { diff --git a/package.json b/package.json index 9e62190..d6329a0 100644 --- a/package.json +++ b/package.json @@ -50,6 +50,7 @@ "globals": "^16.5.0", "jiti": "^2.6.1", "npm-run-all2": "^8.0.4", + "oxfmt": "^0.16.0", "oxlint": "~1.31.0", "prettier": "3.7.3", "typescript": "~5.9.0" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ae48c40..06f582a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -51,6 +51,9 @@ importers: npm-run-all2: specifier: ^8.0.4 version: 8.0.4 + oxfmt: + specifier: ^0.16.0 + version: 0.16.0 oxlint: specifier: ~1.31.0 version: 1.31.0 @@ -233,6 +236,46 @@ packages: '@oxc-project/types@0.99.0': resolution: {integrity: sha512-LLDEhXB7g1m5J+woRSgfKsFPS3LhR9xRhTeIoEBm5WrkwMxn6eZ0Ld0c0K5eHB57ChZX6I3uSmmLjZ8pcjlRcw==} + '@oxfmt/darwin-arm64@0.16.0': + resolution: {integrity: sha512-I+Unj7wePcUTK7p/YKtgbm4yer6dw7dTlmCJa0UilFZyge5uD4rwCSfSDx3A+a6Z3A60/SqXMbNR2UyidWF4Cg==} + cpu: [arm64] + os: [darwin] + + '@oxfmt/darwin-x64@0.16.0': + resolution: {integrity: sha512-EfiXFKEOV5gXgEatFK89OOoSmd8E9Xq83TcjPLWQNFBO4cgaQsfKmctpgJmJjQnoUwD7nQsm0ruj3ae7Gva8QA==} + cpu: [x64] + os: [darwin] + + '@oxfmt/linux-arm64-gnu@0.16.0': + resolution: {integrity: sha512-ydcNY9Fn/8TjVswANhdSh+zdgD3tiikNQA68bgXbENHuV3RyYql1qoOM1eGv5xeIVJfkPJme17MKQz3OwMFS4A==} + cpu: [arm64] + os: [linux] + + '@oxfmt/linux-arm64-musl@0.16.0': + resolution: {integrity: sha512-I9WeYe1/YnrfXgXVaKkZITZzil0G0g9IknS2KJbq1lOnpTw3dwViXZ7XMa2cq6Mv7S+4SoDImb7fLQ59AfVX/w==} + cpu: [arm64] + os: [linux] + + '@oxfmt/linux-x64-gnu@0.16.0': + resolution: {integrity: sha512-Szg9lJtZdN5FoCnNbl3N/2pJv8d056NUmk51m60E2tZV7rvwRTrNC8HPc2sVdb1Ti5ogsicpZDYSWA3cwIrJIQ==} + cpu: [x64] + os: [linux] + + '@oxfmt/linux-x64-musl@0.16.0': + resolution: {integrity: sha512-5koN8nl21ZxOADaMxXHT+mt3YjfXe1nsa23Fanf9aY7B0hcQ6rXYCZ7r5vmpoTtzW/US3aaVcRFZE1cyof+lKw==} + cpu: [x64] + os: [linux] + + '@oxfmt/win32-arm64@0.16.0': + resolution: {integrity: sha512-Jaesn+FYn+MudSmWJMPGBAa0PhQXo52Z0ZYeNfzbQP7v2GFbZBI3Cb87+K0aHGlpqK3VEJKXeIaASaTWlkgO1Q==} + cpu: [arm64] + os: [win32] + + '@oxfmt/win32-x64@0.16.0': + resolution: {integrity: sha512-1obVSlb5blwBKgSsE1mNxvcq1pK9I6aXpZDy5d6jjGdrru33dHrH1ASChrcxwCukkToH2SxwYmnzAto0xeuZlw==} + cpu: [x64] + os: [win32] + '@oxlint/darwin-arm64@1.31.0': resolution: {integrity: sha512-HqoYNH5WFZRdqGUROTFGOdBcA9y/YdHNoR/ujlyVO53it+q96dujbgKEvlff/WEuo4LbDKBrKLWKTKvOd/VYdg==} cpu: [arm64] @@ -754,6 +797,11 @@ packages: resolution: {integrity: sha512-MpS1lbd2vR0NZn1v0drpgu7RUFu3x9Rd0kxExObZc2+F+DIrV0BOMval/RO3BYGwssIOerII6iS8EbbpCCZQpQ==} engines: {node: ^20.19.0 || >=22.12.0} + oxfmt@0.16.0: + resolution: {integrity: sha512-uRnnBAN0zH07FXSfvSKbIw+Jrohv4Px2RwNiZOGI4/pvns4sx0+k4WSt+tqwd7bDeoWaXiGmhZgnbK63hi6hVQ==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + oxlint@1.31.0: resolution: {integrity: sha512-U+Z3VShi1zuLF2Hz/pm4vWJUBm5sDHjwSzj340tz4tS2yXg9H5PTipsZv+Yu/alg6Z7EM2cZPKGNBZAvmdfkQg==} engines: {node: ^20.19.0 || >=22.12.0} @@ -1085,6 +1133,30 @@ snapshots: '@oxc-project/types@0.99.0': {} + '@oxfmt/darwin-arm64@0.16.0': + optional: true + + '@oxfmt/darwin-x64@0.16.0': + optional: true + + '@oxfmt/linux-arm64-gnu@0.16.0': + optional: true + + '@oxfmt/linux-arm64-musl@0.16.0': + optional: true + + '@oxfmt/linux-x64-gnu@0.16.0': + optional: true + + '@oxfmt/linux-x64-musl@0.16.0': + optional: true + + '@oxfmt/win32-arm64@0.16.0': + optional: true + + '@oxfmt/win32-x64@0.16.0': + optional: true + '@oxlint/darwin-arm64@1.31.0': optional: true @@ -1621,6 +1693,17 @@ snapshots: '@oxc-parser/binding-win32-arm64-msvc': 0.99.0 '@oxc-parser/binding-win32-x64-msvc': 0.99.0 + oxfmt@0.16.0: + optionalDependencies: + '@oxfmt/darwin-arm64': 0.16.0 + '@oxfmt/darwin-x64': 0.16.0 + '@oxfmt/linux-arm64-gnu': 0.16.0 + '@oxfmt/linux-arm64-musl': 0.16.0 + '@oxfmt/linux-x64-gnu': 0.16.0 + '@oxfmt/linux-x64-musl': 0.16.0 + '@oxfmt/win32-arm64': 0.16.0 + '@oxfmt/win32-x64': 0.16.0 + oxlint@1.31.0: optionalDependencies: '@oxlint/darwin-arm64': 1.31.0 diff --git a/templates/_oxfmtrc.jsonc b/templates/_oxfmtrc.jsonc new file mode 100644 index 0000000..4bddb67 --- /dev/null +++ b/templates/_oxfmtrc.jsonc @@ -0,0 +1,5 @@ +{ + "$schema": "./node_modules/oxfmt/configuration_schema.json", + "semi": false, + "singleQuote": true +} diff --git a/templates/_prettierrc.json.ejs b/templates/_prettierrc.json.ejs index 1b4db0d..75a1d1f 100644 --- a/templates/_prettierrc.json.ejs +++ b/templates/_prettierrc.json.ejs @@ -6,7 +6,7 @@ "$schema": "https://json.schemastore.org/prettierrc", "semi": false, "singleQuote": true, - "printWidth": 100<%_ if (needsOxlint) { _%>, + "printWidth": 100<%_ if (needsOxlint || needsOxfmt) { _%>, "plugins": [ "@prettier/plugin-oxc" ]