UNPKG

elliptical-datetime

Version:

Elliptical phrases to handle natural language dates and times

219 lines (190 loc) 7.91 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.Range = undefined; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; /** @jsx createElement */ var _lodash = require('lodash'); var _lodash2 = _interopRequireDefault(_lodash); var _moment = require('moment'); var _moment2 = _interopRequireDefault(_moment); var _elliptical = require('elliptical'); var _helpers = require('./helpers'); var _datetime = require('./datetime'); var _duration = require('./duration'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } const TrueDateTime = { describe({ props }) { return (0, _elliptical.createElement)( 'sequence', null, (0, _elliptical.createElement)('literal', { text: 'all day ', id: 'allDay', value: true, optional: true, limited: true }), (0, _elliptical.createElement)( 'choice', { merge: true }, (0, _elliptical.createElement)(_datetime.InternalDateTime, _extends({}, props, { id: undefined })), (0, _elliptical.createElement)( 'map', { 'function': result => ({ dateTime: result }) }, (0, _elliptical.createElement)(_datetime.DateTime, _extends({}, props, { nullify: true })) ) ) ); } }; function* mapRangeResults(result, props) { if (result.start && result.end) { if (!result.start.time && !result.end.time) { for (let startDate of (0, _helpers.possibleDates)(result.start)) { for (let endDate of (0, _helpers.possibleDates)(result.end)) { yield { start: (0, _helpers.join)(startDate, { hour: 0, minute: 0, second: 0 }, props.timezoneOffset), end: (0, _helpers.join)(endDate, { hour: 0, minute: 0, second: 0 }, props.timezoneOffset), allDay: true }; } } } else { for (let startDate of (0, _helpers.possibleDates)(result.start, result.end.date)) { for (let endDate of (0, _helpers.possibleDates)(result.end, startDate)) { yield { start: (0, _helpers.join)(startDate, result.start.time || props.defaultTime, props.timezoneOffset), end: (0, _helpers.join)(endDate, result.end.time || props.defaultTime, props.timezoneOffset), allDay: false }; } } } } else if (result.start && result.duration) { for (let startDate of (0, _helpers.possibleDates)(result.start)) { const start = (0, _helpers.join)(startDate, result.start.time || props.defaultTime, props.timezoneOffset); yield { start, end: (0, _moment2.default)(start).add(result.duration).toDate(), allDay: false }; } } else if (result.start) { if (!result.start.time) { for (let startDate of (0, _helpers.possibleDates)(result.start)) { yield { start: startDate, end: startDate, allDay: true }; } } else { for (let startDate of (0, _helpers.possibleDates)(result.start)) { const start = (0, _helpers.join)(startDate, result.start.time, props.timezoneOffset); yield { start: start, end: (0, _moment2.default)(start).add(props.defaultDuration).toDate(), allDay: false }; } } } } function preprocessRangeAmbiguity(result, props) { if (result.start && result.end) { if (result.end.date && result.end._ambiguousMonth) { const trueEndDate = (0, _moment2.default)(result.end.date).month((0, _moment2.default)(result.start.date).month()).toDate(); const end = _lodash2.default.assign({}, result.end, { date: trueEndDate }); return _lodash2.default.assign({}, result, { end }); } if (result.start._ambiguousAMPM && result.end._specificAMPM) { const start = _lodash2.default.clone(result.start); start.time = (0, _helpers.ambiguousTime)(result.start.time, result.end._specificAMPM); return _lodash2.default.assign({}, result, { start }); } } return result; } function* mapRangeOptions(option, props) { const processedResult = preprocessRangeAmbiguity(option.result, props); for (let result of mapRangeResults(processedResult, props)) { yield _lodash2.default.assign({}, option, { result }); } } function filterRangeOption(option) { const result = option.result; // console.log(result) // it doesn't make any sense to specify a "date to time" or "time to date" if (result.start && result.end && (result.start.date && !result.start.time && !result.end.date && result.end.time || !result.start.date && result.start.time && result.end.date && !result.end.time)) { return false; } // both start and end cannot have month ambiguity if (result.start && result.start._ambiguousMonth && result.end && result.end._ambiguousMonth) { return false; } // if we've specified a time, we can't be allday if (result.allDay && (!result.start._ambiguousTime || result.end && !result.end._ambiguousTime)) { return false; } return true; } const Range = exports.Range = { id: 'elliptical-datetime:Range', defaultProps: { prepositions: false, seconds: true, defaultTime: { hour: 8 }, defaultDuration: { hours: 1 }, future: true, past: true, label: 'period of time' }, filterResult(result, { props }) { const startMoment = (0, _moment2.default)(result.start); const endMoment = (0, _moment2.default)(result.end); if (endMoment.isBefore(startMoment)) return false; const currentMoment = result.allDay ? (0, _moment2.default)().startOf('day') : (0, _moment2.default)(); if (!props.past && currentMoment.isAfter(startMoment)) return false; if (!props.future && currentMoment.isBefore(endMoment)) return false; return true; }, describe({ props }) { return (0, _elliptical.createElement)( 'placeholder', { label: props.label, arguments: props.phraseArguments || (props.phraseArguments ? [props.phraseArgument] : [props.label]) }, (0, _elliptical.createElement)( 'map', { outbound: option => mapRangeOptions(option, props), limit: 1, skipIncomplete: true }, (0, _elliptical.createElement)( 'filter', { outbound: filterRangeOption, skipIncomplete: true }, (0, _elliptical.createElement)( 'sequence', { unique: true }, (0, _elliptical.createElement)( 'sequence', { id: 'duration', optional: true, limited: true }, props.prepositions ? (0, _elliptical.createElement)('literal', { text: 'for ', decorate: true }) : null, (0, _elliptical.createElement)(_duration.Duration, { merge: true }), (0, _elliptical.createElement)('list', { items: [' ', ' starting '], limit: 1 }) ), (0, _elliptical.createElement)(TrueDateTime, { ellipsis: true, id: 'start' }), (0, _elliptical.createElement)( 'choice', { merge: true }, (0, _elliptical.createElement)( 'sequence', { id: 'end' }, (0, _elliptical.createElement)('list', { items: [' to ', ' - ', '-', '- ', ' -'], limit: 1 }), (0, _elliptical.createElement)(TrueDateTime, { merge: true }) ), (0, _elliptical.createElement)( 'sequence', { id: 'duration' }, (0, _elliptical.createElement)('literal', { text: ' for ' }), (0, _elliptical.createElement)(_duration.Duration, { merge: true }) ) ) ) ) ) ); } };