Skip to content
This repository was archived by the owner on Dec 10, 2021. It is now read-only.

Commit c1db182

Browse files
committed
Refactor build to dist, add more test scripts and fix brittle test paths
1 parent 983d6d5 commit c1db182

18 files changed

+178
-179
lines changed

Diff for: .gitignore

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
node_modules
22
/npm-*
3-
/dist
3+
/build
44
.coverage
55
.directory
66
.DS_STORE*

Diff for: .travis.yml

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ install:
1010
script:
1111
- yarn lint
1212
- yarn build
13+
- yarn test:build
1314
- DEBUG=true yarn test:coverage
1415

1516
deploy:

Diff for: jest.config.js

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ module.exports = {
66
"coverageDirectory": ".coverage",
77
"testPathIgnorePatterns": [
88
"/node_modules/",
9+
"/build/",
910
"d.ts"
1011
]
1112
}

Diff for: package.json

+3-5
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,19 @@
22
"name": "serverless-openapi-documentation",
33
"version": "0.0.0",
44
"description": "Serverless 1.0 plugin to generate OpenAPI V3 documentation from serverless configuration",
5-
"main": "dist/index.js",
5+
"main": "index.js",
66
"author": "Abilio Henrique <[email protected]>",
77
"contributors": [
88
"Abilio Henrique <[email protected]>",
99
1010
],
1111
"license": "MIT",
12-
"files": [
13-
"dist"
14-
],
1512
"scripts": {
1613
"test": "jest",
14+
"test:build": "jest -c '{}' build",
1715
"test:coverage": "jest --coverage",
1816
"lint": "tslint 'src/**/*.ts'",
19-
"release": "cd dist && npm publish",
17+
"release": "cd build && npm publish",
2018
"build": "scripts/build.bash"
2119
},
2220
"devDependencies": {

Diff for: scripts/build.bash

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
#!/bin/bash
22

33
# Clean
4-
rm -rf dist
5-
mkdir dist
4+
rm -rf build
5+
mkdir build
66

77
# Copy latent, belonging to the index module
8-
rsync -am . ./dist --exclude '*/*' --include '*'
8+
rsync -am . ./build --exclude '*/*' --include '*'
99

1010
# Copy latent files from source, recursively
11-
rsync -am ./src/* ./dist --exclude '*.ts'
11+
rsync -am ./src/* ./build --exclude '*.ts'
1212

1313
# Build typescript
1414
yarn tsc

Diff for: src/generate.ts renamed to src/DocumentGenerator.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import * as uuid from 'uuid';
66
import { IParameterConfig, IServerlessFunctionConfig, IServiceDescription } from './types';
77
import { clone, merge } from './utils';
88

9-
export default class DocumentGenerator {
9+
export class DocumentGenerator {
1010
// The OpenAPI version we currently validate against
1111
private openapiVersion = '3.0.0-RC1';
1212

Diff for: src/ServerlessOpenApiDocumentation.ts

+134
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
import * as c from 'chalk';
2+
import * as fs from 'fs';
3+
import * as YAML from 'js-yaml';
4+
import { DocumentGenerator } from './DocumentGenerator';
5+
import { IConfigType } from './types';
6+
import { merge } from './utils';
7+
8+
export class ServerlessOpenApiDocumentation {
9+
public hooks;
10+
public commands;
11+
/** Serverless Instance */
12+
private serverless;
13+
/** CLI options */
14+
private options;
15+
/** Serverless Service Custom vars */
16+
private customVars;
17+
18+
/**
19+
* Constructor
20+
* @param serverless
21+
* @param options
22+
*/
23+
constructor (serverless, options) {
24+
// pull the serverless instance into our class vars
25+
this.serverless = serverless;
26+
// pull the CLI options into our class vars
27+
this.options = options;
28+
// Serverless service custom variables
29+
this.customVars = this.serverless.variables.service.custom;
30+
31+
// Declare the commands this plugin exposes for the Serverless CLI
32+
this.commands = {
33+
openapi: {
34+
commands: {
35+
generate: {
36+
lifecycleEvents: [
37+
'serverless',
38+
],
39+
usage: 'Generate OpenAPI v3 Documentation',
40+
options: {
41+
output: {
42+
usage: 'Output file location [default: openapi.yml|json]',
43+
shortcut: 'o',
44+
},
45+
format: {
46+
usage: 'OpenAPI file format (yml|json) [default: yml]',
47+
shortcut: 'f',
48+
},
49+
indent: {
50+
usage: 'File indentation in spaces[default: 2]',
51+
shortcut: 'i',
52+
},
53+
},
54+
},
55+
},
56+
},
57+
};
58+
59+
// Declare the hooks our plugin is interested in
60+
this.hooks = {
61+
'openapi:generate:serverless': this.generate.bind(this),
62+
};
63+
}
64+
65+
/**
66+
* Processes CLI input by reading the input from serverless
67+
* @returns config IConfigType
68+
*/
69+
private processCliInput (): IConfigType {
70+
const config: IConfigType = {
71+
format: 'yaml',
72+
file: 'openapi.yml',
73+
indent: 2,
74+
};
75+
76+
config.indent = this.serverless.processedInput.options.indent || 2;
77+
config.format = this.serverless.processedInput.options.format || 'yaml';
78+
79+
if (['yaml', 'json'].indexOf(config.format.toLowerCase()) < 0) {
80+
throw new Error('Invalid Output Format Specified - must be one of "yaml" or "json"');
81+
}
82+
83+
config.file = this.serverless.processedInput.options.output ||
84+
((config.format === 'yaml') ? 'openapi.yml' : 'openapi.json');
85+
86+
process.stdout.write(
87+
`${c.bold.green('[OPTIONS]')} ` +
88+
`format: "${c.bold.red(config.format)}", ` +
89+
`output file: "${c.bold.red(config.file)}", ` +
90+
`indentation: "${c.bold.red(String(config.indent))}"\n\n`,
91+
);
92+
return config;
93+
}
94+
95+
/**
96+
* Generates OpenAPI Documentation based on serverless configuration and functions
97+
*/
98+
private generate () {
99+
process.stdout.write(c.bold.underline('OpenAPI v3 Documentation Generator\n\n'));
100+
// Instantiate DocumentGenerator
101+
const dg = new DocumentGenerator(this.customVars.documentation);
102+
103+
// Map function configurations
104+
const funcConfigs = this.serverless.service.getAllFunctions().map((functionName) => {
105+
const func = this.serverless.service.getFunction(functionName);
106+
return merge({ _functionName: functionName }, func);
107+
});
108+
109+
// Add Paths to OpenAPI Output from Function Configuration
110+
dg.addPathsFromFunctionConfig(funcConfigs);
111+
112+
// Process CLI Input options
113+
const config = this.processCliInput();
114+
115+
// Generate the resulting OpenAPI Object
116+
const outputObject = dg.generate();
117+
118+
// Output the OpenAPI document to the correct format
119+
let outputContent = '';
120+
switch (config.format.toLowerCase()) {
121+
case 'json':
122+
outputContent = JSON.stringify(outputObject, null, config.indent);
123+
break;
124+
case 'yaml':
125+
default:
126+
outputContent = YAML.safeDump(outputObject, { indent: config.indent });
127+
break;
128+
}
129+
130+
// Write to disk
131+
fs.writeFileSync(config.file, outputContent);
132+
process.stdout.write(`${ c.bold.green('[SUCCESS]') } Output file to "${c.bold.red(config.file)}"\n`);
133+
}
134+
}

