Skip to content

Commit

Permalink
Upgrades (#121)
Browse files Browse the repository at this point in the history
* Upgrades

* Mocha upgrade needs an exit

* Updates

* Updates

* Updates

* Increase timeout
  • Loading branch information
kalinchernev authored Jul 27, 2018
1 parent 0da844f commit 9e55349
Show file tree
Hide file tree
Showing 27 changed files with 445 additions and 2,943 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
4 changes: 4 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"root": true,
"extends": ["airbnb-base", "plugin:prettier/recommended"]
}
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,6 @@ jsdoc
# Editors
.c9
.idea

# In case project is used locally to generate a spec
swagger.json
63 changes: 0 additions & 63 deletions .jshintrc

This file was deleted.

3 changes: 3 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
singleQuote: true
trailingComma: es5
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ documentation, servers, clients, tests and much more based on the rich [OpenAPI
[![npm Version](https://img.shields.io/npm/v/swagger-jsdoc.svg)](https://www.npmjs.com/package/swagger-jsdoc)
[![npm Downloads](https://img.shields.io/npm/dm/swagger-jsdoc.svg)](https://www.npmjs.com/package/swagger-jsdoc)
[![Circle CI](https://img.shields.io/circleci/project/Surnet/swagger-jsdoc/master.svg)](https://circleci.com/gh/Surnet/swagger-jsdoc)
[![Documentation Status](http://inch-ci.org/github/Surnet/swagger-jsdoc.svg?branch=master&style=flat)](http://inch-ci.org/github/Surnet/swagger-jsdoc)
[![Known Vulnerabilities](https://snyk.io/test/github/Surnet/swagger-jsdoc/badge.svg?targetFile=package.json)](https://snyk.io/test/github/Surnet/swagger-jsdoc?targetFile=package.json)

## Goals
Expand Down Expand Up @@ -63,7 +62,7 @@ The swagger spec will be served at http://localhost:3000/api-docs.json

### CLI

You can also use the tool via [command line interface](./docs/CLI.md). It supports selecting multiple files, recursive subdirectories and watch task for continuous listening of changes in your code.
You can also use the tool via [command line interface](./docs/CLI.md).

### Contributing

Expand Down
94 changes: 35 additions & 59 deletions bin/swagger-jsdoc.js
Original file line number Diff line number Diff line change
@@ -1,42 +1,39 @@
#!/usr/bin/env node

'use strict';

/**
* Module dependencies.
*/
var program = require('commander');
var fs = require('fs');
var path = require('path');
var swaggerJSDoc = require('../');
var pkg = require('../package.json');
var jsYaml = require('js-yaml');
var chokidar = require('chokidar');
const program = require('commander');
const fs = require('fs');
const path = require('path');
const jsYaml = require('js-yaml');
const swaggerJSDoc = require('../');
const pkg = require('../package.json');

// Useful input.
var input = process.argv.slice(2);
const input = process.argv.slice(2);
// The spec, following a convention.
var output = 'swagger.json';
let output = 'swagger.json';

/**
* Creates a swagger specification from a definition and a set of files.
* @function
* @param {object} swaggerDefinition - The swagger definition object.
* @param {array} apis - List of files to extract documentation from.
* @param {array} output - Name the output file.
* @param {string} fileName - Name the output file.
*/
function createSpecification(swaggerDefinition, apis, output) {
function createSpecification(swaggerDefinition, apis, fileName) {
// Options for the swagger docs
var options = {
const options = {
// Import swaggerDefinitions
swaggerDefinition: swaggerDefinition,
swaggerDefinition,
// Path to the API docs
apis: apis,
apis,
};

// Initialize swagger-jsdoc -> returns validated JSON or YAML swagger spec
var swaggerSpec;
var ext = path.extname(output);
let swaggerSpec;
const ext = path.extname(fileName);

if (ext === '.yml' || ext === '.yaml') {
swaggerSpec = jsYaml.dump(swaggerJSDoc(options), {
Expand All @@ -47,7 +44,7 @@ function createSpecification(swaggerDefinition, apis, output) {
swaggerSpec = JSON.stringify(swaggerJSDoc(options), null, 2);
}

fs.writeFile(output, swaggerSpec, function writeSpecification(err) {
fs.writeFile(fileName, swaggerSpec, err => {
if (err) {
throw err;
}
Expand All @@ -60,7 +57,6 @@ program
.usage('[options] <path ...>')
.option('-d, --definition <swaggerDef.js>', 'Input swagger definition.')
.option('-o, --output [swaggerSpec.json]', 'Output swagger specification.')
.option('-w, --watch', 'Whether or not to listen for continous changes.')
.parse(process.argv);

// If no arguments provided, display help menu.
Expand All @@ -72,42 +68,46 @@ if (!input.length) {
if (!program.definition) {
console.log('Definition file is required.');
console.log('You can do that, for example: ');
console.log('$ swag-jsdoc -d swaggerDef.js ' + input.join(' '));
console.log(`$ swag-jsdoc -d swaggerDef.js ${input.join(' ')}`);
program.help();
process.exit(1);
}

// Override default output file if provided.
if (program.output) {
// eslint-disable-next-line prefer-destructuring
output = program.output;
}

// Definition file is specified:
fs.readFile(program.definition, 'utf-8', function(err, data) {
fs.readFile(program.definition, 'utf-8', (err, data) => {
if (err || data === undefined) {
return console.log('Definition file provided is not good.');
}

// Check whether the definition file is actually a usable .js file
if (path.extname(program.definition) !== '.js' &&
if (
path.extname(program.definition) !== '.js' &&
path.extname(program.definition) !== '.json'
) {
console.log('Format as a module, it will be imported with require().');
return console.log('Definition file should be .js or .json');
}

// Get an object of the definition file configuration.
var swaggerDefinition = require(path.resolve(program.definition));
// eslint-disable-next-line
const swaggerDefinition = require(path.resolve(program.definition));

// Check for info object in the definition.
if (!swaggerDefinition.hasOwnProperty('info')) {
if (!('info' in swaggerDefinition)) {
console.log('Definition file should contain an info object!');
return console.log('More at http://swagger.io/specification/#infoObject');
}

// Check for title and version properties in the info object.
if (!swaggerDefinition.info.hasOwnProperty('title') ||
!swaggerDefinition.info.hasOwnProperty('version')
if (
!('title' in swaggerDefinition.info) ||
!('version' in swaggerDefinition.info)
) {
console.log('The title and version properties are required!');
return console.log('More at http://swagger.io/specification/#infoObject');
Expand All @@ -117,44 +117,20 @@ fs.readFile(program.definition, 'utf-8', function(err, data) {
if (!swaggerDefinition.apis && !program.args.length) {
console.log('You must provide sources for reading API files.');
// jscs:disable maximumLineLength
return console.log('Either add filenames as arguments, or add an "apis" key in your definitions file.');
return console.log(
'Either add filenames as arguments, or add an "apis" key in your definitions file.'
);
}

// If there's no argument passed, but the user has defined Apis in
// the definition file, pass them them onwards.
if (program.args.length === 0 &&
if (
program.args.length === 0 &&
swaggerDefinition.apis &&
swaggerDefinition.apis instanceof Array) {
swaggerDefinition.apis instanceof Array
) {
program.args = swaggerDefinition.apis;
}

// If watch flag is turned on, listen for changes.
if (program.watch) {
var watcher = chokidar.watch(program.args, {
awaitWriteFinish: {
stabilityThreshold: 2000,
pollInterval: 100,
},
});

watcher.on('ready', function startMessage() {
console.log('Listening for changes ...');
});

watcher.on('change', function detectChange(path) {
console.log('Change detected in ' + path);
});

watcher.on('error', function catchErr(err) {
return console.error(err);
});

watcher.on('all', function regenerateSpec() {
createSpecification(swaggerDefinition, program.args, output);
});
}
// Just create the specification.
else {
createSpecification(swaggerDefinition, program.args, output);
}
return createSpecification(swaggerDefinition, program.args, output);
});
10 changes: 1 addition & 9 deletions docs/CLI.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ This could be any .js or .json file which will be `require()`-ed and parsed/vali
```
$ swagger-jsdoc route1.js route2.js
```

Free form input, can be before or after definition. [Glob patterns](https://github.com/isaacs/node-glob) are acceptable to match multiple files with same extension `*.js`, `*.php`, etc. or patterns selecting files in nested folders as `**/*.js`, `**/*.php`, etc.

#### Specify output file (optional)
Expand All @@ -35,12 +36,3 @@ $ swagger-jsdoc -o custom_specification.json
```

`swagger.json` by default. Output specification can accept also a `.yaml` or `.yml`. This generated OpenAPI specification can then be further tweaked with [`swagger-editor`](http://swagger.io/swagger-editor/) or similar.

#### Watch for changes (optional)

```
$ swagger-jsdoc -d swaggerDef.js route1.js route2.js -w
```

The `-w` flag starts a watch task for input files with API documentation. This may be particularly useful when the output specification file is integrated with [Browsersync](https://browsersync.io/)
with [Swagger UI](http://swagger.io/swagger-ui/) or [ReDoc](https://github.com/Rebilly/ReDoc). Thus, the developer updates documentation in code with fast feedback in an interface showing live documentation based on the OpenAPI specification.
46 changes: 24 additions & 22 deletions example/app.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,29 @@
'use strict';

/* istanbul ignore next */
/* eslint import/no-extraneous-dependencies: 0 */
// This file is an example, it's not functionally used by the module.

// Dependencies
var express = require('express');
var bodyParser = require('body-parser');
var routes = require('./routes');
var routes2 = require('./routes2');
var swaggerJSDoc = require('../');
const express = require('express');
const bodyParser = require('body-parser');
const routes = require('./routes');
const routes2 = require('./routes2');
const swaggerJSDoc = require('../');

// Initialize express
var app = express();
const app = express();
app.use(bodyParser.json()); // To support JSON-encoded bodies
app.use(bodyParser.urlencoded({ // To support URL-encoded bodies
extended: true,
}));
app.use(
bodyParser.urlencoded({
// To support URL-encoded bodies
extended: true,
})
);

// Swagger definition
// You can set every attribute except paths and swagger
// https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md
var swaggerDefinition = {
info: { // API informations (required)
const swaggerDefinition = {
info: {
// API informations (required)
title: 'Hello World', // Title (required)
version: '1.0.0', // Version (required)
description: 'A sample API', // Description (optional)
Expand All @@ -31,18 +33,18 @@ var swaggerDefinition = {
};

// Options for the swagger docs
var options = {
const options = {
// Import swaggerDefinitions
swaggerDefinition: swaggerDefinition,
swaggerDefinition,
// Path to the API docs
apis: ['./example/routes*.js', './example/parameters.yaml'],
};

// Initialize swagger-jsdoc -> returns validated swagger spec in json format
var swaggerSpec = swaggerJSDoc(options);
const swaggerSpec = swaggerJSDoc(options);

// Serve swagger docs the way you like (Recommendation: swagger-tools)
app.get('/api-docs.json', function(req, res) {
app.get('/api-docs.json', (req, res) => {
res.setHeader('Content-Type', 'application/json');
res.send(swaggerSpec);
});
Expand All @@ -52,12 +54,12 @@ routes.setup(app);
routes2.setup(app);

// Expose app
exports = module.exports = app;
module.exports = app;

// Start the server
var server = app.listen(3000, function startExpressServer() {
var host = server.address().address;
var port = server.address().port;
const server = app.listen(3000, () => {
const host = server.address().address;
const { port } = server.address();

console.log('Example app listening at http://%s:%s', host, port);
});
Loading

0 comments on commit 9e55349

Please sign in to comment.