diff --git a/.changes/unreleased/Feature-20240112-142046.yaml b/.changes/unreleased/Feature-20240112-142046.yaml new file mode 100644 index 00000000..18227d35 --- /dev/null +++ b/.changes/unreleased/Feature-20240112-142046.yaml @@ -0,0 +1,3 @@ +kind: Feature +body: Add RefTo - alias for RefOf +time: 2024-01-12T14:20:46.773099-05:00 diff --git a/.changes/unreleased/Refactor-20240109-202355.yaml b/.changes/unreleased/Refactor-20240109-202355.yaml new file mode 100644 index 00000000..2d391240 --- /dev/null +++ b/.changes/unreleased/Refactor-20240109-202355.yaml @@ -0,0 +1,4 @@ +kind: Refactor +body: Combine DeleteService(ID) and DeleteServiceWithAlias(string) into a unified + function +time: 2024-01-09T20:23:55.747843-05:00 diff --git a/.changes/unreleased/Refactor-20240109-202941.yaml b/.changes/unreleased/Refactor-20240109-202941.yaml new file mode 100644 index 00000000..6845e629 --- /dev/null +++ b/.changes/unreleased/Refactor-20240109-202941.yaml @@ -0,0 +1,3 @@ +kind: Refactor +body: DeleteScorecard() now returns a pointer like other Delete functions +time: 2024-01-09T20:29:41.335381-05:00 diff --git a/.changes/unreleased/Refactor-20240109-205045.yaml b/.changes/unreleased/Refactor-20240109-205045.yaml new file mode 100644 index 00000000..8cc74fc2 --- /dev/null +++ b/.changes/unreleased/Refactor-20240109-205045.yaml @@ -0,0 +1,3 @@ +kind: Refactor +body: List() functions consistently return a (*Connection, error) +time: 2024-01-09T20:50:45.694558-05:00 diff --git a/.changes/unreleased/Refactor-20240109-214205.yaml b/.changes/unreleased/Refactor-20240109-214205.yaml new file mode 100644 index 00000000..48479ba0 --- /dev/null +++ b/.changes/unreleased/Refactor-20240109-214205.yaml @@ -0,0 +1,3 @@ +kind: Refactor +body: Merge DeleteTeam(ID) and DeleteTeamWithAlias(string) into DeleteTeam(identifier string) +time: 2024-01-09T21:42:05.208198-05:00 diff --git a/.changes/unreleased/Refactor-20240110-142526.yaml b/.changes/unreleased/Refactor-20240110-142526.yaml new file mode 100644 index 00000000..797fdfc4 --- /dev/null +++ b/.changes/unreleased/Refactor-20240110-142526.yaml @@ -0,0 +1,3 @@ +kind: Refactor +body: NewIdentifierInput() now returns a pointer to be consistent with NewIdentifier() +time: 2024-01-10T14:25:26.514448-05:00 diff --git a/.changes/unreleased/Refactor-20240112-141014.yaml b/.changes/unreleased/Refactor-20240112-141014.yaml new file mode 100644 index 00000000..b6297a5d --- /dev/null +++ b/.changes/unreleased/Refactor-20240112-141014.yaml @@ -0,0 +1,3 @@ +kind: Refactor +body: JSON functions now return (ptr, error) instead of panic()-ing +time: 2024-01-12T14:10:14.452468-05:00 diff --git a/actions.go b/actions.go index bd69c002..0ec8ccc0 100644 --- a/actions.go +++ b/actions.go @@ -116,7 +116,7 @@ func (client *Client) GetCustomAction(input string) (*CustomActionsExternalActio return &q.Account.Action, HandleErrors(err, nil) } -func (client *Client) ListCustomActions(variables *PayloadVariables) (CustomActionsExternalActionsConnection, error) { +func (client *Client) ListCustomActions(variables *PayloadVariables) (*CustomActionsExternalActionsConnection, error) { var q struct { Account struct { Actions CustomActionsExternalActionsConnection `graphql:"customActionsExternalActions(after: $after, first: $first)"` @@ -126,18 +126,18 @@ func (client *Client) ListCustomActions(variables *PayloadVariables) (CustomActi variables = client.InitialPageVariablesPointer() } if err := client.Query(&q, *variables, WithName("ExternalActionList")); err != nil { - return CustomActionsExternalActionsConnection{}, err + return nil, err } for q.Account.Actions.PageInfo.HasNextPage { (*variables)["after"] = q.Account.Actions.PageInfo.End resp, err := client.ListCustomActions(variables) if err != nil { - return CustomActionsExternalActionsConnection{}, err + return nil, err } q.Account.Actions.Nodes = append(q.Account.Actions.Nodes, resp.Nodes...) q.Account.Actions.PageInfo = resp.PageInfo } - return q.Account.Actions, nil + return &q.Account.Actions, nil } func (client *Client) UpdateWebhookAction(input CustomActionsWebhookActionUpdateInput) (*CustomActionsExternalAction, error) { @@ -203,7 +203,7 @@ func (client *Client) GetTriggerDefinition(input string) (*CustomActionsTriggerD return &q.Account.Definition, HandleErrors(err, nil) } -func (client *Client) ListTriggerDefinitions(variables *PayloadVariables) (CustomActionsTriggerDefinitionsConnection, error) { +func (client *Client) ListTriggerDefinitions(variables *PayloadVariables) (*CustomActionsTriggerDefinitionsConnection, error) { var q struct { Account struct { Definitions CustomActionsTriggerDefinitionsConnection `graphql:"customActionsTriggerDefinitions(after: $after, first: $first)"` @@ -213,19 +213,19 @@ func (client *Client) ListTriggerDefinitions(variables *PayloadVariables) (Custo variables = client.InitialPageVariablesPointer() } if err := client.Query(&q, *variables, WithName("TriggerDefinitionList")); err != nil { - return CustomActionsTriggerDefinitionsConnection{}, err + return nil, err } for q.Account.Definitions.PageInfo.HasNextPage { (*variables)["after"] = q.Account.Definitions.PageInfo.End resp, err := client.ListTriggerDefinitions(variables) if err != nil { - return CustomActionsTriggerDefinitionsConnection{}, err + return nil, err } q.Account.Definitions.Nodes = append(q.Account.Definitions.Nodes, resp.Nodes...) q.Account.Definitions.PageInfo = resp.PageInfo q.Account.Definitions.TotalCount += resp.TotalCount } - return q.Account.Definitions, nil + return &q.Account.Definitions, nil } func (client *Client) UpdateTriggerDefinition(input CustomActionsTriggerDefinitionUpdateInput) (*CustomActionsTriggerDefinition, error) { diff --git a/category.go b/category.go index 8203f28d..c9a389a5 100644 --- a/category.go +++ b/category.go @@ -69,13 +69,13 @@ func (client *Client) ListCategories(variables *PayloadVariables) (*CategoryConn variables = client.InitialPageVariablesPointer() } if err := client.Query(&q, *variables, WithName("CategoryList")); err != nil { - return &CategoryConnection{}, err + return nil, err } for q.Account.Rubric.Categories.PageInfo.HasNextPage { (*variables)["after"] = q.Account.Rubric.Categories.PageInfo.End resp, err := client.ListCategories(variables) if err != nil { - return &CategoryConnection{}, err + return nil, err } q.Account.Rubric.Categories.Nodes = append(q.Account.Rubric.Categories.Nodes, resp.Nodes...) q.Account.Rubric.Categories.PageInfo = resp.PageInfo diff --git a/check.go b/check.go index 4a5109ba..ac0c0d84 100644 --- a/check.go +++ b/check.go @@ -231,7 +231,7 @@ func (client *Client) GetCheck(id ID) (*Check, error) { return &q.Account.Check, HandleErrors(err, nil) } -func (client *Client) ListChecks(variables *PayloadVariables) (CheckConnection, error) { +func (client *Client) ListChecks(variables *PayloadVariables) (*CheckConnection, error) { var q struct { Account struct { Rubric struct { @@ -243,19 +243,19 @@ func (client *Client) ListChecks(variables *PayloadVariables) (CheckConnection, variables = client.InitialPageVariablesPointer() } if err := client.Query(&q, *variables, WithName("CheckList")); err != nil { - return CheckConnection{}, err + return nil, err } for q.Account.Rubric.Checks.PageInfo.HasNextPage { (*variables)["after"] = q.Account.Rubric.Checks.PageInfo.End resp, err := client.ListChecks(variables) if err != nil { - return CheckConnection{}, err + return nil, err } q.Account.Rubric.Checks.Nodes = append(q.Account.Rubric.Checks.Nodes, resp.Nodes...) q.Account.Rubric.Checks.PageInfo = resp.PageInfo q.Account.Rubric.Checks.TotalCount += resp.TotalCount } - return q.Account.Rubric.Checks, nil + return &q.Account.Rubric.Checks, nil } //#endregion diff --git a/common.go b/common.go index a9f72ca1..ee8b294f 100644 --- a/common.go +++ b/common.go @@ -52,6 +52,10 @@ func RefOf[T any](v T) *T { return &v } +func RefTo[T any](v T) *T { + return &v +} + func HandleErrors(err error, errs []OpsLevelErrors) error { if err != nil { return err diff --git a/domain.go b/domain.go index 360250f4..0963e333 100644 --- a/domain.go +++ b/domain.go @@ -152,13 +152,13 @@ func (c *Client) ListDomains(variables *PayloadVariables) (*DomainConnection, er variables = c.InitialPageVariablesPointer() } if err := c.Query(&q, *variables, WithName("DomainsList")); err != nil { - return &DomainConnection{}, err + return nil, err } for q.Account.Domains.PageInfo.HasNextPage { (*variables)["after"] = q.Account.Domains.PageInfo.End resp, err := c.ListDomains(variables) if err != nil { - return &DomainConnection{}, err + return nil, err } q.Account.Domains.Nodes = append(q.Account.Domains.Nodes, resp.Nodes...) q.Account.Domains.PageInfo = resp.PageInfo diff --git a/filters.go b/filters.go index 933fe26e..d70a4a20 100644 --- a/filters.go +++ b/filters.go @@ -77,7 +77,7 @@ func (client *Client) GetFilter(id ID) (*Filter, error) { return &q.Account.Filter, HandleErrors(err, nil) } -func (client *Client) ListFilters(variables *PayloadVariables) (FilterConnection, error) { +func (client *Client) ListFilters(variables *PayloadVariables) (*FilterConnection, error) { var q struct { Account struct { Filters FilterConnection `graphql:"filters(after: $after, first: $first)"` @@ -87,19 +87,19 @@ func (client *Client) ListFilters(variables *PayloadVariables) (FilterConnection variables = client.InitialPageVariablesPointer() } if err := client.Query(&q, *variables, WithName("FilterList")); err != nil { - return FilterConnection{}, err + return nil, err } for q.Account.Filters.PageInfo.HasNextPage { (*variables)["after"] = q.Account.Filters.PageInfo.End resp, err := client.ListFilters(variables) if err != nil { - return FilterConnection{}, err + return nil, err } q.Account.Filters.Nodes = append(q.Account.Filters.Nodes, resp.Nodes...) q.Account.Filters.PageInfo = resp.PageInfo q.Account.Filters.TotalCount += resp.TotalCount } - return q.Account.Filters, nil + return &q.Account.Filters, nil } //#endregion diff --git a/go.mod b/go.mod index 6b80ac12..5308c22e 100644 --- a/go.mod +++ b/go.mod @@ -4,16 +4,15 @@ go 1.21 require ( github.com/Masterminds/sprig/v3 v3.2.3 - github.com/creasty/defaults v1.7.0 github.com/go-playground/validator/v10 v10.16.0 github.com/go-resty/resty/v2 v2.11.0 github.com/gosimple/slug v1.13.1 github.com/hashicorp/go-retryablehttp v0.7.5 github.com/hasura/go-graphql-client v0.10.2 + github.com/opslevel/moredefaults v0.0.0-20240112142637-078c8ff8ba9c github.com/relvacode/iso8601 v1.3.0 github.com/rocktavious/autopilot/v2023 v2023.12.7 github.com/rs/zerolog v1.31.0 - gopkg.in/yaml.v3 v3.0.1 ) require ( diff --git a/go.sum b/go.sum index 5b0ff041..07ee729f 100644 --- a/go.sum +++ b/go.sum @@ -5,8 +5,6 @@ github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYr github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA= github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/creasty/defaults v1.7.0 h1:eNdqZvc5B509z18lD8yc212CAqJNvfT1Jq6L8WowdBA= -github.com/creasty/defaults v1.7.0/go.mod h1:iGzKe6pbEHnpMPtfDXZEr0NVxWnPTjb1bbDy08fPzYM= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -61,6 +59,8 @@ github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyua github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/opslevel/moredefaults v0.0.0-20240112142637-078c8ff8ba9c h1:m4sNHcfkE02xZy1oxF2QVGfhHulamxw9UlzRM7c45QQ= +github.com/opslevel/moredefaults v0.0.0-20240112142637-078c8ff8ba9c/go.mod h1:g2GSXVP6LO+5+AIsnMRPN+BeV86OXuFRTX7HXCDtYeI= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -141,7 +141,6 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= diff --git a/infra.go b/infra.go index ee4fbb56..a0d011d3 100644 --- a/infra.go +++ b/infra.go @@ -149,7 +149,7 @@ func (client *Client) GetInfrastructure(identifier string) (*InfrastructureResou return &q.Account.InfrastructureResource, HandleErrors(err, nil) } -func (client *Client) ListInfrastructureSchemas(variables *PayloadVariables) (InfrastructureResourceSchemaConnection, error) { +func (client *Client) ListInfrastructureSchemas(variables *PayloadVariables) (*InfrastructureResourceSchemaConnection, error) { var q struct { Account struct { InfrastructureResourceSchemas InfrastructureResourceSchemaConnection `graphql:"infrastructureResourceSchemas(after: $after, first: $first)"` @@ -159,22 +159,22 @@ func (client *Client) ListInfrastructureSchemas(variables *PayloadVariables) (In variables = client.InitialPageVariablesPointer() } if err := client.Query(&q, *variables, WithName("IntegrationList")); err != nil { - return InfrastructureResourceSchemaConnection{}, err + return nil, err } for q.Account.InfrastructureResourceSchemas.PageInfo.HasNextPage { (*variables)["after"] = q.Account.InfrastructureResourceSchemas.PageInfo.End resp, err := client.ListInfrastructureSchemas(variables) if err != nil { - return InfrastructureResourceSchemaConnection{}, err + return nil, err } q.Account.InfrastructureResourceSchemas.Nodes = append(q.Account.InfrastructureResourceSchemas.Nodes, resp.Nodes...) q.Account.InfrastructureResourceSchemas.PageInfo = resp.PageInfo } q.Account.InfrastructureResourceSchemas.TotalCount = len(q.Account.InfrastructureResourceSchemas.Nodes) - return q.Account.InfrastructureResourceSchemas, nil + return &q.Account.InfrastructureResourceSchemas, nil } -func (client *Client) ListInfrastructure(variables *PayloadVariables) (InfrastructureResourceConnection, error) { +func (client *Client) ListInfrastructure(variables *PayloadVariables) (*InfrastructureResourceConnection, error) { var q struct { Account struct { InfrastructureResource InfrastructureResourceConnection `graphql:"infrastructureResources(after: $after, first: $first)"` @@ -185,19 +185,19 @@ func (client *Client) ListInfrastructure(variables *PayloadVariables) (Infrastru (*variables)["all"] = true } if err := client.Query(&q, *variables, WithName("IntegrationList")); err != nil { - return InfrastructureResourceConnection{}, err + return nil, err } for q.Account.InfrastructureResource.PageInfo.HasNextPage { (*variables)["after"] = q.Account.InfrastructureResource.PageInfo.End resp, err := client.ListInfrastructure(variables) if err != nil { - return InfrastructureResourceConnection{}, err + return nil, err } q.Account.InfrastructureResource.Nodes = append(q.Account.InfrastructureResource.Nodes, resp.Nodes...) q.Account.InfrastructureResource.PageInfo = resp.PageInfo } q.Account.InfrastructureResource.TotalCount = len(q.Account.InfrastructureResource.Nodes) - return q.Account.InfrastructureResource, nil + return &q.Account.InfrastructureResource, nil } func (client *Client) UpdateInfrastructure(identifier string, input InfraInput) (*InfrastructureResource, error) { diff --git a/integration.go b/integration.go index 2c64bb76..7dc41f66 100644 --- a/integration.go +++ b/integration.go @@ -112,7 +112,7 @@ func (client *Client) GetIntegration(id ID) (*Integration, error) { return &q.Account.Integration, HandleErrors(err, nil) } -func (client *Client) ListIntegrations(variables *PayloadVariables) (IntegrationConnection, error) { +func (client *Client) ListIntegrations(variables *PayloadVariables) (*IntegrationConnection, error) { var q struct { Account struct { Integrations IntegrationConnection `graphql:"integrations(after: $after, first: $first)"` @@ -122,19 +122,19 @@ func (client *Client) ListIntegrations(variables *PayloadVariables) (Integration variables = client.InitialPageVariablesPointer() } if err := client.Query(&q, *variables, WithName("IntegrationList")); err != nil { - return IntegrationConnection{}, err + return nil, err } for q.Account.Integrations.PageInfo.HasNextPage { (*variables)["after"] = q.Account.Integrations.PageInfo.End resp, err := client.ListIntegrations(variables) if err != nil { - return IntegrationConnection{}, err + return nil, err } q.Account.Integrations.Nodes = append(q.Account.Integrations.Nodes, resp.Nodes...) q.Account.Integrations.PageInfo = resp.PageInfo q.Account.Integrations.TotalCount += resp.TotalCount } - return q.Account.Integrations, nil + return &q.Account.Integrations, nil } //#endregion diff --git a/json.go b/json.go index 3e1b2c0a..199d4637 100644 --- a/json.go +++ b/json.go @@ -15,12 +15,12 @@ type ( func (s JSONSchema) GetGraphQLType() string { return "JSONSchema" } -func NewJSONSchema(data string) JSONSchema { +func NewJSONSchema(data string) (*JSONSchema, error) { result := make(JSONSchema) if err := json.Unmarshal([]byte(data), &result); err != nil { - panic(err) + return nil, err } - return result + return &result, nil } func (s JSONSchema) AsString() string { @@ -43,12 +43,12 @@ func (s JSONSchema) MarshalJSON() ([]byte, error) { func (s JSON) GetGraphQLType() string { return "JSON" } -func NewJSON(data string) JSON { +func NewJSON(data string) (*JSON, error) { result := make(JSON) if err := json.Unmarshal([]byte(data), &result); err != nil { - panic(err) + return nil, err } - return result + return &result, nil } func (s JSON) ToJSON() string { @@ -74,12 +74,14 @@ type JsonString string func (s JsonString) GetGraphQLType() string { return "JsonString" } -func NewJSONInput(data any) JsonString { +func NewJSONInput(data any) (*JsonString, error) { + var result JsonString bytes, err := json.Marshal(data) if err != nil { - panic(err) + return nil, err } - return JsonString(bytes) + result = JsonString(bytes) + return &result, nil } func JsonStringAs[T any](data JsonString) (T, error) { @@ -120,22 +122,3 @@ func (s JsonString) AsMap() map[string]any { value, _ := JsonStringAs[map[string]any](s) return value } - -// -//func (s *JSON) UnmarshalJSON(data []byte) error { -// escaped, err := strconv.Unquote(string(data)) -// if err != nil { -// return err -// } -// dto := map[string]string{} -// if err := json.Unmarshal([]byte(escaped), &dto); err != nil { -// return err -// } -// if (*s) == nil { -// (*s) = JSON{} -// } -// for k, v := range dto { -// (*s)[k] = v -// } -// return nil -//} diff --git a/json_test.go b/json_test.go index bd271147..e113306f 100644 --- a/json_test.go +++ b/json_test.go @@ -9,6 +9,8 @@ import ( "github.com/rocktavious/autopilot/v2023" ) +var validStringContainingJSON = `{"name":"Thomas","isIntern":false,"age":45,"access":{"aws":"admin","okta":"admin"},"tags":["org:engineering","team:platform"]}` + type JSONTester struct { Key1 ol.JSON `json:"key1"` Key2 ol.JSON `json:"key2,omitempty"` @@ -19,35 +21,43 @@ type JSONTester struct { func TestNewJSON(t *testing.T) { // Arrange data1 := ol.JSON{"foo": "bar"} - data2 := ol.NewJSON(`{"foo":"bar"}`) + data2, data2Err := ol.NewJSON(`{"foo":"bar"}`) // Act result1, err1 := json.Marshal(data1) result2, err2 := json.Marshal(data2) - result3 := ol.NewJSONInput(`{"foo":"bar"}`) - - result4 := ol.NewJSONInput(true) - result4a := ol.NewJSONInput(false) - result5 := ol.NewJSONInput(1.32) - result5a := ol.NewJSONInput(0) - result6 := ol.NewJSONInput("hello world") - result7 := ol.NewJSONInput([]any{"foo", "bar"}) - result8 := ol.NewJSONInput(map[string]any{"foo": "bar"}) + result3, result3Err := ol.NewJSONInput(`{"foo":"bar"}`) + result4, result4Err := ol.NewJSONInput(true) + result4a, result4aErr := ol.NewJSONInput(false) + result5, result5Err := ol.NewJSONInput(1.32) + result5a, result5aErr := ol.NewJSONInput(0) + result6, result6Err := ol.NewJSONInput("hello world") + result7, result7Err := ol.NewJSONInput([]any{"foo", "bar"}) + result8, result8Err := ol.NewJSONInput(map[string]any{"foo": "bar"}) // Assert + autopilot.Ok(t, data2Err) autopilot.Ok(t, err1) autopilot.Ok(t, err2) - autopilot.Equals(t, data1, data2) - autopilot.Assert(t, &data1 != &data2, "The JSON objects have the same memory address") + autopilot.Ok(t, result3Err) + autopilot.Ok(t, result4Err) + autopilot.Ok(t, result4aErr) + autopilot.Ok(t, result5Err) + autopilot.Ok(t, result5aErr) + autopilot.Ok(t, result6Err) + autopilot.Ok(t, result7Err) + autopilot.Ok(t, result8Err) + autopilot.Equals(t, data1, *data2) + autopilot.Assert(t, &data1 != data2, "The JSON objects have the same memory address") autopilot.Equals(t, result1, result2) - autopilot.Equals(t, string(result1), string(result3)) - autopilot.Equals(t, string(result2), string(result3)) + autopilot.Equals(t, string(result1), string(*result3)) + autopilot.Equals(t, string(result2), string(*result3)) - autopilot.Equals(t, `true`, string(result4)) - autopilot.Equals(t, `false`, string(result4a)) - autopilot.Equals(t, `1.32`, string(result5)) - autopilot.Equals(t, `0`, string(result5a)) - autopilot.Equals(t, `"hello world"`, string(result6)) - autopilot.Equals(t, `["foo","bar"]`, string(result7)) - autopilot.Equals(t, `{"foo":"bar"}`, string(result8)) + autopilot.Equals(t, `true`, string(*result4)) + autopilot.Equals(t, `false`, string(*result4a)) + autopilot.Equals(t, `1.32`, string(*result5)) + autopilot.Equals(t, `0`, string(*result5a)) + autopilot.Equals(t, `"hello world"`, string(*result6)) + autopilot.Equals(t, `["foo","bar"]`, string(*result7)) + autopilot.Equals(t, `{"foo":"bar"}`, string(*result8)) } func TestMarshalJSON(t *testing.T) { @@ -98,12 +108,14 @@ func TestConstructQueryJSON(t *testing.T) { } `graphql:"myQuery(id1: $id1 id2: $id2 id3: $id3)"` } } + var3, err := ol.NewJSONInput(map[string]any{ + "foo": "bar", + }) + autopilot.Assert(t, err == nil, "unexpected error") v := ol.PayloadVariables{ "id1": data, "id2": &data, - "id3": ol.NewJSONInput(map[string]any{ - "foo": "bar", - }), + "id3": *var3, } // Act query, err := graphql.ConstructQuery(q, v, ol.WithName("MyQuery")) @@ -124,12 +136,14 @@ func TestConstructMutationJSON(t *testing.T) { } `graphql:"myMutation(id1: $id1 id2: $id2 id3: $id3)"` } } + var3, err := ol.NewJSONInput(map[string]any{ + "foo": "bar", + }) + autopilot.Assert(t, err == nil, "unexpected error") v := ol.PayloadVariables{ "id1": data, "id2": &data, - "id3": ol.NewJSONInput(map[string]any{ - "foo": "bar", - }), + "id3": *var3, } // Act query, err := graphql.ConstructMutation(q, v, ol.WithName("MyMutation")) @@ -148,21 +162,39 @@ func TestUnmarshalJSONString(t *testing.T) { data4 := []any{"foo", "bar"} data5 := map[string]any{"foo": "bar"} // Act - result1 := ol.NewJSONInput(data1).AsBool() - result1a := ol.NewJSONInput(data1a).AsBool() - result2 := ol.NewJSONInput(data2).AsFloat64() - result2a := ol.NewJSONInput(data2a).AsInt() - result3 := ol.NewJSONInput(data3).AsString() - result4 := ol.NewJSONInput(data4).AsArray() - result5 := ol.NewJSONInput(data5).AsMap() - _, err := ol.JsonStringAs[float32](ol.NewJSONInput(data1)) + result1, result1Err := ol.NewJSONInput(data1) + result1a, result1aErr := ol.NewJSONInput(data1a) + result2, result2Err := ol.NewJSONInput(data2) + result2a, result2aErr := ol.NewJSONInput(data2a) + result3, result3Err := ol.NewJSONInput(data3) + result4, result4Err := ol.NewJSONInput(data4) + result5, result5Err := ol.NewJSONInput(data5) + _, err := ol.JsonStringAs[float32](*result1) // Assert - autopilot.Equals(t, data1, result1) - autopilot.Equals(t, data1a, result1a) - autopilot.Equals(t, data2, result2) - autopilot.Equals(t, data2a, result2a) - autopilot.Equals(t, data3, result3) - autopilot.Equals(t, data4, result4) - autopilot.Equals(t, data5, result5) + autopilot.Ok(t, result1Err) + autopilot.Ok(t, result1aErr) + autopilot.Ok(t, result2Err) + autopilot.Ok(t, result2aErr) + autopilot.Ok(t, result3Err) + autopilot.Ok(t, result4Err) + autopilot.Ok(t, result5Err) + autopilot.Equals(t, data1, result1.AsBool()) + autopilot.Equals(t, data1a, result1a.AsBool()) + autopilot.Equals(t, data2, result2.AsFloat64()) + autopilot.Equals(t, data2a, result2a.AsInt()) + autopilot.Equals(t, data3, result3.AsString()) + autopilot.Equals(t, data4, result4.AsArray()) + autopilot.Equals(t, data5, result5.AsMap()) autopilot.Assert(t, err != nil, "The JSON string of type bool should be unable to unmarshalled into a float32") } + +func TestNewJSONSchema(t *testing.T) { + res, err := ol.NewJSONSchema(validStringContainingJSON) + resVal := *res + autopilot.Ok(t, err) + autopilot.Equals(t, resVal["name"], "Thomas") + autopilot.Equals(t, resVal["isIntern"], false) + autopilot.Equals(t, resVal["age"], float64(45)) // this is normal with encoding/json + autopilot.Equals(t, resVal["access"], map[string]interface{}{"aws": "admin", "okta": "admin"}) + autopilot.Equals(t, resVal["tags"], []interface{}{"org:engineering", "team:platform"}) +} diff --git a/property.go b/property.go index ccf67728..6412cfae 100644 --- a/property.go +++ b/property.go @@ -82,7 +82,7 @@ func (client *Client) GetPropertyDefinition(input string) (*PropertyDefinition, return &q.Account.Definition, HandleErrors(err, nil) } -func (client *Client) ListPropertyDefinitions(variables *PayloadVariables) (PropertyDefinitionConnection, error) { +func (client *Client) ListPropertyDefinitions(variables *PayloadVariables) (*PropertyDefinitionConnection, error) { var q struct { Account struct { Definitions PropertyDefinitionConnection `graphql:"propertyDefinitions(after: $after, first: $first)"` @@ -92,19 +92,19 @@ func (client *Client) ListPropertyDefinitions(variables *PayloadVariables) (Prop variables = client.InitialPageVariablesPointer() } if err := client.Query(&q, *variables, WithName("PropertyDefinitionList")); err != nil { - return PropertyDefinitionConnection{}, err + return nil, err } for q.Account.Definitions.PageInfo.HasNextPage { (*variables)["after"] = q.Account.Definitions.PageInfo.End resp, err := client.ListPropertyDefinitions(variables) if err != nil { - return PropertyDefinitionConnection{}, err + return nil, err } q.Account.Definitions.Nodes = append(q.Account.Definitions.Nodes, resp.Nodes...) q.Account.Definitions.PageInfo = resp.PageInfo q.Account.Definitions.TotalCount += len(q.Account.Definitions.Nodes) } - return q.Account.Definitions, nil + return &q.Account.Definitions, nil } func (client *Client) DeletePropertyDefinition(input string) error { diff --git a/property_test.go b/property_test.go index a03ba6e6..da69fc85 100644 --- a/property_test.go +++ b/property_test.go @@ -15,17 +15,19 @@ const ( func TestCreatePropertyDefinition(t *testing.T) { // Arrange - schema := ol.NewJSONSchema(schemaString) - schemaAsJSON := ol.NewJSON(schemaString) + schema, schemaErr := ol.NewJSONSchema(schemaString) + schemaAsJSON, schemaAsJSONErr := ol.NewJSON(schemaString) + autopilot.Ok(t, schemaErr) + autopilot.Ok(t, schemaAsJSONErr) expectedPropertyDefinition := autopilot.Register[ol.PropertyDefinition]("expected_property_definition", ol.PropertyDefinition{ Aliases: []string{"my_prop"}, Id: "XXX", Name: "my-prop", - Schema: schemaAsJSON, + Schema: *schemaAsJSON, }) propertyDefinitionInput := autopilot.Register[ol.PropertyDefinitionInput]("property_definition_input", ol.PropertyDefinitionInput{ Name: ol.RefOf("my-prop"), - Schema: &schema, + Schema: schema, }) testRequest := autopilot.NewTestRequest( `mutation PropertyDefinitionCreate($input:PropertyDefinitionInput!){propertyDefinitionCreate(input: $input){definition{aliases,id,name,description,displaySubtype,displayType,propertyDisplayStatus,schema},errors{message,path}}}`, @@ -45,19 +47,21 @@ func TestCreatePropertyDefinition(t *testing.T) { func TestUpdatePropertyDefinition(t *testing.T) { // Arrange - schema := ol.NewJSONSchema(schemaString) - schemaAsJSON := ol.NewJSON(schemaString2) + schema, schemaErr := ol.NewJSONSchema(schemaString) + schemaAsJSON, schemaAsJSONErr := ol.NewJSON(schemaString2) + autopilot.Ok(t, schemaErr) + autopilot.Ok(t, schemaAsJSONErr) expectedPropertyDefinition := autopilot.Register[ol.PropertyDefinition]("expected_property_definition", ol.PropertyDefinition{ Aliases: []string{"my_prop"}, Id: "XXX", Name: "my-prop", Description: "this description was added", - Schema: schemaAsJSON, + Schema: *schemaAsJSON, PropertyDisplayStatus: ol.PropertyDisplayStatusEnumHidden, }) propertyDefinitionInput := autopilot.Register[ol.PropertyDefinitionInput]("property_definition_input", ol.PropertyDefinitionInput{ Description: ol.RefOf("this description was added"), - Schema: &schema, + Schema: schema, PropertyDisplayStatus: ol.RefOf(ol.PropertyDisplayStatusEnumHidden), }) testRequest := autopilot.NewTestRequest( @@ -94,13 +98,14 @@ func TestDeletePropertyDefinition(t *testing.T) { func TestGetPropertyDefinition(t *testing.T) { // Arrange - schema := ol.NewJSON(schemaString) + schema, schemaErr := ol.NewJSON(schemaString) + autopilot.Ok(t, schemaErr) expectedPropertyDefinition := autopilot.Register[ol.PropertyDefinition]("expected_property_definition", ol.PropertyDefinition{ Aliases: []string{"my_prop"}, Id: "XXX", Name: "my-prop", - Schema: schema, + Schema: *schema, }) testRequest := autopilot.NewTestRequest( `query PropertyDefinitionGet($input:IdentifierInput!){account{propertyDefinition(input: $input){aliases,id,name,description,displaySubtype,displayType,propertyDisplayStatus,schema}}}`, @@ -117,31 +122,38 @@ func TestGetPropertyDefinition(t *testing.T) { autopilot.Equals(t, "XXX", string(property.Id)) autopilot.Equals(t, expectedPropertyDefinition, *property) autopilot.Equals(t, "my-prop", property.Name) - autopilot.Equals(t, schema, property.Schema) + autopilot.Equals(t, *schema, property.Schema) } func TestListPropertyDefinitions(t *testing.T) { // Arrange - schema := ol.NewJSON(schemaString) + schema, schemaErr := ol.NewJSON(schemaString) + schemaPage1, schemaPage1Err := ol.NewJSON(schemaString) + schemaPage2, schemaPage2Err := ol.NewJSON(schemaString) + schemaPage3, schemaPage3Err := ol.NewJSON(schemaString) + autopilot.Ok(t, schemaErr) + autopilot.Ok(t, schemaPage1Err) + autopilot.Ok(t, schemaPage2Err) + autopilot.Ok(t, schemaPage3Err) expectedPropDefsPageOne := autopilot.Register[[]ol.PropertyDefinition]("property_definitions", []ol.PropertyDefinition{ { Aliases: []string{"prop1"}, Id: "XXX", Name: "prop1", - Schema: ol.NewJSON(schemaString), + Schema: *schemaPage1, }, { Aliases: []string{"prop2"}, Id: "XXX", Name: "prop2", - Schema: ol.NewJSON(schemaString), + Schema: *schemaPage2, }, }) expectedPropDefPageTwo := autopilot.Register[ol.PropertyDefinition]("property_definition_3", ol.PropertyDefinition{ Aliases: []string{"prop3"}, Id: "XXX", Name: "prop3", - Schema: ol.NewJSON(schemaString), + Schema: *schemaPage3, }) testRequestOne := autopilot.NewTestRequest( `query PropertyDefinitionList($after:String!$first:Int!){account{propertyDefinitions(after: $after, first: $first){nodes{aliases,id,name,description,displaySubtype,displayType,propertyDisplayStatus,schema},{{ template "pagination_request" }}}}}`, diff --git a/repository.go b/repository.go index 9703e0a8..16940e56 100644 --- a/repository.go +++ b/repository.go @@ -290,12 +290,12 @@ func (client *Client) ListRepositories(variables *PayloadVariables) (*Repository (*variables)["after"] = q.Account.Repositories.PageInfo.End resp, err := client.ListRepositories(variables) if err != nil { - return &RepositoryConnection{}, err + return nil, err } for _, node := range resp.Nodes { err := node.Hydrate(client) if err != nil { - return &RepositoryConnection{}, err + return nil, err } q.Account.Repositories.Nodes = append(q.Account.Repositories.Nodes, node) } @@ -322,12 +322,12 @@ func (client *Client) ListRepositoriesWithTier(tier string, variables *PayloadVa (*variables)["after"] = q.Account.Repositories.PageInfo.End resp, err := client.ListRepositoriesWithTier(tier, variables) if err != nil { - return &RepositoryConnection{}, err + return nil, err } for _, node := range resp.Nodes { err := node.Hydrate(client) if err != nil { - return &RepositoryConnection{}, err + return nil, err } q.Account.Repositories.Nodes = append(q.Account.Repositories.Nodes, node) } diff --git a/scorecards.go b/scorecards.go index 098d77f2..870b86df 100644 --- a/scorecards.go +++ b/scorecards.go @@ -58,7 +58,7 @@ func (client *Client) GetScorecard(input string) (*Scorecard, error) { return &q.Account.Scorecard, HandleErrors(err, nil) } -func (client *Client) ListScorecards(variables *PayloadVariables) (ScorecardConnection, error) { +func (client *Client) ListScorecards(variables *PayloadVariables) (*ScorecardConnection, error) { var q struct { Account struct { Scorecards ScorecardConnection `graphql:"scorecards(after: $after, first: $first)"` @@ -68,19 +68,19 @@ func (client *Client) ListScorecards(variables *PayloadVariables) (ScorecardConn variables = client.InitialPageVariablesPointer() } if err := client.Query(&q, *variables, WithName("ScorecardsList")); err != nil { - return ScorecardConnection{}, err + return nil, err } for q.Account.Scorecards.PageInfo.HasNextPage { (*variables)["after"] = q.Account.Scorecards.PageInfo.End resp, err := client.ListScorecards(variables) if err != nil { - return ScorecardConnection{}, err + return nil, err } q.Account.Scorecards.Nodes = append(q.Account.Scorecards.Nodes, resp.Nodes...) q.Account.Scorecards.PageInfo = resp.PageInfo q.Account.Scorecards.TotalCount = len(q.Account.Scorecards.Nodes) } - return q.Account.Scorecards, nil + return &q.Account.Scorecards, nil } func (client *Client) UpdateScorecard(identifier string, input ScorecardInput) (*Scorecard, error) { @@ -99,7 +99,7 @@ func (client *Client) UpdateScorecard(identifier string, input ScorecardInput) ( return &m.Payload.Scorecard, HandleErrors(err, m.Payload.Errors) } -func (client *Client) DeleteScorecard(identifier string) (ID, error) { +func (client *Client) DeleteScorecard(identifier string) (*ID, error) { var m struct { Payload struct { DeletedScorecardId ID `graphql:"deletedScorecardId"` @@ -111,5 +111,5 @@ func (client *Client) DeleteScorecard(identifier string) (ID, error) { "input": input, } err := client.Mutate(&m, v, WithName("ScorecardDelete")) - return m.Payload.DeletedScorecardId, HandleErrors(err, m.Payload.Errors) + return &m.Payload.DeletedScorecardId, HandleErrors(err, m.Payload.Errors) } diff --git a/scorecards_test.go b/scorecards_test.go index 92f742ec..218c0e90 100644 --- a/scorecards_test.go +++ b/scorecards_test.go @@ -104,7 +104,7 @@ func TestDeleteScorecard(t *testing.T) { deletedScorecardId, err := client.DeleteScorecard(scorecardId) autopilot.Ok(t, err) - autopilot.Equals(t, ol.ID(scorecardId), deletedScorecardId) + autopilot.Equals(t, ol.NewID(scorecardId), deletedScorecardId) } func TestGetScorecard(t *testing.T) { diff --git a/secrets.go b/secrets.go index d14be0eb..2afcb121 100644 --- a/secrets.go +++ b/secrets.go @@ -29,7 +29,7 @@ func (client *Client) CreateSecret(alias string, input SecretInput) (*Secret, er } // List all Secrets for your account. -func (client *Client) ListSecretsVaultsSecret(variables *PayloadVariables) (SecretsVaultsSecretConnection, error) { +func (client *Client) ListSecretsVaultsSecret(variables *PayloadVariables) (*SecretsVaultsSecretConnection, error) { var q struct { Account struct { SecretsVaultsSecrets SecretsVaultsSecretConnection `graphql:"secretsVaultsSecrets(after: $after, first: $first)"` @@ -39,19 +39,19 @@ func (client *Client) ListSecretsVaultsSecret(variables *PayloadVariables) (Secr variables = client.InitialPageVariablesPointer() } if err := client.Query(&q, *variables, WithName("SecretList")); err != nil { - return SecretsVaultsSecretConnection{}, err + return nil, err } for q.Account.SecretsVaultsSecrets.PageInfo.HasNextPage { (*variables)["after"] = q.Account.SecretsVaultsSecrets.PageInfo.End resp, err := client.ListSecretsVaultsSecret(variables) if err != nil { - return SecretsVaultsSecretConnection{}, err + return nil, err } q.Account.SecretsVaultsSecrets.Nodes = append(q.Account.SecretsVaultsSecrets.Nodes, resp.Nodes...) q.Account.SecretsVaultsSecrets.PageInfo = resp.PageInfo } q.Account.SecretsVaultsSecrets.TotalCount = len(q.Account.SecretsVaultsSecrets.Nodes) - return q.Account.SecretsVaultsSecrets, nil + return &q.Account.SecretsVaultsSecrets, nil } func (client *Client) UpdateSecret(identifier string, secretInput SecretInput) (*Secret, error) { diff --git a/secrets_test.go b/secrets_test.go index 3767ca9d..94ae8eec 100644 --- a/secrets_test.go +++ b/secrets_test.go @@ -1,7 +1,6 @@ package opslevel_test import ( - "fmt" "testing" "github.com/opslevel/opslevel-go/v2023" @@ -16,7 +15,6 @@ func TestCreateSecret(t *testing.T) { `{{ template "secret_create_response" }}`, ) client := BestTestClient(t, "secrets/create", testRequest) - fmt.Println(client) // Act secretInput := opslevel.SecretInput{ Owner: opslevel.NewIdentifier(string(id2)), diff --git a/service.go b/service.go index 9b35d2d4..c53cb500 100644 --- a/service.go +++ b/service.go @@ -358,7 +358,7 @@ func (client *Client) GetServiceCount() (int, error) { return int(q.Account.Services.TotalCount), HandleErrors(err, nil) } -func (client *Client) ListServices(variables *PayloadVariables) (ServiceConnection, error) { +func (client *Client) ListServices(variables *PayloadVariables) (*ServiceConnection, error) { var q struct { Account struct { Services ServiceConnection `graphql:"services(after: $after, first: $first)"` @@ -369,28 +369,28 @@ func (client *Client) ListServices(variables *PayloadVariables) (ServiceConnecti } if err := client.Query(&q, *variables, WithName("ServiceList")); err != nil { - return ServiceConnection{}, err + return nil, err } for q.Account.Services.PageInfo.HasNextPage { (*variables)["after"] = q.Account.Services.PageInfo.End resp, err := client.ListServices(variables) if err != nil { - return ServiceConnection{}, err + return nil, err } for _, node := range resp.Nodes { if err := node.Hydrate(client); err != nil { - return ServiceConnection{}, err + return nil, err } q.Account.Services.Nodes = append(q.Account.Services.Nodes, node) } q.Account.Services.PageInfo = resp.PageInfo q.Account.Services.TotalCount += resp.TotalCount } - return q.Account.Services, nil + return &q.Account.Services, nil } -func (client *Client) ListServicesWithFramework(framework string, variables *PayloadVariables) (ServiceConnection, error) { +func (client *Client) ListServicesWithFramework(framework string, variables *PayloadVariables) (*ServiceConnection, error) { var q struct { Account struct { Services ServiceConnection `graphql:"services(framework: $framework, after: $after, first: $first)"` @@ -402,28 +402,28 @@ func (client *Client) ListServicesWithFramework(framework string, variables *Pay (*variables)["framework"] = framework if err := client.Query(&q, *variables, WithName("ServiceListWithFramework")); err != nil { - return ServiceConnection{}, err + return nil, err } for q.Account.Services.PageInfo.HasNextPage { (*variables)["after"] = q.Account.Services.PageInfo.End resp, err := client.ListServicesWithFramework(framework, variables) if err != nil { - return ServiceConnection{}, err + return nil, err } for _, node := range resp.Nodes { if err := node.Hydrate(client); err != nil { - return ServiceConnection{}, err + return nil, err } q.Account.Services.Nodes = append(q.Account.Services.Nodes, node) } q.Account.Services.PageInfo = resp.PageInfo q.Account.Services.TotalCount += resp.TotalCount } - return q.Account.Services, nil + return &q.Account.Services, nil } -func (client *Client) ListServicesWithLanguage(language string, variables *PayloadVariables) (ServiceConnection, error) { +func (client *Client) ListServicesWithLanguage(language string, variables *PayloadVariables) (*ServiceConnection, error) { var q struct { Account struct { Services ServiceConnection `graphql:"services(language: $language, after: $after, first: $first)"` @@ -435,28 +435,28 @@ func (client *Client) ListServicesWithLanguage(language string, variables *Paylo (*variables)["language"] = language if err := client.Query(&q, *variables, WithName("ServiceListWithLanguage")); err != nil { - return ServiceConnection{}, err + return nil, err } for q.Account.Services.PageInfo.HasNextPage { (*variables)["after"] = q.Account.Services.PageInfo.End resp, err := client.ListServicesWithLanguage(language, variables) if err != nil { - return ServiceConnection{}, err + return nil, err } for _, node := range resp.Nodes { if err := node.Hydrate(client); err != nil { - return ServiceConnection{}, err + return nil, err } q.Account.Services.Nodes = append(q.Account.Services.Nodes, node) } q.Account.Services.PageInfo = resp.PageInfo q.Account.Services.TotalCount += resp.TotalCount } - return q.Account.Services, nil + return &q.Account.Services, nil } -func (client *Client) ListServicesWithLifecycle(lifecycle string, variables *PayloadVariables) (ServiceConnection, error) { +func (client *Client) ListServicesWithLifecycle(lifecycle string, variables *PayloadVariables) (*ServiceConnection, error) { var q struct { Account struct { Services ServiceConnection `graphql:"services(lifecycleAlias: $lifecycle, after: $after, first: $first)"` @@ -468,28 +468,28 @@ func (client *Client) ListServicesWithLifecycle(lifecycle string, variables *Pay (*variables)["lifecycle"] = lifecycle if err := client.Query(&q, *variables, WithName("ServiceListWithLifecycle")); err != nil { - return ServiceConnection{}, err + return nil, err } for q.Account.Services.PageInfo.HasNextPage { (*variables)["after"] = q.Account.Services.PageInfo.End resp, err := client.ListServicesWithLifecycle(lifecycle, variables) if err != nil { - return ServiceConnection{}, err + return nil, err } for _, node := range resp.Nodes { if err := node.Hydrate(client); err != nil { - return ServiceConnection{}, err + return nil, err } q.Account.Services.Nodes = append(q.Account.Services.Nodes, node) } q.Account.Services.PageInfo = resp.PageInfo q.Account.Services.TotalCount += resp.TotalCount } - return q.Account.Services, nil + return &q.Account.Services, nil } -func (client *Client) ListServicesWithOwner(owner string, variables *PayloadVariables) (ServiceConnection, error) { +func (client *Client) ListServicesWithOwner(owner string, variables *PayloadVariables) (*ServiceConnection, error) { var q struct { Account struct { Services ServiceConnection `graphql:"services(ownerAlias: $owner, after: $after, first: $first)"` @@ -501,28 +501,28 @@ func (client *Client) ListServicesWithOwner(owner string, variables *PayloadVari (*variables)["owner"] = owner if err := client.Query(&q, *variables, WithName("ServiceListWithOwner")); err != nil { - return ServiceConnection{}, err + return nil, err } for q.Account.Services.PageInfo.HasNextPage { (*variables)["after"] = q.Account.Services.PageInfo.End resp, err := client.ListServicesWithOwner(owner, variables) if err != nil { - return ServiceConnection{}, err + return nil, err } for _, node := range resp.Nodes { if err := node.Hydrate(client); err != nil { - return ServiceConnection{}, err + return nil, err } q.Account.Services.Nodes = append(q.Account.Services.Nodes, node) } q.Account.Services.PageInfo = resp.PageInfo q.Account.Services.TotalCount += resp.TotalCount } - return q.Account.Services, nil + return &q.Account.Services, nil } -func (client *Client) ListServicesWithProduct(product string, variables *PayloadVariables) (ServiceConnection, error) { +func (client *Client) ListServicesWithProduct(product string, variables *PayloadVariables) (*ServiceConnection, error) { var q struct { Account struct { Services ServiceConnection `graphql:"services(product: $product, after: $after, first: $first)"` @@ -534,25 +534,25 @@ func (client *Client) ListServicesWithProduct(product string, variables *Payload (*variables)["product"] = product if err := client.Query(&q, *variables, WithName("ServiceListWithProduct")); err != nil { - return ServiceConnection{}, err + return nil, err } for q.Account.Services.PageInfo.HasNextPage { (*variables)["after"] = q.Account.Services.PageInfo.End resp, err := client.ListServicesWithProduct(product, variables) if err != nil { - return ServiceConnection{}, err + return nil, err } for _, node := range resp.Nodes { if err := node.Hydrate(client); err != nil { - return ServiceConnection{}, err + return nil, err } q.Account.Services.Nodes = append(q.Account.Services.Nodes, node) } q.Account.Services.PageInfo = resp.PageInfo q.Account.Services.TotalCount += resp.TotalCount } - return q.Account.Services, nil + return &q.Account.Services, nil } func NewTagArgs(tag string) TagArgs { @@ -574,7 +574,7 @@ func NewTagArgs(tag string) TagArgs { } } -func (client *Client) ListServicesWithTag(tag TagArgs, variables *PayloadVariables) (ServiceConnection, error) { +func (client *Client) ListServicesWithTag(tag TagArgs, variables *PayloadVariables) (*ServiceConnection, error) { var q struct { Account struct { Services ServiceConnection `graphql:"services(tag: $tag, after: $after, first: $first)"` @@ -586,28 +586,28 @@ func (client *Client) ListServicesWithTag(tag TagArgs, variables *PayloadVariabl (*variables)["tag"] = tag if err := client.Query(&q, *variables, WithName("ServiceListWithTag")); err != nil { - return ServiceConnection{}, err + return nil, err } for q.Account.Services.PageInfo.HasNextPage { (*variables)["after"] = q.Account.Services.PageInfo.End resp, err := client.ListServicesWithTag(tag, variables) if err != nil { - return ServiceConnection{}, err + return nil, err } for _, node := range resp.Nodes { if err := node.Hydrate(client); err != nil { - return ServiceConnection{}, err + return nil, err } q.Account.Services.Nodes = append(q.Account.Services.Nodes, node) } q.Account.Services.PageInfo = resp.PageInfo q.Account.Services.TotalCount += resp.TotalCount } - return q.Account.Services, nil + return &q.Account.Services, nil } -func (client *Client) ListServicesWithTier(tier string, variables *PayloadVariables) (ServiceConnection, error) { +func (client *Client) ListServicesWithTier(tier string, variables *PayloadVariables) (*ServiceConnection, error) { var q struct { Account struct { Services ServiceConnection `graphql:"services(tierAlias: $tier, after: $after, first: $first)"` @@ -619,25 +619,25 @@ func (client *Client) ListServicesWithTier(tier string, variables *PayloadVariab (*variables)["tier"] = tier if err := client.Query(&q, *variables, WithName("ServiceListWithTier")); err != nil { - return ServiceConnection{}, err + return nil, err } for q.Account.Services.PageInfo.HasNextPage { (*variables)["after"] = q.Account.Services.PageInfo.End resp, err := client.ListServicesWithTier(tier, variables) if err != nil { - return ServiceConnection{}, err + return nil, err } for _, node := range resp.Nodes { if err := node.Hydrate(client); err != nil { - return ServiceConnection{}, err + return nil, err } q.Account.Services.Nodes = append(q.Account.Services.Nodes, node) } q.Account.Services.PageInfo = resp.PageInfo q.Account.Services.TotalCount += resp.TotalCount } - return q.Account.Services, nil + return &q.Account.Services, nil } //#endregion @@ -667,8 +667,14 @@ func (client *Client) UpdateService(input ServiceUpdateInput) (*Service, error) //#region Delete -// TODO: we should have a method that takes and ID and that follows the convention of other delete functions -func (client *Client) DeleteService(input ServiceDeleteInput) error { +func (client *Client) DeleteService(identifier string) error { + input := ServiceDeleteInput{} + if IsID(identifier) { + input.Id = NewID(identifier) + } else { + input.Alias = &identifier + } + var m struct { Payload struct { Id ID `graphql:"deletedServiceId"` @@ -683,10 +689,4 @@ func (client *Client) DeleteService(input ServiceDeleteInput) error { return HandleErrors(err, m.Payload.Errors) } -func (client *Client) DeleteServiceWithAlias(alias string) error { - return client.DeleteService(ServiceDeleteInput{ - Alias: RefOf(alias), - }) -} - //#endregion diff --git a/service_test.go b/service_test.go index ac48386c..40b16d8e 100644 --- a/service_test.go +++ b/service_test.go @@ -901,7 +901,7 @@ func TestDeleteService(t *testing.T) { ) client := BestTestClient(t, "service/delete", testRequest) // Act - err := client.DeleteService(ol.ServiceDeleteInput{Id: ol.NewID("Z2lkOi8vb3BzbGV2ZWwvU2VydmljZS82NzQ3")}) + err := client.DeleteService("Z2lkOi8vb3BzbGV2ZWwvU2VydmljZS82NzQ3") // Assert autopilot.Ok(t, err) } @@ -915,7 +915,7 @@ func TestDeleteServicesWithAlias(t *testing.T) { ) client := BestTestClient(t, "service/delete_with_alias", testRequest) // Act - err := client.DeleteServiceWithAlias("db") + err := client.DeleteService("db") // Assert autopilot.Ok(t, err) } diff --git a/system.go b/system.go index 78e2a329..a7dc7717 100644 --- a/system.go +++ b/system.go @@ -153,13 +153,13 @@ func (c *Client) ListSystems(variables *PayloadVariables) (*SystemConnection, er variables = c.InitialPageVariablesPointer() } if err := c.Query(&q, *variables, WithName("SystemsList")); err != nil { - return &SystemConnection{}, err + return nil, err } for q.Account.Systems.PageInfo.HasNextPage { (*variables)["after"] = q.Account.Systems.PageInfo.End resp, err := c.ListSystems(variables) if err != nil { - return &SystemConnection{}, err + return nil, err } q.Account.Systems.Nodes = append(q.Account.Systems.Nodes, resp.Nodes...) q.Account.Systems.PageInfo = resp.PageInfo diff --git a/team.go b/team.go index 37f581ba..26d6c98c 100644 --- a/team.go +++ b/team.go @@ -341,18 +341,18 @@ func (client *Client) ListTeams(variables *PayloadVariables) (*TeamConnection, e } if err := client.Query(&q, *variables, WithName("TeamList")); err != nil { - return &TeamConnection{}, err + return nil, err } for q.Account.Teams.PageInfo.HasNextPage { (*variables)["after"] = q.Account.Teams.PageInfo.End resp, err := client.ListTeams(variables) if err != nil { - return &TeamConnection{}, err + return nil, err } for _, node := range resp.Nodes { if err := node.Hydrate(client); err != nil { - return &TeamConnection{}, err + return nil, err } q.Account.Teams.Nodes = append(q.Account.Teams.Nodes, node) } @@ -374,18 +374,18 @@ func (client *Client) ListTeamsWithManager(email string, variables *PayloadVaria (*variables)["email"] = email if err := client.Query(&q, *variables, WithName("TeamList")); err != nil { - return &TeamConnection{}, err + return nil, err } for q.Account.Teams.PageInfo.HasNextPage { (*variables)["after"] = q.Account.Teams.PageInfo.End resp, err := client.ListTeamsWithManager(email, variables) if err != nil { - return &TeamConnection{}, err + return nil, err } for _, node := range resp.Nodes { if err := node.Hydrate(client); err != nil { - return &TeamConnection{}, err + return nil, err } q.Account.Teams.Nodes = append(q.Account.Teams.Nodes, node) } @@ -446,24 +446,14 @@ func (client *Client) UpdateContact(id ID, contact ContactInput) (*Contact, erro //#region Delete -func (client *Client) DeleteTeamWithAlias(alias string) error { - var m struct { - Payload struct { - Id ID `graphql:"deletedTeamId"` - Alias string `graphql:"deletedTeamAlias"` - Errors []OpsLevelErrors `graphql:"errors"` - } `graphql:"teamDelete(input: $input)"` - } - v := PayloadVariables{ - "input": TeamDeleteInput{ - Alias: &alias, - }, +func (client *Client) DeleteTeam(identifier string) error { + input := TeamDeleteInput{} + if IsID(identifier) { + input.Id = NewID(identifier) + } else { + input.Alias = &identifier } - err := client.Mutate(&m, v, WithName("TeamDelete")) - return HandleErrors(err, m.Payload.Errors) -} -func (client *Client) DeleteTeam(id ID) error { var m struct { Payload struct { Id ID `graphql:"deletedTeamId"` @@ -472,9 +462,7 @@ func (client *Client) DeleteTeam(id ID) error { } `graphql:"teamDelete(input: $input)"` } v := PayloadVariables{ - "input": TeamDeleteInput{ - Id: &id, - }, + "input": input, } err := client.Mutate(&m, v, WithName("TeamDelete")) return HandleErrors(err, m.Payload.Errors) diff --git a/team_test.go b/team_test.go index 0156ca1e..7073bfdc 100644 --- a/team_test.go +++ b/team_test.go @@ -654,7 +654,7 @@ func TestDeleteTeam(t *testing.T) { ) client := BestTestClient(t, "team/delete", testRequest) // Act - err := client.DeleteTeam(id3) + err := client.DeleteTeam(string(id3)) // Assert autopilot.Ok(t, err) } @@ -668,7 +668,7 @@ func TestDeleteTeamWithAlias(t *testing.T) { ) client := BestTestClient(t, "team/delete_with_alias", testRequest) // Act - err := client.DeleteTeamWithAlias("example") + err := client.DeleteTeam("example") // Assert autopilot.Ok(t, err) } diff --git a/user.go b/user.go index add26841..cf1cfcba 100644 --- a/user.go +++ b/user.go @@ -35,13 +35,13 @@ func (u *User) ResourceType() TaggableResource { //#region Helpers -func NewUserIdentifier(value string) UserIdentifierInput { +func NewUserIdentifier(value string) *UserIdentifierInput { if IsID(value) { - return UserIdentifierInput{ + return &UserIdentifierInput{ Id: NewID(value), } } - return UserIdentifierInput{ + return &UserIdentifierInput{ Email: RefOf(value), } } @@ -144,13 +144,13 @@ func (client *Client) GetUser(value string) (*User, error) { } } v := PayloadVariables{ - "input": NewUserIdentifier(value), + "input": *NewUserIdentifier(value), } err := client.Query(&q, v, WithName("UserGet")) return &q.Account.User, HandleErrors(err, nil) } -func (client *Client) ListUsers(variables *PayloadVariables) (UserConnection, error) { +func (client *Client) ListUsers(variables *PayloadVariables) (*UserConnection, error) { var q struct { Account struct { Users UserConnection `graphql:"users(after: $after, first: $first)"` @@ -161,20 +161,20 @@ func (client *Client) ListUsers(variables *PayloadVariables) (UserConnection, er } if err := client.Query(&q, *variables, WithName("UserList")); err != nil { - return UserConnection{}, err + return nil, err } for q.Account.Users.PageInfo.HasNextPage { (*variables)["after"] = q.Account.Users.PageInfo.End resp, err := client.ListUsers(variables) if err != nil { - return UserConnection{}, err + return nil, err } q.Account.Users.Nodes = append(q.Account.Users.Nodes, resp.Nodes...) q.Account.Users.PageInfo = resp.PageInfo q.Account.Users.TotalCount += resp.TotalCount } - return q.Account.Users, nil + return &q.Account.Users, nil } //#endregion @@ -189,7 +189,7 @@ func (client *Client) UpdateUser(user string, input UserInput) (*User, error) { } `graphql:"userUpdate(user: $user input: $input)"` } v := PayloadVariables{ - "user": NewUserIdentifier(user), + "user": *NewUserIdentifier(user), "input": input, } err := client.Mutate(&m, v, WithName("UserUpdate")) @@ -207,7 +207,7 @@ func (client *Client) DeleteUser(user string) error { } `graphql:"userDelete(user: $user)"` } v := PayloadVariables{ - "user": NewUserIdentifier(user), + "user": *NewUserIdentifier(user), } err := client.Mutate(&m, v, WithName("UserDelete")) return HandleErrors(err, m.Payload.Errors) diff --git a/utils.go b/utils.go index 9d798919..272ed172 100644 --- a/utils.go +++ b/utils.go @@ -1,11 +1,8 @@ package opslevel import ( - "encoding/json" - - "github.com/creasty/defaults" "github.com/go-playground/validator/v10" - "gopkg.in/yaml.v3" + "github.com/opslevel/moredefaults" ) var structValidator = validator.New(validator.WithRequiredStructEnabled()) @@ -18,34 +15,22 @@ func IsResourceValid[T any](opslevelResource T) error { // Apply resource's `default:""` struct tags func SetDefaultsFor[T any](opslevelResource *T) { validator.New(validator.WithRequiredStructEnabled()) - if err := defaults.Set(opslevelResource); err != nil { + if err := moredefaults.Set(opslevelResource); err != nil { panic(err) } } -// Make new OpsLevel resource with defaults set -func NewExampleOf[T any]() T { - var opslevelResource T - SetDefaultsFor[T](&opslevelResource) - return opslevelResource -} - -// Get JSON formatted string of an OpsLevel resource - also sets defaults -func JsonOf[T any](opslevelResource T) string { - SetDefaultsFor[T](&opslevelResource) - out, err := json.Marshal(opslevelResource) - if err != nil { +// Apply resource's `example:""` struct tags +func SetExamplesFor[T any](opslevelResource *T) { + validator.New(validator.WithRequiredStructEnabled()) + if err := moredefaults.Set(opslevelResource, "example"); err != nil { panic(err) } - return string(out) } -// Generate yaml formatted string of an OpsLevel resource - also sets defaults -func YamlOf[T any](opslevelResource T) string { - SetDefaultsFor[T](&opslevelResource) - out, err := yaml.Marshal(opslevelResource) - if err != nil { - panic(err) - } - return string(out) +// Make new OpsLevel resource with defaults set +func NewExampleOf[T any]() T { + var opslevelResource T + SetExamplesFor[T](&opslevelResource) + return opslevelResource }