From c3277d2eb430b48102a12a8439ea4f8ce45def1d Mon Sep 17 00:00:00 2001 From: Toan Nguyen Date: Fri, 5 Apr 2024 14:26:03 +0700 Subject: [PATCH] update capabilities v0.1.2 (#64) --- README.md | 2 +- .../templates/new/connector.go.tmpl | 2 +- .../testdata/basic/source/connector.go | 2 +- example/codegen/connector.go | 2 +- example/codegen/testdata/capabilities | 4 +- example/codegen/testdata/schema | 181 +++++---- example/reference/connector.go | 2 +- example/reference/connector_test.go | 13 +- example/reference/testdata/capabilities | 14 + example/reference/testdata/schema | 350 ++++++++++++++++++ 10 files changed, 490 insertions(+), 82 deletions(-) create mode 100644 example/reference/testdata/capabilities create mode 100644 example/reference/testdata/schema diff --git a/README.md b/README.md index 6fd77ba..7d7baf6 100644 --- a/README.md +++ b/README.md @@ -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.1](https://hasura.github.io/ndc-spec/specification/changelog.html#011) 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.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: - Connector HTTP server - Authentication diff --git a/cmd/ndc-go-sdk/templates/new/connector.go.tmpl b/cmd/ndc-go-sdk/templates/new/connector.go.tmpl index e41d9c3..5b84c90 100644 --- a/cmd/ndc-go-sdk/templates/new/connector.go.tmpl +++ b/cmd/ndc-go-sdk/templates/new/connector.go.tmpl @@ -9,7 +9,7 @@ import ( ) var connectorCapabilities = schema.CapabilitiesResponse{ - Version: "0.1.1", + Version: "0.1.2", Capabilities: schema.Capabilities{ Query: schema.QueryCapabilities{ Variables: schema.LeafCapability{}, diff --git a/cmd/ndc-go-sdk/testdata/basic/source/connector.go b/cmd/ndc-go-sdk/testdata/basic/source/connector.go index 33e97e4..77d3bf1 100644 --- a/cmd/ndc-go-sdk/testdata/basic/source/connector.go +++ b/cmd/ndc-go-sdk/testdata/basic/source/connector.go @@ -9,7 +9,7 @@ import ( ) var connectorCapabilities = schema.CapabilitiesResponse{ - Version: "0.1.1", + Version: "0.1.2", Capabilities: schema.Capabilities{ Query: schema.QueryCapabilities{ Variables: schema.LeafCapability{}, diff --git a/example/codegen/connector.go b/example/codegen/connector.go index 537a374..bbf6c38 100644 --- a/example/codegen/connector.go +++ b/example/codegen/connector.go @@ -9,7 +9,7 @@ import ( ) var connectorCapabilities = schema.CapabilitiesResponse{ - Version: "0.1.1", + Version: "0.1.2", Capabilities: schema.Capabilities{ Query: schema.QueryCapabilities{ Variables: schema.LeafCapability{}, diff --git a/example/codegen/testdata/capabilities b/example/codegen/testdata/capabilities index 3435587..9ca52fb 100644 --- a/example/codegen/testdata/capabilities +++ b/example/codegen/testdata/capabilities @@ -1,9 +1,9 @@ { - "version": "0.1.1", + "version": "0.1.2", "capabilities": { "query": { "variables": {} }, "mutation": {} } -} \ No newline at end of file +} diff --git a/example/codegen/testdata/schema b/example/codegen/testdata/schema index 608f038..550cb1c 100644 --- a/example/codegen/testdata/schema +++ b/example/codegen/testdata/schema @@ -8,16 +8,22 @@ "comparison_operators": {} }, "CommentString": { + "representation": { + "type": "string" + }, "aggregate_functions": {}, "comparison_operators": {} }, - "DateTime": { + "Float32": { + "representation": { + "type": "float32" + }, "aggregate_functions": {}, "comparison_operators": {} }, - "Float": { + "Float64": { "representation": { - "type": "number" + "type": "float64" }, "aggregate_functions": {}, "comparison_operators": {} @@ -26,9 +32,30 @@ "aggregate_functions": {}, "comparison_operators": {} }, - "Int": { + "Int16": { + "representation": { + "type": "int16" + }, + "aggregate_functions": {}, + "comparison_operators": {} + }, + "Int32": { + "representation": { + "type": "int32" + }, + "aggregate_functions": {}, + "comparison_operators": {} + }, + "Int64": { + "representation": { + "type": "int64" + }, + "aggregate_functions": {}, + "comparison_operators": {} + }, + "Int8": { "representation": { - "type": "integer" + "type": "int8" }, "aggregate_functions": {}, "comparison_operators": {} @@ -51,9 +78,16 @@ "aggregate_functions": {}, "comparison_operators": {} }, + "TimestampTZ": { + "representation": { + "type": "timestamptz" + }, + "aggregate_functions": {}, + "comparison_operators": {} + }, "UUID": { "representation": { - "type": "string" + "type": "uuid" }, "aggregate_functions": {}, "comparison_operators": {} @@ -65,7 +99,7 @@ "created_at": { "type": { "type": "named", - "name": "DateTime" + "name": "TimestampTZ" } }, "id": { @@ -73,6 +107,15 @@ "type": "named", "name": "String" } + }, + "tags": { + "type": { + "type": "array", + "element_type": { + "type": "named", + "name": "String" + } + } } } }, @@ -81,7 +124,7 @@ "created_at": { "type": { "type": "named", - "name": "DateTime" + "name": "TimestampTZ" } }, "id": { @@ -106,7 +149,7 @@ "id": { "type": { "type": "named", - "name": "Int" + "name": "Int32" } } } @@ -116,13 +159,13 @@ "created_at": { "type": { "type": "named", - "name": "DateTime" + "name": "TimestampTZ" } }, "id": { "type": { "type": "named", - "name": "Int" + "name": "Int32" } }, "name": { @@ -220,7 +263,7 @@ "Float32": { "type": { "type": "named", - "name": "Float" + "name": "Float32" } }, "Float32Ptr": { @@ -228,14 +271,14 @@ "type": "nullable", "underlying_type": { "type": "named", - "name": "Float" + "name": "Float32" } } }, "Float64": { "type": { "type": "named", - "name": "Float" + "name": "Float64" } }, "Float64Ptr": { @@ -243,20 +286,20 @@ "type": "nullable", "underlying_type": { "type": "named", - "name": "Float" + "name": "Float64" } } }, "Int": { "type": { "type": "named", - "name": "Int" + "name": "Int32" } }, "Int16": { "type": { "type": "named", - "name": "Int" + "name": "Int16" } }, "Int16Ptr": { @@ -264,14 +307,14 @@ "type": "nullable", "underlying_type": { "type": "named", - "name": "Int" + "name": "Int16" } } }, "Int32": { "type": { "type": "named", - "name": "Int" + "name": "Int32" } }, "Int32Ptr": { @@ -279,14 +322,14 @@ "type": "nullable", "underlying_type": { "type": "named", - "name": "Int" + "name": "Int32" } } }, "Int64": { "type": { "type": "named", - "name": "Int" + "name": "Int64" } }, "Int64Ptr": { @@ -294,14 +337,14 @@ "type": "nullable", "underlying_type": { "type": "named", - "name": "Int" + "name": "Int64" } } }, "Int8": { "type": { "type": "named", - "name": "Int" + "name": "Int8" } }, "Int8Ptr": { @@ -309,7 +352,7 @@ "type": "nullable", "underlying_type": { "type": "named", - "name": "Int" + "name": "Int8" } } }, @@ -318,7 +361,7 @@ "type": "nullable", "underlying_type": { "type": "named", - "name": "Int" + "name": "Int32" } } }, @@ -406,7 +449,7 @@ "Time": { "type": { "type": "named", - "name": "DateTime" + "name": "TimestampTZ" } }, "TimePtr": { @@ -414,7 +457,7 @@ "type": "nullable", "underlying_type": { "type": "named", - "name": "DateTime" + "name": "TimestampTZ" } } }, @@ -445,13 +488,13 @@ "Uint": { "type": { "type": "named", - "name": "Int" + "name": "Int32" } }, "Uint16": { "type": { "type": "named", - "name": "Int" + "name": "Int16" } }, "Uint16Ptr": { @@ -459,14 +502,14 @@ "type": "nullable", "underlying_type": { "type": "named", - "name": "Int" + "name": "Int16" } } }, "Uint32": { "type": { "type": "named", - "name": "Int" + "name": "Int32" } }, "Uint32Ptr": { @@ -474,14 +517,14 @@ "type": "nullable", "underlying_type": { "type": "named", - "name": "Int" + "name": "Int32" } } }, "Uint64": { "type": { "type": "named", - "name": "Int" + "name": "Int64" } }, "Uint64Ptr": { @@ -489,14 +532,14 @@ "type": "nullable", "underlying_type": { "type": "named", - "name": "Int" + "name": "Int64" } } }, "Uint8": { "type": { "type": "named", - "name": "Int" + "name": "Int8" } }, "Uint8Ptr": { @@ -504,7 +547,7 @@ "type": "nullable", "underlying_type": { "type": "named", - "name": "Int" + "name": "Int8" } } }, @@ -513,7 +556,7 @@ "type": "nullable", "underlying_type": { "type": "named", - "name": "Int" + "name": "Int32" } } } @@ -544,7 +587,7 @@ "created_at": { "type": { "type": "named", - "name": "DateTime" + "name": "TimestampTZ" } }, "id": { @@ -560,13 +603,13 @@ "Lat": { "type": { "type": "named", - "name": "Int" + "name": "Int32" } }, "Long": { "type": { "type": "named", - "name": "Int" + "name": "Int32" } } } @@ -588,7 +631,7 @@ "num": { "type": { "type": "named", - "name": "Int" + "name": "Int32" } }, "text": { @@ -683,7 +726,7 @@ "Float32": { "type": { "type": "named", - "name": "Float" + "name": "Float32" } }, "Float32Ptr": { @@ -691,14 +734,14 @@ "type": "nullable", "underlying_type": { "type": "named", - "name": "Float" + "name": "Float32" } } }, "Float64": { "type": { "type": "named", - "name": "Float" + "name": "Float64" } }, "Float64Ptr": { @@ -706,20 +749,20 @@ "type": "nullable", "underlying_type": { "type": "named", - "name": "Float" + "name": "Float64" } } }, "Int": { "type": { "type": "named", - "name": "Int" + "name": "Int32" } }, "Int16": { "type": { "type": "named", - "name": "Int" + "name": "Int16" } }, "Int16Ptr": { @@ -727,14 +770,14 @@ "type": "nullable", "underlying_type": { "type": "named", - "name": "Int" + "name": "Int16" } } }, "Int32": { "type": { "type": "named", - "name": "Int" + "name": "Int32" } }, "Int32Ptr": { @@ -742,14 +785,14 @@ "type": "nullable", "underlying_type": { "type": "named", - "name": "Int" + "name": "Int32" } } }, "Int64": { "type": { "type": "named", - "name": "Int" + "name": "Int64" } }, "Int64Ptr": { @@ -757,14 +800,14 @@ "type": "nullable", "underlying_type": { "type": "named", - "name": "Int" + "name": "Int64" } } }, "Int8": { "type": { "type": "named", - "name": "Int" + "name": "Int8" } }, "Int8Ptr": { @@ -772,7 +815,7 @@ "type": "nullable", "underlying_type": { "type": "named", - "name": "Int" + "name": "Int8" } } }, @@ -781,7 +824,7 @@ "type": "nullable", "underlying_type": { "type": "named", - "name": "Int" + "name": "Int32" } } }, @@ -869,7 +912,7 @@ "Time": { "type": { "type": "named", - "name": "DateTime" + "name": "TimestampTZ" } }, "TimePtr": { @@ -877,7 +920,7 @@ "type": "nullable", "underlying_type": { "type": "named", - "name": "DateTime" + "name": "TimestampTZ" } } }, @@ -908,13 +951,13 @@ "Uint": { "type": { "type": "named", - "name": "Int" + "name": "Int32" } }, "Uint16": { "type": { "type": "named", - "name": "Int" + "name": "Int16" } }, "Uint16Ptr": { @@ -922,14 +965,14 @@ "type": "nullable", "underlying_type": { "type": "named", - "name": "Int" + "name": "Int16" } } }, "Uint32": { "type": { "type": "named", - "name": "Int" + "name": "Int32" } }, "Uint32Ptr": { @@ -937,14 +980,14 @@ "type": "nullable", "underlying_type": { "type": "named", - "name": "Int" + "name": "Int32" } } }, "Uint64": { "type": { "type": "named", - "name": "Int" + "name": "Int64" } }, "Uint64Ptr": { @@ -952,14 +995,14 @@ "type": "nullable", "underlying_type": { "type": "named", - "name": "Int" + "name": "Int64" } } }, "Uint8": { "type": { "type": "named", - "name": "Int" + "name": "Int8" } }, "Uint8Ptr": { @@ -967,7 +1010,7 @@ "type": "nullable", "underlying_type": { "type": "named", - "name": "Int" + "name": "Int8" } } }, @@ -976,7 +1019,7 @@ "type": "nullable", "underlying_type": { "type": "named", - "name": "Int" + "name": "Int32" } } } @@ -1008,7 +1051,7 @@ "Limit": { "type": { "type": "named", - "name": "Float" + "name": "Float64" } } }, @@ -1047,7 +1090,7 @@ "arguments": {}, "result_type": { "type": "named", - "name": "Int" + "name": "Int32" } }, { diff --git a/example/reference/connector.go b/example/reference/connector.go index 21544d8..e1025ab 100644 --- a/example/reference/connector.go +++ b/example/reference/connector.go @@ -112,7 +112,7 @@ func (mc *Connector) HealthCheck(ctx context.Context, configuration *Configurati func (mc *Connector) GetCapabilities(configuration *Configuration) schema.CapabilitiesResponseMarshaler { return &schema.CapabilitiesResponse{ - Version: "0.1.1", + Version: "0.1.2", Capabilities: schema.Capabilities{ Query: schema.QueryCapabilities{ Aggregates: schema.LeafCapability{}, diff --git a/example/reference/connector_test.go b/example/reference/connector_test.go index 6392735..3646dee 100644 --- a/example/reference/connector_test.go +++ b/example/reference/connector_test.go @@ -6,6 +6,7 @@ import ( "fmt" "io" "net/http" + "os" "testing" "github.com/hasura/ndc-sdk-go/connector" @@ -13,7 +14,7 @@ import ( "github.com/hasura/ndc-sdk-go/schema" ) -const test_SpecVersion = "v0.1.1" +const test_SpecVersion = "v0.1.2" func createTestServer(t *testing.T) *connector.Server[Configuration, State] { server, err := connector.NewServer[Configuration, State](&Connector{}, &connector.ServerOptions{ @@ -83,14 +84,14 @@ func assertHTTPResponse[B any](t *testing.T, res *http.Response, statusCode int, func TestGeneralMethods(t *testing.T) { server := createTestServer(t).BuildTestServer() t.Run("capabilities", func(t *testing.T) { - expectedResp, err := http.Get(fmt.Sprintf("https://raw.githubusercontent.com/hasura/ndc-spec/%s/ndc-reference/tests/capabilities/expected.json", test_SpecVersion)) + expectedBytes, err := os.ReadFile("./testdata/capabilities") if err != nil { - t.Errorf("failed to fetch expected schema: %s", err.Error()) + t.Errorf("failed to get expected capabilities: %s", err.Error()) t.FailNow() } var expectedResult schema.CapabilitiesResponse - err = json.NewDecoder(expectedResp.Body).Decode(&expectedResult) + err = json.Unmarshal(expectedBytes, &expectedResult) if err != nil { t.Errorf("failed to read expected body: %s", err.Error()) t.FailNow() @@ -106,14 +107,14 @@ func TestGeneralMethods(t *testing.T) { }) t.Run("schema", func(t *testing.T) { - expectedSchemaResp, err := http.Get(fmt.Sprintf("https://raw.githubusercontent.com/hasura/ndc-spec/%s/ndc-reference/tests/schema/expected.json", test_SpecVersion)) + expectedBytes, err := os.ReadFile("./testdata/schema") if err != nil { t.Errorf("failed to fetch expected schema: %s", err.Error()) t.FailNow() } var expectedSchema schema.SchemaResponse - err = json.NewDecoder(expectedSchemaResp.Body).Decode(&expectedSchema) + err = json.Unmarshal(expectedBytes, &expectedSchema) if err != nil { t.Errorf("failed to read expected body: %s", err.Error()) t.FailNow() diff --git a/example/reference/testdata/capabilities b/example/reference/testdata/capabilities new file mode 100644 index 0000000..1d97253 --- /dev/null +++ b/example/reference/testdata/capabilities @@ -0,0 +1,14 @@ +{ + "version": "0.1.2", + "capabilities": { + "query": { + "aggregates": {}, + "variables": {} + }, + "mutation": {}, + "relationships": { + "relation_comparisons": {}, + "order_by_aggregate": {} + } + } +} \ No newline at end of file diff --git a/example/reference/testdata/schema b/example/reference/testdata/schema new file mode 100644 index 0000000..3820630 --- /dev/null +++ b/example/reference/testdata/schema @@ -0,0 +1,350 @@ +{ + "scalar_types": { + "Int": { + "representation": { + "type": "integer" + }, + "aggregate_functions": { + "max": { + "result_type": { + "type": "nullable", + "underlying_type": { + "type": "named", + "name": "Int" + } + } + }, + "min": { + "result_type": { + "type": "nullable", + "underlying_type": { + "type": "named", + "name": "Int" + } + } + } + }, + "comparison_operators": { + "eq": { + "type": "equal" + }, + "in": { + "type": "in" + } + } + }, + "String": { + "representation": { + "type": "string" + }, + "aggregate_functions": {}, + "comparison_operators": { + "eq": { + "type": "equal" + }, + "in": { + "type": "in" + }, + "like": { + "type": "custom", + "argument_type": { + "type": "named", + "name": "String" + } + } + } + } + }, + "object_types": { + "article": { + "description": "An article", + "fields": { + "author_id": { + "description": "The article's author ID", + "type": { + "type": "named", + "name": "Int" + } + }, + "id": { + "description": "The article's primary key", + "type": { + "type": "named", + "name": "Int" + } + }, + "title": { + "description": "The article's title", + "type": { + "type": "named", + "name": "String" + } + } + } + }, + "author": { + "description": "An author", + "fields": { + "first_name": { + "description": "The author's first name", + "type": { + "type": "named", + "name": "String" + } + }, + "id": { + "description": "The author's primary key", + "type": { + "type": "named", + "name": "Int" + } + }, + "last_name": { + "description": "The author's last name", + "type": { + "type": "named", + "name": "String" + } + } + } + }, + "institution": { + "description": "An institution", + "fields": { + "departments": { + "description": "The institution's departments", + "type": { + "type": "array", + "element_type": { + "type": "named", + "name": "String" + } + } + }, + "id": { + "description": "The institution's primary key", + "type": { + "type": "named", + "name": "Int" + } + }, + "location": { + "description": "The institution's location", + "type": { + "type": "named", + "name": "location" + } + }, + "name": { + "description": "The institution's name", + "type": { + "type": "named", + "name": "String" + } + }, + "staff": { + "description": "The institution's staff", + "type": { + "type": "array", + "element_type": { + "type": "named", + "name": "staff_member" + } + } + } + } + }, + "location": { + "description": "A location", + "fields": { + "campuses": { + "description": "The location's campuses", + "type": { + "type": "array", + "element_type": { + "type": "named", + "name": "String" + } + } + }, + "city": { + "description": "The location's city", + "type": { + "type": "named", + "name": "String" + } + }, + "country": { + "description": "The location's country", + "type": { + "type": "named", + "name": "String" + } + } + } + }, + "staff_member": { + "description": "A staff member", + "fields": { + "first_name": { + "description": "The staff member's first name", + "type": { + "type": "named", + "name": "String" + } + }, + "last_name": { + "description": "The staff member's last name", + "type": { + "type": "named", + "name": "String" + } + }, + "specialities": { + "description": "The staff member's specialities", + "type": { + "type": "array", + "element_type": { + "type": "named", + "name": "String" + } + } + } + } + } + }, + "collections": [ + { + "name": "articles", + "description": "A collection of articles", + "arguments": {}, + "type": "article", + "uniqueness_constraints": { + "ArticleByID": { + "unique_columns": [ + "id" + ] + } + }, + "foreign_keys": { + "Article_AuthorID": { + "column_mapping": { + "author_id": "id" + }, + "foreign_collection": "authors" + } + } + }, + { + "name": "authors", + "description": "A collection of authors", + "arguments": {}, + "type": "author", + "uniqueness_constraints": { + "AuthorByID": { + "unique_columns": [ + "id" + ] + } + }, + "foreign_keys": {} + }, + { + "name": "institutions", + "description": "A collection of institutions", + "arguments": {}, + "type": "institution", + "uniqueness_constraints": { + "InstitutionByID": { + "unique_columns": [ + "id" + ] + } + }, + "foreign_keys": {} + }, + { + "name": "articles_by_author", + "description": "Articles parameterized by author", + "arguments": { + "author_id": { + "type": { + "type": "named", + "name": "Int" + } + } + }, + "type": "article", + "uniqueness_constraints": {}, + "foreign_keys": {} + } + ], + "functions": [ + { + "name": "latest_article_id", + "description": "Get the ID of the most recent article", + "arguments": {}, + "result_type": { + "type": "nullable", + "underlying_type": { + "type": "named", + "name": "Int" + } + } + }, + { + "name": "latest_article", + "description": "Get the most recent article", + "arguments": {}, + "result_type": { + "type": "nullable", + "underlying_type": { + "type": "named", + "name": "article" + } + } + } + ], + "procedures": [ + { + "name": "upsert_article", + "description": "Insert or update an article", + "arguments": { + "article": { + "description": "The article to insert or update", + "type": { + "type": "named", + "name": "article" + } + } + }, + "result_type": { + "type": "nullable", + "underlying_type": { + "type": "named", + "name": "article" + } + } + }, + { + "name": "delete_articles", + "description": "Delete articles which match a predicate", + "arguments": { + "where": { + "description": "The predicate", + "type": { + "type": "predicate", + "object_type_name": "article" + } + } + }, + "result_type": { + "type": "array", + "element_type": { + "type": "named", + "name": "article" + } + } + } + ] +} \ No newline at end of file