Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions docs/site/OpenAPI-spec-generator.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
lang: en
title: 'OpenAPI spec generator'
keywords: LoopBack 4.0, LoopBack 4
sidebar: lb4_sidebar
permalink: /doc/en/lb4/OpenAPI-spec-generator.html
---

{% include content/generator-create-app.html lang=page.lang %}

### Synopsis

Saves OpenAPI spec to a json or yaml file.

```sh
lb4 openapi-spec [options]
```

### Options

`--out` or `-o` : File name for the OpenAPI spec

{% include_relative includes/CLI-std-options.md %}

### Interactive Prompts

The tool will prompt you for:

- **File name for the OpenAPI spec.** _(outFile)_ If the `--out` had been
supplied from the command line, the prompt is skipped.

### Output

Once all the prompts have been answered, the CLI will do the following:

- Start the application without listening on an Http port.
- Load the OpenAPI spec
- Save the spec to the file in json or yaml format depending on the extension

```
lb4 openapi-spec

? File name for the OpenAPI spec: dist/openapi.json
Server is running at undefined
create dist/openapi.json
OpenAPI spec is written to dist/openapi.json.
```
8 changes: 7 additions & 1 deletion docs/site/tables/lb4-artifact-commands.html
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@

<tr>
<td><code>lb4 openapi</code></td>
<td>Generate controllers and models from OpenAPI specs</td>
<td>Generate controllers, service proxies, and models from OpenAPI specs</td>
<td><a href="OpenAPI-generator.html">OpenAPI generator</a></td>
</tr>

Expand All @@ -81,5 +81,11 @@
<td>Generate rest configs for model endpoints</td>
<td><a href="Rest-Crud-generator.html">Model endpoint generator</a></td>
</tr>

<tr>
<td><code>lb4 openapi-spec</code></td>
<td>Save OpenAPI spec to a json or yaml file</td>
<td><a href="OpenAPI-spec-generator.html">OpenAPI spec generator</a></td>
</tr>
</tbody>
</table>
72 changes: 72 additions & 0 deletions packages/cli/.yo-rc.json
Original file line number Diff line number Diff line change
Expand Up @@ -1643,6 +1643,78 @@
},
"arguments": [],
"name": "copyright"
},
"openapi-spec": {
"options": {
"help": {
"name": "help",
"type": "Boolean",
"alias": "h",
"description": "Print the generator's options and usage"
},
"skip-cache": {
"name": "skip-cache",
"type": "Boolean",
"description": "Do not remember prompt answers",
"default": false
},
"skip-install": {
"name": "skip-install",
"type": "Boolean",
"description": "Do not automatically install dependencies",
"default": false
},
"force-install": {
"name": "force-install",
"type": "Boolean",
"description": "Fail on install dependencies error",
"default": false
},
"ask-answered": {
"type": "Boolean",
"description": "Show prompts for already configured options",
"default": false,
"name": "ask-answered",
"hide": false
},
"out": {
"alias": "o",
"type": "String",
"required": false,
"description": "File name for the OpenAPI spec to be written",
"name": "out",
"hide": false
},
"config": {
"type": "String",
"alias": "c",
"description": "JSON file name or value to configure options",
"name": "config",
"hide": false
},
"yes": {
"type": "Boolean",
"alias": "y",
"description": "Skip all confirmation prompts with default or provided value",
"name": "yes",
"hide": false
},
"format": {
"type": "Boolean",
"description": "Format generated code using npm run lint:fix",
"name": "format",
"hide": false
},
"packageManager": {
"type": "String",
"description": "Change the default package manager",
"alias": "pm",
"name": "packageManager",
"hide": false
}
},
"arguments": [],
"name": "openapi-spec"
}
}
}
79 changes: 79 additions & 0 deletions packages/cli/generators/openapi-spec/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Copyright IBM Corp. 2019,2020. All Rights Reserved.
// Node module: @loopback/cli
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT

'use strict';

const BaseGenerator = require('../../lib/base-generator');
const g = require('../../lib/globalize');
const {dump} = require('js-yaml');

