UNPKG

counterfact

Version:

Generate a TypeScript-based mock server from an OpenAPI spec in seconds — with stateful routes, hot reload, and REPL support.

105 lines (104 loc) 3.89 kB
import { printObject } from "./printers.js"; import { SchemaTypeCoder } from "./schema-type-coder.js"; import { STREAMING_CONTENT_TYPES } from "./streaming-content-types.js"; import { TypeCoder } from "./type-coder.js"; import { pathJoin } from "../util/forward-slash-path.js"; export class ResponseTypeCoder extends TypeCoder { openApi2MediaTypes; constructor(requirement, version = "", openApi2MediaTypes = []) { super(requirement, version); this.openApi2MediaTypes = openApi2MediaTypes; } names() { return super.names(this.requirement.refUrl.split("/").at(-1)); } buildContentObjectType(script, response) { if (response.has("content")) { return response .get("content") .map((content, mediaType) => { let schemaType; if (content.has("itemSchema") && STREAMING_CONTENT_TYPES.has(mediaType)) { schemaType = `AsyncIterable<${new SchemaTypeCoder(content.get("itemSchema"), this.version).write(script)}>`; } else { schemaType = content.has("schema") ? new SchemaTypeCoder(content.get("schema"), this.version).write(script) : "unknown"; } return [ mediaType, `{ schema: ${schemaType} }`, ]; }); } return this.openApi2MediaTypes.map((mediaType) => [ mediaType, `{ schema: ${new SchemaTypeCoder(response.get("schema"), this.version).write(script)} }`, ]); } printContentObjectType(script, response) { if (response.has("content") || response.has("schema")) { return printObject(this.buildContentObjectType(script, response)); } return "never"; } buildHeaders(script, response) { return response .get("headers") .map((value, name) => [ name, `{ schema: ${new SchemaTypeCoder(value.get("schema") ?? value, this.version).write(script)}}`, ]); } printHeaders(script, response) { if (!response.has("headers")) { return "never"; } return printObject(this.buildHeaders(script, response)); } printRequiredHeaders(response) { const requiredHeaders = (response.get("headers")?.map((value, name) => ({ name, required: value.data.required, })) ?? []) .filter(({ required }) => required) .map(({ name }) => `"${name}"`); return requiredHeaders.length === 0 ? "never" : requiredHeaders.join(" | "); } buildExamplesObjectType(response) { if (!response.has("content")) { return "{}"; } const exampleNames = []; response.get("content").forEach((content) => { if (content.has("examples")) { content.get("examples").forEach((_, name) => { if (!exampleNames.includes(name)) { exampleNames.push(name); } }); } }); if (exampleNames.length === 0) { return "{}"; } return printObject(exampleNames.map((name) => [name, "unknown"])); } modulePath() { return pathJoin("types", this.version, this.requirement.refUrl + ".ts"); } writeCode(script) { return `{ headers: ${this.printHeaders(script, this.requirement)}; requiredHeaders: ${this.printRequiredHeaders(this.requirement)}; content: ${this.printContentObjectType(script, this.requirement)}; examples: ${this.buildExamplesObjectType(this.requirement)}; }`; } }