# tools/core/inspectors/manifest.inspector.ts

> 238 lines of code and 34 definitions.

Tree: Coordination tree
Language: typescript
Canonical: https://banes-lab.com/anatomy/coordination#file-coordination-tools-core-inspectors-manifest-inspector-ts
Source text: https://banes-lab.com/assets/sources/source.48b11731ba8184a5f53d83ee7e91b9fb1e9a12cc0776ce759e0ae5b2f5afec30.generated.txt

## Definitions

- `manifestFinding` (lexical_declaration, line 47)
- `entriesOf` (lexical_declaration, line 40)
- `inspectOne` (lexical_declaration, line 238)
- `scriptFindings` (lexical_declaration, line 228)
- `workspaceFindings` (lexical_declaration, line 147)
- `subpathFindings` (lexical_declaration, line 175)
- `targetFinding` (lexical_declaration, line 206)
- `runtimeFindings` (lexical_declaration, line 135)
- `isRepoRelative` (lexical_declaration, line 32)
- `resolvesToPackage` (lexical_declaration, line 80)
- `endsWithAny` (lexical_declaration, line 24)
- `isRooted` (lexical_declaration, line 28)
- `climbsOut` (lexical_declaration, line 36, exported)
- `holdsManifest` (lexical_declaration, line 70)
- `manifestPaths` (lexical_declaration, line 87)
- `reachFinding` (lexical_declaration, line 96)
- `isUnresolvedSubpath` (lexical_declaration, line 167)
- `inspectManifests` (lexical_declaration, line 265, exported)
- `MANIFEST` (lexical_declaration, line 11, exported)
- `SCRIPT_TARGETS` (lexical_declaration, line 13)
- `SUBPATH_FIELDS` (lexical_declaration, line 15)
- `MANIFEST_ROOTS` (lexical_declaration, line 17)
- `CLIMB` (lexical_declaration, line 19)
- `Parsed` (type_alias_declaration, line 21)
- `star` (lexical_declaration, line 81)
- `skip` (lexical_declaration, line 88)
- `parsedManifest` (lexical_declaration, line 121)
- `value` (lexical_declaration, line 123)
- `[concrete = value]` (lexical_declaration, line 171)
- `HOST_CLAIM` (lexical_declaration, line 197)
- `parsed` (lexical_declaration, line 239)
- `manifestPath` (lexical_declaration, line 252)
- `packageDir` (lexical_declaration, line 253)
- `{ value }` (lexical_declaration, line 254)

## Uses

