UNPKG

wikibase-edit

Version:

Edit Wikibase from NodeJS

152 lines 6.63 kB
import { simplifySnak } from 'wikibase-sdk'; import { newError } from '../error.js'; import { inviteToOpenAFeatureRequest } from '../issues.js'; import { isPlainObject, isString } from '../utils.js'; import { parseUnit } from './quantity.js'; export function isMatchingSnak(_existingSnak, _searchedValue) { const existingSnak = 'mainsnak' in _existingSnak ? _existingSnak.mainsnak : _existingSnak; if (typeof _searchedValue === 'object' && 'snaktype' in _searchedValue && _searchedValue.snaktype && (_searchedValue.snaktype !== 'value' || existingSnak.snaktype !== 'value')) { return existingSnak.snaktype === _searchedValue.snaktype; } let searchedValue; if (typeof _searchedValue === 'object' && 'datavalue' in _searchedValue) { searchedValue = _searchedValue.datavalue.value; } else { searchedValue = _searchedValue; } if (!('datavalue' in existingSnak)) return false; const datavalueType = existingSnak.datavalue.type; if (comparatorsByDatavalueType[datavalueType] == null) { const context = { datavalueType }; const featureRequestMessage = inviteToOpenAFeatureRequest({ title: `claim reconciliation: add support for ${datavalueType} datavalue type`, context, }); throw newError(`unsupported datavalue type: ${datavalueType}\n${featureRequestMessage}`, context); } // @ts-expect-error return comparatorsByDatavalueType[datavalueType](existingSnak, searchedValue); } const comparatorsByDatavalueType = { globecoordinate: (snak, searchedValue) => { const value = snak.datavalue.value; const { latitude, longitude, altitude, precision, globe } = value; if (typeof searchedValue === 'object' && !(searchedValue instanceof Array)) { if (latitude !== searchedValue.latitude) return false; if (longitude !== searchedValue.longitude) return false; if (precision !== searchedValue.precision) return false; if (globe !== searchedValue.globe) return false; if (!(altitude === null && searchedValue.altitude === undefined)) { if (altitude !== searchedValue.altitude) return false; } return true; } else { return latitude === searchedValue[0] && longitude === searchedValue[1]; } }, monolingualtext: (snak, searchedValue) => { const value = snak.datavalue.value; const { text, language } = value; if (typeof searchedValue === 'string') { return text === searchedValue; } else { return language === searchedValue.language && text === searchedValue.text; } }, quantity: (snak, searchedValue) => { const value = snak.datavalue.value; let { amount, lowerBound, upperBound } = value; amount = parseAmount(amount); lowerBound = parseAmount(lowerBound); upperBound = parseAmount(upperBound); if (isPlainObject(searchedValue)) { const searchedAmount = parseAmount(searchedValue.amount); const searchedLowerBound = parseAmount(searchedValue.lowerBound); const searchedUpperBound = parseAmount(searchedValue.upperBound); const searchUnit = parseUnit(searchedValue.unit); const snakUnit = getUnit(snak); // Unspecified units do not prevent a match if (searchUnit !== '1' && snakUnit !== '1' && searchUnit !== snakUnit) { return false; } if (lowerBound != null && searchedLowerBound != null && lowerBound !== searchedLowerBound) { return false; } if (upperBound != null && searchedUpperBound != null && upperBound !== searchedUpperBound) { return false; } return searchedAmount === amount; } else { return amount === parseAmount(searchedValue); } }, string: (snak, searchedValue) => { const value = snak.datavalue.value; if (searchedValue.startsWith('http')) { return normalizeUrl(value) === normalizeUrl(searchedValue); } else { return value === searchedValue; } }, time: (snak, searchedValue) => { const value = snak.datavalue.value; const { time, timezone, before, after, precision, calendarmodel } = value; if (typeof searchedValue === 'object') { if (searchedValue.timezone != null && searchedValue.timezone !== timezone) return false; if (searchedValue.before != null && searchedValue.before !== before) return false; if (searchedValue.after != null && searchedValue.after !== after) return false; if (searchedValue.precision != null && searchedValue.precision !== precision) return false; if (searchedValue.calendarmodel != null && searchedValue.calendarmodel !== calendarmodel) return false; const normalizedSnakTime = normalizeTime(time, searchedValue.precision); const normalizedInputValueTime = normalizeTime(searchedValue.time, searchedValue.precision); return normalizedSnakTime === normalizedInputValueTime; } else { const simplifiedSnak = simplifySnak(snak, { timeConverter: 'simple-day' }); return simplifiedSnak === searchedValue; } }, 'wikibase-entityid': (snak, searchedValue) => { const value = snak.datavalue.value; if (typeof searchedValue === 'string') { return value.id === searchedValue; } else if (value.id != null && searchedValue.id != null) { return value.id === searchedValue.id; } else { return value['entity-type'] === searchedValue['entity-type'] && value['numeric-id'] === searchedValue['numeric-id']; } }, }; function getUnit(snak) { return parseUnit(snak.datavalue.value.unit); } const parseAmount = amount => isString(amount) ? parseFloat(amount) : amount; function normalizeTime(time, precison) { time = time.replace(/^\+/, ''); if (precison <= 11) { time = time .replace(/-00/g, '-01') .split('T')[0]; } return time; } const normalizeUrl = url => url.replace(/\/$/, '').replace(/\/\/www\./, '//').toLowerCase(); //# sourceMappingURL=is_matching_snak.js.map