2023-02-09 12:16:36 +01:00
|
|
|
package module
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
|
|
|
|
"forge.cadoles.com/arcad/edge/pkg/app"
|
2023-02-21 12:14:29 +01:00
|
|
|
"forge.cadoles.com/arcad/edge/pkg/module/util"
|
2023-02-09 12:16:36 +01:00
|
|
|
"github.com/dop251/goja"
|
|
|
|
"github.com/pkg/errors"
|
|
|
|
)
|
|
|
|
|
|
|
|
type ContextKey string
|
|
|
|
|
|
|
|
const (
|
|
|
|
ContextKeySessionID ContextKey = "sessionId"
|
|
|
|
ContextKeyOriginRequest ContextKey = "originRequest"
|
|
|
|
)
|
|
|
|
|
|
|
|
type ContextModule struct{}
|
|
|
|
|
|
|
|
func (m *ContextModule) Name() string {
|
|
|
|
return "context"
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *ContextModule) new(call goja.FunctionCall, rt *goja.Runtime) goja.Value {
|
|
|
|
return rt.ToValue(context.Background())
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *ContextModule) with(call goja.FunctionCall, rt *goja.Runtime) goja.Value {
|
2023-02-21 12:14:29 +01:00
|
|
|
ctx := util.AssertContext(call.Argument(0), rt)
|
|
|
|
rawValues := util.AssertObject(call.Argument(1), rt)
|
2023-02-09 12:16:36 +01:00
|
|
|
|
|
|
|
values := make(map[ContextKey]any)
|
|
|
|
for k, v := range rawValues {
|
|
|
|
values[ContextKey(k)] = v
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx = WithContext(ctx, values)
|
|
|
|
|
|
|
|
return rt.ToValue(ctx)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *ContextModule) get(call goja.FunctionCall, rt *goja.Runtime) goja.Value {
|
2023-02-21 12:14:29 +01:00
|
|
|
ctx := util.AssertContext(call.Argument(0), rt)
|
|
|
|
rawKey := util.AssertString(call.Argument(1), rt)
|
2023-02-09 12:16:36 +01:00
|
|
|
|
|
|
|
value := ctx.Value(ContextKey(rawKey))
|
|
|
|
|
|
|
|
return rt.ToValue(value)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *ContextModule) Export(export *goja.Object) {
|
|
|
|
if err := export.Set("new", m.new); err != nil {
|
|
|
|
panic(errors.Wrap(err, "could not set 'new' function"))
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := export.Set("get", m.get); err != nil {
|
|
|
|
panic(errors.Wrap(err, "could not set 'get' function"))
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := export.Set("with", m.with); err != nil {
|
|
|
|
panic(errors.Wrap(err, "could not set 'with' function"))
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := export.Set("ORIGIN_REQUEST", string(ContextKeyOriginRequest)); err != nil {
|
|
|
|
panic(errors.Wrap(err, "could not set 'ORIGIN_REQUEST' property"))
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := export.Set("SESSION_ID", string(ContextKeySessionID)); err != nil {
|
|
|
|
panic(errors.Wrap(err, "could not set 'SESSION_ID' property"))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func ContextModuleFactory() app.ServerModuleFactory {
|
|
|
|
return func(server *app.Server) app.ServerModule {
|
|
|
|
return &ContextModule{}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func ContextValue[T any](ctx context.Context, key ContextKey) T {
|
|
|
|
value, ok := ctx.Value(key).(T)
|
|
|
|
if !ok {
|
|
|
|
return *new(T)
|
|
|
|
}
|
|
|
|
|
|
|
|
return value
|
|
|
|
}
|
|
|
|
|
|
|
|
func WithContext(ctx context.Context, values map[ContextKey]any) context.Context {
|
|
|
|
for k, v := range values {
|
|
|
|
ctx = context.WithValue(ctx, k, v)
|
|
|
|
}
|
|
|
|
|
|
|
|
return ctx
|
|
|
|
}
|