# core/selectors/site.selector.ts

> 41 lines of code and 10 definitions.

Tree: Bane's Lab Build Scripts
Language: typescript
Layer: application
Canonical: https://banes-lab.com/anatomy/build-scripts#file-build-scripts-core-selectors-site-selector-ts
Source text: https://banes-lab.com/source/build-scripts/core/selectors/site.selector.ts.txt

Listed in [core/selectors](https://banes-lab.com/api/source/build-scripts/core/selectors.md), after [core/selectors/record.selector.ts](https://banes-lab.com/source/build-scripts/core/selectors/record.selector.ts.md).

## Definitions

- `fullTextParts` (lexical_declaration, line 18, exported)
- `fullTextRoutes` (lexical_declaration, line 14, exported)
- `tabContentOf` (lexical_declaration, line 32, exported)
- `routeContentOf` (lexical_declaration, line 47, exported)
- `isFullTextRoute` (lexical_declaration, line 6, exported)
- `fullTextFileOf` (lexical_declaration, line 10, exported)
- `isTab` (lexical_declaration, line 28)
- `SLASH` (lexical_declaration, line 4)
- `routeOf` (lexical_declaration, line 39, exported)
- `page` (lexical_declaration, line 48, exported)

## Contained in

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

## Used by

- [core/coordinators/payload.coordinator.ts](https://banes-lab.com/source/build-scripts/core/coordinators/payload.coordinator.ts.md)
- [core/formatters/site.formatter.ts](https://banes-lab.com/source/build-scripts/core/formatters/site.formatter.ts.md)
- [core/persistence/page.persistence.ts](https://banes-lab.com/source/build-scripts/core/persistence/page.persistence.ts.md)

## Linked from

- [core/coordinators](https://banes-lab.com/anatomy/build-scripts/folder-build-scripts-core-coordinators.md)
- [core/formatters](https://banes-lab.com/anatomy/build-scripts/folder-build-scripts-core-formatters.md)
- [core/persistence](https://banes-lab.com/anatomy/build-scripts/folder-build-scripts-core-persistence.md)
- [core/selectors](https://banes-lab.com/anatomy/build-scripts/folder-build-scripts-core-selectors.md)

## Source

```typescript
import type { DiscoveredRoute, Discovery, FullTextPart } from "#types/site.types";
import { FULL_TEXT_EXTENSION, FULL_TEXT_FOLDER, REFERENCE_PAGES } from "#configuration/constants/site.constants";

const SLASH = "/";

export const isFullTextRoute = function isFullTextRoute(route: { readonly page: string }): boolean {
    return !REFERENCE_PAGES.has(route.page);
};

export const fullTextFileOf = function fullTextFileOf(page: string): string {
    return FULL_TEXT_FOLDER + SLASH + page + FULL_TEXT_EXTENSION;
};

export const fullTextRoutes = function fullTextRoutes(discovery: Discovery): readonly DiscoveredRoute[] {
    return discovery.routes.filter(isFullTextRoute);
};

export const fullTextParts = function fullTextParts(discovery: Discovery): readonly FullTextPart[] {
    return discovery.pages
        .filter((page) => isFullTextRoute({ page: page.id }))
        .map((page) => ({
            file: fullTextFileOf(page.id),
            label: page.label,
            routes: discovery.routes.filter((route) => route.page === page.id),
        }));
};

const isTab = function isTab(value: unknown): value is { readonly id: string } {
    return typeof value === "object" && value !== null && "id" in value && typeof value.id === "string";
};

export const tabContentOf = function tabContentOf(content: unknown, tab: string): unknown {
    if (typeof content !== "object" || content === null || !("tabs" in content) || !Array.isArray(content.tabs)) {
        return undefined;
    }
    return content.tabs.find((entry: unknown) => isTab(entry) && entry.id === tab);
};

export const routeOf = function routeOf(
    discovery: Discovery,
    page: string,
    tab: string | null,
): DiscoveredRoute | undefined {
    return discovery.routes.find((route) => route.page === page && route.tab === tab);
};

export const routeContentOf = function routeContentOf(discovery: Discovery, route: DiscoveredRoute): unknown {
    const page = discovery.pages.find((candidate) => candidate.id === route.page);
    return route.tab === null ? page?.content : tabContentOf(page?.content, route.tab);
};
```
