# core/resolvers/specifier.resolver.ts

> 66 lines of code and 15 definitions.

Tree: Bane's Lab Site
Language: typescript
Layer: infrastructure
Canonical: https://banes-lab.com/anatomy/tree#file-core-resolvers-specifier-resolver-ts
Source text: https://banes-lab.com/source/tree/core/resolvers/specifier.resolver.ts.txt

Listed in [core/resolvers](https://banes-lab.com/api/source/tree/core/resolvers.md).

## Definitions

- `packageTargetOf` (lexical_declaration, line 44, exported)
- `packageFileOf` (lexical_declaration, line 60, exported)
- `unrooted` (lexical_declaration, line 35)
- `subpathOf` (lexical_declaration, line 14)
- `targetOf` (lexical_declaration, line 21)
- `star` (lexical_declaration, line 22)
- `head` (lexical_declaration, line 26)
- `tail` (lexical_declaration, line 27)
- `matched` (lexical_declaration, line 31)
- `typedSource` (lexical_declaration, line 39)
- `emitted` (lexical_declaration, line 40)
- `subpath` (lexical_declaration, line 49, exported)
- `target` (lexical_declaration, line 52, exported)
- `qualified` (lexical_declaration, line 65, exported)
- `found` (lexical_declaration, line 66, exported)

## Contained in

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

## Used by

- [core/converters/definition.converter.ts](https://banes-lab.com/source/tree/core/converters/definition.converter.ts.md)

## Linked from

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

## Source

```typescript
import {
    EXTENSION_SEPARATOR,
    JAVASCRIPT_EXTENSION,
    PATH_SEPARATOR,
    RELATIVE_PREFIX,
    TYPESCRIPT_EXTENSION,
    WILDCARD_MARK,
} from "#configuration/constants/anatomy.constants";
import type { PackageExport, PackageTarget } from "#types/package.types";
import { ANATOMY_TREE_DECLARATIONS } from "#core/generated/anatomy.trees.generated";
import type { AnatomyTreeDeclaration } from "#types/anatomy.types";
import { qualifiedPath } from "#core/converters/folder.converter";

const subpathOf = function subpathOf(specifier: string, name: string): string | null {
    if (specifier === name) {
        return RELATIVE_PREFIX.slice(0, -PATH_SEPARATOR.length);
    }
    return specifier.startsWith(name + PATH_SEPARATOR) ? RELATIVE_PREFIX + specifier.slice(name.length + 1) : null;
};

const targetOf = function targetOf(entry: PackageExport, subpath: string): string | null {
    const star = entry.key.indexOf(WILDCARD_MARK);
    if (star === -1) {
        return entry.key === subpath ? entry.target : null;
    }
    const head = entry.key.slice(0, star);
    const tail = entry.key.slice(star + WILDCARD_MARK.length);
    if (!subpath.startsWith(head) || !subpath.endsWith(tail) || subpath.length < head.length + tail.length) {
        return null;
    }
    const matched = subpath.slice(head.length, subpath.length - tail.length);
    return entry.target.split(WILDCARD_MARK).join(matched);
};

const unrooted = function unrooted(target: string): string {
    return target.startsWith(RELATIVE_PREFIX) ? target.slice(RELATIVE_PREFIX.length) : target;
};

const typedSource = function typedSource(path: string): string {
    const emitted = EXTENSION_SEPARATOR + JAVASCRIPT_EXTENSION;
    return path.endsWith(emitted) ? path.slice(0, -emitted.length) + EXTENSION_SEPARATOR + TYPESCRIPT_EXTENSION : path;
};

export const packageTargetOf = function packageTargetOf(
    specifier: string,
    declarations: readonly AnatomyTreeDeclaration[],
): readonly PackageTarget[] {
    for (const declaration of declarations) {
        const subpath = declaration.packageName === null ? null : subpathOf(specifier, declaration.packageName);
        if (subpath !== null) {
            return declaration.exports.flatMap((entry) => {
                const target = targetOf(entry, subpath);
                return target === null ? [] : [{ path: unrooted(target), tab: declaration.tab }];
            });
        }
    }
    return [];
};

export const packageFileOf = function packageFileOf(
    specifier: string,
    existing: (path: string) => string | null,
): string | null {
    for (const target of packageTargetOf(specifier, ANATOMY_TREE_DECLARATIONS)) {
        const qualified = qualifiedPath(target.tab, target.path);
        const found = existing(qualified) ?? existing(typedSource(qualified));
        if (found !== null) {
            return found;
        }
    }
    return null;
};
```
