cocoda-sdk 3.6.1 → 3.6.3
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 +96 -87
- package/dist/cjs/index.cjs +97 -47
- package/dist/cocoda-sdk.js +7 -7
- package/dist/cocoda-sdk.js.map +3 -3
- package/dist/esm/lib/CocodaSDK.js +18 -11
- package/dist/esm/providers/base-provider.js +3 -2
- package/dist/esm/providers/concept-api-provider.js +34 -8
- package/dist/esm/providers/ols-api-provider.js +8 -17
- package/dist/esm/providers/skosmos-api-provider.js +33 -9
- package/dist/esm/utils/index.js +1 -0
- package/package.json +1 -1
|
@@ -139,24 +139,31 @@ class CocodaSDK {
|
|
|
139
139
|
});
|
|
140
140
|
}
|
|
141
141
|
/**
|
|
142
|
-
* Method to get a
|
|
142
|
+
* Method to get a service by URI.
|
|
143
143
|
*
|
|
144
|
-
* @param {string} uri URI of
|
|
145
|
-
* @returns {?Object} initialized
|
|
144
|
+
* @param {string} uri URI of service in config
|
|
145
|
+
* @returns {?Object} initialized service from config if found
|
|
146
146
|
*/
|
|
147
|
-
|
|
147
|
+
getServiceForUri(uri) {
|
|
148
148
|
return this.config.registries.find((r) => r.uri == uri);
|
|
149
149
|
}
|
|
150
|
+
// alias for backwards compatibility
|
|
151
|
+
getRegistryForUri(uri) {
|
|
152
|
+
return this.getRegistryForUri(uri);
|
|
153
|
+
}
|
|
150
154
|
/**
|
|
151
|
-
* Method to initialize
|
|
155
|
+
* Method to initialize service.
|
|
152
156
|
*
|
|
153
|
-
* @param {Object}
|
|
154
|
-
* @returns {Object} initialized
|
|
157
|
+
* @param {Object} service JSKOS service object
|
|
158
|
+
* @returns {Object} initialized service
|
|
155
159
|
*/
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
return
|
|
160
|
+
initializeService(service) {
|
|
161
|
+
service = providers.init(service);
|
|
162
|
+
service.cdk = this;
|
|
163
|
+
return service;
|
|
164
|
+
}
|
|
165
|
+
initializeRegistry(service) {
|
|
166
|
+
return this.initializeService(service);
|
|
160
167
|
}
|
|
161
168
|
/**
|
|
162
169
|
* Method to add custom provider.
|
|
@@ -50,7 +50,8 @@ class BaseProvider {
|
|
|
50
50
|
annotations: registry.annotations,
|
|
51
51
|
occurrences: registry.occurrences,
|
|
52
52
|
reconcile: registry.reconcile,
|
|
53
|
-
api: registry.endpoint || registry.api
|
|
53
|
+
api: registry.endpoint || registry.api,
|
|
54
|
+
registries: registry.registries
|
|
54
55
|
};
|
|
55
56
|
this._config = {};
|
|
56
57
|
this.setRetryConfig();
|
|
@@ -88,7 +89,7 @@ class BaseProvider {
|
|
|
88
89
|
}
|
|
89
90
|
return data;
|
|
90
91
|
}, (error) => {
|
|
91
|
-
const count = error.config
|
|
92
|
+
const count = error.config?._retryCount ?? 0;
|
|
92
93
|
const method = error.config.method;
|
|
93
94
|
const statusCode = error.response?.status;
|
|
94
95
|
if (this._retryConfig.methods.includes(method) && this._retryConfig.statusCodes.includes(statusCode) && count < this._retryConfig.count) {
|
|
@@ -15,7 +15,8 @@ class ConceptApiProvider extends BaseProvider {
|
|
|
15
15
|
types: true,
|
|
16
16
|
suggest: true,
|
|
17
17
|
search: true,
|
|
18
|
-
auth: true
|
|
18
|
+
auth: true,
|
|
19
|
+
registries: true
|
|
19
20
|
};
|
|
20
21
|
/**
|
|
21
22
|
* @private
|
|
@@ -39,7 +40,8 @@ class ConceptApiProvider extends BaseProvider {
|
|
|
39
40
|
ancestors: "/ancestors",
|
|
40
41
|
types: "/types",
|
|
41
42
|
suggest: "/suggest",
|
|
42
|
-
search: "/search"
|
|
43
|
+
search: "/search",
|
|
44
|
+
registries: "/registries"
|
|
43
45
|
};
|
|
44
46
|
for (let key of Object.keys(endpoints)) {
|
|
45
47
|
if (this._api[key] === void 0) {
|
|
@@ -47,6 +49,7 @@ class ConceptApiProvider extends BaseProvider {
|
|
|
47
49
|
}
|
|
48
50
|
}
|
|
49
51
|
}
|
|
52
|
+
this.has.registries = !!this._api.registries;
|
|
50
53
|
this.has.schemes = !!this._api.schemes;
|
|
51
54
|
if (!this.has.schemes && Array.isArray(this.schemes)) {
|
|
52
55
|
this.has.schemes = true;
|
|
@@ -114,6 +117,32 @@ class ConceptApiProvider extends BaseProvider {
|
|
|
114
117
|
return null;
|
|
115
118
|
}
|
|
116
119
|
}
|
|
120
|
+
/**
|
|
121
|
+
* Returns all concept registries.
|
|
122
|
+
*
|
|
123
|
+
* @param {Object} config
|
|
124
|
+
* @returns {Object[]} array of JSKOS concept registry objects
|
|
125
|
+
*/
|
|
126
|
+
async getRegistries(config = {}) {
|
|
127
|
+
if (!this._api.registries) {
|
|
128
|
+
if (Array.isArray(this.registries)) {
|
|
129
|
+
return this.registries;
|
|
130
|
+
}
|
|
131
|
+
throw new errors.MissingApiUrlError();
|
|
132
|
+
}
|
|
133
|
+
const registries = await this.axios({
|
|
134
|
+
...config,
|
|
135
|
+
method: "get",
|
|
136
|
+
url: this._api.registries,
|
|
137
|
+
params: {
|
|
138
|
+
...this._defaultParams,
|
|
139
|
+
// ? What should the default limit be?
|
|
140
|
+
limit: 500,
|
|
141
|
+
...config.params || {}
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
return registries;
|
|
145
|
+
}
|
|
117
146
|
/**
|
|
118
147
|
* Returns all concept schemes.
|
|
119
148
|
*
|
|
@@ -190,13 +219,10 @@ class ConceptApiProvider extends BaseProvider {
|
|
|
190
219
|
if (!url) {
|
|
191
220
|
throw new errors.MissingApiUrlError();
|
|
192
221
|
}
|
|
193
|
-
if (!concepts) {
|
|
194
|
-
throw new errors.InvalidOrMissingParameterError({ parameter: "concepts" });
|
|
195
|
-
}
|
|
196
222
|
if (!Array.isArray(concepts)) {
|
|
197
|
-
concepts = [concepts];
|
|
223
|
+
concepts = concepts ? [concepts] : [];
|
|
198
224
|
}
|
|
199
|
-
|
|
225
|
+
const uris = concepts.map((concept) => concept.uri).filter((uri) => uri != null);
|
|
200
226
|
return this.axios({
|
|
201
227
|
...config,
|
|
202
228
|
method: "get",
|
|
@@ -204,7 +230,7 @@ class ConceptApiProvider extends BaseProvider {
|
|
|
204
230
|
params: {
|
|
205
231
|
...this._defaultParams,
|
|
206
232
|
// ? What should the default limit be?
|
|
207
|
-
limit:
|
|
233
|
+
limit: 100,
|
|
208
234
|
...config.params || {},
|
|
209
235
|
uri: uris.join("|")
|
|
210
236
|
}
|
|
@@ -16,7 +16,7 @@ class OlsApiProvider extends BaseProvider {
|
|
|
16
16
|
};
|
|
17
17
|
constructor(config) {
|
|
18
18
|
super(config);
|
|
19
|
-
this.endpoint = config.endpoint;
|
|
19
|
+
this.endpoint = config.endpoint || config.uri;
|
|
20
20
|
}
|
|
21
21
|
/**
|
|
22
22
|
* Used by `registryForScheme` (see src/lib/CocodaSDK.js) to determine a provider config for a concept schceme.
|
|
@@ -95,7 +95,7 @@ class OlsApiProvider extends BaseProvider {
|
|
|
95
95
|
}
|
|
96
96
|
if (term["http://www.w3.org/2000/01/rdf-schema#label"]) {
|
|
97
97
|
concept.prefLabel = {};
|
|
98
|
-
concept.prefLabel[lan] = term["http://www.w3.org/2000/01/rdf-schema#label"];
|
|
98
|
+
concept.prefLabel[lan] = term["http://www.w3.org/2000/01/rdf-schema#label"].value || term["http://www.w3.org/2000/01/rdf-schema#label"];
|
|
99
99
|
}
|
|
100
100
|
concept.type = [
|
|
101
101
|
"http://www.w3.org/2004/02/skos/core#Concept",
|
|
@@ -261,11 +261,8 @@ class OlsApiProvider extends BaseProvider {
|
|
|
261
261
|
async getTop({ scheme }) {
|
|
262
262
|
const VOCID = await this._getSchemeVOCID(scheme);
|
|
263
263
|
if (VOCID) {
|
|
264
|
-
let
|
|
265
|
-
|
|
266
|
-
if (response?.elements) {
|
|
267
|
-
return Promise.all(response.elements.map((item) => this._termToJSKOS(item)));
|
|
268
|
-
}
|
|
264
|
+
let response = await this._paginate(["ontologies", VOCID, "classes"], { hasDirectParents: "false" }, null);
|
|
265
|
+
return Promise.all(response.map((item) => this._termToJSKOS(item)));
|
|
269
266
|
}
|
|
270
267
|
return [];
|
|
271
268
|
}
|
|
@@ -281,22 +278,16 @@ class OlsApiProvider extends BaseProvider {
|
|
|
281
278
|
async getNarrower({ concept }) {
|
|
282
279
|
const { VOCID, iri } = await this._splitConcept(concept);
|
|
283
280
|
if (VOCID && iri) {
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
if (response?.elements) {
|
|
287
|
-
return Promise.all(response.elements.map((item) => this._termToJSKOS(item)));
|
|
288
|
-
}
|
|
281
|
+
const items = await this._paginate(["ontologies", VOCID, "classes", iri, "children"], {}, 0);
|
|
282
|
+
return Promise.all(items.map((item) => this._termToJSKOS(item)));
|
|
289
283
|
}
|
|
290
284
|
return [];
|
|
291
285
|
}
|
|
292
286
|
async getAncestors({ concept }) {
|
|
293
287
|
const { VOCID, iri } = await this._splitConcept(concept);
|
|
294
288
|
if (VOCID && iri) {
|
|
295
|
-
let
|
|
296
|
-
|
|
297
|
-
if (response?.elements) {
|
|
298
|
-
return Promise.all(response.elements.map((item) => this._termToJSKOS(item)));
|
|
299
|
-
}
|
|
289
|
+
let response = await this._paginate(["ontologies", VOCID, "classes", iri, "ancestors"], {}, null);
|
|
290
|
+
return Promise.all(response.map((item) => this._termToJSKOS(item)));
|
|
300
291
|
}
|
|
301
292
|
return [];
|
|
302
293
|
}
|
|
@@ -45,7 +45,7 @@ class SkosmosApiProvider extends BaseProvider {
|
|
|
45
45
|
* @private
|
|
46
46
|
*/
|
|
47
47
|
_getApiUrl(scheme, endpoint, params) {
|
|
48
|
-
const VOCID = scheme
|
|
48
|
+
const VOCID = scheme?.VOCID || this.schemes.find((s) => jskos.compare(s, scheme))?.VOCID;
|
|
49
49
|
if (!VOCID) {
|
|
50
50
|
throw new errors.InvalidOrMissingParameterError({ parameter: "scheme", message: "Missing scheme or VOCID property on scheme" });
|
|
51
51
|
}
|
|
@@ -179,6 +179,30 @@ class SkosmosApiProvider extends BaseProvider {
|
|
|
179
179
|
if (!concept.type.length) {
|
|
180
180
|
concept.type = ["http://www.w3.org/2004/02/skos/core#Concept"];
|
|
181
181
|
}
|
|
182
|
+
const map = {
|
|
183
|
+
"skos:definition": "definition",
|
|
184
|
+
"skos:note": "note",
|
|
185
|
+
"skos:scopeNote": "scopeNote",
|
|
186
|
+
"skos:example": "example",
|
|
187
|
+
"skos:historyNote": "historyNote",
|
|
188
|
+
"skos:editorialNote": "editorialNote",
|
|
189
|
+
"skos:changeNote": "changeNote"
|
|
190
|
+
};
|
|
191
|
+
for (let key in map) {
|
|
192
|
+
let notes = skosmosConcept[key] || [];
|
|
193
|
+
if (!Array.isArray(notes)) {
|
|
194
|
+
notes = [notes];
|
|
195
|
+
}
|
|
196
|
+
if (notes.length) {
|
|
197
|
+
concept[map[key]] = {};
|
|
198
|
+
for (const { lang, value } of notes) {
|
|
199
|
+
if (lang && value) {
|
|
200
|
+
concept[map[key]][lang] ||= [];
|
|
201
|
+
concept[map[key]][lang].push(value);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
182
206
|
return concept;
|
|
183
207
|
}
|
|
184
208
|
/**
|
|
@@ -258,20 +282,20 @@ class SkosmosApiProvider extends BaseProvider {
|
|
|
258
282
|
concepts = concepts.map((c) => ({ uri: c.uri, inScheme: c.inScheme }));
|
|
259
283
|
const newConcepts = [];
|
|
260
284
|
for (let concept of concepts) {
|
|
261
|
-
|
|
285
|
+
if (!concept || !concept.uri) {
|
|
286
|
+
throw new errors.InvalidOrMissingParameterError({ parameter: "concept", message: "Missing concept URI" });
|
|
287
|
+
}
|
|
288
|
+
const params = { uri: concept.uri, format: "application/json" };
|
|
289
|
+
const url = this._getApiUrl(concept?.inScheme?.[0], "/data", params);
|
|
262
290
|
if (!url) {
|
|
263
291
|
continue;
|
|
264
292
|
}
|
|
265
293
|
const result = await this.axios({
|
|
266
294
|
...config,
|
|
267
295
|
method: "get",
|
|
268
|
-
url
|
|
269
|
-
params: {
|
|
270
|
-
uri: concept.uri,
|
|
271
|
-
format: "application/json"
|
|
272
|
-
}
|
|
296
|
+
url
|
|
273
297
|
});
|
|
274
|
-
const resultConcept = result
|
|
298
|
+
const resultConcept = result?.graph?.find((c) => jskos.compare(c, concept));
|
|
275
299
|
if (resultConcept) {
|
|
276
300
|
const newConcept = this._toJskosConcept(resultConcept, { concept, result });
|
|
277
301
|
for (let type of ["broader", "narrower"]) {
|
|
@@ -385,7 +409,7 @@ class SkosmosApiProvider extends BaseProvider {
|
|
|
385
409
|
method: "get",
|
|
386
410
|
url
|
|
387
411
|
});
|
|
388
|
-
for (let type of response
|
|
412
|
+
for (let type of response?.types || []) {
|
|
389
413
|
if (type.uri == "http://www.w3.org/2004/02/skos/core#Concept") {
|
|
390
414
|
continue;
|
|
391
415
|
}
|
package/dist/esm/utils/index.js
CHANGED