/* * SPDX-FileCopyrightText: 2024-2025 Pagefault Games * * SPDX-License-Identifier: AGPL-3.0-only */ { "$schema": "https://biomejs.dev/schemas/2.6.6/schema.json", "vcs": { "enabled": true, "clientKind": "git", "useIgnoreFile": true, "defaultBranch": "beta" }, "formatter": { "enabled": true, "useEditorconfig": true, "indentStyle": "space", "includes": ["**"], "lineWidth": 120 }, "files": { "ignoreUnknown": true, // Adding folders to the ignore list is GREAT for performance because it prevents biome from descending into them // and having to verify whether each individual file is ignored "includes": [ "**", "!.github/**/*.*", // workaround due to bug/design limitation, should be `"!.github"` ".github/**/*.ts", ".github/**/*.mts", "!!assets", "!!coverage", "!!dist*", "!!docs", "!!locales", "!!typedoc", // TODO: lint/format these file types? "!!*.css", "!!*.html", "!!*.yml", "!!*.yaml", "!!*.md", // this file is too big "!src/data/balance/tm-species-map.ts" ] }, "assist": { "actions": { "source": { "organizeImports": { "level": "on", "options": { "groups": [":ALIAS:", ":NODE:", ":PACKAGE_WITH_PROTOCOL:", ":PACKAGE:", ":PATH:"] } } } } }, "linter": { "enabled": true, "rules": { "preset": "recommended", "correctness": { "noUndeclaredVariables": "error", // we virtually always use base 10 number conversion "useParseIntRadix": "off", "noUnusedVariables": "error", "noSwitchDeclarations": "error", "noVoidTypeReturn": "error", "noUnusedImports": { "level": "error", "fix": "safe" }, "noUnusedFunctionParameters": "error", "noUnusedLabels": "error", "noPrivateImports": "error", "useSingleJsDocAsterisk": "error", "useJsonImportAttributes": "off" // "Import attributes are only supported when the '--module' option is set to 'esnext', 'node18', 'nodenext', or 'preserve'. ts(2823)" }, "style": { "useExplicitLengthCheck": { "level": "error", "fix": "safe" }, "useAtIndex": "error", "noNegationElse": "error", // TODO: Fix all instances of this and promote to `error` - this and enums are the 2 things // barring us from `esModuleInterop` "noParameterProperties": "warn", "useConsistentBuiltinInstantiation": { "level": "error", "fix": "safe" }, "noDefaultExport": "warn", // TODO: Fix `overrides.ts` and enable "noShoutyConstants": "error", "useThrowNewError": { "level": "error", "fix": "safe" }, "useThrowOnlyError": "error", "useTrimStartEnd": "error", "useReadonlyClassProperties": { "level": "info", // TODO: Graduate to error eventually // NOTE: "checkAllProperties" has an immature implementation that // causes many false positives across files. Enable if/when maturity improves "options": { "checkAllProperties": false } }, "useConsistentObjectDefinitions": { "level": "error", "options": { "syntax": "shorthand" } }, "useCollapsedIf": "error", "useCollapsedElseIf": "error", "useDeprecatedReason": "error", "useConsistentArrayType": { "level": "error", "fix": "safe" }, "useShorthandAssign": { "level": "error", "fix": "safe" }, "noSubstr": "error", "noYodaExpression": "error", "useForOf": "error", "useEnumInitializers": "off", // large enums like MoveId/SpeciesId would make this cumbersome "useBlockStatements": { "level": "error", "fix": "safe" }, "useConst": "error", "useImportType": "error", "noNonNullAssertion": "off", // TODO: Turn this on ASAP and fix all non-null assertions in non-test files "noParameterAssign": "off", "useExponentiationOperator": "off", // Too typo-prone and easy to mixup with standard multiplication (* vs **) "useDefaultParameterLast": { // TODO: Fix spots in the codebase where this flag would be triggered // and then set to "error" and re-enable the fixer "level": "warn", "fix": "none" }, "useSingleVarDeclarator": { "level": "error", "fix": "safe" }, // TODO: Consider enabling "useNodejsImportProtocol": "off", // String concatenation can be more readable than template literals // in some situations. "useTemplate": "off", "useAsConstAssertion": "error", "noUnusedTemplateLiteral": "error", "useNumberNamespace": "error", "noInferrableTypes": "error", "noUselessElse": "error", "noRestrictedTypes": { "level": "error", "options": { "types": { "integer": { "message": "This is an alias for 'number' that can provide false impressions of what values can actually be contained in this variable. Use 'number' instead.", "use": "number" } } } }, "useUnifiedTypeSignatures": { "level": "warn", "fix": "unsafe", "options": { // Disable warnings on functions that differ only by parameter names or JSDoc comments, as these are often intentional // (e.g. marking one overload as deprecated) "ignoreDifferentlyNamedParameters": true, "ignoreDifferentJsDoc": true } }, "useGroupedAccessorPairs": "error", "useObjectSpread": "error", "useNumericSeparators": "off", // TODO: Consider enabling? "useNamingConvention": { "level": "error", "options": { "requireAscii": true, "strictCase": false, // evaluated in order from top to bottom "conventions": [ { "selector": { "kind": "interface" }, "formats": ["PascalCase"] }, { "selector": { "kind": "typeAlias" }, "formats": ["PascalCase"] }, { "selector": { "kind": "class" }, "formats": ["PascalCase"] }, { "selector": { "kind": "enum" }, "formats": ["PascalCase"] }, { "selector": { "kind": "enumMember" }, "formats": ["CONSTANT_CASE"] }, // having this section last disables the built-in conventions { "match": ".*" } ] } }, "noRestrictedImports": { "level": "error", "options": { "paths": { "node:test": { "message": "Do not import from `node:test`, use `vitest`" } } } }, "noMultiAssign": "error", "noMultilineString": "error", "noNestedTernary": "warn" // TODO: fix existing instances and make "error" }, "suspicious": { "noExtraNonNullAssertion": "error", "useErrorMessage": "error", "noEvolvingTypes": "error", "noImplicitAnyLet": "off", // covered by noEvolvingTypes; no need for duplicate warnings "useNumberToFixedDigitsArgument": "error", "useGuardForIn": "warn", // TODO: Review and enable ASAP "noDoubleEquals": "error", // While this would be a nice rule to enable, the current structure of the codebase makes this infeasible // due to being used for move/ability `args` params and save data-related code. // This can likely be enabled for all non-utils files once these are eventually reworked, but until then we leave it off. "noExplicitAny": "off", "noAssignInExpressions": "info", // TODO: Increase to "error" once all instances are fixed "noPrototypeBuiltins": "error", "noFallthroughSwitchClause": "error", // Prevents accidental automatic fallthroughs in switch cases (use disable comment if needed) "noRedeclare": "info", // TODO: Refactor and make this an error "noGlobalIsNan": "error", "noGlobalIsFinite": "error", "noAsyncPromiseExecutor": "warn", // TODO: Refactor and make this an error "noVar": "error", "noDocumentCookie": "off", // Firefox has minimal support for the "Cookie Store API" "noConstantBinaryExpressions": "error", "noTsIgnore": "error", "useIterableCallbackReturn": { "level": "warn", // TODO: refactor and make error "options": { "checkForEach": false } }, "noNonNullAssertedOptionalChain": "warn", // TODO: Refactor and change to error "noDuplicateDependencies": "error", "noImportCycles": "error", "noProto": "error", "noShadow": "warn" // TODO: refactor and make "error" }, "complexity": { "useWhile": "error", "noVoid": "warn", // TODO: Review and enable ASAP - this is also bad "noUselessStringConcat": "error", "noExcessiveCognitiveComplexity": "info", // TODO: Refactor and make this an error "useLiteralKeys": "off", // TODO: enable? "noForEach": "off", // Foreach vs for of is not that simple. "noUselessSwitchCase": "off", // Explicit > Implicit "noUselessConstructor": "error", "noBannedTypes": "error", "noThisInStatic": "error", "noUselessThisAlias": "error", "noUselessTernary": "error", "useIndexOf": "error", "noUselessUndefined": "error", "useMaxParams": { "level": "info", // TODO: Change to "error"... eventually... "options": { "max": 7 } }, "useArrayFind": "error" }, "performance": { "noNamespaceImport": "error", "noDelete": "error", "noBarrelFile": "error" }, "nursery": { // TODO: Fix violations then enable this "useAwaitThenable": "off", // TODO: Change to error once promises are used properly "noMisusedPromises": "info" } } }, "javascript": { "formatter": { "quoteStyle": "double", "arrowParentheses": "asNeeded", "operatorLinebreak": "before" }, "globals": [], "parser": { "jsxEverywhere": false } }, "overrides": [ { "includes": ["**/src/ai/**/*.ts"], "linter": { "rules": { "complexity": { "noExcessiveCognitiveComplexity": { "level": "info", "options": { // Code for AI behavior can have a slightly higher complexity due to the nature of decision trees and such "maxAllowedComplexity": 20 } } } } } }, { "includes": ["scripts/**/*"], "linter": { "rules": { "style": { // TODO: Remove this and replace it with an ambient module declaration once TSGo is capable of handling these "noRestrictedImports": { "level": "error", "options": { "paths": { "commander": { "message": "Imports from the commander package lack the strict type safety of @commander-js/extra-typings, producing type errors when passed to relevant utility functions." } } } } }, "nursery": { "noFloatingPromises": "error" } } } }, { "includes": ["**/test/**/*.test.ts"], "linter": { "rules": { "performance": { "noDelete": "off", // TODO: evaluate if this is necessary for the test(s) to function "noNamespaceImport": "off" // this is required for `vi.spyOn` to work in some tests }, "style": { "noNonNullAssertion": "off" // tedious in some tests }, "nursery": { // TODO: Enable for normal test folder files as well "noFloatingPromises": "error" } } } }, // Prevent forcing type-only imports inside `overrides.ts` (where they serve as placeholders for actual runtime symbols) { "includes": ["**/src/overrides.ts"], "linter": { "rules": { "style": { "useImportType": "off" } } } }, { "includes": ["src/**/*.ts"], "linter": { "rules": { "style": { "noRestrictedImports": { "level": "error", "options": { "patterns": [ { "group": ["#test/*"], "message": "Do not import files from `test/` in `src/`." } ] } } } } } }, { "includes": ["src/data/balance/moves/egg-moves.ts"], "formatter": { "lineWidth": 150 } } ] }