 9bdcbe0447
			
		
	
	9bdcbe0447
	
	
	
		
			
			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
 | |
| }
 |