kokopu
Version:
A JavaScript/TypeScript library implementing the chess game rules and providing tools to read/write the standard chess file formats.
248 lines • 12.3 kB
JavaScript
"use strict";
/*!
* -------------------------------------------------------------------------- *
* *
* Kokopu - A JavaScript/TypeScript chess library. *
* <https://www.npmjs.com/package/kokopu> *
* Copyright (C) 2018-2025 Yoann Le Montagner <yo35 -at- melix.net> *
* *
* Kokopu is free software: you can redistribute it and/or *
* modify it under the terms of the GNU Lesser General Public License *
* as published by the Free Software Foundation, either version 3 of *
* the License, or (at your option) any later version. *
* *
* Kokopu is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General *
* Public License along with this program. If not, see *
* <http://www.gnu.org/licenses/>. *
* *
* -------------------------------------------------------------------------- */
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
if (kind === "m") throw new TypeError("Private method is not writable");
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
};
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var _DateValue_type, _DateValue_year, _DateValue_month, _DateValue_day;
Object.defineProperty(exports, "__esModule", { value: true });
exports.DateValue = void 0;
const exception_1 = require("./exception");
/**
* Date of a chess game. It can be either partially defined (with the year only, or with the year and month but without day of month),
* or fully defined (with year, month and day of month).
*
* @see {@link Game.date}
*/
class DateValue {
constructor(dateOrYear, month, day) {
_DateValue_type.set(this, void 0);
_DateValue_year.set(this, void 0);
_DateValue_month.set(this, void 0);
_DateValue_day.set(this, void 0);
if (dateOrYear instanceof Date) {
__classPrivateFieldSet(this, _DateValue_type, 'ymd', "f");
__classPrivateFieldSet(this, _DateValue_year, dateOrYear.getFullYear(), "f");
__classPrivateFieldSet(this, _DateValue_month, dateOrYear.getMonth() + 1, "f");
__classPrivateFieldSet(this, _DateValue_day, dateOrYear.getDate(), "f");
}
else {
const type = computeType(dateOrYear, month, day);
if (!type) {
throw new exception_1.IllegalArgument('DateValue()');
}
__classPrivateFieldSet(this, _DateValue_type, type, "f");
__classPrivateFieldSet(this, _DateValue_year, dateOrYear, "f");
__classPrivateFieldSet(this, _DateValue_month, month ?? undefined, "f");
__classPrivateFieldSet(this, _DateValue_day, day ?? undefined, "f");
}
}
/**
* Type of date value:
* - `'y'` means that only the year is defined,
* - `'ym'` means that the year and the month are defined, but not the day in month,
* - `'ymd'` means that the exact day is defined.
*/
type() {
return __classPrivateFieldGet(this, _DateValue_type, "f");
}
/**
* Year (e.g. `2022`).
*/
year() {
return __classPrivateFieldGet(this, _DateValue_year, "f");
}
/**
* Month index, valued between 1 (January) and 12 (December) inclusive.
*
* @throws {@link exception.IllegalArgument} if the current type is `'y'` (see {@link DateValue.type}).
*/
month() {
if (__classPrivateFieldGet(this, _DateValue_month, "f") === undefined) {
throw new exception_1.IllegalArgument('DateValue.month()');
}
return __classPrivateFieldGet(this, _DateValue_month, "f");
}
/**
* Day in month, valued between 1 and the number of days in the corresponding month (thus 31 at most).
*
* @throws {@link exception.IllegalArgument} if the current type is `'y'` or `'ym'` (see {@link DateValue.type}).
*/
day() {
if (__classPrivateFieldGet(this, _DateValue_day, "f") === undefined) {
throw new exception_1.IllegalArgument('DateValue.day()');
}
return __classPrivateFieldGet(this, _DateValue_day, "f");
}
/**
* Convert the current object into a standard JavaScript [Date](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date)
* object.
*
* If the type of the current object is `'ym'`, the returned `Date` object points at the first day of the corresponding month.
* If the type of the current object is `'y'`, the returned `Date` object points at the first day of the corresponding year.
*/
toDate() {
const month = __classPrivateFieldGet(this, _DateValue_month, "f") === undefined ? 0 : __classPrivateFieldGet(this, _DateValue_month, "f") - 1;
const day = __classPrivateFieldGet(this, _DateValue_day, "f") === undefined ? 1 : __classPrivateFieldGet(this, _DateValue_day, "f");
return new Date(__classPrivateFieldGet(this, _DateValue_year, "f"), month, day);
}
/**
* Get the date in a compact format (e.g. `'2022-07-19'`, `'2022-07-**'` or `'2022-**-**'` depending on the type of the current object).
*/
toString() {
return toStringImpl(__classPrivateFieldGet(this, _DateValue_year, "f"), __classPrivateFieldGet(this, _DateValue_month, "f"), __classPrivateFieldGet(this, _DateValue_day, "f"), '-', '**');
}
/**
* Parse the given value as a date in compact format (e.g. `'2022-07-19'`, `'2022-07-**'` or `'2022-**-**'`).
*
* @returns `undefined` if the value does not represent a valid date.
*/
static fromString(value) {
if (typeof value !== 'string') {
throw new exception_1.IllegalArgument('DateValue.fromString()');
}
return fromStringImpl(value, /^([0-9]{4})-([0-9]{2})-([0-9]{2})$/, /^([0-9]{4})-([0-9]{2})-\*\*$/, /^([0-9]{4})-\*\*-\*\*$/, false);
}
/**
* Get the date in a PGN format (e.g. `'2022.07.19'`, `'2022.07.??'` or `'2022.??.??'` depending on the type of the current object).
*/
toPGNString() {
return toStringImpl(__classPrivateFieldGet(this, _DateValue_year, "f"), __classPrivateFieldGet(this, _DateValue_month, "f"), __classPrivateFieldGet(this, _DateValue_day, "f"), '.', '??');
}
/**
* Parse the given value as a date in PGN format (e.g. `'2022.07.19'`, `'2022.07.??'` or `'2022.??.??'`).
*
* @returns `undefined` if the value does not represent a valid date.
*/
static fromPGNString(value) {
if (typeof value !== 'string') {
throw new exception_1.IllegalArgument('DateValue.fromPGNString()');
}
return fromStringImpl(value, /^([0-9]{4})\.([0-9]{2})\.([0-9]{2})$/, /^([0-9]{4})\.([0-9]{2})\.\?\?$/, /^([0-9]{4})(?:\.\?\?\.\?\?)?$/, true);
}
/**
* Get the date of the game as a human-readable string (e.g. `'November 1955'`, `'September 4, 2021'`).
*
* @param locales - Locales to use to generate the result. If undefined, the default locale of the execution environment is used.
* See [Intl documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl#locale_identification_and_negotiation)
* for more details.
*/
toHumanReadableString(locales) {
switch (__classPrivateFieldGet(this, _DateValue_type, "f")) {
case 'ymd': {
const date = new Date(__classPrivateFieldGet(this, _DateValue_year, "f"), __classPrivateFieldGet(this, _DateValue_month, "f") - 1, __classPrivateFieldGet(this, _DateValue_day, "f"));
return new Intl.DateTimeFormat(locales, { dateStyle: 'long' }).format(date);
}
case 'ym': {
const date = new Date(__classPrivateFieldGet(this, _DateValue_year, "f"), __classPrivateFieldGet(this, _DateValue_month, "f") - 1, 1);
return new Intl.DateTimeFormat(locales, { month: 'long', year: 'numeric' }).format(date);
}
default:
return String(__classPrivateFieldGet(this, _DateValue_year, "f"));
}
}
/**
* Whether the given year/month/day would corresponds to a valid date or not.
*/
static isValid(year, month, day) {
return Boolean(computeType(year, month, day));
}
}
exports.DateValue = DateValue;
_DateValue_type = new WeakMap(), _DateValue_year = new WeakMap(), _DateValue_month = new WeakMap(), _DateValue_day = new WeakMap();
function toStringImpl(year, month, day, separator, undefinedToken) {
const y = String(year).padStart(4, '0');
const m = month === undefined ? undefinedToken : String(month).padStart(2, '0');
const d = day === undefined ? undefinedToken : String(day).padStart(2, '0');
return y + separator + m + separator + d;
}
function fromStringImpl(value, ymdRe, ymRe, yRe, tolerant) {
if (ymdRe.test(value)) {
const y = RegExp.$1;
const m = RegExp.$2;
const d = RegExp.$3;
const year = parseInt(y, 10);
const month = parseInt(m, 10);
const day = parseInt(d, 10);
if (DateValue.isValid(year, month, day)) {
return new DateValue(year, month, day);
}
else if (tolerant) {
return DateValue.isValid(year, month) ? new DateValue(year, month) : new DateValue(year);
}
else {
return undefined;
}
}
else if (ymRe.test(value)) {
const y = RegExp.$1;
const m = RegExp.$2;
const year = parseInt(y, 10);
const month = parseInt(m, 10);
if (DateValue.isValid(year, month)) {
return new DateValue(year, month);
}
else if (tolerant) {
return new DateValue(year);
}
else {
return undefined;
}
}
else if (yRe.test(value)) {
const year = parseInt(RegExp.$1, 10);
return new DateValue(year);
}
else {
return undefined;
}
}
function computeType(year, month, day) {
if (day !== undefined && day !== null) {
return isValidYear(year) && isValidMonth(month) && Number.isInteger(day) && day >= 1 && day <= daysInMonth(year, month) ? 'ymd' : false;
}
else if (month !== undefined && month !== null) {
return isValidYear(year) && isValidMonth(month) ? 'ym' : false;
}
else {
return isValidYear(year) ? 'y' : false;
}
}
function isValidYear(year) {
return Number.isInteger(year) && year >= 0;
}
function isValidMonth(month) {
return Number.isInteger(month) && month >= 1 && month <= 12;
}
function daysInMonth(year, month) {
return new Date(year, month, 0).getDate();
}
//# sourceMappingURL=date_value.js.map