elliptical-datetime
Version:
Elliptical phrases to handle natural language dates and times
687 lines (550 loc) • 19.1 kB
JavaScript
import _regeneratorRuntime from 'babel-runtime/regenerator';
import _extends from 'babel-runtime/helpers/extends';
var _marked = [mapRangeResults, mapRangeOptions].map(_regeneratorRuntime.mark);
/** @jsx createElement */
import _ from 'lodash';
import moment from 'moment';
import { createElement } from 'elliptical';
import { join, relativeDate, possibleDates, ambiguousTime, timeLessThan } from './helpers';
import { DateTime, InternalDateTime } from './datetime';
import { Duration } from './duration';
var TrueDateTime = {
describe: function describe(_ref) {
var props = _ref.props;
return createElement(
'sequence',
null,
createElement('literal', { text: 'all day ', id: 'allDay', value: true, optional: true, limited: true }),
createElement(
'choice',
{ merge: true },
createElement(InternalDateTime, _extends({}, props, { id: undefined })),
createElement(
'map',
{ 'function': function _function(result) {
return { dateTime: result };
} },
createElement(DateTime, _extends({}, props, { nullify: true }))
)
)
);
}
};
function mapRangeResults(result, props) {
var _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, startDate, _iteratorNormalCompletion2, _didIteratorError2, _iteratorError2, _iterator2, _step2, endDate, _iteratorNormalCompletion3, _didIteratorError3, _iteratorError3, _iterator3, _step3, _startDate, _iteratorNormalCompletion4, _didIteratorError4, _iteratorError4, _iterator4, _step4, _endDate, _iteratorNormalCompletion5, _didIteratorError5, _iteratorError5, _iterator5, _step5, _startDate2, start, _iteratorNormalCompletion6, _didIteratorError6, _iteratorError6, _iterator6, _step6, _startDate3, _iteratorNormalCompletion7, _didIteratorError7, _iteratorError7, _iterator7, _step7, _startDate4, _start;
return _regeneratorRuntime.wrap(function mapRangeResults$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
if (!(result.start && result.end)) {
_context.next = 106;
break;
}
if (!(!result.start.time && !result.end.time)) {
_context.next = 54;
break;
}
_iteratorNormalCompletion = true;
_didIteratorError = false;
_iteratorError = undefined;
_context.prev = 5;
_iterator = possibleDates(result.start)[Symbol.iterator]();
case 7:
if (_iteratorNormalCompletion = (_step = _iterator.next()).done) {
_context.next = 38;
break;
}
startDate = _step.value;
_iteratorNormalCompletion2 = true;
_didIteratorError2 = false;
_iteratorError2 = undefined;
_context.prev = 12;
_iterator2 = possibleDates(result.end)[Symbol.iterator]();
case 14:
if (_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done) {
_context.next = 21;
break;
}
endDate = _step2.value;
_context.next = 18;
return {
start: join(startDate, { hour: 0, minute: 0, second: 0 }, props.timezoneOffset),
end: join(endDate, { hour: 0, minute: 0, second: 0 }, props.timezoneOffset),
allDay: true
};
case 18:
_iteratorNormalCompletion2 = true;
_context.next = 14;
break;
case 21:
_context.next = 27;
break;
case 23:
_context.prev = 23;
_context.t0 = _context['catch'](12);
_didIteratorError2 = true;
_iteratorError2 = _context.t0;
case 27:
_context.prev = 27;
_context.prev = 28;
if (!_iteratorNormalCompletion2 && _iterator2.return) {
_iterator2.return();
}
case 30:
_context.prev = 30;
if (!_didIteratorError2) {
_context.next = 33;
break;
}
throw _iteratorError2;
case 33:
return _context.finish(30);
case 34:
return _context.finish(27);
case 35:
_iteratorNormalCompletion = true;
_context.next = 7;
break;
case 38:
_context.next = 44;
break;
case 40:
_context.prev = 40;
_context.t1 = _context['catch'](5);
_didIteratorError = true;
_iteratorError = _context.t1;
case 44:
_context.prev = 44;
_context.prev = 45;
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
case 47:
_context.prev = 47;
if (!_didIteratorError) {
_context.next = 50;
break;
}
throw _iteratorError;
case 50:
return _context.finish(47);
case 51:
return _context.finish(44);
case 52:
_context.next = 104;
break;
case 54:
_iteratorNormalCompletion3 = true;
_didIteratorError3 = false;
_iteratorError3 = undefined;
_context.prev = 57;
_iterator3 = possibleDates(result.start, result.end.date)[Symbol.iterator]();
case 59:
if (_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done) {
_context.next = 90;
break;
}
_startDate = _step3.value;
_iteratorNormalCompletion4 = true;
_didIteratorError4 = false;
_iteratorError4 = undefined;
_context.prev = 64;
_iterator4 = possibleDates(result.end, _startDate)[Symbol.iterator]();
case 66:
if (_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done) {
_context.next = 73;
break;
}
_endDate = _step4.value;
_context.next = 70;
return {
start: join(_startDate, result.start.time || props.defaultTime, props.timezoneOffset),
end: join(_endDate, result.end.time || props.defaultTime, props.timezoneOffset),
allDay: false
};
case 70:
_iteratorNormalCompletion4 = true;
_context.next = 66;
break;
case 73:
_context.next = 79;
break;
case 75:
_context.prev = 75;
_context.t2 = _context['catch'](64);
_didIteratorError4 = true;
_iteratorError4 = _context.t2;
case 79:
_context.prev = 79;
_context.prev = 80;
if (!_iteratorNormalCompletion4 && _iterator4.return) {
_iterator4.return();
}
case 82:
_context.prev = 82;
if (!_didIteratorError4) {
_context.next = 85;
break;
}
throw _iteratorError4;
case 85:
return _context.finish(82);
case 86:
return _context.finish(79);
case 87:
_iteratorNormalCompletion3 = true;
_context.next = 59;
break;
case 90:
_context.next = 96;
break;
case 92:
_context.prev = 92;
_context.t3 = _context['catch'](57);
_didIteratorError3 = true;
_iteratorError3 = _context.t3;
case 96:
_context.prev = 96;
_context.prev = 97;
if (!_iteratorNormalCompletion3 && _iterator3.return) {
_iterator3.return();
}
case 99:
_context.prev = 99;
if (!_didIteratorError3) {
_context.next = 102;
break;
}
throw _iteratorError3;
case 102:
return _context.finish(99);
case 103:
return _context.finish(96);
case 104:
_context.next = 193;
break;
case 106:
if (!(result.start && result.duration)) {
_context.next = 136;
break;
}
_iteratorNormalCompletion5 = true;
_didIteratorError5 = false;
_iteratorError5 = undefined;
_context.prev = 110;
_iterator5 = possibleDates(result.start)[Symbol.iterator]();
case 112:
if (_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done) {
_context.next = 120;
break;
}
_startDate2 = _step5.value;
start = join(_startDate2, result.start.time || props.defaultTime, props.timezoneOffset);
_context.next = 117;
return {
start: start,
end: moment(start).add(result.duration).toDate(),
allDay: false
};
case 117:
_iteratorNormalCompletion5 = true;
_context.next = 112;
break;
case 120:
_context.next = 126;
break;
case 122:
_context.prev = 122;
_context.t4 = _context['catch'](110);
_didIteratorError5 = true;
_iteratorError5 = _context.t4;
case 126:
_context.prev = 126;
_context.prev = 127;
if (!_iteratorNormalCompletion5 && _iterator5.return) {
_iterator5.return();
}
case 129:
_context.prev = 129;
if (!_didIteratorError5) {
_context.next = 132;
break;
}
throw _iteratorError5;
case 132:
return _context.finish(129);
case 133:
return _context.finish(126);
case 134:
_context.next = 193;
break;
case 136:
if (!result.start) {
_context.next = 193;
break;
}
if (result.start.time) {
_context.next = 166;
break;
}
_iteratorNormalCompletion6 = true;
_didIteratorError6 = false;
_iteratorError6 = undefined;
_context.prev = 141;
_iterator6 = possibleDates(result.start)[Symbol.iterator]();
case 143:
if (_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done) {
_context.next = 150;
break;
}
_startDate3 = _step6.value;
_context.next = 147;
return {
start: _startDate3,
end: _startDate3,
allDay: true
};
case 147:
_iteratorNormalCompletion6 = true;
_context.next = 143;
break;
case 150:
_context.next = 156;
break;
case 152:
_context.prev = 152;
_context.t5 = _context['catch'](141);
_didIteratorError6 = true;
_iteratorError6 = _context.t5;
case 156:
_context.prev = 156;
_context.prev = 157;
if (!_iteratorNormalCompletion6 && _iterator6.return) {
_iterator6.return();
}
case 159:
_context.prev = 159;
if (!_didIteratorError6) {
_context.next = 162;
break;
}
throw _iteratorError6;
case 162:
return _context.finish(159);
case 163:
return _context.finish(156);
case 164:
_context.next = 193;
break;
case 166:
_iteratorNormalCompletion7 = true;
_didIteratorError7 = false;
_iteratorError7 = undefined;
_context.prev = 169;
_iterator7 = possibleDates(result.start)[Symbol.iterator]();
case 171:
if (_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done) {
_context.next = 179;
break;
}
_startDate4 = _step7.value;
_start = join(_startDate4, result.start.time, props.timezoneOffset);
_context.next = 176;
return {
start: _start,
end: moment(_start).add(props.defaultDuration).toDate(),
allDay: false
};
case 176:
_iteratorNormalCompletion7 = true;
_context.next = 171;
break;
case 179:
_context.next = 185;
break;
case 181:
_context.prev = 181;
_context.t6 = _context['catch'](169);
_didIteratorError7 = true;
_iteratorError7 = _context.t6;
case 185:
_context.prev = 185;
_context.prev = 186;
if (!_iteratorNormalCompletion7 && _iterator7.return) {
_iterator7.return();
}
case 188:
_context.prev = 188;
if (!_didIteratorError7) {
_context.next = 191;
break;
}
throw _iteratorError7;
case 191:
return _context.finish(188);
case 192:
return _context.finish(185);
case 193:
case 'end':
return _context.stop();
}
}
}, _marked[0], this, [[5, 40, 44, 52], [12, 23, 27, 35], [28,, 30, 34], [45,, 47, 51], [57, 92, 96, 104], [64, 75, 79, 87], [80,, 82, 86], [97,, 99, 103], [110, 122, 126, 134], [127,, 129, 133], [141, 152, 156, 164], [157,, 159, 163], [169, 181, 185, 193], [186,, 188, 192]]);
}
function preprocessRangeAmbiguity(result, props) {
if (result.start && result.end) {
if (result.end.date && result.end._ambiguousMonth) {
var trueEndDate = moment(result.end.date).month(moment(result.start.date).month()).toDate();
var end = _.assign({}, result.end, { date: trueEndDate });
return _.assign({}, result, { end: end });
}
if (result.start._ambiguousAMPM && result.end._specificAMPM) {
var start = _.clone(result.start);
start.time = ambiguousTime(result.start.time, result.end._specificAMPM);
return _.assign({}, result, { start: start });
}
}
return result;
}
function mapRangeOptions(option, props) {
var processedResult, _iteratorNormalCompletion8, _didIteratorError8, _iteratorError8, _iterator8, _step8, result;
return _regeneratorRuntime.wrap(function mapRangeOptions$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
processedResult = preprocessRangeAmbiguity(option.result, props);
_iteratorNormalCompletion8 = true;
_didIteratorError8 = false;
_iteratorError8 = undefined;
_context2.prev = 4;
_iterator8 = mapRangeResults(processedResult, props)[Symbol.iterator]();
case 6:
if (_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done) {
_context2.next = 13;
break;
}
result = _step8.value;
_context2.next = 10;
return _.assign({}, option, { result: result });
case 10:
_iteratorNormalCompletion8 = true;
_context2.next = 6;
break;
case 13:
_context2.next = 19;
break;
case 15:
_context2.prev = 15;
_context2.t0 = _context2['catch'](4);
_didIteratorError8 = true;
_iteratorError8 = _context2.t0;
case 19:
_context2.prev = 19;
_context2.prev = 20;
if (!_iteratorNormalCompletion8 && _iterator8.return) {
_iterator8.return();
}
case 22:
_context2.prev = 22;
if (!_didIteratorError8) {
_context2.next = 25;
break;
}
throw _iteratorError8;
case 25:
return _context2.finish(22);
case 26:
return _context2.finish(19);
case 27:
case 'end':
return _context2.stop();
}
}
}, _marked[1], this, [[4, 15, 19, 27], [20,, 22, 26]]);
}
function filterRangeOption(option) {
var 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;
}
export var 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: function filterResult(result, _ref2) {
var props = _ref2.props;
var startMoment = moment(result.start);
var endMoment = moment(result.end);
if (endMoment.isBefore(startMoment)) return false;
var currentMoment = result.allDay ? moment().startOf('day') : moment();
if (!props.past && currentMoment.isAfter(startMoment)) return false;
if (!props.future && currentMoment.isBefore(endMoment)) return false;
return true;
},
describe: function describe(_ref3) {
var props = _ref3.props;
return createElement(
'placeholder',
{
label: props.label,
arguments: props.phraseArguments || (props.phraseArguments ? [props.phraseArgument] : [props.label]) },
createElement(
'map',
{ outbound: function outbound(option) {
return mapRangeOptions(option, props);
}, limit: 1, skipIncomplete: true },
createElement(
'filter',
{ outbound: filterRangeOption, skipIncomplete: true },
createElement(
'sequence',
{ unique: true },
createElement(
'sequence',
{ id: 'duration', optional: true, limited: true },
props.prepositions ? createElement('literal', { text: 'for ', decorate: true }) : null,
createElement(Duration, { merge: true }),
createElement('list', { items: [' ', ' starting '], limit: 1 })
),
createElement(TrueDateTime, { ellipsis: true, id: 'start' }),
createElement(
'choice',
{ merge: true },
createElement(
'sequence',
{ id: 'end' },
createElement('list', { items: [' to ', ' - ', '-', '- ', ' -'], limit: 1 }),
createElement(TrueDateTime, { merge: true })
),
createElement(
'sequence',
{ id: 'duration' },
createElement('literal', { text: ' for ' }),
createElement(Duration, { merge: true })
)
)
)
)
)
);
}
};