From c339993f968c09824bc73fd8dae5f69085690738 Mon Sep 17 00:00:00 2001 From: syumai Date: Tue, 13 Sep 2022 23:15:47 +0900 Subject: [PATCH 1/4] make public jsutil symbols --- env.go | 2 +- handler.go | 4 ++-- jsutil.go | 66 ++++++++++++++++++++++++++-------------------------- kv.go | 24 +++++++++---------- r2bucket.go | 18 +++++++------- r2object.go | 20 ++++++++-------- r2objects.go | 2 +- request.go | 2 +- response.go | 6 ++--- stream.go | 12 +++++----- 10 files changed, 78 insertions(+), 78 deletions(-) diff --git a/env.go b/env.go index 136972d..48e8617 100644 --- a/env.go +++ b/env.go @@ -4,5 +4,5 @@ package workers // - 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 Global.Get(name).String() } diff --git a/handler.go b/handler.go index 0b3cbf4..abd86d3 100644 --- a/handler.go +++ b/handler.go @@ -28,9 +28,9 @@ func init() { }() return js.Undefined() }) - return newPromise(cb) + return NewPromise(cb) }) - global.Set("handleRequest", handleRequestCallback) + Global.Set("handleRequest", handleRequestCallback) } // handleRequest accepts a Request object and returns Response object. diff --git a/jsutil.go b/jsutil.go index 6affd51..3657cb1 100644 --- a/jsutil.go +++ b/jsutil.go @@ -7,36 +7,36 @@ import ( ) var ( - global = js.Global() - objectClass = global.Get("Object") - promiseClass = global.Get("Promise") - responseClass = global.Get("Response") - headersClass = global.Get("Headers") - arrayClass = global.Get("Array") - uint8ArrayClass = global.Get("Uint8Array") - errorClass = global.Get("Error") - readableStreamClass = global.Get("ReadableStream") - dateClass = global.Get("Date") + Global = js.Global() + ObjectClass = Global.Get("Object") + PromiseClass = Global.Get("Promise") + ResponseClass = Global.Get("Response") + HeadersClass = Global.Get("Headers") + ArrayClass = Global.Get("Array") + Uint8ArrayClass = Global.Get("Uint8Array") + ErrorClass = Global.Get("Error") + ReadableStreamClass = Global.Get("ReadableStream") + DateClass = Global.Get("Date") ) -func newObject() js.Value { - return objectClass.New() +func NewObject() js.Value { + return ObjectClass.New() } -func newUint8Array(size int) js.Value { - return uint8ArrayClass.New(size) +func NewUint8Array(size int) js.Value { + return Uint8ArrayClass.New(size) } -func newPromise(fn js.Func) js.Value { - return promiseClass.New(fn) +func NewPromise(fn js.Func) js.Value { + return PromiseClass.New(fn) } -// arrayFrom calls Array.from to given argument and returns result Array. -func arrayFrom(v js.Value) js.Value { - return arrayClass.Call("from", v) +// ArrayFrom calls Array.from to given argument and returns result Array. +func ArrayFrom(v js.Value) js.Value { + return ArrayClass.Call("from", v) } -func awaitPromise(promiseVal js.Value) (js.Value, error) { +func AwaitPromise(promiseVal js.Value) (js.Value, error) { resultCh := make(chan js.Value) errCh := make(chan error) var then, catch js.Func @@ -61,9 +61,9 @@ func awaitPromise(promiseVal js.Value) (js.Value, error) { } } -// strRecordToMap converts JavaScript side's Record into map[string]string. -func strRecordToMap(v js.Value) map[string]string { - entries := objectClass.Call("entries", v) +// StrRecordToMap converts JavaScript side's Record into map[string]string. +func StrRecordToMap(v js.Value) map[string]string { + entries := ObjectClass.Call("entries", v) entriesLen := entries.Get("length").Int() result := make(map[string]string, entriesLen) for i := 0; i < entriesLen; i++ { @@ -75,29 +75,29 @@ func strRecordToMap(v js.Value) map[string]string { return result } -// maybeString returns string value of given JavaScript value or returns nil if the value is undefined. -func maybeString(v js.Value) string { +// MaybeString returns string value of given JavaScript value or returns nil if the value is undefined. +func MaybeString(v js.Value) string { if v.IsUndefined() { return "" } return v.String() } -// maybeDate returns time.Time value of given JavaScript Date value or returns nil if the value is undefined. -func maybeDate(v js.Value) (time.Time, error) { +// MaybeDate returns time.Time value of given JavaScript Date value or returns nil if the value is undefined. +func MaybeDate(v js.Value) (time.Time, error) { if v.IsUndefined() { return time.Time{}, nil } - return dateToTime(v) + return DateToTime(v) } -// dateToTime converts JavaScript side's Data object into time.Time. -func dateToTime(v js.Value) (time.Time, error) { +// DateToTime converts JavaScript side's Data object into time.Time. +func DateToTime(v js.Value) (time.Time, error) { milli := v.Call("getTime").Float() return time.UnixMilli(int64(milli)), nil } -// timeToDate converts Go side's time.Time into Date object. -func timeToDate(t time.Time) js.Value { - return dateClass.New(t.UnixMilli()) +// TimeToDate converts Go side's time.Time into Date object. +func TimeToDate(t time.Time) js.Value { + return DateClass.New(t.UnixMilli()) } diff --git a/kv.go b/kv.go index 7fc5cc4..ff53851 100644 --- a/kv.go +++ b/kv.go @@ -15,7 +15,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() { @@ -31,7 +31,7 @@ type KVNamespaceGetOptions struct { } func (opts *KVNamespaceGetOptions) toJS(type_ string) js.Value { - obj := newObject() + obj := NewObject() obj.Set("type", type_) if opts == nil { return obj @@ -46,7 +46,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 := AwaitPromise(p) if err != nil { return "", err } @@ -57,11 +57,11 @@ 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 := AwaitPromise(p) if err != nil { return nil, err } - global.Get("console").Call("log", v) + Global.Get("console").Call("log", v) return convertStreamReaderToReader(v.Call("getReader")), nil } @@ -77,7 +77,7 @@ func (opts *KVNamespaceListOptions) toJS() js.Value { if opts == nil { return js.Undefined() } - obj := newObject() + obj := NewObject() if opts.Limit != 0 { obj.Set("limit", opts.Limit) } @@ -151,7 +151,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 := AwaitPromise(p) if err != nil { return nil, err } @@ -170,7 +170,7 @@ func (opts *KVNamespacePutOptions) toJS() js.Value { if opts == nil { return js.Undefined() } - obj := newObject() + obj := NewObject() if opts.Expiration != 0 { obj.Set("expiration", opts.Expiration) } @@ -184,7 +184,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 := AwaitPromise(p) if err != nil { return err } @@ -200,10 +200,10 @@ func (kv *KVNamespace) PutReader(key string, value io.Reader, opts *KVNamespaceP if err != nil { return err } - ua := newUint8Array(len(b)) + ua := NewUint8Array(len(b)) js.CopyBytesToJS(ua, b) p := kv.instance.Call("put", key, ua.Get("buffer"), opts.toJS()) - _, err = awaitPromise(p) + _, err = AwaitPromise(p) if err != nil { return err } @@ -214,7 +214,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 := AwaitPromise(p) if err != nil { return err } diff --git a/r2bucket.go b/r2bucket.go index 1afd8c4..7862803 100644 --- a/r2bucket.go +++ b/r2bucket.go @@ -15,8 +15,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() { @@ -31,7 +31,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 := AwaitPromise(p) if err != nil { return nil, err } @@ -46,7 +46,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 := AwaitPromise(p) if err != nil { return nil, err } @@ -68,7 +68,7 @@ func (opts *R2PutOptions) toJS() js.Value { if opts == nil { return js.Undefined() } - obj := newObject() + obj := NewObject() if opts.HTTPMetadata != (R2HTTPMetadata{}) { obj.Set("httpMetadata", opts.HTTPMetadata.toJS()) } @@ -99,10 +99,10 @@ func (r *R2Bucket) Put(key string, value io.ReadCloser, opts *R2PutOptions) (*R2 return nil, err } defer value.Close() - ua := newUint8Array(len(b)) + ua := NewUint8Array(len(b)) js.CopyBytesToJS(ua, b) p := r.instance.Call("put", key, ua.Get("buffer"), opts.toJS()) - v, err := awaitPromise(p) + v, err := AwaitPromise(p) if err != nil { return nil, err } @@ -113,7 +113,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 := AwaitPromise(p); err != nil { return err } return nil @@ -123,7 +123,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 := AwaitPromise(p) if err != nil { return nil, err } diff --git a/r2object.go b/r2object.go index 29f528e..da26cd4 100644 --- a/r2object.go +++ b/r2object.go @@ -41,7 +41,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 := DateToTime(v.Get("uploaded")) if err != nil { return nil, fmt.Errorf("error converting uploaded: %w", err) } @@ -63,7 +63,7 @@ func toR2Object(v js.Value) (*R2Object, error) { HTTPETag: v.Get("httpEtag").String(), Uploaded: uploaded, HTTPMetadata: r2Meta, - CustomMetadata: strRecordToMap(v.Get("customMetadata")), + CustomMetadata: StrRecordToMap(v.Get("customMetadata")), Body: body, }, nil } @@ -80,22 +80,22 @@ type R2HTTPMetadata struct { } func toR2HTTPMetadata(v js.Value) (R2HTTPMetadata, error) { - cacheExpiry, err := maybeDate(v.Get("cacheExpiry")) + cacheExpiry, err := 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: MaybeString(v.Get("contentType")), + ContentLanguage: MaybeString(v.Get("contentLanguage")), + ContentDisposition: MaybeString(v.Get("contentDisposition")), + ContentEncoding: MaybeString(v.Get("contentEncoding")), + CacheControl: MaybeString(v.Get("cacheControl")), CacheExpiry: cacheExpiry, }, nil } func (md *R2HTTPMetadata) toJS() js.Value { - obj := newObject() + obj := NewObject() kv := map[string]string{ "contentType": md.ContentType, "contentLanguage": md.ContentLanguage, @@ -109,7 +109,7 @@ func (md *R2HTTPMetadata) toJS() js.Value { } } if !md.CacheExpiry.IsZero() { - obj.Set("cacheExpiry", timeToDate(md.CacheExpiry)) + obj.Set("cacheExpiry", TimeToDate(md.CacheExpiry)) } return obj } diff --git a/r2objects.go b/r2objects.go index 5948915..9da69fd 100644 --- a/r2objects.go +++ b/r2objects.go @@ -36,7 +36,7 @@ func toR2Objects(v js.Value) (*R2Objects, error) { return &R2Objects{ Objects: objects, Truncated: v.Get("truncated").Bool(), - Cursor: maybeString(v.Get("cursor")), + Cursor: MaybeString(v.Get("cursor")), DelimitedPrefixes: prefixes, }, nil } diff --git a/request.go b/request.go index dccbca5..22da6a7 100644 --- a/request.go +++ b/request.go @@ -22,7 +22,7 @@ func toBody(streamOrNull js.Value) io.ReadCloser { // toHeader converts JavaScript sides Headers to http.Header. // - Headers: https://developer.mozilla.org/ja/docs/Web/API/Headers func toHeader(headers js.Value) http.Header { - entries := arrayFrom(headers.Call("entries")) + entries := ArrayFrom(headers.Call("entries")) headerLen := entries.Length() h := http.Header{} for i := 0; i < headerLen; i++ { diff --git a/response.go b/response.go index 2b23c29..f490e7d 100644 --- a/response.go +++ b/response.go @@ -6,7 +6,7 @@ import ( ) func toJSHeader(header http.Header) js.Value { - h := headersClass.New() + h := HeadersClass.New() for key, values := range header { for _, value := range values { h.Call("append", key, value) @@ -21,10 +21,10 @@ func toJSResponse(w *responseWriterBuffer) (js.Value, error) { if status == 0 { status = http.StatusOK } - respInit := newObject() + respInit := NewObject() respInit.Set("status", status) respInit.Set("statusText", http.StatusText(status)) respInit.Set("headers", toJSHeader(w.Header())) readableStream := convertReaderToReadableStream(w.reader) - return responseClass.New(readableStream, respInit), nil + return ResponseClass.New(readableStream, respInit), nil } diff --git a/stream.go b/stream.go index 13c2513..683ba33 100644 --- a/stream.go +++ b/stream.go @@ -83,14 +83,14 @@ func (rs *readerToReadableStream) Pull(controller js.Value) error { return nil } if err != nil { - jsErr := errorClass.New(err.Error()) + jsErr := ErrorClass.New(err.Error()) controller.Call("error", jsErr) if err := rs.reader.Close(); err != nil { return err } return err } - ua := newUint8Array(n) + ua := NewUint8Array(n) _ = js.CopyBytesToJS(ua, rs.chunkBuf[:n]) controller.Call("enqueue", ua) return nil @@ -111,7 +111,7 @@ func convertReaderToReadableStream(reader io.ReadCloser) js.Value { reader: reader, chunkBuf: make([]byte, defaultChunkSize), } - rsInit := newObject() + rsInit := NewObject() rsInit.Set("pull", js.FuncOf(func(_ js.Value, args []js.Value) any { var cb js.Func cb = js.FuncOf(func(this js.Value, pArgs []js.Value) any { @@ -121,13 +121,13 @@ func convertReaderToReadableStream(reader io.ReadCloser) js.Value { controller := args[0] err := stream.Pull(controller) if err != nil { - reject.Invoke(errorClass.New(err.Error())) + reject.Invoke(ErrorClass.New(err.Error())) return js.Undefined() } resolve.Invoke() return js.Undefined() }) - return newPromise(cb) + return NewPromise(cb) })) rsInit.Set("cancel", js.FuncOf(func(js.Value, []js.Value) any { err := stream.Cancel() @@ -136,5 +136,5 @@ func convertReaderToReadableStream(reader io.ReadCloser) js.Value { } return js.Undefined() })) - return readableStreamClass.New(rsInit) + return ReadableStreamClass.New(rsInit) } From 555b3e54bcb0f4cdb543f7e9dc9476cbc248e58f Mon Sep 17 00:00:00 2001 From: syumai Date: Tue, 13 Sep 2022 23:16:58 +0900 Subject: [PATCH 2/4] make public stream util symbols --- kv.go | 2 +- r2object.go | 2 +- request.go | 2 +- response.go | 2 +- stream.go | 8 ++++---- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/kv.go b/kv.go index ff53851..dee0eaf 100644 --- a/kv.go +++ b/kv.go @@ -62,7 +62,7 @@ func (kv *KVNamespace) GetReader(key string, opts *KVNamespaceGetOptions) (io.Re return nil, err } Global.Get("console").Call("log", v) - return convertStreamReaderToReader(v.Call("getReader")), nil + return ConvertStreamReaderToReader(v.Call("getReader")), nil } // KVNamespaceListOptions represents Cloudflare KV namespace list options. diff --git a/r2object.go b/r2object.go index da26cd4..b322978 100644 --- a/r2object.go +++ b/r2object.go @@ -52,7 +52,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 = ConvertStreamReaderToReader(v.Get("body").Call("getReader")) } return &R2Object{ instance: v, diff --git a/request.go b/request.go index 22da6a7..5c5eed9 100644 --- a/request.go +++ b/request.go @@ -16,7 +16,7 @@ func toBody(streamOrNull js.Value) io.ReadCloser { return nil } sr := streamOrNull.Call("getReader") - return io.NopCloser(convertStreamReaderToReader(sr)) + return io.NopCloser(ConvertStreamReaderToReader(sr)) } // toHeader converts JavaScript sides Headers to http.Header. diff --git a/response.go b/response.go index f490e7d..636bc64 100644 --- a/response.go +++ b/response.go @@ -25,6 +25,6 @@ func toJSResponse(w *responseWriterBuffer) (js.Value, error) { respInit.Set("status", status) respInit.Set("statusText", http.StatusText(status)) respInit.Set("headers", toJSHeader(w.Header())) - readableStream := convertReaderToReadableStream(w.reader) + readableStream := ConvertReaderToReadableStream(w.reader) return ResponseClass.New(readableStream, respInit), nil } diff --git a/stream.go b/stream.go index 683ba33..e3e5c7e 100644 --- a/stream.go +++ b/stream.go @@ -56,8 +56,8 @@ func (sr *streamReaderToReader) Read(p []byte) (n int, err error) { return sr.buf.Read(p) } -// convertStreamReaderToReader converts ReadableStreamDefaultReader to io.Reader. -func convertStreamReaderToReader(sr js.Value) io.Reader { +// ConvertStreamReaderToReader converts ReadableStreamDefaultReader to io.Reader. +func ConvertStreamReaderToReader(sr js.Value) io.Reader { return &streamReaderToReader{ streamReader: sr, } @@ -105,8 +105,8 @@ func (rs *readerToReadableStream) Cancel() error { // https://deno.land/std@0.139.0/streams/conversion.ts#L5 const defaultChunkSize = 16_640 -// convertReaderToReadableStream converts io.ReadCloser to ReadableStream. -func convertReaderToReadableStream(reader io.ReadCloser) js.Value { +// ConvertReaderToReadableStream converts io.ReadCloser to ReadableStream. +func ConvertReaderToReadableStream(reader io.ReadCloser) js.Value { stream := &readerToReadableStream{ reader: reader, chunkBuf: make([]byte, defaultChunkSize), From 890096fce9cd77f9ae66af0366f919789c602e8d Mon Sep 17 00:00:00 2001 From: syumai Date: Tue, 13 Sep 2022 23:18:17 +0900 Subject: [PATCH 3/4] split internal/jsutil --- env.go | 4 +++- handler.go | 6 ++++-- jsutil.go => internal/jsutil/jsutil.go | 2 +- stream.go => internal/jsutil/stream.go | 2 +- kv.go | 26 ++++++++++++++------------ r2bucket.go | 16 +++++++++------- r2object.go | 24 +++++++++++++----------- r2objects.go | 4 +++- request.go | 6 ++++-- response.go | 10 ++++++---- 10 files changed, 58 insertions(+), 42 deletions(-) rename jsutil.go => internal/jsutil/jsutil.go (99%) rename stream.go => internal/jsutil/stream.go (99%) diff --git a/env.go b/env.go index 48e8617..6b9344c 100644 --- a/env.go +++ b/env.go @@ -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() } diff --git a/handler.go b/handler.go index abd86d3..ec28017 100644 --- a/handler.go +++ b/handler.go @@ -5,6 +5,8 @@ import ( "io" "net/http" "syscall/js" + + "github.com/syumai/workers/internal/jsutil" ) var httpHandler http.Handler @@ -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. diff --git a/jsutil.go b/internal/jsutil/jsutil.go similarity index 99% rename from jsutil.go rename to internal/jsutil/jsutil.go index 3657cb1..c76bff3 100644 --- a/jsutil.go +++ b/internal/jsutil/jsutil.go @@ -1,4 +1,4 @@ -package workers +package jsutil import ( "fmt" diff --git a/stream.go b/internal/jsutil/stream.go similarity index 99% rename from stream.go rename to internal/jsutil/stream.go index e3e5c7e..4dc45ba 100644 --- a/stream.go +++ b/internal/jsutil/stream.go @@ -1,4 +1,4 @@ -package workers +package jsutil import ( "bytes" diff --git a/kv.go b/kv.go index dee0eaf..40f1685 100644 --- a/kv.go +++ b/kv.go @@ -4,6 +4,8 @@ import ( "fmt" "io" "syscall/js" + + "github.com/syumai/workers/internal/jsutil" ) // KVNamespace represents interface of Cloudflare Worker's KV namespace instance. @@ -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 @@ -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 } @@ -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. @@ -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) } @@ -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 } @@ -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) } @@ -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 } @@ -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 } @@ -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 } diff --git a/r2bucket.go b/r2bucket.go index 7862803..ded1bb6 100644 --- a/r2bucket.go +++ b/r2bucket.go @@ -4,6 +4,8 @@ import ( "fmt" "io" "syscall/js" + + "github.com/syumai/workers/internal/jsutil" ) // R2Bucket represents interface of Cloudflare Worker's R2 Bucket instance. @@ -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 } @@ -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 } @@ -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()) } @@ -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 } @@ -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 @@ -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 } diff --git a/r2object.go b/r2object.go index b322978..d6b6322 100644 --- a/r2object.go +++ b/r2object.go @@ -6,6 +6,8 @@ import ( "io" "syscall/js" "time" + + "github.com/syumai/workers/internal/jsutil" ) // R2Object represents Cloudflare R2 object. @@ -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) } @@ -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, @@ -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 } @@ -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, @@ -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 } diff --git a/r2objects.go b/r2objects.go index 9da69fd..92208f7 100644 --- a/r2objects.go +++ b/r2objects.go @@ -3,6 +3,8 @@ package workers import ( "fmt" "syscall/js" + + "github.com/syumai/workers/internal/jsutil" ) // R2Objects represents Cloudflare R2 objects. @@ -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 } diff --git a/request.go b/request.go index 5c5eed9..43af70d 100644 --- a/request.go +++ b/request.go @@ -7,6 +7,8 @@ import ( "strconv" "strings" "syscall/js" + + "github.com/syumai/workers/internal/jsutil" ) // toBody converts JavaScripts sides ReadableStream (can be null) to io.ReadCloser. @@ -16,13 +18,13 @@ func toBody(streamOrNull js.Value) io.ReadCloser { return nil } sr := streamOrNull.Call("getReader") - return io.NopCloser(ConvertStreamReaderToReader(sr)) + return io.NopCloser(jsutil.ConvertStreamReaderToReader(sr)) } // toHeader converts JavaScript sides Headers to http.Header. // - Headers: https://developer.mozilla.org/ja/docs/Web/API/Headers func toHeader(headers js.Value) http.Header { - entries := ArrayFrom(headers.Call("entries")) + entries := jsutil.ArrayFrom(headers.Call("entries")) headerLen := entries.Length() h := http.Header{} for i := 0; i < headerLen; i++ { diff --git a/response.go b/response.go index 636bc64..da9505a 100644 --- a/response.go +++ b/response.go @@ -3,10 +3,12 @@ package workers import ( "net/http" "syscall/js" + + "github.com/syumai/workers/internal/jsutil" ) func toJSHeader(header http.Header) js.Value { - h := HeadersClass.New() + h := jsutil.HeadersClass.New() for key, values := range header { for _, value := range values { h.Call("append", key, value) @@ -21,10 +23,10 @@ func toJSResponse(w *responseWriterBuffer) (js.Value, error) { if status == 0 { status = http.StatusOK } - respInit := NewObject() + respInit := jsutil.NewObject() respInit.Set("status", status) respInit.Set("statusText", http.StatusText(status)) respInit.Set("headers", toJSHeader(w.Header())) - readableStream := ConvertReaderToReadableStream(w.reader) - return ResponseClass.New(readableStream, respInit), nil + readableStream := jsutil.ConvertReaderToReadableStream(w.reader) + return jsutil.ResponseClass.New(readableStream, respInit), nil } From 17013001765bfb16ee6bfcc4435ea6576ce3b5d0 Mon Sep 17 00:00:00 2001 From: syumai Date: Tue, 13 Sep 2022 23:19:32 +0900 Subject: [PATCH 4/4] split cloudflare package --- kv.go => cloudflare/kv.go | 2 +- r2bucket.go => cloudflare/r2bucket.go | 2 +- r2object.go => cloudflare/r2object.go | 2 +- r2objects.go => cloudflare/r2objects.go | 2 +- examples/kv-counter/main.go | 4 +++- examples/r2-image-server/main.go | 9 +++++---- examples/r2-image-viewer/main.go | 3 ++- 7 files changed, 14 insertions(+), 10 deletions(-) rename kv.go => cloudflare/kv.go (99%) rename r2bucket.go => cloudflare/r2bucket.go (99%) rename r2object.go => cloudflare/r2object.go (99%) rename r2objects.go => cloudflare/r2objects.go (98%) diff --git a/kv.go b/cloudflare/kv.go similarity index 99% rename from kv.go rename to cloudflare/kv.go index 40f1685..f5d0387 100644 --- a/kv.go +++ b/cloudflare/kv.go @@ -1,4 +1,4 @@ -package workers +package cloudflare import ( "fmt" diff --git a/r2bucket.go b/cloudflare/r2bucket.go similarity index 99% rename from r2bucket.go rename to cloudflare/r2bucket.go index ded1bb6..2fbc899 100644 --- a/r2bucket.go +++ b/cloudflare/r2bucket.go @@ -1,4 +1,4 @@ -package workers +package cloudflare import ( "fmt" diff --git a/r2object.go b/cloudflare/r2object.go similarity index 99% rename from r2object.go rename to cloudflare/r2object.go index d6b6322..8a26a31 100644 --- a/r2object.go +++ b/cloudflare/r2object.go @@ -1,4 +1,4 @@ -package workers +package cloudflare import ( "errors" diff --git a/r2objects.go b/cloudflare/r2objects.go similarity index 98% rename from r2objects.go rename to cloudflare/r2objects.go index 92208f7..4d0302b 100644 --- a/r2objects.go +++ b/cloudflare/r2objects.go @@ -1,4 +1,4 @@ -package workers +package cloudflare import ( "fmt" diff --git a/examples/kv-counter/main.go b/examples/kv-counter/main.go index fb3761e..b9a0768 100644 --- a/examples/kv-counter/main.go +++ b/examples/kv-counter/main.go @@ -7,6 +7,8 @@ import ( "os" "strconv" + "github.com/syumai/workers/cloudflare" + "github.com/syumai/workers" ) @@ -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) diff --git a/examples/r2-image-server/main.go b/examples/r2-image-server/main.go index 73e2d01..518dc92 100644 --- a/examples/r2-image-server/main.go +++ b/examples/r2-image-server/main.go @@ -9,6 +9,7 @@ import ( "strings" "github.com/syumai/workers" + "github.com/syumai/workers/cloudflare" ) // bucketName is R2 bucket name defined in wrangler.toml. @@ -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 } @@ -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"}, diff --git a/examples/r2-image-viewer/main.go b/examples/r2-image-viewer/main.go index 5b7c022..924281a 100644 --- a/examples/r2-image-viewer/main.go +++ b/examples/r2-image-viewer/main.go @@ -8,6 +8,7 @@ import ( "strings" "github.com/syumai/workers" + "github.com/syumai/workers/cloudflare" ) // bucketName is R2 bucket name defined in wrangler.toml. @@ -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