Skip to content

Commit 870b897

Browse files
authored
Merge pull request #77 from Mermade/v2
Use of remote templates
2 parents 5958bca + bd79bf9 commit 870b897

File tree

6 files changed

+150
-22
lines changed

6 files changed

+150
-22
lines changed

README.md

+8-14
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33
[![Build status](https://travis-ci.org/Mermade/openapi-codegen.svg?branch=master)](https://travis-ci.org/Mermade/openapi-codegen)
44
[![Greenkeeper badge](https://badges.greenkeeper.io/Mermade/openapi-codegen.svg)](https://greenkeeper.io/)
55

6-
Experimental port of [swagger-codegen](https://github.com/swagger-api/swagger-codegen) templates to Node.js. This project was initially a 24-hour hackathon. The model adaptor code is entirely original and has been reverse-engineered from the existing documentation and template usage.
6+
Node.js-based codegen for OpenAPI documents. This project was initially a 24-hour hackathon. The local model adaptor code is entirely original and has been reverse-engineered from the existing documentation and template usage.
77

88
**Work in progress**
99

10-
Supports OpenAPI 3.0.x natively, and Swagger/OpenAPI 1.2 and 2.0 by internal conversion
10+
Supports OpenAPI 3.0.x natively, and Swagger/OpenAPI 1.2 and 2.0 by internal conversion. Node.js LTS versions are supported.
1111

1212
## Usage
1313

@@ -32,6 +32,8 @@ cg [options] {[path]configName} {openapi-definition}
3232
Options:
3333
--help Show help [boolean]
3434
--version Show version number [boolean]
35+
--filter Filter term to use with --list [string]
36+
--list List available templates for provider (og or sc) [string]
3537
-d, --debug Turn on debugging information in the model [boolean]
3638
-f, --flat Do not include config-name in output directory structure
3739
[boolean]
@@ -54,8 +56,6 @@ In this case, the generated code will be written to the `.out/nodejs` directory.
5456

5557
You can also load the OpenAPI definition from a URL.
5658

57-
If you are using Node 6.x or lower, please specify the `--harmony` flag.
58-
5959
### API
6060

6161
```javascript
@@ -66,15 +66,17 @@ renderer.main(definition,config,configName);
6666

6767
## Templates
6868

69-
Templates are taken directly from `swagger-codegen`. This project is also licensed under [Apache-2.0](LICENSE) for this reason. Generated code is explicitly covered by the [Unlicense](templates/_common/UNLICENSE). Code to downconvert OpenAPI 3.0 definitions is taken from [Angular-Swagger-UI](https://github.com/Orange-OpenSource/angular-swagger-ui) and is MIT licensed.
69+
The local templates were taken directly from `swagger-codegen`. This project is also licensed under [Apache-2.0](LICENSE) for this reason. Generated code is explicitly covered by the [Unlicense](templates/_common/UNLICENSE). Code to downconvert OpenAPI 3.0 definitions is taken from [Angular-Swagger-UI](https://github.com/Orange-OpenSource/angular-swagger-ui) and is MIT licensed.
70+
71+
You can also use the latest online templates from two providers: `og` ([openapi-generator](https://github.com/OpenAPITools/openapi-generator)) and `sc` ([swagger-codegen](https://github.com/swagger-api/swagger-codegen)). The `--list` and `--filter` options allow you to see which templates are available. Note that using the online templates involves sending your API definition to a remote server.
7072

7173
### Contributors
7274

7375
See [here](https://github.com/swagger-api/swagger-codegen#template-creator) for a partial list of template contributors.
7476

7577
### Status of the template configurations
7678

77-
The templates with a status have a working (if not necessarily tested) configuration in the **configs** directory.
79+
The local templates with a status have a working (if not necessarily tested) configuration in the **configs** directory. Contributions are welcomed from the community of new and updated configurations and template updates.
7880

7981
<details>
8082
<summary>Click here to expand...</summary>
@@ -177,11 +179,3 @@ These templates are examples of how features of OpenAPI Codegen may be used, and
177179

178180
* [See here](docs/README.md) - contributions welcome
179181

180-
## See also
181-
182-
These projects use their own template model, not that of `swagger-codegen`
183-
184-
* https://github.com/fmvilas/swagger-node-codegen
185-
* https://github.com/wcandillon/swagger-js-codegen
186-
* https://github.com/Cian-Chambliss/swagger-codegen-prepare
187-

cg.js

+62-6
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,33 @@ const fetch = require('node-fetch');
1212
const co = require('co');
1313
const swagger2openapi = require('swagger2openapi');
1414
const stools = require('swagger-tools');
15+
const mkdirp = require('mkdirp');
16+
const rimraf = require('rimraf');
1517
const admzip = require('adm-zip');
1618

17-
const processor = require('./index.js');
19+
const processor = require('./local.js');
20+
const remote = require('./remote.js');
21+
22+
async function list(provider, filter) {
23+
process.exitCode = await remote.list(provider, filter);
24+
process.exit();
25+
}
1826

1927
var argv = require('yargs')
2028
.usage('cg [options] {[path]configName} {openapi-definition}')
2129
.boolean('debug')
2230
.alias('d','debug')
2331
.describe('debug','Turn on debugging information in the model')
32+
.string('filter')
33+
.describe('filter','Filter term to use with --list')
2434
.boolean('flat')
2535
.alias('f','flat')
2636
.describe('flat','Do not include config-name in output directory structure')
2737
.boolean('lint')
2838
.alias('l','lint')
2939
.describe('lint','Lint input definition')
40+
.string('list')
41+
.describe('list','List available templates for provider (og or sc)')
3042
.string('output')
3143
.alias('o','output')
3244
.describe('output','Specify output directory')
@@ -46,14 +58,21 @@ var argv = require('yargs')
4658
.version()
4759
.argv;
4860

61+
if (argv.list) {
62+
list(argv.list, argv.filter);
63+
}
64+
4965
let configStr = argv._[0] || 'nodejs';
5066
let configName = path.basename(configStr);
67+
let remoteConfig = configName.indexOf(':')>-1;
5168
let configPath = path.dirname(configStr);
5269
if (!configPath || (configPath === '.')) configPath = './configs';
5370
let configFile = path.resolve(configPath,configName)+'.json';
54-
let config = require(configFile);
71+
let config = remoteConfig ? { defaults: {} } : require(configFile);
5572
let defName = argv._[1] || './defs/petstore3.json';
5673

74+
let finish = remoteConfig ? finishRemote : finishLocal;
75+
5776
config.outputDir = argv.output;
5877
config.templateDir = argv.templates;
5978

@@ -70,7 +89,7 @@ function zipFile(filename,contents,encoding) {
7089
zipFiles[filename] = contents;
7190
}
7291

73-
function finish(err,result) {
92+
function finishLocal(err,result) {
7493
if (argv.zip) {
7594
// create archive
7695
var zip = new admzip();
@@ -84,6 +103,38 @@ function finish(err,result) {
84103
}
85104
}
86105

106+
function finishRemote(err,result) {
107+
configName = configName.split(':').pop();
108+
if (argv.verbose) console.log('Making/cleaning output directories');
109+
mkdirp(path.join(config.outputDir,configName),function(){
110+
rimraf(path.join(config.outputDir,configName)+'/*',function(){
111+
if (argv.zip) {
112+
fs.writeFileSync(path.join(config.outputDir,configName,configName+'.zip'),result);
113+
}
114+
else {
115+
const zip = new admzip(result);
116+
if (argv.verbose) {
117+
console.log('Unzipping...');
118+
const zipEntries = zip.getEntries(); // an array of ZipEntry records
119+
zipEntries.forEach(function(zipEntry) {
120+
console.log(zipEntry.entryName);
121+
});
122+
}
123+
zip.extractAllTo(config.outputDir,true);
124+
}
125+
});
126+
});
127+
}
128+
129+
function despatch(obj, config, configName, callback) {
130+
if (remoteConfig) {
131+
remote.main(obj, config, configName, callback);
132+
}
133+
else {
134+
processor.main(obj, config, configName, callback);
135+
}
136+
}
137+
87138
function convert20(obj){
88139
if (argv.verbose) console.log('Converting OpenAPI 2.0 definition');
89140
swagger2openapi.convertObj(obj,{patch:true,warnOnly:true,direct:true},function(err,openapi){
@@ -92,7 +143,7 @@ function convert20(obj){
92143
}
93144
else {
94145
config.defaults.swagger = obj;
95-
processor.main(openapi,config,configName,finish);
146+
despatch(openapi,config,configName,finish);
96147
}
97148
});
98149
}
@@ -176,14 +227,19 @@ function main(s) {
176227
if (argv.verbose) console.log('Loaded definition '+defName);
177228

178229
if (o && o.openapi) {
179-
processor.main(o,config,configName,finish);
230+
despatch(o,config,configName,finish);
180231
}
181232
else {
182233
if (o && o.swaggerVersion && o.swaggerVersion === '1.2') {
183234
convert12(o);
184235
}
185236
else if (o && o.swagger && o.swagger === '2.0') {
186-
convert20(o);
237+
if (remoteConfig) {
238+
despatch(o,config,configName,finish);
239+
}
240+
else {
241+
convert20(o);
242+
}
187243
}
188244
else {
189245
console.error('Unrecognised OpenAPI/Swagger version');

docs/modelProperties.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -156,5 +156,5 @@
156156
|hasEnums|model|false||
157157
|vars|model|[array]||
158158
|isMapContainer|model|false|boolean - set to true when container is a map|
159-
|isArrayContainer|model|false|boolean - set to true when container is a array|
159+
|isArrayContainer|model|false|boolean - set to true when container is an array|
160160
|itemsComplexType|vars|OrderDetails|Stores the name of the model for array elements|

index.js local.js

File renamed without changes.

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "openapi-codegen",
33
"version": "1.5.6",
44
"description": "OpenAPI 3.0 CodeGen",
5-
"main": "index.js",
5+
"main": "local.js",
66
"bin": {
77
"cg": "./cg.js"
88
},

remote.js

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// @ts-check
2+
'use strict';
3+
4+
const fetch = require('node-fetch');
5+
const util = require('util');
6+
7+
function getServer(prefix) {
8+
if (prefix === 'og') {
9+
return 'https://api.openapi-generator.tech/api/gen/';
10+
}
11+
else if (prefix === 'sc') {
12+
return 'https://generator.swagger.io/api/gen/';
13+
}
14+
console.warn('Unknown API provider prefix',prefix);
15+
return false;
16+
}
17+
18+
async function main(obj, config, configName, callback) {
19+
const components = configName.split(':');
20+
const prefix = components[0];
21+
const type = components[1];
22+
const template = components[2];
23+
const server = getServer(prefix);
24+
const body = { options: {}, spec: obj };
25+
const response = await fetch(server+type+'s/'+template, {
26+
method: 'post',
27+
body: JSON.stringify(body),
28+
headers: { 'Content-Type': 'application/json' }
29+
})
30+
.then(res => res.json())
31+
.then(json => json);
32+
if (response.link) {
33+
const zipfile = await fetch(response.link)
34+
.then(res => res.buffer())
35+
.then(buffer => buffer);
36+
callback(null, zipfile);
37+
}
38+
else {
39+
console.warn(util.inspect(response));
40+
}
41+
}
42+
43+
function format(templates, prefix, type, filter) {
44+
for (let template of templates) {
45+
if (!filter || (template.indexOf(filter)>-1)) {
46+
console.log(prefix+':'+type+':'+template);
47+
}
48+
}
49+
}
50+
51+
async function slurp(server, prefix, type, plural, filter) {
52+
await fetch(server+plural)
53+
.then(res => {
54+
return res.text();
55+
})
56+
.then(data => {
57+
format(JSON.parse(data), prefix, type, filter);
58+
})
59+
.catch(err => {
60+
console.error(util.inspect(err));
61+
});
62+
}
63+
64+
async function list(prefix, filter) {
65+
const server = getServer(prefix);
66+
if (server) {
67+
await slurp(server, prefix, 'client', 'clients', filter);
68+
await slurp(server, prefix, 'server', 'servers', filter);
69+
return 0;
70+
}
71+
return 1;
72+
}
73+
74+
module.exports = {
75+
main,
76+
list
77+
};
78+

0 commit comments

Comments
 (0)