moment-relative-range
Version:
Calculate a date range in the past from a certain moment
494 lines (427 loc) • 12.9 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.RANGE_MEASURES = exports.RANGE_PARTS = exports.RANGE_TYPES = exports.DAY_FORMAT = 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; };
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
exports.extendMoment = extendMoment;
var _moment = require('moment');
var _moment2 = _interopRequireDefault(_moment);
var _format2 = require('./format');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var DAY_FORMAT = exports.DAY_FORMAT = 'YYYY-MM-DD';
function isDateType(Type) {
return Object.prototype.toString.call(new Type()) === '[object Date]';
}
function makeMomentOrNull(value) {
return value ? (0, _moment2.default)(value) : value;
}
var RANGE_TYPES = exports.RANGE_TYPES = Object.freeze({
previous: 'previous',
current: 'current',
next: 'next'
});
var RANGE_PARTS = exports.RANGE_PARTS = Object.freeze({
start: 'start',
end: 'end'
});
var RANGE_MEASURES = exports.RANGE_MEASURES = Object.freeze({
day: 'day',
days: 'day',
week: 'week',
weeks: 'week',
isoWeek: 'isoWeek',
isoWeeks: 'isoWeek',
month: 'month',
months: 'month',
quarter: 'quarter',
quarters: 'quarter',
year: 'year',
years: 'year'
});
var rangeSchema = {
date: {
type: Date
},
measure: {
type: String,
default: RANGE_MEASURES.day,
enum: Object.keys(RANGE_MEASURES)
},
units: {
type: Number,
default: 1,
calculate: function calculate(value) {
return this.type === RANGE_TYPES.current ? 1 : value;
}
},
type: {
type: String,
default: RANGE_TYPES.current,
enum: Object.keys(RANGE_TYPES)
},
whole: {
type: Boolean
},
margin: {
type: Number,
calculate: function calculate(value) {
var defaultValue = this.type === RANGE_TYPES.current ? 0 : 1;
return value !== undefined ? value : defaultValue;
}
},
start: {
type: Date
},
end: {
type: Date
},
minimumStart: {
type: Date
},
// eslint-disable-next-line no-underscore-dangle
_isARelativeRangeObject: {
type: Boolean,
default: true
}
};
var RelativeRange = function () {
_createClass(RelativeRange, [{
key: 'isToDate',
value: function isToDate() {
return this.type === RANGE_TYPES.current;
}
}, {
key: 'isWhole',
// Days are always whole days.
// If something is `current`, then it isn't whole by default.
// Can be manually overruled for things that aren't a day.
value: function isWhole() {
var whole = this.data.whole;
return this.cleanMeasure === RANGE_MEASURES.day || (whole != null ? whole : !this.isToDate());
}
}, {
key: 'start',
get: function get() {
var end = this.end;
if (this.data.start) {
return _moment2.default.min((0, _moment2.default)(this.data.start), end);
}
var start = (0, _moment2.default)(end);
if (!this.isWhole()) {
start.subtract(this.units, this.countableMeasure);
if (this.isToDate()) {
start.endOf(this.cleanMeasure);
}
start.add(1, RANGE_MEASURES.day);
} else {
start.subtract(this.units - 1, this.countableMeasure).startOf(this.cleanMeasure);
}
start.startOf(RANGE_MEASURES.day);
if (this.minimumStart) {
start = _moment2.default.max(start, (0, _moment2.default)(this.minimumStart));
start = _moment2.default.min(end, start);
}
return start;
},
set: function set(value) {
this.data.start = makeMomentOrNull(value);
}
}, {
key: 'end',
get: function get() {
var end = (0, _moment2.default)(this.date);
if (this.data.end) {
return _moment2.default.min((0, _moment2.default)(this.data.end), end);
}
var change = void 0;
var move = void 0;
var units = void 0;
var measure = void 0;
switch (this.type) {
case RANGE_TYPES.next:
change = 'add';
move = 'endOf';
units = this.units;
measure = this.countableMeasure;
break;
default:
change = 'subtract';
move = 'startOf';
units = 1;
measure = RANGE_MEASURES.day;
}
if (this.isWhole()) {
end[change](this.margin - 1, RANGE_MEASURES.day)[move](this.cleanMeasure)[change](units, measure).endOf(this.cleanMeasure);
} else {
end[change](this.margin, RANGE_MEASURES.day);
}
return end.endOf(RANGE_MEASURES.day);
},
set: function set(value) {
this.data.end = makeMomentOrNull(value);
}
// set date(value: string | moment.Moment | Date): void { this.__date = makeMomentOrNull(value); }
// get date(): moment.Moment { return this.__date; }
}, {
key: 'length',
get: function get() {
return 1 + this.end.diff(this.start, RANGE_MEASURES.days);
}
}, {
key: 'count',
get: function get() {
switch (this.type) {
case RANGE_TYPES.current:
return 0;
case RANGE_TYPES.previous:
return this.units * -1;
case RANGE_TYPES.next:
default:
return this.units;
}
}
}, {
key: 'cleanMeasure',
get: function get() {
return RANGE_MEASURES[this.measure];
}
}, {
key: 'countableMeasure',
get: function get() {
switch (this.cleanMeasure) {
case RANGE_MEASURES.isoWeek:
return RANGE_MEASURES.week;
default:
return this.cleanMeasure;
}
}
}]);
function RelativeRange() {
var data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
_classCallCheck(this, RelativeRange);
this.data = {};
this.set(data);
}
_createClass(RelativeRange, [{
key: 'set',
value: function set() {
var data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
this.data = _extends({}, this.data, data);
return this;
}
}, {
key: 'previous',
value: function previous(units, measure, whole) {
return new this.constructor({
date: this.start,
type: RANGE_TYPES.previous,
units: units,
measure: measure,
whole: whole
});
}
}, {
key: 'current',
value: function current(measure, whole) {
return new this.constructor({
date: this.end,
type: RANGE_TYPES.current,
units: 1,
measure: measure,
whole: whole
});
}
}, {
key: 'next',
value: function next(units, measure, whole) {
return new this.constructor({
date: this.end,
type: RANGE_TYPES.next,
units: units,
measure: measure,
whole: whole
});
}
}, {
key: 'lock',
value: function lock(part) {
if (part) {
this[part] = this[part];
} else {
this.data.start = this.start;
this.data.end = this.end;
}
return this;
}
}, {
key: 'unlock',
value: function unlock(part) {
if (part) {
this[part] = null;
} else {
this.start = null;
this.end = null;
}
return this;
}
}, {
key: 'isLocked',
value: function isLocked(part) {
var _this = this;
var parts = part ? [part] : Object.keys(RANGE_PARTS);
return parts.every(function (key) {
return _this.data[key];
});
}
}, {
key: 'locale',
value: function (_locale) {
function locale(_x) {
return _locale.apply(this, arguments);
}
locale.toString = function () {
return _locale.toString();
};
return locale;
}(function (locale) {
if (typeof locale === 'undefined') {
var localeLocale = this.data.locale || _moment2.default.locale();
return localeLocale;
}
if (typeof locale === 'boolean') {
if (locale === false) {
delete this.data.locale;
}
return this;
}
this.data.locale = locale;
return this;
})
}, {
key: 'format',
value: function (_format) {
function format(_x2, _x3) {
return _format.apply(this, arguments);
}
format.toString = function () {
return _format.toString();
};
return format;
}(function (format, options) {
var localLocale = this.locale();
var locale = void 0;
if (typeof localLocale === 'string') {
locale = localLocale;
}
switch (format) {
case 'r':
case 'R':
return (0, _format2.formatRelative)({
count: this.count,
measure: this.countableMeasure,
locale: locale
}, format);
default:
return (0, _format2.formatStatic)({
date: this.date,
start: this.start,
end: this.end,
locale: locale
}, format, options);
}
})
}, {
key: 'toJSON',
value: function toJSON() {
var _this2 = this;
var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
_ref$format = _ref.format,
format = _ref$format === undefined ? DAY_FORMAT : _ref$format,
_ref$defaults = _ref.defaults,
defaults = _ref$defaults === undefined ? true : _ref$defaults;
var json = {};
var data = defaults ? this : this.data;
Object.keys(rangeSchema).filter(function (attr) {
return data[attr] != null;
}).forEach(function (attr) {
var schema = rangeSchema[attr];
if (isDateType(schema.type)) {
json[attr] = data[attr] && (0, _moment2.default)(_this2[attr]).format(format);
} else {
json[attr] = data[attr];
}
});
return json;
}
}, {
key: 'toArray',
value: function toArray() {
var format = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : DAY_FORMAT;
return [this.start.format(format), this.end.format(format)];
}
}]);
return RelativeRange;
}();
Object.keys(rangeSchema).forEach(function (attr) {
var settings = rangeSchema[attr];
var descriptor = Object.getOwnPropertyDescriptor(RelativeRange.prototype, attr);
var property = {};
if (!descriptor || !descriptor.get) {
property.get = function get() {
var value = this.data[attr] != null ? this.data[attr] : settings.default;
return settings.calculate ? settings.calculate.call(this, value) : value;
};
}
if (!descriptor || !descriptor.set) {
property.set = function set(value) {
var schema = rangeSchema[attr];
if (schema.enum && value != null && schema.enum.indexOf(value) === -1) {
var valueString = String(value);
throw new Error(valueString + ' isn\'t an allowed value for RelativeRange.' + attr);
}
if (isDateType(schema.type)) {
this.data[attr] = makeMomentOrNull(value);
} else {
this.data[attr] = value;
}
};
}
if (Object.keys(property).length) {
Object.defineProperty(RelativeRange.prototype, attr, property);
}
});
function extendMoment(m) {
// eslint-disable-next-line no-param-reassign
m.fn.previous = function previous(units, measure, whole) {
return new RelativeRange({
date: this,
type: RANGE_TYPES.previous,
units: units,
measure: measure,
whole: whole
});
};
// eslint-disable-next-line no-param-reassign
m.fn.next = function next(units, measure, whole) {
return new RelativeRange({
date: this,
type: RANGE_TYPES.next,
units: units,
measure: measure,
whole: whole
});
};
// eslint-disable-next-line no-param-reassign
m.fn.current = function current(measure, whole) {
return new RelativeRange({
date: this,
type: RANGE_TYPES.current,
measure: measure,
whole: whole
});
};
}
exports.default = RelativeRange;