MCPcopy
hub / github.com/pocketbase/pocketbase / hooksBinds

Function hooksBinds

plugins/jsvm/binds.go:43–102  ·  view source on GitHub ↗

hooksBinds adds wrapped "on*" hook methods by reflecting on core.App.

(app core.App, loader *goja.Runtime, executors *vmsPool)

Source from the content-addressed store, hash-verified

41
42// hooksBinds adds wrapped "on*" hook methods by reflecting on core.App.
43func hooksBinds(app core.App, loader *goja.Runtime, executors *vmsPool) {
44 fm := FieldMapper{}
45
46 appType := reflect.TypeOf(app)
47 appValue := reflect.ValueOf(app)
48 totalMethods := appType.NumMethod()
49 excludeHooks := []string{"OnServe"}
50
51 for i := 0; i < totalMethods; i++ {
52 method := appType.Method(i)
53 if !strings.HasPrefix(method.Name, "On") || slices.Contains(excludeHooks, method.Name) {
54 continue // not a hook or excluded
55 }
56
57 jsName := fm.MethodName(appType, method)
58
59 // register the hook to the loader
60 loader.Set(jsName, func(callback string, tags ...string) {
61 // overwrite the global $app with the hook scoped instance
62 callback = `function(e) { $app = e.app; return (` + callback + `).call(undefined, e) }`
63 pr := goja.MustCompile(defaultScriptPath, "{("+callback+").apply(undefined, __args)}", true)
64
65 tagsAsValues := make([]reflect.Value, len(tags))
66 for i, tag := range tags {
67 tagsAsValues[i] = reflect.ValueOf(tag)
68 }
69
70 hookInstance := appValue.MethodByName(method.Name).Call(tagsAsValues)[0]
71 hookBindFunc := hookInstance.MethodByName("BindFunc")
72
73 handlerType := hookBindFunc.Type().In(0)
74
75 handler := reflect.MakeFunc(handlerType, func(args []reflect.Value) (results []reflect.Value) {
76 handlerArgs := make([]any, len(args))
77 for i, arg := range args {
78 handlerArgs[i] = arg.Interface()
79 }
80
81 err := executors.run(func(executor *goja.Runtime) error {
82 executor.Set("$app", goja.Undefined())
83 executor.Set("__args", handlerArgs)
84 res, err := executor.RunProgram(pr)
85 executor.Set("__args", goja.Undefined())
86
87 // check for returned Go error value
88 if resErr := checkGojaValueForError(app, res); resErr != nil {
89 return resErr
90 }
91
92 return normalizeException(err)
93 })
94
95 return []reflect.Value{reflect.ValueOf(&err).Elem()}
96 })
97
98 // register the wrapped hook handler
99 hookBindFunc.Call([]reflect.Value{handler})
100 })

Callers 4

TestHooksBindsCountFunction · 0.85
TestHooksBindsFunction · 0.85
registerHooksMethod · 0.85

Calls 7

MethodNameMethod · 0.95
checkGojaValueForErrorFunction · 0.85
normalizeExceptionFunction · 0.85
MethodMethod · 0.80
SetMethod · 0.65
TypeMethod · 0.65
runMethod · 0.65

Tested by 3

TestHooksBindsCountFunction · 0.68
TestHooksBindsFunction · 0.68

Used in the wild real call sites across dependent graphs

searching dependent graphs…