Skip to content

Commit

Permalink
Merge pull request #14 from syumai/split-cloudflare-package
Browse files Browse the repository at this point in the history
split cloudflare package
  • Loading branch information
syumai authored Sep 13, 2022
2 parents 1d1d2a9 + 1701300 commit af65c8d
Show file tree
Hide file tree
Showing 14 changed files with 187 additions and 167 deletions.
30 changes: 16 additions & 14 deletions kv.go → cloudflare/kv.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package workers
package cloudflare

import (
"fmt"
"io"
"syscall/js"

"github.com/syumai/workers/internal/jsutil"
)

// KVNamespace represents interface of Cloudflare Worker's KV namespace instance.
Expand All @@ -15,7 +17,7 @@ type KVNamespace struct {

// NewKVNamespace returns KVNamespace for given variable name.
// - variable name must be defined in wrangler.toml as kv_namespace's binding.
// - if the given variable name doesn't exist on global object, returns error.
// - if the given variable name doesn't exist on Global object, returns error.
func NewKVNamespace(varName string) (*KVNamespace, error) {
inst := js.Global().Get(varName)
if inst.IsUndefined() {
Expand All @@ -31,7 +33,7 @@ type KVNamespaceGetOptions struct {
}

func (opts *KVNamespaceGetOptions) toJS(type_ string) js.Value {
obj := newObject()
obj := jsutil.NewObject()
obj.Set("type", type_)
if opts == nil {
return obj
Expand All @@ -46,7 +48,7 @@ func (opts *KVNamespaceGetOptions) toJS(type_ string) js.Value {
// - if a network error happens, returns error.
func (kv *KVNamespace) GetString(key string, opts *KVNamespaceGetOptions) (string, error) {
p := kv.instance.Call("get", key, opts.toJS("text"))
v, err := awaitPromise(p)
v, err := jsutil.AwaitPromise(p)
if err != nil {
return "", err
}
Expand All @@ -57,12 +59,12 @@ func (kv *KVNamespace) GetString(key string, opts *KVNamespaceGetOptions) (strin
// - if a network error happens, returns error.
func (kv *KVNamespace) GetReader(key string, opts *KVNamespaceGetOptions) (io.Reader, error) {
p := kv.instance.Call("get", key, opts.toJS("stream"))
v, err := awaitPromise(p)
v, err := jsutil.AwaitPromise(p)
if err != nil {
return nil, err
}
global.Get("console").Call("log", v)
return convertStreamReaderToReader(v.Call("getReader")), nil
jsutil.Global.Get("console").Call("log", v)
return jsutil.ConvertStreamReaderToReader(v.Call("getReader")), nil
}

// KVNamespaceListOptions represents Cloudflare KV namespace list options.
Expand All @@ -77,7 +79,7 @@ func (opts *KVNamespaceListOptions) toJS() js.Value {
if opts == nil {
return js.Undefined()
}
obj := newObject()
obj := jsutil.NewObject()
if opts.Limit != 0 {
obj.Set("limit", opts.Limit)
}
Expand Down Expand Up @@ -151,7 +153,7 @@ func toKVNamespaceListResult(v js.Value) (*KVNamespaceListResult, error) {
// List lists keys stored into the KV namespace.
func (kv *KVNamespace) List(opts *KVNamespaceListOptions) (*KVNamespaceListResult, error) {
p := kv.instance.Call("list", opts.toJS())
v, err := awaitPromise(p)
v, err := jsutil.AwaitPromise(p)
if err != nil {
return nil, err
}
Expand All @@ -170,7 +172,7 @@ func (opts *KVNamespacePutOptions) toJS() js.Value {
if opts == nil {
return js.Undefined()
}
obj := newObject()
obj := jsutil.NewObject()
if opts.Expiration != 0 {
obj.Set("expiration", opts.Expiration)
}
Expand All @@ -184,7 +186,7 @@ func (opts *KVNamespacePutOptions) toJS() js.Value {
// - if a network error happens, returns error.
func (kv *KVNamespace) PutString(key string, value string, opts *KVNamespacePutOptions) error {
p := kv.instance.Call("put", key, value, opts.toJS())
_, err := awaitPromise(p)
_, err := jsutil.AwaitPromise(p)
if err != nil {
return err
}
Expand All @@ -200,10 +202,10 @@ func (kv *KVNamespace) PutReader(key string, value io.Reader, opts *KVNamespaceP
if err != nil {
return err
}
ua := newUint8Array(len(b))
ua := jsutil.NewUint8Array(len(b))
js.CopyBytesToJS(ua, b)
p := kv.instance.Call("put", key, ua.Get("buffer"), opts.toJS())
_, err = awaitPromise(p)
_, err = jsutil.AwaitPromise(p)
if err != nil {
return err
}
Expand All @@ -214,7 +216,7 @@ func (kv *KVNamespace) PutReader(key string, value io.Reader, opts *KVNamespaceP
// - if a network error happens, returns error.
func (kv *KVNamespace) Delete(key string) error {
p := kv.instance.Call("delete", key)
_, err := awaitPromise(p)
_, err := jsutil.AwaitPromise(p)
if err != nil {
return err
}
Expand Down
22 changes: 12 additions & 10 deletions r2bucket.go → cloudflare/r2bucket.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package workers
package cloudflare

import (
"fmt"
"io"
"syscall/js"

"github.com/syumai/workers/internal/jsutil"
)

// R2Bucket represents interface of Cloudflare Worker's R2 Bucket instance.
Expand All @@ -15,8 +17,8 @@ type R2Bucket struct {

// NewR2Bucket returns R2Bucket for given variable name.
// - variable name must be defined in wrangler.toml.
// - see example: https://github.com/syumai/workers/tree/main/examples/r2-image-viewer
// - if the given variable name doesn't exist on global object, returns error.
// - see example: https://github.com/syumai/workers/tree/main/examples/r2-image-viewer
// - if the given variable name doesn't exist on Global object, returns error.
func NewR2Bucket(varName string) (*R2Bucket, error) {
inst := js.Global().Get(varName)
if inst.IsUndefined() {
Expand All @@ -31,7 +33,7 @@ func NewR2Bucket(varName string) (*R2Bucket, error) {
// - if a network error happens, returns error.
func (r *R2Bucket) Head(key string) (*R2Object, error) {
p := r.instance.Call("head", key)
v, err := awaitPromise(p)
v, err := jsutil.AwaitPromise(p)
if err != nil {
return nil, err
}
Expand All @@ -46,7 +48,7 @@ func (r *R2Bucket) Head(key string) (*R2Object, error) {
// - if a network error happens, returns error.
func (r *R2Bucket) Get(key string) (*R2Object, error) {
p := r.instance.Call("get", key)
v, err := awaitPromise(p)
v, err := jsutil.AwaitPromise(p)
if err != nil {
return nil, err
}
Expand All @@ -68,7 +70,7 @@ func (opts *R2PutOptions) toJS() js.Value {
if opts == nil {
return js.Undefined()
}
obj := newObject()
obj := jsutil.NewObject()
if opts.HTTPMetadata != (R2HTTPMetadata{}) {
obj.Set("httpMetadata", opts.HTTPMetadata.toJS())
}
Expand Down Expand Up @@ -99,10 +101,10 @@ func (r *R2Bucket) Put(key string, value io.ReadCloser, opts *R2PutOptions) (*R2
return nil, err
}
defer value.Close()
ua := newUint8Array(len(b))
ua := jsutil.NewUint8Array(len(b))
js.CopyBytesToJS(ua, b)
p := r.instance.Call("put", key, ua.Get("buffer"), opts.toJS())
v, err := awaitPromise(p)
v, err := jsutil.AwaitPromise(p)
if err != nil {
return nil, err
}
Expand All @@ -113,7 +115,7 @@ func (r *R2Bucket) Put(key string, value io.ReadCloser, opts *R2PutOptions) (*R2
// - if a network error happens, returns error.
func (r *R2Bucket) Delete(key string) error {
p := r.instance.Call("delete", key)
if _, err := awaitPromise(p); err != nil {
if _, err := jsutil.AwaitPromise(p); err != nil {
return err
}
return nil
Expand All @@ -123,7 +125,7 @@ func (r *R2Bucket) Delete(key string) error {
// - if a network error happens, returns error.
func (r *R2Bucket) List() (*R2Objects, error) {
p := r.instance.Call("list")
v, err := awaitPromise(p)
v, err := jsutil.AwaitPromise(p)
if err != nil {
return nil, err
}
Expand Down
26 changes: 14 additions & 12 deletions r2object.go → cloudflare/r2object.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package workers
package cloudflare

import (
"errors"
"fmt"
"io"
"syscall/js"
"time"

"github.com/syumai/workers/internal/jsutil"
)

// R2Object represents Cloudflare R2 object.
Expand Down Expand Up @@ -41,7 +43,7 @@ func (o *R2Object) BodyUsed() (bool, error) {
// toR2Object converts JavaScript side's R2Object to *R2Object.
// - https://github.com/cloudflare/workers-types/blob/3012f263fb1239825e5f0061b267c8650d01b717/index.d.ts#L1094
func toR2Object(v js.Value) (*R2Object, error) {
uploaded, err := dateToTime(v.Get("uploaded"))
uploaded, err := jsutil.DateToTime(v.Get("uploaded"))
if err != nil {
return nil, fmt.Errorf("error converting uploaded: %w", err)
}
Expand All @@ -52,7 +54,7 @@ func toR2Object(v js.Value) (*R2Object, error) {
bodyVal := v.Get("body")
var body io.Reader
if !bodyVal.IsUndefined() {
body = convertStreamReaderToReader(v.Get("body").Call("getReader"))
body = jsutil.ConvertStreamReaderToReader(v.Get("body").Call("getReader"))
}
return &R2Object{
instance: v,
Expand All @@ -63,7 +65,7 @@ func toR2Object(v js.Value) (*R2Object, error) {
HTTPETag: v.Get("httpEtag").String(),
Uploaded: uploaded,
HTTPMetadata: r2Meta,
CustomMetadata: strRecordToMap(v.Get("customMetadata")),
CustomMetadata: jsutil.StrRecordToMap(v.Get("customMetadata")),
Body: body,
}, nil
}
Expand All @@ -80,22 +82,22 @@ type R2HTTPMetadata struct {
}

func toR2HTTPMetadata(v js.Value) (R2HTTPMetadata, error) {
cacheExpiry, err := maybeDate(v.Get("cacheExpiry"))
cacheExpiry, err := jsutil.MaybeDate(v.Get("cacheExpiry"))
if err != nil {
return R2HTTPMetadata{}, fmt.Errorf("error converting cacheExpiry: %w", err)
}
return R2HTTPMetadata{
ContentType: maybeString(v.Get("contentType")),
ContentLanguage: maybeString(v.Get("contentLanguage")),
ContentDisposition: maybeString(v.Get("contentDisposition")),
ContentEncoding: maybeString(v.Get("contentEncoding")),
CacheControl: maybeString(v.Get("cacheControl")),
ContentType: jsutil.MaybeString(v.Get("contentType")),
ContentLanguage: jsutil.MaybeString(v.Get("contentLanguage")),
ContentDisposition: jsutil.MaybeString(v.Get("contentDisposition")),
ContentEncoding: jsutil.MaybeString(v.Get("contentEncoding")),
CacheControl: jsutil.MaybeString(v.Get("cacheControl")),
CacheExpiry: cacheExpiry,
}, nil
}

func (md *R2HTTPMetadata) toJS() js.Value {
obj := newObject()
obj := jsutil.NewObject()
kv := map[string]string{
"contentType": md.ContentType,
"contentLanguage": md.ContentLanguage,
Expand All @@ -109,7 +111,7 @@ func (md *R2HTTPMetadata) toJS() js.Value {
}
}
if !md.CacheExpiry.IsZero() {
obj.Set("cacheExpiry", timeToDate(md.CacheExpiry))
obj.Set("cacheExpiry", jsutil.TimeToDate(md.CacheExpiry))
}
return obj
}
6 changes: 4 additions & 2 deletions r2objects.go → cloudflare/r2objects.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package workers
package cloudflare

import (
"fmt"
"syscall/js"

"github.com/syumai/workers/internal/jsutil"
)

// R2Objects represents Cloudflare R2 objects.
Expand Down Expand Up @@ -36,7 +38,7 @@ func toR2Objects(v js.Value) (*R2Objects, error) {
return &R2Objects{
Objects: objects,
Truncated: v.Get("truncated").Bool(),
Cursor: maybeString(v.Get("cursor")),
Cursor: jsutil.MaybeString(v.Get("cursor")),
DelimitedPrefixes: prefixes,
}, nil
}
4 changes: 3 additions & 1 deletion env.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package workers

import "github.com/syumai/workers/internal/jsutil"

// Getenv gets a value of an environment variable.
// - https://developers.cloudflare.com/workers/platform/environment-variables/
// - Technically, this function is just an alias for js.Global().Get(env_name).String().
func Getenv(name string) string {
return global.Get(name).String()
return jsutil.Global.Get(name).String()
}
4 changes: 3 additions & 1 deletion examples/kv-counter/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (
"os"
"strconv"

"github.com/syumai/workers/cloudflare"

"github.com/syumai/workers"
)

Expand All @@ -24,7 +26,7 @@ func handleErr(w http.ResponseWriter, msg string, err error) {

func main() {
// initialize KV namespace instance
kv, err := workers.NewKVNamespace(counterNamespace)
kv, err := cloudflare.NewKVNamespace(counterNamespace)
if err != nil {
fmt.Fprintf(os.Stderr, "failed to init KV: %v", err)
os.Exit(1)
Expand Down
9 changes: 5 additions & 4 deletions examples/r2-image-server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"strings"

"github.com/syumai/workers"
"github.com/syumai/workers/cloudflare"
)

// bucketName is R2 bucket name defined in wrangler.toml.
Expand All @@ -22,11 +23,11 @@ func handleErr(w http.ResponseWriter, msg string, err error) {
}

type server struct {
bucket *workers.R2Bucket
bucket *cloudflare.R2Bucket
}

func newServer() (*server, error) {
bucket, err := workers.NewR2Bucket(bucketName)
bucket, err := cloudflare.NewR2Bucket(bucketName)
if err != nil {
return nil, err
}
Expand All @@ -46,8 +47,8 @@ func (s *server) post(w http.ResponseWriter, req *http.Request, key string) {
return
}
}
_, err = s.bucket.Put(key, req.Body, &workers.R2PutOptions{
HTTPMetadata: workers.R2HTTPMetadata{
_, err = s.bucket.Put(key, req.Body, &cloudflare.R2PutOptions{
HTTPMetadata: cloudflare.R2HTTPMetadata{
ContentType: req.Header.Get("Content-Type"),
},
CustomMetadata: map[string]string{"custom-key": "custom-value"},
Expand Down
3 changes: 2 additions & 1 deletion examples/r2-image-viewer/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"strings"

"github.com/syumai/workers"
"github.com/syumai/workers/cloudflare"
)

// bucketName is R2 bucket name defined in wrangler.toml.
Expand All @@ -22,7 +23,7 @@ func handleErr(w http.ResponseWriter, msg string, err error) {
// This example is based on implementation in syumai/workers-playground
// - https://github.com/syumai/workers-playground/blob/e32881648ccc055e3690a0d9c750a834261c333e/r2-image-viewer/src/index.ts#L30
func handler(w http.ResponseWriter, req *http.Request) {
bucket, err := workers.NewR2Bucket(bucketName)
bucket, err := cloudflare.NewR2Bucket(bucketName)
if err != nil {
handleErr(w, "failed to get R2Bucket\n", err)
return
Expand Down
6 changes: 4 additions & 2 deletions handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"io"
"net/http"
"syscall/js"

"github.com/syumai/workers/internal/jsutil"
)

var httpHandler http.Handler
Expand All @@ -28,9 +30,9 @@ func init() {
}()
return js.Undefined()
})
return newPromise(cb)
return jsutil.NewPromise(cb)
})
global.Set("handleRequest", handleRequestCallback)
jsutil.Global.Set("handleRequest", handleRequestCallback)
}

// handleRequest accepts a Request object and returns Response object.
Expand Down
Loading

0 comments on commit af65c8d

Please sign in to comment.