# core/resolvers/barrel.resolver.ts

> 160 lines of code and 52 definitions.

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

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

## Definitions

- `resolveSourceBarrels` (lexical_declaration, line 170, exported)
- `entryFilesIn` (lexical_declaration, line 113)
- `stemOf` (lexical_declaration, line 103)
- `mainBarrels` (lexical_declaration, line 152)
- `entryStrings` (lexical_declaration, line 54)
- `looksLikeEntryFile` (lexical_declaration, line 108)
- `wildcardRoot` (lexical_declaration, line 119)
- `wildcardBarrels` (lexical_declaration, line 128)
- `REL_PREFIX` (lexical_declaration, line 8)
- `DIST_PREFIX` (lexical_declaration, line 9)
- `BUILD_PREFIX` (lexical_declaration, line 10)
- `SOURCE_PREFIX` (lexical_declaration, line 11)
- `WILDCARD` (lexical_declaration, line 12)
- `MAIN_AXIS` (lexical_declaration, line 13)
- `AXIS_NAMES` (lexical_declaration, line 14)
- `ENTRY_SUBKEYS` (lexical_declaration, line 15)
- `OUTPUT_PREFIXES` (lexical_declaration, line 16)
- `MAIN_CANDIDATES` (lexical_declaration, line 17)
- `EXT_TO_TS` (lexical_declaration, line 28)
- `ENTRY_STEMS` (lexical_declaration, line 35)
- `SOURCE_EXTENSIONS` (lexical_declaration, line 47)
- `DECLARATION_SUFFIX` (lexical_declaration, line 48)
- `withoutRelPrefix` (lexical_declaration, line 50)
- `exportEntryPaths` (lexical_declaration, line 64)
- `fields` (lexical_declaration, line 66)
- `rootsFor` (lexical_declaration, line 70)
- `prefix` (lexical_declaration, line 71)
- `rest` (lexical_declaration, line 75)
- `sourceVariants` (lexical_declaration, line 79)
- `sourceCandidates` (lexical_declaration, line 88)
- `candidates` (lexical_declaration, line 89)
- `firstExisting` (lexical_declaration, line 93)
- `path` (lexical_declaration, line 95)
- `dot` (lexical_declaration, line 104)
- `isSource` (lexical_declaration, line 109)
- `rel` (lexical_declaration, line 120)
- `literal` (lexical_declaration, line 121)
- `cut` (lexical_declaration, line 122)
- `dirRel` (lexical_declaration, line 123)
- `dir` (lexical_declaration, line 124)
- `root` (lexical_declaration, line 129)
- `nested` (lexical_declaration, line 133)
- `declaredBarrels` (lexical_declaration, line 140)
- `targets` (lexical_declaration, line 141)
- `concrete` (lexical_declaration, line 142)
- `expanded` (lexical_declaration, line 146)
- `declared` (lexical_declaration, line 153)
- `fallback` (lexical_declaration, line 159)
- `axisBarrels` (lexical_declaration, line 163)
- `barrel` (lexical_declaration, line 165)
- `exported` (lexical_declaration, line 174, exported)
- `dual` (lexical_declaration, line 175, exported)

## Contained in

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

## Uses

