"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.TypeGenerator = void 0;
var _stellarBase = require("@stellar/stellar-base");
var _utils = require("./utils");
/**
* Interface for struct fields
*/
/**
* Interface for union cases
*/
/**
* Interface for enum cases
*/
/**
* Generates TypeScript type definitions from Stellar contract specs
*/
class TypeGenerator {
constructor(spec) {
this.spec = spec;
}
/**
* Generate all TypeScript type definitions
*/
generate() {
// Generate types for each entry in the spec
const types = this.spec.entries.map(entry => this.generateEntry(entry)).filter(t => t).join("\n\n");
// Generate imports for all types
const imports = this.generateImports();
return `${imports}
${types}
`;
}
/**
* Generate TypeScript for a single spec entry
*/
generateEntry(entry) {
switch (entry.switch()) {
case _stellarBase.xdr.ScSpecEntryKind.scSpecEntryUdtStructV0():
if ((0, _utils.isTupleStruct)(entry.udtStructV0())) {
return this.generateTupleStruct(entry.udtStructV0());
}
return this.generateStruct(entry.udtStructV0());
case _stellarBase.xdr.ScSpecEntryKind.scSpecEntryUdtUnionV0():
return this.generateUnion(entry.udtUnionV0());
case _stellarBase.xdr.ScSpecEntryKind.scSpecEntryUdtEnumV0():
return this.generateEnum(entry.udtEnumV0());
case _stellarBase.xdr.ScSpecEntryKind.scSpecEntryUdtErrorEnumV0():
return this.generateErrorEnum(entry.udtErrorEnumV0());
default:
return null;
}
}
generateImports() {
const imports = (0, _utils.generateTypeImports)(this.spec.entries.flatMap(entry => {
switch (entry.switch()) {
case _stellarBase.xdr.ScSpecEntryKind.scSpecEntryUdtStructV0():
return entry.udtStructV0().fields().map(field => field.type());
case _stellarBase.xdr.ScSpecEntryKind.scSpecEntryUdtUnionV0():
return entry.udtUnionV0().cases().flatMap(unionCase => {
if (unionCase.switch() === _stellarBase.xdr.ScSpecUdtUnionCaseV0Kind.scSpecUdtUnionCaseTupleV0()) {
return unionCase.tupleCase().type();
}
return [];
});
case _stellarBase.xdr.ScSpecEntryKind.scSpecEntryUdtEnumV0():
// Enums do not have associated types
return [];
case _stellarBase.xdr.ScSpecEntryKind.scSpecEntryUdtErrorEnumV0():
// Enums do not have associated types
return [];
default:
return [];
}
}));
return (0, _utils.formatImports)(imports, {
includeTypeFileImports: false // Types file doesn't import from itself
});
}
/**
* Generate TypeScript interface for a struct
*/
generateStruct(struct) {
const name = (0, _utils.sanitizeIdentifier)(struct.name().toString());
const doc = (0, _utils.formatJSDocComment)(struct.doc().toString() || `Struct: ${name}`, 0);
const fields = struct.fields().map(field => {
const fieldName = field.name().toString();
const fieldType = (0, _utils.parseTypeFromTypeDef)(field.type());
const fieldDoc = (0, _utils.formatJSDocComment)(field.doc().toString(), 2);
return `${fieldDoc} ${fieldName}: ${fieldType};`;
}).join("\n");
return `${doc}export interface ${name} {
${fields}
}`;
}
/**
* Generate TypeScript union type
*/
generateUnion(union) {
const name = (0, _utils.sanitizeIdentifier)(union.name().toString());
const doc = (0, _utils.formatJSDocComment)(union.doc().toString() || `Union: ${name}`, 0);
const cases = union.cases().map(unionCase => this.generateUnionCase(unionCase));
const caseTypes = cases.map(c => {
if (c.types.length > 0) {
return `${(0, _utils.formatJSDocComment)(c.doc, 2)} { tag: "${c.name}"; values: readonly [${c.types.join(", ")}] }`;
}
return `${(0, _utils.formatJSDocComment)(c.doc, 2)} { tag: "${c.name}"; values: void }`;
}).join(" |\n");
return `${doc} export type ${name} =
${caseTypes};`;
}
/**
* Generate TypeScript enum
*/
generateEnum(enumEntry) {
const name = (0, _utils.sanitizeIdentifier)(enumEntry.name().toString());
const doc = (0, _utils.formatJSDocComment)(enumEntry.doc().toString() || `Enum: ${name}`, 0);
const members = enumEntry.cases().map(enumCase => {
const caseName = enumCase.name().toString();
const caseValue = enumCase.value();
const caseDoc = enumCase.doc().toString() || `Enum Case: ${caseName}`;
return `${(0, _utils.formatJSDocComment)(caseDoc, 2)} ${caseName} = ${caseValue}`;
}).join(",\n");
return `${doc}export enum ${name} {
${members}
}`;
}
/**
* Generate TypeScript error enum
*/
generateErrorEnum(errorEnum) {
const name = (0, _utils.sanitizeIdentifier)(errorEnum.name().toString());
const doc = (0, _utils.formatJSDocComment)(errorEnum.doc().toString() || `Error Enum: ${name}`, 0);
const cases = errorEnum.cases().map(enumCase => this.generateEnumCase(enumCase));
const members = cases.map(c => {
return `${(0, _utils.formatJSDocComment)(c.doc, 2)} ${c.value} : { message: "${c.name}" }`;
}).join(",\n");
return `${doc}export const ${name} = {
${members}
}`;
}
/**
* Generate union case
*/
generateUnionCase(unionCase) {
switch (unionCase.switch()) {
case _stellarBase.xdr.ScSpecUdtUnionCaseV0Kind.scSpecUdtUnionCaseVoidV0():
{
const voidCase = unionCase.voidCase();
return {
doc: voidCase.doc().toString(),
name: voidCase.name().toString(),
types: []
};
}
case _stellarBase.xdr.ScSpecUdtUnionCaseV0Kind.scSpecUdtUnionCaseTupleV0():
{
const tupleCase = unionCase.tupleCase();
return {
doc: tupleCase.doc().toString(),
name: tupleCase.name().toString(),
types: tupleCase.type().map(t => (0, _utils.parseTypeFromTypeDef)(t))
};
}
default:
throw new Error(`Unknown union case kind: ${unionCase.switch()}`);
}
}
/**
* Generate enum case
*/
generateEnumCase(enumCase) {
return {
doc: enumCase.doc().toString(),
name: enumCase.name().toString(),
value: enumCase.value()
};
}
generateTupleStruct(udtStruct) {
const name = (0, _utils.sanitizeIdentifier)(udtStruct.name().toString());
const doc = (0, _utils.formatJSDocComment)(udtStruct.doc().toString() || `Tuple Struct: ${name}`, 0);
const types = udtStruct.fields().map(field => (0, _utils.parseTypeFromTypeDef)(field.type())).join(", ");
return `${doc}export type ${name} = readonly [${types}];`;
}
}
exports.TypeGenerator = TypeGenerator;
Source