From 2ebab9d5cfabf549c527e7353cbaccd1fe339355 Mon Sep 17 00:00:00 2001 From: Sacha Al Himdani Date: Mon, 4 Aug 2025 21:41:20 +0200 Subject: [PATCH] Share types between API Signed-off-by: Sacha Al Himdani --- pkg/server/api/console/v1/types/cursorkey.go | 27 ++--------- pkg/server/api/console/v1/types/gid.go | 28 ++--------- pkg/server/api/console/v1/types/pageinfo.go | 21 +++------ pkg/server/api/trust/v1/types/cursorkey.go | 27 ++--------- pkg/server/api/trust/v1/types/gid.go | 28 ++--------- pkg/server/api/trust/v1/types/pageinfo.go | 21 +++------ pkg/server/api/types/cursorkey.go | 44 ++++++++++++++++++ pkg/server/api/types/gid.go | 44 ++++++++++++++++++ pkg/server/api/types/pageinfo.go | 49 ++++++++++++++++++++ 9 files changed, 161 insertions(+), 128 deletions(-) create mode 100644 pkg/server/api/types/cursorkey.go create mode 100644 pkg/server/api/types/gid.go create mode 100644 pkg/server/api/types/pageinfo.go diff --git a/pkg/server/api/console/v1/types/cursorkey.go b/pkg/server/api/console/v1/types/cursorkey.go index 00acf530f..e7b1911b5 100644 --- a/pkg/server/api/console/v1/types/cursorkey.go +++ b/pkg/server/api/console/v1/types/cursorkey.go @@ -15,12 +15,8 @@ package types import ( - "errors" - "io" - "strconv" - - "github.com/99designs/gqlgen/graphql" "github.com/getprobo/probo/pkg/page" + sharedTypes "github.com/getprobo/probo/pkg/server/api/types" ) func NewCursor[O page.OrderField]( @@ -49,22 +45,5 @@ func NewCursor[O page.OrderField]( return page.NewCursor(size, from, direction, orderBy) } -func MarshalCursorKeyScalar(ck page.CursorKey) graphql.Marshaler { - return graphql.WriterFunc(func(w io.Writer) { - _, _ = w.Write([]byte(strconv.Quote(ck.String()))) - }) -} - -func UnmarshalCursorKeyScalar(v interface{}) (page.CursorKey, error) { - s, ok := v.(string) - if !ok { - return page.CursorKeyNil, errors.New("must be a string") - } - - ck, err := page.ParseCursorKey(s) - if err != nil { - return page.CursorKeyNil, err - } - - return ck, nil -} +var MarshalCursorKeyScalar = sharedTypes.MarshalCursorKeyScalar +var UnmarshalCursorKeyScalar = sharedTypes.UnmarshalCursorKeyScalar diff --git a/pkg/server/api/console/v1/types/gid.go b/pkg/server/api/console/v1/types/gid.go index 2f7ca1869..90a62b18c 100644 --- a/pkg/server/api/console/v1/types/gid.go +++ b/pkg/server/api/console/v1/types/gid.go @@ -15,30 +15,8 @@ package types import ( - "errors" - "io" - "strconv" - - "github.com/99designs/gqlgen/graphql" - "github.com/getprobo/probo/pkg/gid" + sharedTypes "github.com/getprobo/probo/pkg/server/api/types" ) -func MarshalGIDScalar(id gid.GID) graphql.Marshaler { - return graphql.WriterFunc(func(w io.Writer) { - w.Write([]byte(strconv.Quote(id.String()))) - }) -} - -func UnmarshalGIDScalar(v interface{}) (gid.GID, error) { - s, ok := v.(string) - if !ok { - return gid.Nil, errors.New("must be a string") - } - - id, err := gid.ParseGID(s) - if err != nil { - return gid.Nil, err - } - - return id, nil -} +var MarshalGIDScalar = sharedTypes.MarshalGIDScalar +var UnmarshalGIDScalar = sharedTypes.UnmarshalGIDScalar diff --git a/pkg/server/api/console/v1/types/pageinfo.go b/pkg/server/api/console/v1/types/pageinfo.go index 4dbaa9abb..fce0bb517 100644 --- a/pkg/server/api/console/v1/types/pageinfo.go +++ b/pkg/server/api/console/v1/types/pageinfo.go @@ -15,25 +15,16 @@ package types import ( - "go.gearno.de/x/ref" "github.com/getprobo/probo/pkg/page" + sharedTypes "github.com/getprobo/probo/pkg/server/api/types" ) func NewPageInfo[T page.Paginable[O], O page.OrderField](p *page.Page[T, O]) *PageInfo { - var ( - startCursor *page.CursorKey - endCursor *page.CursorKey - ) - - if len(p.Data) > 0 { - startCursor = ref.Ref(p.First().CursorKey(p.Cursor.OrderBy.Field)) - endCursor = ref.Ref(p.Last().CursorKey(p.Cursor.OrderBy.Field)) - } - + data := sharedTypes.NewPageInfoData(p) return &PageInfo{ - HasNextPage: p.Info.HasNext, - HasPreviousPage: p.Info.HasPrev, - StartCursor: startCursor, - EndCursor: endCursor, + HasNextPage: data.HasNextPage, + HasPreviousPage: data.HasPreviousPage, + StartCursor: data.StartCursor, + EndCursor: data.EndCursor, } } diff --git a/pkg/server/api/trust/v1/types/cursorkey.go b/pkg/server/api/trust/v1/types/cursorkey.go index 00acf530f..e7b1911b5 100644 --- a/pkg/server/api/trust/v1/types/cursorkey.go +++ b/pkg/server/api/trust/v1/types/cursorkey.go @@ -15,12 +15,8 @@ package types import ( - "errors" - "io" - "strconv" - - "github.com/99designs/gqlgen/graphql" "github.com/getprobo/probo/pkg/page" + sharedTypes "github.com/getprobo/probo/pkg/server/api/types" ) func NewCursor[O page.OrderField]( @@ -49,22 +45,5 @@ func NewCursor[O page.OrderField]( return page.NewCursor(size, from, direction, orderBy) } -func MarshalCursorKeyScalar(ck page.CursorKey) graphql.Marshaler { - return graphql.WriterFunc(func(w io.Writer) { - _, _ = w.Write([]byte(strconv.Quote(ck.String()))) - }) -} - -func UnmarshalCursorKeyScalar(v interface{}) (page.CursorKey, error) { - s, ok := v.(string) - if !ok { - return page.CursorKeyNil, errors.New("must be a string") - } - - ck, err := page.ParseCursorKey(s) - if err != nil { - return page.CursorKeyNil, err - } - - return ck, nil -} +var MarshalCursorKeyScalar = sharedTypes.MarshalCursorKeyScalar +var UnmarshalCursorKeyScalar = sharedTypes.UnmarshalCursorKeyScalar diff --git a/pkg/server/api/trust/v1/types/gid.go b/pkg/server/api/trust/v1/types/gid.go index 2f7ca1869..90a62b18c 100644 --- a/pkg/server/api/trust/v1/types/gid.go +++ b/pkg/server/api/trust/v1/types/gid.go @@ -15,30 +15,8 @@ package types import ( - "errors" - "io" - "strconv" - - "github.com/99designs/gqlgen/graphql" - "github.com/getprobo/probo/pkg/gid" + sharedTypes "github.com/getprobo/probo/pkg/server/api/types" ) -func MarshalGIDScalar(id gid.GID) graphql.Marshaler { - return graphql.WriterFunc(func(w io.Writer) { - w.Write([]byte(strconv.Quote(id.String()))) - }) -} - -func UnmarshalGIDScalar(v interface{}) (gid.GID, error) { - s, ok := v.(string) - if !ok { - return gid.Nil, errors.New("must be a string") - } - - id, err := gid.ParseGID(s) - if err != nil { - return gid.Nil, err - } - - return id, nil -} +var MarshalGIDScalar = sharedTypes.MarshalGIDScalar +var UnmarshalGIDScalar = sharedTypes.UnmarshalGIDScalar diff --git a/pkg/server/api/trust/v1/types/pageinfo.go b/pkg/server/api/trust/v1/types/pageinfo.go index bd60d2049..fce0bb517 100644 --- a/pkg/server/api/trust/v1/types/pageinfo.go +++ b/pkg/server/api/trust/v1/types/pageinfo.go @@ -16,24 +16,15 @@ package types import ( "github.com/getprobo/probo/pkg/page" - "go.gearno.de/x/ref" + sharedTypes "github.com/getprobo/probo/pkg/server/api/types" ) func NewPageInfo[T page.Paginable[O], O page.OrderField](p *page.Page[T, O]) *PageInfo { - var ( - startCursor *page.CursorKey - endCursor *page.CursorKey - ) - - if len(p.Data) > 0 { - startCursor = ref.Ref(p.First().CursorKey(p.Cursor.OrderBy.Field)) - endCursor = ref.Ref(p.Last().CursorKey(p.Cursor.OrderBy.Field)) - } - + data := sharedTypes.NewPageInfoData(p) return &PageInfo{ - HasNextPage: p.Info.HasNext, - HasPreviousPage: p.Info.HasPrev, - StartCursor: startCursor, - EndCursor: endCursor, + HasNextPage: data.HasNextPage, + HasPreviousPage: data.HasPreviousPage, + StartCursor: data.StartCursor, + EndCursor: data.EndCursor, } } diff --git a/pkg/server/api/types/cursorkey.go b/pkg/server/api/types/cursorkey.go new file mode 100644 index 000000000..7aecddfda --- /dev/null +++ b/pkg/server/api/types/cursorkey.go @@ -0,0 +1,44 @@ +// Copyright (c) 2025 Probo Inc . +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +package types + +import ( + "errors" + "io" + "strconv" + + "github.com/99designs/gqlgen/graphql" + "github.com/getprobo/probo/pkg/page" +) + +func MarshalCursorKeyScalar(ck page.CursorKey) graphql.Marshaler { + return graphql.WriterFunc(func(w io.Writer) { + _, _ = w.Write([]byte(strconv.Quote(ck.String()))) + }) +} + +func UnmarshalCursorKeyScalar(v interface{}) (page.CursorKey, error) { + s, ok := v.(string) + if !ok { + return page.CursorKeyNil, errors.New("must be a string") + } + + ck, err := page.ParseCursorKey(s) + if err != nil { + return page.CursorKeyNil, err + } + + return ck, nil +} diff --git a/pkg/server/api/types/gid.go b/pkg/server/api/types/gid.go new file mode 100644 index 000000000..2f7ca1869 --- /dev/null +++ b/pkg/server/api/types/gid.go @@ -0,0 +1,44 @@ +// Copyright (c) 2025 Probo Inc . +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +package types + +import ( + "errors" + "io" + "strconv" + + "github.com/99designs/gqlgen/graphql" + "github.com/getprobo/probo/pkg/gid" +) + +func MarshalGIDScalar(id gid.GID) graphql.Marshaler { + return graphql.WriterFunc(func(w io.Writer) { + w.Write([]byte(strconv.Quote(id.String()))) + }) +} + +func UnmarshalGIDScalar(v interface{}) (gid.GID, error) { + s, ok := v.(string) + if !ok { + return gid.Nil, errors.New("must be a string") + } + + id, err := gid.ParseGID(s) + if err != nil { + return gid.Nil, err + } + + return id, nil +} diff --git a/pkg/server/api/types/pageinfo.go b/pkg/server/api/types/pageinfo.go new file mode 100644 index 000000000..57919dd8c --- /dev/null +++ b/pkg/server/api/types/pageinfo.go @@ -0,0 +1,49 @@ +// Copyright (c) 2025 Probo Inc . +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +package types + +import ( + "github.com/getprobo/probo/pkg/page" + "go.gearno.de/x/ref" +) + +// PageInfoData contains the raw data for constructing PageInfo structs +type PageInfoData struct { + HasNextPage bool + HasPreviousPage bool + StartCursor *page.CursorKey + EndCursor *page.CursorKey +} + +// NewPageInfoData creates PageInfo data from a Page result. +// This can be used by local packages to construct their PageInfo structs. +func NewPageInfoData[T page.Paginable[O], O page.OrderField](p *page.Page[T, O]) PageInfoData { + var ( + startCursor *page.CursorKey + endCursor *page.CursorKey + ) + + if len(p.Data) > 0 { + startCursor = ref.Ref(p.First().CursorKey(p.Cursor.OrderBy.Field)) + endCursor = ref.Ref(p.Last().CursorKey(p.Cursor.OrderBy.Field)) + } + + return PageInfoData{ + HasNextPage: p.Info.HasNext, + HasPreviousPage: p.Info.HasPrev, + StartCursor: startCursor, + EndCursor: endCursor, + } +}