diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 5122444..9b821d7 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,4 +1,5 @@ { + "packages/biome-config": "0.0.0", "packages/bundlecheck": "2.1.12", "packages/bundlesize": "5.3.1", "packages/envtools": "5.0.0", diff --git a/biome.json b/biome.json index 6f60489..7b8f73d 100644 --- a/biome.json +++ b/biome.json @@ -1,4 +1,4 @@ { "$schema": "./node_modules/@biomejs/biome/configuration_schema.json", - "extends": ["@versini/dev-dependencies-common/biome"] + "extends": ["@node-cli/biome-config/biome"] } diff --git a/package.json b/package.json index 0635a94..f136aac 100644 --- a/package.json +++ b/package.json @@ -18,11 +18,11 @@ }, "devDependencies": { "@biomejs/biome": "2.6.2", + "@node-cli/biome-config": "workspace:*", "@node-cli/comments": "workspace:*", "@swc/cli": "0.8.1", "@swc/core": "1.16.18", "@types/node": "26.6.5", - "@versini/dev-dependencies-common": "15.0.0", "barrelsby": "2.8.1", "husky": "9.1.7", "lint-staged": "17.6.0", diff --git a/packages/biome-config/README.md b/packages/biome-config/README.md new file mode 100644 index 0000000..e36a88c --- /dev/null +++ b/packages/biome-config/README.md @@ -0,0 +1,34 @@ +# @node-cli/biome-config + +The biome config shared across the `@versini` and `@node-cli` repos. It ships +`biome.json` and nothing else. + +```json +{ + "extends": ["@node-cli/biome-config/biome"] +} +``` + +`@biomejs/biome` is a peer dependency. Each repo declares the biome version it +runs, along with every other tool it uses, directly in its own `package.json`. +With `autoInstallPeers: false`, which every consumer sets, nothing installs +biome for you. + +## Why it holds no dependencies + +This config used to live in `@versini/dev-dependencies-common`, which also +bundled the tooling, so a repo got biome, typescript, vitest and the rest from +one pin. That coupled every repo to the bundle's release: a new major of any +tool reached the whole fleet the moment the bundle published, and a package one +repo needed was installed by all of them. Each repo now owns its tooling and +moves on its own schedule, and deps-train keeps the non-major versions aligned +across them. + +Do not add dependencies here. A tool the repos share goes in each repo's +`package.json`. + +## Changing the config + +A rule that needs a newer biome raises the floor of the peer range in the same +change, so a repo on an older biome gets a peer warning instead of a config +error it cannot explain. diff --git a/packages/biome-config/biome.json b/packages/biome-config/biome.json new file mode 100644 index 0000000..ba74c2c --- /dev/null +++ b/packages/biome-config/biome.json @@ -0,0 +1,152 @@ +{ + "root": false, + "$schema": "./node_modules/@biomejs/biome/configuration_schema.json", + "assist": { "actions": { "source": { "organizeImports": "on" } } }, + "vcs": { + "enabled": true, + "clientKind": "git", + "useIgnoreFile": true + }, + "formatter": { + "attributePosition": "auto", + "enabled": true, + "formatWithErrors": true, + "indentStyle": "tab", + "indentWidth": 2, + "lineEnding": "lf", + "lineWidth": 80 + }, + "linter": { + "enabled": true, + "rules": { + "preset": "none", + "a11y": {}, + "complexity": { + "noBannedTypes": "error", + "noExtraBooleanCast": "error", + "noUselessCatch": "error", + "noUselessFragments": "error", + "noUselessThisAlias": "error", + "noUselessTypeConstraint": "error", + "noAdjacentSpacesInRegex": "error", + "noArguments": "error" + }, + "correctness": { + "noChildrenProp": "error", + "noConstAssign": "error", + "noConstantCondition": "error", + "noEmptyCharacterClassInRegex": "error", + "noEmptyPattern": "error", + "noGlobalObjectCalls": "error", + "noInnerDeclarations": "error", + "noInvalidConstructorSuper": "error", + "noInvalidUseBeforeDeclaration": "error", + "noNonoctalDecimalEscape": "error", + "noPrecisionLoss": "error", + "noSelfAssign": "error", + "noSetterReturn": "error", + "noSwitchDeclarations": "error", + "noUndeclaredVariables": "error", + "noUnreachable": "error", + "noUnreachableSuper": "error", + "noUnsafeFinally": "error", + "noUnsafeOptionalChaining": "error", + "noUnusedImports": { + "options": {}, + "level": "warn", + "fix": "safe" + }, + "noUnusedLabels": "error", + "noUnusedVariables": "error", + "useExhaustiveDependencies": "warn", + "useHookAtTopLevel": "error", + "useIsNan": "error", + "useJsxKeyInIterable": "error", + "useValidForDirection": "error", + "useYield": "error", + "noInvalidBuiltinInstantiation": "error", + "useValidTypeof": "error" + }, + "security": { + "noDangerouslySetInnerHtml": "error", + "noGlobalEval": "error", + "noBlankTarget": "error" + }, + "style": { + "useAsConstAssertion": "error", + "useBlockStatements": "error", + "useConst": "error" + }, + "suspicious": { + "noAssignInExpressions": "error", + "noAsyncPromiseExecutor": "error", + "noCatchAssign": "error", + "noClassAssign": "error", + "noCommentText": "error", + "noCompareNegZero": "error", + "noControlCharactersInRegex": "error", + "noDebugger": "error", + "noDoubleEquals": "error", + "noDuplicateCase": "error", + "noDuplicateClassMembers": "error", + "noDuplicateJsxProps": "error", + "noDuplicateObjectKeys": "error", + "noDuplicateParameters": "error", + "noEmptyBlockStatements": "off", + "noExplicitAny": "off", + "noExtraNonNullAssertion": "error", + "noFallthroughSwitchClause": "error", + "noFunctionAssign": "error", + "noGlobalAssign": "error", + "noImportAssign": "error", + "noLabelVar": "error", + "noMisleadingCharacterClass": "error", + "noMisleadingInstantiator": "error", + "noPrototypeBuiltins": "error", + "noRedeclare": "error", + "noShadowRestrictedNames": "error", + "noUnsafeDeclarationMerging": "error", + "noUnsafeNegation": "error", + "useGetterReturn": "error", + "noWith": "error", + "noVar": "error", + "noConsole": { + "level": "warn", + "options": { "allow": ["info", "error", "warn"] } + } + } + }, + "includes": ["**", "!**/dist", "!**/.eslintrc.cjs"] + }, + "javascript": { + "globals": ["React"], + "formatter": { + "arrowParentheses": "always", + "attributePosition": "auto", + "bracketSameLine": false, + "bracketSpacing": true, + "jsxQuoteStyle": "double", + "quoteProperties": "asNeeded", + "quoteStyle": "double", + "semicolons": "always", + "trailingCommas": "all" + } + }, + "css": { + "parser": { + "tailwindDirectives": true + } + }, + "overrides": [ + { + "includes": ["**/*.test.ts", "**/*.test.tsx"], + "linter": { + "rules": { + "correctness": { + "noUndeclaredVariables": "off" + } + } + } + } + ] +} diff --git a/packages/biome-config/package.json b/packages/biome-config/package.json new file mode 100644 index 0000000..d6fa087 --- /dev/null +++ b/packages/biome-config/package.json @@ -0,0 +1,26 @@ +{ + "name": "@node-cli/biome-config", + "version": "0.0.0", + "license": "MIT", + "author": "Arno Versini", + "description": "The biome config shared across the @versini and @node-cli repos", + "repository": { + "type": "git", + "url": "git+https://github.com/versini-org/node-cli.git", + "directory": "packages/biome-config" + }, + "type": "module", + "files": [ + "biome.json", + "README.md" + ], + "exports": { + "./biome": "./biome.json" + }, + "publishConfig": { + "access": "public" + }, + "peerDependencies": { + "@biomejs/biome": "^2.5.15" + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 16095f0..2954225 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -169,6 +169,9 @@ importers: '@biomejs/biome': specifier: 2.6.2 version: 2.6.2 + '@node-cli/biome-config': + specifier: workspace:* + version: link:packages/biome-config '@node-cli/comments': specifier: workspace:* version: link:packages/comments @@ -181,9 +184,6 @@ importers: '@types/node': specifier: 26.6.5 version: 26.6.5 - '@versini/dev-dependencies-common': - specifier: 15.0.0 - version: 15.0.0(@biomejs/biome@2.6.2) barrelsby: specifier: 2.8.1 version: 2.8.1 @@ -236,6 +236,8 @@ importers: specifier: workspace:* version: link:../../packages/run + packages/biome-config: {} + packages/bundlecheck: dependencies: '@inquirer/select': @@ -1441,11 +1443,6 @@ packages: '@types/yargs@17.0.35': resolution: {integrity: sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==} - '@versini/dev-dependencies-common@15.0.0': - resolution: {integrity: sha512-ImzN9NZNEpsdOF7BcO56jTEp8rSNkIOABaW18gh4m8Iamypnvg4KonOV7OAIEeaKPGDLgCnNFzBKAZzHs8gcww==} - peerDependencies: - '@biomejs/biome': ^2.5.15 - '@vitest/coverage-v8@5.0.5': resolution: {integrity: sha512-4KpkGdIrSqBihx/JyP/e+S+IKB98etg1XDQiLAxksLfcShnwi1VReGeOT9NI43hLHbknosKp/1CCLn9Zgcs8mg==} peerDependencies: @@ -3589,10 +3586,6 @@ snapshots: dependencies: '@types/yargs-parser': 21.0.3 - '@versini/dev-dependencies-common@15.0.0(@biomejs/biome@2.6.2)': - dependencies: - '@biomejs/biome': 2.6.2 - '@vitest/coverage-v8@5.0.5(vitest@5.0.5)': dependencies: '@bcoe/v8-coverage': 1.0.2 diff --git a/release-please-config.json b/release-please-config.json index 4a4dfdb..ba0c186 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -1,5 +1,6 @@ { "packages": { + "packages/biome-config": {}, "packages/bundlecheck": {}, "packages/bundlesize": {}, "packages/envtools": {},