UNPKG

jrgen

Version:

Generates docs, tests, clients and servers for json-rpc apis.

131 lines (114 loc) 3.65 kB
const json2ts = require("json-schema-to-typescript"); const path = require("path"); const utils = require(path.join(__dirname, "../../../../", "utils.js")); buildInternalMethodTypes = async (schema) => { const json2tsOptions = { bannerComment: "", style: { singleQuote: true, }, }; let types = ""; for (const [methodName, methodSchema] of Object.entries(schema.methods)) { const methodTypeName = methodName.replace(/\./g, ""); if (methodSchema.params) { types += await json2ts.compile( methodSchema.params, methodTypeName + "Params.json", json2tsOptions ); types += ` export type ${methodTypeName}Request = WithRequired<Request<"${methodName}", ${methodTypeName}Params>, "params">; `; } else { types += ` export type ${methodTypeName}Params = void; export type ${methodTypeName}Request = Request<"${methodName}", ${methodTypeName}Params>; `; } if (methodSchema.result) { types += (await json2ts.compile( methodSchema.result, methodTypeName + "Result.json", json2tsOptions )) + "\n\n"; } else { types += ` export type ${methodTypeName}Result = void; `; } types += ` export type ${methodTypeName}Response = Response<"${methodName}", ${methodTypeName}Result, ${methodTypeName}ErrorCode>; `; if (methodSchema.errors) { const errorPrefix = schema.info.title.charAt(0).toUpperCase() + schema.info.title.replace(/\s/g, "").slice(1); const methodErrors = methodSchema.errors .map( (error) => `typeof ${errorPrefix}ErrorCode.` + error.message.replace(/\s/g, "") ) .join(" | "); types += ` export type ${methodTypeName}ErrorCode = ${methodErrors}; export type ${methodTypeName}Error = RpcError<${methodTypeName}ErrorCode>; `; } else { types += ` export type ${methodTypeName}ErrorCode = void; `; } } for (const [schemaName, schemaDefinition] of Object.entries( schema.definitions )) { types += (await json2ts.compile( schemaDefinition, schemaName.replace(/\./g, "") + ".json", json2tsOptions )) + "\n\n"; } return types; }; module.exports = async (schema) => { return { templates: Object.entries( utils.loadFileTreeFrom(path.join(__dirname, "templates")) ).reduce((acc, [templatePath, templateValue]) => { if (templatePath.endsWith("api-client.ts.mustache")) { templatePath = `${schema.info.title .toLowerCase() .replace(/\s/g, "-")}-client.ts.mustache`; } acc[templatePath] = templateValue; return acc; }, {}), model: { title: schema.info.title.charAt(0).toUpperCase() + schema.info.title.replace(/\s/g, "").slice(1), methodTypes: Object.keys(schema.methods).map((key) => key.replace(/\./g, "") ), methodRequestResponseMap: Object.keys(schema.methods).map((key) => ({ method: key, type: key.replace(/\./g, ""), })), internalMethodTypes: await buildInternalMethodTypes(schema), errors: Object.entries( Object.values(schema.methods).reduce((accumulator, methodSchema) => { methodSchema.errors?.forEach((error) => { accumulator[error.message.replace(/\s/g, "")] = error.code; }); return accumulator; }, {}) ).map(([key, value]) => ({ code: value, message: key, })), }, }; };