package console_v1 // 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 version v0.17.90 import ( "context" "encoding/json" "errors" "github.com/vikstrous/dataloadgen" "go.gearno.de/kit/log" "go.probo.inc/probo/pkg/cookiebanner" "go.probo.inc/probo/pkg/coredata" "go.probo.inc/probo/pkg/page" "go.probo.inc/probo/pkg/probo" "go.probo.inc/probo/pkg/server/api/console/v1/dataloader" "go.probo.inc/probo/pkg/server/api/console/v1/schema" "go.probo.inc/probo/pkg/server/api/console/v1/types" "go.probo.inc/probo/pkg/server/gqlutils" "go.probo.inc/probo/pkg/validator" ) // Organization is the resolver for the organization field. func (r *cookieBannerResolver) Organization(ctx context.Context, obj *types.CookieBanner) (*types.Organization, error) { if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet); err != nil { return nil, err } loaders := dataloader.FromContext(ctx) organization, err := loaders.Organization.Load(ctx, obj.Organization.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) || errors.Is(err, dataloadgen.ErrNotFound) { return nil, gqlutils.NotFound(ctx, err) } r.logger.ErrorCtx(ctx, "cannot get organization", log.Error(err)) return nil, gqlutils.Internal(ctx) } return types.NewOrganization(organization), nil } // Categories is the resolver for the categories field. func (r *cookieBannerResolver) Categories(ctx context.Context, obj *types.CookieBanner, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.CookieCategoryOrderBy, filter *types.CookieCategoryFilter) (*types.CookieCategoryConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionCookieCategoryList); err != nil { return nil, err } pageOrderBy := page.OrderBy[coredata.CookieCategoryOrderField]{ Field: coredata.CookieCategoryOrderFieldRank, Direction: page.OrderDirectionAsc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.CookieCategoryOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) scope := coredata.NewScopeFromObjectID(obj.ID) var excludeKind *coredata.CookieCategoryKind if filter != nil { excludeKind = filter.ExcludeKind } cdFilter := coredata.NewCookieCategoryFilter(excludeKind) categories, err := r.cookieBanner.ListCategoriesForBanner(ctx, scope, obj.ID, cursor, cdFilter) if err != nil { r.logger.ErrorCtx(ctx, "cannot list cookie categories", log.Error(err)) return nil, gqlutils.Internal(ctx) } p := page.NewPage(categories, cursor) return types.NewCookieCategoryConnectionWithFilter(p, r, obj.ID, cdFilter), nil } // Translations is the resolver for the translations field. func (r *cookieBannerResolver) Translations(ctx context.Context, obj *types.CookieBanner) ([]*types.CookieBannerTranslation, error) { if err := r.authorize(ctx, obj.ID, probo.ActionCookieBannerGet); err != nil { return nil, err } scope := coredata.NewScopeFromObjectID(obj.ID) translations, err := r.cookieBanner.ListCookieBannerTranslations(ctx, scope, obj.ID) if err != nil { r.logger.ErrorCtx(ctx, "cannot list cookie banner translations", log.Error(err)) return nil, gqlutils.Internal(ctx) } result := make([]*types.CookieBannerTranslation, len(translations)) for i, t := range translations { result[i] = types.NewCookieBannerTranslation(t) } return result, nil } // LatestVersion is the resolver for the latestVersion field. func (r *cookieBannerResolver) LatestVersion(ctx context.Context, obj *types.CookieBanner) (*types.CookieBannerVersion, error) { if err := r.authorize(ctx, obj.ID, probo.ActionCookieBannerVersionList); err != nil { return nil, err } scope := coredata.NewScopeFromObjectID(obj.ID) cursor := &page.Cursor[coredata.CookieBannerVersionOrderField]{ Size: 1, Position: page.Head, OrderBy: page.OrderBy[coredata.CookieBannerVersionOrderField]{ Field: coredata.CookieBannerVersionOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, }, } versions, err := r.cookieBanner.ListCookieBannerVersionsForBanner(ctx, scope, obj.ID, cursor) if err != nil { r.logger.ErrorCtx(ctx, "cannot load latest cookie banner version", log.Error(err)) return nil, gqlutils.Internal(ctx) } if len(versions) == 0 { return nil, nil } v := versions[0] return &types.CookieBannerVersion{ ID: v.ID, Version: v.Version, State: string(v.State), CreatedAt: v.CreatedAt, UpdatedAt: v.UpdatedAt, }, nil } // ConsentRecords is the resolver for the consentRecords field. func (r *cookieBannerResolver) ConsentRecords(ctx context.Context, obj *types.CookieBanner, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.CookieConsentRecordOrderBy, filter *types.CookieConsentRecordFilter) (*types.CookieConsentRecordConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionCookieConsentRecordList); err != nil { return nil, err } pageOrderBy := page.OrderBy[coredata.CookieConsentRecordOrderField]{ Field: coredata.CookieConsentRecordOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.CookieConsentRecordOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) scope := coredata.NewScopeFromObjectID(obj.ID) var ( action *coredata.CookieConsentAction visitorID *string version *int ) if filter != nil { action = filter.Action visitorID = filter.VisitorID version = filter.Version } coredataFilter := coredata.NewCookieConsentRecordFilter(action, visitorID, version) records, err := r.cookieBanner.ListCookieConsentRecordsForBanner(ctx, scope, obj.ID, cursor, coredataFilter) if err != nil { r.logger.ErrorCtx(ctx, "cannot list consent records", log.Error(err)) return nil, gqlutils.Internal(ctx) } p := page.NewPage(records, cursor) return types.NewCookieConsentRecordConnection(p, r, obj.ID, coredataFilter), nil } // TrackerPatterns is the resolver for the trackerPatterns field. func (r *cookieBannerResolver) TrackerPatterns(ctx context.Context, obj *types.CookieBanner, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.TrackerPatternOrderBy, filter *types.TrackerPatternFilter) (*types.TrackerPatternConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionTrackerPatternList); err != nil { return nil, err } pageOrderBy := page.OrderBy[coredata.TrackerPatternOrderField]{ Field: coredata.TrackerPatternOrderFieldName, Direction: page.OrderDirectionAsc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.TrackerPatternOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) scope := coredata.NewScopeFromObjectID(obj.ID) coredataFilter := coredata.NewTrackerPatternFilter(nil, nil, nil) if filter != nil { coredataFilter = coredata.NewTrackerPatternFilter(nil, filter.CookieCategoryID, nil) coredataFilter = coredataFilter.WithQuery(filter.Query).WithSource(filter.Source).WithTrackerType(filter.TrackerType) } patterns, err := r.cookieBanner.ListTrackerPatternsForBanner(ctx, scope, obj.ID, cursor, coredataFilter) if err != nil { r.logger.ErrorCtx(ctx, "cannot list tracker patterns", log.Error(err)) return nil, gqlutils.Internal(ctx) } p := page.NewPage(patterns, cursor) return types.NewTrackerPatternConnectionWithFilter(p, r, obj.ID, filter), nil } // UncategorisedTrackerResources is the resolver for the uncategorisedTrackerResources field. func (r *cookieBannerResolver) UncategorisedTrackerResources(ctx context.Context, obj *types.CookieBanner, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.TrackerResourceOrderBy, filter *types.TrackerResourceFilter) (*types.TrackerResourceConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionTrackerResourceList); err != nil { return nil, err } pageOrderBy := page.OrderBy[coredata.TrackerResourceOrderField]{ Field: coredata.TrackerResourceOrderFieldLastDetectedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.TrackerResourceOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) scope := coredata.NewScopeFromObjectID(obj.ID) coredataFilter := coredata.NewTrackerResourceFilter(nil, nil) if filter != nil { coredataFilter = coredataFilter.WithQuery(filter.Query).WithResourceType(filter.Type) } resources, err := r.cookieBanner.ListUncategorisedTrackerResources(ctx, scope, obj.ID, cursor, coredataFilter) if err != nil { r.logger.ErrorCtx(ctx, "cannot list uncategorised tracker resources", log.Error(err)) return nil, gqlutils.Internal(ctx) } p := page.NewPage(resources, cursor) return types.NewTrackerResourceConnectionWithFilter(p, r, obj.ID, filter), nil } // Permission is the resolver for the permission field. func (r *cookieBannerResolver) Permission(ctx context.Context, obj *types.CookieBanner, action string) (bool, error) { return r.Resolver.Permission(ctx, obj, action) } // TotalCount is the resolver for the totalCount field. func (r *cookieBannerConnectionResolver) TotalCount(ctx context.Context, obj *types.CookieBannerConnection) (int, error) { if err := r.authorize(ctx, obj.ParentID, probo.ActionCookieBannerList); err != nil { return 0, err } scope := coredata.NewScopeFromObjectID(obj.ParentID) count, err := r.cookieBanner.CountCookieBannersForOrganization(ctx, scope, obj.ParentID, coredata.NewCookieBannerFilter(nil)) if err != nil { r.logger.ErrorCtx(ctx, "cannot count cookie banners", log.Error(err)) return 0, gqlutils.Internal(ctx) } return count, nil } // Categories is the resolver for the categories field. func (r *cookieBannerVersionResolver) Categories(ctx context.Context, obj *types.CookieBannerVersion) ([]*types.CookieBannerVersionCategory, error) { if err := r.authorize(ctx, obj.ID, probo.ActionCookieBannerVersionGet); err != nil { return nil, err } scope := coredata.NewScopeFromObjectID(obj.ID) version, err := r.cookieBanner.GetCookieBannerVersion(ctx, scope, obj.ID) if err != nil { r.logger.ErrorCtx(ctx, "cannot get cookie banner version", log.Error(err)) return nil, gqlutils.Internal(ctx) } snapshot, err := version.GetSnapshot() if err != nil { r.logger.ErrorCtx(ctx, "cannot get version snapshot", log.Error(err)) return nil, gqlutils.Internal(ctx) } categories := make([]*types.CookieBannerVersionCategory, len(snapshot.Categories)) for i, cat := range snapshot.Categories { cookies := make([]*types.CookieBannerVersionCookie, len(cat.Cookies)) for j, c := range cat.Cookies { cookies[j] = &types.CookieBannerVersionCookie{ Name: c.Name, MaxAgeSeconds: c.MaxAgeSeconds, Description: c.Description, } } categories[i] = &types.CookieBannerVersionCategory{ Name: cat.Name, Slug: cat.Slug, Description: cat.Description, Kind: cat.Kind, Cookies: cookies, } } return categories, nil } // CookieBanner is the resolver for the cookieBanner field. func (r *cookieCategoryResolver) CookieBanner(ctx context.Context, obj *types.CookieCategory) (*types.CookieBanner, error) { if obj.CookieBanner == nil { return nil, nil } if err := r.authorize(ctx, obj.CookieBanner.ID, probo.ActionCookieBannerGet); err != nil { return nil, err } loaders := dataloader.FromContext(ctx) banner, err := loaders.CookieBanner.Load(ctx, obj.CookieBanner.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) || errors.Is(err, dataloadgen.ErrNotFound) { return nil, nil } r.logger.ErrorCtx(ctx, "cannot get cookie banner", log.Error(err)) return nil, gqlutils.Internal(ctx) } return types.NewCookieBanner(banner), nil } // TrackerPatterns is the resolver for the trackerPatterns field. func (r *cookieCategoryResolver) TrackerPatterns(ctx context.Context, obj *types.CookieCategory, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.TrackerPatternOrderBy) (*types.TrackerPatternConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionTrackerPatternList); err != nil { return nil, err } pageOrderBy := page.OrderBy[coredata.TrackerPatternOrderField]{ Field: coredata.TrackerPatternOrderFieldCreatedAt, Direction: page.OrderDirectionAsc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.TrackerPatternOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) scope := coredata.NewScopeFromObjectID(obj.ID) patterns, err := r.cookieBanner.ListTrackerPatternsForCategory(ctx, scope, obj.ID, cursor) if err != nil { r.logger.ErrorCtx(ctx, "cannot list tracker patterns", log.Error(err)) return nil, gqlutils.Internal(ctx) } p := page.NewPage(patterns, cursor) return types.NewTrackerPatternConnection(p, r, obj.ID), nil } // TrackerResources is the resolver for the trackerResources field. func (r *cookieCategoryResolver) TrackerResources(ctx context.Context, obj *types.CookieCategory, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.TrackerResourceOrderBy) (*types.TrackerResourceConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionTrackerResourceList); err != nil { return nil, err } pageOrderBy := page.OrderBy[coredata.TrackerResourceOrderField]{ Field: coredata.TrackerResourceOrderFieldCreatedAt, Direction: page.OrderDirectionAsc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.TrackerResourceOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) scope := coredata.NewScopeFromObjectID(obj.ID) resources, err := r.cookieBanner.ListTrackerResourcesForCategory(ctx, scope, obj.ID, cursor) if err != nil { r.logger.ErrorCtx(ctx, "cannot list tracker resources", log.Error(err)) return nil, gqlutils.Internal(ctx) } p := page.NewPage(resources, cursor) return types.NewTrackerResourceConnection(p, r, obj.ID), nil } // Permission is the resolver for the permission field. func (r *cookieCategoryResolver) Permission(ctx context.Context, obj *types.CookieCategory, action string) (bool, error) { return r.Resolver.Permission(ctx, obj, action) } // TotalCount is the resolver for the totalCount field. func (r *cookieCategoryConnectionResolver) TotalCount(ctx context.Context, obj *types.CookieCategoryConnection) (int, error) { if err := r.authorize(ctx, obj.ParentID, probo.ActionCookieCategoryList); err != nil { return 0, err } scope := coredata.NewScopeFromObjectID(obj.ParentID) count, err := r.cookieBanner.CountCategoriesForBanner(ctx, scope, obj.ParentID, obj.Filter) if err != nil { r.logger.ErrorCtx(ctx, "cannot count cookie categories", log.Error(err)) return 0, gqlutils.Internal(ctx) } return count, nil } // TotalCount is the resolver for the totalCount field. func (r *detectedTrackerConnectionResolver) TotalCount(ctx context.Context, obj *types.DetectedTrackerConnection) (int, error) { scope := coredata.NewScopeFromObjectID(obj.ParentID) count, err := r.cookieBanner.CountDetectedTrackersByPatternID(ctx, scope, obj.ParentID) if err != nil { r.logger.ErrorCtx(ctx, "cannot count detected trackers", log.Error(err)) return 0, gqlutils.Internal(ctx) } return count, nil } // CreateCookieBanner is the resolver for the createCookieBanner field. func (r *mutationResolver) CreateCookieBanner(ctx context.Context, input types.CreateCookieBannerInput) (*types.CreateCookieBannerPayload, error) { if err := r.authorize(ctx, input.OrganizationID, probo.ActionCookieBannerCreate); err != nil { return nil, err } scope := coredata.NewScopeFromObjectID(input.OrganizationID) banner, err := r.cookieBanner.CreateCookieBanner( ctx, scope, cookiebanner.CreateCookieBannerRequest{ OrganizationID: input.OrganizationID, Name: input.Name, Origin: input.Origin, PrivacyPolicyURL: input.PrivacyPolicyURL, CookiePolicyURL: input.CookiePolicyURL, ConsentExpiryDays: input.ConsentExpiryDays, }, ) if err != nil { if errors.Is(err, cookiebanner.ErrOriginAlreadyInUse) { return nil, gqlutils.Conflict(ctx, err) } if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok { return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors) } r.logger.ErrorCtx(ctx, "cannot create cookie banner", log.Error(err)) return nil, gqlutils.Internal(ctx) } return &types.CreateCookieBannerPayload{ CookieBannerEdge: types.NewCookieBannerEdge(banner, coredata.CookieBannerOrderFieldCreatedAt), }, nil } // UpdateCookieBanner is the resolver for the updateCookieBanner field. func (r *mutationResolver) UpdateCookieBanner(ctx context.Context, input types.UpdateCookieBannerInput) (*types.UpdateCookieBannerPayload, error) { if err := r.authorize(ctx, input.CookieBannerID, probo.ActionCookieBannerUpdate); err != nil { return nil, err } scope := coredata.NewScopeFromObjectID(input.CookieBannerID) banner, err := r.cookieBanner.UpdateCookieBanner( ctx, scope, cookiebanner.UpdateCookieBannerRequest{ CookieBannerID: input.CookieBannerID, Name: input.Name, PrivacyPolicyURL: input.PrivacyPolicyURL, CookiePolicyURL: input.CookiePolicyURL, ConsentExpiryDays: input.ConsentExpiryDays, DefaultLanguage: input.DefaultLanguage, }, ) if err != nil { if errors.Is(err, cookiebanner.ErrBannerNotFound) { return nil, gqlutils.NotFound(ctx, err) } if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok { return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors) } r.logger.ErrorCtx(ctx, "cannot update cookie banner", log.Error(err)) return nil, gqlutils.Internal(ctx) } return &types.UpdateCookieBannerPayload{ CookieBanner: types.NewCookieBanner(banner), }, nil } // DeleteCookieBanner is the resolver for the deleteCookieBanner field. func (r *mutationResolver) DeleteCookieBanner(ctx context.Context, input types.DeleteCookieBannerInput) (*types.DeleteCookieBannerPayload, error) { if err := r.authorize(ctx, input.CookieBannerID, probo.ActionCookieBannerDelete); err != nil { return nil, err } scope := coredata.NewScopeFromObjectID(input.CookieBannerID) err := r.cookieBanner.DeleteCookieBanner(ctx, scope, input.CookieBannerID) if err != nil { if errors.Is(err, cookiebanner.ErrBannerNotFound) { return nil, gqlutils.NotFound(ctx, err) } r.logger.ErrorCtx(ctx, "cannot delete cookie banner", log.Error(err)) return nil, gqlutils.Internal(ctx) } return &types.DeleteCookieBannerPayload{ DeletedCookieBannerID: input.CookieBannerID, }, nil } // ActivateCookieBanner is the resolver for the activateCookieBanner field. func (r *mutationResolver) ActivateCookieBanner(ctx context.Context, input types.ActivateCookieBannerInput) (*types.ActivateCookieBannerPayload, error) { if err := r.authorize(ctx, input.CookieBannerID, probo.ActionCookieBannerActivate); err != nil { return nil, err } scope := coredata.NewScopeFromObjectID(input.CookieBannerID) banner, err := r.cookieBanner.ActivateCookieBanner(ctx, scope, input.CookieBannerID) if err != nil { if errors.Is(err, cookiebanner.ErrBannerNotFound) { return nil, gqlutils.NotFound(ctx, err) } if errors.Is(err, cookiebanner.ErrBannerAlreadyActive) { return nil, gqlutils.Conflict(ctx, err) } if errors.Is(err, cookiebanner.ErrOriginAlreadyInUse) { return nil, gqlutils.Conflict(ctx, err) } r.logger.ErrorCtx(ctx, "cannot activate cookie banner", log.Error(err)) return nil, gqlutils.Internal(ctx) } return &types.ActivateCookieBannerPayload{ CookieBanner: types.NewCookieBanner(banner), }, nil } // DeactivateCookieBanner is the resolver for the deactivateCookieBanner field. func (r *mutationResolver) DeactivateCookieBanner(ctx context.Context, input types.DeactivateCookieBannerInput) (*types.DeactivateCookieBannerPayload, error) { if err := r.authorize(ctx, input.CookieBannerID, probo.ActionCookieBannerDeactivate); err != nil { return nil, err } scope := coredata.NewScopeFromObjectID(input.CookieBannerID) banner, err := r.cookieBanner.DeactivateCookieBanner(ctx, scope, input.CookieBannerID) if err != nil { if errors.Is(err, cookiebanner.ErrBannerNotFound) { return nil, gqlutils.NotFound(ctx, err) } if errors.Is(err, cookiebanner.ErrBannerAlreadyInactive) { return nil, gqlutils.Conflict(ctx, err) } r.logger.ErrorCtx(ctx, "cannot deactivate cookie banner", log.Error(err)) return nil, gqlutils.Internal(ctx) } return &types.DeactivateCookieBannerPayload{ CookieBanner: types.NewCookieBanner(banner), }, nil } // PublishCookieBannerVersion is the resolver for the publishCookieBannerVersion field. func (r *mutationResolver) PublishCookieBannerVersion(ctx context.Context, input types.PublishCookieBannerVersionInput) (*types.PublishCookieBannerVersionPayload, error) { if err := r.authorize(ctx, input.CookieBannerID, probo.ActionCookieBannerVersionPublish); err != nil { return nil, err } scope := coredata.NewScopeFromObjectID(input.CookieBannerID) version, err := r.cookieBanner.PublishCookieBannerVersion(ctx, scope, input.CookieBannerID) if err != nil { if errors.Is(err, cookiebanner.ErrNoDraftVersion) { return nil, gqlutils.Conflict(ctx, err) } r.logger.ErrorCtx(ctx, "cannot publish cookie banner version", log.Error(err)) return nil, gqlutils.Internal(ctx) } banner, err := r.cookieBanner.GetCookieBanner(ctx, scope, input.CookieBannerID) if err != nil { r.logger.ErrorCtx(ctx, "cannot get cookie banner", log.Error(err)) return nil, gqlutils.Internal(ctx) } return &types.PublishCookieBannerVersionPayload{ CookieBannerVersion: &types.CookieBannerVersion{ ID: version.ID, Version: version.Version, State: string(version.State), CreatedAt: version.CreatedAt, UpdatedAt: version.UpdatedAt, }, CookieBanner: types.NewCookieBanner(banner), }, nil } // CreateCookieCategory is the resolver for the createCookieCategory field. func (r *mutationResolver) CreateCookieCategory(ctx context.Context, input types.CreateCookieCategoryInput) (*types.CreateCookieCategoryPayload, error) { if err := r.authorize(ctx, input.CookieBannerID, probo.ActionCookieCategoryCreate); err != nil { return nil, err } scope := coredata.NewScopeFromObjectID(input.CookieBannerID) category, err := r.cookieBanner.CreateCookieCategory( ctx, scope, cookiebanner.CreateCookieCategoryRequest{ CookieBannerID: input.CookieBannerID, Name: input.Name, Slug: input.Slug, Description: input.Description, Rank: input.Rank, }, ) if err != nil { if errors.Is(err, cookiebanner.ErrBannerNotFound) { return nil, gqlutils.NotFound(ctx, err) } if errors.Is(err, cookiebanner.ErrCategorySlugAlreadyExists) { return nil, gqlutils.Conflict(ctx, err) } if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok { return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors) } r.logger.ErrorCtx(ctx, "cannot create cookie category", log.Error(err)) return nil, gqlutils.Internal(ctx) } banner, err := r.cookieBanner.GetCookieBanner(ctx, scope, input.CookieBannerID) if err != nil { r.logger.ErrorCtx(ctx, "cannot get cookie banner", log.Error(err)) return nil, gqlutils.Internal(ctx) } return &types.CreateCookieCategoryPayload{ CookieCategoryEdge: types.NewCookieCategoryEdge(category, coredata.CookieCategoryOrderFieldRank), CookieBanner: types.NewCookieBanner(banner), }, nil } // UpdateCookieCategory is the resolver for the updateCookieCategory field. func (r *mutationResolver) UpdateCookieCategory(ctx context.Context, input types.UpdateCookieCategoryInput) (*types.UpdateCookieCategoryPayload, error) { if err := r.authorize(ctx, input.CookieCategoryID, probo.ActionCookieCategoryUpdate); err != nil { return nil, err } scope := coredata.NewScopeFromObjectID(input.CookieCategoryID) var gcmConsentTypes *[]string if input.GcmConsentTypes != nil { gcmConsentTypes = &input.GcmConsentTypes } category, err := r.cookieBanner.UpdateCookieCategory( ctx, scope, cookiebanner.UpdateCookieCategoryRequest{ CookieCategoryID: input.CookieCategoryID, Name: input.Name, Slug: input.Slug, Description: input.Description, GCMConsentTypes: gcmConsentTypes, PostHogConsent: input.PosthogConsent, }, ) if err != nil { if errors.Is(err, cookiebanner.ErrCategoryNotFound) { return nil, gqlutils.NotFound(ctx, err) } if errors.Is(err, cookiebanner.ErrCategorySlugAlreadyExists) { return nil, gqlutils.Conflict(ctx, err) } if errors.Is(err, cookiebanner.ErrPostHogConsentKindInvalid) { return nil, gqlutils.Invalid(ctx, err) } if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok { return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors) } r.logger.ErrorCtx(ctx, "cannot update cookie category", log.Error(err)) return nil, gqlutils.Internal(ctx) } bannerScope := coredata.NewScopeFromObjectID(category.CookieBannerID) banner, err := r.cookieBanner.GetCookieBanner(ctx, bannerScope, category.CookieBannerID) if err != nil { r.logger.ErrorCtx(ctx, "cannot get cookie banner", log.Error(err)) return nil, gqlutils.Internal(ctx) } return &types.UpdateCookieCategoryPayload{ CookieCategory: types.NewCookieCategory(category), CookieBanner: types.NewCookieBanner(banner), }, nil } // DeleteCookieCategory is the resolver for the deleteCookieCategory field. func (r *mutationResolver) DeleteCookieCategory(ctx context.Context, input types.DeleteCookieCategoryInput) (*types.DeleteCookieCategoryPayload, error) { if err := r.authorize(ctx, input.CookieCategoryID, probo.ActionCookieCategoryDelete); err != nil { return nil, err } scope := coredata.NewScopeFromObjectID(input.CookieCategoryID) category, err := r.cookieBanner.GetCookieCategory(ctx, scope, input.CookieCategoryID) if err != nil { if errors.Is(err, cookiebanner.ErrCategoryNotFound) { return nil, gqlutils.NotFound(ctx, err) } r.logger.ErrorCtx(ctx, "cannot get cookie category", log.Error(err)) return nil, gqlutils.Internal(ctx) } bannerID := category.CookieBannerID err = r.cookieBanner.DeleteCookieCategory(ctx, scope, input.CookieCategoryID) if err != nil { if errors.Is(err, cookiebanner.ErrCategoryNotFound) { return nil, gqlutils.NotFound(ctx, err) } if errors.Is(err, cookiebanner.ErrCannotDeleteSystemCategory) { return nil, gqlutils.Conflict(ctx, err) } r.logger.ErrorCtx(ctx, "cannot delete cookie category", log.Error(err)) return nil, gqlutils.Internal(ctx) } bannerScope := coredata.NewScopeFromObjectID(bannerID) banner, err := r.cookieBanner.GetCookieBanner(ctx, bannerScope, bannerID) if err != nil { r.logger.ErrorCtx(ctx, "cannot get cookie banner", log.Error(err)) return nil, gqlutils.Internal(ctx) } return &types.DeleteCookieCategoryPayload{ DeletedCookieCategoryID: input.CookieCategoryID, CookieBanner: types.NewCookieBanner(banner), }, nil } // ReorderCookieCategory is the resolver for the reorderCookieCategory field. func (r *mutationResolver) ReorderCookieCategory(ctx context.Context, input types.ReorderCookieCategoryInput) (*types.ReorderCookieCategoryPayload, error) { if err := r.authorize(ctx, input.CookieCategoryID, probo.ActionCookieCategoryUpdate); err != nil { return nil, err } scope := coredata.NewScopeFromObjectID(input.CookieCategoryID) banner, err := r.cookieBanner.ReorderCookieCategory( ctx, scope, cookiebanner.ReorderCookieCategoryRequest{ CookieCategoryID: input.CookieCategoryID, Rank: input.Rank, }, ) if err != nil { if errors.Is(err, cookiebanner.ErrCategoryNotFound) { return nil, gqlutils.NotFound(ctx, err) } if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok { return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors) } r.logger.ErrorCtx(ctx, "cannot reorder cookie category", log.Error(err)) return nil, gqlutils.Internal(ctx) } return &types.ReorderCookieCategoryPayload{ CookieBanner: types.NewCookieBanner(banner), }, nil } // UpsertCookieBannerTranslation is the resolver for the upsertCookieBannerTranslation field. func (r *mutationResolver) UpsertCookieBannerTranslation(ctx context.Context, input types.UpsertCookieBannerTranslationInput) (*types.UpsertCookieBannerTranslationPayload, error) { if err := r.authorize(ctx, input.CookieBannerID, probo.ActionCookieBannerUpdate); err != nil { return nil, err } scope := coredata.NewScopeFromObjectID(input.CookieBannerID) translation, err := r.cookieBanner.UpsertCookieBannerTranslation( ctx, scope, cookiebanner.UpsertCookieBannerTranslationRequest{ CookieBannerID: input.CookieBannerID, Language: input.Language, Translations: json.RawMessage(input.Translations), }, ) if err != nil { if errors.Is(err, cookiebanner.ErrBannerNotFound) { return nil, gqlutils.NotFound(ctx, err) } if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok { return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors) } r.logger.ErrorCtx(ctx, "cannot upsert cookie banner translation", log.Error(err)) return nil, gqlutils.Internal(ctx) } banner, err := r.cookieBanner.GetCookieBanner(ctx, scope, input.CookieBannerID) if err != nil { r.logger.ErrorCtx(ctx, "cannot load cookie banner", log.Error(err)) return nil, gqlutils.Internal(ctx) } return &types.UpsertCookieBannerTranslationPayload{ CookieBannerTranslation: types.NewCookieBannerTranslation(translation), CookieBanner: types.NewCookieBanner(banner), }, nil } // CreateTrackerPattern is the resolver for the createTrackerPattern field. func (r *mutationResolver) CreateTrackerPattern(ctx context.Context, input types.CreateTrackerPatternInput) (*types.CreateTrackerPatternPayload, error) { if err := r.authorize(ctx, input.CookieCategoryID, probo.ActionTrackerPatternCreate); err != nil { return nil, err } scope := coredata.NewScopeFromObjectID(input.CookieCategoryID) trackerType := coredata.TrackerTypeCookie if input.TrackerType != nil { trackerType = *input.TrackerType } var description string if input.Description != nil { description = *input.Description } pattern, err := r.cookieBanner.CreateTrackerPattern( ctx, scope, cookiebanner.CreateTrackerPatternRequest{ CookieCategoryID: input.CookieCategoryID, TrackerType: trackerType, Pattern: input.Pattern, MatchType: input.MatchType, DisplayName: input.DisplayName, MaxAgeSeconds: input.MaxAgeSeconds, Description: description, }, ) if err != nil { if errors.Is(err, cookiebanner.ErrPatternAlreadyExists) { return nil, gqlutils.Conflictf(ctx, "a pattern with this name already exists in this banner") } if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok { return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors) } r.logger.ErrorCtx(ctx, "cannot create tracker pattern", log.Error(err)) return nil, gqlutils.Internal(ctx) } bannerScope := coredata.NewScopeFromObjectID(pattern.CookieBannerID) banner, err := r.cookieBanner.GetCookieBanner(ctx, bannerScope, pattern.CookieBannerID) if err != nil { r.logger.ErrorCtx(ctx, "cannot get cookie banner", log.Error(err)) return nil, gqlutils.Internal(ctx) } return &types.CreateTrackerPatternPayload{ TrackerPatternEdge: types.NewTrackerPatternEdge(pattern, coredata.TrackerPatternOrderFieldCreatedAt), CookieBanner: types.NewCookieBanner(banner), }, nil } // UpdateTrackerPattern is the resolver for the updateTrackerPattern field. func (r *mutationResolver) UpdateTrackerPattern(ctx context.Context, input types.UpdateTrackerPatternInput) (*types.UpdateTrackerPatternPayload, error) { if err := r.authorize(ctx, input.TrackerPatternID, probo.ActionTrackerPatternUpdate); err != nil { return nil, err } scope := coredata.NewScopeFromObjectID(input.TrackerPatternID) pattern, err := r.cookieBanner.UpdateTrackerPattern( ctx, scope, cookiebanner.UpdateTrackerPatternRequest{ TrackerPatternID: input.TrackerPatternID, MaxAgeSeconds: gqlutils.UnwrapOmittable(input.MaxAgeSeconds), Description: input.Description, Excluded: input.Excluded, }, ) if err != nil { if errors.Is(err, cookiebanner.ErrTrackerPatternNotFound) { return nil, gqlutils.NotFound(ctx, err) } r.logger.ErrorCtx(ctx, "cannot update tracker pattern", log.Error(err)) return nil, gqlutils.Internal(ctx) } bannerScope := coredata.NewScopeFromObjectID(pattern.CookieBannerID) banner, err := r.cookieBanner.GetCookieBanner(ctx, bannerScope, pattern.CookieBannerID) if err != nil { r.logger.ErrorCtx(ctx, "cannot get cookie banner", log.Error(err)) return nil, gqlutils.Internal(ctx) } return &types.UpdateTrackerPatternPayload{ TrackerPattern: types.NewTrackerPatternNode(pattern), CookieBanner: types.NewCookieBanner(banner), }, nil } // DeleteTrackerPattern is the resolver for the deleteTrackerPattern field. func (r *mutationResolver) DeleteTrackerPattern(ctx context.Context, input types.DeleteTrackerPatternInput) (*types.DeleteTrackerPatternPayload, error) { if err := r.authorize(ctx, input.TrackerPatternID, probo.ActionTrackerPatternDelete); err != nil { return nil, err } scope := coredata.NewScopeFromObjectID(input.TrackerPatternID) pattern, err := r.cookieBanner.GetTrackerPattern(ctx, scope, input.TrackerPatternID) if err != nil { if errors.Is(err, cookiebanner.ErrTrackerPatternNotFound) { return nil, gqlutils.NotFound(ctx, err) } r.logger.ErrorCtx(ctx, "cannot get tracker pattern", log.Error(err)) return nil, gqlutils.Internal(ctx) } bannerID := pattern.CookieBannerID if err := r.cookieBanner.DeleteTrackerPattern(ctx, scope, input.TrackerPatternID); err != nil { if errors.Is(err, cookiebanner.ErrTrackerPatternNotFound) { return nil, gqlutils.NotFound(ctx, err) } r.logger.ErrorCtx(ctx, "cannot delete tracker pattern", log.Error(err)) return nil, gqlutils.Internal(ctx) } bannerScope := coredata.NewScopeFromObjectID(bannerID) banner, err := r.cookieBanner.GetCookieBanner(ctx, bannerScope, bannerID) if err != nil { r.logger.ErrorCtx(ctx, "cannot get cookie banner", log.Error(err)) return nil, gqlutils.Internal(ctx) } return &types.DeleteTrackerPatternPayload{ DeletedTrackerPatternID: input.TrackerPatternID, CookieBanner: types.NewCookieBanner(banner), }, nil } // MoveTrackerPatternToCategory is the resolver for the moveTrackerPatternToCategory field. func (r *mutationResolver) MoveTrackerPatternToCategory(ctx context.Context, input types.MoveTrackerPatternToCategoryInput) (*types.MoveTrackerPatternToCategoryPayload, error) { if err := r.authorize(ctx, input.TrackerPatternID, probo.ActionTrackerPatternUpdate); err != nil { return nil, err } if err := r.authorize(ctx, input.TargetCookieCategoryID, probo.ActionCookieCategoryUpdate); err != nil { return nil, err } scope := coredata.NewScopeFromObjectID(input.TrackerPatternID) result, err := r.cookieBanner.MoveTrackerPatternToCategory( ctx, scope, cookiebanner.MoveTrackerPatternToCategoryRequest{ TrackerPatternID: input.TrackerPatternID, TargetCookieCategoryID: input.TargetCookieCategoryID, }, ) if err != nil { switch { case errors.Is(err, cookiebanner.ErrCategoryNotFound): return nil, gqlutils.NotFound(ctx, err) case errors.Is(err, cookiebanner.ErrTrackerPatternNotFound): return nil, gqlutils.NotFound(ctx, err) case errors.Is(err, cookiebanner.ErrCategoriesBannerMismatch): return nil, gqlutils.NotFoundf(ctx, "tracker pattern or target category not found") default: r.logger.ErrorCtx(ctx, "cannot move tracker pattern to category", log.Error(err)) return nil, gqlutils.Internal(ctx) } } return &types.MoveTrackerPatternToCategoryPayload{ TrackerPattern: types.NewTrackerPatternNode(result.TrackerPattern), CookieBanner: types.NewCookieBanner(result.Banner), }, nil } // CreateTrackerResource is the resolver for the createTrackerResource field. func (r *mutationResolver) CreateTrackerResource(ctx context.Context, input types.CreateTrackerResourceInput) (*types.CreateTrackerResourcePayload, error) { if err := r.authorize(ctx, input.CookieCategoryID, probo.ActionTrackerResourceCreate); err != nil { return nil, err } scope := coredata.NewScopeFromObjectID(input.CookieCategoryID) var description string if input.Description != nil { description = *input.Description } resource, err := r.cookieBanner.CreateTrackerResource( ctx, scope, cookiebanner.CreateTrackerResourceRequest{ CookieCategoryID: input.CookieCategoryID, ResourceType: input.Type, Origin: input.Origin, Path: input.Path, DisplayName: input.DisplayName, Description: description, }, ) if err != nil { if errors.Is(err, cookiebanner.ErrResourceAlreadyExists) { return nil, gqlutils.Conflictf(ctx, "a resource with this origin and path already exists in this banner") } if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok { return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors) } r.logger.ErrorCtx(ctx, "cannot create tracker resource", log.Error(err)) return nil, gqlutils.Internal(ctx) } bannerScope := coredata.NewScopeFromObjectID(resource.CookieBannerID) banner, err := r.cookieBanner.GetCookieBanner(ctx, bannerScope, resource.CookieBannerID) if err != nil { r.logger.ErrorCtx(ctx, "cannot get cookie banner", log.Error(err)) return nil, gqlutils.Internal(ctx) } return &types.CreateTrackerResourcePayload{ TrackerResourceEdge: types.NewTrackerResourceEdge(resource, coredata.TrackerResourceOrderFieldCreatedAt), CookieBanner: types.NewCookieBanner(banner), }, nil } // UpdateTrackerResource is the resolver for the updateTrackerResource field. func (r *mutationResolver) UpdateTrackerResource(ctx context.Context, input types.UpdateTrackerResourceInput) (*types.UpdateTrackerResourcePayload, error) { if err := r.authorize(ctx, input.TrackerResourceID, probo.ActionTrackerResourceUpdate); err != nil { return nil, err } scope := coredata.NewScopeFromObjectID(input.TrackerResourceID) resource, err := r.cookieBanner.UpdateTrackerResource( ctx, scope, cookiebanner.UpdateTrackerResourceRequest{ TrackerResourceID: input.TrackerResourceID, DisplayName: input.DisplayName, Description: input.Description, Excluded: input.Excluded, }, ) if err != nil { if errors.Is(err, cookiebanner.ErrTrackerResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok { return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors) } r.logger.ErrorCtx(ctx, "cannot update tracker resource", log.Error(err)) return nil, gqlutils.Internal(ctx) } bannerScope := coredata.NewScopeFromObjectID(resource.CookieBannerID) banner, err := r.cookieBanner.GetCookieBanner(ctx, bannerScope, resource.CookieBannerID) if err != nil { r.logger.ErrorCtx(ctx, "cannot get cookie banner", log.Error(err)) return nil, gqlutils.Internal(ctx) } return &types.UpdateTrackerResourcePayload{ TrackerResource: types.NewTrackerResourceNode(resource), CookieBanner: types.NewCookieBanner(banner), }, nil } // DeleteTrackerResource is the resolver for the deleteTrackerResource field. func (r *mutationResolver) DeleteTrackerResource(ctx context.Context, input types.DeleteTrackerResourceInput) (*types.DeleteTrackerResourcePayload, error) { if err := r.authorize(ctx, input.TrackerResourceID, probo.ActionTrackerResourceDelete); err != nil { return nil, err } scope := coredata.NewScopeFromObjectID(input.TrackerResourceID) resource, err := r.cookieBanner.GetTrackerResource(ctx, scope, input.TrackerResourceID) if err != nil { if errors.Is(err, cookiebanner.ErrTrackerResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } r.logger.ErrorCtx(ctx, "cannot get tracker resource", log.Error(err)) return nil, gqlutils.Internal(ctx) } bannerID := resource.CookieBannerID if err := r.cookieBanner.DeleteTrackerResource(ctx, scope, input.TrackerResourceID); err != nil { if errors.Is(err, cookiebanner.ErrTrackerResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } r.logger.ErrorCtx(ctx, "cannot delete tracker resource", log.Error(err)) return nil, gqlutils.Internal(ctx) } bannerScope := coredata.NewScopeFromObjectID(bannerID) banner, err := r.cookieBanner.GetCookieBanner(ctx, bannerScope, bannerID) if err != nil { r.logger.ErrorCtx(ctx, "cannot get cookie banner", log.Error(err)) return nil, gqlutils.Internal(ctx) } return &types.DeleteTrackerResourcePayload{ DeletedTrackerResourceID: input.TrackerResourceID, CookieBanner: types.NewCookieBanner(banner), }, nil } // MoveTrackerResourceToCategory is the resolver for the moveTrackerResourceToCategory field. func (r *mutationResolver) MoveTrackerResourceToCategory(ctx context.Context, input types.MoveTrackerResourceToCategoryInput) (*types.MoveTrackerResourceToCategoryPayload, error) { if err := r.authorize(ctx, input.TrackerResourceID, probo.ActionTrackerResourceUpdate); err != nil { return nil, err } if err := r.authorize(ctx, input.TargetCookieCategoryID, probo.ActionCookieCategoryUpdate); err != nil { return nil, err } scope := coredata.NewScopeFromObjectID(input.TrackerResourceID) result, err := r.cookieBanner.MoveTrackerResourceToCategory( ctx, scope, cookiebanner.MoveTrackerResourceToCategoryRequest{ TrackerResourceID: input.TrackerResourceID, TargetCookieCategoryID: input.TargetCookieCategoryID, }, ) if err != nil { switch { case errors.Is(err, cookiebanner.ErrCategoryNotFound): return nil, gqlutils.NotFound(ctx, err) case errors.Is(err, cookiebanner.ErrTrackerResourceNotFound): return nil, gqlutils.NotFound(ctx, err) case errors.Is(err, cookiebanner.ErrCategoriesBannerMismatch): return nil, gqlutils.NotFoundf(ctx, "tracker resource or target category not found") case errors.Is(err, cookiebanner.ErrSameResourceCategoryMove): return nil, gqlutils.Invalidf(ctx, "tracker resource is already in the target category") default: r.logger.ErrorCtx(ctx, "cannot move tracker resource to category", log.Error(err)) return nil, gqlutils.Internal(ctx) } } return &types.MoveTrackerResourceToCategoryPayload{ TrackerResource: types.NewTrackerResourceNode(result.TrackerResource), CookieBanner: types.NewCookieBanner(result.Banner), }, nil } // CookieCategory is the resolver for the cookieCategory field. func (r *trackerPatternResolver) CookieCategory(ctx context.Context, obj *types.TrackerPattern) (*types.CookieCategory, error) { if err := r.authorize(ctx, obj.CookieCategory.ID, probo.ActionCookieCategoryGet); err != nil { return nil, err } loaders := dataloader.FromContext(ctx) category, err := loaders.CookieCategory.Load(ctx, obj.CookieCategory.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) || errors.Is(err, dataloadgen.ErrNotFound) { return nil, nil } r.logger.ErrorCtx(ctx, "cannot get cookie category", log.Error(err)) return nil, gqlutils.Internal(ctx) } return types.NewCookieCategory(category), nil } // DetectedCount is the resolver for the detectedCount field. func (r *trackerPatternResolver) DetectedCount(ctx context.Context, obj *types.TrackerPattern) (int, error) { scope := coredata.NewScopeFromObjectID(obj.ID) count, err := r.cookieBanner.CountDetectedTrackersByPatternID(ctx, scope, obj.ID) if err != nil { r.logger.ErrorCtx(ctx, "cannot count detected trackers", log.Error(err)) return 0, gqlutils.Internal(ctx) } return count, nil } // DetectedTrackers is the resolver for the detectedTrackers field. func (r *trackerPatternResolver) DetectedTrackers(ctx context.Context, obj *types.TrackerPattern, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.DetectedTrackerOrderBy) (*types.DetectedTrackerConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionTrackerPatternGet); err != nil { return nil, err } pageOrderBy := page.OrderBy[coredata.DetectedTrackerOrderField]{ Field: coredata.DetectedTrackerOrderFieldLastDetectedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.DetectedTrackerOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) scope := coredata.NewScopeFromObjectID(obj.ID) trackers, err := r.cookieBanner.ListDetectedTrackersForPattern(ctx, scope, obj.ID, cursor) if err != nil { r.logger.ErrorCtx(ctx, "cannot list detected trackers", log.Error(err)) return nil, gqlutils.Internal(ctx) } p := page.NewPage(trackers, cursor) return types.NewDetectedTrackerConnection(p, r, obj.ID), nil } // Permission is the resolver for the permission field. func (r *trackerPatternResolver) Permission(ctx context.Context, obj *types.TrackerPattern, action string) (bool, error) { return r.Resolver.Permission(ctx, obj, action) } // TotalCount is the resolver for the totalCount field. func (r *trackerPatternConnectionResolver) TotalCount(ctx context.Context, obj *types.TrackerPatternConnection) (int, error) { scope := coredata.NewScopeFromObjectID(obj.ParentID) var ( count int err error ) switch obj.Resolver.(type) { case *cookieCategoryResolver: count, err = r.cookieBanner.CountTrackerPatternsForCategory(ctx, scope, obj.ParentID) default: filter := coredata.NewTrackerPatternFilter(nil, nil, nil) if obj.Filter != nil { filter = coredata.NewTrackerPatternFilter(nil, obj.Filter.CookieCategoryID, nil) filter = filter.WithQuery(obj.Filter.Query).WithSource(obj.Filter.Source).WithTrackerType(obj.Filter.TrackerType) } count, err = r.cookieBanner.CountTrackerPatternsForBanner(ctx, scope, obj.ParentID, filter) } if err != nil { r.logger.ErrorCtx(ctx, "cannot count tracker patterns", log.Error(err)) return 0, gqlutils.Internal(ctx) } return count, nil } // CookieCategory is the resolver for the cookieCategory field. func (r *trackerResourceResolver) CookieCategory(ctx context.Context, obj *types.TrackerResource) (*types.CookieCategory, error) { if err := r.authorize(ctx, obj.CookieCategory.ID, probo.ActionCookieCategoryGet); err != nil { return nil, err } loaders := dataloader.FromContext(ctx) category, err := loaders.CookieCategory.Load(ctx, obj.CookieCategory.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) || errors.Is(err, dataloadgen.ErrNotFound) { return nil, nil } r.logger.ErrorCtx(ctx, "cannot get cookie category", log.Error(err)) return nil, gqlutils.Internal(ctx) } return types.NewCookieCategory(category), nil } // Permission is the resolver for the permission field. func (r *trackerResourceResolver) Permission(ctx context.Context, obj *types.TrackerResource, action string) (bool, error) { return r.Resolver.Permission(ctx, obj, action) } // TotalCount is the resolver for the totalCount field. func (r *trackerResourceConnectionResolver) TotalCount(ctx context.Context, obj *types.TrackerResourceConnection) (int, error) { scope := coredata.NewScopeFromObjectID(obj.ParentID) var ( count int err error ) switch obj.Resolver.(type) { case *cookieCategoryResolver: count, err = r.cookieBanner.CountTrackerResourcesForCategory(ctx, scope, obj.ParentID) default: filter := coredata.NewTrackerResourceFilter(nil, nil) if obj.Filter != nil { filter = filter.WithQuery(obj.Filter.Query).WithResourceType(obj.Filter.Type) } count, err = r.cookieBanner.CountUncategorisedTrackerResources(ctx, scope, obj.ParentID, filter) } if err != nil { r.logger.ErrorCtx(ctx, "cannot count tracker resources", log.Error(err)) return 0, gqlutils.Internal(ctx) } return count, nil } // CookieBanner returns schema.CookieBannerResolver implementation. func (r *Resolver) CookieBanner() schema.CookieBannerResolver { return &cookieBannerResolver{r} } // CookieBannerConnection returns schema.CookieBannerConnectionResolver implementation. func (r *Resolver) CookieBannerConnection() schema.CookieBannerConnectionResolver { return &cookieBannerConnectionResolver{r} } // CookieBannerVersion returns schema.CookieBannerVersionResolver implementation. func (r *Resolver) CookieBannerVersion() schema.CookieBannerVersionResolver { return &cookieBannerVersionResolver{r} } // CookieCategory returns schema.CookieCategoryResolver implementation. func (r *Resolver) CookieCategory() schema.CookieCategoryResolver { return &cookieCategoryResolver{r} } // CookieCategoryConnection returns schema.CookieCategoryConnectionResolver implementation. func (r *Resolver) CookieCategoryConnection() schema.CookieCategoryConnectionResolver { return &cookieCategoryConnectionResolver{r} } // DetectedTrackerConnection returns schema.DetectedTrackerConnectionResolver implementation. func (r *Resolver) DetectedTrackerConnection() schema.DetectedTrackerConnectionResolver { return &detectedTrackerConnectionResolver{r} } // TrackerPattern returns schema.TrackerPatternResolver implementation. func (r *Resolver) TrackerPattern() schema.TrackerPatternResolver { return &trackerPatternResolver{r} } // TrackerPatternConnection returns schema.TrackerPatternConnectionResolver implementation. func (r *Resolver) TrackerPatternConnection() schema.TrackerPatternConnectionResolver { return &trackerPatternConnectionResolver{r} } // TrackerResource returns schema.TrackerResourceResolver implementation. func (r *Resolver) TrackerResource() schema.TrackerResourceResolver { return &trackerResourceResolver{r} } // TrackerResourceConnection returns schema.TrackerResourceConnectionResolver implementation. func (r *Resolver) TrackerResourceConnection() schema.TrackerResourceConnectionResolver { return &trackerResourceConnectionResolver{r} } type cookieBannerResolver struct{ *Resolver } type cookieBannerConnectionResolver struct{ *Resolver } type cookieBannerVersionResolver struct{ *Resolver } type cookieCategoryResolver struct{ *Resolver } type cookieCategoryConnectionResolver struct{ *Resolver } type detectedTrackerConnectionResolver struct{ *Resolver } type trackerPatternResolver struct{ *Resolver } type trackerPatternConnectionResolver struct{ *Resolver } type trackerResourceResolver struct{ *Resolver } type trackerResourceConnectionResolver struct{ *Resolver }