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.
Files changed (36) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +74 -28
  3. package/dist/cjs/index.cjs +2673 -0
  4. package/dist/cocoda-sdk.js +33 -17423
  5. package/dist/cocoda-sdk.js.LICENSES.txt +105 -86
  6. package/dist/cocoda-sdk.js.map +7 -0
  7. package/dist/esm/errors/index.js +46 -0
  8. package/dist/esm/index.js +9 -0
  9. package/dist/esm/lib/CocodaSDK.js +269 -0
  10. package/dist/esm/providers/base-provider.js +368 -0
  11. package/dist/esm/providers/concept-api-provider.js +278 -0
  12. package/dist/esm/providers/index.js +20 -0
  13. package/dist/esm/providers/label-search-suggestion-provider.js +101 -0
  14. package/dist/esm/providers/loc-api-provider.js +185 -0
  15. package/dist/esm/providers/local-mappings-provider.js +337 -0
  16. package/dist/esm/providers/mappings-api-provider.js +264 -0
  17. package/dist/esm/providers/occurrences-api-provider.js +163 -0
  18. package/dist/esm/providers/reconciliation-api-provider.js +140 -0
  19. package/dist/esm/providers/skosmos-api-provider.js +345 -0
  20. package/{utils → dist/esm/utils}/index.js +40 -53
  21. package/dist/esm/utils/lodash.js +34 -0
  22. package/package.json +16 -17
  23. package/errors/index.js +0 -119
  24. package/index.js +0 -5
  25. package/lib/CocodaSDK.js +0 -360
  26. package/providers/base-provider.js +0 -581
  27. package/providers/concept-api-provider.js +0 -377
  28. package/providers/index.js +0 -34
  29. package/providers/label-search-suggestion-provider.js +0 -219
  30. package/providers/loc-api-provider.js +0 -275
  31. package/providers/local-mappings-provider.js +0 -459
  32. package/providers/mappings-api-provider.js +0 -396
  33. package/providers/occurrences-api-provider.js +0 -234
  34. package/providers/reconciliation-api-provider.js +0 -211
  35. package/providers/skosmos-api-provider.js +0 -441
  36. package/utils/lodash.js +0 -21
