github.com/evanw/esbuild@v0.21.4/internal/resolver/dataurl.go (about) 1 package resolver 2 3 import ( 4 "encoding/base64" 5 "fmt" 6 "net/url" 7 "strings" 8 ) 9 10 type DataURL struct { 11 mimeType string 12 data string 13 isBase64 bool 14 } 15 16 func ParseDataURL(url string) (parsed DataURL, ok bool) { 17 if strings.HasPrefix(url, "data:") { 18 if comma := strings.IndexByte(url, ','); comma != -1 { 19 parsed.mimeType = url[len("data:"):comma] 20 parsed.data = url[comma+1:] 21 if strings.HasSuffix(parsed.mimeType, ";base64") { 22 parsed.mimeType = parsed.mimeType[:len(parsed.mimeType)-len(";base64")] 23 parsed.isBase64 = true 24 } 25 ok = true 26 } 27 } 28 return 29 } 30 31 type MIMEType uint8 32 33 const ( 34 MIMETypeUnsupported MIMEType = iota 35 MIMETypeTextCSS 36 MIMETypeTextJavaScript 37 MIMETypeApplicationJSON 38 ) 39 40 func (parsed DataURL) DecodeMIMEType() MIMEType { 41 // Remove things like ";charset=utf-8" 42 mimeType := parsed.mimeType 43 if semicolon := strings.IndexByte(mimeType, ';'); semicolon != -1 { 44 mimeType = mimeType[:semicolon] 45 } 46 47 // Hard-code a few supported types 48 switch mimeType { 49 case "text/css": 50 return MIMETypeTextCSS 51 case "text/javascript": 52 return MIMETypeTextJavaScript 53 case "application/json": 54 return MIMETypeApplicationJSON 55 default: 56 return MIMETypeUnsupported 57 } 58 } 59 60 func (parsed DataURL) DecodeData() (string, error) { 61 // Try to read base64 data 62 if parsed.isBase64 { 63 bytes, err := base64.StdEncoding.DecodeString(parsed.data) 64 if err != nil { 65 return "", fmt.Errorf("could not decode base64 data: %s", err.Error()) 66 } 67 return string(bytes), nil 68 } 69 70 // Try to read percent-escaped data 71 content, err := url.PathUnescape(parsed.data) 72 if err != nil { 73 return "", fmt.Errorf("could not decode percent-escaped data: %s", err.Error()) 74 } 75 return content, nil 76 }