# core/schemas/tool.schema.ts

> 99 lines of code and 31 definitions.

Tree: GovLab Quality
Language: typescript
Layer: infrastructure
Canonical: https://banes-lab.com/anatomy/quality#file-quality-core-schemas-tool-schema-ts
Source text: https://banes-lab.com/source/quality/core/schemas/tool.schema.ts.txt

Listed in [core/schemas](https://banes-lab.com/api/source/quality/core/schemas.md), after [core/schemas/eslint.schema.ts](https://banes-lab.com/source/quality/core/schemas/eslint.schema.ts.md).

## Definitions

- `objectWithStringFields` (lexical_declaration, line 13)
- `objectWithExtras` (lexical_declaration, line 19)
- `stylelintSection` (lexical_declaration, line 22, exported)
- `prettierSection` (lexical_declaration, line 28, exported)
- `htmlhintSection` (lexical_declaration, line 33, exported)
- `yamllintSection` (lexical_declaration, line 38, exported)
- `knipSection` (lexical_declaration, line 44, exported)
- `jscpdSection` (lexical_declaration, line 46, exported)
- `oxlintSection` (lexical_declaration, line 54, exported)
- `sqlfluffSection` (lexical_declaration, line 65, exported)
- `banditSection` (lexical_declaration, line 66, exported)
- `clangTidySection` (lexical_declaration, line 67, exported)
- `checkstyleSection` (lexical_declaration, line 68, exported)
- `pmdSection` (lexical_declaration, line 69, exported)
- `swiftlintSection` (lexical_declaration, line 70, exported)
- `kicsSection` (lexical_declaration, line 71, exported)
- `credoSection` (lexical_declaration, line 72, exported)
- `lintrSection` (lexical_declaration, line 73, exported)
- `perlcriticSection` (lexical_declaration, line 74, exported)
- `semgrepSection` (lexical_declaration, line 75, exported)
- `slitherSection` (lexical_declaration, line 76, exported)
- `cljKondoSection` (lexical_declaration, line 77, exported)
- `scalastyleSection` (lexical_declaration, line 78, exported)
- `detektSection` (lexical_declaration, line 79, exported)
- `checkovSection` (lexical_declaration, line 80, exported)
- `styluaSection` (lexical_declaration, line 82, exported)
- `phpcsSection` (lexical_declaration, line 84, exported)
- `validate` (method_definition, line 86, exported)
- `phpmdSection` (lexical_declaration, line 93, exported)
- `hadolintSection` (lexical_declaration, line 101, exported)
- `shellcheckSection` (lexical_declaration, line 108, exported)

## Contained in

- [core/schemas](https://banes-lab.com/anatomy/quality/folder-quality-core-schemas.md)

## Uses

- [core/adapters/tool.knip.adapter.ts](https://banes-lab.com/source/quality/core/adapters/tool.knip.adapter.ts.md)
- [core/registries/section.registry.ts](https://banes-lab.com/source/quality/core/registries/section.registry.ts.md)
- [core/validators/section.validator.ts](https://banes-lab.com/source/quality/core/validators/section.validator.ts.md)

## Linked from

- [core/adapters](https://banes-lab.com/anatomy/quality/folder-quality-core-adapters.md)
- [core/registries](https://banes-lab.com/anatomy/quality/folder-quality-core-registries.md)
- [core/validators](https://banes-lab.com/anatomy/quality/folder-quality-core-validators.md)

## Source

```typescript
import {
    MUST_BE_OBJECT,
    booleanFieldError,
    isObject,
    requireObjectField,
    stringArrayFieldError,
    stringFieldErrors,
    validateBlockExclusions,
} from "#core/validators/section.validator";
import type { ConfigSection } from "#types/config.types";
import { defineConfigSection } from "#core/registries/section.registry";

const objectWithStringFields = (key: string, fields: string[]): ConfigSection =>
    defineConfigSection({
        key,
        validate: (value) => (isObject(value) ? stringFieldErrors(value, fields) : [MUST_BE_OBJECT]),
    });

const objectWithExtras = (key: string, extras: (value: Record<string, unknown>) => string[]): ConfigSection =>
    defineConfigSection({ key, validate: (value) => (isObject(value) ? extras(value) : [MUST_BE_OBJECT]) });

export const stylelintSection = objectWithExtras("stylelint", (value) => [
    ...requireObjectField(value, "base"),
    ...requireObjectField(value, "rules"),
    ...stringArrayFieldError(value, "exclude", "exclude must be an array of strings"),
]);

export const prettierSection = objectWithExtras("prettier", (value) => [
    ...requireObjectField(value, "base"),
    ...stringArrayFieldError(value, "ignore", "ignore must be an array of strings"),
]);

export const htmlhintSection = objectWithExtras("htmlhint", (value) => [
    ...requireObjectField(value, "rules"),
    ...stringArrayFieldError(value, "ignore", "ignore must be an array of strings"),
]);

export const yamllintSection = objectWithExtras("yamllint", (value) => [
    ...stringFieldErrors(value, ["command", "extends"]),
    ...requireObjectField(value, "rules"),
    ...stringArrayFieldError(value, "ignore", "ignore must be an array of strings"),
]);

export const knipSection = objectWithExtras("knip", () => []);

export const jscpdSection = objectWithExtras("jscpd", (value) => [
    ...["threshold", "minTokens", "minLines"]
        .filter((key) => value[key] !== undefined && typeof value[key] !== "number")
        .map((key) => `${key} must be a number`),
    ...stringArrayFieldError(value, "ignore", "ignore must be an array of globs"),
    ...stringArrayFieldError(value, "format", "format must be an array of jscpd format ids"),
]);

export const oxlintSection = objectWithExtras("oxlint", (value) => [
    ...stringArrayFieldError(value, "plugins", "plugins must be an array of strings"),
    ...requireObjectField(value, "categories"),
    ...requireObjectField(value, "rules"),
    ...requireObjectField(value, "env"),
    ...requireObjectField(value, "globals"),
    ...stringArrayFieldError(value, "ignorePatterns", "ignorePatterns must be an array of strings"),
    ...stringArrayFieldError(value, "reportOnly", "reportOnly must be an array of rule ids"),
    ...validateBlockExclusions(value["blockExclusions"]),
]);

export const sqlfluffSection = objectWithStringFields("sqlfluff", ["command", "dialect"]);
export const banditSection = objectWithStringFields("bandit", ["command"]);
export const clangTidySection = objectWithStringFields("clang-tidy", ["checks"]);
export const checkstyleSection = objectWithStringFields("checkstyle", ["command", "config"]);
export const pmdSection = objectWithStringFields("pmd", ["command", "ruleset"]);
export const swiftlintSection = objectWithStringFields("swiftlint", ["command"]);
export const kicsSection = objectWithStringFields("kics", ["command", "queries", "libraries"]);
export const credoSection = objectWithStringFields("credo", ["command"]);
export const lintrSection = objectWithStringFields("lintr", ["command"]);
export const perlcriticSection = objectWithStringFields("perlcritic", ["command", "severity"]);
export const semgrepSection = objectWithStringFields("semgrep", ["command", "config"]);
export const slitherSection = objectWithStringFields("slither", ["command", "solc"]);
export const cljKondoSection = objectWithStringFields("clj-kondo", ["command", "config"]);
export const scalastyleSection = objectWithStringFields("scalastyle", ["command", "config"]);
export const detektSection = objectWithStringFields("detekt", ["command", "config"]);
export const checkovSection = objectWithStringFields("checkov", ["command"]);

export const styluaSection = objectWithExtras("stylua", () => []);

export const phpcsSection = defineConfigSection({
    key: "phpcs",
    validate(value) {
        return isObject(value) && (!Object.hasOwn(value, "standard") || typeof value["standard"] === "string")
            ? []
            : ["must be an object with an optional string `standard`"];
    },
});

export const phpmdSection = objectWithExtras("phpmd", (value) =>
    stringArrayFieldError(
        value,
        "rulesets",
        "rulesets must be an array of strings (phpmd rule-set names or ruleset.xml paths)",
    ),
);

export const hadolintSection = objectWithExtras("hadolint", (value) => [
    ...(Object.hasOwn(value, "failureThreshold") && typeof value["failureThreshold"] !== "string"
        ? ["failureThreshold must be a string (error | warning | info | style)"]
        : []),
    ...stringArrayFieldError(value, "ignore", "ignore must be an array of strings (DL rule ids)"),
]);

export const shellcheckSection = objectWithExtras("shellcheck", (value) => [
    ...(Object.hasOwn(value, "severity") && typeof value["severity"] !== "string"
        ? ["severity must be a string (error | warning | info | style)"]
        : []),
    ...booleanFieldError(value, "enableAll", "enableAll must be a boolean"),
    ...stringArrayFieldError(value, "exclude", "exclude must be an array of strings"),
]);
```