@@ -1,459 +0,0 @@
1
- const BaseProvider = require("./base-provider")
2
- const jskos = require("jskos-tools")
3
- const _ = require("../utils/lodash")
4
- const localforage = require("localforage").default || require("localforage")
5
- const { v4: uuid } = require("uuid")
6
- const errors = require("../errors")
7
- const uriPrefix = "urn:uuid:"
8
-
9
- /**
10
- * Local Mappings.
11
- *
12
- * This class provides read-write access to mappings in the browser's local storage.
13
- *
14
- * To use it in a registry, specify `provider` as "LocalMappings":
15
- * ```json
16
- * {
17
- * "uri": "http://coli-conc.gbv.de/registry/local-mappings",
18
- * "provider": "LocalMappings"
19
- * }
20
- * ```
21
- *
22
- * Additionally, the following JSKOS properties can be provided: `prefLabel`, `notation`, `definition`
23
- *
24
- * @extends BaseProvider
25
- * @category Providers
26
- */
27
- class LocalMappingsProvider extends BaseProvider {
28
-
29
- /**
30
- * @private
31
- */
32
- _setup() {
33
- this.has.mappings = {
34
- read: true,
35
- create: true,
36
- update: true,
37
- delete: true,
38
- }
39
- this.queue = []
40
- this.localStorageKey = "cocoda-mappings--" + this._path
41
- let oldLocalStorageKey = "mappings"
42
- // Function that adds URIs to all existing local mappings that don't yet have one
43
- let addUris = () => {
44
- return localforage.getItem(this.localStorageKey).then(mappings => {
45
- mappings = mappings || []
46
- let adjusted = 0
47
- for (let mapping of mappings.filter(m => !m.uri || !m.uri.startsWith(uriPrefix))) {
48
- if (mapping.uri) {
49
- // Keep previous URI in identifier
50
- if (!mapping.identifier) {
51
- mapping.identifier = []
52
- }
53
- mapping.identifier.push(mapping.uri)
54
- }
55
- mapping.uri = `${uriPrefix}${uuid()}`
56
- adjusted += 1
57
- }
58
- if (adjusted) {
59
- console.warn(`URIs added to ${adjusted} local mappings.`)
60
- }
61
- return localforage.setItem(this.localStorageKey, mappings)
62
- })
63
- }
64
- // Show warning if there are mappings in local storage that use the old local storage key.
65
- localforage.getItem(oldLocalStorageKey).then(results => {
66
- if (results) {
67
- console.warn(`Warning: There is old data in local storage (or IndexedDB, depending on the ) with the key "${oldLocalStorageKey}". This data will not be used anymore. A manual export is necessary to get this data back.`)
68
- }
69
- })
70
- // Put promise into queue so that getMappings requests are waiting for adjustments to finish
71
- this.queue.push(
72
- addUris().catch(error => {
73
- console.warn("Error when adding URIs to local mappings:", error)
74
- }),
75
- )
76
- }
77
-
78
- isAuthorizedFor({ type, action }) {
79
- // Allow all for mappings
80
- if (type == "mappings" && action != "anonymous") {
81
- return true
82
- }
83
- return false
84
- }
85
-
86
- /**
87
- * Returns a Promise that returns an object { mappings, done } with the local mappings and a done function that is supposed to be called when the transaction is finished.
88
- * This prevents conflicts when saveMapping is called multiple times simultaneously.
89
- *
90
- * TODO: There might be a better solution for this...
91
- *
92
- * @private
93
- */
94
- _getMappingsQueue() {
95
- let last = _.last(this.queue) || Promise.resolve()
96
- return new Promise((resolve) => {
97
- function defer() {
98
- var res, rej
99
-
100
- var promise = new Promise((resolve, reject) => {
101
- res = resolve
102
- rej = reject
103
- })
104
-
105
- promise.resolve = res
106
- promise.reject = rej
107
-
108
- return promise
109
- }
110
- let promise = defer()
111
- let done = () => {
112
- promise.resolve()
113
- }
114
- this.queue.push(promise)
115
-
116
- last.then(() => {
117
- return localforage.getItem(this.localStorageKey)
118
- }).then(mappings => {
119
- resolve({ mappings, done })
120
- })
121
- })
122
- }
123
-
124
- /**
125
- * Returns a single mapping.
126
- *
127
- * @param {Object} config
128
- * @param {Object} config.mapping JSKOS mapping
129
- * @returns {Object} JSKOS mapping object
130
- */
131
- async getMapping({ mapping, ...config }) {
132
- config._raw = true
133
- if (!mapping || !mapping.uri) {
134
- throw new errors.InvalidOrMissingParameterError({ parameter: "mapping" })
135
- }
136
- return (await this.getMappings({ ...config, uri: mapping.uri }))[0]
137
- }
138
-
139
- /**
140
- * Returns a list of local mappings.
141
- *
142
- * TODO: Add support for sort (`created` or `modified`) and order (`asc` or `desc`).
143
- * TODO: Clean up and use async/await
144
- *
145
- * @returns {Object[]} array of JSKOS mapping objects
146
- */
147
- async getMappings({ from, fromScheme, to, toScheme, creator, type, partOf, offset, limit, direction, mode, identifier, uri } = {}) {
148
- let params = {}
149
- if (from) {
150
- params.from = _.isString(from) ? from : from.uri
151
- }
152
- if (fromScheme) {
153
- params.fromScheme = _.isString(fromScheme) ? { uri: fromScheme } : fromScheme
154
- }
155
- if (to) {
156
- params.to = _.isString(to) ? to : to.uri
157
- }
158
- if (toScheme) {
159
- params.toScheme = _.isString(toScheme) ? { uri: toScheme } : toScheme
160
- }
161
- if (creator) {
162
- params.creator = _.isString(creator) ? creator : jskos.prefLabel(creator)
163
- }
164
- if (type) {
165
- params.type = _.isString(type) ? type : type.uri
166
- }
167
- if (partOf) {
168
- params.partOf = _.isString(partOf) ? partOf : partOf.uri
169
- }
170
- if (offset) {
171
- params.offset = offset
172
- }
173
- if (limit) {
174
- params.limit = limit
175
- }
176
- if (direction) {
177
- params.direction = direction
178
- }
179
- if (mode) {
180
- params.mode = mode
181
- }
182
- if (identifier) {
183
- params.identifier = identifier
184
- }
185
- if (uri) {
186
- params.uri = uri
187
- }
188
- return this._getMappingsQueue().catch(relatedError => {
189
- throw new errors.CDKError({ message: "Could not get mappings from local storage", relatedError })
190
- }).then(({ mappings, done }) => {
191
- done()
192
- // Check concept with param
193
- let checkConcept = (concept, param) => concept.uri == param || (param && concept.notation && concept.notation[0].toLowerCase() == param.toLowerCase())
194
- // Filter mappings according to params (support for from + to)
195
- // TODO: - Support more parameters.
196
- // TODO: - Move to its own things.
197
- // TODO: - Clean all this up.
198
- if (params.from || params.to) {
199
- mappings = mappings.filter(mapping => {
200
- let fromInFrom = null != jskos.conceptsOfMapping(mapping, "from").find(concept => checkConcept(concept, params.from))
201
- let fromInTo = null != jskos.conceptsOfMapping(mapping, "to").find(concept => checkConcept(concept, params.from))
202
- let toInFrom = null != jskos.conceptsOfMapping(mapping, "from").find(concept => checkConcept(concept, params.to))
203
- let toInTo = null != jskos.conceptsOfMapping(mapping, "to").find(concept => checkConcept(concept, params.to))
204
- if (params.direction == "backward") {
205
- if (params.mode == "or") {
206
- return (params.from && fromInTo) || (params.to && toInFrom)
207
- } else {
208
- return (!params.from || fromInTo) && (!params.to || toInFrom)
209
- }
210
- } else if (params.direction == "both") {
211
- if (params.mode == "or") {
212
- return (params.from && (fromInFrom || fromInTo)) || (params.to && (toInFrom || toInTo))
213
- } else {
214
- return ((!params.from || fromInFrom) && (!params.to || toInTo)) || ((!params.from || fromInTo) && (!params.to || toInFrom))
215
- }
216
- } else {
217
- if (params.mode == "or") {
218
- return (params.from && fromInFrom) || (params.to && toInTo)
219
- } else {
220
- return (!params.from || fromInFrom) && (!params.to || toInTo)
221
- }
222
- }
223
- })
224
- }
225
- if (params.fromScheme || params.toScheme) {
226
- mappings = mappings.filter(mapping => {
227
- let fromInFrom = jskos.compare(mapping.fromScheme, params.fromScheme)
228
- let fromInTo = jskos.compare(mapping.toScheme, params.fromScheme)
229
- let toInFrom = jskos.compare(mapping.fromScheme, params.toScheme)
230
- let toInTo = jskos.compare(mapping.toScheme, params.toScheme)
231
- if (params.direction == "backward") {
232
- if (params.mode == "or") {
233
- return (params.fromScheme && fromInTo) || (params.toScheme && toInFrom)
234
- } else {
235
- return (!params.fromScheme || fromInTo) && (!params.toScheme || toInFrom)
236
- }
237
- } else if (params.direction == "both") {
238
- if (params.mode == "or") {
239
- return (params.fromScheme && (fromInFrom || fromInTo)) || (params.toScheme && (toInFrom || toInTo))
240
- } else {
241
- return ((!params.fromScheme || fromInFrom) && (!params.toScheme || toInTo)) || ((!params.fromScheme || fromInTo) && (!params.toScheme || toInFrom))
242
- }
243
- } else {
244
- if (params.mode == "or") {
245
- return (params.fromScheme && fromInFrom) || (params.toScheme && toInTo)
246
- } else {
247
- return (!params.fromScheme || fromInFrom) && (!params.toScheme || toInTo)
248
- }
249
- }
250
- })
251
- }
252
- // creator
253
- if (params.creator) {
254
- let creators = params.creator.split("|")
255
- mappings = mappings.filter(mapping => {
256
- return (mapping.creator && mapping.creator.find(creator => creators.includes(jskos.prefLabel(creator)) || creators.includes(creator.uri))) != null
257
- })
258
- }
259
- // type
260
- if (params.type) {
261
- mappings = mappings.filter(mapping => (mapping.type || [jskos.defaultMappingType.uri]).includes(params.type))
262
- }
263
- // concordance
264
- if (params.partOf) {
265
- mappings = mappings.filter(mapping => {
266
- return mapping.partOf != null && mapping.partOf.find(partOf => jskos.compare(partOf, { uri: params.partOf })) != null
267
- })
268
- }
269
- // identifier
270
- if (params.identifier) {
271
- mappings = mappings.filter(mapping => {
272
- return params.identifier.split("|").map(identifier => {
273
- return (mapping.identifier || []).includes(identifier) || mapping.uri == identifier
274
- }).reduce((current, total) => current || total)
275
- })
276
- }
277
- if (params.uri) {
278
- mappings = mappings.filter(mapping => mapping.uri == params.uri)
279
- }
280
- let totalCount = mappings.length
281
- // Sort mappings (default: modified/created date descending)
282
- mappings = mappings.sort((a, b) => {
283
- let aDate = a.modified || a.created
284
- let bDate = b.modified || b.created
285
- if (bDate == null) {
286
- return -1
287
- }
288
- if (aDate == null) {
289
- return 1
290
- }
291
- if (aDate > bDate) {
292
- return -1
293
- }
294
- return 1
295
- })
296
- mappings = mappings.slice(params.offset || 0)
297
- mappings = mappings.slice(0, params.limit)
298
- mappings._totalCount = totalCount
299
- return mappings
300
- })
301
- }
302
-
303
- /**
304
- * Creates a mapping.
305
- *
306
- * @param {Object} config
307
- * @param {Object} config.mapping JSKOS mapping
308
- * @returns {Object} JSKOS mapping object
309
- */
310
- async postMapping({ mapping }) {
311
- if (!mapping) {
312
- throw new errors.InvalidOrMissingParameterError({ parameter: "mapping" })
313
- }
314
- let { mappings: localMappings, done } = await this._getMappingsQueue()
315
- // Set URI if necessary
316
- if (!mapping.uri || !mapping.uri.startsWith(uriPrefix)) {
317
- if (mapping.uri) {
318
- // Keep previous URI in identifier
319
- if (!mapping.identifier) {
320
- mapping.identifier = []
321
- }
322
- mapping.identifier.push(mapping.uri)
323
- }
324
- mapping.uri = `${uriPrefix}${uuid()}`
325
- }
326
- // Check if mapping already exists => throw error
327
- if (localMappings.find(m => m.uri == mapping.uri)) {
328
- done()
329
- throw new errors.InvalidOrMissingParameterError({ parameter: "mapping", message: "Duplicate URI" })
330
- }
331
- // Set created/modified
332
- if (!mapping.created) {
333
- mapping.created = (new Date()).toISOString()
334
- }
335
- if (!mapping.modified) {
336
- mapping.modified = mapping.created
337
- }
338
- // Add to local mappings
339
- localMappings.push(mapping)
340
- // Minify mappings before saving back to local storage
341
- localMappings = localMappings.map(mapping => jskos.minifyMapping(mapping))
342
- // Write local mappings
343
- try {
344
- await localforage.setItem(this.localStorageKey, localMappings)
345
- done()
346
- return mapping
347
- } catch(error) {
348
- done()
349
- throw error
350
- }
351
- }
352
-
353
- /**
354
- * Overwrites a mapping.
355
- *
356
- * @param {Object} config
357
- * @param {Object} config.mapping JSKOS mapping
358
- * @returns {Object} JSKOS mapping object
359
- */
360
- async putMapping({ mapping }) {
361
- if (!mapping) {
362
- throw new errors.InvalidOrMissingParameterError({ parameter: "mapping" })
363
- }
364
- let { mappings: localMappings, done } = await this._getMappingsQueue()
365
- // Check if mapping already exists => throw error if it doesn't
366
- const index = localMappings.findIndex(m => m.uri == mapping.uri)
367
- if (index == -1) {
368
- done()
369
- throw new errors.InvalidOrMissingParameterError({ parameter: "mapping", message: "Mapping not found" })
370
- }
371
- // Set created/modified
372
- if (!mapping.created) {
373
- mapping.created = localMappings[index].created
374
- }
375
- mapping.modified = (new Date()).toISOString()
376
- // Add to local mappings
377
- localMappings[index] = mapping
378
- // Minify mappings before saving back to local storage
379
- localMappings = localMappings.map(mapping => jskos.minifyMapping(mapping))
380
- // Write local mappings
381
- try {
382
- await localforage.setItem(this.localStorageKey, localMappings)
383
- done()
384
- return mapping
385
- } catch(error) {
386
- done()
387
- throw error
388
- }
389
- }
390
-
391
- /**
392
- * Patches a mapping.
393
- *
394
- * @param {Object} config
395
- * @param {Object} mapping JSKOS mapping (or part of mapping)
396
- * @returns {Object} JSKOS mapping object
397
- */
398
- async patchMapping({ mapping }) {
399
- if (!mapping) {
400
- throw new errors.InvalidOrMissingParameterError({ parameter: "mapping" })
401
- }
402
- let { mappings: localMappings, done } = await this._getMappingsQueue()
403
- // Check if mapping already exists => throw error if it doesn't
404
- const index = localMappings.findIndex(m => m.uri == mapping.uri)
405
- if (index == -1) {
406
- done()
407
- throw new errors.InvalidOrMissingParameterError({ parameter: "mapping", message: "Mapping not found" })
408
- }
409
- // Set created/modified
410
- if (!mapping.created) {
411
- mapping.created = localMappings[index].created
412
- }
413
- mapping.modified = (new Date()).toISOString()
414
- // Add to local mappings
415
- localMappings[index] = Object.assign(localMappings[index], mapping)
416
- // Minify mappings before saving back to local storage
417
- localMappings = localMappings.map(mapping => jskos.minifyMapping(mapping))
418
- // Write local mappings
419
- try {
420
- await localforage.setItem(this.localStorageKey, localMappings)
421
- done()
422
- return mapping
423
- } catch(error) {
424
- done()
425
- throw error
426
- }
427
- }
428
-
429
- /**
430
- * Removes a mapping from local storage.
431
- *
432
- * @param {Object} config
433
- * @param {Object} mapping JSKOS mapping
434
- * @returns {boolean} boolean whether deleting the mapping was successful
435
- */
436
- async deleteMapping({ mapping }) {
437
- if (!mapping) {
438
- throw new errors.InvalidOrMissingParameterError({ parameter: "mapping" })
439
- }
440
- let { mappings: localMappings, done } = await this._getMappingsQueue()
441
- try {
442
- // Remove by URI
443
- localMappings = localMappings.filter(m => m.uri != mapping.uri)
444
- // Minify mappings before saving back to local storage
445
- localMappings = localMappings.map(mapping => jskos.minifyMapping(mapping))
446
- await localforage.setItem(this.localStorageKey, localMappings)
447
- done()
448
- return true
449
- } catch(error) {
450
- done()
451
- throw error
452
- }
453
- }
454
- }
455
-
456
- LocalMappingsProvider.providerName = "LocalMappings"
457
- LocalMappingsProvider.stored = true
458
-
459
- module.exports = LocalMappingsProvider