UNPKG

klog.js

Version:

A JavaScript implementation of the Klog time tracking file format

102 lines (101 loc) 3.23 kB
import { Duration } from "./duration.js"; import { Time } from "./time.js"; /** * Formatting options for spacing around a range's dash. */ export var RangeDashFormat; (function (RangeDashFormat) { RangeDashFormat[RangeDashFormat["Spaces"] = 0] = "Spaces"; RangeDashFormat[RangeDashFormat["NoSpaces"] = 1] = "NoSpaces"; })(RangeDashFormat || (RangeDashFormat = {})); /** * A range of time with a start time and optional end time. */ export class Range { start; /** @internal */ #end; /** The format for dashes in the time range. */ format; /** The number of placeholder characters to use for an open range. */ openRangePlaceholderCharCount; /** * Create a new range. * @throws {Error} The end time is before the start time. */ constructor( /** The start time of the range. */ start, /** The end time of the range. `null` if the range is open. */ end = null, /** Configuration options for the range */ { format = RangeDashFormat.Spaces, openRangePlaceholderCharCount = 1, } = {}) { this.start = start; if (end && !end.afterOrEquals(start)) throw new Error("End of range cannot be before its start"); this.#end = end; this.format = format; this.openRangePlaceholderCharCount = openRangePlaceholderCharCount; } /** @internal */ static fromAST = (node) => { const start = Time.fromAST(node.start); const end = !node.open ? Time.fromAST(node.end) : null; return new this(start, end, { openRangePlaceholderCharCount: node.open ? node.placeholderCount : 1, format: node.format, }); }; /** The end time of the range. */ get end() { return this.#end; } /** * @throws {Error} The end time is before the start time. */ set end(value) { if (!value) this.#end = value; else if (!value.afterOrEquals(this.start)) throw new Error("End of range cannot be before its start"); else this.#end = value; } /** * Whether or not the range is considered open. */ get open() { return !this.end; } /** * Convert the range to a duration. */ toDuration() { return Duration.fromMinutes(this.toMinutes()); } /** * Converts the range to minutes. * @returns 0 if an open range, otherwise the duration of the time range in minutes. */ toMinutes() { if (this.open) return 0; // unlimited potential! const start = this.start.toMinutesSinceMidnight(); const end = this.end.toMinutesSinceMidnight(); return end - start; } /** * Render the range as a Klog string. */ toString() { const dash = this.format === RangeDashFormat.Spaces ? " - " : "-"; return `${this.start}${dash}${this.open ? "?".repeat(this.openRangePlaceholderCharCount) : this.end}`; } /** * Convert the range to a JSON object. */ toJSON() { const { start, end, format, openRangePlaceholderCharCount } = this; return { start, end, format, openRangePlaceholderCharCount }; } }