# core/plugins/manifest.domain.plugin.ts

> 55 lines of code and 11 definitions.

Tree: GovLab Docs
Language: typescript
Layer: infrastructure
Canonical: https://banes-lab.com/anatomy/docs#file-docs-core-plugins-manifest-domain-plugin-ts
Source text: https://banes-lab.com/source/docs/core/plugins/manifest.domain.plugin.ts.txt

Listed in [core/plugins](https://banes-lab.com/api/source/docs/core/plugins.md), after [core/plugins/manifest.document.plugin.ts](https://banes-lab.com/source/docs/core/plugins/manifest.document.plugin.ts.md) and before [core/plugins/manifest.governance.plugin.ts](https://banes-lab.com/source/docs/core/plugins/manifest.governance.plugin.ts.md).

## Definitions

- `entryErrors` (lexical_declaration, line 15)
- `duplicateErrors` (lexical_declaration, line 30)
- `validate` (method_definition, line 49, exported)
- `domainKey` (lexical_declaration, line 26)
- `SECTION` (lexical_declaration, line 12)
- `KEY_SEPARATOR` (lexical_declaration, line 13)
- `{ meta, sub }` (lexical_declaration, line 19)
- `keys` (lexical_declaration, line 31)
- `plugin` (lexical_declaration, line 37, exported)
- `contribute` (method_definition, line 38, exported)
- `domains` (lexical_declaration, line 50, exported)

## Contained in

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

## Uses

- [configuration/strings/manifest.strings.ts](https://banes-lab.com/source/docs/configuration/strings/manifest.strings.ts.md)
- [core/predicates/record.predicate.ts](https://banes-lab.com/source/docs/core/predicates/record.predicate.ts.md)
- [core/predicates/taxonomy.domain.predicate.ts](https://banes-lab.com/source/docs/core/predicates/taxonomy.domain.predicate.ts.md)

## Linked from

- [configuration/strings](https://banes-lab.com/anatomy/docs/folder-docs-configuration-strings.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)

## Source

```typescript
import {
    MANIFEST_ERRORS,
    domainObject,
    duplicateDomain,
    unknownDomainMeta,
    unknownDomainSub,
} from "#configuration/strings/manifest.strings";
import { isDomainMeta, isDomainSub } from "#core/predicates/taxonomy.domain.predicate";
import type { ManifestPlugin } from "#types/manifest.types";
import { isPlainRecord } from "#core/predicates/record.predicate";

const SECTION = "domains";
const KEY_SEPARATOR = "/";

const entryErrors = function entryErrors(domain: unknown, at: string): string[] {
    if (!isPlainRecord(domain)) {
        return [domainObject(at)];
    }
    const { meta, sub } = domain;
    if (!isDomainMeta(meta)) {
        return [unknownDomainMeta(at, String(meta))];
    }
    return isDomainSub(meta, sub) ? [] : [unknownDomainSub(at, String(sub), meta)];
};

const domainKey = function domainKey(domain: unknown): string | null {
    return isPlainRecord(domain) ? [String(domain["meta"]), String(domain["sub"])].join(KEY_SEPARATOR) : null;
};

const duplicateErrors = function duplicateErrors(domains: readonly unknown[]): string[] {
    const keys = domains.map(domainKey);
    return keys.flatMap((key, index) =>
        key !== null && keys.indexOf(key) < index ? [duplicateDomain(index, key)] : [],
    );
};

export const plugin: ManifestPlugin = {
    contribute(manifest, entry) {
        const domains = manifest[SECTION];
        if (Array.isArray(domains) && domains.length > 0) {
            entry[SECTION] = domains
                .filter(isPlainRecord)
                .map((domain) => ({ meta: domain["meta"], sub: domain["sub"] }));
        }
    },
    name: "domains",
    section: {
        keys: [SECTION],
        validate(manifest) {
            const domains = manifest[SECTION];
            if (!Array.isArray(domains) || domains.length === 0) {
                return [MANIFEST_ERRORS.domainsRequired];
            }
            return [
                ...domains.flatMap((domain, index) => entryErrors(domain, `${SECTION}[${index}]`)),
                ...duplicateErrors(domains),
            ];
        },
    },
};
```
