added support for optional Model and Record event hook tags
This commit is contained in:
parent
32af49dbec
commit
b8d7609e9e
|
@ -56,6 +56,8 @@
|
||||||
store.GetAll() map[string]T
|
store.GetAll() map[string]T
|
||||||
```
|
```
|
||||||
|
|
||||||
|
- Added tagged/proxy hook for all Record and Model events (@todo document).
|
||||||
|
|
||||||
|
|
||||||
## v0.11.4
|
## v0.11.4
|
||||||
|
|
||||||
|
|
|
@ -39,11 +39,10 @@ func (api *adminApi) authResponse(c echo.Context, admin *models.Admin) error {
|
||||||
return NewBadRequestError("Failed to create auth token.", tokenErr)
|
return NewBadRequestError("Failed to create auth token.", tokenErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
event := &core.AdminAuthEvent{
|
event := new(core.AdminAuthEvent)
|
||||||
HttpContext: c,
|
event.HttpContext = c
|
||||||
Admin: admin,
|
event.Admin = admin
|
||||||
Token: token,
|
event.Token = token
|
||||||
}
|
|
||||||
|
|
||||||
return api.app.OnAdminAuthRequest().Trigger(event, func(e *core.AdminAuthEvent) error {
|
return api.app.OnAdminAuthRequest().Trigger(event, func(e *core.AdminAuthEvent) error {
|
||||||
return e.HttpContext.JSON(200, map[string]any{
|
return e.HttpContext.JSON(200, map[string]any{
|
||||||
|
@ -59,10 +58,9 @@ func (api *adminApi) authRefresh(c echo.Context) error {
|
||||||
return NewNotFoundError("Missing auth admin context.", nil)
|
return NewNotFoundError("Missing auth admin context.", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
event := &core.AdminAuthRefreshEvent{
|
event := new(core.AdminAuthRefreshEvent)
|
||||||
HttpContext: c,
|
event.HttpContext = c
|
||||||
Admin: admin,
|
event.Admin = admin
|
||||||
}
|
|
||||||
|
|
||||||
handlerErr := api.app.OnAdminBeforeAuthRefreshRequest().Trigger(event, func(e *core.AdminAuthRefreshEvent) error {
|
handlerErr := api.app.OnAdminBeforeAuthRefreshRequest().Trigger(event, func(e *core.AdminAuthRefreshEvent) error {
|
||||||
return api.authResponse(e.HttpContext, e.Admin)
|
return api.authResponse(e.HttpContext, e.Admin)
|
||||||
|
@ -83,11 +81,10 @@ func (api *adminApi) authWithPassword(c echo.Context) error {
|
||||||
return NewBadRequestError("An error occurred while loading the submitted data.", err)
|
return NewBadRequestError("An error occurred while loading the submitted data.", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
event := &core.AdminAuthWithPasswordEvent{
|
event := new(core.AdminAuthWithPasswordEvent)
|
||||||
HttpContext: c,
|
event.HttpContext = c
|
||||||
Password: form.Password,
|
event.Password = form.Password
|
||||||
Identity: form.Identity,
|
event.Identity = form.Identity
|
||||||
}
|
|
||||||
|
|
||||||
_, submitErr := form.Submit(func(next forms.InterceptorNextFunc[*models.Admin]) forms.InterceptorNextFunc[*models.Admin] {
|
_, submitErr := form.Submit(func(next forms.InterceptorNextFunc[*models.Admin]) forms.InterceptorNextFunc[*models.Admin] {
|
||||||
return func(admin *models.Admin) error {
|
return func(admin *models.Admin) error {
|
||||||
|
@ -122,9 +119,8 @@ func (api *adminApi) requestPasswordReset(c echo.Context) error {
|
||||||
return NewBadRequestError("An error occurred while validating the form.", err)
|
return NewBadRequestError("An error occurred while validating the form.", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
event := &core.AdminRequestPasswordResetEvent{
|
event := new(core.AdminRequestPasswordResetEvent)
|
||||||
HttpContext: c,
|
event.HttpContext = c
|
||||||
}
|
|
||||||
|
|
||||||
submitErr := form.Submit(func(next forms.InterceptorNextFunc[*models.Admin]) forms.InterceptorNextFunc[*models.Admin] {
|
submitErr := form.Submit(func(next forms.InterceptorNextFunc[*models.Admin]) forms.InterceptorNextFunc[*models.Admin] {
|
||||||
return func(Admin *models.Admin) error {
|
return func(Admin *models.Admin) error {
|
||||||
|
@ -165,9 +161,8 @@ func (api *adminApi) confirmPasswordReset(c echo.Context) error {
|
||||||
return NewBadRequestError("An error occurred while loading the submitted data.", readErr)
|
return NewBadRequestError("An error occurred while loading the submitted data.", readErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
event := &core.AdminConfirmPasswordResetEvent{
|
event := new(core.AdminConfirmPasswordResetEvent)
|
||||||
HttpContext: c,
|
event.HttpContext = c
|
||||||
}
|
|
||||||
|
|
||||||
_, submitErr := form.Submit(func(next forms.InterceptorNextFunc[*models.Admin]) forms.InterceptorNextFunc[*models.Admin] {
|
_, submitErr := form.Submit(func(next forms.InterceptorNextFunc[*models.Admin]) forms.InterceptorNextFunc[*models.Admin] {
|
||||||
return func(admin *models.Admin) error {
|
return func(admin *models.Admin) error {
|
||||||
|
@ -207,11 +202,10 @@ func (api *adminApi) list(c echo.Context) error {
|
||||||
return NewBadRequestError("", err)
|
return NewBadRequestError("", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
event := &core.AdminsListEvent{
|
event := new(core.AdminsListEvent)
|
||||||
HttpContext: c,
|
event.HttpContext = c
|
||||||
Admins: admins,
|
event.Admins = admins
|
||||||
Result: result,
|
event.Result = result
|
||||||
}
|
|
||||||
|
|
||||||
return api.app.OnAdminsListRequest().Trigger(event, func(e *core.AdminsListEvent) error {
|
return api.app.OnAdminsListRequest().Trigger(event, func(e *core.AdminsListEvent) error {
|
||||||
return e.HttpContext.JSON(http.StatusOK, e.Result)
|
return e.HttpContext.JSON(http.StatusOK, e.Result)
|
||||||
|
@ -229,10 +223,9 @@ func (api *adminApi) view(c echo.Context) error {
|
||||||
return NewNotFoundError("", err)
|
return NewNotFoundError("", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
event := &core.AdminViewEvent{
|
event := new(core.AdminViewEvent)
|
||||||
HttpContext: c,
|
event.HttpContext = c
|
||||||
Admin: admin,
|
event.Admin = admin
|
||||||
}
|
|
||||||
|
|
||||||
return api.app.OnAdminViewRequest().Trigger(event, func(e *core.AdminViewEvent) error {
|
return api.app.OnAdminViewRequest().Trigger(event, func(e *core.AdminViewEvent) error {
|
||||||
return e.HttpContext.JSON(http.StatusOK, e.Admin)
|
return e.HttpContext.JSON(http.StatusOK, e.Admin)
|
||||||
|
@ -249,10 +242,9 @@ func (api *adminApi) create(c echo.Context) error {
|
||||||
return NewBadRequestError("Failed to load the submitted data due to invalid formatting.", err)
|
return NewBadRequestError("Failed to load the submitted data due to invalid formatting.", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
event := &core.AdminCreateEvent{
|
event := new(core.AdminCreateEvent)
|
||||||
HttpContext: c,
|
event.HttpContext = c
|
||||||
Admin: admin,
|
event.Admin = admin
|
||||||
}
|
|
||||||
|
|
||||||
// create the admin
|
// create the admin
|
||||||
submitErr := form.Submit(func(next forms.InterceptorNextFunc[*models.Admin]) forms.InterceptorNextFunc[*models.Admin] {
|
submitErr := form.Submit(func(next forms.InterceptorNextFunc[*models.Admin]) forms.InterceptorNextFunc[*models.Admin] {
|
||||||
|
@ -296,10 +288,9 @@ func (api *adminApi) update(c echo.Context) error {
|
||||||
return NewBadRequestError("Failed to load the submitted data due to invalid formatting.", err)
|
return NewBadRequestError("Failed to load the submitted data due to invalid formatting.", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
event := &core.AdminUpdateEvent{
|
event := new(core.AdminUpdateEvent)
|
||||||
HttpContext: c,
|
event.HttpContext = c
|
||||||
Admin: admin,
|
event.Admin = admin
|
||||||
}
|
|
||||||
|
|
||||||
// update the admin
|
// update the admin
|
||||||
submitErr := form.Submit(func(next forms.InterceptorNextFunc[*models.Admin]) forms.InterceptorNextFunc[*models.Admin] {
|
submitErr := form.Submit(func(next forms.InterceptorNextFunc[*models.Admin]) forms.InterceptorNextFunc[*models.Admin] {
|
||||||
|
@ -336,10 +327,9 @@ func (api *adminApi) delete(c echo.Context) error {
|
||||||
return NewNotFoundError("", err)
|
return NewNotFoundError("", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
event := &core.AdminDeleteEvent{
|
event := new(core.AdminDeleteEvent)
|
||||||
HttpContext: c,
|
event.HttpContext = c
|
||||||
Admin: admin,
|
event.Admin = admin
|
||||||
}
|
|
||||||
|
|
||||||
handlerErr := api.app.OnAdminBeforeDeleteRequest().Trigger(event, func(e *core.AdminDeleteEvent) error {
|
handlerErr := api.app.OnAdminBeforeDeleteRequest().Trigger(event, func(e *core.AdminDeleteEvent) error {
|
||||||
if err := api.app.Dao().DeleteAdmin(e.Admin); err != nil {
|
if err := api.app.Dao().DeleteAdmin(e.Admin); err != nil {
|
||||||
|
|
|
@ -71,10 +71,9 @@ func InitApi(app core.App) (*echo.Echo, error) {
|
||||||
apiErr = NewBadRequestError("", err)
|
apiErr = NewBadRequestError("", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
event := &core.ApiErrorEvent{
|
event := new(core.ApiErrorEvent)
|
||||||
HttpContext: c,
|
event.HttpContext = c
|
||||||
Error: apiErr,
|
event.Error = apiErr
|
||||||
}
|
|
||||||
|
|
||||||
// send error response
|
// send error response
|
||||||
hookErr := app.OnBeforeApiError().Trigger(event, func(e *core.ApiErrorEvent) error {
|
hookErr := app.OnBeforeApiError().Trigger(event, func(e *core.ApiErrorEvent) error {
|
||||||
|
|
|
@ -43,11 +43,10 @@ func (api *collectionApi) list(c echo.Context) error {
|
||||||
return NewBadRequestError("", err)
|
return NewBadRequestError("", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
event := &core.CollectionsListEvent{
|
event := new(core.CollectionsListEvent)
|
||||||
HttpContext: c,
|
event.HttpContext = c
|
||||||
Collections: collections,
|
event.Collections = collections
|
||||||
Result: result,
|
event.Result = result
|
||||||
}
|
|
||||||
|
|
||||||
return api.app.OnCollectionsListRequest().Trigger(event, func(e *core.CollectionsListEvent) error {
|
return api.app.OnCollectionsListRequest().Trigger(event, func(e *core.CollectionsListEvent) error {
|
||||||
return e.HttpContext.JSON(http.StatusOK, e.Result)
|
return e.HttpContext.JSON(http.StatusOK, e.Result)
|
||||||
|
@ -60,10 +59,9 @@ func (api *collectionApi) view(c echo.Context) error {
|
||||||
return NewNotFoundError("", err)
|
return NewNotFoundError("", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
event := &core.CollectionViewEvent{
|
event := new(core.CollectionViewEvent)
|
||||||
HttpContext: c,
|
event.HttpContext = c
|
||||||
Collection: collection,
|
event.Collection = collection
|
||||||
}
|
|
||||||
|
|
||||||
return api.app.OnCollectionViewRequest().Trigger(event, func(e *core.CollectionViewEvent) error {
|
return api.app.OnCollectionViewRequest().Trigger(event, func(e *core.CollectionViewEvent) error {
|
||||||
return e.HttpContext.JSON(http.StatusOK, e.Collection)
|
return e.HttpContext.JSON(http.StatusOK, e.Collection)
|
||||||
|
@ -80,10 +78,9 @@ func (api *collectionApi) create(c echo.Context) error {
|
||||||
return NewBadRequestError("Failed to load the submitted data due to invalid formatting.", err)
|
return NewBadRequestError("Failed to load the submitted data due to invalid formatting.", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
event := &core.CollectionCreateEvent{
|
event := new(core.CollectionCreateEvent)
|
||||||
HttpContext: c,
|
event.HttpContext = c
|
||||||
Collection: collection,
|
event.Collection = collection
|
||||||
}
|
|
||||||
|
|
||||||
// create the collection
|
// create the collection
|
||||||
submitErr := form.Submit(func(next forms.InterceptorNextFunc[*models.Collection]) forms.InterceptorNextFunc[*models.Collection] {
|
submitErr := form.Submit(func(next forms.InterceptorNextFunc[*models.Collection]) forms.InterceptorNextFunc[*models.Collection] {
|
||||||
|
@ -122,10 +119,9 @@ func (api *collectionApi) update(c echo.Context) error {
|
||||||
return NewBadRequestError("Failed to load the submitted data due to invalid formatting.", err)
|
return NewBadRequestError("Failed to load the submitted data due to invalid formatting.", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
event := &core.CollectionUpdateEvent{
|
event := new(core.CollectionUpdateEvent)
|
||||||
HttpContext: c,
|
event.HttpContext = c
|
||||||
Collection: collection,
|
event.Collection = collection
|
||||||
}
|
|
||||||
|
|
||||||
// update the collection
|
// update the collection
|
||||||
submitErr := form.Submit(func(next forms.InterceptorNextFunc[*models.Collection]) forms.InterceptorNextFunc[*models.Collection] {
|
submitErr := form.Submit(func(next forms.InterceptorNextFunc[*models.Collection]) forms.InterceptorNextFunc[*models.Collection] {
|
||||||
|
@ -157,10 +153,9 @@ func (api *collectionApi) delete(c echo.Context) error {
|
||||||
return NewNotFoundError("", err)
|
return NewNotFoundError("", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
event := &core.CollectionDeleteEvent{
|
event := new(core.CollectionDeleteEvent)
|
||||||
HttpContext: c,
|
event.HttpContext = c
|
||||||
Collection: collection,
|
event.Collection = collection
|
||||||
}
|
|
||||||
|
|
||||||
handlerErr := api.app.OnCollectionBeforeDeleteRequest().Trigger(event, func(e *core.CollectionDeleteEvent) error {
|
handlerErr := api.app.OnCollectionBeforeDeleteRequest().Trigger(event, func(e *core.CollectionDeleteEvent) error {
|
||||||
if err := api.app.Dao().DeleteCollection(e.Collection); err != nil {
|
if err := api.app.Dao().DeleteCollection(e.Collection); err != nil {
|
||||||
|
@ -187,10 +182,9 @@ func (api *collectionApi) bulkImport(c echo.Context) error {
|
||||||
return NewBadRequestError("Failed to load the submitted data due to invalid formatting.", err)
|
return NewBadRequestError("Failed to load the submitted data due to invalid formatting.", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
event := &core.CollectionsImportEvent{
|
event := new(core.CollectionsImportEvent)
|
||||||
HttpContext: c,
|
event.HttpContext = c
|
||||||
Collections: form.Collections,
|
event.Collections = form.Collections
|
||||||
}
|
|
||||||
|
|
||||||
// import collections
|
// import collections
|
||||||
submitErr := form.Submit(func(next forms.InterceptorNextFunc[[]*models.Collection]) forms.InterceptorNextFunc[[]*models.Collection] {
|
submitErr := form.Submit(func(next forms.InterceptorNextFunc[[]*models.Collection]) forms.InterceptorNextFunc[[]*models.Collection] {
|
||||||
|
|
15
apis/file.go
15
apis/file.go
|
@ -84,14 +84,13 @@ func (api *fileApi) download(c echo.Context) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
event := &core.FileDownloadEvent{
|
event := new(core.FileDownloadEvent)
|
||||||
HttpContext: c,
|
event.HttpContext = c
|
||||||
Record: record,
|
event.Collection = collection
|
||||||
Collection: collection,
|
event.Record = record
|
||||||
FileField: fileField,
|
event.FileField = fileField
|
||||||
ServedPath: servedPath,
|
event.ServedPath = servedPath
|
||||||
ServedName: servedName,
|
event.ServedName = servedName
|
||||||
}
|
|
||||||
|
|
||||||
return api.app.OnFileDownloadRequest().Trigger(event, func(e *core.FileDownloadEvent) error {
|
return api.app.OnFileDownloadRequest().Trigger(event, func(e *core.FileDownloadEvent) error {
|
||||||
res := e.HttpContext.Response()
|
res := e.HttpContext.Response()
|
||||||
|
|
|
@ -55,10 +55,10 @@ func (api *recordAuthApi) authRefresh(c echo.Context) error {
|
||||||
return NewNotFoundError("Missing auth record context.", nil)
|
return NewNotFoundError("Missing auth record context.", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
event := &core.RecordAuthRefreshEvent{
|
event := new(core.RecordAuthRefreshEvent)
|
||||||
HttpContext: c,
|
event.HttpContext = c
|
||||||
Record: record,
|
event.Collection = record.Collection()
|
||||||
}
|
event.Record = record
|
||||||
|
|
||||||
handlerErr := api.app.OnRecordBeforeAuthRefreshRequest().Trigger(event, func(e *core.RecordAuthRefreshEvent) error {
|
handlerErr := api.app.OnRecordBeforeAuthRefreshRequest().Trigger(event, func(e *core.RecordAuthRefreshEvent) error {
|
||||||
return RecordAuthResponse(api.app, e.HttpContext, e.Record, nil)
|
return RecordAuthResponse(api.app, e.HttpContext, e.Record, nil)
|
||||||
|
@ -204,9 +204,9 @@ func (api *recordAuthApi) authWithOAuth2(c echo.Context) error {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
event := &core.RecordAuthWithOAuth2Event{
|
event := new(core.RecordAuthWithOAuth2Event)
|
||||||
HttpContext: c,
|
event.HttpContext = c
|
||||||
}
|
event.Collection = collection
|
||||||
|
|
||||||
_, _, submitErr := form.Submit(func(next forms.InterceptorNextFunc[*forms.RecordOAuth2LoginData]) forms.InterceptorNextFunc[*forms.RecordOAuth2LoginData] {
|
_, _, submitErr := form.Submit(func(next forms.InterceptorNextFunc[*forms.RecordOAuth2LoginData]) forms.InterceptorNextFunc[*forms.RecordOAuth2LoginData] {
|
||||||
return func(data *forms.RecordOAuth2LoginData) error {
|
return func(data *forms.RecordOAuth2LoginData) error {
|
||||||
|
@ -249,11 +249,11 @@ func (api *recordAuthApi) authWithPassword(c echo.Context) error {
|
||||||
return NewBadRequestError("An error occurred while loading the submitted data.", readErr)
|
return NewBadRequestError("An error occurred while loading the submitted data.", readErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
event := &core.RecordAuthWithPasswordEvent{
|
event := new(core.RecordAuthWithPasswordEvent)
|
||||||
HttpContext: c,
|
event.HttpContext = c
|
||||||
Password: form.Password,
|
event.Collection = collection
|
||||||
Identity: form.Identity,
|
event.Password = form.Password
|
||||||
}
|
event.Identity = form.Identity
|
||||||
|
|
||||||
_, submitErr := form.Submit(func(next forms.InterceptorNextFunc[*models.Record]) forms.InterceptorNextFunc[*models.Record] {
|
_, submitErr := form.Submit(func(next forms.InterceptorNextFunc[*models.Record]) forms.InterceptorNextFunc[*models.Record] {
|
||||||
return func(record *models.Record) error {
|
return func(record *models.Record) error {
|
||||||
|
@ -298,9 +298,9 @@ func (api *recordAuthApi) requestPasswordReset(c echo.Context) error {
|
||||||
return NewBadRequestError("An error occurred while validating the form.", err)
|
return NewBadRequestError("An error occurred while validating the form.", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
event := &core.RecordRequestPasswordResetEvent{
|
event := new(core.RecordRequestPasswordResetEvent)
|
||||||
HttpContext: c,
|
event.HttpContext = c
|
||||||
}
|
event.Collection = collection
|
||||||
|
|
||||||
submitErr := form.Submit(func(next forms.InterceptorNextFunc[*models.Record]) forms.InterceptorNextFunc[*models.Record] {
|
submitErr := form.Submit(func(next forms.InterceptorNextFunc[*models.Record]) forms.InterceptorNextFunc[*models.Record] {
|
||||||
return func(record *models.Record) error {
|
return func(record *models.Record) error {
|
||||||
|
@ -346,9 +346,9 @@ func (api *recordAuthApi) confirmPasswordReset(c echo.Context) error {
|
||||||
return NewBadRequestError("An error occurred while loading the submitted data.", readErr)
|
return NewBadRequestError("An error occurred while loading the submitted data.", readErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
event := &core.RecordConfirmPasswordResetEvent{
|
event := new(core.RecordConfirmPasswordResetEvent)
|
||||||
HttpContext: c,
|
event.HttpContext = c
|
||||||
}
|
event.Collection = collection
|
||||||
|
|
||||||
_, submitErr := form.Submit(func(next forms.InterceptorNextFunc[*models.Record]) forms.InterceptorNextFunc[*models.Record] {
|
_, submitErr := form.Submit(func(next forms.InterceptorNextFunc[*models.Record]) forms.InterceptorNextFunc[*models.Record] {
|
||||||
return func(record *models.Record) error {
|
return func(record *models.Record) error {
|
||||||
|
@ -388,9 +388,9 @@ func (api *recordAuthApi) requestVerification(c echo.Context) error {
|
||||||
return NewBadRequestError("An error occurred while validating the form.", err)
|
return NewBadRequestError("An error occurred while validating the form.", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
event := &core.RecordRequestVerificationEvent{
|
event := new(core.RecordRequestVerificationEvent)
|
||||||
HttpContext: c,
|
event.HttpContext = c
|
||||||
}
|
event.Collection = collection
|
||||||
|
|
||||||
submitErr := form.Submit(func(next forms.InterceptorNextFunc[*models.Record]) forms.InterceptorNextFunc[*models.Record] {
|
submitErr := form.Submit(func(next forms.InterceptorNextFunc[*models.Record]) forms.InterceptorNextFunc[*models.Record] {
|
||||||
return func(record *models.Record) error {
|
return func(record *models.Record) error {
|
||||||
|
@ -436,9 +436,9 @@ func (api *recordAuthApi) confirmVerification(c echo.Context) error {
|
||||||
return NewBadRequestError("An error occurred while loading the submitted data.", readErr)
|
return NewBadRequestError("An error occurred while loading the submitted data.", readErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
event := &core.RecordConfirmVerificationEvent{
|
event := new(core.RecordConfirmVerificationEvent)
|
||||||
HttpContext: c,
|
event.HttpContext = c
|
||||||
}
|
event.Collection = collection
|
||||||
|
|
||||||
_, submitErr := form.Submit(func(next forms.InterceptorNextFunc[*models.Record]) forms.InterceptorNextFunc[*models.Record] {
|
_, submitErr := form.Submit(func(next forms.InterceptorNextFunc[*models.Record]) forms.InterceptorNextFunc[*models.Record] {
|
||||||
return func(record *models.Record) error {
|
return func(record *models.Record) error {
|
||||||
|
@ -464,6 +464,11 @@ func (api *recordAuthApi) confirmVerification(c echo.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *recordAuthApi) requestEmailChange(c echo.Context) error {
|
func (api *recordAuthApi) requestEmailChange(c echo.Context) error {
|
||||||
|
collection, _ := c.Get(ContextCollectionKey).(*models.Collection)
|
||||||
|
if collection == nil {
|
||||||
|
return NewNotFoundError("Missing collection context.", nil)
|
||||||
|
}
|
||||||
|
|
||||||
record, _ := c.Get(ContextAuthRecordKey).(*models.Record)
|
record, _ := c.Get(ContextAuthRecordKey).(*models.Record)
|
||||||
if record == nil {
|
if record == nil {
|
||||||
return NewUnauthorizedError("The request requires valid auth record.", nil)
|
return NewUnauthorizedError("The request requires valid auth record.", nil)
|
||||||
|
@ -474,10 +479,10 @@ func (api *recordAuthApi) requestEmailChange(c echo.Context) error {
|
||||||
return NewBadRequestError("An error occurred while loading the submitted data.", err)
|
return NewBadRequestError("An error occurred while loading the submitted data.", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
event := &core.RecordRequestEmailChangeEvent{
|
event := new(core.RecordRequestEmailChangeEvent)
|
||||||
HttpContext: c,
|
event.HttpContext = c
|
||||||
Record: record,
|
event.Collection = collection
|
||||||
}
|
event.Record = record
|
||||||
|
|
||||||
submitErr := form.Submit(func(next forms.InterceptorNextFunc[*models.Record]) forms.InterceptorNextFunc[*models.Record] {
|
submitErr := form.Submit(func(next forms.InterceptorNextFunc[*models.Record]) forms.InterceptorNextFunc[*models.Record] {
|
||||||
return func(record *models.Record) error {
|
return func(record *models.Record) error {
|
||||||
|
@ -509,9 +514,9 @@ func (api *recordAuthApi) confirmEmailChange(c echo.Context) error {
|
||||||
return NewBadRequestError("An error occurred while loading the submitted data.", readErr)
|
return NewBadRequestError("An error occurred while loading the submitted data.", readErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
event := &core.RecordConfirmEmailChangeEvent{
|
event := new(core.RecordConfirmEmailChangeEvent)
|
||||||
HttpContext: c,
|
event.HttpContext = c
|
||||||
}
|
event.Collection = collection
|
||||||
|
|
||||||
_, submitErr := form.Submit(func(next forms.InterceptorNextFunc[*models.Record]) forms.InterceptorNextFunc[*models.Record] {
|
_, submitErr := form.Submit(func(next forms.InterceptorNextFunc[*models.Record]) forms.InterceptorNextFunc[*models.Record] {
|
||||||
return func(record *models.Record) error {
|
return func(record *models.Record) error {
|
||||||
|
@ -557,11 +562,11 @@ func (api *recordAuthApi) listExternalAuths(c echo.Context) error {
|
||||||
return NewBadRequestError("Failed to fetch the external auths for the specified auth record.", err)
|
return NewBadRequestError("Failed to fetch the external auths for the specified auth record.", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
event := &core.RecordListExternalAuthsEvent{
|
event := new(core.RecordListExternalAuthsEvent)
|
||||||
HttpContext: c,
|
event.HttpContext = c
|
||||||
Record: record,
|
event.Collection = collection
|
||||||
ExternalAuths: externalAuths,
|
event.Record = record
|
||||||
}
|
event.ExternalAuths = externalAuths
|
||||||
|
|
||||||
return api.app.OnRecordListExternalAuthsRequest().Trigger(event, func(e *core.RecordListExternalAuthsEvent) error {
|
return api.app.OnRecordListExternalAuthsRequest().Trigger(event, func(e *core.RecordListExternalAuthsEvent) error {
|
||||||
return e.HttpContext.JSON(http.StatusOK, e.ExternalAuths)
|
return e.HttpContext.JSON(http.StatusOK, e.ExternalAuths)
|
||||||
|
@ -590,11 +595,11 @@ func (api *recordAuthApi) unlinkExternalAuth(c echo.Context) error {
|
||||||
return NewNotFoundError("Missing external auth provider relation.", err)
|
return NewNotFoundError("Missing external auth provider relation.", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
event := &core.RecordUnlinkExternalAuthEvent{
|
event := new(core.RecordUnlinkExternalAuthEvent)
|
||||||
HttpContext: c,
|
event.HttpContext = c
|
||||||
Record: record,
|
event.Collection = collection
|
||||||
ExternalAuth: externalAuth,
|
event.Record = record
|
||||||
}
|
event.ExternalAuth = externalAuth
|
||||||
|
|
||||||
handlerErr := api.app.OnRecordBeforeUnlinkExternalAuthRequest().Trigger(event, func(e *core.RecordUnlinkExternalAuthEvent) error {
|
handlerErr := api.app.OnRecordBeforeUnlinkExternalAuthRequest().Trigger(event, func(e *core.RecordUnlinkExternalAuthEvent) error {
|
||||||
if err := api.app.Dao().DeleteExternalAuth(externalAuth); err != nil {
|
if err := api.app.Dao().DeleteExternalAuth(externalAuth); err != nil {
|
||||||
|
|
|
@ -83,12 +83,11 @@ func (api *recordApi) list(c echo.Context) error {
|
||||||
|
|
||||||
result.Items = records
|
result.Items = records
|
||||||
|
|
||||||
event := &core.RecordsListEvent{
|
event := new(core.RecordsListEvent)
|
||||||
HttpContext: c,
|
event.HttpContext = c
|
||||||
Collection: collection,
|
event.Collection = collection
|
||||||
Records: records,
|
event.Records = records
|
||||||
Result: result,
|
event.Result = result
|
||||||
}
|
|
||||||
|
|
||||||
return api.app.OnRecordsListRequest().Trigger(event, func(e *core.RecordsListEvent) error {
|
return api.app.OnRecordsListRequest().Trigger(event, func(e *core.RecordsListEvent) error {
|
||||||
if err := EnrichRecords(e.HttpContext, api.app.Dao(), e.Records); err != nil && api.app.IsDebug() {
|
if err := EnrichRecords(e.HttpContext, api.app.Dao(), e.Records); err != nil && api.app.IsDebug() {
|
||||||
|
@ -135,10 +134,10 @@ func (api *recordApi) view(c echo.Context) error {
|
||||||
return NewNotFoundError("", fetchErr)
|
return NewNotFoundError("", fetchErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
event := &core.RecordViewEvent{
|
event := new(core.RecordViewEvent)
|
||||||
HttpContext: c,
|
event.HttpContext = c
|
||||||
Record: record,
|
event.Collection = collection
|
||||||
}
|
event.Record = record
|
||||||
|
|
||||||
return api.app.OnRecordViewRequest().Trigger(event, func(e *core.RecordViewEvent) error {
|
return api.app.OnRecordViewRequest().Trigger(event, func(e *core.RecordViewEvent) error {
|
||||||
if err := EnrichRecord(e.HttpContext, api.app.Dao(), e.Record); err != nil && api.app.IsDebug() {
|
if err := EnrichRecord(e.HttpContext, api.app.Dao(), e.Record); err != nil && api.app.IsDebug() {
|
||||||
|
@ -218,10 +217,10 @@ func (api *recordApi) create(c echo.Context) error {
|
||||||
return NewBadRequestError("Failed to load the submitted data due to invalid formatting.", err)
|
return NewBadRequestError("Failed to load the submitted data due to invalid formatting.", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
event := &core.RecordCreateEvent{
|
event := new(core.RecordCreateEvent)
|
||||||
HttpContext: c,
|
event.HttpContext = c
|
||||||
Record: record,
|
event.Collection = collection
|
||||||
}
|
event.Record = record
|
||||||
|
|
||||||
// create the record
|
// create the record
|
||||||
submitErr := form.Submit(func(next forms.InterceptorNextFunc[*models.Record]) forms.InterceptorNextFunc[*models.Record] {
|
submitErr := form.Submit(func(next forms.InterceptorNextFunc[*models.Record]) forms.InterceptorNextFunc[*models.Record] {
|
||||||
|
@ -306,10 +305,10 @@ func (api *recordApi) update(c echo.Context) error {
|
||||||
return NewBadRequestError("Failed to load the submitted data due to invalid formatting.", err)
|
return NewBadRequestError("Failed to load the submitted data due to invalid formatting.", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
event := &core.RecordUpdateEvent{
|
event := new(core.RecordUpdateEvent)
|
||||||
HttpContext: c,
|
event.HttpContext = c
|
||||||
Record: record,
|
event.Collection = collection
|
||||||
}
|
event.Record = record
|
||||||
|
|
||||||
// update the record
|
// update the record
|
||||||
submitErr := form.Submit(func(next forms.InterceptorNextFunc[*models.Record]) forms.InterceptorNextFunc[*models.Record] {
|
submitErr := form.Submit(func(next forms.InterceptorNextFunc[*models.Record]) forms.InterceptorNextFunc[*models.Record] {
|
||||||
|
@ -375,10 +374,10 @@ func (api *recordApi) delete(c echo.Context) error {
|
||||||
return NewNotFoundError("", fetchErr)
|
return NewNotFoundError("", fetchErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
event := &core.RecordDeleteEvent{
|
event := new(core.RecordDeleteEvent)
|
||||||
HttpContext: c,
|
event.HttpContext = c
|
||||||
Record: record,
|
event.Collection = collection
|
||||||
}
|
event.Record = record
|
||||||
|
|
||||||
handlerErr := api.app.OnRecordBeforeDeleteRequest().Trigger(event, func(e *core.RecordDeleteEvent) error {
|
handlerErr := api.app.OnRecordBeforeDeleteRequest().Trigger(event, func(e *core.RecordDeleteEvent) error {
|
||||||
// delete the record
|
// delete the record
|
||||||
|
|
|
@ -51,12 +51,12 @@ func RecordAuthResponse(app core.App, c echo.Context, authRecord *models.Record,
|
||||||
return NewBadRequestError("Failed to create auth token.", tokenErr)
|
return NewBadRequestError("Failed to create auth token.", tokenErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
event := &core.RecordAuthEvent{
|
event := new(core.RecordAuthEvent)
|
||||||
HttpContext: c,
|
event.HttpContext = c
|
||||||
Record: authRecord,
|
event.Collection = authRecord.Collection()
|
||||||
Token: token,
|
event.Record = authRecord
|
||||||
Meta: meta,
|
event.Token = token
|
||||||
}
|
event.Meta = meta
|
||||||
|
|
||||||
return app.OnRecordAuthRequest().Trigger(event, func(e *core.RecordAuthEvent) error {
|
return app.OnRecordAuthRequest().Trigger(event, func(e *core.RecordAuthEvent) error {
|
||||||
// allow always returning the email address of the authenticated account
|
// allow always returning the email address of the authenticated account
|
||||||
|
@ -93,17 +93,17 @@ func RecordAuthResponse(app core.App, c echo.Context, authRecord *models.Record,
|
||||||
}
|
}
|
||||||
|
|
||||||
// EnrichRecord parses the request context and enrich the provided record:
|
// EnrichRecord parses the request context and enrich the provided record:
|
||||||
// - expands relations (if defaultExpands and/or ?expand query param is set)
|
// - expands relations (if defaultExpands and/or ?expand query param is set)
|
||||||
// - ensures that the emails of the auth record and its expanded auth relations
|
// - ensures that the emails of the auth record and its expanded auth relations
|
||||||
// are visibe only for the current logged admin, record owner or record with manage access
|
// are visibe only for the current logged admin, record owner or record with manage access
|
||||||
func EnrichRecord(c echo.Context, dao *daos.Dao, record *models.Record, defaultExpands ...string) error {
|
func EnrichRecord(c echo.Context, dao *daos.Dao, record *models.Record, defaultExpands ...string) error {
|
||||||
return EnrichRecords(c, dao, []*models.Record{record}, defaultExpands...)
|
return EnrichRecords(c, dao, []*models.Record{record}, defaultExpands...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// EnrichRecords parses the request context and enriches the provided records:
|
// EnrichRecords parses the request context and enriches the provided records:
|
||||||
// - expands relations (if defaultExpands and/or ?expand query param is set)
|
// - expands relations (if defaultExpands and/or ?expand query param is set)
|
||||||
// - ensures that the emails of the auth records and their expanded auth relations
|
// - ensures that the emails of the auth records and their expanded auth relations
|
||||||
// are visibe only for the current logged admin, record owner or record with manage access
|
// are visibe only for the current logged admin, record owner or record with manage access
|
||||||
func EnrichRecords(c echo.Context, dao *daos.Dao, records []*models.Record, defaultExpands ...string) error {
|
func EnrichRecords(c echo.Context, dao *daos.Dao, records []*models.Record, defaultExpands ...string) error {
|
||||||
requestData := RequestData(c)
|
requestData := RequestData(c)
|
||||||
|
|
||||||
|
|
|
@ -34,10 +34,9 @@ func (api *settingsApi) list(c echo.Context) error {
|
||||||
return NewBadRequestError("", err)
|
return NewBadRequestError("", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
event := &core.SettingsListEvent{
|
event := new(core.SettingsListEvent)
|
||||||
HttpContext: c,
|
event.HttpContext = c
|
||||||
RedactedSettings: settings,
|
event.RedactedSettings = settings
|
||||||
}
|
|
||||||
|
|
||||||
return api.app.OnSettingsListRequest().Trigger(event, func(e *core.SettingsListEvent) error {
|
return api.app.OnSettingsListRequest().Trigger(event, func(e *core.SettingsListEvent) error {
|
||||||
return e.HttpContext.JSON(http.StatusOK, e.RedactedSettings)
|
return e.HttpContext.JSON(http.StatusOK, e.RedactedSettings)
|
||||||
|
@ -52,10 +51,9 @@ func (api *settingsApi) set(c echo.Context) error {
|
||||||
return NewBadRequestError("An error occurred while loading the submitted data.", err)
|
return NewBadRequestError("An error occurred while loading the submitted data.", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
event := &core.SettingsUpdateEvent{
|
event := new(core.SettingsUpdateEvent)
|
||||||
HttpContext: c,
|
event.HttpContext = c
|
||||||
OldSettings: api.app.Settings(),
|
event.OldSettings = api.app.Settings()
|
||||||
}
|
|
||||||
|
|
||||||
// update the settings
|
// update the settings
|
||||||
submitErr := form.Submit(func(next forms.InterceptorNextFunc[*settings.Settings]) forms.InterceptorNextFunc[*settings.Settings] {
|
submitErr := form.Submit(func(next forms.InterceptorNextFunc[*settings.Settings]) forms.InterceptorNextFunc[*settings.Settings] {
|
||||||
|
|
218
core/app.go
218
core/app.go
|
@ -124,27 +124,51 @@ type App interface {
|
||||||
|
|
||||||
// OnModelBeforeCreate hook is triggered before inserting a new
|
// OnModelBeforeCreate hook is triggered before inserting a new
|
||||||
// entry in the DB, allowing you to modify or validate the stored data.
|
// entry in the DB, allowing you to modify or validate the stored data.
|
||||||
OnModelBeforeCreate() *hook.Hook[*ModelEvent]
|
//
|
||||||
|
// You can optionally specify a list of "tags"
|
||||||
|
// (table names and/or the Collection id for Record models)
|
||||||
|
// to filter any the newly attached event data handler.
|
||||||
|
OnModelBeforeCreate(tags ...string) *hook.TaggedHook[*ModelEvent]
|
||||||
|
|
||||||
// OnModelAfterCreate hook is triggered after successfully
|
// OnModelAfterCreate hook is triggered after successfully
|
||||||
// inserting a new entry in the DB.
|
// inserting a new entry in the DB.
|
||||||
OnModelAfterCreate() *hook.Hook[*ModelEvent]
|
//
|
||||||
|
// You can optionally specify a list of "tags"
|
||||||
|
// (table names and/or the Collection id for Record models)
|
||||||
|
// to filter any the newly attached event data handler.
|
||||||
|
OnModelAfterCreate(tags ...string) *hook.TaggedHook[*ModelEvent]
|
||||||
|
|
||||||
// OnModelBeforeUpdate hook is triggered before updating existing
|
// OnModelBeforeUpdate hook is triggered before updating existing
|
||||||
// entry in the DB, allowing you to modify or validate the stored data.
|
// entry in the DB, allowing you to modify or validate the stored data.
|
||||||
OnModelBeforeUpdate() *hook.Hook[*ModelEvent]
|
//
|
||||||
|
// You can optionally specify a list of "tags"
|
||||||
|
// (table names and/or the Collection id for Record models)
|
||||||
|
// to filter any the newly attached event data handler.
|
||||||
|
OnModelBeforeUpdate(tags ...string) *hook.TaggedHook[*ModelEvent]
|
||||||
|
|
||||||
// OnModelAfterUpdate hook is triggered after successfully updating
|
// OnModelAfterUpdate hook is triggered after successfully updating
|
||||||
// existing entry in the DB.
|
// existing entry in the DB.
|
||||||
OnModelAfterUpdate() *hook.Hook[*ModelEvent]
|
//
|
||||||
|
// You can optionally specify a list of "tags"
|
||||||
|
// (table names and/or the Collection id for Record models)
|
||||||
|
// to filter any the newly attached event data handler.
|
||||||
|
OnModelAfterUpdate(tags ...string) *hook.TaggedHook[*ModelEvent]
|
||||||
|
|
||||||
// OnModelBeforeDelete hook is triggered before deleting an
|
// OnModelBeforeDelete hook is triggered before deleting an
|
||||||
// existing entry from the DB.
|
// existing entry from the DB.
|
||||||
OnModelBeforeDelete() *hook.Hook[*ModelEvent]
|
//
|
||||||
|
// You can optionally specify a list of "tags"
|
||||||
|
// (table names and/or the Collection id for Record models)
|
||||||
|
// to filter any the newly attached event data handler.
|
||||||
|
OnModelBeforeDelete(tags ...string) *hook.TaggedHook[*ModelEvent]
|
||||||
|
|
||||||
// OnModelAfterDelete is triggered after successfully deleting an
|
// OnModelAfterDelete is triggered after successfully deleting an
|
||||||
// existing entry from the DB.
|
// existing entry from the DB.
|
||||||
OnModelAfterDelete() *hook.Hook[*ModelEvent]
|
//
|
||||||
|
// You can optionally specify a list of "tags"
|
||||||
|
// (table names and/or the Collection id for Record models)
|
||||||
|
// to filter any the newly attached event data handler.
|
||||||
|
OnModelAfterDelete(tags ...string) *hook.TaggedHook[*ModelEvent]
|
||||||
|
|
||||||
// ---------------------------------------------------------------
|
// ---------------------------------------------------------------
|
||||||
// Mailer event hooks
|
// Mailer event hooks
|
||||||
|
@ -166,33 +190,51 @@ type App interface {
|
||||||
//
|
//
|
||||||
// Could be used to send your own custom email template if
|
// Could be used to send your own custom email template if
|
||||||
// [hook.StopPropagation] is returned in one of its listeners.
|
// [hook.StopPropagation] is returned in one of its listeners.
|
||||||
OnMailerBeforeRecordResetPasswordSend() *hook.Hook[*MailerRecordEvent]
|
//
|
||||||
|
// You can optionally specify a list of "tags" (Collection ids or names)
|
||||||
|
// to filter any newly attached event data handler.
|
||||||
|
OnMailerBeforeRecordResetPasswordSend(tags ...string) *hook.TaggedHook[*MailerRecordEvent]
|
||||||
|
|
||||||
// OnMailerAfterRecordResetPasswordSend hook is triggered after
|
// OnMailerAfterRecordResetPasswordSend hook is triggered after
|
||||||
// an auth record password reset email was successfully sent.
|
// an auth record password reset email was successfully sent.
|
||||||
OnMailerAfterRecordResetPasswordSend() *hook.Hook[*MailerRecordEvent]
|
//
|
||||||
|
// You can optionally specify a list of "tags" (Collection ids or names)
|
||||||
|
// to filter any newly attached event data handler.
|
||||||
|
OnMailerAfterRecordResetPasswordSend(tags ...string) *hook.TaggedHook[*MailerRecordEvent]
|
||||||
|
|
||||||
// OnMailerBeforeRecordVerificationSend hook is triggered right before
|
// OnMailerBeforeRecordVerificationSend hook is triggered right before
|
||||||
// sending a verification email to an auth record.
|
// sending a verification email to an auth record.
|
||||||
//
|
//
|
||||||
// Could be used to send your own custom email template if
|
// Could be used to send your own custom email template if
|
||||||
// [hook.StopPropagation] is returned in one of its listeners.
|
// [hook.StopPropagation] is returned in one of its listeners.
|
||||||
OnMailerBeforeRecordVerificationSend() *hook.Hook[*MailerRecordEvent]
|
//
|
||||||
|
// You can optionally specify a list of "tags" (Collection ids or names)
|
||||||
|
// to filter any newly attached event data handler.
|
||||||
|
OnMailerBeforeRecordVerificationSend(tags ...string) *hook.TaggedHook[*MailerRecordEvent]
|
||||||
|
|
||||||
// OnMailerAfterRecordVerificationSend hook is triggered after a
|
// OnMailerAfterRecordVerificationSend hook is triggered after a
|
||||||
// verification email was successfully sent to an auth record.
|
// verification email was successfully sent to an auth record.
|
||||||
OnMailerAfterRecordVerificationSend() *hook.Hook[*MailerRecordEvent]
|
//
|
||||||
|
// You can optionally specify a list of "tags" (Collection ids or names)
|
||||||
|
// to filter any newly attached event data handler.
|
||||||
|
OnMailerAfterRecordVerificationSend(tags ...string) *hook.TaggedHook[*MailerRecordEvent]
|
||||||
|
|
||||||
// OnMailerBeforeRecordChangeEmailSend hook is triggered right before
|
// OnMailerBeforeRecordChangeEmailSend hook is triggered right before
|
||||||
// sending a confirmation new address email to an auth record.
|
// sending a confirmation new address email to an auth record.
|
||||||
//
|
//
|
||||||
// Could be used to send your own custom email template if
|
// Could be used to send your own custom email template if
|
||||||
// [hook.StopPropagation] is returned in one of its listeners.
|
// [hook.StopPropagation] is returned in one of its listeners.
|
||||||
OnMailerBeforeRecordChangeEmailSend() *hook.Hook[*MailerRecordEvent]
|
//
|
||||||
|
// You can optionally specify a list of "tags" (Collection ids or names)
|
||||||
|
// to filter any newly attached event data handler.
|
||||||
|
OnMailerBeforeRecordChangeEmailSend(tags ...string) *hook.TaggedHook[*MailerRecordEvent]
|
||||||
|
|
||||||
// OnMailerAfterRecordChangeEmailSend hook is triggered after a
|
// OnMailerAfterRecordChangeEmailSend hook is triggered after a
|
||||||
// verification email was successfully sent to an auth record.
|
// verification email was successfully sent to an auth record.
|
||||||
OnMailerAfterRecordChangeEmailSend() *hook.Hook[*MailerRecordEvent]
|
//
|
||||||
|
// You can optionally specify a list of "tags" (Collection ids or names)
|
||||||
|
// to filter any newly attached event data handler.
|
||||||
|
OnMailerAfterRecordChangeEmailSend(tags ...string) *hook.TaggedHook[*MailerRecordEvent]
|
||||||
|
|
||||||
// ---------------------------------------------------------------
|
// ---------------------------------------------------------------
|
||||||
// Realtime API event hooks
|
// Realtime API event hooks
|
||||||
|
@ -257,7 +299,7 @@ type App interface {
|
||||||
//
|
//
|
||||||
// Could be used to validate or modify the file response before
|
// Could be used to validate or modify the file response before
|
||||||
// returning it to the client.
|
// returning it to the client.
|
||||||
OnFileDownloadRequest() *hook.Hook[*FileDownloadEvent]
|
OnFileDownloadRequest(tags ...string) *hook.TaggedHook[*FileDownloadEvent]
|
||||||
|
|
||||||
// ---------------------------------------------------------------
|
// ---------------------------------------------------------------
|
||||||
// Admin API event hooks
|
// Admin API event hooks
|
||||||
|
@ -366,18 +408,27 @@ type App interface {
|
||||||
//
|
//
|
||||||
// Could be used to additionally validate or modify the authenticated
|
// Could be used to additionally validate or modify the authenticated
|
||||||
// record data and token.
|
// record data and token.
|
||||||
OnRecordAuthRequest() *hook.Hook[*RecordAuthEvent]
|
//
|
||||||
|
// You can optionally specify a list of "tags" (Collection ids or names)
|
||||||
|
// to filter any newly attached event data handler.
|
||||||
|
OnRecordAuthRequest(tags ...string) *hook.TaggedHook[*RecordAuthEvent]
|
||||||
|
|
||||||
// OnRecordBeforeAuthWithPasswordRequest hook is triggered before each Record
|
// OnRecordBeforeAuthWithPasswordRequest hook is triggered before each Record
|
||||||
// auth with password API request (after request data load and before password validation).
|
// auth with password API request (after request data load and before password validation).
|
||||||
//
|
//
|
||||||
// Could be used to implement for example a custom password validation
|
// Could be used to implement for example a custom password validation
|
||||||
// or to locate a different Record identity (by assigning [RecordAuthWithPasswordEvent.Record]).
|
// or to locate a different Record identity (by assigning [RecordAuthWithPasswordEvent.Record]).
|
||||||
OnRecordBeforeAuthWithPasswordRequest() *hook.Hook[*RecordAuthWithPasswordEvent]
|
//
|
||||||
|
// You can optionally specify a list of "tags" (Collection ids or names)
|
||||||
|
// to filter any newly attached event data handler.
|
||||||
|
OnRecordBeforeAuthWithPasswordRequest(tags ...string) *hook.TaggedHook[*RecordAuthWithPasswordEvent]
|
||||||
|
|
||||||
// OnRecordAfterAuthWithPasswordRequest hook is triggered after each
|
// OnRecordAfterAuthWithPasswordRequest hook is triggered after each
|
||||||
// successful Record auth with password API request.
|
// successful Record auth with password API request.
|
||||||
OnRecordAfterAuthWithPasswordRequest() *hook.Hook[*RecordAuthWithPasswordEvent]
|
//
|
||||||
|
// You can optionally specify a list of "tags" (Collection ids or names)
|
||||||
|
// to filter any newly attached event data handler.
|
||||||
|
OnRecordAfterAuthWithPasswordRequest(tags ...string) *hook.TaggedHook[*RecordAuthWithPasswordEvent]
|
||||||
|
|
||||||
// OnRecordBeforeAuthWithOAuth2Request hook is triggered before each Record
|
// OnRecordBeforeAuthWithOAuth2Request hook is triggered before each Record
|
||||||
// OAuth2 sign-in/sign-up API request (after token exchange and before external provider linking).
|
// OAuth2 sign-in/sign-up API request (after token exchange and before external provider linking).
|
||||||
|
@ -387,104 +438,161 @@ type App interface {
|
||||||
//
|
//
|
||||||
// To assign or link a different existing record model you can
|
// To assign or link a different existing record model you can
|
||||||
// overwrite/modify the [RecordAuthWithOAuth2Event.Record] field.
|
// overwrite/modify the [RecordAuthWithOAuth2Event.Record] field.
|
||||||
OnRecordBeforeAuthWithOAuth2Request() *hook.Hook[*RecordAuthWithOAuth2Event]
|
//
|
||||||
|
// You can optionally specify a list of "tags" (Collection ids or names)
|
||||||
|
// to filter any newly attached event data handler.
|
||||||
|
OnRecordBeforeAuthWithOAuth2Request(tags ...string) *hook.TaggedHook[*RecordAuthWithOAuth2Event]
|
||||||
|
|
||||||
// OnRecordAfterAuthWithOAuth2Request hook is triggered after each
|
// OnRecordAfterAuthWithOAuth2Request hook is triggered after each
|
||||||
// successful Record OAuth2 API request.
|
// successful Record OAuth2 API request.
|
||||||
OnRecordAfterAuthWithOAuth2Request() *hook.Hook[*RecordAuthWithOAuth2Event]
|
//
|
||||||
|
// You can optionally specify a list of "tags" (Collection ids or names)
|
||||||
|
// to filter any newly attached event data handler.
|
||||||
|
OnRecordAfterAuthWithOAuth2Request(tags ...string) *hook.TaggedHook[*RecordAuthWithOAuth2Event]
|
||||||
|
|
||||||
// OnRecordBeforeAuthRefreshRequest hook is triggered before each Record
|
// OnRecordBeforeAuthRefreshRequest hook is triggered before each Record
|
||||||
// auth refresh API request (right before generating a new auth token).
|
// auth refresh API request (right before generating a new auth token).
|
||||||
//
|
//
|
||||||
// Could be used to additionally validate the request data or implement
|
// Could be used to additionally validate the request data or implement
|
||||||
// completely different auth refresh behavior (returning [hook.StopPropagation]).
|
// completely different auth refresh behavior (returning [hook.StopPropagation]).
|
||||||
OnRecordBeforeAuthRefreshRequest() *hook.Hook[*RecordAuthRefreshEvent]
|
//
|
||||||
|
// You can optionally specify a list of "tags" (Collection ids or names)
|
||||||
|
// to filter any newly attached event data handler.
|
||||||
|
OnRecordBeforeAuthRefreshRequest(tags ...string) *hook.TaggedHook[*RecordAuthRefreshEvent]
|
||||||
|
|
||||||
// OnRecordAfterAuthRefreshRequest hook is triggered after each
|
// OnRecordAfterAuthRefreshRequest hook is triggered after each
|
||||||
// successful auth refresh API request (right after generating a new auth token).
|
// successful auth refresh API request (right after generating a new auth token).
|
||||||
OnRecordAfterAuthRefreshRequest() *hook.Hook[*RecordAuthRefreshEvent]
|
//
|
||||||
|
// You can optionally specify a list of "tags" (Collection ids or names)
|
||||||
|
// to filter any newly attached event data handler.
|
||||||
|
OnRecordAfterAuthRefreshRequest(tags ...string) *hook.TaggedHook[*RecordAuthRefreshEvent]
|
||||||
|
|
||||||
// OnRecordBeforeRequestPasswordResetRequest hook is triggered before each Record
|
// OnRecordBeforeRequestPasswordResetRequest hook is triggered before each Record
|
||||||
// request password reset API request (after request data load and before sending the reset email).
|
// request password reset API request (after request data load and before sending the reset email).
|
||||||
//
|
//
|
||||||
// Could be used to additionally validate the request data or implement
|
// Could be used to additionally validate the request data or implement
|
||||||
// completely different password reset behavior (returning [hook.StopPropagation]).
|
// completely different password reset behavior (returning [hook.StopPropagation]).
|
||||||
OnRecordBeforeRequestPasswordResetRequest() *hook.Hook[*RecordRequestPasswordResetEvent]
|
//
|
||||||
|
// You can optionally specify a list of "tags" (Collection ids or names)
|
||||||
|
// to filter any newly attached event data handler.
|
||||||
|
OnRecordBeforeRequestPasswordResetRequest(tags ...string) *hook.TaggedHook[*RecordRequestPasswordResetEvent]
|
||||||
|
|
||||||
// OnRecordAfterRequestPasswordResetRequest hook is triggered after each
|
// OnRecordAfterRequestPasswordResetRequest hook is triggered after each
|
||||||
// successful request password reset API request.
|
// successful request password reset API request.
|
||||||
OnRecordAfterRequestPasswordResetRequest() *hook.Hook[*RecordRequestPasswordResetEvent]
|
//
|
||||||
|
// You can optionally specify a list of "tags" (Collection ids or names)
|
||||||
|
// to filter any newly attached event data handler.
|
||||||
|
OnRecordAfterRequestPasswordResetRequest(tags ...string) *hook.TaggedHook[*RecordRequestPasswordResetEvent]
|
||||||
|
|
||||||
// OnRecordBeforeConfirmPasswordResetRequest hook is triggered before each Record
|
// OnRecordBeforeConfirmPasswordResetRequest hook is triggered before each Record
|
||||||
// confirm password reset API request (after request data load and before persistence).
|
// confirm password reset API request (after request data load and before persistence).
|
||||||
//
|
//
|
||||||
// Could be used to additionally validate the request data or implement
|
// Could be used to additionally validate the request data or implement
|
||||||
// completely different persistence behavior (returning [hook.StopPropagation]).
|
// completely different persistence behavior (returning [hook.StopPropagation]).
|
||||||
OnRecordBeforeConfirmPasswordResetRequest() *hook.Hook[*RecordConfirmPasswordResetEvent]
|
//
|
||||||
|
// You can optionally specify a list of "tags" (Collection ids or names)
|
||||||
|
// to filter any newly attached event data handler.
|
||||||
|
OnRecordBeforeConfirmPasswordResetRequest(tags ...string) *hook.TaggedHook[*RecordConfirmPasswordResetEvent]
|
||||||
|
|
||||||
// OnRecordAfterConfirmPasswordResetRequest hook is triggered after each
|
// OnRecordAfterConfirmPasswordResetRequest hook is triggered after each
|
||||||
// successful confirm password reset API request.
|
// successful confirm password reset API request.
|
||||||
OnRecordAfterConfirmPasswordResetRequest() *hook.Hook[*RecordConfirmPasswordResetEvent]
|
//
|
||||||
|
// You can optionally specify a list of "tags" (Collection ids or names)
|
||||||
|
// to filter any newly attached event data handler.
|
||||||
|
OnRecordAfterConfirmPasswordResetRequest(tags ...string) *hook.TaggedHook[*RecordConfirmPasswordResetEvent]
|
||||||
|
|
||||||
// OnRecordBeforeRequestVerificationRequest hook is triggered before each Record
|
// OnRecordBeforeRequestVerificationRequest hook is triggered before each Record
|
||||||
// request verification API request (after request data load and before sending the verification email).
|
// request verification API request (after request data load and before sending the verification email).
|
||||||
//
|
//
|
||||||
// Could be used to additionally validate the loaded request data or implement
|
// Could be used to additionally validate the loaded request data or implement
|
||||||
// completely different verification behavior (returning [hook.StopPropagation]).
|
// completely different verification behavior (returning [hook.StopPropagation]).
|
||||||
OnRecordBeforeRequestVerificationRequest() *hook.Hook[*RecordRequestVerificationEvent]
|
//
|
||||||
|
// You can optionally specify a list of "tags" (Collection ids or names)
|
||||||
|
// to filter any newly attached event data handler.
|
||||||
|
OnRecordBeforeRequestVerificationRequest(tags ...string) *hook.TaggedHook[*RecordRequestVerificationEvent]
|
||||||
|
|
||||||
// OnRecordAfterRequestVerificationRequest hook is triggered after each
|
// OnRecordAfterRequestVerificationRequest hook is triggered after each
|
||||||
// successful request verification API request.
|
// successful request verification API request.
|
||||||
OnRecordAfterRequestVerificationRequest() *hook.Hook[*RecordRequestVerificationEvent]
|
//
|
||||||
|
// You can optionally specify a list of "tags" (Collection ids or names)
|
||||||
|
// to filter any newly attached event data handler.
|
||||||
|
OnRecordAfterRequestVerificationRequest(tags ...string) *hook.TaggedHook[*RecordRequestVerificationEvent]
|
||||||
|
|
||||||
// OnRecordBeforeConfirmVerificationRequest hook is triggered before each Record
|
// OnRecordBeforeConfirmVerificationRequest hook is triggered before each Record
|
||||||
// confirm verification API request (after request data load and before persistence).
|
// confirm verification API request (after request data load and before persistence).
|
||||||
//
|
//
|
||||||
// Could be used to additionally validate the request data or implement
|
// Could be used to additionally validate the request data or implement
|
||||||
// completely different persistence behavior (returning [hook.StopPropagation]).
|
// completely different persistence behavior (returning [hook.StopPropagation]).
|
||||||
OnRecordBeforeConfirmVerificationRequest() *hook.Hook[*RecordConfirmVerificationEvent]
|
//
|
||||||
|
// You can optionally specify a list of "tags" (Collection ids or names)
|
||||||
|
// to filter any newly attached event data handler.
|
||||||
|
OnRecordBeforeConfirmVerificationRequest(tags ...string) *hook.TaggedHook[*RecordConfirmVerificationEvent]
|
||||||
|
|
||||||
// OnRecordAfterConfirmVerificationRequest hook is triggered after each
|
// OnRecordAfterConfirmVerificationRequest hook is triggered after each
|
||||||
// successful confirm verification API request.
|
// successful confirm verification API request.
|
||||||
OnRecordAfterConfirmVerificationRequest() *hook.Hook[*RecordConfirmVerificationEvent]
|
//
|
||||||
|
// You can optionally specify a list of "tags" (Collection ids or names)
|
||||||
|
// to filter any newly attached event data handler.
|
||||||
|
OnRecordAfterConfirmVerificationRequest(tags ...string) *hook.TaggedHook[*RecordConfirmVerificationEvent]
|
||||||
|
|
||||||
// OnRecordBeforeRequestEmailChangeRequest hook is triggered before each Record request email change API request
|
// OnRecordBeforeRequestEmailChangeRequest hook is triggered before each Record request email change API request
|
||||||
// (after request data load and before sending the email link to confirm the change).
|
// (after request data load and before sending the email link to confirm the change).
|
||||||
//
|
//
|
||||||
// Could be used to additionally validate the request data or implement
|
// Could be used to additionally validate the request data or implement
|
||||||
// completely different request email change behavior (returning [hook.StopPropagation]).
|
// completely different request email change behavior (returning [hook.StopPropagation]).
|
||||||
OnRecordBeforeRequestEmailChangeRequest() *hook.Hook[*RecordRequestEmailChangeEvent]
|
//
|
||||||
|
// You can optionally specify a list of "tags" (Collection ids or names)
|
||||||
|
// to filter any newly attached event data handler.
|
||||||
|
OnRecordBeforeRequestEmailChangeRequest(tags ...string) *hook.TaggedHook[*RecordRequestEmailChangeEvent]
|
||||||
|
|
||||||
// OnRecordAfterRequestEmailChangeRequest hook is triggered after each
|
// OnRecordAfterRequestEmailChangeRequest hook is triggered after each
|
||||||
// successful request email change API request.
|
// successful request email change API request.
|
||||||
OnRecordAfterRequestEmailChangeRequest() *hook.Hook[*RecordRequestEmailChangeEvent]
|
//
|
||||||
|
// You can optionally specify a list of "tags" (Collection ids or names)
|
||||||
|
// to filter any newly attached event data handler.
|
||||||
|
OnRecordAfterRequestEmailChangeRequest(tags ...string) *hook.TaggedHook[*RecordRequestEmailChangeEvent]
|
||||||
|
|
||||||
// OnRecordBeforeConfirmEmailChangeRequest hook is triggered before each Record
|
// OnRecordBeforeConfirmEmailChangeRequest hook is triggered before each Record
|
||||||
// confirm email change API request (after request data load and before persistence).
|
// confirm email change API request (after request data load and before persistence).
|
||||||
//
|
//
|
||||||
// Could be used to additionally validate the request data or implement
|
// Could be used to additionally validate the request data or implement
|
||||||
// completely different persistence behavior (returning [hook.StopPropagation]).
|
// completely different persistence behavior (returning [hook.StopPropagation]).
|
||||||
OnRecordBeforeConfirmEmailChangeRequest() *hook.Hook[*RecordConfirmEmailChangeEvent]
|
//
|
||||||
|
// You can optionally specify a list of "tags" (Collection ids or names)
|
||||||
|
// to filter any newly attached event data handler.
|
||||||
|
OnRecordBeforeConfirmEmailChangeRequest(tags ...string) *hook.TaggedHook[*RecordConfirmEmailChangeEvent]
|
||||||
|
|
||||||
// OnRecordAfterConfirmEmailChangeRequest hook is triggered after each
|
// OnRecordAfterConfirmEmailChangeRequest hook is triggered after each
|
||||||
// successful confirm email change API request.
|
// successful confirm email change API request.
|
||||||
OnRecordAfterConfirmEmailChangeRequest() *hook.Hook[*RecordConfirmEmailChangeEvent]
|
//
|
||||||
|
// You can optionally specify a list of "tags" (Collection ids or names)
|
||||||
|
// to filter any newly attached event data handler.
|
||||||
|
OnRecordAfterConfirmEmailChangeRequest(tags ...string) *hook.TaggedHook[*RecordConfirmEmailChangeEvent]
|
||||||
|
|
||||||
// OnRecordListExternalAuthsRequest hook is triggered on each API record external auths list request.
|
// OnRecordListExternalAuthsRequest hook is triggered on each API record external auths list request.
|
||||||
//
|
//
|
||||||
// Could be used to validate or modify the response before returning it to the client.
|
// Could be used to validate or modify the response before returning it to the client.
|
||||||
OnRecordListExternalAuthsRequest() *hook.Hook[*RecordListExternalAuthsEvent]
|
//
|
||||||
|
// You can optionally specify a list of "tags" (Collection ids or names)
|
||||||
|
// to filter any newly attached event data handler.
|
||||||
|
OnRecordListExternalAuthsRequest(tags ...string) *hook.TaggedHook[*RecordListExternalAuthsEvent]
|
||||||
|
|
||||||
// OnRecordBeforeUnlinkExternalAuthRequest hook is triggered before each API record
|
// OnRecordBeforeUnlinkExternalAuthRequest hook is triggered before each API record
|
||||||
// external auth unlink request (after models load and before the actual relation deletion).
|
// external auth unlink request (after models load and before the actual relation deletion).
|
||||||
//
|
//
|
||||||
// Could be used to additionally validate the request data or implement
|
// Could be used to additionally validate the request data or implement
|
||||||
// completely different delete behavior (returning [hook.StopPropagation]).
|
// completely different delete behavior (returning [hook.StopPropagation]).
|
||||||
OnRecordBeforeUnlinkExternalAuthRequest() *hook.Hook[*RecordUnlinkExternalAuthEvent]
|
//
|
||||||
|
// You can optionally specify a list of "tags" (Collection ids or names)
|
||||||
|
// to filter any newly attached event data handler.
|
||||||
|
OnRecordBeforeUnlinkExternalAuthRequest(tags ...string) *hook.TaggedHook[*RecordUnlinkExternalAuthEvent]
|
||||||
|
|
||||||
// OnRecordAfterUnlinkExternalAuthRequest hook is triggered after each
|
// OnRecordAfterUnlinkExternalAuthRequest hook is triggered after each
|
||||||
// successful API record external auth unlink request.
|
// successful API record external auth unlink request.
|
||||||
OnRecordAfterUnlinkExternalAuthRequest() *hook.Hook[*RecordUnlinkExternalAuthEvent]
|
//
|
||||||
|
// You can optionally specify a list of "tags" (Collection ids or names)
|
||||||
|
// to filter any newly attached event data handler.
|
||||||
|
OnRecordAfterUnlinkExternalAuthRequest(tags ...string) *hook.TaggedHook[*RecordUnlinkExternalAuthEvent]
|
||||||
|
|
||||||
// ---------------------------------------------------------------
|
// ---------------------------------------------------------------
|
||||||
// Record CRUD API event hooks
|
// Record CRUD API event hooks
|
||||||
|
@ -493,45 +601,69 @@ type App interface {
|
||||||
// OnRecordsListRequest hook is triggered on each API Records list request.
|
// OnRecordsListRequest hook is triggered on each API Records list request.
|
||||||
//
|
//
|
||||||
// Could be used to validate or modify the response before returning it to the client.
|
// Could be used to validate or modify the response before returning it to the client.
|
||||||
OnRecordsListRequest() *hook.Hook[*RecordsListEvent]
|
//
|
||||||
|
// You can optionally specify a list of "tags" (Collection ids or names)
|
||||||
|
// to filter any newly attached event data handler.
|
||||||
|
OnRecordsListRequest(tags ...string) *hook.TaggedHook[*RecordsListEvent]
|
||||||
|
|
||||||
// OnRecordViewRequest hook is triggered on each API Record view request.
|
// OnRecordViewRequest hook is triggered on each API Record view request.
|
||||||
//
|
//
|
||||||
// Could be used to validate or modify the response before returning it to the client.
|
// Could be used to validate or modify the response before returning it to the client.
|
||||||
OnRecordViewRequest() *hook.Hook[*RecordViewEvent]
|
//
|
||||||
|
// You can optionally specify a list of "tags" (Collection ids or names)
|
||||||
|
// to filter any newly attached event data handler.
|
||||||
|
OnRecordViewRequest(tags ...string) *hook.TaggedHook[*RecordViewEvent]
|
||||||
|
|
||||||
// OnRecordBeforeCreateRequest hook is triggered before each API Record
|
// OnRecordBeforeCreateRequest hook is triggered before each API Record
|
||||||
// create request (after request data load and before model persistence).
|
// create request (after request data load and before model persistence).
|
||||||
//
|
//
|
||||||
// Could be used to additionally validate the request data or implement
|
// Could be used to additionally validate the request data or implement
|
||||||
// completely different persistence behavior (returning [hook.StopPropagation]).
|
// completely different persistence behavior (returning [hook.StopPropagation]).
|
||||||
OnRecordBeforeCreateRequest() *hook.Hook[*RecordCreateEvent]
|
//
|
||||||
|
// You can optionally specify a list of "tags" (Collection ids or names)
|
||||||
|
// to filter any newly attached event data handler.
|
||||||
|
OnRecordBeforeCreateRequest(tags ...string) *hook.TaggedHook[*RecordCreateEvent]
|
||||||
|
|
||||||
// OnRecordAfterCreateRequest hook is triggered after each
|
// OnRecordAfterCreateRequest hook is triggered after each
|
||||||
// successful API Record create request.
|
// successful API Record create request.
|
||||||
OnRecordAfterCreateRequest() *hook.Hook[*RecordCreateEvent]
|
//
|
||||||
|
// You can optionally specify a list of "tags" (Collection ids or names)
|
||||||
|
// to filter any newly attached event data handler.
|
||||||
|
OnRecordAfterCreateRequest(tags ...string) *hook.TaggedHook[*RecordCreateEvent]
|
||||||
|
|
||||||
// OnRecordBeforeUpdateRequest hook is triggered before each API Record
|
// OnRecordBeforeUpdateRequest hook is triggered before each API Record
|
||||||
// update request (after request data load and before model persistence).
|
// update request (after request data load and before model persistence).
|
||||||
//
|
//
|
||||||
// Could be used to additionally validate the request data or implement
|
// Could be used to additionally validate the request data or implement
|
||||||
// completely different persistence behavior (returning [hook.StopPropagation]).
|
// completely different persistence behavior (returning [hook.StopPropagation]).
|
||||||
OnRecordBeforeUpdateRequest() *hook.Hook[*RecordUpdateEvent]
|
//
|
||||||
|
// You can optionally specify a list of "tags" (Collection ids or names)
|
||||||
|
// to filter any newly attached event data handler.
|
||||||
|
OnRecordBeforeUpdateRequest(tags ...string) *hook.TaggedHook[*RecordUpdateEvent]
|
||||||
|
|
||||||
// OnRecordAfterUpdateRequest hook is triggered after each
|
// OnRecordAfterUpdateRequest hook is triggered after each
|
||||||
// successful API Record update request.
|
// successful API Record update request.
|
||||||
OnRecordAfterUpdateRequest() *hook.Hook[*RecordUpdateEvent]
|
//
|
||||||
|
// You can optionally specify a list of "tags" (Collection ids or names)
|
||||||
|
// to filter any newly attached event data handler.
|
||||||
|
OnRecordAfterUpdateRequest(tags ...string) *hook.TaggedHook[*RecordUpdateEvent]
|
||||||
|
|
||||||
// OnRecordBeforeDeleteRequest hook is triggered before each API Record
|
// OnRecordBeforeDeleteRequest hook is triggered before each API Record
|
||||||
// delete request (after model load and before actual deletion).
|
// delete request (after model load and before actual deletion).
|
||||||
//
|
//
|
||||||
// Could be used to additionally validate the request data or implement
|
// Could be used to additionally validate the request data or implement
|
||||||
// completely different delete behavior (returning [hook.StopPropagation]).
|
// completely different delete behavior (returning [hook.StopPropagation]).
|
||||||
OnRecordBeforeDeleteRequest() *hook.Hook[*RecordDeleteEvent]
|
//
|
||||||
|
// You can optionally specify a list of "tags" (Collection ids or names)
|
||||||
|
// to filter any newly attached event data handler.
|
||||||
|
OnRecordBeforeDeleteRequest(tags ...string) *hook.TaggedHook[*RecordDeleteEvent]
|
||||||
|
|
||||||
// OnRecordAfterDeleteRequest hook is triggered after each
|
// OnRecordAfterDeleteRequest hook is triggered after each
|
||||||
// successful API Record delete request.
|
// successful API Record delete request.
|
||||||
OnRecordAfterDeleteRequest() *hook.Hook[*RecordDeleteEvent]
|
//
|
||||||
|
// You can optionally specify a list of "tags" (Collection ids or names)
|
||||||
|
// to filter any newly attached event data handler.
|
||||||
|
OnRecordAfterDeleteRequest(tags ...string) *hook.TaggedHook[*RecordDeleteEvent]
|
||||||
|
|
||||||
// ---------------------------------------------------------------
|
// ---------------------------------------------------------------
|
||||||
// Collection API event hooks
|
// Collection API event hooks
|
||||||
|
|
172
core/base.go
172
core/base.go
|
@ -541,28 +541,28 @@ func (app *BaseApp) OnAfterApiError() *hook.Hook[*ApiErrorEvent] {
|
||||||
// Dao event hooks
|
// Dao event hooks
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
|
||||||
func (app *BaseApp) OnModelBeforeCreate() *hook.Hook[*ModelEvent] {
|
func (app *BaseApp) OnModelBeforeCreate(tags ...string) *hook.TaggedHook[*ModelEvent] {
|
||||||
return app.onModelBeforeCreate
|
return hook.NewTaggedHook(app.onModelBeforeCreate, tags...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *BaseApp) OnModelAfterCreate() *hook.Hook[*ModelEvent] {
|
func (app *BaseApp) OnModelAfterCreate(tags ...string) *hook.TaggedHook[*ModelEvent] {
|
||||||
return app.onModelAfterCreate
|
return hook.NewTaggedHook(app.onModelAfterCreate, tags...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *BaseApp) OnModelBeforeUpdate() *hook.Hook[*ModelEvent] {
|
func (app *BaseApp) OnModelBeforeUpdate(tags ...string) *hook.TaggedHook[*ModelEvent] {
|
||||||
return app.onModelBeforeUpdate
|
return hook.NewTaggedHook(app.onModelBeforeUpdate, tags...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *BaseApp) OnModelAfterUpdate() *hook.Hook[*ModelEvent] {
|
func (app *BaseApp) OnModelAfterUpdate(tags ...string) *hook.TaggedHook[*ModelEvent] {
|
||||||
return app.onModelAfterUpdate
|
return hook.NewTaggedHook(app.onModelAfterUpdate, tags...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *BaseApp) OnModelBeforeDelete() *hook.Hook[*ModelEvent] {
|
func (app *BaseApp) OnModelBeforeDelete(tags ...string) *hook.TaggedHook[*ModelEvent] {
|
||||||
return app.onModelBeforeDelete
|
return hook.NewTaggedHook(app.onModelBeforeDelete, tags...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *BaseApp) OnModelAfterDelete() *hook.Hook[*ModelEvent] {
|
func (app *BaseApp) OnModelAfterDelete(tags ...string) *hook.TaggedHook[*ModelEvent] {
|
||||||
return app.onModelAfterDelete
|
return hook.NewTaggedHook(app.onModelAfterDelete, tags...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
@ -577,28 +577,28 @@ func (app *BaseApp) OnMailerAfterAdminResetPasswordSend() *hook.Hook[*MailerAdmi
|
||||||
return app.onMailerAfterAdminResetPasswordSend
|
return app.onMailerAfterAdminResetPasswordSend
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *BaseApp) OnMailerBeforeRecordResetPasswordSend() *hook.Hook[*MailerRecordEvent] {
|
func (app *BaseApp) OnMailerBeforeRecordResetPasswordSend(tags ...string) *hook.TaggedHook[*MailerRecordEvent] {
|
||||||
return app.onMailerBeforeRecordResetPasswordSend
|
return hook.NewTaggedHook(app.onMailerBeforeRecordResetPasswordSend, tags...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *BaseApp) OnMailerAfterRecordResetPasswordSend() *hook.Hook[*MailerRecordEvent] {
|
func (app *BaseApp) OnMailerAfterRecordResetPasswordSend(tags ...string) *hook.TaggedHook[*MailerRecordEvent] {
|
||||||
return app.onMailerAfterRecordResetPasswordSend
|
return hook.NewTaggedHook(app.onMailerAfterRecordResetPasswordSend, tags...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *BaseApp) OnMailerBeforeRecordVerificationSend() *hook.Hook[*MailerRecordEvent] {
|
func (app *BaseApp) OnMailerBeforeRecordVerificationSend(tags ...string) *hook.TaggedHook[*MailerRecordEvent] {
|
||||||
return app.onMailerBeforeRecordVerificationSend
|
return hook.NewTaggedHook(app.onMailerBeforeRecordVerificationSend, tags...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *BaseApp) OnMailerAfterRecordVerificationSend() *hook.Hook[*MailerRecordEvent] {
|
func (app *BaseApp) OnMailerAfterRecordVerificationSend(tags ...string) *hook.TaggedHook[*MailerRecordEvent] {
|
||||||
return app.onMailerAfterRecordVerificationSend
|
return hook.NewTaggedHook(app.onMailerAfterRecordVerificationSend, tags...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *BaseApp) OnMailerBeforeRecordChangeEmailSend() *hook.Hook[*MailerRecordEvent] {
|
func (app *BaseApp) OnMailerBeforeRecordChangeEmailSend(tags ...string) *hook.TaggedHook[*MailerRecordEvent] {
|
||||||
return app.onMailerBeforeRecordChangeEmailSend
|
return hook.NewTaggedHook(app.onMailerBeforeRecordChangeEmailSend, tags...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *BaseApp) OnMailerAfterRecordChangeEmailSend() *hook.Hook[*MailerRecordEvent] {
|
func (app *BaseApp) OnMailerAfterRecordChangeEmailSend(tags ...string) *hook.TaggedHook[*MailerRecordEvent] {
|
||||||
return app.onMailerAfterRecordChangeEmailSend
|
return hook.NewTaggedHook(app.onMailerAfterRecordChangeEmailSend, tags...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
@ -649,8 +649,8 @@ func (app *BaseApp) OnSettingsAfterUpdateRequest() *hook.Hook[*SettingsUpdateEve
|
||||||
// File API event hooks
|
// File API event hooks
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
|
||||||
func (app *BaseApp) OnFileDownloadRequest() *hook.Hook[*FileDownloadEvent] {
|
func (app *BaseApp) OnFileDownloadRequest(tags ...string) *hook.TaggedHook[*FileDownloadEvent] {
|
||||||
return app.onFileDownloadRequest
|
return hook.NewTaggedHook(app.onFileDownloadRequest, tags...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
@ -729,128 +729,128 @@ func (app *BaseApp) OnAdminAfterConfirmPasswordResetRequest() *hook.Hook[*AdminC
|
||||||
// Record auth API event hooks
|
// Record auth API event hooks
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
|
||||||
func (app *BaseApp) OnRecordAuthRequest() *hook.Hook[*RecordAuthEvent] {
|
func (app *BaseApp) OnRecordAuthRequest(tags ...string) *hook.TaggedHook[*RecordAuthEvent] {
|
||||||
return app.onRecordAuthRequest
|
return hook.NewTaggedHook(app.onRecordAuthRequest, tags...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *BaseApp) OnRecordBeforeAuthWithPasswordRequest() *hook.Hook[*RecordAuthWithPasswordEvent] {
|
func (app *BaseApp) OnRecordBeforeAuthWithPasswordRequest(tags ...string) *hook.TaggedHook[*RecordAuthWithPasswordEvent] {
|
||||||
return app.onRecordBeforeAuthWithPasswordRequest
|
return hook.NewTaggedHook(app.onRecordBeforeAuthWithPasswordRequest, tags...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *BaseApp) OnRecordAfterAuthWithPasswordRequest() *hook.Hook[*RecordAuthWithPasswordEvent] {
|
func (app *BaseApp) OnRecordAfterAuthWithPasswordRequest(tags ...string) *hook.TaggedHook[*RecordAuthWithPasswordEvent] {
|
||||||
return app.onRecordAfterAuthWithPasswordRequest
|
return hook.NewTaggedHook(app.onRecordAfterAuthWithPasswordRequest, tags...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *BaseApp) OnRecordBeforeAuthWithOAuth2Request() *hook.Hook[*RecordAuthWithOAuth2Event] {
|
func (app *BaseApp) OnRecordBeforeAuthWithOAuth2Request(tags ...string) *hook.TaggedHook[*RecordAuthWithOAuth2Event] {
|
||||||
return app.onRecordBeforeAuthWithOAuth2Request
|
return hook.NewTaggedHook(app.onRecordBeforeAuthWithOAuth2Request, tags...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *BaseApp) OnRecordAfterAuthWithOAuth2Request() *hook.Hook[*RecordAuthWithOAuth2Event] {
|
func (app *BaseApp) OnRecordAfterAuthWithOAuth2Request(tags ...string) *hook.TaggedHook[*RecordAuthWithOAuth2Event] {
|
||||||
return app.onRecordAfterAuthWithOAuth2Request
|
return hook.NewTaggedHook(app.onRecordAfterAuthWithOAuth2Request, tags...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *BaseApp) OnRecordBeforeAuthRefreshRequest() *hook.Hook[*RecordAuthRefreshEvent] {
|
func (app *BaseApp) OnRecordBeforeAuthRefreshRequest(tags ...string) *hook.TaggedHook[*RecordAuthRefreshEvent] {
|
||||||
return app.onRecordBeforeAuthRefreshRequest
|
return hook.NewTaggedHook(app.onRecordBeforeAuthRefreshRequest, tags...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *BaseApp) OnRecordAfterAuthRefreshRequest() *hook.Hook[*RecordAuthRefreshEvent] {
|
func (app *BaseApp) OnRecordAfterAuthRefreshRequest(tags ...string) *hook.TaggedHook[*RecordAuthRefreshEvent] {
|
||||||
return app.onRecordAfterAuthRefreshRequest
|
return hook.NewTaggedHook(app.onRecordAfterAuthRefreshRequest, tags...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *BaseApp) OnRecordBeforeRequestPasswordResetRequest() *hook.Hook[*RecordRequestPasswordResetEvent] {
|
func (app *BaseApp) OnRecordBeforeRequestPasswordResetRequest(tags ...string) *hook.TaggedHook[*RecordRequestPasswordResetEvent] {
|
||||||
return app.onRecordBeforeRequestPasswordResetRequest
|
return hook.NewTaggedHook(app.onRecordBeforeRequestPasswordResetRequest, tags...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *BaseApp) OnRecordAfterRequestPasswordResetRequest() *hook.Hook[*RecordRequestPasswordResetEvent] {
|
func (app *BaseApp) OnRecordAfterRequestPasswordResetRequest(tags ...string) *hook.TaggedHook[*RecordRequestPasswordResetEvent] {
|
||||||
return app.onRecordAfterRequestPasswordResetRequest
|
return hook.NewTaggedHook(app.onRecordAfterRequestPasswordResetRequest, tags...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *BaseApp) OnRecordBeforeConfirmPasswordResetRequest() *hook.Hook[*RecordConfirmPasswordResetEvent] {
|
func (app *BaseApp) OnRecordBeforeConfirmPasswordResetRequest(tags ...string) *hook.TaggedHook[*RecordConfirmPasswordResetEvent] {
|
||||||
return app.onRecordBeforeConfirmPasswordResetRequest
|
return hook.NewTaggedHook(app.onRecordBeforeConfirmPasswordResetRequest, tags...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *BaseApp) OnRecordAfterConfirmPasswordResetRequest() *hook.Hook[*RecordConfirmPasswordResetEvent] {
|
func (app *BaseApp) OnRecordAfterConfirmPasswordResetRequest(tags ...string) *hook.TaggedHook[*RecordConfirmPasswordResetEvent] {
|
||||||
return app.onRecordAfterConfirmPasswordResetRequest
|
return hook.NewTaggedHook(app.onRecordAfterConfirmPasswordResetRequest, tags...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *BaseApp) OnRecordBeforeRequestVerificationRequest() *hook.Hook[*RecordRequestVerificationEvent] {
|
func (app *BaseApp) OnRecordBeforeRequestVerificationRequest(tags ...string) *hook.TaggedHook[*RecordRequestVerificationEvent] {
|
||||||
return app.onRecordBeforeRequestVerificationRequest
|
return hook.NewTaggedHook(app.onRecordBeforeRequestVerificationRequest, tags...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *BaseApp) OnRecordAfterRequestVerificationRequest() *hook.Hook[*RecordRequestVerificationEvent] {
|
func (app *BaseApp) OnRecordAfterRequestVerificationRequest(tags ...string) *hook.TaggedHook[*RecordRequestVerificationEvent] {
|
||||||
return app.onRecordAfterRequestVerificationRequest
|
return hook.NewTaggedHook(app.onRecordAfterRequestVerificationRequest, tags...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *BaseApp) OnRecordBeforeConfirmVerificationRequest() *hook.Hook[*RecordConfirmVerificationEvent] {
|
func (app *BaseApp) OnRecordBeforeConfirmVerificationRequest(tags ...string) *hook.TaggedHook[*RecordConfirmVerificationEvent] {
|
||||||
return app.onRecordBeforeConfirmVerificationRequest
|
return hook.NewTaggedHook(app.onRecordBeforeConfirmVerificationRequest, tags...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *BaseApp) OnRecordAfterConfirmVerificationRequest() *hook.Hook[*RecordConfirmVerificationEvent] {
|
func (app *BaseApp) OnRecordAfterConfirmVerificationRequest(tags ...string) *hook.TaggedHook[*RecordConfirmVerificationEvent] {
|
||||||
return app.onRecordAfterConfirmVerificationRequest
|
return hook.NewTaggedHook(app.onRecordAfterConfirmVerificationRequest, tags...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *BaseApp) OnRecordBeforeRequestEmailChangeRequest() *hook.Hook[*RecordRequestEmailChangeEvent] {
|
func (app *BaseApp) OnRecordBeforeRequestEmailChangeRequest(tags ...string) *hook.TaggedHook[*RecordRequestEmailChangeEvent] {
|
||||||
return app.onRecordBeforeRequestEmailChangeRequest
|
return hook.NewTaggedHook(app.onRecordBeforeRequestEmailChangeRequest, tags...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *BaseApp) OnRecordAfterRequestEmailChangeRequest() *hook.Hook[*RecordRequestEmailChangeEvent] {
|
func (app *BaseApp) OnRecordAfterRequestEmailChangeRequest(tags ...string) *hook.TaggedHook[*RecordRequestEmailChangeEvent] {
|
||||||
return app.onRecordAfterRequestEmailChangeRequest
|
return hook.NewTaggedHook(app.onRecordAfterRequestEmailChangeRequest, tags...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *BaseApp) OnRecordBeforeConfirmEmailChangeRequest() *hook.Hook[*RecordConfirmEmailChangeEvent] {
|
func (app *BaseApp) OnRecordBeforeConfirmEmailChangeRequest(tags ...string) *hook.TaggedHook[*RecordConfirmEmailChangeEvent] {
|
||||||
return app.onRecordBeforeConfirmEmailChangeRequest
|
return hook.NewTaggedHook(app.onRecordBeforeConfirmEmailChangeRequest, tags...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *BaseApp) OnRecordAfterConfirmEmailChangeRequest() *hook.Hook[*RecordConfirmEmailChangeEvent] {
|
func (app *BaseApp) OnRecordAfterConfirmEmailChangeRequest(tags ...string) *hook.TaggedHook[*RecordConfirmEmailChangeEvent] {
|
||||||
return app.onRecordAfterConfirmEmailChangeRequest
|
return hook.NewTaggedHook(app.onRecordAfterConfirmEmailChangeRequest, tags...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *BaseApp) OnRecordListExternalAuthsRequest() *hook.Hook[*RecordListExternalAuthsEvent] {
|
func (app *BaseApp) OnRecordListExternalAuthsRequest(tags ...string) *hook.TaggedHook[*RecordListExternalAuthsEvent] {
|
||||||
return app.onRecordListExternalAuthsRequest
|
return hook.NewTaggedHook(app.onRecordListExternalAuthsRequest, tags...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *BaseApp) OnRecordBeforeUnlinkExternalAuthRequest() *hook.Hook[*RecordUnlinkExternalAuthEvent] {
|
func (app *BaseApp) OnRecordBeforeUnlinkExternalAuthRequest(tags ...string) *hook.TaggedHook[*RecordUnlinkExternalAuthEvent] {
|
||||||
return app.onRecordBeforeUnlinkExternalAuthRequest
|
return hook.NewTaggedHook(app.onRecordBeforeUnlinkExternalAuthRequest, tags...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *BaseApp) OnRecordAfterUnlinkExternalAuthRequest() *hook.Hook[*RecordUnlinkExternalAuthEvent] {
|
func (app *BaseApp) OnRecordAfterUnlinkExternalAuthRequest(tags ...string) *hook.TaggedHook[*RecordUnlinkExternalAuthEvent] {
|
||||||
return app.onRecordAfterUnlinkExternalAuthRequest
|
return hook.NewTaggedHook(app.onRecordAfterUnlinkExternalAuthRequest, tags...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Record CRUD API event hooks
|
// Record CRUD API event hooks
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
|
||||||
func (app *BaseApp) OnRecordsListRequest() *hook.Hook[*RecordsListEvent] {
|
func (app *BaseApp) OnRecordsListRequest(tags ...string) *hook.TaggedHook[*RecordsListEvent] {
|
||||||
return app.onRecordsListRequest
|
return hook.NewTaggedHook(app.onRecordsListRequest, tags...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *BaseApp) OnRecordViewRequest() *hook.Hook[*RecordViewEvent] {
|
func (app *BaseApp) OnRecordViewRequest(tags ...string) *hook.TaggedHook[*RecordViewEvent] {
|
||||||
return app.onRecordViewRequest
|
return hook.NewTaggedHook(app.onRecordViewRequest, tags...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *BaseApp) OnRecordBeforeCreateRequest() *hook.Hook[*RecordCreateEvent] {
|
func (app *BaseApp) OnRecordBeforeCreateRequest(tags ...string) *hook.TaggedHook[*RecordCreateEvent] {
|
||||||
return app.onRecordBeforeCreateRequest
|
return hook.NewTaggedHook(app.onRecordBeforeCreateRequest, tags...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *BaseApp) OnRecordAfterCreateRequest() *hook.Hook[*RecordCreateEvent] {
|
func (app *BaseApp) OnRecordAfterCreateRequest(tags ...string) *hook.TaggedHook[*RecordCreateEvent] {
|
||||||
return app.onRecordAfterCreateRequest
|
return hook.NewTaggedHook(app.onRecordAfterCreateRequest, tags...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *BaseApp) OnRecordBeforeUpdateRequest() *hook.Hook[*RecordUpdateEvent] {
|
func (app *BaseApp) OnRecordBeforeUpdateRequest(tags ...string) *hook.TaggedHook[*RecordUpdateEvent] {
|
||||||
return app.onRecordBeforeUpdateRequest
|
return hook.NewTaggedHook(app.onRecordBeforeUpdateRequest, tags...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *BaseApp) OnRecordAfterUpdateRequest() *hook.Hook[*RecordUpdateEvent] {
|
func (app *BaseApp) OnRecordAfterUpdateRequest(tags ...string) *hook.TaggedHook[*RecordUpdateEvent] {
|
||||||
return app.onRecordAfterUpdateRequest
|
return hook.NewTaggedHook(app.onRecordAfterUpdateRequest, tags...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *BaseApp) OnRecordBeforeDeleteRequest() *hook.Hook[*RecordDeleteEvent] {
|
func (app *BaseApp) OnRecordBeforeDeleteRequest(tags ...string) *hook.TaggedHook[*RecordDeleteEvent] {
|
||||||
return app.onRecordBeforeDeleteRequest
|
return hook.NewTaggedHook(app.onRecordBeforeDeleteRequest, tags...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *BaseApp) OnRecordAfterDeleteRequest() *hook.Hook[*RecordDeleteEvent] {
|
func (app *BaseApp) OnRecordAfterDeleteRequest(tags ...string) *hook.TaggedHook[*RecordDeleteEvent] {
|
||||||
return app.onRecordAfterDeleteRequest
|
return hook.NewTaggedHook(app.onRecordAfterDeleteRequest, tags...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
|
|
@ -182,238 +182,6 @@ func TestBaseAppGetters(t *testing.T) {
|
||||||
if app.onBeforeServe != app.OnBeforeServe() || app.OnBeforeServe() == nil {
|
if app.onBeforeServe != app.OnBeforeServe() || app.OnBeforeServe() == nil {
|
||||||
t.Fatalf("Getter app.OnBeforeServe does not match or nil (%v vs %v)", app.OnBeforeServe(), app.onBeforeServe)
|
t.Fatalf("Getter app.OnBeforeServe does not match or nil (%v vs %v)", app.OnBeforeServe(), app.onBeforeServe)
|
||||||
}
|
}
|
||||||
|
|
||||||
if app.onModelBeforeCreate != app.OnModelBeforeCreate() || app.OnModelBeforeCreate() == nil {
|
|
||||||
t.Fatalf("Getter app.OnModelBeforeCreate does not match or nil (%v vs %v)", app.OnModelBeforeCreate(), app.onModelBeforeCreate)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onModelAfterCreate != app.OnModelAfterCreate() || app.OnModelAfterCreate() == nil {
|
|
||||||
t.Fatalf("Getter app.OnModelAfterCreate does not match or nil (%v vs %v)", app.OnModelAfterCreate(), app.onModelAfterCreate)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onModelBeforeUpdate != app.OnModelBeforeUpdate() || app.OnModelBeforeUpdate() == nil {
|
|
||||||
t.Fatalf("Getter app.OnModelBeforeUpdate does not match or nil (%v vs %v)", app.OnModelBeforeUpdate(), app.onModelBeforeUpdate)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onModelAfterUpdate != app.OnModelAfterUpdate() || app.OnModelAfterUpdate() == nil {
|
|
||||||
t.Fatalf("Getter app.OnModelAfterUpdate does not match or nil (%v vs %v)", app.OnModelAfterUpdate(), app.onModelAfterUpdate)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onModelBeforeDelete != app.OnModelBeforeDelete() || app.OnModelBeforeDelete() == nil {
|
|
||||||
t.Fatalf("Getter app.OnModelBeforeDelete does not match or nil (%v vs %v)", app.OnModelBeforeDelete(), app.onModelBeforeDelete)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onModelAfterDelete != app.OnModelAfterDelete() || app.OnModelAfterDelete() == nil {
|
|
||||||
t.Fatalf("Getter app.OnModelAfterDelete does not match or nil (%v vs %v)", app.OnModelAfterDelete(), app.onModelAfterDelete)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onMailerBeforeAdminResetPasswordSend != app.OnMailerBeforeAdminResetPasswordSend() || app.OnMailerBeforeAdminResetPasswordSend() == nil {
|
|
||||||
t.Fatalf("Getter app.OnMailerBeforeAdminResetPasswordSend does not match or nil (%v vs %v)", app.OnMailerBeforeAdminResetPasswordSend(), app.onMailerBeforeAdminResetPasswordSend)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onMailerAfterAdminResetPasswordSend != app.OnMailerAfterAdminResetPasswordSend() || app.OnMailerAfterAdminResetPasswordSend() == nil {
|
|
||||||
t.Fatalf("Getter app.OnMailerAfterAdminResetPasswordSend does not match or nil (%v vs %v)", app.OnMailerAfterAdminResetPasswordSend(), app.onMailerAfterAdminResetPasswordSend)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onMailerBeforeRecordResetPasswordSend != app.OnMailerBeforeRecordResetPasswordSend() || app.OnMailerBeforeRecordResetPasswordSend() == nil {
|
|
||||||
t.Fatalf("Getter app.OnMailerBeforeRecordResetPasswordSend does not match or nil (%v vs %v)", app.OnMailerBeforeRecordResetPasswordSend(), app.onMailerBeforeRecordResetPasswordSend)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onMailerAfterRecordResetPasswordSend != app.OnMailerAfterRecordResetPasswordSend() || app.OnMailerAfterRecordResetPasswordSend() == nil {
|
|
||||||
t.Fatalf("Getter app.OnMailerAfterRecordResetPasswordSend does not match or nil (%v vs %v)", app.OnMailerAfterRecordResetPasswordSend(), app.onMailerAfterRecordResetPasswordSend)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onMailerBeforeRecordVerificationSend != app.OnMailerBeforeRecordVerificationSend() || app.OnMailerBeforeRecordVerificationSend() == nil {
|
|
||||||
t.Fatalf("Getter app.OnMailerBeforeRecordVerificationSend does not match or nil (%v vs %v)", app.OnMailerBeforeRecordVerificationSend(), app.onMailerBeforeRecordVerificationSend)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onMailerAfterRecordVerificationSend != app.OnMailerAfterRecordVerificationSend() || app.OnMailerAfterRecordVerificationSend() == nil {
|
|
||||||
t.Fatalf("Getter app.OnMailerAfterRecordVerificationSend does not match or nil (%v vs %v)", app.OnMailerAfterRecordVerificationSend(), app.onMailerAfterRecordVerificationSend)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onMailerBeforeRecordChangeEmailSend != app.OnMailerBeforeRecordChangeEmailSend() || app.OnMailerBeforeRecordChangeEmailSend() == nil {
|
|
||||||
t.Fatalf("Getter app.OnMailerBeforeRecordChangeEmailSend does not match or nil (%v vs %v)", app.OnMailerBeforeRecordChangeEmailSend(), app.onMailerBeforeRecordChangeEmailSend)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onMailerAfterRecordChangeEmailSend != app.OnMailerAfterRecordChangeEmailSend() || app.OnMailerAfterRecordChangeEmailSend() == nil {
|
|
||||||
t.Fatalf("Getter app.OnMailerAfterRecordChangeEmailSend does not match or nil (%v vs %v)", app.OnMailerAfterRecordChangeEmailSend(), app.onMailerAfterRecordChangeEmailSend)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onRealtimeConnectRequest != app.OnRealtimeConnectRequest() || app.OnRealtimeConnectRequest() == nil {
|
|
||||||
t.Fatalf("Getter app.OnRealtimeConnectRequest does not match or nil (%v vs %v)", app.OnRealtimeConnectRequest(), app.onRealtimeConnectRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onRealtimeBeforeSubscribeRequest != app.OnRealtimeBeforeSubscribeRequest() || app.OnRealtimeBeforeSubscribeRequest() == nil {
|
|
||||||
t.Fatalf("Getter app.OnRealtimeBeforeSubscribeRequest does not match or nil (%v vs %v)", app.OnRealtimeBeforeSubscribeRequest(), app.onRealtimeBeforeSubscribeRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onRealtimeAfterSubscribeRequest != app.OnRealtimeAfterSubscribeRequest() || app.OnRealtimeAfterSubscribeRequest() == nil {
|
|
||||||
t.Fatalf("Getter app.OnRealtimeAfterSubscribeRequest does not match or nil (%v vs %v)", app.OnRealtimeAfterSubscribeRequest(), app.onRealtimeAfterSubscribeRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onSettingsListRequest != app.OnSettingsListRequest() || app.OnSettingsListRequest() == nil {
|
|
||||||
t.Fatalf("Getter app.OnSettingsListRequest does not match or nil (%v vs %v)", app.OnSettingsListRequest(), app.onSettingsListRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onSettingsBeforeUpdateRequest != app.OnSettingsBeforeUpdateRequest() || app.OnSettingsBeforeUpdateRequest() == nil {
|
|
||||||
t.Fatalf("Getter app.OnSettingsBeforeUpdateRequest does not match or nil (%v vs %v)", app.OnSettingsBeforeUpdateRequest(), app.onSettingsBeforeUpdateRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onSettingsAfterUpdateRequest != app.OnSettingsAfterUpdateRequest() || app.OnSettingsAfterUpdateRequest() == nil {
|
|
||||||
t.Fatalf("Getter app.OnSettingsAfterUpdateRequest does not match or nil (%v vs %v)", app.OnSettingsAfterUpdateRequest(), app.onSettingsAfterUpdateRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onFileDownloadRequest != app.OnFileDownloadRequest() || app.OnFileDownloadRequest() == nil {
|
|
||||||
t.Fatalf("Getter app.OnFileDownloadRequest does not match or nil (%v vs %v)", app.OnFileDownloadRequest(), app.onFileDownloadRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onAdminsListRequest != app.OnAdminsListRequest() || app.OnAdminsListRequest() == nil {
|
|
||||||
t.Fatalf("Getter app.OnAdminsListRequest does not match or nil (%v vs %v)", app.OnAdminsListRequest(), app.onAdminsListRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onAdminViewRequest != app.OnAdminViewRequest() || app.OnAdminViewRequest() == nil {
|
|
||||||
t.Fatalf("Getter app.OnAdminViewRequest does not match or nil (%v vs %v)", app.OnAdminViewRequest(), app.onAdminViewRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onAdminBeforeCreateRequest != app.OnAdminBeforeCreateRequest() || app.OnAdminBeforeCreateRequest() == nil {
|
|
||||||
t.Fatalf("Getter app.OnAdminBeforeCreateRequest does not match or nil (%v vs %v)", app.OnAdminBeforeCreateRequest(), app.onAdminBeforeCreateRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onAdminAfterCreateRequest != app.OnAdminAfterCreateRequest() || app.OnAdminAfterCreateRequest() == nil {
|
|
||||||
t.Fatalf("Getter app.OnAdminAfterCreateRequest does not match or nil (%v vs %v)", app.OnAdminAfterCreateRequest(), app.onAdminAfterCreateRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onAdminBeforeUpdateRequest != app.OnAdminBeforeUpdateRequest() || app.OnAdminBeforeUpdateRequest() == nil {
|
|
||||||
t.Fatalf("Getter app.OnAdminBeforeUpdateRequest does not match or nil (%v vs %v)", app.OnAdminBeforeUpdateRequest(), app.onAdminBeforeUpdateRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onAdminAfterUpdateRequest != app.OnAdminAfterUpdateRequest() || app.OnAdminAfterUpdateRequest() == nil {
|
|
||||||
t.Fatalf("Getter app.OnAdminAfterUpdateRequest does not match or nil (%v vs %v)", app.OnAdminAfterUpdateRequest(), app.onAdminAfterUpdateRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onAdminBeforeDeleteRequest != app.OnAdminBeforeDeleteRequest() || app.OnAdminBeforeDeleteRequest() == nil {
|
|
||||||
t.Fatalf("Getter app.OnAdminBeforeDeleteRequest does not match or nil (%v vs %v)", app.OnAdminBeforeDeleteRequest(), app.onAdminBeforeDeleteRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onAdminAfterDeleteRequest != app.OnAdminAfterDeleteRequest() || app.OnAdminAfterDeleteRequest() == nil {
|
|
||||||
t.Fatalf("Getter app.OnAdminAfterDeleteRequest does not match or nil (%v vs %v)", app.OnAdminAfterDeleteRequest(), app.onAdminAfterDeleteRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onAdminAuthRequest != app.OnAdminAuthRequest() || app.OnAdminAuthRequest() == nil {
|
|
||||||
t.Fatalf("Getter app.OnAdminAuthRequest does not match or nil (%v vs %v)", app.OnAdminAuthRequest(), app.onAdminAuthRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onRecordsListRequest != app.OnRecordsListRequest() || app.OnRecordsListRequest() == nil {
|
|
||||||
t.Fatalf("Getter app.OnRecordsListRequest does not match or nil (%v vs %v)", app.OnRecordsListRequest(), app.onRecordsListRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onRecordViewRequest != app.OnRecordViewRequest() || app.OnRecordViewRequest() == nil {
|
|
||||||
t.Fatalf("Getter app.OnRecordViewRequest does not match or nil (%v vs %v)", app.OnRecordViewRequest(), app.onRecordViewRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onRecordBeforeCreateRequest != app.OnRecordBeforeCreateRequest() || app.OnRecordBeforeCreateRequest() == nil {
|
|
||||||
t.Fatalf("Getter app.OnRecordBeforeCreateRequest does not match or nil (%v vs %v)", app.OnRecordBeforeCreateRequest(), app.onRecordBeforeCreateRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onRecordAfterCreateRequest != app.OnRecordAfterCreateRequest() || app.OnRecordAfterCreateRequest() == nil {
|
|
||||||
t.Fatalf("Getter app.OnRecordAfterCreateRequest does not match or nil (%v vs %v)", app.OnRecordAfterCreateRequest(), app.onRecordAfterCreateRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onRecordBeforeUpdateRequest != app.OnRecordBeforeUpdateRequest() || app.OnRecordBeforeUpdateRequest() == nil {
|
|
||||||
t.Fatalf("Getter app.OnRecordBeforeUpdateRequest does not match or nil (%v vs %v)", app.OnRecordBeforeUpdateRequest(), app.onRecordBeforeUpdateRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onRecordAfterUpdateRequest != app.OnRecordAfterUpdateRequest() || app.OnRecordAfterUpdateRequest() == nil {
|
|
||||||
t.Fatalf("Getter app.OnRecordAfterUpdateRequest does not match or nil (%v vs %v)", app.OnRecordAfterUpdateRequest(), app.onRecordAfterUpdateRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onRecordBeforeDeleteRequest != app.OnRecordBeforeDeleteRequest() || app.OnRecordBeforeDeleteRequest() == nil {
|
|
||||||
t.Fatalf("Getter app.OnRecordBeforeDeleteRequest does not match or nil (%v vs %v)", app.OnRecordBeforeDeleteRequest(), app.onRecordBeforeDeleteRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onRecordAfterDeleteRequest != app.OnRecordAfterDeleteRequest() || app.OnRecordAfterDeleteRequest() == nil {
|
|
||||||
t.Fatalf("Getter app.OnRecordAfterDeleteRequest does not match or nil (%v vs %v)", app.OnRecordAfterDeleteRequest(), app.onRecordAfterDeleteRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onRecordAuthRequest != app.OnRecordAuthRequest() || app.OnRecordAuthRequest() == nil {
|
|
||||||
t.Fatalf("Getter app.OnRecordAuthRequest does not match or nil (%v vs %v)", app.OnRecordAuthRequest(), app.onRecordAuthRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onRecordListExternalAuthsRequest != app.OnRecordListExternalAuthsRequest() || app.OnRecordListExternalAuthsRequest() == nil {
|
|
||||||
t.Fatalf("Getter app.OnRecordListExternalAuthsRequest does not match or nil (%v vs %v)", app.OnRecordListExternalAuthsRequest(), app.onRecordListExternalAuthsRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onRecordBeforeUnlinkExternalAuthRequest != app.OnRecordBeforeUnlinkExternalAuthRequest() || app.OnRecordBeforeUnlinkExternalAuthRequest() == nil {
|
|
||||||
t.Fatalf("Getter app.OnRecordBeforeUnlinkExternalAuthRequest does not match or nil (%v vs %v)", app.OnRecordBeforeUnlinkExternalAuthRequest(), app.onRecordBeforeUnlinkExternalAuthRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onRecordAfterUnlinkExternalAuthRequest != app.OnRecordAfterUnlinkExternalAuthRequest() || app.OnRecordAfterUnlinkExternalAuthRequest() == nil {
|
|
||||||
t.Fatalf("Getter app.OnRecordAfterUnlinkExternalAuthRequest does not match or nil (%v vs %v)", app.OnRecordAfterUnlinkExternalAuthRequest(), app.onRecordAfterUnlinkExternalAuthRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onRecordsListRequest != app.OnRecordsListRequest() || app.OnRecordsListRequest() == nil {
|
|
||||||
t.Fatalf("Getter app.OnRecordsListRequest does not match or nil (%v vs %v)", app.OnRecordsListRequest(), app.onRecordsListRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onRecordViewRequest != app.OnRecordViewRequest() || app.OnRecordViewRequest() == nil {
|
|
||||||
t.Fatalf("Getter app.OnRecordViewRequest does not match or nil (%v vs %v)", app.OnRecordViewRequest(), app.onRecordViewRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onRecordBeforeCreateRequest != app.OnRecordBeforeCreateRequest() || app.OnRecordBeforeCreateRequest() == nil {
|
|
||||||
t.Fatalf("Getter app.OnRecordBeforeCreateRequest does not match or nil (%v vs %v)", app.OnRecordBeforeCreateRequest(), app.onRecordBeforeCreateRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onRecordAfterCreateRequest != app.OnRecordAfterCreateRequest() || app.OnRecordAfterCreateRequest() == nil {
|
|
||||||
t.Fatalf("Getter app.OnRecordAfterCreateRequest does not match or nil (%v vs %v)", app.OnRecordAfterCreateRequest(), app.onRecordAfterCreateRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onRecordBeforeUpdateRequest != app.OnRecordBeforeUpdateRequest() || app.OnRecordBeforeUpdateRequest() == nil {
|
|
||||||
t.Fatalf("Getter app.OnRecordBeforeUpdateRequest does not match or nil (%v vs %v)", app.OnRecordBeforeUpdateRequest(), app.onRecordBeforeUpdateRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onRecordAfterUpdateRequest != app.OnRecordAfterUpdateRequest() || app.OnRecordAfterUpdateRequest() == nil {
|
|
||||||
t.Fatalf("Getter app.OnRecordAfterUpdateRequest does not match or nil (%v vs %v)", app.OnRecordAfterUpdateRequest(), app.onRecordAfterUpdateRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onRecordBeforeDeleteRequest != app.OnRecordBeforeDeleteRequest() || app.OnRecordBeforeDeleteRequest() == nil {
|
|
||||||
t.Fatalf("Getter app.OnRecordBeforeDeleteRequest does not match or nil (%v vs %v)", app.OnRecordBeforeDeleteRequest(), app.onRecordBeforeDeleteRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onRecordAfterDeleteRequest != app.OnRecordAfterDeleteRequest() || app.OnRecordAfterDeleteRequest() == nil {
|
|
||||||
t.Fatalf("Getter app.OnRecordAfterDeleteRequest does not match or nil (%v vs %v)", app.OnRecordAfterDeleteRequest(), app.onRecordAfterDeleteRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onCollectionsListRequest != app.OnCollectionsListRequest() || app.OnCollectionsListRequest() == nil {
|
|
||||||
t.Fatalf("Getter app.OnCollectionsListRequest does not match or nil (%v vs %v)", app.OnCollectionsListRequest(), app.onCollectionsListRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onCollectionViewRequest != app.OnCollectionViewRequest() || app.OnCollectionViewRequest() == nil {
|
|
||||||
t.Fatalf("Getter app.OnCollectionViewRequest does not match or nil (%v vs %v)", app.OnCollectionViewRequest(), app.onCollectionViewRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onCollectionBeforeCreateRequest != app.OnCollectionBeforeCreateRequest() || app.OnCollectionBeforeCreateRequest() == nil {
|
|
||||||
t.Fatalf("Getter app.OnCollectionBeforeCreateRequest does not match or nil (%v vs %v)", app.OnCollectionBeforeCreateRequest(), app.onCollectionBeforeCreateRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onCollectionAfterCreateRequest != app.OnCollectionAfterCreateRequest() || app.OnCollectionAfterCreateRequest() == nil {
|
|
||||||
t.Fatalf("Getter app.OnCollectionAfterCreateRequest does not match or nil (%v vs %v)", app.OnCollectionAfterCreateRequest(), app.onCollectionAfterCreateRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onCollectionBeforeUpdateRequest != app.OnCollectionBeforeUpdateRequest() || app.OnCollectionBeforeUpdateRequest() == nil {
|
|
||||||
t.Fatalf("Getter app.OnCollectionBeforeUpdateRequest does not match or nil (%v vs %v)", app.OnCollectionBeforeUpdateRequest(), app.onCollectionBeforeUpdateRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onCollectionAfterUpdateRequest != app.OnCollectionAfterUpdateRequest() || app.OnCollectionAfterUpdateRequest() == nil {
|
|
||||||
t.Fatalf("Getter app.OnCollectionAfterUpdateRequest does not match or nil (%v vs %v)", app.OnCollectionAfterUpdateRequest(), app.onCollectionAfterUpdateRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onCollectionBeforeDeleteRequest != app.OnCollectionBeforeDeleteRequest() || app.OnCollectionBeforeDeleteRequest() == nil {
|
|
||||||
t.Fatalf("Getter app.OnCollectionBeforeDeleteRequest does not match or nil (%v vs %v)", app.OnCollectionBeforeDeleteRequest(), app.onCollectionBeforeDeleteRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
if app.onCollectionAfterDeleteRequest != app.OnCollectionAfterDeleteRequest() || app.OnCollectionAfterDeleteRequest() == nil {
|
|
||||||
t.Fatalf("Getter app.OnCollectionAfterDeleteRequest does not match or nil (%v vs %v)", app.OnCollectionAfterDeleteRequest(), app.onCollectionAfterDeleteRequest)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBaseAppNewMailClient(t *testing.T) {
|
func TestBaseAppNewMailClient(t *testing.T) {
|
||||||
|
|
|
@ -11,7 +11,7 @@ func initPragmas(db *dbx.DB) error {
|
||||||
_, err := db.NewQuery(`
|
_, err := db.NewQuery(`
|
||||||
PRAGMA busy_timeout = 10000;
|
PRAGMA busy_timeout = 10000;
|
||||||
PRAGMA journal_mode = WAL;
|
PRAGMA journal_mode = WAL;
|
||||||
PRAGMA journal_size_limit = 100000000;
|
PRAGMA journal_size_limit = 200000000;
|
||||||
PRAGMA synchronous = NORMAL;
|
PRAGMA synchronous = NORMAL;
|
||||||
PRAGMA foreign_keys = TRUE;
|
PRAGMA foreign_keys = TRUE;
|
||||||
`).Execute()
|
`).Execute()
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"github.com/pocketbase/pocketbase/models/schema"
|
"github.com/pocketbase/pocketbase/models/schema"
|
||||||
"github.com/pocketbase/pocketbase/models/settings"
|
"github.com/pocketbase/pocketbase/models/settings"
|
||||||
"github.com/pocketbase/pocketbase/tools/auth"
|
"github.com/pocketbase/pocketbase/tools/auth"
|
||||||
|
"github.com/pocketbase/pocketbase/tools/hook"
|
||||||
"github.com/pocketbase/pocketbase/tools/mailer"
|
"github.com/pocketbase/pocketbase/tools/mailer"
|
||||||
"github.com/pocketbase/pocketbase/tools/search"
|
"github.com/pocketbase/pocketbase/tools/search"
|
||||||
"github.com/pocketbase/pocketbase/tools/subscriptions"
|
"github.com/pocketbase/pocketbase/tools/subscriptions"
|
||||||
|
@ -13,6 +14,28 @@ import (
|
||||||
"github.com/labstack/echo/v5"
|
"github.com/labstack/echo/v5"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type BaseCollectionEvent struct {
|
||||||
|
Collection *models.Collection
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *BaseCollectionEvent) Tags() []string {
|
||||||
|
if e.Collection == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
tags := make([]string, 0, 2)
|
||||||
|
|
||||||
|
if e.Collection.Id != "" {
|
||||||
|
tags = append(tags, e.Collection.Id)
|
||||||
|
}
|
||||||
|
|
||||||
|
if e.Collection.Name != "" {
|
||||||
|
tags = append(tags, e.Collection.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
return tags
|
||||||
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Serve events data
|
// Serve events data
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
@ -35,16 +58,32 @@ type ApiErrorEvent struct {
|
||||||
// Model DAO events data
|
// Model DAO events data
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
|
||||||
|
var _ hook.Tagger = (*ModelEvent)(nil)
|
||||||
|
|
||||||
type ModelEvent struct {
|
type ModelEvent struct {
|
||||||
Dao *daos.Dao
|
Dao *daos.Dao
|
||||||
Model models.Model
|
Model models.Model
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *ModelEvent) Tags() []string {
|
||||||
|
if e.Model == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if r, ok := e.Model.(*models.Record); ok && r.Collection() != nil {
|
||||||
|
return []string{r.Collection().Id, r.Collection().Name}
|
||||||
|
}
|
||||||
|
|
||||||
|
return []string{e.Model.TableName()}
|
||||||
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Mailer events data
|
// Mailer events data
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
|
||||||
type MailerRecordEvent struct {
|
type MailerRecordEvent struct {
|
||||||
|
BaseCollectionEvent
|
||||||
|
|
||||||
MailClient mailer.Mailer
|
MailClient mailer.Mailer
|
||||||
Message *mailer.Message
|
Message *mailer.Message
|
||||||
Record *models.Record
|
Record *models.Record
|
||||||
|
@ -104,28 +143,37 @@ type SettingsUpdateEvent struct {
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
|
||||||
type RecordsListEvent struct {
|
type RecordsListEvent struct {
|
||||||
|
BaseCollectionEvent
|
||||||
|
|
||||||
HttpContext echo.Context
|
HttpContext echo.Context
|
||||||
Collection *models.Collection
|
|
||||||
Records []*models.Record
|
Records []*models.Record
|
||||||
Result *search.Result
|
Result *search.Result
|
||||||
}
|
}
|
||||||
|
|
||||||
type RecordViewEvent struct {
|
type RecordViewEvent struct {
|
||||||
|
BaseCollectionEvent
|
||||||
|
|
||||||
HttpContext echo.Context
|
HttpContext echo.Context
|
||||||
Record *models.Record
|
Record *models.Record
|
||||||
}
|
}
|
||||||
|
|
||||||
type RecordCreateEvent struct {
|
type RecordCreateEvent struct {
|
||||||
|
BaseCollectionEvent
|
||||||
|
|
||||||
HttpContext echo.Context
|
HttpContext echo.Context
|
||||||
Record *models.Record
|
Record *models.Record
|
||||||
}
|
}
|
||||||
|
|
||||||
type RecordUpdateEvent struct {
|
type RecordUpdateEvent struct {
|
||||||
|
BaseCollectionEvent
|
||||||
|
|
||||||
HttpContext echo.Context
|
HttpContext echo.Context
|
||||||
Record *models.Record
|
Record *models.Record
|
||||||
}
|
}
|
||||||
|
|
||||||
type RecordDeleteEvent struct {
|
type RecordDeleteEvent struct {
|
||||||
|
BaseCollectionEvent
|
||||||
|
|
||||||
HttpContext echo.Context
|
HttpContext echo.Context
|
||||||
Record *models.Record
|
Record *models.Record
|
||||||
}
|
}
|
||||||
|
@ -135,6 +183,8 @@ type RecordDeleteEvent struct {
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
|
||||||
type RecordAuthEvent struct {
|
type RecordAuthEvent struct {
|
||||||
|
BaseCollectionEvent
|
||||||
|
|
||||||
HttpContext echo.Context
|
HttpContext echo.Context
|
||||||
Record *models.Record
|
Record *models.Record
|
||||||
Token string
|
Token string
|
||||||
|
@ -142,6 +192,8 @@ type RecordAuthEvent struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type RecordAuthWithPasswordEvent struct {
|
type RecordAuthWithPasswordEvent struct {
|
||||||
|
BaseCollectionEvent
|
||||||
|
|
||||||
HttpContext echo.Context
|
HttpContext echo.Context
|
||||||
Record *models.Record
|
Record *models.Record
|
||||||
Identity string
|
Identity string
|
||||||
|
@ -149,53 +201,73 @@ type RecordAuthWithPasswordEvent struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type RecordAuthWithOAuth2Event struct {
|
type RecordAuthWithOAuth2Event struct {
|
||||||
|
BaseCollectionEvent
|
||||||
|
|
||||||
HttpContext echo.Context
|
HttpContext echo.Context
|
||||||
Record *models.Record
|
Record *models.Record
|
||||||
OAuth2User *auth.AuthUser
|
OAuth2User *auth.AuthUser
|
||||||
}
|
}
|
||||||
|
|
||||||
type RecordAuthRefreshEvent struct {
|
type RecordAuthRefreshEvent struct {
|
||||||
|
BaseCollectionEvent
|
||||||
|
|
||||||
HttpContext echo.Context
|
HttpContext echo.Context
|
||||||
Record *models.Record
|
Record *models.Record
|
||||||
}
|
}
|
||||||
|
|
||||||
type RecordRequestPasswordResetEvent struct {
|
type RecordRequestPasswordResetEvent struct {
|
||||||
|
BaseCollectionEvent
|
||||||
|
|
||||||
HttpContext echo.Context
|
HttpContext echo.Context
|
||||||
Record *models.Record
|
Record *models.Record
|
||||||
}
|
}
|
||||||
|
|
||||||
type RecordConfirmPasswordResetEvent struct {
|
type RecordConfirmPasswordResetEvent struct {
|
||||||
|
BaseCollectionEvent
|
||||||
|
|
||||||
HttpContext echo.Context
|
HttpContext echo.Context
|
||||||
Record *models.Record
|
Record *models.Record
|
||||||
}
|
}
|
||||||
|
|
||||||
type RecordRequestVerificationEvent struct {
|
type RecordRequestVerificationEvent struct {
|
||||||
|
BaseCollectionEvent
|
||||||
|
|
||||||
HttpContext echo.Context
|
HttpContext echo.Context
|
||||||
Record *models.Record
|
Record *models.Record
|
||||||
}
|
}
|
||||||
|
|
||||||
type RecordConfirmVerificationEvent struct {
|
type RecordConfirmVerificationEvent struct {
|
||||||
|
BaseCollectionEvent
|
||||||
|
|
||||||
HttpContext echo.Context
|
HttpContext echo.Context
|
||||||
Record *models.Record
|
Record *models.Record
|
||||||
}
|
}
|
||||||
|
|
||||||
type RecordRequestEmailChangeEvent struct {
|
type RecordRequestEmailChangeEvent struct {
|
||||||
|
BaseCollectionEvent
|
||||||
|
|
||||||
HttpContext echo.Context
|
HttpContext echo.Context
|
||||||
Record *models.Record
|
Record *models.Record
|
||||||
}
|
}
|
||||||
|
|
||||||
type RecordConfirmEmailChangeEvent struct {
|
type RecordConfirmEmailChangeEvent struct {
|
||||||
|
BaseCollectionEvent
|
||||||
|
|
||||||
HttpContext echo.Context
|
HttpContext echo.Context
|
||||||
Record *models.Record
|
Record *models.Record
|
||||||
}
|
}
|
||||||
|
|
||||||
type RecordListExternalAuthsEvent struct {
|
type RecordListExternalAuthsEvent struct {
|
||||||
|
BaseCollectionEvent
|
||||||
|
|
||||||
HttpContext echo.Context
|
HttpContext echo.Context
|
||||||
Record *models.Record
|
Record *models.Record
|
||||||
ExternalAuths []*models.ExternalAuth
|
ExternalAuths []*models.ExternalAuth
|
||||||
}
|
}
|
||||||
|
|
||||||
type RecordUnlinkExternalAuthEvent struct {
|
type RecordUnlinkExternalAuthEvent struct {
|
||||||
|
BaseCollectionEvent
|
||||||
|
|
||||||
HttpContext echo.Context
|
HttpContext echo.Context
|
||||||
Record *models.Record
|
Record *models.Record
|
||||||
ExternalAuth *models.ExternalAuth
|
ExternalAuth *models.ExternalAuth
|
||||||
|
@ -270,23 +342,27 @@ type CollectionsListEvent struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type CollectionViewEvent struct {
|
type CollectionViewEvent struct {
|
||||||
|
BaseCollectionEvent
|
||||||
|
|
||||||
HttpContext echo.Context
|
HttpContext echo.Context
|
||||||
Collection *models.Collection
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type CollectionCreateEvent struct {
|
type CollectionCreateEvent struct {
|
||||||
|
BaseCollectionEvent
|
||||||
|
|
||||||
HttpContext echo.Context
|
HttpContext echo.Context
|
||||||
Collection *models.Collection
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type CollectionUpdateEvent struct {
|
type CollectionUpdateEvent struct {
|
||||||
|
BaseCollectionEvent
|
||||||
|
|
||||||
HttpContext echo.Context
|
HttpContext echo.Context
|
||||||
Collection *models.Collection
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type CollectionDeleteEvent struct {
|
type CollectionDeleteEvent struct {
|
||||||
|
BaseCollectionEvent
|
||||||
|
|
||||||
HttpContext echo.Context
|
HttpContext echo.Context
|
||||||
Collection *models.Collection
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type CollectionsImportEvent struct {
|
type CollectionsImportEvent struct {
|
||||||
|
@ -299,8 +375,9 @@ type CollectionsImportEvent struct {
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
|
||||||
type FileDownloadEvent struct {
|
type FileDownloadEvent struct {
|
||||||
|
BaseCollectionEvent
|
||||||
|
|
||||||
HttpContext echo.Context
|
HttpContext echo.Context
|
||||||
Collection *models.Collection
|
|
||||||
Record *models.Record
|
Record *models.Record
|
||||||
FileField *schema.SchemaField
|
FileField *schema.SchemaField
|
||||||
ServedPath string
|
ServedPath string
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
package core_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/pocketbase/pocketbase/core"
|
||||||
|
"github.com/pocketbase/pocketbase/models"
|
||||||
|
"github.com/pocketbase/pocketbase/tools/list"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestBaseCollectionEventTags(t *testing.T) {
|
||||||
|
c1 := new(models.Collection)
|
||||||
|
|
||||||
|
c2 := new(models.Collection)
|
||||||
|
c2.Id = "a"
|
||||||
|
|
||||||
|
c3 := new(models.Collection)
|
||||||
|
c3.Name = "b"
|
||||||
|
|
||||||
|
c4 := new(models.Collection)
|
||||||
|
c4.Id = "a"
|
||||||
|
c4.Name = "b"
|
||||||
|
|
||||||
|
scenarios := []struct {
|
||||||
|
collection *models.Collection
|
||||||
|
expectedTags []string
|
||||||
|
}{
|
||||||
|
{c1, []string{}},
|
||||||
|
{c2, []string{"a"}},
|
||||||
|
{c3, []string{"b"}},
|
||||||
|
{c4, []string{"a", "b"}},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, s := range scenarios {
|
||||||
|
event := new(core.BaseCollectionEvent)
|
||||||
|
event.Collection = s.collection
|
||||||
|
|
||||||
|
tags := event.Tags()
|
||||||
|
|
||||||
|
if len(s.expectedTags) != len(tags) {
|
||||||
|
t.Fatalf("[%d] Expected %v tags, got %v", i, s.expectedTags, tags)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tag := range s.expectedTags {
|
||||||
|
if !list.ExistInSlice(tag, tags) {
|
||||||
|
t.Fatalf("[%d] Expected %v tags, got %v", i, s.expectedTags, tags)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestModelEventTags(t *testing.T) {
|
||||||
|
m1 := new(models.Admin)
|
||||||
|
|
||||||
|
c := new(models.Collection)
|
||||||
|
c.Id = "a"
|
||||||
|
c.Name = "b"
|
||||||
|
m2 := models.NewRecord(c)
|
||||||
|
|
||||||
|
scenarios := []struct {
|
||||||
|
model models.Model
|
||||||
|
expectedTags []string
|
||||||
|
}{
|
||||||
|
{m1, []string{"_admins"}},
|
||||||
|
{m2, []string{"a", "b"}},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, s := range scenarios {
|
||||||
|
event := new(core.ModelEvent)
|
||||||
|
event.Model = s.model
|
||||||
|
|
||||||
|
tags := event.Tags()
|
||||||
|
|
||||||
|
if len(s.expectedTags) != len(tags) {
|
||||||
|
t.Fatalf("[%d] Expected %v tags, got %v", i, s.expectedTags, tags)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tag := range s.expectedTags {
|
||||||
|
if !list.ExistInSlice(tag, tags) {
|
||||||
|
t.Fatalf("[%d] Expected %v tags, got %v", i, s.expectedTags, tags)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -61,12 +61,11 @@ func SendAdminPasswordReset(app core.App, admin *models.Admin) error {
|
||||||
HTML: body,
|
HTML: body,
|
||||||
}
|
}
|
||||||
|
|
||||||
event := &core.MailerAdminEvent{
|
event := new(core.MailerAdminEvent)
|
||||||
MailClient: mailClient,
|
event.MailClient = mailClient
|
||||||
Message: message,
|
event.Message = message
|
||||||
Admin: admin,
|
event.Admin = admin
|
||||||
Meta: map[string]any{"token": token},
|
event.Meta = map[string]any{"token": token}
|
||||||
}
|
|
||||||
|
|
||||||
sendErr := app.OnMailerBeforeAdminResetPasswordSend().Trigger(event, func(e *core.MailerAdminEvent) error {
|
sendErr := app.OnMailerBeforeAdminResetPasswordSend().Trigger(event, func(e *core.MailerAdminEvent) error {
|
||||||
return e.MailClient.Send(e.Message)
|
return e.MailClient.Send(e.Message)
|
||||||
|
|
|
@ -37,12 +37,12 @@ func SendRecordPasswordReset(app core.App, authRecord *models.Record) error {
|
||||||
HTML: body,
|
HTML: body,
|
||||||
}
|
}
|
||||||
|
|
||||||
event := &core.MailerRecordEvent{
|
event := new(core.MailerRecordEvent)
|
||||||
MailClient: mailClient,
|
event.MailClient = mailClient
|
||||||
Message: message,
|
event.Message = message
|
||||||
Record: authRecord,
|
event.Collection = authRecord.Collection()
|
||||||
Meta: map[string]any{"token": token},
|
event.Record = authRecord
|
||||||
}
|
event.Meta = map[string]any{"token": token}
|
||||||
|
|
||||||
sendErr := app.OnMailerBeforeRecordResetPasswordSend().Trigger(event, func(e *core.MailerRecordEvent) error {
|
sendErr := app.OnMailerBeforeRecordResetPasswordSend().Trigger(event, func(e *core.MailerRecordEvent) error {
|
||||||
return e.MailClient.Send(e.Message)
|
return e.MailClient.Send(e.Message)
|
||||||
|
@ -81,12 +81,12 @@ func SendRecordVerification(app core.App, authRecord *models.Record) error {
|
||||||
HTML: body,
|
HTML: body,
|
||||||
}
|
}
|
||||||
|
|
||||||
event := &core.MailerRecordEvent{
|
event := new(core.MailerRecordEvent)
|
||||||
MailClient: mailClient,
|
event.MailClient = mailClient
|
||||||
Message: message,
|
event.Message = message
|
||||||
Record: authRecord,
|
event.Collection = authRecord.Collection()
|
||||||
Meta: map[string]any{"token": token},
|
event.Record = authRecord
|
||||||
}
|
event.Meta = map[string]any{"token": token}
|
||||||
|
|
||||||
sendErr := app.OnMailerBeforeRecordVerificationSend().Trigger(event, func(e *core.MailerRecordEvent) error {
|
sendErr := app.OnMailerBeforeRecordVerificationSend().Trigger(event, func(e *core.MailerRecordEvent) error {
|
||||||
return e.MailClient.Send(e.Message)
|
return e.MailClient.Send(e.Message)
|
||||||
|
@ -125,14 +125,14 @@ func SendRecordChangeEmail(app core.App, record *models.Record, newEmail string)
|
||||||
HTML: body,
|
HTML: body,
|
||||||
}
|
}
|
||||||
|
|
||||||
event := &core.MailerRecordEvent{
|
event := new(core.MailerRecordEvent)
|
||||||
MailClient: mailClient,
|
event.MailClient = mailClient
|
||||||
Message: message,
|
event.Message = message
|
||||||
Record: record,
|
event.Collection = record.Collection()
|
||||||
Meta: map[string]any{
|
event.Record = record
|
||||||
"token": token,
|
event.Meta = map[string]any{
|
||||||
"newEmail": newEmail,
|
"token": token,
|
||||||
},
|
"newEmail": newEmail,
|
||||||
}
|
}
|
||||||
|
|
||||||
sendErr := app.OnMailerBeforeRecordChangeEmailSend().Trigger(event, func(e *core.MailerRecordEvent) error {
|
sendErr := app.OnMailerBeforeRecordChangeEmailSend().Trigger(event, func(e *core.MailerRecordEvent) error {
|
||||||
|
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestAddAndPreAdd(t *testing.T) {
|
func TestHookAddAndPreAdd(t *testing.T) {
|
||||||
h := Hook[int]{}
|
h := Hook[int]{}
|
||||||
|
|
||||||
if total := len(h.handlers); total != 0 {
|
if total := len(h.handlers); total != 0 {
|
||||||
|
@ -36,7 +36,7 @@ func TestAddAndPreAdd(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestReset(t *testing.T) {
|
func TestHookReset(t *testing.T) {
|
||||||
h := Hook[int]{}
|
h := Hook[int]{}
|
||||||
|
|
||||||
h.Reset() // should do nothing and not panic
|
h.Reset() // should do nothing and not panic
|
||||||
|
@ -55,7 +55,7 @@ func TestReset(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTrigger(t *testing.T) {
|
func TestHookTrigger(t *testing.T) {
|
||||||
err1 := errors.New("demo")
|
err1 := errors.New("demo")
|
||||||
err2 := errors.New("demo")
|
err2 := errors.New("demo")
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ func TestTrigger(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTriggerStopPropagation(t *testing.T) {
|
func TestHookTriggerStopPropagation(t *testing.T) {
|
||||||
called1 := false
|
called1 := false
|
||||||
f1 := func(data int) error { called1 = true; return nil }
|
f1 := func(data int) error { called1 = true; return nil }
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
package hook
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/pocketbase/pocketbase/tools/list"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Tagger defines an interface for event data structs that support tags/groups/categories/etc.
|
||||||
|
// Usually used together with TaggedHook.
|
||||||
|
type Tagger interface {
|
||||||
|
Tags() []string
|
||||||
|
}
|
||||||
|
|
||||||
|
// wrapped local Hook embedded struct to limit the public API surface.
|
||||||
|
type mainHook[T Tagger] struct {
|
||||||
|
*Hook[T]
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewTaggedHook creates a new TaggedHook with the provided main hook and optional tags.
|
||||||
|
func NewTaggedHook[T Tagger](hook *Hook[T], tags ...string) *TaggedHook[T] {
|
||||||
|
return &TaggedHook[T]{
|
||||||
|
mainHook[T]{hook},
|
||||||
|
tags,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TaggedHook defines a proxy hook which register handlers that are triggered only
|
||||||
|
// if the TaggedHook.tags are empty or includes at least one of the event data tag(s).
|
||||||
|
type TaggedHook[T Tagger] struct {
|
||||||
|
mainHook[T]
|
||||||
|
|
||||||
|
tags []string
|
||||||
|
}
|
||||||
|
|
||||||
|
// CanTriggerOn checks if the current TaggedHook can be triggered with
|
||||||
|
// the provided event data tags.
|
||||||
|
func (p *TaggedHook[T]) CanTriggerOn(tags []string) bool {
|
||||||
|
if len(p.tags) == 0 {
|
||||||
|
return true // match all
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, t := range tags {
|
||||||
|
if list.ExistInSlice(t, p.tags) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// PreAdd registers a new handler to the hook by prepending it to the existing queue.
|
||||||
|
//
|
||||||
|
// The fn handler will be called only if the event data tags satisfy p.CanTriggerOn.
|
||||||
|
func (p *TaggedHook[T]) PreAdd(fn Handler[T]) {
|
||||||
|
p.mainHook.PreAdd(func(e T) error {
|
||||||
|
if p.CanTriggerOn(e.Tags()) {
|
||||||
|
return fn(e)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add registers a new handler to the hook by appending it to the existing queue.
|
||||||
|
//
|
||||||
|
// The fn handler will be called only if the event data tags satisfy p.CanTriggerOn.
|
||||||
|
func (p *TaggedHook[T]) Add(fn Handler[T]) {
|
||||||
|
p.mainHook.Add(func(e T) error {
|
||||||
|
if p.CanTriggerOn(e.Tags()) {
|
||||||
|
return fn(e)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
package hook
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
type mockTagsData struct {
|
||||||
|
tags []string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m mockTagsData) Tags() []string {
|
||||||
|
return m.tags
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTaggedHook(t *testing.T) {
|
||||||
|
triggerSequence := ""
|
||||||
|
|
||||||
|
base := &Hook[mockTagsData]{}
|
||||||
|
base.Add(func(data mockTagsData) error { triggerSequence += "f0"; return nil })
|
||||||
|
|
||||||
|
hA := NewTaggedHook(base)
|
||||||
|
hA.Add(func(data mockTagsData) error { triggerSequence += "a1"; return nil })
|
||||||
|
hA.PreAdd(func(data mockTagsData) error { triggerSequence += "a2"; return nil })
|
||||||
|
|
||||||
|
hB := NewTaggedHook(base, "b1", "b2")
|
||||||
|
hB.Add(func(data mockTagsData) error { triggerSequence += "b1"; return nil })
|
||||||
|
hB.PreAdd(func(data mockTagsData) error { triggerSequence += "b2"; return nil })
|
||||||
|
|
||||||
|
hC := NewTaggedHook(base, "c1", "c2")
|
||||||
|
hC.Add(func(data mockTagsData) error { triggerSequence += "c1"; return nil })
|
||||||
|
hC.PreAdd(func(data mockTagsData) error { triggerSequence += "c2"; return nil })
|
||||||
|
|
||||||
|
scenarios := []struct {
|
||||||
|
data mockTagsData
|
||||||
|
expectedSequence string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
mockTagsData{},
|
||||||
|
"a2f0a1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
mockTagsData{[]string{"missing"}},
|
||||||
|
"a2f0a1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
mockTagsData{[]string{"b2"}},
|
||||||
|
"b2a2f0a1b1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
mockTagsData{[]string{"c1"}},
|
||||||
|
"c2a2f0a1c1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
mockTagsData{[]string{"b1", "c2"}},
|
||||||
|
"c2b2a2f0a1b1c1",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, s := range scenarios {
|
||||||
|
triggerSequence = "" // reset
|
||||||
|
|
||||||
|
err := hA.Trigger(s.data)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("[%d] Unexpected trigger error: %v", i, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if triggerSequence != s.expectedSequence {
|
||||||
|
t.Fatalf("[%d] Expected trigger sequence %s, got %s", i, s.expectedSequence, triggerSequence)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue