mwn
Version:
JavaScript & TypeScript MediaWiki bot framework for Node.js
230 lines • 9.63 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = default_1;
const wikitext_1 = require("./wikitext");
function default_1(bot) {
class XDate extends Date {
constructor(...args) {
if (args.length === 1 && typeof args[0] === 'string') {
// parse MediaWiki format: YYYYMMDDHHmmss
if (/^\d{14}$/.test(args[0])) {
let match = /(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/.exec(args[0]);
let dateParts = match.slice(1).map((e) => parseInt(e));
super(Date.UTC(dateParts[0], dateParts[1] - 1, // fix month
dateParts[2], dateParts[3], dateParts[4], dateParts[5]));
}
else {
// Attempt to remove a comma and paren-wrapped timezone, to get MediaWiki
// signature timestamps to parse. Firefox (at least in 75) seems to be
// okay with the comma, though
args[0] = args[0].replace(/(\d\d:\d\d),/, '$1').replace(/\(UTC\)/, 'UTC');
super(args[0]);
}
}
else {
// @ts-ignore
super(...args);
}
// Still no?
if (isNaN(this.getTime()) && !bot.options.suppressInvalidDateWarning) {
console.warn('Invalid initialisation of MwnDate object: ', args);
}
}
isValid() {
return !isNaN(this.getTime());
}
isBefore(date) {
return this.getTime() < date.getTime();
}
isAfter(date) {
return this.getTime() > date.getTime();
}
getUTCMonthName() {
return XDate.localeData.months[this.getUTCMonth()];
}
getUTCMonthNameAbbrev() {
return XDate.localeData.monthsShort[this.getUTCMonth()];
}
getMonthName() {
return XDate.localeData.months[this.getMonth()];
}
getMonthNameAbbrev() {
return XDate.localeData.monthsShort[this.getMonth()];
}
getUTCDayName() {
return XDate.localeData.days[this.getUTCDay()];
}
getUTCDayNameAbbrev() {
return XDate.localeData.daysShort[this.getUTCDay()];
}
getDayName() {
return XDate.localeData.days[this.getDay()];
}
getDayNameAbbrev() {
return XDate.localeData.daysShort[this.getDay()];
}
/** @inheritDoc */
add(number, unit) {
// @ts-ignore
let unitNorm = unitMap[unit] || unitMap[unit + 's']; // so that both singular and plural forms work
if (unitNorm) {
// @ts-ignore
this['set' + unitNorm](this['get' + unitNorm]() + number);
return this;
}
throw new Error('Invalid unit "' + unit + '": Only ' + Object.keys(unitMap).join(', ') + ' are allowed.');
}
/** @inheritDoc */
subtract(number, unit) {
return this.add(-number, unit);
}
/** @inheritDoc */
format(formatstr, zone = 'utc') {
if (!this.isValid()) {
return ''; // avoid bogus NaNs in output
}
// eslint-disable-next-line @typescript-eslint/no-this-alias
let udate = this;
// create a new date object that will contain the date to display as system time
if (!zone || zone === 'utc') {
udate = new XDate(this.getTime()).add(this.getTimezoneOffset(), 'minutes');
}
else if (typeof zone === 'number') {
// convert to utc, then add the utc offset given
udate = new XDate(this.getTime()).add(this.getTimezoneOffset() + zone, 'minutes');
}
const pad = function (num) {
return String(num < 10 ? '0' + num : num);
};
const h24 = udate.getHours(), m = udate.getMinutes(), s = udate.getSeconds();
const D = udate.getDate(), M = udate.getMonth() + 1, Y = udate.getFullYear();
const h12 = h24 % 12 || 12, amOrPm = h24 >= 12 ? 'PM' : 'AM';
const replacementMap = {
HH: pad(h24),
H: h24,
hh: pad(h12),
h: h12,
A: amOrPm,
mm: pad(m),
m: m,
ss: pad(s),
s: s,
dddd: udate.getDayName(),
ddd: udate.getDayNameAbbrev(),
d: udate.getDay(),
DD: pad(D),
D: D,
MMMM: udate.getMonthName(),
MMM: udate.getMonthNameAbbrev(),
MM: pad(M),
M: M,
YYYY: Y,
YY: pad(Y % 100),
Y: Y,
};
let unbinder = new wikitext_1.Unbinder(formatstr); // escape stuff between [...]
unbinder.unbind('\\[', '\\]');
unbinder.text = unbinder.text.replace(
/* Regex notes:
* d(d{2,3})? matches exactly 1, 3 or 4 occurrences of 'd' ('dd' is treated as a double match of 'd')
* Y{1,2}(Y{2})? matches exactly 1, 2 or 4 occurrences of 'Y'
*/
/H{1,2}|h{1,2}|m{1,2}|s{1,2}|d(d{2,3})?|D{1,2}|M{1,4}|Y{1,2}(Y{2})?|A/g, function (match) {
// @ts-ignore
return replacementMap[match];
});
return unbinder.rebind().replace(/\[(.*?)\]/g, '$1');
}
/** @inheritDoc */
calendar(zone = 'utc') {
// Zero out the hours, minutes, seconds and milliseconds - keeping only the date;
// find the difference. Note that setHours() returns the same thing as getTime().
const dateDiff = (new Date().setHours(0, 0, 0, 0) - new Date(this).setHours(0, 0, 0, 0)) / 8.64e7;
switch (true) {
case dateDiff === 0:
return this.format(XDate.localeData.relativeTimes.thisDay, zone);
case dateDiff === 1:
return this.format(XDate.localeData.relativeTimes.prevDay, zone);
case dateDiff > 0 && dateDiff < 7:
return this.format(XDate.localeData.relativeTimes.pastWeek, zone);
case dateDiff === -1:
return this.format(XDate.localeData.relativeTimes.nextDay, zone);
case dateDiff < 0 && dateDiff > -7:
return this.format(XDate.localeData.relativeTimes.thisWeek, zone);
default:
return this.format(XDate.localeData.relativeTimes.other, zone);
}
}
toString() {
return this.format('D MMMM YYYY, HH:mm:ss (UTC)', 'utc');
}
/** @inheritDoc */
static async populateLocaleData(lang) {
const monthsKeys = 'january|february|march|april|may_long|june|july|august|september|october|november|december'.split('|');
const monthsShortKeys = 'jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec'.split('|');
const daysKeys = 'sunday|monday|tuesday|wednesday|thursday|friday|saturday'.split('|');
const daysShortKeys = 'sun|mon|tue|wed|thu|fri|sat'.split('|');
const messages = await bot.getMessages([...monthsKeys, ...monthsShortKeys, ...daysKeys, ...daysShortKeys], {
amlang: lang || 'content',
});
this.localeData.months = monthsKeys.map((key) => messages[key]);
this.localeData.monthsShort = monthsShortKeys.map((key) => messages[key]);
this.localeData.days = daysKeys.map((key) => messages[key]);
this.localeData.daysShort = daysShortKeys.map((key) => messages[key]);
}
/** @inheritDoc */
static getMonthName(monthNum) {
return XDate.localeData.months[monthNum - 1];
}
/** @inheritDoc */
static getMonthNameAbbrev(monthNum) {
return XDate.localeData.monthsShort[monthNum - 1];
}
/** @inheritDoc */
static getDayName(dayNum) {
return XDate.localeData.days[dayNum - 1];
}
/** @inheritDoc */
static getDayNameAbbrev(dayNum) {
return XDate.localeData.daysShort[dayNum - 1];
}
}
XDate.localeData = {
months: [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December',
],
monthsShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
days: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
daysShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
relativeTimes: {
thisDay: '[Today at] h:mm A',
prevDay: '[Yesterday at] h:mm A',
nextDay: '[Tomorrow at] h:mm A',
thisWeek: 'dddd [at] h:mm A',
pastWeek: '[Last] dddd [at] h:mm A',
other: 'YYYY-MM-DD',
},
};
return XDate;
}
// mapping time units with getter/setter function names for add and subtract
const unitMap = {
seconds: 'Seconds',
minutes: 'Minutes',
hours: 'Hours',
days: 'Date',
months: 'Month',
years: 'FullYear',
};
//# sourceMappingURL=date.js.map