Share types between API
Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
This commit is contained in:
@@ -15,12 +15,8 @@
|
|||||||
package types
|
package types
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"io"
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"github.com/99designs/gqlgen/graphql"
|
|
||||||
"github.com/getprobo/probo/pkg/page"
|
"github.com/getprobo/probo/pkg/page"
|
||||||
|
sharedTypes "github.com/getprobo/probo/pkg/server/api/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewCursor[O page.OrderField](
|
func NewCursor[O page.OrderField](
|
||||||
@@ -49,22 +45,5 @@ func NewCursor[O page.OrderField](
|
|||||||
return page.NewCursor(size, from, direction, orderBy)
|
return page.NewCursor(size, from, direction, orderBy)
|
||||||
}
|
}
|
||||||
|
|
||||||
func MarshalCursorKeyScalar(ck page.CursorKey) graphql.Marshaler {
|
var MarshalCursorKeyScalar = sharedTypes.MarshalCursorKeyScalar
|
||||||
return graphql.WriterFunc(func(w io.Writer) {
|
var UnmarshalCursorKeyScalar = sharedTypes.UnmarshalCursorKeyScalar
|
||||||
_, _ = 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
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -15,30 +15,8 @@
|
|||||||
package types
|
package types
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
sharedTypes "github.com/getprobo/probo/pkg/server/api/types"
|
||||||
"io"
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"github.com/99designs/gqlgen/graphql"
|
|
||||||
"github.com/getprobo/probo/pkg/gid"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func MarshalGIDScalar(id gid.GID) graphql.Marshaler {
|
var MarshalGIDScalar = sharedTypes.MarshalGIDScalar
|
||||||
return graphql.WriterFunc(func(w io.Writer) {
|
var UnmarshalGIDScalar = sharedTypes.UnmarshalGIDScalar
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -15,25 +15,16 @@
|
|||||||
package types
|
package types
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"go.gearno.de/x/ref"
|
|
||||||
"github.com/getprobo/probo/pkg/page"
|
"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 {
|
func NewPageInfo[T page.Paginable[O], O page.OrderField](p *page.Page[T, O]) *PageInfo {
|
||||||
var (
|
data := sharedTypes.NewPageInfoData(p)
|
||||||
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 &PageInfo{
|
return &PageInfo{
|
||||||
HasNextPage: p.Info.HasNext,
|
HasNextPage: data.HasNextPage,
|
||||||
HasPreviousPage: p.Info.HasPrev,
|
HasPreviousPage: data.HasPreviousPage,
|
||||||
StartCursor: startCursor,
|
StartCursor: data.StartCursor,
|
||||||
EndCursor: endCursor,
|
EndCursor: data.EndCursor,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,12 +15,8 @@
|
|||||||
package types
|
package types
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"io"
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"github.com/99designs/gqlgen/graphql"
|
|
||||||
"github.com/getprobo/probo/pkg/page"
|
"github.com/getprobo/probo/pkg/page"
|
||||||
|
sharedTypes "github.com/getprobo/probo/pkg/server/api/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewCursor[O page.OrderField](
|
func NewCursor[O page.OrderField](
|
||||||
@@ -49,22 +45,5 @@ func NewCursor[O page.OrderField](
|
|||||||
return page.NewCursor(size, from, direction, orderBy)
|
return page.NewCursor(size, from, direction, orderBy)
|
||||||
}
|
}
|
||||||
|
|
||||||
func MarshalCursorKeyScalar(ck page.CursorKey) graphql.Marshaler {
|
var MarshalCursorKeyScalar = sharedTypes.MarshalCursorKeyScalar
|
||||||
return graphql.WriterFunc(func(w io.Writer) {
|
var UnmarshalCursorKeyScalar = sharedTypes.UnmarshalCursorKeyScalar
|
||||||
_, _ = 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
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -15,30 +15,8 @@
|
|||||||
package types
|
package types
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
sharedTypes "github.com/getprobo/probo/pkg/server/api/types"
|
||||||
"io"
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"github.com/99designs/gqlgen/graphql"
|
|
||||||
"github.com/getprobo/probo/pkg/gid"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func MarshalGIDScalar(id gid.GID) graphql.Marshaler {
|
var MarshalGIDScalar = sharedTypes.MarshalGIDScalar
|
||||||
return graphql.WriterFunc(func(w io.Writer) {
|
var UnmarshalGIDScalar = sharedTypes.UnmarshalGIDScalar
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -16,24 +16,15 @@ package types
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/getprobo/probo/pkg/page"
|
"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 {
|
func NewPageInfo[T page.Paginable[O], O page.OrderField](p *page.Page[T, O]) *PageInfo {
|
||||||
var (
|
data := sharedTypes.NewPageInfoData(p)
|
||||||
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 &PageInfo{
|
return &PageInfo{
|
||||||
HasNextPage: p.Info.HasNext,
|
HasNextPage: data.HasNextPage,
|
||||||
HasPreviousPage: p.Info.HasPrev,
|
HasPreviousPage: data.HasPreviousPage,
|
||||||
StartCursor: startCursor,
|
StartCursor: data.StartCursor,
|
||||||
EndCursor: endCursor,
|
EndCursor: data.EndCursor,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
44
pkg/server/api/types/cursorkey.go
Normal file
44
pkg/server/api/types/cursorkey.go
Normal 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
|
||||||
|
}
|
||||||
44
pkg/server/api/types/gid.go
Normal file
44
pkg/server/api/types/gid.go
Normal 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
|
||||||
|
}
|
||||||
49
pkg/server/api/types/pageinfo.go
Normal file
49
pkg/server/api/types/pageinfo.go
Normal 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,
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user