# core/resolvers/evidence.resolver.ts

> 80 lines of code and 13 definitions.

Tree: Bane's Lab Build Scripts
Language: typescript
Layer: infrastructure
Canonical: https://banes-lab.com/anatomy/build-scripts#file-build-scripts-core-resolvers-evidence-resolver-ts
Source text: https://banes-lab.com/source/build-scripts/core/resolvers/evidence.resolver.ts.txt

Listed in [core/resolvers](https://banes-lab.com/api/source/build-scripts/core/resolvers.md), after [core/resolvers/diagram.resolver.ts](https://banes-lab.com/source/build-scripts/core/resolvers/diagram.resolver.ts.md) and before [core/resolvers/graph.resolver.ts](https://banes-lab.com/source/build-scripts/core/resolvers/graph.resolver.ts.md).

## Definitions

- `definitionKey` (lexical_declaration, line 16)
- `definitionIdsOf` (lexical_declaration, line 20)
- `codeTargetRefOf` (lexical_declaration, line 33, exported)
- `KEY_JOINER` (lexical_declaration, line 9)
- `PATH_SEPARATOR` (lexical_declaration, line 10)
- `filesOf` (lexical_declaration, line 12)
- `{ file, line, name }` (lexical_declaration, line 41, exported)
- `evidenceTargetOf` (lexical_declaration, line 64, exported)
- `definitions` (lexical_declaration, line 69, exported)
- `location` (lexical_declaration, line 72, exported)
- `id` (lexical_declaration, line 73, exported)
- `path` (lexical_declaration, line 80, exported)
- `folder` (lexical_declaration, line 83, exported)

## Contained in

- [core/resolvers](https://banes-lab.com/anatomy/build-scripts/folder-build-scripts-core-resolvers.md)

## Uses

- [configuration/strings/graph.strings.ts](https://banes-lab.com/source/build-scripts/configuration/strings/graph.strings.ts.md)

## Linked from

- [configuration/strings](https://banes-lab.com/anatomy/build-scripts/folder-build-scripts-configuration-strings.md)
- [core/resolvers](https://banes-lab.com/anatomy/build-scripts/folder-build-scripts-core-resolvers.md)

## Source

```typescript
import type { AnatomyFile, AnatomyFolder } from "@banes-lab/web/types/anatomy.types.js";
import { ANATOMY_PREFIX } from "#configuration/constants/graph.constants";
import type { CodeTarget } from "@banes-lab/web/types/code.types.js";
import type { DefinitionIndex } from "@banes-lab/web/types/definition.types.js";
import type { EvidenceNode } from "@banes-lab/web/types/evidence.types.js";
import type { SourceIds } from "#types/graph.types";
import { unknownTargetKind } from "#configuration/strings/graph.strings";

const KEY_JOINER = "\n";
const PATH_SEPARATOR = "/";

const filesOf = function filesOf(folder: AnatomyFolder): readonly AnatomyFile[] {
    return [...folder.files, ...folder.folders.flatMap(filesOf)];
};

const definitionKey = function definitionKey(file: string, line: number, name: string): string {
    return [file, String(line), name].join(KEY_JOINER);
};

const definitionIdsOf = function definitionIdsOf(roots: readonly AnatomyFolder[]): ReadonlyMap<string, string> {
    return new Map(
        roots
            .flatMap(filesOf)
            .flatMap((file) =>
                file.definitions.map(
                    (definition) =>
                        [definitionKey(file.path, definition.line, definition.name), definition.id] as const,
                ),
            ),
    );
};

export const codeTargetRefOf = function codeTargetRefOf(
    roots: readonly AnatomyFolder[],
    ids: Pick<SourceIds, "fileId" | "folderId">,
): (target: CodeTarget) => string | null {
    const definitions = definitionIdsOf(roots);
    return (target) => {
        switch (target.kind) {
            case "definition": {
                const { file, line, name } = target.location;
                const id = definitions.get(definitionKey(file, line, name));
                return id === undefined ? null : ANATOMY_PREFIX + id;
            }
            case "file": {
                return ANATOMY_PREFIX + ids.fileId(target.path);
            }
            case "folder": {
                return ANATOMY_PREFIX + ids.folderId(target.path);
            }
            case "record": {
                return target.ref;
            }
            case "candidates": {
                return null;
            }
            default: {
                throw new Error(unknownTargetKind(JSON.stringify(target)));
            }
        }
    };
};

export const evidenceTargetOf = function evidenceTargetOf(
    roots: readonly AnatomyFolder[],
    index: DefinitionIndex,
    ids: Pick<SourceIds, "fileId" | "folderId">,
): (node: EvidenceNode) => string | null {
    const definitions = definitionIdsOf(roots);
    return (node) => {
        if (node.kind === "definition") {
            const location = index.citedDefinition(node.name, node.file);
            const id =
                location === null
                    ? undefined
                    : definitions.get(definitionKey(location.file, location.line, location.name));
            return id === undefined ? null : ANATOMY_PREFIX + id;
        }
        if (node.kind === "file") {
            const path = index.resolvePath(node.name);
            return path === null ? null : ANATOMY_PREFIX + ids.fileId(path);
        }
        const folder = index.resolveFolder(node.words.join(PATH_SEPARATOR));
        return folder === null ? null : ANATOMY_PREFIX + ids.folderId(folder);
    };
};
```
