UNPKG

elliptical-datetime

Version:

Elliptical phrases to handle natural language dates and times

279 lines (247 loc) 10 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.InternalDateTime = exports.DateTime = 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 _elliptical = require('elliptical'); var _time = require('./time'); var _moment = require('moment'); var _moment2 = _interopRequireDefault(_moment); var _helpers = require('./helpers'); var _date = require('./date'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function isNoonOrMidnight(time) { return (time.hour === 12 || time.hour === 0) && !time.minute && !time.second; } function timeIsInAMPM(time, ampm) { if (ampm === 'am') { return time.hour >= 0 && time.hour < 12; } else if (ampm === 'pm') { return time.hour >= 12 && time.hour < 24; } } const TrueDate = { describe({ props }) { return (0, _elliptical.createElement)( 'sequence', null, (0, _elliptical.createElement)( 'choice', { merge: true }, (0, _elliptical.createElement)(_date.InternalDate, _extends({}, props, { id: undefined })), (0, _elliptical.createElement)( 'map', { 'function': result => ({ date: result }), skipIncomplete: true }, (0, _elliptical.createElement)(_date.Date, _extends({}, props, { nullify: true })) ) ) ); } }; function* getDateTimeResults(result, props) { let dates; if (result.date) { if (result._ambiguousWeek) { dates = _lodash2.default.map([0, 1, -1], weeks => (0, _moment2.default)(result.date).add(weeks, 'weeks').toDate()); } else if (result._ambiguousCentury) { dates = _lodash2.default.map([0, 100, -100], years => (0, _moment2.default)(result.date).add(years, 'years').toDate()); } else if (result._ambiguousYear) { if (result._ambiguousMonth) { dates = _lodash2.default.flatMap([0, 1, -1], y => { return _lodash2.default.map([0, 1, -1], m => { return (0, _moment2.default)(result.date).add(y, 'years').add(m, 'months').toDate(); }); }); } else { dates = _lodash2.default.map([0, 1, -1], years => (0, _moment2.default)(result.date).add(years, 'years').toDate()); } } else { dates = [result.date]; } } else { dates = [undefined]; } for (let date of dates) { if (date && result.time) { yield (0, _helpers.join)(date, result.time, props.timezoneOffset); } else if (result.time && result.relativeDate) { yield (0, _helpers.join)((0, _helpers.relativeDate)(result.relativeDate), result.time, props.timezoneOffset); } else if (date) { yield (0, _helpers.join)(date, props.defaultTime, props.timezoneOffset); } else if (result.time) { for (let i of [0, 1, -1]) { yield (0, _helpers.join)((0, _helpers.relativeDate)({ days: i }), result.time, props.timezoneOffset); } } } } function* getDateTimeOptions(option, props) { for (let result of getDateTimeResults(option.result, props)) { yield _lodash2.default.assign({}, option, { result }); } } // function filterDateTimeResult (result) { // return true // } const DateTime = exports.DateTime = { id: 'elliptical-datetime:DateTime', defaultProps: { defaultTime: { hour: 8, minute: 0, second: 0 }, past: true, future: true, prepositions: false, label: 'date and time' }, filterResult(result, { props }) { if (!props.past && (0, _moment2.default)().isAfter(result)) { return false; } if (!props.future && (0, _moment2.default)().isBefore(result)) { return false; } return true; }, describe({ props }) { return props.nullify ? null : (0, _elliptical.createElement)( 'map', { outbound: option => getDateTimeOptions(option, props), limit: 1, skipIncomplete: true }, (0, _elliptical.createElement)(InternalDateTime, props) ); } }; function filterInternalDateTime(option) { const result = option.result; /*if (option.result.time && option.result.time._ambiguousAMPM && !option.result.timeOfDay) { return false } else */if (result.time && result.timeOfDay && isNoonOrMidnight(result.time)) { return false; } else if (result.time && result.timeOfDay && !result.time._ambiguousAMPM && !timeIsInAMPM(result.time, result.timeOfDay.impliedAMPM)) { return false; } return true; } const InternalDateTime = exports.InternalDateTime = { defaultProps: { label: 'date and time' }, mapResult(result) { let time = result.time; if (result.timeOfDay && result.time && result.time._ambiguousAMPM) { time = (0, _helpers.ambiguousTime)(result.time, result.timeOfDay.impliedAMPM); } else if (result.timeOfDay && !result.time) { time = { hour: result.timeOfDay.default }; } let date = result.date && result.date.date; if (result.relativeDate) { date = (0, _helpers.relativeDate)(result.relativeDate); } // console.log(result) return { date, time, _ambiguousYear: result.date && result.date._ambiguousYear, _ambiguousCentury: result.date && result.date._ambiguousCentury, _ambiguousWeek: result.date && result.date._ambiguousWeek, _ambiguousMonth: result.date && result.date._ambiguousMonth, _ambiguousAMPM: result.time && result.time._ambiguousAMPM, _specificAMPM: result.time && result.time._specificAMPM }; }, describe({ props }) { return (0, _elliptical.createElement)( 'placeholder', { label: props.label, arguments: props.phraseArguments || (props.phraseArguments ? [props.phraseArgument] : [props.label]) }, (0, _elliptical.createElement)( 'filter', { outbound: filterInternalDateTime, skipIncomplete: true }, (0, _elliptical.createElement)( 'choice', null, (0, _elliptical.createElement)( 'sequence', { unique: true }, (0, _elliptical.createElement)( 'sequence', { merge: true }, (0, _elliptical.createElement)(_time.InternalTime, { id: 'time', ellipsis: true, prepositions: props.prepositions, seconds: false }), (0, _elliptical.createElement)( 'sequence', { optional: true, limited: true, ellipsis: true, merge: true }, (0, _elliptical.createElement)( 'sequence', { id: 'timeOfDay', optional: true, limited: true }, (0, _elliptical.createElement)('literal', { text: ' the ' }), (0, _elliptical.createElement)(_time.TimeOfDay, { merge: true }), (0, _elliptical.createElement)('literal', { text: ' of' }) ), (0, _elliptical.createElement)( 'sequence', { id: 'date' }, (0, _elliptical.createElement)('literal', { text: ' ' }), (0, _elliptical.createElement)(TrueDate, { merge: true, prepositions: true }) ) ), (0, _elliptical.createElement)( 'sequence', { id: 'timeOfDay' }, (0, _elliptical.createElement)('list', { items: [' ', ' in the '], limit: 1 }), (0, _elliptical.createElement)(_time.TimeOfDay, { merge: true }) ) ) ), (0, _elliptical.createElement)( 'sequence', { unique: true }, (0, _elliptical.createElement)( 'sequence', { id: 'timeOfDay', optional: true, limited: true }, (0, _elliptical.createElement)('literal', { text: 'the ' }), (0, _elliptical.createElement)(_time.TimeOfDay, { merge: true }), (0, _elliptical.createElement)('literal', { text: ' of ' }) ), (0, _elliptical.createElement)( 'choice', { merge: true, ellipsis: true }, (0, _elliptical.createElement)(TrueDate, { id: 'date', prepositions: props.prepositions }), (0, _elliptical.createElement)( 'sequence', null, (0, _elliptical.createElement)('literal', { id: 'relativeDate', text: 'this ', value: { day: 0 } }), (0, _elliptical.createElement)(_time.TimeOfDay, { id: 'timeOfDay' }) ), (0, _elliptical.createElement)( 'placeholder', { label: 'date' }, (0, _elliptical.createElement)('literal', { text: 'tonight', value: { relativeDate: { day: 0 }, time: { hour: 20 } } }) ) ), (0, _elliptical.createElement)( 'sequence', { id: 'timeOfDay', optional: true, limited: true, ellipsis: true }, (0, _elliptical.createElement)('list', { items: [' ', ' in the '], limit: 1 }), (0, _elliptical.createElement)(_time.TimeOfDay, { merge: true }) ), (0, _elliptical.createElement)( 'sequence', { id: 'time', ellipsis: true }, (0, _elliptical.createElement)('literal', { text: ' ' }), (0, _elliptical.createElement)(_time.InternalTime, { merge: true, prepositions: true, seconds: false }) ), (0, _elliptical.createElement)( 'sequence', { id: 'timeOfDay' }, (0, _elliptical.createElement)('literal', { text: ' in the ' }), (0, _elliptical.createElement)(_time.TimeOfDay, { merge: true }) ) ) ) ) ); } };