package main import ( "bytes" "errors" "fmt" "syscall/js" "github.com/thegrumpylion/jsref" "covergen/pkg/covergen" ) type jsmap = map[string]interface{} type covergenArgs struct { Customer string `jsref:"customer"` Number string `jsref:"number"` NumberPrefix string `jsref:"numberPrefix"` HLColor string `jsref:"hlColor"` } func parseHexColor(s string) (c covergen.Color, err error) { switch len(s) { case 7: _, err = fmt.Sscanf(s, "#%02x%02x%02x", &c.R, &c.G, &c.B) case 4: _, err = fmt.Sscanf(s, "#%1x%1x%1x", &c.R, &c.G, &c.B) // Double the hex digits: c.R *= 17 c.G *= 17 c.B *= 17 default: err = fmt.Errorf("invalid length, must be 7 or 4") } return } func settingsFromValue(arg js.Value) (*covergen.CoverSettings, error) { settings := covergenArgs{ NumberPrefix: "offerte", } err := jsref.Unmarshal(&settings, arg) if err != nil { return nil, err } if settings.Number == "" { return nil, errors.New("number: shouldn't be empty") } if settings.Customer == "" { return nil, errors.New("customer: shouldn't be empty") } color := covergen.Color{R: 255} if settings.HLColor != "" { color, err = parseHexColor(settings.HLColor) if err != nil { return nil, fmt.Errorf("hlColor: %w", err) } } return &covergen.CoverSettings{ Number: settings.Number, NumberPrefix: settings.NumberPrefix, CustomerName: settings.Customer, HLColor: color, }, nil } func generateCover(this js.Value, args []js.Value) interface{} { defer func() { if r := recover(); r != nil { fmt.Println("recovered", r) } }() if len(args) != 1 { return jsmap{"error": "missing argument"} } arg := args[0] if arg.Type() != js.TypeObject { return jsmap{"error": "expected object"} } settings, err := settingsFromValue(arg) if err != nil { return jsmap{"error": err.Error()} } pdf, err := covergen.GenerateInvoice(*settings) if err != nil { return jsmap{"error": err.Error()} } var buf bytes.Buffer if err = pdf.Output(&buf); err != nil { return jsmap{"error": err.Error()} } s := buf.Bytes() ta := js.Global().Get("Uint8Array").New(len(s)) js.CopyBytesToJS(ta, s) return ta } func main() { js.Global().Set("covergen", js.FuncOf(generateCover)) <-make(chan bool) }