# core/resolvers/location.resolver.ts

> 51 lines of code and 11 definitions.

Tree: GovLab Paths
Language: typescript
Layer: infrastructure
Canonical: https://banes-lab.com/anatomy/paths#file-paths-core-resolvers-location-resolver-ts
Source text: https://banes-lab.com/source/paths/core/resolvers/location.resolver.ts.txt

Listed in [core/resolvers](https://banes-lab.com/api/source/paths/core/resolvers.md), before [core/resolvers/location.root.resolver.ts](https://banes-lab.com/source/paths/core/resolvers/location.root.resolver.ts.md).

## Definitions

- `leafOf` (lexical_declaration, line 30)
- `selfOf` (lexical_declaration, line 8)
- `terminalOf` (lexical_declaration, line 20)
- `stepInto` (lexical_declaration, line 13)
- `absolutePath` (lexical_declaration, line 51, exported)
- `relativePath` (lexical_declaration, line 55, exported)
- `parts` (lexical_declaration, line 31)
- `prefix` (lexical_declaration, line 32)
- `node` (lexical_declaration, line 33)
- `next` (lexical_declaration, line 35)
- `own` (lexical_declaration, line 42)

## Contained in

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

## Uses

- [configuration/strings/location.strings.ts](https://banes-lab.com/source/paths/configuration/strings/location.strings.ts.md)
- [core/predicates/location.predicate.ts](https://banes-lab.com/source/paths/core/predicates/location.predicate.ts.md)

## Linked from

- [configuration/strings](https://banes-lab.com/anatomy/paths/folder-paths-configuration-strings.md)
- [core/predicates](https://banes-lab.com/anatomy/paths/folder-paths-core-predicates.md)
- [core/resolvers](https://banes-lab.com/anatomy/paths/folder-paths-core-resolvers.md)

## Source

```typescript
import { KEY_SEPARATOR, SEGMENT_SEPARATOR, SELF_KEY } from "#configuration/constants/location.constants";
import { branchWithoutLocation, descendsThroughLeaf, unknownKey } from "#configuration/strings/location.strings";
import { LOCATION_TREE } from "#core/loaders/location.loader";
import { ROOT } from "#core/resolvers/location.root.resolver";
import { isRecord } from "#core/predicates/location.predicate";
import { join } from "node:path";

const selfOf = function selfOf(node: Record<string, unknown>): string {
    const own = node[SELF_KEY];
    return typeof own === "string" ? own : "";
};

const stepInto = function stepInto(node: unknown, part: string, dottedKey: string): unknown {
    if (!isRecord(node) || !(part in node)) {
        throw new Error(unknownKey(dottedKey));
    }
    return node[part];
};

const terminalOf = function terminalOf(next: unknown, part: string, prefix: string[], dottedKey: string): string {
    if (typeof next === "string") {
        return part === SELF_KEY ? prefix.join(SEGMENT_SEPARATOR) : [...prefix, next].join(SEGMENT_SEPARATOR);
    }
    if (isRecord(next) && selfOf(next).length > 0) {
        return [...prefix, selfOf(next)].join(SEGMENT_SEPARATOR);
    }
    throw new TypeError(branchWithoutLocation(dottedKey));
};

const leafOf = function leafOf(dottedKey: string): string {
    const parts = dottedKey.split(KEY_SEPARATOR);
    const prefix: string[] = [];
    let node: unknown = LOCATION_TREE;
    for (const [index, part] of parts.entries()) {
        const next: unknown = stepInto(node, part, dottedKey);
        if (index === parts.length - 1) {
            return terminalOf(next, part, prefix, dottedKey);
        }
        if (!isRecord(next)) {
            throw new TypeError(descendsThroughLeaf(dottedKey));
        }
        const own = selfOf(next);
        if (own.length > 0) {
            prefix.push(own);
        }
        node = next;
    }
    throw new Error(unknownKey(dottedKey));
};

export const absolutePath = function absolutePath(dottedKey: string, ...segments: string[]): string {
    return join(ROOT, ...leafOf(dottedKey).split(SEGMENT_SEPARATOR), ...segments);
};

export const relativePath = function relativePath(dottedKey: string, ...segments: string[]): string {
    return [leafOf(dottedKey), ...segments].join(SEGMENT_SEPARATOR);
};
```
