From 59c9fa9e06a08779afdd241ae648372f46e8f29b Mon Sep 17 00:00:00 2001 From: Ilyar Date: Tue, 26 Aug 2025 12:40:51 +0200 Subject: [PATCH] feat: remove node dependency form exports --- CHANGELOG.md | 1 + package.json | 10 +- src/cli.ts | 49 +++++--- src/index.ts | 3 +- src/main.ts | 19 ++- src/node.ts | 33 ------ test/__snapshots__/main.spec.ts.snap | 171 +++++++++++++++++++++++++++ test/generate.ts | 17 ++- test/main.spec.ts | 13 ++ test/tlbgen.spec.ts | 6 + 10 files changed, 250 insertions(+), 72 deletions(-) delete mode 100644 src/node.ts create mode 100644 test/__snapshots__/main.spec.ts.snap create mode 100644 test/main.spec.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index d46764a..9bca440 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/package.json b/package.json index 7431f41..d9a4017 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "2.0.0-beta.3", "description": "TLB code generator", "files": [ - "./build/*", + "./build/**/*", "LICENSE", "README.md" ], @@ -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": { @@ -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", diff --git a/src/cli.ts b/src/cli.ts index 2b6dbc0..c9df1ea 100755 --- a/src/cli.ts +++ b/src/cli.ts @@ -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( ` @@ -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); +}); diff --git a/src/index.ts b/src/index.ts index 670ec3a..8484b25 100644 --- a/src/index.ts +++ b/src/index.ts @@ -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'; diff --git a/src/main.ts b/src/main.ts index 051f003..a3c3e12 100644 --- a/src/main.ts +++ b/src/main.ts @@ -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); @@ -70,7 +74,14 @@ export function getGenerator(resultLanguage: string) { }; } -export async function generateCodeFromData(input: string, resultLanguage: string): Promise { - 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)); } diff --git a/src/node.ts b/src/node.ts deleted file mode 100644 index 86112fe..0000000 --- a/src/node.ts +++ /dev/null @@ -1,33 +0,0 @@ -import fs from 'fs/promises'; - -import { ast } from '@ton-community/tlb-parser'; - -import { TLBCode } from './ast'; -import { CodeGenerator } from './generators/generator'; -import { generateCodeByAST, getGenerator, getTLBCodeByAST } from './main'; - -export async function getTLBCode(inputPath: string) { - const input = await fs.readFile(inputPath, 'utf-8'); - - const tree = ast(input); - - return getTLBCodeByAST(tree, input); -} - -export async function generateCodeWithGenerator( - inputPath: string, - outputPath: string, - getGenerator: (tlbCode: TLBCode) => CodeGenerator, -) { - const input = await fs.readFile(inputPath, 'utf-8'); - - const tree = ast(input); - - await fs.writeFile(outputPath, generateCodeByAST(tree, input, getGenerator), {}); - // eslint-disable-next-line no-console - console.log(`Generated code is saved to ${outputPath}`); -} - -export async function generateCode(inputPath: string, outputPath: string, resultLanguage: string) { - return generateCodeWithGenerator(inputPath, outputPath, getGenerator(resultLanguage)); -} diff --git a/test/__snapshots__/main.spec.ts.snap b/test/__snapshots__/main.spec.ts.snap new file mode 100644 index 0000000..0a472ce --- /dev/null +++ b/test/__snapshots__/main.spec.ts.snap @@ -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", + }, + }, +} +`; diff --git a/test/generate.ts b/test/generate.ts index 3653a2f..d7b4c12 100644 --- a/test/generate.ts +++ b/test/generate.ts @@ -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'); diff --git a/test/main.spec.ts b/test/main.spec.ts new file mode 100644 index 0000000..41007ac --- /dev/null +++ b/test/main.spec.ts @@ -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(); + }); +}); diff --git a/test/tlbgen.spec.ts b/test/tlbgen.spec.ts index 1a3b6a6..489c066 100644 --- a/test/tlbgen.spec.ts +++ b/test/tlbgen.spec.ts @@ -191,6 +191,7 @@ import { storeTagCalculatorExample, loadTagCalculatorExample, } from './generated_files/generated_test'; +import { genCodeForTest } from './generate'; function isPrimitive(input: object) { if (input == null) { @@ -306,6 +307,11 @@ export type TLFunction = { }; describe('Generating tlb code', () => { + beforeAll(async () => { + await genCodeForTest('block'); + await genCodeForTest('test'); + }); + test('Basic types', () => { expect.hasAssertions();