"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.ClientGenerator = void 0;
var _utils = require("./utils");
/**
* Generates TypeScript client class for contract methods
*/
class ClientGenerator {
constructor(spec) {
this.spec = spec;
}
/**
* Generate client class
*/
generate() {
// Generate constructor method if it exists
let deployMethod = "";
try {
const constructorFunc = this.spec.getFunc("__constructor");
deployMethod = this.generateDeployMethod(constructorFunc);
} catch {
// For specs without a constructor, generate a deploy method without params
deployMethod = this.generateDeployMethod(undefined);
}
// Generate interface methods
const interfaceMethods = this.spec.funcs().filter(func => func.name().toString() !== "__constructor").map(func => this.generateInterfaceMethod(func)).join("\n");
const imports = this.generateImports();
const specEntries = this.spec.entries.map(entry => `"${entry.toXDR("base64")}"`);
const fromJSON = this.spec.funcs().filter(func => func.name().toString() !== "__constructor").map(func => this.generateFromJSONMethod(func)).join(",");
return `${imports}
export interface Client {
${interfaceMethods}
}
export class Client extends ContractClient {
constructor(public readonly options: ContractClientOptions) {
super(
new Spec([${specEntries.join(", ")}]),
options
);
}
${deployMethod}
public readonly fromJSON = {
${fromJSON}
};
}`;
}
generateImports() {
const imports = (0, _utils.generateTypeImports)(this.spec.funcs().flatMap(func => {
const inputs = func.inputs();
const outputs = func.outputs();
const defs = inputs.map(input => input.type()).concat(outputs);
return defs;
}));
return (0, _utils.formatImports)(imports, {
includeTypeFileImports: true,
// Client imports types
additionalStellarContractImports: ["Spec", "AssembledTransaction", "Client as ContractClient", "ClientOptions as ContractClientOptions", "MethodOptions"]
});
}
/**
* Generate interface method signature
*/
generateInterfaceMethod(func) {
const name = (0, _utils.sanitizeIdentifier)(func.name().toString());
const inputs = func.inputs().map(input => ({
name: input.name().toString(),
type: (0, _utils.parseTypeFromTypeDef)(input.type(), true)
}));
const outputType = func.outputs().length > 0 ? (0, _utils.parseTypeFromTypeDef)(func.outputs()[0]) : "void";
const docs = (0, _utils.formatJSDocComment)(func.doc().toString(), 2);
const params = this.formatMethodParameters(inputs);
return `${docs} ${name}(${params}): Promise<AssembledTransaction<${outputType}>>;`;
}
generateFromJSONMethod(func) {
const name = func.name().toString();
const outputType = func.outputs().length > 0 ? (0, _utils.parseTypeFromTypeDef)(func.outputs()[0]) : "void";
return ` ${name} : this.txFromJSON<${outputType}>`;
}
/**
* Generate deploy method
*/
generateDeployMethod(constructorFunc) {
// If no constructor, generate deploy with no params
if (!constructorFunc) {
const params = this.formatConstructorParameters([]);
return ` static deploy<T = Client>(${params}): Promise<AssembledTransaction<T>> {
return ContractClient.deploy(null, options);
}`;
}
const inputs = constructorFunc.inputs().map(input => ({
name: input.name().toString(),
type: (0, _utils.parseTypeFromTypeDef)(input.type(), true)
}));
const params = this.formatConstructorParameters(inputs);
const inputsDestructure = inputs.length > 0 ? `{ ${inputs.map(i => i.name).join(", ")} }, ` : "";
return ` static deploy<T = Client>(${params}): Promise<AssembledTransaction<T>> {
return ContractClient.deploy(${inputsDestructure}options);
}`;
}
/**
* Format method parameters
*/
formatMethodParameters(inputs) {
const params = [];
if (inputs.length > 0) {
const inputsParam = `{ ${inputs.map(i => `${i.name}: ${i.type}`).join("; ")} }`;
params.push(`{ ${inputs.map(i => i.name).join(", ")} }: ${inputsParam}`);
}
params.push("options?: MethodOptions");
return params.join(", ");
}
/**
* Format constructor parameters
*/
formatConstructorParameters(inputs) {
const params = [];
if (inputs.length > 0) {
const inputsParam = `{ ${inputs.map(i => `${i.name}: ${i.type}`).join("; ")} }`;
params.push(`{ ${inputs.map(i => i.name).join(", ")} }: ${inputsParam}`);
}
params.push('options: MethodOptions & Omit<ContractClientOptions, \'contractId\'> & { wasmHash: Buffer | string; salt?: Buffer | Uint8Array; format?: "hex" | "base64"; address?: string; }');
return params.join(", ");
}
}
exports.ClientGenerator = ClientGenerator;
Source