# core/factories/schema.factory.ts

> 48 lines of code and 7 definitions.

Tree: Bane's Lab Site
Language: typescript
Layer: infrastructure
Canonical: https://banes-lab.com/anatomy/tree#file-core-factories-schema-factory-ts
Source text: https://banes-lab.com/source/tree/core/factories/schema.factory.ts.txt

Listed in [core/factories](https://banes-lab.com/api/source/tree/core/factories.md), after [core/factories/evidence.factory.ts](https://banes-lab.com/source/tree/core/factories/evidence.factory.ts.md).

## Definitions

- `datesOf` (lexical_declaration, line 33, exported)
- `encoding` (lexical_declaration, line 22, exported)
- `instantOf` (lexical_declaration, line 29, exported)
- `breadcrumb` (lexical_declaration, line 10, exported)
- `basePage` (lexical_declaration, line 39, exported)
- `MARKDOWN_FORMAT` (lexical_declaration, line 7)
- `DAY_START` (lexical_declaration, line 8)

## Contained in

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

## Used by

- [presentation/renderers/schema.renderer.ts](https://banes-lab.com/source/tree/presentation/renderers/schema.renderer.ts.md)

## Linked from

- [core/factories](https://banes-lab.com/anatomy/tree/folder-core-factories.md)
- [presentation/renderers](https://banes-lab.com/anatomy/tree/folder-presentation-renderers.md)

## Source

```typescript
import type { Crumb, SchemaEntity } from "#types/schema.types";
import { ORGANIZATION_ID, PERSON_ID, SCHEMA_LANGUAGE, WEBSITE_ID } from "#configuration/constants/schema.constants";
import type { PageDates, SchemaSubject } from "#types/page.types";
import { JSON_FORMAT } from "#configuration/constants/code.constants";
import { SITE_URL } from "#core/assets/link.assets";

const MARKDOWN_FORMAT = "text/markdown";
const DAY_START = "T00:00:00+00:00";

export const breadcrumb = function breadcrumb(crumbs: readonly Crumb[]): SchemaEntity {
    return {
        "@type": "BreadcrumbList",
        itemListElement: crumbs.map((crumb, index) => ({
            "@type": "ListItem",
            item: SITE_URL + crumb.path,
            name: crumb.name,
            position: index + 1,
        })),
    };
};

export const encoding = function encoding(json: string, markdown: string): readonly SchemaEntity[] {
    return [
        { "@type": "MediaObject", contentUrl: SITE_URL + json, encodingFormat: JSON_FORMAT },
        { "@type": "MediaObject", contentUrl: SITE_URL + markdown, encodingFormat: MARKDOWN_FORMAT },
    ];
};

export const instantOf = function instantOf(day: string): string {
    return day + DAY_START;
};

export const datesOf = function datesOf(dates: PageDates | undefined): SchemaEntity {
    return dates === undefined
        ? {}
        : { dateModified: instantOf(dates.modified), datePublished: instantOf(dates.published) };
};

export const basePage = function basePage(
    subject: Pick<SchemaSubject, "dates" | "description" | "path" | "title">,
): SchemaEntity {
    return {
        "@id": SITE_URL + subject.path,
        "@type": "WebPage",
        author: { "@id": PERSON_ID },
        ...datesOf(subject.dates),
        description: subject.description,
        inLanguage: SCHEMA_LANGUAGE,
        isPartOf: { "@id": WEBSITE_ID },
        name: subject.title,
        publisher: { "@id": ORGANIZATION_ID },
        url: SITE_URL + subject.path,
    };
};
```
