Major integrations and fixes: - Added BACKBEAT SDK integration for P2P operation timing - Implemented beat-aware status tracking for distributed operations - Added Docker secrets support for secure license management - Resolved KACHING license validation via HTTPS/TLS - Updated docker-compose configuration for clean stack deployment - Disabled rollback policies to prevent deployment failures - Added license credential storage (CHORUS-DEV-MULTI-001) Technical improvements: - BACKBEAT P2P operation tracking with phase management - Enhanced configuration system with file-based secrets - Improved error handling for license validation - Clean separation of KACHING and CHORUS deployment stacks 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
140 lines
3.6 KiB
Go
140 lines
3.6 KiB
Go
package bindnode
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"go/format"
|
|
"io"
|
|
"strings"
|
|
|
|
"github.com/ipld/go-ipld-prime/schema"
|
|
)
|
|
|
|
// TODO(mvdan): deduplicate with inferGoType once reflect supports creating named types
|
|
|
|
func produceGoType(goTypes map[string]string, typ schema.Type) (name, src string) {
|
|
if typ, ok := typ.(interface{ IsAnonymous() bool }); ok {
|
|
if typ.IsAnonymous() {
|
|
panic("TODO: does this ever happen?")
|
|
}
|
|
}
|
|
|
|
name = string(typ.Name())
|
|
|
|
switch typ.(type) {
|
|
case *schema.TypeBool:
|
|
return goTypeBool.String(), ""
|
|
case *schema.TypeInt:
|
|
return goTypeInt.String(), ""
|
|
case *schema.TypeFloat:
|
|
return goTypeFloat.String(), ""
|
|
case *schema.TypeString:
|
|
return goTypeString.String(), ""
|
|
case *schema.TypeBytes:
|
|
return goTypeBytes.String(), ""
|
|
case *schema.TypeLink:
|
|
return goTypeLink.String(), "" // datamodel.Link
|
|
case *schema.TypeAny:
|
|
return goTypeNode.String(), "" // datamodel.Node
|
|
}
|
|
|
|
// Results are cached in goTypes.
|
|
if src := goTypes[name]; src != "" {
|
|
return name, src
|
|
}
|
|
|
|
src = produceGoTypeInner(goTypes, name, typ)
|
|
goTypes[name] = src
|
|
return name, src
|
|
}
|
|
|
|
func produceGoTypeInner(goTypes map[string]string, name string, typ schema.Type) (src string) {
|
|
// Avoid infinite cycles.
|
|
// produceGoType will fill in the final type later.
|
|
goTypes[name] = "WIP"
|
|
|
|
switch typ := typ.(type) {
|
|
case *schema.TypeEnum:
|
|
// TODO: also generate named constants for the members.
|
|
return goTypeString.String()
|
|
case *schema.TypeStruct:
|
|
var b strings.Builder
|
|
fmt.Fprintf(&b, "struct {\n")
|
|
fields := typ.Fields()
|
|
for _, field := range fields {
|
|
fmt.Fprintf(&b, "%s ", fieldNameFromSchema(field.Name()))
|
|
ftypGo, _ := produceGoType(goTypes, field.Type())
|
|
if field.IsNullable() {
|
|
fmt.Fprintf(&b, "*")
|
|
}
|
|
if field.IsOptional() {
|
|
fmt.Fprintf(&b, "*")
|
|
}
|
|
fmt.Fprintf(&b, "%s\n", ftypGo)
|
|
}
|
|
fmt.Fprintf(&b, "\n}")
|
|
return b.String()
|
|
case *schema.TypeMap:
|
|
ktyp, _ := produceGoType(goTypes, typ.KeyType())
|
|
vtyp, _ := produceGoType(goTypes, typ.ValueType())
|
|
if typ.ValueIsNullable() {
|
|
vtyp = "*" + vtyp
|
|
}
|
|
return fmt.Sprintf(`struct {
|
|
Keys []%s
|
|
Values map[%s]%s
|
|
}`, ktyp, ktyp, vtyp)
|
|
case *schema.TypeList:
|
|
etyp, _ := produceGoType(goTypes, typ.ValueType())
|
|
if typ.ValueIsNullable() {
|
|
etyp = "*" + etyp
|
|
}
|
|
return fmt.Sprintf("[]%s", etyp)
|
|
case *schema.TypeUnion:
|
|
var b strings.Builder
|
|
fmt.Fprintf(&b, "struct{\n")
|
|
members := typ.Members()
|
|
for _, ftyp := range members {
|
|
ftypGo, _ := produceGoType(goTypes, ftyp)
|
|
fmt.Fprintf(&b, "%s ", fieldNameFromSchema(string(ftyp.Name())))
|
|
fmt.Fprintf(&b, "*%s\n", ftypGo)
|
|
}
|
|
fmt.Fprintf(&b, "\n}")
|
|
return b.String()
|
|
}
|
|
panic(fmt.Sprintf("%T\n", typ))
|
|
}
|
|
|
|
// ProduceGoTypes infers Go types from an IPLD schema in ts
|
|
// and writes their Go source code type declarations to w.
|
|
// Note that just the types are written,
|
|
// without a package declaration nor any imports.
|
|
//
|
|
// This gives a good starting point when wanting to use bindnode with Go types,
|
|
// but users will generally want to own and modify the types afterward,
|
|
// so they can add documentation or tweak the types as needed.
|
|
func ProduceGoTypes(w io.Writer, ts *schema.TypeSystem) error {
|
|
goTypes := make(map[string]string)
|
|
var buf bytes.Buffer
|
|
for _, name := range ts.Names() {
|
|
schemaType := ts.TypeByName(string(name))
|
|
if name != schemaType.Name() {
|
|
panic(fmt.Sprintf("%s vs %s", name, schemaType.Name()))
|
|
}
|
|
_, src := produceGoType(goTypes, schemaType)
|
|
if src == "" {
|
|
continue // scalar type used directly
|
|
}
|
|
fmt.Fprintf(&buf, "type %s %s\n", name, src)
|
|
}
|
|
|
|
src, err := format.Source(buf.Bytes())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if _, err := w.Write(src); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|