UNPKG

@frostup/swr-request-generator

Version:

A tool for generating TypeScript code and interface from swagger by using SWR and axios as client.

171 lines (140 loc) 4.68 kB
import { get, indexOf, map, reduce } from "lodash"; import { Schema } from "@openapi-integration/openapi-schema"; import { isArray, isObject } from "../utils/specifications"; import { addPrefixForInterface, toCapitalCase } from "../utils/formatters"; import { ISchemaResolverInputs, TDictionary } from "../types"; import { ENUM_SUFFIX } from "../constants"; export class SchemaResolver { private schemaType: TDictionary<any> | string = {}; static of(inputs: ISchemaResolverInputs) { return new SchemaResolver(inputs); } constructor(private inputs: ISchemaResolverInputs) {} getSchemaType = () => this.schemaType; resolve = (type?: string) => { const { schema = {}, results, parentKey, key } = this.inputs; const advancedType = this.resolveRef(schema.$ref, type || schema.type); if (schema.$ref) { this.schemaType = advancedType; return this; } if (schema.allOf || schema.oneOf || schema.anyOf) { const schemas = schema.oneOf || schema.allOf || schema.anyOf; this.schemaType = this.resolveRef((schemas ?? [])[0].$ref, type || schema.type); return this; } if (schema.items) { this.schemaType = this.resolveItems(schema.items, schema.type, key, parentKey); return this; } if (schema.enum) { const enumKey = this.getEnumName(key!, parentKey); // Implicit operation!: Assign enum array definition to results results[enumKey] = schema.enum; this.schemaType = enumKey; return this; } if (schema.type === "object") { if (schema.properties) { this.schemaType = this.resolveProperties(schema.properties, schema.required, parentKey); return this; } if (schema.title) { this.schemaType = schema.type; return this; } this.schemaType = "{[key:string]:any}"; return this; } if (schema.type === "string" && schema.format === "binary") { this.schemaType = "FormData"; return this; } this.schemaType = this.getBasicType(schema.type, advancedType); return this; }; resolveNullable = () => { if (this.inputs.schema?.nullable) { this.schemaType = isObject(this.schemaType) ? `${JSON.stringify(this.schemaType)} | null` : `${this.schemaType} | null`; } return this; }; getEnumName = (propertyName: string, parentKey: string = "") => `${toCapitalCase(parentKey)}${toCapitalCase(propertyName)}${ENUM_SUFFIX}`; resolveRef = ($ref?: string, type?: string): string => { if (!$ref) { return ""; } const refType = addPrefixForInterface(toCapitalCase(this.pickTypeByRef($ref))); return type === "array" ? `${refType}[]` : refType; }; getBasicType = (basicType: string = "", advancedType?: string): string => { switch (basicType) { case "integer": return "number"; case "array": return this.getTypeForArray(advancedType); case "": return advancedType || ""; default: return basicType; } }; getTypeForArray = (advancedType?: string) => (advancedType ? `${advancedType}[]` : "Array<any>"); pickTypeByRef = (str?: string) => { if (!str) { return; } const list = str.split("/"); return list[list.length - 1]; }; resolveItems = (items?: Schema | Schema[], type?: string, key?: string, parentKey?: string): any => { if (!items) { return {}; } const child = get(items, "items"); if (type === "array") { if (child) { return `${this.resolveItems(child, (items as any).type, key, parentKey)}[]`; } if (!get(items, "$ref")) { return `${get(items, "type")}[]`; } } if (isArray(items)) { return map(items, (item) => SchemaResolver.of({ results: this.inputs.results, schema: item as Schema, key, parentKey }) .resolve() .resolveNullable() .getSchemaType(), ); } return SchemaResolver.of({ results: this.inputs.results, schema: items as Schema, key, parentKey }) .resolve(type) .resolveNullable() .getSchemaType(); }; resolveProperties = ( properties: { [propertyName: string]: Schema } = {}, required: string[] = [], parentKey?: string, ): TDictionary<any> => reduce( properties, (o, v, k) => ({ ...o, [`${k}${indexOf(required, k) > -1 ? "" : "?"}`]: SchemaResolver.of({ results: this.inputs.results, schema: v as Schema, key: k, parentKey, }) .resolve() .resolveNullable() .getSchemaType(), }), {}, ); }