Skip to content

Commit 9b93465

Browse files
Create composite params for post methods
1 parent 8f6f6ba commit 9b93465

File tree

2 files changed

+67
-34
lines changed

2 files changed

+67
-34
lines changed

OpenApi.ts

Lines changed: 66 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ interface IBuildParametersArguments {
3131

3232
const PATH_VARIABLES_REGEX = /:([A-Za-z]+)/g
3333

34+
function resolveBodySchemaName(route: Route): string {
35+
return `${route.operationName}Body`;
36+
}
37+
3438
function translateScalarType(scalarType: string): string {
3539
switch (scalarType) {
3640
case 'Int':
@@ -74,6 +78,19 @@ function buildObjectDefinition(node: any): any {
7478
return objectDoc;
7579
}
7680

81+
function buildBodyDefinition(variables: IOperationVariable[], refLocation: string): any {
82+
const bodyDoc: any = {};
83+
84+
bodyDoc.type = 'object';
85+
bodyDoc.properties = {};
86+
87+
variables.forEach((field: IOperationVariable) => {
88+
bodyDoc.properties[field.name] = buildSchemaParameter(field, refLocation);
89+
});
90+
91+
return bodyDoc;
92+
}
93+
7794
function buildDefinition(node: any): any {
7895
switch (node.kind) {
7996
case 'INPUT_OBJECT':
@@ -107,32 +124,31 @@ function openApiPath(path: string): string {
107124
return path.replace(PATH_VARIABLES_REGEX, '{$1}');
108125
}
109126

127+
function buildSchemaParameter(variableDefinition: IOperationVariable, refLocation: string): IParameterArraySchema | IParameterItemTypeOrRef {
128+
if (variableDefinition.array) {
129+
return {
130+
type: 'array',
131+
items: {
132+
'$ref': `${refLocation}/${variableDefinition.type}`
133+
},
134+
};
135+
}
136+
137+
return {
138+
'$ref': `${refLocation}/${variableDefinition.type}`
139+
};
140+
}
141+
110142
// TODO: Return Type and Attempt to get description from graphql
111143
function buildParametersArray({ variableDefinitions, variableLocation, refLocation }: IBuildParametersArguments): IParameter[] {
112144
return variableDefinitions.map(
113-
(variableDefinition: IOperationVariable): IParameter => {
114-
const parameter: IParameter = {
115-
name: variableDefinition.name,
116-
required: variableDefinition.required,
117-
// default: variableDefinition.defaultValue,
118-
in: variableLocation,
119-
};
120-
121-
if (variableDefinition.array) {
122-
parameter.schema = {
123-
type: 'array',
124-
items: {
125-
'$ref': `${refLocation}/${variableDefinition.type}`
126-
},
127-
};
128-
} else {
129-
parameter.schema = {
130-
'$ref': `${refLocation}/${variableDefinition.type}`
131-
};
132-
}
133-
134-
return parameter;
135-
}
145+
(variableDefinition: IOperationVariable): IParameter => ({
146+
name: variableDefinition.name,
147+
required: variableDefinition.required,
148+
in: variableLocation,
149+
schema: buildSchemaParameter(variableDefinition, refLocation),
150+
// default: variableDefinition.defaultValue,
151+
})
136152
);
137153
}
138154

@@ -322,6 +338,7 @@ export class V3 extends MountableDocument {
322338
const { options } = this;
323339

324340
const doc: any = {};
341+
const refLocation = '#/components/schemas';
325342

326343
doc.openapi = '3.0.0';
327344
doc.info = {};
@@ -368,25 +385,31 @@ export class V3 extends MountableDocument {
368385
...buildParametersArray({
369386
variableDefinitions: route.queryVariables,
370387
variableLocation: 'query',
371-
refLocation: '#/components/schemas',
388+
refLocation,
372389
})
373390
);
374391

375392
routeDoc.parameters.push(
376393
...buildParametersArray({
377394
variableDefinitions: route.pathVariables,
378395
variableLocation: 'path',
379-
refLocation: '#/components/schemas',
396+
refLocation,
380397
})
381398
);
382399

383-
routeDoc.parameters.push(
384-
...buildParametersArray({
385-
variableDefinitions: route.bodyVariables,
386-
variableLocation: 'body',
387-
refLocation: '#/components/schemas',
388-
})
389-
);
400+
if (route.bodyVariables.length) {
401+
const schemaName = resolveBodySchemaName(route);
402+
403+
routeDoc.requestBody = {
404+
content: {
405+
'application/json': {
406+
schema: {
407+
"$ref": `${refLocation}/${schemaName}`
408+
},
409+
},
410+
},
411+
};
412+
}
390413
});
391414

392415
doc.components = {};
@@ -401,6 +424,17 @@ export class V3 extends MountableDocument {
401424
doc.components.schemas[variableName] = buildDefinition(variableDefinition);
402425
});
403426

427+
// Build out definitions for each route to contain a "body" schema in case it's used
428+
// for anything besides GET
429+
router.routes.forEach(
430+
(route) => {
431+
const schemaName = resolveBodySchemaName(route);
432+
433+
doc.components.schemas[schemaName] =
434+
buildBodyDefinition(route.bodyVariables, refLocation);
435+
}
436+
);
437+
404438
return doc;
405439
} catch (error) {
406440
return {

Route.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ export default class Route implements IMountableItem {
4848

4949
public passThroughHeaders: string[] = [];
5050
public operationVariables!: IOperationVariable[];
51+
public operationName!: string;
5152

5253
// TODO:
5354
// The route should be frozen on any type of export
@@ -60,8 +61,6 @@ export default class Route implements IMountableItem {
6061
private axios!: AxiosInstance;
6162
private schema!: DocumentNode;
6263

63-
private operationName!: string;
64-
6564
private transformRequestFn: AxiosTransformer[] = [];
6665
private transformResponseFn: AxiosTransformer[] = [];
6766

0 commit comments

Comments
 (0)