cocoda-sdk 1.0.13 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +74 -28
- package/dist/cjs/index.cjs +2673 -0
- package/dist/cocoda-sdk.js +33 -17423
- package/dist/cocoda-sdk.js.LICENSES.txt +105 -86
- package/dist/cocoda-sdk.js.map +7 -0
- package/dist/esm/errors/index.js +46 -0
- package/dist/esm/index.js +9 -0
- package/dist/esm/lib/CocodaSDK.js +269 -0
- package/dist/esm/providers/base-provider.js +368 -0
- package/dist/esm/providers/concept-api-provider.js +278 -0
- package/dist/esm/providers/index.js +20 -0
- package/dist/esm/providers/label-search-suggestion-provider.js +101 -0
- package/dist/esm/providers/loc-api-provider.js +185 -0
- package/dist/esm/providers/local-mappings-provider.js +337 -0
- package/dist/esm/providers/mappings-api-provider.js +264 -0
- package/dist/esm/providers/occurrences-api-provider.js +163 -0
- package/dist/esm/providers/reconciliation-api-provider.js +140 -0
- package/dist/esm/providers/skosmos-api-provider.js +345 -0
- package/{utils → dist/esm/utils}/index.js +40 -53
- package/dist/esm/utils/lodash.js +34 -0
- package/package.json +16 -17
- package/errors/index.js +0 -119
- package/index.js +0 -5
- package/lib/CocodaSDK.js +0 -360
- package/providers/base-provider.js +0 -581
- package/providers/concept-api-provider.js +0 -377
- package/providers/index.js +0 -34
- package/providers/label-search-suggestion-provider.js +0 -219
- package/providers/loc-api-provider.js +0 -275
- package/providers/local-mappings-provider.js +0 -459
- package/providers/mappings-api-provider.js +0 -396
- package/providers/occurrences-api-provider.js +0 -234
- package/providers/reconciliation-api-provider.js +0 -211
- package/providers/skosmos-api-provider.js +0 -441
- package/utils/lodash.js +0 -21
|
@@ -1,396 +0,0 @@
|
|
|
1
|
-
const BaseProvider = require("./base-provider")
|
|
2
|
-
const jskos = require("jskos-tools")
|
|
3
|
-
const _ = require("../utils/lodash")
|
|
4
|
-
const errors = require("../errors")
|
|
5
|
-
const utils = require("../utils")
|
|
6
|
-
|
|
7
|
-
// TODO: Check capabilities (`this.has`) and authorization (`this.isAuthorizedFor`) before actions.
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* JSKOS Mappings API.
|
|
11
|
-
*
|
|
12
|
-
* This class provides access to concept mappings via JSKOS API in [JSKOS format](https://gbv.github.io/jskos/).
|
|
13
|
-
* See [jskos-server](https://github.com/gbv/jskos-server) for a JSKOS API reference implementation
|
|
14
|
-
*
|
|
15
|
-
* To use it in a registry, specify `provider` as "MappingsApi" and provide the API base URL as `api`:
|
|
16
|
-
* ```json
|
|
17
|
-
* {
|
|
18
|
-
* "uri": "http://coli-conc.gbv.de/registry/coli-conc-mappings",
|
|
19
|
-
* "provider": "MappingsApi",
|
|
20
|
-
* "api": "https://coli-conc.gbv.de/api/"
|
|
21
|
-
* }
|
|
22
|
-
* ```
|
|
23
|
-
*
|
|
24
|
-
* If the `/status` endpoint can be queried, the remaining API methods will be taken from that. As a fallback, the default endpoints will be appended to `api`.
|
|
25
|
-
*
|
|
26
|
-
* Alternatively, you can provide the endpoints separately: `status`, `mappings`, `concordances`, `annotations`
|
|
27
|
-
*
|
|
28
|
-
* Additionally, the following JSKOS properties can be provided: `prefLabel`, `notation`, `definition`
|
|
29
|
-
*
|
|
30
|
-
* @extends BaseProvider
|
|
31
|
-
* @category Providers
|
|
32
|
-
*/
|
|
33
|
-
class MappingsApiProvider extends BaseProvider {
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* @private
|
|
37
|
-
*/
|
|
38
|
-
_prepare() {
|
|
39
|
-
// Set status endpoint only
|
|
40
|
-
if (this._api.api && this._api.status === undefined) {
|
|
41
|
-
this._api.status = utils.concatUrl(this._api.api, "/status")
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* @private
|
|
47
|
-
*/
|
|
48
|
-
_setup() {
|
|
49
|
-
// Fill `this._api` if necessary
|
|
50
|
-
if (this._api.api) {
|
|
51
|
-
const endpoints = {
|
|
52
|
-
mappings: "/mappings",
|
|
53
|
-
concordances: "/concordances",
|
|
54
|
-
annotations: "/annotations",
|
|
55
|
-
}
|
|
56
|
-
for (let key of Object.keys(endpoints)) {
|
|
57
|
-
if (this._api[key] === undefined) {
|
|
58
|
-
this._api[key] = utils.concatUrl(this._api.api, endpoints[key])
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
this.has.mappings = this._api.mappings ? {} : false
|
|
63
|
-
if (this.has.mappings) {
|
|
64
|
-
this.has.mappings.read = !!_.get(this._config, "mappings.read", true)
|
|
65
|
-
this.has.mappings.create = !!_.get(this._config, "mappings.create")
|
|
66
|
-
this.has.mappings.update = !!_.get(this._config, "mappings.update")
|
|
67
|
-
this.has.mappings.delete = !!_.get(this._config, "mappings.delete")
|
|
68
|
-
this.has.mappings.anonymous = !!_.get(this._config, "mappings.anonymous")
|
|
69
|
-
}
|
|
70
|
-
this.has.concordances = !!this._api.concordances
|
|
71
|
-
this.has.annotations = this._api.annotations ? {} : false
|
|
72
|
-
if (this.has.annotations) {
|
|
73
|
-
this.has.annotations.read = !!_.get(this._config, "annotations.read")
|
|
74
|
-
this.has.annotations.create = !!_.get(this._config, "annotations.create")
|
|
75
|
-
this.has.annotations.update = !!_.get(this._config, "annotations.update")
|
|
76
|
-
this.has.annotations.delete = !!_.get(this._config, "annotations.delete")
|
|
77
|
-
}
|
|
78
|
-
this.has.auth = _.get(this._config, "auth.key") != null
|
|
79
|
-
this._defaultParams = {
|
|
80
|
-
properties: "annotations",
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Returns a single mapping.
|
|
86
|
-
*
|
|
87
|
-
* @param {Object} config
|
|
88
|
-
* @param {Object} config.mapping JSKOS mapping
|
|
89
|
-
* @returns {Object} JSKOS mapping object
|
|
90
|
-
*/
|
|
91
|
-
async getMapping({ mapping, ...config }) {
|
|
92
|
-
if (!mapping) {
|
|
93
|
-
throw new errors.InvalidOrMissingParameterError({ parameter: "mapping" })
|
|
94
|
-
}
|
|
95
|
-
if (!mapping.uri || !mapping.uri.startsWith(this._api.mappings)) {
|
|
96
|
-
throw new errors.InvalidOrMissingParameterError({ parameter: "mapping", message: "URI doesn't seem to be part of this registry." })
|
|
97
|
-
}
|
|
98
|
-
try {
|
|
99
|
-
return await this.axios({
|
|
100
|
-
...config,
|
|
101
|
-
url: mapping.uri,
|
|
102
|
-
params: {
|
|
103
|
-
...this._defaultParams,
|
|
104
|
-
...(config.params || {}),
|
|
105
|
-
},
|
|
106
|
-
})
|
|
107
|
-
} catch (error) {
|
|
108
|
-
if (_.get(error, "response.status") == 404) {
|
|
109
|
-
return null
|
|
110
|
-
}
|
|
111
|
-
throw error
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* Returns a list of mappings.
|
|
117
|
-
*
|
|
118
|
-
* @param {Object} config request config with parameters
|
|
119
|
-
* @returns {Object[]} array of JSKOS mapping objects
|
|
120
|
-
*/
|
|
121
|
-
async getMappings({ from, fromScheme, to, toScheme, creator, type, partOf, offset, limit, direction, mode, identifier, sort, order, ...config }) {
|
|
122
|
-
let params = {}, url = this._api.mappings
|
|
123
|
-
if (from) {
|
|
124
|
-
params.from = _.isString(from) ? from : from.uri
|
|
125
|
-
}
|
|
126
|
-
if (fromScheme) {
|
|
127
|
-
params.fromScheme = _.isString(fromScheme) ? fromScheme : fromScheme.uri
|
|
128
|
-
}
|
|
129
|
-
if (to) {
|
|
130
|
-
params.to = _.isString(to) ? to : to.uri
|
|
131
|
-
}
|
|
132
|
-
if (toScheme) {
|
|
133
|
-
params.toScheme = _.isString(toScheme) ? toScheme : toScheme.uri
|
|
134
|
-
}
|
|
135
|
-
if (creator) {
|
|
136
|
-
params.creator = _.isString(creator) ? creator : jskos.prefLabel(creator)
|
|
137
|
-
}
|
|
138
|
-
if (type) {
|
|
139
|
-
params.type = _.isString(type) ? type : type.uri
|
|
140
|
-
}
|
|
141
|
-
if (partOf) {
|
|
142
|
-
params.partOf = _.isString(partOf) ? partOf : partOf.uri
|
|
143
|
-
}
|
|
144
|
-
if (offset) {
|
|
145
|
-
params.offset = offset
|
|
146
|
-
}
|
|
147
|
-
if (limit) {
|
|
148
|
-
params.limit = limit
|
|
149
|
-
}
|
|
150
|
-
if (direction) {
|
|
151
|
-
params.direction = direction
|
|
152
|
-
}
|
|
153
|
-
if (mode) {
|
|
154
|
-
params.mode = mode
|
|
155
|
-
}
|
|
156
|
-
if (identifier) {
|
|
157
|
-
params.identifier = identifier
|
|
158
|
-
}
|
|
159
|
-
if (sort) {
|
|
160
|
-
params.sort = sort
|
|
161
|
-
}
|
|
162
|
-
if (order) {
|
|
163
|
-
params.order = order
|
|
164
|
-
}
|
|
165
|
-
return this.axios({
|
|
166
|
-
...config,
|
|
167
|
-
method: "get",
|
|
168
|
-
url,
|
|
169
|
-
params: {
|
|
170
|
-
...this._defaultParams,
|
|
171
|
-
...(config.params || {}),
|
|
172
|
-
...params,
|
|
173
|
-
},
|
|
174
|
-
})
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* Creates a mapping.
|
|
179
|
-
*
|
|
180
|
-
* @param {Object} config
|
|
181
|
-
* @param {Object} config.mapping JSKOS mapping
|
|
182
|
-
* @returns {Object} JSKOS mapping object
|
|
183
|
-
*/
|
|
184
|
-
async postMapping({ mapping, ...config }) {
|
|
185
|
-
if (!mapping) {
|
|
186
|
-
throw new errors.InvalidOrMissingParameterError({ parameter: "mapping" })
|
|
187
|
-
}
|
|
188
|
-
mapping = jskos.minifyMapping(mapping)
|
|
189
|
-
mapping = jskos.addMappingIdentifiers(mapping)
|
|
190
|
-
return this.axios({
|
|
191
|
-
...config,
|
|
192
|
-
method: "post",
|
|
193
|
-
url: this._api.mappings,
|
|
194
|
-
data: mapping,
|
|
195
|
-
params: {
|
|
196
|
-
...this._defaultParams,
|
|
197
|
-
...(config.params || {}),
|
|
198
|
-
},
|
|
199
|
-
})
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
/**
|
|
203
|
-
* Overwrites a mapping.
|
|
204
|
-
*
|
|
205
|
-
* @param {Object} config
|
|
206
|
-
* @param {Object} config.mapping JSKOS mapping
|
|
207
|
-
* @returns {Object} JSKOS mapping object
|
|
208
|
-
*/
|
|
209
|
-
async putMapping({ mapping, ...config }) {
|
|
210
|
-
if (!mapping) {
|
|
211
|
-
throw new errors.InvalidOrMissingParameterError({ parameter: "mapping" })
|
|
212
|
-
}
|
|
213
|
-
mapping = jskos.minifyMapping(mapping)
|
|
214
|
-
mapping = jskos.addMappingIdentifiers(mapping)
|
|
215
|
-
const uri = mapping.uri
|
|
216
|
-
if (!uri || !uri.startsWith(this._api.mappings)) {
|
|
217
|
-
throw new errors.InvalidOrMissingParameterError({ parameter: "mapping", message: "URI doesn't seem to be part of this registry." })
|
|
218
|
-
}
|
|
219
|
-
return this.axios({
|
|
220
|
-
...config,
|
|
221
|
-
method: "put",
|
|
222
|
-
url: uri,
|
|
223
|
-
data: mapping,
|
|
224
|
-
params: {
|
|
225
|
-
...this._defaultParams,
|
|
226
|
-
...(config.params || {}),
|
|
227
|
-
},
|
|
228
|
-
})
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
/**
|
|
232
|
-
* Patches a mapping.
|
|
233
|
-
*
|
|
234
|
-
* @param {Object} config
|
|
235
|
-
* @param {Object} config.mapping JSKOS mapping (or part of mapping)
|
|
236
|
-
* @returns {Object} JSKOS mapping object
|
|
237
|
-
*/
|
|
238
|
-
async patchMapping({ mapping, ...config }) {
|
|
239
|
-
if (!mapping) {
|
|
240
|
-
throw new errors.InvalidOrMissingParameterError({ parameter: "mapping" })
|
|
241
|
-
}
|
|
242
|
-
mapping = jskos.minifyMapping(mapping)
|
|
243
|
-
mapping = jskos.addMappingIdentifiers(mapping)
|
|
244
|
-
const uri = mapping.uri
|
|
245
|
-
if (!uri || !uri.startsWith(this._api.mappings)) {
|
|
246
|
-
throw new errors.InvalidOrMissingParameterError({ parameter: "mapping", message: "URI doesn't seem to be part of this registry." })
|
|
247
|
-
}
|
|
248
|
-
return this.axios({
|
|
249
|
-
...config,
|
|
250
|
-
method: "patch",
|
|
251
|
-
url: uri,
|
|
252
|
-
data: mapping,
|
|
253
|
-
params: {
|
|
254
|
-
...this._defaultParams,
|
|
255
|
-
...(config.params || {}),
|
|
256
|
-
},
|
|
257
|
-
})
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
/**
|
|
261
|
-
* Deletes a mapping.
|
|
262
|
-
*
|
|
263
|
-
* @param {Object} config
|
|
264
|
-
* @param {Object} config.mapping JSKOS mapping
|
|
265
|
-
* @returns {boolean} `true` if deletion was successful
|
|
266
|
-
*/
|
|
267
|
-
async deleteMapping({ mapping, ...config }) {
|
|
268
|
-
if (!mapping) {
|
|
269
|
-
throw new errors.InvalidOrMissingParameterError({ parameter: "mapping" })
|
|
270
|
-
}
|
|
271
|
-
const uri = mapping.uri
|
|
272
|
-
if (!uri || !uri.startsWith(this._api.mappings)) {
|
|
273
|
-
throw new errors.InvalidOrMissingParameterError({ parameter: "mapping", message: "URI doesn't seem to be part of this registry." })
|
|
274
|
-
}
|
|
275
|
-
await this.axios({
|
|
276
|
-
...config,
|
|
277
|
-
method: "delete",
|
|
278
|
-
url: uri,
|
|
279
|
-
})
|
|
280
|
-
return true
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
/**
|
|
284
|
-
* Returns a list of annotations.
|
|
285
|
-
*
|
|
286
|
-
* @param {Object} config
|
|
287
|
-
* @param {string} [config.target] target URI
|
|
288
|
-
* @returns {Object[]} array of JSKOS annotation objects
|
|
289
|
-
*/
|
|
290
|
-
async getAnnotations({ target, ...config }) {
|
|
291
|
-
if (target) {
|
|
292
|
-
_.set(config, "params.target", target)
|
|
293
|
-
}
|
|
294
|
-
return this.axios({
|
|
295
|
-
...config,
|
|
296
|
-
method: "get",
|
|
297
|
-
url: this._api.annotations,
|
|
298
|
-
})
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
/**
|
|
302
|
-
* Creates an annotation.
|
|
303
|
-
*
|
|
304
|
-
* @param {Object} config
|
|
305
|
-
* @param {Object} config.annotation JSKOS annotation
|
|
306
|
-
* @returns {Object} JSKOS annotation object
|
|
307
|
-
*/
|
|
308
|
-
async postAnnotation({ annotation, ...config }) {
|
|
309
|
-
return this.axios({
|
|
310
|
-
...config,
|
|
311
|
-
method: "post",
|
|
312
|
-
url: this._api.annotations,
|
|
313
|
-
data: annotation,
|
|
314
|
-
})
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
/**
|
|
318
|
-
* Overwrites an annotation.
|
|
319
|
-
*
|
|
320
|
-
* @param {Object} config
|
|
321
|
-
* @param {Object} config.annotation JSKOS annotation
|
|
322
|
-
* @returns {Object} JSKOS annotation object
|
|
323
|
-
*/
|
|
324
|
-
async putAnnotation({ annotation, ...config }) {
|
|
325
|
-
const uri = annotation.id
|
|
326
|
-
if (!uri || !uri.startsWith(this._api.annotations)) {
|
|
327
|
-
throw new errors.InvalidOrMissingParameterError({ parameter: "annotation", message: "URI doesn't seem to be part of this registry." })
|
|
328
|
-
}
|
|
329
|
-
return this.axios({
|
|
330
|
-
...config,
|
|
331
|
-
method: "put",
|
|
332
|
-
url: uri,
|
|
333
|
-
data: annotation,
|
|
334
|
-
})
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
/**
|
|
338
|
-
* Patches an annotation.
|
|
339
|
-
*
|
|
340
|
-
* @param {Object} config
|
|
341
|
-
* @param {Object} config.annotation JSKOS annotation
|
|
342
|
-
* @returns {Object} JSKOS annotation object
|
|
343
|
-
*/
|
|
344
|
-
async patchAnnotation({ annotation, ...config }) {
|
|
345
|
-
const uri = annotation.id
|
|
346
|
-
if (!uri || !uri.startsWith(this._api.annotations)) {
|
|
347
|
-
throw new errors.InvalidOrMissingParameterError({ parameter: "annotation", message: "URI doesn't seem to be part of this registry." })
|
|
348
|
-
}
|
|
349
|
-
return this.axios({
|
|
350
|
-
...config,
|
|
351
|
-
method: "patch",
|
|
352
|
-
url: uri,
|
|
353
|
-
data: annotation,
|
|
354
|
-
})
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
/**
|
|
358
|
-
* Deletes an annotation.
|
|
359
|
-
*
|
|
360
|
-
* @param {Object} config
|
|
361
|
-
* @param {Object} config.annotation JSKOS annotation
|
|
362
|
-
* @returns {boolean} `true` if deletion was successful
|
|
363
|
-
*/
|
|
364
|
-
async deleteAnnotation({ annotation, ...config }) {
|
|
365
|
-
const uri = annotation.id
|
|
366
|
-
if (!uri || !uri.startsWith(this._api.annotations)) {
|
|
367
|
-
throw new errors.InvalidOrMissingParameterError({ parameter: "annotation", message: "URI doesn't seem to be part of this registry." })
|
|
368
|
-
}
|
|
369
|
-
await this.axios({
|
|
370
|
-
...config,
|
|
371
|
-
method: "delete",
|
|
372
|
-
url: uri,
|
|
373
|
-
})
|
|
374
|
-
return true
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
/**
|
|
378
|
-
* Returns a list of concordances.
|
|
379
|
-
*
|
|
380
|
-
* @param {Object} config
|
|
381
|
-
* @returns {Object[]} array of JSKOS concordance objects
|
|
382
|
-
*/
|
|
383
|
-
async getConcordances(config) {
|
|
384
|
-
return this.axios({
|
|
385
|
-
...config,
|
|
386
|
-
method: "get",
|
|
387
|
-
url: this._api.concordances,
|
|
388
|
-
})
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
MappingsApiProvider.providerName = "MappingsApi"
|
|
394
|
-
MappingsApiProvider.stored = true
|
|
395
|
-
|
|
396
|
-
module.exports = MappingsApiProvider
|
|
@@ -1,234 +0,0 @@
|
|
|
1
|
-
const BaseProvider = require("./base-provider")
|
|
2
|
-
const jskos = require("jskos-tools")
|
|
3
|
-
const _ = require("../utils/lodash")
|
|
4
|
-
const errors = require("../errors")
|
|
5
|
-
const utils = require("../utils")
|
|
6
|
-
|
|
7
|
-
// TODO: Modernize.
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* JSKOS Occurrences API.
|
|
11
|
-
*
|
|
12
|
-
* This class provides access to concept occurrences via JSKOS API in [JSKOS format](https://gbv.github.io/jskos/).
|
|
13
|
-
*
|
|
14
|
-
* To use it in a registry, specify `provider` as "OccurrencesApi" and provide the API base URL as `api`:
|
|
15
|
-
* ```json
|
|
16
|
-
* {
|
|
17
|
-
* "uri": "http://coli-conc.gbv.de/registry/occurrences",
|
|
18
|
-
* "provider": "OccurrencesApi",
|
|
19
|
-
* "api": "https://coli-conc.gbv.de/occurrences/api/"
|
|
20
|
-
* }
|
|
21
|
-
* ```
|
|
22
|
-
*
|
|
23
|
-
* Additionally, the following JSKOS properties can be provided: `prefLabel`, `notation`, `definition`
|
|
24
|
-
*
|
|
25
|
-
* @extends BaseProvider
|
|
26
|
-
* @category Providers
|
|
27
|
-
*/
|
|
28
|
-
class OccurrencesApiProvider extends BaseProvider {
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* @private
|
|
32
|
-
*/
|
|
33
|
-
_setup() {
|
|
34
|
-
this._cache = []
|
|
35
|
-
this._occurrencesSupportedSchemes = []
|
|
36
|
-
this.has.occurrences = true
|
|
37
|
-
this.has.mappings = true
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Returns whether a concept scheme is supported for occurrences.
|
|
42
|
-
*
|
|
43
|
-
* @private
|
|
44
|
-
*
|
|
45
|
-
* @param {Object} scheme JSKOS scheme to query
|
|
46
|
-
*/
|
|
47
|
-
async _occurrencesIsSupported(scheme) {
|
|
48
|
-
if (this._occurrencesSupportedSchemes && this._occurrencesSupportedSchemes.length) {
|
|
49
|
-
// No action needed
|
|
50
|
-
} else {
|
|
51
|
-
// Load supported schemes from API
|
|
52
|
-
try {
|
|
53
|
-
const url = utils.concatUrl(this._api.api, "voc")
|
|
54
|
-
const data = await this.axios({
|
|
55
|
-
method: "get",
|
|
56
|
-
url,
|
|
57
|
-
})
|
|
58
|
-
this._occurrencesSupportedSchemes = data || []
|
|
59
|
-
} catch(error) {
|
|
60
|
-
// Do nothing so that it is tried again next time
|
|
61
|
-
// TODO: Save number of failures?
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
let supported = false
|
|
65
|
-
for (let supportedScheme of this._occurrencesSupportedSchemes) {
|
|
66
|
-
if (jskos.compare(scheme, supportedScheme)) {
|
|
67
|
-
supported = true
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
return supported
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Wrapper around getOccurrences that converts occurrences into mappings.
|
|
75
|
-
*
|
|
76
|
-
* @param {Object} config config object for getOccurrences request
|
|
77
|
-
* @returns {Object[]} array of JSKOS mapping objects
|
|
78
|
-
*/
|
|
79
|
-
async getMappings(config) {
|
|
80
|
-
const occurrences = await this.getOccurrences(config)
|
|
81
|
-
const fromScheme = _.get(config, "from.inScheme[0]") || config.fromScheme
|
|
82
|
-
const toScheme = _.get(config, "to.inScheme[0]") || config.toScheme
|
|
83
|
-
const mappings = []
|
|
84
|
-
// Convert occurrences to mappings
|
|
85
|
-
for (let occurrence of occurrences) {
|
|
86
|
-
if (!occurrence) {
|
|
87
|
-
continue
|
|
88
|
-
}
|
|
89
|
-
let mapping = {}
|
|
90
|
-
mapping.from = _.get(occurrence, "memberSet[0]")
|
|
91
|
-
if (mapping.from) {
|
|
92
|
-
mapping.from = { memberSet: [mapping.from] }
|
|
93
|
-
} else {
|
|
94
|
-
mapping.from = null
|
|
95
|
-
}
|
|
96
|
-
mapping.fromScheme = _.get(occurrence, "memberSet[0].inScheme[0]")
|
|
97
|
-
mapping.to = _.get(occurrence, "memberSet[1]")
|
|
98
|
-
if (mapping.to) {
|
|
99
|
-
mapping.to = { memberSet: [mapping.to] }
|
|
100
|
-
} else {
|
|
101
|
-
mapping.to = { memberSet: [] }
|
|
102
|
-
}
|
|
103
|
-
mapping.toScheme = _.get(occurrence, "memberSet[1].inScheme[0]")
|
|
104
|
-
// Swap sides if necessary
|
|
105
|
-
if ((fromScheme && mapping.fromScheme && !jskos.compare(mapping.fromScheme, fromScheme)) || (toScheme && mapping.toScheme && !jskos.compare(mapping.toScheme, toScheme))) {
|
|
106
|
-
[mapping.from, mapping.fromScheme, mapping.to, mapping.toScheme] = [mapping.to, mapping.toScheme, mapping.from, mapping.fromScheme]
|
|
107
|
-
}
|
|
108
|
-
// Set fromScheme/toScheme if necessary
|
|
109
|
-
if (!mapping.fromScheme && fromScheme) {
|
|
110
|
-
mapping.fromScheme = fromScheme
|
|
111
|
-
}
|
|
112
|
-
if (!mapping.toScheme && toScheme) {
|
|
113
|
-
mapping.toScheme = toScheme
|
|
114
|
-
}
|
|
115
|
-
mapping.type = [jskos.defaultMappingType.uri]
|
|
116
|
-
mapping._occurrence = occurrence
|
|
117
|
-
mapping = jskos.addMappingIdentifiers(mapping)
|
|
118
|
-
if (occurrence.database) {
|
|
119
|
-
mapping.creator = [occurrence.database]
|
|
120
|
-
}
|
|
121
|
-
mappings.push(mapping)
|
|
122
|
-
}
|
|
123
|
-
return mappings
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* Returns a list of occurrences.
|
|
128
|
-
*
|
|
129
|
-
* @param {Object} config
|
|
130
|
-
* @param {Object} [config.from] JSKOS concept to load occurrences for (from side)
|
|
131
|
-
* @param {Object} [config.to] JSKOS concept to load occurrences for (to side)
|
|
132
|
-
* @param {Object[]} [config.concepts] list of JSKOS concepts to load occurrences for
|
|
133
|
-
* @returns {Object[]} array of JSKOS occurrence objects
|
|
134
|
-
*/
|
|
135
|
-
async getOccurrences({ from, to, concepts, ...config }) {
|
|
136
|
-
let promises = []
|
|
137
|
-
concepts = (concepts || []).concat([from, to]).filter(c => !!c)
|
|
138
|
-
for (let concept of concepts) {
|
|
139
|
-
promises.push(this._occurrencesIsSupported(_.get(concept, "inScheme[0]")).then(supported => {
|
|
140
|
-
if (supported && concept.uri) {
|
|
141
|
-
return concept.uri
|
|
142
|
-
} else {
|
|
143
|
-
return null
|
|
144
|
-
}
|
|
145
|
-
}))
|
|
146
|
-
}
|
|
147
|
-
let uris = await Promise.all(promises)
|
|
148
|
-
uris = uris.filter(uri => uri != null)
|
|
149
|
-
if (uris.length == 0) {
|
|
150
|
-
throw new errors.InvalidOrMissingParameterError({ parameter: "concepts" })
|
|
151
|
-
}
|
|
152
|
-
promises = []
|
|
153
|
-
for (let uri of uris) {
|
|
154
|
-
promises.push(this._getOccurrences({
|
|
155
|
-
...config,
|
|
156
|
-
params: {
|
|
157
|
-
member: uri,
|
|
158
|
-
scheme: "*",
|
|
159
|
-
threshold: 5,
|
|
160
|
-
},
|
|
161
|
-
}))
|
|
162
|
-
}
|
|
163
|
-
// Another request for co-occurrences between two specific concepts
|
|
164
|
-
if (uris.length > 1) {
|
|
165
|
-
let urisString = uris.join(" ")
|
|
166
|
-
promises.push(this._getOccurrences({
|
|
167
|
-
...config,
|
|
168
|
-
params: {
|
|
169
|
-
member: urisString,
|
|
170
|
-
threshold: 5,
|
|
171
|
-
},
|
|
172
|
-
}))
|
|
173
|
-
}
|
|
174
|
-
const results = await Promise.all(promises)
|
|
175
|
-
let occurrences = _.concat([], ...results)
|
|
176
|
-
// Filter duplicates
|
|
177
|
-
let existingUris = []
|
|
178
|
-
let indexesToDelete = []
|
|
179
|
-
for (let i = 0; i < occurrences.length; i += 1) {
|
|
180
|
-
let occurrence = occurrences[i]
|
|
181
|
-
if (!occurrence) {
|
|
182
|
-
continue
|
|
183
|
-
}
|
|
184
|
-
let uris = occurrence.memberSet.reduce((total, current) => total.concat(current.uri), []).sort().join(" ")
|
|
185
|
-
if (existingUris.includes(uris)) {
|
|
186
|
-
indexesToDelete.push(i)
|
|
187
|
-
} else {
|
|
188
|
-
existingUris.push(uris)
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
indexesToDelete.forEach(value => {
|
|
192
|
-
delete occurrences[value]
|
|
193
|
-
})
|
|
194
|
-
// Filter null values
|
|
195
|
-
occurrences = occurrences.filter(o => o != null)
|
|
196
|
-
// Sort occurrences
|
|
197
|
-
return occurrences.sort((a, b) => parseInt(b.count || 0) - parseInt(a.count || 0))
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
/**
|
|
201
|
-
* Internal function for getOccurrences that either makes an API request or uses a local cache.
|
|
202
|
-
*
|
|
203
|
-
* @private
|
|
204
|
-
*
|
|
205
|
-
* @param {Object} config passthrough of config parameter for axios request
|
|
206
|
-
*/
|
|
207
|
-
async _getOccurrences(config) {
|
|
208
|
-
// Use local cache.
|
|
209
|
-
let resultsFromCache = this._cache.find(item => {
|
|
210
|
-
return _.isEqual(item.config.params, config.params)
|
|
211
|
-
})
|
|
212
|
-
if (resultsFromCache) {
|
|
213
|
-
return resultsFromCache.data
|
|
214
|
-
}
|
|
215
|
-
const data = await this.axios({
|
|
216
|
-
...config,
|
|
217
|
-
method: "get",
|
|
218
|
-
url: this._api.api,
|
|
219
|
-
})
|
|
220
|
-
this._cache.push({
|
|
221
|
-
config,
|
|
222
|
-
data,
|
|
223
|
-
})
|
|
224
|
-
if (this._cache.length > 20) {
|
|
225
|
-
this._cache = this._cache.slice(this._cache.length - 20)
|
|
226
|
-
}
|
|
227
|
-
return data
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
OccurrencesApiProvider.providerName = "OccurrencesApi"
|
|
232
|
-
OccurrencesApiProvider.stored = false
|
|
233
|
-
|
|
234
|
-
module.exports = OccurrencesApiProvider
|