# core/selectors/metadata.selector.ts

> 29 lines of code and 13 definitions.

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

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

## Definitions

- `docStem` (lexical_declaration, line 24, exported)
- `stemParts` (lexical_declaration, line 30, exported)
- `POSIX_SEPARATOR` (lexical_declaration, line 4)
- `EXTENSION_DOT` (lexical_declaration, line 5)
- `DEFAULT_PROFILE` (lexical_declaration, line 7)
- `spineProfileFor` (lexical_declaration, line 9, exported)
- `{ harnessRoot }` (lexical_declaration, line 10, exported)
- `profile` (lexical_declaration, line 14, exported)
- `docBasename` (lexical_declaration, line 20, exported)
- `filename` (lexical_declaration, line 25, exported)
- `suffix` (lexical_declaration, line 31, exported)
- `bare` (lexical_declaration, line 32, exported)
- `dot` (lexical_declaration, line 33, exported)

## Contained in

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

## Used by

- [core/analyzers/document.analyzer.ts](https://banes-lab.com/source/docs/core/analyzers/document.analyzer.ts.md)

## Linked from

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

## Source

```typescript
import type { SpineContext, SpineProfile, StemParts } from "#types/document.types";
import { SPINE_KEYS } from "#configuration/constants/document.constants";

const POSIX_SEPARATOR = "/";
const EXTENSION_DOT = ".";

const DEFAULT_PROFILE: SpineProfile = { keys: [...SPINE_KEYS], requireFrontmatter: true, requireTitle: true };

export const spineProfileFor = function spineProfileFor(relDoc: string, context: SpineContext): SpineProfile {
    const { harnessRoot } = context;
    if (harnessRoot === null || !relDoc.startsWith(harnessRoot)) {
        return DEFAULT_PROFILE;
    }
    const profile = context.harnessProfiles.find((candidate) => relDoc.startsWith(harnessRoot + candidate.prefix));
    return profile === undefined
        ? DEFAULT_PROFILE
        : { keys: profile.keys, requireFrontmatter: profile.requireFrontmatter, requireTitle: profile.requireTitle };
};

export const docBasename = function docBasename(relDoc: string): string {
    return relDoc.slice(relDoc.lastIndexOf(POSIX_SEPARATOR) + 1);
};

export const docStem = function docStem(relDoc: string): string {
    const filename = docBasename(relDoc);
    const dot = filename.lastIndexOf(EXTENSION_DOT);
    return dot === -1 ? filename : filename.slice(0, dot);
};

export const stemParts = function stemParts(stem: string, tag?: string): StemParts {
    const suffix = `${EXTENSION_DOT}${tag ?? ""}`;
    const bare = tag !== undefined && tag.length > 0 && stem.endsWith(suffix) ? stem.slice(0, -suffix.length) : stem;
    const dot = bare.lastIndexOf(EXTENSION_DOT);
    return dot === -1 ? { name: bare } : { member: bare.slice(dot + 1), name: bare.slice(0, dot) };
};
```
