added native echo.HandlerFunc support and .staticDirectoryHandler bind

This commit is contained in:
Gani Georgiev 2023-07-24 21:11:55 +03:00
parent 99ea916c14
commit 8dfc90985b
7 changed files with 6938 additions and 9881 deletions

View File

@ -193,19 +193,6 @@ func bindStaticAdminUI(app core.App, e *echo.Echo) error {
return nil return nil
} }
const totalAdminsCacheKey = "@totalAdmins"
func updateTotalAdminsCache(app core.App) error {
total, err := app.Dao().TotalAdmins()
if err != nil {
return err
}
app.Cache().Set(totalAdminsCacheKey, total)
return nil
}
func uiCacheControl() echo.MiddlewareFunc { func uiCacheControl() echo.MiddlewareFunc {
return func(next echo.HandlerFunc) echo.HandlerFunc { return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error { return func(c echo.Context) error {
@ -220,6 +207,19 @@ func uiCacheControl() echo.MiddlewareFunc {
} }
} }
const totalAdminsCacheKey = "@totalAdmins"
func updateTotalAdminsCache(app core.App) error {
total, err := app.Dao().TotalAdmins()
if err != nil {
return err
}
app.Cache().Set(totalAdminsCacheKey, total)
return nil
}
// installerRedirect redirects the user to the installer admin UI page // installerRedirect redirects the user to the installer admin UI page
// when the application needs some preliminary configurations to be done. // when the application needs some preliminary configurations to be done.
func installerRedirect(app core.App) echo.MiddlewareFunc { func installerRedirect(app core.App) echo.MiddlewareFunc {

42
go.mod
View File

@ -4,7 +4,7 @@ go 1.18
require ( require (
github.com/AlecAivazis/survey/v2 v2.3.7 github.com/AlecAivazis/survey/v2 v2.3.7
github.com/aws/aws-sdk-go v1.44.299 github.com/aws/aws-sdk-go v1.44.306
github.com/disintegration/imaging v1.6.2 github.com/disintegration/imaging v1.6.2
github.com/domodwyer/mailyak/v3 v3.6.0 github.com/domodwyer/mailyak/v3 v3.6.0
github.com/dop251/goja v0.0.0-20230707174833-636fdf960de1 github.com/dop251/goja v0.0.0-20230707174833-636fdf960de1
@ -21,34 +21,34 @@ require (
github.com/pocketbase/tygoja v0.0.0-20230618203136-2f8d57768be1 github.com/pocketbase/tygoja v0.0.0-20230618203136-2f8d57768be1
github.com/spf13/cast v1.5.1 github.com/spf13/cast v1.5.1
github.com/spf13/cobra v1.7.0 github.com/spf13/cobra v1.7.0
gocloud.dev v0.30.0 gocloud.dev v0.32.0
golang.org/x/crypto v0.11.0 golang.org/x/crypto v0.11.0
golang.org/x/net v0.12.0 golang.org/x/net v0.12.0
golang.org/x/oauth2 v0.10.0 golang.org/x/oauth2 v0.10.0
golang.org/x/sync v0.3.0 golang.org/x/sync v0.3.0
modernc.org/sqlite v1.23.1 modernc.org/sqlite v1.24.0
) )
require ( require (
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
github.com/aws/aws-sdk-go-v2 v1.18.1 // indirect github.com/aws/aws-sdk-go-v2 v1.19.0 // indirect
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.10 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.10 // indirect
github.com/aws/aws-sdk-go-v2/config v1.18.27 // indirect github.com/aws/aws-sdk-go-v2/config v1.18.28 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.13.26 // indirect github.com/aws/aws-sdk-go-v2/credentials v1.13.27 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.4 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.5 // indirect
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.71 // indirect github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.72 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.34 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.35 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.28 // indirect github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.29 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.35 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.3.36 // indirect
github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.26 // indirect github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.27 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.11 // indirect github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.11 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.29 // indirect github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.30 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.28 // indirect github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.29 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.14.3 // indirect github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.14.4 // indirect
github.com/aws/aws-sdk-go-v2/service/s3 v1.36.0 // indirect github.com/aws/aws-sdk-go-v2/service/s3 v1.37.0 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.12.12 // indirect github.com/aws/aws-sdk-go-v2/service/sso v1.12.13 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.12 // indirect github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.13 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.19.2 // indirect github.com/aws/aws-sdk-go-v2/service/sts v1.19.3 // indirect
github.com/aws/smithy-go v1.13.5 // indirect github.com/aws/smithy-go v1.13.5 // indirect
github.com/dlclark/regexp2 v1.10.0 // indirect github.com/dlclark/regexp2 v1.10.0 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect github.com/dustin/go-humanize v1.0.1 // indirect
@ -78,9 +78,9 @@ require (
golang.org/x/time v0.3.0 // indirect golang.org/x/time v0.3.0 // indirect
golang.org/x/tools v0.11.0 // indirect golang.org/x/tools v0.11.0 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
google.golang.org/api v0.130.0 // indirect google.golang.org/api v0.133.0 // indirect
google.golang.org/appengine v1.6.7 // indirect google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230710151506-e685fd7b542b // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230724170836-66ad5b6ff146 // indirect
google.golang.org/grpc v1.56.2 // indirect google.golang.org/grpc v1.56.2 // indirect
google.golang.org/protobuf v1.31.0 // indirect google.golang.org/protobuf v1.31.0 // indirect
lukechampine.com/uint128 v1.3.0 // indirect lukechampine.com/uint128 v1.3.0 // indirect

3085
go.sum

File diff suppressed because it is too large Load Diff

View File

@ -144,31 +144,19 @@ func cronBinds(app core.App, loader *goja.Runtime, executors *vmsPool) {
} }
func routerBinds(app core.App, loader *goja.Runtime, executors *vmsPool) { func routerBinds(app core.App, loader *goja.Runtime, executors *vmsPool) {
loader.Set("routerAdd", func(method string, path string, handler string, middlewares ...goja.Value) { loader.Set("routerAdd", func(method string, path string, handler goja.Value, middlewares ...goja.Value) {
wrappedMiddlewares, err := wrapMiddlewares(executors, middlewares...) wrappedMiddlewares, err := wrapMiddlewares(executors, middlewares...)
if err != nil { if err != nil {
panic("[routerAdd] failed to wrap middlewares: " + err.Error()) panic("[routerAdd] failed to wrap middlewares: " + err.Error())
} }
pr := goja.MustCompile("", "{("+handler+").apply(undefined, __args)}", true) wrappedHandler, err := wrapHandler(executors, handler)
if err != nil {
panic("[routerAdd] failed to wrap handler: " + err.Error())
}
app.OnBeforeServe().Add(func(e *core.ServeEvent) error { app.OnBeforeServe().Add(func(e *core.ServeEvent) error {
e.Router.Add(strings.ToUpper(method), path, func(c echo.Context) error { e.Router.Add(strings.ToUpper(method), path, wrappedHandler, wrappedMiddlewares...)
return executors.run(func(executor *goja.Runtime) error {
executor.Set("__args", []any{c})
res, err := executor.RunProgram(pr)
executor.Set("__args", goja.Undefined())
// check for returned error
if res != nil {
if v, ok := res.Export().(error); ok {
return v
}
}
return err
})
}, wrappedMiddlewares...)
return nil return nil
}) })
@ -199,6 +187,37 @@ func routerBinds(app core.App, loader *goja.Runtime, executors *vmsPool) {
}) })
} }
func wrapHandler(executors *vmsPool, handler goja.Value) (echo.HandlerFunc, error) {
switch h := handler.Export().(type) {
case echo.HandlerFunc:
// "native" handler - no need to wrap
return h, nil
case func(goja.FunctionCall) goja.Value, string:
pr := goja.MustCompile("", "{("+handler.String()+").apply(undefined, __args)}", true)
wrappedHandler := func(c echo.Context) error {
return executors.run(func(executor *goja.Runtime) error {
executor.Set("__args", []any{c})
res, err := executor.RunProgram(pr)
executor.Set("__args", goja.Undefined())
// check for returned error
if res != nil {
if v, ok := res.Export().(error); ok {
return v
}
}
return err
})
}
return wrappedHandler, nil
default:
return nil, errors.New("unsupported goja handler type")
}
}
func wrapMiddlewares(executors *vmsPool, rawMiddlewares ...goja.Value) ([]echo.MiddlewareFunc, error) { func wrapMiddlewares(executors *vmsPool, rawMiddlewares ...goja.Value) ([]echo.MiddlewareFunc, error) {
wrappedMiddlewares := make([]echo.MiddlewareFunc, len(rawMiddlewares)) wrappedMiddlewares := make([]echo.MiddlewareFunc, len(rawMiddlewares))
@ -531,6 +550,10 @@ func apisBinds(vm *goja.Runtime) {
obj := vm.NewObject() obj := vm.NewObject()
vm.Set("$apis", obj) vm.Set("$apis", obj)
obj.Set("staticDirectoryHandler", func(dir string, indexFallback bool) echo.HandlerFunc {
return apis.StaticDirectoryHandler(os.DirFS(dir), indexFallback)
})
// middlewares // middlewares
obj.Set("requireRecordAuth", apis.RequireRecordAuth) obj.Set("requireRecordAuth", apis.RequireRecordAuth)
obj.Set("requireAdminAuth", apis.RequireAdminAuth) obj.Set("requireAdminAuth", apis.RequireAdminAuth)

View File

@ -734,7 +734,7 @@ func TestApisBindsCount(t *testing.T) {
apisBinds(vm) apisBinds(vm)
testBindsCount(vm, "this", 6, t) testBindsCount(vm, "this", 6, t)
testBindsCount(vm, "$apis", 10, t) testBindsCount(vm, "$apis", 11, t)
} }
func TestApisBindsApiError(t *testing.T) { func TestApisBindsApiError(t *testing.T) {

File diff suppressed because it is too large Load Diff

View File

@ -814,6 +814,14 @@ declare class UnauthorizedError implements apis.ApiError {
* @group PocketBase * @group PocketBase
*/ */
declare namespace $apis { declare namespace $apis {
/**
* Route handler to serve static directory content (html, js, css, etc.).
*
* If a file resource is missing and indexFallback is set, the request
* will be forwarded to the base index.html (useful for SPA).
*/
export function staticDirectoryHandler(dir: string, indexFallback: boolean): echo.HandlerFunc
let requireRecordAuth: apis.requireRecordAuth let requireRecordAuth: apis.requireRecordAuth
let requireAdminAuth: apis.requireAdminAuth let requireAdminAuth: apis.requireAdminAuth
let requireAdminAuthOnlyIfAny: apis.requireAdminAuthOnlyIfAny let requireAdminAuthOnlyIfAny: apis.requireAdminAuthOnlyIfAny