diff --git a/packages/oxfmt-config/src/configs/base.ts b/packages/oxfmt-config/src/configs/base.ts index 7333b83..9185ecd 100644 --- a/packages/oxfmt-config/src/configs/base.ts +++ b/packages/oxfmt-config/src/configs/base.ts @@ -12,3 +12,13 @@ export const base: OxfmtConfig = { jsxSingleQuote: true, trailingComma: 'none' } + +/** + * Default configuration that is always applied regardless of presets. + * + * Disable sorting of package.json due that is enabled by default in Oxfmt. + * @see https://oxc.rs/docs/guide/usage/formatter/sorting.html#sort-package-json-fields + */ +export const defaults: OxfmtConfig = { + sortPackageJson: false +} diff --git a/packages/oxfmt-config/src/configs/index.ts b/packages/oxfmt-config/src/configs/index.ts index a9381bb..c5f792d 100644 --- a/packages/oxfmt-config/src/configs/index.ts +++ b/packages/oxfmt-config/src/configs/index.ts @@ -2,3 +2,4 @@ export { base } from './base.ts' export { jsdoc } from './jsdoc.ts' export { mdx } from './mdx.ts' export { yaml } from './yaml.ts' +export { packageJson } from './packageJson.ts' diff --git a/packages/oxfmt-config/src/configs/packageJson.ts b/packages/oxfmt-config/src/configs/packageJson.ts new file mode 100644 index 0000000..b884ae4 --- /dev/null +++ b/packages/oxfmt-config/src/configs/packageJson.ts @@ -0,0 +1,13 @@ +import type { OxfmtConfig } from 'oxfmt' + +/** + * Package json order configuration for Oxfmt. + * + * This configuration is designed to enforce a specific order of properties in package.json files. + * Displaying properties in a predefined order can help maintain consistency and readability. + */ +export const packageJson: OxfmtConfig = { + sortPackageJson: { + sortScripts: true + } +} diff --git a/packages/oxfmt-config/src/presets.ts b/packages/oxfmt-config/src/presets.ts index 969a144..0146135 100644 --- a/packages/oxfmt-config/src/presets.ts +++ b/packages/oxfmt-config/src/presets.ts @@ -1,17 +1,19 @@ import type { PresetName } from './types/index.ts' -import { base, jsdoc, mdx, yaml } from './configs/index.ts' +import { base, jsdoc, mdx, yaml, packageJson } from './configs/index.ts' export const presetEntries = [ ['base', base], ['jsdoc', jsdoc], ['mdx', mdx], - ['yaml', yaml] + ['yaml', yaml], + ['packageJson', packageJson] ] as const export const defaultOptions: Readonly> = { base: true, jsdoc: true, mdx: true, - yaml: true + yaml: true, + packageJson: false } diff --git a/packages/oxfmt-config/src/utils/selectPresetConfigs.ts b/packages/oxfmt-config/src/utils/selectPresetConfigs.ts index 89cd529..4c0d37a 100644 --- a/packages/oxfmt-config/src/utils/selectPresetConfigs.ts +++ b/packages/oxfmt-config/src/utils/selectPresetConfigs.ts @@ -1,12 +1,15 @@ import type { OxfmtConfig } from 'oxfmt' import type { Options, PresetMap, PresetName } from '../types/index.ts' +import { defaults } from '../configs/base.ts' import { presetEntries } from '../presets.ts' export function selectPresetConfigs(options: Required): OxfmtConfig[] { const presets = Object.fromEntries(presetEntries) as PresetMap - return (Object.keys(options) as PresetName[]) + const configs = (Object.keys(options) as PresetName[]) .filter(name => options[name]) .map(name => presets[name]) + + return [defaults, ...configs] } diff --git a/packages/oxfmt-config/tests/fixture.test.ts b/packages/oxfmt-config/tests/fixture.test.ts index 1fbcf1c..26d4330 100644 --- a/packages/oxfmt-config/tests/fixture.test.ts +++ b/packages/oxfmt-config/tests/fixture.test.ts @@ -37,11 +37,14 @@ runWithConfig('without-presets', { base: false, yaml: false, jsdoc: false, - mdx: false + mdx: false, + packageJson: false }) runWithConfig( 'with-user-config', - {}, + { + packageJson: true + }, { semi: true, trailingComma: 'all', @@ -94,14 +97,8 @@ function runWithConfig(name: string, options: Options, ...userConfigs: OxfmtConf await Promise.all( files.map(async(file: string) => { const content = await readFile(join(target, file), 'utf-8') - const source = await readFile(join(from, file), 'utf-8') const outputPath = join(output, file) - if (content === source) { - await rm(outputPath, { force: true }) - return - } - await expect.soft(content).toMatchFileSnapshot(outputPath) }) ) diff --git a/packages/oxfmt-config/tests/fixtures/input/package.json b/packages/oxfmt-config/tests/fixtures/input/package.json new file mode 100644 index 0000000..c9cc5d8 --- /dev/null +++ b/packages/oxfmt-config/tests/fixtures/input/package.json @@ -0,0 +1,33 @@ +{ + "simple-git-hooks": { + "pre-commit": "pnpm nano-staged" + }, + "author": "Felix Icaza ", + "version": "0.0.0", + "license": "ISC", + "type": "module", + "description": "Package.json example for testing the packageJson option of oxfmt", + "scripts": { + "format": "oxfmt . --check", + "dev": "servor --reload src", + "lint": "oxlint .", + "format:fix": "oxfmt . --write", + "lint:fix": "oxlint . --fix", + "prepare": "simple-git-hooks" + }, + "private": true, + "devDependencies": { + "@felixicaza/oxfmt-config": "0.1.1", + "@felixicaza/oxlint-config": "0.1.1", + "eslint": "10.4.0", + "nano-staged": "1.0.2", + "oxfmt": "0.50.0", + "oxlint": "1.65.0", + "servor": "4.0.2", + "simple-git-hooks": "2.13.1" + }, + "name": "example", + "nano-staged": { + "*": "pnpm lint:fix" + } +} diff --git a/packages/oxfmt-config/tests/fixtures/output/default/package.json b/packages/oxfmt-config/tests/fixtures/output/default/package.json new file mode 100644 index 0000000..c9cc5d8 --- /dev/null +++ b/packages/oxfmt-config/tests/fixtures/output/default/package.json @@ -0,0 +1,33 @@ +{ + "simple-git-hooks": { + "pre-commit": "pnpm nano-staged" + }, + "author": "Felix Icaza ", + "version": "0.0.0", + "license": "ISC", + "type": "module", + "description": "Package.json example for testing the packageJson option of oxfmt", + "scripts": { + "format": "oxfmt . --check", + "dev": "servor --reload src", + "lint": "oxlint .", + "format:fix": "oxfmt . --write", + "lint:fix": "oxlint . --fix", + "prepare": "simple-git-hooks" + }, + "private": true, + "devDependencies": { + "@felixicaza/oxfmt-config": "0.1.1", + "@felixicaza/oxlint-config": "0.1.1", + "eslint": "10.4.0", + "nano-staged": "1.0.2", + "oxfmt": "0.50.0", + "oxlint": "1.65.0", + "servor": "4.0.2", + "simple-git-hooks": "2.13.1" + }, + "name": "example", + "nano-staged": { + "*": "pnpm lint:fix" + } +} diff --git a/packages/oxfmt-config/tests/fixtures/output/with-user-config/package.json b/packages/oxfmt-config/tests/fixtures/output/with-user-config/package.json new file mode 100644 index 0000000..d71db5d --- /dev/null +++ b/packages/oxfmt-config/tests/fixtures/output/with-user-config/package.json @@ -0,0 +1,33 @@ +{ + "name": "example", + "version": "0.0.0", + "private": true, + "description": "Package.json example for testing the packageJson option of oxfmt", + "license": "ISC", + "author": "Felix Icaza ", + "type": "module", + "scripts": { + "dev": "servor --reload src", + "format": "oxfmt . --check", + "format:fix": "oxfmt . --write", + "lint": "oxlint .", + "lint:fix": "oxlint . --fix", + "prepare": "simple-git-hooks" + }, + "devDependencies": { + "@felixicaza/oxfmt-config": "0.1.1", + "@felixicaza/oxlint-config": "0.1.1", + "eslint": "10.4.0", + "nano-staged": "1.0.2", + "oxfmt": "0.50.0", + "oxlint": "1.65.0", + "servor": "4.0.2", + "simple-git-hooks": "2.13.1" + }, + "simple-git-hooks": { + "pre-commit": "pnpm nano-staged" + }, + "nano-staged": { + "*": "pnpm lint:fix" + } +} diff --git a/packages/oxfmt-config/tests/fixtures/output/without-presets/package.json b/packages/oxfmt-config/tests/fixtures/output/without-presets/package.json new file mode 100644 index 0000000..c9cc5d8 --- /dev/null +++ b/packages/oxfmt-config/tests/fixtures/output/without-presets/package.json @@ -0,0 +1,33 @@ +{ + "simple-git-hooks": { + "pre-commit": "pnpm nano-staged" + }, + "author": "Felix Icaza ", + "version": "0.0.0", + "license": "ISC", + "type": "module", + "description": "Package.json example for testing the packageJson option of oxfmt", + "scripts": { + "format": "oxfmt . --check", + "dev": "servor --reload src", + "lint": "oxlint .", + "format:fix": "oxfmt . --write", + "lint:fix": "oxlint . --fix", + "prepare": "simple-git-hooks" + }, + "private": true, + "devDependencies": { + "@felixicaza/oxfmt-config": "0.1.1", + "@felixicaza/oxlint-config": "0.1.1", + "eslint": "10.4.0", + "nano-staged": "1.0.2", + "oxfmt": "0.50.0", + "oxlint": "1.65.0", + "servor": "4.0.2", + "simple-git-hooks": "2.13.1" + }, + "name": "example", + "nano-staged": { + "*": "pnpm lint:fix" + } +} diff --git a/packages/oxfmt-config/tests/index.test.ts b/packages/oxfmt-config/tests/index.test.ts index 66baf67..693f6aa 100644 --- a/packages/oxfmt-config/tests/index.test.ts +++ b/packages/oxfmt-config/tests/index.test.ts @@ -10,7 +10,8 @@ const allDisabled: Required = { base: false, jsdoc: false, mdx: false, - yaml: false + yaml: false, + packageJson: false } describe('index public API', () => { diff --git a/packages/oxfmt-config/tests/selectPresetConfigs.test.ts b/packages/oxfmt-config/tests/selectPresetConfigs.test.ts index 635344f..cb18fae 100644 --- a/packages/oxfmt-config/tests/selectPresetConfigs.test.ts +++ b/packages/oxfmt-config/tests/selectPresetConfigs.test.ts @@ -1,18 +1,20 @@ import { describe, expect, it } from 'vitest' -import { base, jsdoc, mdx, yaml } from '../src/configs/index.ts' +import { base, jsdoc, mdx, yaml, packageJson } from '../src/configs/index.ts' +import { defaults } from '../src/configs/base.ts' import { selectPresetConfigs } from '../src/utils/selectPresetConfigs.ts' describe('utils/selectPresetConfigs', () => { - it('returns empty list when all presets are disabled', () => { + it('returns only defaults when all presets are disabled', () => { const result = selectPresetConfigs({ base: false, jsdoc: false, mdx: false, - yaml: false + yaml: false, + packageJson: false }) - expect(result).toEqual([]) + expect(result).toEqual([defaults]) }) it('selects only base preset when base is enabled', () => { @@ -20,21 +22,23 @@ describe('utils/selectPresetConfigs', () => { base: true, jsdoc: false, mdx: false, - yaml: false + yaml: false, + packageJson: false }) - expect(result).toEqual([base]) + expect(result).toEqual([defaults, base]) }) - it('selects only mdx preset when mdx is enabled', () => { + it('selects only mdx and yaml presets when they are enabled', () => { const result = selectPresetConfigs({ base: false, jsdoc: false, mdx: true, - yaml: true + yaml: true, + packageJson: false }) - expect(result).toEqual([mdx, yaml]) + expect(result).toEqual([defaults, mdx, yaml]) }) it('selects all presets in declaration order when all are enabled', () => { @@ -42,9 +46,10 @@ describe('utils/selectPresetConfigs', () => { base: true, jsdoc: true, mdx: true, - yaml: true + yaml: true, + packageJson: true }) - expect(result).toEqual([base, jsdoc, mdx, yaml]) + expect(result).toEqual([defaults, base, jsdoc, mdx, yaml, packageJson]) }) })