optimade 1.2.1 → 2.0.4
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/.jshintrc +1 -0
- package/CHANGELOG.md +19 -5
- package/README.md +51 -11
- package/dist/index.d.ts +2 -2
- package/dist/index.js +31 -10
- package/dist/index.mjs +31 -10
- package/dist/prefetched.json +1 -1
- package/dist/providers.json +1 -0
- package/dist/types.d.ts +17 -3
- package/package.json +1 -1
- package/prefetch.js +64 -11
- package/src/index.ts +35 -18
- package/src/types.ts +21 -6
- package/src/utils.ts +1 -1
package/.jshintrc
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"esversion": 6}
|
package/CHANGELOG.md
CHANGED
|
@@ -1,17 +1,31 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Optimade changelog
|
|
2
|
+
|
|
3
|
+
## 2.0.3
|
|
4
|
+
|
|
5
|
+
- Bugfix release
|
|
6
|
+
|
|
7
|
+
## 2.0.0
|
|
8
|
+
|
|
9
|
+
- Add new `npm run prefetch` logic in prefetch.js to check provider avialability,
|
|
10
|
+
cache provider pagination limits in `provider.attributes.query_limits`,
|
|
11
|
+
introduce the sorted and structured providers.json (as source) and prefetched.json (as cache)
|
|
12
|
+
- Add new arguments `getStructures(providerId, filter, page, limit)` for pagination
|
|
13
|
+
and pagination limits
|
|
14
|
+
- Add new logic for catching errors like
|
|
15
|
+
`Error: messageFromProvider { response: { errors, meta } }`
|
|
2
16
|
|
|
3
17
|
## 1.2.1
|
|
4
18
|
|
|
5
|
-
|
|
19
|
+
- Fix providers prefetching
|
|
6
20
|
|
|
7
21
|
## 1.2.0
|
|
8
22
|
|
|
9
|
-
|
|
23
|
+
- Make batch data aggregation is optional to support per-provider progressive data receiving
|
|
10
24
|
|
|
11
25
|
## 1.1.5
|
|
12
26
|
|
|
13
|
-
|
|
27
|
+
- Add http request timeout
|
|
14
28
|
|
|
15
29
|
## 1.0.0
|
|
16
30
|
|
|
17
|
-
|
|
31
|
+
- First release
|
package/README.md
CHANGED
|
@@ -1,26 +1,32 @@
|
|
|
1
1
|
# Aggregating Optimade client for the online materials databases
|
|
2
2
|
|
|
3
|
-
[](https://www.npmjs.com/package/optimade)
|
|
3
|
+
[](https://www.npmjs.com/package/optimade)
|
|
4
|
+
[](https://www.npmjs.com/package/optimade)
|
|
5
|
+
[](https://github.com/tilde-lab/optimade-client/issues)
|
|
4
6
|
|
|
5
7
|
## Features
|
|
6
8
|
|
|
7
9
|
- discovers all the [official Optimade databases](https://providers.optimade.org) recursively
|
|
8
10
|
- caches the discovered list (`prefetched.json`) for future and boosts the retrieval performance
|
|
9
11
|
- queries them all, in the browser, at the server, everywhere
|
|
12
|
+
- provides pagination, with the minimized number of pages
|
|
10
13
|
|
|
11
14
|
## Install
|
|
12
15
|
|
|
13
|
-
```
|
|
16
|
+
```sh
|
|
14
17
|
npm i optimade --save
|
|
15
18
|
```
|
|
16
19
|
|
|
17
|
-
```
|
|
20
|
+
```sh
|
|
18
21
|
yarn add optimade
|
|
19
22
|
```
|
|
20
23
|
|
|
21
|
-
CDN: [UNPKG](https://unpkg.com/optimade/) |
|
|
24
|
+
CDN: [UNPKG](https://unpkg.com/optimade/) |
|
|
25
|
+
[jsDelivr](https://cdn.jsdelivr.net/npm/optimade/) (available as
|
|
26
|
+
`window.optimade`)
|
|
22
27
|
|
|
23
|
-
If you are **not** using
|
|
28
|
+
If you are **not** using ES6 or CDN, add to your HTML just before closing the
|
|
29
|
+
`body` tag:
|
|
24
30
|
|
|
25
31
|
```html
|
|
26
32
|
<script src="/path/to/optimade/dist/index.js"></script>
|
|
@@ -30,10 +36,19 @@ If you are **not** using es6 or CDN, add to your HTML just before closing the `b
|
|
|
30
36
|
|
|
31
37
|
## Usage
|
|
32
38
|
|
|
33
|
-
|
|
39
|
+
The code is generally isomorphic, however one should additionally take care of
|
|
40
|
+
downloading the cache or setting the CORS policy for the browsers. Concerning
|
|
41
|
+
the CORS, the `Optimade` class constructor accepts the `corsProxyUrl` parameter,
|
|
42
|
+
pointing to a running `cors-anywhere` proxy instance. This will be valid
|
|
43
|
+
until all the Optimade providers are supplying the header
|
|
44
|
+
`Access-Control-Allow-Origin $http_origin` in their responses. For the
|
|
45
|
+
server-side environment this is not required.
|
|
34
46
|
|
|
47
|
+
### Discovery and querying
|
|
48
|
+
|
|
49
|
+
```ts
|
|
35
50
|
const optimadeClient = new Optimade({
|
|
36
|
-
|
|
51
|
+
providersUrl: "https://providers.optimade.org/providers.json",
|
|
37
52
|
});
|
|
38
53
|
|
|
39
54
|
console.log(optimadeClient.providers); // { [id: string]: Provider }[]
|
|
@@ -42,13 +57,38 @@ const providersMap = await optimadeClient.getProviders(); // { [id: string]: Pro
|
|
|
42
57
|
|
|
43
58
|
const providerIds = Object.keys(providersMap); // string[]
|
|
44
59
|
|
|
45
|
-
const results = await optimadeClient.getStructuresAll(
|
|
60
|
+
const results = await optimadeClient.getStructuresAll(
|
|
61
|
+
providerIds,
|
|
62
|
+
YOUR_OPTIMADE_QUERY,
|
|
63
|
+
); // [StructuresResponse[], Provider][]
|
|
46
64
|
```
|
|
47
65
|
|
|
48
|
-
Importing depends on your environment. See also the `examples` folder. The
|
|
66
|
+
Importing depends on your environment. See also the `examples` folder. The
|
|
67
|
+
`.html` examples are suited for the browser environment, the `.js` examples are
|
|
68
|
+
suited for the server environment.
|
|
69
|
+
|
|
70
|
+
### Pagination
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
import prefetched from 'optimade/dist/prefetched.json';
|
|
74
|
+
|
|
75
|
+
const optimadeClient = new Optimade({
|
|
76
|
+
providersUrl: "https://providers.optimade.org/providers.json",
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
optimadeClient.providers = prefetched.providers;
|
|
80
|
+
optimadeClient.apis = prefetched.apis;
|
|
81
|
+
|
|
82
|
+
const results = await optimadeClient.getStructuresAll(
|
|
83
|
+
providerIds,
|
|
84
|
+
YOUR_OPTIMADE_QUERY,
|
|
85
|
+
page: number,
|
|
86
|
+
limit: number
|
|
87
|
+
); // [StructuresResponse[], Provider][]
|
|
88
|
+
```
|
|
49
89
|
|
|
50
|
-
|
|
90
|
+
See also the `demo` folder.
|
|
51
91
|
|
|
52
92
|
## License
|
|
53
93
|
|
|
54
|
-
MIT © [
|
|
94
|
+
MIT © [Pavel Malyshev](https://github.com/PaulMaly) and [Alexander Volkov](https://github.com/valexr), Tilde Materials Informatics
|
package/dist/index.d.ts
CHANGED
|
@@ -12,8 +12,8 @@ export declare class Optimade {
|
|
|
12
12
|
});
|
|
13
13
|
getProviders(api?: Types.Api): Promise<Types.ProvidersMap | null>;
|
|
14
14
|
getApis(provider: Types.Provider | string, version?: string): Promise<Types.Api | null>;
|
|
15
|
-
getStructures(providerId: string, filter
|
|
16
|
-
getStructuresAll(providerIds: string[], filter
|
|
15
|
+
getStructures(providerId: string, filter: string, page: number, limit: number): Promise<Types.StructuresResponse[] | Types.ResponseError>;
|
|
16
|
+
getStructuresAll(providerIds: string[], filter: string, page: number, limit: number, batch?: boolean): Promise<Promise<Types.StructuresResult>[]> | Promise<Types.StructuresResult>[];
|
|
17
17
|
private followLinks;
|
|
18
18
|
private wrapUrl;
|
|
19
19
|
private isDuplicatedReq;
|
package/dist/index.js
CHANGED
|
@@ -79,24 +79,44 @@
|
|
|
79
79
|
const apis = await Optimade.getJSON(url);
|
|
80
80
|
return Optimade.apiVersion(apis);
|
|
81
81
|
}
|
|
82
|
-
async getStructures(providerId, filter = '') {
|
|
82
|
+
async getStructures(providerId, filter = '', page = 1, limit) {
|
|
83
83
|
if (!this.apis[providerId])
|
|
84
84
|
return null;
|
|
85
85
|
const apis = this.apis[providerId].filter(api => api.attributes.available_endpoints.includes('structures'));
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
|
|
86
|
+
const provider = this.providers[providerId];
|
|
87
|
+
const structures = await allSettled(apis.map(async (api) => {
|
|
88
|
+
if (page <= 0)
|
|
89
|
+
page = 1;
|
|
90
|
+
const pageLimit = limit ? `&page_limit=${limit}` : '';
|
|
91
|
+
const pageNumber = page ? `&page_number=${page - 1}` : '';
|
|
92
|
+
const pageOffset = limit && page ? `&page_offset=${limit * (page - 1)}` : '';
|
|
93
|
+
const params = filter ? `${pageLimit + pageNumber + pageOffset}` : `?${pageLimit}`;
|
|
94
|
+
const url = this.wrapUrl(Optimade.apiVersionUrl(api), filter ? `/structures?filter=${filter + params}` : `/structures${params}`);
|
|
95
|
+
try {
|
|
96
|
+
return await Optimade.getJSON(url, {}, { Origin: 'https://cors.optimade.science', 'X-Requested-With': 'XMLHttpRequest' });
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
return error;
|
|
100
|
+
}
|
|
89
101
|
}));
|
|
90
102
|
return structures.reduce((structures, structure) => {
|
|
91
|
-
|
|
103
|
+
console.dir(`optimade-client-${providerId}:`, structure);
|
|
104
|
+
if (structure instanceof Error || Object.keys(structure).includes('errors')) {
|
|
105
|
+
return structures.concat(structure);
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
structure.meta.pages = Math.ceil(structure.meta.data_returned / (limit || structure.data.length));
|
|
109
|
+
structure.meta.limits = provider.attributes.query_limits || [10];
|
|
110
|
+
return structures.concat(structure);
|
|
111
|
+
}
|
|
92
112
|
}, []);
|
|
93
113
|
}
|
|
94
|
-
getStructuresAll(providerIds, filter = '', batch = true) {
|
|
114
|
+
getStructuresAll(providerIds, filter = '', page = 1, limit, batch = true) {
|
|
95
115
|
const results = providerIds.reduce((structures, providerId) => {
|
|
96
116
|
const provider = this.providers[providerId];
|
|
97
117
|
if (provider) {
|
|
98
118
|
structures.push(allSettled([
|
|
99
|
-
this.getStructures(providerId, filter),
|
|
119
|
+
this.getStructures(providerId, filter, page, limit),
|
|
100
120
|
Promise.resolve(provider)
|
|
101
121
|
]));
|
|
102
122
|
}
|
|
@@ -125,9 +145,10 @@
|
|
|
125
145
|
}
|
|
126
146
|
const res = await fetchWithTimeout(url.toString(), { headers }, timeout);
|
|
127
147
|
if (!res.ok) {
|
|
128
|
-
const err =
|
|
129
|
-
|
|
130
|
-
|
|
148
|
+
const err = await res.json();
|
|
149
|
+
const error = new Error(err.errors[0].detail);
|
|
150
|
+
error.response = err;
|
|
151
|
+
throw error;
|
|
131
152
|
}
|
|
132
153
|
if (res.status !== 204) {
|
|
133
154
|
return await res.json();
|
package/dist/index.mjs
CHANGED
|
@@ -75,24 +75,44 @@ class Optimade {
|
|
|
75
75
|
const apis = await Optimade.getJSON(url);
|
|
76
76
|
return Optimade.apiVersion(apis);
|
|
77
77
|
}
|
|
78
|
-
async getStructures(providerId, filter = '') {
|
|
78
|
+
async getStructures(providerId, filter = '', page = 1, limit) {
|
|
79
79
|
if (!this.apis[providerId])
|
|
80
80
|
return null;
|
|
81
81
|
const apis = this.apis[providerId].filter(api => api.attributes.available_endpoints.includes('structures'));
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
|
|
82
|
+
const provider = this.providers[providerId];
|
|
83
|
+
const structures = await allSettled(apis.map(async (api) => {
|
|
84
|
+
if (page <= 0)
|
|
85
|
+
page = 1;
|
|
86
|
+
const pageLimit = limit ? `&page_limit=${limit}` : '';
|
|
87
|
+
const pageNumber = page ? `&page_number=${page - 1}` : '';
|
|
88
|
+
const pageOffset = limit && page ? `&page_offset=${limit * (page - 1)}` : '';
|
|
89
|
+
const params = filter ? `${pageLimit + pageNumber + pageOffset}` : `?${pageLimit}`;
|
|
90
|
+
const url = this.wrapUrl(Optimade.apiVersionUrl(api), filter ? `/structures?filter=${filter + params}` : `/structures${params}`);
|
|
91
|
+
try {
|
|
92
|
+
return await Optimade.getJSON(url, {}, { Origin: 'https://cors.optimade.science', 'X-Requested-With': 'XMLHttpRequest' });
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
return error;
|
|
96
|
+
}
|
|
85
97
|
}));
|
|
86
98
|
return structures.reduce((structures, structure) => {
|
|
87
|
-
|
|
99
|
+
console.dir(`optimade-client-${providerId}:`, structure);
|
|
100
|
+
if (structure instanceof Error || Object.keys(structure).includes('errors')) {
|
|
101
|
+
return structures.concat(structure);
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
structure.meta.pages = Math.ceil(structure.meta.data_returned / (limit || structure.data.length));
|
|
105
|
+
structure.meta.limits = provider.attributes.query_limits || [10];
|
|
106
|
+
return structures.concat(structure);
|
|
107
|
+
}
|
|
88
108
|
}, []);
|
|
89
109
|
}
|
|
90
|
-
getStructuresAll(providerIds, filter = '', batch = true) {
|
|
110
|
+
getStructuresAll(providerIds, filter = '', page = 1, limit, batch = true) {
|
|
91
111
|
const results = providerIds.reduce((structures, providerId) => {
|
|
92
112
|
const provider = this.providers[providerId];
|
|
93
113
|
if (provider) {
|
|
94
114
|
structures.push(allSettled([
|
|
95
|
-
this.getStructures(providerId, filter),
|
|
115
|
+
this.getStructures(providerId, filter, page, limit),
|
|
96
116
|
Promise.resolve(provider)
|
|
97
117
|
]));
|
|
98
118
|
}
|
|
@@ -121,9 +141,10 @@ class Optimade {
|
|
|
121
141
|
}
|
|
122
142
|
const res = await fetchWithTimeout(url.toString(), { headers }, timeout);
|
|
123
143
|
if (!res.ok) {
|
|
124
|
-
const err =
|
|
125
|
-
|
|
126
|
-
|
|
144
|
+
const err = await res.json();
|
|
145
|
+
const error = new Error(err.errors[0].detail);
|
|
146
|
+
error.response = err;
|
|
147
|
+
throw error;
|
|
127
148
|
}
|
|
128
149
|
if (res.status !== 204) {
|
|
129
150
|
return await res.json();
|
package/dist/prefetched.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"providers":{"aflow":{"id":"aflow","type":"links","attributes":{"name":"AFLOW","description":"The AFLOW OPTIMADE endpoint","base_url":"http://aflow.org/API/optimade/","homepage":"http://aflow.org","link_type":"child"}},"cod":{"id":"cod","type":"links","attributes":{"name":"Crystallography Open Database","description":"Open-access collection of crystal structures of organic, inorganic, metal-organics compounds and minerals, excluding biopolymers","base_url":"https://www.crystallography.net/cod/optimade","homepage":"https://www.crystallography.net/cod","link_type":"child"}},"sssp":{"id":"sssp","type":"links","attributes":{"name":"Standard solid-state pseudopotentials (SSSP)","description":"It contains data generated from the testing protocol of the standard solid-state pseudopotentials library.\n","base_url":"https://aiida.materialscloud.org/sssplibrary/optimade","homepage":"https://materialscloud.org/explore/sssplibrary","link_type":"child","aggregate":"ok","no_aggregate_reason":null}},"2dstructures":{"id":"2dstructures","type":"links","attributes":{"name":"2D Structures","description":"Two-dimensional (2D) materials from high-throughput computational exfoliation of experimentally known compounds.","base_url":"https://aiida.materialscloud.org/2dstructures/optimade","homepage":"https://materialscloud.org/explore/2dstructures","link_type":"child","aggregate":"ok","no_aggregate_reason":null}},"2dtopo":{"id":"2dtopo","type":"links","attributes":{"name":"2D topological insulators","description":"Quantum spin Hall insulator (QSHI) candidates through DFT band structure calculations of a database with 1825 compounds.","base_url":"https://aiida.materialscloud.org/2dtopo/optimade","homepage":"https://materialscloud.org/explore/2dtopo","link_type":"child","aggregate":"ok","no_aggregate_reason":null}},"tc-applicability":{"id":"tc-applicability","type":"links","attributes":{"name":"Applicability of tail-corrections in the molecular simulations of porous materials","description":"Tail-corrections in molecular simulations for adsorption of gasses in a diverse set of nanoporous crystalline materials (zeolites, Covalent Organic Framworks (COFs), and Metal Organic Frameworks (MOFs)).","base_url":"https://aiida.materialscloud.org/tc-applicability/optimade","homepage":"https://materialscloud.org/explore/tc-applicability","link_type":"child","aggregate":"ok","no_aggregate_reason":null}},"threedd":{"id":"threedd","type":"links","attributes":{"name":"Three-dimensional crystals database","description":"Curated set of relaxed three-dimensional crystal structures based on raw CIF data from the experimantal databases MPDS, COD, and ICSD.","base_url":"https://aiida.materialscloud.org/3dd/optimade","homepage":"https://materialscloud.org/explore/3dd","link_type":"child","aggregate":"ok","no_aggregate_reason":null}},"scdm":{"id":"scdm","type":"links","attributes":{"name":"Automated high-throughput Wannierisation","description":"Validation results of an automated protocol for generating maximally-localized Wannier functions in a high-throughput framework.","base_url":"https://aiida.materialscloud.org/autowannier/optimade","homepage":"https://materialscloud.org/explore/autowannier","link_type":"child","aggregate":"ok","no_aggregate_reason":null}},"curated-cofs":{"id":"curated-cofs","type":"links","attributes":{"name":"CURATED covalent organic frameworks database","description":"Database of experimentally reported Covalent-Organic Frameworks (COFs), provided with DFT-optimized geometry and DDEC partial charges for molecular simulations.","base_url":"https://aiida.materialscloud.org/curated-cofs/optimade","homepage":"https://materialscloud.org/discover/curated-cofs","link_type":"child","aggregate":"ok","no_aggregate_reason":null}},"optimade-sample":{"id":"optimade-sample","type":"links","attributes":{"name":"OPTIMADE Sample Database","description":"Database with example structures for OPTIMADE tests.","base_url":"https://aiida.materialscloud.org/optimade-sample/optimade","homepage":"https://materialscloud.org/explore/optimade-sample","link_type":"child","aggregate":"test","no_aggregate_reason":null}},"stoceriaitf":{"id":"stoceriaitf","type":"links","attributes":{"name":"SrTiO3-CeO2 interfaces","description":"Refining random structure searching results of SrTiO3-CeO2 interfaces, and exploring how it can affect ionic conduction. Candidate structures of the DFT validation calculations.","base_url":"https://aiida.materialscloud.org/stoceriaitf/optimade","homepage":"https://materialscloud.org/explore/stoceriaitf","link_type":"child","aggregate":"ok","no_aggregate_reason":null}},"pyrene-mofs":{"id":"pyrene-mofs","type":"links","attributes":{"name":"Pyrene MOFs","description":"Pyrene Metal Organic Frameworks (MOFs).","base_url":"https://aiida.materialscloud.org/pyrene-mofs/optimade","homepage":"https://materialscloud.org/discover/pyrene-mofs","link_type":"child","aggregate":"ok","no_aggregate_reason":null}},"li-ion-conductors":{"id":"li-ion-conductors","type":"links","attributes":{"name":"Solid-state Li-ion conductors.","description":"High-throughput computational screening study for solid-state Li-ion conductors.","base_url":"https://aiida.materialscloud.org/li-ion-conductors/optimade","homepage":"https://materialscloud.org/explore/li-ion-conductors","link_type":"child","aggregate":"staging","no_aggregate_reason":null}},"tin-antimony-sulfoiodide":{"id":"tin-antimony-sulfoiodide","type":"links","attributes":{"name":"Hidden spontaneous polarisation in the chalcohalide photovoltaic Sn2SbS2I3","description":"Structural, dynamic and electronic characterisation of a novel mixed-metal chalcohalide revealing hidden symmetry breaking and spontaneous polarisation.","base_url":"https://aiida.materialscloud.org/tin-antimony-sulfoiodide/optimade","homepage":"https://materialscloud.org/explore/tin-antimony-sulfoiodide","link_type":"child","aggregate":"ok","no_aggregate_reason":null}},"mp":{"id":"mp","type":"links","attributes":{"name":"The Materials Project","description":"The Materials Project OPTIMADE endpoint","base_url":"https://optimade.materialsproject.org","homepage":"https://www.materialsproject.org","link_type":"child"}},"mpds":{"id":"mpds","type":"links","attributes":{"name":"Materials Platform for Data Science","description":"A highly curated Pauling File dataset based on ~0.5M publications and backing up Springer Materials, ICDD PDF, ASM APD, MedeA, Pearson Crystal Data, AtomWork Advanced, etc.","base_url":"https://api.mpds.io","homepage":"https://mpds.io","link_type":"child"}},"nmd":{"id":"nmd","type":"links","attributes":{"name":"novel materials discovery (NOMAD)","description":"A FAIR data sharing platform for materials science data","base_url":"https://nomad-lab.eu/prod/rae/optimade/","homepage":"https://nomad-lab.eu","link_type":"child"}},"odbx":{"id":"odbx","type":"links","attributes":{"name":"odbx","description":"The Open Database of Xtals is run by the group of Dr Andrew Morris at the universities of Birmingham and Cambridge and is constructed using the matador library.","base_url":"https://optimade.odbx.science","homepage":"https://odbx.science","link_type":"child","aggregate":"ok","no_aggregate_reason":null}},"omdb_production":{"id":"omdb_production","type":"links","attributes":{"name":"Open Materials Database (omdb) production database","description":"This is the main production version of the Open Materials Database","base_url":"http://optimade.openmaterialsdb.se","homepage":"http://openmaterialsdb.se","link_type":"child"}},"oqmd":{"id":"oqmd","type":"links","attributes":{"name":"The OQMD","description":"The Open Quantum Materials Database endpoint","base_url":"http://oqmd.org/optimade/","homepage":"http://oqmd.org","link_type":"child"}},"jarvis":{"id":"jarvis","type":"links","attributes":{"name":"JARVIS-DFT","description":"JARVIS-DFT is a materials property repository focused on density functional theory (DFT) predictions of material properties, especially for crystalline materials.","base_url":"https://jarvis.nist.gov/optimade/jarvisdft","homepage":"https://jarvis.nist.gov","link_type":"child"}},"tcod":{"id":"tcod","type":"links","attributes":{"name":"Theoretical Crystallography Open Database","description":"Open-access collection of theoretically calculated or refined crystal structures of organic, inorganic, metal-organic compounds and minerals, excluding biopolymers","base_url":"https://www.crystallography.net/tcod/optimade","homepage":"https://www.crystallography.net/tcod","link_type":"child"}},"twodmatpedia":{"id":"twodmatpedia","type":"links","attributes":{"name":"2DMatpedia","description":"2DMatpedia, an open computational database of two-dimensional materials from top-down and bottom-up approaches","base_url":"http://optimade.2dmatpedia.org","homepage":"http://2dmatpedia.org","link_type":"child"}}},"apis":{"aflow":[{"type":"info","id":"/","attributes":{"api_version":"1.0.0","available_api_versions":[{"url":"http://aflow.org/API/optimade/v0.9/","version":"0.9.0"},{"url":"http://aflow.org/API/optimade/v1.0/","version":"1.0.0"},{"url":"http://aflow.org/API/optimade/v1.1/","version":"1.1.0"}],"formats":["json"],"entry_types_by_format":{"json":["structures","calculations"]},"available_endpoints":["structures","calculations","info","links"]},"is_index":false}],"optimade-providers":[],"cod":[{"attributes":{"api_version":"1.0.0","available_api_versions":[{"url":"https://www.crystallography.net/cod/optimade/v1.0.0/","version":"1.0.0"}],"available_endpoints":["structures","info"],"entry_types_by_format":{"json":["structures"]},"formats":["json"]},"id":"/","type":"info"}],"exmpl":[],"matcloud":[],"mcloud":[],"index":[],"sssp":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://aiida.materialscloud.org/sssplibrary/optimade/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","extensions/docs","extensions/redoc","extensions/openapi.json","structures"],"entry_types_by_format":{"json":["structures"]},"is_index":false}}],"2dstructures":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://aiida.materialscloud.org/2dstructures/optimade/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","extensions/docs","extensions/redoc","extensions/openapi.json","structures"],"entry_types_by_format":{"json":["structures"]},"is_index":false}}],"2dtopo":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://aiida.materialscloud.org/2dtopo/optimade/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","extensions/docs","extensions/redoc","extensions/openapi.json","structures"],"entry_types_by_format":{"json":["structures"]},"is_index":false}}],"tc-applicability":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://aiida.materialscloud.org/tc-applicability/optimade/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","extensions/docs","extensions/redoc","extensions/openapi.json","structures"],"entry_types_by_format":{"json":["structures"]},"is_index":false}}],"threedd":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://aiida.materialscloud.org/3dd/optimade/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","extensions/docs","extensions/redoc","extensions/openapi.json","structures"],"entry_types_by_format":{"json":["structures"]},"is_index":false}}],"scdm":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://aiida.materialscloud.org/autowannier/optimade/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","extensions/docs","extensions/redoc","extensions/openapi.json","structures"],"entry_types_by_format":{"json":["structures"]},"is_index":false}}],"curated-cofs":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://aiida.materialscloud.org/curated-cofs/optimade/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","extensions/docs","extensions/redoc","extensions/openapi.json","structures"],"entry_types_by_format":{"json":["structures"]},"is_index":false}}],"optimade-sample":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://aiida.materialscloud.org/optimade-sample/optimade/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","extensions/docs","extensions/redoc","extensions/openapi.json","structures"],"entry_types_by_format":{"json":["structures"]},"is_index":false}}],"stoceriaitf":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://aiida.materialscloud.org/stoceriaitf/optimade/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","extensions/docs","extensions/redoc","extensions/openapi.json","structures"],"entry_types_by_format":{"json":["structures"]},"is_index":false}}],"pyrene-mofs":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://aiida.materialscloud.org/pyrene-mofs/optimade/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","extensions/docs","extensions/redoc","extensions/openapi.json","structures"],"entry_types_by_format":{"json":["structures"]},"is_index":false}}],"li-ion-conductors":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://aiida.materialscloud.org/li-ion-conductors/optimade/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","extensions/docs","extensions/redoc","extensions/openapi.json","structures"],"entry_types_by_format":{"json":["structures"]},"is_index":false}}],"tin-antimony-sulfoiodide":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://aiida.materialscloud.org/tin-antimony-sulfoiodide/optimade/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","extensions/docs","extensions/redoc","extensions/openapi.json","structures"],"entry_types_by_format":{"json":["structures"]},"is_index":false}}],"mp":[{"id":"/","type":"info","attributes":{"api_version":"1.0.1","available_api_versions":[{"url":"http://optimade.materialsproject.org/v1","version":"1.0.1"}],"formats":["json"],"available_endpoints":["info","links","structures","references"],"entry_types_by_format":{"json":["structures","references"]},"is_index":false}}],"mpds":[{"type":"info","attributes":{"api_version":"1.0.0","available_api_versions":[{"url":"https://api.mpds.io/v1","version":"1.0.0"}],"available_endpoints":["info","links","structures","extensions/properties","extensions/phase_diagrams","extensions/phases"],"formats":["json"],"entry_types_by_format":{"json":["info","links","structures","extensions/properties","extensions/phase_diagrams","extensions/phases"]}}}],"necro":[],"nmd":[{"id":"/","type":"info","attributes":{"api_version":"1.0.1","available_api_versions":[{"url":"https://nomad-lab.eu/prod/rae/optimade/v1","version":"1.0.1"}],"formats":["json"],"available_endpoints":["info","links","structures","references"],"entry_types_by_format":{"json":["structures","references"]},"is_index":false}}],"odbx":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://optimade.odbx.science/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","structures","references"],"entry_types_by_format":{"json":["structures","references"]},"is_index":false}}],"omdb":[],"omdb_production":[{"attributes":{"api_version":"1.0.0","available_api_versions":[{"url":"http://optimade.openmaterialsdb.se/v1","version":"1.0.0"},{"url":"http://optimade.openmaterialsdb.se/v1.0.0","version":"1.0.0"},{"url":"http://optimade.openmaterialsdb.se/v1.0","version":"1.0.0"}],"available_endpoints":["info","links","structures"],"entry_types_by_format":{"json":["structures"]},"formats":["json"],"is_index":false},"id":"/","type":"info"}],"oqmd":[{"type":"info","id":"/","attributes":{"api_version":"1.0.0","available_api_versions":[{"url":"http://oqmd.org/optimade/v1/","version":"1.0.0"}],"formats":["json","xml","yaml"],"entry_types_by_format":{"json":["structures"],"xml":["structures"],"yaml":["structures"]},"available_endpoints":["structures","info","links","versions"],"is_index":false}}],"jarvis":[{"type":"info","id":"/","attributes":{"api_version":"1.0.0","available_api_versions":[{"url":"https://jarvis.nist.gov/optimade/jarvisdft/v1","version":"1.0.0"}],"formats":["json","xml","yaml"],"entry_types_by_format":{"json":["structures"],"xml":["structures"],"yaml":["structures"]},"available_endpoints":["structures","info","links","versions"],"is_index":false}}],"tcod":[{"attributes":{"api_version":"1.0.0","available_api_versions":[{"url":"https://www.crystallography.net/tcod/optimade/v1.0.0/","version":"1.0.0"}],"available_endpoints":["structures","info"],"entry_types_by_format":{"json":["structures"]},"formats":["json"]},"id":"/","type":"info"}],"twodmatpedia":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"http://optimade.2dmatpedia.org/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","structures","references"],"entry_types_by_format":{"json":["structures","references"]},"is_index":false}}]}}
|
|
1
|
+
{"providers":{"2dstructures":{"id":"2dstructures","type":"links","attributes":{"name":"2D Structures","description":"Two-dimensional (2D) materials from high-throughput computational exfoliation of experimentally known compounds.","base_url":"https://aiida.materialscloud.org/2dstructures/optimade","homepage":"https://materialscloud.org/explore/2dstructures","link_type":"child","aggregate":"ok","no_aggregate_reason":null,"api_version":"1.1.0","query_limits":[100]}},"2dtopo":{"id":"2dtopo","type":"links","attributes":{"name":"2D topological insulators","description":"Quantum spin Hall insulator (QSHI) candidates through DFT band structure calculations of a database with 1825 compounds.","base_url":"https://aiida.materialscloud.org/2dtopo/optimade","homepage":"https://materialscloud.org/explore/2dtopo","link_type":"child","aggregate":"ok","no_aggregate_reason":null,"api_version":"1.1.0","query_limits":[100]}},"cod":{"id":"cod","type":"links","attributes":{"name":"Crystallography Open Database","description":"Open-access collection of crystal structures of organic, inorganic, metal-organics compounds and minerals, excluding biopolymers","base_url":"https://www.crystallography.net/cod/optimade","homepage":"https://www.crystallography.net/cod","link_type":"child","api_version":"1.0.0","query_limits":[10]}},"curated-cofs":{"id":"curated-cofs","type":"links","attributes":{"name":"CURATED covalent organic frameworks database","description":"Database of experimentally reported Covalent-Organic Frameworks (COFs), provided with DFT-optimized geometry and DDEC partial charges for molecular simulations.","base_url":"https://aiida.materialscloud.org/curated-cofs/optimade","homepage":"https://materialscloud.org/discover/curated-cofs","link_type":"child","aggregate":"ok","no_aggregate_reason":null,"api_version":"1.1.0","query_limits":[100]}},"li-ion-conductors":{"id":"li-ion-conductors","type":"links","attributes":{"name":"Solid-state Li-ion conductors.","description":"High-throughput computational screening study for solid-state Li-ion conductors.","base_url":"https://aiida.materialscloud.org/li-ion-conductors/optimade","homepage":"https://materialscloud.org/explore/li-ion-conductors","link_type":"child","aggregate":"staging","no_aggregate_reason":null,"api_version":"1.1.0","query_limits":[100]}},"mp":{"id":"mp","type":"links","attributes":{"name":"The Materials Project","description":"The Materials Project OPTIMADE endpoint","base_url":"https://optimade.materialsproject.org","homepage":"https://www.materialsproject.org","link_type":"child","api_version":"1.0.1","query_limits":[500]}},"mpds":{"id":"mpds","type":"links","attributes":{"name":"Materials Platform for Data Science","description":"A highly curated Pauling File dataset based on ~0.5M publications and backing up Springer Materials, ICDD PDF, ASM APD, MedeA, Pearson Crystal Data, AtomWork Advanced, etc.","base_url":"https://api.mpds.io","homepage":"https://mpds.io","link_type":"child","api_version":"1.0.0","query_limits":[5,10,100,750]}},"nmd":{"id":"nmd","type":"links","attributes":{"name":"novel materials discovery (NOMAD)","description":"A FAIR data sharing platform for materials science data","base_url":"https://nomad-lab.eu/prod/rae/optimade/","homepage":"https://nomad-lab.eu","link_type":"child","api_version":"1.0.1","query_limits":[500]}},"odbx":{"id":"odbx","type":"links","attributes":{"name":"odbx","description":"The Open Database of Xtals is run by the group of Dr Andrew Morris at the universities of Birmingham and Cambridge and is constructed using the matador library.","base_url":"https://optimade.odbx.science","homepage":"https://odbx.science","link_type":"child","aggregate":"ok","no_aggregate_reason":null,"api_version":"1.1.0","query_limits":[500]}},"optimade-sample":{"id":"optimade-sample","type":"links","attributes":{"name":"OPTIMADE Sample Database","description":"Database with example structures for OPTIMADE tests.","base_url":"https://aiida.materialscloud.org/optimade-sample/optimade","homepage":"https://materialscloud.org/explore/optimade-sample","link_type":"child","aggregate":"test","no_aggregate_reason":null,"api_version":"1.1.0","query_limits":[100]}},"pyrene-mofs":{"id":"pyrene-mofs","type":"links","attributes":{"name":"Pyrene MOFs","description":"Pyrene Metal Organic Frameworks (MOFs).","base_url":"https://aiida.materialscloud.org/pyrene-mofs/optimade","homepage":"https://materialscloud.org/discover/pyrene-mofs","link_type":"child","aggregate":"ok","no_aggregate_reason":null,"api_version":"1.1.0","query_limits":[100]}},"scdm":{"id":"scdm","type":"links","attributes":{"name":"Automated high-throughput Wannierisation","description":"Validation results of an automated protocol for generating maximally-localized Wannier functions in a high-throughput framework.","base_url":"https://aiida.materialscloud.org/autowannier/optimade","homepage":"https://materialscloud.org/explore/autowannier","link_type":"child","aggregate":"ok","no_aggregate_reason":null,"api_version":"1.1.0","query_limits":[100]}},"sssp":{"id":"sssp","type":"links","attributes":{"name":"Standard solid-state pseudopotentials (SSSP)","description":"It contains data generated from the testing protocol of the standard solid-state pseudopotentials library.\n","base_url":"https://aiida.materialscloud.org/sssplibrary/optimade","homepage":"https://materialscloud.org/explore/sssplibrary","link_type":"child","aggregate":"ok","no_aggregate_reason":null,"api_version":"1.1.0","query_limits":[100]}},"stoceriaitf":{"id":"stoceriaitf","type":"links","attributes":{"name":"SrTiO3-CeO2 interfaces","description":"Refining random structure searching results of SrTiO3-CeO2 interfaces, and exploring how it can affect ionic conduction. Candidate structures of the DFT validation calculations.","base_url":"https://aiida.materialscloud.org/stoceriaitf/optimade","homepage":"https://materialscloud.org/explore/stoceriaitf","link_type":"child","aggregate":"ok","no_aggregate_reason":null,"api_version":"1.1.0","query_limits":[100]}},"tc-applicability":{"id":"tc-applicability","type":"links","attributes":{"name":"Applicability of tail-corrections in the molecular simulations of porous materials","description":"Tail-corrections in molecular simulations for adsorption of gasses in a diverse set of nanoporous crystalline materials (zeolites, Covalent Organic Framworks (COFs), and Metal Organic Frameworks (MOFs)).","base_url":"https://aiida.materialscloud.org/tc-applicability/optimade","homepage":"https://materialscloud.org/explore/tc-applicability","link_type":"child","aggregate":"ok","no_aggregate_reason":null,"api_version":"1.1.0","query_limits":[100]}},"tcod":{"id":"tcod","type":"links","attributes":{"name":"Theoretical Crystallography Open Database","description":"Open-access collection of theoretically calculated or refined crystal structures of organic, inorganic, metal-organic compounds and minerals, excluding biopolymers","base_url":"https://www.crystallography.net/tcod/optimade","homepage":"https://www.crystallography.net/tcod","link_type":"child","api_version":"1.0.0","query_limits":[10]}},"threedd":{"id":"threedd","type":"links","attributes":{"name":"Three-dimensional crystals database","description":"Curated set of relaxed three-dimensional crystal structures based on raw CIF data from the experimantal databases MPDS, COD, and ICSD.","base_url":"https://aiida.materialscloud.org/3dd/optimade","homepage":"https://materialscloud.org/explore/3dd","link_type":"child","aggregate":"ok","no_aggregate_reason":null,"api_version":"1.1.0","query_limits":[100]}},"tin-antimony-sulfoiodide":{"id":"tin-antimony-sulfoiodide","type":"links","attributes":{"name":"Hidden spontaneous polarisation in the chalcohalide photovoltaic Sn2SbS2I3","description":"Structural, dynamic and electronic characterisation of a novel mixed-metal chalcohalide revealing hidden symmetry breaking and spontaneous polarisation.","base_url":"https://aiida.materialscloud.org/tin-antimony-sulfoiodide/optimade","homepage":"https://materialscloud.org/explore/tin-antimony-sulfoiodide","link_type":"child","aggregate":"ok","no_aggregate_reason":null,"api_version":"1.1.0","query_limits":[100]}},"twodmatpedia":{"id":"twodmatpedia","type":"links","attributes":{"name":"2DMatpedia","description":"2DMatpedia, an open computational database of two-dimensional materials from top-down and bottom-up approaches","base_url":"http://optimade.2dmatpedia.org","homepage":"http://2dmatpedia.org","link_type":"child","api_version":"1.1.0","query_limits":[500]}}},"apis":{"2dstructures":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://aiida.materialscloud.org/2dstructures/optimade/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","extensions/docs","extensions/redoc","extensions/openapi.json","structures"],"entry_types_by_format":{"json":["structures"]},"is_index":false}}],"2dtopo":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://aiida.materialscloud.org/2dtopo/optimade/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","extensions/docs","extensions/redoc","extensions/openapi.json","structures"],"entry_types_by_format":{"json":["structures"]},"is_index":false}}],"aflow":[{"type":"info","id":"/","attributes":{"api_version":"1.0.0","available_api_versions":[{"url":"https://aflow.org/API/optimade/v0.9/","version":"0.9.0"},{"url":"https://aflow.org/API/optimade/v1.0/","version":"1.0.0"},{"url":"https://aflow.org/API/optimade/v1.1/","version":"1.1.0"}],"formats":["json"],"entry_types_by_format":{"json":["structures","calculations"]},"available_endpoints":["structures","calculations","info","links"]},"is_index":false}],"cod":[{"attributes":{"api_version":"1.0.0","available_api_versions":[{"url":"https://www.crystallography.net/cod/optimade/v1.0.0/","version":"1.0.0"}],"available_endpoints":["structures","info"],"entry_types_by_format":{"json":["structures"]},"formats":["json"]},"id":"/","type":"info"}],"curated-cofs":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://aiida.materialscloud.org/curated-cofs/optimade/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","extensions/docs","extensions/redoc","extensions/openapi.json","structures"],"entry_types_by_format":{"json":["structures"]},"is_index":false}}],"jarvis":[{"type":"info","id":"/","attributes":{"api_version":"1.0.0","available_api_versions":[{"url":"https://jarvis.nist.gov/optimade/jarvisdft/v1","version":"1.0.0"}],"formats":["json","xml","yaml"],"entry_types_by_format":{"json":["structures"],"xml":["structures"],"yaml":["structures"]},"available_endpoints":["structures","info","links","versions"],"is_index":false}}],"li-ion-conductors":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://aiida.materialscloud.org/li-ion-conductors/optimade/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","extensions/docs","extensions/redoc","extensions/openapi.json","structures"],"entry_types_by_format":{"json":["structures"]},"is_index":false}}],"mp":[{"id":"/","type":"info","attributes":{"api_version":"1.0.1","available_api_versions":[{"url":"http://optimade.materialsproject.org/v1","version":"1.0.1"}],"formats":["json"],"available_endpoints":["info","links","structures","references"],"entry_types_by_format":{"json":["structures","references"]},"is_index":false}}],"mpds":[{"type":"info","attributes":{"api_version":"1.0.0","available_api_versions":[{"url":"https://api.mpds.io/v1","version":"1.0.0"}],"available_endpoints":["structures","extensions/properties","extensions/phase_diagrams","extensions/phases"],"formats":["json"],"entry_types_by_format":{"json":["structures","extensions/properties","extensions/phase_diagrams","extensions/phases"]}}}],"nmd":[{"id":"/","type":"info","attributes":{"api_version":"1.0.1","available_api_versions":[{"url":"http://nomad-lab.eu/v1","version":"1.0.1"}],"formats":["json"],"available_endpoints":["info","links","structures","references"],"entry_types_by_format":{"json":["structures","references"]},"is_index":false}}],"odbx":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://optimade.odbx.science/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","structures","references"],"entry_types_by_format":{"json":["structures","references"]},"is_index":false}}],"omdb_production":[{"attributes":{"api_version":"1.0.0","available_api_versions":[{"url":"http://optimade.openmaterialsdb.se/v1","version":"1.0.0"},{"url":"http://optimade.openmaterialsdb.se/v1.0.0","version":"1.0.0"},{"url":"http://optimade.openmaterialsdb.se/v1.0","version":"1.0.0"}],"available_endpoints":["info","links","structures"],"entry_types_by_format":{"json":["structures"]},"formats":["json"],"is_index":false},"id":"/","type":"info"}],"optimade-sample":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://aiida.materialscloud.org/optimade-sample/optimade/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","extensions/docs","extensions/redoc","extensions/openapi.json","structures"],"entry_types_by_format":{"json":["structures"]},"is_index":false}}],"oqmd":[{"type":"info","id":"/","attributes":{"api_version":"1.0.0","available_api_versions":[{"url":"http://oqmd.org/optimade/v1/","version":"1.0.0"}],"formats":["json","xml","yaml"],"entry_types_by_format":{"json":["structures"],"xml":["structures"],"yaml":["structures"]},"available_endpoints":["structures","info","links","versions"],"is_index":false}}],"pyrene-mofs":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://aiida.materialscloud.org/pyrene-mofs/optimade/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","extensions/docs","extensions/redoc","extensions/openapi.json","structures"],"entry_types_by_format":{"json":["structures"]},"is_index":false}}],"scdm":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://aiida.materialscloud.org/autowannier/optimade/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","extensions/docs","extensions/redoc","extensions/openapi.json","structures"],"entry_types_by_format":{"json":["structures"]},"is_index":false}}],"sssp":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://aiida.materialscloud.org/sssplibrary/optimade/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","extensions/docs","extensions/redoc","extensions/openapi.json","structures"],"entry_types_by_format":{"json":["structures"]},"is_index":false}}],"stoceriaitf":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://aiida.materialscloud.org/stoceriaitf/optimade/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","extensions/docs","extensions/redoc","extensions/openapi.json","structures"],"entry_types_by_format":{"json":["structures"]},"is_index":false}}],"tc-applicability":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://aiida.materialscloud.org/tc-applicability/optimade/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","extensions/docs","extensions/redoc","extensions/openapi.json","structures"],"entry_types_by_format":{"json":["structures"]},"is_index":false}}],"tcod":[{"attributes":{"api_version":"1.0.0","available_api_versions":[{"url":"https://www.crystallography.net/tcod/optimade/v1.0.0/","version":"1.0.0"}],"available_endpoints":["structures","info"],"entry_types_by_format":{"json":["structures"]},"formats":["json"]},"id":"/","type":"info"}],"threedd":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://aiida.materialscloud.org/3dd/optimade/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","extensions/docs","extensions/redoc","extensions/openapi.json","structures"],"entry_types_by_format":{"json":["structures"]},"is_index":false}}],"tin-antimony-sulfoiodide":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"https://aiida.materialscloud.org/tin-antimony-sulfoiodide/optimade/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","extensions/docs","extensions/redoc","extensions/openapi.json","structures"],"entry_types_by_format":{"json":["structures"]},"is_index":false}}],"twodmatpedia":[{"id":"/","type":"info","attributes":{"api_version":"1.1.0","available_api_versions":[{"url":"http://optimade.2dmatpedia.org/v1","version":"1.1.0"}],"formats":["json"],"available_endpoints":["info","links","structures","references"],"entry_types_by_format":{"json":["structures","references"]},"is_index":false}}]}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"2dstructures":{"id":"2dstructures","type":"links","attributes":{"name":"2D Structures","description":"Two-dimensional (2D) materials from high-throughput computational exfoliation of experimentally known compounds.","base_url":"https://aiida.materialscloud.org/2dstructures/optimade","homepage":"https://materialscloud.org/explore/2dstructures","link_type":"child","aggregate":"ok","no_aggregate_reason":null}},"2dtopo":{"id":"2dtopo","type":"links","attributes":{"name":"2D topological insulators","description":"Quantum spin Hall insulator (QSHI) candidates through DFT band structure calculations of a database with 1825 compounds.","base_url":"https://aiida.materialscloud.org/2dtopo/optimade","homepage":"https://materialscloud.org/explore/2dtopo","link_type":"child","aggregate":"ok","no_aggregate_reason":null}},"aflow":{"id":"aflow","type":"links","attributes":{"name":"AFLOW","description":"The AFLOW OPTIMADE endpoint","base_url":"http://aflow.org/API/optimade/","homepage":"http://aflow.org","link_type":"child"}},"cod":{"id":"cod","type":"links","attributes":{"name":"Crystallography Open Database","description":"Open-access collection of crystal structures of organic, inorganic, metal-organics compounds and minerals, excluding biopolymers","base_url":"https://www.crystallography.net/cod/optimade","homepage":"https://www.crystallography.net/cod","link_type":"child"}},"curated-cofs":{"id":"curated-cofs","type":"links","attributes":{"name":"CURATED covalent organic frameworks database","description":"Database of experimentally reported Covalent-Organic Frameworks (COFs), provided with DFT-optimized geometry and DDEC partial charges for molecular simulations.","base_url":"https://aiida.materialscloud.org/curated-cofs/optimade","homepage":"https://materialscloud.org/discover/curated-cofs","link_type":"child","aggregate":"ok","no_aggregate_reason":null}},"jarvis":{"id":"jarvis","type":"links","attributes":{"name":"JARVIS-DFT","description":"JARVIS-DFT is a materials property repository focused on density functional theory (DFT) predictions of material properties, especially for crystalline materials.","base_url":"https://jarvis.nist.gov/optimade/jarvisdft","homepage":"https://jarvis.nist.gov","link_type":"child"}},"li-ion-conductors":{"id":"li-ion-conductors","type":"links","attributes":{"name":"Solid-state Li-ion conductors.","description":"High-throughput computational screening study for solid-state Li-ion conductors.","base_url":"https://aiida.materialscloud.org/li-ion-conductors/optimade","homepage":"https://materialscloud.org/explore/li-ion-conductors","link_type":"child","aggregate":"staging","no_aggregate_reason":null}},"mp":{"id":"mp","type":"links","attributes":{"name":"The Materials Project","description":"The Materials Project OPTIMADE endpoint","base_url":"https://optimade.materialsproject.org","homepage":"https://www.materialsproject.org","link_type":"child"}},"mpds":{"id":"mpds","type":"links","attributes":{"name":"Materials Platform for Data Science","description":"A highly curated Pauling File dataset based on ~0.5M publications and backing up Springer Materials, ICDD PDF, ASM APD, MedeA, Pearson Crystal Data, AtomWork Advanced, etc.","base_url":"https://api.mpds.io","homepage":"https://mpds.io","link_type":"child"}},"nmd":{"id":"nmd","type":"links","attributes":{"name":"novel materials discovery (NOMAD)","description":"A FAIR data sharing platform for materials science data","base_url":"https://nomad-lab.eu/prod/rae/optimade/","homepage":"https://nomad-lab.eu","link_type":"child"}},"odbx":{"id":"odbx","type":"links","attributes":{"name":"odbx","description":"The Open Database of Xtals is run by the group of Dr Andrew Morris at the universities of Birmingham and Cambridge and is constructed using the matador library.","base_url":"https://optimade.odbx.science","homepage":"https://odbx.science","link_type":"child","aggregate":"ok","no_aggregate_reason":null}},"omdb_production":{"id":"omdb_production","type":"links","attributes":{"name":"Open Materials Database (omdb) production database","description":"This is the main production version of the Open Materials Database","base_url":"http://optimade.openmaterialsdb.se","homepage":"http://openmaterialsdb.se","link_type":"child"}},"optimade-sample":{"id":"optimade-sample","type":"links","attributes":{"name":"OPTIMADE Sample Database","description":"Database with example structures for OPTIMADE tests.","base_url":"https://aiida.materialscloud.org/optimade-sample/optimade","homepage":"https://materialscloud.org/explore/optimade-sample","link_type":"child","aggregate":"test","no_aggregate_reason":null}},"oqmd":{"id":"oqmd","type":"links","attributes":{"name":"The OQMD","description":"The Open Quantum Materials Database endpoint","base_url":"http://oqmd.org/optimade/","homepage":"http://oqmd.org","link_type":"child"}},"pyrene-mofs":{"id":"pyrene-mofs","type":"links","attributes":{"name":"Pyrene MOFs","description":"Pyrene Metal Organic Frameworks (MOFs).","base_url":"https://aiida.materialscloud.org/pyrene-mofs/optimade","homepage":"https://materialscloud.org/discover/pyrene-mofs","link_type":"child","aggregate":"ok","no_aggregate_reason":null}},"scdm":{"id":"scdm","type":"links","attributes":{"name":"Automated high-throughput Wannierisation","description":"Validation results of an automated protocol for generating maximally-localized Wannier functions in a high-throughput framework.","base_url":"https://aiida.materialscloud.org/autowannier/optimade","homepage":"https://materialscloud.org/explore/autowannier","link_type":"child","aggregate":"ok","no_aggregate_reason":null}},"sssp":{"id":"sssp","type":"links","attributes":{"name":"Standard solid-state pseudopotentials (SSSP)","description":"It contains data generated from the testing protocol of the standard solid-state pseudopotentials library.\n","base_url":"https://aiida.materialscloud.org/sssplibrary/optimade","homepage":"https://materialscloud.org/explore/sssplibrary","link_type":"child","aggregate":"ok","no_aggregate_reason":null}},"stoceriaitf":{"id":"stoceriaitf","type":"links","attributes":{"name":"SrTiO3-CeO2 interfaces","description":"Refining random structure searching results of SrTiO3-CeO2 interfaces, and exploring how it can affect ionic conduction. Candidate structures of the DFT validation calculations.","base_url":"https://aiida.materialscloud.org/stoceriaitf/optimade","homepage":"https://materialscloud.org/explore/stoceriaitf","link_type":"child","aggregate":"ok","no_aggregate_reason":null}},"tc-applicability":{"id":"tc-applicability","type":"links","attributes":{"name":"Applicability of tail-corrections in the molecular simulations of porous materials","description":"Tail-corrections in molecular simulations for adsorption of gasses in a diverse set of nanoporous crystalline materials (zeolites, Covalent Organic Framworks (COFs), and Metal Organic Frameworks (MOFs)).","base_url":"https://aiida.materialscloud.org/tc-applicability/optimade","homepage":"https://materialscloud.org/explore/tc-applicability","link_type":"child","aggregate":"ok","no_aggregate_reason":null}},"tcod":{"id":"tcod","type":"links","attributes":{"name":"Theoretical Crystallography Open Database","description":"Open-access collection of theoretically calculated or refined crystal structures of organic, inorganic, metal-organic compounds and minerals, excluding biopolymers","base_url":"https://www.crystallography.net/tcod/optimade","homepage":"https://www.crystallography.net/tcod","link_type":"child"}},"threedd":{"id":"threedd","type":"links","attributes":{"name":"Three-dimensional crystals database","description":"Curated set of relaxed three-dimensional crystal structures based on raw CIF data from the experimantal databases MPDS, COD, and ICSD.","base_url":"https://aiida.materialscloud.org/3dd/optimade","homepage":"https://materialscloud.org/explore/3dd","link_type":"child","aggregate":"ok","no_aggregate_reason":null}},"tin-antimony-sulfoiodide":{"id":"tin-antimony-sulfoiodide","type":"links","attributes":{"name":"Hidden spontaneous polarisation in the chalcohalide photovoltaic Sn2SbS2I3","description":"Structural, dynamic and electronic characterisation of a novel mixed-metal chalcohalide revealing hidden symmetry breaking and spontaneous polarisation.","base_url":"https://aiida.materialscloud.org/tin-antimony-sulfoiodide/optimade","homepage":"https://materialscloud.org/explore/tin-antimony-sulfoiodide","link_type":"child","aggregate":"ok","no_aggregate_reason":null}},"twodmatpedia":{"id":"twodmatpedia","type":"links","attributes":{"name":"2DMatpedia","description":"2DMatpedia, an open computational database of two-dimensional materials from top-down and bottom-up approaches","base_url":"http://optimade.2dmatpedia.org","homepage":"http://2dmatpedia.org","link_type":"child"}}}
|
package/dist/types.d.ts
CHANGED
|
@@ -19,6 +19,8 @@ export interface Meta {
|
|
|
19
19
|
description: string;
|
|
20
20
|
prefix: string;
|
|
21
21
|
};
|
|
22
|
+
pages?: number;
|
|
23
|
+
limits?: number[];
|
|
22
24
|
}
|
|
23
25
|
export interface Links {
|
|
24
26
|
base_url: string;
|
|
@@ -35,8 +37,8 @@ export interface ApiVer {
|
|
|
35
37
|
[key: string]: string;
|
|
36
38
|
}
|
|
37
39
|
export interface Api {
|
|
38
|
-
type: string;
|
|
39
40
|
id: string;
|
|
41
|
+
type: string;
|
|
40
42
|
attributes: {
|
|
41
43
|
api_version: string;
|
|
42
44
|
available_api_versions: ApiVer | ApiVer[];
|
|
@@ -54,6 +56,8 @@ export interface Provider {
|
|
|
54
56
|
base_url: string | null;
|
|
55
57
|
homepage?: string | null;
|
|
56
58
|
link_type?: string;
|
|
59
|
+
query_limits?: number[];
|
|
60
|
+
api_version?: string;
|
|
57
61
|
};
|
|
58
62
|
}
|
|
59
63
|
export interface Structure {
|
|
@@ -78,7 +82,7 @@ export interface InfoResponse {
|
|
|
78
82
|
[key: string]: any;
|
|
79
83
|
}
|
|
80
84
|
export interface StructuresResponse {
|
|
81
|
-
data
|
|
85
|
+
data?: Structure[];
|
|
82
86
|
links?: Links;
|
|
83
87
|
meta?: Meta;
|
|
84
88
|
}
|
|
@@ -90,10 +94,20 @@ export interface LinksResponse {
|
|
|
90
94
|
export interface ResponseError extends Error {
|
|
91
95
|
response?: any;
|
|
92
96
|
}
|
|
97
|
+
export interface ErrorObject {
|
|
98
|
+
status: string;
|
|
99
|
+
title: string;
|
|
100
|
+
detail?: string;
|
|
101
|
+
length?: string;
|
|
102
|
+
}
|
|
103
|
+
export interface ErrorResponse {
|
|
104
|
+
errors: ErrorObject;
|
|
105
|
+
meta: any;
|
|
106
|
+
}
|
|
93
107
|
export declare type ProvidersMap = {
|
|
94
108
|
[key: string]: Provider;
|
|
95
109
|
};
|
|
96
110
|
export declare type ApisMap = {
|
|
97
111
|
[key: string]: Api[];
|
|
98
112
|
};
|
|
99
|
-
export declare type StructuresResult = [Promise<
|
|
113
|
+
export declare type StructuresResult = [Promise<StructuresResponse[]>, Promise<Provider>][];
|
package/package.json
CHANGED
package/prefetch.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
+
/* jshint esversion: 6 */
|
|
4
|
+
|
|
3
5
|
const fs = require('fs');
|
|
4
6
|
const path = require('path');
|
|
5
7
|
const { Optimade } = require('./dist/index');
|
|
@@ -9,19 +11,70 @@ const { AbortController } = require('node-abort-controller');
|
|
|
9
11
|
global.AbortController = AbortController;
|
|
10
12
|
|
|
11
13
|
const optimade = new Optimade({
|
|
12
|
-
|
|
14
|
+
providersUrl: 'https://providers.optimade.org/providers.json'
|
|
13
15
|
});
|
|
14
16
|
|
|
15
|
-
optimade.getProviders().then(() => {
|
|
17
|
+
optimade.getProviders().then(async () => {
|
|
18
|
+
|
|
19
|
+
const filteredApis = Object.entries(optimade.apis).filter(([k, v]) => v.length);
|
|
20
|
+
const apis = filteredApis.sort().reduce((acc, [k, v]) => {
|
|
21
|
+
return { ...acc, ...{ [k]: v } };
|
|
22
|
+
}, {});
|
|
23
|
+
|
|
24
|
+
const source = Object.keys(optimade.providers).sort().reduce(
|
|
25
|
+
(obj, key) => {
|
|
26
|
+
obj[key] = optimade.providers[key];
|
|
27
|
+
return obj;
|
|
28
|
+
}, {});
|
|
29
|
+
|
|
30
|
+
async function getQueryLimits(providers, max = 1000) {
|
|
16
31
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
32
|
+
const fetchLimits = async (k, v) => {
|
|
33
|
+
const formula = `chemical_formula_anonymous="A2B"`;
|
|
34
|
+
const url = `${v.attributes.base_url}/v1/structures?filter=${formula}&page_limit=${max}`;
|
|
35
|
+
try {
|
|
36
|
+
const res = await fetch(url).then(res => res.json());
|
|
37
|
+
const api = res.meta && res.meta.api_version || apis[k][0].attributes.api_version;
|
|
38
|
+
//console.dir(res);
|
|
39
|
+
const detail = (e) => {
|
|
40
|
+
return e
|
|
41
|
+
? e.length
|
|
42
|
+
? e[0].detail
|
|
43
|
+
: e.detail
|
|
44
|
+
: '0';
|
|
45
|
+
};
|
|
46
|
+
const nums = detail(res.errors).match(/\d+/g).filter(n => +n < max).map(n => +n);
|
|
47
|
+
if (!nums.includes(0))
|
|
48
|
+
return {
|
|
49
|
+
[k]: { ...v, attributes: { ...v.attributes, api_version: api, ['query_limits']: nums } }
|
|
50
|
+
};
|
|
51
|
+
} catch (error) {
|
|
52
|
+
console.log(error);
|
|
53
|
+
}
|
|
54
|
+
};
|
|
21
55
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
56
|
+
providers = await Object.entries(providers).reduce(async (promise, [k, v]) => {
|
|
57
|
+
const provider = await fetchLimits(k, v);
|
|
58
|
+
const acc = await promise;
|
|
59
|
+
return { ...acc, ...provider };
|
|
60
|
+
}, Promise.resolve({}));
|
|
26
61
|
|
|
27
|
-
}
|
|
62
|
+
//const log = { prefetched: Object.keys(providers).length, source: Object.keys(source).length };
|
|
63
|
+
//console.log(log);
|
|
64
|
+
|
|
65
|
+
return providers;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
getQueryLimits(source).then(providers => {
|
|
69
|
+
const data = { providers, apis };
|
|
70
|
+
fs.writeFile(path.join(__dirname, 'dist/prefetched.json'), JSON.stringify(data), (err) => {
|
|
71
|
+
if (err) throw err;
|
|
72
|
+
console.log('The prefetched.json file has been saved!');
|
|
73
|
+
});
|
|
74
|
+
fs.writeFile(path.join(__dirname, 'dist/providers.json'), JSON.stringify(source), (err) => {
|
|
75
|
+
if (err) throw err;
|
|
76
|
+
console.log('The providers.json file has been saved!');
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
});
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
import { allSettled, fetchWithTimeout } from './utils';
|
|
3
2
|
|
|
4
3
|
import type * as Types from './types';
|
|
@@ -7,11 +6,11 @@ export { Types };
|
|
|
7
6
|
export class Optimade {
|
|
8
7
|
private providersUrl: string = '';
|
|
9
8
|
private corsProxyUrl: string = '';
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
providers: Types.ProvidersMap | null = null;
|
|
10
|
+
apis: Types.ApisMap = {};
|
|
12
11
|
private reqStack: string[] = [];
|
|
13
12
|
|
|
14
|
-
constructor({ providersUrl = '', corsProxyUrl = '' }
|
|
13
|
+
constructor({ providersUrl = '', corsProxyUrl = '' }: { providersUrl?: string; corsProxyUrl?: string; } = {}) {
|
|
15
14
|
this.corsProxyUrl = corsProxyUrl;
|
|
16
15
|
this.providersUrl = this.wrapUrl(providersUrl);
|
|
17
16
|
}
|
|
@@ -64,31 +63,48 @@ export class Optimade {
|
|
|
64
63
|
return Optimade.apiVersion(apis);
|
|
65
64
|
}
|
|
66
65
|
|
|
67
|
-
async getStructures(providerId: string, filter: string = ''): Promise<Types.
|
|
66
|
+
async getStructures(providerId: string, filter: string = '', page: number = 1, limit: number): Promise<Types.StructuresResponse[] | Types.ResponseError> {
|
|
68
67
|
|
|
69
68
|
if (!this.apis[providerId]) return null;
|
|
70
69
|
|
|
71
70
|
const apis = this.apis[providerId].filter(api => api.attributes.available_endpoints.includes('structures'));
|
|
71
|
+
const provider = this.providers[providerId];
|
|
72
|
+
|
|
73
|
+
const structures: Types.StructuresResponse[] = await allSettled(apis.map(async (api: Types.Api) => {
|
|
74
|
+
if (page <= 0) page = 1;
|
|
75
|
+
const pageLimit = limit ? `&page_limit=${limit}` : '';
|
|
76
|
+
const pageNumber = page ? `&page_number=${page - 1}` : '';
|
|
77
|
+
const pageOffset = limit && page ? `&page_offset=${limit * (page - 1)}` : '';
|
|
78
|
+
const params = filter ? `${pageLimit + pageNumber + pageOffset}` : `?${pageLimit}`;
|
|
79
|
+
const url: string = this.wrapUrl(Optimade.apiVersionUrl(api), filter ? `/structures?filter=${filter + params}` : `/structures${params}`);
|
|
72
80
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
81
|
+
try {
|
|
82
|
+
return await Optimade.getJSON(url, {}, { Origin: 'https://cors.optimade.science', 'X-Requested-With': 'XMLHttpRequest' });
|
|
83
|
+
} catch (error) {
|
|
84
|
+
return error;
|
|
85
|
+
}
|
|
77
86
|
}));
|
|
78
87
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
88
|
+
return structures.reduce((structures: any[], structure: Types.StructuresResponse | Types.ResponseError): Types.StructuresResponse[] => {
|
|
89
|
+
console.dir(`optimade-client-${providerId}:`, structure);
|
|
90
|
+
|
|
91
|
+
if (structure instanceof Error || Object.keys(structure).includes('errors')) {
|
|
92
|
+
return structures.concat(structure);
|
|
93
|
+
} else {
|
|
94
|
+
structure.meta.pages = Math.ceil(structure.meta.data_returned / (limit || structure.data.length));
|
|
95
|
+
structure.meta.limits = provider.attributes.query_limits || [10];
|
|
96
|
+
return structures.concat(structure);
|
|
97
|
+
}
|
|
82
98
|
}, []);
|
|
83
99
|
}
|
|
84
100
|
|
|
85
|
-
getStructuresAll(providerIds: string[], filter: string = '', batch: boolean = true): Promise<Promise<Types.StructuresResult>[]> | Promise<Types.StructuresResult>[] {
|
|
86
|
-
|
|
101
|
+
getStructuresAll(providerIds: string[], filter: string = '', page: number = 1, limit: number, batch: boolean = true): Promise<Promise<Types.StructuresResult>[]> | Promise<Types.StructuresResult>[] {
|
|
102
|
+
|
|
87
103
|
const results = providerIds.reduce((structures: Promise<any>[], providerId: string) => {
|
|
88
104
|
const provider = this.providers[providerId];
|
|
89
105
|
if (provider) {
|
|
90
106
|
structures.push(allSettled([
|
|
91
|
-
this.getStructures(providerId, filter),
|
|
107
|
+
this.getStructures(providerId, filter, page, limit),
|
|
92
108
|
Promise.resolve(provider)
|
|
93
109
|
]));
|
|
94
110
|
}
|
|
@@ -127,9 +143,10 @@ export class Optimade {
|
|
|
127
143
|
const res = await fetchWithTimeout(url.toString(), { headers }, timeout);
|
|
128
144
|
|
|
129
145
|
if (!res.ok) {
|
|
130
|
-
const err: Types.
|
|
131
|
-
|
|
132
|
-
|
|
146
|
+
const err: Types.ErrorResponse = await res.json();
|
|
147
|
+
const error: Types.ResponseError = new Error(err.errors[0].detail);
|
|
148
|
+
error.response = err;
|
|
149
|
+
throw error;
|
|
133
150
|
}
|
|
134
151
|
|
|
135
152
|
if (res.status !== 204) {
|
package/src/types.ts
CHANGED
|
@@ -18,7 +18,9 @@ export interface Meta {
|
|
|
18
18
|
name: string;
|
|
19
19
|
description: string;
|
|
20
20
|
prefix: string;
|
|
21
|
-
}
|
|
21
|
+
},
|
|
22
|
+
pages?: number;
|
|
23
|
+
limits?: number[];
|
|
22
24
|
}
|
|
23
25
|
|
|
24
26
|
export interface Links {
|
|
@@ -38,8 +40,8 @@ export interface ApiVer {
|
|
|
38
40
|
}
|
|
39
41
|
|
|
40
42
|
export interface Api {
|
|
41
|
-
type: string;
|
|
42
43
|
id: string;
|
|
44
|
+
type: string;
|
|
43
45
|
attributes: {
|
|
44
46
|
api_version: string;
|
|
45
47
|
available_api_versions: ApiVer | ApiVer[];
|
|
@@ -58,6 +60,8 @@ export interface Provider {
|
|
|
58
60
|
base_url: string | null;
|
|
59
61
|
homepage?: string | null;
|
|
60
62
|
link_type?: string;
|
|
63
|
+
query_limits?: number[];
|
|
64
|
+
api_version?: string;
|
|
61
65
|
};
|
|
62
66
|
}
|
|
63
67
|
|
|
@@ -87,7 +91,7 @@ export interface InfoResponse {
|
|
|
87
91
|
}
|
|
88
92
|
|
|
89
93
|
export interface StructuresResponse {
|
|
90
|
-
data
|
|
94
|
+
data?: Structure[];
|
|
91
95
|
links?: Links;
|
|
92
96
|
meta?: Meta;
|
|
93
97
|
}
|
|
@@ -102,7 +106,18 @@ export interface ResponseError extends Error {
|
|
|
102
106
|
response?: any;
|
|
103
107
|
}
|
|
104
108
|
|
|
105
|
-
export
|
|
106
|
-
|
|
109
|
+
export interface ErrorObject {
|
|
110
|
+
status: string;
|
|
111
|
+
title: string;
|
|
112
|
+
detail?: string;
|
|
113
|
+
length?: string;
|
|
114
|
+
}
|
|
115
|
+
export interface ErrorResponse {
|
|
116
|
+
errors: ErrorObject;
|
|
117
|
+
meta: any;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export type ProvidersMap = { [key: string]: Provider; };
|
|
121
|
+
export type ApisMap = { [key: string]: Api[]; };
|
|
107
122
|
|
|
108
|
-
export type StructuresResult = [Promise<
|
|
123
|
+
export type StructuresResult = [Promise<StructuresResponse[]>, Promise<Provider>][];
|
package/src/utils.ts
CHANGED
|
@@ -14,7 +14,7 @@ export async function fetchWithTimeout(url, options = {}, timeout = 5000): Promi
|
|
|
14
14
|
|
|
15
15
|
try {
|
|
16
16
|
return await fetch(url, { ...options, signal });
|
|
17
|
-
} catch(err) {
|
|
17
|
+
} catch (err) {
|
|
18
18
|
if (err.name === 'AbortError') {
|
|
19
19
|
throw new Error('Request timed out');
|
|
20
20
|
}
|