A vibe coded tangled fork which supports pijul.
at 5b627fe9a35eb406ec33a6f9f4cf173b61e1b94c 80 lines 2.6 kB view raw
1package cloudflare 2 3import ( 4 "context" 5 "fmt" 6 "io" 7 "strings" 8 9 cf "github.com/cloudflare/cloudflare-go/v6" 10 "github.com/cloudflare/cloudflare-go/v6/kv" 11 "github.com/cloudflare/cloudflare-go/v6/shared" 12) 13 14// KVPut writes or overwrites a single Workers KV entry. 15func (cl *Client) KVPut(ctx context.Context, key string, value []byte) error { 16 _, err := cl.kvAPI.KV.Namespaces.Values.Update(ctx, cl.kvNS, key, kv.NamespaceValueUpdateParams{ 17 AccountID: cf.F(cl.cfAcct), 18 Value: cf.F[kv.NamespaceValueUpdateParamsValueUnion](shared.UnionString(value)), 19 }) 20 if err != nil { 21 return fmt.Errorf("writing KV entry %q: %w", key, err) 22 } 23 return nil 24} 25 26// KVGet reads a single Workers KV entry. Returns nil, nil if the key does not exist. 27func (cl *Client) KVGet(ctx context.Context, key string) ([]byte, error) { 28 res, err := cl.kvAPI.KV.Namespaces.Values.Get(ctx, cl.kvNS, key, kv.NamespaceValueGetParams{ 29 AccountID: cf.F(cl.cfAcct), 30 }) 31 if err != nil { 32 // The CF SDK returns a 404 when the key doesn't exist. The error type 33 // lives in an internal package so we match on the error string instead. 34 if strings.Contains(err.Error(), "404") && strings.Contains(err.Error(), "key not found") { 35 return nil, nil 36 } 37 return nil, fmt.Errorf("reading KV entry %q: %w", key, err) 38 } 39 defer res.Body.Close() 40 val, err := io.ReadAll(res.Body) 41 if err != nil { 42 return nil, fmt.Errorf("reading KV entry body %q: %w", key, err) 43 } 44 return val, nil 45} 46 47// KVDelete removes a single Workers KV entry. 48// Safe to call even if the entry does not exist. 49func (cl *Client) KVDelete(ctx context.Context, key string) error { 50 _, err := cl.kvAPI.KV.Namespaces.Values.Delete(ctx, cl.kvNS, key, kv.NamespaceValueDeleteParams{ 51 AccountID: cf.F(cl.cfAcct), 52 }) 53 if err != nil { 54 return fmt.Errorf("deleting KV entry %q: %w", key, err) 55 } 56 return nil 57} 58 59// KVDeleteByPrefix removes every Workers KV entry whose key starts with prefix, 60// handling pagination automatically. 61func (cl *Client) KVDeleteByPrefix(ctx context.Context, prefix string) error { 62 iter := cl.kvAPI.KV.Namespaces.Keys.ListAutoPaging(ctx, cl.kvNS, kv.NamespaceKeyListParams{ 63 AccountID: cf.F(cl.cfAcct), 64 Prefix: cf.F(prefix), 65 }) 66 67 for iter.Next() { 68 entry := iter.Current() 69 if _, err := cl.kvAPI.KV.Namespaces.Values.Delete(ctx, cl.kvNS, entry.Name, kv.NamespaceValueDeleteParams{ 70 AccountID: cf.F(cl.cfAcct), 71 }); err != nil { 72 return fmt.Errorf("deleting KV entry %q: %w", entry.Name, err) 73 } 74 } 75 if err := iter.Err(); err != nil { 76 return fmt.Errorf("listing KV entries with prefix %q: %w", prefix, err) 77 } 78 79 return nil 80}