UNPKG

wikibase-edit

Version:

Edit Wikibase from NodeJS

140 lines 5.24 kB
import { omit } from 'lodash-es'; import { isEntityId, datatypes } from 'wikibase-sdk'; import { newError } from '../error.js'; import { getEntityClaims } from '../get_entity.js'; import { arrayIncludes, forceArray, objectEntries } from '../utils.js'; import { formatClaims, formatSitelinks, formatTermsObject } from './format.js'; import { isIdAliasPattern, resolveIdAlias } from './id_alias.js'; const editableTypes = [ // 'form', 'item', 'lexeme', 'mediainfo', 'property', // 'sense', ]; export async function editEntity(inputParams, properties, instance, config) { return _editEntity(inputParams, properties, instance, config); } export async function _rawEditEntity(inputParams, properties, instance, config) { return _editEntity(inputParams, properties, instance, config); } async function _editEntity(inputParams, properties, instance, config) { validateParameters(inputParams); let { id } = inputParams; const { create, type = 'item', clear, reconciliation } = inputParams; const datatype = 'datatype' in inputParams ? inputParams.datatype : undefined; const rawMode = 'rawMode' in inputParams ? inputParams.rawMode : false; if (!arrayIncludes(editableTypes, type)) { throw newError('invalid entity type', { type }); } let params = { type, data: {} }; let existingClaims; if (create) { if (type === 'property') { if (!datatype) throw newError('missing property datatype', { datatype }); if (!datatypesSet.has(datatype)) { throw newError('invalid property datatype', { datatype, knownDatatypes: datatypes }); } params = { ...params, new: 'property', data: { datatype, }, }; } else { if (datatype) { throw newError("an item can't have a datatype", { datatype }); } params.new = 'item'; } } else if (isEntityId(id) || isIdAliasPattern(id)) { if (isIdAliasPattern(id)) { id = await resolveIdAlias(id, instance); } params.id = id; // @ts-expect-error if (hasReconciliationSettings(reconciliation, inputParams.claims || inputParams.statements)) { existingClaims = await getEntityClaims(id, config); } } else { throw newError('invalid entity id', { id }); } for (const [attribute, types] of objectEntries(attributesPerEntityType)) { if (arrayIncludes(types, params.type)) { if (attribute in inputParams && inputParams[attribute] != null) { const inputParam = inputParams[attribute]; if (rawMode) { params.data[attribute] = inputParam; } else { if (attribute === 'claims' || attribute === 'statements') { params.data[attribute] = formatClaims(inputParam, properties, instance, reconciliation, existingClaims); } else { params.data[attribute] = simplifiedInputFormatters[attribute](inputParam); } } } } } if (clear === true) params.clear = true; if (!clear && Object.keys(params.data).length === 0) { throw newError('no data was passed', { id }); } return { action: 'wbeditentity', data: { ...omit(params, 'type', 'data'), // Stringify as it will be passed as form data data: JSON.stringify(params.data), }, }; } // TODO: add support for lemmas, forms and senses const attributesPerEntityType = { aliases: ['item', 'property'], claims: ['item', 'property', 'lexeme'], descriptions: ['item', 'property', 'mediainfo'], labels: ['item', 'property', 'mediainfo'], statements: ['mediainfo'], sitelinks: ['item'], }; // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type const simplifiedInputFormatters = { aliases: formatTermsObject.bind(null, 'alias'), descriptions: formatTermsObject.bind(null, 'description'), labels: formatTermsObject.bind(null, 'label'), sitelinks: formatSitelinks, }; const datatypesSet = new Set(datatypes); const allowedParameters = new Set([ 'id', 'create', 'type', 'datatype', 'clear', 'rawMode', 'summary', 'baserevid', 'labels', 'aliases', 'descriptions', 'claims', 'statements', 'sitelinks', 'reconciliation', 'origin', ]); function validateParameters(params) { for (const parameter in params) { if (!allowedParameters.has(parameter)) { throw newError(`invalid parameter: ${parameter}`, 400, { parameter, allowedParameters, params }); } } } function hasReconciliationSettings(reconciliation, claims) { if (reconciliation != null) return true; for (const property in claims) { for (const claim of forceArray(claims[property])) { if (claim.reconciliation != null) return true; } } return false; } //# sourceMappingURL=edit.js.map