mirror of
https://github.com/pocketbase/pocketbase.git
synced 2025-04-17 22:16:24 +02:00
added custom goja field mapper to handle all caps identifiers and allowed errors unwrapping
This commit is contained in:
parent
799e1d96f8
commit
0fa5edb0b1
@ -105,6 +105,8 @@
|
|||||||
|
|
||||||
- Fixed concurrent multi-relation cascade update/delete ([#1138](https://github.com/pocketbase/pocketbase/issues/1138)).
|
- Fixed concurrent multi-relation cascade update/delete ([#1138](https://github.com/pocketbase/pocketbase/issues/1138)).
|
||||||
|
|
||||||
|
- Added the raw OAuth2 user data (`meta.rawUser`) and OAuth2 access token (`meta.accessToken`) to the auth response ([#654](https://github.com/pocketbase/pocketbase/discussions/654)).
|
||||||
|
|
||||||
|
|
||||||
## v0.8.0
|
## v0.8.0
|
||||||
|
|
||||||
|
@ -231,7 +231,7 @@ func (api *recordAuthApi) authWithOAuth2(c echo.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if _, err := txDao.FindRecordById(collection.Id, createForm.Id, createRuleFunc); err != nil {
|
if _, err := txDao.FindRecordById(collection.Id, createForm.Id, createRuleFunc); err != nil {
|
||||||
return fmt.Errorf("Failed create rule constraint: %v", err)
|
return fmt.Errorf("Failed create rule constraint: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -191,7 +191,7 @@ func (api *recordApi) create(c echo.Context) error {
|
|||||||
testErr := testForm.DrySubmit(func(txDao *daos.Dao) error {
|
testErr := testForm.DrySubmit(func(txDao *daos.Dao) error {
|
||||||
foundRecord, err := txDao.FindRecordById(collection.Id, testRecord.Id, createRuleFunc)
|
foundRecord, err := txDao.FindRecordById(collection.Id, testRecord.Id, createRuleFunc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("DrySubmit create rule failure: %v", err)
|
return fmt.Errorf("DrySubmit create rule failure: %w", err)
|
||||||
}
|
}
|
||||||
hasFullManageAccess = hasAuthManageAccess(txDao, foundRecord, requestData)
|
hasFullManageAccess = hasAuthManageAccess(txDao, foundRecord, requestData)
|
||||||
return nil
|
return nil
|
||||||
|
@ -62,7 +62,7 @@ func EnrichRecords(c echo.Context, dao *daos.Dao, records []*models.Record, defa
|
|||||||
requestData := RequestData(c)
|
requestData := RequestData(c)
|
||||||
|
|
||||||
if err := autoIgnoreAuthRecordsEmailVisibility(dao, records, requestData); err != nil {
|
if err := autoIgnoreAuthRecordsEmailVisibility(dao, records, requestData); err != nil {
|
||||||
return fmt.Errorf("Failed to resolve email visibility: %v", err)
|
return fmt.Errorf("Failed to resolve email visibility: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
expands := defaultExpands
|
expands := defaultExpands
|
||||||
|
@ -324,7 +324,7 @@ func (dao *Dao) SaveRecord(record *models.Record) error {
|
|||||||
// This is to make sure that the filter `@request.auth.id` always returns a unique id.
|
// This is to make sure that the filter `@request.auth.id` always returns a unique id.
|
||||||
authCollections, err := dao.FindCollectionsByType(models.CollectionTypeAuth)
|
authCollections, err := dao.FindCollectionsByType(models.CollectionTypeAuth)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Unable to fetch the auth collections for cross-id unique check: %v", err)
|
return fmt.Errorf("Unable to fetch the auth collections for cross-id unique check: %w", err)
|
||||||
}
|
}
|
||||||
for _, collection := range authCollections {
|
for _, collection := range authCollections {
|
||||||
if record.Collection().Id == collection.Id {
|
if record.Collection().Id == collection.Id {
|
||||||
|
@ -651,12 +651,12 @@ func (form *RecordUpsert) Submit(interceptors ...InterceptorFunc) error {
|
|||||||
return form.dao.RunInTransaction(func(txDao *daos.Dao) error {
|
return form.dao.RunInTransaction(func(txDao *daos.Dao) error {
|
||||||
// persist record model
|
// persist record model
|
||||||
if err := txDao.SaveRecord(form.record); err != nil {
|
if err := txDao.SaveRecord(form.record); err != nil {
|
||||||
return fmt.Errorf("Failed to save the record: %v", err)
|
return fmt.Errorf("Failed to save the record: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// upload new files (if any)
|
// upload new files (if any)
|
||||||
if err := form.processFilesToUpload(); err != nil {
|
if err := form.processFilesToUpload(); err != nil {
|
||||||
return fmt.Errorf("Failed to process the upload files: %v", err)
|
return fmt.Errorf("Failed to process the upload files: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete old files (if any)
|
// delete old files (if any)
|
||||||
|
@ -2,6 +2,9 @@ package jsvm
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
"unicode"
|
||||||
|
|
||||||
"github.com/dop251/goja"
|
"github.com/dop251/goja"
|
||||||
"github.com/pocketbase/dbx"
|
"github.com/pocketbase/dbx"
|
||||||
@ -14,7 +17,7 @@ import (
|
|||||||
|
|
||||||
func NewBaseVM(app core.App) *goja.Runtime {
|
func NewBaseVM(app core.App) *goja.Runtime {
|
||||||
vm := goja.New()
|
vm := goja.New()
|
||||||
vm.SetFieldNameMapper(goja.UncapFieldNameMapper())
|
vm.SetFieldNameMapper(fieldMapper{})
|
||||||
vm.Set("$app", app)
|
vm.Set("$app", app)
|
||||||
|
|
||||||
baseBind(vm)
|
baseBind(vm)
|
||||||
@ -137,3 +140,38 @@ func apisBind(vm *goja.Runtime) {
|
|||||||
obj.Set("enrichRecord", apis.EnrichRecord)
|
obj.Set("enrichRecord", apis.EnrichRecord)
|
||||||
obj.Set("enrichRecords", apis.EnrichRecords)
|
obj.Set("enrichRecords", apis.EnrichRecords)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fieldMapper provides custom mapping between Go and JavaScript property names.
|
||||||
|
//
|
||||||
|
// It is similar to the builtin "uncapFieldNameMapper" but also converts
|
||||||
|
// all uppercase identifiers to their lowercase equivalent (eg. "GET" -> "get").
|
||||||
|
type fieldMapper struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
// FieldName implements the [FieldNameMapper.FieldName] interface method.
|
||||||
|
func (u fieldMapper) FieldName(_ reflect.Type, f reflect.StructField) string {
|
||||||
|
return convertGoToJSName(f.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MethodName implements the [FieldNameMapper.MethodName] interface method.
|
||||||
|
func (u fieldMapper) MethodName(_ reflect.Type, m reflect.Method) string {
|
||||||
|
return convertGoToJSName(m.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func convertGoToJSName(name string) string {
|
||||||
|
allUppercase := true
|
||||||
|
for _, c := range name {
|
||||||
|
if !unicode.IsUpper(c) {
|
||||||
|
allUppercase = false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// eg. "JSON" -> "json"
|
||||||
|
if allUppercase {
|
||||||
|
return strings.ToLower(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// eg. "GetField" -> "getField"
|
||||||
|
return strings.ToLower(name[0:1]) + name[1:]
|
||||||
|
}
|
||||||
|
@ -43,7 +43,7 @@ func (p *plugin) afterCollectionChange() func(*core.ModelEvent) error {
|
|||||||
template, templateErr = p.goDiffTemplate(new, old)
|
template, templateErr = p.goDiffTemplate(new, old)
|
||||||
}
|
}
|
||||||
if templateErr != nil {
|
if templateErr != nil {
|
||||||
return fmt.Errorf("failed to resolve template: %v", templateErr)
|
return fmt.Errorf("failed to resolve template: %w", templateErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
var action string
|
var action string
|
||||||
@ -61,11 +61,11 @@ func (p *plugin) afterCollectionChange() func(*core.ModelEvent) error {
|
|||||||
|
|
||||||
// ensure that the local migrations dir exist
|
// ensure that the local migrations dir exist
|
||||||
if err := os.MkdirAll(p.options.Dir, os.ModePerm); err != nil {
|
if err := os.MkdirAll(p.options.Dir, os.ModePerm); err != nil {
|
||||||
return fmt.Errorf("failed to create migration dir: %v", err)
|
return fmt.Errorf("failed to create migration dir: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := os.WriteFile(fileDest, []byte(template), 0644); err != nil {
|
if err := os.WriteFile(fileDest, []byte(template), 0644); err != nil {
|
||||||
return fmt.Errorf("failed to save automigrate file: %v", err)
|
return fmt.Errorf("failed to save automigrate file: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
p.refreshCachedCollections()
|
p.refreshCachedCollections()
|
||||||
|
@ -35,7 +35,7 @@ func (p *plugin) jsBlankTemplate() (string, error) {
|
|||||||
func (p *plugin) jsSnapshotTemplate(collections []*models.Collection) (string, error) {
|
func (p *plugin) jsSnapshotTemplate(collections []*models.Collection) (string, error) {
|
||||||
jsonData, err := marhshalWithoutEscape(collections, " ", " ")
|
jsonData, err := marhshalWithoutEscape(collections, " ", " ")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("failed to serialize collections list: %v", err)
|
return "", fmt.Errorf("failed to serialize collections list: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
const template = `migrate((db) => {
|
const template = `migrate((db) => {
|
||||||
@ -55,7 +55,7 @@ func (p *plugin) jsSnapshotTemplate(collections []*models.Collection) (string, e
|
|||||||
func (p *plugin) jsCreateTemplate(collection *models.Collection) (string, error) {
|
func (p *plugin) jsCreateTemplate(collection *models.Collection) (string, error) {
|
||||||
jsonData, err := marhshalWithoutEscape(collection, " ", " ")
|
jsonData, err := marhshalWithoutEscape(collection, " ", " ")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("failed to serialize collections list: %v", err)
|
return "", fmt.Errorf("failed to serialize collections list: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
const template = `migrate((db) => {
|
const template = `migrate((db) => {
|
||||||
@ -76,7 +76,7 @@ func (p *plugin) jsCreateTemplate(collection *models.Collection) (string, error)
|
|||||||
func (p *plugin) jsDeleteTemplate(collection *models.Collection) (string, error) {
|
func (p *plugin) jsDeleteTemplate(collection *models.Collection) (string, error) {
|
||||||
jsonData, err := marhshalWithoutEscape(collection, " ", " ")
|
jsonData, err := marhshalWithoutEscape(collection, " ", " ")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("failed to serialize collections list: %v", err)
|
return "", fmt.Errorf("failed to serialize collections list: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
const template = `migrate((db) => {
|
const template = `migrate((db) => {
|
||||||
@ -329,7 +329,7 @@ func init() {
|
|||||||
func (p *plugin) goSnapshotTemplate(collections []*models.Collection) (string, error) {
|
func (p *plugin) goSnapshotTemplate(collections []*models.Collection) (string, error) {
|
||||||
jsonData, err := marhshalWithoutEscape(collections, "\t\t", "\t")
|
jsonData, err := marhshalWithoutEscape(collections, "\t\t", "\t")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("failed to serialize collections list: %v", err)
|
return "", fmt.Errorf("failed to serialize collections list: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
const template = `package %s
|
const template = `package %s
|
||||||
@ -368,7 +368,7 @@ func init() {
|
|||||||
func (p *plugin) goCreateTemplate(collection *models.Collection) (string, error) {
|
func (p *plugin) goCreateTemplate(collection *models.Collection) (string, error) {
|
||||||
jsonData, err := marhshalWithoutEscape(collection, "\t\t", "\t")
|
jsonData, err := marhshalWithoutEscape(collection, "\t\t", "\t")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("failed to serialize collections list: %v", err)
|
return "", fmt.Errorf("failed to serialize collections list: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
const template = `package %s
|
const template = `package %s
|
||||||
@ -416,7 +416,7 @@ func init() {
|
|||||||
func (p *plugin) goDeleteTemplate(collection *models.Collection) (string, error) {
|
func (p *plugin) goDeleteTemplate(collection *models.Collection) (string, error) {
|
||||||
jsonData, err := marhshalWithoutEscape(collection, "\t\t", "\t")
|
jsonData, err := marhshalWithoutEscape(collection, "\t\t", "\t")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("failed to serialize collections list: %v", err)
|
return "", fmt.Errorf("failed to serialize collections list: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
const template = `package %s
|
const template = `package %s
|
||||||
|
Loading…
x
Reference in New Issue
Block a user