Share types between API

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
This commit is contained in:
Sacha Al Himdani
2025-08-04 21:41:20 +02:00
parent 4ff71312f9
commit 2ebab9d5cf
9 changed files with 161 additions and 128 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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,
}
}

View File

@@ -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

View File

@@ -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

View File

@@ -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,
}
}

View File

@@ -0,0 +1,44 @@
// Copyright (c) 2025 Probo Inc <hello@getprobo.com>.
//
// 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
}

View File

@@ -0,0 +1,44 @@
// Copyright (c) 2025 Probo Inc <hello@getprobo.com>.
//
// 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
}

View File

@@ -0,0 +1,49 @@
// Copyright (c) 2025 Probo Inc <hello@getprobo.com>.
//
// 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,
}
}