Skip to content

Commit

Permalink
Support ndc-spec v0.1.3 (#105) (#106)
Browse files Browse the repository at this point in the history
  • Loading branch information
hgiasac authored May 29, 2024
1 parent 106cd27 commit 2a9d1bb
Show file tree
Hide file tree
Showing 9 changed files with 271 additions and 8 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ All functions of the Connector interface are analogous to their Rust counterpart

## Features

The SDK fully supports [NDC Specification v0.1.2](https://hasura.github.io/ndc-spec/specification/changelog.html#012) and [Connector Deployment spec](https://github.com/hasura/ndc-hub/blob/main/rfcs/0000-deployment.md) with following features:
The SDK fully supports [NDC Specification v0.1.3](https://hasura.github.io/ndc-spec/specification/changelog.html#013) and [Connector Deployment spec](https://github.com/hasura/ndc-hub/blob/main/rfcs/0000-deployment.md) with following features:

- Connector HTTP server
- Authentication
Expand Down
2 changes: 1 addition & 1 deletion cmd/hasura-ndc-go/templates/new/connector.go.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
)

var connectorCapabilities = schema.CapabilitiesResponse{
Version: "0.1.2",
Version: "0.1.3",
Capabilities: schema.Capabilities{
Query: schema.QueryCapabilities{
Variables: schema.LeafCapability{},
Expand Down
2 changes: 1 addition & 1 deletion cmd/hasura-ndc-go/testdata/basic/source/connector.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
)

var connectorCapabilities = schema.CapabilitiesResponse{
Version: "0.1.2",
Version: "0.1.3",
Capabilities: schema.Capabilities{
Query: schema.QueryCapabilities{
Variables: schema.LeafCapability{},
Expand Down
2 changes: 1 addition & 1 deletion cmd/hasura-ndc-go/testdata/empty/source/connector.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
)

var connectorCapabilities = schema.CapabilitiesResponse{
Version: "0.1.2",
Version: "0.1.3",
Capabilities: schema.Capabilities{
Query: schema.QueryCapabilities{
Variables: schema.LeafCapability{},
Expand Down
2 changes: 1 addition & 1 deletion example/codegen/connector.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
)

var connectorCapabilities = schema.CapabilitiesResponse{
Version: "0.1.2",
Version: "0.1.3",
Capabilities: schema.Capabilities{
Query: schema.QueryCapabilities{
Variables: schema.LeafCapability{},
Expand Down
2 changes: 1 addition & 1 deletion example/codegen/testdata/capabilities
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "0.1.2",
"version": "0.1.3",
"capabilities": {
"query": {
"variables": {}
Expand Down
2 changes: 1 addition & 1 deletion example/reference/connector_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
"github.com/hasura/ndc-sdk-go/schema"
)

const test_SpecVersion = "v0.1.2"
const test_SpecVersion = "v0.1.3"

func createTestServer(t *testing.T) *connector.Server[Configuration, State] {
server, err := connector.NewServer[Configuration, State](&Connector{}, &connector.ServerOptions{
Expand Down
196 changes: 195 additions & 1 deletion schema/extend.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,22 @@ type Argument struct {
Value any `json:"value" yaml:"value" mapstructure:"value"`
}

// NewLiteralArgument creates an argument with a literal value
func NewLiteralArgument(value any) *Argument {
return &Argument{
Type: ArgumentTypeLiteral,
Value: value,
}
}

// NewVariableArgument creates an argument with a variable name
func NewVariableArgument(name string) *Argument {
return &Argument{
Type: ArgumentTypeVariable,
Name: name,
}
}

// MarshalJSON implements json.Marshaler.
func (j Argument) MarshalJSON() ([]byte, error) {
result := map[string]any{
Expand Down Expand Up @@ -298,6 +314,14 @@ func (j *Field) UnmarshalJSON(b []byte) error {
}
results["fields"] = fields
}
var arguments map[string]Argument
rawArguments, ok := raw["arguments"]
if ok && !isNullJSON(rawArguments) {
if err = json.Unmarshal(rawArguments, &arguments); err != nil {
return fmt.Errorf("field arguments in Field: %s", err)
}
results["arguments"] = arguments
}
case FieldTypeRelationship:
relationship, err := unmarshalStringFromJsonMap(raw, "relationship", true)
if err != nil {
Expand Down Expand Up @@ -378,6 +402,15 @@ func (j Field) AsColumn() (*ColumnField, error) {
result.Fields = fields
}

rawArguments, ok := j["arguments"]
if ok && !isNil(rawArguments) {
arguments, ok := rawArguments.(map[string]Argument)
if !ok {
return nil, fmt.Errorf("invalid ColumnField.arguments type; expected map[string]Argument, got %+v", rawArguments)
}
result.Arguments = arguments
}

return result, nil
}

Expand Down Expand Up @@ -453,6 +486,8 @@ type ColumnField struct {
// the caller can request a subset of the complete column data, by specifying fields to fetch here.
// If omitted, the column data will be fetched in full.
Fields NestedField `json:"fields,omitempty" yaml:"fields,omitempty" mapstructure:"fields"`

Arguments map[string]Argument `json:"arguments,omitempty" yaml:"arguments,omitempty" mapstructure:"fields"`
}

// Encode converts the instance to raw Field
Expand All @@ -465,6 +500,9 @@ func (f ColumnField) Encode() Field {
if len(f.Fields) > 0 {
r["fields"] = f.Fields
}
if len(f.Arguments) > 0 {
r["arguments"] = f.Arguments
}
return r
}

Expand All @@ -481,6 +519,13 @@ func NewColumnField(column string, fields NestedFieldEncoder) *ColumnField {
}
}

// NewColumnFieldWithArguments creates a new ColumnField instance with arguments
func NewColumnFieldWithArguments(column string, fields NestedFieldEncoder, arguments map[string]Argument) *ColumnField {
cf := NewColumnField(column, fields)
cf.Arguments = arguments
return cf
}

// RelationshipField represents a relationship field
type RelationshipField struct {
Type FieldType `json:"type" yaml:"type" mapstructure:"type"`
Expand Down Expand Up @@ -564,6 +609,25 @@ type ComparisonTarget struct {
FieldPath []string `json:"field_path,omitempty" yaml:"field_path,omitempty" mapstructure:"field_path"`
}

// NewComparisonTargetColumn creates a ComparisonTarget with column type
func NewComparisonTargetColumn(name string, fieldPath []string, path []PathElement) *ComparisonTarget {
return &ComparisonTarget{
Type: ComparisonTargetTypeColumn,
Name: name,
Path: path,
FieldPath: fieldPath,
}
}

// NewComparisonTargetRootCollectionColumn creates a ComparisonTarget with root_collection_column type
func NewComparisonTargetRootCollectionColumn(name string, fieldPath []string) *ComparisonTarget {
return &ComparisonTarget{
Type: ComparisonTargetTypeRootCollectionColumn,
Name: name,
FieldPath: fieldPath,
}
}

// ExpressionType represents the filtering expression enums
type ExpressionType string

Expand Down Expand Up @@ -843,6 +907,14 @@ type ComparisonValueColumn struct {
Column ComparisonTarget `json:"column" yaml:"column" mapstructure:"column"`
}

// NewComparisonValueColumn creates a new ComparisonValueColumn instance
func NewComparisonValueColumn(column ComparisonTarget) *ComparisonValueColumn {
return &ComparisonValueColumn{
Type: ComparisonValueTypeColumn,
Column: column,
}
}

// Encode converts to the raw comparison value
func (cv ComparisonValueColumn) Encode() ComparisonValue {
return map[string]any{
Expand All @@ -857,6 +929,14 @@ type ComparisonValueScalar struct {
Value any `json:"value" yaml:"value" mapstructure:"value"`
}

// NewComparisonValueScalar creates a new ComparisonValueScalar instance
func NewComparisonValueScalar(value any) *ComparisonValueScalar {
return &ComparisonValueScalar{
Type: ComparisonValueTypeScalar,
Value: value,
}
}

// Encode converts to the raw comparison value
func (cv ComparisonValueScalar) Encode() ComparisonValue {
return map[string]any{
Expand All @@ -871,6 +951,14 @@ type ComparisonValueVariable struct {
Name string `json:"name" yaml:"name" mapstructure:"name"`
}

// NewComparisonValueVariable creates a new ComparisonValueVariable instance
func NewComparisonValueVariable(name string) *ComparisonValueVariable {
return &ComparisonValueVariable{
Type: ComparisonValueTypeVariable,
Name: name,
}
}

// Encode converts to the raw comparison value
func (cv ComparisonValueVariable) Encode() ComparisonValue {
return map[string]any{
Expand Down Expand Up @@ -1510,6 +1598,21 @@ type ExpressionAnd struct {
Expressions []Expression `json:"expressions" yaml:"expressions" mapstructure:"expressions"`
}

// NewExpressionAnd creates an ExpressionAnd instance
func NewExpressionAnd(expressions ...ExpressionEncoder) *ExpressionAnd {
exprs := make([]Expression, len(expressions))
for i, expr := range expressions {
if expr == nil {
continue
}
exprs[i] = expr.Encode()
}
return &ExpressionAnd{
Type: ExpressionTypeAnd,
Expressions: exprs,
}
}

// Encode converts the instance to a raw Expression
func (exp ExpressionAnd) Encode() Expression {
return Expression{
Expand All @@ -1526,6 +1629,21 @@ type ExpressionOr struct {
Expressions []Expression `json:"expressions" yaml:"expressions" mapstructure:"expressions"`
}

// NewExpressionOr creates an ExpressionOr instance
func NewExpressionOr(expressions ...ExpressionEncoder) *ExpressionOr {
exprs := make([]Expression, len(expressions))
for i, expr := range expressions {
if expr == nil {
continue
}
exprs[i] = expr.Encode()
}
return &ExpressionOr{
Type: ExpressionTypeOr,
Expressions: exprs,
}
}

// Encode converts the instance to a raw Expression
func (exp ExpressionOr) Encode() Expression {
return Expression{
Expand All @@ -1542,6 +1660,17 @@ type ExpressionNot struct {
Expression Expression `json:"expression" yaml:"expression" mapstructure:"expression"`
}

// NewExpressionNot creates an ExpressionNot instance
func NewExpressionNot(expression ExpressionEncoder) *ExpressionNot {
result := &ExpressionNot{
Type: ExpressionTypeNot,
}
if expression != nil {
result.Expression = expression.Encode()
}
return result
}

// Encode converts the instance to a raw Expression
func (exp ExpressionNot) Encode() Expression {
return Expression{
Expand All @@ -1559,6 +1688,15 @@ type ExpressionUnaryComparisonOperator struct {
Column ComparisonTarget `json:"column" yaml:"column" mapstructure:"column"`
}

// NewExpressionUnaryComparisonOperator creates an ExpressionUnaryComparisonOperator instance
func NewExpressionUnaryComparisonOperator(column ComparisonTarget, operator UnaryComparisonOperator) *ExpressionUnaryComparisonOperator {
return &ExpressionUnaryComparisonOperator{
Type: ExpressionTypeUnaryComparisonOperator,
Column: column,
Operator: operator,
}
}

// Encode converts the instance to a raw Expression
func (exp ExpressionUnaryComparisonOperator) Encode() Expression {
return Expression{
Expand All @@ -1578,6 +1716,19 @@ type ExpressionBinaryComparisonOperator struct {
Value ComparisonValue `json:"value" yaml:"value" mapstructure:"value"`
}

// NewExpressionBinaryComparisonOperator creates an ExpressionBinaryComparisonOperator instance
func NewExpressionBinaryComparisonOperator(column ComparisonTarget, operator string, value ComparisonValueEncoder) *ExpressionBinaryComparisonOperator {
result := &ExpressionBinaryComparisonOperator{
Type: ExpressionTypeBinaryComparisonOperator,
Column: column,
Operator: operator,
}
if value != nil {
result.Value = value.Encode()
}
return result
}

// Encode converts the instance to a raw Expression
func (exp ExpressionBinaryComparisonOperator) Encode() Expression {
return Expression{
Expand All @@ -1597,6 +1748,21 @@ type ExpressionExists struct {
InCollection ExistsInCollection `json:"in_collection" yaml:"in_collection" mapstructure:"in_collection"`
}

// NewExpressionExists creates an ExpressionExists instance
func NewExpressionExists(predicate ExpressionEncoder, inCollection ExistsInCollectionEncoder) *ExpressionExists {
result := &ExpressionExists{
Type: ExpressionTypeExists,
InCollection: inCollection.Encode(),
}
if predicate != nil {
result.Predicate = predicate.Encode()
}
if inCollection != nil {
result.InCollection = inCollection.Encode()
}
return result
}

// Encode converts the instance to a raw Expression
func (exp ExpressionExists) Encode() Expression {
return Expression{
Expand Down Expand Up @@ -2225,7 +2391,17 @@ type OrderByColumn struct {
// Any relationships to traverse to reach this column
Path []PathElement `json:"path" yaml:"path" mapstructure:"path"`
// Any field path to a nested field within the column
FieldPath []string `json:"field_path" yaml:"field_path" mapstructure:"field_path"`
FieldPath []string `json:"field_path,omitempty" yaml:"field_path,omitempty" mapstructure:"field_path"`
}

// NewOrderByColumn creates an OrderByColumn instance
func NewOrderByColumn(name string, fieldPath []string, path []PathElement) *OrderByColumn {
return &OrderByColumn{
Type: OrderByTargetTypeColumn,
Name: name,
FieldPath: fieldPath,
Path: path,
}
}

// Encode converts the instance to raw OrderByTarget
Expand All @@ -2252,6 +2428,16 @@ type OrderBySingleColumnAggregate struct {
Path []PathElement `json:"path" yaml:"path" mapstructure:"path"`
}

// NewOrderBySingleColumnAggregate creates an OrderBySingleColumnAggregate instance
func NewOrderBySingleColumnAggregate(column string, function string, path []PathElement) *OrderBySingleColumnAggregate {
return &OrderBySingleColumnAggregate{
Type: OrderByTargetTypeSingleColumnAggregate,
Column: column,
Function: function,
Path: path,
}
}

// Encode converts the instance to raw OrderByTarget
func (ob OrderBySingleColumnAggregate) Encode() OrderByTarget {
return OrderByTarget{
Expand All @@ -2272,6 +2458,14 @@ type OrderByStarCountAggregate struct {
Path []PathElement `json:"path" yaml:"path" mapstructure:"path"`
}

// NewOrderByStarCountAggregate creates an OrderByStarCountAggregate instance
func NewOrderByStarCountAggregate(path []PathElement) *OrderByStarCountAggregate {
return &OrderByStarCountAggregate{
Type: OrderByTargetTypeStarCountAggregate,
Path: path,
}
}

// Encode converts the instance to raw OrderByTarget
func (ob OrderByStarCountAggregate) Encode() OrderByTarget {
return OrderByTarget{
Expand Down
Loading

0 comments on commit 2a9d1bb

Please sign in to comment.