UNPKG

@digital-magic/io-ts-local-date-time

Version:

LocalDate, LocalTime and TimeSlot types and utilities for TS

79 lines (78 loc) 4.05 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.hasOverlaps = exports.slotOverlaps = exports.timeSlotOrd = exports.secondsTimeSlotToTimeSlot = exports.secondsTimeSlotToTimeSlotEncoder = exports.SecondsTimeSlotToTimeSlotDecoder = exports.TimeSlot = exports.SecondsTimeSlot = void 0; const t = __importStar(require("io-ts")); const O = __importStar(require("fp-ts/lib/Option")); const A = __importStar(require("fp-ts/lib/ReadonlyArray")); const E = __importStar(require("fp-ts/lib/Either")); const pipeable_1 = require("fp-ts/lib/pipeable"); const Ord_1 = require("fp-ts/lib/Ord"); const Apply_1 = require("fp-ts/lib/Apply"); const localtime_1 = require("./localtime"); const io_ts_extensions_1 = require("@digital-magic/io-ts-extensions"); exports.SecondsTimeSlot = t.type({ timeSince: t.number, timeBefore: t.number }, 'TimeSlot'); exports.TimeSlot = t.type({ timeSince: localtime_1.LocalTime, timeBefore: localtime_1.LocalTime }, 'TimeSlot'); exports.SecondsTimeSlotToTimeSlotDecoder = io_ts_extensions_1.decoder('ApiTimeSlotToTimeSlot', (u, c) => E.flatten(E.either.map(exports.TimeSlot.validate(u, c), (v) => { const timeSince = localtime_1.SecondsFromLocalTimeDecoder.validate(v.timeSince, c); const timeBefore = localtime_1.SecondsFromLocalTimeDecoder.validate(v.timeBefore, c); return pipeable_1.pipe(Apply_1.sequenceT(E.either)(timeSince, timeBefore), E.map(([ts, tb]) => { return { timeSince: ts, timeBefore: tb }; })); }))); const secondsTimeSlotToTimeSlotEncoder = (dateFormat) => io_ts_extensions_1.encoder((v) => { return { timeSince: localtime_1.secondsFromLocalTimeEncoder(dateFormat).encode(v.timeSince), timeBefore: localtime_1.secondsFromLocalTimeEncoder(dateFormat).encode(v.timeBefore) }; }); exports.secondsTimeSlotToTimeSlotEncoder = secondsTimeSlotToTimeSlotEncoder; // Example how to build codec /* export const SecondsTimeSlotToTimeSlot = codec<SecondsTimeSlot, TimeSlot, TimeSlot>(SecondsTimeSlotToTimeSlotDecoder, secondsTimeSlotToTimeSlotEncoder(''), SecondsTimeSlot.is) */ exports.secondsTimeSlotToTimeSlot = io_ts_extensions_1.unsafeDecode(exports.SecondsTimeSlotToTimeSlotDecoder); exports.timeSlotOrd = Ord_1.contramap((v) => localtime_1.secondsFromLocalTime(v.timeBefore))(Ord_1.ordNumber); function slotOverlaps(x, y) { return x.timeSince <= y.timeBefore && y.timeSince <= x.timeBefore; } exports.slotOverlaps = slotOverlaps; function pair(first, second) { return { first, second }; } function getLastTimeSlot(acc) { return pipeable_1.pipe(acc, A.last, O.map((v) => v.second)); } function hasOverlaps(slots) { return pipeable_1.pipe(slots, A.sort(exports.timeSlotOrd), A.reduce([], (acc, current) => acc.concat(pair(getLastTimeSlot(acc), current))), A.filterMap(({ first, second }) => pipeable_1.pipe(first, O.map((v) => pair(v, second)))), // TODO: Not a type safe code: secondsTimeSlotToTimeSlot - consider refactoring A.map(({ first, second }) => slotOverlaps(exports.secondsTimeSlotToTimeSlot(first), exports.secondsTimeSlotToTimeSlot(second)))).some((v) => v); } exports.hasOverlaps = hasOverlaps;