From d1804b24d210633cc964e7b067ed09b7851420d7 Mon Sep 17 00:00:00 2001 From: Sarah Funkhouser <147884153+golanglemonade@users.noreply.github.com> Date: Sun, 1 Nov 2026 21:45:22 -0700 Subject: [PATCH] feat: group vuln by cve id Signed-off-by: Sarah Funkhouser <147884153+golanglemonade@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 +- internal/ent/schema/mixin_controls.go | 4 + internal/ent/schema/mixin_customenums.go | 19 +- internal/ent/schema/vulnerability.go | 14 +- .../checksum/.history_schema_checksum | 2 +- internal/graphapi/clientschema/schema.graphql | 315 +++- internal/graphapi/generate/gen_gqlgen.go | 4 + internal/graphapi/generated/ent.generated.go | 340 ++++ .../graphapi/generated/groupby.generated.go | 1504 +++++++++++++++++ .../graphapi/generated/root_.generated.go | 662 +++++++- internal/graphapi/groupby.resolvers.go | 305 ++++ .../historygenerated/ent.generated.go | 6 +- .../historygenerated/prelude.generated.go | 75 +- .../checksum/.history_schema_checksum | 2 +- internal/graphapi/model/gen_models.go | 174 ++ internal/graphapi/notes_test.go | 2 +- .../graphapi/query/controlextended.graphql | 46 + .../query/vulnerabilityextended.graphql | 109 ++ .../graphapi/schema/controlextended.graphql | 10 +- internal/graphapi/schema/groupby.graphql | 287 ++++ .../schema/vulnerability_summary.graphql | 2 +- internal/graphapi/testclient/graphclient.go | 1161 +++++++++++++ internal/graphapi/testclient/models.go | 174 ++ internal/graphapi/vulnerability_test.go | 130 +- 25 files changed, 5283 insertions(+), 70 deletions(-) create mode 100644 internal/graphapi/generated/groupby.generated.go create mode 100644 internal/graphapi/groupby.resolvers.go create mode 100644 internal/graphapi/query/vulnerabilityextended.graphql create mode 100644 internal/graphapi/schema/groupby.graphql diff --git a/go.mod b/go.mod index bfcd7d0b97..9e9d3934b3 100644 --- a/go.mod +++ b/go.mod @@ -119,7 +119,7 @@ require ( github.com/theopenlane/eddy v0.1.0 github.com/theopenlane/entx v0.36.3 github.com/theopenlane/go-client v0.15.0 - github.com/theopenlane/gqlgen-plugins v0.18.4 + github.com/theopenlane/gqlgen-plugins v0.19.0 github.com/theopenlane/httpsling v0.3.0 github.com/theopenlane/iam v0.41.1 github.com/theopenlane/logx v0.1.1 diff --git a/go.sum b/go.sum index 2d903fcae5..0fcb2c1497 100644 --- a/go.sum +++ b/go.sum @@ -822,8 +822,8 @@ github.com/theopenlane/entx v0.36.3 h1:BMVtL+FESaSAI5AtNQSly/DU6WZyep3ENYeyHhcC6 github.com/theopenlane/entx v0.36.3/go.mod h1:p1eAOkVRExjf17q7WkFknI7/Q+l8tOGpFH4pI/98odc= github.com/theopenlane/go-client v0.15.0 h1:Jz1y0cm46lN24rog8YakV7u7jxgTZ9NZ4iIxP6mbMLs= github.com/theopenlane/go-client v0.15.0/go.mod h1:E0KiZ+wOpJf/GAD0F223vpsizFmqRomJETKMtMaLmZI= -github.com/theopenlane/gqlgen-plugins v0.18.4 h1:433KyDIW5y72aqMqkMAiIq0R7Y4OJ7laRBJaO6UchYM= -github.com/theopenlane/gqlgen-plugins v0.18.4/go.mod h1:AhBPUZSil2tXQOejR1co98DQznofub4PXFeK/7SXsxA= +github.com/theopenlane/gqlgen-plugins v0.19.0 h1:tMnVF6ET2oKRewhlO78lCGUROOp4B/MTpi2al+SgQ6I= +github.com/theopenlane/gqlgen-plugins v0.19.0/go.mod h1:27Najan1nmCf2X79lYVvHJBs0R+kOzuwzGaP8uTQXF8= github.com/theopenlane/httpsling v0.3.0 h1:Bad0dGdqCqAB8UVDyVo+YCevzRvGHhmkK22F7T3pXtY= github.com/theopenlane/httpsling v0.3.0/go.mod h1:iJc3XRLYTFIpfCnPpLZVMBP0xsWIPAb7ozARtQoclAE= github.com/theopenlane/iam v0.41.1 h1:Rgeh1xod4emmv1BKgK0IWeg7G98ouUfziFDtcdP7Vwk= diff --git a/internal/ent/schema/mixin_controls.go b/internal/ent/schema/mixin_controls.go index e461159db5..0975462d34 100644 --- a/internal/ent/schema/mixin_controls.go +++ b/internal/ent/schema/mixin_controls.go @@ -19,6 +19,8 @@ import ( "github.com/theopenlane/entx/accessmap" + "github.com/theopenlane/gqlgen-plugins/groupby" + "github.com/theopenlane/core/common/enums" "github.com/theopenlane/core/common/models" "github.com/theopenlane/core/v2/internal/ent/generated/hook" @@ -363,6 +365,7 @@ var controlFields = []ent.Field{ entgql.OrderField("category"), entx.FieldWorkflowEligible(), directives.ExternalSourceDirectiveAnnotation, + groupby.Groupable(), ). Comment("category of the control"), field.String("category_id"). @@ -379,6 +382,7 @@ var controlFields = []ent.Field{ entgql.OrderField("subcategory"), directives.ExternalSourceDirectiveAnnotation, entx.FieldWorkflowEligible(), + groupby.Groupable(), ). Comment("subcategory of the control"), field.Strings("mapped_categories"). diff --git a/internal/ent/schema/mixin_customenums.go b/internal/ent/schema/mixin_customenums.go index fc5a07ccbb..5bababeae5 100644 --- a/internal/ent/schema/mixin_customenums.go +++ b/internal/ent/schema/mixin_customenums.go @@ -12,6 +12,7 @@ import ( "github.com/theopenlane/core/v2/internal/ent/hooks" "github.com/theopenlane/entx" "github.com/theopenlane/entx/accessmap" + "github.com/theopenlane/gqlgen-plugins/groupby" ) // CustomEnumMixin holds the schema definition for the custom enums @@ -28,6 +29,8 @@ type CustomEnumMixin struct { GlobalEnum bool // DisableAutoCreate disables auto-creation of the enum if it doesn't exist DisableAutoCreate bool + // GroupBy adds the enum name field to the schema's generated group by query + GroupBy bool } // newCustomEnumMixin creates a new CustomEnumMixin with the given schema type and options @@ -68,16 +71,26 @@ func withGlobalEnum() customEnumOptions { } } +// withGroupByEnum makes the enum name field groupable in the schema's group by query +func withGroupByEnum() customEnumOptions { + return func(c *CustomEnumMixin) { + c.GroupBy = true + } +} + // Fields of the CustomEnumMixin. func (c CustomEnumMixin) Fields() []ent.Field { + nameAnnotations := []schema.Annotation{entx.FieldCaseInsensitive()} + if c.GroupBy { + nameAnnotations = append(nameAnnotations, groupby.Groupable()) + } + schema := toSchemaFuncs(c.schemaType) fields := []ent.Field{ field.String(c.getEnumFieldName()). Comment("the " + c.fieldName + " of the " + schema.Name()). Optional(). - Annotations( - entx.FieldCaseInsensitive(), - ), + Annotations(nameAnnotations...), field.String(c.getEnumEdgeName() + "_id"). Comment("the " + c.fieldName + " of the " + schema.Name()). Optional(), diff --git a/internal/ent/schema/vulnerability.go b/internal/ent/schema/vulnerability.go index f216c7bbeb..89f3f0c8ff 100644 --- a/internal/ent/schema/vulnerability.go +++ b/internal/ent/schema/vulnerability.go @@ -12,8 +12,10 @@ import ( "github.com/theopenlane/iam/entfga" "github.com/theopenlane/core/common/enums" - "github.com/theopenlane/core/common/models" + + "github.com/theopenlane/gqlgen-plugins/groupby" + "github.com/theopenlane/core/v2/internal/ent/generated" "github.com/theopenlane/core/v2/internal/ent/hooks" "github.com/theopenlane/core/v2/internal/ent/mixin" @@ -56,6 +58,7 @@ func (Vulnerability) Fields() []ent.Field { Annotations( entx.FieldSearchable(), entgql.OrderField("external_owner_id"), + groupby.Groupable(), ), field.Enum("security_level"). Comment("security level of the vulnerability"). @@ -74,10 +77,14 @@ func (Vulnerability) Fields() []ent.Field { entx.FieldSearchable(), entgql.OrderField("cve_id"), entx.IntegrationMappingField(), + groupby.Groupable(), ), field.String("source"). Comment("system that produced the vulnerability record"). - Optional(), + Optional(). + Annotations( + groupby.Groupable(), + ), field.String("display_name"). Comment("display name for the vulnerability when provided"). Optional(), @@ -94,6 +101,7 @@ func (Vulnerability) Fields() []ent.Field { entgql.OrderField("severity"), entx.FieldSearchable(), entx.FieldWorkflowEligible(), + groupby.Groupable(), ), field.Float("score"). Comment("overall score such as CVSS for the vulnerability"). @@ -396,7 +404,7 @@ func (v Vulnerability) Mixin() []ent.Mixin { mixin.NewSystemOwnedMixin(mixin.SkipTupleCreation()), newCustomEnumMixin(v, withEnumFieldName("environment"), withGlobalEnum()), newCustomEnumMixin(v, withEnumFieldName("scope"), withGlobalEnum()), - newCustomEnumMixin(v, withEnumFieldName("status")), + newCustomEnumMixin(v, withEnumFieldName("status"), withGroupByEnum()), WorkflowApprovalMixin{}, }, }.getMixins(v) diff --git a/internal/graphapi/checksum/.history_schema_checksum b/internal/graphapi/checksum/.history_schema_checksum index 14d8f62f32..b30df8ebd1 100644 --- a/internal/graphapi/checksum/.history_schema_checksum +++ b/internal/graphapi/checksum/.history_schema_checksum @@ -1 +1 @@ -fb5cd59253feb3228c795d7555c6d07ce8bff65a719c3b20f4ab212d89a3481e \ No newline at end of file +32829015adf08e77033cdb594304b9314db26283cf1a0221a054802ef292a543 \ No newline at end of file diff --git a/internal/graphapi/clientschema/schema.graphql b/internal/graphapi/clientschema/schema.graphql index e0eac38934..1338fbf3cd 100644 --- a/internal/graphapi/clientschema/schema.graphql +++ b/internal/graphapi/clientschema/schema.graphql @@ -13,6 +13,7 @@ Indicates that this field cannot be set on the input, and comes from an external This does not prevent the viewing of the field """ directive @externalSource(source: ControlControlSource) on OBJECT | FIELD_DEFINITION +directive @goEnum(value: String) on ENUM_VALUE directive @goField(forceResolver: Boolean, name: String, omittable: Boolean) on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @goModel(model: String, models: [String!], forceGenerate: Boolean) on OBJECT | INPUT_OBJECT | SCALAR | ENUM | INTERFACE | UNION """ @@ -10673,6 +10674,60 @@ type ControlGroup { category: String! controls: ControlConnection! } +""" +ControlGroupByBucket is a group of controls sharing the same value for the grouped field +""" +type ControlGroupByBucket @goModel(model: "github.com/theopenlane/gqlgen-plugins/groupby.Bucket") { + """ + The grouped value, null when the rows have no value + """ + key: String + """ + The number of controls in the group + """ + count: Int! + """ + The controls in the group + """ + controls(after: Cursor, first: Int, before: Cursor, last: Int, orderBy: [ControlOrder!]): ControlConnection! @goField(forceResolver: true) +} +""" +ControlGroupByConnection is a paginated list of Control group by buckets +""" +type ControlGroupByConnection @goModel(model: "github.com/theopenlane/gqlgen-plugins/groupby.Connection") { + """ + A list of edges + """ + edges: [ControlGroupByEdge!]! + """ + Information to aid in pagination + """ + pageInfo: PageInfo! + """ + Identifies the total count of groups in the connection + """ + totalCount: Int! +} +""" +ControlGroupByEdge is a Control group by bucket with its pagination cursor +""" +type ControlGroupByEdge @goModel(model: "github.com/theopenlane/gqlgen-plugins/groupby.Edge") { + """ + The bucket at the end of the edge + """ + node: ControlGroupByBucket! + """ + A cursor for use in pagination + """ + cursor: Cursor! +} +""" +ControlGroupByField are the Control fields that can be grouped on +""" +enum ControlGroupByField { + CATEGORY + SUBCATEGORY +} type ControlGroupConnection { edges: [ControlGroupEdge!]! } @@ -36264,6 +36319,26 @@ type GroupBulkUpdatePayload { error: String } """ +GroupByOrder is the ordering of group by buckets +""" +input GroupByOrder @goModel(model: "github.com/theopenlane/gqlgen-plugins/groupby.Order") { + """ + The ordering direction + """ + direction: OrderDirection! = DESC + """ + The field by which to order the groups + """ + field: GroupByOrderField! = COUNT +} +""" +GroupByOrderField is the field group by buckets are ordered by +""" +enum GroupByOrderField @goModel(model: "github.com/theopenlane/gqlgen-plugins/groupby.OrderField") { + COUNT @goEnum(value: "github.com/theopenlane/gqlgen-plugins/groupby.OrderFieldCount") + KEY @goEnum(value: "github.com/theopenlane/gqlgen-plugins/groupby.OrderFieldKey") +} +""" A connection to a list of items. """ type GroupConnection { @@ -68606,11 +68681,11 @@ type Query { """ All existing categories or domains used in the organization @deprecated """ - controlCategories: [String!] + controlCategories: [String!] @deprecated(reason: "use controlsGroupBy and subcontrolsGroupBy with field: CATEGORY") """ All existing subcategories or domains used in the organization @deprecated """ - controlSubcategories: [String!] + controlSubcategories: [String!] @deprecated(reason: "use controlsGroupBy and subcontrolsGroupBy with field: SUBCATEGORY") """ Existing categories or domains for controls used in the organization """ @@ -68624,7 +68699,7 @@ type Query { Filtering options for APITokens returned from the connection. """ where: ControlWhereInput - ): [ControlCategoryEdge!] + ): [ControlCategoryEdge!] @deprecated(reason: "use controlsGroupBy with field: CATEGORY") """ Existing subcategories or subdomains for controls used in the organization """ @@ -68638,7 +68713,7 @@ type Query { Filtering options for APITokens returned from the connection. """ where: ControlWhereInput - ): [ControlCategoryEdge!] + ): [ControlCategoryEdge!] @deprecated(reason: "use controlsGroupBy with field: SUBCATEGORY") """ Get controls grouped by category """ @@ -68677,7 +68752,7 @@ type Query { Filter by category, used for paginated requests to pull more data per category """ category: String - ): ControlGroupConnection! + ): ControlGroupConnection! @deprecated(reason: "use controlsGroupBy with field: CATEGORY") """ Look up controlImplementation by ID """ @@ -68930,6 +69005,123 @@ type Query { id: ID! ): Group! """ + controlsGroupBy groups controls by a field and returns each group with its count and rows + """ + controlsGroupBy( + """ + The field to group by + """ + field: ControlGroupByField! + + """ + Filtering options for controls included in the groups + """ + where: ControlWhereInput + + """ + Ordering options for the groups, defaults to count descending + """ + orderBy: GroupByOrder + + """ + Returns the groups that come after the specified cursor + """ + after: Cursor + + """ + Returns the first _n_ groups + """ + first: Int + + """ + Returns the groups that come before the specified cursor + """ + before: Cursor + + """ + Returns the last _n_ groups + """ + last: Int + ): ControlGroupByConnection! + """ + subcontrolsGroupBy groups subcontrols by a field and returns each group with its count and rows + """ + subcontrolsGroupBy( + """ + The field to group by + """ + field: SubcontrolGroupByField! + + """ + Filtering options for subcontrols included in the groups + """ + where: SubcontrolWhereInput + + """ + Ordering options for the groups, defaults to count descending + """ + orderBy: GroupByOrder + + """ + Returns the groups that come after the specified cursor + """ + after: Cursor + + """ + Returns the first _n_ groups + """ + first: Int + + """ + Returns the groups that come before the specified cursor + """ + before: Cursor + + """ + Returns the last _n_ groups + """ + last: Int + ): SubcontrolGroupByConnection! + """ + vulnerabilitiesGroupBy groups vulnerabilities by a field and returns each group with its count and rows + """ + vulnerabilitiesGroupBy( + """ + The field to group by + """ + field: VulnerabilityGroupByField! + + """ + Filtering options for vulnerabilities included in the groups + """ + where: VulnerabilityWhereInput + + """ + Ordering options for the groups, defaults to count descending + """ + orderBy: GroupByOrder + + """ + Returns the groups that come after the specified cursor + """ + after: Cursor + + """ + Returns the first _n_ groups + """ + first: Int + + """ + Returns the groups that come before the specified cursor + """ + before: Cursor + + """ + Returns the last _n_ groups + """ + last: Int + ): VulnerabilityGroupByConnection! + """ Look up groupMembership by ID """ groupMembership( @@ -70612,7 +70804,7 @@ type Query { Filtering options for vulnerabilities included in the summary. """ where: VulnerabilityWhereInput - ): VulnerabilitySummary! + ): VulnerabilitySummary! @deprecated(reason: "use vulnerabilitiesGroupBy with field: SEVERITY, SOURCE, or VULNERABILITY_STATUS_NAME") """ Look up workflowAssignment by ID """ @@ -80145,6 +80337,60 @@ type SubcontrolEdge { cursor: Cursor! } """ +SubcontrolGroupByBucket is a group of subcontrols sharing the same value for the grouped field +""" +type SubcontrolGroupByBucket @goModel(model: "github.com/theopenlane/gqlgen-plugins/groupby.Bucket") { + """ + The grouped value, null when the rows have no value + """ + key: String + """ + The number of subcontrols in the group + """ + count: Int! + """ + The subcontrols in the group + """ + subcontrols(after: Cursor, first: Int, before: Cursor, last: Int, orderBy: [SubcontrolOrder!]): SubcontrolConnection! @goField(forceResolver: true) +} +""" +SubcontrolGroupByConnection is a paginated list of Subcontrol group by buckets +""" +type SubcontrolGroupByConnection @goModel(model: "github.com/theopenlane/gqlgen-plugins/groupby.Connection") { + """ + A list of edges + """ + edges: [SubcontrolGroupByEdge!]! + """ + Information to aid in pagination + """ + pageInfo: PageInfo! + """ + Identifies the total count of groups in the connection + """ + totalCount: Int! +} +""" +SubcontrolGroupByEdge is a Subcontrol group by bucket with its pagination cursor +""" +type SubcontrolGroupByEdge @goModel(model: "github.com/theopenlane/gqlgen-plugins/groupby.Edge") { + """ + The bucket at the end of the edge + """ + node: SubcontrolGroupByBucket! + """ + A cursor for use in pagination + """ + cursor: Cursor! +} +""" +SubcontrolGroupByField are the Subcontrol fields that can be grouped on +""" +enum SubcontrolGroupByField { + CATEGORY + SUBCATEGORY +} +""" Ordering options for Subcontrol connections """ input SubcontrolOrder { @@ -102473,6 +102719,63 @@ type VulnerabilityEdge { cursor: Cursor! } """ +VulnerabilityGroupByBucket is a group of vulnerabilities sharing the same value for the grouped field +""" +type VulnerabilityGroupByBucket @goModel(model: "github.com/theopenlane/gqlgen-plugins/groupby.Bucket") { + """ + The grouped value, null when the rows have no value + """ + key: String + """ + The number of vulnerabilities in the group + """ + count: Int! + """ + The vulnerabilities in the group + """ + vulnerabilities(after: Cursor, first: Int, before: Cursor, last: Int, orderBy: [VulnerabilityOrder!]): VulnerabilityConnection! @goField(forceResolver: true) +} +""" +VulnerabilityGroupByConnection is a paginated list of Vulnerability group by buckets +""" +type VulnerabilityGroupByConnection @goModel(model: "github.com/theopenlane/gqlgen-plugins/groupby.Connection") { + """ + A list of edges + """ + edges: [VulnerabilityGroupByEdge!]! + """ + Information to aid in pagination + """ + pageInfo: PageInfo! + """ + Identifies the total count of groups in the connection + """ + totalCount: Int! +} +""" +VulnerabilityGroupByEdge is a Vulnerability group by bucket with its pagination cursor +""" +type VulnerabilityGroupByEdge @goModel(model: "github.com/theopenlane/gqlgen-plugins/groupby.Edge") { + """ + The bucket at the end of the edge + """ + node: VulnerabilityGroupByBucket! + """ + A cursor for use in pagination + """ + cursor: Cursor! +} +""" +VulnerabilityGroupByField are the Vulnerability fields that can be grouped on +""" +enum VulnerabilityGroupByField { + VULNERABILITY_STATUS_NAME + EXTERNAL_OWNER_ID + CVE_ID + SOURCE + SEVERITY +} +""" Ordering options for Vulnerability connections """ input VulnerabilityOrder { diff --git a/internal/graphapi/generate/gen_gqlgen.go b/internal/graphapi/generate/gen_gqlgen.go index 5e0f36cd90..970a392b45 100644 --- a/internal/graphapi/generate/gen_gqlgen.go +++ b/internal/graphapi/generate/gen_gqlgen.go @@ -82,6 +82,10 @@ func gqlGenerate() { log.Fatal().Err(err).Msg("failed to write catalog schema") } + if err := resolverPlugin.WriteGroupBySchema("./internal/ent/schema", graphapiSchemaDir); err != nil { + log.Fatal().Err(err).Msg("failed to write group by schema") + } + // check if there were schema changes before running full codegen hasChanges, err := genhelpers.HasSchemaChanges(schemaChecksumFile, mainInputPaths...) if err != nil { diff --git a/internal/graphapi/generated/ent.generated.go b/internal/graphapi/generated/ent.generated.go index 2126523e64..c0499e897b 100644 --- a/internal/graphapi/generated/ent.generated.go +++ b/internal/graphapi/generated/ent.generated.go @@ -20,6 +20,7 @@ import ( "github.com/theopenlane/core/v2/internal/ent/generated" "github.com/theopenlane/core/v2/internal/graphapi/model" "github.com/theopenlane/entx" + "github.com/theopenlane/gqlgen-plugins/groupby" "github.com/vektah/gqlparser/v2/ast" ) @@ -249,6 +250,9 @@ type QueryResolver interface { Finding(ctx context.Context, id string) (*generated.Finding, error) FindingControl(ctx context.Context, id string) (*generated.FindingControl, error) Group(ctx context.Context, id string) (*generated.Group, error) + ControlsGroupBy(ctx context.Context, field model.ControlGroupByField, where *generated.ControlWhereInput, orderBy *groupby.Order, after *entgql.Cursor[string], first *int, before *entgql.Cursor[string], last *int) (*groupby.Connection, error) + SubcontrolsGroupBy(ctx context.Context, field model.SubcontrolGroupByField, where *generated.SubcontrolWhereInput, orderBy *groupby.Order, after *entgql.Cursor[string], first *int, before *entgql.Cursor[string], last *int) (*groupby.Connection, error) + VulnerabilitiesGroupBy(ctx context.Context, field model.VulnerabilityGroupByField, where *generated.VulnerabilityWhereInput, orderBy *groupby.Order, after *entgql.Cursor[string], first *int, before *entgql.Cursor[string], last *int) (*groupby.Connection, error) GroupMembership(ctx context.Context, id string) (*generated.GroupMembership, error) GroupSetting(ctx context.Context, id string) (*generated.GroupSetting, error) Hush(ctx context.Context, id string) (*generated.Hush, error) @@ -32445,6 +32449,68 @@ func (ec *executionContext) field_Query_controlsGroupByCategory_args(ctx context return args, nil } +func (ec *executionContext) field_Query_controlsGroupBy_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := graphql.ProcessArgField(ctx, rawArgs, "field", + func(ctx context.Context, v any) (model.ControlGroupByField, error) { + return ec.unmarshalNControlGroupByField2githubᚗcomᚋtheopenlaneᚋcoreᚋv2ᚋinternalᚋgraphapiᚋmodelᚐControlGroupByField(ctx, v) + }) + if err != nil { + return nil, err + } + args["field"] = arg0 + arg1, err := graphql.ProcessArgField(ctx, rawArgs, "where", + func(ctx context.Context, v any) (*generated.ControlWhereInput, error) { + return ec.unmarshalOControlWhereInput2ᚖgithubᚗcomᚋtheopenlaneᚋcoreᚋv2ᚋinternalᚋentᚋgeneratedᚐControlWhereInput(ctx, v) + }) + if err != nil { + return nil, err + } + args["where"] = arg1 + arg2, err := graphql.ProcessArgField(ctx, rawArgs, "orderBy", + func(ctx context.Context, v any) (*groupby.Order, error) { + return ec.unmarshalOGroupByOrder2ᚖgithubᚗcomᚋtheopenlaneᚋgqlgenᚑpluginsᚋgroupbyᚐOrder(ctx, v) + }) + if err != nil { + return nil, err + } + args["orderBy"] = arg2 + arg3, err := graphql.ProcessArgField(ctx, rawArgs, "after", + func(ctx context.Context, v any) (*entgql.Cursor[string], error) { + return ec.unmarshalOCursor2ᚖentgoᚗioᚋcontribᚋentgqlᚐCursor(ctx, v) + }) + if err != nil { + return nil, err + } + args["after"] = arg3 + arg4, err := graphql.ProcessArgField(ctx, rawArgs, "first", + func(ctx context.Context, v any) (*int, error) { + return ec.unmarshalOInt2ᚖint(ctx, v) + }) + if err != nil { + return nil, err + } + args["first"] = arg4 + arg5, err := graphql.ProcessArgField(ctx, rawArgs, "before", + func(ctx context.Context, v any) (*entgql.Cursor[string], error) { + return ec.unmarshalOCursor2ᚖentgoᚗioᚋcontribᚋentgqlᚐCursor(ctx, v) + }) + if err != nil { + return nil, err + } + args["before"] = arg5 + arg6, err := graphql.ProcessArgField(ctx, rawArgs, "last", + func(ctx context.Context, v any) (*int, error) { + return ec.unmarshalOInt2ᚖint(ctx, v) + }) + if err != nil { + return nil, err + } + args["last"] = arg6 + return args, nil +} + func (ec *executionContext) field_Query_controls_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { var err error args := map[string]any{} @@ -37161,6 +37227,68 @@ func (ec *executionContext) field_Query_subcontrol_args(ctx context.Context, raw return args, nil } +func (ec *executionContext) field_Query_subcontrolsGroupBy_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := graphql.ProcessArgField(ctx, rawArgs, "field", + func(ctx context.Context, v any) (model.SubcontrolGroupByField, error) { + return ec.unmarshalNSubcontrolGroupByField2githubᚗcomᚋtheopenlaneᚋcoreᚋv2ᚋinternalᚋgraphapiᚋmodelᚐSubcontrolGroupByField(ctx, v) + }) + if err != nil { + return nil, err + } + args["field"] = arg0 + arg1, err := graphql.ProcessArgField(ctx, rawArgs, "where", + func(ctx context.Context, v any) (*generated.SubcontrolWhereInput, error) { + return ec.unmarshalOSubcontrolWhereInput2ᚖgithubᚗcomᚋtheopenlaneᚋcoreᚋv2ᚋinternalᚋentᚋgeneratedᚐSubcontrolWhereInput(ctx, v) + }) + if err != nil { + return nil, err + } + args["where"] = arg1 + arg2, err := graphql.ProcessArgField(ctx, rawArgs, "orderBy", + func(ctx context.Context, v any) (*groupby.Order, error) { + return ec.unmarshalOGroupByOrder2ᚖgithubᚗcomᚋtheopenlaneᚋgqlgenᚑpluginsᚋgroupbyᚐOrder(ctx, v) + }) + if err != nil { + return nil, err + } + args["orderBy"] = arg2 + arg3, err := graphql.ProcessArgField(ctx, rawArgs, "after", + func(ctx context.Context, v any) (*entgql.Cursor[string], error) { + return ec.unmarshalOCursor2ᚖentgoᚗioᚋcontribᚋentgqlᚐCursor(ctx, v) + }) + if err != nil { + return nil, err + } + args["after"] = arg3 + arg4, err := graphql.ProcessArgField(ctx, rawArgs, "first", + func(ctx context.Context, v any) (*int, error) { + return ec.unmarshalOInt2ᚖint(ctx, v) + }) + if err != nil { + return nil, err + } + args["first"] = arg4 + arg5, err := graphql.ProcessArgField(ctx, rawArgs, "before", + func(ctx context.Context, v any) (*entgql.Cursor[string], error) { + return ec.unmarshalOCursor2ᚖentgoᚗioᚋcontribᚋentgqlᚐCursor(ctx, v) + }) + if err != nil { + return nil, err + } + args["before"] = arg5 + arg6, err := graphql.ProcessArgField(ctx, rawArgs, "last", + func(ctx context.Context, v any) (*int, error) { + return ec.unmarshalOInt2ᚖint(ctx, v) + }) + if err != nil { + return nil, err + } + args["last"] = arg6 + return args, nil +} + func (ec *executionContext) field_Query_subcontrols_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { var err error args := map[string]any{} @@ -38897,6 +39025,68 @@ func (ec *executionContext) field_Query_vendorScoringConfigs_args(ctx context.Co return args, nil } +func (ec *executionContext) field_Query_vulnerabilitiesGroupBy_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := graphql.ProcessArgField(ctx, rawArgs, "field", + func(ctx context.Context, v any) (model.VulnerabilityGroupByField, error) { + return ec.unmarshalNVulnerabilityGroupByField2githubᚗcomᚋtheopenlaneᚋcoreᚋv2ᚋinternalᚋgraphapiᚋmodelᚐVulnerabilityGroupByField(ctx, v) + }) + if err != nil { + return nil, err + } + args["field"] = arg0 + arg1, err := graphql.ProcessArgField(ctx, rawArgs, "where", + func(ctx context.Context, v any) (*generated.VulnerabilityWhereInput, error) { + return ec.unmarshalOVulnerabilityWhereInput2ᚖgithubᚗcomᚋtheopenlaneᚋcoreᚋv2ᚋinternalᚋentᚋgeneratedᚐVulnerabilityWhereInput(ctx, v) + }) + if err != nil { + return nil, err + } + args["where"] = arg1 + arg2, err := graphql.ProcessArgField(ctx, rawArgs, "orderBy", + func(ctx context.Context, v any) (*groupby.Order, error) { + return ec.unmarshalOGroupByOrder2ᚖgithubᚗcomᚋtheopenlaneᚋgqlgenᚑpluginsᚋgroupbyᚐOrder(ctx, v) + }) + if err != nil { + return nil, err + } + args["orderBy"] = arg2 + arg3, err := graphql.ProcessArgField(ctx, rawArgs, "after", + func(ctx context.Context, v any) (*entgql.Cursor[string], error) { + return ec.unmarshalOCursor2ᚖentgoᚗioᚋcontribᚋentgqlᚐCursor(ctx, v) + }) + if err != nil { + return nil, err + } + args["after"] = arg3 + arg4, err := graphql.ProcessArgField(ctx, rawArgs, "first", + func(ctx context.Context, v any) (*int, error) { + return ec.unmarshalOInt2ᚖint(ctx, v) + }) + if err != nil { + return nil, err + } + args["first"] = arg4 + arg5, err := graphql.ProcessArgField(ctx, rawArgs, "before", + func(ctx context.Context, v any) (*entgql.Cursor[string], error) { + return ec.unmarshalOCursor2ᚖentgoᚗioᚋcontribᚋentgqlᚐCursor(ctx, v) + }) + if err != nil { + return nil, err + } + args["before"] = arg5 + arg6, err := graphql.ProcessArgField(ctx, rawArgs, "last", + func(ctx context.Context, v any) (*int, error) { + return ec.unmarshalOInt2ᚖint(ctx, v) + }) + if err != nil { + return nil, err + } + args["last"] = arg6 + return args, nil +} + func (ec *executionContext) field_Query_vulnerabilities_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { var err error args := map[string]any{} @@ -137099,6 +137289,138 @@ func (ec *executionContext) fieldContext_Query_group(ctx context.Context, field return fc, nil } +func (ec *executionContext) _Query_controlsGroupBy(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_Query_controlsGroupBy(ctx, field) + }, + func(ctx context.Context) (any, error) { + fc := graphql.GetFieldContext(ctx) + return ec.Resolvers.Query().ControlsGroupBy(ctx, fc.Args["field"].(model.ControlGroupByField), fc.Args["where"].(*generated.ControlWhereInput), fc.Args["orderBy"].(*groupby.Order), fc.Args["after"].(*entgql.Cursor[string]), fc.Args["first"].(*int), fc.Args["before"].(*entgql.Cursor[string]), fc.Args["last"].(*int)) + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *groupby.Connection) graphql.Marshaler { + return ec.marshalNControlGroupByConnection2ᚖgithubᚗcomᚋtheopenlaneᚋgqlgenᚑpluginsᚋgroupbyᚐConnection(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_Query_controlsGroupBy(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_ControlGroupByConnection(ctx, field) + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_Query_controlsGroupBy_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query_subcontrolsGroupBy(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_Query_subcontrolsGroupBy(ctx, field) + }, + func(ctx context.Context) (any, error) { + fc := graphql.GetFieldContext(ctx) + return ec.Resolvers.Query().SubcontrolsGroupBy(ctx, fc.Args["field"].(model.SubcontrolGroupByField), fc.Args["where"].(*generated.SubcontrolWhereInput), fc.Args["orderBy"].(*groupby.Order), fc.Args["after"].(*entgql.Cursor[string]), fc.Args["first"].(*int), fc.Args["before"].(*entgql.Cursor[string]), fc.Args["last"].(*int)) + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *groupby.Connection) graphql.Marshaler { + return ec.marshalNSubcontrolGroupByConnection2ᚖgithubᚗcomᚋtheopenlaneᚋgqlgenᚑpluginsᚋgroupbyᚐConnection(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_Query_subcontrolsGroupBy(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_SubcontrolGroupByConnection(ctx, field) + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_Query_subcontrolsGroupBy_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query_vulnerabilitiesGroupBy(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_Query_vulnerabilitiesGroupBy(ctx, field) + }, + func(ctx context.Context) (any, error) { + fc := graphql.GetFieldContext(ctx) + return ec.Resolvers.Query().VulnerabilitiesGroupBy(ctx, fc.Args["field"].(model.VulnerabilityGroupByField), fc.Args["where"].(*generated.VulnerabilityWhereInput), fc.Args["orderBy"].(*groupby.Order), fc.Args["after"].(*entgql.Cursor[string]), fc.Args["first"].(*int), fc.Args["before"].(*entgql.Cursor[string]), fc.Args["last"].(*int)) + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *groupby.Connection) graphql.Marshaler { + return ec.marshalNVulnerabilityGroupByConnection2ᚖgithubᚗcomᚋtheopenlaneᚋgqlgenᚑpluginsᚋgroupbyᚐConnection(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_Query_vulnerabilitiesGroupBy(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_VulnerabilityGroupByConnection(ctx, field) + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_Query_vulnerabilitiesGroupBy_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + func (ec *executionContext) _Query_groupMembership(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -433966,6 +434288,24 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr func(ctx context.Context) graphql.Marshaler { return ec._Query_group(ctx, field) }) + case "controlsGroupBy": + out.ResolveRootConcurrently(innerCtx, ec.OperationContext, i, + true, true, + func(ctx context.Context) graphql.Marshaler { + return ec._Query_controlsGroupBy(ctx, field) + }) + case "subcontrolsGroupBy": + out.ResolveRootConcurrently(innerCtx, ec.OperationContext, i, + true, true, + func(ctx context.Context) graphql.Marshaler { + return ec._Query_subcontrolsGroupBy(ctx, field) + }) + case "vulnerabilitiesGroupBy": + out.ResolveRootConcurrently(innerCtx, ec.OperationContext, i, + true, true, + func(ctx context.Context) graphql.Marshaler { + return ec._Query_vulnerabilitiesGroupBy(ctx, field) + }) case "groupMembership": out.ResolveRootConcurrently(innerCtx, ec.OperationContext, i, true, true, diff --git a/internal/graphapi/generated/groupby.generated.go b/internal/graphapi/generated/groupby.generated.go new file mode 100644 index 0000000000..76ece30308 --- /dev/null +++ b/internal/graphapi/generated/groupby.generated.go @@ -0,0 +1,1504 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package gqlgenerated + +import ( + "context" + "math" + "strconv" + "sync/atomic" + + "entgo.io/contrib/entgql" + "github.com/99designs/gqlgen/graphql" + "github.com/theopenlane/core/v2/internal/ent/generated" + "github.com/theopenlane/core/v2/internal/graphapi/model" + "github.com/theopenlane/gqlgen-plugins/groupby" + "github.com/vektah/gqlparser/v2/ast" +) + +// region ************************** generated!.gotpl ************************** + +type ControlGroupByBucketResolver interface { + Controls(ctx context.Context, obj *groupby.Bucket, after *entgql.Cursor[string], first *int, before *entgql.Cursor[string], last *int, orderBy []*generated.ControlOrder) (*generated.ControlConnection, error) +} +type SubcontrolGroupByBucketResolver interface { + Subcontrols(ctx context.Context, obj *groupby.Bucket, after *entgql.Cursor[string], first *int, before *entgql.Cursor[string], last *int, orderBy []*generated.SubcontrolOrder) (*generated.SubcontrolConnection, error) +} +type VulnerabilityGroupByBucketResolver interface { + Vulnerabilities(ctx context.Context, obj *groupby.Bucket, after *entgql.Cursor[string], first *int, before *entgql.Cursor[string], last *int, orderBy []*generated.VulnerabilityOrder) (*generated.VulnerabilityConnection, error) +} + +// endregion ************************** generated!.gotpl ************************** + +// region ***************************** args.gotpl ***************************** + +func (ec *executionContext) field_ControlGroupByBucket_controls_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := graphql.ProcessArgField(ctx, rawArgs, "after", + func(ctx context.Context, v any) (*entgql.Cursor[string], error) { + return ec.unmarshalOCursor2ᚖentgoᚗioᚋcontribᚋentgqlᚐCursor(ctx, v) + }) + if err != nil { + return nil, err + } + args["after"] = arg0 + arg1, err := graphql.ProcessArgField(ctx, rawArgs, "first", + func(ctx context.Context, v any) (*int, error) { + return ec.unmarshalOInt2ᚖint(ctx, v) + }) + if err != nil { + return nil, err + } + args["first"] = arg1 + arg2, err := graphql.ProcessArgField(ctx, rawArgs, "before", + func(ctx context.Context, v any) (*entgql.Cursor[string], error) { + return ec.unmarshalOCursor2ᚖentgoᚗioᚋcontribᚋentgqlᚐCursor(ctx, v) + }) + if err != nil { + return nil, err + } + args["before"] = arg2 + arg3, err := graphql.ProcessArgField(ctx, rawArgs, "last", + func(ctx context.Context, v any) (*int, error) { + return ec.unmarshalOInt2ᚖint(ctx, v) + }) + if err != nil { + return nil, err + } + args["last"] = arg3 + arg4, err := graphql.ProcessArgField(ctx, rawArgs, "orderBy", + func(ctx context.Context, v any) ([]*generated.ControlOrder, error) { + return ec.unmarshalOControlOrder2ᚕᚖgithubᚗcomᚋtheopenlaneᚋcoreᚋv2ᚋinternalᚋentᚋgeneratedᚐControlOrderᚄ(ctx, v) + }) + if err != nil { + return nil, err + } + args["orderBy"] = arg4 + return args, nil +} + +func (ec *executionContext) field_SubcontrolGroupByBucket_subcontrols_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := graphql.ProcessArgField(ctx, rawArgs, "after", + func(ctx context.Context, v any) (*entgql.Cursor[string], error) { + return ec.unmarshalOCursor2ᚖentgoᚗioᚋcontribᚋentgqlᚐCursor(ctx, v) + }) + if err != nil { + return nil, err + } + args["after"] = arg0 + arg1, err := graphql.ProcessArgField(ctx, rawArgs, "first", + func(ctx context.Context, v any) (*int, error) { + return ec.unmarshalOInt2ᚖint(ctx, v) + }) + if err != nil { + return nil, err + } + args["first"] = arg1 + arg2, err := graphql.ProcessArgField(ctx, rawArgs, "before", + func(ctx context.Context, v any) (*entgql.Cursor[string], error) { + return ec.unmarshalOCursor2ᚖentgoᚗioᚋcontribᚋentgqlᚐCursor(ctx, v) + }) + if err != nil { + return nil, err + } + args["before"] = arg2 + arg3, err := graphql.ProcessArgField(ctx, rawArgs, "last", + func(ctx context.Context, v any) (*int, error) { + return ec.unmarshalOInt2ᚖint(ctx, v) + }) + if err != nil { + return nil, err + } + args["last"] = arg3 + arg4, err := graphql.ProcessArgField(ctx, rawArgs, "orderBy", + func(ctx context.Context, v any) ([]*generated.SubcontrolOrder, error) { + return ec.unmarshalOSubcontrolOrder2ᚕᚖgithubᚗcomᚋtheopenlaneᚋcoreᚋv2ᚋinternalᚋentᚋgeneratedᚐSubcontrolOrderᚄ(ctx, v) + }) + if err != nil { + return nil, err + } + args["orderBy"] = arg4 + return args, nil +} + +func (ec *executionContext) field_VulnerabilityGroupByBucket_vulnerabilities_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := graphql.ProcessArgField(ctx, rawArgs, "after", + func(ctx context.Context, v any) (*entgql.Cursor[string], error) { + return ec.unmarshalOCursor2ᚖentgoᚗioᚋcontribᚋentgqlᚐCursor(ctx, v) + }) + if err != nil { + return nil, err + } + args["after"] = arg0 + arg1, err := graphql.ProcessArgField(ctx, rawArgs, "first", + func(ctx context.Context, v any) (*int, error) { + return ec.unmarshalOInt2ᚖint(ctx, v) + }) + if err != nil { + return nil, err + } + args["first"] = arg1 + arg2, err := graphql.ProcessArgField(ctx, rawArgs, "before", + func(ctx context.Context, v any) (*entgql.Cursor[string], error) { + return ec.unmarshalOCursor2ᚖentgoᚗioᚋcontribᚋentgqlᚐCursor(ctx, v) + }) + if err != nil { + return nil, err + } + args["before"] = arg2 + arg3, err := graphql.ProcessArgField(ctx, rawArgs, "last", + func(ctx context.Context, v any) (*int, error) { + return ec.unmarshalOInt2ᚖint(ctx, v) + }) + if err != nil { + return nil, err + } + args["last"] = arg3 + arg4, err := graphql.ProcessArgField(ctx, rawArgs, "orderBy", + func(ctx context.Context, v any) ([]*generated.VulnerabilityOrder, error) { + return ec.unmarshalOVulnerabilityOrder2ᚕᚖgithubᚗcomᚋtheopenlaneᚋcoreᚋv2ᚋinternalᚋentᚋgeneratedᚐVulnerabilityOrderᚄ(ctx, v) + }) + if err != nil { + return nil, err + } + args["orderBy"] = arg4 + return args, nil +} + +// endregion ***************************** args.gotpl ***************************** + +// region **************************** field.gotpl ***************************** + +func (ec *executionContext) _ControlGroupByBucket_key(ctx context.Context, field graphql.CollectedField, obj *groupby.Bucket) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_ControlGroupByBucket_key(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.Key, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *string) graphql.Marshaler { + return ec.marshalOString2ᚖstring(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_ControlGroupByBucket_key(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("ControlGroupByBucket", field, false, false, "String") +} + +func (ec *executionContext) _ControlGroupByBucket_count(ctx context.Context, field graphql.CollectedField, obj *groupby.Bucket) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_ControlGroupByBucket_count(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.Count, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v int) graphql.Marshaler { + return ec.marshalNInt2int(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_ControlGroupByBucket_count(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("ControlGroupByBucket", field, false, false, "Int") +} + +func (ec *executionContext) _ControlGroupByBucket_controls(ctx context.Context, field graphql.CollectedField, obj *groupby.Bucket) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_ControlGroupByBucket_controls(ctx, field) + }, + func(ctx context.Context) (any, error) { + fc := graphql.GetFieldContext(ctx) + return ec.Resolvers.ControlGroupByBucket().Controls(ctx, obj, fc.Args["after"].(*entgql.Cursor[string]), fc.Args["first"].(*int), fc.Args["before"].(*entgql.Cursor[string]), fc.Args["last"].(*int), fc.Args["orderBy"].([]*generated.ControlOrder)) + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *generated.ControlConnection) graphql.Marshaler { + return ec.marshalNControlConnection2ᚖgithubᚗcomᚋtheopenlaneᚋcoreᚋv2ᚋinternalᚋentᚋgeneratedᚐControlConnection(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_ControlGroupByBucket_controls(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ControlGroupByBucket", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_ControlConnection(ctx, field) + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_ControlGroupByBucket_controls_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _ControlGroupByConnection_edges(ctx context.Context, field graphql.CollectedField, obj *groupby.Connection) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_ControlGroupByConnection_edges(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.Edges, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v []*groupby.Edge) graphql.Marshaler { + return ec.marshalNControlGroupByEdge2ᚕᚖgithubᚗcomᚋtheopenlaneᚋgqlgenᚑpluginsᚋgroupbyᚐEdgeᚄ(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_ControlGroupByConnection_edges(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ControlGroupByConnection", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_ControlGroupByEdge(ctx, field) + }, + } + return fc, nil +} + +func (ec *executionContext) _ControlGroupByConnection_pageInfo(ctx context.Context, field graphql.CollectedField, obj *groupby.Connection) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_ControlGroupByConnection_pageInfo(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.PageInfo, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v entgql.PageInfo[string]) graphql.Marshaler { + return ec.marshalNPageInfo2entgoᚗioᚋcontribᚋentgqlᚐPageInfo(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_ControlGroupByConnection_pageInfo(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ControlGroupByConnection", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_PageInfo(ctx, field) + }, + } + return fc, nil +} + +func (ec *executionContext) _ControlGroupByConnection_totalCount(ctx context.Context, field graphql.CollectedField, obj *groupby.Connection) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_ControlGroupByConnection_totalCount(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.TotalCount, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v int) graphql.Marshaler { + return ec.marshalNInt2int(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_ControlGroupByConnection_totalCount(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("ControlGroupByConnection", field, false, false, "Int") +} + +func (ec *executionContext) _ControlGroupByEdge_node(ctx context.Context, field graphql.CollectedField, obj *groupby.Edge) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_ControlGroupByEdge_node(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.Node, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *groupby.Bucket) graphql.Marshaler { + return ec.marshalNControlGroupByBucket2ᚖgithubᚗcomᚋtheopenlaneᚋgqlgenᚑpluginsᚋgroupbyᚐBucket(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_ControlGroupByEdge_node(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ControlGroupByEdge", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_ControlGroupByBucket(ctx, field) + }, + } + return fc, nil +} + +func (ec *executionContext) _ControlGroupByEdge_cursor(ctx context.Context, field graphql.CollectedField, obj *groupby.Edge) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_ControlGroupByEdge_cursor(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.Cursor, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v entgql.Cursor[string]) graphql.Marshaler { + return ec.marshalNCursor2entgoᚗioᚋcontribᚋentgqlᚐCursor(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_ControlGroupByEdge_cursor(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("ControlGroupByEdge", field, false, false, "Cursor") +} + +func (ec *executionContext) _SubcontrolGroupByBucket_key(ctx context.Context, field graphql.CollectedField, obj *groupby.Bucket) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_SubcontrolGroupByBucket_key(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.Key, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *string) graphql.Marshaler { + return ec.marshalOString2ᚖstring(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_SubcontrolGroupByBucket_key(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("SubcontrolGroupByBucket", field, false, false, "String") +} + +func (ec *executionContext) _SubcontrolGroupByBucket_count(ctx context.Context, field graphql.CollectedField, obj *groupby.Bucket) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_SubcontrolGroupByBucket_count(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.Count, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v int) graphql.Marshaler { + return ec.marshalNInt2int(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_SubcontrolGroupByBucket_count(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("SubcontrolGroupByBucket", field, false, false, "Int") +} + +func (ec *executionContext) _SubcontrolGroupByBucket_subcontrols(ctx context.Context, field graphql.CollectedField, obj *groupby.Bucket) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_SubcontrolGroupByBucket_subcontrols(ctx, field) + }, + func(ctx context.Context) (any, error) { + fc := graphql.GetFieldContext(ctx) + return ec.Resolvers.SubcontrolGroupByBucket().Subcontrols(ctx, obj, fc.Args["after"].(*entgql.Cursor[string]), fc.Args["first"].(*int), fc.Args["before"].(*entgql.Cursor[string]), fc.Args["last"].(*int), fc.Args["orderBy"].([]*generated.SubcontrolOrder)) + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *generated.SubcontrolConnection) graphql.Marshaler { + return ec.marshalNSubcontrolConnection2ᚖgithubᚗcomᚋtheopenlaneᚋcoreᚋv2ᚋinternalᚋentᚋgeneratedᚐSubcontrolConnection(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_SubcontrolGroupByBucket_subcontrols(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "SubcontrolGroupByBucket", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_SubcontrolConnection(ctx, field) + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_SubcontrolGroupByBucket_subcontrols_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _SubcontrolGroupByConnection_edges(ctx context.Context, field graphql.CollectedField, obj *groupby.Connection) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_SubcontrolGroupByConnection_edges(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.Edges, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v []*groupby.Edge) graphql.Marshaler { + return ec.marshalNSubcontrolGroupByEdge2ᚕᚖgithubᚗcomᚋtheopenlaneᚋgqlgenᚑpluginsᚋgroupbyᚐEdgeᚄ(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_SubcontrolGroupByConnection_edges(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "SubcontrolGroupByConnection", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_SubcontrolGroupByEdge(ctx, field) + }, + } + return fc, nil +} + +func (ec *executionContext) _SubcontrolGroupByConnection_pageInfo(ctx context.Context, field graphql.CollectedField, obj *groupby.Connection) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_SubcontrolGroupByConnection_pageInfo(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.PageInfo, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v entgql.PageInfo[string]) graphql.Marshaler { + return ec.marshalNPageInfo2entgoᚗioᚋcontribᚋentgqlᚐPageInfo(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_SubcontrolGroupByConnection_pageInfo(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "SubcontrolGroupByConnection", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_PageInfo(ctx, field) + }, + } + return fc, nil +} + +func (ec *executionContext) _SubcontrolGroupByConnection_totalCount(ctx context.Context, field graphql.CollectedField, obj *groupby.Connection) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_SubcontrolGroupByConnection_totalCount(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.TotalCount, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v int) graphql.Marshaler { + return ec.marshalNInt2int(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_SubcontrolGroupByConnection_totalCount(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("SubcontrolGroupByConnection", field, false, false, "Int") +} + +func (ec *executionContext) _SubcontrolGroupByEdge_node(ctx context.Context, field graphql.CollectedField, obj *groupby.Edge) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_SubcontrolGroupByEdge_node(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.Node, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *groupby.Bucket) graphql.Marshaler { + return ec.marshalNSubcontrolGroupByBucket2ᚖgithubᚗcomᚋtheopenlaneᚋgqlgenᚑpluginsᚋgroupbyᚐBucket(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_SubcontrolGroupByEdge_node(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "SubcontrolGroupByEdge", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_SubcontrolGroupByBucket(ctx, field) + }, + } + return fc, nil +} + +func (ec *executionContext) _SubcontrolGroupByEdge_cursor(ctx context.Context, field graphql.CollectedField, obj *groupby.Edge) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_SubcontrolGroupByEdge_cursor(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.Cursor, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v entgql.Cursor[string]) graphql.Marshaler { + return ec.marshalNCursor2entgoᚗioᚋcontribᚋentgqlᚐCursor(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_SubcontrolGroupByEdge_cursor(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("SubcontrolGroupByEdge", field, false, false, "Cursor") +} + +func (ec *executionContext) _VulnerabilityGroupByBucket_key(ctx context.Context, field graphql.CollectedField, obj *groupby.Bucket) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_VulnerabilityGroupByBucket_key(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.Key, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *string) graphql.Marshaler { + return ec.marshalOString2ᚖstring(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_VulnerabilityGroupByBucket_key(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("VulnerabilityGroupByBucket", field, false, false, "String") +} + +func (ec *executionContext) _VulnerabilityGroupByBucket_count(ctx context.Context, field graphql.CollectedField, obj *groupby.Bucket) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_VulnerabilityGroupByBucket_count(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.Count, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v int) graphql.Marshaler { + return ec.marshalNInt2int(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_VulnerabilityGroupByBucket_count(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("VulnerabilityGroupByBucket", field, false, false, "Int") +} + +func (ec *executionContext) _VulnerabilityGroupByBucket_vulnerabilities(ctx context.Context, field graphql.CollectedField, obj *groupby.Bucket) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_VulnerabilityGroupByBucket_vulnerabilities(ctx, field) + }, + func(ctx context.Context) (any, error) { + fc := graphql.GetFieldContext(ctx) + return ec.Resolvers.VulnerabilityGroupByBucket().Vulnerabilities(ctx, obj, fc.Args["after"].(*entgql.Cursor[string]), fc.Args["first"].(*int), fc.Args["before"].(*entgql.Cursor[string]), fc.Args["last"].(*int), fc.Args["orderBy"].([]*generated.VulnerabilityOrder)) + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *generated.VulnerabilityConnection) graphql.Marshaler { + return ec.marshalNVulnerabilityConnection2ᚖgithubᚗcomᚋtheopenlaneᚋcoreᚋv2ᚋinternalᚋentᚋgeneratedᚐVulnerabilityConnection(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_VulnerabilityGroupByBucket_vulnerabilities(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "VulnerabilityGroupByBucket", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_VulnerabilityConnection(ctx, field) + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_VulnerabilityGroupByBucket_vulnerabilities_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _VulnerabilityGroupByConnection_edges(ctx context.Context, field graphql.CollectedField, obj *groupby.Connection) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_VulnerabilityGroupByConnection_edges(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.Edges, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v []*groupby.Edge) graphql.Marshaler { + return ec.marshalNVulnerabilityGroupByEdge2ᚕᚖgithubᚗcomᚋtheopenlaneᚋgqlgenᚑpluginsᚋgroupbyᚐEdgeᚄ(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_VulnerabilityGroupByConnection_edges(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "VulnerabilityGroupByConnection", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_VulnerabilityGroupByEdge(ctx, field) + }, + } + return fc, nil +} + +func (ec *executionContext) _VulnerabilityGroupByConnection_pageInfo(ctx context.Context, field graphql.CollectedField, obj *groupby.Connection) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_VulnerabilityGroupByConnection_pageInfo(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.PageInfo, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v entgql.PageInfo[string]) graphql.Marshaler { + return ec.marshalNPageInfo2entgoᚗioᚋcontribᚋentgqlᚐPageInfo(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_VulnerabilityGroupByConnection_pageInfo(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "VulnerabilityGroupByConnection", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_PageInfo(ctx, field) + }, + } + return fc, nil +} + +func (ec *executionContext) _VulnerabilityGroupByConnection_totalCount(ctx context.Context, field graphql.CollectedField, obj *groupby.Connection) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_VulnerabilityGroupByConnection_totalCount(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.TotalCount, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v int) graphql.Marshaler { + return ec.marshalNInt2int(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_VulnerabilityGroupByConnection_totalCount(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("VulnerabilityGroupByConnection", field, false, false, "Int") +} + +func (ec *executionContext) _VulnerabilityGroupByEdge_node(ctx context.Context, field graphql.CollectedField, obj *groupby.Edge) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_VulnerabilityGroupByEdge_node(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.Node, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *groupby.Bucket) graphql.Marshaler { + return ec.marshalNVulnerabilityGroupByBucket2ᚖgithubᚗcomᚋtheopenlaneᚋgqlgenᚑpluginsᚋgroupbyᚐBucket(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_VulnerabilityGroupByEdge_node(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "VulnerabilityGroupByEdge", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_VulnerabilityGroupByBucket(ctx, field) + }, + } + return fc, nil +} + +func (ec *executionContext) _VulnerabilityGroupByEdge_cursor(ctx context.Context, field graphql.CollectedField, obj *groupby.Edge) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_VulnerabilityGroupByEdge_cursor(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.Cursor, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v entgql.Cursor[string]) graphql.Marshaler { + return ec.marshalNCursor2entgoᚗioᚋcontribᚋentgqlᚐCursor(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_VulnerabilityGroupByEdge_cursor(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("VulnerabilityGroupByEdge", field, false, false, "Cursor") +} + +// endregion **************************** field.gotpl ***************************** + +// region **************************** input.gotpl ***************************** + +func (ec *executionContext) unmarshalInputGroupByOrder(ctx context.Context, obj any) (groupby.Order, error) { + var it groupby.Order + if obj == nil { + return it, nil + } + + asMap := map[string]any{} + for k, v := range obj.(map[string]any) { + asMap[k] = v + } + + if _, present := asMap["direction"]; !present { + asMap["direction"] = "DESC" + } + if _, present := asMap["field"]; !present { + asMap["field"] = "COUNT" + } + + fieldsInOrder := [...]string{"direction", "field"} + for _, k := range fieldsInOrder { + v, ok := asMap[k] + if !ok { + continue + } + switch k { + case "direction": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("direction")) + data, err := ec.unmarshalNOrderDirection2entgoᚗioᚋcontribᚋentgqlᚐOrderDirection(ctx, v) + if err != nil { + return it, err + } + it.Direction = data + case "field": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("field")) + data, err := ec.unmarshalNGroupByOrderField2githubᚗcomᚋtheopenlaneᚋgqlgenᚑpluginsᚋgroupbyᚐOrderField(ctx, v) + if err != nil { + return it, err + } + it.Field = data + } + } + return it, nil +} + +// UnmarshalGroupByOrder unmarshals raw into the GroupByOrder input type, using the +// unmarshaler bound to ctx's request. Call it from a resolver to decode an input +// object that was not passed as a field argument. +// +// ctx must come from a gqlgen request; outside one there is no unmarshaler to use +// and the returned error says so. +func UnmarshalGroupByOrder(ctx context.Context, raw any) (groupby.Order, error) { + var out groupby.Order + err := graphql.UnmarshalNamedInputFromContext(ctx, "GroupByOrder", raw, &out) + return out, err +} + +// endregion **************************** input.gotpl ***************************** + +// region ************************** interface.gotpl *************************** + +// endregion ************************** interface.gotpl *************************** + +// region **************************** object.gotpl **************************** + +var controlGroupByBucketImplementors = []string{"ControlGroupByBucket"} + +func (ec *executionContext) _ControlGroupByBucket(ctx context.Context, sel ast.SelectionSet, obj *groupby.Bucket) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, controlGroupByBucketImplementors) + + out := graphql.NewFieldSet(fields) + deferred := graphql.NewDeferredGroup(ctx) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("ControlGroupByBucket") + case "key": + out.Values[i] = ec._ControlGroupByBucket_key(ctx, field, obj) + if out.Values[i] == graphql.RequiredNull { + atomic.AddUint32(&out.Invalids, 1) + } + case "count": + out.Values[i] = ec._ControlGroupByBucket_count(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "controls": + out.ResolveConcurrently(ec.OperationContext, &deferred, i, + true, true, + func(ctx context.Context) graphql.Marshaler { + return ec._ControlGroupByBucket_controls(ctx, field, obj) + }) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + if n := len(deferred.Defers); n > 0 { + atomic.AddInt32(&ec.Deferred, int32(min(n, math.MaxInt32))) + ec.ProcessDeferredGroup(deferred) + } + + return out +} + +var controlGroupByConnectionImplementors = []string{"ControlGroupByConnection"} + +func (ec *executionContext) _ControlGroupByConnection(ctx context.Context, sel ast.SelectionSet, obj *groupby.Connection) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, controlGroupByConnectionImplementors) + + out := graphql.NewFieldSet(fields) + deferred := graphql.NewDeferredGroup(ctx) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("ControlGroupByConnection") + case "edges": + out.Values[i] = ec._ControlGroupByConnection_edges(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "pageInfo": + out.Values[i] = ec._ControlGroupByConnection_pageInfo(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "totalCount": + out.Values[i] = ec._ControlGroupByConnection_totalCount(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + if n := len(deferred.Defers); n > 0 { + atomic.AddInt32(&ec.Deferred, int32(min(n, math.MaxInt32))) + ec.ProcessDeferredGroup(deferred) + } + + return out +} + +var controlGroupByEdgeImplementors = []string{"ControlGroupByEdge"} + +func (ec *executionContext) _ControlGroupByEdge(ctx context.Context, sel ast.SelectionSet, obj *groupby.Edge) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, controlGroupByEdgeImplementors) + + out := graphql.NewFieldSet(fields) + deferred := graphql.NewDeferredGroup(ctx) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("ControlGroupByEdge") + case "node": + out.Values[i] = ec._ControlGroupByEdge_node(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "cursor": + out.Values[i] = ec._ControlGroupByEdge_cursor(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + if n := len(deferred.Defers); n > 0 { + atomic.AddInt32(&ec.Deferred, int32(min(n, math.MaxInt32))) + ec.ProcessDeferredGroup(deferred) + } + + return out +} + +var subcontrolGroupByBucketImplementors = []string{"SubcontrolGroupByBucket"} + +func (ec *executionContext) _SubcontrolGroupByBucket(ctx context.Context, sel ast.SelectionSet, obj *groupby.Bucket) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, subcontrolGroupByBucketImplementors) + + out := graphql.NewFieldSet(fields) + deferred := graphql.NewDeferredGroup(ctx) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("SubcontrolGroupByBucket") + case "key": + out.Values[i] = ec._SubcontrolGroupByBucket_key(ctx, field, obj) + if out.Values[i] == graphql.RequiredNull { + atomic.AddUint32(&out.Invalids, 1) + } + case "count": + out.Values[i] = ec._SubcontrolGroupByBucket_count(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "subcontrols": + out.ResolveConcurrently(ec.OperationContext, &deferred, i, + true, true, + func(ctx context.Context) graphql.Marshaler { + return ec._SubcontrolGroupByBucket_subcontrols(ctx, field, obj) + }) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + if n := len(deferred.Defers); n > 0 { + atomic.AddInt32(&ec.Deferred, int32(min(n, math.MaxInt32))) + ec.ProcessDeferredGroup(deferred) + } + + return out +} + +var subcontrolGroupByConnectionImplementors = []string{"SubcontrolGroupByConnection"} + +func (ec *executionContext) _SubcontrolGroupByConnection(ctx context.Context, sel ast.SelectionSet, obj *groupby.Connection) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, subcontrolGroupByConnectionImplementors) + + out := graphql.NewFieldSet(fields) + deferred := graphql.NewDeferredGroup(ctx) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("SubcontrolGroupByConnection") + case "edges": + out.Values[i] = ec._SubcontrolGroupByConnection_edges(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "pageInfo": + out.Values[i] = ec._SubcontrolGroupByConnection_pageInfo(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "totalCount": + out.Values[i] = ec._SubcontrolGroupByConnection_totalCount(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + if n := len(deferred.Defers); n > 0 { + atomic.AddInt32(&ec.Deferred, int32(min(n, math.MaxInt32))) + ec.ProcessDeferredGroup(deferred) + } + + return out +} + +var subcontrolGroupByEdgeImplementors = []string{"SubcontrolGroupByEdge"} + +func (ec *executionContext) _SubcontrolGroupByEdge(ctx context.Context, sel ast.SelectionSet, obj *groupby.Edge) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, subcontrolGroupByEdgeImplementors) + + out := graphql.NewFieldSet(fields) + deferred := graphql.NewDeferredGroup(ctx) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("SubcontrolGroupByEdge") + case "node": + out.Values[i] = ec._SubcontrolGroupByEdge_node(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "cursor": + out.Values[i] = ec._SubcontrolGroupByEdge_cursor(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + if n := len(deferred.Defers); n > 0 { + atomic.AddInt32(&ec.Deferred, int32(min(n, math.MaxInt32))) + ec.ProcessDeferredGroup(deferred) + } + + return out +} + +var vulnerabilityGroupByBucketImplementors = []string{"VulnerabilityGroupByBucket"} + +func (ec *executionContext) _VulnerabilityGroupByBucket(ctx context.Context, sel ast.SelectionSet, obj *groupby.Bucket) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, vulnerabilityGroupByBucketImplementors) + + out := graphql.NewFieldSet(fields) + deferred := graphql.NewDeferredGroup(ctx) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("VulnerabilityGroupByBucket") + case "key": + out.Values[i] = ec._VulnerabilityGroupByBucket_key(ctx, field, obj) + if out.Values[i] == graphql.RequiredNull { + atomic.AddUint32(&out.Invalids, 1) + } + case "count": + out.Values[i] = ec._VulnerabilityGroupByBucket_count(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "vulnerabilities": + out.ResolveConcurrently(ec.OperationContext, &deferred, i, + true, true, + func(ctx context.Context) graphql.Marshaler { + return ec._VulnerabilityGroupByBucket_vulnerabilities(ctx, field, obj) + }) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + if n := len(deferred.Defers); n > 0 { + atomic.AddInt32(&ec.Deferred, int32(min(n, math.MaxInt32))) + ec.ProcessDeferredGroup(deferred) + } + + return out +} + +var vulnerabilityGroupByConnectionImplementors = []string{"VulnerabilityGroupByConnection"} + +func (ec *executionContext) _VulnerabilityGroupByConnection(ctx context.Context, sel ast.SelectionSet, obj *groupby.Connection) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, vulnerabilityGroupByConnectionImplementors) + + out := graphql.NewFieldSet(fields) + deferred := graphql.NewDeferredGroup(ctx) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("VulnerabilityGroupByConnection") + case "edges": + out.Values[i] = ec._VulnerabilityGroupByConnection_edges(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "pageInfo": + out.Values[i] = ec._VulnerabilityGroupByConnection_pageInfo(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "totalCount": + out.Values[i] = ec._VulnerabilityGroupByConnection_totalCount(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + if n := len(deferred.Defers); n > 0 { + atomic.AddInt32(&ec.Deferred, int32(min(n, math.MaxInt32))) + ec.ProcessDeferredGroup(deferred) + } + + return out +} + +var vulnerabilityGroupByEdgeImplementors = []string{"VulnerabilityGroupByEdge"} + +func (ec *executionContext) _VulnerabilityGroupByEdge(ctx context.Context, sel ast.SelectionSet, obj *groupby.Edge) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, vulnerabilityGroupByEdgeImplementors) + + out := graphql.NewFieldSet(fields) + deferred := graphql.NewDeferredGroup(ctx) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("VulnerabilityGroupByEdge") + case "node": + out.Values[i] = ec._VulnerabilityGroupByEdge_node(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "cursor": + out.Values[i] = ec._VulnerabilityGroupByEdge_cursor(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + if n := len(deferred.Defers); n > 0 { + atomic.AddInt32(&ec.Deferred, int32(min(n, math.MaxInt32))) + ec.ProcessDeferredGroup(deferred) + } + + return out +} + +// endregion **************************** object.gotpl **************************** + +// region ***************************** type.gotpl ***************************** + +func (ec *executionContext) marshalNControlGroupByBucket2ᚖgithubᚗcomᚋtheopenlaneᚋgqlgenᚑpluginsᚋgroupbyᚐBucket(ctx context.Context, sel ast.SelectionSet, v *groupby.Bucket) graphql.Marshaler { + if v == nil { + graphql.AddInvalidNullError(ctx, "ControlGroupByBucket!") + return graphql.Null + } + return ec._ControlGroupByBucket(ctx, sel, v) +} + +func (ec *executionContext) marshalNControlGroupByConnection2ᚖgithubᚗcomᚋtheopenlaneᚋgqlgenᚑpluginsᚋgroupbyᚐConnection(ctx context.Context, sel ast.SelectionSet, v *groupby.Connection) graphql.Marshaler { + if v == nil { + graphql.AddInvalidNullError(ctx, "ControlGroupByConnection!") + return graphql.Null + } + return ec._ControlGroupByConnection(ctx, sel, v) +} + +func (ec *executionContext) marshalNControlGroupByEdge2ᚕᚖgithubᚗcomᚋtheopenlaneᚋgqlgenᚑpluginsᚋgroupbyᚐEdgeᚄ(ctx context.Context, sel ast.SelectionSet, v []*groupby.Edge) graphql.Marshaler { + ret := graphql.MarshalSliceConcurrently(ctx, len(v), 0, false, func(ctx context.Context, i int) graphql.Marshaler { + fc := graphql.GetFieldContext(ctx) + fc.Result = &v[i] + return ec.marshalNControlGroupByEdge2ᚖgithubᚗcomᚋtheopenlaneᚋgqlgenᚑpluginsᚋgroupbyᚐEdge(ctx, sel, v[i]) + }) + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalNControlGroupByEdge2ᚖgithubᚗcomᚋtheopenlaneᚋgqlgenᚑpluginsᚋgroupbyᚐEdge(ctx context.Context, sel ast.SelectionSet, v *groupby.Edge) graphql.Marshaler { + if v == nil { + graphql.AddInvalidNullError(ctx, "ControlGroupByEdge!") + return graphql.Null + } + return ec._ControlGroupByEdge(ctx, sel, v) +} + +func (ec *executionContext) unmarshalNControlGroupByField2githubᚗcomᚋtheopenlaneᚋcoreᚋv2ᚋinternalᚋgraphapiᚋmodelᚐControlGroupByField(ctx context.Context, v any) (model.ControlGroupByField, error) { + var res model.ControlGroupByField + err := res.UnmarshalGQL(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNControlGroupByField2githubᚗcomᚋtheopenlaneᚋcoreᚋv2ᚋinternalᚋgraphapiᚋmodelᚐControlGroupByField(ctx context.Context, sel ast.SelectionSet, v model.ControlGroupByField) graphql.Marshaler { + return v +} + +func (ec *executionContext) unmarshalNGroupByOrderField2githubᚗcomᚋtheopenlaneᚋgqlgenᚑpluginsᚋgroupbyᚐOrderField(ctx context.Context, v any) (groupby.OrderField, error) { + tmp, err := graphql.UnmarshalString(v) + res := unmarshalNGroupByOrderField2githubᚗcomᚋtheopenlaneᚋgqlgenᚑpluginsᚋgroupbyᚐOrderField[tmp] + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNGroupByOrderField2githubᚗcomᚋtheopenlaneᚋgqlgenᚑpluginsᚋgroupbyᚐOrderField(ctx context.Context, sel ast.SelectionSet, v groupby.OrderField) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(marshalNGroupByOrderField2githubᚗcomᚋtheopenlaneᚋgqlgenᚑpluginsᚋgroupbyᚐOrderField[v]) + if res == graphql.Null { + graphql.AddInvalidNullFromMarshaler(ctx, "GroupByOrderField!") + } + return res +} + +var ( + unmarshalNGroupByOrderField2githubᚗcomᚋtheopenlaneᚋgqlgenᚑpluginsᚋgroupbyᚐOrderField = map[string]groupby.OrderField{ + "COUNT": groupby.OrderFieldCount, + "KEY": groupby.OrderFieldKey, + } + marshalNGroupByOrderField2githubᚗcomᚋtheopenlaneᚋgqlgenᚑpluginsᚋgroupbyᚐOrderField = map[groupby.OrderField]string{ + groupby.OrderFieldCount: "COUNT", + groupby.OrderFieldKey: "KEY", + } +) + +func (ec *executionContext) marshalNSubcontrolGroupByBucket2ᚖgithubᚗcomᚋtheopenlaneᚋgqlgenᚑpluginsᚋgroupbyᚐBucket(ctx context.Context, sel ast.SelectionSet, v *groupby.Bucket) graphql.Marshaler { + if v == nil { + graphql.AddInvalidNullError(ctx, "SubcontrolGroupByBucket!") + return graphql.Null + } + return ec._SubcontrolGroupByBucket(ctx, sel, v) +} + +func (ec *executionContext) marshalNSubcontrolGroupByConnection2ᚖgithubᚗcomᚋtheopenlaneᚋgqlgenᚑpluginsᚋgroupbyᚐConnection(ctx context.Context, sel ast.SelectionSet, v *groupby.Connection) graphql.Marshaler { + if v == nil { + graphql.AddInvalidNullError(ctx, "SubcontrolGroupByConnection!") + return graphql.Null + } + return ec._SubcontrolGroupByConnection(ctx, sel, v) +} + +func (ec *executionContext) marshalNSubcontrolGroupByEdge2ᚕᚖgithubᚗcomᚋtheopenlaneᚋgqlgenᚑpluginsᚋgroupbyᚐEdgeᚄ(ctx context.Context, sel ast.SelectionSet, v []*groupby.Edge) graphql.Marshaler { + ret := graphql.MarshalSliceConcurrently(ctx, len(v), 0, false, func(ctx context.Context, i int) graphql.Marshaler { + fc := graphql.GetFieldContext(ctx) + fc.Result = &v[i] + return ec.marshalNSubcontrolGroupByEdge2ᚖgithubᚗcomᚋtheopenlaneᚋgqlgenᚑpluginsᚋgroupbyᚐEdge(ctx, sel, v[i]) + }) + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalNSubcontrolGroupByEdge2ᚖgithubᚗcomᚋtheopenlaneᚋgqlgenᚑpluginsᚋgroupbyᚐEdge(ctx context.Context, sel ast.SelectionSet, v *groupby.Edge) graphql.Marshaler { + if v == nil { + graphql.AddInvalidNullError(ctx, "SubcontrolGroupByEdge!") + return graphql.Null + } + return ec._SubcontrolGroupByEdge(ctx, sel, v) +} + +func (ec *executionContext) unmarshalNSubcontrolGroupByField2githubᚗcomᚋtheopenlaneᚋcoreᚋv2ᚋinternalᚋgraphapiᚋmodelᚐSubcontrolGroupByField(ctx context.Context, v any) (model.SubcontrolGroupByField, error) { + var res model.SubcontrolGroupByField + err := res.UnmarshalGQL(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNSubcontrolGroupByField2githubᚗcomᚋtheopenlaneᚋcoreᚋv2ᚋinternalᚋgraphapiᚋmodelᚐSubcontrolGroupByField(ctx context.Context, sel ast.SelectionSet, v model.SubcontrolGroupByField) graphql.Marshaler { + return v +} + +func (ec *executionContext) marshalNVulnerabilityGroupByBucket2ᚖgithubᚗcomᚋtheopenlaneᚋgqlgenᚑpluginsᚋgroupbyᚐBucket(ctx context.Context, sel ast.SelectionSet, v *groupby.Bucket) graphql.Marshaler { + if v == nil { + graphql.AddInvalidNullError(ctx, "VulnerabilityGroupByBucket!") + return graphql.Null + } + return ec._VulnerabilityGroupByBucket(ctx, sel, v) +} + +func (ec *executionContext) marshalNVulnerabilityGroupByConnection2ᚖgithubᚗcomᚋtheopenlaneᚋgqlgenᚑpluginsᚋgroupbyᚐConnection(ctx context.Context, sel ast.SelectionSet, v *groupby.Connection) graphql.Marshaler { + if v == nil { + graphql.AddInvalidNullError(ctx, "VulnerabilityGroupByConnection!") + return graphql.Null + } + return ec._VulnerabilityGroupByConnection(ctx, sel, v) +} + +func (ec *executionContext) marshalNVulnerabilityGroupByEdge2ᚕᚖgithubᚗcomᚋtheopenlaneᚋgqlgenᚑpluginsᚋgroupbyᚐEdgeᚄ(ctx context.Context, sel ast.SelectionSet, v []*groupby.Edge) graphql.Marshaler { + ret := graphql.MarshalSliceConcurrently(ctx, len(v), 0, false, func(ctx context.Context, i int) graphql.Marshaler { + fc := graphql.GetFieldContext(ctx) + fc.Result = &v[i] + return ec.marshalNVulnerabilityGroupByEdge2ᚖgithubᚗcomᚋtheopenlaneᚋgqlgenᚑpluginsᚋgroupbyᚐEdge(ctx, sel, v[i]) + }) + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalNVulnerabilityGroupByEdge2ᚖgithubᚗcomᚋtheopenlaneᚋgqlgenᚑpluginsᚋgroupbyᚐEdge(ctx context.Context, sel ast.SelectionSet, v *groupby.Edge) graphql.Marshaler { + if v == nil { + graphql.AddInvalidNullError(ctx, "VulnerabilityGroupByEdge!") + return graphql.Null + } + return ec._VulnerabilityGroupByEdge(ctx, sel, v) +} + +func (ec *executionContext) unmarshalNVulnerabilityGroupByField2githubᚗcomᚋtheopenlaneᚋcoreᚋv2ᚋinternalᚋgraphapiᚋmodelᚐVulnerabilityGroupByField(ctx context.Context, v any) (model.VulnerabilityGroupByField, error) { + var res model.VulnerabilityGroupByField + err := res.UnmarshalGQL(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNVulnerabilityGroupByField2githubᚗcomᚋtheopenlaneᚋcoreᚋv2ᚋinternalᚋgraphapiᚋmodelᚐVulnerabilityGroupByField(ctx context.Context, sel ast.SelectionSet, v model.VulnerabilityGroupByField) graphql.Marshaler { + return v +} + +func (ec *executionContext) unmarshalOGroupByOrder2ᚖgithubᚗcomᚋtheopenlaneᚋgqlgenᚑpluginsᚋgroupbyᚐOrder(ctx context.Context, v any) (*groupby.Order, error) { + if v == nil { + return nil, nil + } + res, err := ec.unmarshalInputGroupByOrder(ctx, v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +// endregion ***************************** type.gotpl ***************************** diff --git a/internal/graphapi/generated/root_.generated.go b/internal/graphapi/generated/root_.generated.go index 6bb22ec9d7..87ff5cba0a 100644 --- a/internal/graphapi/generated/root_.generated.go +++ b/internal/graphapi/generated/root_.generated.go @@ -13,6 +13,7 @@ import ( "github.com/theopenlane/core/common/enums" "github.com/theopenlane/core/v2/internal/ent/generated" "github.com/theopenlane/core/v2/internal/graphapi/model" + "github.com/theopenlane/gqlgen-plugins/groupby" gqlparser "github.com/vektah/gqlparser/v2" "github.com/vektah/gqlparser/v2/ast" ) @@ -31,6 +32,7 @@ type ResolverRoot interface { Campaign() CampaignResolver CampaignTarget() CampaignTargetResolver Control() ControlResolver + ControlGroupByBucket() ControlGroupByBucketResolver Evidence() EvidenceResolver Finding() FindingResolver Group() GroupResolver @@ -45,10 +47,12 @@ type ResolverRoot interface { Remediation() RemediationResolver Risk() RiskResolver Subcontrol() SubcontrolResolver + SubcontrolGroupByBucket() SubcontrolGroupByBucketResolver Subscription() SubscriptionResolver Task() TaskResolver TemplateContextEntry() TemplateContextEntryResolver Vulnerability() VulnerabilityResolver + VulnerabilityGroupByBucket() VulnerabilityGroupByBucketResolver WorkflowInstance() WorkflowInstanceResolver WorkflowProposal() WorkflowProposalResolver CreateDiscussionInput() CreateDiscussionInputResolver @@ -1143,6 +1147,23 @@ type ComplexityRoot struct { Controls func(childComplexity int) int } + ControlGroupByBucket struct { + Controls func(childComplexity int, after *entgql.Cursor[string], first *int, before *entgql.Cursor[string], last *int, orderBy []*generated.ControlOrder) int + Count func(childComplexity int) int + Key func(childComplexity int) int + } + + ControlGroupByConnection struct { + Edges func(childComplexity int) int + PageInfo func(childComplexity int) int + TotalCount func(childComplexity int) int + } + + ControlGroupByEdge struct { + Cursor func(childComplexity int) int + Node func(childComplexity int) int + } + ControlGroupConnection struct { Edges func(childComplexity int) int } @@ -5471,6 +5492,7 @@ type ComplexityRoot struct { ControlSubcategories func(childComplexity int) int ControlSubcategoriesByFramework func(childComplexity int, orderBy []*model.ControlCategoryOrder, where *generated.ControlWhereInput) int Controls func(childComplexity int, after *entgql.Cursor[string], first *int, before *entgql.Cursor[string], last *int, orderBy []*generated.ControlOrder, where *generated.ControlWhereInput) int + ControlsGroupBy func(childComplexity int, field model.ControlGroupByField, where *generated.ControlWhereInput, orderBy *groupby.Order, after *entgql.Cursor[string], first *int, before *entgql.Cursor[string], last *int) int ControlsGroupByCategory func(childComplexity int, after *entgql.Cursor[string], first *int, before *entgql.Cursor[string], last *int, orderBy []*generated.ControlOrder, where *generated.ControlWhereInput, category *string) int CustomDomain func(childComplexity int, id string) int CustomDomains func(childComplexity int, after *entgql.Cursor[string], first *int, before *entgql.Cursor[string], last *int, orderBy []*generated.CustomDomainOrder, where *generated.CustomDomainWhereInput) int @@ -5604,6 +5626,7 @@ type ComplexityRoot struct { Subcontrol func(childComplexity int, id string) int SubcontrolSearch func(childComplexity int, query string, after *entgql.Cursor[string], first *int, before *entgql.Cursor[string], last *int) int Subcontrols func(childComplexity int, after *entgql.Cursor[string], first *int, before *entgql.Cursor[string], last *int, orderBy []*generated.SubcontrolOrder, where *generated.SubcontrolWhereInput) int + SubcontrolsGroupBy func(childComplexity int, field model.SubcontrolGroupByField, where *generated.SubcontrolWhereInput, orderBy *groupby.Order, after *entgql.Cursor[string], first *int, before *entgql.Cursor[string], last *int) int Subprocessor func(childComplexity int, id string) int SubprocessorSearch func(childComplexity int, query string, after *entgql.Cursor[string], first *int, before *entgql.Cursor[string], last *int) int Subprocessors func(childComplexity int, after *entgql.Cursor[string], first *int, before *entgql.Cursor[string], last *int, orderBy []*generated.SubprocessorOrder, where *generated.SubprocessorWhereInput) int @@ -5653,6 +5676,7 @@ type ComplexityRoot struct { VendorScoringConfig func(childComplexity int, id string) int VendorScoringConfigs func(childComplexity int, after *entgql.Cursor[string], first *int, before *entgql.Cursor[string], last *int, orderBy []*generated.VendorScoringConfigOrder, where *generated.VendorScoringConfigWhereInput) int Vulnerabilities func(childComplexity int, after *entgql.Cursor[string], first *int, before *entgql.Cursor[string], last *int, orderBy []*generated.VulnerabilityOrder, where *generated.VulnerabilityWhereInput) int + VulnerabilitiesGroupBy func(childComplexity int, field model.VulnerabilityGroupByField, where *generated.VulnerabilityWhereInput, orderBy *groupby.Order, after *entgql.Cursor[string], first *int, before *entgql.Cursor[string], last *int) int Vulnerability func(childComplexity int, id string) int VulnerabilitySearch func(childComplexity int, query string, after *entgql.Cursor[string], first *int, before *entgql.Cursor[string], last *int) int VulnerabilitySummary func(childComplexity int, where *generated.VulnerabilityWhereInput) int @@ -6564,6 +6588,23 @@ type ComplexityRoot struct { Node func(childComplexity int) int } + SubcontrolGroupByBucket struct { + Count func(childComplexity int) int + Key func(childComplexity int) int + Subcontrols func(childComplexity int, after *entgql.Cursor[string], first *int, before *entgql.Cursor[string], last *int, orderBy []*generated.SubcontrolOrder) int + } + + SubcontrolGroupByConnection struct { + Edges func(childComplexity int) int + PageInfo func(childComplexity int) int + TotalCount func(childComplexity int) int + } + + SubcontrolGroupByEdge struct { + Cursor func(childComplexity int) int + Node func(childComplexity int) int + } + SubcontrolUpdatePayload struct { Subcontrol func(childComplexity int) int } @@ -8037,6 +8078,23 @@ type ComplexityRoot struct { Node func(childComplexity int) int } + VulnerabilityGroupByBucket struct { + Count func(childComplexity int) int + Key func(childComplexity int) int + Vulnerabilities func(childComplexity int, after *entgql.Cursor[string], first *int, before *entgql.Cursor[string], last *int, orderBy []*generated.VulnerabilityOrder) int + } + + VulnerabilityGroupByConnection struct { + Edges func(childComplexity int) int + PageInfo func(childComplexity int) int + TotalCount func(childComplexity int) int + } + + VulnerabilityGroupByEdge struct { + Cursor func(childComplexity int) int + Node func(childComplexity int) int + } + VulnerabilityResolvePayload struct { Review func(childComplexity int) int Vulnerability func(childComplexity int) int @@ -13607,6 +13665,62 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.ControlGroup.Controls(childComplexity), true + case "ControlGroupByBucket.controls": + if e.ComplexityRoot.ControlGroupByBucket.Controls == nil { + break + } + + args, err := ec.field_ControlGroupByBucket_controls_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.ComplexityRoot.ControlGroupByBucket.Controls(childComplexity, args["after"].(*entgql.Cursor[string]), args["first"].(*int), args["before"].(*entgql.Cursor[string]), args["last"].(*int), args["orderBy"].([]*generated.ControlOrder)), true + case "ControlGroupByBucket.count": + if e.ComplexityRoot.ControlGroupByBucket.Count == nil { + break + } + + return e.ComplexityRoot.ControlGroupByBucket.Count(childComplexity), true + case "ControlGroupByBucket.key": + if e.ComplexityRoot.ControlGroupByBucket.Key == nil { + break + } + + return e.ComplexityRoot.ControlGroupByBucket.Key(childComplexity), true + + case "ControlGroupByConnection.edges": + if e.ComplexityRoot.ControlGroupByConnection.Edges == nil { + break + } + + return e.ComplexityRoot.ControlGroupByConnection.Edges(childComplexity), true + case "ControlGroupByConnection.pageInfo": + if e.ComplexityRoot.ControlGroupByConnection.PageInfo == nil { + break + } + + return e.ComplexityRoot.ControlGroupByConnection.PageInfo(childComplexity), true + case "ControlGroupByConnection.totalCount": + if e.ComplexityRoot.ControlGroupByConnection.TotalCount == nil { + break + } + + return e.ComplexityRoot.ControlGroupByConnection.TotalCount(childComplexity), true + + case "ControlGroupByEdge.cursor": + if e.ComplexityRoot.ControlGroupByEdge.Cursor == nil { + break + } + + return e.ComplexityRoot.ControlGroupByEdge.Cursor(childComplexity), true + case "ControlGroupByEdge.node": + if e.ComplexityRoot.ControlGroupByEdge.Node == nil { + break + } + + return e.ComplexityRoot.ControlGroupByEdge.Node(childComplexity), true + case "ControlGroupConnection.edges": if e.ComplexityRoot.ControlGroupConnection.Edges == nil { break @@ -38656,6 +38770,17 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin } return e.ComplexityRoot.Query.Controls(childComplexity, args["after"].(*entgql.Cursor[string]), args["first"].(*int), args["before"].(*entgql.Cursor[string]), args["last"].(*int), args["orderBy"].([]*generated.ControlOrder), args["where"].(*generated.ControlWhereInput)), true + case "Query.controlsGroupBy": + if e.ComplexityRoot.Query.ControlsGroupBy == nil { + break + } + + args, err := ec.field_Query_controlsGroupBy_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.ComplexityRoot.Query.ControlsGroupBy(childComplexity, args["field"].(model.ControlGroupByField), args["where"].(*generated.ControlWhereInput), args["orderBy"].(*groupby.Order), args["after"].(*entgql.Cursor[string]), args["first"].(*int), args["before"].(*entgql.Cursor[string]), args["last"].(*int)), true case "Query.controlsGroupByCategory": if e.ComplexityRoot.Query.ControlsGroupByCategory == nil { break @@ -40110,6 +40235,17 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin } return e.ComplexityRoot.Query.Subcontrols(childComplexity, args["after"].(*entgql.Cursor[string]), args["first"].(*int), args["before"].(*entgql.Cursor[string]), args["last"].(*int), args["orderBy"].([]*generated.SubcontrolOrder), args["where"].(*generated.SubcontrolWhereInput)), true + case "Query.subcontrolsGroupBy": + if e.ComplexityRoot.Query.SubcontrolsGroupBy == nil { + break + } + + args, err := ec.field_Query_subcontrolsGroupBy_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.ComplexityRoot.Query.SubcontrolsGroupBy(childComplexity, args["field"].(model.SubcontrolGroupByField), args["where"].(*generated.SubcontrolWhereInput), args["orderBy"].(*groupby.Order), args["after"].(*entgql.Cursor[string]), args["first"].(*int), args["before"].(*entgql.Cursor[string]), args["last"].(*int)), true case "Query.subprocessor": if e.ComplexityRoot.Query.Subprocessor == nil { break @@ -40644,6 +40780,17 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin } return e.ComplexityRoot.Query.Vulnerabilities(childComplexity, args["after"].(*entgql.Cursor[string]), args["first"].(*int), args["before"].(*entgql.Cursor[string]), args["last"].(*int), args["orderBy"].([]*generated.VulnerabilityOrder), args["where"].(*generated.VulnerabilityWhereInput)), true + case "Query.vulnerabilitiesGroupBy": + if e.ComplexityRoot.Query.VulnerabilitiesGroupBy == nil { + break + } + + args, err := ec.field_Query_vulnerabilitiesGroupBy_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.ComplexityRoot.Query.VulnerabilitiesGroupBy(childComplexity, args["field"].(model.VulnerabilityGroupByField), args["where"].(*generated.VulnerabilityWhereInput), args["orderBy"].(*groupby.Order), args["after"].(*entgql.Cursor[string]), args["first"].(*int), args["before"].(*entgql.Cursor[string]), args["last"].(*int)), true case "Query.vulnerability": if e.ComplexityRoot.Query.Vulnerability == nil { break @@ -45345,6 +45492,62 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.SubcontrolEdge.Node(childComplexity), true + case "SubcontrolGroupByBucket.count": + if e.ComplexityRoot.SubcontrolGroupByBucket.Count == nil { + break + } + + return e.ComplexityRoot.SubcontrolGroupByBucket.Count(childComplexity), true + case "SubcontrolGroupByBucket.key": + if e.ComplexityRoot.SubcontrolGroupByBucket.Key == nil { + break + } + + return e.ComplexityRoot.SubcontrolGroupByBucket.Key(childComplexity), true + case "SubcontrolGroupByBucket.subcontrols": + if e.ComplexityRoot.SubcontrolGroupByBucket.Subcontrols == nil { + break + } + + args, err := ec.field_SubcontrolGroupByBucket_subcontrols_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.ComplexityRoot.SubcontrolGroupByBucket.Subcontrols(childComplexity, args["after"].(*entgql.Cursor[string]), args["first"].(*int), args["before"].(*entgql.Cursor[string]), args["last"].(*int), args["orderBy"].([]*generated.SubcontrolOrder)), true + + case "SubcontrolGroupByConnection.edges": + if e.ComplexityRoot.SubcontrolGroupByConnection.Edges == nil { + break + } + + return e.ComplexityRoot.SubcontrolGroupByConnection.Edges(childComplexity), true + case "SubcontrolGroupByConnection.pageInfo": + if e.ComplexityRoot.SubcontrolGroupByConnection.PageInfo == nil { + break + } + + return e.ComplexityRoot.SubcontrolGroupByConnection.PageInfo(childComplexity), true + case "SubcontrolGroupByConnection.totalCount": + if e.ComplexityRoot.SubcontrolGroupByConnection.TotalCount == nil { + break + } + + return e.ComplexityRoot.SubcontrolGroupByConnection.TotalCount(childComplexity), true + + case "SubcontrolGroupByEdge.cursor": + if e.ComplexityRoot.SubcontrolGroupByEdge.Cursor == nil { + break + } + + return e.ComplexityRoot.SubcontrolGroupByEdge.Cursor(childComplexity), true + case "SubcontrolGroupByEdge.node": + if e.ComplexityRoot.SubcontrolGroupByEdge.Node == nil { + break + } + + return e.ComplexityRoot.SubcontrolGroupByEdge.Node(childComplexity), true + case "SubcontrolUpdatePayload.subcontrol": if e.ComplexityRoot.SubcontrolUpdatePayload.Subcontrol == nil { break @@ -51729,6 +51932,62 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.VulnerabilityEdge.Node(childComplexity), true + case "VulnerabilityGroupByBucket.count": + if e.ComplexityRoot.VulnerabilityGroupByBucket.Count == nil { + break + } + + return e.ComplexityRoot.VulnerabilityGroupByBucket.Count(childComplexity), true + case "VulnerabilityGroupByBucket.key": + if e.ComplexityRoot.VulnerabilityGroupByBucket.Key == nil { + break + } + + return e.ComplexityRoot.VulnerabilityGroupByBucket.Key(childComplexity), true + case "VulnerabilityGroupByBucket.vulnerabilities": + if e.ComplexityRoot.VulnerabilityGroupByBucket.Vulnerabilities == nil { + break + } + + args, err := ec.field_VulnerabilityGroupByBucket_vulnerabilities_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.ComplexityRoot.VulnerabilityGroupByBucket.Vulnerabilities(childComplexity, args["after"].(*entgql.Cursor[string]), args["first"].(*int), args["before"].(*entgql.Cursor[string]), args["last"].(*int), args["orderBy"].([]*generated.VulnerabilityOrder)), true + + case "VulnerabilityGroupByConnection.edges": + if e.ComplexityRoot.VulnerabilityGroupByConnection.Edges == nil { + break + } + + return e.ComplexityRoot.VulnerabilityGroupByConnection.Edges(childComplexity), true + case "VulnerabilityGroupByConnection.pageInfo": + if e.ComplexityRoot.VulnerabilityGroupByConnection.PageInfo == nil { + break + } + + return e.ComplexityRoot.VulnerabilityGroupByConnection.PageInfo(childComplexity), true + case "VulnerabilityGroupByConnection.totalCount": + if e.ComplexityRoot.VulnerabilityGroupByConnection.TotalCount == nil { + break + } + + return e.ComplexityRoot.VulnerabilityGroupByConnection.TotalCount(childComplexity), true + + case "VulnerabilityGroupByEdge.cursor": + if e.ComplexityRoot.VulnerabilityGroupByEdge.Cursor == nil { + break + } + + return e.ComplexityRoot.VulnerabilityGroupByEdge.Cursor(childComplexity), true + case "VulnerabilityGroupByEdge.node": + if e.ComplexityRoot.VulnerabilityGroupByEdge.Node == nil { + break + } + + return e.ComplexityRoot.VulnerabilityGroupByEdge.Node(childComplexity), true + case "VulnerabilityResolvePayload.review": if e.ComplexityRoot.VulnerabilityResolvePayload.Review == nil { break @@ -53901,6 +54160,7 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { graphql.NewInputUnmarshaler("FindingControlWhereInput", ec.unmarshalInputFindingControlWhereInput), graphql.NewInputUnmarshaler("FindingOrder", ec.unmarshalInputFindingOrder), graphql.NewInputUnmarshaler("FindingWhereInput", ec.unmarshalInputFindingWhereInput), + graphql.NewInputUnmarshaler("GroupByOrder", ec.unmarshalInputGroupByOrder), graphql.NewInputUnmarshaler("GroupMembersInput", ec.unmarshalInputGroupMembersInput), graphql.NewInputUnmarshaler("GroupMembershipOrder", ec.unmarshalInputGroupMembershipOrder), graphql.NewInputUnmarshaler("GroupMembershipWhereInput", ec.unmarshalInputGroupMembershipWhereInput), @@ -56672,11 +56932,11 @@ extend type Query { """ All existing categories or domains used in the organization @deprecated """ - controlCategories: [String!] + controlCategories: [String!] @deprecated(reason: "use controlsGroupBy and subcontrolsGroupBy with field: CATEGORY") """ All existing subcategories or domains used in the organization @deprecated """ - controlSubcategories: [String!] + controlSubcategories: [String!] @deprecated(reason: "use controlsGroupBy and subcontrolsGroupBy with field: SUBCATEGORY") """ Existing categories or domains for controls used in the organization """ @@ -56690,7 +56950,7 @@ extend type Query { Filtering options for APITokens returned from the connection. """ where: ControlWhereInput - ): [ControlCategoryEdge!] + ): [ControlCategoryEdge!] @deprecated(reason: "use controlsGroupBy with field: CATEGORY") """ Existing subcategories or subdomains for controls used in the organization """ @@ -56703,7 +56963,7 @@ extend type Query { Filtering options for APITokens returned from the connection. """ where: ControlWhereInput - ): [ControlCategoryEdge!] + ): [ControlCategoryEdge!] @deprecated(reason: "use controlsGroupBy with field: SUBCATEGORY") """ Get controls grouped by category @@ -56742,7 +57002,7 @@ extend type Query { Filter by category, used for paginated requests to pull more data per category """ category: String - ): ControlGroupConnection! + ): ControlGroupConnection! @deprecated(reason: "use controlsGroupBy with field: CATEGORY") } type ControlCategory { @@ -151707,6 +151967,294 @@ type GroupBulkUpdatePayload { """ error: String } +`, BuiltIn: false}, + {Name: "../schema/groupby.graphql", Input: `directive @goEnum(value: String) on ENUM_VALUE +""" +GroupByOrderField is the field group by buckets are ordered by +""" +enum GroupByOrderField @goModel(model: "github.com/theopenlane/gqlgen-plugins/groupby.OrderField") { + COUNT @goEnum(value: "github.com/theopenlane/gqlgen-plugins/groupby.OrderFieldCount") + KEY @goEnum(value: "github.com/theopenlane/gqlgen-plugins/groupby.OrderFieldKey") +} +""" +GroupByOrder is the ordering of group by buckets +""" +input GroupByOrder @goModel(model: "github.com/theopenlane/gqlgen-plugins/groupby.Order") { + """ + The ordering direction + """ + direction: OrderDirection! = DESC + """ + The field by which to order the groups + """ + field: GroupByOrderField! = COUNT +} +""" +ControlGroupByField are the Control fields that can be grouped on +""" +enum ControlGroupByField { + CATEGORY + SUBCATEGORY +} +""" +ControlGroupByBucket is a group of controls sharing the same value for the grouped field +""" +type ControlGroupByBucket @goModel(model: "github.com/theopenlane/gqlgen-plugins/groupby.Bucket") { + """ + The grouped value, null when the rows have no value + """ + key: String + """ + The number of controls in the group + """ + count: Int! + """ + The controls in the group + """ + controls(after: Cursor, first: Int, before: Cursor, last: Int, orderBy: [ControlOrder!]): ControlConnection! @goField(forceResolver: true) +} +""" +ControlGroupByEdge is a Control group by bucket with its pagination cursor +""" +type ControlGroupByEdge @goModel(model: "github.com/theopenlane/gqlgen-plugins/groupby.Edge") { + """ + The bucket at the end of the edge + """ + node: ControlGroupByBucket! + """ + A cursor for use in pagination + """ + cursor: Cursor! +} +""" +ControlGroupByConnection is a paginated list of Control group by buckets +""" +type ControlGroupByConnection @goModel(model: "github.com/theopenlane/gqlgen-plugins/groupby.Connection") { + """ + A list of edges + """ + edges: [ControlGroupByEdge!]! + """ + Information to aid in pagination + """ + pageInfo: PageInfo! + """ + Identifies the total count of groups in the connection + """ + totalCount: Int! +} +""" +SubcontrolGroupByField are the Subcontrol fields that can be grouped on +""" +enum SubcontrolGroupByField { + CATEGORY + SUBCATEGORY +} +""" +SubcontrolGroupByBucket is a group of subcontrols sharing the same value for the grouped field +""" +type SubcontrolGroupByBucket @goModel(model: "github.com/theopenlane/gqlgen-plugins/groupby.Bucket") { + """ + The grouped value, null when the rows have no value + """ + key: String + """ + The number of subcontrols in the group + """ + count: Int! + """ + The subcontrols in the group + """ + subcontrols(after: Cursor, first: Int, before: Cursor, last: Int, orderBy: [SubcontrolOrder!]): SubcontrolConnection! @goField(forceResolver: true) +} +""" +SubcontrolGroupByEdge is a Subcontrol group by bucket with its pagination cursor +""" +type SubcontrolGroupByEdge @goModel(model: "github.com/theopenlane/gqlgen-plugins/groupby.Edge") { + """ + The bucket at the end of the edge + """ + node: SubcontrolGroupByBucket! + """ + A cursor for use in pagination + """ + cursor: Cursor! +} +""" +SubcontrolGroupByConnection is a paginated list of Subcontrol group by buckets +""" +type SubcontrolGroupByConnection @goModel(model: "github.com/theopenlane/gqlgen-plugins/groupby.Connection") { + """ + A list of edges + """ + edges: [SubcontrolGroupByEdge!]! + """ + Information to aid in pagination + """ + pageInfo: PageInfo! + """ + Identifies the total count of groups in the connection + """ + totalCount: Int! +} +""" +VulnerabilityGroupByField are the Vulnerability fields that can be grouped on +""" +enum VulnerabilityGroupByField { + VULNERABILITY_STATUS_NAME + EXTERNAL_OWNER_ID + CVE_ID + SOURCE + SEVERITY +} +""" +VulnerabilityGroupByBucket is a group of vulnerabilities sharing the same value for the grouped field +""" +type VulnerabilityGroupByBucket @goModel(model: "github.com/theopenlane/gqlgen-plugins/groupby.Bucket") { + """ + The grouped value, null when the rows have no value + """ + key: String + """ + The number of vulnerabilities in the group + """ + count: Int! + """ + The vulnerabilities in the group + """ + vulnerabilities(after: Cursor, first: Int, before: Cursor, last: Int, orderBy: [VulnerabilityOrder!]): VulnerabilityConnection! @goField(forceResolver: true) +} +""" +VulnerabilityGroupByEdge is a Vulnerability group by bucket with its pagination cursor +""" +type VulnerabilityGroupByEdge @goModel(model: "github.com/theopenlane/gqlgen-plugins/groupby.Edge") { + """ + The bucket at the end of the edge + """ + node: VulnerabilityGroupByBucket! + """ + A cursor for use in pagination + """ + cursor: Cursor! +} +""" +VulnerabilityGroupByConnection is a paginated list of Vulnerability group by buckets +""" +type VulnerabilityGroupByConnection @goModel(model: "github.com/theopenlane/gqlgen-plugins/groupby.Connection") { + """ + A list of edges + """ + edges: [VulnerabilityGroupByEdge!]! + """ + Information to aid in pagination + """ + pageInfo: PageInfo! + """ + Identifies the total count of groups in the connection + """ + totalCount: Int! +} +extend type Query { + """ + controlsGroupBy groups controls by a field and returns each group with its count and rows + """ + controlsGroupBy( + """ + The field to group by + """ + field: ControlGroupByField! + """ + Filtering options for controls included in the groups + """ + where: ControlWhereInput + """ + Ordering options for the groups, defaults to count descending + """ + orderBy: GroupByOrder + """ + Returns the groups that come after the specified cursor + """ + after: Cursor + """ + Returns the first _n_ groups + """ + first: Int + """ + Returns the groups that come before the specified cursor + """ + before: Cursor + """ + Returns the last _n_ groups + """ + last: Int + ): ControlGroupByConnection! + """ + subcontrolsGroupBy groups subcontrols by a field and returns each group with its count and rows + """ + subcontrolsGroupBy( + """ + The field to group by + """ + field: SubcontrolGroupByField! + """ + Filtering options for subcontrols included in the groups + """ + where: SubcontrolWhereInput + """ + Ordering options for the groups, defaults to count descending + """ + orderBy: GroupByOrder + """ + Returns the groups that come after the specified cursor + """ + after: Cursor + """ + Returns the first _n_ groups + """ + first: Int + """ + Returns the groups that come before the specified cursor + """ + before: Cursor + """ + Returns the last _n_ groups + """ + last: Int + ): SubcontrolGroupByConnection! + """ + vulnerabilitiesGroupBy groups vulnerabilities by a field and returns each group with its count and rows + """ + vulnerabilitiesGroupBy( + """ + The field to group by + """ + field: VulnerabilityGroupByField! + """ + Filtering options for vulnerabilities included in the groups + """ + where: VulnerabilityWhereInput + """ + Ordering options for the groups, defaults to count descending + """ + orderBy: GroupByOrder + """ + Returns the groups that come after the specified cursor + """ + after: Cursor + """ + Returns the first _n_ groups + """ + first: Int + """ + Returns the groups that come before the specified cursor + """ + before: Cursor + """ + Returns the last _n_ groups + """ + last: Int + ): VulnerabilityGroupByConnection! +} `, BuiltIn: false}, {Name: "../schema/groupextended.graphql", Input: `extend input CreateGroupInput { createGroupSettings: CreateGroupSettingInput @@ -162223,7 +162771,7 @@ extend type Query { Filtering options for vulnerabilities included in the summary. """ where: VulnerabilityWhereInput - ): VulnerabilitySummary! + ): VulnerabilitySummary! @deprecated(reason: "use vulnerabilitiesGroupBy with field: SEVERITY, SOURCE, or VULNERABILITY_STATUS_NAME") } `, BuiltIn: false}, {Name: "../schema/webauthn.graphql", Input: `extend type Mutation{ @@ -165045,6 +165593,40 @@ func (ec *executionContext) childFields_ControlGroup(ctx context.Context, field return nil, fmt.Errorf("no field named %q was found under type ControlGroup", field.Name) } +func (ec *executionContext) childFields_ControlGroupByBucket(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "key": + return ec.fieldContext_ControlGroupByBucket_key(ctx, field) + case "count": + return ec.fieldContext_ControlGroupByBucket_count(ctx, field) + case "controls": + return ec.fieldContext_ControlGroupByBucket_controls(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type ControlGroupByBucket", field.Name) +} + +func (ec *executionContext) childFields_ControlGroupByConnection(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "edges": + return ec.fieldContext_ControlGroupByConnection_edges(ctx, field) + case "pageInfo": + return ec.fieldContext_ControlGroupByConnection_pageInfo(ctx, field) + case "totalCount": + return ec.fieldContext_ControlGroupByConnection_totalCount(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type ControlGroupByConnection", field.Name) +} + +func (ec *executionContext) childFields_ControlGroupByEdge(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "node": + return ec.fieldContext_ControlGroupByEdge_node(ctx, field) + case "cursor": + return ec.fieldContext_ControlGroupByEdge_cursor(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type ControlGroupByEdge", field.Name) +} + func (ec *executionContext) childFields_ControlGroupConnection(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { switch field.Name { case "edges": @@ -174111,6 +174693,40 @@ func (ec *executionContext) childFields_SubcontrolEdge(ctx context.Context, fiel return nil, fmt.Errorf("no field named %q was found under type SubcontrolEdge", field.Name) } +func (ec *executionContext) childFields_SubcontrolGroupByBucket(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "key": + return ec.fieldContext_SubcontrolGroupByBucket_key(ctx, field) + case "count": + return ec.fieldContext_SubcontrolGroupByBucket_count(ctx, field) + case "subcontrols": + return ec.fieldContext_SubcontrolGroupByBucket_subcontrols(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type SubcontrolGroupByBucket", field.Name) +} + +func (ec *executionContext) childFields_SubcontrolGroupByConnection(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "edges": + return ec.fieldContext_SubcontrolGroupByConnection_edges(ctx, field) + case "pageInfo": + return ec.fieldContext_SubcontrolGroupByConnection_pageInfo(ctx, field) + case "totalCount": + return ec.fieldContext_SubcontrolGroupByConnection_totalCount(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type SubcontrolGroupByConnection", field.Name) +} + +func (ec *executionContext) childFields_SubcontrolGroupByEdge(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "node": + return ec.fieldContext_SubcontrolGroupByEdge_node(ctx, field) + case "cursor": + return ec.fieldContext_SubcontrolGroupByEdge_cursor(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type SubcontrolGroupByEdge", field.Name) +} + func (ec *executionContext) childFields_SubcontrolUpdatePayload(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { switch field.Name { case "subcontrol": @@ -177025,6 +177641,40 @@ func (ec *executionContext) childFields_VulnerabilityEdge(ctx context.Context, f return nil, fmt.Errorf("no field named %q was found under type VulnerabilityEdge", field.Name) } +func (ec *executionContext) childFields_VulnerabilityGroupByBucket(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "key": + return ec.fieldContext_VulnerabilityGroupByBucket_key(ctx, field) + case "count": + return ec.fieldContext_VulnerabilityGroupByBucket_count(ctx, field) + case "vulnerabilities": + return ec.fieldContext_VulnerabilityGroupByBucket_vulnerabilities(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type VulnerabilityGroupByBucket", field.Name) +} + +func (ec *executionContext) childFields_VulnerabilityGroupByConnection(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "edges": + return ec.fieldContext_VulnerabilityGroupByConnection_edges(ctx, field) + case "pageInfo": + return ec.fieldContext_VulnerabilityGroupByConnection_pageInfo(ctx, field) + case "totalCount": + return ec.fieldContext_VulnerabilityGroupByConnection_totalCount(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type VulnerabilityGroupByConnection", field.Name) +} + +func (ec *executionContext) childFields_VulnerabilityGroupByEdge(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "node": + return ec.fieldContext_VulnerabilityGroupByEdge_node(ctx, field) + case "cursor": + return ec.fieldContext_VulnerabilityGroupByEdge_cursor(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type VulnerabilityGroupByEdge", field.Name) +} + func (ec *executionContext) childFields_VulnerabilityResolvePayload(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { switch field.Name { case "vulnerability": diff --git a/internal/graphapi/groupby.resolvers.go b/internal/graphapi/groupby.resolvers.go new file mode 100644 index 0000000000..ed67241908 --- /dev/null +++ b/internal/graphapi/groupby.resolvers.go @@ -0,0 +1,305 @@ +package graphapi + +// This file will be automatically regenerated based on the schema, any resolver +// implementations +// will be copied through when generating and any unknown code will be moved to the end. +// Code generated by github.com/99designs/gqlgen + +import ( + "context" + "errors" + + "entgo.io/contrib/entgql" + "github.com/theopenlane/core/v2/internal/ent/generated" + "github.com/theopenlane/core/v2/internal/ent/generated/control" + "github.com/theopenlane/core/v2/internal/ent/generated/predicate" + "github.com/theopenlane/core/v2/internal/ent/generated/subcontrol" + "github.com/theopenlane/core/v2/internal/ent/generated/vulnerability" + "github.com/theopenlane/core/v2/internal/graphapi/common" + gqlgenerated "github.com/theopenlane/core/v2/internal/graphapi/generated" + "github.com/theopenlane/core/v2/internal/graphapi/model" + "github.com/theopenlane/gqlgen-plugins/graphutils" + "github.com/theopenlane/gqlgen-plugins/groupby" +) + +// Controls is the resolver for the controls field. +func (r *controlGroupByBucketResolver) Controls(ctx context.Context, obj *groupby.Bucket, after *entgql.Cursor[string], first *int, before *entgql.Cursor[string], last *int, orderBy []*generated.ControlOrder) (*generated.ControlConnection, error) { + // set page limit if nothing was set + first, last = graphutils.SetFirstLastDefaults(first, last, r.maxResultLimit) + + if orderBy == nil { + orderBy = []*generated.ControlOrder{ + { + Field: generated.ControlOrderFieldCreatedAt, + Direction: entgql.OrderDirectionDesc, + }, + } + } + + query, err := withTransactionalMutation(ctx).Control.Query().Where(predicate.Control(obj.Filter)).CollectFields(ctx) + if err != nil { + return nil, parseRequestError(ctx, err, common.Action{Action: common.ActionGet, Object: "control"}) + } + + res, err := query.Paginate( + ctx, + after, + first, + before, + last, + generated.WithControlOrder(orderBy)) + if err != nil { + return nil, parseRequestError(ctx, err, common.Action{Action: common.ActionGet, Object: "control"}) + } + + return res, err +} + +// ControlsGroupBy is the resolver for the controlsGroupBy field. +func (r *queryResolver) ControlsGroupBy(ctx context.Context, field model.ControlGroupByField, where *generated.ControlWhereInput, orderBy *groupby.Order, after *entgql.Cursor[string], first *int, before *entgql.Cursor[string], last *int) (*groupby.Connection, error) { + // set page limit if nothing was set + first, last = graphutils.SetFirstLastDefaults(first, last, r.maxResultLimit) + + var column string + + switch field { + case model.ControlGroupByFieldCategory: + column = control.FieldCategory + case model.ControlGroupByFieldSubcategory: + column = control.FieldSubcategory + default: + return nil, parseRequestError(ctx, groupby.ErrInvalidField, common.Action{Action: common.ActionGet, Object: "control"}) + } + + var ( + filter predicate.Control + rows []groupby.Row + total int + err error + ) + + query := withTransactionalMutation(ctx).Control.Query() + + if where != nil { + filter, err = where.P() + if err != nil && !errors.Is(err, generated.ErrEmptyControlWhereInput) { + return nil, parseRequestError(ctx, err, common.Action{Action: common.ActionGet, Object: "control"}) + } + } + + if filter != nil { + query = query.Where(filter) + } + + groupQuery := groupby.NewQuery(column, filter, orderBy, after, first, before, last) + + if err := query.Clone().Modify(groupQuery.Modifier).Scan(ctx, &rows); err != nil { + return nil, parseRequestError(ctx, err, common.Action{Action: common.ActionGet, Object: "control"}) + } + + if graphutils.CheckForRequestedField(ctx, "totalCount") { + total, err = query.Modify(groupQuery.TotalModifier).Int(ctx) + if err != nil { + return nil, parseRequestError(ctx, err, common.Action{Action: common.ActionGet, Object: "control"}) + } + } + + return groupQuery.Connection(rows, total), nil +} + +// SubcontrolsGroupBy is the resolver for the subcontrolsGroupBy field. +func (r *queryResolver) SubcontrolsGroupBy(ctx context.Context, field model.SubcontrolGroupByField, where *generated.SubcontrolWhereInput, orderBy *groupby.Order, after *entgql.Cursor[string], first *int, before *entgql.Cursor[string], last *int) (*groupby.Connection, error) { + // set page limit if nothing was set + first, last = graphutils.SetFirstLastDefaults(first, last, r.maxResultLimit) + + var column string + + switch field { + case model.SubcontrolGroupByFieldCategory: + column = subcontrol.FieldCategory + case model.SubcontrolGroupByFieldSubcategory: + column = subcontrol.FieldSubcategory + default: + return nil, parseRequestError(ctx, groupby.ErrInvalidField, common.Action{Action: common.ActionGet, Object: "subcontrol"}) + } + + var ( + filter predicate.Subcontrol + rows []groupby.Row + total int + err error + ) + + query := withTransactionalMutation(ctx).Subcontrol.Query() + + if where != nil { + filter, err = where.P() + if err != nil && !errors.Is(err, generated.ErrEmptySubcontrolWhereInput) { + return nil, parseRequestError(ctx, err, common.Action{Action: common.ActionGet, Object: "subcontrol"}) + } + } + + if filter != nil { + query = query.Where(filter) + } + + groupQuery := groupby.NewQuery(column, filter, orderBy, after, first, before, last) + + if err := query.Clone().Modify(groupQuery.Modifier).Scan(ctx, &rows); err != nil { + return nil, parseRequestError(ctx, err, common.Action{Action: common.ActionGet, Object: "subcontrol"}) + } + + if graphutils.CheckForRequestedField(ctx, "totalCount") { + total, err = query.Modify(groupQuery.TotalModifier).Int(ctx) + if err != nil { + return nil, parseRequestError(ctx, err, common.Action{Action: common.ActionGet, Object: "subcontrol"}) + } + } + + return groupQuery.Connection(rows, total), nil +} + +// VulnerabilitiesGroupBy is the resolver for the vulnerabilitiesGroupBy field. +func (r *queryResolver) VulnerabilitiesGroupBy(ctx context.Context, field model.VulnerabilityGroupByField, where *generated.VulnerabilityWhereInput, orderBy *groupby.Order, after *entgql.Cursor[string], first *int, before *entgql.Cursor[string], last *int) (*groupby.Connection, error) { + // set page limit if nothing was set + first, last = graphutils.SetFirstLastDefaults(first, last, r.maxResultLimit) + + var column string + + switch field { + case model.VulnerabilityGroupByFieldVulnerabilityStatusName: + column = vulnerability.FieldVulnerabilityStatusName + case model.VulnerabilityGroupByFieldExternalOwnerID: + column = vulnerability.FieldExternalOwnerID + case model.VulnerabilityGroupByFieldCveID: + column = vulnerability.FieldCveID + case model.VulnerabilityGroupByFieldSource: + column = vulnerability.FieldSource + case model.VulnerabilityGroupByFieldSeverity: + column = vulnerability.FieldSeverity + default: + return nil, parseRequestError(ctx, groupby.ErrInvalidField, common.Action{Action: common.ActionGet, Object: "vulnerability"}) + } + + var ( + filter predicate.Vulnerability + rows []groupby.Row + total int + err error + ) + + query := withTransactionalMutation(ctx).Vulnerability.Query() + + if where != nil { + filter, err = where.P() + if err != nil && !errors.Is(err, generated.ErrEmptyVulnerabilityWhereInput) { + return nil, parseRequestError(ctx, err, common.Action{Action: common.ActionGet, Object: "vulnerability"}) + } + } + + if filter != nil { + query = query.Where(filter) + } + + groupQuery := groupby.NewQuery(column, filter, orderBy, after, first, before, last) + + if err := query.Clone().Modify(groupQuery.Modifier).Scan(ctx, &rows); err != nil { + return nil, parseRequestError(ctx, err, common.Action{Action: common.ActionGet, Object: "vulnerability"}) + } + + if graphutils.CheckForRequestedField(ctx, "totalCount") { + total, err = query.Modify(groupQuery.TotalModifier).Int(ctx) + if err != nil { + return nil, parseRequestError(ctx, err, common.Action{Action: common.ActionGet, Object: "vulnerability"}) + } + } + + return groupQuery.Connection(rows, total), nil +} + +// Subcontrols is the resolver for the subcontrols field. +func (r *subcontrolGroupByBucketResolver) Subcontrols(ctx context.Context, obj *groupby.Bucket, after *entgql.Cursor[string], first *int, before *entgql.Cursor[string], last *int, orderBy []*generated.SubcontrolOrder) (*generated.SubcontrolConnection, error) { + // set page limit if nothing was set + first, last = graphutils.SetFirstLastDefaults(first, last, r.maxResultLimit) + + if orderBy == nil { + orderBy = []*generated.SubcontrolOrder{ + { + Field: generated.SubcontrolOrderFieldCreatedAt, + Direction: entgql.OrderDirectionDesc, + }, + } + } + + query, err := withTransactionalMutation(ctx).Subcontrol.Query().Where(predicate.Subcontrol(obj.Filter)).CollectFields(ctx) + if err != nil { + return nil, parseRequestError(ctx, err, common.Action{Action: common.ActionGet, Object: "subcontrol"}) + } + + res, err := query.Paginate( + ctx, + after, + first, + before, + last, + generated.WithSubcontrolOrder(orderBy)) + if err != nil { + return nil, parseRequestError(ctx, err, common.Action{Action: common.ActionGet, Object: "subcontrol"}) + } + + return res, err +} + +// Vulnerabilities is the resolver for the vulnerabilities field. +func (r *vulnerabilityGroupByBucketResolver) Vulnerabilities(ctx context.Context, obj *groupby.Bucket, after *entgql.Cursor[string], first *int, before *entgql.Cursor[string], last *int, orderBy []*generated.VulnerabilityOrder) (*generated.VulnerabilityConnection, error) { + // set page limit if nothing was set + first, last = graphutils.SetFirstLastDefaults(first, last, r.maxResultLimit) + + if orderBy == nil { + orderBy = []*generated.VulnerabilityOrder{ + { + Field: generated.VulnerabilityOrderFieldCreatedAt, + Direction: entgql.OrderDirectionDesc, + }, + } + } + + query, err := withTransactionalMutation(ctx).Vulnerability.Query().Where(predicate.Vulnerability(obj.Filter)).CollectFields(ctx) + if err != nil { + return nil, parseRequestError(ctx, err, common.Action{Action: common.ActionGet, Object: "vulnerability"}) + } + + res, err := query.Paginate( + ctx, + after, + first, + before, + last, + generated.WithVulnerabilityOrder(orderBy)) + if err != nil { + return nil, parseRequestError(ctx, err, common.Action{Action: common.ActionGet, Object: "vulnerability"}) + } + + return res, err +} + +// ControlGroupByBucket returns gqlgenerated.ControlGroupByBucketResolver implementation. +func (r *Resolver) ControlGroupByBucket() gqlgenerated.ControlGroupByBucketResolver { + return &controlGroupByBucketResolver{r} +} + +// SubcontrolGroupByBucket returns gqlgenerated.SubcontrolGroupByBucketResolver implementation. +func (r *Resolver) SubcontrolGroupByBucket() gqlgenerated.SubcontrolGroupByBucketResolver { + return &subcontrolGroupByBucketResolver{r} +} + +// VulnerabilityGroupByBucket returns gqlgenerated.VulnerabilityGroupByBucketResolver implementation. +func (r *Resolver) VulnerabilityGroupByBucket() gqlgenerated.VulnerabilityGroupByBucketResolver { + return &vulnerabilityGroupByBucketResolver{r} +} + +type ( + controlGroupByBucketResolver struct{ *Resolver } + subcontrolGroupByBucketResolver struct{ *Resolver } + vulnerabilityGroupByBucketResolver struct{ *Resolver } +) diff --git a/internal/graphapi/historygenerated/ent.generated.go b/internal/graphapi/historygenerated/ent.generated.go index 6b920f54e6..d4d2161f3b 100644 --- a/internal/graphapi/historygenerated/ent.generated.go +++ b/internal/graphapi/historygenerated/ent.generated.go @@ -44835,10 +44835,10 @@ func (ec *executionContext) _Query___schema(ctx context.Context, field graphql.C }, nil, func(ctx context.Context, selections ast.SelectionSet, v *introspection.Schema) graphql.Marshaler { - return ec.marshalO__Schema2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐSchema(ctx, selections, v) + return ec.marshalN__Schema2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐSchema(ctx, selections, v) }, true, - false, + true, ) } func (ec *executionContext) fieldContext_Query___schema(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -211588,7 +211588,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { return ec._Query___schema(ctx, field) }) - if out.Values[i] == graphql.RequiredNull { + if out.Values[i] == graphql.Null { atomic.AddUint32(&out.Invalids, 1) } default: diff --git a/internal/graphapi/historygenerated/prelude.generated.go b/internal/graphapi/historygenerated/prelude.generated.go index 2af4e026ce..4f739f9699 100644 --- a/internal/graphapi/historygenerated/prelude.generated.go +++ b/internal/graphapi/historygenerated/prelude.generated.go @@ -20,34 +20,26 @@ import ( // region ***************************** args.gotpl ***************************** -func (ec *executionContext) dir_defer_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { +func (ec *executionContext) field___Directive_args_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { var err error args := map[string]any{} - arg0, err := graphql.ProcessArgField(ctx, rawArgs, "if", - func(ctx context.Context, v any) (*bool, error) { - return ec.unmarshalOBoolean2ᚖbool(ctx, v) - }) - if err != nil { - return nil, err - } - args["if"] = arg0 - arg1, err := graphql.ProcessArgField(ctx, rawArgs, "label", - func(ctx context.Context, v any) (*string, error) { - return ec.unmarshalOString2ᚖstring(ctx, v) + arg0, err := graphql.ProcessArgField(ctx, rawArgs, "includeDeprecated", + func(ctx context.Context, v any) (bool, error) { + return ec.unmarshalOBoolean2bool(ctx, v) }) if err != nil { return nil, err } - args["label"] = arg1 + args["includeDeprecated"] = arg0 return args, nil } -func (ec *executionContext) field___Directive_args_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { +func (ec *executionContext) field___Field_args_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { var err error args := map[string]any{} arg0, err := graphql.ProcessArgField(ctx, rawArgs, "includeDeprecated", - func(ctx context.Context, v any) (*bool, error) { - return ec.unmarshalOBoolean2ᚖbool(ctx, v) + func(ctx context.Context, v any) (bool, error) { + return ec.unmarshalOBoolean2bool(ctx, v) }) if err != nil { return nil, err @@ -56,12 +48,12 @@ func (ec *executionContext) field___Directive_args_args(ctx context.Context, raw return args, nil } -func (ec *executionContext) field___Field_args_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { +func (ec *executionContext) field___Type_enumValues_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { var err error args := map[string]any{} arg0, err := graphql.ProcessArgField(ctx, rawArgs, "includeDeprecated", - func(ctx context.Context, v any) (*bool, error) { - return ec.unmarshalOBoolean2ᚖbool(ctx, v) + func(ctx context.Context, v any) (bool, error) { + return ec.unmarshalOBoolean2bool(ctx, v) }) if err != nil { return nil, err @@ -70,7 +62,7 @@ func (ec *executionContext) field___Field_args_args(ctx context.Context, rawArgs return args, nil } -func (ec *executionContext) field___Type_enumValues_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { +func (ec *executionContext) field___Type_fields_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { var err error args := map[string]any{} arg0, err := graphql.ProcessArgField(ctx, rawArgs, "includeDeprecated", @@ -84,7 +76,7 @@ func (ec *executionContext) field___Type_enumValues_args(ctx context.Context, ra return args, nil } -func (ec *executionContext) field___Type_fields_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { +func (ec *executionContext) field___Type_inputFields_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { var err error args := map[string]any{} arg0, err := graphql.ProcessArgField(ctx, rawArgs, "includeDeprecated", @@ -203,7 +195,8 @@ func (ec *executionContext) ___Directive_args(ctx context.Context, field graphql return ec.fieldContext___Directive_args(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.Args, nil + fc := graphql.GetFieldContext(ctx) + return obj.VisibleArgs(fc.Args["includeDeprecated"].(bool)), nil }, nil, func(ctx context.Context, selections ast.SelectionSet, v []introspection.InputValue) graphql.Marshaler { @@ -217,7 +210,7 @@ func (ec *executionContext) fieldContext___Directive_args(ctx context.Context, f fc = &graphql.FieldContext{ Object: "__Directive", Field: field, - IsMethod: false, + IsMethod: true, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { return ec.childFields___InputValue(ctx, field) @@ -384,7 +377,8 @@ func (ec *executionContext) ___Field_args(ctx context.Context, field graphql.Col return ec.fieldContext___Field_args(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.Args, nil + fc := graphql.GetFieldContext(ctx) + return obj.VisibleArgs(fc.Args["includeDeprecated"].(bool)), nil }, nil, func(ctx context.Context, selections ast.SelectionSet, v []introspection.InputValue) graphql.Marshaler { @@ -398,7 +392,7 @@ func (ec *executionContext) fieldContext___Field_args(ctx context.Context, field fc = &graphql.FieldContext{ Object: "__Field", Field: field, - IsMethod: false, + IsMethod: true, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { return ec.childFields___InputValue(ctx, field) @@ -1079,7 +1073,8 @@ func (ec *executionContext) ___Type_inputFields(ctx context.Context, field graph return ec.fieldContext___Type_inputFields(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.InputFields(), nil + fc := graphql.GetFieldContext(ctx) + return obj.VisibleInputFields(fc.Args["includeDeprecated"].(bool)), nil }, nil, func(ctx context.Context, selections ast.SelectionSet, v []introspection.InputValue) graphql.Marshaler { @@ -1089,7 +1084,7 @@ func (ec *executionContext) ___Type_inputFields(ctx context.Context, field graph false, ) } -func (ec *executionContext) fieldContext___Type_inputFields(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Type_inputFields(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Type", Field: field, @@ -1099,6 +1094,17 @@ func (ec *executionContext) fieldContext___Type_inputFields(_ context.Context, f return ec.childFields___InputValue(ctx, field) }, } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field___Type_inputFields_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } return fc, nil } @@ -1751,6 +1757,14 @@ func (ec *executionContext) marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋg return ret } +func (ec *executionContext) marshalN__Schema2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐSchema(ctx context.Context, sel ast.SelectionSet, v *introspection.Schema) graphql.Marshaler { + if v == nil { + graphql.AddInvalidNullError(ctx, "__Schema!") + return graphql.Null + } + return ec.___Schema(ctx, sel, v) +} + func (ec *executionContext) marshalN__Type2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx context.Context, sel ast.SelectionSet, v introspection.Type) graphql.Marshaler { return ec.___Type(ctx, sel, &v) } @@ -2137,13 +2151,6 @@ func (ec *executionContext) marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋg return ret } -func (ec *executionContext) marshalO__Schema2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐSchema(ctx context.Context, sel ast.SelectionSet, v *introspection.Schema) graphql.Marshaler { - if v == nil { - return graphql.Null - } - return ec.___Schema(ctx, sel, v) -} - func (ec *executionContext) marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.Type) graphql.Marshaler { if v == nil { return graphql.Null diff --git a/internal/graphapi/historyschema/checksum/.history_schema_checksum b/internal/graphapi/historyschema/checksum/.history_schema_checksum index 444cf5c51a..820649cba8 100644 --- a/internal/graphapi/historyschema/checksum/.history_schema_checksum +++ b/internal/graphapi/historyschema/checksum/.history_schema_checksum @@ -1 +1 @@ -5c997c7bd6909c8e5fa882aebd48636c715d6178af675a7e007df92280741557 \ No newline at end of file +31e43ddaef22744b50c58a1ca1185a958eb8fd1f815f8f4073b918b20eddb1af \ No newline at end of file diff --git a/internal/graphapi/model/gen_models.go b/internal/graphapi/model/gen_models.go index 7250a0159e..3e9f1c95b6 100644 --- a/internal/graphapi/model/gen_models.go +++ b/internal/graphapi/model/gen_models.go @@ -4346,6 +4346,62 @@ func (e ControlCategoryOrderField) MarshalJSON() ([]byte, error) { return buf.Bytes(), nil } +// ControlGroupByField are the Control fields that can be grouped on +type ControlGroupByField string + +const ( + ControlGroupByFieldCategory ControlGroupByField = "CATEGORY" + ControlGroupByFieldSubcategory ControlGroupByField = "SUBCATEGORY" +) + +var AllControlGroupByField = []ControlGroupByField{ + ControlGroupByFieldCategory, + ControlGroupByFieldSubcategory, +} + +func (e ControlGroupByField) IsValid() bool { + switch e { + case ControlGroupByFieldCategory, ControlGroupByFieldSubcategory: + return true + } + return false +} + +func (e ControlGroupByField) String() string { + return string(e) +} + +func (e *ControlGroupByField) UnmarshalGQL(v any) error { + str, ok := v.(string) + if !ok { + return fmt.Errorf("enums must be strings") + } + + *e = ControlGroupByField(str) + if !e.IsValid() { + return fmt.Errorf("%s is not a valid ControlGroupByField", str) + } + return nil +} + +func (e ControlGroupByField) MarshalGQL(w io.Writer) { + _, _ = fmt.Fprint(w, strconv.Quote(e.String())) +} + +func (e *ControlGroupByField) UnmarshalJSON(b []byte) error { + s, err := strconv.Unquote(string(b)) + if err != nil { + return err + } + return e.UnmarshalGQL(s) +} + +func (e ControlGroupByField) MarshalJSON() ([]byte, error) { + var buf bytes.Buffer + e.MarshalGQL(&buf) + return buf.Bytes(), nil +} + // Properties by which ControlReport connections can be ordered. type ControlReportOrderField string @@ -4470,3 +4526,121 @@ func (e GroupPermissionOrderField) MarshalJSON() ([]byte, error) { e.MarshalGQL(&buf) return buf.Bytes(), nil } + +// SubcontrolGroupByField are the Subcontrol fields that can be grouped on +type SubcontrolGroupByField string + +const ( + SubcontrolGroupByFieldCategory SubcontrolGroupByField = "CATEGORY" + SubcontrolGroupByFieldSubcategory SubcontrolGroupByField = "SUBCATEGORY" +) + +var AllSubcontrolGroupByField = []SubcontrolGroupByField{ + SubcontrolGroupByFieldCategory, + SubcontrolGroupByFieldSubcategory, +} + +func (e SubcontrolGroupByField) IsValid() bool { + switch e { + case SubcontrolGroupByFieldCategory, SubcontrolGroupByFieldSubcategory: + return true + } + return false +} + +func (e SubcontrolGroupByField) String() string { + return string(e) +} + +func (e *SubcontrolGroupByField) UnmarshalGQL(v any) error { + str, ok := v.(string) + if !ok { + return fmt.Errorf("enums must be strings") + } + + *e = SubcontrolGroupByField(str) + if !e.IsValid() { + return fmt.Errorf("%s is not a valid SubcontrolGroupByField", str) + } + return nil +} + +func (e SubcontrolGroupByField) MarshalGQL(w io.Writer) { + _, _ = fmt.Fprint(w, strconv.Quote(e.String())) +} + +func (e *SubcontrolGroupByField) UnmarshalJSON(b []byte) error { + s, err := strconv.Unquote(string(b)) + if err != nil { + return err + } + return e.UnmarshalGQL(s) +} + +func (e SubcontrolGroupByField) MarshalJSON() ([]byte, error) { + var buf bytes.Buffer + e.MarshalGQL(&buf) + return buf.Bytes(), nil +} + +// VulnerabilityGroupByField are the Vulnerability fields that can be grouped on +type VulnerabilityGroupByField string + +const ( + VulnerabilityGroupByFieldVulnerabilityStatusName VulnerabilityGroupByField = "VULNERABILITY_STATUS_NAME" + VulnerabilityGroupByFieldExternalOwnerID VulnerabilityGroupByField = "EXTERNAL_OWNER_ID" + VulnerabilityGroupByFieldCveID VulnerabilityGroupByField = "CVE_ID" + VulnerabilityGroupByFieldSource VulnerabilityGroupByField = "SOURCE" + VulnerabilityGroupByFieldSeverity VulnerabilityGroupByField = "SEVERITY" +) + +var AllVulnerabilityGroupByField = []VulnerabilityGroupByField{ + VulnerabilityGroupByFieldVulnerabilityStatusName, + VulnerabilityGroupByFieldExternalOwnerID, + VulnerabilityGroupByFieldCveID, + VulnerabilityGroupByFieldSource, + VulnerabilityGroupByFieldSeverity, +} + +func (e VulnerabilityGroupByField) IsValid() bool { + switch e { + case VulnerabilityGroupByFieldVulnerabilityStatusName, VulnerabilityGroupByFieldExternalOwnerID, VulnerabilityGroupByFieldCveID, VulnerabilityGroupByFieldSource, VulnerabilityGroupByFieldSeverity: + return true + } + return false +} + +func (e VulnerabilityGroupByField) String() string { + return string(e) +} + +func (e *VulnerabilityGroupByField) UnmarshalGQL(v any) error { + str, ok := v.(string) + if !ok { + return fmt.Errorf("enums must be strings") + } + + *e = VulnerabilityGroupByField(str) + if !e.IsValid() { + return fmt.Errorf("%s is not a valid VulnerabilityGroupByField", str) + } + return nil +} + +func (e VulnerabilityGroupByField) MarshalGQL(w io.Writer) { + _, _ = fmt.Fprint(w, strconv.Quote(e.String())) +} + +func (e *VulnerabilityGroupByField) UnmarshalJSON(b []byte) error { + s, err := strconv.Unquote(string(b)) + if err != nil { + return err + } + return e.UnmarshalGQL(s) +} + +func (e VulnerabilityGroupByField) MarshalJSON() ([]byte, error) { + var buf bytes.Buffer + e.MarshalGQL(&buf) + return buf.Bytes(), nil +} diff --git a/internal/graphapi/notes_test.go b/internal/graphapi/notes_test.go index ada5622e49..386f106691 100644 --- a/internal/graphapi/notes_test.go +++ b/internal/graphapi/notes_test.go @@ -649,7 +649,7 @@ func TestQueryNote(t *testing.T) { const ownerCommentText = "comment from the owner" func TestMutationCommentsForVulnerability(t *testing.T) { - vuln := createVulnerability(t, th.SharedTestUser1.UserCtx, "Commentable Vulnerability") + vuln := createVulnerability(t, th.SharedTestUser1.UserCtx, "Commentable Vulnerability", nil) testCases := []struct { name string diff --git a/internal/graphapi/query/controlextended.graphql b/internal/graphapi/query/controlextended.graphql index 56ef9a71dc..d7b494bbea 100644 --- a/internal/graphapi/query/controlextended.graphql +++ b/internal/graphapi/query/controlextended.graphql @@ -133,6 +133,52 @@ query GetControlCategoriesWithFramework($where: ControlWhereInput) { } } +query GetControlsGroupBy($field: ControlGroupByField!, $first: Int, $last: Int, $after: Cursor, $before: Cursor, $where: ControlWhereInput, $orderBy: GroupByOrder, $rowsFirst: Int, $rowsAfter: Cursor, $rowsOrderBy: [ControlOrder!]) { + controlsGroupBy( + field: $field + first: $first + last: $last + after: $after + before: $before + where: $where + orderBy: $orderBy + ) { + totalCount + pageInfo { + startCursor + endCursor + hasPreviousPage + hasNextPage + } + edges { + cursor + node { + key + count + controls(first: $rowsFirst, after: $rowsAfter, orderBy: $rowsOrderBy) { + totalCount + pageInfo { + startCursor + endCursor + hasPreviousPage + hasNextPage + } + edges { + node { + id + refCode + category + subcategory + referenceFramework + ownerID + } + } + } + } + } + } +} + query GetControlsGroupByCategory($first: Int, $last: Int, $after: Cursor, $before: Cursor, $where: ControlWhereInput, $orderBy: [ControlOrder!], $category: String) { controlsGroupByCategory( first: $first diff --git a/internal/graphapi/query/vulnerabilityextended.graphql b/internal/graphapi/query/vulnerabilityextended.graphql new file mode 100644 index 0000000000..9e8c7782c0 --- /dev/null +++ b/internal/graphapi/query/vulnerabilityextended.graphql @@ -0,0 +1,109 @@ +query GetVulnerabilitiesGroupBy ($field: VulnerabilityGroupByField!, $first: Int, $last: Int, $after: Cursor, $before: Cursor, $where: VulnerabilityWhereInput, $orderBy: GroupByOrder, $rowsFirst: Int, $rowsAfter: Cursor, $rowsOrderBy: [VulnerabilityOrder!]) { + vulnerabilitiesGroupBy(field: $field, first: $first, last: $last, after: $after, before: $before, where: $where, orderBy: $orderBy) { + totalCount + pageInfo { + startCursor + endCursor + hasPreviousPage + hasNextPage + } + edges { + cursor + node { + key + count + vulnerabilities(first: $rowsFirst, after: $rowsAfter, orderBy: $rowsOrderBy) { + totalCount + pageInfo { + startCursor + endCursor + hasPreviousPage + hasNextPage + } + edges { + node { + assignedTo + assignedToGroupID + assignedToIdentityHolderID + assignedToUserID + autoDismissedAt + blocking + category + createdAt + createdBy + cveID + cweIds + dependencyScope + description + discoveredAt + dismissedAt + dismissedComment + dismissedReason + displayID + displayName + environmentID + environmentName + exploitability + externalID + externalOwnerID + externalURI + firstPatchedVersion + fixAvailable + fixedAt + id + impact + impacts + integrationRunID + internalNotes + internalOwner + internalOwnerGroupID + internalOwnerIdentityHolderID + internalOwnerUserID + managedBy + manifestPath + metadata + open + ownerID + packageEcosystem + packageName + priority + production + public + publishedAt + rawPayload + references + remediationSLA + reviewedBy + reviewedByGroupID + reviewedByIdentityHolderID + reviewedByUserID + scopeID + scopeName + score + securityLevel + severity + source + sourceDefinitionID + sourceDefinitionVersion + sourceInstanceID + sourceUpdatedAt + summary + systemInternalID + systemOwned + tags + updatedAt + updatedBy + updatedByImpersonator + validated + vector + vulnerabilityStatusID + vulnerabilityStatusName + vulnerableVersionRange + workflowEligibleMarker + } + } + } + } + } + } +} diff --git a/internal/graphapi/schema/controlextended.graphql b/internal/graphapi/schema/controlextended.graphql index 46754c7de3..d773aa15ea 100644 --- a/internal/graphapi/schema/controlextended.graphql +++ b/internal/graphapi/schema/controlextended.graphql @@ -215,11 +215,11 @@ extend type Query { """ All existing categories or domains used in the organization @deprecated """ - controlCategories: [String!] + controlCategories: [String!] @deprecated(reason: "use controlsGroupBy and subcontrolsGroupBy with field: CATEGORY") """ All existing subcategories or domains used in the organization @deprecated """ - controlSubcategories: [String!] + controlSubcategories: [String!] @deprecated(reason: "use controlsGroupBy and subcontrolsGroupBy with field: SUBCATEGORY") """ Existing categories or domains for controls used in the organization """ @@ -233,7 +233,7 @@ extend type Query { Filtering options for APITokens returned from the connection. """ where: ControlWhereInput - ): [ControlCategoryEdge!] + ): [ControlCategoryEdge!] @deprecated(reason: "use controlsGroupBy with field: CATEGORY") """ Existing subcategories or subdomains for controls used in the organization """ @@ -246,7 +246,7 @@ extend type Query { Filtering options for APITokens returned from the connection. """ where: ControlWhereInput - ): [ControlCategoryEdge!] + ): [ControlCategoryEdge!] @deprecated(reason: "use controlsGroupBy with field: SUBCATEGORY") """ Get controls grouped by category @@ -285,7 +285,7 @@ extend type Query { Filter by category, used for paginated requests to pull more data per category """ category: String - ): ControlGroupConnection! + ): ControlGroupConnection! @deprecated(reason: "use controlsGroupBy with field: CATEGORY") } type ControlCategory { diff --git a/internal/graphapi/schema/groupby.graphql b/internal/graphapi/schema/groupby.graphql new file mode 100644 index 0000000000..8833034c7f --- /dev/null +++ b/internal/graphapi/schema/groupby.graphql @@ -0,0 +1,287 @@ +directive @goEnum(value: String) on ENUM_VALUE +""" +GroupByOrderField is the field group by buckets are ordered by +""" +enum GroupByOrderField @goModel(model: "github.com/theopenlane/gqlgen-plugins/groupby.OrderField") { + COUNT @goEnum(value: "github.com/theopenlane/gqlgen-plugins/groupby.OrderFieldCount") + KEY @goEnum(value: "github.com/theopenlane/gqlgen-plugins/groupby.OrderFieldKey") +} +""" +GroupByOrder is the ordering of group by buckets +""" +input GroupByOrder @goModel(model: "github.com/theopenlane/gqlgen-plugins/groupby.Order") { + """ + The ordering direction + """ + direction: OrderDirection! = DESC + """ + The field by which to order the groups + """ + field: GroupByOrderField! = COUNT +} +""" +ControlGroupByField are the Control fields that can be grouped on +""" +enum ControlGroupByField { + CATEGORY + SUBCATEGORY +} +""" +ControlGroupByBucket is a group of controls sharing the same value for the grouped field +""" +type ControlGroupByBucket @goModel(model: "github.com/theopenlane/gqlgen-plugins/groupby.Bucket") { + """ + The grouped value, null when the rows have no value + """ + key: String + """ + The number of controls in the group + """ + count: Int! + """ + The controls in the group + """ + controls(after: Cursor, first: Int, before: Cursor, last: Int, orderBy: [ControlOrder!]): ControlConnection! @goField(forceResolver: true) +} +""" +ControlGroupByEdge is a Control group by bucket with its pagination cursor +""" +type ControlGroupByEdge @goModel(model: "github.com/theopenlane/gqlgen-plugins/groupby.Edge") { + """ + The bucket at the end of the edge + """ + node: ControlGroupByBucket! + """ + A cursor for use in pagination + """ + cursor: Cursor! +} +""" +ControlGroupByConnection is a paginated list of Control group by buckets +""" +type ControlGroupByConnection @goModel(model: "github.com/theopenlane/gqlgen-plugins/groupby.Connection") { + """ + A list of edges + """ + edges: [ControlGroupByEdge!]! + """ + Information to aid in pagination + """ + pageInfo: PageInfo! + """ + Identifies the total count of groups in the connection + """ + totalCount: Int! +} +""" +SubcontrolGroupByField are the Subcontrol fields that can be grouped on +""" +enum SubcontrolGroupByField { + CATEGORY + SUBCATEGORY +} +""" +SubcontrolGroupByBucket is a group of subcontrols sharing the same value for the grouped field +""" +type SubcontrolGroupByBucket @goModel(model: "github.com/theopenlane/gqlgen-plugins/groupby.Bucket") { + """ + The grouped value, null when the rows have no value + """ + key: String + """ + The number of subcontrols in the group + """ + count: Int! + """ + The subcontrols in the group + """ + subcontrols(after: Cursor, first: Int, before: Cursor, last: Int, orderBy: [SubcontrolOrder!]): SubcontrolConnection! @goField(forceResolver: true) +} +""" +SubcontrolGroupByEdge is a Subcontrol group by bucket with its pagination cursor +""" +type SubcontrolGroupByEdge @goModel(model: "github.com/theopenlane/gqlgen-plugins/groupby.Edge") { + """ + The bucket at the end of the edge + """ + node: SubcontrolGroupByBucket! + """ + A cursor for use in pagination + """ + cursor: Cursor! +} +""" +SubcontrolGroupByConnection is a paginated list of Subcontrol group by buckets +""" +type SubcontrolGroupByConnection @goModel(model: "github.com/theopenlane/gqlgen-plugins/groupby.Connection") { + """ + A list of edges + """ + edges: [SubcontrolGroupByEdge!]! + """ + Information to aid in pagination + """ + pageInfo: PageInfo! + """ + Identifies the total count of groups in the connection + """ + totalCount: Int! +} +""" +VulnerabilityGroupByField are the Vulnerability fields that can be grouped on +""" +enum VulnerabilityGroupByField { + VULNERABILITY_STATUS_NAME + EXTERNAL_OWNER_ID + CVE_ID + SOURCE + SEVERITY +} +""" +VulnerabilityGroupByBucket is a group of vulnerabilities sharing the same value for the grouped field +""" +type VulnerabilityGroupByBucket @goModel(model: "github.com/theopenlane/gqlgen-plugins/groupby.Bucket") { + """ + The grouped value, null when the rows have no value + """ + key: String + """ + The number of vulnerabilities in the group + """ + count: Int! + """ + The vulnerabilities in the group + """ + vulnerabilities(after: Cursor, first: Int, before: Cursor, last: Int, orderBy: [VulnerabilityOrder!]): VulnerabilityConnection! @goField(forceResolver: true) +} +""" +VulnerabilityGroupByEdge is a Vulnerability group by bucket with its pagination cursor +""" +type VulnerabilityGroupByEdge @goModel(model: "github.com/theopenlane/gqlgen-plugins/groupby.Edge") { + """ + The bucket at the end of the edge + """ + node: VulnerabilityGroupByBucket! + """ + A cursor for use in pagination + """ + cursor: Cursor! +} +""" +VulnerabilityGroupByConnection is a paginated list of Vulnerability group by buckets +""" +type VulnerabilityGroupByConnection @goModel(model: "github.com/theopenlane/gqlgen-plugins/groupby.Connection") { + """ + A list of edges + """ + edges: [VulnerabilityGroupByEdge!]! + """ + Information to aid in pagination + """ + pageInfo: PageInfo! + """ + Identifies the total count of groups in the connection + """ + totalCount: Int! +} +extend type Query { + """ + controlsGroupBy groups controls by a field and returns each group with its count and rows + """ + controlsGroupBy( + """ + The field to group by + """ + field: ControlGroupByField! + """ + Filtering options for controls included in the groups + """ + where: ControlWhereInput + """ + Ordering options for the groups, defaults to count descending + """ + orderBy: GroupByOrder + """ + Returns the groups that come after the specified cursor + """ + after: Cursor + """ + Returns the first _n_ groups + """ + first: Int + """ + Returns the groups that come before the specified cursor + """ + before: Cursor + """ + Returns the last _n_ groups + """ + last: Int + ): ControlGroupByConnection! + """ + subcontrolsGroupBy groups subcontrols by a field and returns each group with its count and rows + """ + subcontrolsGroupBy( + """ + The field to group by + """ + field: SubcontrolGroupByField! + """ + Filtering options for subcontrols included in the groups + """ + where: SubcontrolWhereInput + """ + Ordering options for the groups, defaults to count descending + """ + orderBy: GroupByOrder + """ + Returns the groups that come after the specified cursor + """ + after: Cursor + """ + Returns the first _n_ groups + """ + first: Int + """ + Returns the groups that come before the specified cursor + """ + before: Cursor + """ + Returns the last _n_ groups + """ + last: Int + ): SubcontrolGroupByConnection! + """ + vulnerabilitiesGroupBy groups vulnerabilities by a field and returns each group with its count and rows + """ + vulnerabilitiesGroupBy( + """ + The field to group by + """ + field: VulnerabilityGroupByField! + """ + Filtering options for vulnerabilities included in the groups + """ + where: VulnerabilityWhereInput + """ + Ordering options for the groups, defaults to count descending + """ + orderBy: GroupByOrder + """ + Returns the groups that come after the specified cursor + """ + after: Cursor + """ + Returns the first _n_ groups + """ + first: Int + """ + Returns the groups that come before the specified cursor + """ + before: Cursor + """ + Returns the last _n_ groups + """ + last: Int + ): VulnerabilityGroupByConnection! +} diff --git a/internal/graphapi/schema/vulnerability_summary.graphql b/internal/graphapi/schema/vulnerability_summary.graphql index 469a5fa5d8..28c8cf075f 100644 --- a/internal/graphapi/schema/vulnerability_summary.graphql +++ b/internal/graphapi/schema/vulnerability_summary.graphql @@ -43,5 +43,5 @@ extend type Query { Filtering options for vulnerabilities included in the summary. """ where: VulnerabilityWhereInput - ): VulnerabilitySummary! + ): VulnerabilitySummary! @deprecated(reason: "use vulnerabilitiesGroupBy with field: SEVERITY, SOURCE, or VULNERABILITY_STATUS_NAME") } diff --git a/internal/graphapi/testclient/graphclient.go b/internal/graphapi/testclient/graphclient.go index ffbf89f205..d4265241b2 100644 --- a/internal/graphapi/testclient/graphclient.go +++ b/internal/graphapi/testclient/graphclient.go @@ -10,6 +10,7 @@ import ( "github.com/gqlgo/gqlgenc/clientv2" "github.com/theopenlane/core/common/enums" "github.com/theopenlane/core/common/models" + "github.com/theopenlane/gqlgen-plugins/groupby" ) type TestGraphClient interface { @@ -127,6 +128,7 @@ type TestGraphClient interface { GetControlSubcategories(ctx context.Context, interceptors ...clientv2.RequestInterceptor) (*GetControlSubcategories, error) GetControlSubcategoriesWithFramework(ctx context.Context, where *ControlWhereInput, interceptors ...clientv2.RequestInterceptor) (*GetControlSubcategoriesWithFramework, error) UpdateControlComment(ctx context.Context, updateControlCommentID string, input UpdateNoteInput, interceptors ...clientv2.RequestInterceptor) (*UpdateControlComment, error) + GetControlsGroupBy(ctx context.Context, field ControlGroupByField, first *int64, last *int64, after *string, before *string, where *ControlWhereInput, orderBy *groupby.Order, rowsFirst *int64, rowsAfter *string, rowsOrderBy []*ControlOrder, interceptors ...clientv2.RequestInterceptor) (*GetControlsGroupBy, error) CreateBulkCSVControlImplementation(ctx context.Context, input graphql.Upload, interceptors ...clientv2.RequestInterceptor) (*CreateBulkCSVControlImplementation, error) CreateBulkControlImplementation(ctx context.Context, input []*CreateControlImplementationInput, interceptors ...clientv2.RequestInterceptor) (*CreateBulkControlImplementation, error) CreateControlImplementation(ctx context.Context, input CreateControlImplementationInput, interceptors ...clientv2.RequestInterceptor) (*CreateControlImplementation, error) @@ -739,6 +741,7 @@ type TestGraphClient interface { UpdateBulkVulnerability(ctx context.Context, ids []string, input UpdateVulnerabilityInput, interceptors ...clientv2.RequestInterceptor) (*UpdateBulkVulnerability, error) UpdateVulnerability(ctx context.Context, updateVulnerabilityID string, input UpdateVulnerabilityInput, interceptors ...clientv2.RequestInterceptor) (*UpdateVulnerability, error) UpdateVulnerabilityComment(ctx context.Context, updateVulnerabilityCommentID string, input UpdateNoteInput, noteFiles []*graphql.Upload, interceptors ...clientv2.RequestInterceptor) (*UpdateVulnerabilityComment, error) + GetVulnerabilitiesGroupBy(ctx context.Context, field VulnerabilityGroupByField, first *int64, last *int64, after *string, before *string, where *VulnerabilityWhereInput, orderBy *groupby.Order, rowsFirst *int64, rowsAfter *string, rowsOrderBy []*VulnerabilityOrder, interceptors ...clientv2.RequestInterceptor) (*GetVulnerabilitiesGroupBy, error) DeleteWebauthn(ctx context.Context, deleteWebauthnID string, interceptors ...clientv2.RequestInterceptor) (*DeleteWebauthn, error) GetAllWebauthns(ctx context.Context, interceptors ...clientv2.RequestInterceptor) (*GetAllWebauthns, error) ApproveWorkflowAssignment(ctx context.Context, id string, interceptors ...clientv2.RequestInterceptor) (*ApproveWorkflowAssignment, error) @@ -26888,6 +26891,220 @@ func (t *UpdateControlComment_UpdateControlComment) GetControl() *UpdateControlC return &t.Control } +type GetControlsGroupBy_ControlsGroupBy_PageInfo struct { + EndCursor *string "json:\"endCursor,omitempty\" graphql:\"endCursor\"" + HasNextPage bool "json:\"hasNextPage\" graphql:\"hasNextPage\"" + HasPreviousPage bool "json:\"hasPreviousPage\" graphql:\"hasPreviousPage\"" + StartCursor *string "json:\"startCursor,omitempty\" graphql:\"startCursor\"" +} + +func (t *GetControlsGroupBy_ControlsGroupBy_PageInfo) GetEndCursor() *string { + if t == nil { + t = &GetControlsGroupBy_ControlsGroupBy_PageInfo{} + } + return t.EndCursor +} +func (t *GetControlsGroupBy_ControlsGroupBy_PageInfo) GetHasNextPage() bool { + if t == nil { + t = &GetControlsGroupBy_ControlsGroupBy_PageInfo{} + } + return t.HasNextPage +} +func (t *GetControlsGroupBy_ControlsGroupBy_PageInfo) GetHasPreviousPage() bool { + if t == nil { + t = &GetControlsGroupBy_ControlsGroupBy_PageInfo{} + } + return t.HasPreviousPage +} +func (t *GetControlsGroupBy_ControlsGroupBy_PageInfo) GetStartCursor() *string { + if t == nil { + t = &GetControlsGroupBy_ControlsGroupBy_PageInfo{} + } + return t.StartCursor +} + +type GetControlsGroupBy_ControlsGroupBy_Edges_Node_Controls_PageInfo struct { + EndCursor *string "json:\"endCursor,omitempty\" graphql:\"endCursor\"" + HasNextPage bool "json:\"hasNextPage\" graphql:\"hasNextPage\"" + HasPreviousPage bool "json:\"hasPreviousPage\" graphql:\"hasPreviousPage\"" + StartCursor *string "json:\"startCursor,omitempty\" graphql:\"startCursor\"" +} + +func (t *GetControlsGroupBy_ControlsGroupBy_Edges_Node_Controls_PageInfo) GetEndCursor() *string { + if t == nil { + t = &GetControlsGroupBy_ControlsGroupBy_Edges_Node_Controls_PageInfo{} + } + return t.EndCursor +} +func (t *GetControlsGroupBy_ControlsGroupBy_Edges_Node_Controls_PageInfo) GetHasNextPage() bool { + if t == nil { + t = &GetControlsGroupBy_ControlsGroupBy_Edges_Node_Controls_PageInfo{} + } + return t.HasNextPage +} +func (t *GetControlsGroupBy_ControlsGroupBy_Edges_Node_Controls_PageInfo) GetHasPreviousPage() bool { + if t == nil { + t = &GetControlsGroupBy_ControlsGroupBy_Edges_Node_Controls_PageInfo{} + } + return t.HasPreviousPage +} +func (t *GetControlsGroupBy_ControlsGroupBy_Edges_Node_Controls_PageInfo) GetStartCursor() *string { + if t == nil { + t = &GetControlsGroupBy_ControlsGroupBy_Edges_Node_Controls_PageInfo{} + } + return t.StartCursor +} + +type GetControlsGroupBy_ControlsGroupBy_Edges_Node_Controls_Edges_Node struct { + Category *string "json:\"category,omitempty\" graphql:\"category\"" + ID string "json:\"id\" graphql:\"id\"" + OwnerID *string "json:\"ownerID,omitempty\" graphql:\"ownerID\"" + RefCode string "json:\"refCode\" graphql:\"refCode\"" + ReferenceFramework *string "json:\"referenceFramework,omitempty\" graphql:\"referenceFramework\"" + Subcategory *string "json:\"subcategory,omitempty\" graphql:\"subcategory\"" +} + +func (t *GetControlsGroupBy_ControlsGroupBy_Edges_Node_Controls_Edges_Node) GetCategory() *string { + if t == nil { + t = &GetControlsGroupBy_ControlsGroupBy_Edges_Node_Controls_Edges_Node{} + } + return t.Category +} +func (t *GetControlsGroupBy_ControlsGroupBy_Edges_Node_Controls_Edges_Node) GetID() string { + if t == nil { + t = &GetControlsGroupBy_ControlsGroupBy_Edges_Node_Controls_Edges_Node{} + } + return t.ID +} +func (t *GetControlsGroupBy_ControlsGroupBy_Edges_Node_Controls_Edges_Node) GetOwnerID() *string { + if t == nil { + t = &GetControlsGroupBy_ControlsGroupBy_Edges_Node_Controls_Edges_Node{} + } + return t.OwnerID +} +func (t *GetControlsGroupBy_ControlsGroupBy_Edges_Node_Controls_Edges_Node) GetRefCode() string { + if t == nil { + t = &GetControlsGroupBy_ControlsGroupBy_Edges_Node_Controls_Edges_Node{} + } + return t.RefCode +} +func (t *GetControlsGroupBy_ControlsGroupBy_Edges_Node_Controls_Edges_Node) GetReferenceFramework() *string { + if t == nil { + t = &GetControlsGroupBy_ControlsGroupBy_Edges_Node_Controls_Edges_Node{} + } + return t.ReferenceFramework +} +func (t *GetControlsGroupBy_ControlsGroupBy_Edges_Node_Controls_Edges_Node) GetSubcategory() *string { + if t == nil { + t = &GetControlsGroupBy_ControlsGroupBy_Edges_Node_Controls_Edges_Node{} + } + return t.Subcategory +} + +type GetControlsGroupBy_ControlsGroupBy_Edges_Node_Controls_Edges struct { + Node *GetControlsGroupBy_ControlsGroupBy_Edges_Node_Controls_Edges_Node "json:\"node,omitempty\" graphql:\"node\"" +} + +func (t *GetControlsGroupBy_ControlsGroupBy_Edges_Node_Controls_Edges) GetNode() *GetControlsGroupBy_ControlsGroupBy_Edges_Node_Controls_Edges_Node { + if t == nil { + t = &GetControlsGroupBy_ControlsGroupBy_Edges_Node_Controls_Edges{} + } + return t.Node +} + +type GetControlsGroupBy_ControlsGroupBy_Edges_Node_Controls struct { + Edges []*GetControlsGroupBy_ControlsGroupBy_Edges_Node_Controls_Edges "json:\"edges,omitempty\" graphql:\"edges\"" + PageInfo GetControlsGroupBy_ControlsGroupBy_Edges_Node_Controls_PageInfo "json:\"pageInfo\" graphql:\"pageInfo\"" + TotalCount int64 "json:\"totalCount\" graphql:\"totalCount\"" +} + +func (t *GetControlsGroupBy_ControlsGroupBy_Edges_Node_Controls) GetEdges() []*GetControlsGroupBy_ControlsGroupBy_Edges_Node_Controls_Edges { + if t == nil { + t = &GetControlsGroupBy_ControlsGroupBy_Edges_Node_Controls{} + } + return t.Edges +} +func (t *GetControlsGroupBy_ControlsGroupBy_Edges_Node_Controls) GetPageInfo() *GetControlsGroupBy_ControlsGroupBy_Edges_Node_Controls_PageInfo { + if t == nil { + t = &GetControlsGroupBy_ControlsGroupBy_Edges_Node_Controls{} + } + return &t.PageInfo +} +func (t *GetControlsGroupBy_ControlsGroupBy_Edges_Node_Controls) GetTotalCount() int64 { + if t == nil { + t = &GetControlsGroupBy_ControlsGroupBy_Edges_Node_Controls{} + } + return t.TotalCount +} + +type GetControlsGroupBy_ControlsGroupBy_Edges_Node struct { + Controls GetControlsGroupBy_ControlsGroupBy_Edges_Node_Controls "json:\"controls\" graphql:\"controls\"" + Count int64 "json:\"count\" graphql:\"count\"" + Key *string "json:\"key,omitempty\" graphql:\"key\"" +} + +func (t *GetControlsGroupBy_ControlsGroupBy_Edges_Node) GetControls() *GetControlsGroupBy_ControlsGroupBy_Edges_Node_Controls { + if t == nil { + t = &GetControlsGroupBy_ControlsGroupBy_Edges_Node{} + } + return &t.Controls +} +func (t *GetControlsGroupBy_ControlsGroupBy_Edges_Node) GetCount() int64 { + if t == nil { + t = &GetControlsGroupBy_ControlsGroupBy_Edges_Node{} + } + return t.Count +} +func (t *GetControlsGroupBy_ControlsGroupBy_Edges_Node) GetKey() *string { + if t == nil { + t = &GetControlsGroupBy_ControlsGroupBy_Edges_Node{} + } + return t.Key +} + +type GetControlsGroupBy_ControlsGroupBy_Edges struct { + Cursor string "json:\"cursor\" graphql:\"cursor\"" + Node GetControlsGroupBy_ControlsGroupBy_Edges_Node "json:\"node\" graphql:\"node\"" +} + +func (t *GetControlsGroupBy_ControlsGroupBy_Edges) GetCursor() string { + if t == nil { + t = &GetControlsGroupBy_ControlsGroupBy_Edges{} + } + return t.Cursor +} +func (t *GetControlsGroupBy_ControlsGroupBy_Edges) GetNode() *GetControlsGroupBy_ControlsGroupBy_Edges_Node { + if t == nil { + t = &GetControlsGroupBy_ControlsGroupBy_Edges{} + } + return &t.Node +} + +type GetControlsGroupBy_ControlsGroupBy struct { + Edges []*GetControlsGroupBy_ControlsGroupBy_Edges "json:\"edges\" graphql:\"edges\"" + PageInfo GetControlsGroupBy_ControlsGroupBy_PageInfo "json:\"pageInfo\" graphql:\"pageInfo\"" + TotalCount int64 "json:\"totalCount\" graphql:\"totalCount\"" +} + +func (t *GetControlsGroupBy_ControlsGroupBy) GetEdges() []*GetControlsGroupBy_ControlsGroupBy_Edges { + if t == nil { + t = &GetControlsGroupBy_ControlsGroupBy{} + } + return t.Edges +} +func (t *GetControlsGroupBy_ControlsGroupBy) GetPageInfo() *GetControlsGroupBy_ControlsGroupBy_PageInfo { + if t == nil { + t = &GetControlsGroupBy_ControlsGroupBy{} + } + return &t.PageInfo +} +func (t *GetControlsGroupBy_ControlsGroupBy) GetTotalCount() int64 { + if t == nil { + t = &GetControlsGroupBy_ControlsGroupBy{} + } + return t.TotalCount +} + type CreateBulkCSVControlImplementation_CreateBulkCSVControlImplementation_ControlImplementations_Controls_Edges_Node struct { ID string "json:\"id\" graphql:\"id\"" RefCode string "json:\"refCode\" graphql:\"refCode\"" @@ -163059,6 +163276,724 @@ func (t *UpdateVulnerabilityComment_UpdateVulnerabilityComment) GetVulnerability return &t.Vulnerability } +type GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_PageInfo struct { + EndCursor *string "json:\"endCursor,omitempty\" graphql:\"endCursor\"" + HasNextPage bool "json:\"hasNextPage\" graphql:\"hasNextPage\"" + HasPreviousPage bool "json:\"hasPreviousPage\" graphql:\"hasPreviousPage\"" + StartCursor *string "json:\"startCursor,omitempty\" graphql:\"startCursor\"" +} + +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_PageInfo) GetEndCursor() *string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_PageInfo{} + } + return t.EndCursor +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_PageInfo) GetHasNextPage() bool { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_PageInfo{} + } + return t.HasNextPage +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_PageInfo) GetHasPreviousPage() bool { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_PageInfo{} + } + return t.HasPreviousPage +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_PageInfo) GetStartCursor() *string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_PageInfo{} + } + return t.StartCursor +} + +type GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_PageInfo struct { + EndCursor *string "json:\"endCursor,omitempty\" graphql:\"endCursor\"" + HasNextPage bool "json:\"hasNextPage\" graphql:\"hasNextPage\"" + HasPreviousPage bool "json:\"hasPreviousPage\" graphql:\"hasPreviousPage\"" + StartCursor *string "json:\"startCursor,omitempty\" graphql:\"startCursor\"" +} + +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_PageInfo) GetEndCursor() *string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_PageInfo{} + } + return t.EndCursor +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_PageInfo) GetHasNextPage() bool { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_PageInfo{} + } + return t.HasNextPage +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_PageInfo) GetHasPreviousPage() bool { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_PageInfo{} + } + return t.HasPreviousPage +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_PageInfo) GetStartCursor() *string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_PageInfo{} + } + return t.StartCursor +} + +type GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node struct { + AssignedTo *string "json:\"assignedTo,omitempty\" graphql:\"assignedTo\"" + AssignedToGroupID *string "json:\"assignedToGroupID,omitempty\" graphql:\"assignedToGroupID\"" + AssignedToIdentityHolderID *string "json:\"assignedToIdentityHolderID,omitempty\" graphql:\"assignedToIdentityHolderID\"" + AssignedToUserID *string "json:\"assignedToUserID,omitempty\" graphql:\"assignedToUserID\"" + AutoDismissedAt *models.DateTime "json:\"autoDismissedAt,omitempty\" graphql:\"autoDismissedAt\"" + Blocking *bool "json:\"blocking,omitempty\" graphql:\"blocking\"" + Category *string "json:\"category,omitempty\" graphql:\"category\"" + CreatedAt *time.Time "json:\"createdAt,omitempty\" graphql:\"createdAt\"" + CreatedBy *string "json:\"createdBy,omitempty\" graphql:\"createdBy\"" + CveID *string "json:\"cveID,omitempty\" graphql:\"cveID\"" + CweIds []string "json:\"cweIds,omitempty\" graphql:\"cweIds\"" + DependencyScope *string "json:\"dependencyScope,omitempty\" graphql:\"dependencyScope\"" + Description *string "json:\"description,omitempty\" graphql:\"description\"" + DiscoveredAt *models.DateTime "json:\"discoveredAt,omitempty\" graphql:\"discoveredAt\"" + DismissedAt *models.DateTime "json:\"dismissedAt,omitempty\" graphql:\"dismissedAt\"" + DismissedComment *string "json:\"dismissedComment,omitempty\" graphql:\"dismissedComment\"" + DismissedReason *string "json:\"dismissedReason,omitempty\" graphql:\"dismissedReason\"" + DisplayID string "json:\"displayID\" graphql:\"displayID\"" + DisplayName *string "json:\"displayName,omitempty\" graphql:\"displayName\"" + EnvironmentID *string "json:\"environmentID,omitempty\" graphql:\"environmentID\"" + EnvironmentName *string "json:\"environmentName,omitempty\" graphql:\"environmentName\"" + Exploitability *float64 "json:\"exploitability,omitempty\" graphql:\"exploitability\"" + ExternalID string "json:\"externalID\" graphql:\"externalID\"" + ExternalOwnerID *string "json:\"externalOwnerID,omitempty\" graphql:\"externalOwnerID\"" + ExternalURI *string "json:\"externalURI,omitempty\" graphql:\"externalURI\"" + FirstPatchedVersion *string "json:\"firstPatchedVersion,omitempty\" graphql:\"firstPatchedVersion\"" + FixAvailable *bool "json:\"fixAvailable,omitempty\" graphql:\"fixAvailable\"" + FixedAt *models.DateTime "json:\"fixedAt,omitempty\" graphql:\"fixedAt\"" + ID string "json:\"id\" graphql:\"id\"" + Impact *float64 "json:\"impact,omitempty\" graphql:\"impact\"" + Impacts []string "json:\"impacts,omitempty\" graphql:\"impacts\"" + IntegrationRunID *string "json:\"integrationRunID,omitempty\" graphql:\"integrationRunID\"" + InternalNotes *string "json:\"internalNotes,omitempty\" graphql:\"internalNotes\"" + InternalOwner *string "json:\"internalOwner,omitempty\" graphql:\"internalOwner\"" + InternalOwnerGroupID *string "json:\"internalOwnerGroupID,omitempty\" graphql:\"internalOwnerGroupID\"" + InternalOwnerIdentityHolderID *string "json:\"internalOwnerIdentityHolderID,omitempty\" graphql:\"internalOwnerIdentityHolderID\"" + InternalOwnerUserID *string "json:\"internalOwnerUserID,omitempty\" graphql:\"internalOwnerUserID\"" + ManagedBy *string "json:\"managedBy,omitempty\" graphql:\"managedBy\"" + ManifestPath *string "json:\"manifestPath,omitempty\" graphql:\"manifestPath\"" + Metadata map[string]any "json:\"metadata,omitempty\" graphql:\"metadata\"" + Open *bool "json:\"open,omitempty\" graphql:\"open\"" + OwnerID *string "json:\"ownerID,omitempty\" graphql:\"ownerID\"" + PackageEcosystem *string "json:\"packageEcosystem,omitempty\" graphql:\"packageEcosystem\"" + PackageName *string "json:\"packageName,omitempty\" graphql:\"packageName\"" + Priority *string "json:\"priority,omitempty\" graphql:\"priority\"" + Production *bool "json:\"production,omitempty\" graphql:\"production\"" + Public *bool "json:\"public,omitempty\" graphql:\"public\"" + PublishedAt *models.DateTime "json:\"publishedAt,omitempty\" graphql:\"publishedAt\"" + RawPayload map[string]any "json:\"rawPayload,omitempty\" graphql:\"rawPayload\"" + References []string "json:\"references,omitempty\" graphql:\"references\"" + RemediationSLA *int64 "json:\"remediationSLA,omitempty\" graphql:\"remediationSLA\"" + ReviewedBy *string "json:\"reviewedBy,omitempty\" graphql:\"reviewedBy\"" + ReviewedByGroupID *string "json:\"reviewedByGroupID,omitempty\" graphql:\"reviewedByGroupID\"" + ReviewedByIdentityHolderID *string "json:\"reviewedByIdentityHolderID,omitempty\" graphql:\"reviewedByIdentityHolderID\"" + ReviewedByUserID *string "json:\"reviewedByUserID,omitempty\" graphql:\"reviewedByUserID\"" + ScopeID *string "json:\"scopeID,omitempty\" graphql:\"scopeID\"" + ScopeName *string "json:\"scopeName,omitempty\" graphql:\"scopeName\"" + Score *float64 "json:\"score,omitempty\" graphql:\"score\"" + SecurityLevel *enums.SecurityLevel "json:\"securityLevel,omitempty\" graphql:\"securityLevel\"" + Severity *string "json:\"severity,omitempty\" graphql:\"severity\"" + Source *string "json:\"source,omitempty\" graphql:\"source\"" + SourceDefinitionID *string "json:\"sourceDefinitionID,omitempty\" graphql:\"sourceDefinitionID\"" + SourceDefinitionVersion *string "json:\"sourceDefinitionVersion,omitempty\" graphql:\"sourceDefinitionVersion\"" + SourceInstanceID *string "json:\"sourceInstanceID,omitempty\" graphql:\"sourceInstanceID\"" + SourceUpdatedAt *models.DateTime "json:\"sourceUpdatedAt,omitempty\" graphql:\"sourceUpdatedAt\"" + Summary *string "json:\"summary,omitempty\" graphql:\"summary\"" + SystemInternalID *string "json:\"systemInternalID,omitempty\" graphql:\"systemInternalID\"" + SystemOwned *bool "json:\"systemOwned,omitempty\" graphql:\"systemOwned\"" + Tags []string "json:\"tags,omitempty\" graphql:\"tags\"" + UpdatedAt *time.Time "json:\"updatedAt,omitempty\" graphql:\"updatedAt\"" + UpdatedBy *string "json:\"updatedBy,omitempty\" graphql:\"updatedBy\"" + UpdatedByImpersonator *string "json:\"updatedByImpersonator,omitempty\" graphql:\"updatedByImpersonator\"" + Validated *bool "json:\"validated,omitempty\" graphql:\"validated\"" + Vector *string "json:\"vector,omitempty\" graphql:\"vector\"" + VulnerabilityStatusID *string "json:\"vulnerabilityStatusID,omitempty\" graphql:\"vulnerabilityStatusID\"" + VulnerabilityStatusName *string "json:\"vulnerabilityStatusName,omitempty\" graphql:\"vulnerabilityStatusName\"" + VulnerableVersionRange *string "json:\"vulnerableVersionRange,omitempty\" graphql:\"vulnerableVersionRange\"" + WorkflowEligibleMarker *bool "json:\"workflowEligibleMarker,omitempty\" graphql:\"workflowEligibleMarker\"" +} + +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetAssignedTo() *string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.AssignedTo +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetAssignedToGroupID() *string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.AssignedToGroupID +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetAssignedToIdentityHolderID() *string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.AssignedToIdentityHolderID +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetAssignedToUserID() *string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.AssignedToUserID +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetAutoDismissedAt() *models.DateTime { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.AutoDismissedAt +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetBlocking() *bool { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.Blocking +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetCategory() *string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.Category +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetCreatedAt() *time.Time { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.CreatedAt +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetCreatedBy() *string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.CreatedBy +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetCveID() *string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.CveID +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetCweIds() []string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.CweIds +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetDependencyScope() *string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.DependencyScope +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetDescription() *string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.Description +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetDiscoveredAt() *models.DateTime { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.DiscoveredAt +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetDismissedAt() *models.DateTime { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.DismissedAt +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetDismissedComment() *string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.DismissedComment +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetDismissedReason() *string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.DismissedReason +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetDisplayID() string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.DisplayID +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetDisplayName() *string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.DisplayName +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetEnvironmentID() *string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.EnvironmentID +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetEnvironmentName() *string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.EnvironmentName +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetExploitability() *float64 { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.Exploitability +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetExternalID() string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.ExternalID +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetExternalOwnerID() *string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.ExternalOwnerID +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetExternalURI() *string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.ExternalURI +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetFirstPatchedVersion() *string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.FirstPatchedVersion +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetFixAvailable() *bool { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.FixAvailable +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetFixedAt() *models.DateTime { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.FixedAt +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetID() string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.ID +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetImpact() *float64 { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.Impact +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetImpacts() []string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.Impacts +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetIntegrationRunID() *string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.IntegrationRunID +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetInternalNotes() *string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.InternalNotes +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetInternalOwner() *string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.InternalOwner +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetInternalOwnerGroupID() *string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.InternalOwnerGroupID +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetInternalOwnerIdentityHolderID() *string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.InternalOwnerIdentityHolderID +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetInternalOwnerUserID() *string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.InternalOwnerUserID +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetManagedBy() *string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.ManagedBy +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetManifestPath() *string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.ManifestPath +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetMetadata() map[string]any { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.Metadata +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetOpen() *bool { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.Open +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetOwnerID() *string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.OwnerID +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetPackageEcosystem() *string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.PackageEcosystem +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetPackageName() *string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.PackageName +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetPriority() *string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.Priority +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetProduction() *bool { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.Production +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetPublic() *bool { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.Public +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetPublishedAt() *models.DateTime { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.PublishedAt +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetRawPayload() map[string]any { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.RawPayload +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetReferences() []string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.References +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetRemediationSLA() *int64 { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.RemediationSLA +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetReviewedBy() *string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.ReviewedBy +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetReviewedByGroupID() *string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.ReviewedByGroupID +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetReviewedByIdentityHolderID() *string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.ReviewedByIdentityHolderID +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetReviewedByUserID() *string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.ReviewedByUserID +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetScopeID() *string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.ScopeID +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetScopeName() *string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.ScopeName +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetScore() *float64 { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.Score +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetSecurityLevel() *enums.SecurityLevel { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.SecurityLevel +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetSeverity() *string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.Severity +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetSource() *string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.Source +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetSourceDefinitionID() *string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.SourceDefinitionID +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetSourceDefinitionVersion() *string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.SourceDefinitionVersion +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetSourceInstanceID() *string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.SourceInstanceID +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetSourceUpdatedAt() *models.DateTime { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.SourceUpdatedAt +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetSummary() *string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.Summary +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetSystemInternalID() *string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.SystemInternalID +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetSystemOwned() *bool { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.SystemOwned +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetTags() []string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.Tags +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetUpdatedAt() *time.Time { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.UpdatedAt +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetUpdatedBy() *string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.UpdatedBy +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetUpdatedByImpersonator() *string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.UpdatedByImpersonator +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetValidated() *bool { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.Validated +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetVector() *string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.Vector +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetVulnerabilityStatusID() *string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.VulnerabilityStatusID +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetVulnerabilityStatusName() *string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.VulnerabilityStatusName +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetVulnerableVersionRange() *string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.VulnerableVersionRange +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node) GetWorkflowEligibleMarker() *bool { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node{} + } + return t.WorkflowEligibleMarker +} + +type GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges struct { + Node *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node "json:\"node,omitempty\" graphql:\"node\"" +} + +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges) GetNode() *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges_Node { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges{} + } + return t.Node +} + +type GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities struct { + Edges []*GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges "json:\"edges,omitempty\" graphql:\"edges\"" + PageInfo GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_PageInfo "json:\"pageInfo\" graphql:\"pageInfo\"" + TotalCount int64 "json:\"totalCount\" graphql:\"totalCount\"" +} + +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities) GetEdges() []*GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_Edges { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities{} + } + return t.Edges +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities) GetPageInfo() *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities_PageInfo { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities{} + } + return &t.PageInfo +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities) GetTotalCount() int64 { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities{} + } + return t.TotalCount +} + +type GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node struct { + Count int64 "json:\"count\" graphql:\"count\"" + Key *string "json:\"key,omitempty\" graphql:\"key\"" + Vulnerabilities GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities "json:\"vulnerabilities\" graphql:\"vulnerabilities\"" +} + +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node) GetCount() int64 { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node{} + } + return t.Count +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node) GetKey() *string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node{} + } + return t.Key +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node) GetVulnerabilities() *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node_Vulnerabilities { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node{} + } + return &t.Vulnerabilities +} + +type GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges struct { + Cursor string "json:\"cursor\" graphql:\"cursor\"" + Node GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node "json:\"node\" graphql:\"node\"" +} + +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges) GetCursor() string { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges{} + } + return t.Cursor +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges) GetNode() *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges_Node { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges{} + } + return &t.Node +} + +type GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy struct { + Edges []*GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges "json:\"edges\" graphql:\"edges\"" + PageInfo GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_PageInfo "json:\"pageInfo\" graphql:\"pageInfo\"" + TotalCount int64 "json:\"totalCount\" graphql:\"totalCount\"" +} + +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy) GetEdges() []*GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_Edges { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy{} + } + return t.Edges +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy) GetPageInfo() *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy_PageInfo { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy{} + } + return &t.PageInfo +} +func (t *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy) GetTotalCount() int64 { + if t == nil { + t = &GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy{} + } + return t.TotalCount +} + type DeleteWebauthn_DeleteWebauthn struct { DeletedID string "json:\"deletedID\" graphql:\"deletedID\"" } @@ -177269,6 +178204,17 @@ func (t *UpdateControlComment) GetUpdateControlComment() *UpdateControlComment_U return &t.UpdateControlComment } +type GetControlsGroupBy struct { + ControlsGroupBy GetControlsGroupBy_ControlsGroupBy "json:\"controlsGroupBy\" graphql:\"controlsGroupBy\"" +} + +func (t *GetControlsGroupBy) GetControlsGroupBy() *GetControlsGroupBy_ControlsGroupBy { + if t == nil { + t = &GetControlsGroupBy{} + } + return &t.ControlsGroupBy +} + type CreateBulkCSVControlImplementation struct { CreateBulkCSVControlImplementation CreateBulkCSVControlImplementation_CreateBulkCSVControlImplementation "json:\"createBulkCSVControlImplementation\" graphql:\"createBulkCSVControlImplementation\"" } @@ -184008,6 +184954,17 @@ func (t *UpdateVulnerabilityComment) GetUpdateVulnerabilityComment() *UpdateVuln return &t.UpdateVulnerabilityComment } +type GetVulnerabilitiesGroupBy struct { + VulnerabilitiesGroupBy GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy "json:\"vulnerabilitiesGroupBy\" graphql:\"vulnerabilitiesGroupBy\"" +} + +func (t *GetVulnerabilitiesGroupBy) GetVulnerabilitiesGroupBy() *GetVulnerabilitiesGroupBy_VulnerabilitiesGroupBy { + if t == nil { + t = &GetVulnerabilitiesGroupBy{} + } + return &t.VulnerabilitiesGroupBy +} + type DeleteWebauthn struct { DeleteWebauthn DeleteWebauthn_DeleteWebauthn "json:\"deleteWebauthn\" graphql:\"deleteWebauthn\"" } @@ -191157,6 +192114,71 @@ func (c *Client) UpdateControlComment(ctx context.Context, updateControlCommentI return &res, nil } +const GetControlsGroupByDocument = `query GetControlsGroupBy ($field: ControlGroupByField!, $first: Int, $last: Int, $after: Cursor, $before: Cursor, $where: ControlWhereInput, $orderBy: GroupByOrder, $rowsFirst: Int, $rowsAfter: Cursor, $rowsOrderBy: [ControlOrder!]) { + controlsGroupBy(field: $field, first: $first, last: $last, after: $after, before: $before, where: $where, orderBy: $orderBy) { + totalCount + pageInfo { + startCursor + endCursor + hasPreviousPage + hasNextPage + } + edges { + cursor + node { + key + count + controls(first: $rowsFirst, after: $rowsAfter, orderBy: $rowsOrderBy) { + totalCount + pageInfo { + startCursor + endCursor + hasPreviousPage + hasNextPage + } + edges { + node { + id + refCode + category + subcategory + referenceFramework + ownerID + } + } + } + } + } + } +} +` + +func (c *Client) GetControlsGroupBy(ctx context.Context, field ControlGroupByField, first *int64, last *int64, after *string, before *string, where *ControlWhereInput, orderBy *groupby.Order, rowsFirst *int64, rowsAfter *string, rowsOrderBy []*ControlOrder, interceptors ...clientv2.RequestInterceptor) (*GetControlsGroupBy, error) { + vars := map[string]any{ + "field": field, + "first": first, + "last": last, + "after": after, + "before": before, + "where": where, + "orderBy": orderBy, + "rowsFirst": rowsFirst, + "rowsAfter": rowsAfter, + "rowsOrderBy": rowsOrderBy, + } + + var res GetControlsGroupBy + if err := c.Client.Post(ctx, "GetControlsGroupBy", GetControlsGroupByDocument, &res, vars, interceptors...); err != nil { + if c.Client.ParseDataWhenErrors { + return &res, err + } + + return nil, err + } + + return &res, nil +} + const CreateBulkCSVControlImplementationDocument = `mutation CreateBulkCSVControlImplementation ($input: Upload!) { createBulkCSVControlImplementation(input: $input) { controlImplementations { @@ -225657,6 +226679,143 @@ func (c *Client) UpdateVulnerabilityComment(ctx context.Context, updateVulnerabi return &res, nil } +const GetVulnerabilitiesGroupByDocument = `query GetVulnerabilitiesGroupBy ($field: VulnerabilityGroupByField!, $first: Int, $last: Int, $after: Cursor, $before: Cursor, $where: VulnerabilityWhereInput, $orderBy: GroupByOrder, $rowsFirst: Int, $rowsAfter: Cursor, $rowsOrderBy: [VulnerabilityOrder!]) { + vulnerabilitiesGroupBy(field: $field, first: $first, last: $last, after: $after, before: $before, where: $where, orderBy: $orderBy) { + totalCount + pageInfo { + startCursor + endCursor + hasPreviousPage + hasNextPage + } + edges { + cursor + node { + key + count + vulnerabilities(first: $rowsFirst, after: $rowsAfter, orderBy: $rowsOrderBy) { + totalCount + pageInfo { + startCursor + endCursor + hasPreviousPage + hasNextPage + } + edges { + node { + assignedTo + assignedToGroupID + assignedToIdentityHolderID + assignedToUserID + autoDismissedAt + blocking + category + createdAt + createdBy + cveID + cweIds + dependencyScope + description + discoveredAt + dismissedAt + dismissedComment + dismissedReason + displayID + displayName + environmentID + environmentName + exploitability + externalID + externalOwnerID + externalURI + firstPatchedVersion + fixAvailable + fixedAt + id + impact + impacts + integrationRunID + internalNotes + internalOwner + internalOwnerGroupID + internalOwnerIdentityHolderID + internalOwnerUserID + managedBy + manifestPath + metadata + open + ownerID + packageEcosystem + packageName + priority + production + public + publishedAt + rawPayload + references + remediationSLA + reviewedBy + reviewedByGroupID + reviewedByIdentityHolderID + reviewedByUserID + scopeID + scopeName + score + securityLevel + severity + source + sourceDefinitionID + sourceDefinitionVersion + sourceInstanceID + sourceUpdatedAt + summary + systemInternalID + systemOwned + tags + updatedAt + updatedBy + updatedByImpersonator + validated + vector + vulnerabilityStatusID + vulnerabilityStatusName + vulnerableVersionRange + workflowEligibleMarker + } + } + } + } + } + } +} +` + +func (c *Client) GetVulnerabilitiesGroupBy(ctx context.Context, field VulnerabilityGroupByField, first *int64, last *int64, after *string, before *string, where *VulnerabilityWhereInput, orderBy *groupby.Order, rowsFirst *int64, rowsAfter *string, rowsOrderBy []*VulnerabilityOrder, interceptors ...clientv2.RequestInterceptor) (*GetVulnerabilitiesGroupBy, error) { + vars := map[string]any{ + "field": field, + "first": first, + "last": last, + "after": after, + "before": before, + "where": where, + "orderBy": orderBy, + "rowsFirst": rowsFirst, + "rowsAfter": rowsAfter, + "rowsOrderBy": rowsOrderBy, + } + + var res GetVulnerabilitiesGroupBy + if err := c.Client.Post(ctx, "GetVulnerabilitiesGroupBy", GetVulnerabilitiesGroupByDocument, &res, vars, interceptors...); err != nil { + if c.Client.ParseDataWhenErrors { + return &res, err + } + + return nil, err + } + + return &res, nil +} + const DeleteWebauthnDocument = `mutation DeleteWebauthn ($deleteWebauthnId: ID!) { deleteWebauthn(id: $deleteWebauthnId) { deletedID @@ -229206,6 +230365,7 @@ var DocumentOperationNames = map[string]string{ GetControlSubcategoriesDocument: "GetControlSubcategories", GetControlSubcategoriesWithFrameworkDocument: "GetControlSubcategoriesWithFramework", UpdateControlCommentDocument: "UpdateControlComment", + GetControlsGroupByDocument: "GetControlsGroupBy", CreateBulkCSVControlImplementationDocument: "CreateBulkCSVControlImplementation", CreateBulkControlImplementationDocument: "CreateBulkControlImplementation", CreateControlImplementationDocument: "CreateControlImplementation", @@ -229818,6 +230978,7 @@ var DocumentOperationNames = map[string]string{ UpdateBulkVulnerabilityDocument: "UpdateBulkVulnerability", UpdateVulnerabilityDocument: "UpdateVulnerability", UpdateVulnerabilityCommentDocument: "UpdateVulnerabilityComment", + GetVulnerabilitiesGroupByDocument: "GetVulnerabilitiesGroupBy", DeleteWebauthnDocument: "DeleteWebauthn", GetAllWebauthnsDocument: "GetAllWebauthns", ApproveWorkflowAssignmentDocument: "ApproveWorkflowAssignment", diff --git a/internal/graphapi/testclient/models.go b/internal/graphapi/testclient/models.go index 53f6457dde..2867538a75 100644 --- a/internal/graphapi/testclient/models.go +++ b/internal/graphapi/testclient/models.go @@ -51006,6 +51006,62 @@ func (e ControlCategoryOrderField) MarshalJSON() ([]byte, error) { return buf.Bytes(), nil } +// ControlGroupByField are the Control fields that can be grouped on +type ControlGroupByField string + +const ( + ControlGroupByFieldCategory ControlGroupByField = "CATEGORY" + ControlGroupByFieldSubcategory ControlGroupByField = "SUBCATEGORY" +) + +var AllControlGroupByField = []ControlGroupByField{ + ControlGroupByFieldCategory, + ControlGroupByFieldSubcategory, +} + +func (e ControlGroupByField) IsValid() bool { + switch e { + case ControlGroupByFieldCategory, ControlGroupByFieldSubcategory: + return true + } + return false +} + +func (e ControlGroupByField) String() string { + return string(e) +} + +func (e *ControlGroupByField) UnmarshalGQL(v any) error { + str, ok := v.(string) + if !ok { + return fmt.Errorf("enums must be strings") + } + + *e = ControlGroupByField(str) + if !e.IsValid() { + return fmt.Errorf("%s is not a valid ControlGroupByField", str) + } + return nil +} + +func (e ControlGroupByField) MarshalGQL(w io.Writer) { + _, _ = fmt.Fprint(w, strconv.Quote(e.String())) +} + +func (e *ControlGroupByField) UnmarshalJSON(b []byte) error { + s, err := strconv.Unquote(string(b)) + if err != nil { + return err + } + return e.UnmarshalGQL(s) +} + +func (e ControlGroupByField) MarshalJSON() ([]byte, error) { + var buf bytes.Buffer + e.MarshalGQL(&buf) + return buf.Bytes(), nil +} + // Properties by which ControlImplementation connections can be ordered. type ControlImplementationOrderField string @@ -54731,6 +54787,62 @@ func (e StandardOrderField) MarshalJSON() ([]byte, error) { return buf.Bytes(), nil } +// SubcontrolGroupByField are the Subcontrol fields that can be grouped on +type SubcontrolGroupByField string + +const ( + SubcontrolGroupByFieldCategory SubcontrolGroupByField = "CATEGORY" + SubcontrolGroupByFieldSubcategory SubcontrolGroupByField = "SUBCATEGORY" +) + +var AllSubcontrolGroupByField = []SubcontrolGroupByField{ + SubcontrolGroupByFieldCategory, + SubcontrolGroupByFieldSubcategory, +} + +func (e SubcontrolGroupByField) IsValid() bool { + switch e { + case SubcontrolGroupByFieldCategory, SubcontrolGroupByFieldSubcategory: + return true + } + return false +} + +func (e SubcontrolGroupByField) String() string { + return string(e) +} + +func (e *SubcontrolGroupByField) UnmarshalGQL(v any) error { + str, ok := v.(string) + if !ok { + return fmt.Errorf("enums must be strings") + } + + *e = SubcontrolGroupByField(str) + if !e.IsValid() { + return fmt.Errorf("%s is not a valid SubcontrolGroupByField", str) + } + return nil +} + +func (e SubcontrolGroupByField) MarshalGQL(w io.Writer) { + _, _ = fmt.Fprint(w, strconv.Quote(e.String())) +} + +func (e *SubcontrolGroupByField) UnmarshalJSON(b []byte) error { + s, err := strconv.Unquote(string(b)) + if err != nil { + return err + } + return e.UnmarshalGQL(s) +} + +func (e SubcontrolGroupByField) MarshalJSON() ([]byte, error) { + var buf bytes.Buffer + e.MarshalGQL(&buf) + return buf.Bytes(), nil +} + // Properties by which Subcontrol connections can be ordered. type SubcontrolOrderField string @@ -55997,6 +56109,68 @@ func (e VendorScoringConfigOrderField) MarshalJSON() ([]byte, error) { return buf.Bytes(), nil } +// VulnerabilityGroupByField are the Vulnerability fields that can be grouped on +type VulnerabilityGroupByField string + +const ( + VulnerabilityGroupByFieldVulnerabilityStatusName VulnerabilityGroupByField = "VULNERABILITY_STATUS_NAME" + VulnerabilityGroupByFieldExternalOwnerID VulnerabilityGroupByField = "EXTERNAL_OWNER_ID" + VulnerabilityGroupByFieldCveID VulnerabilityGroupByField = "CVE_ID" + VulnerabilityGroupByFieldSource VulnerabilityGroupByField = "SOURCE" + VulnerabilityGroupByFieldSeverity VulnerabilityGroupByField = "SEVERITY" +) + +var AllVulnerabilityGroupByField = []VulnerabilityGroupByField{ + VulnerabilityGroupByFieldVulnerabilityStatusName, + VulnerabilityGroupByFieldExternalOwnerID, + VulnerabilityGroupByFieldCveID, + VulnerabilityGroupByFieldSource, + VulnerabilityGroupByFieldSeverity, +} + +func (e VulnerabilityGroupByField) IsValid() bool { + switch e { + case VulnerabilityGroupByFieldVulnerabilityStatusName, VulnerabilityGroupByFieldExternalOwnerID, VulnerabilityGroupByFieldCveID, VulnerabilityGroupByFieldSource, VulnerabilityGroupByFieldSeverity: + return true + } + return false +} + +func (e VulnerabilityGroupByField) String() string { + return string(e) +} + +func (e *VulnerabilityGroupByField) UnmarshalGQL(v any) error { + str, ok := v.(string) + if !ok { + return fmt.Errorf("enums must be strings") + } + + *e = VulnerabilityGroupByField(str) + if !e.IsValid() { + return fmt.Errorf("%s is not a valid VulnerabilityGroupByField", str) + } + return nil +} + +func (e VulnerabilityGroupByField) MarshalGQL(w io.Writer) { + _, _ = fmt.Fprint(w, strconv.Quote(e.String())) +} + +func (e *VulnerabilityGroupByField) UnmarshalJSON(b []byte) error { + s, err := strconv.Unquote(string(b)) + if err != nil { + return err + } + return e.UnmarshalGQL(s) +} + +func (e VulnerabilityGroupByField) MarshalJSON() ([]byte, error) { + var buf bytes.Buffer + e.MarshalGQL(&buf) + return buf.Bytes(), nil +} + // Properties by which Vulnerability connections can be ordered. type VulnerabilityOrderField string diff --git a/internal/graphapi/vulnerability_test.go b/internal/graphapi/vulnerability_test.go index cf1d6ea13d..d59e265b46 100644 --- a/internal/graphapi/vulnerability_test.go +++ b/internal/graphapi/vulnerability_test.go @@ -6,7 +6,9 @@ import ( th "github.com/theopenlane/core/v2/internal/graphapi/testharness" + "entgo.io/contrib/entgql" "github.com/samber/lo" + "github.com/theopenlane/gqlgen-plugins/groupby" "gotest.tools/v3/assert" is "gotest.tools/v3/assert/cmp" @@ -16,13 +18,14 @@ import ( "github.com/theopenlane/core/v2/internal/graphapi/testclient" ) -func createVulnerability(t *testing.T, ctx context.Context, displayName string) *testclient.CreateVulnerability_CreateVulnerability_Vulnerability { +func createVulnerability(t *testing.T, ctx context.Context, displayName string, cveID *string) *testclient.CreateVulnerability_CreateVulnerability_Vulnerability { t.Helper() resp, err := suite.Client.API.CreateVulnerability(ctx, testclient.CreateVulnerabilityInput{ DisplayName: &displayName, ExternalID: "vuln-" + ulids.New().String(), ExternalOwnerID: lo.ToPtr("external-owner"), + CveID: cveID, }) assert.NilError(t, err) assert.Assert(t, resp != nil) @@ -153,9 +156,9 @@ func TestMutationCreateVulnerability(t *testing.T) { } func TestMutationUpdateVulnerability(t *testing.T) { - vuln := createVulnerability(t, th.SharedTestUser1.UserCtx, "Update Vulnerability") + vuln := createVulnerability(t, th.SharedTestUser1.UserCtx, "Update Vulnerability", nil) - anotherOrgVuln := createVulnerability(t, th.SharedTestUser2.UserCtx, "Unauthorized Update Vulnerability") + anotherOrgVuln := createVulnerability(t, th.SharedTestUser2.UserCtx, "Unauthorized Update Vulnerability", nil) testCases := []struct { name string @@ -354,3 +357,124 @@ func TestQueryVulnerabilitiesOrderByScore(t *testing.T) { (&th.Cleanup[*generated.VulnerabilityDeleteOne]{Client: suite.Client.DB.Vulnerability, IDs: ids}).MustDelete(th.SharedTestUser1.UserCtx, t) } + +func TestQueryVulnerabilitiesGroupByCVE(t *testing.T) { + token := "group-by-cve-" + ulids.New().String() + cveA := "CVE-" + token + "-A" + cveB := "CVE-" + token + "-B" + + ids := []string{ + createVulnerability(t, th.SharedTestUser1.UserCtx, token, &cveA).ID, + createVulnerability(t, th.SharedTestUser1.UserCtx, token, &cveA).ID, + createVulnerability(t, th.SharedTestUser1.UserCtx, token, &cveA).ID, + createVulnerability(t, th.SharedTestUser1.UserCtx, token, &cveB).ID, + createVulnerability(t, th.SharedTestUser1.UserCtx, token, nil).ID, + createVulnerability(t, th.SharedTestUser1.UserCtx, token, nil).ID, + } + + anotherOrgVuln := createVulnerability(t, th.SharedTestUser2.UserCtx, token, &cveA) + + t.Cleanup(func() { + (&th.Cleanup[*generated.VulnerabilityDeleteOne]{Client: suite.Client.DB.Vulnerability, IDs: ids}).MustDelete(th.SharedTestUser1.UserCtx, t) + (&th.Cleanup[*generated.VulnerabilityDeleteOne]{Client: suite.Client.DB.Vulnerability, ID: anotherOrgVuln.ID}).MustDelete(th.SharedTestUser2.UserCtx, t) + }) + + where := &testclient.VulnerabilityWhereInput{DisplayName: &token} + rowsFirst := int64(10) + + t.Run("groups by count descending with the rows of each group", func(t *testing.T) { + resp, err := suite.Client.API.GetVulnerabilitiesGroupBy(th.SharedTestUser1.UserCtx, testclient.VulnerabilityGroupByFieldCveID,nil, nil, nil, nil, where, nil, &rowsFirst, nil, nil) + assert.NilError(t, err) + assert.Assert(t, resp != nil) + + groups := resp.VulnerabilitiesGroupBy + assert.Check(t, is.Equal(int64(3), groups.TotalCount)) + assert.Check(t, !groups.PageInfo.HasNextPage) + expected := []struct { + key *string + count int64 + }{ + {key: &cveA, count: 3}, + {key: nil, count: 2}, + {key: &cveB, count: 1}, + } + + assert.Assert(t, is.Len(groups.Edges, len(expected))) + + for i, want := range expected { + assert.Check(t, is.DeepEqual(want.key, groups.Edges[i].Node.Key)) + assert.Check(t, is.Equal(want.count, groups.Edges[i].Node.Count)) + } + + for _, edge := range groups.Edges { + rows := edge.Node.Vulnerabilities + assert.Check(t, is.Equal(edge.Node.Count, rows.TotalCount)) + assert.Check(t, is.Len(rows.Edges, int(edge.Node.Count))) + + for _, row := range rows.Edges { + assert.Assert(t, row.Node != nil) + assert.Check(t, is.Equal(lo.FromPtr(edge.Node.Key), lo.FromPtr(row.Node.CveID))) + assert.Check(t, is.Contains(ids, row.Node.ID)) + assert.Check(t, row.Node.ID != anotherOrgVuln.ID) + } + } + }) + + t.Run("paginates the groups", func(t *testing.T) { + first := int64(1) + + page1, err := suite.Client.API.GetVulnerabilitiesGroupBy(th.SharedTestUser1.UserCtx, testclient.VulnerabilityGroupByFieldCveID,&first, nil, nil, nil, where, nil, nil, nil, nil) + assert.NilError(t, err) + assert.Assert(t, page1 != nil) + assert.Assert(t, is.Len(page1.VulnerabilitiesGroupBy.Edges, 1)) + assert.Check(t, is.DeepEqual(&cveA, page1.VulnerabilitiesGroupBy.Edges[0].Node.Key)) + assert.Check(t, is.Equal(int64(3), page1.VulnerabilitiesGroupBy.Edges[0].Node.Count)) + assert.Check(t, page1.VulnerabilitiesGroupBy.PageInfo.HasNextPage) + assert.Assert(t, page1.VulnerabilitiesGroupBy.PageInfo.EndCursor != nil) + + page2, err := suite.Client.API.GetVulnerabilitiesGroupBy(th.SharedTestUser1.UserCtx, testclient.VulnerabilityGroupByFieldCveID,&first, nil, page1.VulnerabilitiesGroupBy.PageInfo.EndCursor, nil, where, nil, nil, nil, nil) + assert.NilError(t, err) + assert.Assert(t, page2 != nil) + assert.Assert(t, is.Len(page2.VulnerabilitiesGroupBy.Edges, 1)) + assert.Check(t, page2.VulnerabilitiesGroupBy.Edges[0].Node.Key == nil) + assert.Check(t, is.Equal(int64(2), page2.VulnerabilitiesGroupBy.Edges[0].Node.Count)) + assert.Check(t, page2.VulnerabilitiesGroupBy.PageInfo.HasNextPage) + }) + + t.Run("orders groups by key", func(t *testing.T) { + orderBy := &groupby.Order{Field: groupby.OrderFieldKey, Direction: entgql.OrderDirectionAsc} + + resp, err := suite.Client.API.GetVulnerabilitiesGroupBy(th.SharedTestUser1.UserCtx, testclient.VulnerabilityGroupByFieldCveID,nil, nil, nil, nil, where, orderBy, nil, nil, nil) + assert.NilError(t, err) + assert.Assert(t, resp != nil) + expected := []struct { + key *string + count int64 + }{ + {key: nil, count: 2}, + {key: &cveA, count: 3}, + {key: &cveB, count: 1}, + } + + assert.Assert(t, is.Len(resp.VulnerabilitiesGroupBy.Edges, len(expected))) + + for i, want := range expected { + assert.Check(t, is.DeepEqual(want.key, resp.VulnerabilitiesGroupBy.Edges[i].Node.Key)) + assert.Check(t, is.Equal(want.count, resp.VulnerabilitiesGroupBy.Edges[i].Node.Count)) + } + }) + + t.Run("only returns the other organization's matching CVE", func(t *testing.T) { + resp, err := suite.Client.API.GetVulnerabilitiesGroupBy(th.SharedTestUser2.UserCtx, testclient.VulnerabilityGroupByFieldCveID,nil, nil, nil, nil, where, nil, &rowsFirst, nil, nil) + assert.NilError(t, err) + assert.Assert(t, resp != nil) + + groups := resp.VulnerabilitiesGroupBy + assert.Check(t, is.Equal(int64(1), groups.TotalCount)) + assert.Assert(t, is.Len(groups.Edges, 1)) + assert.Check(t, is.DeepEqual(&cveA, groups.Edges[0].Node.Key)) + assert.Check(t, is.Equal(int64(1), groups.Edges[0].Node.Count)) + assert.Assert(t, is.Len(groups.Edges[0].Node.Vulnerabilities.Edges, 1)) + assert.Check(t, is.Equal(anotherOrgVuln.ID, groups.Edges[0].Node.Vulnerabilities.Edges[0].Node.ID)) + }) +}