forked from zitadel/zitadel
-
Notifications
You must be signed in to change notification settings - Fork 0
/
actions.go
113 lines (96 loc) · 2.18 KB
/
actions.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package actions
import (
"context"
"errors"
"fmt"
z_errs "github.com/dennigogo/zitadel/internal/errors"
"github.com/dennigogo/zitadel/internal/query"
"github.com/dop251/goja_nodejs/require"
)
type Config struct {
HTTP HTTPConfig
}
var (
ErrHalt = errors.New("interrupt")
)
type jsAction func(fields, fields) error
func Run(ctx context.Context, ctxParam contextFields, apiParam apiFields, script, name string, opts ...Option) error {
config, err := prepareRun(ctx, ctxParam, apiParam, script, opts)
if err != nil {
return err
}
var fn jsAction
jsFn := config.vm.Get(name)
if jsFn == nil {
return errors.New("function not found")
}
err = config.vm.ExportTo(jsFn, &fn)
if err != nil {
return err
}
t := config.Start()
defer func() {
t.Stop()
}()
return executeFn(config, fn)
}
func prepareRun(ctx context.Context, ctxParam contextFields, apiParam apiFields, script string, opts []Option) (config *runConfig, err error) {
config = newRunConfig(ctx, opts...)
if config.timeout == 0 {
return nil, z_errs.ThrowInternal(nil, "ACTIO-uCpCx", "Errrors.Internal")
}
t := config.Prepare()
defer func() {
t.Stop()
}()
if ctxParam != nil {
ctxParam(config.ctxParam)
}
if apiParam != nil {
apiParam(config.apiParam)
}
registry := new(require.Registry)
registry.Enable(config.vm)
for name, loader := range config.modules {
registry.RegisterNativeModule(name, loader)
}
// overload error if function panics
defer func() {
r := recover()
if r != nil {
err = r.(error)
return
}
}()
_, err = config.vm.RunString(script)
return config, err
}
func executeFn(config *runConfig, fn jsAction) (err error) {
defer func() {
r := recover()
if r != nil && !config.allowedToFail {
var ok bool
if err, ok = r.(error); ok {
return
}
e, ok := r.(string)
if ok {
err = errors.New(e)
return
}
err = fmt.Errorf("unknown error occured: %v", r)
}
}()
err = fn(config.ctxParam.fields, config.apiParam.fields)
if err != nil && !config.allowedToFail {
return err
}
return nil
}
func ActionToOptions(a *query.Action) []Option {
opts := make([]Option, 0, 1)
if a.AllowedToFail {
opts = append(opts, WithAllowedToFail())
}
return opts
}