Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## [2.0.0-beta.3] – 2025-08-25

- Remove node dependency form exports
- Make export friendly use in web

## [2.0.0-beta.2] – 2025-08-25
Expand Down
10 changes: 2 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"version": "2.0.0-beta.3",
"description": "TLB code generator",
"files": [
"./build/*",
"./build/**/*",
"LICENSE",
"README.md"
],
Expand All @@ -16,12 +16,6 @@
"import": "./build/index.js",
"require": "./build/index.js",
"default": "./index.js"
},
"./node": {
"types": "./build/node.d.ts",
"import": "./build/node.js",
"require": "./build/node.js",
"default": "./build/node.js"
}
},
"typesVersions": {
Expand All @@ -39,7 +33,7 @@
"scripts": {
"lint": "eslint . --max-warnings 0",
"lint:fix": "eslint . --max-warnings 0 --fix",
"test:gen": "ts-node test/generate.ts",
"test:coverage": "jest --coverage",
"test": "jest",
"build": "npm run compile",
"prepublishOnly": "npm run build",
Expand Down
49 changes: 34 additions & 15 deletions src/cli.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#!/usr/bin/env node
import fs from 'fs/promises';

import meow from 'meow';

import { generateCode } from './node';
import { generateCode } from '.';

const cli = meow(
`
Expand Down Expand Up @@ -36,21 +38,38 @@ const cli = meow(
},
);

let input = cli.input.at(0);
if (input) {
if (input.match(/\.tlb$/) == null) {
async function main() {
let input = cli.input.at(0);
if (input) {
if (input.match(/\.tlb$/) == null) {
// eslint-disable-next-line no-console
console.error('Input file must have .tlb extension');
process.exit(1);
}

let output = input.replace('.tlb', '.ts');
if (cli.flags.output) {
output = cli.flags.output;
}
let language = 'typescript';
if (cli.flags.language) {
language = cli.flags.language;
}
const tlb = await fs.readFile(input, 'utf-8');
const code = generateCode(tlb, language);
await fs.writeFile(output, code, {});
// eslint-disable-next-line no-console
console.error('Input file must have .tlb extension');
process.exit(1);
console.log(`Generated code is saved to ${output}`);
}
}

let output = input.replace('.tlb', '.ts');
if (cli.flags.output) {
output = cli.flags.output;
}
let language = 'typescript';
if (cli.flags.language) {
language = cli.flags.language;
main().catch((error) => {
if (error instanceof Error) {
// eslint-disable-next-line no-console
console.error(error.message);
} else {
// eslint-disable-next-line no-console
console.error('Unknown error:', error);
}
generateCode(input, output, language);
}
process.exit(1);
});
3 changes: 1 addition & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
export * from './ast';
export { getTLBCodeByAST, generateCodeByAST, generateCodeFromData } from './main';
export { generateCode, getTLBCode, generateCodeWithGenerator } from './node';
export { getTLBCodeByAST, generateCodeByAST, getTLBCode, generateCodeWithGenerator, generateCode } from './main';
export { isBigInt, isBigIntExpr } from './generators/typescript/utils';
export type { CodeGenerator } from './generators/generator';
export { TypescriptGenerator } from './generators/typescript/generator';
19 changes: 15 additions & 4 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ export function getTLBCodeByAST(tree: Program, input: string): TLBCode {
return convertCodeToReadonly(oldTlbCode);
}

export function generateCodeByAST(tree: Program, input: string, getGenerator: (tlbCode: TLBCode) => CodeGenerator) {
export function generateCodeByAST(
tree: Program,
input: string,
getGenerator: (tlbCode: TLBCode) => CodeGenerator,
): string {
let tlbCode = getTLBCodeByAST(tree, input);
let codeGenerator: CodeGenerator = getGenerator(tlbCode);

Expand Down Expand Up @@ -70,7 +74,14 @@ export function getGenerator(resultLanguage: string) {
};
}

export async function generateCodeFromData(input: string, resultLanguage: string): Promise<string> {
const tree = ast(input);
return generateCodeByAST(tree, input, getGenerator(resultLanguage));
export function getTLBCode(input: string) {
return getTLBCodeByAST(ast(input), input);
}

export function generateCodeWithGenerator(input: string, getGenerator: (tlbCode: TLBCode) => CodeGenerator): string {
return generateCodeByAST(ast(input), input, getGenerator);
}

export function generateCode(input: string, resultLanguage: string): string {
return generateCodeWithGenerator(input, getGenerator(resultLanguage));
}
33 changes: 0 additions & 33 deletions src/node.ts

This file was deleted.

171 changes: 171 additions & 0 deletions test/__snapshots__/main.spec.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`main generateCode 1`] = `
"import { Builder } from '@ton/core'
import { Slice } from '@ton/core'
import { beginCell } from '@ton/core'
import { BitString } from '@ton/core'
import { Cell } from '@ton/core'
import { Address } from '@ton/core'
import { ExternalAddress } from '@ton/core'
import { Dictionary } from '@ton/core'
import { DictionaryValue } from '@ton/core'
import { TupleItem } from '@ton/core'
import { parseTuple } from '@ton/core'
import { serializeTuple } from '@ton/core'
export function bitLen(n: number) {
return n.toString(2).length;
}

export interface Bool {
readonly kind: 'Bool';
readonly value: boolean;
}

export function loadBool(slice: Slice): Bool {
if (slice.remainingBits >= 1) {
let value = slice.loadUint(1);
return {
kind: 'Bool',
value: value == 1
}

}
throw new Error('Expected one of "BoolFalse" in loading "BoolFalse", but data does not satisfy any constructor');
}

export function storeBool(bool: Bool): (builder: Builder) => void {
return ((builder: Builder) => {
builder.storeUint(bool.value ? 1: 0, 1);
})

}



export function loadBoolFalse(slice: Slice): Bool {
if (((slice.remainingBits >= 1) && (slice.preloadUint(1) == 0b0))) {
slice.loadUint(1);
return {
kind: 'Bool',
value: false
}

}
throw new Error('Expected one of "BoolFalse" in loading "BoolFalse", but data does not satisfy any constructor');
}

export function loadBoolTrue(slice: Slice): Bool {
if (((slice.remainingBits >= 1) && (slice.preloadUint(1) == 0b1))) {
slice.loadUint(1);
return {
kind: 'Bool',
value: true
}

}
throw new Error('Expected one of "BoolTrue" in loading "BoolTrue", but data does not satisfy any constructor');
}

export function copyCellToBuilder(from: Cell, to: Builder): void {
let slice = from.beginParse();
to.storeBits(slice.loadBits(slice.remainingBits));
while (slice.remainingRefs) {
to.storeRef(slice.loadRef());
}
}
// _ x:# = Foo;

export interface Foo {
readonly kind: 'Foo';
readonly x: number;
}

// _ x:# = Foo;

export function loadFoo(slice: Slice): Foo {
let x: number = slice.loadUint(32);
return {
kind: 'Foo',
x: x,
}

}

export function storeFoo(foo: Foo): (builder: Builder) => void {
return ((builder: Builder) => {
builder.storeUint(foo.x, 32);
})

}

"
`;

exports[`main getTLBCode 1`] = `
TLBCode {
"types": Map {
"Foo" => TLBType {
"constructors": [
TLBConstructor {
"constraints": [],
"declaration": "_ x:# = Foo;",
"fields": [
{
"anonymous": false,
"fieldType": {
"bits": TLBNumberExpr {
"hasNeg": false,
"n": 32,
"variables": Set {},
},
"kind": "TLBNumberType",
"maxBits": 32,
"signed": false,
"storeBits": TLBNumberExpr {
"hasNeg": false,
"n": 32,
"variables": Set {},
},
},
"name": "x",
"subFields": [],
},
],
"name": "_",
"parameters": [],
"parametersMap": Map {},
"tag": {
"binary": "",
"bitLen": 0,
},
"tlbType": "Foo",
"variables": [
TLBVariable {
"deriveExpr": undefined,
"initialExpr": undefined,
"isConst": false,
"isField": true,
"name": "x",
"negated": false,
"type": "#",
},
],
"variablesMap": Map {
"x" => TLBVariable {
"deriveExpr": undefined,
"initialExpr": undefined,
"isConst": false,
"isField": true,
"name": "x",
"negated": false,
"type": "#",
},
},
},
],
"name": "Foo",
},
},
}
`;
17 changes: 7 additions & 10 deletions test/generate.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
import path from 'path';
import fs from 'fs/promises';

import { generateCode } from '../src/node';
import { generateCode } from '../src';

function genCodeForTest(name: string) {
export async function genCodeForTest(name: string) {
const fixturesDir = path.resolve(__dirname, 'tlb');
generateCode(
path.resolve(fixturesDir, name + '.tlb'),
'test/generated_files/generated_' + name + '.ts',
'typescript',
);
const tlb = await fs.readFile(path.resolve(fixturesDir, name + '.tlb'), 'utf-8');
const code = generateCode(tlb, 'typescript');
const output = path.resolve(__dirname, 'generated_files/generated_' + name + '.ts');
await fs.writeFile(output, code, {});
}

genCodeForTest('block');
genCodeForTest('test');
13 changes: 13 additions & 0 deletions test/main.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { describe, expect, test } from '@jest/globals';

import { generateCode, getTLBCode } from '../src';

describe('main', () => {
test('generateCode', () => {
expect(generateCode('_ x:# = Foo;', 'typescript')).toMatchSnapshot();
});

test('getTLBCode', () => {
expect(getTLBCode('_ x:# = Foo;')).toMatchSnapshot();
});
});
Loading
Loading