@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
JavaScript
;
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;