# core/selectors/field.selector.ts

> 21 lines of code and 4 definitions.

Tree: GovLab Context
Language: typescript
Layer: application
Canonical: https://banes-lab.com/anatomy/context#file-context-core-selectors-field-selector-ts
Source text: https://banes-lab.com/source/context/core/selectors/field.selector.ts.txt

Listed in [core/selectors](https://banes-lab.com/api/source/context/core/selectors.md), after [core/selectors/document.selector.ts](https://banes-lab.com/source/context/core/selectors/document.selector.ts.md) and before [core/selectors/grammar.selector.ts](https://banes-lab.com/source/context/core/selectors/grammar.selector.ts.md).

## Definitions

- `valuesAt` (lexical_declaration, line 18, exported)
- `fieldValue` (lexical_declaration, line 14, exported)
- `stepInto` (lexical_declaration, line 4)
- `value` (lexical_declaration, line 19, exported)

## Contained in

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

## Uses

- [core/predicates/record.predicate.ts](https://banes-lab.com/source/context/core/predicates/record.predicate.ts.md)

## Used by

- [core/validators/field.validator.ts](https://banes-lab.com/source/context/core/validators/field.validator.ts.md)

## Linked from

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

## Source

```typescript
import { isPlainRecord, isStringList } from "#core/predicates/record.predicate";
import { PATH_MARK } from "#configuration/constants/field.constants";

const stepInto = function stepInto(held: unknown, key: string): unknown {
    if (Array.isArray(held)) {
        return held.flatMap((item) => {
            const value = stepInto(item, key);
            return value === undefined ? [] : [value];
        });
    }
    return isPlainRecord(held) ? held[key] : undefined;
};

export const fieldValue = function fieldValue(record: unknown, path: string): unknown {
    return path.split(PATH_MARK).reduce(stepInto, record);
};

export const valuesAt = function valuesAt(record: unknown, path: string): string[] {
    const value = fieldValue(record, path);
    if (typeof value === "string") {
        return [value];
    }
    return isStringList(value) ? value : [];
};
```
