# tools/core/writers/repair.writer.ts

> 38 lines of code and 10 definitions.

Tree: Coordination tree
Language: typescript
Canonical: https://banes-lab.com/anatomy/coordination#file-coordination-tools-core-writers-repair-writer-ts
Source text: https://banes-lab.com/assets/sources/source.96e2b9c270ca5630886d2a797a60534a541d3a969ae6fec67828dd9ad2830370.generated.txt

## Definitions

- `writeRepair` (lexical_declaration, line 35, exported)
- `containedBy` (lexical_declaration, line 22, exported)
- `isEnumerable` (lexical_declaration, line 31, exported)
- `RepairScope` (interface_declaration, line 7, exported)
- `RepairOutcome` (interface_declaration, line 13, exported)
- `WHOLE` (lexical_declaration, line 18)
- `CLIMB` (lexical_declaration, line 20)
- `from` (lexical_declaration, line 27, exported)
- `regions` (lexical_declaration, line 36, exported)
- `absolute` (lexical_declaration, line 46, exported)

## Uses

- [tools/core/strings/repair.strings.ts](https://banes-lab.com/source/coordination/tools/core/strings/repair.strings.ts.md)

## Used by

- [tools/core/generators/agenda.generator.ts](https://banes-lab.com/source/coordination/tools/core/generators/agenda.generator.ts.md)
- [tools/core/generators/binding.generator.ts](https://banes-lab.com/source/coordination/tools/core/generators/binding.generator.ts.md)
- [tools/core/generators/board.generator.ts](https://banes-lab.com/source/coordination/tools/core/generators/board.generator.ts.md)

## Source

```typescript
import { dirname, relative, resolve } from "node:path";
import { mkdirSync, writeFileSync } from "node:fs";

import { outsideScope, unclaimedRegion } from "../strings/repair.strings.ts";
import { slotList } from "../../../config/surface.config.ts";

export interface RepairScope {
    readonly repoRoot: string;
    readonly declared: string;
    readonly claimed?: boolean;
}

export interface RepairOutcome {
    readonly written: boolean;
    readonly refusal: string | null;
}

const WHOLE = "whole";

const CLIMB = "..";

export const containedBy = function containedBy(declared: string, path: string): boolean {
    if (declared.length === 0 || declared === WHOLE) {
        return true;
    }

    const from = relative(declared, path);
    return from.length > 0 && !from.startsWith(CLIMB) && !resolve(from).startsWith(CLIMB);
};

export const isEnumerable = function isEnumerable(path: string, regions: readonly string[]): boolean {
    return regions.some((region) => containedBy(region, path));
};

export const writeRepair = function writeRepair(scope: RepairScope, path: string, text: string): RepairOutcome {
    const regions = slotList("convention", "enumerable_write_regions");

    if (isEnumerable(path, regions) && scope.claimed === false) {
        return { refusal: unclaimedRegion(path), written: false };
    }

    if (!containedBy(scope.declared, path)) {
        return { refusal: outsideScope(path, scope.declared), written: false };
    }

    const absolute = resolve(scope.repoRoot, path);
    mkdirSync(dirname(absolute), { recursive: true });
    writeFileSync(absolute, text, "utf8");

    return { refusal: null, written: true };
};
```
