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
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
class CDKError extends Error {
|
|
2
|
+
constructor({ message = "", relatedError = null, code = null } = {}) {
|
|
3
|
+
if (!message && relatedError && relatedError.message) {
|
|
4
|
+
message = relatedError.message;
|
|
5
|
+
}
|
|
6
|
+
super(message);
|
|
7
|
+
this.name = this.constructor.name;
|
|
8
|
+
this.relatedError = relatedError;
|
|
9
|
+
this.code = code;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
class MethodNotImplementedError extends CDKError {
|
|
13
|
+
constructor({ method, message = "", ...options }) {
|
|
14
|
+
options.message = `Method not implemented: ${method} (${message})`;
|
|
15
|
+
super(options);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
class InvalidOrMissingParameterError extends CDKError {
|
|
19
|
+
constructor({ parameter, message = "", ...options }) {
|
|
20
|
+
options.message = `Invalid or missing parameter: ${parameter} (${message})`;
|
|
21
|
+
super(options);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
class InvalidRequestError extends CDKError {
|
|
25
|
+
}
|
|
26
|
+
class BackendError extends CDKError {
|
|
27
|
+
}
|
|
28
|
+
class BackendUnavailableError extends CDKError {
|
|
29
|
+
}
|
|
30
|
+
class NetworkError extends CDKError {
|
|
31
|
+
}
|
|
32
|
+
class MissingApiUrlError extends CDKError {
|
|
33
|
+
}
|
|
34
|
+
class InvalidProviderError extends CDKError {
|
|
35
|
+
}
|
|
36
|
+
export {
|
|
37
|
+
BackendError,
|
|
38
|
+
BackendUnavailableError,
|
|
39
|
+
CDKError,
|
|
40
|
+
InvalidOrMissingParameterError,
|
|
41
|
+
InvalidProviderError,
|
|
42
|
+
InvalidRequestError,
|
|
43
|
+
MethodNotImplementedError,
|
|
44
|
+
MissingApiUrlError,
|
|
45
|
+
NetworkError
|
|
46
|
+
};
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
import * as errors from "../errors/index.js";
|
|
2
|
+
import axios from "axios";
|
|
3
|
+
import * as _ from "../utils/lodash.js";
|
|
4
|
+
import jskos from "jskos-tools";
|
|
5
|
+
import { BaseProvider, ConceptApiProvider, MappingsApiProvider } from "../providers/index.js";
|
|
6
|
+
const providers = {
|
|
7
|
+
[BaseProvider.providerName]: BaseProvider,
|
|
8
|
+
init(registry) {
|
|
9
|
+
if (this[registry.provider]) {
|
|
10
|
+
return new this[registry.provider](registry);
|
|
11
|
+
}
|
|
12
|
+
throw new errors.InvalidProviderError();
|
|
13
|
+
},
|
|
14
|
+
addProvider(provider) {
|
|
15
|
+
if (provider.prototype instanceof BaseProvider || provider === BaseProvider) {
|
|
16
|
+
this[provider.providerName] = provider;
|
|
17
|
+
} else {
|
|
18
|
+
throw new errors.InvalidProviderError();
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
providers.addProvider(ConceptApiProvider);
|
|
23
|
+
providers.addProvider(MappingsApiProvider);
|
|
24
|
+
class CocodaSDK {
|
|
25
|
+
constructor(config) {
|
|
26
|
+
this.config = config;
|
|
27
|
+
this.axios = axios.create();
|
|
28
|
+
}
|
|
29
|
+
setConfig(config) {
|
|
30
|
+
this.config = config;
|
|
31
|
+
}
|
|
32
|
+
get config() {
|
|
33
|
+
return this._config;
|
|
34
|
+
}
|
|
35
|
+
set config(config) {
|
|
36
|
+
config = config || {};
|
|
37
|
+
config.registries = config.registries || [];
|
|
38
|
+
config.registries = config.registries.map((registry) => providers.init(registry)).filter((r) => r);
|
|
39
|
+
config.registries.forEach((registry) => {
|
|
40
|
+
registry.cdk = this;
|
|
41
|
+
});
|
|
42
|
+
this._config = config;
|
|
43
|
+
}
|
|
44
|
+
get providers() {
|
|
45
|
+
return providers;
|
|
46
|
+
}
|
|
47
|
+
createInstance(config) {
|
|
48
|
+
return new CocodaSDK(config);
|
|
49
|
+
}
|
|
50
|
+
async loadConfig(url) {
|
|
51
|
+
const response = await this.axios.get(url);
|
|
52
|
+
this.config = response.data;
|
|
53
|
+
}
|
|
54
|
+
loadBuildInfo({ url, buildInfo = null, interval = 6e4, callback, ...config }) {
|
|
55
|
+
if (!url && !this.config.cocodaBaseUrl) {
|
|
56
|
+
throw new errors.CDKError({ message: "Could not determine URL to load build config." });
|
|
57
|
+
}
|
|
58
|
+
if (!url) {
|
|
59
|
+
url = `${this.config.cocodaBaseUrl}build-info.json`;
|
|
60
|
+
}
|
|
61
|
+
return this.repeat({
|
|
62
|
+
...config,
|
|
63
|
+
function: async () => {
|
|
64
|
+
return (await this.axios.get(url, {
|
|
65
|
+
headers: {
|
|
66
|
+
"Cache-Control": "no-cache"
|
|
67
|
+
}
|
|
68
|
+
})).data;
|
|
69
|
+
},
|
|
70
|
+
interval,
|
|
71
|
+
callback: (error, result, previousResult) => {
|
|
72
|
+
if (error) {
|
|
73
|
+
callback(error);
|
|
74
|
+
} else if (previousResult || !previousResult && buildInfo && !_.isEqual(result, buildInfo)) {
|
|
75
|
+
callback(null, result, previousResult || buildInfo);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
getRegistryForUri(uri) {
|
|
81
|
+
return this.config.registries.find((r) => r.uri == uri);
|
|
82
|
+
}
|
|
83
|
+
initializeRegistry(registry) {
|
|
84
|
+
registry = providers.init(registry);
|
|
85
|
+
registry.cdk = this;
|
|
86
|
+
return registry;
|
|
87
|
+
}
|
|
88
|
+
addProvider(provider) {
|
|
89
|
+
providers.addProvider(provider);
|
|
90
|
+
}
|
|
91
|
+
static addProvider(provider) {
|
|
92
|
+
providers.addProvider(provider);
|
|
93
|
+
}
|
|
94
|
+
repeat({ function: func, interval = 15e3, callback, callImmediately = true } = {}) {
|
|
95
|
+
if (!func) {
|
|
96
|
+
throw new errors.InvalidOrMissingParameterError({ parameter: "function" });
|
|
97
|
+
}
|
|
98
|
+
if (typeof func != "function") {
|
|
99
|
+
throw new errors.InvalidOrMissingParameterError({ parameter: "function", message: "function needs to be a function" });
|
|
100
|
+
}
|
|
101
|
+
const asyncFunc = async () => func();
|
|
102
|
+
interval = parseInt(interval);
|
|
103
|
+
if (isNaN(interval)) {
|
|
104
|
+
throw new errors.InvalidOrMissingParameterError({ parameter: "interval" });
|
|
105
|
+
}
|
|
106
|
+
if (!callback) {
|
|
107
|
+
throw new errors.InvalidOrMissingParameterError({ parameter: "callback" });
|
|
108
|
+
}
|
|
109
|
+
if (typeof callback != "function") {
|
|
110
|
+
throw new errors.InvalidOrMissingParameterError({ parameter: "callback", message: "callback needs to be a function" });
|
|
111
|
+
}
|
|
112
|
+
let repeat = {
|
|
113
|
+
timer: null,
|
|
114
|
+
result: null,
|
|
115
|
+
error: null,
|
|
116
|
+
isPaused: false
|
|
117
|
+
};
|
|
118
|
+
const handleResult = (result) => {
|
|
119
|
+
const previousResult = repeat.result;
|
|
120
|
+
if (!_.isEqual(previousResult, result)) {
|
|
121
|
+
repeat.result = result;
|
|
122
|
+
repeat.error = null;
|
|
123
|
+
callback(null, result, previousResult);
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
const handleError = (error) => {
|
|
127
|
+
repeat.error = error;
|
|
128
|
+
callback(error);
|
|
129
|
+
};
|
|
130
|
+
const repeatIfNecessary = (toCall) => {
|
|
131
|
+
if (repeat.isPaused) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
repeat.timer = setTimeout(() => {
|
|
135
|
+
toCall();
|
|
136
|
+
}, interval);
|
|
137
|
+
};
|
|
138
|
+
const call = () => asyncFunc().then(handleResult).catch(handleError).then(() => repeatIfNecessary(call));
|
|
139
|
+
const setup = (_callImmediately = callImmediately) => {
|
|
140
|
+
if (_callImmediately) {
|
|
141
|
+
call();
|
|
142
|
+
} else {
|
|
143
|
+
repeatIfNecessary(call);
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
setup();
|
|
147
|
+
return {
|
|
148
|
+
start: (...params) => {
|
|
149
|
+
repeat.isPaused = false;
|
|
150
|
+
setup(...params);
|
|
151
|
+
},
|
|
152
|
+
stop: () => {
|
|
153
|
+
repeat.isPaused = true;
|
|
154
|
+
if (repeat.timer) {
|
|
155
|
+
clearTimeout(repeat.timer);
|
|
156
|
+
} else {
|
|
157
|
+
setTimeout(() => {
|
|
158
|
+
repeat.timer && clearTimeout(repeat.timer);
|
|
159
|
+
}, interval);
|
|
160
|
+
}
|
|
161
|
+
},
|
|
162
|
+
get isPaused() {
|
|
163
|
+
return repeat.isPaused;
|
|
164
|
+
},
|
|
165
|
+
get lastResult() {
|
|
166
|
+
return repeat.result;
|
|
167
|
+
},
|
|
168
|
+
get hasErrored() {
|
|
169
|
+
return !!repeat.error;
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
async getSchemes(config = {}) {
|
|
174
|
+
let schemes = [], promises = [];
|
|
175
|
+
for (let registry of this.config.registries) {
|
|
176
|
+
if (registry.has.schemes) {
|
|
177
|
+
let promise = registry.getSchemes(config).then((results) => {
|
|
178
|
+
for (let scheme of results) {
|
|
179
|
+
scheme.__DETAILSLOADED__ = 1;
|
|
180
|
+
scheme.type = scheme.type || ["http://www.w3.org/2004/02/skos/core#ConceptScheme"];
|
|
181
|
+
let otherScheme = schemes.find((s) => jskos.compare(s, scheme)), prio, otherPrio, override = false;
|
|
182
|
+
if (otherScheme) {
|
|
183
|
+
prio = this.config.registries.indexOf(registry);
|
|
184
|
+
if (prio != -1) {
|
|
185
|
+
prio = this.config.registries.length - prio;
|
|
186
|
+
}
|
|
187
|
+
otherPrio = this.config.registries.indexOf(_.get(otherScheme, "_registry"));
|
|
188
|
+
if (otherPrio != -1) {
|
|
189
|
+
otherPrio = this.config.registries.length - otherPrio;
|
|
190
|
+
}
|
|
191
|
+
let currentHasConcepts = !scheme.concepts ? 0 : scheme.concepts.length == 0 ? -1 : 1;
|
|
192
|
+
let otherHasConcepts = !otherScheme.concepts ? 0 : otherScheme.concepts.length == 0 ? -1 : 1;
|
|
193
|
+
if (currentHasConcepts > otherHasConcepts) {
|
|
194
|
+
override = true;
|
|
195
|
+
} else if (currentHasConcepts < otherHasConcepts) {
|
|
196
|
+
override = false;
|
|
197
|
+
} else {
|
|
198
|
+
override = otherPrio < prio;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
if (!otherScheme || override) {
|
|
202
|
+
if (override) {
|
|
203
|
+
let otherSchemeIndex = schemes.findIndex((s) => jskos.compare(s, otherScheme));
|
|
204
|
+
if (otherSchemeIndex != -1) {
|
|
205
|
+
schemes.splice(otherSchemeIndex, 1);
|
|
206
|
+
}
|
|
207
|
+
scheme = jskos.merge(scheme, otherScheme, { mergeUris: true, skipPaths: ["_registry"] });
|
|
208
|
+
}
|
|
209
|
+
scheme._registry = registry;
|
|
210
|
+
schemes.push(scheme);
|
|
211
|
+
} else {
|
|
212
|
+
let index = schemes.findIndex((s) => jskos.compare(s, scheme));
|
|
213
|
+
if (index != -1) {
|
|
214
|
+
let registry2 = schemes[index]._registry;
|
|
215
|
+
schemes[index] = jskos.merge(schemes[index], _.omit(scheme, ["concepts", "topConcepts"]), { mergeUris: true, skipPaths: ["_registry"] });
|
|
216
|
+
schemes[index]._registry = registry2;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}).catch((error) => {
|
|
221
|
+
console.warn("Couldn't load schemes for registry", registry.uri, error);
|
|
222
|
+
});
|
|
223
|
+
promises.push(promise);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
return Promise.all(promises).then(() => {
|
|
227
|
+
for (let scheme of schemes) {
|
|
228
|
+
if (scheme.concepts && scheme.concepts.length == 0) {
|
|
229
|
+
delete scheme.concepts;
|
|
230
|
+
}
|
|
231
|
+
if (scheme.topConcepts && scheme.topConcepts.length == 0) {
|
|
232
|
+
delete scheme.topConcepts;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
schemes = schemes.filter((scheme) => scheme != null);
|
|
236
|
+
schemes = jskos.sortSchemes(schemes);
|
|
237
|
+
return schemes;
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
registryForScheme(scheme) {
|
|
241
|
+
let registry = scheme._registry;
|
|
242
|
+
if (registry) {
|
|
243
|
+
return registry;
|
|
244
|
+
}
|
|
245
|
+
for (let { type, ...config } of scheme.API || []) {
|
|
246
|
+
const provider = Object.values(providers).find((p) => p.providerType === type);
|
|
247
|
+
if (!provider || !provider._registryConfigForBartocApiConfig) {
|
|
248
|
+
continue;
|
|
249
|
+
}
|
|
250
|
+
const providerName = provider.providerName;
|
|
251
|
+
config.scheme = scheme;
|
|
252
|
+
config = providers[providerName]._registryConfigForBartocApiConfig(config);
|
|
253
|
+
if (!config) {
|
|
254
|
+
continue;
|
|
255
|
+
}
|
|
256
|
+
config.provider = providerName;
|
|
257
|
+
try {
|
|
258
|
+
registry = this.initializeRegistry(config);
|
|
259
|
+
return registry;
|
|
260
|
+
} catch (error) {
|
|
261
|
+
continue;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
return null;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
export {
|
|
268
|
+
CocodaSDK as default
|
|
269
|
+
};
|
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
import jskos from "jskos-tools";
|
|
2
|
+
import * as _ from "../utils/lodash.js";
|
|
3
|
+
import axios from "axios";
|
|
4
|
+
import * as utils from "../utils/index.js";
|
|
5
|
+
import * as errors from "../errors/index.js";
|
|
6
|
+
class BaseProvider {
|
|
7
|
+
constructor(registry = {}) {
|
|
8
|
+
this._jskos = registry;
|
|
9
|
+
this.axios = axios.create({
|
|
10
|
+
timeout: 2e4
|
|
11
|
+
});
|
|
12
|
+
this._path = typeof window !== "undefined" && window.location.pathname;
|
|
13
|
+
this.has = {};
|
|
14
|
+
this._defaultLanguages = "en,de,fr,es,nl,it,fi,pl,ru,cs,jp".split(",");
|
|
15
|
+
this.languages = [];
|
|
16
|
+
this._auth = {
|
|
17
|
+
key: null,
|
|
18
|
+
bearerToken: null
|
|
19
|
+
};
|
|
20
|
+
this._repeating = [];
|
|
21
|
+
this._api = {
|
|
22
|
+
status: registry.status,
|
|
23
|
+
schemes: registry.schemes,
|
|
24
|
+
top: registry.top,
|
|
25
|
+
data: registry.data,
|
|
26
|
+
concepts: registry.concepts,
|
|
27
|
+
narrower: registry.narrower,
|
|
28
|
+
ancestors: registry.ancestors,
|
|
29
|
+
types: registry.types,
|
|
30
|
+
suggest: registry.suggest,
|
|
31
|
+
search: registry.search,
|
|
32
|
+
"voc-suggest": registry["voc-suggest"],
|
|
33
|
+
"voc-search": registry["voc-search"],
|
|
34
|
+
mappings: registry.mappings,
|
|
35
|
+
concordances: registry.concordances,
|
|
36
|
+
annotations: registry.annotations,
|
|
37
|
+
occurrences: registry.occurrences,
|
|
38
|
+
reconcile: registry.reconcile,
|
|
39
|
+
api: registry.api
|
|
40
|
+
};
|
|
41
|
+
this._config = {};
|
|
42
|
+
this.setRetryConfig();
|
|
43
|
+
this.axios.interceptors.request.use((config) => {
|
|
44
|
+
const language = _.uniq([].concat(_.get(config, "params.language", "").split(","), this.languages, this._defaultLanguages).filter((lang) => lang != "")).join(",");
|
|
45
|
+
_.set(config, "params.language", language);
|
|
46
|
+
if (this.has.auth && this._auth.bearerToken && !_.get(config, "headers.Authorization")) {
|
|
47
|
+
_.set(config, "headers.Authorization", `Bearer ${this._auth.bearerToken}`);
|
|
48
|
+
}
|
|
49
|
+
if (config.url.startsWith("http:") && typeof window !== "undefined" && window.location.protocol == "https:") {
|
|
50
|
+
throw new axios.Cancel("Can't call http API from https.");
|
|
51
|
+
}
|
|
52
|
+
return config;
|
|
53
|
+
});
|
|
54
|
+
this.axios.interceptors.response.use(({ data, headers = {}, config = {} }) => {
|
|
55
|
+
data = jskos.normalize(data);
|
|
56
|
+
let url = config.url;
|
|
57
|
+
if (!url.endsWith("?")) {
|
|
58
|
+
url += "?";
|
|
59
|
+
}
|
|
60
|
+
_.forOwn(config.params || {}, (value, key) => {
|
|
61
|
+
url += `${key}=${encodeURIComponent(value)}&`;
|
|
62
|
+
});
|
|
63
|
+
if (_.isArray(data) || _.isObject(data)) {
|
|
64
|
+
let totalCount = parseInt(headers["x-total-count"]);
|
|
65
|
+
if (!isNaN(totalCount)) {
|
|
66
|
+
data._totalCount = totalCount;
|
|
67
|
+
}
|
|
68
|
+
data._url = url;
|
|
69
|
+
}
|
|
70
|
+
return data;
|
|
71
|
+
}, (error) => {
|
|
72
|
+
const count = _.get(error, "config._retryCount", 0);
|
|
73
|
+
const method = _.get(error, "config.method");
|
|
74
|
+
const statusCode = _.get(error, "response.status");
|
|
75
|
+
if (this._retryConfig.methods.includes(method) && this._retryConfig.statusCodes.includes(statusCode) && count < this._retryConfig.count) {
|
|
76
|
+
error.config._retryCount = count + 1;
|
|
77
|
+
if (error.config.data)
|
|
78
|
+
error.config.data = JSON.parse(error.config.data);
|
|
79
|
+
return new Promise((resolve, reject) => {
|
|
80
|
+
setTimeout(() => {
|
|
81
|
+
this.axios(error.config).then(resolve).catch(reject);
|
|
82
|
+
}, (() => {
|
|
83
|
+
const delay = this._retryConfig.delay;
|
|
84
|
+
if (typeof delay === "function") {
|
|
85
|
+
return delay(count);
|
|
86
|
+
}
|
|
87
|
+
return delay;
|
|
88
|
+
})());
|
|
89
|
+
});
|
|
90
|
+
} else {
|
|
91
|
+
return Promise.reject(error);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
const currentRequests = [];
|
|
95
|
+
for (let { method, type } of utils.requestMethods) {
|
|
96
|
+
const existingMethod = this[method] && this[method].bind(this);
|
|
97
|
+
if (!existingMethod) {
|
|
98
|
+
this[method] = () => {
|
|
99
|
+
throw new errors.MethodNotImplementedError({ method });
|
|
100
|
+
};
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
this[method] = (options = {}) => {
|
|
104
|
+
if (options._raw) {
|
|
105
|
+
delete options._raw;
|
|
106
|
+
return existingMethod(options);
|
|
107
|
+
}
|
|
108
|
+
const existingRequest = currentRequests.find((r) => r.method == method && _.isEqual(r.options, options));
|
|
109
|
+
if (existingRequest) {
|
|
110
|
+
return existingRequest.promise;
|
|
111
|
+
}
|
|
112
|
+
let source;
|
|
113
|
+
if (!options.cancelToken) {
|
|
114
|
+
source = this.getCancelTokenSource();
|
|
115
|
+
options.cancelToken = source.token;
|
|
116
|
+
}
|
|
117
|
+
const promise = this.init().then(() => existingMethod(options)).then((result) => {
|
|
118
|
+
if (_.isArray(result) && result._totalCount === void 0) {
|
|
119
|
+
result._totalCount = result.length;
|
|
120
|
+
} else if (_.isObject(result) && result._totalCount === void 0) {
|
|
121
|
+
result._totalCount = 1;
|
|
122
|
+
}
|
|
123
|
+
if (result && type && this[`adjust${type}`]) {
|
|
124
|
+
result = this[`adjust${type}`](result);
|
|
125
|
+
}
|
|
126
|
+
return result;
|
|
127
|
+
}).catch((error) => {
|
|
128
|
+
if (error instanceof errors.CDKError) {
|
|
129
|
+
throw error;
|
|
130
|
+
} else {
|
|
131
|
+
if (error.response) {
|
|
132
|
+
if (error.response.status.toString().startsWith(4)) {
|
|
133
|
+
throw new errors.InvalidRequestError({ relatedError: error, code: error.response.status });
|
|
134
|
+
} else {
|
|
135
|
+
throw new errors.BackendError({ relatedError: error, code: error.response.status });
|
|
136
|
+
}
|
|
137
|
+
} else if (error.request) {
|
|
138
|
+
if (typeof navigator !== "undefined") {
|
|
139
|
+
if (navigator.connection || navigator.mozConnection || navigator.webkitConnection) {
|
|
140
|
+
throw new errors.BackendUnavailableError({ relatedError: error });
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
throw new errors.NetworkError({ relatedError: error });
|
|
144
|
+
} else {
|
|
145
|
+
throw new errors.CDKError({ relatedError: error });
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
if (source) {
|
|
150
|
+
promise.cancel = (...args) => {
|
|
151
|
+
return source.cancel(...args);
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
const request = {
|
|
155
|
+
method,
|
|
156
|
+
options: _.omit(options, ["cancelToken"]),
|
|
157
|
+
promise
|
|
158
|
+
};
|
|
159
|
+
currentRequests.push(request);
|
|
160
|
+
promise.catch(() => {
|
|
161
|
+
}).then(() => currentRequests.splice(currentRequests.indexOf(request), 1));
|
|
162
|
+
return promise;
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
get uri() {
|
|
167
|
+
return this._jskos.uri;
|
|
168
|
+
}
|
|
169
|
+
get notation() {
|
|
170
|
+
return this._jskos.notation;
|
|
171
|
+
}
|
|
172
|
+
get prefLabel() {
|
|
173
|
+
return this._jskos.prefLabel;
|
|
174
|
+
}
|
|
175
|
+
get definition() {
|
|
176
|
+
return this._jskos.definition;
|
|
177
|
+
}
|
|
178
|
+
get schemes() {
|
|
179
|
+
return this._jskos.schemes;
|
|
180
|
+
}
|
|
181
|
+
get excludedSchemes() {
|
|
182
|
+
return this._jskos.excludedSchemes;
|
|
183
|
+
}
|
|
184
|
+
get stored() {
|
|
185
|
+
return this._jskos.stored !== void 0 ? this._jskos.stored : this.constructor.stored;
|
|
186
|
+
}
|
|
187
|
+
async init() {
|
|
188
|
+
if (this._init) {
|
|
189
|
+
return this._init;
|
|
190
|
+
}
|
|
191
|
+
this._init = (async () => {
|
|
192
|
+
this._prepare();
|
|
193
|
+
let status;
|
|
194
|
+
if (_.isString(this._api.status)) {
|
|
195
|
+
try {
|
|
196
|
+
status = await this.axios({
|
|
197
|
+
method: "get",
|
|
198
|
+
url: this._api.status
|
|
199
|
+
});
|
|
200
|
+
} catch (error) {
|
|
201
|
+
if (_.get(error, "response.status") === 404) {
|
|
202
|
+
this._api.status = null;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
} else {
|
|
206
|
+
status = this._api.status;
|
|
207
|
+
}
|
|
208
|
+
if (_.isObject(status) && !_.isEmpty(status)) {
|
|
209
|
+
this._config = status.config || {};
|
|
210
|
+
for (let key of Object.keys(this._api)) {
|
|
211
|
+
if (this._api[key] === void 0) {
|
|
212
|
+
this._api[key] = status[key] || null;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
this._setup();
|
|
217
|
+
})();
|
|
218
|
+
return this._init;
|
|
219
|
+
}
|
|
220
|
+
_prepare() {
|
|
221
|
+
}
|
|
222
|
+
_setup() {
|
|
223
|
+
}
|
|
224
|
+
getCancelTokenSource() {
|
|
225
|
+
return axios.CancelToken.source();
|
|
226
|
+
}
|
|
227
|
+
setAuth({ key = this._auth.key, bearerToken = this._auth.bearerToken }) {
|
|
228
|
+
this._auth.key = key;
|
|
229
|
+
this._auth.bearerToken = bearerToken;
|
|
230
|
+
}
|
|
231
|
+
setRetryConfig(config = {}) {
|
|
232
|
+
this._retryConfig = Object.assign({
|
|
233
|
+
methods: ["get", "head", "options"],
|
|
234
|
+
statusCodes: [401, 403],
|
|
235
|
+
count: 3,
|
|
236
|
+
delay: (count) => {
|
|
237
|
+
return 300 * count;
|
|
238
|
+
}
|
|
239
|
+
}, config);
|
|
240
|
+
}
|
|
241
|
+
isAuthorizedFor({ type, action, user, crossUser }) {
|
|
242
|
+
if (action == "read" && this.has[type] === true) {
|
|
243
|
+
return true;
|
|
244
|
+
}
|
|
245
|
+
if (!this.has[type]) {
|
|
246
|
+
return false;
|
|
247
|
+
}
|
|
248
|
+
const options = _.get(this._config, `${type}.${action}`);
|
|
249
|
+
if (!options) {
|
|
250
|
+
return !!this.has[type][action];
|
|
251
|
+
}
|
|
252
|
+
if (options.auth && (!user || !this._auth.key)) {
|
|
253
|
+
return false;
|
|
254
|
+
}
|
|
255
|
+
if (options.auth && this._auth.key != _.get(this._config, "auth.key")) {
|
|
256
|
+
return false;
|
|
257
|
+
}
|
|
258
|
+
if (options.auth && options.identities) {
|
|
259
|
+
const uris = [user.uri].concat(Object.values(user.identities || {}).map((id) => id.uri)).filter((uri) => uri != null);
|
|
260
|
+
if (_.intersection(uris, options.identities).length == 0) {
|
|
261
|
+
return false;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
if (options.auth && options.identityProviders) {
|
|
265
|
+
const providers = Object.keys(user && user.identities || {});
|
|
266
|
+
if (_.intersection(providers, options.identityProviders).length == 0) {
|
|
267
|
+
return false;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
if (crossUser) {
|
|
271
|
+
return !!options.crossUser;
|
|
272
|
+
}
|
|
273
|
+
return !!this.has[type][action];
|
|
274
|
+
}
|
|
275
|
+
supportsScheme(scheme) {
|
|
276
|
+
if (!scheme) {
|
|
277
|
+
return false;
|
|
278
|
+
}
|
|
279
|
+
let schemes = _.isArray(this.schemes) ? this.schemes : null;
|
|
280
|
+
if (schemes == null && !jskos.isContainedIn(scheme, this.excludedSchemes || [])) {
|
|
281
|
+
return true;
|
|
282
|
+
}
|
|
283
|
+
return jskos.isContainedIn(scheme, schemes);
|
|
284
|
+
}
|
|
285
|
+
adjustConcept(concept) {
|
|
286
|
+
concept._getNarrower = (config) => {
|
|
287
|
+
return this.getNarrower({ ...config, concept });
|
|
288
|
+
};
|
|
289
|
+
concept._getAncestors = (config) => {
|
|
290
|
+
return this.getAncestors({ ...config, concept });
|
|
291
|
+
};
|
|
292
|
+
concept._getDetails = async (config) => {
|
|
293
|
+
return (await this.getConcepts({ ...config, concepts: [concept] }))[0];
|
|
294
|
+
};
|
|
295
|
+
for (let type of ["broader", "narrower", "ancestors"]) {
|
|
296
|
+
if (Array.isArray(concept[type]) && !concept[type].includes(null)) {
|
|
297
|
+
concept[type] = this.adjustConcepts(concept[type]);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
concept._registry = this;
|
|
301
|
+
return concept;
|
|
302
|
+
}
|
|
303
|
+
adjustConcepts(concepts) {
|
|
304
|
+
return utils.withCustomProps(concepts.map((concept) => this.adjustConcept(concept)), concepts);
|
|
305
|
+
}
|
|
306
|
+
adjustRegistries(registries) {
|
|
307
|
+
return registries;
|
|
308
|
+
}
|
|
309
|
+
adjustScheme(scheme) {
|
|
310
|
+
scheme._registry = this.cdk && this.cdk.registryForScheme(scheme) || this;
|
|
311
|
+
if (scheme._registry) {
|
|
312
|
+
scheme._getTop = (config) => {
|
|
313
|
+
return scheme._registry.getTop({ ...config, scheme });
|
|
314
|
+
};
|
|
315
|
+
scheme._getTypes = (config) => {
|
|
316
|
+
return scheme._registry.getTypes({ ...config, scheme });
|
|
317
|
+
};
|
|
318
|
+
scheme._suggest = ({ search, ...config }) => {
|
|
319
|
+
return scheme._registry.suggest({ ...config, search, scheme });
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
return scheme;
|
|
323
|
+
}
|
|
324
|
+
adjustSchemes(schemes) {
|
|
325
|
+
return utils.withCustomProps(schemes.map((scheme) => this.adjustScheme(scheme)), schemes);
|
|
326
|
+
}
|
|
327
|
+
adjustConcordances(concordances) {
|
|
328
|
+
for (let concordance of concordances) {
|
|
329
|
+
concordance._registry = this;
|
|
330
|
+
}
|
|
331
|
+
return concordances;
|
|
332
|
+
}
|
|
333
|
+
adjustMapping(mapping) {
|
|
334
|
+
for (let side of ["from", "to"]) {
|
|
335
|
+
let sideScheme = `${side}Scheme`;
|
|
336
|
+
if (!mapping[sideScheme]) {
|
|
337
|
+
mapping[sideScheme] = _.get(jskos.conceptsOfMapping(mapping, side), "[0].inScheme[0]", null);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
mapping._registry = this;
|
|
341
|
+
if (!mapping.identifier) {
|
|
342
|
+
let identifier = _.get(jskos.addMappingIdentifiers(mapping), "identifier");
|
|
343
|
+
if (identifier) {
|
|
344
|
+
mapping.identifier = identifier;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
return mapping;
|
|
348
|
+
}
|
|
349
|
+
adjustMappings(mappings) {
|
|
350
|
+
return utils.withCustomProps(mappings.map((mapping) => this.adjustMapping(mapping)), mappings);
|
|
351
|
+
}
|
|
352
|
+
async postMappings({ mappings, ...config } = {}) {
|
|
353
|
+
if (!mappings || !mappings.length) {
|
|
354
|
+
throw new errors.InvalidOrMissingParameterError({ parameter: "mappings" });
|
|
355
|
+
}
|
|
356
|
+
return Promise.all(mappings.map((mapping) => this.postMapping({ mapping, ...config, _raw: true })));
|
|
357
|
+
}
|
|
358
|
+
async deleteMappings({ mappings, ...config } = {}) {
|
|
359
|
+
if (!mappings || !mappings.length) {
|
|
360
|
+
throw new errors.InvalidOrMissingParameterError({ parameter: "mappings" });
|
|
361
|
+
}
|
|
362
|
+
return Promise.all(mappings.map((mapping) => this.deleteMapping({ mapping, ...config, _raw: true })));
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
BaseProvider.providerName = "Base";
|
|
366
|
+
export {
|
|
367
|
+
BaseProvider as default
|
|
368
|
+
};
|