cocoda-sdk 3.4.13 → 3.6.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.
@@ -27,8 +27,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
27
27
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
28
 
29
29
  // src/index.js
30
- var src_exports = {};
31
- __export(src_exports, {
30
+ var index_exports = {};
31
+ __export(index_exports, {
32
32
  BaseProvider: () => BaseProvider,
33
33
  CocodaSDK: () => CocodaSDK,
34
34
  ConceptApiProvider: () => ConceptApiProvider,
@@ -37,9 +37,11 @@ __export(src_exports, {
37
37
  LocApiProvider: () => LocApiProvider,
38
38
  LocalMappingsProvider: () => LocalMappingsProvider,
39
39
  MappingsApiProvider: () => MappingsApiProvider,
40
+ ModApiProvider: () => ModApiProvider,
40
41
  MyCoReProvider: () => MyCoReProvider,
41
42
  NoTApiProvider: () => NoTApiProvider,
42
43
  OccurrencesApiProvider: () => OccurrencesApiProvider,
44
+ OlsApiProvider: () => OlsApiProvider,
43
45
  ReconciliationApiProvider: () => ReconciliationApiProvider,
44
46
  SkohubProvider: () => SkohubProvider,
45
47
  SkosmosApiProvider: () => SkosmosApiProvider,
@@ -48,7 +50,7 @@ __export(src_exports, {
48
50
  errors: () => errors_exports,
49
51
  utils: () => utils_exports
50
52
  });
51
- module.exports = __toCommonJS(src_exports);
53
+ module.exports = __toCommonJS(index_exports);
52
54
 
53
55
  // src/errors/index.js
54
56
  var errors_exports = {};
@@ -154,9 +156,11 @@ __export(providers_exports, {
154
156
  LocApiProvider: () => LocApiProvider,
155
157
  LocalMappingsProvider: () => LocalMappingsProvider,
156
158
  MappingsApiProvider: () => MappingsApiProvider,
159
+ ModApiProvider: () => ModApiProvider,
157
160
  MyCoReProvider: () => MyCoReProvider,
158
161
  NoTApiProvider: () => NoTApiProvider,
159
162
  OccurrencesApiProvider: () => OccurrencesApiProvider,
163
+ OlsApiProvider: () => OlsApiProvider,
160
164
  ReconciliationApiProvider: () => ReconciliationApiProvider,
161
165
  SkohubProvider: () => SkohubProvider,
162
166
  SkosmosApiProvider: () => SkosmosApiProvider
@@ -355,7 +359,7 @@ var BaseProvider = class {
355
359
  this._jskos = registry;
356
360
  this.axios = import_axios.default.create({
357
361
  // TODO: Decide on timeout value
358
- timeout: 2e4
362
+ timeout: 2e5
359
363
  });
360
364
  this._path = typeof window !== "undefined" && window.location.pathname;
361
365
  this.has = {};
@@ -500,6 +504,7 @@ var BaseProvider = class {
500
504
  }
501
505
  throw new NetworkError({ relatedError: error });
502
506
  } else {
507
+ console.error(error);
503
508
  throw new CDKError({ relatedError: error });
504
509
  }
505
510
  }
@@ -633,6 +638,34 @@ var BaseProvider = class {
633
638
  }
634
639
  }, config);
635
640
  }
641
+ /**
642
+ * Returns suggestion result in OpenSearch Suggest Format.
643
+ *
644
+ * @param {Object} config
645
+ * @param {string} config.search search string
646
+ * @param {Object} [config.scheme] concept scheme to search in
647
+ * @param {number} [config.limit=100] maximum number of search results (default might be overridden by registry)
648
+ * @param {string[]} [config.types=[]] list of type URIs
649
+ * @returns {Array} result in OpenSearch Suggest Format
650
+ */
651
+ async suggest(config) {
652
+ config._raw = true;
653
+ const concepts = await this.search(config);
654
+ const result = [config.search, [], [], []];
655
+ for (let concept of concepts) {
656
+ const notation = import_jskos_tools.default.notation(concept);
657
+ const label = import_jskos_tools.default.prefLabel(concept);
658
+ result[1].push((notation ? notation + " " : "") + label);
659
+ result[2].push("");
660
+ result[3].push(concept.uri);
661
+ }
662
+ if (concepts._totalCount != void 0) {
663
+ result._totalCount = concepts._totalCount;
664
+ } else {
665
+ result._totalCount = concepts.length;
666
+ }
667
+ return result;
668
+ }
636
669
  /**
637
670
  * Returns whether a user is authorized for a certain request.
638
671
  *
@@ -1894,6 +1927,8 @@ OccurrencesApiProvider.stored = false;
1894
1927
  // src/providers/concept-api-provider.js
1895
1928
  var import_jskos_tools5 = __toESM(require("jskos-tools"), 1);
1896
1929
  var ConceptApiProvider = class extends BaseProvider {
1930
+ static providerName = "ConceptApi";
1931
+ static providerType = "http://bartoc.org/api-type/jskos";
1897
1932
  static supports = {
1898
1933
  schemes: true,
1899
1934
  top: true,
@@ -2075,7 +2110,8 @@ var ConceptApiProvider = class extends BaseProvider {
2075
2110
  * @returns {Object[]} array of JSKOS concept objects
2076
2111
  */
2077
2112
  async getConcepts({ concepts, ...config }) {
2078
- if (this.has.data === false) {
2113
+ const url = this._api.concepts || this._api.data;
2114
+ if (!url) {
2079
2115
  throw new MissingApiUrlError();
2080
2116
  }
2081
2117
  if (!concepts) {
@@ -2088,7 +2124,7 @@ var ConceptApiProvider = class extends BaseProvider {
2088
2124
  return this.axios({
2089
2125
  ...config,
2090
2126
  method: "get",
2091
- url: this._api.data,
2127
+ url,
2092
2128
  params: {
2093
2129
  ...this._defaultParams,
2094
2130
  // ? What should the default limit be?
@@ -2106,24 +2142,29 @@ var ConceptApiProvider = class extends BaseProvider {
2106
2142
  * @returns {Object[]} array of JSKOS concept objects
2107
2143
  */
2108
2144
  async getNarrower({ concept, ...config }) {
2109
- if (!this._api.narrower) {
2110
- throw new MissingApiUrlError();
2111
- }
2112
2145
  if (!concept || !concept.uri) {
2113
2146
  throw new InvalidOrMissingParameterError({ parameter: "concept" });
2114
2147
  }
2115
- return this.axios({
2116
- ...config,
2117
- method: "get",
2118
- url: this._api.narrower,
2119
- params: {
2120
- ...this._defaultParams,
2121
- // ? What should the default limit be?
2122
- limit: 1e4,
2123
- ...config.params || {},
2124
- uri: concept.uri
2125
- }
2126
- });
2148
+ if (this._api.narrower) {
2149
+ return this.axios({
2150
+ ...config,
2151
+ method: "get",
2152
+ url: this._api.narrower,
2153
+ params: {
2154
+ ...this._defaultParams,
2155
+ // ? What should the default limit be?
2156
+ limit: 1e4,
2157
+ ...config.params || {},
2158
+ uri: concept.uri
2159
+ }
2160
+ });
2161
+ } else {
2162
+ const conf2 = { params: {}, ...config };
2163
+ conf2.params.properties = "narrower";
2164
+ const response = await this.getConcepts({ concepts: [concept], ...conf2 });
2165
+ const narrower = response[0]?.narrower || [];
2166
+ return narrower.length ? this.getConcepts({ concepts: narrower, ...config }) : [];
2167
+ }
2127
2168
  }
2128
2169
  /**
2129
2170
  * Returns ancestor concepts for a concept.
@@ -2133,24 +2174,29 @@ var ConceptApiProvider = class extends BaseProvider {
2133
2174
  * @returns {Object[]} array of JSKOS concept objects
2134
2175
  */
2135
2176
  async getAncestors({ concept, ...config }) {
2136
- if (!this._api.ancestors) {
2137
- throw new MissingApiUrlError();
2138
- }
2139
2177
  if (!concept || !concept.uri) {
2140
2178
  throw new InvalidOrMissingParameterError({ parameter: "concept" });
2141
2179
  }
2142
- return this.axios({
2143
- ...config,
2144
- method: "get",
2145
- url: this._api.ancestors,
2146
- params: {
2147
- ...this._defaultParams,
2148
- // ? What should the default limit be?
2149
- limit: 1e4,
2150
- ...config.params || {},
2151
- uri: concept.uri
2152
- }
2153
- });
2180
+ if (this._api.ancestors) {
2181
+ return this.axios({
2182
+ ...config,
2183
+ method: "get",
2184
+ url: this._api.ancestors,
2185
+ params: {
2186
+ ...this._defaultParams,
2187
+ // ? What should the default limit be?
2188
+ limit: 1e4,
2189
+ ...config.params || {},
2190
+ uri: concept.uri
2191
+ }
2192
+ });
2193
+ } else {
2194
+ const conf2 = { params: {}, ...config };
2195
+ conf2.params.properties = "ancestors";
2196
+ const response = await this.getConcepts({ concepts: [concept], ...conf2 });
2197
+ const ancestors = response[0]?.ancestors || [];
2198
+ return ancestors.length ? this.getConcepts({ concepts: ancestors, ...config }) : [];
2199
+ }
2154
2200
  }
2155
2201
  /**
2156
2202
  * Returns suggestion result in OpenSearch Suggest Format.
@@ -2291,8 +2337,6 @@ var ConceptApiProvider = class extends BaseProvider {
2291
2337
  return types;
2292
2338
  }
2293
2339
  };
2294
- ConceptApiProvider.providerName = "ConceptApi";
2295
- ConceptApiProvider.providerType = "http://bartoc.org/api-type/jskos";
2296
2340
 
2297
2341
  // src/providers/reconciliation-api-provider.js
2298
2342
  var import_jskos_tools6 = __toESM(require("jskos-tools"), 1);
@@ -2954,34 +2998,6 @@ var SkosmosApiProvider = class extends BaseProvider {
2954
2998
  const concepts = ancestors.map((c) => this._toJskosConcept(c, { scheme })).filter((c) => c.uri != concept.uri);
2955
2999
  return concepts;
2956
3000
  }
2957
- /**
2958
- * Returns suggestion result in OpenSearch Suggest Format.
2959
- *
2960
- * @param {Object} config
2961
- * @param {string} config.search search string
2962
- * @param {Object} [config.scheme] concept scheme to search in
2963
- * @param {number} [config.limit=100] maximum number of search results (default might be overridden by registry)
2964
- * @param {string[]} [config.types=[]] list of type URIs
2965
- * @returns {Array} result in OpenSearch Suggest Format
2966
- */
2967
- async suggest(config) {
2968
- config._raw = true;
2969
- const concepts = await this.search(config);
2970
- const result = [config.search, [], [], []];
2971
- for (let concept of concepts) {
2972
- const notation = import_jskos_tools8.default.notation(concept);
2973
- const label = import_jskos_tools8.default.prefLabel(concept);
2974
- result[1].push((notation ? notation + " " : "") + label);
2975
- result[2].push("");
2976
- result[3].push(concept.uri);
2977
- }
2978
- if (concepts._totalCount != void 0) {
2979
- result._totalCount = concepts._totalCount;
2980
- } else {
2981
- result._totalCount = concepts.length;
2982
- }
2983
- return result;
2984
- }
2985
3001
  /**
2986
3002
  * Returns concept search results.
2987
3003
  *
@@ -3886,6 +3902,779 @@ var LobidApiProvider = class extends BaseProvider {
3886
3902
  LobidApiProvider.providerName = "LobidApi";
3887
3903
  LobidApiProvider.providerType = "http://bartoc.org/api-type/lobid-gnd";
3888
3904
 
3905
+ // src/providers/mod-api-provider.js
3906
+ var ModApiProvider = class extends BaseProvider {
3907
+ // #### PROPERTIES ####
3908
+ // - providerName (This is how a provider is identified in a "registry" object in field `provider`.)
3909
+ static providerName = "ModApi";
3910
+ // - providerType (Optional BARTOC API type URI. Supported types: https://github.com/gbv/bartoc.org/blob/main/data/bartoc-api-types.concepts.csv, the URI prefix is "http://bartoc.org/api-type/".)
3911
+ static providerType = "http://bartoc.org/en/node/20333";
3912
+ // - supports (Optional object of supported capabilities. The keys should be values from this list: https://github.com/gbv/cocoda-sdk/blob/9145952398d6828004beb395c1d392a4d24e9288/src/utils/index.js#L159-L174; values should be a boolean. `false` values can be left out. They will be used to initialize `this.has` (see below). Alternatively, `this.has` can be filled in `_prepare` or `_setup`.)
3913
+ static supports = {
3914
+ schemes: true,
3915
+ top: false,
3916
+ data: false,
3917
+ concepts: true,
3918
+ narrower: false,
3919
+ ancestors: false,
3920
+ types: false,
3921
+ suggest: false,
3922
+ search: false,
3923
+ auth: false,
3924
+ mappings: false,
3925
+ concordances: false,
3926
+ annotations: false,
3927
+ occurrences: false
3928
+ };
3929
+ // #### CUSTOM METHODS ####
3930
+ /**
3931
+ * Constructs the full API URL for a given endpoint.
3932
+ * @param {Array} parts - Array of api parts (e.g., "[artifacts, <schemeShort>]")
3933
+ * @param {Object} params - An object containing query parameters as key-value pairs.
3934
+ * @returns {string} The full URL. Returns undefined if any part is undefined.
3935
+ * @private
3936
+ */
3937
+ _getApiUrl(parts, params) {
3938
+ let result = this.uri || "";
3939
+ if (result.endsWith("/")) {
3940
+ result = result.slice(0, -1);
3941
+ }
3942
+ for (const part of parts) {
3943
+ if (part) {
3944
+ result += "/" + part;
3945
+ } else {
3946
+ return;
3947
+ }
3948
+ }
3949
+ if (params) {
3950
+ const paramString = Object.keys(params).map((k) => `${k}=${encodeURIComponent(params[k])}`).join("&");
3951
+ result += (result.includes("?") ? "&" : "?") + paramString;
3952
+ }
3953
+ return result;
3954
+ }
3955
+ /*
3956
+ _artefactToJSKOS(artefact) {
3957
+ switch (this._jskos.transformation) {
3958
+ //case "jsonld":
3959
+ // return this._modToJskosJsonLD(artefact)
3960
+ case "manual":
3961
+ return this._modToJskosManual(artefact)
3962
+ default:
3963
+ // If no specific transformation is set, default to JSON-LD conversion
3964
+ return this._modToJskosJsonLD(artefact)
3965
+ }
3966
+ }
3967
+
3968
+ _modToJskosJsonLD(artefact) {
3969
+ if (artefact["@id"]) {
3970
+ delete artefact["@id"]
3971
+ }
3972
+
3973
+ artefact["@context"] = context_mod["@context"]
3974
+
3975
+ return jsonld
3976
+ .expand(artefact)
3977
+ .then((expanded) => jsonld.compact(expanded, context_jskos))
3978
+ .then((compacted) => {
3979
+ jskos.clean(compacted)
3980
+ delete compacted["@context"]
3981
+ for (const key in compacted) {
3982
+ if (compacted[key]?.["@none"]) {
3983
+ compacted[key][this._language] = compacted[key]["@none"]
3984
+ delete compacted[key]["@none"]
3985
+ }
3986
+ }
3987
+ compacted = jskos.clean(compacted)
3988
+ compacted = this._repairJsonLD(compacted)
3989
+
3990
+ return compacted
3991
+ })
3992
+ }
3993
+
3994
+ _repairJsonLD(json){
3995
+ // This function is used to repair the JSON-LD context, translating erroneous keys
3996
+ const map = {
3997
+ narrower: "http://www.w3.org/2004/02/skos/core#narrower",
3998
+ altLabel: "http://www.w3.org/2004/02/skos/core#altLabel",
3999
+ definition: "http://www.w3.org/2004/02/skos/core#definition",
4000
+ }
4001
+
4002
+ for (const key in map) {
4003
+ if (json[map[key]]) {
4004
+ json[key] = json[map[key]]
4005
+ delete json[map[key]]
4006
+ }
4007
+ }
4008
+ return json
4009
+ }
4010
+ */
4011
+ // _modToJskosManual(artefact) {
4012
+ _artefactToJSKOS(artefact) {
4013
+ const lan = artefact.language || this._language || "en";
4014
+ const concept = {};
4015
+ if (artefact.subject) {
4016
+ concept.subject = [artefact.subject];
4017
+ }
4018
+ if (artefact.includedInDataCatalog) {
4019
+ concept.api = [artefact.includedInDataCatalog];
4020
+ }
4021
+ if (artefact["@type"]) {
4022
+ concept["@type"] = artefact["@type"];
4023
+ }
4024
+ if (artefact.type) {
4025
+ concept.type = [artefact.type];
4026
+ }
4027
+ if (artefact.source_name) {
4028
+ concept.notation = [artefact.source_name];
4029
+ }
4030
+ if (artefact.short_form) {
4031
+ if (!concept.notation) {
4032
+ concept.notation = [artefact.short_form];
4033
+ } else {
4034
+ concept.notation.push(artefact.short_form);
4035
+ }
4036
+ }
4037
+ if (artefact.label) {
4038
+ concept.prefLabel = {};
4039
+ concept.prefLabel[lan] = [];
4040
+ concept.prefLabel[lan].push(artefact.label);
4041
+ }
4042
+ if (artefact.synonyms) {
4043
+ concept.altLabel = {};
4044
+ concept.altLabel[lan] = artefact.synonyms;
4045
+ }
4046
+ if (artefact.descriptions) {
4047
+ concept.definition = {};
4048
+ concept.definition[lan] = artefact.descriptions;
4049
+ }
4050
+ if (artefact.language) {
4051
+ concept.languages = artefact.language;
4052
+ }
4053
+ if (artefact["@id"]) {
4054
+ concept.uri = artefact["@id"];
4055
+ }
4056
+ if (artefact.iri) {
4057
+ concept.iri = artefact.iri;
4058
+ }
4059
+ if (artefact.identifier) {
4060
+ concept.identifier = [artefact.identifier];
4061
+ }
4062
+ if (artefact.source) {
4063
+ concept.source = [artefact.source];
4064
+ }
4065
+ if (artefact.source_url) {
4066
+ concept.namespace = artefact.source_url;
4067
+ }
4068
+ if (artefact.landingPage) {
4069
+ concept.url = artefact.landingPage;
4070
+ }
4071
+ if (artefact.version) {
4072
+ concept.version = artefact.version;
4073
+ }
4074
+ if (artefact.modified) {
4075
+ concept.modified = artefact.modified;
4076
+ }
4077
+ if (artefact.created) {
4078
+ concept.created = artefact.created;
4079
+ }
4080
+ if (artefact.hasFormat) {
4081
+ concept.format = artefact.hasFormat;
4082
+ }
4083
+ if (artefact.license) {
4084
+ concept.license = [artefact.license];
4085
+ }
4086
+ if (artefact.creator) {
4087
+ concept.creator = artefact.creator;
4088
+ }
4089
+ if (artefact.contributor) {
4090
+ concept.contributor = {};
4091
+ concept.contributor.prefLabel = {};
4092
+ concept.contributor.prefLabel[lan] = artefact.contributor;
4093
+ }
4094
+ if (artefact.publisher) {
4095
+ concept.publisher = {};
4096
+ concept.publisher[lan] = artefact.publisher;
4097
+ }
4098
+ if (artefact.released) {
4099
+ concept.issued = artefact.released;
4100
+ }
4101
+ if (artefact.children) {
4102
+ concept.narrower = {};
4103
+ concept.narrower[lan] = artefact.children;
4104
+ }
4105
+ return concept;
4106
+ }
4107
+ // #### API REQUESTS ####
4108
+ async _request(url, ..._config) {
4109
+ if (!url) {
4110
+ return;
4111
+ }
4112
+ const result = await this.axios({
4113
+ method: "get",
4114
+ url,
4115
+ headers: {
4116
+ "Content-Type": "application/json",
4117
+ Accept: "application/json"
4118
+ },
4119
+ ..._config
4120
+ });
4121
+ if (!result?._url || Object.keys(result).length != 1) {
4122
+ return result;
4123
+ }
4124
+ }
4125
+ // API REQUESTS SCHEMES
4126
+ async _getSchemesMod() {
4127
+ const url = this._getApiUrl(["artefacts"], null);
4128
+ return await this._request(url);
4129
+ }
4130
+ async _getSchemesModLimit(limit) {
4131
+ const artifacts = await this._getSchemesMod();
4132
+ if (limit && limit > 0) {
4133
+ return artifacts.slice(0, limit);
4134
+ }
4135
+ return artifacts;
4136
+ }
4137
+ async _getSchemeMod(schemeParam) {
4138
+ if (schemeParam.short) {
4139
+ return await this._getSchemeFromShort(schemeParam.short);
4140
+ } else if (schemeParam.uri) {
4141
+ return await this._getSchemeFromUri(schemeParam.uri);
4142
+ }
4143
+ }
4144
+ async _getSchemeFromShort(short) {
4145
+ const url = this._getApiUrl(["artefacts", short], null);
4146
+ return await this._request(url);
4147
+ }
4148
+ async _getSchemeFromUri(uri) {
4149
+ const schemesMod = await this._getSchemesMod();
4150
+ if (!schemesMod) {
4151
+ return;
4152
+ }
4153
+ for (const scheme of await schemesMod) {
4154
+ if (scheme.source == uri || scheme.source_url == uri || scheme.source_name == uri || scheme["@id"] == uri || scheme.iri == uri || scheme.includedInDataCatalog && scheme.includedInDataCatalog.includes(uri)) {
4155
+ return await scheme;
4156
+ }
4157
+ }
4158
+ }
4159
+ // API REQUESTS CONCEPTS
4160
+ async _getConceptsMod(scheme) {
4161
+ let schemeShort = await this._schemeShortFromObj(scheme);
4162
+ if (!schemeShort) {
4163
+ return [];
4164
+ }
4165
+ const url = this._getApiUrl(["artefacts", schemeShort, "resources", "concepts"], null);
4166
+ const pageOne = await this._request(url);
4167
+ if (!pageOne) {
4168
+ return [];
4169
+ }
4170
+ const { page, totalPages, member: conceptsOne } = pageOne;
4171
+ let concepts = [];
4172
+ for (const concept of conceptsOne) {
4173
+ if (concept) {
4174
+ concepts.push(concept);
4175
+ }
4176
+ }
4177
+ for (let p = page + 1; p <= totalPages; p++) {
4178
+ const urlPage = this._getApiUrl(["artefacts", schemeShort, "resources", "concepts"], { page: p });
4179
+ const pageP = await this._request(urlPage);
4180
+ if (!pageP) {
4181
+ break;
4182
+ }
4183
+ const { member: conceptsNew } = pageP;
4184
+ for (const concept of conceptsNew) {
4185
+ if (concept) {
4186
+ concepts.push(concept);
4187
+ }
4188
+ }
4189
+ }
4190
+ return concepts;
4191
+ }
4192
+ async _getConceptsModLimit(scheme, limit) {
4193
+ let concepts = await this._getConceptsMod(scheme);
4194
+ if (limit && limit > 0) {
4195
+ return concepts.slice(0, limit);
4196
+ }
4197
+ return concepts;
4198
+ }
4199
+ async _getConceptMod(concept) {
4200
+ const { conceptNotation, schemeShort } = await this._conceptNotationFromObj(concept);
4201
+ const url = this._getApiUrl(["artefacts", schemeShort, "resources", "concepts", conceptNotation], null);
4202
+ return await this._request(url);
4203
+ }
4204
+ // UTILITIES
4205
+ _containsString(obj, searchString) {
4206
+ for (const key in obj) {
4207
+ const value = obj[key];
4208
+ if (typeof value === "string" && value.includes(searchString)) {
4209
+ return true;
4210
+ }
4211
+ if (typeof value === "object" && value !== null) {
4212
+ if (this.containsString(value, searchString)) {
4213
+ return true;
4214
+ }
4215
+ }
4216
+ }
4217
+ return false;
4218
+ }
4219
+ async _getSchemesContaining(partstring) {
4220
+ let schemes = [];
4221
+ const schemesMod = await this._getSchemesMod();
4222
+ for (const scheme of schemesMod) {
4223
+ if (this.containsString(scheme, partstring)) {
4224
+ schemes.push(scheme);
4225
+ }
4226
+ }
4227
+ return schemes;
4228
+ }
4229
+ async _getSchemeShort(uri) {
4230
+ const schemeMod = await this._getSchemeFromUri(uri);
4231
+ if (schemeMod) {
4232
+ return await schemeMod.short_form.toLowerCase();
4233
+ }
4234
+ }
4235
+ _getconceptNotation(uri) {
4236
+ return uri.split("/").pop();
4237
+ }
4238
+ async _schemeShortFromObj(scheme) {
4239
+ if (scheme.short) {
4240
+ return scheme.short;
4241
+ } else if (scheme.uri) {
4242
+ return await this._getSchemeShort(scheme.uri);
4243
+ }
4244
+ }
4245
+ async _conceptNotationFromObj(concept) {
4246
+ if (!concept.inScheme || !concept.inScheme[0]) {
4247
+ return;
4248
+ }
4249
+ let schemeShort = await this._schemeShortFromObj(concept.inScheme[0]);
4250
+ let conceptNotation = concept.notation;
4251
+ if (!conceptNotation) {
4252
+ conceptNotation = await this._getconceptNotation(concept.uri);
4253
+ }
4254
+ return { conceptNotation, schemeShort };
4255
+ }
4256
+ // #### OVERRIDE METHODS ####
4257
+ /**
4258
+ * will be called before the registry is initialized (i.e. it's `/status` endpoint is queries if necessasry)
4259
+ * @private
4260
+ */
4261
+ _prepare() {
4262
+ }
4263
+ /**
4264
+ * Sets up provider-specific properties.
4265
+ * Enables support for mappings in this provider.
4266
+ * will be called after registry is initialized (i.e. it's `/status` endpoint is queries if necessary), should be used to set properties on this.has and custom preparations
4267
+ * @private
4268
+ */
4269
+ _setup() {
4270
+ }
4271
+ /**
4272
+ * Retrieves all concept schemes from the MOD API.
4273
+ *
4274
+ * @param {Object} [params={}] - Optional parameters for the request.
4275
+ * @returns {Promise<Array>} An array of JSKOS concept schemes.
4276
+ * @async
4277
+ */
4278
+ async getSchemes({ schemes, limit, ..._config }) {
4279
+ let schemes_results = [];
4280
+ let artefacts = [];
4281
+ if (schemes) {
4282
+ for (const s of schemes) {
4283
+ let sc = await this._getSchemeMod(s);
4284
+ if (sc) {
4285
+ artefacts.push(sc);
4286
+ }
4287
+ }
4288
+ } else {
4289
+ artefacts = await this._getSchemesModLimit(limit);
4290
+ }
4291
+ for (const artefact of artefacts) {
4292
+ let scheme = await this._artefactToJSKOS(artefact);
4293
+ if (scheme) {
4294
+ schemes_results.push(scheme);
4295
+ } else {
4296
+ console.warn("JSKOS transformation failed for artefact: ", artefact);
4297
+ }
4298
+ }
4299
+ return schemes_results;
4300
+ }
4301
+ /**
4302
+ * Retrieves all concepts from the MOD API.
4303
+ *
4304
+ * @param {Object} params - The options object.
4305
+ * @param {string[]} params.concepts - List of concept objects to request specific concepts.
4306
+ * @param {string} params.scheme - A scheme object to request concepts from a specific scheme.
4307
+ * @param {number} [params.limit] - Optional limit for results when requesting concepts from a scheme.
4308
+ * @param {Object} [params._config] - Additional config options.
4309
+ * @returns {Promise<Array>} An array of JSKOS concepts.
4310
+ * @async
4311
+ */
4312
+ async getConcepts({ concepts, scheme, limit, ..._config }) {
4313
+ let concept_results = [];
4314
+ if (concepts) {
4315
+ for (const concept of concepts) {
4316
+ let conceptMod = await this._getConceptMod(concept);
4317
+ if (conceptMod) {
4318
+ const concept2 = await this._artefactToJSKOS(conceptMod);
4319
+ if (concept2) {
4320
+ concept_results.push(concept2);
4321
+ } else {
4322
+ console.warn("JSKOS transformation failed for concept: ", conceptMod);
4323
+ }
4324
+ }
4325
+ }
4326
+ } else if (scheme) {
4327
+ const conceptsMod = await this._getConceptsModLimit(scheme, limit);
4328
+ for (const conceptMod of conceptsMod) {
4329
+ const conceptJ = await this._artefactToJSKOS(conceptMod);
4330
+ if (conceptJ) {
4331
+ concept_results.push(conceptJ);
4332
+ } else {
4333
+ console.warn("JSKOS transformation failed for concept: ", conceptMod);
4334
+ }
4335
+ }
4336
+ }
4337
+ return concept_results;
4338
+ }
4339
+ /**
4340
+ * @private
4341
+ */
4342
+ get _language() {
4343
+ return this._jskos.language || this.languages[0] || this._defaultLanguages[0] || "en";
4344
+ }
4345
+ /**
4346
+ * Retrieves an array of mappings.
4347
+ * @returns {Array} An array containing mapping objects.
4348
+ */
4349
+ getMappings() {
4350
+ const mappings = [];
4351
+ return mappings;
4352
+ }
4353
+ };
4354
+
4355
+ // src/providers/ols-api-provider.js
4356
+ var OlsApiProvider = class extends BaseProvider {
4357
+ static providerName = "OlsApi";
4358
+ static providerType = "http://bartoc.org/api-type/ols";
4359
+ static supports = {
4360
+ schemes: true,
4361
+ top: true,
4362
+ data: false,
4363
+ // TODO
4364
+ concepts: true,
4365
+ narrower: true,
4366
+ ancestors: true,
4367
+ types: true,
4368
+ suggest: true,
4369
+ search: true
4370
+ };
4371
+ constructor(config) {
4372
+ super(config);
4373
+ this.endpoint = config.endpoint;
4374
+ }
4375
+ /**
4376
+ * Used by `registryForScheme` (see src/lib/CocodaSDK.js) to determine a provider config for a concept schceme.
4377
+ * TODO: make this obsolete
4378
+ */
4379
+ static _registryConfigForBartocApiConfig({ url } = {}) {
4380
+ if (url) {
4381
+ return { endpoint: url };
4382
+ }
4383
+ }
4384
+ /**
4385
+ * Constructs the full API URL for a given endpoint.
4386
+ */
4387
+ _getApiUrl(parts, params = {}) {
4388
+ const url = this.endpoint + parts.join("/");
4389
+ params = Object.fromEntries(Object.entries(params).filter(([_, v]) => v != null));
4390
+ params = new URLSearchParams(params);
4391
+ return params.size ? `${url}?${params}` : url;
4392
+ }
4393
+ _ontologyToJSKOS(ontology) {
4394
+ const lan = ontology.lang || this._language || "en";
4395
+ const scheme = {};
4396
+ if (ontology.iri) {
4397
+ scheme.uri = ontology.iri;
4398
+ }
4399
+ scheme.type = [
4400
+ "http://www.w3.org/2004/02/skos/core#ConceptScheme"
4401
+ ];
4402
+ if (ontology["http://www.w3.org/1999/02/22-rdf-syntax-ns#type"]) {
4403
+ scheme.type = scheme.type.concat(ontology["http://www.w3.org/1999/02/22-rdf-syntax-ns#type"]);
4404
+ }
4405
+ if (ontology.title) {
4406
+ scheme.prefLabel = {};
4407
+ scheme.prefLabel[lan] = ontology.title;
4408
+ }
4409
+ if (ontology.description) {
4410
+ scheme.definition = {};
4411
+ scheme.definition[lan] = [ontology.description];
4412
+ }
4413
+ if (ontology.homepage) {
4414
+ scheme.url = ontology.homepage;
4415
+ }
4416
+ if (ontology.tracker) {
4417
+ scheme.issueTracker = [{ url: ontology.tracker }];
4418
+ }
4419
+ if (ontology.language) {
4420
+ scheme.languages = ontology.language;
4421
+ }
4422
+ if (ontology.ontologyId) {
4423
+ scheme.VOCID = ontology.ontologyId;
4424
+ scheme.notation = [ontology.ontologyId];
4425
+ }
4426
+ if (ontology.license?.url) {
4427
+ scheme.license = [{ uri: ontology.license.url }];
4428
+ }
4429
+ return scheme;
4430
+ }
4431
+ _termToJSKOS(term) {
4432
+ const lan = term.language || this._language || "en";
4433
+ const concept = {};
4434
+ if (term.curie) {
4435
+ concept.notation = [term.curie];
4436
+ }
4437
+ if (term.hasDirectChildren) {
4438
+ concept.narrower = [null];
4439
+ } else {
4440
+ concept.narrower = [];
4441
+ }
4442
+ if (term.hasDirectParents) {
4443
+ concept.broader = [null];
4444
+ } else {
4445
+ concept.broader = [];
4446
+ }
4447
+ if (term.iri) {
4448
+ concept.uri = term.iri;
4449
+ }
4450
+ if (term["http://www.w3.org/2000/01/rdf-schema#label"]) {
4451
+ concept.prefLabel = {};
4452
+ concept.prefLabel[lan] = term["http://www.w3.org/2000/01/rdf-schema#label"];
4453
+ }
4454
+ concept.type = [
4455
+ "http://www.w3.org/2004/02/skos/core#Concept",
4456
+ // FIXME: properties are no classes
4457
+ "http://www.w3.org/2002/07/owl#Class"
4458
+ ];
4459
+ if (term.ontologyIri) {
4460
+ concept.inScheme = [{ uri: term.ontologyIri }];
4461
+ }
4462
+ return concept;
4463
+ }
4464
+ // #### API REQUESTS ####
4465
+ // TODO: rename _skipAdditionalParameters
4466
+ async _request(url, config = { _skipAdditionalParameters: true }) {
4467
+ if (url) {
4468
+ url = new URL(url);
4469
+ const given = Object.fromEntries(url.searchParams.entries());
4470
+ return this.axios({
4471
+ method: "get",
4472
+ url: url.origin + url.pathname,
4473
+ params: {
4474
+ ...given,
4475
+ ...config.params
4476
+ // explicit params win
4477
+ },
4478
+ ...config
4479
+ });
4480
+ }
4481
+ }
4482
+ // API REQUESTS SCHEMES
4483
+ async _paginate(base, query, limit) {
4484
+ const size = limit > 0 ? limit : null;
4485
+ let url = this._getApiUrl(base, { ...query, size });
4486
+ let page = await this._request(url);
4487
+ let items = page?.elements || [];
4488
+ if (!size) {
4489
+ const totalPages = page?.totalPages || 0;
4490
+ for (let n = 1; n < totalPages; n++) {
4491
+ url = this._getApiUrl(base, { ...query, page: n });
4492
+ page = await this._request(url);
4493
+ items = items.concat(page?.elements || []);
4494
+ }
4495
+ }
4496
+ return items;
4497
+ }
4498
+ // API REQUESTS CONCEPTS
4499
+ async _getConceptOls(concept) {
4500
+ const VOCID = await this._getSchemeVOCID(concept?.inScheme?.[0]);
4501
+ if (VOCID) {
4502
+ let url = null;
4503
+ if (concept.notation) {
4504
+ url = this._getApiUrl(["ontologies", VOCID, "classes"], { curie: concept.notation });
4505
+ } else if (concept.uri) {
4506
+ url = this._getApiUrl(["ontologies", VOCID, "classes"], { iri: concept.uri });
4507
+ }
4508
+ let response = await this._request(url);
4509
+ return response?.elements?.[0] || null;
4510
+ }
4511
+ }
4512
+ async _searchOls(search, scheme, limit, types) {
4513
+ let items = [];
4514
+ const knownTypes = {
4515
+ "http://www.w3.org/2002/07/owl#Class": "classes",
4516
+ "http://www.w3.org/1999/02/22-rdf-syntax-ns#Property": "properties"
4517
+ };
4518
+ if (!types?.length) {
4519
+ types = Object.keys(knownTypes);
4520
+ }
4521
+ for (const type of types) {
4522
+ if (type in knownTypes) {
4523
+ const VOCID = scheme ? await this._getSchemeVOCID(scheme) : null;
4524
+ const query = { search, ontology: VOCID };
4525
+ if (!scheme || VOCID) {
4526
+ const found = await this._paginate([knownTypes[type]], query, limit);
4527
+ items.push(...found);
4528
+ }
4529
+ }
4530
+ }
4531
+ return items;
4532
+ }
4533
+ // UTILITIES
4534
+ async _conceptIriFromObj(VOCID, conceptNotation) {
4535
+ let url = this._getApiUrl(["ontologies", VOCID, "classes"], { curie: conceptNotation });
4536
+ let response = await this._request(url);
4537
+ if (response && response.elements && response.elements.length > 0) {
4538
+ return response.elements[0].iri;
4539
+ }
4540
+ }
4541
+ get _language() {
4542
+ return this._jskos.language || this.languages[0] || this._defaultLanguages[0] || "en";
4543
+ }
4544
+ async _getSchemeVOCID(scheme) {
4545
+ return scheme?.VOCID ? scheme.VOCID : this._getScheme(scheme).then((s) => s?.ontologyId);
4546
+ }
4547
+ async _getScheme(scheme) {
4548
+ if (scheme) {
4549
+ const { VOCID, uri, notation, identifier } = scheme;
4550
+ if (VOCID) {
4551
+ return this._request(this._getApiUrl(["ontologies", VOCID]));
4552
+ }
4553
+ if (uri) {
4554
+ scheme = await this._getSchemeFromUri(uri);
4555
+ if (scheme) {
4556
+ return scheme;
4557
+ }
4558
+ }
4559
+ if (notation?.[0] && (uri || identifier?.length)) {
4560
+ scheme = await this._request(this._getApiUrl(["ontologies", notation[0]]));
4561
+ if (scheme.iri === uri || identifier?.includes(scheme.iri)) {
4562
+ return scheme;
4563
+ }
4564
+ }
4565
+ for (let id of identifier || []) {
4566
+ const found = await this._getSchemeFromUri(id);
4567
+ if (found) {
4568
+ return found;
4569
+ }
4570
+ }
4571
+ }
4572
+ }
4573
+ async _getSchemeFromUri(uri) {
4574
+ if (uri) {
4575
+ const url = this._getApiUrl(["ontologies"], { searchFields: "iri", search: uri });
4576
+ const response = await this._request(url);
4577
+ const schemes = response?.elements || [];
4578
+ return schemes.reduce((short, cur) => cur.ontologyId.length < short.ontologyId.length ? cur : short, schemes[0]);
4579
+ }
4580
+ return null;
4581
+ }
4582
+ // MAIN FUNCTIONS
4583
+ // TODO: query parameter are different: schemes are in "params.uri"?
4584
+ async getSchemes({ schemes, limit }) {
4585
+ let ontologies = [];
4586
+ if (schemes) {
4587
+ ontologies = (await Promise.all(schemes.map((s) => this._getScheme(s)))).filter(Boolean);
4588
+ } else if (limit > 0) {
4589
+ const url = this._getApiUrl(["ontologies"], { size: limit });
4590
+ const response = await this._request(url);
4591
+ ontologies = response.elements || [];
4592
+ } else {
4593
+ ontologies = await this._paginate(["ontologies"], {});
4594
+ }
4595
+ return Promise.all(ontologies.map((scheme) => this._ontologyToJSKOS(scheme)));
4596
+ }
4597
+ async getConcepts({ concepts, scheme, limit }) {
4598
+ let result = [];
4599
+ if (concepts) {
4600
+ for (const concept of concepts) {
4601
+ let item = await this._getConceptOls(concept);
4602
+ if (item) {
4603
+ result.push(await this._termToJSKOS(item));
4604
+ }
4605
+ }
4606
+ } else if (scheme) {
4607
+ const VOCID = await this._getSchemeVOCID(scheme);
4608
+ if (VOCID) {
4609
+ const items = await this._paginate(["ontologies", VOCID, "classes"], {}, limit);
4610
+ result = Promise.all(items.map((item) => this._termToJSKOS(item)));
4611
+ }
4612
+ }
4613
+ return result;
4614
+ }
4615
+ async getTop({ scheme }) {
4616
+ const VOCID = await this._getSchemeVOCID(scheme);
4617
+ if (VOCID) {
4618
+ let url = this._getApiUrl(["ontologies", VOCID, "classes"], { hasDirectParents: "false" });
4619
+ let response = await this._request(url);
4620
+ if (response?.elements) {
4621
+ return Promise.all(response.elements.map((item) => this._termToJSKOS(item)));
4622
+ }
4623
+ }
4624
+ return [];
4625
+ }
4626
+ async _splitConcept(concept) {
4627
+ const obj = {};
4628
+ if (concept) {
4629
+ obj.VOCID = await this._getSchemeVOCID(concept?.inScheme?.[0]);
4630
+ obj.iri = concept.uri || await this._conceptIriFromObj(obj.VOCID, concept.notation);
4631
+ obj.iri = encodeURIComponent(encodeURIComponent(obj.iri));
4632
+ }
4633
+ return obj;
4634
+ }
4635
+ async getNarrower({ concept }) {
4636
+ const { VOCID, iri } = await this._splitConcept(concept);
4637
+ if (VOCID && iri) {
4638
+ let url = this._getApiUrl(["ontologies", VOCID, "classes", iri, "children"]);
4639
+ let response = await this._request(url);
4640
+ if (response?.elements) {
4641
+ return Promise.all(response.elements.map((item) => this._termToJSKOS(item)));
4642
+ }
4643
+ }
4644
+ return [];
4645
+ }
4646
+ async getAncestors({ concept }) {
4647
+ const { VOCID, iri } = await this._splitConcept(concept);
4648
+ if (VOCID && iri) {
4649
+ let url = this._getApiUrl(["ontologies", VOCID, "classes", iri, "ancestors"]);
4650
+ let response = await this._request(url);
4651
+ if (response?.elements) {
4652
+ return Promise.all(response.elements.map((item) => this._termToJSKOS(item)));
4653
+ }
4654
+ }
4655
+ return [];
4656
+ }
4657
+ async getTypes() {
4658
+ return [{
4659
+ uri: "http://www.w3.org/2002/07/owl#Class",
4660
+ prefLabel: {
4661
+ en: "Class",
4662
+ de: "Klasse"
4663
+ }
4664
+ }, {
4665
+ uri: "http://www.w3.org/1999/02/22-rdf-syntax-ns#Property",
4666
+ prefLabel: {
4667
+ en: "Property",
4668
+ de: "Eigenschaft"
4669
+ }
4670
+ }];
4671
+ }
4672
+ async search({ search, scheme = null, limit = 0, types = ["http://www.w3.org/2002/07/owl#Class"] }) {
4673
+ let items = await this._searchOls(search, scheme, limit, types);
4674
+ return Promise.all(items.map((item) => this._termToJSKOS(item)));
4675
+ }
4676
+ };
4677
+
3889
4678
  // src/providers/mycore-provider.js
3890
4679
  var import_jskos_tools12 = __toESM(require("jskos-tools"), 1);
3891
4680
  var import_flexsearch2 = __toESM(require("flexsearch"), 1);
@@ -4688,9 +5477,11 @@ function addAllProviders(_cdk) {
4688
5477
  LocApiProvider,
4689
5478
  LocalMappingsProvider,
4690
5479
  MappingsApiProvider,
5480
+ ModApiProvider,
4691
5481
  MyCoReProvider,
4692
5482
  NoTApiProvider,
4693
5483
  OccurrencesApiProvider,
5484
+ OlsApiProvider,
4694
5485
  ReconciliationApiProvider,
4695
5486
  SkohubProvider,
4696
5487
  SkosmosApiProvider,