Skip to content

Commit

Permalink
fix(types): fixing responses on http, and conflicting types in tests
Browse files Browse the repository at this point in the history
  • Loading branch information
SamWSoftware committed Jan 19, 2022
1 parent 186f3a4 commit 138626f
Show file tree
Hide file tree
Showing 5 changed files with 366 additions and 307 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ You can then assign these typescript definitions to requests as `bodyType` on th
You can also add expected responses to each of the http endpoint events. This is an object that contains the response code with some example details:
```js
responses: {
responseData: {
// response with description and response body
200: {
description: 'this went well',
Expand Down Expand Up @@ -113,14 +113,17 @@ http: {
![Query String Parameters](./doc_images/queryStringParams.png)

### Exclude an endpoint

You can exclude some endpoints from the swagger generation by adding `exclude` to the http event:

```
http: {
path: 'hello',
method: 'post',
exclude: true,
}
```

## with Serverless Offline

In the plugin list, you must list serverless-auto-swagger before the serverless-offline plugin. If you don't you won't get the required endpoints added to your local endpoints.
96 changes: 47 additions & 49 deletions src/ServerlessAutoSwagger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,42 +54,41 @@ class ServerlessAutoSwagger {
};
}


registerOptions = () => {
this.serverless.configSchemaHandler.defineFunctionEventProperties('aws', 'http', {
this.serverless.configSchemaHandler?.defineFunctionEventProperties('aws', 'http', {
properties: {
exclude: {
type: 'boolean',
nullable: true,
defaultValue: false
defaultValue: false,
},
swaggerTags: {
type: 'array',
nullable: true,
items: {type: 'string'}
items: { type: 'string' },
},
responses: {
type: 'object',
nullable: true,
additionalProperties: {
anyOf: [
{
type: 'string'
type: 'string',
},
{
type: 'object',
required: [],
properties: {
description: {
type: 'string'
type: 'string',
},
bodyType: {
type: 'string'
}
}
}
]
}
type: 'string',
},
},
},
],
},
},
queryStringParameters: {
type: 'object',
Expand All @@ -104,19 +103,19 @@ class ServerlessAutoSwagger {
},
type: {
type: 'string',
enum: ['string', 'integer']
enum: ['string', 'integer'],
},
description: {
type: 'string',
nullable: true
nullable: true,
},
minimum: {
type: 'number',
nullable: true
}
}
}
}
nullable: true,
},
},
},
},
},
required: [],
});
Expand All @@ -133,35 +132,34 @@ class ServerlessAutoSwagger {
};

gatherSwaggerFiles = async () => {
const swaggerFiles = this.serverless.service.custom?.autoswagger
?.swaggerFiles as string[];
const swaggerFiles = this.serverless.service.custom?.autoswagger?.swaggerFiles as string[];

if (!swaggerFiles || swaggerFiles.length < 1) {
return;
}

await Promise.all(swaggerFiles.map(async (filepath) => {
const fileData = fs.readFileSync(filepath, 'utf8');

const jsonData = JSON.parse(fileData);


const { paths = {}, definitions = {}, ...swagger } = jsonData;


this.swagger = {
...this.swagger,
...swagger,
paths: {
...this.swagger.paths,
...paths,
},
definitions: {
...this.swagger.definitions,
...definitions,
}
};
}));
await Promise.all(
swaggerFiles.map(async filepath => {
const fileData = fs.readFileSync(filepath, 'utf8');

const jsonData = JSON.parse(fileData);

const { paths = {}, definitions = {}, ...swagger } = jsonData;

this.swagger = {
...this.swagger,
...swagger,
paths: {
...this.swagger.paths,
...paths,
},
definitions: {
...this.swagger.definitions,
...definitions,
},
};
})
);
};

gatherTypes = async () => {
Expand Down Expand Up @@ -222,15 +220,15 @@ class ServerlessAutoSwagger {
await this.gatherTypes();

this.generatePaths();

this.serverless.cli.log(`Creating your Swagger File now`);

// TODO enable user to specify swagger file path. also needs to update the swagger json endpoint.

await fs.copy('./node_modules/serverless-auto-swagger/dist/resources', './swagger');
if (this.serverless.service.provider.runtime.includes('python')) {
const swaggerPythonString = `# this file was generated by serverless-auto-swagger
docs = ${JSON.stringify(this.swagger, null, 2)}`
docs = ${JSON.stringify(this.swagger, null, 2)}`;
await writeFile('./swagger/swagger.py', swaggerPythonString);
} else {
const swaggerJavaScriptString = `// this file was generated by serverless-auto-swagger
Expand Down Expand Up @@ -286,15 +284,15 @@ docs = ${JSON.stringify(this.swagger, null, 2)}`
consumes: ['application/json'],
produces: ['application/json'],
parameters: this.httpEventToParameters(http),
responses: this.formatResponses(http.responses),
responses: this.formatResponses(http.responseData || http.responses),
security: this.httpEventToSecurity(http),
};
});
});
};

