-
Notifications
You must be signed in to change notification settings - Fork 228
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Prepare to support multiple versions of the specification * Preparing createSpecification * Accept versions in definitions * Improve factory method * Start tests on open api specification support * Example api-with-examples * Example callback-example * Link example * Remove repetition * Update documentation * Correct function documentation * Include a lock file for dependencies. Please enter the commit message for your changes. Lines starting
- Loading branch information
1 parent
9e55349
commit 2d2475e
Showing
46 changed files
with
9,351 additions
and
249 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
const glob = require('glob'); | ||
|
||
/** | ||
* Converts an array of globs to full paths | ||
* @function | ||
* @param {array} globs - Array of globs and/or normal paths | ||
* @return {array} Array of fully-qualified paths | ||
* @requires glob | ||
*/ | ||
function convertGlobPaths(globs) { | ||
return globs | ||
.map(globString => glob.sync(globString)) | ||
.reduce((previous, current) => previous.concat(current), []); | ||
} | ||
|
||
module.exports = convertGlobPaths; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
/* eslint no-self-assign: 0 */ | ||
|
||
/** | ||
* Adds necessary properties for a given specification. | ||
* @see https://goo.gl/Eoagtl | ||
* @function | ||
* @param {object} definition - The `definition` or `swaggerDefinition` from options. | ||
* @returns {object} Object containing required properties of a given specification version. | ||
*/ | ||
function createSpecification(definition) { | ||
const specification = JSON.parse(JSON.stringify(definition)); | ||
|
||
// Properties corresponding to their specifications. | ||
const v2 = [ | ||
'paths', | ||
'definitions', | ||
'responses', | ||
'parameters', | ||
'securityDefinitions', | ||
]; | ||
const v3 = [...v2, 'components']; | ||
|
||
if (specification.openapi) { | ||
specification.openapi = specification.openapi; | ||
v3.forEach(property => { | ||
specification[property] = specification[property] || {}; | ||
}); | ||
} else if (specification.swagger) { | ||
specification.swagger = specification.swagger; | ||
v2.forEach(property => { | ||
specification[property] = specification[property] || {}; | ||
}); | ||
} else { | ||
specification.swagger = '2.0'; | ||
v2.forEach(property => { | ||
specification[property] = specification[property] || {}; | ||
}); | ||
} | ||
|
||
specification.tags = specification.tags || []; | ||
|
||
return specification; | ||
} | ||
|
||
module.exports = createSpecification; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
const jsYaml = require('js-yaml'); | ||
|
||
/** | ||
* Filters JSDoc comments for those tagged with '@swagger' | ||
* @function | ||
* @param {array} jsDocComments - JSDoc comments | ||
* @returns {array} JSDoc comments tagged with '@swagger' | ||
* @requires js-yaml | ||
*/ | ||
function filterJsDocComments(jsDocComments) { | ||
const swaggerJsDocComments = []; | ||
|
||
for (let i = 0; i < jsDocComments.length; i += 1) { | ||
const jsDocComment = jsDocComments[i]; | ||
for (let j = 0; j < jsDocComment.tags.length; j += 1) { | ||
const tag = jsDocComment.tags[j]; | ||
if (tag.title === 'swagger') { | ||
swaggerJsDocComments.push(jsYaml.safeLoad(tag.description)); | ||
} | ||
} | ||
} | ||
|
||
return swaggerJsDocComments; | ||
} | ||
|
||
module.exports = filterJsDocComments; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
const parser = require('swagger-parser'); | ||
const createSpecification = require('./createSpecification'); | ||
const specHelper = require('./specification'); | ||
const parseApiFile = require('./parseApiFile'); | ||
const filterJsDocComments = require('./filterJsDocComments'); | ||
const convertGlobPaths = require('./convertGlobPaths'); | ||
|
||
function isEmptyObject(obj) { | ||
// eslint-disable-next-line | ||
Object.keys(obj).forEach(key => { | ||
if (key in obj) return false; | ||
}); | ||
|
||
return true; | ||
} | ||
|
||
/** | ||
* OpenAPI specification validator does not accept empty values for a few properties. | ||
* Solves validator error: "Schema error should NOT have additional properties" | ||
* @function | ||
* @param {object} inputSpec - The swagger/openapi specification | ||
* @param {object} improvedSpec - The cleaned version of the inputSpec | ||
*/ | ||
function cleanUselessProperties(inputSpec) { | ||
const improvedSpec = JSON.parse(JSON.stringify(inputSpec)); | ||
const toClean = [ | ||
'definitions', | ||
'responses', | ||
'parameters', | ||
'securityDefinitions', | ||
]; | ||
|
||
toClean.forEach(unncessaryProp => { | ||
if (isEmptyObject(improvedSpec[unncessaryProp])) { | ||
delete improvedSpec[unncessaryProp]; | ||
} | ||
}); | ||
|
||
return improvedSpec; | ||
} | ||
|
||
function getSpecificationObject(options) { | ||
// Get input definition and prepare the specification's skeleton | ||
const definition = options.swaggerDefinition || options.definition; | ||
let specification = createSpecification(definition); | ||
|
||
// Parse the documentation containing information about APIs. | ||
const apiPaths = convertGlobPaths(options.apis); | ||
|
||
for (let i = 0; i < apiPaths.length; i += 1) { | ||
const files = parseApiFile(apiPaths[i]); | ||
const swaggerJsDocComments = filterJsDocComments(files.jsdoc); | ||
|
||
specHelper.addDataToSwaggerObject(specification, files.yaml); | ||
specHelper.addDataToSwaggerObject(specification, swaggerJsDocComments); | ||
} | ||
|
||
parser.parse(specification, (err, api) => { | ||
if (!err) { | ||
specification = api; | ||
} | ||
}); | ||
|
||
if (specification.openapi) { | ||
specification = cleanUselessProperties(specification); | ||
} | ||
|
||
return specification; | ||
} | ||
|
||
module.exports = getSpecificationObject; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
const fs = require('fs'); | ||
const path = require('path'); | ||
const doctrine = require('doctrine'); | ||
const jsYaml = require('js-yaml'); | ||
|
||
/** | ||
* Parses the provided API file for JSDoc comments. | ||
* @function | ||
* @param {string} file - File to be parsed | ||
* @returns {{jsdoc: array, yaml: array}} JSDoc comments and Yaml files | ||
* @requires doctrine | ||
*/ | ||
function parseApiFile(file) { | ||
const jsDocRegex = /\/\*\*([\s\S]*?)\*\//gm; | ||
const fileContent = fs.readFileSync(file, { encoding: 'utf8' }); | ||
const ext = path.extname(file); | ||
const yaml = []; | ||
const jsDocComments = []; | ||
|
||
if (ext === '.yaml' || ext === '.yml') { | ||
yaml.push(jsYaml.safeLoad(fileContent)); | ||
} else { | ||
const regexResults = fileContent.match(jsDocRegex); | ||
if (regexResults) { | ||
for (let i = 0; i < regexResults.length; i += 1) { | ||
const jsDocComment = doctrine.parse(regexResults[i], { unwrap: true }); | ||
jsDocComments.push(jsDocComment); | ||
} | ||
} | ||
} | ||
|
||
return { | ||
yaml, | ||
jsdoc: jsDocComments, | ||
}; | ||
} | ||
|
||
module.exports = parseApiFile; |
Oops, something went wrong.