Skip to content

Commit 74ec083

Browse files
committed
add initial files to swagger parser
1 parent 3d5d9dc commit 74ec083

File tree

4 files changed

+1341
-0
lines changed

4 files changed

+1341
-0
lines changed

src/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ export Api from './Api';
22
export Resource from './Resource';
33
export Field from './Field';
44
export * from './hydra';
5+
export * from './swagger';

src/swagger/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export parseSwaggerDocumentation from './parseSwaggerDocumentation';
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
import Api from '../Api'
2+
import Field from '../Field'
3+
import Resource from '../Resource'
4+
5+
/**
6+
* Extracts the short name of a resource.
7+
*
8+
* @param {string} url
9+
* @param {string} entrypointUrl
10+
* @return {string}
11+
*/
12+
function guessNameFromUrl(url, entrypointUrl) {
13+
return url.substr(entrypointUrl.length + 1);
14+
}
15+
16+
/**
17+
* Finds the description of the class with the given id.
18+
*
19+
* @param {object[]} docs
20+
* @param {string} supportedClass
21+
* @return {object}
22+
*/
23+
function findSupportedClass(docs, supportedClass) {
24+
const supportedClasses = docs[0]['http://www.w3.org/ns/hydra/core#supportedClass'];
25+
26+
for (let i = 0; i < supportedClasses.length; i++) {
27+
if (supportedClasses[i]['@id'] === supportedClass) {
28+
return supportedClasses[i];
29+
}
30+
}
31+
32+
throw new Error(`The class ${supportedClass} doesn't exist.`);
33+
}
34+
35+
36+
/**
37+
* Retrieves Hydra's entrypoint and API docs.
38+
*
39+
* @param {string} entrypointUrl
40+
* @param {object} options
41+
* @return {Promise}
42+
*/
43+
function fetchEntrypointAndDocs(entrypointUrl) {
44+
return fetch(entrypointUrl).then(d => {
45+
return {
46+
entrypointUrl,
47+
docsUrl: null,
48+
entrypoint: d.body,
49+
response: Promise.resolve(d.json().then(body => ({ d, body, document: body })))
50+
}
51+
})
52+
}
53+
54+
function removeTrailingSlash(url) {
55+
if (/\/$/.test(url)) {
56+
url = url.slice(0, -1)
57+
}
58+
59+
return url
60+
}
61+
62+
/**
63+
* Parses a Hydra documentation and converts it to an intermediate representation.
64+
*
65+
* @param {string} entrypointUrl
66+
* @param {object} options
67+
* @return {Promise.<Api>}
68+
*/
69+
export default function parseSwaggerDocumentation(entrypointUrl) {
70+
entrypointUrl = removeTrailingSlash(entrypointUrl)
71+
return fetchEntrypointAndDocs(entrypointUrl).then(
72+
({ entrypoint, docs, response }) => {
73+
74+
// const title = 'undefined' === typeof docs[0]['http://www.w3.org/ns/hydra/core#title'] ? 'API Platform' : docs[0]['http://www.w3.org/ns/hydra/core#title'][0]['@value'];
75+
// const entrypointSupportedClass = findSupportedClass(docs, entrypoint[0]['@type'][0]);
76+
77+
// let resources = [];
78+
// let fields = [];
79+
80+
// // Add resources
81+
// for (let properties of entrypointSupportedClass['http://www.w3.org/ns/hydra/core#supportedProperty']) {
82+
// const property = properties['http://www.w3.org/ns/hydra/core#property'][0];
83+
// const entrypointSupportedOperations = property['http://www.w3.org/ns/hydra/core#supportedOperation'];
84+
85+
// let readableFields = [];
86+
// let resourceFields = [];
87+
// let writableFields = [];
88+
89+
// // Add fields
90+
// for (let j = 0; j < entrypointSupportedOperations.length; j++) {
91+
// let className = entrypointSupportedOperations[j]['http://www.w3.org/ns/hydra/core#returns'];
92+
93+
// // Skip operations not having a return type
94+
// if (!className) {
95+
// continue;
96+
// }
97+
98+
// className = className[0]['@id'];
99+
100+
// if (0 === className.indexOf('http://www.w3.org/ns/hydra/core')) {
101+
// continue;
102+
// }
103+
104+
// const supportedClass = findSupportedClass(docs, className);
105+
// for (let supportedProperties of supportedClass['http://www.w3.org/ns/hydra/core#supportedProperty']) {
106+
// const supportedProperty = supportedProperties['http://www.w3.org/ns/hydra/core#property'][0];
107+
// const range = supportedProperty['http://www.w3.org/2000/01/rdf-schema#range'] ? supportedProperty['http://www.w3.org/2000/01/rdf-schema#range'][0]['@id'] : null;
108+
109+
// const field = new Field(
110+
// supportedProperty['http://www.w3.org/2000/01/rdf-schema#label'][0]['@value'],
111+
// {
112+
// id: supportedProperty['@id'],
113+
// range,
114+
// reference: 'http://www.w3.org/ns/hydra/core#Link' === property['@type'][0] ? range : null, // Will be updated in a subsequent pass
115+
// required: supportedProperties['http://www.w3.org/ns/hydra/core#required'] ? supportedProperties['http://www.w3.org/ns/hydra/core#required'][0]['@value'] : false,
116+
// description: supportedProperties['http://www.w3.org/ns/hydra/core#description'] ? supportedProperties['http://www.w3.org/ns/hydra/core#description'][0]['@value'] : ''
117+
// },
118+
// );
119+
120+
// fields.push(field);
121+
// resourceFields.push(field);
122+
123+
// if (supportedProperties['http://www.w3.org/ns/hydra/core#readable'][0]['@value']) {
124+
// readableFields.push(field);
125+
// }
126+
127+
// if (supportedProperties['http://www.w3.org/ns/hydra/core#writable'][0]['@value']) {
128+
// writableFields.push(field);
129+
// }
130+
// }
131+
132+
// resources.push(new Resource(
133+
// guessNameFromUrl(entrypoint[0][property['@id']][0]['@id'], entrypointUrl),
134+
// entrypoint[0][property['@id']][0]['@id'],
135+
// {
136+
// id: supportedClass['@id'],
137+
// title: supportedClass['http://www.w3.org/ns/hydra/core#title'][0]['@value'],
138+
// fields: resourceFields,
139+
// readableFields,
140+
// writableFields
141+
// }
142+
// ));
143+
144+
// break;
145+
// }
146+
// }
147+
148+
// // Resolve references
149+
// for (let field of fields) {
150+
// if (null !== field.reference) {
151+
// field.reference = resources.find(resource => resource.id === field.reference) || null;
152+
// }
153+
// }
154+
155+
// return Promise.resolve({ api: new Api(entrypointUrl, {title, resources}), response , status: response.status });
156+
return Promise.resolve({ api: {} }, response)
157+
},
158+
({ response }) => Promise.reject({ api: new Api(entrypointUrl, {resources: []}), response, status: response.status })
159+
);
160+
}

0 commit comments

Comments
 (0)