module.exports = class OpenApiSpecGenerator extends BaseGenerator {
// Note: arguments and options should be defined in the constructor.
constructor(args, opts) {
super(args, opts);
}

_setupGenerator() {
this.option('out', {
alias: 'o',
type: String,
required: false,
description: g.f('File name for the OpenAPI spec to be written'),
});
return super._setupGenerator();
}

setOptions() {
return super.setOptions();
}

checkLoopBackProject() {
if (this.shouldExit()) return;
return super.checkLoopBackProject();
}

async promptFileName() {
if (this.shouldExit()) return;
if (this.options.out) {
this.outFile = this.options.out;
return;
}
const prompts = [
{
type: 'input',
name: 'outFile',
message: g.f('File name for the OpenAPI spec:'),
default: 'dist/openapi.json',

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it possible to make the default at the root of the project?

},
];
const answers = await this.prompt(prompts);
this.outFile = answers && answers.outFile;
}

async saveSpec() {
if (this.shouldExit()) return;
this.log('Loading application %s...', this.packageJson.name);
// Load the `main` function
const main = require(this.destinationRoot()).main;
const app = await main({rest: {listenOnStart: false}});

// Get the OpenAPI spec
const spec = await app.restServer.getApiSpec();
const outFile = this.outFile || 'dist/openapi.json';
const fileName = this.outFile.toLowerCase();
if (fileName.endsWith('.yaml') || fileName.endsWith('.yml')) {
const yaml = dump(spec);
this.fs.write(outFile, yaml);
} else {
this.fs.writeJSON(outFile, spec, null, 2);
}
await app.stop();
}

async end() {
this.log('The OpenAPI spec has been saved to %s.', this.outFile);
await super.end();
}
};
4 changes: 4 additions & 0 deletions packages/cli/lib/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@ function setupGenerators() {
path.join(__dirname, '../generators/copyright'),
PREFIX + 'copyright',
);
env.register(
path.join(__dirname, '../generators/openapi-spec'),
PREFIX + 'openapi-spec',
);
return env;
}

Expand Down
1 change: 1 addition & 0 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
"fs-extra": "^9.0.0",
"glob": "^7.1.6",
"inquirer-autocomplete-prompt": "^1.0.2",
"js-yaml": "^3.13.1",
"json5": "^2.1.3",
"latest-version": "^5.1.0",
"lodash": "^4.17.15",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ Available commands:
lb4 update
lb4 rest-crud
lb4 copyright
lb4 openapi-spec
lb4 install-completion
lb4 uninstall-completion
`;
Expand All @@ -50,6 +51,7 @@ Available commands:
lb4 update
lb4 rest-crud
lb4 copyright
lb4 openapi-spec
lb4 install-completion
lb4 uninstall-completion
`;
Expand Down Expand Up @@ -1701,6 +1703,78 @@ exports[`cli saves command metadata to .yo-rc.json 1`] = `
},
"arguments": [],
"name": "copyright"
},
"openapi-spec": {
"options": {
"help": {
"name": "help",
"type": "Boolean",
"alias": "h",
"description": "Print the generator's options and usage"
},
"skip-cache": {
"name": "skip-cache",
"type": "Boolean",
"description": "Do not remember prompt answers",
"default": false
},
"skip-install": {
"name": "skip-install",
"type": "Boolean",
"description": "Do not automatically install dependencies",
"default": false
},
"force-install": {
"name": "force-install",
"type": "Boolean",
"description": "Fail on install dependencies error",
"default": false
},
"ask-answered": {
"type": "Boolean",
"description": "Show prompts for already configured options",
"default": false,
"name": "ask-answered",
"hide": false
},
"out": {
"alias": "o",
"type": "String",
"required": false,
"description": "File name for the OpenAPI spec to be written",
"name": "out",
"hide": false
},
"config": {
"type": "String",
"alias": "c",
"description": "JSON file name or value to configure options",
"name": "config",
"hide": false
},
"yes": {
"type": "Boolean",
"alias": "y",
"description": "Skip all confirmation prompts with default or provided value",
"name": "yes",
"hide": false
},
"format": {
"type": "Boolean",
"description": "Format generated code using npm run lint:fix",
"name": "format",
"hide": false
},
"packageManager": {
"type": "String",
"description": "Change the default package manager",
"alias": "pm",
"name": "packageManager",
"hide": false
}
},
"arguments": [],
"name": "openapi-spec"
}
}
}
Expand Down
Loading