in packages/extensions/modelerfour/src/modeler/modelerfour.ts [2160:2320]
processResponses(httpOperation: OpenAPI.HttpOperation, operation: Operation) {
const acceptTypes = new Set<string>();
const modelerResponses = httpOperation.responses;
// If the operation has final-state-schema lro option, add a "200" response if there isn't one already
if (httpOperation["x-ms-long-running-operation-options"]?.["final-state-schema"]) {
const finalStateSchema = httpOperation["x-ms-long-running-operation-options"]?.["final-state-schema"] as string;
if (!Object.keys(modelerResponses).some((k) => k === "200")) {
modelerResponses["200"] = {
description: "Success",
content: {
"application/json": {
schema: {
$ref: finalStateSchema,
},
},
},
};
}
}
// === Response ===
for (const { key: responseCode, value: response } of this.resolveDictionary(modelerResponses)) {
const isErr = responseCode === "default" || response["x-ms-error-response"];
const knownMediaTypes = this.filterMediaTypes(response.content);
if (knownMediaTypes.size === 0) {
// it has no actual response *payload*
// so we just want to create a simple response .
const rsp = new Response({
extensions: this.interpret.getExtensionProperties(response),
});
rsp.language.default.description = response.description;
const headers = this.processResponseHeaders(response.headers);
rsp.protocol.http = SetType(HttpResponse, {
statusCodes: [responseCode],
headers: headers.length ? headers : undefined,
});
if (isErr) {
operation.addException(rsp);
} else {
operation.addResponse(rsp);
}
} else {
for (const [knownMediaType, mediatypes] of knownMediaTypes.entries()) {
const allMt = mediatypes.map((each: any) => each.mediaType);
for (const mediaType of allMt) {
acceptTypes.add(mediaType);
}
const headers = this.processResponseHeaders(response.headers);
if (knownMediaType === KnownMediaType.Binary) {
// binary response needs different response type.
const rsp = new BinaryResponse({
extensions: this.interpret.getExtensionProperties(response),
});
rsp.language.default.description = response.description;
rsp.protocol.http = SetType(HttpBinaryResponse, {
statusCodes: [responseCode],
knownMediaType: knownMediaType,
mediaTypes: allMt,
headers: headers.length ? headers : undefined,
});
if (isErr) {
//op.addException(rsp);
// errors should not be binary streams!
throw new Error(`The response body should not be a binary! ${httpOperation.operationId}/${responseCode}`);
} else {
operation.addResponse(rsp);
}
continue;
}
const schema = mediatypes[0].schema.instance;
if (schema) {
let s = this.processSchema(mediatypes[0].schema.name || "response", schema);
// response schemas should not be constant types.
// this replaces the constant value with the value type itself.
if (s.type === SchemaType.Constant) {
s = (<ConstantSchema>s).valueType;
}
if (isErr) {
// Track the usage of this schema as an exception with media type
this.trackSchemaUsage(s, {
usage: [SchemaContext.Exception],
serializationFormats: [knownMediaType as KnownMediaType],
});
} else {
// Track the usage of this schema as an output with media type
this.trackSchemaUsage(s, {
usage: [SchemaContext.Output],
serializationFormats: [knownMediaType as KnownMediaType],
});
}
const rsp = new SchemaResponse(s, {
extensions: this.interpret.getExtensionProperties(response),
nullable: schema.nullable,
});
rsp.language.default.description = response.description;
rsp.protocol.http = SetType(HttpResponse, {
statusCodes: [responseCode],
knownMediaType: knownMediaType,
mediaTypes: allMt,
headers: headers.length ? headers : undefined,
});
if (isErr) {
operation.addException(rsp);
} else {
operation.addResponse(rsp);
}
}
}
}
}
function isAcceptHeaderParam(p: Parameter): boolean {
return p.protocol.http?.in === ParameterLocation.Header && p.language.default.serializedName === "Accept";
}
// Synthesize an 'Accept' header based on the media types in this
// operation and add it to all requests. Before adding the header,
// make sure there isn't an existing Accept parameter.
const mediaTypes = Array.from(acceptTypes);
if (this.options["always-create-accept-parameter"] === true && acceptTypes.size > 0) {
const acceptSchema = this.getAcceptParameterSchema(mediaTypes);
if (!operation.parameters?.find(isAcceptHeaderParam)) {
for (const request of operation.requests ?? []) {
if (request.parameters?.find(isAcceptHeaderParam)) {
// Already has an accept parameter, move on to the next.
continue;
}
request.addParameter(
new Parameter("accept", "Accept header", acceptSchema, {
implementation: ImplementationLocation.Method,
required: true,
origin: "modelerfour:synthesized/accept",
protocol: {
http: new HttpParameter(ParameterLocation.Header),
},
language: {
default: {
serializedName: "Accept",
},
},
}),
);
}
}
}
}