- [tools/core/predicates/schema.predicate.ts](https://banes-lab.com/source/coordination/tools/core/predicates/schema.predicate.ts.md)
- [tools/core/predicates/text.predicate.ts](https://banes-lab.com/source/coordination/tools/core/predicates/text.predicate.ts.md)
- [tools/core/resolvers/dependency.resolver.ts](https://banes-lab.com/source/coordination/tools/core/resolvers/dependency.resolver.ts.md)

## Source

```typescript
import { basename, dirname, relative, resolve } from "node:path";
import { existsSync, readFileSync, readdirSync } from "node:fs";
import { toPosix, walk } from "../iterators/file.iterator.ts";
import type { Finding } from "../types/segment.types.ts";
import { SURFACE_ROOT } from "../constants/path.constants.ts";
import { dependencyReach } from "../resolvers/dependency.resolver.ts";
import { isObject } from "../predicates/schema.predicate.ts";
import { readJson } from "../readers/json.reader.ts";
import { splitWords } from "../predicates/text.predicate.ts";

export const MANIFEST = "package.json";

const SCRIPT_TARGETS = [".ts", ".js", ".mjs", ".cjs", ".json"];

const SUBPATH_FIELDS = ["imports", "exports"];

const MANIFEST_ROOTS = [SURFACE_ROOT];

const CLIMB = "..";

type Parsed =
    { readonly ok: false; readonly error: string } | { readonly ok: true; readonly value: Record<string, unknown> };

const endsWithAny = function endsWithAny(text: string, suffixes: readonly string[]): boolean {
    return suffixes.some((suffix) => text.length > suffix.length && text.endsWith(suffix));
};

const isRooted = function isRooted(token: string): boolean {
    return token.startsWith("/") || token.startsWith("\\") || token.charAt(1) === ":";
};

const isRepoRelative = function isRepoRelative(token: string): boolean {
    return token.length > 0 && !token.startsWith("-") && !isRooted(token);
};

export const climbsOut = function climbsOut(token: string): boolean {
    return token.split("/").includes(CLIMB);
};

const entriesOf = function entriesOf(value: unknown): [string, unknown][] {
    if (Array.isArray(value)) {
        return value.map((item: unknown, index): [string, unknown] => [String(index), item]);
    }
    return isObject(value) ? Object.entries(value) : [];
};

const manifestFinding = function manifestFinding(
    manifestPath: string,
    kind: string,
    locus: string,
    actual: string,
    decide: string,
): Finding {
    return {
        actual,
        expected: null,
        healed: false,
        line: 0,
        locus,
        path: manifestPath,
        remediation: { action: "declare", decide, deterministic: false, from: actual, target: manifestPath, to: null },
        rule: `declaration/${kind}`,
        stack: [
            { check: "declared", resolved: locus },
            { check: "onDisk", resolved: "absent" },
        ],
    };
};

const holdsManifest = function holdsManifest(parent: string): boolean {
    try {
        return readdirSync(parent, { withFileTypes: true }).some(
            (child) => child.isDirectory() && existsSync(resolve(parent, child.name, MANIFEST)),
        );
    } catch {
        return false;
    }
};

const resolvesToPackage = function resolvesToPackage(packageDir: string, entry: string): boolean {
    const star = entry.indexOf("*");
    return star === -1
        ? existsSync(resolve(packageDir, entry, MANIFEST))
        : holdsManifest(resolve(packageDir, entry.slice(0, star)));
};

const manifestPaths = function manifestPaths(repoRoot: string, ignored: readonly string[]): string[] {
    const skip = ignored.filter((name) => name !== MANIFEST);

    return MANIFEST_ROOTS.map((root) => resolve(repoRoot, root))
        .filter((absolute) => existsSync(absolute))
        .flatMap((absolute) => walk({ extensions: [], ignored: skip, root: absolute }))
        .filter((file) => basename(file) === MANIFEST);
};

const reachFinding = function reachFinding(manifestPath: string, name: string): Finding {
    return {
        actual: `${name} is declared and no source or configuration in this package reaches it`,
        expected: null,
        healed: false,
        line: 0,
        locus: `dependency "${name}"`,
        path: manifestPath,
        remediation: {
            action: "declare",
            decide: "a declared dependency nothing reaches makes the dependency set claim a coverage it does not have, and the claim is read by installers rather than by readers — so it costs an install on every consumer and buys nothing. Reach it from source or configuration, or remove the declaration. THE REACH CORPUS IS SOURCE AND CONFIGURATION ONLY, because a package NAMED in prose is being discussed rather than invoked, and a check counting a report about an unused dependency as evidence that it is used measures the opposite of its own question. This does not heal: whether a declaration is premature or obsolete is a judgement about intent that no artifact carries",
            deterministic: false,
            from: name,
            target: manifestPath,
            to: null,
        },
        rule: "declaration/unreachedDependency",
        stack: [
            { check: "declared", resolved: name },
            { check: "specifier", resolved: "absent" },
            { check: "invocation", resolved: "absent" },
        ],
    };
};

const parsedManifest = function parsedManifest(repoRoot: string, manifestAbs: string): Parsed {
    try {
        const value = readJson(
            readFileSync(manifestAbs, "utf8"),
            isObject,
            relative(repoRoot, manifestAbs),
            "a JSON object",
        );
        return { ok: true, value };
    } catch (error) {
        return { error: String(error), ok: false };
    }
};

const runtimeFindings = function runtimeFindings(manifestPath: string, runtime: unknown): Finding[] {
    return entriesOf(runtime).map(([name]) =>
        manifestFinding(
            manifestPath,
            "declaredRuntimeDependency",
            `dependencies "${name}"`,
            `${name} is declared as a RUNTIME dependency`,
            "runtime code here takes no third-party dependency, so a consumer needs no toolchain of its own to run what it adopted — a declared runtime dependency makes this package's reach a function of what the consumer already has, and the invariant it breaks is one no amount of noticing holds because a manifest field is read by installers rather than by readers. Vendor the behavior, move it behind an injected port the consumer supplies, or demote it to a development dependency where it does not travel; where one is genuinely structurally unavoidable, that judgement is the maintainer's and is recorded rather than assumed, which is why this does not heal",
        ),
    );
};

const workspaceFindings = function workspaceFindings(
    manifestPath: string,
    packageDir: string,
    workspaces: unknown,
): Finding[] {
    return entriesOf(Array.isArray(workspaces) ? workspaces : [])
        .map(([, entry]) => entry)
        .filter((entry): entry is string => typeof entry === "string")
        .filter((entry) => !resolvesToPackage(packageDir, entry))
        .map((entry) =>
            manifestFinding(
                manifestPath,
                "emptyWorkspaceGlob",
                `workspaces "${entry}"`,
                `${entry} matches no directory holding a ${MANIFEST}`,
                `point the glob at the directory that actually holds the ${MANIFEST}, or drop it — a glob matching nothing installs nothing and warns only on some commands`,
            ),
        );
};

const isUnresolvedSubpath = function isUnresolvedSubpath(packageDir: string, value: unknown): value is string {
    if (typeof value !== "string") {
        return false;
    }
    const [concrete = value] = value.split("*");
    return concrete.length > 0 && !existsSync(resolve(packageDir, concrete));
};

const subpathFindings = function subpathFindings(
    manifestPath: string,
    packageDir: string,
    parsed: Record<string, unknown>,
): Finding[] {
    return SUBPATH_FIELDS.flatMap((field) =>
        entriesOf(parsed[field]).flatMap(([key, value]) =>
            isUnresolvedSubpath(packageDir, value)
                ? [
                      manifestFinding(
                          manifestPath,
                          "unresolvedSubpath",
                          `${field} "${key}"`,
                          value,
                          "the target does not exist — correct it or remove the entry, because a broken subpath fails only at the import that uses it",
                      ),
                  ]
                : [],
        ),
    );
};

const HOST_CLAIM =
    "the script names a target OUTSIDE this package's own root, which is a claim about a tree this " +
    "package does not own — so it resolves onto one consumer's layout or onto nothing, and it is " +
    "green on exactly the tree it was authored against. A DECLARATION WALK RUNS IN ONE DIRECTION: " +
    "it catches a claim with no referent and is constitutionally unable to catch a referent that " +
    "should not have been claimed, because its criterion is disk existence rather than ownership. " +
    "Move the invocation to the party that owns the capability, and let this package carry the DATA " +
    "that capability reads";

const targetFinding = function targetFinding(
    manifestPath: string,
    packageDir: string,
    name: string,
    token: string,
): Finding[] {
    if (climbsOut(token)) {
        return [manifestFinding(manifestPath, "hostClaimingScriptTarget", `scripts.${name}`, token, HOST_CLAIM)];
    }
    return existsSync(resolve(packageDir, token))
        ? []
        : [
              manifestFinding(
                  manifestPath,
                  "unresolvedScriptTarget",
                  `scripts.${name}`,
                  token,
                  "the script names a file that does not exist — a renamed entrypoint leaves the documented command failing at the moment someone needs it",
              ),
          ];
};

const scriptFindings = function scriptFindings(manifestPath: string, packageDir: string, scripts: unknown): Finding[] {
    return entriesOf(scripts).flatMap(([name, command]) =>
        typeof command === "string"
            ? splitWords(command)
                  .filter((token) => isRepoRelative(token) && endsWithAny(token, SCRIPT_TARGETS))
                  .flatMap((token) => targetFinding(manifestPath, packageDir, name, token))
            : [],
    );
};

const inspectOne = function inspectOne(repoRoot: string, manifestAbs: string): Finding[] {
    const parsed = parsedManifest(repoRoot, manifestAbs);
    if (!parsed.ok) {
        return [
            manifestFinding(
                relative(repoRoot, manifestAbs),
                "unparsableManifest",
                MANIFEST,
                parsed.error,
                "the manifest is not valid JSON — every npm script in this package is dead until it parses",
            ),
        ];
    }

    const manifestPath = toPosix(repoRoot, manifestAbs);
    const packageDir = dirname(manifestAbs);
    const { value } = parsed;

    return [
        ...runtimeFindings(manifestPath, value["dependencies"]),
        ...dependencyReach(packageDir, manifestAbs).unreached.map((name) => reachFinding(manifestPath, name)),
        ...workspaceFindings(manifestPath, packageDir, value["workspaces"]),
        ...subpathFindings(manifestPath, packageDir, value),
        ...scriptFindings(manifestPath, packageDir, value["scripts"]),
    ];
};

export const inspectManifests = function inspectManifests(repoRoot: string, ignored: readonly string[]): Finding[] {
    return manifestPaths(repoRoot, ignored).flatMap((manifest) => inspectOne(repoRoot, manifest));
};
```
