# core/selectors/context.fragment.selector.ts

> 69 lines of code and 16 definitions.

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

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

## Definitions

- `stringValue` (lexical_declaration, line 58, exported)
- `identifierName` (lexical_declaration, line 4, exported)
- `keyName` (lexical_declaration, line 17)
- `property` (lexical_declaration, line 45, exported)
- `fragmentObject` (lexical_declaration, line 8, exported)
- `stringArrayValues` (lexical_declaration, line 65, exported)
- `args` (lexical_declaration, line 12, exported)
- `first` (lexical_declaration, line 13, exported)
- `{ key }` (lexical_declaration, line 21)
- `propertyNames` (lexical_declaration, line 31, exported)
- `names` (lexical_declaration, line 32, exported)
- `name` (lexical_declaration, line 36, exported)
- `{ properties }` (lexical_declaration, line 46, exported)
- `{ value }` (lexical_declaration, line 50, exported)
- `out` (lexical_declaration, line 66, exported)
- `value` (lexical_declaration, line 69, exported)

## Contained in

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

## Uses

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

## Used by

- [core/fragment/eslint/no-duplicate-fragment.eslint.rule.ts](https://banes-lab.com/source/quality/core/fragment/eslint/no-duplicate-fragment.eslint.rule.ts.md)
- [core/fragment/eslint/no-inline-context-literal.eslint.rule.ts](https://banes-lab.com/source/quality/core/fragment/eslint/no-inline-context-literal.eslint.rule.ts.md)
- [core/fragment/eslint/require-fragment-metadata.eslint.rule.ts](https://banes-lab.com/source/quality/core/fragment/eslint/require-fragment-metadata.eslint.rule.ts.md)

## Linked from

- [core/fragment/eslint](https://banes-lab.com/anatomy/quality/folder-quality-core-fragment-eslint.md)
- [core/predicates](https://banes-lab.com/anatomy/quality/folder-quality-core-predicates.md)
- [core/selectors](https://banes-lab.com/anatomy/quality/folder-quality-core-selectors.md)

## Source

```typescript
import { isArray, isNode, isRecord } from "#core/predicates/context.fragment.predicate";
import type { AstNode } from "#types/context.types";

export const identifierName = function identifierName(node: unknown): string | null {
    return isNode(node) && node.type === "Identifier" && typeof node["name"] === "string" ? node["name"] : null;
};

export const fragmentObject = function fragmentObject(node: unknown): AstNode | null {
    if (!isRecord(node)) {
        return null;
    }
    const args = node["arguments"];
    const first = isArray(args) ? args[0] : null;
    return isNode(first) && first.type === "ObjectExpression" ? first : null;
};

const keyName = function keyName(candidate: unknown): string | null {
    if (!isRecord(candidate)) {
        return null;
    }
    const { key } = candidate;
    if (!isRecord(key)) {
        return null;
    }
    if (typeof key["name"] === "string") {
        return key["name"];
    }
    return typeof key["value"] === "string" ? key["value"] : null;
};

export const propertyNames = function propertyNames(object: AstNode): Set<string> {
    const names = new Set<string>();
    const { properties } = object;
    if (Array.isArray(properties)) {
        for (const prop of properties) {
            const name = keyName(prop);
            if (name !== null) {
                names.add(name);
            }
        }
    }
    return names;
};

export const property = function property(object: AstNode, name: string): AstNode | null {
    const { properties } = object;
    if (Array.isArray(properties)) {
        for (const prop of properties) {
            if (keyName(prop) === name && isRecord(prop)) {
                const { value } = prop;
                return isNode(value) ? value : null;
            }
        }
    }
    return null;
};

export const stringValue = function stringValue(node: unknown): string | null {
    if (isNode(node) && node.type === "Literal" && typeof node["value"] === "string") {
        return node["value"];
    }
    return null;
};

export const stringArrayValues = function stringArrayValues(node: unknown): string[] {
    const out: string[] = [];
    if (isNode(node) && node.type === "ArrayExpression" && Array.isArray(node["elements"])) {
        for (const element of node["elements"]) {
            const value = stringValue(element);
            if (value !== null) {
                out.push(value);
            }
        }
    }
    return out;
};
```
