@wharfkit/contract
Advanced tools
Comparing version 0.4.0 to 0.4.1
@@ -80,3 +80,3 @@ import { ABI, APIClient, API, ABIDef, NameType, Name, PermissionLevelType, BytesType, ABISerializableObject, Action, Blob } from '@wharfkit/antelope'; | ||
index?: string; | ||
scope?: NameType; | ||
scope?: NameType | number; | ||
key_type?: keyof API.v1.TableIndexTypes; | ||
@@ -103,2 +103,3 @@ json?: boolean; | ||
defaultRowLimit?: number; | ||
defaultScope?: NameType; | ||
} | ||
@@ -123,2 +124,3 @@ interface GetTableRowsOptions { | ||
private fieldToIndex?; | ||
defaultScope?: NameType; | ||
defaultRowLimit: number; | ||
@@ -220,3 +222,3 @@ /** | ||
hasTable(name: NameType): boolean; | ||
table<RowType = any>(name: NameType, rowType?: any): Table<RowType>; | ||
table<RowType = any>(name: NameType, scope?: NameType, rowType?: any): Table<RowType>; | ||
get actionNames(): string[]; | ||
@@ -223,0 +225,0 @@ hasAction(name: NameType): boolean; |
@@ -224,2 +224,3 @@ 'use strict'; | ||
this.tableABI = tableABI; | ||
this.defaultScope = args.defaultScope; | ||
} | ||
@@ -233,3 +234,5 @@ static from(tableParams) { | ||
code: this.account, | ||
scope: params.scope || this.account, | ||
scope: params.scope !== undefined | ||
? String(params.scope) | ||
: this.defaultScope || this.account, | ||
type: this.rowType, | ||
@@ -261,3 +264,5 @@ key_type: params.key_type, | ||
code: this.account, | ||
scope: params.scope || this.account, | ||
scope: params.scope !== undefined | ||
? String(params.scope) | ||
: this.defaultScope || this.account, | ||
type: this.rowType, | ||
@@ -347,3 +352,3 @@ limit: 1, | ||
} | ||
table(name, rowType) { | ||
table(name, scope, rowType) { | ||
if (!this.hasTable(name)) { | ||
@@ -350,0 +355,0 @@ throw new Error(`Contract (${this.account}) does not have a table named (${name})`); |
@@ -199,2 +199,3 @@ import { isInstanceOf, UInt128, UInt64, Float64, Checksum256, Checksum160, Name, Serializer, ABI, Blob, PermissionLevel, Action } from '@wharfkit/antelope'; | ||
this.tableABI = tableABI; | ||
this.defaultScope = args.defaultScope; | ||
} | ||
@@ -208,3 +209,5 @@ static from(tableParams) { | ||
code: this.account, | ||
scope: params.scope || this.account, | ||
scope: params.scope !== undefined | ||
? String(params.scope) | ||
: this.defaultScope || this.account, | ||
type: this.rowType, | ||
@@ -235,3 +238,5 @@ key_type: params.key_type, | ||
code: this.account, | ||
scope: params.scope || this.account, | ||
scope: params.scope !== undefined | ||
? String(params.scope) | ||
: this.defaultScope || this.account, | ||
type: this.rowType, | ||
@@ -321,3 +326,3 @@ limit: 1, | ||
} | ||
table(name, rowType) { | ||
table(name, scope, rowType) { | ||
if (!this.hasTable(name)) { | ||
@@ -324,0 +329,0 @@ throw new Error(`Contract (${this.account}) does not have a table named (${name})`); |
{ | ||
"name": "@wharfkit/contract", | ||
"description": "ContractKit for Wharf", | ||
"version": "0.4.0", | ||
"version": "0.4.1", | ||
"homepage": "https://github.com/wharfkit/contract", | ||
@@ -6,0 +6,0 @@ "license": "BSD-3-Clause", |
@@ -0,14 +1,9 @@ | ||
import * as prettier from 'prettier' | ||
import * as ts from 'typescript' | ||
import * as prettier from 'prettier' | ||
import { | ||
EOSIO_CORE_CLASSES, | ||
EOSIO_CORE_TYPES, | ||
generateField, | ||
generateImportStatement, | ||
generateStruct, | ||
getFieldTypesFromAbi, | ||
} from './codegen/helpers' | ||
import {generateContractClass} from './codegen/contract' | ||
import {generateImportStatement, getCoreImports} from './codegen/helpers' | ||
import {generateActionNamesInterface, generateActionsNamespace} from './codegen/interfaces' | ||
import {generateTableMap} from './codegen/maps' | ||
import {generateNamespace, generateNamespaceName} from './codegen/namespace' | ||
import {generateContractClass} from './codegen/contract' | ||
import {generateStructClasses} from './codegen/structs' | ||
import {abiToBlob} from './utils' | ||
@@ -19,104 +14,107 @@ | ||
export async function codegen(contractName, abi) { | ||
const namespaceName = generateNamespaceName(contractName) | ||
try { | ||
const namespaceName = generateNamespaceName(contractName) | ||
const importCoreStatement = generateImportStatement( | ||
[ | ||
'ABI', | ||
'APIClient', | ||
'Session', | ||
'Struct', | ||
'TransactResult', | ||
...EOSIO_CORE_CLASSES, | ||
...EOSIO_CORE_TYPES, | ||
], | ||
'@wharfkit/session' | ||
) | ||
const importContractStatement = generateImportStatement( | ||
['Contract as BaseContract', 'ContractArgs', 'PartialBy', 'blobStringToAbi'], | ||
'@wharfkit/contract' | ||
) | ||
const importContractStatement = generateImportStatement( | ||
['ActionOptions', 'Contract as BaseContract', 'ContractArgs', 'PartialBy'], | ||
'@wharfkit/contract' | ||
) | ||
const {classDeclaration} = await generateContractClass(namespaceName, contractName) | ||
const antelopeImports = ['ABI', 'Action', 'Blob', 'Struct', ...getCoreImports(abi)] | ||
// Extract fields from the ABI | ||
const structs = getFieldTypesFromAbi(abi) | ||
antelopeImports.sort() | ||
const structDeclarations: ts.ClassDeclaration[] = [] | ||
const importCoreStatement = generateImportStatement(antelopeImports, '@wharfkit/antelope') | ||
// Iterate through structs and create struct with fields | ||
for (const struct of structs) { | ||
const structMembers: ts.ClassElement[] = [] | ||
const {classDeclaration} = await generateContractClass(contractName, abi) | ||
for (const field of struct.fields) { | ||
structMembers.push(generateField(field, true, `${namespaceName}.Types`, abi)) | ||
} | ||
const actionNamesInterface = generateActionNamesInterface(abi) | ||
structDeclarations.push(generateStruct(struct.structName, true, structMembers)) | ||
} | ||
const actionsNamespace = generateActionsNamespace(abi) | ||
// Encode the ABI as a binary hex string | ||
const abiBlob = abiToBlob(abi) | ||
// Iterate through structs and create struct classes with fields | ||
const structDeclarations = generateStructClasses(abi) | ||
// Generate `abiBlob` field | ||
const abiBlobField = ts.factory.createVariableStatement( | ||
[ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], | ||
ts.factory.createVariableDeclarationList( | ||
[ | ||
ts.factory.createVariableDeclaration( | ||
'abiBlob', | ||
undefined, | ||
undefined, | ||
ts.factory.createCallExpression( | ||
ts.factory.createPropertyAccessExpression( | ||
ts.factory.createIdentifier('Blob'), | ||
ts.factory.createIdentifier('from') | ||
), | ||
// Encode the ABI as a binary hex string | ||
const abiBlob = abiToBlob(abi) | ||
// Generate `abiBlob` field | ||
const abiBlobField = ts.factory.createVariableStatement( | ||
[ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], | ||
ts.factory.createVariableDeclarationList( | ||
[ | ||
ts.factory.createVariableDeclaration( | ||
'abiBlob', | ||
undefined, | ||
[ts.factory.createStringLiteral(String(abiBlob))] | ||
) | ||
), | ||
], | ||
ts.NodeFlags.Const | ||
undefined, | ||
ts.factory.createCallExpression( | ||
ts.factory.createPropertyAccessExpression( | ||
ts.factory.createIdentifier('Blob'), | ||
ts.factory.createIdentifier('from') | ||
), | ||
undefined, | ||
[ts.factory.createStringLiteral(String(abiBlob))] | ||
) | ||
), | ||
], | ||
ts.NodeFlags.Const | ||
) | ||
) | ||
) | ||
// Generate `abiBlob` field | ||
const abiField = ts.factory.createVariableStatement( | ||
[ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], | ||
ts.factory.createVariableDeclarationList( | ||
[ | ||
ts.factory.createVariableDeclaration( | ||
'abi', | ||
undefined, | ||
undefined, | ||
ts.factory.createCallExpression( | ||
ts.factory.createPropertyAccessExpression( | ||
ts.factory.createIdentifier('ABI'), | ||
ts.factory.createIdentifier('from') | ||
), | ||
// Generate `abiBlob` field | ||
const abiField = ts.factory.createVariableStatement( | ||
[ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], | ||
ts.factory.createVariableDeclarationList( | ||
[ | ||
ts.factory.createVariableDeclaration( | ||
'abi', | ||
undefined, | ||
[ts.factory.createIdentifier('abiBlob')] | ||
) | ||
), | ||
], | ||
ts.NodeFlags.Const | ||
undefined, | ||
ts.factory.createCallExpression( | ||
ts.factory.createPropertyAccessExpression( | ||
ts.factory.createIdentifier('ABI'), | ||
ts.factory.createIdentifier('from') | ||
), | ||
undefined, | ||
[ts.factory.createIdentifier('abiBlob')] | ||
) | ||
), | ||
], | ||
ts.NodeFlags.Const | ||
) | ||
) | ||
) | ||
// Generate types namespace | ||
const namespaceDeclaration = generateNamespace(namespaceName, [ | ||
abiBlobField, | ||
abiField, | ||
classDeclaration, | ||
generateNamespace('Types', structDeclarations), | ||
]) | ||
const tableMap = generateTableMap(abi) | ||
const sourceFile = ts.factory.createSourceFile( | ||
[importContractStatement, importCoreStatement, namespaceDeclaration], | ||
ts.factory.createToken(ts.SyntaxKind.EndOfFileToken), | ||
ts.NodeFlags.None | ||
) | ||
const exportStatement = ts.factory.createExportAssignment( | ||
undefined, | ||
undefined, | ||
false, | ||
ts.factory.createIdentifier(namespaceName) | ||
) | ||
const options = await prettier.resolveConfig(process.cwd()) | ||
return await prettier.format(printer.printFile(sourceFile), options) | ||
// Generate types namespace | ||
const namespaceDeclaration = generateNamespace(namespaceName, [ | ||
abiBlobField, | ||
abiField, | ||
classDeclaration, | ||
actionNamesInterface, | ||
actionsNamespace, | ||
generateNamespace('Types', structDeclarations), | ||
tableMap, | ||
]) | ||
const sourceFile = ts.factory.createSourceFile( | ||
[importContractStatement, importCoreStatement, namespaceDeclaration, exportStatement], | ||
ts.factory.createToken(ts.SyntaxKind.EndOfFileToken), | ||
ts.NodeFlags.None | ||
) | ||
const options = await prettier.resolveConfig(process.cwd()) | ||
return prettier.format(printer.printFile(sourceFile), options) | ||
} catch (e) { | ||
// eslint-disable-next-line no-console | ||
console.error(`An error occurred while generating the contract code: ${e}`) | ||
throw e | ||
} | ||
} |
@@ -0,1 +1,2 @@ | ||
import {ABI} from '@wharfkit/antelope' | ||
import * as ts from 'typescript' | ||
@@ -5,3 +6,3 @@ | ||
export async function generateContractClass(namespaceName: string, contractName: string) { | ||
export async function generateContractClass(contractName: string, abi: ABI.Def) { | ||
// Prepare the member fields of the class | ||
@@ -33,35 +34,3 @@ const classMembers: ts.ClassElement[] = [] | ||
const constructorBody = ts.factory.createBlock( | ||
[ | ||
ts.factory.createExpressionStatement( | ||
ts.factory.createCallExpression(ts.factory.createSuper(), undefined, [ | ||
ts.factory.createObjectLiteralExpression( | ||
[ | ||
ts.factory.createPropertyAssignment( | ||
'client', | ||
ts.factory.createPropertyAccessExpression( | ||
ts.factory.createIdentifier('args'), | ||
'client' | ||
) | ||
), | ||
ts.factory.createPropertyAssignment( | ||
'abi', | ||
ts.factory.createIdentifier('abi') | ||
), | ||
ts.factory.createPropertyAssignment( | ||
'account', | ||
ts.factory.createCallExpression( | ||
ts.factory.createPropertyAccessExpression( | ||
ts.factory.createIdentifier('Name'), | ||
'from' | ||
), | ||
undefined, | ||
[ts.factory.createStringLiteral(contractName)] | ||
) | ||
), | ||
], | ||
true | ||
), | ||
]) | ||
), | ||
], | ||
[generateConstructorFunction(contractName)], | ||
true | ||
@@ -79,2 +48,14 @@ ) | ||
if (abi.actions.length) { | ||
const actionMethod = generateActionMethod(abi) | ||
classMembers.push(actionMethod) | ||
} | ||
if (abi.tables.length) { | ||
const tableMethod = generateTableMethod(abi) | ||
classMembers.push(tableMethod) | ||
} | ||
// Construct class declaration | ||
@@ -88,1 +69,174 @@ const classDeclaration = generateClassDeclaration('Contract', classMembers, { | ||
} | ||
function generateConstructorFunction(contractName): ts.ExpressionStatement { | ||
return ts.factory.createExpressionStatement( | ||
ts.factory.createCallExpression(ts.factory.createSuper(), undefined, [ | ||
ts.factory.createObjectLiteralExpression( | ||
[ | ||
ts.factory.createPropertyAssignment( | ||
'client', | ||
ts.factory.createPropertyAccessExpression( | ||
ts.factory.createIdentifier('args'), | ||
'client' | ||
) | ||
), | ||
ts.factory.createPropertyAssignment('abi', ts.factory.createIdentifier('abi')), | ||
ts.factory.createPropertyAssignment( | ||
'account', | ||
ts.factory.createCallExpression( | ||
ts.factory.createPropertyAccessExpression( | ||
ts.factory.createIdentifier('Name'), | ||
'from' | ||
), | ||
undefined, | ||
[ts.factory.createStringLiteral(contractName)] | ||
) | ||
), | ||
], | ||
true | ||
), | ||
]) | ||
) | ||
} | ||
function generateActionMethod(abi: ABI.Def): ts.MethodDeclaration { | ||
const typeParameter = ts.factory.createTypeParameterDeclaration( | ||
'T', | ||
ts.factory.createUnionTypeNode( | ||
abi.actions.map((action) => | ||
ts.factory.createLiteralTypeNode( | ||
ts.factory.createStringLiteral(String(action.name)) | ||
) | ||
) | ||
) | ||
) | ||
// 3. Create the function parameters. | ||
const nameParameter = ts.factory.createParameterDeclaration( | ||
undefined, | ||
undefined, | ||
undefined, | ||
'name', | ||
undefined, | ||
ts.factory.createTypeReferenceNode('T'), | ||
undefined | ||
) | ||
const dataParameter = ts.factory.createParameterDeclaration( | ||
undefined, | ||
undefined, | ||
undefined, | ||
'data', | ||
undefined, | ||
ts.factory.createTypeReferenceNode('ActionNameParams[T]'), | ||
undefined | ||
) | ||
const optionsParameter = ts.factory.createParameterDeclaration( | ||
undefined, | ||
undefined, | ||
undefined, | ||
'options', | ||
ts.factory.createToken(ts.SyntaxKind.QuestionToken), | ||
ts.factory.createTypeReferenceNode('ActionOptions'), | ||
undefined | ||
) | ||
// 4. Generate the function body. | ||
const methodBody = ts.factory.createBlock( | ||
[ | ||
ts.factory.createReturnStatement( | ||
ts.factory.createCallExpression( | ||
ts.factory.createPropertyAccessExpression( | ||
ts.factory.createSuper(), | ||
ts.factory.createIdentifier('action') | ||
), | ||
undefined, | ||
[ | ||
ts.factory.createIdentifier('name'), | ||
ts.factory.createIdentifier('data'), | ||
ts.factory.createIdentifier('options'), | ||
] | ||
) | ||
), | ||
], | ||
true | ||
) | ||
return ts.factory.createMethodDeclaration( | ||
undefined, | ||
undefined, | ||
undefined, | ||
'action', | ||
undefined, | ||
[typeParameter], | ||
[nameParameter, dataParameter, optionsParameter], | ||
ts.factory.createTypeReferenceNode('Action'), | ||
methodBody | ||
) | ||
} | ||
function generateTableMethod(abi: ABI.Def): ts.MethodDeclaration { | ||
const typeParameter = ts.factory.createTypeParameterDeclaration( | ||
'T', | ||
ts.factory.createUnionTypeNode( | ||
abi.tables.map((table) => | ||
ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(String(table.name))) | ||
) | ||
) | ||
) | ||
// 3. Create the function parameters. | ||
const nameParameter = ts.factory.createParameterDeclaration( | ||
undefined, | ||
undefined, | ||
undefined, | ||
'name', | ||
undefined, | ||
ts.factory.createTypeReferenceNode('T'), | ||
undefined | ||
) | ||
const scopeParameter = ts.factory.createParameterDeclaration( | ||
undefined, | ||
undefined, | ||
undefined, | ||
'scope', | ||
ts.factory.createToken(ts.SyntaxKind.QuestionToken), | ||
ts.factory.createTypeReferenceNode('NameType'), | ||
undefined | ||
) | ||
// 4. Generate the function body. | ||
const methodBody = ts.factory.createBlock( | ||
[ | ||
ts.factory.createReturnStatement( | ||
ts.factory.createCallExpression( | ||
ts.factory.createPropertyAccessExpression( | ||
ts.factory.createSuper(), | ||
ts.factory.createIdentifier('table') | ||
), | ||
undefined, | ||
[ | ||
ts.factory.createIdentifier('name'), | ||
ts.factory.createIdentifier('scope'), | ||
ts.factory.createIdentifier('TableMap[name]'), | ||
] | ||
) | ||
), | ||
], | ||
true | ||
) | ||
return ts.factory.createMethodDeclaration( | ||
undefined, | ||
undefined, | ||
undefined, | ||
'table', | ||
undefined, | ||
[typeParameter], | ||
[nameParameter, scopeParameter], | ||
undefined, | ||
methodBody | ||
) | ||
} |
@@ -0,1 +1,2 @@ | ||
import * as Antelope from '@wharfkit/antelope' | ||
import {ABI} from '@wharfkit/antelope' | ||
@@ -6,22 +7,32 @@ import * as ts from 'typescript' | ||
export const EOSIO_CORE_CLASSES = [ | ||
'Asset', | ||
'Checksum256', | ||
'Float64', | ||
'Name', | ||
'TimePoint', | ||
'TimePointSec', | ||
'UInt128', | ||
'UInt16', | ||
'UInt32', | ||
'UInt64', | ||
'UInt8', | ||
] | ||
const EOSIO_CORE_CLASSES: string[] = [] | ||
Object.keys(Antelope).map((key) => { | ||
if (Antelope[key].abiName) { | ||
EOSIO_CORE_CLASSES.push(key) | ||
} | ||
}) | ||
export const EOSIO_CORE_TYPES = [ | ||
'AssetType', | ||
'Blob', | ||
'BlobType', | ||
'BlockIdType', | ||
'BytesType', | ||
'ChecksumType', | ||
'Checksum160Type', | ||
'Checksum256Type', | ||
'Checksum512Type', | ||
'FloatType', | ||
'Float32Type', | ||
'Float64Type', | ||
'Float128Type', | ||
'IntType', | ||
'Int8Type', | ||
'Int16Type', | ||
'Int32Type', | ||
'Int64Type', | ||
'Int128Type', | ||
'NameType', | ||
'PermissionLevelType', | ||
'PublicKeyType', | ||
'SignatureType', | ||
'TimePointType', | ||
@@ -33,7 +44,31 @@ 'UInt128Type', | ||
'UInt8Type', | ||
'VarIntType', | ||
'VarUIntType', | ||
] | ||
interface FieldType { | ||
name: string | ||
type: string | ||
export function getCoreImports(abi: ABI.Def) { | ||
const coreImports: string[] = [] | ||
for (const struct of abi.structs) { | ||
for (const field of struct.fields) { | ||
const coreClass = findCoreClass(field.type) | ||
if (coreClass) { | ||
coreImports.push(coreClass) | ||
} | ||
const isAction = abi.actions.find((action) => action.type === struct.name) | ||
if (!isAction) { | ||
continue | ||
} | ||
const coreType = findCoreType(field.type) | ||
if (coreType) { | ||
coreImports.push(coreType) | ||
} | ||
} | ||
} | ||
return coreImports.filter((value, index, self) => self.indexOf(value) === index) | ||
} | ||
@@ -74,61 +109,2 @@ | ||
export function generatePropertyDeclarationForField(name: string, type: ABI.ResolvedType) { | ||
// field options is an object with all optional fields, e.g.: {array: true, optional: true, extension: true} | ||
const optionsProps: ts.ObjectLiteralElementLike[] = [] | ||
if (type.isArray) { | ||
optionsProps.push( | ||
ts.factory.createPropertyAssignment( | ||
ts.factory.createIdentifier('array'), | ||
ts.factory.createTrue() | ||
) | ||
) | ||
} | ||
if (type.isOptional) { | ||
optionsProps.push( | ||
ts.factory.createPropertyAssignment( | ||
ts.factory.createIdentifier('optional'), | ||
ts.factory.createTrue() | ||
) | ||
) | ||
} | ||
if (type.isExtension) { | ||
optionsProps.push( | ||
ts.factory.createPropertyAssignment( | ||
ts.factory.createIdentifier('extension'), | ||
ts.factory.createTrue() | ||
) | ||
) | ||
} | ||
let optionsObject: ts.ObjectLiteralExpression | undefined | ||
if (optionsProps.length > 0) { | ||
optionsObject = ts.factory.createObjectLiteralExpression(optionsProps) | ||
} | ||
// decorator is a function call, e.g.: @Struct.field(fieldTypeStringorClass, options) | ||
const decoratorArguments: ts.Expression[] = [ts.factory.createStringLiteral(type.name)] | ||
if (optionsObject) { | ||
decoratorArguments.push(optionsObject) | ||
} | ||
const fieldDecorator = ts.factory.createDecorator( | ||
ts.factory.createCallExpression( | ||
ts.factory.createPropertyAccessExpression( | ||
ts.factory.createIdentifier('Struct'), | ||
ts.factory.createIdentifier('field') | ||
), | ||
undefined, // type arguments | ||
decoratorArguments | ||
) | ||
) | ||
// modifier token: declare | ||
const declareModifier = ts.factory.createModifier(ts.SyntaxKind.DeclareKeyword) | ||
const propertyDeclaration = ts.factory.createPropertyDeclaration( | ||
[fieldDecorator, declareModifier], // decorators | ||
ts.factory.createIdentifier(name), // name | ||
undefined, // question token | ||
ts.factory.createTypeReferenceNode(type.name), // type | ||
undefined // initializer | ||
) | ||
return propertyDeclaration | ||
} | ||
export function generateImportStatement(classes, path): ts.ImportDeclaration { | ||
@@ -154,62 +130,2 @@ return ts.factory.createImportDeclaration( | ||
export function generateStruct( | ||
structName: string, | ||
isExport = false, | ||
members: ts.ClassElement[] = [] | ||
): ts.ClassDeclaration { | ||
const decorators = [ | ||
ts.factory.createDecorator( | ||
ts.factory.createCallExpression(ts.factory.createIdentifier('Struct.type'), undefined, [ | ||
ts.factory.createStringLiteral(structName), | ||
]) | ||
), | ||
] | ||
return ts.factory.createClassDeclaration( | ||
isExport | ||
? [...decorators, ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)] | ||
: decorators, | ||
ts.factory.createIdentifier(capitalize(structName)), | ||
undefined, // typeParameters | ||
[ | ||
ts.factory.createHeritageClause(ts.SyntaxKind.ExtendsKeyword, [ | ||
ts.factory.createExpressionWithTypeArguments( | ||
ts.factory.createIdentifier('Struct'), | ||
[] | ||
), | ||
]), | ||
], // heritageClauses | ||
members // Pass the members array | ||
) | ||
} | ||
export function generateField( | ||
field: FieldType, | ||
isExport = false, | ||
namespace: string, | ||
abi: ABI.Def | ||
): ts.PropertyDeclaration { | ||
const fieldName = field.name.toLowerCase() | ||
const decorators = [ | ||
ts.factory.createDecorator( | ||
ts.factory.createCallExpression( | ||
ts.factory.createIdentifier('Struct.field'), | ||
undefined, | ||
[ts.factory.createStringLiteral(field.type)] | ||
) | ||
), | ||
] | ||
return ts.factory.createPropertyDeclaration( | ||
isExport | ||
? [...decorators, ts.factory.createModifier(ts.SyntaxKind.DeclareKeyword)] | ||
: decorators, | ||
ts.factory.createIdentifier(fieldName), // Fixed: Use field.name as the identifier | ||
undefined, // questionToken | ||
ts.factory.createTypeReferenceNode(findInternalType(field.type, namespace, abi)), // Fixed: Use field.type as the type reference | ||
undefined // initializer | ||
) | ||
} | ||
export function generateInterface( | ||
@@ -231,23 +147,2 @@ interfaceName: string, | ||
export function getFieldTypesFromAbi(abi: any): {structName: string; fields: FieldType[]}[] { | ||
const structTypes: {structName: string; fields: FieldType[]}[] = [] | ||
if (abi && abi.structs) { | ||
for (const struct of abi.structs) { | ||
const fields: FieldType[] = [] | ||
for (const field of struct.fields) { | ||
fields.push({ | ||
name: field.name.charAt(0).toUpperCase() + field.name.slice(1), | ||
type: field.type, | ||
}) | ||
} | ||
structTypes.push({structName: struct.name, fields}) | ||
} | ||
} | ||
return structTypes | ||
} | ||
export function findCoreClass(type: string): string | undefined { | ||
@@ -269,4 +164,4 @@ for (const coreType of EOSIO_CORE_CLASSES) { | ||
export function findInternalType(type: string, namespace: string, abi: ABI.Def): string { | ||
let typeString = removeDecorators(type) | ||
export function findInternalType(type: string, typeNamespace: string | null, abi: ABI.Def): string { | ||
let {type: typeString} = extractDecorator(type) | ||
@@ -279,3 +174,3 @@ const relevantAbitype = findAbiType(typeString, abi) | ||
const variantType = findVariantType(typeString, namespace, abi) | ||
const variantType = findVariantType(typeString, typeNamespace, abi) | ||
@@ -286,10 +181,10 @@ if (variantType) { | ||
return formatInternalType(typeString, namespace, abi) | ||
return formatInternalType(typeString, typeNamespace, abi) | ||
} | ||
function formatInternalType(typeString: string, namespace: string, abi: ABI.Def): string { | ||
function formatInternalType(typeString: string, namespace: string | null, abi: ABI.Def): string { | ||
const structNames = abi.structs.map((struct) => struct.name.toLowerCase()) | ||
if (structNames.includes(typeString.toLowerCase())) { | ||
return `${namespace}.${capitalize(typeString)}` | ||
return `${namespace ? `${namespace}.` : ''}${generateStructClassName(typeString)}` | ||
} else { | ||
@@ -300,3 +195,14 @@ return findCoreClass(typeString) || capitalize(typeString) | ||
function findVariantType(typeString: string, namespace: string, abi: ABI.Def): string | undefined { | ||
export function generateStructClassName(name) { | ||
return name | ||
.split('_') | ||
.map((word) => capitalize(word)) | ||
.join('') | ||
} | ||
function findVariantType( | ||
typeString: string, | ||
namespace: string | null, | ||
abi: ABI.Def | ||
): string | undefined { | ||
const abiVariant = abi.variants.find( | ||
@@ -315,12 +221,19 @@ (variant) => variant.name.toLowerCase() === typeString.toLowerCase() | ||
function findAbiType(typeString: string, abi: ABI.Def): string | undefined { | ||
return abi.types.find( | ||
(abiType) => abiType.new_type_name.toLowerCase() === typeString.toLowerCase() | ||
)?.type | ||
export function findAbiType( | ||
typeString: string, | ||
abi: ABI.Def, | ||
typeNamespace = '' | ||
): string | undefined { | ||
const abiType = abi.structs.find((abiType) => abiType.name === typeString)?.name | ||
if (abiType) { | ||
return `${typeNamespace}${generateStructClassName(abiType)}` | ||
} | ||
} | ||
export function findExternalType(type: string, abi: ABI.Def): string { | ||
let typeString = removeDecorators(type) | ||
export function findExternalType(type: string, abi: ABI.Def, typeNamespace?: string): string { | ||
let {type: typeString} = extractDecorator(type) | ||
const {decorator} = extractDecorator(type) | ||
const relevantAbitype = findAbiType(typeString, abi) | ||
const relevantAbitype = findAbiType(typeString, abi, typeNamespace) | ||
@@ -331,15 +244,16 @@ if (relevantAbitype) { | ||
return findCoreType(typeString) || capitalize(typeString) | ||
return `${findCoreType(typeString) || capitalize(typeString)}${decorator === '[]' ? '[]' : ''}` | ||
} | ||
const decorators = ['?', '[]'] | ||
function removeDecorators(type: string) { | ||
export function extractDecorator(type: string): {type: string; decorator?: string} { | ||
for (const decorator of decorators) { | ||
if (type.includes(decorator)) { | ||
type = type.replace(decorator, '') | ||
break | ||
return {type, decorator} | ||
} | ||
} | ||
return type | ||
return {type} | ||
} |
@@ -76,3 +76,3 @@ import { | ||
public table<RowType = any>(name: NameType, rowType?): Table<RowType> { | ||
public table<RowType = any>(name: NameType, scope?: NameType, rowType?): Table<RowType> { | ||
if (!this.hasTable(name)) { | ||
@@ -79,0 +79,0 @@ throw new Error(`Contract (${this.account}) does not have a table named (${name})`) |
import {ABI, ABIDef, API, APIClient, Name, NameType, Serializer} from '@wharfkit/antelope' | ||
import {indexPositionInWords, wrapIndexValue} from '../utils' | ||
import {TableCursor} from './table-cursor' | ||
import {TableRowCursor} from './row-cursor' | ||
import {TableScopeCursor} from './scope-cursor' | ||
import {TableCursor} from './table-cursor' | ||
export interface QueryParams { | ||
index?: string | ||
scope?: NameType | ||
scope?: NameType | number | ||
key_type?: keyof API.v1.TableIndexTypes | ||
@@ -32,2 +32,3 @@ json?: boolean | ||
defaultRowLimit?: number | ||
defaultScope?: NameType | ||
} | ||
@@ -56,2 +57,3 @@ | ||
public defaultScope?: NameType | ||
public defaultRowLimit = 1000 | ||
@@ -82,2 +84,3 @@ | ||
this.tableABI = tableABI | ||
this.defaultScope = args.defaultScope | ||
} | ||
@@ -116,3 +119,6 @@ | ||
code: this.account, | ||
scope: params.scope || this.account, | ||
scope: | ||
params.scope !== undefined | ||
? String(params.scope) | ||
: this.defaultScope || this.account, | ||
// Response typing | ||
@@ -158,3 +164,6 @@ type: this.rowType, | ||
code: this.account, | ||
scope: params.scope || this.account, | ||
scope: | ||
params.scope !== undefined | ||
? String(params.scope) | ||
: this.defaultScope || this.account, | ||
type: this.rowType!, | ||
@@ -161,0 +170,0 @@ limit: 1, |
export * from './contract' | ||
export * from './contract/table' | ||
export * from './contract/row-cursor' | ||
export * from './contract/scope-cursor' | ||
export * from './contract/table' | ||
export * from './kit' | ||
export * from './utils' |
@@ -0,4 +1,4 @@ | ||
import type {ABICacheInterface} from '@wharfkit/abicache' | ||
import {ABICache} from '@wharfkit/abicache' | ||
import {ABI, ABIDef, APIClient, Name, NameType} from '@wharfkit/antelope' | ||
import {ABICache} from '@wharfkit/abicache' | ||
import type {ABICacheInterface} from '@wharfkit/abicache' | ||
import {Contract} from './contract' | ||
@@ -5,0 +5,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
128852
26
2630