-
Notifications
You must be signed in to change notification settings - Fork 11
/
responses.ts
118 lines (105 loc) · 4.3 KB
/
responses.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import { isPlainObject } from '@stoplight/json';
import type {
DeepPartial,
IBundledHttpService,
IHttpOperationResponse,
IMediaTypeContent,
Optional,
} from '@stoplight/types';
import { pickBy } from 'lodash';
import type { Operation, Reference } from 'swagger-schema-official';
import { withContext } from '../../context';
import { isNonNullable } from '../../guards';
import { isReferenceObject } from '../../oas/guards';
import { getSharedKey, setSharedKey } from '../../oas/resolver';
import { translateToDefaultExample } from '../../oas/transformers/examples';
import { translateSchemaObject } from '../../oas/transformers/schema';
import { Fragment } from '../../types';
import { entries } from '../../utils';
import { getExamplesFromSchema, getProduces } from '../accessors';
import { isResponseObject } from '../guards';
import { Oas2TranslateFunction } from '../types';
import { translateToHeaderParams } from './params';
export const translateToResponse = withContext<
Oas2TranslateFunction<
[produces: string[], statusCode: string, response: unknown],
Optional<IHttpOperationResponse<true> | (Pick<IHttpOperationResponse<true>, 'code'> & Reference)>
>
>(function (produces, statusCode, response) {
const maybeResponseObject = this.maybeResolveLocalRef(response) ?? response;
if (isReferenceObject(maybeResponseObject)) {
(maybeResponseObject as Pick<IHttpOperationResponse, 'code'> & Reference).code = statusCode;
return maybeResponseObject as Pick<IHttpOperationResponse, 'code'> & Reference;
}
if (!isResponseObject(maybeResponseObject)) return;
const codeOrKey = this.context === 'service' ? getSharedKey(maybeResponseObject, statusCode) : statusCode;
const id = this.generateId.httpResponse({ codeOrKey, produces });
const headers = translateToHeaderParams.call(this, maybeResponseObject.headers);
const objectifiedExamples = entries(
maybeResponseObject.examples || getExamplesFromSchema(maybeResponseObject.schema),
).map(([key, value]) => translateToDefaultExample.call(this, key, value));
const contents = produces
.map<IMediaTypeContent<true> & { examples: NonNullable<IMediaTypeContent<true>['examples']> }>(
withContext(produceElement => {
return {
id: this.generateId.httpMedia({ mediaType: produceElement }),
mediaType: produceElement,
examples: objectifiedExamples.filter(example => example.key === produceElement),
...pickBy(
{
schema: isPlainObject(maybeResponseObject.schema)
? translateSchemaObject.call(this, maybeResponseObject.schema)
: undefined,
},
isNonNullable,
),
};
}),
this,
)
.filter(({ schema, examples }) => !!schema || examples.length > 0);
const translatedResponse = {
id,
code: statusCode,
description: maybeResponseObject.description,
headers,
contents,
};
const foreignExamples = objectifiedExamples.filter(example => !produces.includes(example.key));
if (foreignExamples.length > 0) {
if (translatedResponse.contents.length === 0)
translatedResponse.contents[0] = {
id: this.generateId.httpMedia({ mediaType: '' }),
mediaType: '',
schema: {},
examples: [],
};
translatedResponse.contents[0].examples!.push(...foreignExamples);
}
return translatedResponse;
});
export const translateToResponses: Oas2TranslateFunction<
[operation: DeepPartial<Operation>],
NonNullable<ReturnType<typeof translateToResponse>>[]
> = function (operation) {
const produces = getProduces(this.document, operation);
return entries(operation.responses)
.map(([statusCode, response]) => translateToResponse.call(this, produces, statusCode, response))
.filter(isNonNullable);
};
type ResponsesComponents = Pick<IBundledHttpService['components'], 'responses'>;
export const translateToSharedResponses: Oas2TranslateFunction<[root: Fragment], ResponsesComponents> = function (
root,
) {
const sharedResponses: ResponsesComponents = {
responses: [],
};
for (const [key, value] of entries(root.responses)) {
setSharedKey(value, key);
sharedResponses.responses.push({
key,
...(translateToResponse.call(this, ['application/x-stoplight-placeholder'], key, value) as any),
});
}
return sharedResponses;
};