diff --git a/workers.go b/workers.go index 40cc333c6a5..26c9a176157 100644 --- a/workers.go +++ b/workers.go @@ -107,6 +107,8 @@ const ( WorkerPlainTextBindingType WorkerBindingType = "plain_text" // WorkerServiceBindingType is the type for worker service bindings. WorkerServiceBindingType WorkerBindingType = "service" + // WorkerDynamicDispatchBindingType is the type for dynamic dispatch bindings. + WorkerDynamicDispatchBindingType WorkerBindingType = "dynamic_dispatch" ) // WorkerBindingListItem a struct representing an individual binding in a list of bindings. @@ -305,6 +307,27 @@ func (b WorkerServiceBinding) serialize(bindingName string) (workerBindingMeta, }, nil, nil } +// WorkerDynamicDispatchBinding is a binding to a dispatcher than can dispatch another Worker +// +// https://developers.cloudflare.com/workers/tooling/api/scripts/#add-a-plain-text-binding +type WorkerDynamicDispatchBinding struct{} + +// Type returns the type of the binding. +func (b WorkerDynamicDispatchBinding) Type() WorkerBindingType { + return WorkerDynamicDispatchBindingType +} + +func (b WorkerDynamicDispatchBinding) serialize(bindingName string) (workerBindingMeta, workerBindingBodyWriter, error) { + if bindingName == "" { + return nil, nil, errors.Errorf(`Name for Dynamic Dispatch binding "%s" cannot be empty`, bindingName) + } + + return workerBindingMeta{ + "name": bindingName, + "type": b.Type(), + }, nil, nil +} + // Each binding that adds a part to the multipart form body will need // a unique part name so we just generate a random 128bit hex string. func getRandomPartName() string { @@ -459,6 +482,8 @@ func (api *API) ListWorkerBindings(ctx context.Context, requestParams *WorkerReq Service: jsonBinding["service"].(string), Environment: jsonBinding["environment"].(string), } + case WorkerDynamicDispatchBindingType: + bindingListItem.Binding = WorkerDynamicDispatchBinding{} default: bindingListItem.Binding = WorkerInheritBinding{} } diff --git a/workers_test.go b/workers_test.go index f9119e68dc1..fcb9aaa9169 100644 --- a/workers_test.go +++ b/workers_test.go @@ -136,6 +136,10 @@ const ( "service": "test_service", "environment": "production" }, + { + "name": "MY_DISPATCHER", + "type": "dynamic_dispatch" + }, { "name": "MY_NEW_BINDING", "type": "some_imaginary_new_binding_type" @@ -767,6 +771,40 @@ func TestWorkers_UploadWorkerWithCompatibilityFlags(t *testing.T) { assert.NoError(t, err) } +func TestWorkers_UploadWorkerWithDynamicDispatch(t *testing.T) { + setup(UsingAccount("foo")) + defer teardown() + + handler := func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, http.MethodPut, r.Method, "Expected method 'PUT', got %s", r.Method) + + mpUpload, err := parseMultipartUpload(r) + assert.NoError(t, err) + + expectedBindings := map[string]workerBindingMeta{ + "b1": { + "type": "dynamic_dispatch", + "name": "b1", + }, + } + assert.Equal(t, workerScript, mpUpload.Script) + assert.Equal(t, expectedBindings, mpUpload.BindingMeta) + + w.Header().Set("content-type", "application/json") + fmt.Fprintf(w, uploadWorkerResponseData) //nolint + } + mux.HandleFunc("/accounts/foo/workers/scripts/bar", handler) + + scriptParams := WorkerScriptParams{ + Script: workerScript, + Bindings: map[string]WorkerBinding{ + "b1": WorkerDynamicDispatchBinding{}, + }, + } + _, err := client.UploadWorkerWithBindings(context.Background(), &WorkerRequestParams{ScriptName: "bar"}, &scriptParams) + assert.NoError(t, err) +} + func TestWorkers_CreateWorkerRoute(t *testing.T) { setup() defer teardown() @@ -1034,7 +1072,7 @@ func TestWorkers_ListWorkerBindingsMultiScript(t *testing.T) { assert.NoError(t, err) assert.Equal(t, successResponse, res.Response) - assert.Equal(t, 6, len(res.BindingList)) + assert.Equal(t, 7, len(res.BindingList)) assert.Equal(t, res.BindingList[0], WorkerBindingListItem{ Name: "MY_KV", @@ -1075,10 +1113,16 @@ func TestWorkers_ListWorkerBindingsMultiScript(t *testing.T) { assert.Equal(t, WorkerServiceBindingType, res.BindingList[4].Binding.Type()) assert.Equal(t, res.BindingList[5], WorkerBindingListItem{ + Name: "MY_DISPATCHER", + Binding: WorkerDynamicDispatchBinding{}, + }) + assert.Equal(t, WorkerDynamicDispatchBindingType, res.BindingList[5].Binding.Type()) + + assert.Equal(t, res.BindingList[6], WorkerBindingListItem{ Name: "MY_NEW_BINDING", Binding: WorkerInheritBinding{}, }) - assert.Equal(t, WorkerInheritBindingType, res.BindingList[5].Binding.Type()) + assert.Equal(t, WorkerInheritBindingType, res.BindingList[6].Binding.Type()) } func TestWorkers_UpdateWorkerRouteErrorsWhenMixingSingleAndMultiScriptProperties(t *testing.T) {