Diff for: test/openapi-generate.test.ts renamed to src/__tests__/DocumentGenerator.spec.ts

+7-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
import * as fs from 'fs-extra';
21
import * as path from 'path';
32
import * as Serverless from 'serverless';
4-
import DocumentGenerator from '../src/generate';
3+
import { DocumentGenerator } from '../DocumentGenerator';
54

65
class ServerlessInterface extends Serverless {
76
public service: any = {};
@@ -13,21 +12,24 @@ class ServerlessInterface extends Serverless {
1312

1413
describe('OpenAPI Documentation Generator', () => {
1514
it('Generates OpenAPI document', async () => {
16-
const serverlessConfig = await fs.readFile('test/fixtures/serverless.yml');
15+
const servicePath = path.join(__dirname, './fixtures');
16+
const serverlessYamlPath = path.join(servicePath, './serverless.yml');
1717
const sls: ServerlessInterface = new Serverless();
1818

1919
sls.config.update({
20-
servicePath: path.join(process.cwd(), 'test/fixtures'),
20+
servicePath,
2121
});
2222

23-
const config = await sls.yamlParser.parse(path.join(process.cwd(), 'test/fixtures/serverless.yml'));
23+
const config = await sls.yamlParser.parse(serverlessYamlPath);
2424
sls.pluginManager.cliOptions = { stage: 'dev' };
2525

2626
await sls.service.load(config);
2727
await sls.variables.populateService();
2828

2929
if ('documentation' in sls.service.custom) {
3030
const docGen = new DocumentGenerator(sls.service.custom.documentation);
31+
32+
expect(docGen).not.toBeNull();
3133
} else {
3234
throw new Error('Cannot find "documentation" in custom section of "serverless.yml"');
3335
}
File renamed without changes.
File renamed without changes.

Diff for: src/__tests__/fixtures/tsconfig.json

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"compilerOptions": {
3+
"target": "es6",
4+
"module": "commonjs",
5+
"moduleResolution": "node",
6+
"outDir":"./build",
7+
"sourceMap": true,
8+
"declaration": true,
9+
"lib": [
10+
"es6",
11+
"es7",
12+
"dom"
13+
]
14+
},
15+
"exclude": [],
16+
"include": [
17+
"src/**/*"
18+
]
19+
}
File renamed without changes.

0 commit comments

Comments
 (0)