# core/validators/tokens.validator.ts

> 42 lines of code and 5 definitions.

Tree: GovLab Quality
Language: typescript
Layer: processing
Canonical: https://banes-lab.com/anatomy/quality#file-quality-core-validators-tokens-validator-ts
Source text: https://banes-lab.com/source/quality/core/validators/tokens.validator.ts.txt

Listed in [core/validators](https://banes-lab.com/api/source/quality/core/validators.md), after [core/validators/surface.validator.ts](https://banes-lab.com/source/quality/core/validators/surface.validator.ts.md).

## Definitions

- `strayVarFindings` (lexical_declaration, line 17)
- `isAllowedVarFile` (lexical_declaration, line 9)
- `validate` (method_definition, line 37)
- `normalized` (lexical_declaration, line 10)
- `baseVars` (lexical_declaration, line 38)

## Contained in

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

## Uses

- [configuration/strings/validation.strings.ts](https://banes-lab.com/source/quality/configuration/strings/validation.strings.ts.md)
- [core/factories/finding.factory.ts](https://banes-lab.com/source/quality/core/factories/finding.factory.ts.md)
- [core/parsers/css.parser.ts](https://banes-lab.com/source/quality/core/parsers/css.parser.ts.md)

## Linked from

- [configuration/strings](https://banes-lab.com/anatomy/quality/folder-quality-configuration-strings.md)
- [core/factories](https://banes-lab.com/anatomy/quality/folder-quality-core-factories.md)
- [core/parsers](https://banes-lab.com/anatomy/quality/folder-quality-core-parsers.md)
- [core/validators](https://banes-lab.com/anatomy/quality/folder-quality-core-validators.md)

## Source

```typescript
import { ALLOWED_VAR_DIRS, ALLOWED_VAR_FILES, CSS_EXTENSIONS } from "#configuration/constants/validation.constants";
import { strayVar, strayVarFix } from "#configuration/strings/validation.strings";
import type { FileInput } from "#types/validation.types";
import type { Finding } from "#types/finding.types";
import { defineValidator } from "#core/registries/validation.registry";
import { definedVars } from "#core/parsers/css.parser";
import { projectFinding } from "#core/factories/finding.factory";

const isAllowedVarFile = function isAllowedVarFile(path: string): boolean {
    const normalized = `/${path.split("\\").join("/")}`;
    return (
        ALLOWED_VAR_FILES.some((allowed) => normalized.endsWith(allowed)) ||
        ALLOWED_VAR_DIRS.some((dir) => normalized.includes(dir))
    );
};

const strayVarFindings = function strayVarFindings(file: FileInput, baseVars: ReadonlySet<string>): Finding[] {
    return [...new Set(definedVars(file.content))]
        .filter((name) => !baseVars.has(name))
        .map((name) =>
            projectFinding({
                file: file.path,
                message: strayVar(name),
                ruleId: "css-variable-location",
                suggestion: strayVarFix(name),
            }),
        );
};

defineValidator({
    appliesTo: CSS_EXTENSIONS,
    id: "css-variable-location",
    meta: {
        canonical: ["css-architecture", "design-tokens"],
        description: "Require custom-property definitions to live in the token/config files",
    },
    validate(files): Finding[] {
        const baseVars = new Set(
            files.filter((entry) => isAllowedVarFile(entry.path)).flatMap((entry) => definedVars(entry.content)),
        );
        return files
            .filter((entry) => !isAllowedVarFile(entry.path))
            .flatMap((entry) => strayVarFindings(entry, baseVars));
    },
});
```
