"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.createGenerator = createGenerator;
exports.deriveContractName = deriveContractName;
exports.generateAndWrite = generateAndWrite;
exports.logSourceInfo = logSourceInfo;
exports.writeBindings = writeBindings;
var fs = _interopRequireWildcard(require("fs/promises"));
var path = _interopRequireWildcard(require("path"));
var _generator = require("../bindings/generator");
var _bindings = require("../bindings");
var _server = require("../rpc/server");
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
/**
* Source information about where the contract was fetched from
*/
/**
* Verify that the server is on the expected network
*/
async function verifyNetwork(server, expectedPassphrase) {
const networkResponse = await server.getNetwork();
if (networkResponse.passphrase !== expectedPassphrase) {
throw new _bindings.WasmFetchError(`Network mismatch: expected "${expectedPassphrase}", got "${networkResponse.passphrase}"`);
}
}
/**
* Create a BindingGenerator from local file, network hash, or contract ID
*/
async function createGenerator(args) {
// Validate exactly one source is provided
const sources = [args.wasm, args.wasmHash, args.contractId].filter(Boolean);
if (sources.length === 0) {
throw new _bindings.WasmFetchError("Must provide one of: --wasm, --wasm-hash, or --contract-id");
}
if (sources.length > 1) {
throw new _bindings.WasmFetchError("Must provide only one of: --wasm, --wasm-hash, or --contract-id");
}
// Local WASM file
if (args.wasm) {
const wasmBuffer = await fs.readFile(args.wasm);
return {
generator: _generator.BindingGenerator.fromWasm(wasmBuffer),
source: {
type: "file",
path: args.wasm
}
};
}
// Network sources require RPC URL and network
if (!args.rpcUrl) {
throw new _bindings.WasmFetchError("--rpc-url is required when fetching from network");
}
if (!args.networkPassphrase) {
throw new _bindings.WasmFetchError("--network is required when fetching from network");
}
const server = new _server.RpcServer(args.rpcUrl, args.serverOptions);
await verifyNetwork(server, args.networkPassphrase);
// WASM hash
if (args.wasmHash) {
return {
generator: await _generator.BindingGenerator.fromWasmHash(args.wasmHash, server),
source: {
type: "wasm-hash",
hash: args.wasmHash,
rpcUrl: args.rpcUrl,
network: args.networkPassphrase
}
};
}
if (args.contractId) {
const generator = await _generator.BindingGenerator.fromContractId(args.contractId, server);
return {
generator,
source: {
type: "contract-id",
contractId: args.contractId,
rpcUrl: args.rpcUrl,
network: args.networkPassphrase
}
};
}
throw new _bindings.WasmFetchError("Invalid arguments");
}
/**
* Write generated bindings to disk
*/
async function writeBindings(outputDir, bindings, overwrite) {
// Check if output directory exists
try {
const stat = await fs.stat(outputDir);
if (stat.isFile()) {
throw new Error(`Output path is a file: ${outputDir}`);
}
if (!overwrite) {
throw new Error(`Directory exists (use --overwrite): ${outputDir}`);
}
await fs.rm(outputDir, {
recursive: true,
force: true
});
} catch (error) {
if (error.code !== "ENOENT") throw error;
}
await fs.mkdir(path.join(outputDir, "src"), {
recursive: true
});
const writes = [fs.writeFile(path.join(outputDir, "src/index.ts"), bindings.index), fs.writeFile(path.join(outputDir, "src/client.ts"), bindings.client), fs.writeFile(path.join(outputDir, ".gitignore"), bindings.gitignore), fs.writeFile(path.join(outputDir, "README.md"), bindings.readme), fs.writeFile(path.join(outputDir, "package.json"), bindings.packageJson), fs.writeFile(path.join(outputDir, "tsconfig.json"), bindings.tsConfig)];
if (bindings.types.trim()) {
writes.push(fs.writeFile(path.join(outputDir, "src/types.ts"), bindings.types));
}
await Promise.all(writes);
}
/**
* Generate and write bindings to disk
*/
async function generateAndWrite(generator, options) {
const {
outputDir,
overwrite = false,
...genOptions
} = options;
const bindings = generator.generate(genOptions);
await writeBindings(outputDir, bindings, overwrite);
}
/**
* Log source information
*/
function logSourceInfo(source) {
console.log("\nSource:");
switch (source.type) {
case "file":
console.log(` Type: Local file`);
console.log(` Path: ${source.path}`);
break;
case "wasm-hash":
console.log(` Type: WASM hash`);
console.log(` Hash: ${source.hash}`);
console.log(` RPC: ${source.rpcUrl}`);
console.log(` Network: ${source.network}`);
break;
case "contract-id":
console.log(` Type: Contract ID`);
console.log(` Address: ${source.contractId}`);
console.log(` RPC: ${source.rpcUrl}`);
console.log(` Network: ${source.network}`);
break;
}
}
/**
* Derive contract name from source path
*/
function deriveContractName(source) {
if (source.type !== "file") return null;
return path.basename(source.path, path.extname(source.path)).replace(/([a-z])([A-Z])/g, "$1-$2").replace(/_/g, "-").toLowerCase();
}
Source