wikibase-edit
Version:
Edit Wikibase from NodeJS
93 lines • 3.8 kB
JavaScript
import { isEntityId, isItemId } from 'wikibase-sdk';
import { parseCalendar } from './claim/parse_calendar.js';
import { parseUnit } from './claim/quantity.js';
import { newError } from './error.js';
import { isNonEmptyString, isNumber, isStringNumber } from './utils.js';
export const string = isNonEmptyString;
export const entity = isEntityId;
// See https://www.mediawiki.org/wiki/Wikibase/DataModel#Dates_and_times
// The positive years will be signed later
export const time = time => {
time = time.value || time;
let precision, calendar, calendarmodel;
if (typeof time === 'object') {
const dateObject = time;
({ precision, calendar, calendarmodel, time } = time);
if (typeof precision === 'number' && (precision < 0 || precision > 14)) {
return false;
}
if (precision > 11)
throw newError('time precision not supported by the Wikibase API', dateObject);
calendarmodel = calendarmodel || calendar;
if (calendarmodel && !parseCalendar(calendarmodel, time)) {
throw newError('invalid calendar', dateObject);
}
}
time = time.toString();
const sign = time[0] === '-' ? '-' : '+';
const year = time.replace(/^(-|\+)/, '').split('-')[0];
// Parsing as an ISO String should not throw an Invalid time value error
// Only trying to parse 5-digit years or below, as higher years
// will fail, even when valid Wikibase dates
// Excluding negative years as the format expected by Wikibase
// doesn't have the padding zeros expected by ISO
if (sign === '+' && year.length <= 5) {
try {
time = time.replace(/^\+/, '');
let isoTime = time;
// ISO validation would fail if either date or month are 0
// Replace date or date and month digits with 01
// if precision is less than 11 or 10, respectively
if (precision != null) {
if (precision < 10) {
isoTime = isoTime.replace(/^(\d{4})-\d{1,2}-\d{1,2}/, '$1-01-01');
}
else if (precision < 11) {
isoTime = isoTime.replace(/^(\d{4}-\d{1,2})-\d{1,2}/, '$1-01');
}
}
new Date(isoTime).toISOString();
}
catch (err) {
if (err.name === 'RangeError')
return false;
else
throw err;
}
}
if (precision != null && precision > 11) {
return /^(-|\+)?\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2,3}Z$/.test(time);
}
else if (time.match('T')) {
return /^(-|\+)?\d{4,16}-\d{2}-\d{2}T00:00:00(\.000)?Z$/.test(time);
}
else {
return /^(-|\+)?\d{4,16}(-\d{2}){0,2}$/.test(time);
}
};
export const monolingualtext = value => {
value = value.value || value;
const { text, language } = value;
return isNonEmptyString(text) && isNonEmptyString(language);
};
// cf https://www.mediawiki.org/wiki/Wikibase/DataModel#Quantities
export const quantity = amount => {
amount = amount.value || amount;
if (typeof amount === 'object') {
let unit;
({ unit, amount } = amount);
if (unit && !isItemId(parseUnit(unit)) && unit !== '1')
return false;
}
// Accepting both numbers or string numbers as the amount will be
// turned as a string lib/claim/builders.js signAmount function anyway
return isNumber(amount) || isStringNumber(amount);
};
export const globecoordinate = obj => {
obj = obj.value || obj;
if (typeof obj !== 'object')
return false;
const { latitude, longitude, precision } = obj;
return isNumber(latitude) && isNumber(longitude) && isNumber(precision);
};
//# sourceMappingURL=datatype_tests.js.map