Skip to content

Commit

Permalink
Add Typescript action builder
Browse files Browse the repository at this point in the history
  • Loading branch information
maxifom committed Mar 26, 2022
1 parent b49a449 commit 07fd6fb
Show file tree
Hide file tree
Showing 7 changed files with 118 additions and 9 deletions.
2 changes: 1 addition & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
"github.com/spf13/viper"
)

var VERSION = "0.0.1"
var VERSION = "0.0.6"

var cfgFile string

Expand Down
32 changes: 31 additions & 1 deletion pkg/commands/generate-ts/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,14 @@ func Run(opts Opts) error {
if err != nil {
return err
}

t, err = t.New("nested").Parse(ts.NestedArrayTemplate)
if err != nil {
return err
}
t, err = t.New("action_builder").Parse(ts.ActionBuilderTemplate)
if err != nil {
return err
}

contractName := strings.TrimSuffix(filepath.Base(opts.ContractFilePath), filepath.Ext(opts.ContractFilePath))

Expand Down Expand Up @@ -118,6 +121,11 @@ type Method struct {
Struct Struct
}

type Action struct {
Name string
ParamsName string
}

func gen(abi abitypes.ABI, contractName string, realContractName string, generatedFolder string, version string, t *template.Template) error {
typesF, err := os.Create(filepath.Join(generatedFolder, contractName, "types.ts"))
if err != nil {
Expand All @@ -137,6 +145,12 @@ func gen(abi abitypes.ABI, contractName string, realContractName string, generat
}
defer clientF.Close()

actionBuilderF, err := os.Create(filepath.Join(generatedFolder, contractName, "action_builder.ts"))
if err != nil {
return err
}
defer actionBuilderF.Close()

err = t.ExecuteTemplate(indexF, "index", map[string]interface{}{
"Version": version,
})
Expand Down Expand Up @@ -204,6 +218,22 @@ func gen(abi abitypes.ABI, contractName string, realContractName string, generat
return err
}

var actions []Action
for _, action := range abi.Actions {
actions = append(actions, Action{
Name: action.Name,
ParamsName: strcase.UpperCamelCase(action.Type),
})
}

err = t.ExecuteTemplate(actionBuilderF, "action_builder", map[string]interface{}{
"Version": version,
"Actions": actions,
})
if err != nil {
return err
}

return nil
}

Expand Down
61 changes: 61 additions & 0 deletions templates/ts/action_builder.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package ts

import "strings"

var ActionBuilderTemplate = strings.TrimSpace(`
// Generated by eos-abigen-js version {{.Version}}
import * as types from "./types"
import {Authorization} from "./types"
export interface ActionBuilderOpts {
defaultAuthorization?: Authorization;
}
export class ActionBuilder {
private readonly actions: types.Action[];
private readonly defaultAuthorization?: Authorization;
constructor(opts?: ActionBuilderOpts) {
this.actions = [];
this.defaultAuthorization = opts?.defaultAuthorization;
}
addRawAction(action: types.Action): this {
this.actions.push(action);
return this;
}
build(): types.Action[] {
return this.actions;
}
{{range $i, $a := .Actions -}}
{{ $a.Name }}(params: types.{{ $a.ParamsName }}, ...authorizations: Authorization[]): this {
const actionName = "{{ $a.Name }}";
this.actions.push(
{
account: types.CONTRACT_NAME,
name: actionName,
authorization: this.getAuth(actionName, authorizations),
data: params
}
);
return this;
}
{{ end -}}
private getAuth(actionName: string, authorizations?: types.Authorization[]): types.Authorization[] {
if (!authorizations || authorizations.length === 0) {
if (!this.defaultAuthorization) {
throw new Error("Authorizations or default authorization is required for action " + actionName)
}
return [this.defaultAuthorization]
}
return authorizations
}
}
`)
9 changes: 7 additions & 2 deletions templates/ts/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,14 @@ var ClientTemplate = strings.TrimSpace(`
import {JsonRpc} from "eosjs";
import * as types from "./types";
export class Client {
export interface ClientOpts {
rpc: JsonRpc;
}
export class Client {
private readonly rpc: JsonRpc;
public constructor(opts: types.ClientOpts) {
public constructor(opts: ClientOpts) {
this.rpc = opts.rpc;
}
{{ range .Methods }}
Expand Down Expand Up @@ -52,6 +56,7 @@ export class Client {
// Mapping for {{ .Name }} field
{
{{- template "nested" (genStructForNestedArray 0 .)}}
// @ts-ignore
row.{{.Name}} = arr0;
}
{{- end -}}
Expand Down
1 change: 1 addition & 0 deletions templates/ts/index.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ var IndexTemplate = strings.TrimSpace(`
// Generated by eos-abigen-js version {{.Version}}
export * from "./client";
export * from "./action_builder";
`)
10 changes: 7 additions & 3 deletions templates/ts/nested_array.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,20 @@ import "strings"

var NestedArrayTemplate = strings.TrimSpace(`
{{ define "nested" }}
{{ generateTabs (sub .I -4)}}// @ts-ignore
{{ generateTabs (sub .I -4)}}let arr{{.I}} = [];
{{ generateTabs (sub .I -4)}}// @ts-ignore
{{ generateTabs (sub .I -4)}}for (let i{{.I}} = 0; i{{.I}} < row.{{.F.Name}}{{generateIBrackets .I}}.length; i{{.I}}++) {
{{- if eq .I (sub .F.ArraysCount 1) }}
{{ generateTabs (sub .I -5)}}arr{{.I}}.push({{.F.Func}}(row.{{.F.Name}}{{generateIBrackets (sub .I -1)}}){{ if ne .F.Method ""}}.{{.F.Method}}(){{end}})
{{- if eq .I (sub .F.ArraysCount 1) }}
{{ generateTabs (sub .I -5)}}// @ts-ignore
{{ generateTabs (sub .I -5)}}arr{{.I}}.push({{.F.Func}}{{if ne .F.Func ""}}({{end}}row.{{.F.Name}}{{generateIBrackets (sub .I -1)}}{{if ne .F.Func ""}}){{end}}{{ if ne .F.Method ""}}.{{.F.Method}}(){{end}})
{{- else -}}
{{- template "nested" (genStructForNestedArray (sub .I -1) .F) -}}
{{- end }}
{{ generateTabs (sub .I -4) -}} }
{{ if gt .I 0 -}}
{{ generateTabs (sub .I -2) -}} arr{{sub .I 1}}.push(arr{{.I}});
{{ generateTabs (sub .I -2) }}// @ts-ignore
{{ generateTabs (sub .I -4) -}}arr{{sub .I 1}}.push(arr{{.I}});
{{- end -}}
{{end -}}
`)
12 changes: 10 additions & 2 deletions templates/ts/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,16 @@ import {JsonRpc} from "eosjs";
export const CONTRACT_NAME = "{{.ContractName}}";
export interface ClientOpts {
rpc: JsonRpc;
export type Authorization = {
actor: string;
permission: string;
}
export type Action = {
account: string;
name: string;
authorization: Authorization[];
data: object;
}
export type GetTableRowsParams = Partial<{
Expand Down

0 comments on commit 07fd6fb

Please sign in to comment.