UNPKG

@frostup/swr-request-generator

Version:

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

165 lines (164 loc) 9.19 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.PathResolver = void 0; const SchemaResolver_1 = require("./SchemaResolver"); const lodash_1 = require("lodash"); const constants_1 = require("../constants"); const specifications_1 = require("../utils/specifications"); const generators_1 = require("../utils/generators"); const formatters_1 = require("../utils/formatters"); // TODO: Should handle `deprecated` and `security` in Operation? class PathResolver { constructor(paths) { this.paths = paths; this.resolvedPaths = []; this.extraDefinitions = {}; this.contentType = {}; this.resolve = () => { this.resolvedPaths = lodash_1.reduce(this.paths, (results, path, pathName) => [...results, ...this.resolvePath(path, pathName)], []); return this; }; this.toRequest = () => { const data = lodash_1.sortBy(this.resolvedPaths, (o) => o.operationId); const requests = data.map((resolvedPath) => { const bodyData = lodash_1.get(resolvedPath.bodyParams, "[0]"); const headerType = lodash_1.get(resolvedPath, "THeader"); const cookie = lodash_1.get(resolvedPath.formDataParams, "[0]"); const requestBody = lodash_1.get(resolvedPath, "requestBody"); const body = lodash_1.camelCase(formatters_1.toCapitalCase(requestBody || bodyData || cookie)); const params = this.toRequestParams(lodash_1.get(resolvedPath, "queryParams")); const axiosHeaderConfig = generators_1.generateHeader(!lodash_1.isEmpty(body), this.contentType, resolvedPath.operationId, headerType); return `export const ${generators_1.generateFunctionName(resolvedPath.method, resolvedPath.operationId)} = (${generators_1.generateRequestArguments(resolvedPath)}) => ${generators_1.generateClientName(resolvedPath.method, resolvedPath.TResp)}({ url: \`${resolvedPath.url}\`, method: "${resolvedPath.method}",${axiosHeaderConfig}${generators_1.generateResponseType(axiosHeaderConfig)} ${body ? `data: ${body},` : ""}${params ? `params: ${params},` : ""}...axiosConfig}${resolvedPath.method === "get" ? ", SWRConfig" : ""});`; }); const enums = Object.keys(this.extraDefinitions).map((k) => generators_1.generateEnums(this.extraDefinitions, k)); return [...requests, ...enums]; }; this.toRequestParams = (data = []) => !lodash_1.isEmpty(data) ? `{ ${data.join(",\n")} }` : undefined; this.getRequestURL = (pathName) => { return lodash_1.chain(pathName) .split(constants_1.SLASH) .map((p) => (this.isPathParam(p) ? `$${p}` : p)) .join(constants_1.SLASH) .value(); }; this.isPathParam = (str) => str.startsWith("{"); // TODO: handle the case when v.parameters = Reference this.resolveOperation = (operation) => { const pickParamsByType = this.pickParams(operation.parameters); const headerParams = pickParamsByType("header"); const params = { pathParams: pickParamsByType("path"), queryParams: pickParamsByType("query"), bodyParams: pickParamsByType("body"), formDataParams: pickParamsByType("cookie"), }; return Object.assign(Object.assign({ operationId: operation.operationId, TResp: this.getResponseTypes(operation.responses), TReq: this.getRequestTypes(params, operation.operationId, lodash_1.get(operation, "requestBody")), THeader: this.getPathParamsTypes(headerParams) }, this.getParamsNames(params)), this.getRequestBodyName(lodash_1.get(operation, "requestBody"), operation.operationId)); }; this.getParamsNames = (params) => { const getNames = (list) => (lodash_1.isEmpty(list) ? [] : lodash_1.map(list, (item) => item.name)); return { pathParams: getNames(params.pathParams), queryParams: getNames(params.queryParams), bodyParams: getNames(params.bodyParams), formDataParams: getNames(params.formDataParams), }; }; this.getRequestTypes = (params, operationId, requestBody) => (Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, this.getPathParamsTypes(params.pathParams)), this.getBodyAndQueryParamsTypes(params.bodyParams)), this.getBodyAndQueryParamsTypes(params.queryParams)), this.getFormDataParamsTypes(params.formDataParams)), this.getRequestBodyTypes(operationId, requestBody))); this.getPathParamsTypes = (pathParams) => pathParams.reduce((results, param) => { const schema = lodash_1.get(param, "schema"); if (specifications_1.isSchema(schema)) { return Object.assign(Object.assign({}, results), { [`${param.name}${param.required ? "" : "?"}`]: schema.type === "integer" ? "number" : schema.type }); } return Object.assign({}, results); }, {}); this.getBodyAndQueryParamsTypes = (bodyParams) => bodyParams.reduce((results, param) => (Object.assign(Object.assign({}, results), { [`${param.name}${param.required ? "" : "?"}`]: SchemaResolver_1.SchemaResolver.of({ results: this.extraDefinitions, schema: param.schema, key: param.name, parentKey: param.name, }) .resolve() .getSchemaType() })), {}); // TODO: handle other params here? this.getFormDataParamsTypes = (formDataParams) => { return formDataParams.reduce((results, param) => { if (param.schema) { return Object.assign(Object.assign({}, results), { [`${param.name}${param.required ? "" : "?"}`]: SchemaResolver_1.SchemaResolver.of({ results: this.extraDefinitions, schema: param.schema, key: param.name, parentKey: param.name, }) .resolve() .getSchemaType() }); } return Object.assign(Object.assign({}, results), { [`${param.name}${param.required ? "" : "?"}`]: param.type === "file" ? "File" : param.type }); }, {}); }; // TODO: handle Response or Reference this.getResponseTypes = (responses) => SchemaResolver_1.SchemaResolver.of({ results: this.extraDefinitions, // TODO: handle other content type here schema: lodash_1.get(responses, "200.content.application/json.schema") || lodash_1.get(responses, "200.content.*/*.schema") || lodash_1.get(responses, "201.content.application/json.schema") || lodash_1.get(responses, "201.content.*/*.schema"), }) .resolve() .getSchemaType(); // TODO: when parameters has enum this.pickParams = (parameters) => (type) => lodash_1.filter(parameters, (param) => param.in === type); } static of(paths) { return new PathResolver(paths); } resolvePath(path, pathName) { const operations = lodash_1.pick(path, constants_1.HTTP_METHODS); return Object.keys(operations).map((httpMethod) => (Object.assign({ url: this.getRequestURL(pathName), method: httpMethod }, this.resolveOperation(operations[httpMethod])))); } getContentType(operationId, key) { // in openAPI spec, the key of content in requestBody field is content type lodash_1.assign(this.contentType, { [operationId]: key }); } getRequestBodyTypes(operationId, requestBody) { if (specifications_1.isRequestBody(requestBody)) { return lodash_1.reduce(lodash_1.get(requestBody, "content"), (results, content, key) => { this.getContentType(operationId, key); return Object.assign(Object.assign({}, results), { [`${operationId}Request`]: SchemaResolver_1.SchemaResolver.of({ results: this.extraDefinitions, schema: content.schema, key: `${operationId}Request`, parentKey: `${operationId}Request`, }) .resolve() .getSchemaType() }); }, {}); } return { [`${operationId}Request`]: SchemaResolver_1.SchemaResolver.of({ results: this.extraDefinitions, schema: requestBody, key: `${operationId}Request`, parentKey: `${operationId}Request`, }) .resolve() .getSchemaType(), }; } getRequestBodyName(requestBody, operationId) { if (requestBody) { return { requestBody: `${operationId}Request`, }; } } } exports.PathResolver = PathResolver;