11import { uniq } from '../utils/utils.js'
22import { parseClaim } from './parse_claim.js'
33import { truthyPropertyClaims , nonDeprecatedPropertyClaims } from './rank.js'
4- import type { Claim , Claims , PropertyClaims , PropertyQualifiers , Qualifier , Qualifiers , Reference } from '../types/claim.js'
4+ import type { Claim , Claims , DataType , PropertyClaims , PropertyQualifiers , QualifierSnak , Qualifiers , Reference , ReferenceSnak , SnakType } from '../types/claim.js'
5+ import type { PropertyId } from '../types/entity.js'
56import type { SimplifiedClaim , SimplifiedClaims , SimplifiedPropertyClaims , SimplifySnakOptions , SimplifySnaksOptions } from '../types/simplify_claims.js'
7+ import type { SnakValue } from '../types/snakvalue.js'
68
7- function simplifySnaks ( snaks , options ) {
9+ function simplifySnaks ( snaks : Record < PropertyId , any [ ] > , options : SimplifySnaksOptions ) {
810 const { propertyPrefix } = options
911 const simplifiedSnaks : any = { }
10- for ( let id in snaks ) {
11- const propertySnaks = snaks [ id ]
12+ for ( let [ id , propertySnaks ] of Object . entries ( snaks ) ) {
1213 if ( propertyPrefix ) {
1314 id = propertyPrefix + ':' + id
1415 }
@@ -17,7 +18,7 @@ function simplifySnaks (snaks, options) {
1718 return simplifiedSnaks
1819}
1920
20- function simplifyPropertySnaks ( propertySnaks , options ) {
21+ function simplifyPropertySnaks ( propertySnaks : any [ ] , options : SimplifySnaksOptions ) {
2122 // Avoid to throw on empty inputs to allow to simplify claims array
2223 // without having to know if the entity as claims for this property
2324 // Ex: simplifyPropertyClaims(entity.claims.P124211616)
@@ -31,35 +32,40 @@ function simplifyPropertySnaks (propertySnaks, options) {
3132 propertySnaks = truthyPropertyClaims ( propertySnaks )
3233 }
3334
34- propertySnaks = propertySnaks
35+ const simplified = propertySnaks
3536 . map ( claim => simplifyClaim ( claim , options ) )
3637 // Filter-out novalue and somevalue claims,
3738 // unless a novalueValue or a somevalueValue is passed in options
3839 // Considers null as defined
3940 . filter ( obj => obj !== undefined )
4041
4142 // Deduplicate values unless we return a rich value object
42- if ( propertySnaks [ 0 ] && typeof propertySnaks [ 0 ] !== 'object' ) {
43- return uniq ( propertySnaks )
43+ if ( simplified [ 0 ] && typeof simplified [ 0 ] !== 'object' ) {
44+ return uniq ( simplified )
4445 } else {
45- return propertySnaks
46+ return simplified
4647 }
4748}
4849
49- // Expects a single snak object
50- // Ex: entity.claims.P369[0]
51- function simplifySnak ( claim , options ) {
50+ /**
51+ * tries to replace wikidata deep claim object by a simple value
52+ * e.g. a string, an entity Qid or an epoch time number
53+ *
54+ * Expects a single snak object
55+ * Ex: entity.claims.P369[0]
56+ */
57+ function simplifySnak ( claim : Claim | QualifierSnak | ReferenceSnak , options : SimplifySnakOptions ) {
5258 const { keepQualifiers, keepReferences, keepIds, keepHashes, keepTypes, keepSnaktypes, keepRanks } = parseKeepOptions ( options )
5359
54- // tries to replace wikidata deep claim object by a simple value
55- // e.g. a string, an entity Qid or an epoch time number
56- const { mainsnak , rank } = claim
57-
58- let value , datatype , datavalue , snaktype , isQualifierSnak , isReferenceSnak
59- if ( mainsnak ) {
60- datatype = mainsnak . datatype
61- datavalue = mainsnak . datavalue
62- snaktype = mainsnak . snaktype
60+ let datatype : DataType | undefined
61+ let datavalue : SnakValue
62+ let snaktype : SnakType
63+ let isQualifierSnak : boolean
64+ let isReferenceSnak : boolean
65+ if ( ' mainsnak' in claim ) {
66+ datatype = claim . mainsnak . datatype
67+ datavalue = claim . mainsnak . datavalue
68+ snaktype = claim . mainsnak . snaktype
6369 } else {
6470 // Qualifiers have no mainsnak, and define datatype, datavalue on claim
6571 datavalue = claim . datavalue
@@ -70,6 +76,7 @@ function simplifySnak (claim, options) {
7076 else isReferenceSnak = true
7177 }
7278
79+ let value : any
7380 if ( datavalue ) {
7481 value = parseClaim ( datatype , datavalue , options , claim . id )
7582 } else {
@@ -84,7 +91,7 @@ function simplifySnak (claim, options) {
8491
8592 const valueObj : any = { value }
8693
87- if ( keepHashes ) valueObj . hash = claim . hash
94+ if ( keepHashes && 'hash' in claim ) valueObj . hash = claim . hash
8895 if ( keepTypes ) valueObj . type = datatype
8996 if ( keepSnaktypes ) valueObj . snaktype = snaktype
9097
@@ -109,18 +116,16 @@ function simplifySnak (claim, options) {
109116
110117 if ( keepSnaktypes ) valueObj . snaktype = snaktype
111118
112- if ( keepRanks ) valueObj . rank = rank
119+ if ( keepRanks && 'rank' in claim ) valueObj . rank = claim . rank
113120
114- const subSnaksOptions = getSubSnakOptions ( options )
115- subSnaksOptions . keepHashes = keepHashes
121+ const subSnaksOptions = { ...options , areSubSnaks : true }
116122
117123 if ( keepQualifiers ) {
118- valueObj . qualifiers = simplifyQualifiers ( claim . qualifiers , subSnaksOptions )
124+ valueObj . qualifiers = 'qualifiers' in claim ? simplifyQualifiers ( claim . qualifiers , subSnaksOptions ) : { }
119125 }
120126
121127 if ( keepReferences ) {
122- claim . references = claim . references || [ ]
123- valueObj . references = simplifyReferences ( claim . references , subSnaksOptions )
128+ valueObj . references = 'references' in claim ? simplifyReferences ( claim . references , subSnaksOptions ) : [ ]
124129 }
125130
126131 if ( keepIds ) valueObj . id = claim . id
@@ -139,38 +144,42 @@ export function simplifyClaim (claim: Claim, options: SimplifySnakOptions = {}):
139144}
140145
141146export function simplifyQualifiers ( qualifiers : Qualifiers , options : SimplifySnaksOptions = { } ) {
142- return simplifySnaks ( qualifiers , getSubSnakOptions ( options ) )
147+ return simplifySnaks ( qualifiers , { ... options , areSubSnaks : true } )
143148}
144149export function simplifyPropertyQualifiers ( propertyQualifiers : PropertyQualifiers , options : SimplifySnaksOptions = { } ) {
145- return simplifyPropertySnaks ( propertyQualifiers , getSubSnakOptions ( options ) )
150+ return simplifyPropertySnaks ( propertyQualifiers , { ... options , areSubSnaks : true } )
146151}
147- export function simplifyQualifier ( qualifier : Qualifier , options : SimplifySnakOptions = { } ) {
152+ export function simplifyQualifier ( qualifier : QualifierSnak , options : SimplifySnakOptions = { } ) {
148153 return simplifySnak ( qualifier , options )
149154}
150155
151- export function simplifyReferences ( references : Reference [ ] , options ) {
156+ export function simplifyReferences ( references : Reference [ ] , options : SimplifySnaksOptions ) {
152157 return references . map ( refRecord => simplifyReferenceRecord ( refRecord , options ) )
153158}
154- export function simplifyReferenceRecord ( refRecord , options ) {
155- const subSnaksOptions = getSubSnakOptions ( options )
159+ export function simplifyReferenceRecord ( refRecord : Reference , options : SimplifySnaksOptions ) {
160+ const subSnaksOptions = { ... options , areSubSnaks : true }
156161 const snaks = simplifySnaks ( refRecord . snaks , subSnaksOptions )
157162 if ( subSnaksOptions . keepHashes ) return { snaks, hash : refRecord . hash }
158163 else return snaks
159164}
160165
161- const getSubSnakOptions = ( options : any = { } ) => {
162- if ( options . areSubSnaks ) return options
163- // Using a new object so that the original options object isn't modified
164- else return Object . assign ( { } , options , { areSubSnaks : true } )
165- }
166-
167- const keepOptions = [ 'keepQualifiers' , 'keepReferences' , 'keepIds' , 'keepHashes' , 'keepTypes' , 'keepSnaktypes' , 'keepRanks' , 'keepRichValues' ]
168-
169- const parseKeepOptions = options => {
166+ const keepOptions = [
167+ 'keepHashes' ,
168+ 'keepIds' ,
169+ 'keepQualifiers' ,
170+ 'keepRanks' ,
171+ 'keepReferences' ,
172+ 'keepRichValues' ,
173+ 'keepSnaktypes' ,
174+ 'keepTypes' ,
175+ ] as const
176+ type KeepOption = typeof keepOptions [ number ]
177+
178+ const parseKeepOptions = ( options : SimplifySnakOptions ) : Record < KeepOption , boolean > => {
170179 if ( options . keepAll ) {
171180 keepOptions . forEach ( optionName => {
172- if ( options [ optionName ] == null ) options [ optionName ] = true
181+ options [ optionName ] = options [ optionName ] ?? true
173182 } )
174183 }
175- return options
184+ return options as Record < KeepOption , boolean >
176185}
0 commit comments