core/formatters/mark.formatter.ts

core/formatters/mark.formatter.ts is a file in Canonical Write. 49 lines of code and 12 definitions.

import {
    FIELD_SEPARATOR,
    GENERATED_MARK_PREFIX,
    LINE_END,
    MARK_CLOSE,
    MINUTE_LENGTH,
    UTC_SUFFIX,
    VERSION_PREFIX,
} from "#configuration/constants/mark.constants";
import { bodyStartOf, markLineAt, parseMark } from "#core/selectors/mark.selector";
import type { GeneratedMark } from "#types/mark.types";

export const markTimeOf = function markTimeOf(date: Date): string {
    return date.toISOString().slice(0, MINUTE_LENGTH) + UTC_SUFFIX;
};

export const composeMark = function composeMark(mark: GeneratedMark): string {
    return GENERATED_MARK_PREFIX + mark.time + FIELD_SEPARATOR + VERSION_PREFIX + String(mark.version) + MARK_CLOSE;
};

const skipBlankLines = function skipBlankLines(text: string, from: number): number {
    let at = from;
    while (text.startsWith(LINE_END, at)) {
        at += LINE_END.length;
    }
    return at;
};

export const stripMark = function stripMark(text: string): string {
    const at = markLineAt(text);
    return at === null ? text : text.slice(0, at.start) + text.slice(skipBlankLines(text, at.end));
};

const insertMark = function insertMark(body: string, mark: GeneratedMark): string {
    const line = composeMark(mark) + LINE_END + LINE_END;
    const after = bodyStartOf(body);
    return body.slice(0, after) + line + body.slice(skipBlankLines(body, after));
};

export const stampGenerated = function stampGenerated(
    body: string,
    previous: string,
    now: Date,
    normalize: (text: string) => string = (text) => text,
): string {
    const held = parseMark(previous);
    const unmarked = stripMark(body);
    if (held !== null) {
        const kept = insertMark(unmarked, held);
        if (normalize(kept) === normalize(previous)) {
            return kept;
        }
    }
    return insertMark(unmarked, { time: markTimeOf(now), version: (held?.version ?? 0) + 1 });
};