wikibase-edit
Version:
Edit Wikibase from NodeJS
107 lines (90 loc) • 3.55 kB
text/typescript
import { isGuid, getEntityIdFromGuid, type Guid, type PropertyId, type Rank, type Claim, type SnakBase } from 'wikibase-sdk'
import { newError } from '../error.js'
import { getEntityClaims } from '../get_entity.js'
import { findSnak } from './find_snak.js'
import { findClaimByGuid, isGuidClaim, simplifyClaimForEdit } from './helpers.js'
import { hasSpecialSnaktype } from './special_snaktype.js'
import type { EditEntitySimplifiedModeParams } from '../entity/edit.js'
import type { WikibaseEditAPI } from '../index.js'
import type { BaseRevId } from '../types/common.js'
import type { SerializedConfig } from '../types/config.js'
import type { RawEditableEntity } from '../types/edit_entity.js'
import type { EditableMonolingualTextSnakValue, EditableSnakValue } from '../types/snaks.js'
export interface UpdateClaimParams {
id?: RawEditableEntity['id']
guid?: Guid<RawEditableEntity['id']>
property?: PropertyId
oldValue?: EditableSnakValue
newValue?: EditableSnakValue
rank?: Rank
summary?: string
baserevid?: BaseRevId
}
export async function updateClaim (params: UpdateClaimParams, config: SerializedConfig, API: WikibaseEditAPI) {
let { id, guid, property } = params
const { oldValue, newValue, rank } = params
const { statementsKey } = config
if (!(rank != null || newValue != null)) {
throw newError('expected a rank or a newValue', 400, params)
}
if (isGuid(guid)) {
id = getEntityIdFromGuid(guid) as RawEditableEntity['id']
} else {
const values = { oldValue, newValue }
if (oldValue === newValue) {
throw newError("old and new claim values can't be the same", 400, values)
}
if (typeof oldValue !== typeof newValue) {
throw newError('old and new claim should have the same type', 400, values)
}
}
const claims = await getEntityClaims(id, config)
let claim
if (guid) {
claim = findClaimByGuid(claims, guid)
property = claim?.mainsnak.property
} else {
claim = findSnak(property, claims[property] as Claim[], oldValue)
}
if (!claim) {
throw newError('claim not found', 400, params)
}
const simplifiedClaim = simplifyClaimForEdit(claim)
guid = claim.id
if (rank) simplifiedClaim.rank = rank
if (newValue != null) {
if (hasSpecialSnaktype(newValue)) {
simplifiedClaim.snaktype = newValue.snaktype
delete simplifiedClaim.value
} else {
simplifiedClaim.value = formatUpdatedSnakValue(newValue, claim.mainsnak)
}
}
const data: EditEntitySimplifiedModeParams = {
id,
[statementsKey]: {
[property]: simplifiedClaim,
},
// Using wbeditentity, as the endpoint is more complete, so we need to recover the summary
summary: params.summary || config.summary || `update ${property} claim`,
baserevid: params.baserevid || config.baserevid,
}
const { entity, success } = await API.entity.edit(data, config)
const updatedClaim = entity[statementsKey][property].find(isGuidClaim(guid))
// Mimick claim actions responses
return { claim: updatedClaim, success }
}
export function formatUpdatedSnakValue (newValue: EditableSnakValue, updatedSnak: SnakBase) {
if (updatedSnak.snaktype !== 'value') return newValue
const { type } = updatedSnak.datavalue
if (type === 'monolingualtext' && typeof newValue === 'string') {
const { language } = updatedSnak.datavalue.value
return { text: newValue, language } as EditableMonolingualTextSnakValue
} else {
return newValue
}
}
export interface UpdateClaimResponse {
claim: Claim
success: 1
}