UNPKG

@canonical/jujulib

Version:

Juju API client

155 lines (135 loc) 4.14 kB
import type { FacadeTemplate, InterfaceData, InterfaceType, InterfaceValueType, } from "../interfaces.js"; const padString = (doc: string, indent: number): string => { if (!doc) { return ""; } const segments = doc .split("\n") .map((segment) => segment ? segment.padStart(segment.length + indent) : "" ); return segments.join("\n"); }; const generateType = ( interfaceType: InterfaceType | InterfaceValueType ): string => { if (typeof interfaceType === "string") { return interfaceType; } return interfaceType.type === "object" && interfaceType.valueType ? `Record<string, ${generateType(interfaceType.valueType)}>` : interfaceType.type; }; export const generateInterface = (i: InterfaceData) => { return ` export interface ${i.name} { ${i.types .map((t) => { let name: string = t.name; if (name.indexOf("-") !== -1) { name = `"${name}"`; } // Don't make index signatures optional (this is a syntax error). const optional = !t.required && !name.endsWith("]") ? "?" : ""; return padString(`${name}${optional}: ${generateType(t)};`, 2); }) .join("\n")} }`; }; const lowerCaseFirstChar = (name: string): string => name.charAt(0).toLowerCase() + name.slice(1); const upperCaseFirstChar = (name: string): string => name.charAt(0).toUpperCase() + name.slice(1); const generateAvailableList = (availableTo: string[]) => padString( availableTo .map((env) => upperCaseFirstChar(env.replace("-user", "s"))) .join("\n"), 4 ); export function generateMethods(facadeTemplate: FacadeTemplate): string { return facadeTemplate.methods .map((m) => { const paramsType = m.params && typeof m.params === "object" ? `{ ${Object.entries(m.params) .map(([key, value]) => `${key}: ${value};`) .join(" ")} }` : m.params; const paramsBlock = m.params ? `${ typeof m.params === "object" ? Object.keys(m.params) .map((key) => ` ${key}: params.${key},`) .join("\n") : " params: params," } };` : null; return `/** ${padString(m.docBlock || "", 4)} */ ${lowerCaseFirstChar(m.name)}(${ m.params ? `params: ${paramsType}` : "" }): Promise<${m.result}> { return new Promise((resolve, reject) => { const req: JujuRequest = { type: "${facadeTemplate.name}", request: "${m.name}", version: ${facadeTemplate.version}, ${paramsBlock ?? " };"} this._transport.write(req, resolve, reject); }); } `; }) .join("\n"); } export default function generateFacadeTemplate( facadeTemplate: FacadeTemplate ): string { const availableTo = facadeTemplate.availableTo ? ` This facade is available on: ${generateAvailableList(facadeTemplate.availableTo)} ` : ""; return `/** Juju ${facadeTemplate.name} version ${facadeTemplate.version}. ${availableTo} NOTE: This file was generated using the Juju schema from Juju ${facadeTemplate.jujuVersion} at the git SHA ${ facadeTemplate.jujuGitSHA }. Do not manually edit this file. */ import type { JujuRequest } from "../../../generator/interfaces.js"; import { ConnectionInfo, Transport } from "../../client.js"; import { Facade } from "../../types.js"; import { autoBind } from "../../utils.js"; ${facadeTemplate.interfaces.map(generateInterface).join("\n")} /** ${padString(facadeTemplate.docBlock, 2)} */ class ${facadeTemplate.name}V${facadeTemplate.version} implements Facade { static NAME = "${facadeTemplate.name}"; static VERSION = ${facadeTemplate.version}; NAME = "${facadeTemplate.name}"; VERSION = ${facadeTemplate.version}; _transport: Transport; _info: ConnectionInfo; constructor(transport: Transport, info: ConnectionInfo) { this._transport = transport; this._info = info; // Automatically bind all methods to instances. autoBind(this); } ${generateMethods(facadeTemplate)} } export default ${facadeTemplate.name}V${facadeTemplate.version}; `; }