# core/selectors/catalog.selector.ts

> 46 lines of code and 7 definitions.

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

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

## Definitions

- `at` (lexical_declaration, line 38, exported)
- `columnValues` (lexical_declaration, line 33, exported)
- `rowsOf` (lexical_declaration, line 15, exported)
- `shardFilesOf` (lexical_declaration, line 42, exported)
- `stringsIn` (lexical_declaration, line 5, exported)
- `columns` (lexical_declaration, line 20, exported)
- `parsed` (lexical_declaration, line 43, exported)

## Contained in

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

## Uses

- [core/resolvers/catalog.resolver.ts](https://banes-lab.com/source/build-scripts/core/resolvers/catalog.resolver.ts.md)

## Used by

- [core/validators/catalog.validator.ts](https://banes-lab.com/source/build-scripts/core/validators/catalog.validator.ts.md)

## Linked from

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

## Source

```typescript
import { fileOfAddress, localAddress } from "#core/resolvers/catalog.resolver";
import type { ManifestRow } from "#types/catalog.types";
import { isRecord } from "#core/selectors/base.selector";

export const stringsIn = function stringsIn(value: unknown): string[] {
    if (typeof value === "string") {
        return [value];
    }
    if (Array.isArray(value)) {
        return value.flatMap(stringsIn);
    }
    return isRecord(value) ? Object.values(value).flatMap(stringsIn) : [];
};

export const rowsOf = function rowsOf(raw: string): readonly ManifestRow[] {
    const parsed: unknown = JSON.parse(raw);
    if (!isRecord(parsed) || !Array.isArray(parsed["columns"]) || !Array.isArray(parsed["rows"])) {
        return [];
    }
    const columns: readonly unknown[] = parsed["columns"];
    const at = (name: string): number => columns.indexOf(name);
    return parsed["rows"]
        .filter(Array.isArray)
        .map((row: readonly unknown[]) => ({
            bytes: Number(row[at("bytes")]),
            fingerprint: String(row[at("fingerprint")]),
            json: String(row[at("json")]),
            markdown: typeof row[at("markdown")] === "string" ? String(row[at("markdown")]) : null,
            ref: String(row[at("ref")]),
        }));
};

export const columnValues = function columnValues(raw: string, column: string): readonly unknown[] {
    const parsed: unknown = JSON.parse(raw);
    if (!isRecord(parsed) || !Array.isArray(parsed["columns"]) || !Array.isArray(parsed["rows"])) {
        return [];
    }
    const at = parsed["columns"].indexOf(column);
    return at === -1 ? [] : parsed["rows"].filter(Array.isArray).map((row: readonly unknown[]) => row[at]);
};

export const shardFilesOf = function shardFilesOf(raw: string, site: string): readonly string[] {
    const parsed: unknown = JSON.parse(raw);
    if (!isRecord(parsed) || !Array.isArray(parsed["shards"])) {
        return [];
    }
    return parsed["shards"].flatMap((shard: unknown) =>
        isRecord(shard) && typeof shard["json"] === "string" ? [fileOfAddress(localAddress(site, shard["json"]))] : [],
    );
};
```
