cocoda-sdk 2.0.13 → 3.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.
@@ -21,6 +21,7 @@ const providers = {
21
21
  };
22
22
  providers.addProvider(ConceptApiProvider);
23
23
  providers.addProvider(MappingsApiProvider);
24
+ const registryCache = {};
24
25
  class CocodaSDK {
25
26
  constructor(config) {
26
27
  this.config = config;
@@ -173,9 +174,10 @@ class CocodaSDK {
173
174
  async getSchemes(config = {}) {
174
175
  let schemes = [], promises = [];
175
176
  for (let registry of this.config.registries) {
176
- if (registry.has.schemes) {
177
+ if (registry.has.schemes !== false) {
177
178
  let promise = registry.getSchemes(config).then((results) => {
178
179
  for (let scheme of results) {
180
+ const currentSchemeRegistry = scheme._registry;
179
181
  scheme.__DETAILSLOADED__ = 1;
180
182
  scheme.type = scheme.type || ["http://www.w3.org/2004/02/skos/core#ConceptScheme"];
181
183
  let otherScheme = schemes.find((s) => jskos.compare(s, scheme)), prio, otherPrio, override = false;
@@ -206,14 +208,14 @@ class CocodaSDK {
206
208
  }
207
209
  scheme = jskos.merge(scheme, _.omit(otherScheme, ["concepts", "topConcepts"]), { mergeUris: true, skipPaths: ["_registry"] });
208
210
  }
209
- scheme._registry = registry;
211
+ scheme._registry = currentSchemeRegistry;
210
212
  schemes.push(scheme);
211
213
  } else {
212
- let index = schemes.findIndex((s) => jskos.compare(s, scheme));
214
+ const index = schemes.findIndex((s) => jskos.compare(s, scheme));
213
215
  if (index != -1) {
214
- let registry2 = schemes[index]._registry;
216
+ const otherSchemeRegistry = schemes[index]._registry;
215
217
  schemes[index] = jskos.merge(schemes[index], _.omit(scheme, ["concepts", "topConcepts"]), { mergeUris: true, skipPaths: ["_registry"] });
216
- schemes[index]._registry = registry2;
218
+ schemes[index]._registry = otherSchemeRegistry;
217
219
  }
218
220
  }
219
221
  }
@@ -232,22 +234,34 @@ class CocodaSDK {
232
234
  return registry;
233
235
  }
234
236
  for (let { type, ...config } of scheme.API || []) {
235
- const provider = Object.values(providers).find((p) => p.providerType === type);
236
- if (!provider || !provider._registryConfigForBartocApiConfig) {
237
- continue;
238
- }
239
- const providerName = provider.providerName;
240
- config.scheme = scheme;
241
- config = providers[providerName]._registryConfigForBartocApiConfig(config);
242
- if (!config) {
243
- continue;
244
- }
245
- config.provider = providerName;
246
- try {
247
- registry = this.initializeRegistry(config);
248
- return registry;
249
- } catch (error) {
250
- continue;
237
+ const url = config.url;
238
+ if (registryCache[url]) {
239
+ const registry2 = registryCache[url];
240
+ if (Array.isArray(registry2._jskos.schemes) && !jskos.isContainedIn(scheme, registry2._jskos.schemes)) {
241
+ registry2._jskos.schemes.push(scheme);
242
+ }
243
+ return registry2;
244
+ } else {
245
+ const provider = Object.values(providers).find((p) => p.providerType === type);
246
+ if (!provider || !provider._registryConfigForBartocApiConfig) {
247
+ continue;
248
+ }
249
+ const providerName = provider.providerName;
250
+ config.scheme = scheme;
251
+ config = providers[providerName]._registryConfigForBartocApiConfig(config);
252
+ if (!config) {
253
+ continue;
254
+ }
255
+ config.provider = providerName;
256
+ try {
257
+ registry = this.initializeRegistry(config);
258
+ if (registry) {
259
+ registryCache[url] = registry;
260
+ return registry;
261
+ }
262
+ } catch (error) {
263
+ continue;
264
+ }
251
265
  }
252
266
  }
253
267
  return null;
@@ -20,7 +20,7 @@ class BaseProvider {
20
20
  this._repeating = [];
21
21
  this._api = {
22
22
  status: registry.status,
23
- schemes: registry.schemes,
23
+ schemes: Array.isArray(registry.schemes) ? void 0 : registry.schemes,
24
24
  top: registry.top,
25
25
  data: registry.data,
26
26
  concepts: registry.concepts,
@@ -307,7 +307,16 @@ class BaseProvider {
307
307
  return registries;
308
308
  }
309
309
  adjustScheme(scheme) {
310
- scheme._registry = this.cdk && this.cdk.registryForScheme(scheme) || this;
310
+ scheme._registry = this.cdk && this.cdk.registryForScheme(scheme);
311
+ if (!scheme._registry) {
312
+ scheme._registry = this;
313
+ } else {
314
+ ["concepts", "topConcepts"].forEach((key) => {
315
+ if (Array.isArray(scheme[key]) && (scheme[key].length === 0 || scheme[key][0] === null)) {
316
+ delete scheme[key];
317
+ }
318
+ });
319
+ }
311
320
  if (scheme._registry) {
312
321
  scheme._getTop = (config) => {
313
322
  return scheme._registry.getTop({ ...config, scheme });
@@ -18,6 +18,9 @@ class ConceptApiProvider extends BaseProvider {
18
18
  this.has.suggest = true;
19
19
  this.has.search = true;
20
20
  this.has.auth = true;
21
+ utils.listOfCapabilities.filter((c) => !this.has[c]).forEach((c) => {
22
+ this.has[c] = false;
23
+ });
21
24
  }
22
25
  _setup() {
23
26
  if (this._api.api) {
@@ -49,15 +52,16 @@ class ConceptApiProvider extends BaseProvider {
49
52
  this.has.search = !!this._api.search;
50
53
  this.has.auth = _.get(this._config, "auth.key") != null;
51
54
  this._defaultParams = {
52
- properties: "uri,prefLabel,notation,inScheme"
55
+ properties: "+created,issued,modified,editorialNote,scopeNote"
53
56
  };
54
57
  }
55
- static _registryConfigForBartocApiConfig({ url } = {}) {
56
- if (!url) {
58
+ static _registryConfigForBartocApiConfig({ url, scheme } = {}) {
59
+ if (!url || !scheme) {
57
60
  return null;
58
61
  }
59
62
  return {
60
- api: url
63
+ api: url,
64
+ schemes: [scheme]
61
65
  };
62
66
  }
63
67
  async _getSchemeUri(scheme) {
@@ -70,7 +74,9 @@ class ConceptApiProvider extends BaseProvider {
70
74
  if (this._rejectedSchemes.find((s) => jskos.compare(scheme, s))) {
71
75
  return null;
72
76
  }
73
- const schemes = await this.getSchemes({ uri: jskos.getAllUris(scheme) });
77
+ const schemes = await this.getSchemes({ params: {
78
+ uri: jskos.getAllUris(scheme).join("|")
79
+ } });
74
80
  const resultScheme = schemes.find((s) => jskos.compare(s, scheme));
75
81
  if (resultScheme) {
76
82
  this._approvedSchemes.push({
@@ -90,9 +96,6 @@ class ConceptApiProvider extends BaseProvider {
90
96
  if (!this._api.schemes) {
91
97
  throw new errors.MissingApiUrlError();
92
98
  }
93
- if (Array.isArray(this._api.schemes)) {
94
- return this._api.schemes;
95
- }
96
99
  const schemes = await this.axios({
97
100
  ...config,
98
101
  method: "get",
@@ -103,8 +106,8 @@ class ConceptApiProvider extends BaseProvider {
103
106
  ...config.params || {}
104
107
  }
105
108
  });
106
- if (Array.isArray(this._jskos.schemes)) {
107
- return utils.withCustomProps(schemes.filter((s) => jskos.isContainedIn(s, this._jskos.schemes)), schemes);
109
+ if (Array.isArray(this.schemes)) {
110
+ return utils.withCustomProps(schemes.filter((s) => jskos.isContainedIn(s, this.schemes)), schemes);
108
111
  } else {
109
112
  return schemes;
110
113
  }
@@ -136,7 +139,7 @@ class ConceptApiProvider extends BaseProvider {
136
139
  });
137
140
  }
138
141
  async getConcepts({ concepts, ...config }) {
139
- if (!this.has.data) {
142
+ if (this.has.data === false) {
140
143
  throw new errors.MissingApiUrlError();
141
144
  }
142
145
  if (!concepts) {
@@ -196,26 +199,24 @@ class ConceptApiProvider extends BaseProvider {
196
199
  }
197
200
  });
198
201
  }
199
- async suggest({ scheme, use = "notation,label", types = [], sort = "score", ...config }) {
202
+ async suggest({ use = "notation,label", types = [], sort = "score", ...config }) {
200
203
  return this._search({
201
204
  ...config,
202
205
  endpoint: "suggest",
203
206
  params: {
204
207
  ...config.params,
205
- voc: _.get(scheme, "uri", ""),
206
208
  type: types.join("|"),
207
209
  use,
208
210
  sort
209
211
  }
210
212
  });
211
213
  }
212
- async search({ scheme, types = [], ...config }) {
214
+ async search({ types = [], ...config }) {
213
215
  return this._search({
214
216
  ...config,
215
217
  endpoint: "search",
216
218
  params: {
217
219
  ...config.params,
218
- voc: _.get(scheme, "uri", ""),
219
220
  type: types.join("|")
220
221
  }
221
222
  });
@@ -237,7 +238,7 @@ class ConceptApiProvider extends BaseProvider {
237
238
  endpoint: "voc-search"
238
239
  });
239
240
  }
240
- async _search({ endpoint, search, limit, offset, params, ...config }) {
241
+ async _search({ endpoint, scheme, search, limit, offset, params, ...config }) {
241
242
  let url = this._api[endpoint];
242
243
  if (!url) {
243
244
  throw new errors.MissingApiUrlError();
@@ -247,6 +248,7 @@ class ConceptApiProvider extends BaseProvider {
247
248
  }
248
249
  limit = limit || this._jskos.suggestResultLimit || 100;
249
250
  offset = offset || 0;
251
+ const voc = scheme && await this._getSchemeUri(scheme);
250
252
  url = url.replace("{searchTerms}", search);
251
253
  return this.axios({
252
254
  ...config,
@@ -257,7 +259,8 @@ class ConceptApiProvider extends BaseProvider {
257
259
  count: limit,
258
260
  offset,
259
261
  search,
260
- query: search
262
+ query: search,
263
+ voc
261
264
  },
262
265
  method: "get",
263
266
  url
@@ -1,11 +1,15 @@
1
1
  import BaseProvider from "./base-provider.js";
2
2
  import jskos from "jskos-tools";
3
3
  import * as _ from "../utils/lodash.js";
4
+ import { listOfCapabilities } from "../utils/index.js";
4
5
  import * as errors from "../errors/index.js";
5
6
  class LabelSearchSuggestionProvider extends BaseProvider {
6
- _setup() {
7
+ _prepare() {
7
8
  this._cache = [];
8
9
  this.has.mappings = true;
10
+ listOfCapabilities.filter((c) => !this.has[c]).forEach((c) => {
11
+ this.has[c] = false;
12
+ });
9
13
  }
10
14
  supportsScheme(scheme) {
11
15
  return _.get(scheme, "_registry.has.search", false);
@@ -54,6 +58,8 @@ class LabelSearchSuggestionProvider extends BaseProvider {
54
58
  if (!label) {
55
59
  return [];
56
60
  }
61
+ const regexResult = /^[\s\wäüöÄÜÖß]*\w/.exec(label);
62
+ label = regexResult ? regexResult[0] : label;
57
63
  const results = await this._getResults({ ...config, label, targetScheme, limit });
58
64
  let mappings = results.map((result) => ({
59
65
  fromScheme: sourceScheme,
@@ -78,7 +84,7 @@ class LabelSearchSuggestionProvider extends BaseProvider {
78
84
  return resultsFromCache;
79
85
  }
80
86
  const registry = _.get(targetScheme, "_registry");
81
- if (!registry || !registry.has.search) {
87
+ if (!registry || registry.has.search === false) {
82
88
  return [];
83
89
  }
84
90
  const data = await registry.search({
@@ -1,5 +1,6 @@
1
1
  import BaseProvider from "./base-provider.js";
2
2
  import * as errors from "../errors/index.js";
3
+ import { listOfCapabilities } from "../utils/index.js";
3
4
  import jskos from "jskos-tools";
4
5
  import axios from "axios";
5
6
  const locUriPrefix = "http://id.loc.gov/authorities/";
@@ -70,7 +71,7 @@ function madsToJskosConcept(data, { scheme }) {
70
71
  return concept;
71
72
  }
72
73
  class LocApiProvider extends BaseProvider {
73
- _setup() {
74
+ _prepare() {
74
75
  this.has.schemes = true;
75
76
  this.has.top = false;
76
77
  this.has.data = true;
@@ -79,6 +80,9 @@ class LocApiProvider extends BaseProvider {
79
80
  this.has.ancestors = false;
80
81
  this.has.suggest = true;
81
82
  this.has.search = true;
83
+ listOfCapabilities.filter((c) => !this.has[c]).forEach((c) => {
84
+ this.has[c] = false;
85
+ });
82
86
  }
83
87
  static _registryConfigForBartocApiConfig({ scheme } = {}) {
84
88
  if (!scheme || !supportedSchemes.find((s) => jskos.compare(s, scheme))) {
@@ -4,15 +4,21 @@ import * as _ from "../utils/lodash.js";
4
4
  import localforage from "localforage";
5
5
  import { v4 as uuid } from "uuid";
6
6
  import * as errors from "../errors/index.js";
7
+ import { listOfCapabilities } from "../utils/index.js";
7
8
  const uriPrefix = "urn:uuid:";
8
9
  class LocalMappingsProvider extends BaseProvider {
9
- _setup() {
10
+ _prepare() {
10
11
  this.has.mappings = {
11
12
  read: true,
12
13
  create: true,
13
14
  update: true,
14
15
  delete: true
15
16
  };
17
+ listOfCapabilities.filter((c) => !this.has[c]).forEach((c) => {
18
+ this.has[c] = false;
19
+ });
20
+ }
21
+ _setup() {
16
22
  this.queue = [];
17
23
  this.localStorageKey = "cocoda-mappings--" + this._path;
18
24
  let oldLocalStorageKey = "mappings";
@@ -8,6 +8,12 @@ class MappingsApiProvider extends BaseProvider {
8
8
  if (this._api.api && this._api.status === void 0) {
9
9
  this._api.status = utils.concatUrl(this._api.api, "/status");
10
10
  }
11
+ this.has.mappings = true;
12
+ this.has.concordances = true;
13
+ this.has.annotations = true;
14
+ utils.listOfCapabilities.filter((c) => !this.has[c]).forEach((c) => {
15
+ this.has[c] = false;
16
+ });
11
17
  }
12
18
  _setup() {
13
19
  if (this._api.api) {
@@ -4,11 +4,14 @@ import * as _ from "../utils/lodash.js";
4
4
  import * as errors from "../errors/index.js";
5
5
  import * as utils from "../utils/index.js";
6
6
  class OccurrencesApiProvider extends BaseProvider {
7
- _setup() {
7
+ _prepare() {
8
8
  this._cache = [];
9
9
  this._occurrencesSupportedSchemes = [];
10
10
  this.has.occurrences = true;
11
11
  this.has.mappings = true;
12
+ utils.listOfCapabilities.filter((c) => !this.has[c]).forEach((c) => {
13
+ this.has[c] = false;
14
+ });
12
15
  }
13
16
  async _occurrencesIsSupported(scheme) {
14
17
  if (this._occurrencesSupportedSchemes && this._occurrencesSupportedSchemes.length) {
@@ -2,10 +2,14 @@ import BaseProvider from "./base-provider.js";
2
2
  import jskos from "jskos-tools";
3
3
  import * as _ from "../utils/lodash.js";
4
4
  import * as errors from "../errors/index.js";
5
+ import { listOfCapabilities } from "../utils/index.js";
5
6
  class ReconciliationApiProvider extends BaseProvider {
6
- _setup() {
7
- this.has.mappings = true;
7
+ _prepare() {
8
8
  this._cache = [];
9
+ this.has.mappings = true;
10
+ listOfCapabilities.filter((c) => !this.has[c]).forEach((c) => {
11
+ this.has[c] = false;
12
+ });
9
13
  }
10
14
  async getMappings({ from, to, mode, ...config }) {
11
15
  let schemes = [];
@@ -2,8 +2,9 @@ import BaseProvider from "./base-provider.js";
2
2
  import jskos from "jskos-tools";
3
3
  import * as _ from "../utils/lodash.js";
4
4
  import * as errors from "../errors/index.js";
5
+ import { listOfCapabilities } from "../utils/index.js";
5
6
  class SkosmosApiProvider extends BaseProvider {
6
- _setup() {
7
+ _prepare() {
7
8
  this.has.schemes = true;
8
9
  this.has.top = true;
9
10
  this.has.data = true;
@@ -13,6 +14,9 @@ class SkosmosApiProvider extends BaseProvider {
13
14
  this.has.types = true;
14
15
  this.has.suggest = true;
15
16
  this.has.search = true;
17
+ listOfCapabilities.filter((c) => !this.has[c]).forEach((c) => {
18
+ this.has[c] = false;
19
+ });
16
20
  }
17
21
  static _registryConfigForBartocApiConfig({ url, scheme } = {}) {
18
22
  if (!url || !scheme) {
@@ -143,8 +143,25 @@ function withCustomProps(arr, from) {
143
143
  arr._url = from._url;
144
144
  return arr;
145
145
  }
146
+ const listOfCapabilities = [
147
+ "schemes",
148
+ "top",
149
+ "data",
150
+ "concepts",
151
+ "narrower",
152
+ "ancestors",
153
+ "types",
154
+ "suggest",
155
+ "search",
156
+ "auth",
157
+ "mappings",
158
+ "concordances",
159
+ "annotations",
160
+ "occurrences"
161
+ ];
146
162
  export {
147
163
  concatUrl,
164
+ listOfCapabilities,
148
165
  requestMethods,
149
166
  withCustomProps
150
167
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cocoda-sdk",
3
- "version": "2.0.13",
3
+ "version": "3.0.0",
4
4
  "description": "SDK for Cocoda",
5
5
  "main": "dist/cjs/index.cjs",
6
6
  "module": "dist/esm/index.js",