[#943] exposed apis.EnrichRecord and apis.EnrichRecords
This commit is contained in:
@@ -52,10 +52,11 @@ type RecordFieldResolver struct {
|
||||
baseCollection *models.Collection
|
||||
allowHiddenFields bool
|
||||
allowedFields []string
|
||||
requestData map[string]any
|
||||
loadedCollections []*models.Collection
|
||||
joins []join // we cannot use a map because the insertion order is not preserved
|
||||
exprs []dbx.Expression
|
||||
requestData *models.FilterRequestData
|
||||
staticRequestData map[string]any
|
||||
}
|
||||
|
||||
// NewRecordFieldResolver creates and initializes a new `RecordFieldResolver`.
|
||||
@@ -66,10 +67,10 @@ type RecordFieldResolver struct {
|
||||
func NewRecordFieldResolver(
|
||||
dao *daos.Dao,
|
||||
baseCollection *models.Collection,
|
||||
requestData map[string]any,
|
||||
requestData *models.FilterRequestData,
|
||||
allowHiddenFields bool,
|
||||
) *RecordFieldResolver {
|
||||
return &RecordFieldResolver{
|
||||
r := &RecordFieldResolver{
|
||||
dao: dao,
|
||||
baseCollection: baseCollection,
|
||||
requestData: requestData,
|
||||
@@ -86,6 +87,22 @@ func NewRecordFieldResolver(
|
||||
`^\@collection\.\w+\.\w+[\w\.]*$`,
|
||||
},
|
||||
}
|
||||
|
||||
// @todo remove after IN operator and multi-match filter enhancements
|
||||
r.staticRequestData = map[string]any{}
|
||||
if r.requestData != nil {
|
||||
r.staticRequestData["method"] = r.requestData.Method
|
||||
r.staticRequestData["query"] = r.requestData.Query
|
||||
r.staticRequestData["data"] = r.requestData.Data
|
||||
r.staticRequestData["auth"] = nil
|
||||
if r.requestData.AuthRecord != nil {
|
||||
r.requestData.AuthRecord.IgnoreEmailVisibility(true)
|
||||
r.staticRequestData["auth"] = r.requestData.AuthRecord.PublicExport()
|
||||
r.requestData.AuthRecord.IgnoreEmailVisibility(false)
|
||||
}
|
||||
}
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
// UpdateQuery implements `search.FieldResolver` interface.
|
||||
@@ -159,6 +176,10 @@ func (r *RecordFieldResolver) Resolve(fieldName string) (resultName string, plac
|
||||
return "", nil, fmt.Errorf("Invalid @request data field path in %q.", fieldName)
|
||||
}
|
||||
|
||||
if r.requestData == nil {
|
||||
return "NULL", nil, nil
|
||||
}
|
||||
|
||||
// plain @request.* field
|
||||
if !strings.HasPrefix(fieldName, "@request.auth.") || list.ExistInSlice(fieldName, plainRequestAuthFields) {
|
||||
return r.resolveStaticRequestField(props[1:]...)
|
||||
@@ -173,28 +194,18 @@ func (r *RecordFieldResolver) Resolve(fieldName string) (resultName string, plac
|
||||
|
||||
// resolve the auth collection fields
|
||||
// ---
|
||||
rawAuthRecordId, _ := extractNestedMapVal(r.requestData, "auth", "id")
|
||||
authRecordId := cast.ToString(rawAuthRecordId)
|
||||
if authRecordId == "" {
|
||||
if r.requestData == nil || r.requestData.AuthRecord == nil || r.requestData.AuthRecord.Collection() == nil {
|
||||
return "NULL", nil, nil
|
||||
}
|
||||
|
||||
rawAuthCollectionId, _ := extractNestedMapVal(r.requestData, "auth", schema.FieldNameCollectionId)
|
||||
authCollectionId := cast.ToString(rawAuthCollectionId)
|
||||
if authCollectionId == "" {
|
||||
return "NULL", nil, nil
|
||||
}
|
||||
|
||||
collection, err := r.loadCollection(authCollectionId)
|
||||
if err != nil {
|
||||
return "", nil, fmt.Errorf("Failed to load collection %q from field path %q.", currentCollectionName, fieldName)
|
||||
}
|
||||
collection := r.requestData.AuthRecord.Collection()
|
||||
r.loadedCollections = append(r.loadedCollections, collection)
|
||||
|
||||
currentCollectionName = collection.Name
|
||||
currentTableAlias = "__auth_" + inflector.Columnify(currentCollectionName)
|
||||
|
||||
authIdParamKey := "auth" + security.PseudorandomString(5)
|
||||
authIdParams := dbx.Params{authIdParamKey: authRecordId}
|
||||
authIdParams := dbx.Params{authIdParamKey: r.requestData.AuthRecord.Id}
|
||||
// ---
|
||||
|
||||
// join the auth collection
|
||||
@@ -331,7 +342,7 @@ func (r *RecordFieldResolver) Resolve(fieldName string) (resultName string, plac
|
||||
func (r *RecordFieldResolver) resolveStaticRequestField(path ...string) (resultName string, placeholderParams dbx.Params, err error) {
|
||||
// ignore error because requestData is dynamic and some of the
|
||||
// lookup keys may not be defined for the request
|
||||
resultVal, _ := extractNestedMapVal(r.requestData, path...)
|
||||
resultVal, _ := extractNestedMapVal(r.staticRequestData, path...)
|
||||
|
||||
switch v := resultVal.(type) {
|
||||
case nil:
|
||||
@@ -387,7 +398,7 @@ func extractNestedMapVal(m map[string]any, keys ...string) (result any, err erro
|
||||
func (r *RecordFieldResolver) loadCollection(collectionNameOrId string) (*models.Collection, error) {
|
||||
// return already loaded
|
||||
for _, collection := range r.loadedCollections {
|
||||
if collection.Name == collectionNameOrId || collection.Id == collectionNameOrId {
|
||||
if collection.Id == collectionNameOrId || strings.EqualFold(collection.Name, collectionNameOrId) {
|
||||
return collection, nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"regexp"
|
||||
"testing"
|
||||
|
||||
"github.com/pocketbase/pocketbase/models"
|
||||
"github.com/pocketbase/pocketbase/resolvers"
|
||||
"github.com/pocketbase/pocketbase/tests"
|
||||
"github.com/pocketbase/pocketbase/tools/list"
|
||||
@@ -19,8 +20,8 @@ func TestRecordFieldResolverUpdateQuery(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
requestData := map[string]any{
|
||||
"auth": authRecord.PublicExport(),
|
||||
requestData := &models.FilterRequestData{
|
||||
AuthRecord: authRecord,
|
||||
}
|
||||
|
||||
scenarios := []struct {
|
||||
@@ -181,8 +182,8 @@ func TestRecordFieldResolverResolveSchemaFields(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
requestData := map[string]any{
|
||||
"auth": authRecord.PublicExport(),
|
||||
requestData := &models.FilterRequestData{
|
||||
AuthRecord: authRecord,
|
||||
}
|
||||
|
||||
r := resolvers.NewRecordFieldResolver(app.Dao(), collection, requestData, true)
|
||||
@@ -262,16 +263,16 @@ func TestRecordFieldResolverResolveStaticRequestDataFields(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
requestData := map[string]any{
|
||||
"method": "get",
|
||||
"query": map[string]any{
|
||||
requestData := &models.FilterRequestData{
|
||||
Method: "get",
|
||||
Query: map[string]any{
|
||||
"a": 123,
|
||||
},
|
||||
"data": map[string]any{
|
||||
Data: map[string]any{
|
||||
"b": 456,
|
||||
"c": map[string]int{"sub": 1},
|
||||
},
|
||||
"user": authRecord.PublicExport(),
|
||||
AuthRecord: authRecord,
|
||||
}
|
||||
|
||||
r := resolvers.NewRecordFieldResolver(app.Dao(), collection, requestData, true)
|
||||
@@ -295,7 +296,11 @@ func TestRecordFieldResolverResolveStaticRequestDataFields(t *testing.T) {
|
||||
{"@request.data.c", false, `"{\"sub\":1}"`},
|
||||
{"@request.auth", true, ""},
|
||||
{"@request.auth.id", false, `"4q1xlclmfloku33"`},
|
||||
{"@request.auth.file", false, `"[]"`},
|
||||
{"@request.auth.email", false, `"test@example.com"`},
|
||||
{"@request.auth.username", false, `"users75657"`},
|
||||
{"@request.auth.verified", false, `false`},
|
||||
{"@request.auth.emailVisibility", false, `false`},
|
||||
{"@request.auth.missing", false, `NULL`},
|
||||
}
|
||||
|
||||
for i, s := range scenarios {
|
||||
@@ -315,7 +320,7 @@ func TestRecordFieldResolverResolveStaticRequestDataFields(t *testing.T) {
|
||||
// ---
|
||||
if len(params) == 0 {
|
||||
if name != "NULL" {
|
||||
t.Errorf("(%d) Expected 0 placeholder parameters, got %v", i, params)
|
||||
t.Errorf("(%d) Expected 0 placeholder parameters for %v, got %v", i, name, params)
|
||||
}
|
||||
continue
|
||||
}
|
||||
@@ -323,7 +328,7 @@ func TestRecordFieldResolverResolveStaticRequestDataFields(t *testing.T) {
|
||||
// existing key
|
||||
// ---
|
||||
if len(params) != 1 {
|
||||
t.Errorf("(%d) Expected 1 placeholder parameter, got %v", i, params)
|
||||
t.Errorf("(%d) Expected 1 placeholder parameter for %v, got %v", i, name, params)
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -340,7 +345,7 @@ func TestRecordFieldResolverResolveStaticRequestDataFields(t *testing.T) {
|
||||
|
||||
encodedParamValue, _ := json.Marshal(paramValue)
|
||||
if string(encodedParamValue) != s.expectParamValue {
|
||||
t.Errorf("(%d) Expected params %v, got %v", i, s.expectParamValue, string(encodedParamValue))
|
||||
t.Errorf("(%d) Expected params %v for %v, got %v", i, s.expectParamValue, name, string(encodedParamValue))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user