cocoda-sdk 3.0.2 → 3.2.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/README.md +20 -0
- package/dist/cjs/index.cjs +360 -39
- package/dist/cocoda-sdk.js +6 -6
- package/dist/cocoda-sdk.js.LICENSES.txt +209 -2
- package/dist/cocoda-sdk.js.map +3 -3
- package/dist/esm/lib/CocodaSDK.js +22 -5
- package/dist/esm/providers/base-provider.js +7 -5
- package/dist/esm/providers/index.js +2 -0
- package/dist/esm/providers/mappings-api-provider.js +89 -5
- package/dist/esm/providers/skohub-provider.js +227 -0
- package/package.json +12 -10
|
@@ -114,7 +114,8 @@ class CocodaSDK {
|
|
|
114
114
|
timer: null,
|
|
115
115
|
result: null,
|
|
116
116
|
error: null,
|
|
117
|
-
isPaused: false
|
|
117
|
+
isPaused: false,
|
|
118
|
+
interval
|
|
118
119
|
};
|
|
119
120
|
const handleResult = (result) => {
|
|
120
121
|
const previousResult = repeat.result;
|
|
@@ -134,7 +135,7 @@ class CocodaSDK {
|
|
|
134
135
|
}
|
|
135
136
|
repeat.timer = setTimeout(() => {
|
|
136
137
|
toCall();
|
|
137
|
-
}, interval);
|
|
138
|
+
}, repeat.interval);
|
|
138
139
|
};
|
|
139
140
|
const call = () => asyncFunc().then(handleResult).catch(handleError).then(() => repeatIfNecessary(call));
|
|
140
141
|
const setup = (_callImmediately = callImmediately) => {
|
|
@@ -157,7 +158,7 @@ class CocodaSDK {
|
|
|
157
158
|
} else {
|
|
158
159
|
setTimeout(() => {
|
|
159
160
|
repeat.timer && clearTimeout(repeat.timer);
|
|
160
|
-
}, interval);
|
|
161
|
+
}, repeat.interval);
|
|
161
162
|
}
|
|
162
163
|
},
|
|
163
164
|
get isPaused() {
|
|
@@ -168,6 +169,12 @@ class CocodaSDK {
|
|
|
168
169
|
},
|
|
169
170
|
get hasErrored() {
|
|
170
171
|
return !!repeat.error;
|
|
172
|
+
},
|
|
173
|
+
get interval() {
|
|
174
|
+
return repeat.interval;
|
|
175
|
+
},
|
|
176
|
+
set interval(value) {
|
|
177
|
+
repeat.interval = value;
|
|
171
178
|
}
|
|
172
179
|
};
|
|
173
180
|
}
|
|
@@ -177,7 +184,7 @@ class CocodaSDK {
|
|
|
177
184
|
if (registry.has.schemes !== false) {
|
|
178
185
|
let promise = registry.getSchemes(config).then((results) => {
|
|
179
186
|
for (let scheme of results) {
|
|
180
|
-
|
|
187
|
+
scheme._registry = registry;
|
|
181
188
|
scheme.__DETAILSLOADED__ = 1;
|
|
182
189
|
scheme.type = scheme.type || ["http://www.w3.org/2004/02/skos/core#ConceptScheme"];
|
|
183
190
|
let otherScheme = schemes.find((s) => jskos.compare(s, scheme)), prio, otherPrio, override = false;
|
|
@@ -208,7 +215,7 @@ class CocodaSDK {
|
|
|
208
215
|
}
|
|
209
216
|
scheme = jskos.merge(scheme, _.omit(otherScheme, ["concepts", "topConcepts"]), { mergeUris: true, skipPaths: ["_registry"] });
|
|
210
217
|
}
|
|
211
|
-
scheme._registry =
|
|
218
|
+
scheme._registry = registry;
|
|
212
219
|
schemes.push(scheme);
|
|
213
220
|
} else {
|
|
214
221
|
const index = schemes.findIndex((s) => jskos.compare(s, scheme));
|
|
@@ -226,6 +233,16 @@ class CocodaSDK {
|
|
|
226
233
|
}
|
|
227
234
|
}
|
|
228
235
|
await Promise.all(promises);
|
|
236
|
+
schemes.forEach((scheme) => {
|
|
237
|
+
const previousRegistry = scheme._registry;
|
|
238
|
+
delete scheme._registry;
|
|
239
|
+
const newRegistry = this.registryForScheme(scheme);
|
|
240
|
+
if (!newRegistry || newRegistry._api.api === previousRegistry._api.api) {
|
|
241
|
+
scheme._registry = previousRegistry;
|
|
242
|
+
} else {
|
|
243
|
+
scheme._registry = newRegistry;
|
|
244
|
+
}
|
|
245
|
+
});
|
|
229
246
|
return jskos.sortSchemes(schemes.filter(Boolean));
|
|
230
247
|
}
|
|
231
248
|
registryForScheme(scheme) {
|
|
@@ -41,10 +41,12 @@ class BaseProvider {
|
|
|
41
41
|
this._config = {};
|
|
42
42
|
this.setRetryConfig();
|
|
43
43
|
this.axios.interceptors.request.use((config) => {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
_.
|
|
44
|
+
if (!config._skipAdditionalParameters) {
|
|
45
|
+
const language = _.uniq([].concat(_.get(config, "params.language", "").split(","), this.languages, this._defaultLanguages).filter((lang) => lang != "")).join(",");
|
|
46
|
+
_.set(config, "params.language", language);
|
|
47
|
+
if (this.has.auth && this._auth.bearerToken && !_.get(config, "headers.Authorization")) {
|
|
48
|
+
_.set(config, "headers.Authorization", `Bearer ${this._auth.bearerToken}`);
|
|
49
|
+
}
|
|
48
50
|
}
|
|
49
51
|
if (config.url.startsWith("http:") && typeof window !== "undefined" && window.location.protocol == "https:") {
|
|
50
52
|
throw new axios.Cancel("Can't call http API from https.");
|
|
@@ -315,7 +317,7 @@ class BaseProvider {
|
|
|
315
317
|
}
|
|
316
318
|
const previousRegistry = scheme._registry;
|
|
317
319
|
scheme._registry = this.cdk && this.cdk.registryForScheme(scheme);
|
|
318
|
-
if (!scheme._registry || previousRegistry === scheme._registry) {
|
|
320
|
+
if (!scheme._registry || previousRegistry === scheme._registry || scheme._registry._api.api === this._api.api) {
|
|
319
321
|
scheme._registry = previousRegistry || this;
|
|
320
322
|
} else {
|
|
321
323
|
["concepts", "topConcepts"].forEach((key) => {
|
|
@@ -7,6 +7,7 @@ import ReconciliationApiProvider from "./reconciliation-api-provider.js";
|
|
|
7
7
|
import LabelSearchSuggestionProvider from "./label-search-suggestion-provider.js";
|
|
8
8
|
import SkosmosApiProvider from "./skosmos-api-provider.js";
|
|
9
9
|
import LocApiProvider from "./loc-api-provider.js";
|
|
10
|
+
import SkohubProvider from "./skohub-provider.js";
|
|
10
11
|
export {
|
|
11
12
|
BaseProvider,
|
|
12
13
|
ConceptApiProvider,
|
|
@@ -16,5 +17,6 @@ export {
|
|
|
16
17
|
MappingsApiProvider,
|
|
17
18
|
OccurrencesApiProvider,
|
|
18
19
|
ReconciliationApiProvider,
|
|
20
|
+
SkohubProvider,
|
|
19
21
|
SkosmosApiProvider
|
|
20
22
|
};
|
|
@@ -36,7 +36,13 @@ class MappingsApiProvider extends BaseProvider {
|
|
|
36
36
|
this.has.mappings.delete = !!_.get(this._config, "mappings.delete");
|
|
37
37
|
this.has.mappings.anonymous = !!_.get(this._config, "mappings.anonymous");
|
|
38
38
|
}
|
|
39
|
-
this.has.concordances =
|
|
39
|
+
this.has.concordances = this._api.concordances ? {} : false;
|
|
40
|
+
if (this.has.concordances) {
|
|
41
|
+
this.has.concordances.read = !!_.get(this._config, "concordances.read");
|
|
42
|
+
this.has.concordances.create = !!_.get(this._config, "concordances.create");
|
|
43
|
+
this.has.concordances.update = !!_.get(this._config, "concordances.update");
|
|
44
|
+
this.has.concordances.delete = !!_.get(this._config, "concordances.delete");
|
|
45
|
+
}
|
|
40
46
|
this.has.annotations = this._api.annotations ? {} : false;
|
|
41
47
|
if (this.has.annotations) {
|
|
42
48
|
this.has.annotations.read = !!_.get(this._config, "annotations.read");
|
|
@@ -72,7 +78,7 @@ class MappingsApiProvider extends BaseProvider {
|
|
|
72
78
|
throw error;
|
|
73
79
|
}
|
|
74
80
|
}
|
|
75
|
-
async getMappings({ from, fromScheme, to, toScheme, creator, type, partOf, offset, limit, direction, mode, identifier, sort, order, ...config }) {
|
|
81
|
+
async getMappings({ from, fromScheme, to, toScheme, creator, type, partOf, offset, limit, direction, mode, identifier, cardinality, annotatedBy, annotatedFor, annotatedWith, sort, order, ...config }) {
|
|
76
82
|
let params = {}, url = this._api.mappings;
|
|
77
83
|
if (from) {
|
|
78
84
|
params.from = _.isString(from) ? from : from.uri;
|
|
@@ -104,6 +110,18 @@ class MappingsApiProvider extends BaseProvider {
|
|
|
104
110
|
if (direction) {
|
|
105
111
|
params.direction = direction;
|
|
106
112
|
}
|
|
113
|
+
if (cardinality) {
|
|
114
|
+
params.cardinality = cardinality;
|
|
115
|
+
}
|
|
116
|
+
if (annotatedBy) {
|
|
117
|
+
params.annotatedBy = annotatedBy;
|
|
118
|
+
}
|
|
119
|
+
if (annotatedFor) {
|
|
120
|
+
params.annotatedFor = annotatedFor;
|
|
121
|
+
}
|
|
122
|
+
if (annotatedWith) {
|
|
123
|
+
params.annotatedWith = annotatedWith;
|
|
124
|
+
}
|
|
107
125
|
if (mode) {
|
|
108
126
|
params.mode = mode;
|
|
109
127
|
}
|
|
@@ -169,8 +187,6 @@ class MappingsApiProvider extends BaseProvider {
|
|
|
169
187
|
if (!mapping) {
|
|
170
188
|
throw new errors.InvalidOrMissingParameterError({ parameter: "mapping" });
|
|
171
189
|
}
|
|
172
|
-
mapping = jskos.minifyMapping(mapping);
|
|
173
|
-
mapping = jskos.addMappingIdentifiers(mapping);
|
|
174
190
|
const uri = mapping.uri;
|
|
175
191
|
if (!uri || !uri.startsWith(this._api.mappings)) {
|
|
176
192
|
throw new errors.InvalidOrMissingParameterError({ parameter: "mapping", message: "URI doesn't seem to be part of this registry." });
|
|
@@ -179,7 +195,7 @@ class MappingsApiProvider extends BaseProvider {
|
|
|
179
195
|
...config,
|
|
180
196
|
method: "patch",
|
|
181
197
|
url: uri,
|
|
182
|
-
data: mapping,
|
|
198
|
+
data: _.omit(mapping, "uri"),
|
|
183
199
|
params: {
|
|
184
200
|
...this._defaultParams,
|
|
185
201
|
...config.params || {}
|
|
@@ -262,6 +278,74 @@ class MappingsApiProvider extends BaseProvider {
|
|
|
262
278
|
url: this._api.concordances
|
|
263
279
|
});
|
|
264
280
|
}
|
|
281
|
+
async postConcordance({ concordance, ...config }) {
|
|
282
|
+
if (!concordance) {
|
|
283
|
+
throw new errors.InvalidOrMissingParameterError({ parameter: "concordance" });
|
|
284
|
+
}
|
|
285
|
+
return this.axios({
|
|
286
|
+
...config,
|
|
287
|
+
method: "post",
|
|
288
|
+
url: this._api.concordances,
|
|
289
|
+
data: concordance,
|
|
290
|
+
params: {
|
|
291
|
+
...this._defaultParams,
|
|
292
|
+
...config.params || {}
|
|
293
|
+
}
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
async putConcordance({ concordance, ...config }) {
|
|
297
|
+
if (!concordance) {
|
|
298
|
+
throw new errors.InvalidOrMissingParameterError({ parameter: "concordance" });
|
|
299
|
+
}
|
|
300
|
+
const uri = concordance.uri;
|
|
301
|
+
if (!uri || !uri.startsWith(this._api.concordances)) {
|
|
302
|
+
throw new errors.InvalidOrMissingParameterError({ parameter: "concordance", message: "URI doesn't seem to be part of this registry." });
|
|
303
|
+
}
|
|
304
|
+
return this.axios({
|
|
305
|
+
...config,
|
|
306
|
+
method: "put",
|
|
307
|
+
url: uri,
|
|
308
|
+
data: concordance,
|
|
309
|
+
params: {
|
|
310
|
+
...this._defaultParams,
|
|
311
|
+
...config.params || {}
|
|
312
|
+
}
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
async patchConcordance({ concordance, ...config }) {
|
|
316
|
+
if (!concordance) {
|
|
317
|
+
throw new errors.InvalidOrMissingParameterError({ parameter: "concordance" });
|
|
318
|
+
}
|
|
319
|
+
const uri = concordance.uri;
|
|
320
|
+
if (!uri || !uri.startsWith(this._api.concordances)) {
|
|
321
|
+
throw new errors.InvalidOrMissingParameterError({ parameter: "concordance", message: "URI doesn't seem to be part of this registry." });
|
|
322
|
+
}
|
|
323
|
+
return this.axios({
|
|
324
|
+
...config,
|
|
325
|
+
method: "patch",
|
|
326
|
+
url: uri,
|
|
327
|
+
data: _.omit(concordance, "uri"),
|
|
328
|
+
params: {
|
|
329
|
+
...this._defaultParams,
|
|
330
|
+
...config.params || {}
|
|
331
|
+
}
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
async deleteConcordance({ concordance, ...config }) {
|
|
335
|
+
if (!concordance) {
|
|
336
|
+
throw new errors.InvalidOrMissingParameterError({ parameter: "concordance" });
|
|
337
|
+
}
|
|
338
|
+
const uri = concordance.uri;
|
|
339
|
+
if (!uri || !uri.startsWith(this._api.concordances)) {
|
|
340
|
+
throw new errors.InvalidOrMissingParameterError({ parameter: "concordance", message: "URI doesn't seem to be part of this registry." });
|
|
341
|
+
}
|
|
342
|
+
await this.axios({
|
|
343
|
+
...config,
|
|
344
|
+
method: "delete",
|
|
345
|
+
url: uri
|
|
346
|
+
});
|
|
347
|
+
return true;
|
|
348
|
+
}
|
|
265
349
|
}
|
|
266
350
|
MappingsApiProvider.providerName = "MappingsApi";
|
|
267
351
|
MappingsApiProvider.stored = true;
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import BaseProvider from "./base-provider.js";
|
|
2
|
+
import * as _ from "../utils/lodash.js";
|
|
3
|
+
import * as errors from "../errors/index.js";
|
|
4
|
+
import { listOfCapabilities } from "../utils/index.js";
|
|
5
|
+
import jskos from "jskos-tools";
|
|
6
|
+
import FlexSearch from "flexsearch";
|
|
7
|
+
function decodeUnicode(text) {
|
|
8
|
+
return text.replace(/\\u[\dA-F]{4}/gi, function(match) {
|
|
9
|
+
return String.fromCharCode(parseInt(match.replace(/\\u/g, ""), 16));
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
class SkohubProvider extends BaseProvider {
|
|
13
|
+
_prepare() {
|
|
14
|
+
this.has.schemes = true;
|
|
15
|
+
this.has.top = true;
|
|
16
|
+
this.has.data = true;
|
|
17
|
+
this.has.concepts = true;
|
|
18
|
+
this.has.narrower = true;
|
|
19
|
+
this.has.ancestors = true;
|
|
20
|
+
this.has.suggest = true;
|
|
21
|
+
this.has.search = true;
|
|
22
|
+
listOfCapabilities.filter((c) => !this.has[c]).forEach((c) => {
|
|
23
|
+
this.has[c] = false;
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
_setup() {
|
|
27
|
+
this._index = {};
|
|
28
|
+
this._conceptCache = {};
|
|
29
|
+
this._schemeCache = {};
|
|
30
|
+
}
|
|
31
|
+
static _registryConfigForBartocApiConfig({ url, scheme } = {}) {
|
|
32
|
+
if (!url || !scheme) {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
const newScheme = { uri: url, identifier: jskos.getAllUris(scheme).filter((uri) => uri !== url) };
|
|
36
|
+
return { schemes: [newScheme] };
|
|
37
|
+
}
|
|
38
|
+
async _loadScheme({ scheme, ...config }) {
|
|
39
|
+
let uris = jskos.getAllUris(scheme);
|
|
40
|
+
for (let uri2 of uris) {
|
|
41
|
+
if (this._schemeCache[uri2]) {
|
|
42
|
+
return this._schemeCache[uri2];
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
const schemeFromList = this.schemes.find((s) => jskos.compare(s, scheme));
|
|
46
|
+
if (!schemeFromList || !schemeFromList.uri) {
|
|
47
|
+
throw new errors.InvalidRequestError({ message: `Tried to load unsupported scheme (${scheme && scheme.uri})` });
|
|
48
|
+
}
|
|
49
|
+
const uri = schemeFromList.uri;
|
|
50
|
+
uris = _.uniq(uris.concat(jskos.getAllUris(schemeFromList)));
|
|
51
|
+
let postfix = ".json";
|
|
52
|
+
if (uri.endsWith("/")) {
|
|
53
|
+
postfix = "index.json";
|
|
54
|
+
}
|
|
55
|
+
const data = await this.axios({ ...config, url: `${uri}${postfix}`, _skipAdditionalParameters: true });
|
|
56
|
+
if (data.id !== uri) {
|
|
57
|
+
throw new errors.InvalidRequestError({ message: "Skohub URL did not return expected concept scheme" });
|
|
58
|
+
}
|
|
59
|
+
const { title, preferredNamespaceUri, hasTopConcept, description } = data;
|
|
60
|
+
scheme = { uri, identifier: uris.filter((u) => u !== uri) };
|
|
61
|
+
scheme.prefLabel = title;
|
|
62
|
+
Object.keys(scheme.prefLabel || {}).forEach((key) => {
|
|
63
|
+
scheme.prefLabel[key] = decodeUnicode(scheme.prefLabel[key]);
|
|
64
|
+
});
|
|
65
|
+
scheme.namespace = preferredNamespaceUri;
|
|
66
|
+
scheme.topConcepts = (hasTopConcept || []).map((c) => this._toJskosConcept(c));
|
|
67
|
+
scheme.concepts = [null];
|
|
68
|
+
if (description) {
|
|
69
|
+
scheme.definition = description;
|
|
70
|
+
Object.keys(scheme.definition).forEach((key) => {
|
|
71
|
+
scheme.definition[key] = [decodeUnicode(scheme.definition[key])];
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
for (let key of Object.keys(scheme).filter((key2) => !scheme[key2])) {
|
|
75
|
+
delete scheme[key];
|
|
76
|
+
}
|
|
77
|
+
for (let uri2 of uris) {
|
|
78
|
+
this._schemeCache[uri2] = scheme;
|
|
79
|
+
}
|
|
80
|
+
return scheme;
|
|
81
|
+
}
|
|
82
|
+
async _loadConcept({ uri, ...config }) {
|
|
83
|
+
if (this._conceptCache[uri]) {
|
|
84
|
+
return this._conceptCache[uri];
|
|
85
|
+
}
|
|
86
|
+
try {
|
|
87
|
+
const data = await this.axios({ ...config, url: `${uri}.json`, _skipAdditionalParameters: true });
|
|
88
|
+
if (data.id !== uri) {
|
|
89
|
+
throw new errors.InvalidRequestError({ message: "Skohub URL did not return expected concept URI" });
|
|
90
|
+
}
|
|
91
|
+
const concept = this._toJskosConcept(data);
|
|
92
|
+
this._conceptCache[uri] = concept;
|
|
93
|
+
return concept;
|
|
94
|
+
} catch (error) {
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
_toJskosConcept(data) {
|
|
99
|
+
const concept = { uri: data.id };
|
|
100
|
+
concept.prefLabel = data.prefLabel;
|
|
101
|
+
Object.keys(concept.prefLabel || {}).forEach((key) => {
|
|
102
|
+
concept.prefLabel[key] = decodeUnicode(concept.prefLabel[key]);
|
|
103
|
+
});
|
|
104
|
+
concept.narrower = (data.narrower || []).map((c) => this._toJskosConcept(c));
|
|
105
|
+
concept.notation = data.notation || [];
|
|
106
|
+
if (data.broader && data.broader.id) {
|
|
107
|
+
concept.broader = [{ uri: data.broader.id }];
|
|
108
|
+
}
|
|
109
|
+
if (data.inScheme && data.inScheme.id) {
|
|
110
|
+
concept.inScheme = [{ uri: data.inScheme.id }];
|
|
111
|
+
}
|
|
112
|
+
if (data.scopeNote) {
|
|
113
|
+
concept.scopeNote = data.scopeNote;
|
|
114
|
+
Object.keys(concept.scopeNote).forEach((key) => {
|
|
115
|
+
concept.scopeNote[key] = [decodeUnicode(concept.scopeNote[key])];
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
return concept;
|
|
119
|
+
}
|
|
120
|
+
async getSchemes({ ...config }) {
|
|
121
|
+
return Promise.all(this.schemes.map((scheme) => this._loadScheme({ ...config, scheme })));
|
|
122
|
+
}
|
|
123
|
+
async getTop({ scheme, ...config }) {
|
|
124
|
+
if (!scheme || !scheme.uri) {
|
|
125
|
+
throw new errors.InvalidOrMissingParameterError({ parameter: "scheme", message: "Missing scheme URI" });
|
|
126
|
+
}
|
|
127
|
+
scheme = await this._loadScheme({ scheme, ...config });
|
|
128
|
+
return scheme.topConcepts || [];
|
|
129
|
+
}
|
|
130
|
+
async getConcepts({ concepts, ...config }) {
|
|
131
|
+
if (!_.isArray(concepts)) {
|
|
132
|
+
concepts = [concepts];
|
|
133
|
+
}
|
|
134
|
+
return (await Promise.all(concepts.map(({ uri }) => this._loadConcept({ ...config, uri })))).filter(Boolean);
|
|
135
|
+
}
|
|
136
|
+
async getAncestors({ concept, ...config }) {
|
|
137
|
+
if (!concept || !concept.uri) {
|
|
138
|
+
throw new errors.InvalidOrMissingParameterError({ parameter: "concept" });
|
|
139
|
+
}
|
|
140
|
+
if (concept.ancestors && concept.ancestors[0] !== null) {
|
|
141
|
+
return concept.ancestors;
|
|
142
|
+
}
|
|
143
|
+
concept = await this._loadConcept({ ...config, uri: concept.uri });
|
|
144
|
+
if (!concept || !concept.broader || !concept.broader.length) {
|
|
145
|
+
return [];
|
|
146
|
+
}
|
|
147
|
+
const broader = concept.broader[0];
|
|
148
|
+
return [broader].concat(await this.getAncestors({ concept: broader, ...config })).map((c) => ({ uri: c.uri }));
|
|
149
|
+
}
|
|
150
|
+
async getNarrower({ concept, ...config }) {
|
|
151
|
+
if (!concept || !concept.uri) {
|
|
152
|
+
throw new errors.InvalidOrMissingParameterError({ parameter: "concept" });
|
|
153
|
+
}
|
|
154
|
+
if (concept.narrower && concept.narrower[0] !== null) {
|
|
155
|
+
return concept.narrower;
|
|
156
|
+
}
|
|
157
|
+
concept = await this._loadConcept({ ...config, uri: concept.uri });
|
|
158
|
+
return concept.narrower;
|
|
159
|
+
}
|
|
160
|
+
async search({ search, scheme, limit = 100 }) {
|
|
161
|
+
if (!scheme || !scheme.uri) {
|
|
162
|
+
throw new errors.InvalidOrMissingParameterError({ parameter: "scheme" });
|
|
163
|
+
}
|
|
164
|
+
if (!search) {
|
|
165
|
+
throw new errors.InvalidOrMissingParameterError({ parameter: "search" });
|
|
166
|
+
}
|
|
167
|
+
let index;
|
|
168
|
+
if (!this._index[scheme.uri]) {
|
|
169
|
+
this._index[scheme.uri] = {};
|
|
170
|
+
}
|
|
171
|
+
for (const lang of [""].concat(this.languages)) {
|
|
172
|
+
if (this._index[scheme.uri][lang]) {
|
|
173
|
+
index = this._index[scheme.uri][lang];
|
|
174
|
+
break;
|
|
175
|
+
}
|
|
176
|
+
if (this._index[scheme.uri][lang] === null) {
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
179
|
+
try {
|
|
180
|
+
let postfix = lang ? `.${lang}.index` : ".index";
|
|
181
|
+
if (scheme.uri.endsWith("/")) {
|
|
182
|
+
postfix = `index${postfix}`;
|
|
183
|
+
}
|
|
184
|
+
const data = await this.axios({ url: `${scheme.uri}${postfix}`, _skipAdditionalParameters: true });
|
|
185
|
+
if (data.length < 100) {
|
|
186
|
+
this._index[scheme.uri][lang] = null;
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
index = FlexSearch.create();
|
|
190
|
+
index.import(data);
|
|
191
|
+
this._index[scheme.uri][lang] = index;
|
|
192
|
+
break;
|
|
193
|
+
} catch (error) {
|
|
194
|
+
this._index[scheme.uri][lang] = null;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
if (!index) {
|
|
198
|
+
throw new errors.InvalidRequestError({ message: "Could not find search index for any of the available languages " + this.languages.join(",") });
|
|
199
|
+
}
|
|
200
|
+
const result = index.search(search);
|
|
201
|
+
const concepts = await this.getConcepts({ concepts: result.map((uri) => ({ uri })) });
|
|
202
|
+
return concepts.slice(0, limit);
|
|
203
|
+
}
|
|
204
|
+
async suggest(config) {
|
|
205
|
+
config._raw = true;
|
|
206
|
+
const concepts = await this.search(config);
|
|
207
|
+
const result = [config.search, [], [], []];
|
|
208
|
+
for (let concept of concepts) {
|
|
209
|
+
const notation = jskos.notation(concept);
|
|
210
|
+
const label = jskos.prefLabel(concept);
|
|
211
|
+
result[1].push((notation ? notation + " " : "") + label);
|
|
212
|
+
result[2].push("");
|
|
213
|
+
result[3].push(concept.uri);
|
|
214
|
+
}
|
|
215
|
+
if (concepts._totalCount != void 0) {
|
|
216
|
+
result._totalCount = concepts._totalCount;
|
|
217
|
+
} else {
|
|
218
|
+
result._totalCount = concepts.length;
|
|
219
|
+
}
|
|
220
|
+
return result;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
SkohubProvider.providerName = "Skohub";
|
|
224
|
+
SkohubProvider.providerType = "http://bartoc.org/api-type/skohub";
|
|
225
|
+
export {
|
|
226
|
+
SkohubProvider as default
|
|
227
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cocoda-sdk",
|
|
3
|
-
"version": "3.0
|
|
3
|
+
"version": "3.2.0",
|
|
4
4
|
"description": "SDK for Cocoda",
|
|
5
5
|
"main": "dist/cjs/index.cjs",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -26,7 +26,8 @@
|
|
|
26
26
|
"release": "npm run build && npm test && git checkout dev && git pull && npm version $SEMVER && git push && git checkout master && git merge dev && git push --follow-tags && git checkout dev",
|
|
27
27
|
"release:patch": "SEMVER=patch npm run release",
|
|
28
28
|
"release:minor": "SEMVER=minor npm run release",
|
|
29
|
-
"release:major": "SEMVER=major npm run release"
|
|
29
|
+
"release:major": "SEMVER=major npm run release",
|
|
30
|
+
"postinstall": "[ -d './dist' ] || npm run build"
|
|
30
31
|
},
|
|
31
32
|
"lint-staged": {
|
|
32
33
|
"**/*.js": [
|
|
@@ -51,23 +52,24 @@
|
|
|
51
52
|
},
|
|
52
53
|
"homepage": "https://github.com/gbv/cocoda-sdk#readme",
|
|
53
54
|
"devDependencies": {
|
|
54
|
-
"axios-mock-adapter": "^1.
|
|
55
|
+
"axios-mock-adapter": "^1.21.1",
|
|
55
56
|
"better-docs": "^2.7.2",
|
|
56
|
-
"esbuild": "~0.14.
|
|
57
|
+
"esbuild": "~0.14.43",
|
|
57
58
|
"esbuild-plugin-ifdef": "^1.0.1",
|
|
58
|
-
"eslint": "^8.
|
|
59
|
+
"eslint": "^8.17.0",
|
|
59
60
|
"eslint-config-gbv": "^1.0.3",
|
|
60
|
-
"glob": "^
|
|
61
|
+
"glob": "^8.0.3",
|
|
61
62
|
"jsdoc": "^3.6.10",
|
|
62
63
|
"license-checker": "^25.0.1",
|
|
63
|
-
"lint-staged": "^12.
|
|
64
|
-
"mocha": "^9.2.
|
|
64
|
+
"lint-staged": "^12.5.0",
|
|
65
|
+
"mocha": "^9.2.2",
|
|
65
66
|
"mocha-eslint": "^7.0.0",
|
|
66
67
|
"pre-commit": "^1.2.2"
|
|
67
68
|
},
|
|
68
69
|
"dependencies": {
|
|
69
|
-
"axios": "
|
|
70
|
-
"
|
|
70
|
+
"axios": "~0.26.1",
|
|
71
|
+
"flexsearch": "~0.6.32",
|
|
72
|
+
"jskos-tools": "^1.0.26",
|
|
71
73
|
"localforage": "^1.10.0",
|
|
72
74
|
"lodash": "^4.17.21",
|
|
73
75
|
"uuid": "^8.3.2"
|