- [core/loaders/base.loader.ts](https://banes-lab.com/source/docs/core/loaders/base.loader.ts.md)
- [core/predicates/record.predicate.ts](https://banes-lab.com/source/docs/core/predicates/record.predicate.ts.md)

## Used by

- [core/factories/seed.factory.ts](https://banes-lab.com/source/docs/core/factories/seed.factory.ts.md)
- [core/plugins/code.typescript.plugin.ts](https://banes-lab.com/source/docs/core/plugins/code.typescript.plugin.ts.md)
- [core/validators/barrel.validator.ts](https://banes-lab.com/source/docs/core/validators/barrel.validator.ts.md)

## Linked from

- [core/factories](https://banes-lab.com/anatomy/docs/folder-docs-core-factories.md)
- [core/loaders](https://banes-lab.com/anatomy/docs/folder-docs-core-loaders.md)
- [core/plugins](https://banes-lab.com/anatomy/docs/folder-docs-core-plugins.md)
- [core/predicates](https://banes-lab.com/anatomy/docs/folder-docs-core-predicates.md)
- [core/resolvers](https://banes-lab.com/anatomy/docs/folder-docs-core-resolvers.md)
- [core/validators](https://banes-lab.com/anatomy/docs/folder-docs-core-validators.md)

## Source

```typescript
import type { AxisBarrel, PackageJsonLike } from "#types/code.types";
import { isDirectory, sortedNames } from "#core/loaders/base.loader";
import { existsSync } from "node:fs";
import { isRecord } from "#core/predicates/record.predicate";
import { join } from "node:path";
import { manifestBarrels } from "#core/loaders/manifest.loader";

const REL_PREFIX = "./";
const DIST_PREFIX = "dist/";
const BUILD_PREFIX = "build/";
const SOURCE_PREFIX = "src/";
const WILDCARD = "*";
const MAIN_AXIS = "main";
const AXIS_NAMES: readonly string[] = ["frontend", "backend"];
const ENTRY_SUBKEYS: readonly string[] = ["types", "import", "module", "default", "require"];
const OUTPUT_PREFIXES: readonly string[] = [DIST_PREFIX, BUILD_PREFIX];
const MAIN_CANDIDATES: readonly string[] = [
    "index.ts",
    "src/index.ts",
    "src/main.ts",
    "src/main.tsx",
    "main.ts",
    "main.tsx",
    "app.ts",
    "src/app.ts",
    "server.ts",
];
const EXT_TO_TS: readonly (readonly [string, string])[] = [
    [".d.ts", ".ts"],
    [".js", ".ts"],
    [".mjs", ".mts"],
    [".cjs", ".cts"],
    [".jsx", ".tsx"],
];
const ENTRY_STEMS: ReadonlySet<string> = new Set([
    "index",
    "main",
    "cli",
    "app",
    "server",
    "run",
    "deploy",
    "start",
    "bin",
    "cmd",
]);
const SOURCE_EXTENSIONS: readonly string[] = [".ts", ".tsx", ".mts", ".cts"];
const DECLARATION_SUFFIX = ".d.ts";

const withoutRelPrefix = function withoutRelPrefix(entry: string): string {
    return entry.startsWith(REL_PREFIX) ? entry.slice(REL_PREFIX.length) : entry;
};

const entryStrings = function entryStrings(value: unknown): string[] {
    if (typeof value === "string") {
        return [value];
    }
    if (!isRecord(value)) {
        return [];
    }
    return ENTRY_SUBKEYS.map((key) => value[key]).filter((entry): entry is string => typeof entry === "string");
};

const exportEntryPaths = function exportEntryPaths(pkg: PackageJsonLike): string[] {
    const targets = isRecord(pkg.exports) ? Object.values(pkg.exports).flatMap(entryStrings) : [];
    const fields = [pkg.module, pkg.main, pkg.types].filter((field): field is string => typeof field === "string");
    return [...targets, ...fields];
};

const rootsFor = function rootsFor(entry: string): string[] {
    const prefix = OUTPUT_PREFIXES.find((candidate) => entry.startsWith(candidate));
    if (prefix === undefined) {
        return [entry];
    }
    const rest = entry.slice(prefix.length);
    return [rest, `${SOURCE_PREFIX}${rest}`];
};

const sourceVariants = function sourceVariants(root: string): string[] {
    return [
        root,
        ...EXT_TO_TS.filter(([extension]) => root.endsWith(extension)).map(
            ([extension, replacement]) => root.slice(0, -extension.length) + replacement,
        ),
    ];
};

const sourceCandidates = function sourceCandidates(entry: string): string[] {
    const candidates = new Set(rootsFor(withoutRelPrefix(entry)).flatMap(sourceVariants));
    return [...candidates].filter((path) => !OUTPUT_PREFIXES.some((prefix) => path.startsWith(prefix)));
};

const firstExisting = function firstExisting(moduleDir: string, relPaths: readonly string[]): string | null {
    for (const rel of relPaths) {
        const path = join(moduleDir, ...rel.split("/"));
        if (existsSync(path)) {
            return path;
        }
    }
    return null;
};

const stemOf = function stemOf(name: string): string {
    const dot = name.lastIndexOf(".");
    return dot === -1 ? name : name.slice(0, dot);
};

const looksLikeEntryFile = function looksLikeEntryFile(name: string): boolean {
    const isSource = SOURCE_EXTENSIONS.some((extension) => name.endsWith(extension));
    return !name.endsWith(DECLARATION_SUFFIX) && isSource && ENTRY_STEMS.has(stemOf(name));
};

const entryFilesIn = function entryFilesIn(dir: string): string[] {
    return sortedNames(dir)
        .filter(looksLikeEntryFile)
        .map((name) => join(dir, name));
};

const wildcardRoot = function wildcardRoot(moduleDir: string, target: string): string | null {
    const rel = withoutRelPrefix(target);
    const literal = rel.slice(0, rel.indexOf(WILDCARD));
    const cut = literal.lastIndexOf("/");
    const dirRel = cut === -1 ? "" : literal.slice(0, cut);
    const dir = dirRel === "" ? moduleDir : join(moduleDir, ...dirRel.split("/"));
    return isDirectory(dir) ? dir : null;
};

const wildcardBarrels = function wildcardBarrels(moduleDir: string, target: string): string[] {
    const root = wildcardRoot(moduleDir, target);
    if (root === null) {
        return [];
    }
    const nested = sortedNames(root)
        .map((name) => join(root, name))
        .filter(isDirectory)
        .flatMap(entryFilesIn);
    return [...entryFilesIn(root), ...nested];
};

const declaredBarrels = function declaredBarrels(moduleDir: string, pkg: PackageJsonLike): string[] {
    const targets = exportEntryPaths(pkg);
    const concrete = targets
        .filter((target) => !target.includes(WILDCARD))
        .map((target) => firstExisting(moduleDir, sourceCandidates(target)))
        .filter((path): path is string => path !== null);
    const expanded = targets
        .filter((target) => target.includes(WILDCARD))
        .flatMap((target) => wildcardBarrels(moduleDir, target));
    return [...concrete, ...expanded];
};

const mainBarrels = function mainBarrels(moduleDir: string, pkg: PackageJsonLike): AxisBarrel[] {
    const declared = [...manifestBarrels(moduleDir), ...declaredBarrels(moduleDir, pkg)];
    if (declared.length > 0) {
        return [...new Set(declared)]
            .toSorted((left, right) => left.localeCompare(right))
            .map((barrel) => ({ axis: MAIN_AXIS, barrel }));
    }
    const fallback = firstExisting(moduleDir, MAIN_CANDIDATES);
    return fallback === null ? [] : [{ axis: MAIN_AXIS, barrel: fallback }];
};

const axisBarrels = function axisBarrels(moduleDir: string, exported: Record<string, unknown>): AxisBarrel[] {
    return AXIS_NAMES.filter((axis) => Object.hasOwn(exported, `${REL_PREFIX}${axis}`)).flatMap((axis) => {
        const barrel = firstExisting(moduleDir, [`${axis}/index.ts`, `${axis}/src/index.ts`]);
        return barrel === null ? [] : [{ axis, barrel }];
    });
};

export const resolveSourceBarrels = function resolveSourceBarrels(
    moduleDir: string,
    pkg: PackageJsonLike,
): AxisBarrel[] {
    const exported = isRecord(pkg.exports) ? pkg.exports : {};
    const dual = axisBarrels(moduleDir, exported);
    return dual.length > 0 ? dual : mainBarrels(moduleDir, pkg);
};
```