formatResponses = (responses: HttpResponses | undefined) => {
if (!responses) {
formatResponses = (responseData: HttpResponses | undefined) => {
if (!responseData) {
// could throw error
return {
200: {
Expand All @@ -303,7 +301,7 @@ docs = ${JSON.stringify(this.swagger, null, 2)}`
};
}
const formatted: { [key: string]: Response } = {};
Object.entries(responses).map(([statusCode, responseDetails]) => {
Object.entries(responseData).map(([statusCode, responseDetails]) => {
if (typeof responseDetails == 'string') {
formatted[statusCode] = {
description: responseDetails,
Expand Down
6 changes: 4 additions & 2 deletions src/resources/functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ import { ServerlessFunction, Serverless } from '../serverlessPlugin';

export default (serverless: Serverless) => {
const handlerPath = 'swagger/';
const configInput = serverless?.configurationInput || serverless.service;
const path = serverless.service.custom?.autoswagger?.swaggerPath ?? 'swagger';
const name = serverless.configurationInput?.service?.name;
const stage = serverless.configurationInput?.provider?.stage;
const name =
typeof configInput?.service == 'object' ? configInput.service.name : configInput.service;
const stage = configInput?.provider?.stage;
return {
swaggerUI: {
name: name && stage ? `${name}-${stage}-swaggerUI` : undefined,
Expand Down
20 changes: 13 additions & 7 deletions src/serverlessPlugin.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,19 @@ export interface Serverless {
};
service: ServerlessConfig;
configurationInput: {
service?: { name?: string },
service?: string | { name?: string };
provider?: {
stage?: string
}
},
stage?: string;
};
};
configSchemaHandler: {
defineCustomProperties(schema: unknown): void;
defineFunctionEvent(provider: string, event: string, schema: Record<string, unknown>): void;
defineFunctionEventProperties(provider: string, existingEvent: string, schema: unknown): void;
defineFunctionEventProperties(
provider: string,
existingEvent: string,
schema: unknown
): void;
defineFunctionProperties(provider: string, schema: unknown): void;
defineProvider(provider: string, options?: Record<string, unknown>): void;
defineTopLevelProperty(provider: string, schema: Record<string, unknown>): void;
Expand Down Expand Up @@ -54,7 +58,8 @@ export interface FullHttpEvent {
cors?: boolean | CorsConfig;
swaggerTags?: string[];
description?: string;
responses?: HttpResponses;
responseData?: HttpResponses;
responses?: HttpResponses; // Ideally don't use as it conflicts with serverless offline
exclude?: boolean;
bodyType?: string;
queryStringParameters?: Record<
Expand All @@ -80,7 +85,8 @@ export interface FullHttpApiEvent {
method: string;
swaggerTags?: string[];
description?: string;
responses?: HttpResponses;
responseData?: HttpResponses;
responses?: HttpResponses; // Ideally don't use as it conflicts with serverless offline
exclude?: boolean;
bodyType?: string;
queryStringParameterType?: string;
Expand Down
Loading

0 comments on commit 138626f

Please sign in to comment.