|
| 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