UNPKG

@eliseev_s/tolk-tlb-transpiler

Version:

Transpile Tolk structs to TLB definitions and generate TypeScript wrappers for TON blockchain smart contracts

181 lines • 8.4 kB
#!/usr/bin/env node "use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const commander_1 = require("commander"); const fs_1 = require("fs"); const path_1 = require("path"); const tlb_codegen_1 = require("@ton-community/tlb-codegen"); const handlers_1 = require("../src/handlers"); const package_json_1 = __importDefault(require("../package.json")); const { version } = package_json_1.default; const commonTLB = `// Common TLB definitions bool_false$0 = Bool; bool_true$1 = Bool; nothing$0 {X:Type} = Maybe X; just$1 {X:Type} value:X = Maybe X; left$0 {X:Type} {Y:Type} value:X = Either X Y; right$1 {X:Type} {Y:Type} value:Y = Either X Y; pair$_ {X:Type} {Y:Type} first:X second:Y = Both X Y; `; const program = new commander_1.Command(); program .name('tolk-tlb') .description('Transpile Tolk structs to TLB (Type Language Binary) definitions') .version(version); // Original transpile command program .command('transpile') .description('Transpile Tolk structs to TLB definitions') .argument('<input>', 'Input Tolk file path') .option('-o, --output <path>', 'Output directory (default: same as input directory)') .option('-n, --name <name>', 'Output file name (default: based on input file name)') .option('--no-ts', 'Skip TypeScript code generation', true) .option('-v, --verbose', 'Verbose output') .action(async (input, options) => { try { await transpileCommand(input, options); } catch (error) { console.error('āŒ Error:', error instanceof Error ? error.message : error); process.exit(1); } }); // New wrapper generation command program .command('wrapper') .description('Generate TypeScript wrapper for smart contract') .argument('<structures>', 'Tolk file with struct definitions') .argument('<get-methods>', 'Tolk file with get method definitions') .argument('<contract-name>', 'Contract name (e.g., "Minter")') .option('-o, --output <path>', 'Output directory (default: same as structures directory)') .option('-n, --name <name>', 'Output file name (default: based on contract name)') .option('-v, --verbose', 'Verbose output') .action(async (structures, getMethods, contractName, options) => { try { await wrapperCommand(structures, getMethods, contractName, options); } catch (error) { console.error('āŒ Error:', error instanceof Error ? error.message : error); process.exit(1); } }); async function wrapperCommand(structuresPath, getMethodsPath, contractName, options) { const verbose = options.verbose; if (verbose) { console.log('šŸš€ Smart Contract Wrapper Generator'); console.log('===================================\n'); } const resolvedStructures = (0, path_1.resolve)(structuresPath); const resolvedGetMethods = (0, path_1.resolve)(getMethodsPath); if (!(0, fs_1.existsSync)(resolvedStructures)) { throw new Error(`Structures file not found: ${structuresPath}`); } if (!(0, fs_1.existsSync)(resolvedGetMethods)) { throw new Error(`Get methods file not found: ${getMethodsPath}`); } const structuresDir = (0, path_1.dirname)(resolvedStructures); const outputDir = options.output ? (0, path_1.resolve)(options.output) : structuresDir; const outputName = options.name || contractName; if (!(0, fs_1.existsSync)(outputDir)) { (0, fs_1.mkdirSync)(outputDir, { recursive: true }); } if (verbose) { console.log(`šŸ“– Reading structures from ${structuresPath}...`); console.log(`šŸ“– Reading get methods from ${getMethodsPath}...`); } const structuresCode = (0, fs_1.readFileSync)(resolvedStructures, 'utf-8'); const getMethodsCode = (0, fs_1.readFileSync)(resolvedGetMethods, 'utf-8'); if (verbose) { console.log(`āœ… Read ${structuresCode.length} characters from structures file`); console.log(`āœ… Read ${getMethodsCode.length} characters from get methods file\n`); console.log('šŸ”§ Generating wrapper...'); } const result = await (0, handlers_1.generateContractWrapper)(structuresCode, getMethodsCode, contractName); const tlbPath = (0, path_1.join)(outputDir, `${outputName}.tlb`); (0, fs_1.writeFileSync)(tlbPath, result.tlbString); console.log(`šŸ’¾ TLB definitions written to: ${tlbPath}`); const tsPath = (0, path_1.join)(outputDir, `${outputName}.ts`); (0, fs_1.writeFileSync)(tsPath, result.fullCode); console.log(`šŸ’¾ TypeScript wrapper written to: ${tsPath}`); if (verbose) { const stats = (0, handlers_1.getTlbStats)(result.tlbDefinitions); console.log('\nšŸ“Š Summary:'); console.log('==========='); console.log(`Contract: ${contractName}`); console.log(`Structures: ${structuresPath} (${structuresCode.length} chars)`); console.log(`Get methods: ${getMethodsPath} (${getMethodsCode.length} chars)`); console.log(`Output directory: ${outputDir}`); console.log(`Generated ${stats.totalDefinitions} TLB definitions`); console.log(`Total constructors: ${stats.totalConstructors}`); console.log('šŸŽ‰ Wrapper generation completed successfully!'); } } async function transpileCommand(inputPath, options) { const verbose = options.verbose; if (verbose) { console.log('šŸš€ Tolk-to-TLB Transpiler'); console.log('========================\n'); } const resolvedInput = (0, path_1.resolve)(inputPath); if (!(0, fs_1.existsSync)(resolvedInput)) { throw new Error(`Input file not found: ${inputPath}`); } const inputDir = (0, path_1.dirname)(resolvedInput); const inputBaseName = (0, path_1.join)(inputPath).replace((0, path_1.extname)(inputPath), ''); const outputDir = options.output ? (0, path_1.resolve)(options.output) : inputDir; const outputName = options.name || (0, path_1.join)(inputBaseName).split('/').pop(); if (!(0, fs_1.existsSync)(outputDir)) { (0, fs_1.mkdirSync)(outputDir, { recursive: true }); } if (verbose) { console.log(`šŸ“– Reading ${inputPath}...`); } const tolkCode = (0, fs_1.readFileSync)(resolvedInput, 'utf-8'); if (verbose) { console.log(`āœ… Read ${tolkCode.length} characters\n`); console.log('šŸ”§ Initializing transpiler...'); } const tlbDefinitions = await (0, handlers_1.transpileTolkToTlbDefinitions)(tolkCode); if (verbose) { console.log(`āœ… Generated ${tlbDefinitions.length} TLB definitions\n`); } const tlbHeader = `TLB Schema Generated from ${(0, path_1.join)(inputPath)}`; const outputContent = (0, handlers_1.formatTlbDefinitions)(tlbDefinitions, tlbHeader); const tlbPath = (0, path_1.join)(outputDir, `${outputName}.tlb`); (0, fs_1.writeFileSync)(tlbPath, outputContent); console.log(`šŸ’¾ TLB definitions written to: ${tlbPath}`); if (options.ts) { try { const tsPath = (0, path_1.join)(outputDir, `${outputName}.ts`); const tsCode = await (0, tlb_codegen_1.generateCodeFromData)(commonTLB + outputContent, 'typescript'); (0, fs_1.writeFileSync)(tsPath, tsCode); console.log(`šŸ’¾ TypeScript code written to: ${tsPath}`); } catch (error) { console.warn('āš ļø TypeScript generation failed:', error instanceof Error ? error.message : error); } } if (verbose) { const stats = (0, handlers_1.getTlbStats)(tlbDefinitions); console.log('\nšŸ“Š Summary:'); console.log('==========='); console.log(`Input: ${inputPath} (${tolkCode.length} chars)`); console.log(`Output directory: ${outputDir}`); console.log(`Generated ${stats.totalDefinitions} TLB definitions`); console.log(`Total constructors: ${stats.totalConstructors}`); console.log('šŸŽ‰ Transpilation completed successfully!'); } } process.on('uncaughtException', (error) => { console.error('āŒ Uncaught exception:', error.message); process.exit(1); }); process.on('unhandledRejection', (reason) => { console.error('āŒ Unhandled rejection:', reason); process.exit(1); }); program.parse(); //# sourceMappingURL=cli.js.map