From cdc480aeb67ed89e9e4a76bdce700ff7bfada990 Mon Sep 17 00:00:00 2001 From: nedsalk Date: Fri, 4 Oct 2024 17:32:53 +0200 Subject: [PATCH] improve structure --- .../abi/src/gen/renderers/ts/render-ts.ts | 19 ++++----- .../ts/renderers/get-parent-dir-wrapper.ts | 24 +++++++++++ .../ts/renderers/render-program-templates.ts | 40 ++++++++++--------- .../ts/renderers/render-types-template.ts | 12 +++--- .../src/gen/renderers/ts/templates/index.hbs | 2 +- packages/abi/src/gen/renderers/types.ts | 2 +- packages/abi/src/parser/abi.ts | 2 +- .../parser/specifications/v1/specification.ts | 2 +- packages/fuel-gauge/src/abi/abi-gen.test.ts | 36 ++++++++++------- .../fuel-gauge/src/abi/fixtures/index.txt | 8 ++-- 10 files changed, 91 insertions(+), 56 deletions(-) create mode 100644 packages/abi/src/gen/renderers/ts/renderers/get-parent-dir-wrapper.ts diff --git a/packages/abi/src/gen/renderers/ts/render-ts.ts b/packages/abi/src/gen/renderers/ts/render-ts.ts index 192bae18595..708a622b102 100644 --- a/packages/abi/src/gen/renderers/ts/render-ts.ts +++ b/packages/abi/src/gen/renderers/ts/render-ts.ts @@ -18,24 +18,25 @@ export const renderTs: Renderer = (details: ProgramDetails[]): AbiGenResult[] => .flat(); results.push({ - filename: 'common', - extension: 'ts', + filename: 'common.ts', content: renderHbsTemplate({ template: commonTemplate }), }); results.push({ - filename: 'index', - extension: 'ts', + filename: 'index.ts', content: renderHbsTemplate({ template: indexTemplate, data: { - members: results.filter((r) => r.exportInIndex).map((r) => r.filename), + members: results + .filter((r) => r.exportInIndexFile) + .map( + (r) => + // remove .ts extension + r.filename.split('.')[0] + ), }, }), }); - return results.map((r) => ({ - content: r.content, - filename: `${r.filename}.${r.extension}`, - })); + return results; }; diff --git a/packages/abi/src/gen/renderers/ts/renderers/get-parent-dir-wrapper.ts b/packages/abi/src/gen/renderers/ts/renderers/get-parent-dir-wrapper.ts new file mode 100644 index 00000000000..076790e0620 --- /dev/null +++ b/packages/abi/src/gen/renderers/ts/renderers/get-parent-dir-wrapper.ts @@ -0,0 +1,24 @@ +import { assertUnreachable } from '@fuel-ts/utils'; + +import type { Abi } from '../../../../parser'; + +export function getParentDirWrapper(programType: Abi['programType']): (file: string) => string { + let directory: string = ''; + switch (programType) { + case 'contract': + directory = 'contracts'; + break; + case 'predicate': + directory = 'predicates'; + break; + case 'script': + directory = 'scripts'; + break; + case 'library': + break; + default: + assertUnreachable(programType); + } + + return (file) => `${directory}/${file}`; +} diff --git a/packages/abi/src/gen/renderers/ts/renderers/render-program-templates.ts b/packages/abi/src/gen/renderers/ts/renderers/render-program-templates.ts index 61dab64fc7c..6eaf0797f7b 100644 --- a/packages/abi/src/gen/renderers/ts/renderers/render-program-templates.ts +++ b/packages/abi/src/gen/renderers/ts/renderers/render-program-templates.ts @@ -1,3 +1,5 @@ +import { assertUnreachable } from '@fuel-ts/utils'; + import type { ProgramDetails } from '../../../utils/get-program-details'; import type { TsAbiGenResult } from '../../types'; import bytecodeTemplate from '../templates/bytecode.hbs'; @@ -6,6 +8,7 @@ import contractTemplate from '../templates/contract.hbs'; import predicateTemplate from '../templates/predicate.hbs'; import scriptTemplate from '../templates/script.hbs'; +import { getParentDirWrapper } from './get-parent-dir-wrapper'; import { renderHbsTemplate } from './render-hbs-template'; export function renderProgramTemplates(programDetails: ProgramDetails): TsAbiGenResult[] { @@ -13,13 +16,11 @@ export function renderProgramTemplates(programDetails: ProgramDetails): TsAbiGen const results: TsAbiGenResult[] = [ { - filename: `${name}-abi`, - extension: 'json', + filename: `${name}-abi.json`, content: programDetails.abiContents, }, { - filename: `${name}-bytecode`, - extension: 'ts', + filename: `${name}-bytecode.ts`, content: renderHbsTemplate({ template: bytecodeTemplate, data: { binCompressed } }), }, ]; @@ -28,55 +29,56 @@ export function renderProgramTemplates(programDetails: ProgramDetails): TsAbiGen case 'contract': results.push( { - filename: name, - extension: 'ts', + filename: `${name}.ts`, content: renderHbsTemplate({ template: contractTemplate, data: { name }, }), - exportInIndex: true, + exportInIndexFile: true, }, { - filename: `${name}Factory`, - extension: 'ts', + filename: `${name}Factory.ts`, content: renderHbsTemplate({ template: contractFactoryTemplate, data: { name }, }), - exportInIndex: true, + exportInIndexFile: true, }, { - filename: `${name}-storage-slots`, - extension: 'json', + filename: `${name}-storage-slots.json`, content: programDetails.storageSlots as string, } ); break; case 'predicate': results.push({ - filename: name, - extension: 'ts', + filename: `${name}.ts`, content: renderHbsTemplate({ template: predicateTemplate, data: { name }, }), - exportInIndex: true, + exportInIndexFile: true, }); break; case 'script': results.push({ - filename: name, - extension: 'ts', + filename: `${name}.ts`, content: renderHbsTemplate({ template: scriptTemplate, data: { name }, }), - exportInIndex: true, + exportInIndexFile: true, }); break; + case 'library': + // we do nothing for library + break; default: + assertUnreachable(abi.programType); break; } - return results; + const withParentDir = getParentDirWrapper(abi.programType); + + return results.map((r) => ({ ...r, filename: withParentDir(r.filename) })); } diff --git a/packages/abi/src/gen/renderers/ts/renderers/render-types-template.ts b/packages/abi/src/gen/renderers/ts/renderers/render-types-template.ts index 2c65024489e..ab8e6d12d90 100644 --- a/packages/abi/src/gen/renderers/ts/renderers/render-types-template.ts +++ b/packages/abi/src/gen/renderers/ts/renderers/render-types-template.ts @@ -7,9 +7,13 @@ import { generateTsType } from '../typers/generate-ts-type'; import { flattenImports } from '../typers/helpers'; import type { TyperReturn } from '../typers/types'; +import { getParentDirWrapper } from './get-parent-dir-wrapper'; import { renderHbsTemplate } from './render-hbs-template'; const metadataTypeFilter = createMatcher({ + enum: true, + struct: true, + assetId: true, string: false, void: false, bool: false, @@ -23,15 +27,12 @@ const metadataTypeFilter = createMatcher({ stdString: false, option: false, result: false, - enum: true, - struct: true, str: false, b512: false, bytes: false, vector: false, tuple: false, array: false, - assetId: true, evmAddress: false, rawUntypedPtr: false, rawUntypedSlice: false, @@ -120,9 +121,10 @@ export function renderTypesTemplate({ name, abi }: ProgramDetails): TsAbiGenResu }, }); + const withParentDir = getParentDirWrapper(abi.programType); + return { - filename: `${name}Types`, - extension: 'ts', + filename: withParentDir(`${name}Types.ts`), content, }; } diff --git a/packages/abi/src/gen/renderers/ts/templates/index.hbs b/packages/abi/src/gen/renderers/ts/templates/index.hbs index 27aa9d36a51..ce662efcffc 100644 --- a/packages/abi/src/gen/renderers/ts/templates/index.hbs +++ b/packages/abi/src/gen/renderers/ts/templates/index.hbs @@ -1,5 +1,5 @@ {{header}} {{#each members}} -export { {{this}} } from './{{this}}'; +export * from './{{this}}'; {{/each}} \ No newline at end of file diff --git a/packages/abi/src/gen/renderers/types.ts b/packages/abi/src/gen/renderers/types.ts index 1ea8f94a865..5abc0f5e98c 100644 --- a/packages/abi/src/gen/renderers/types.ts +++ b/packages/abi/src/gen/renderers/types.ts @@ -3,4 +3,4 @@ import type { ProgramDetails } from '../utils/get-program-details'; export type Renderer = (details: ProgramDetails[]) => AbiGenResult[]; -export type TsAbiGenResult = AbiGenResult & { exportInIndex?: boolean; extension: 'ts' | 'json' }; +export type TsAbiGenResult = AbiGenResult & { exportInIndexFile?: boolean }; diff --git a/packages/abi/src/parser/abi.ts b/packages/abi/src/parser/abi.ts index 962d0bec2a0..e672783233c 100644 --- a/packages/abi/src/parser/abi.ts +++ b/packages/abi/src/parser/abi.ts @@ -1,7 +1,7 @@ export interface Abi { specVersion: string; encodingVersion: string; - programType: string; + programType: 'contract' | 'script' | 'predicate' | 'library'; metadataTypes: AbiTypeMetadata[]; types: AbiType[]; functions: AbiFunction[]; diff --git a/packages/abi/src/parser/specifications/v1/specification.ts b/packages/abi/src/parser/specifications/v1/specification.ts index 5c718108005..ad98006fb3d 100644 --- a/packages/abi/src/parser/specifications/v1/specification.ts +++ b/packages/abi/src/parser/specifications/v1/specification.ts @@ -5,7 +5,7 @@ export interface AbiSpecificationV1 { readonly specVersion: '1'; readonly encodingVersion: string; - readonly programType: string; + readonly programType: 'contract' | 'script' | 'predicate' | 'library'; readonly concreteTypes: readonly AbiConcreteTypeV1[]; readonly metadataTypes: readonly AbiMetadataTypeV1[]; readonly functions: readonly AbiFunctionV1[]; diff --git a/packages/fuel-gauge/src/abi/abi-gen.test.ts b/packages/fuel-gauge/src/abi/abi-gen.test.ts index c3aa6dc14d7..ec553aec026 100644 --- a/packages/fuel-gauge/src/abi/abi-gen.test.ts +++ b/packages/fuel-gauge/src/abi/abi-gen.test.ts @@ -8,22 +8,25 @@ import { AbiProjectsEnum, getAbiForcProject } from './utils'; * @group node */ describe('AbiGen', () => { - test('contract', () => { + test('AbiGen generates all files correctly', () => { const fixtureResultMap = new Map([ - ['common', 'common.ts'], - ['contract', 'AbiContract.ts'], - ['contract-types', 'AbiContractTypes.ts'], - ['contract-factory', 'AbiContractFactory.ts'], - ['contract-bytecode', 'AbiContract-bytecode.ts'], - ['contract-abi', 'AbiContract-abi.json'], - ['contract-storage-slots', 'AbiContract-storage-slots.json'], - ['predicate', 'AbiPredicate.ts'], - ['predicate-types', 'AbiPredicateTypes.ts'], - ['predicate-abi', 'AbiPredicate-abi.json'], - ['script', 'AbiScript.ts'], - ['script-types', 'AbiScriptTypes.ts'], - ['script-abi', 'AbiScript-abi.json'], ['index', 'index.ts'], + ['common', 'common.ts'], + + ['contract', 'contracts/AbiContract.ts'], + ['contract-types', 'contracts/AbiContractTypes.ts'], + ['contract-factory', 'contracts/AbiContractFactory.ts'], + ['contract-bytecode', 'contracts/AbiContract-bytecode.ts'], + ['contract-abi', 'contracts/AbiContract-abi.json'], + ['contract-storage-slots', 'contracts/AbiContract-storage-slots.json'], + + ['predicate', 'predicates/AbiPredicate.ts'], + ['predicate-types', 'predicates/AbiPredicateTypes.ts'], + ['predicate-abi', 'predicates/AbiPredicate-abi.json'], + ['script', 'scripts/AbiScript.ts'], + + ['script-types', 'scripts/AbiScriptTypes.ts'], + ['script-abi', 'scripts/AbiScript-abi.json'], ]); const { buildDir: contractDir } = getAbiForcProject(AbiProjectsEnum.ABI_CONTRACT); @@ -31,7 +34,7 @@ describe('AbiGen', () => { const { buildDir: scriptDir } = getAbiForcProject(AbiProjectsEnum.ABI_SCRIPT); const programDetails = getProgramDetails([contractDir, predicateDir, scriptDir]); - const { results } = new AbiGen({ programDetails }); + const results = AbiGen.generate({ programDetails }); fixtureResultMap.forEach((filename, fixture) => { const fixtureFile = join( @@ -42,6 +45,9 @@ describe('AbiGen', () => { const result = results.find((r) => r.filename === filename); expect(result?.content).toEqual(fixtureContent); + + // verify only one file generated + expect(results.filter((r) => r.filename === filename)).toHaveLength(1); }); }); }); diff --git a/packages/fuel-gauge/src/abi/fixtures/index.txt b/packages/fuel-gauge/src/abi/fixtures/index.txt index 04505c19e38..ae8a6693680 100644 --- a/packages/fuel-gauge/src/abi/fixtures/index.txt +++ b/packages/fuel-gauge/src/abi/fixtures/index.txt @@ -9,7 +9,7 @@ */ -export { AbiContract } from './AbiContract'; -export { AbiContractFactory } from './AbiContractFactory'; -export { AbiPredicate } from './AbiPredicate'; -export { AbiScript } from './AbiScript'; +export * from './contracts/AbiContract'; +export * from './contracts/AbiContractFactory'; +export * from './predicates/AbiPredicate'; +export * from './scripts/AbiScript';