diff --git a/go.mod b/go.mod index 66405e839290cb4ebb15663c7dd39f1925ffc0e4..abc8a8b72f4f9af7ddc69934a3b56ac2f9062b65 100644 --- a/go.mod +++ b/go.mod @@ -9,31 +9,23 @@ require ( github.com/davecgh/go-spew v1.1.1 github.com/deckarep/golang-set v1.8.0 github.com/ethereum/go-ethereum v1.10.22 - github.com/go-openapi/spec v0.20.7 github.com/gobuffalo/packr/v2 v2.8.3 - github.com/imdario/mergo v0.3.13 + github.com/iancoleman/strcase v0.2.0 github.com/json-iterator/go v1.1.12 - github.com/test-go/testify v1.1.4 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce nhooyr.io/websocket v1.8.7 - sigs.k8s.io/yaml v1.3.0 ) require ( github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 // indirect github.com/go-ole/go-ole v1.2.1 // indirect - github.com/go-openapi/jsonpointer v0.19.5 // indirect - github.com/go-openapi/jsonreference v0.20.0 // indirect - github.com/go-openapi/swag v0.19.15 // indirect github.com/go-stack/stack v1.8.0 // indirect github.com/gobuffalo/logger v1.0.6 // indirect github.com/gobuffalo/packd v1.0.1 // indirect github.com/gorilla/websocket v1.4.2 // indirect - github.com/josharian/intern v1.0.0 // indirect github.com/karrick/godirwalk v1.16.1 // indirect github.com/klauspost/compress v1.10.3 // indirect - github.com/mailru/easyjson v0.7.6 // indirect github.com/markbates/errx v1.1.0 // indirect github.com/markbates/oncer v1.0.0 // indirect github.com/markbates/safe v1.0.1 // indirect @@ -41,15 +33,11 @@ require ( github.com/mattn/go-isatty v0.0.14 // indirect github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect github.com/sirupsen/logrus v1.8.1 // indirect - github.com/stretchr/testify v1.7.2 // indirect github.com/tklauser/go-sysconf v0.3.5 // indirect github.com/tklauser/numcpus v0.2.2 // indirect golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 523fc55d93f3d2202cb1563e2c02bc08bdfe006f..1b0274548404495e119a32623073a10ec5aff0ec 100644 --- a/go.sum +++ b/go.sum @@ -67,7 +67,6 @@ github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -94,16 +93,6 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-ole/go-ole v1.2.1 h1:2lOsA72HgjxAuMlKpFiCbHTvu44PIVkZ5hqm3RSdI/E= github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= -github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= -github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonreference v0.20.0 h1:MYlu0sBgChmCfJxxUKZ8g1cPWFOB37YSZqewK7OKeyA= -github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= -github.com/go-openapi/spec v0.20.7 h1:1Rlu/ZrOCCob0n+JKKJAWhNWMPW8bOZRg8FJaY+0SKI= -github.com/go-openapi/spec v0.20.7/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA= -github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM= -github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= @@ -215,13 +204,11 @@ github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/iancoleman/strcase v0.2.0 h1:05I4QRnGpI0m37iZQRuskXh+w77mr6Z41lwQzuHLwW0= +github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= -github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= @@ -239,15 +226,9 @@ github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= -github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= -github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/markbates/errx v1.1.0 h1:QDFeR+UP95dO12JgW+tgi2UVfo0V8YBHiUIOaeBPiEI= github.com/markbates/errx v1.1.0/go.mod h1:PLa46Oex9KNbVDZhKel8v1OT7hD5JZ2eI7AHhA0wswc= github.com/markbates/oncer v1.0.0 h1:E83IaVAHygyndzPimgUYJjbshhDTALZyXxvk9FOlQRY= @@ -276,8 +257,6 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= @@ -319,8 +298,6 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/test-go/testify v1.1.4 h1:Tf9lntrKUMHiXQ07qBScBTSA0dhYQlu83hswqelv1iE= -github.com/test-go/testify v1.1.4/go.mod h1:rH7cfJo/47vWGdi4GPj16x3/t1xGOj2YxzmNQzk2ghU= github.com/tklauser/go-sysconf v0.3.5 h1:uu3Xl4nkLzQfXNsWn15rPc/HQCJKObbt1dKJeWp3vU4= github.com/tklauser/go-sysconf v0.3.5/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI= github.com/tklauser/numcpus v0.2.2 h1:oyhllyrScuYI6g+h/zUvNXNp1wy7x8qQy3t/piefldA= @@ -680,8 +657,6 @@ google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/l google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU= @@ -692,9 +667,7 @@ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -709,5 +682,3 @@ nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0 rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= -sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= diff --git a/openrpc/cmd/cli.go b/openrpc/cmd/cli.go index 2805cb04c44f9d62df8e7862414d473b03329cc9..ba7c40dfd8a6990700541757fc327794a8a93c48 100644 --- a/openrpc/cmd/cli.go +++ b/openrpc/cmd/cli.go @@ -1,16 +1,14 @@ package main +import "C" import ( "encoding/json" "fmt" - "io/ioutil" + "gfx.cafe/open/jrpc/openrpc/generate" "os" - "gfx.cafe/open/jrpc/openrpc/generate" - "gfx.cafe/open/jrpc/openrpc/parse" "gfx.cafe/open/jrpc/openrpc/types" "github.com/alecthomas/kong" - "github.com/gobuffalo/packr/v2" ) var CLI struct { @@ -25,28 +23,7 @@ type CompileCommand struct { } func (c *CompileCommand) Run() error { - openrpc := types.NewOpenRPCSpec1() - var err error - for _, v := range c.Methods { - err = openrpc.AddMethods(v) - if err != nil { - return err - } - } - for _, v := range c.Schemas { - err = openrpc.AddSchemas(v) - if err != nil { - return err - } - } - jzn, err := json.MarshalIndent(openrpc, "", " ") - if err != nil { - return err - } - err = os.WriteFile(c.Output, jzn, 0644) - if err != nil { - return err - } + // TODO return nil } @@ -64,31 +41,24 @@ func (c *GenerateCommand) Run() error { if err != nil { return err } - parse.GetTypes(openrpc, openrpc.Objects) - box := packr.New("template", "./templates") - if err = generate.WriteFile(box, "server", c.Output, openrpc); err != nil { - return err - } - if err = generate.WriteFile(box, "types", c.Output, openrpc); err != nil { + if err = generate.Generate(openrpc, c.Templates, c.Output); err != nil { return err } + return nil } -func readSpec(file string) (*types.OpenRPCSpec1, error) { - data, err := ioutil.ReadFile(file) - if err != nil { - return nil, err - } - - spec := types.NewOpenRPCSpec1() - err = json.Unmarshal(data, spec) +func readSpec(file string) (out *types.OpenRPC, err error) { + var data []byte + data, err = os.ReadFile(file) if err != nil { - return nil, err + return } - return spec, nil + out = new(types.OpenRPC) + err = json.Unmarshal(data, out) + return } func NewCLI() *kong.Context { diff --git a/openrpc/eth-api.json b/openrpc/eth-api.json index da2e5c00c3a968d5bf465e570fcfc6c2330a6e45..06d85ef2f827b7e1db91d40ca5ab169699cb91e7 100644 --- a/openrpc/eth-api.json +++ b/openrpc/eth-api.json @@ -1959,7 +1959,7 @@ }, "bytes65": { "type": "string", - "title": "bytes645", + "title": "bytes65", "pattern": "^0x[0-9a-f]{512}$" }, "bytes8": { diff --git a/openrpc/generate/generate.go b/openrpc/generate/generate.go index 63e0334c3219bb1ebb6f1d124235a432a2b7ef2a..c7268ed76d239019f4eef485dd780d58376700a5 100644 --- a/openrpc/generate/generate.go +++ b/openrpc/generate/generate.go @@ -2,242 +2,77 @@ package generate import ( "bytes" - "encoding/json" "fmt" + "gfx.cafe/open/jrpc/openrpc/types" + "github.com/iancoleman/strcase" "go/format" "os" - "path" "path/filepath" - "regexp" - "strings" "text/template" - - "gfx.cafe/open/jrpc/openrpc/types" - "gfx.cafe/open/jrpc/openrpc/util" - "github.com/go-openapi/spec" - "github.com/gobuffalo/packr/v2" - "github.com/imdario/mergo" ) -const ( - params = "Params" - result = "Result" - goExt = "go" - goTmplExt = goExt + "tmpl" -) - -var ProgramName = "CHANGME" - -func schemaAsJSONPretty(s spec.Schema) string { - b, err := json.MarshalIndent(s, "", " ") - if err != nil { - return "" - } - b = bytes.ReplaceAll(b, []byte("{"), []byte("")) - b = bytes.ReplaceAll(b, []byte("}"), []byte("")) - b = bytes.ReplaceAll(b, []byte(`"`), []byte("")) - b = bytes.ReplaceAll(b, []byte(`$ref: #`), []byte("")) - - // Remove empty JSON $refs - reg := regexp.MustCompile(`^\s*\$ref.*$/mg`) - ss := reg.ReplaceAllString(string(b), "") - - return ss -} - -func maybeLookupComponentsContentDescriptor(cmpnts *types.Components, cd *types.ContentDescriptor) (rootCD *types.ContentDescriptor, err error) { - rootCD = cd - if cd == nil || cmpnts == nil { - return - } - if strings.Contains(cd.Schema.Ref.String(), "contentDescriptors") { - r := filepath.Base(cd.Schema.Ref.String()) - rootCD = cmpnts.ContentDescriptors[r] - return - } - return -} - -func schemaHazRef(sch spec.Schema) bool { - return sch.Ref.String() != "" +var defaultTemplates = []string{ + "./templates/types.gotmpl", } -func derefSchemaRecurse(cts *types.Components, sch spec.Schema) spec.Schema { - if schemaHazRef(sch) { - sch = getSchemaFromRef(cts, sch.Ref) - sch = derefSchemaRecurse(cts, sch) - } - for i := range sch.OneOf { - got := derefSchemaRecurse(cts, sch.OneOf[i]) - if err := mergo.Merge(&got, sch.OneOf[i]); err != nil { - panic(err.Error()) - } - got.Schema = "" - sch.OneOf[i] = got - } - for i := range sch.AnyOf { - got := derefSchemaRecurse(cts, sch.AnyOf[i]) - if err := mergo.Merge(&got, sch.AnyOf[i]); err != nil { - panic(err.Error()) - } - got.Schema = "" - sch.AnyOf[i] = got - } - for i := range sch.AllOf { - got := derefSchemaRecurse(cts, sch.AllOf[i]) - if err := mergo.Merge(&got, sch.AllOf[i]); err != nil { - panic(err.Error()) - } - got.Schema = "" - sch.AllOf[i] = got - } - for k := range sch.Properties { - got := derefSchemaRecurse(cts, sch.Properties[k]) - if err := mergo.Merge(&got, sch.Properties[k]); err != nil { - panic(err.Error()) - } - got.Schema = "" - sch.Properties[k] = got - } - for k := range sch.PatternProperties { - got := derefSchemaRecurse(cts, sch.PatternProperties[k]) - if err := mergo.Merge(&got, sch.PatternProperties[k]); err != nil { - panic(err.Error()) - } - got.Schema = "" - sch.PatternProperties[k] = got - } - if sch.Items == nil { - return sch - } - if sch.Items.Len() > 1 { - for i := range sch.Items.Schemas { - got := derefSchemaRecurse(cts, sch.Items.Schemas[i]) - if err := mergo.Merge(&got, sch.Items.Schemas[i]); err != nil { - panic(err.Error()) - } - got.Schema = "" - sch.Items.Schemas[i] = got - } - } else { - // Is schema - got := derefSchemaRecurse(cts, *sch.Items.Schema) - if err := mergo.Merge(&got, sch.Items.Schema); err != nil { - panic(err.Error()) +var funcs = template.FuncMap{ + "list": func(v ...any) []any { + return v + }, + "camelCase": func(v string) string { + return strcase.ToCamel(v) + }, + "goType": func(v string) string { + switch v { + case "boolean": + return "bool" + case "number": + return "float64" + case "string": + return "string" + case "null": + return "struct{}" + default: + panic(fmt.Sprintln("unknown go type:", v)) } - got.Schema = "" - sch.Items.Schema = &got - } - - return sch -} - -func getSchemaFromRef(cmpnts *types.Components, ref spec.Ref) (sch spec.Schema) { - if cmpnts == nil || ref.String() == "" { - return - } - r := filepath.Base(ref.String()) - sch = cmpnts.Schemas[r] // Trust parser - return -} - -func maybeMethodParams(method types.Method) string { - if len(method.Params) > 0 { - return fmt.Sprintf("%s%s", util.CamelCase(method.Name), params) - } - return "" -} - -func maybeMethodResult(method types.Method) string { - if method.Result != nil { - return fmt.Sprintf("%s%s", util.CamelCase(method.Name), result) - } - return "" -} - -func maybeMethodComment(method types.Method) string { - if comment := util.FirstOf(method.Description, method.Summary); comment != "" { - return fmt.Sprintf("// %s", comment) - } - return "" + }, + "refName": func(v string) string { + return filepath.Base(v) + }, } -func maybeFieldComment(desc string) string { - if desc != "" { - return fmt.Sprintf("// %s", desc) +func Generate(rpc *types.OpenRPC, templates []string, output string) error { + if len(templates) == 0 { + templates = defaultTemplates } - return "" -} - -func getProgramName() string { - return ProgramName -} -type object struct { - Name string - Fields *types.FieldMap -} - -func funcMap(openrpc *types.OpenRPCSpec1) template.FuncMap { - return template.FuncMap{ - "programName": getProgramName, - "derefSchema": derefSchemaRecurse, - "schemaHasRef": schemaHazRef, - "schemaAsJSONPretty": schemaAsJSONPretty, - "lookupContentDescriptor": maybeLookupComponentsContentDescriptor, - "sanitizeBackticks": util.SanitizeBackticks, - "inspect": util.Inpect, - "slice": util.Slice, - "camelCase": util.CamelCase, - "lowerFirst": util.LowerFirst, - "maybeMethodComment": maybeMethodComment, - "maybeMethodParams": maybeMethodParams, - "maybeMethodResult": maybeMethodResult, - "maybeFieldComment": maybeFieldComment, - "getObjects": func(om *types.ObjectMap) []object { - keys := om.GetKeys() - objects := make([]object, 0, len(keys)) - for _, k := range keys { - objects = append(objects, object{Name: k, Fields: om.Get(k)}) - } - return objects - }, - "getFields": func(fm *types.FieldMap) []types.BasicType { - keys := fm.GetKeys() - fields := make([]types.BasicType, 0, len(keys)) - for _, k := range keys { - fields = append(fields, fm.Get(k)) - } - return fields - }, - "indent": func(spaces int, v string) string { - pad := strings.Repeat(" ", spaces) - return pad + strings.Replace(v, "\n", "\n"+pad, -1) - }, - } -} + var wr bytes.Buffer + for _, tmpl := range templates { + name := filepath.Base(tmpl) -func WriteFile(box *packr.Box, name, pkg string, openrpc *types.OpenRPCSpec1) error { - data, err := box.Find(fmt.Sprintf("%s.%s", name, goTmplExt)) - if err != nil { - return err - } + t, err := template.New(name).Funcs(funcs).ParseFiles(tmpl) + if err != nil { + return err + } - tmp, err := template.New(name).Funcs(funcMap(openrpc)).Parse(string(data)) - if err != nil { - return err - } + err = t.Execute(&wr, rpc) + if err != nil { + return err + } - tmpl := new(bytes.Buffer) - err = tmp.Execute(tmpl, openrpc) - if err != nil { - return err - } + var fmtd []byte + fmtd, err = format.Source(wr.Bytes()) + if err != nil { + return err + } + wr.Reset() - fmtd, err := format.Source(tmpl.Bytes()) - if err != nil { - return err + name = name[:len(name)-len(filepath.Ext(name))] + err = os.WriteFile(filepath.Join(output, name+".go"), fmtd, 0777) + if err != nil { + return err + } } - return os.WriteFile(path.Join(pkg, fmt.Sprintf("%s.%s", name, goExt)), fmtd, 0644) + return nil } diff --git a/openrpc/generate/generate_test.go b/openrpc/generate/generate_test.go deleted file mode 100644 index c18a5ec91f9dac0b223fe6808750c27ce4560abf..0000000000000000000000000000000000000000 --- a/openrpc/generate/generate_test.go +++ /dev/null @@ -1,83 +0,0 @@ -package generate - -import ( - "bytes" - "encoding/json" - "io/ioutil" - "testing" - "text/template" - - "gfx.cafe/open/jrpc/openrpc/parse" - "gfx.cafe/open/jrpc/openrpc/types" - "github.com/test-go/testify/require" -) - -var exp = `package generate -type ServiceMethodParams struct { -// this is a desc -Param1 string -// this is a desc -Param2 string - -Param3 string -// this is an object -Param4 -} -type Param4 struct { -// this is a foo -Foo string -// this is a bar -Bar string -} -type ServiceMethodResult struct { -// the requested data -Data string -} -` - -func tmpl(t *testing.T) string { - data, err := ioutil.ReadFile("test.json") - require.NoError(t, err) - - spec := types.NewOpenRPCSpec1() - err = json.Unmarshal(data, spec) - require.NoError(t, err) - - parse.GetTypes(spec, spec.Objects) - - data, err = ioutil.ReadFile("test.gotmpl") - require.NoError(t, err) - tmp, err := template.New("server").Funcs(funcMap(spec)).Parse(string(data)) - require.NoError(t, err) - - buf := new(bytes.Buffer) - err = tmp.Execute(buf, spec) - require.NoError(t, err) - - return buf.String() -} - -func TestGenerate(t *testing.T) { - - t.Run("Should be same at least once, in a while", func(t *testing.T) { - require.Equal(t, exp, tmpl(t)) - }) - - t.Skip("isaac gets fail here") - t.Run("Should be deterministic", func(t *testing.T) { - for i := 0; i < 20; i++ { - got := tmpl(t) - if exp == got { - t.Log("same same") - continue - } - t.Log("but different") - require.Equal(t, exp, got) - } - }) -} - -func TestMaybeComment(t *testing.T) { - require.Equal(t, "", maybeFieldComment("")) - require.Equal(t, "// hello, world", maybeFieldComment("hello, world")) -} diff --git a/openrpc/out/types.go b/openrpc/out/types.go index 6bb0777143d418b753074ef332e41c15660f40fc..da062d367d8df4b9da8233e7dbe535b444cc6523 100644 --- a/openrpc/out/types.go +++ b/openrpc/out/types.go @@ -4,663 +4,382 @@ package main type GoOpenRPCService interface { // Returns an RLP-encoded header. - DebugGetRawHeader(*DebugGetRawHeaderParams) (*DebugGetRawHeaderResult, error) + DebugGetRawHeader( + Block BlockNumberOrTag, + ) (HeaderRLP Bytes) // Returns an RLP-encoded block. - DebugGetRawBlock(*DebugGetRawBlockParams) (*DebugGetRawBlockResult, error) + DebugGetRawBlock( + Block BlockNumberOrTag, + ) (BlockRLP Bytes) // Returns an array of EIP-2718 binary-encoded transactions. - DebugGetRawTransaction(*DebugGetRawTransactionParams) (*DebugGetRawTransactionResult, error) + DebugGetRawTransaction( + TransactionHash Hash32, + ) (EIP2718BinaryEncodedTransaction Bytes) // Returns an array of EIP-2718 binary-encoded receipts. - DebugGetRawReceipts(*DebugGetRawReceiptsParams) (*DebugGetRawReceiptsResult, error) + DebugGetRawReceipts( + Block BlockNumberOrTag, + ) (Receipts []Bytes) // Returns an array of recent bad blocks that the client has seen on the network. - DebugGetBadBlocks() (*DebugGetBadBlocksResult, error) + DebugGetBadBlocks() (Blocks []BadBlock) // Returns information about a block by hash. - EthGetBlockByHash(*EthGetBlockByHashParams) (*EthGetBlockByHashResult, error) + EthGetBlockByHash( + BlockHash Hash32, + HydratedTransactions bool, + ) (BlockInformation Block) // Returns information about a block by number. - EthGetBlockByNumber(*EthGetBlockByNumberParams) (*EthGetBlockByNumberResult, error) + EthGetBlockByNumber( + Block BlockNumberOrTag, + HydratedTransactions bool, + ) (BlockInformation Block) // Returns the number of transactions in a block from a block matching the given block hash. - EthGetBlockTransactionCountByHash(*EthGetBlockTransactionCountByHashParams) (*EthGetBlockTransactionCountByHashResult, error) + EthGetBlockTransactionCountByHash( + BlockHash Hash32, + ) (TransactionCount Uint) // Returns the number of transactions in a block matching the given block number. - EthGetBlockTransactionCountByNumber(*EthGetBlockTransactionCountByNumberParams) (*EthGetBlockTransactionCountByNumberResult, error) + EthGetBlockTransactionCountByNumber( + Block BlockNumberOrTag, + ) (TransactionCount Uint) // Returns the number of uncles in a block from a block matching the given block hash. - EthGetUncleCountByBlockHash(*EthGetUncleCountByBlockHashParams) (*EthGetUncleCountByBlockHashResult, error) + EthGetUncleCountByBlockHash( + BlockHash Hash32, + ) (UncleCount Uint) // Returns the number of transactions in a block matching the given block number. - EthGetUncleCountByBlockNumber(*EthGetUncleCountByBlockNumberParams) (*EthGetUncleCountByBlockNumberResult, error) + EthGetUncleCountByBlockNumber( + Block BlockNumberOrTag, + ) (UncleCount Uint) // Returns the chain ID of the current network. - EthChainId() (*EthChainIdResult, error) + EthChainId() (ChainID Uint) // Returns an object with data about the sync status or false. - EthSyncing() (*EthSyncingResult, error) + EthSyncing() (SyncingStatus SyncingStatus) // Returns the client coinbase address. - EthCoinbase() (*EthCoinbaseResult, error) + EthCoinbase() (CoinbaseAddress Address) // Returns a list of addresses owned by client. - EthAccounts() (*EthAccountsResult, error) + EthAccounts() (Accounts []Address) // Returns the number of most recent block. - EthBlockNumber() (*EthBlockNumberResult, error) + EthBlockNumber() (BlockNumber Uint) // Executes a new message call immediately without creating a transaction on the block chain. - EthCall(*EthCallParams) (*EthCallResult, error) + EthCall( + Transaction GenericTransaction, + Block BlockNumberOrTag, + ) (ReturnData Bytes) // Generates and returns an estimate of how much gas is necessary to allow the transaction to complete. - EthEstimateGas(*EthEstimateGasParams) (*EthEstimateGasResult, error) + EthEstimateGas( + Transaction GenericTransaction, + Block BlockNumberOrTag, + ) (GasUsed Uint) // Generates an access list for a transaction. - EthCreateAccessList(*EthCreateAccessListParams) (*EthCreateAccessListResult, error) + EthCreateAccessList( + Transaction GenericTransaction, + Block BlockNumberOrTag, + ) (GasUsed struct { + AccessList AccessList + Error string + GasUsed Uint + }) // Returns the current price per gas in wei. - EthGasPrice() (*EthGasPriceResult, error) + EthGasPrice() (GasPrice Uint) // Returns the current maxPriorityFeePerGas per gas in wei. - EthMaxPriorityFeePerGas() (*EthMaxPriorityFeePerGasResult, error) - // Returns transaction base fee per gas and effective priority fee per gas for the requested/supported block range. - EthFeeHistory(*EthFeeHistoryParams) (*EthFeeHistoryResult, error) + EthMaxPriorityFeePerGas() (MaxPriorityFeePerGas Uint) + // Transaction fee history + EthFeeHistory( + BlockCount Uint, + NewestBlock BlockNumberOrTag, + RewardPercentiles []float64, + ) (FeeHistoryResult struct { + BaseFeePerGas []Uint + OldestBlock Uint + Reward [][]Uint + }) // Creates a filter object, based on filter options, to notify when the state changes (logs). - EthNewFilter(*EthNewFilterParams) (*EthNewFilterResult, error) + EthNewFilter( + Filter Filter, + ) (FilterIdentifier Uint) // Creates a filter in the node, to notify when a new block arrives. - EthNewBlockFilter() (*EthNewBlockFilterResult, error) + EthNewBlockFilter() (FilterIdentifier Uint) // Creates a filter in the node, to notify when new pending transactions arrive. - EthNewPendingTransactionFilter() (*EthNewPendingTransactionFilterResult, error) + EthNewPendingTransactionFilter() (FilterIdentifier Uint) // Uninstalls a filter with given id. - EthUninstallFilter(*EthUninstallFilterParams) (*EthUninstallFilterResult, error) + EthUninstallFilter( + FilterIdentifier Uint, + ) (Success bool) // Polling method for a filter, which returns an array of logs which occurred since last poll. - EthGetFilterChanges(*EthGetFilterChangesParams) (*EthGetFilterChangesResult, error) + EthGetFilterChanges( + FilterIdentifier Uint, + ) (LogObjects FilterResults) // Returns an array of all logs matching filter with given id. - EthGetFilterLogs(*EthGetFilterLogsParams) (*EthGetFilterLogsResult, error) + EthGetFilterLogs( + FilterIdentifier Uint, + ) (LogObjects FilterResults) // Returns an array of all logs matching filter with given id. - EthGetLogs(*EthGetLogsParams) (*EthGetLogsResult, error) + EthGetLogs( + Filter Filter, + ) (LogObjects FilterResults) // Returns whether the client is actively mining new blocks. - EthMining() (*EthMiningResult, error) + EthMining() (MiningStatus bool) // Returns the number of hashes per second that the node is mining with. - EthHashrate() (*EthHashrateResult, error) + EthHashrate() (MiningStatus Uint) // Returns the hash of the current block, the seedHash, and the boundary condition to be met (“targetâ€). - EthGetWork() (*EthGetWorkResult, error) + EthGetWork() (CurrentWork []Bytes32) // Used for submitting a proof-of-work solution. - EthSubmitWork(*EthSubmitWorkParams) (*EthSubmitWorkResult, error) + EthSubmitWork( + Nonce Bytes8, + Hash Bytes32, + Digest Bytes32, + ) (Success bool) // Used for submitting mining hashrate. - EthSubmitHashrate(*EthSubmitHashrateParams) (*EthSubmitHashrateResult, error) + EthSubmitHashrate( + Hashrate Bytes32, + Id Bytes32, + ) (Success bool) // Returns an EIP-191 signature over the provided data. - EthSign(*EthSignParams) (*EthSignResult, error) + EthSign( + Address Address, + Message Bytes, + ) (Signature Bytes65) // Returns an RLP encoded transaction signed by the specified account. - EthSignTransaction(*EthSignTransactionParams) (*EthSignTransactionResult, error) + EthSignTransaction( + Transaction GenericTransaction, + ) (EncodedTransaction Bytes) // Returns the balance of the account of given address. - EthGetBalance(*EthGetBalanceParams) (*EthGetBalanceResult, error) + EthGetBalance( + Address Address, + Block BlockNumberOrTag, + ) (Balance Uint) // Returns the value from a storage position at a given address. - EthGetStorageAt(*EthGetStorageAtParams) (*EthGetStorageAtResult, error) + EthGetStorageAt( + Address Address, + StorageSlot Uint256, + Block BlockNumberOrTag, + ) (Value Bytes) // Returns the number of transactions sent from an address. - EthGetTransactionCount(*EthGetTransactionCountParams) (*EthGetTransactionCountResult, error) + EthGetTransactionCount( + Address Address, + Block BlockNumberOrTag, + ) (TransactionCount Uint) // Returns code at a given address. - EthGetCode(*EthGetCodeParams) (*EthGetCodeResult, error) + EthGetCode( + Address Address, + Block BlockNumberOrTag, + ) (Bytecode Bytes) // Returns the merkle proof for a given account and optionally some storage keys. - EthGetProof(*EthGetProofParams) (*EthGetProofResult, error) + EthGetProof( + Address Address, + StorageKeys []Hash32, + Block BlockNumberOrTag, + ) (Account AccountProof) // Signs and submits a transaction. - EthSendTransaction(*EthSendTransactionParams) (*EthSendTransactionResult, error) + EthSendTransaction( + Transaction GenericTransaction, + ) (TransactionHash Hash32) // Submits a raw transaction. - EthSendRawTransaction(*EthSendRawTransactionParams) (*EthSendRawTransactionResult, error) + EthSendRawTransaction( + Transaction Bytes, + ) (TransactionHash Hash32) // Returns the information about a transaction requested by transaction hash. - EthGetTransactionByHash(*EthGetTransactionByHashParams) (*EthGetTransactionByHashResult, error) + EthGetTransactionByHash( + TransactionHash Hash32, + ) (TransactionInformation TransactionInfo) // Returns information about a transaction by block hash and transaction index position. - EthGetTransactionByBlockHashAndIndex(*EthGetTransactionByBlockHashAndIndexParams) (*EthGetTransactionByBlockHashAndIndexResult, error) + EthGetTransactionByBlockHashAndIndex( + BlockHash Hash32, + TransactionIndex Uint, + ) (TransactionInformation TransactionInfo) // Returns information about a transaction by block number and transaction index position. - EthGetTransactionByBlockNumberAndIndex(*EthGetTransactionByBlockNumberAndIndexParams) (*EthGetTransactionByBlockNumberAndIndexResult, error) + EthGetTransactionByBlockNumberAndIndex( + Block BlockNumberOrTag, + TransactionIndex Uint, + ) (TransactionInformation TransactionInfo) // Returns the receipt of a transaction by transaction hash. - EthGetTransactionReceipt(*EthGetTransactionReceiptParams) (*EthGetTransactionReceiptResult, error) + EthGetTransactionReceipt( + TransactionHash Hash32, + ) (ReceiptInformation ReceiptInfo) } -type BlockNumberOrTag struct { - FieldUint string `json:"uint"` -} -type DebugGetRawHeaderParams struct { - FieldBlockNumberOrTag string `json:"blockNumberOrTag"` -} -type DebugGetRawHeaderResult struct { - FieldBytes string `json:"bytes"` -} -type DebugGetRawBlockParams struct { - FieldBlockNumberOrTag string `json:"blockNumberOrTag"` -} -type DebugGetRawBlockResult struct { - FieldBytes string `json:"bytes"` -} -type DebugGetRawTransactionParams struct { - FieldHash32 string `json:"hash32"` +type AccessList []AccessListEntry +type AccessListEntry struct { + Address Address + StorageKeys []Hash32 } -type DebugGetRawTransactionResult struct { - FieldBytes string `json:"bytes"` -} -type DebugGetRawReceiptsParams struct { - FieldBlockNumberOrTag string `json:"blockNumberOrTag"` -} -type ReceiptArray struct { - FieldBytes string `json:"bytes"` -} -type DebugGetRawReceiptsResult struct { - FieldBytes string `json:"bytes"` - - FieldReceiptArray []string `json:"receiptArray"` +type AccountProof struct { + AccountProof []Bytes + Address Address + Balance Uint256 + CodeHash Hash32 + Nonce Uint64 + StorageHash Hash32 + StorageProof []StorageProof +} +type BadBlock struct { + Block Bytes + Hash Hash32 + Rlp Bytes } type Block struct { - FieldBytes string `json:"bytes"` -} -type Hash struct { - FieldHash32 string `json:"hash32"` -} -type Rlp struct { - FieldBytes string `json:"bytes"` -} -type BadBlockArray struct { - BadBlock -} -type DebugGetBadBlocksResult struct { - BadBlock - - FieldBadBlockArray []BadBlock `json:"badBlockArray"` -} -type EthGetBlockByHashParams struct { - FieldHash32 string `json:"hash32"` - - FieldHydrated bool `json:"hydrated"` -} -type StateRoot struct { - FieldHash32 string `json:"hash32"` -} -type TransactionsRoot struct { - FieldHash32 string `json:"hash32"` -} -type GasLimit struct { - FieldUint string `json:"uint"` -} -type MixHash struct { - FieldHash32 string `json:"hash32"` -} -type Nonce struct { - FieldBytes8 string `json:"bytes8"` - - FieldUint string `json:"uint"` - - FieldUint64 string `json:"uint64"` -} -type Number struct { - FieldUint string `json:"uint"` -} -type Size struct { - FieldUint string `json:"uint"` -} -type Difficulty struct { - FieldBytes string `json:"bytes"` -} -type ExtraData struct { - FieldBytes string `json:"bytes"` -} -type LogsBloom struct { - FieldBytes256 string `json:"bytes256"` -} -type Sha3Uncles struct { - FieldHash32 string `json:"hash32"` -} -type Timestamp struct { - FieldUint string `json:"uint"` -} -type BaseFeePerGas struct { - // An array of block base fees per gas. This includes the next block after the newest of the returned range, because this value can be derived from the newest block. Zeroes are returned for pre-EIP-1559 blocks. - FieldUint string `json:"uint"` - // An array of block base fees per gas. This includes the next block after the newest of the returned range, because this value can be derived from the newest block. Zeroes are returned for pre-EIP-1559 blocks. - FieldBaseFeePerGas []string `json:"baseFeePerGas"` -} -type GasUsed struct { - // The amount of gas used for this specific transaction alone. - FieldUint string `json:"uint"` -} -type Miner struct { - FieldAddress string `json:"address"` -} -type Uncles struct { - FieldHash32 string `json:"hash32"` - - FieldUncles []string `json:"uncles"` -} -type ParentHash struct { - FieldHash32 string `json:"hash32"` -} -type ReceiptsRoot struct { - FieldHash32 string `json:"hash32"` -} -type TotalDifficulty struct { - FieldUint string `json:"uint"` -} -type EthGetBlockByHashResult struct { - BlockObject -} -type EthGetBlockByNumberParams struct { - FieldBlockNumberOrTag string `json:"blockNumberOrTag"` - - FieldHydrated bool `json:"hydrated"` -} -type EthGetBlockByNumberResult struct { - BlockObject -} -type EthGetBlockTransactionCountByHashParams struct { - FieldHash32 string `json:"hash32"` -} -type EthGetBlockTransactionCountByHashResult struct { - FieldUint string `json:"uint"` -} -type EthGetBlockTransactionCountByNumberParams struct { - FieldBlockNumberOrTag string `json:"blockNumberOrTag"` -} -type EthGetBlockTransactionCountByNumberResult struct { - FieldUint string `json:"uint"` -} -type EthGetUncleCountByBlockHashParams struct { - FieldHash32 string `json:"hash32"` -} -type EthGetUncleCountByBlockHashResult struct { - FieldUint string `json:"uint"` -} -type EthGetUncleCountByBlockNumberParams struct { - FieldBlockNumberOrTag string `json:"blockNumberOrTag"` -} -type EthGetUncleCountByBlockNumberResult struct { - FieldUint string `json:"uint"` -} -type EthChainIdResult struct { - FieldUint string `json:"uint"` -} -type CurrentBlock struct { - FieldUint string `json:"uint"` -} -type HighestBlock struct { - FieldUint string `json:"uint"` -} -type StartingBlock struct { - FieldUint string `json:"uint"` -} -type SyncingStatus struct { - SyncingProgress -} -type EthSyncingResult struct { - FieldSyncingStatus SyncingProgress `json:"syncingStatus"` -} -type EthCoinbaseResult struct { - FieldAddress string `json:"address"` -} -type Accounts struct { - FieldAddress string `json:"address"` -} -type EthAccountsResult struct { - FieldAddress string `json:"address"` - - FieldAccounts []string `json:"accounts"` -} -type EthBlockNumberResult struct { - FieldUint string `json:"uint"` -} -type Address struct { - FieldAddress string `json:"address"` -} -type StorageKeys struct { - FieldHash32 string `json:"hash32"` - - FieldStorageKeys []string `json:"storageKeys"` -} -type AccessList struct { - // EIP-2930 access list - AccessListEntry - // EIP-2930 access list - FieldAccessList []AccessListEntry `json:"accessList"` -} -type MaxFeePerGas struct { - // The maximum total fee per gas the sender is willing to pay (includes the network / base fee and miner / priority fee) in wei - FieldUint string `json:"uint"` -} -type Type struct { - FieldByte string `json:"byte"` -} -type To struct { - // Address of the receiver or null in a contract creation transaction. - FieldAddress string `json:"address"` -} -type ChainId struct { - // Chain ID that this transaction is valid on. - FieldUint string `json:"uint"` -} -type From struct { - FieldAddress string `json:"address"` -} -type Gas struct { - FieldUint string `json:"uint"` -} -type GasPrice struct { - // The gas price willing to be paid by the sender in wei - FieldUint string `json:"uint"` -} -type Input struct { - FieldBytes string `json:"bytes"` -} -type MaxPriorityFeePerGas struct { - // Maximum fee per gas the sender is willing to pay to miners in wei - FieldUint string `json:"uint"` -} -type Value struct { - FieldUint string `json:"uint"` - - FieldUint256 string `json:"uint256"` -} -type EthCallParams struct { - TransactionObjectGenericToAllTypes - - FieldBlockNumberOrTag string `json:"blockNumberOrTag"` -} -type EthCallResult struct { - FieldBytes string `json:"bytes"` -} -type EthEstimateGasParams struct { - TransactionObjectGenericToAllTypes - - FieldBlockNumberOrTag string `json:"blockNumberOrTag"` -} -type EthEstimateGasResult struct { - FieldUint string `json:"uint"` -} -type EthCreateAccessListParams struct { - TransactionObjectGenericToAllTypes - - FieldBlockNumberOrTag string `json:"blockNumberOrTag"` -} -type Error struct { - FieldError string `json:"error"` -} -type EthCreateAccessListResult struct { - AccessListResult -} -type EthGasPriceResult struct { - FieldUint string `json:"uint"` -} -type EthMaxPriorityFeePerGasResult struct { - FieldUint string `json:"uint"` -} -type EthFeeHistoryParams struct { - // Requested range of blocks. Clients will return less than the requested range if not all blocks are available. - FieldUint string `json:"uint"` - // Highest block of the requested range. - FieldBlockNumberOrTag string `json:"blockNumberOrTag"` - // Floating point value between 0 and 100. - FieldRewardPercentile float64 `json:"rewardPercentile"` - // A monotonically increasing list of percentile values. For each block in the requested range, the transactions will be sorted in ascending order by effective tip per gas and the coresponding effective tip for the percentile will be determined, accounting for gas consumed. - FieldRewardPercentiles []float64 `json:"rewardPercentiles"` -} -type RewardPercentiles struct { - // Floating point value between 0 and 100. - FieldRewardPercentile float64 `json:"rewardPercentile"` -} -type OldestBlock struct { - // Lowest number block of returned range. - FieldUint string `json:"uint"` + BaseFeePerGas Uint + Difficulty Bytes + ExtraData Bytes + GasLimit Uint + GasUsed Uint + LogsBloom Bytes256 + Miner Address + MixHash Hash32 + Nonce Bytes8 + Number Uint + ParentHash Hash32 + ReceiptsRoot Hash32 + Sha3Uncles Hash32 + Size Uint + StateRoot Hash32 + Timestamp Uint + TotalDifficulty Uint + Transactions struct { + Option0 []Hash32 + Option1 []TransactionSigned + } + TransactionsRoot Hash32 + Uncles []Hash32 } -type RewardPercentile struct { - // A given percentile sample of effective priority fees per gas from a single block in ascending order, weighted by gas used. Zeroes are returned if the block is empty. - FieldUint string `json:"uint"` -} -type Reward struct { - // A given percentile sample of effective priority fees per gas from a single block in ascending order, weighted by gas used. Zeroes are returned if the block is empty. - FieldUint string `json:"uint"` - // An array of effective priority fee per gas data points from a single block. All zeroes are returned if the block is empty. - FieldRewardPercentile []string `json:"rewardPercentile"` - // A two-dimensional array of effective priority fees per gas at the requested block percentiles. - FieldReward []array `json:"reward"` -} -type EthFeeHistoryResult struct { - // Fee history results. - FeeHistoryResults -} -type FromBlock struct { - FieldUint string `json:"uint"` -} -type ToBlock struct { - FieldUint string `json:"uint"` -} -type FilterTopicListEntry struct { - FieldAnyTopicMatch null `json:"anyTopicMatch"` -} -type FilterTopics struct { - FieldFilterTopicListEntry null `json:"filterTopicListEntry"` -} -type Topics struct { - FieldFilterTopicListEntry null `json:"filterTopicListEntry"` - - FieldFilterTopics []FilterTopicListEntry `json:"filterTopics"` - - FieldBytes32 string `json:"bytes32"` - - FieldTopics []string `json:"topics"` -} -type EthNewFilterParams struct { - Filter -} -type EthNewFilterResult struct { - FieldUint string `json:"uint"` -} -type EthNewBlockFilterResult struct { - FieldUint string `json:"uint"` -} -type EthNewPendingTransactionFilterResult struct { - FieldUint string `json:"uint"` -} -type EthUninstallFilterParams struct { - FieldUint string `json:"uint"` -} -type EthUninstallFilterResult struct { - FieldSuccess bool `json:"success"` -} -type EthGetFilterChangesParams struct { - FieldUint string `json:"uint"` -} -type NewBlockHashes struct { - FieldHash32 string `json:"hash32"` +type BlockNumberOrTag struct { + Option0 Uint + Option1 BlockTag +} +type BlockTag string +type Filter struct { + Address struct { + Option0 Address + Option1 Addresses + } + FromBlock Uint + ToBlock Uint + Topics FilterTopics } type FilterResults struct { - FieldHash32 string `json:"hash32"` - - FieldNewBlockHashes []string `json:"newBlockHashes"` -} -type EthGetFilterChangesResult struct { - FieldFilterResults array `json:"filterResults"` -} -type EthGetFilterLogsParams struct { - FieldUint string `json:"uint"` -} -type EthGetFilterLogsResult struct { - FieldFilterResults array `json:"filterResults"` -} -type EthGetLogsParams struct { - Filter -} -type EthGetLogsResult struct { - FieldFilterResults array `json:"filterResults"` -} -type EthMiningResult struct { - FieldMiningStatus bool `json:"miningStatus"` -} -type EthHashrateResult struct { - FieldUint string `json:"uint"` -} -type EthGetWorkResult struct { - FieldCurrentWork []string `json:"currentWork"` -} -type EthSubmitWorkParams struct { - FieldBytes8 string `json:"bytes8"` - - FieldBytes32 string `json:"bytes32"` -} -type EthSubmitWorkResult struct { - FieldSuccess bool `json:"success"` -} -type EthSubmitHashrateParams struct { - FieldBytes32 string `json:"bytes32"` -} -type EthSubmitHashrateResult struct { - FieldSuccess bool `json:"success"` -} -type EthSignParams struct { - FieldAddress string `json:"address"` - - FieldBytes string `json:"bytes"` -} -type EthSignResult struct { - FieldBytes645 string `json:"bytes645"` -} -type EthSignTransactionParams struct { - TransactionObjectGenericToAllTypes -} -type EthSignTransactionResult struct { - FieldBytes string `json:"bytes"` -} -type EthGetBalanceParams struct { - FieldAddress string `json:"address"` - - FieldBlockNumberOrTag string `json:"blockNumberOrTag"` -} -type EthGetBalanceResult struct { - FieldUint string `json:"uint"` -} -type EthGetStorageAtParams struct { - FieldAddress string `json:"address"` - - FieldUint256 string `json:"uint256"` - - FieldBlockNumberOrTag string `json:"blockNumberOrTag"` -} -type EthGetStorageAtResult struct { - FieldBytes string `json:"bytes"` -} -type EthGetTransactionCountParams struct { - FieldAddress string `json:"address"` - - FieldBlockNumberOrTag string `json:"blockNumberOrTag"` -} -type EthGetTransactionCountResult struct { - FieldUint string `json:"uint"` -} -type EthGetCodeParams struct { - FieldAddress string `json:"address"` - - FieldBlockNumberOrTag string `json:"blockNumberOrTag"` -} -type EthGetCodeResult struct { - FieldBytes string `json:"bytes"` -} -type EthGetProofParams struct { - FieldAddress string `json:"address"` - - FieldHash32 string `json:"hash32"` - - FieldStorageKeys []string `json:"storageKeys"` - - FieldBlockNumberOrTag string `json:"blockNumberOrTag"` -} -type AccountProof struct { - FieldBytes string `json:"bytes"` - - FieldAccountProof []string `json:"accountProof"` -} -type Balance struct { - FieldUint256 string `json:"uint256"` -} -type CodeHash struct { - FieldHash32 string `json:"hash32"` -} -type StorageHash struct { - FieldHash32 string `json:"hash32"` -} -type Key struct { - FieldHash32 string `json:"hash32"` -} -type Proof struct { - FieldBytes string `json:"bytes"` - - FieldProof []string `json:"proof"` + Option0 []Hash32 + Option1 []Hash32 + Option2 []Log +} +type FilterTopic struct { + Option0 struct{} + Option1 Bytes32 + Option2 []Bytes32 +} +type FilterTopics []FilterTopic +type GenericTransaction struct { + AccessList AccessList + ChainId Uint + From Address + Gas Uint + GasPrice Uint + Input Bytes + MaxFeePerGas Uint + MaxPriorityFeePerGas Uint + Nonce Uint + To Address + Type Byte + Value Uint +} +type Log struct { + Address Address + BlockHash Hash32 + BlockNumber Uint + Data Bytes + LogIndex Uint + Removed bool + Topics []Bytes32 + TransactionHash Hash32 + TransactionIndex Uint +} +type ReceiptInfo struct { + BlockHash Hash32 + BlockNumber Uint + ContractAddress struct { + Option0 Address + Option1 struct{} + } + CumulativeGasUsed Uint + EffectiveGasPrice Uint + From Address + GasUsed Uint + Logs []Log + LogsBloom Bytes256 + Root Bytes32 + Status Uint + To Address + TransactionHash Hash32 + TransactionIndex Uint } type StorageProof struct { - FieldStorageProof []StorageProof `json:"storageProof"` -} -type EthGetProofResult struct { - AccountProof -} -type EthSendTransactionParams struct { - TransactionObjectGenericToAllTypes -} -type EthSendTransactionResult struct { - FieldHash32 string `json:"hash32"` -} -type EthSendRawTransactionParams struct { - FieldBytes string `json:"bytes"` -} -type EthSendRawTransactionResult struct { - FieldHash32 string `json:"hash32"` -} -type EthGetTransactionByHashParams struct { - FieldHash32 string `json:"hash32"` -} -type EthGetTransactionByHashResult struct { - FieldTransactionInformation object `json:"transactionInformation"` -} -type EthGetTransactionByBlockHashAndIndexParams struct { - FieldHash32 string `json:"hash32"` - - FieldUint string `json:"uint"` -} -type EthGetTransactionByBlockHashAndIndexResult struct { - FieldTransactionInformation object `json:"transactionInformation"` -} -type EthGetTransactionByBlockNumberAndIndexParams struct { - FieldBlockNumberOrTag string `json:"blockNumberOrTag"` - - FieldUint string `json:"uint"` -} -type EthGetTransactionByBlockNumberAndIndexResult struct { - FieldTransactionInformation object `json:"transactionInformation"` -} -type EthGetTransactionReceiptParams struct { - FieldHash32 string `json:"hash32"` -} -type EffectiveGasPrice struct { - // The actual value per gas deducted from the senders account. Before EIP-1559, this is equal to the transaction's gas price. After, it is equal to baseFeePerGas + min(maxFeePerGas - baseFeePerGas, maxPriorityFeePerGas). - FieldUint string `json:"uint"` -} -type Status struct { - // Either 1 (success) or 0 (failure). Only specified for transactions included after the Byzantium upgrade. - FieldUint string `json:"uint"` -} -type BlockNumber struct { - FieldUint string `json:"uint"` -} -type ContractAddress struct { - FieldAddress string `json:"address"` - // The contract address created, if the transaction was a contract creation, otherwise null. - FieldContractAddress string `json:"contractAddress"` -} -type BlockHash struct { - FieldHash32 string `json:"hash32"` -} -type CumulativeGasUsed struct { - // The sum of gas used by this transaction and all preceding transactions in the same block. - FieldUint string `json:"uint"` -} -type Root struct { - // The post-transaction state root. Only specified for transactions included before the Byzantium upgrade. - FieldBytes32 string `json:"bytes32"` -} -type TransactionHash struct { - FieldHash32 string `json:"hash32"` -} -type TransactionIndex struct { - FieldUint string `json:"uint"` -} -type Data struct { - FieldBytes string `json:"bytes"` -} -type LogIndex struct { - FieldUint string `json:"uint"` -} -type Removed struct { - FieldRemoved bool `json:"removed"` -} -type Logs struct { - Log - - FieldLogs []Log `json:"logs"` -} -type EthGetTransactionReceiptResult struct { - ReceiptInfo + Key Hash32 + Proof []Bytes + Value Uint256 } +type SyncingStatus struct { + Option0 struct { + CurrentBlock Uint + HighestBlock Uint + StartingBlock Uint + } + Option1 bool +} +type Transaction1559Signed struct { +} +type Transaction1559Unsigned struct { + AccessList AccessList + ChainId Uint + Gas Uint + Input Bytes + MaxFeePerGas Uint + MaxPriorityFeePerGas Uint + Nonce Uint + To Address + Type Byte + Value Uint +} +type Transaction2930Signed struct { +} +type Transaction2930Unsigned struct { + AccessList AccessList + ChainId Uint + Gas Uint + GasPrice Uint + Input Bytes + Nonce Uint + To Address + Type Byte + Value Uint +} +type TransactionInfo struct { +} +type TransactionLegacySigned struct { +} +type TransactionLegacyUnsigned struct { + ChainId Uint + Gas Uint + GasPrice Uint + Input Bytes + Nonce Uint + To Address + Type Byte + Value Uint +} +type TransactionSigned struct { + Option0 Transaction1559Signed + Option1 Transaction2930Signed + Option2 TransactionLegacySigned +} +type TransactionUnsigned struct { + Option0 Transaction1559Unsigned + Option1 Transaction2930Unsigned + Option2 TransactionLegacyUnsigned +} +type Address string +type Addresses []Address +type Byte string +type Bytes string +type Bytes256 string +type Bytes32 string +type Bytes65 string +type Bytes8 string +type Hash32 string +type Uint string +type Uint256 string +type Uint64 string diff --git a/openrpc/parse/parse.go b/openrpc/parse/parse.go index 5f43a25bf77e5fc121f7ce9ce1baef1306d6491b..fe2554d0439ed05fbafd43eff3bf2da124649cb9 100644 --- a/openrpc/parse/parse.go +++ b/openrpc/parse/parse.go @@ -1,122 +1 @@ package parse - -import ( - "fmt" - "path" - "reflect" - - "gfx.cafe/open/jrpc/openrpc/types" - "gfx.cafe/open/jrpc/openrpc/util" - "github.com/go-openapi/spec" -) - -const ( - params = "Params" - result = "Result" -) - -func persistTitleAndDesc(prev, next spec.Schema) spec.Schema { - next.Title = util.FirstOf(next.Title, prev.Title) - next.Description = util.FirstOf(next.Description, prev.Description) - return next -} - -func persistFields(prev, next spec.Schema) spec.Schema { - next.Title = util.FirstOf(next.Title, prev.Title, path.Base(prev.Ref.String())) - next.Description = util.FirstOf(next.Description, prev.Description) - if next.Items == nil { - next.Items = prev.Items - } - return next -} - -func resolveSchema(openrpc *types.OpenRPCSpec1, sch spec.Schema) spec.Schema { - pt := sch.Ref.GetPointer() - doc, _, _ := pt.Get(openrpc) - if s, ok := doc.(spec.Schema); ok { - sch = persistFields(sch, s) - } else if cd, ok := doc.(*types.ContentDescriptor); ok { - sch = persistFields(sch, cd.Schema) - } - - if sch.Ref.GetURL() != nil { - return resolveSchema(openrpc, sch) - } - return sch -} - -func getConcreteType(in string) string { - switch in { - case reflect.Bool.String(), "boolean": - return reflect.Bool.String() - case "number": - return "float64" - default: - return in - } -} - -func getObjectType(openrpc *types.OpenRPCSpec1, sch spec.Schema) string { - sch = resolveSchema(openrpc, sch) - - if len(sch.Properties) > 0 || len(sch.Type) < 1 { - return util.CamelCase(sch.Title) - } - - return getConcreteType(sch.Type[0]) -} - -func dereference(openrpc *types.OpenRPCSpec1, name string, sch spec.Schema, om *types.ObjectMap) { - // resolve all pointers - sch = resolveSchema(openrpc, sch) - - if len(sch.Properties) > 0 { - for key, value := range sch.Properties { - value.Title = key - dereference(openrpc, key, value, om) - } - om.Set(name, types.BasicType{ - Desc: sch.Description, Name: sch.Title, Type: util.CamelCase(sch.Title)}) - return - } else if len(sch.OneOf) > 0 { - next := sch.OneOf[0] - dereference(openrpc, sch.Title, next, om) - om.Set(name, types.BasicType{Desc: sch.Description, Name: sch.Title, Type: getObjectType(openrpc, resolveSchema(openrpc, next))}) - return - } else if sch.Items != nil { - if sch.Items.Schema != nil { - dereference(openrpc, sch.Title, *sch.Items.Schema, om) - dereference(openrpc, name, persistTitleAndDesc(sch, *sch.Items.Schema), om) - om.Set(name, types.BasicType{Desc: sch.Description, Name: sch.Title, Type: fmt.Sprintf("[]%s", getObjectType(openrpc, persistTitleAndDesc(sch, *sch.Items.Schema)))}) - } else if len(sch.Items.Schemas) > 0 { - om.Set(name, types.BasicType{Desc: sch.Description, Name: sch.Title, Type: "[]string"}) - } - return - } - if len(sch.Type) == 0 { - return - } - om.Set(name, types.BasicType{Desc: sch.Description, Name: sch.Title, Type: getConcreteType(sch.Type[0])}) - return -} - -// GetTypes constructs all possible type definitions from the spec -func GetTypes(openrpc *types.OpenRPCSpec1, om *types.ObjectMap) { - for _, m := range openrpc.Methods { - name := fmt.Sprintf("%s%s", util.CamelCase(m.Name), params) - for _, param := range m.Params { - sch := param.Schema - sch.Title = util.FirstOf(sch.Title, param.Name) - sch.Description = util.FirstOf(sch.Description, param.Description) - dereference(openrpc, name, sch, om) - } - if m.Result != nil { - name = fmt.Sprintf("%s%s", util.CamelCase(m.Name), result) - res := m.Result - sch := res.Schema - sch.Title = util.FirstOf(sch.Title, res.Name) - sch.Description = util.FirstOf(sch.Description, res.Description) - dereference(openrpc, name, sch, om) - } - } -} diff --git a/openrpc/parse/parse_test.go b/openrpc/parse/parse_test.go deleted file mode 100644 index 6326ec1470ee8a2930f006f6048694eae1df759d..0000000000000000000000000000000000000000 --- a/openrpc/parse/parse_test.go +++ /dev/null @@ -1,73 +0,0 @@ -package parse - -import ( - "encoding/json" - "io/ioutil" - "testing" - - "gfx.cafe/open/jrpc/openrpc/types" - "github.com/test-go/testify/require" -) - -func TestParse(t *testing.T) { - data, err := ioutil.ReadFile("testdata/eth_openrpc.json") - require.NoError(t, err) - spec := types.NewOpenRPCSpec1() - err = json.Unmarshal(data, spec) - require.NoError(t, err) - GetTypes(spec, spec.Objects) - - result := spec.Objects.Get("GetBlockByHashResult") - require.NotNil(t, result) - require.Len(t, result.GetKeys(), 1) - - result = spec.Objects.Get("EthBlockNumberResult") - require.NotNil(t, result) - require.Len(t, result.GetKeys(), 1) - - result = spec.Objects.Get("BlockNumber") - require.NotNil(t, result) - require.Len(t, result.GetKeys(), 1) - - result = spec.Objects.Get("EthAccountsResult") - require.NotNil(t, result) - bt := result.Get("Addresses") - require.Equal(t, "Addresses", bt.Name) - require.Equal(t, "[]string", bt.Type) - - result = spec.Objects.Get("EthGetTransactionReceiptResult") - require.NotNil(t, result) - bt = result.Get("Receipt") - require.Equal(t, "Receipt", bt.Name) - require.Equal(t, "Receipt", bt.Type) - - result = spec.Objects.Get("EthSyncingResult") - require.NotNil(t, result) - bt = result.Get("Syncing") - require.Equal(t, "Syncing", bt.Name) - require.Equal(t, "SyncStatus", bt.Type) - - result = spec.Objects.Get("EthGetTransactionByHashResult") - require.NotNil(t, result) - bt = result.Get("Transaction") - require.Equal(t, "Transaction", bt.Name) - - result = spec.Objects.Get("Transaction") - require.NotNil(t, result) - bt = result.Get("BlockHash") - require.Equal(t, "BlockHash", bt.Name) -} - -func TestParseMulti(t *testing.T) { - sp := types.NewOpenRPCSpec1() - var err error - err = sp.AddSchemas("./testdata/execution-api/schemas") - require.NoError(t, err) - err = sp.AddMethods("./testdata/execution-api/eth") - require.NoError(t, err) - err = sp.AddMethods("./testdata/execution-api/engine") - require.NoError(t, err) - err = sp.AddMethods("./testdata/execution-api/debug") - require.NoError(t, err) - // TODO: finish this test -} diff --git a/openrpc/parse/parsing.go b/openrpc/parse/parsing.go deleted file mode 100644 index 1b26d9e515152212af6f8847828bcac130851c38..0000000000000000000000000000000000000000 --- a/openrpc/parse/parsing.go +++ /dev/null @@ -1,102 +0,0 @@ -package parse - -import ( - "strings" - - "gfx.cafe/open/jrpc/openrpc/types" - "gfx.cafe/open/jrpc/openrpc/util" - "github.com/go-openapi/spec" -) - -type GoGlobal struct { - Structs map[string]*GoStruct - Types map[string]*GoType - Methods map[string]*GoMethod -} - -type GoStruct struct { - Name string - Description string - - Fields map[string]string -} -type GoField struct { - Name string - Type *GoType - Optional bool - - Description string -} - -type GoType struct { - Name string - Type string - - Description string -} - -type GoMethod struct { - Input string - Output string - Name string -} - -func (g *GoGlobal) ReadOpenRPC(s types.OpenRPCSpec1) { - for k, v := range s.Components.Schemas { - g.AddSchema(k, v) - } - for _, v := range s.Methods { - g.AddMethod(v.Name, v) - } -} - -func (g *GoGlobal) AddSchema(name string, m spec.Schema) { - if len(m.Type) > 0 { - switch m.Type[0] { - case "string": - case "number": - case "boolean": - case "object": - case "array": - default: - } - return - } - if len(m.OneOf) > 0 { - //todo: handle - return - } -} - -func (g *GoGlobal) AddMethod(name string, m types.Method) { - inStruct := "Params" + util.CamelCase(name) - outStruct := "" - if m.Result != nil { - outStruct = "Result" + util.CamelCase(name) - } - g.Methods[name] = &GoMethod{ - Input: inStruct, - Output: outStruct, - Name: util.CamelCase(name), - } -} - -func (g *GoGlobal) AddStruct(name string, m spec.Schema) { - s := &GoStruct{} - g.Structs[name] = s - s.Name = name - s.Description = m.Description - s.Fields = map[string]string{} - for k, v := range m.Properties { - g.AddSchema(k, v) - if ref := v.Ref.GetPointer(); ref != nil { - refstr := strings.ToTitle(ref.String()) - s.Fields[k] = refstr - } else { - if len(v.Type) > 0 { - refstr := v.Type[0] - s.Fields[k] = refstr - } - } - } -} diff --git a/openrpc/templates/types.gotmpl b/openrpc/templates/types.gotmpl index 045e28dd7551753628154ebfbd1318f41e1657a4..69370af733792373b6eaeae0edf7c7ecfb921dbb 100644 --- a/openrpc/templates/types.gotmpl +++ b/openrpc/templates/types.gotmpl @@ -2,34 +2,54 @@ package main +{{define "schemaType" -}} + {{if not (eq .Ref "") -}} + {{camelCase (refName .Ref)}} + {{- else if eq .Type "object" -}} + struct { + {{range $name, $property := .Properties -}} + {{camelCase $name}} {{template "schemaType" $property}} + {{end -}} + } + {{- else if eq .Type "array" -}} + []{{template "schemaType" (index .Items 0)}} + {{- else if not (eq (len .OneOf) 0) -}} + struct{ + {{range $idx, $v := .OneOf -}} + Option{{$idx}} {{template "schemaType" $v}} + {{end -}} + } + {{- else if not (eq (len .AnyOf) 0) -}} + struct{ + {{range $idx, $v := .AnyOf -}} + Option{{$idx}} {{template "schemaType" $v}} + {{end -}} + } + {{- else if not (eq (len .AllOf) 0) -}} + struct{ + {{range $idx, $v := .AllOf -}} + Field{{$idx}} {{template "schemaType" $v}} + {{end -}} + } + {{- else if not (eq (len .Enum) 0) -}} + string + {{- else -}} + {{goType .Type}} + {{- end}} +{{- end -}} + type GoOpenRPCService interface { - {{- range .Methods }} - {{- $name := .Name | camelCase }} - {{- $params := (maybeMethodParams .) }} - {{- $result := (maybeMethodResult .) }} - {{ maybeMethodComment . }} - {{$name}} - {{- if $params -}} - (*{{$params}}) - {{- else -}} - () - {{- end }} - {{- if $result }} (*{{$result}}, error) - {{- else }} error - {{- end }} - {{- end }} + {{range .Methods -}} + // {{.Summary}} + {{camelCase .Name}}( + {{range .Params -}} + {{camelCase .Name}} {{template "schemaType" .Schema}}, + {{end -}} + ) ({{camelCase .Result.Name}} {{template "schemaType" .Result.Schema}}) + {{end -}} } -{{- range (getObjects .Objects) }} -type {{.Name}} struct { - {{- range (getFields .Fields) }} - {{ maybeFieldComment .Desc }} - {{- if (eq .Name .Type) }} - {{ .Name }} - {{- else }} - Field{{camelCase .Name}} {{.Type}} `json:"{{lowerFirst .Name}}"` - {{- end }} - {{- end }} -} +{{- range $name, $component := .Components.Schemas }} + type {{camelCase $name}} {{template "schemaType" $component}} {{- end }} diff --git a/openrpc/types/objects.go b/openrpc/types/objects.go deleted file mode 100644 index 0400292580468c1c1cb35a6b7a75155c45243889..0000000000000000000000000000000000000000 --- a/openrpc/types/objects.go +++ /dev/null @@ -1,79 +0,0 @@ -package types - -import "gfx.cafe/open/jrpc/openrpc/util" - -type BasicType struct { - Desc string - Name string - Type string -} - -type FieldMap struct { - fields map[string]BasicType - keys []string -} - -func NewFieldMap() *FieldMap { - return &FieldMap{ - fields: make(map[string]BasicType, 0), - keys: make([]string, 0), - } -} - -func (fm *FieldMap) Set(key string, value BasicType) { - key = util.CamelCase(key) - value.Name = util.CamelCase(value.Name) - _, exists := fm.fields[key] - fm.fields[key] = value - if !exists { - fm.keys = append(fm.keys, key) - } -} - -func (fm *FieldMap) Get(key string) BasicType { - a := fm.fields[key] - return a -} - -func (fm *FieldMap) GetKeys() []string { - return fm.keys -} - -type ObjectMap struct { - objects map[string]*FieldMap - keys []string -} - -func NewObjectMap() *ObjectMap { - return &ObjectMap{ - objects: make(map[string]*FieldMap, 0), - keys: make([]string, 0), - } -} - -func (om *ObjectMap) Set(key string, value BasicType) { - if key == "" { - return - } else if value.Name == "" { - return - } else if util.CamelCase(key) == value.Type { - return - } - key = util.CamelCase(key) - _, exists := om.objects[key] - if !exists { - if om.objects[key] == nil { - om.objects[key] = NewFieldMap() - } - om.keys = append(om.keys, key) - } - om.objects[key].Set(value.Name, value) -} - -func (om *ObjectMap) Get(key string) *FieldMap { - return om.objects[key] -} - -func (om *ObjectMap) GetKeys() []string { - return om.keys -} diff --git a/openrpc/types/types.go b/openrpc/types/types.go index 9227c7978c5749992f1f60bab61f1dba4c994b1c..f8461de6c2e1ce98728fa0b96b15569ee1b0c75e 100644 --- a/openrpc/types/types.go +++ b/openrpc/types/types.go @@ -2,264 +2,70 @@ package types import ( "encoding/json" - "os" - "path" - "path/filepath" - - "github.com/go-openapi/spec" - "sigs.k8s.io/yaml" + "fmt" ) -type Contact struct { - Name string `json:"name,omitempty"` - URL string `json:"url,omitempty"` - Email string `json:"email,omitempty"` -} - -type License struct { - Name string `json:"name,omitempty"` - URL string `json:"url,omitempty"` -} - type Info struct { - Title string `json:"title"` - Description string `json:"description,omitempty"` - TermsOfService string `json:"termsOfService,omitempty"` - Contact *Contact `json:"contact,omitempty"` - License *License `json:"license,omitempty"` - Version string `json:"version"` -} - -type ServerVariable struct { - Enum []string `json:"enum,omitempty"` - Default string `json:"default,omitempty"` - Description string `json:"description,omitempty"` -} - -type Server struct { - Name string `json:"name"` - URL string `json:"url"` - Summary string `json:"summary,omitempty"` - Description string `json:"description,omitempty"` - Variables map[string]ServerVariable `json:"variables,omitempty"` -} - -type ExternalDocs struct { - Description string `json:"description,omitempty"` - URL string `json:"url,omitempty"` -} - -type Tag struct { - Name string `json:"name"` - Summary string `json:"summary,omitempty"` - Description string `json:"description,omitempty"` - ExternalDocs *ExternalDocs `json:"externalDocs,omitempty"` -} - -type Content struct { - Name string `json:"name"` - Summary string `json:"summary,omitempty"` - Description string `json:"description,omitempty"` - Required bool `json:"required,omitempty"` - Deprecated bool `json:"deprecated,omitempty"` - Schema spec.Schema `json:"schema"` + Title string `json:"title"` + Version string `json:"version"` } -type ContentDescriptor struct { - Content -} - -func (cd *ContentDescriptor) UnmarshalJSON(data []byte) error { - cont := new(Content) - err := json.Unmarshal(data, cont) - if err != nil { - return err - } - cd.Content = *cont - - params := make(map[string]interface{}) - err = json.Unmarshal(data, ¶ms) - if err != nil { - return err - } +type Items []Schema - if _, ok := params["$ref"]; ok { - sch := new(spec.Schema) - err = json.Unmarshal(data, sch) - if err != nil { - return err +func (I *Items) UnmarshalJSON(b []byte) error { + switch b[0] { + case '{': + *I = []Schema{ + {}, } - cd.Schema = *sch + return json.Unmarshal(b, &(*I)[0]) + case '[': + return json.Unmarshal(b, (*[]Schema)(I)) + default: + return fmt.Errorf("expected array or object") } - return nil - } -// https://www.jsonrpc.org/specification#error_object -type Error struct { - Code int `json:"code"` - Message string `json:"message"` - Data interface{} `json:"data"` -} +var _ json.Unmarshaler = (*Items)(nil) -type Link struct { - Name string `json:"name"` - Description string `json:"description"` - Summary string `json:"summary"` - Method string `json:"method"` - Params map[string]interface{} `json:"params"` - Server Server `json:"server"` +type Schema struct { + Ref string `json:"$ref,omitempty"` + Type string `json:"type,omitempty"` + Title string `json:"title"` + Required []string `json:"required,omitempty"` + Items Items `json:"items,omitempty"` + Properties map[string]Schema `json:"properties,omitempty"` + OneOf []Schema `json:"oneOf,omitempty"` + AnyOf []Schema `json:"anyOf,omitempty"` + AllOf []Schema `json:"allOf,omitempty"` + Enum []string `json:"enum,omitempty"` + Pattern string `json:"pattern"` } -type Example struct { - Name string `json:"name"` - Summary string `json:"summary"` - Description string `json:"description"` - Value interface{} `json:"value"` - ExternalValue string `json:"externalValue"` +type Param struct { + Name string `json:"name"` + Required bool `json:"required"` + Schema Schema `json:"schema"` } -type ExamplePairing struct { - Name string `json:"name"` - Description string `json:"description"` - Summary string `json:"summary"` - Params []Example `json:"params"` - Result Example `json:"result"` +type Result struct { + Name string `json:"name"` + Schema Schema `json:"schema"` } type Method struct { - Name string `json:"name"` - Tags []Tag `json:"tags,omitempty"` - Summary string `json:"summary,omitempty"` - Description string `json:"description,omitempty"` - ExternalDocs *ExternalDocs `json:"externalDocs,omitempty"` - Params []*ContentDescriptor `json:"params"` - Result *ContentDescriptor `json:"result"` - Deprecated bool `json:"deprecated,omitempty"` - Servers []Server `json:"servers,omitempty"` - Errors []Error `json:"errors,omitempty"` - Links []Link `json:"links,omitempty"` - ParamStructure string `json:"paramStructure,omitempty"` - Examples []ExamplePairing `json:"examples,omitempty"` -} - -type Components struct { - ContentDescriptors map[string]*ContentDescriptor `json:"contentDescriptors,omitempty"` - Schemas map[string]spec.Schema `json:"schemas,omitempty"` - Examples map[string]Example `json:"examples,omitempty"` - Links map[string]Link `json:"links,omitempty"` - Errors map[string]Error `json:"errors,omitempty"` - ExamplePairingObjects map[string]ExamplePairing `json:"examplePairingObjects,omitempty"` - Tags map[string]Tag `json:"tags,omitempty"` -} - -type OpenRPCSpec1 struct { - OpenRPC string `json:"openrpc"` - Info Info `json:"info"` - Servers []Server `json:"servers"` - Methods []Method `json:"methods"` - Components Components `json:"components"` - ExternalDocs *ExternalDocs `json:"externalDocs,omitempty"` - - Objects *ObjectMap `json:"-"` -} - -func NewOpenRPCSpec1() *OpenRPCSpec1 { - return &OpenRPCSpec1{ - OpenRPC: "1.0.0", - Info: Info{ - Title: "gfx.cafe/open/jrpc/openrpc", - Version: "0.0.0", - }, - Servers: make([]Server, 0), - Methods: make([]Method, 0), - - Objects: NewObjectMap(), - } -} - -func (o *OpenRPCSpec1) AddSchemas(pth string) error { - dr, err := os.ReadDir(pth) - if err != nil { - return err - } - for _, v := range dr { - if v.IsDir() { - if err := o.AddSchemas(path.Join(pth, v.Name())); err != nil { - return err - } - } else { - if err := o.AddSchema(path.Join(pth, v.Name())); err != nil { - return err - } - } - } - return nil -} - -func (o *OpenRPCSpec1) AddSchema(pth string) error { - schem := map[string]spec.Schema{} - bts, err := os.ReadFile(pth) - if err != nil { - return err - } - ext := filepath.Ext(path.Base(pth)) - switch ext { - case ".json": - err = json.Unmarshal(bts, &schem) - case ".yml", ".yaml": - err = yaml.Unmarshal(bts, &schem) - } - if err != nil { - return err - } - if o.Components.Schemas == nil { - o.Components.Schemas = map[string]spec.Schema{} - } - for k, v := range schem { - o.Components.Schemas[k] = v - } - return nil -} - -func (o *OpenRPCSpec1) AddMethods(pth string) error { - dr, err := os.ReadDir(pth) - if err != nil { - return err - } - for _, v := range dr { - if v.IsDir() { - if err := o.AddMethods(path.Join(pth, v.Name())); err != nil { - return err - } - } else { - if err := o.AddMethod(path.Join(pth, v.Name())); err != nil { - return err - } - } - } - return nil -} - -func (o *OpenRPCSpec1) AddMethod(pth string) error { - var meth []Method - bts, err := os.ReadFile(pth) - if err != nil { - return err - } - switch filepath.Ext(path.Base(pth)) { - case ".json": - err = json.Unmarshal(bts, &meth) - case ".yml", ".yaml": - err = yaml.Unmarshal(bts, &meth) - if err != nil { - return err - } - } - if err != nil { - return err - } - o.Methods = append(o.Methods, meth...) - return nil + Name string `json:"name"` + Summary string `json:"summary"` + Params []Param `json:"params"` + Result Result `json:"result"` +} + +type OpenRPC struct { + Version string `json:"openrpc"` + Info Info `json:"info"` + Methods []Method `json:"methods"` + Components struct { + Schemas map[string]Schema `json:"schemas"` + } `json:"components"` }