# core/converters/canon.converter.ts

> 30 lines of code and 13 definitions.

Tree: GovLab Quality
Language: typescript
Layer: processing
Canonical: https://banes-lab.com/anatomy/quality#file-quality-core-converters-canon-converter-ts
Source text: https://banes-lab.com/source/quality/core/converters/canon.converter.ts.txt

Listed in [core/converters](https://banes-lab.com/api/source/quality/core/converters.md), after [core/converters/canon.concept.converter.ts](https://banes-lab.com/source/quality/core/converters/canon.concept.converter.ts.md) and before [core/converters/comment.converter.ts](https://banes-lab.com/source/quality/core/converters/comment.converter.ts.md).

## Definitions

- `canonicalizeId` (lexical_declaration, line 22, exported)
- `isCanonicalId` (lexical_declaration, line 27, exported)
- `KIND_LOOKUP` (lexical_declaration, line 5)
- `KIND_MAP` (lexical_declaration, line 6)
- `PAREN_OPEN` (lexical_declaration, line 7)
- `PAREN_CLOSE` (lexical_declaration, line 8)
- `ALIAS_IDS` (lexical_declaration, line 10)
- `withoutAcronym` (lexical_declaration, line 16)
- `open` (lexical_declaration, line 17)
- `close` (lexical_declaration, line 18)
- `plain` (lexical_declaration, line 23, exported)
- `canonicalizeKind` (lexical_declaration, line 31, exported)
- `isCanonicalKind` (lexical_declaration, line 35, exported)

## Contained in

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

## Linked from

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

## Source

```typescript
import { createArchRelations, createLexicon, slugify } from "@govlab/context";
import { KIND_SET } from "#configuration/constants/canon.constants";
import { loadKindMap } from "#core/loaders/kind.loader";

const KIND_LOOKUP: ReadonlySet<string> = new Set(KIND_SET);
const KIND_MAP = loadKindMap();
const PAREN_OPEN = "(";
const PAREN_CLOSE = ")";

const ALIAS_IDS: ReadonlyMap<string, string> = new Map(
    [...createArchRelations().all(), ...createLexicon().all()].flatMap((record) =>
        (record.aliases ?? []).map((alias): [string, string] => [slugify(alias), record.id]),
    ),
);

const withoutAcronym = function withoutAcronym(term: string): string {
    const open = term.lastIndexOf(PAREN_OPEN);
    const close = term.lastIndexOf(PAREN_CLOSE);
    return open !== -1 && close > open ? `${term.slice(0, open)}${term.slice(close + 1)}`.trim() : term;
};

export const canonicalizeId = function canonicalizeId(term: string): string {
    const plain = slugify(withoutAcronym(term));
    return ALIAS_IDS.get(slugify(term)) ?? ALIAS_IDS.get(plain) ?? plain;
};

export const isCanonicalId = function isCanonicalId(term: string): boolean {
    return canonicalizeId(term) === term;
};

export const canonicalizeKind = function canonicalizeKind(type: string): string | null {
    return KIND_MAP.get(type) ?? null;
};

export const isCanonicalKind = function isCanonicalKind(kind: string): boolean {
    return KIND_LOOKUP.has(kind);
};
```
