cocoda-sdk 3.6.2 → 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 CHANGED
@@ -11,10 +11,10 @@
11
11
  - [Install](#install)
12
12
  - [Usage](#usage)
13
13
  - [Import](#import)
14
+ - [Multiple Instances](#multiple-instances)
14
15
  - [Configuration](#configuration)
15
- - [Registries](#registries)
16
16
  - [Providers](#providers)
17
- - [Multiple Instances](#multiple-instances)
17
+ - [Services](#services)
18
18
  - [Authenticated Requests](#authenticated-requests)
19
19
  - [API](#api)
20
20
  - [General](#general)
@@ -22,6 +22,7 @@
22
22
  - [Concepts](#concepts)
23
23
  - [Concordances](#concordances)
24
24
  - [Mappings](#mappings)
25
+ - [Registries](#registries)
25
26
  - [Annotations](#annotations)
26
27
  - [Occurrences](#occurrences)
27
28
  - [Types](#types)
@@ -60,6 +61,14 @@ cocoda-sdk also exports some other members:
60
61
  - `addAllProviders` - a method that adds all avaiable providers to an instance
61
62
  - Can be called without parameters to add to the default instance. Useful if you need all providers.
62
63
 
64
+ ### Multiple Instances
65
+
66
+ The `createInstance` method can be used to create a new and independent instance with a separate configuration if needed:
67
+
68
+ ```js
69
+ const newCdk = cdk.createInstance(config)
70
+ ```
71
+
63
72
  ### Configuration
64
73
  cocoda-sdk can be configured after import:
65
74
 
@@ -75,76 +84,9 @@ import { cdk } from "cocoda-sdk"
75
84
  await cdk.loadConfig("https://raw.githubusercontent.com/gbv/cocoda/dev/config/cocoda.default.json")
76
85
  ```
77
86
 
78
- The configuration is a JSON object corresponding the the [configuration format of Cocoda](https://github.com/gbv/cocoda#configuration). In particular, the configuration contains an array property [`registries`](#registries).
79
-
80
- If you only use cocoda-sdk with a single registry, configuration might not be necessary (see below).
81
-
82
- ### Registries
83
-
84
- A registry is an individual source of data, for instance a set of concept schemes available from a specific terminology service. The simplest registry consists only of a unique identifier (`uri`) and the name of the access provider (`provider`):
85
-
86
- ```json
87
- {
88
- "uri": "http://coli-conc.gbv.de/registry/local-mappings",
89
- "provider": "LocalMappings"
90
- }
91
- ```
92
-
93
- For most providers the configuration should use the BARTOC vocabulary API type URI instead:
94
-
95
- ```json
96
- {
97
- "api": "http://bartoc.org/api-type/skosmos",
98
- "endpoint": "https://www.loterre.fr/skosmos/905/"
99
- }
100
- ```
101
-
102
- A list of available providers can be found [below](#providers). Most providers need additional properties to work correctly.
103
-
104
- #### Endpoint Determination
105
- For many providers, you need to specify one or more endpoints on the registry object for it to work. There are, however, three steps in which these endpoints are determined:
106
-
107
- 1. By explicitly specifying an endpoint on the registry object.
108
- 2. By performaning a request to the provider's `/status` endpoint and parsing its result (which is done in `registry.init()`).
109
- 3. By implication using the `api` base URL.
110
-
111
- Values set earlier in these steps will never be overwritten by later steps. That means to disable an endpoint explicitly, you can set it to `null` when configuring the registry. Also, if step 2 is successful, it will be assumed that no further endpoints exist and all missing endpoints will be set to `null`, i.e. essentially skipping step 3.
112
-
113
- #### Using a Single Registry
114
-
115
- If you only have a single registry you want to access, you can initialize it as follows:
116
-
117
- ```js
118
- import { cdk, LocalMappingsProvider } from "cocoda-sdk"
119
- // Local mappings are not included by default
120
- cdk.addProvider(LocalMappingsProvider)
121
- const registry = cdk.initializeRegistry({
122
- uri: "http://coli-conc.gbv.de/registry/local-mappings",
123
- provider: "LocalMappings"
124
- })
125
- // Now, access methods are available on the registry:
126
- registry.getMappings()
127
- ```
128
-
129
- Most Providers can also be initialized with API Type URI from [BARTOC vocabulary API types list](https://bartoc.org/en/node/20002):
130
-
131
- ```js
132
- const registry = cdk.initializeRegistry({
133
- api: "http://bartoc.org/api-type/skosmos",
134
- endpoint: "https://www.loterre.fr/skosmos/905/"
135
- })
136
- ```
137
-
138
- It's also possible to directly use Registry classes.
139
-
140
- #### Using Registries From a Configuration
87
+ The configuration is a JSON object corresponding the the [configuration format of Cocoda](https://github.com/gbv/cocoda#configuration). In particular, the configuration contains an array property `registries` holding a list of [services](#services).
141
88
 
142
- If you initialize cocoda-sdk with a [configuration](#configuration), it will initialize all included registries automatically. Those registries are then accessible via `cdk.config.registries`. Alternatively, you can retrieve registries by URI:
143
-
144
- ```js
145
- // After setting up cdk
146
- const registry = cdk.getRegistryForUri("...")
147
- ```
89
+ If you use cocoda-sdk [with one single service](#using-a-single-service) only, configuration might not be necessary.
148
90
 
149
91
  ### Providers
150
92
 
@@ -166,10 +108,10 @@ The following providers are also exported, but have to be added via `cdk.addProv
166
108
  - `LobidApi` - access to GND via [lobid](https://lobid.org)
167
109
  - **This integration is currently experimental.**
168
110
  - `MyCoRe` - access to vocabularies via [MyCoRe](https://www.mycore.de/)
169
- - **This integration is currently experimental. Only one vocabulary per registry is supported. Not recommended for large vocabularies as all of the vocabulary data is loaded and kept in memory.**
111
+ - **This integration is currently experimental. Only one vocabulary per service is supported. Not recommended for large vocabularies as all of the vocabulary data is loaded and kept in memory.**
170
112
  - `ReconciliationApi` - access to mapping suggestions via a [Reconciliation Service API](https://reconciliation-api.github.io/specs/draft/)
171
113
  - `OccurrencesApi` - access to concept occurrences via [occurrences-api](https://github.com/gbv/occurrences-api) (will be changed to [occurrences-server](https://github.com/gbv/occurrences-server) in the future)
172
- - `LabelSearchSuggestion` - access to mapping suggestions using other registries' search endpoints (using [jskos-server])
114
+ - `LabelSearchSuggestion` - access to mapping suggestions using other services' search endpoints (using [jskos-server])
173
115
  - `ModApi` - (experimental) access to concept schemes and concepts via a [MOD](https://github.com/FAIR-IMPACT/MOD) API
174
116
 
175
117
  To add a provider, append `Provider` to its name and import it together with `cdk`:
@@ -206,12 +148,75 @@ cdk.addProvider(CustomProvider)
206
148
 
207
149
  See [`examples/custom-provider.js`](https://github.com/gbv/cocoda-sdk/blob/main/examples/custom-provider.js) for an extended example.
208
150
 
209
- ### Multiple Instances
151
+ ### Services
210
152
 
211
- The `createInstance` method can be used to create a new and independent instance with a separate configuration if needed:
153
+ *Services have also been called registries until cocoda-sdk 3.7.0 but the name was changed to not confuse with JSKOS Registries!*
154
+
155
+ A service is an individual source of data, for instance a set of concept schemes available from a specific terminology web service.
156
+
157
+ For most providers the service configuration must include an `api` URI from [BARTOC vocabulary API types](http://bartoc.org/en/node/20002):
158
+
159
+ ```json
160
+ {
161
+ "api": "http://bartoc.org/api-type/skosmos",
162
+ "endpoint": "https://www.loterre.fr/skosmos/905/"
163
+ }
164
+ ```
165
+
166
+ Some services can also be configured with the name of the access provider (`provider`) instead:
167
+
168
+ ```json
169
+ {
170
+ "provider": "LocalMappings"
171
+ }
172
+ ```
173
+
174
+ A list of available providers can be found [below](#providers). Most providers need additional properties to work correctly.
175
+
176
+ #### Endpoint Determination
177
+
178
+ For many providers, you need to specify one or more endpoints on the service object for it to work. There are, however, three steps in which these endpoints are determined:
179
+
180
+ 1. By explicitly specifying an endpoint on the service object.
181
+ 2. By performaning a request to the provider's `/status` endpoint and parsing its result (which is done in `service.init()`).
182
+ 3. By implication using the `api` base URL.
183
+
184
+ Values set earlier in these steps will never be overwritten by later steps. That means to disable an endpoint explicitly, you can set it to `null` when configuring the service. Also, if step 2 is successful, it will be assumed that no further endpoints exist and all missing endpoints will be set to `null`, i.e. essentially skipping step 3.
185
+
186
+ #### Using a Single Service
187
+
188
+ If you only have a single service you want to access, you can initialize it as follows:
212
189
 
213
190
  ```js
214
- const newCdk = cdk.createInstance(config)
191
+ import { cdk, LocalMappingsProvider } from "cocoda-sdk"
192
+ // Local mappings are not included by default
193
+ cdk.addProvider(LocalMappingsProvider)
194
+ const service = cdk.initializeRegistry({
195
+ uri: "http://coli-conc.gbv.de/registry/local-mappings",
196
+ provider: "LocalMappings"
197
+ })
198
+ // Now, access methods are available on the service:
199
+ service.getMappings()
200
+ ```
201
+
202
+ Most Providers can also be initialized with API Type URI from [BARTOC vocabulary API types list](https://bartoc.org/en/node/20002):
203
+
204
+ ```js
205
+ const service = cdk.initializeRegistry({
206
+ api: "http://bartoc.org/api-type/skosmos",
207
+ endpoint: "https://www.loterre.fr/skosmos/905/"
208
+ })
209
+ ```
210
+
211
+ It's also possible to directly use Provider classes.
212
+
213
+ #### Using services from a configuration
214
+
215
+ If you initialize cocoda-sdk with a [configuration](#configuration), it will initialize all included services automatically. Those services are then accessible via `cdk.config.registries`. Alternatively, you can retrieve services by URI:
216
+
217
+ ```js
218
+ // After setting up cdk
219
+ const service = cdk.getServiceForUri("...")
215
220
  ```
216
221
 
217
222
  ### Authenticated Requests
@@ -242,14 +247,14 @@ See also the code comments inside the example.
242
247
  <script src="https://cdn.jsdelivr.net/npm/gbv-login-client@0"></script>
243
248
  <script src="https://cdn.jsdelivr.net/npm/cocoda-sdk@2"></script>
244
249
  <script>
245
- // Initialize mapping registry at localhost:3000
246
- const registry = CDK.cdk.initializeRegistry({
250
+ // Initialize mapping service at localhost:3000
251
+ const service = CDK.cdk.initializeRegistry({
247
252
  provider: "MappingsApi",
248
253
  uri: "local:mappings",
249
254
  status: "http://localhost:3000/status",
250
255
  })
251
256
  // Note: This is an async function, so we might be dealing with race conditions here.
252
- registry.init()
257
+ service.init()
253
258
  // Create client to connect to Login Server at localhost:3004
254
259
  let client = new LoginClient("localhost:3004", { ssl: false })
255
260
  let user
@@ -258,26 +263,26 @@ client.addEventListener(null, event => {
258
263
  switch (event.type) {
259
264
  case LoginClient.events.connect:
260
265
  // At this point, we don't know whether the user has logged in yet, but we can try
261
- console.log(registry.isAuthorizedFor({ type: "mappings", action: "create", user }))
266
+ console.log(service.isAuthorizedFor({ type: "mappings", action: "create", user }))
262
267
  break
263
268
  case LoginClient.events.login:
264
269
  // Update user
265
270
  user = event.user
266
271
  // Now we know the user is logged in, so this should return true
267
272
  // Note that if the user is already logged in, this event will fire before connected
268
- console.log(registry.isAuthorizedFor({ type: "mappings", action: "create", user }))
273
+ console.log(service.isAuthorizedFor({ type: "mappings", action: "create", user }))
269
274
  break
270
275
  case LoginClient.events.update:
271
276
  // Update user
272
277
  user = event.user
273
278
  break
274
279
  case LoginClient.events.about:
275
- // Register the server's public key in the registry
276
- registry.setAuth({ key: event.publicKey })
280
+ // Register the server's public key in the service
281
+ service.setAuth({ key: event.publicKey })
277
282
  break
278
283
  case LoginClient.events.token:
279
- // On every token update, update the token in the registry
280
- registry.setAuth({ bearerToken: event.token })
284
+ // On every token update, update the token in the service
285
+ service.setAuth({ bearerToken: event.token })
281
286
  break
282
287
  }
283
288
  })
@@ -291,7 +296,7 @@ client.connect()
291
296
  Note that for a real application, there are more things necessary:
292
297
  - Track whether the client is connected and whether the user is logged in
293
298
  - Tell the user to log in if necessary
294
- - Check if the `registry.init()` call finished before making requests (might not be necessary because requests will wait for initialization)
299
+ - Check if the `init()` call finished before making requests (might not be necessary because requests will wait for initialization)
295
300
  - Error handling
296
301
  - etc.
297
302
 
@@ -303,7 +308,7 @@ You can find more in-depth examples here:
303
308
 
304
309
  ## API
305
310
 
306
- A cocoda-sdk instance itself offers only a handful of methods. The actual access to APIs happens through [registries](#registries). The following list of methods assume either an instance of cocoda-sdk (`cdk.someMethod`) or an initialized registry (`registry.someMethod`). Documentation for registry methods is on a per-provider basis. While the API should be the same for a particular methods across providers, the details on how to use it might differ.
311
+ A cocoda-sdk instance itself offers only a handful of methods. The actual access to APIs happens through [services](#services). The following list of methods assume either an instance of cocoda-sdk (`cdk.someMethod`) or an initialized service (`service.someMethod`). Documentation for service methods is on a per-provider basis. While the API should be the same for a particular methods across providers, the details on how to use it might differ.
307
312
 
308
313
  Please refer to the [documentation](https://gbv.github.io/cocoda-sdk/CocodaSDK.html) for a list of methods of for cocoda-sdk instances.
309
314
 
@@ -429,6 +434,10 @@ Please refer to the [documentation](https://gbv.github.io/cocoda-sdk/CocodaSDK.h
429
434
  #### deleteMappings
430
435
  - [BaseProvider - deleteMappings](https://gbv.github.io/cocoda-sdk/BaseProvider.html#deleteMappings)
431
436
 
437
+ ### Registries
438
+
439
+ - [getRegistries](https://gbv.github.io/cocoda-sdk/ConceptApiProvider.html#getRegistries)
440
+
432
441
  ### Annotations
433
442
 
434
443
  - [getAnnotations](https://gbv.github.io/cocoda-sdk/MappingsApiProvider.html#getAnnotations)
@@ -291,6 +291,7 @@ function withCustomProps(arr, from) {
291
291
  return arr;
292
292
  }
293
293
  var listOfCapabilities = [
294
+ "registries",
294
295
  "schemes",
295
296
  "top",
296
297
  "data",
@@ -398,7 +399,8 @@ var BaseProvider = class {
398
399
  annotations: registry.annotations,
399
400
  occurrences: registry.occurrences,
400
401
  reconcile: registry.reconcile,
401
- api: registry.endpoint || registry.api
402
+ api: registry.endpoint || registry.api,
403
+ registries: registry.registries
402
404
  };
403
405
  this._config = {};
404
406
  this.setRetryConfig();
@@ -1942,7 +1944,8 @@ var ConceptApiProvider = class extends BaseProvider {
1942
1944
  types: true,
1943
1945
  suggest: true,
1944
1946
  search: true,
1945
- auth: true
1947
+ auth: true,
1948
+ registries: true
1946
1949
  };
1947
1950
  /**
1948
1951
  * @private
@@ -1966,7 +1969,8 @@ var ConceptApiProvider = class extends BaseProvider {
1966
1969
  ancestors: "/ancestors",
1967
1970
  types: "/types",
1968
1971
  suggest: "/suggest",
1969
- search: "/search"
1972
+ search: "/search",
1973
+ registries: "/registries"
1970
1974
  };
1971
1975
  for (let key of Object.keys(endpoints)) {
1972
1976
  if (this._api[key] === void 0) {
@@ -1974,6 +1978,7 @@ var ConceptApiProvider = class extends BaseProvider {
1974
1978
  }
1975
1979
  }
1976
1980
  }
1981
+ this.has.registries = !!this._api.registries;
1977
1982
  this.has.schemes = !!this._api.schemes;
1978
1983
  if (!this.has.schemes && Array.isArray(this.schemes)) {
1979
1984
  this.has.schemes = true;
@@ -2041,6 +2046,32 @@ var ConceptApiProvider = class extends BaseProvider {
2041
2046
  return null;
2042
2047
  }
2043
2048
  }
2049
+ /**
2050
+ * Returns all concept registries.
2051
+ *
2052
+ * @param {Object} config
2053
+ * @returns {Object[]} array of JSKOS concept registry objects
2054
+ */
2055
+ async getRegistries(config = {}) {
2056
+ if (!this._api.registries) {
2057
+ if (Array.isArray(this.registries)) {
2058
+ return this.registries;
2059
+ }
2060
+ throw new MissingApiUrlError();
2061
+ }
2062
+ const registries = await this.axios({
2063
+ ...config,
2064
+ method: "get",
2065
+ url: this._api.registries,
2066
+ params: {
2067
+ ...this._defaultParams,
2068
+ // ? What should the default limit be?
2069
+ limit: 500,
2070
+ ...config.params || {}
2071
+ }
2072
+ });
2073
+ return registries;
2074
+ }
2044
2075
  /**
2045
2076
  * Returns all concept schemes.
2046
2077
  *
@@ -2850,18 +2881,16 @@ var SkosmosApiProvider = class extends BaseProvider {
2850
2881
  "skos:changeNote": "changeNote"
2851
2882
  };
2852
2883
  for (let key in map) {
2853
- if (skosmosConcept[key]) {
2854
- const value = skosmosConcept[key];
2855
- if (value.lang && value.value) {
2856
- concept[map[key]] = {
2857
- [value.lang]: value.value
2858
- };
2859
- } else if (Array.isArray(value)) {
2860
- concept[map[key]] = {};
2861
- for (let val of value) {
2862
- if (val.lang && val.value) {
2863
- concept[map[key]][val.lang] = val.value;
2864
- }
2884
+ let notes = skosmosConcept[key] || [];
2885
+ if (!Array.isArray(notes)) {
2886
+ notes = [notes];
2887
+ }
2888
+ if (notes.length) {
2889
+ concept[map[key]] = {};
2890
+ for (const { lang, value } of notes) {
2891
+ if (lang && value) {
2892
+ concept[map[key]][lang] ||= [];
2893
+ concept[map[key]][lang].push(value);
2865
2894
  }
2866
2895
  }
2867
2896
  }
@@ -5229,24 +5258,31 @@ var CocodaSDK = class _CocodaSDK {
5229
5258
  });
5230
5259
  }
5231
5260
  /**
5232
- * Method to get a registry by URI.
5261
+ * Method to get a service by URI.
5233
5262
  *
5234
- * @param {string} uri URI of registry in config
5235
- * @returns {?Object} initialized registry from config if found
5263
+ * @param {string} uri URI of service in config
5264
+ * @returns {?Object} initialized service from config if found
5236
5265
  */
5237
- getRegistryForUri(uri) {
5266
+ getServiceForUri(uri) {
5238
5267
  return this.config.registries.find((r) => r.uri == uri);
5239
5268
  }
5269
+ // alias for backwards compatibility
5270
+ getRegistryForUri(uri) {
5271
+ return this.getRegistryForUri(uri);
5272
+ }
5240
5273
  /**
5241
- * Method to initialize registry.
5274
+ * Method to initialize service.
5242
5275
  *
5243
- * @param {Object} registry JSKOS registry object
5244
- * @returns {Object} initialized registry
5276
+ * @param {Object} service JSKOS service object
5277
+ * @returns {Object} initialized service
5245
5278
  */
5246
- initializeRegistry(registry) {
5247
- registry = providers.init(registry);
5248
- registry.cdk = this;
5249
- return registry;
5279
+ initializeService(service) {
5280
+ service = providers.init(service);
5281
+ service.cdk = this;
5282
+ return service;
5283
+ }
5284
+ initializeRegistry(service) {
5285
+ return this.initializeService(service);
5250
5286
  }
5251
5287
  /**
5252
5288
  * Method to add custom provider.