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

Commit 41292cc

Browse files
authored
Merge pull request #1 from Deadarius/support-recursive-schema
Support recursive schema
2 parents 6df0be3 + be14829 commit 41292cc

File tree

11 files changed

+1706
-544
lines changed

11 files changed

+1706
-544
lines changed

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "serverless-openapi-documentation",
3-
"version": "0.4.0",
3+
"version": "1.0.0",
44
"description": "Serverless 1.0 plugin to generate OpenAPI V3 documentation from serverless configuration",
55
"main": "index.js",
66
"repository": {
@@ -39,6 +39,7 @@
3939
"@types/fs-extra": "^4.0.0",
4040
"@types/jest": "^20.0.2",
4141
"@types/js-yaml": "^3.5.31",
42+
"@types/json-schema": "^7.0.3",
4243
"@types/node": "^8.0.7",
4344
"@types/uuid": "^3.0.0",
4445
"changelog-verify": "^1.0.4",
@@ -52,7 +53,6 @@
5253
"version-changelog": "^2.1.0"
5354
},
5455
"dependencies": {
55-
"@jdw/jst": "^2.0.0-beta.9",
5656
"bluebird": "^3.5.0",
5757
"chalk": "^2.0.1",
5858
"fs-extra": "^4.0.1",

src/DefinitionGenerator.ts

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
import { dereference } from '@jdw/jst';
1+
import { JSONSchema7 } from 'json-schema';
22
// tslint:disable-next-line no-submodule-imports
33
import { validateSync as openApiValidatorSync } from 'swagger2openapi/validate';
44
import * as uuid from 'uuid';
5+
56
import { IDefinition, IDefinitionConfig, IOperation, IParameterConfig, IServerlessFunctionConfig } from './types';
6-
import { clone, isIterable, merge } from './utils';
7+
import { clone, isIterable, merge, omit } from './utils';
78

89
export class DefinitionGenerator {
910
// The OpenAPI version we currently validate against
@@ -49,9 +50,16 @@ export class DefinitionGenerator {
4950
continue;
5051
}
5152

52-
this.definition.components.schemas[model.name] = this.cleanSchema(
53-
dereference(model.schema),
54-
);
53+
for (const definitionName of Object.keys(model.schema.definitions || {})) {
54+
const definition = model.schema.definitions[definitionName];
55+
if (typeof definition !== 'boolean') {
56+
this.definition.components.schemas[definitionName] = this.cleanSchema(this.updateReferences(definition));
57+
}
58+
}
59+
60+
const schemaWithoutDefinitions = omit(model.schema, ['definitions']);
61+
62+
this.definition.components.schemas[model.name] = this.cleanSchema(this.updateReferences(schemaWithoutDefinitions));
5563
}
5664
}
5765

@@ -116,6 +124,28 @@ export class DefinitionGenerator {
116124
return cleanedSchema;
117125
}
118126

127+
/**
128+
* Walks through the schema object recursively and updates references to point to openapi's components
129+
* @param schema JSON Schema Object
130+
*/
131+
private updateReferences (schema: JSONSchema7): JSONSchema7 {
132+
const cloned = clone(schema) as JSONSchema7;
133+
134+
if (cloned.$ref) {
135+
cloned.$ref = cloned.$ref.replace('#/definitions', '#/components/schemas');
136+
} else {
137+
for (const key of Object.getOwnPropertyNames(cloned)) {
138+
const value = cloned[key];
139+
140+
if (typeof value === 'object') {
141+
cloned[key] = this.updateReferences(value);
142+
}
143+
}
144+
}
145+
146+
return cloned;
147+
}
148+
119149
/**
120150
* Generate Operation objects from the Serverless Config.
121151
*

src/types.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1+
import { JSONSchema7 } from 'json-schema';
12

23
export interface IModels {
34
name: string;
45
description: string;
56
contentType: string;
6-
schema: object | any[];
7+
schema: JSONSchema7;
78
examples: any[];
89
example: object;
910
}

src/utils.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,13 @@ export function isIterable (obj) {
1010

1111
return typeof obj[Symbol.iterator] === 'function';
1212
}
13+
14+
export function omit<T extends object> (obj: T, keys: string[]): T {
15+
const cloned = clone(obj);
16+
17+
for (const key of keys) {
18+
delete cloned[key];
19+
}
20+
21+
return cloned;
22+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema#",
3+
"definitions": {
4+
"folder": {
5+
"type": "object",
6+
"title": "Folder Schema",
7+
"properties": {
8+
"id": {
9+
"type": "string",
10+
"example": "3ba1c69c-3c81-4d6d-b304-873d898b2e3c",
11+
"format": "uuid"
12+
},
13+
"folders": {
14+
"type": "array",
15+
"items": {
16+
"$ref": "#/definitions/folder"
17+
}
18+
}
19+
},
20+
"additionalProperties": false,
21+
"required": ["id", "name", "folders", "checklists"]
22+
}
23+
},
24+
"type": "object",
25+
"title": "Folders Response Schema",
26+
"properties": {
27+
"data": {
28+
"$ref": "#/definitions/folder"
29+
}
30+
}
31+
}

0 commit comments

Comments
 (0)