From 51f766e5522c9d8cd2c7da3772b64e5d05be048d Mon Sep 17 00:00:00 2001 From: Milinda Dias Date: Wed, 10 Jun 2026 18:06:55 +0530 Subject: [PATCH 1/7] feat(composition): entity caching directives, proto config types, and generated bindings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extracted from jensneuse/entity-caching-v2 (PR #2777) — composition + proto layer only. - composition: @openfed__entityCache / @openfed__queryCache / @openfed__requestScoped directive definitions, extraction in normalization-factory, ConfigurationData types, warnings, and tests (incl. fuzz + mapping rules) - proto: additive DataSourceConfiguration fields 17-21 and new messages (EntityCacheConfiguration, RootFieldCacheConfiguration, EntityKeyMapping, EntityCacheFieldMapping, CachePopulateConfiguration, CacheInvalidateConfiguration, RequestScopedFieldConfiguration) - regenerated bindings: router/gen, connect-go, connect (incl. graphqlmetrics regen side-effects), composition-go bundle - shared: router-config serializer for the new proto fields Co-Authored-By: Claude Fable 5 --- .../directive-definition-data.ts | 182 +- composition/src/errors/errors.ts | 297 ++ composition/src/router-configuration/types.ts | 92 + composition/src/utils/string-constants.ts | 14 +- composition/src/v1/constants/constants.ts | 18 + .../src/v1/constants/directive-definitions.ts | 142 +- composition/src/v1/constants/type-nodes.ts | 7 +- .../v1/normalization/normalization-factory.ts | 1728 +++++++++- composition/src/v1/normalization/utils.ts | 18 + composition/src/v1/warnings/params.ts | 55 + composition/src/v1/warnings/warnings.ts | 138 + .../v1/directives/entity-cache-fuzz.test.ts | 1163 +++++++ .../entity-cache-mapping-rules.test.ts | 3007 +++++++++++++++++ .../v1/directives/entity-caching.test.ts | 1604 +++++++++ .../gen/proto/wg/cosmo/node/v1/node.pb.go | 1265 +++++-- connect/src/wg/cosmo/node/v1/node_pb.ts | 434 +++ proto/wg/cosmo/node/v1/node.proto | 74 + router/gen/proto/wg/cosmo/node/v1/node.pb.go | 1265 +++++-- shared/src/router-config/builder.ts | 22 +- .../router-config/graphql-configuration.ts | 93 + 20 files changed, 10932 insertions(+), 686 deletions(-) create mode 100644 composition/tests/v1/directives/entity-cache-fuzz.test.ts create mode 100644 composition/tests/v1/directives/entity-cache-mapping-rules.test.ts create mode 100644 composition/tests/v1/directives/entity-caching.test.ts diff --git a/composition/src/directive-definition-data/directive-definition-data.ts b/composition/src/directive-definition-data/directive-definition-data.ts index c3d8e0af4e..dd74896647 100644 --- a/composition/src/directive-definition-data/directive-definition-data.ts +++ b/composition/src/directive-definition-data/directive-definition-data.ts @@ -81,6 +81,17 @@ import { UNION_UPPER, URL_LOWER, WEIGHT, + CACHE_INVALIDATE, + CACHE_POPULATE, + ENTITY_CACHE, + INCLUDE_HEADERS, + IS, + MAX_AGE, + NEGATIVE_CACHE_TTL, + PARTIAL_CACHE_LOAD, + QUERY_CACHE, + REQUEST_SCOPED, + SHADOW_MODE, } from '../utils/string-constants'; import { AUTHENTICATED_DEFINITION, @@ -115,8 +126,18 @@ import { SPECIFIED_BY_DEFINITION, SUBSCRIPTION_FILTER_DEFINITION, TAG_DEFINITION, + CACHE_INVALIDATE_DEFINITION, + CACHE_POPULATE_DEFINITION, + ENTITY_CACHE_DEFINITION, + IS_DEFINITION, + QUERY_CACHE_DEFINITION, + REQUEST_SCOPED_DEFINITION, } from '../v1/constants/directive-definitions'; -import { REQUIRED_FIELDSET_TYPE_NODE, REQUIRED_STRING_TYPE_NODE } from '../v1/constants/type-nodes'; +import { + REQUIRED_FIELDSET_TYPE_NODE, + REQUIRED_INT_TYPE_NODE, + REQUIRED_STRING_TYPE_NODE, +} from '../v1/constants/type-nodes'; import { type ArgumentName, type DirectiveLocation } from '../types/types'; import { newDirectiveArgumentData, newDirectiveDefinitionData } from './utils'; import { type DirectiveArgumentData, DirectiveDefinitionData } from './types/types'; @@ -945,3 +966,162 @@ export const TAG_DEFINITION_DATA = newDirectiveDefinitionData({ node: TAG_DEFINITION, requiredArgumentNames: new Set([NAME]), }); + +export const CACHE_INVALIDATE_DEFINITION_DATA = newDirectiveDefinitionData({ + argumentDataByName: new Map(), + locations: new Set([FIELD_DEFINITION_UPPER]), + name: CACHE_INVALIDATE, + node: CACHE_INVALIDATE_DEFINITION, +}); + +export const CACHE_POPULATE_DEFINITION_DATA = newDirectiveDefinitionData({ + argumentDataByName: new Map([ + [ + MAX_AGE, + newDirectiveArgumentData({ + directive: `@${CACHE_POPULATE}`, + name: MAX_AGE, + namedTypeKind: Kind.SCALAR_TYPE_DEFINITION, + typeNode: stringToNamedTypeNode(INT_SCALAR), + }), + ], + ]), + locations: new Set([FIELD_DEFINITION_UPPER]), + name: CACHE_POPULATE, + node: CACHE_POPULATE_DEFINITION, + optionalArgumentNames: new Set([MAX_AGE]), +}); + +export const ENTITY_CACHE_DEFINITION_DATA = newDirectiveDefinitionData({ + argumentDataByName: new Map([ + [ + MAX_AGE, + newDirectiveArgumentData({ + directive: `@${ENTITY_CACHE}`, + name: MAX_AGE, + namedTypeKind: Kind.SCALAR_TYPE_DEFINITION, + typeNode: REQUIRED_INT_TYPE_NODE, + }), + ], + [ + NEGATIVE_CACHE_TTL, + newDirectiveArgumentData({ + directive: `@${ENTITY_CACHE}`, + defaultValue: { kind: Kind.INT, value: '0' }, + name: NEGATIVE_CACHE_TTL, + namedTypeKind: Kind.SCALAR_TYPE_DEFINITION, + typeNode: stringToNamedTypeNode(INT_SCALAR), + }), + ], + [ + INCLUDE_HEADERS, + newDirectiveArgumentData({ + directive: `@${ENTITY_CACHE}`, + defaultValue: { kind: Kind.BOOLEAN, value: false }, + name: INCLUDE_HEADERS, + namedTypeKind: Kind.SCALAR_TYPE_DEFINITION, + typeNode: stringToNamedTypeNode(BOOLEAN_SCALAR), + }), + ], + [ + PARTIAL_CACHE_LOAD, + newDirectiveArgumentData({ + directive: `@${ENTITY_CACHE}`, + defaultValue: { kind: Kind.BOOLEAN, value: false }, + name: PARTIAL_CACHE_LOAD, + namedTypeKind: Kind.SCALAR_TYPE_DEFINITION, + typeNode: stringToNamedTypeNode(BOOLEAN_SCALAR), + }), + ], + [ + SHADOW_MODE, + newDirectiveArgumentData({ + directive: `@${ENTITY_CACHE}`, + defaultValue: { kind: Kind.BOOLEAN, value: false }, + name: SHADOW_MODE, + namedTypeKind: Kind.SCALAR_TYPE_DEFINITION, + typeNode: stringToNamedTypeNode(BOOLEAN_SCALAR), + }), + ], + ]), + locations: new Set([OBJECT_UPPER]), + name: ENTITY_CACHE, + node: ENTITY_CACHE_DEFINITION, + optionalArgumentNames: new Set([NEGATIVE_CACHE_TTL, INCLUDE_HEADERS, PARTIAL_CACHE_LOAD, SHADOW_MODE]), + requiredArgumentNames: new Set([MAX_AGE]), +}); + +export const IS_DEFINITION_DATA = newDirectiveDefinitionData({ + argumentDataByName: new Map([ + [ + FIELDS, + newDirectiveArgumentData({ + directive: `@${IS}`, + name: FIELDS, + namedTypeKind: Kind.SCALAR_TYPE_DEFINITION, + typeNode: REQUIRED_STRING_TYPE_NODE, + }), + ], + ]), + locations: new Set([ARGUMENT_DEFINITION_UPPER]), + name: IS, + node: IS_DEFINITION, + requiredArgumentNames: new Set([FIELDS]), +}); + +export const QUERY_CACHE_DEFINITION_DATA = newDirectiveDefinitionData({ + argumentDataByName: new Map([ + [ + MAX_AGE, + newDirectiveArgumentData({ + directive: `@${QUERY_CACHE}`, + name: MAX_AGE, + namedTypeKind: Kind.SCALAR_TYPE_DEFINITION, + typeNode: REQUIRED_INT_TYPE_NODE, + }), + ], + [ + INCLUDE_HEADERS, + newDirectiveArgumentData({ + directive: `@${QUERY_CACHE}`, + defaultValue: { kind: Kind.BOOLEAN, value: false }, + name: INCLUDE_HEADERS, + namedTypeKind: Kind.SCALAR_TYPE_DEFINITION, + typeNode: stringToNamedTypeNode(BOOLEAN_SCALAR), + }), + ], + [ + SHADOW_MODE, + newDirectiveArgumentData({ + directive: `@${QUERY_CACHE}`, + defaultValue: { kind: Kind.BOOLEAN, value: false }, + name: SHADOW_MODE, + namedTypeKind: Kind.SCALAR_TYPE_DEFINITION, + typeNode: stringToNamedTypeNode(BOOLEAN_SCALAR), + }), + ], + ]), + locations: new Set([FIELD_DEFINITION_UPPER]), + name: QUERY_CACHE, + node: QUERY_CACHE_DEFINITION, + optionalArgumentNames: new Set([INCLUDE_HEADERS, SHADOW_MODE]), + requiredArgumentNames: new Set([MAX_AGE]), +}); + +export const REQUEST_SCOPED_DEFINITION_DATA = newDirectiveDefinitionData({ + argumentDataByName: new Map([ + [ + KEY, + newDirectiveArgumentData({ + directive: `@${REQUEST_SCOPED}`, + name: KEY, + namedTypeKind: Kind.SCALAR_TYPE_DEFINITION, + typeNode: REQUIRED_STRING_TYPE_NODE, + }), + ], + ]), + locations: new Set([FIELD_DEFINITION_UPPER]), + name: REQUEST_SCOPED, + node: REQUEST_SCOPED_DEFINITION, + requiredArgumentNames: new Set([KEY]), +}); diff --git a/composition/src/errors/errors.ts b/composition/src/errors/errors.ts index 3d9258b484..3766f57663 100644 --- a/composition/src/errors/errors.ts +++ b/composition/src/errors/errors.ts @@ -1810,6 +1810,303 @@ export function oneOfRequiredFieldsError({ requiredFieldNames, typeName }: OneOf ); } +// Entity caching directive error messages. +// These are reported during composition when subgraph schemas use entity caching directives +// incorrectly. Each error corresponds to a validation rule in validateAndExtractEntityCachingConfigs(). + +// @openfed__entityCache requires the type to be a federation entity (must have @key) +export function entityCacheWithoutKeyErrorMessage(typeName: string): string { + return `Type "${typeName}" has @openfed__entityCache but no @key directive.`; +} + +// @openfed__queryCache must only be defined on fields of the root query type. +// Mutation/Subscription fields use @openfed__cachePopulate or @openfed__cacheInvalidate. +// The root query type may be renamed via `schema { query: MyQuery }`; this validation runs +// after resolving the canonical root type, so the field coords reported here reflect the +// declared (possibly renamed) type. +export function queryCacheOnNonQueryFieldErrorMessage(fieldCoords: string): string { + return ( + `@openfed__queryCache must only be defined on fields of the root query type; found on "${fieldCoords}".` + + ` Use @openfed__cachePopulate or @openfed__cacheInvalidate on mutation or subscription fields.` + ); +} + +// @openfed__queryCache requires the return type to be a federation entity — non-entity types have no @key for cache key construction +export function queryCacheOnNonEntityReturnTypeErrorMessage(fieldCoords: string, returnType: string): string { + return ( + `Field "${fieldCoords}" has @openfed__queryCache but returns non-entity type "${returnType}".` + + ` @openfed__queryCache requires the return type to be an entity with @key.` + ); +} + +// Shared validation for maxAge across @openfed__entityCache, @openfed__queryCache, and @openfed__cachePopulate +export function maxAgeNotPositiveIntegerErrorMessage(directiveName: string, value: number): string { + return `@${directiveName} maxAge must be a positive integer, got "${value}".`; +} + +// Validation for @openfed__entityCache negativeCacheTTL. 0 disables negative caching; negative values rejected. +export function negativeCacheTTLNotNonNegativeIntegerErrorMessage(directiveName: string, value: number): string { + return `@${directiveName} negativeCacheTTL must be a non-negative integer, got "${value}".`; +} + +// @openfed__is maps arguments to @key fields — it's meaningless without @openfed__queryCache since only @openfed__queryCache uses argument-to-key mappings +export function isWithoutQueryCacheErrorMessage(argumentName: string, fieldCoords: string): string { + return `@openfed__is on argument "${argumentName}" of field "${fieldCoords}" has no effect without @openfed__queryCache.`; +} + +// @openfed__is(fields: "...") must reference a field that appears in the entity's @key directive +export function isReferencesUnknownKeyFieldErrorMessage( + isField: string, + argumentName: string, + fieldCoords: string, + entityType: string, +): string { + return ( + `@openfed__is(fields: "${isField}") on argument "${argumentName}" of field "${fieldCoords}"` + + ` references unknown @key field "${isField}" on type "${entityType}".` + ); +} + +// Each @key field may only be mapped to one argument — duplicates would create ambiguous cache keys +export function duplicateKeyFieldMappingErrorMessage(fieldCoords: string, keyField: string): string { + return `Multiple arguments on field "${fieldCoords}" map to @key field "${keyField}".`; +} + +// @openfed__cacheInvalidate is for side-effect operations — Query fields should use @openfed__queryCache instead +export function cacheInvalidateOnNonMutationSubscriptionFieldErrorMessage(fieldCoords: string): string { + return `@openfed__cacheInvalidate is only valid on Mutation or Subscription fields, found on "${fieldCoords}".`; +} + +// @openfed__cacheInvalidate needs to know which entity to evict — non-entity return types have no cache key +export function cacheInvalidateOnNonEntityReturnTypeErrorMessage(fieldCoords: string, returnType: string): string { + return `Field "${fieldCoords}" has @openfed__cacheInvalidate but returns non-entity type "${returnType}".`; +} + +// @openfed__cachePopulate is for side-effect operations — Query fields should use @openfed__queryCache instead +export function cachePopulateOnNonMutationSubscriptionFieldErrorMessage(fieldCoords: string): string { + return `@openfed__cachePopulate is only valid on Mutation or Subscription fields, found on "${fieldCoords}".`; +} + +// @openfed__cachePopulate needs to know which entity to write — non-entity return types have no cache key +export function cachePopulateOnNonEntityReturnTypeErrorMessage(fieldCoords: string, returnType: string): string { + return `Field "${fieldCoords}" has @openfed__cachePopulate but returns non-entity type "${returnType}".`; +} + +// A field cannot both populate and invalidate — these are contradictory cache operations +export function cacheInvalidateAndPopulateMutualExclusionErrorMessage(fieldCoords: string): string { + return ( + `Field "${fieldCoords}" has both @openfed__cacheInvalidate and @openfed__cachePopulate.` + + ` A field must use one or the other, not both.` + ); +} + +export function explicitTypeMismatchErrorMessage( + argumentName: string, + fieldCoords: string, + argumentType: string, + isField: string, + entityType: string, + keyFieldType: string, +): string { + return `Argument "${argumentName}" on field "${fieldCoords}" has type "${argumentType}" but @openfed__is(fields: "${isField}") targets @key field "${isField}" of type "${keyFieldType}" on entity "${entityType}".`; +} + +export function nonKeyFieldSpecErrorMessage( + argumentName: string, + fieldCoords: string, + isField: string, + entityType: string, +): string { + return `Argument "${argumentName}" on field "${fieldCoords}" uses @openfed__is(fields: "${isField}"), but "${isField}" is not a @key field on entity "${entityType}". @openfed__is can only target fields that are part of a @key.`; +} + +export function listArgumentToScalarKeySpecErrorMessage( + argumentName: string, + fieldCoords: string, + argumentType: string, + isField: string, + entityType: string, + keyFieldType: string, +): string { + return ( + `Argument "${argumentName}" on field "${fieldCoords}" has type "${argumentType}" but @openfed__is(fields: "${isField}") targets @key field "${isField}" of type "${keyFieldType}" on entity "${entityType}".` + + ' List arguments can only map to scalar key fields when the field returns a list of entities, or to list key fields when the key field itself is a list type.' + ); +} + +export function scalarArgumentToListKeySpecErrorMessage( + argumentName: string, + fieldCoords: string, + argumentType: string, + isField: string, + entityType: string, + keyFieldType: string, +): string { + return ( + `Argument "${argumentName}" on field "${fieldCoords}" has type "${argumentType}" but @openfed__is(fields: "${isField}") targets @key field "${isField}" of type "${keyFieldType}" on entity "${entityType}".` + + ' A scalar argument cannot map to a list key field.' + ); +} + +export function explicitIncompleteCompositeKeyErrorMessage( + fieldCoords: string, + argumentName: string, + mappedField: string, + entityType: string, + compositeKey: string, + missingField: string, +): string { + return `Field "${fieldCoords}" has argument "${argumentName}" with @openfed__is mapping to @key field "${mappedField}" on entity "${entityType}", but composite @key "${compositeKey}" is incomplete because no argument maps to required key field "${missingField}".`; +} + +export function explicitSingularAdditionalNonKeyArgumentErrorMessage( + fieldCoords: string, + argumentName: string, + keyField: string, + entityType: string, + extraArgument: string, +): string { + return `Field "${fieldCoords}" has argument "${argumentName}" with @openfed__is mapping to @key field "${keyField}" on entity "${entityType}", but also has additional argument "${extraArgument}" which is not mapped to a key field. All arguments must be key arguments — additional arguments may filter the response, making the cache key incomplete.`; +} + +export function explicitCompositeAdditionalNonKeyArgumentErrorMessage( + fieldCoords: string, + firstArgument: string, + secondArgument: string, + compositeKey: string, + entityType: string, + extraArgument: string, +): string { + return `Field "${fieldCoords}" has arguments "${firstArgument}" and "${secondArgument}" with @openfed__is mappings covering composite @key "${compositeKey}" on entity "${entityType}", but also has additional argument "${extraArgument}" which is not mapped to a key field. All arguments must be key arguments — additional arguments may filter the response, making the cache key incomplete.`; +} + +export function batchListValuedKeyRequiresNestedListsErrorMessage( + fieldCoords: string, + isField: string, + entityType: string, + actualType: string, +): string { + return `Field "${fieldCoords}" returns a list of entities, so cache lookup is a batch lookup and requires one key value per entity. Because @openfed__is(fields: "${isField}") targets list-valued @key field "${isField}" on entity "${entityType}", the argument must provide a list of tag lists (e.g., "[[String!]!]!"), not ${actualType}.`; +} + +export function explicitBatchAdditionalNonKeyArgumentErrorMessage( + fieldCoords: string, + argumentName: string, + keyField: string, + entityType: string, + extraArgument: string, +): string { + return `Field "${fieldCoords}" returns a list of entities, so cache lookup is a batch lookup and requires a single key input that determines the returned entities. Argument "${argumentName}" uses @openfed__is to map to @key field "${keyField}" on entity "${entityType}", but additional argument "${extraArgument}" is not mapped to a key field and may filter the response, so the batch key would be incomplete.`; +} + +export function explicitScalarArgumentsCannotEstablishBatchMappingErrorMessage( + fieldCoords: string, + entityType: string, +): string { + return `Field "${fieldCoords}" returns a list of entities, so cache lookup is a batch lookup and requires one key value per entity. Scalar arguments with @openfed__is mapping to @key fields on entity "${entityType}" cannot provide a batch of keys, so they cannot establish cache key mappings for this field. Use list arguments for batch cache lookups.`; +} + +export function multipleListArgumentsBatchFactoryMessage(fieldCoords: string, entityType: string): string { + return ( + `Field "${fieldCoords}" has multiple list arguments mapping to @key fields on entity "${entityType}".` + + ' Batch cache lookups require a single list argument.' + + ' For composite keys, use a single list of input objects instead.' + ); +} + +export function inputObjectCompositeTypeMismatchErrorMessage( + argumentName: string, + fieldCoords: string, + keyFields: string, + entityType: string, + inputType: string, + inputFieldName: string, + inputFieldType: string, + entityFieldPath: string, + entityFieldType: string, +): string { + return ( + `Argument "${argumentName}" on field "${fieldCoords}" uses @openfed__is(fields: "${keyFields}") mapping to composite @key on entity "${entityType}",` + + ` but input type "${inputType}" field "${inputFieldName}" has type "${inputFieldType}"` + + ` which does not match key field "${entityFieldPath}" of type "${entityFieldType}".` + ); +} + +export function inputObjectCompositeMissingFieldErrorMessage( + argumentName: string, + fieldCoords: string, + keyFields: string, + entityType: string, + inputType: string, + missingFieldName: string, +): string { + return ( + `Argument "${argumentName}" on field "${fieldCoords}" uses @openfed__is(fields: "${keyFields}") mapping to composite @key on entity "${entityType}",` + + ` but input type "${inputType}" is missing required key field "${missingFieldName}".` + ); +} + +export function nestedKeyRequiresInputObjectErrorMessage( + argumentName: string, + fieldCoords: string, + keyFields: string, + entityType: string, + inputTypeName: string, + entityKeyPath: string, +): string { + return ( + `Argument "${argumentName}" on field "${fieldCoords}" maps to nested @key "${keyFields}" on entity "${entityType}",` + + ` but the input field at key path "${entityKeyPath}" has type "${inputTypeName}",` + + ` which is not an input object type and therefore cannot provide the nested key selection.` + ); +} + +export function nestedInputObjectTypeMismatchErrorMessage( + argumentName: string, + fieldCoords: string, + keyFields: string, + entityType: string, + inputType: string, + inputFieldName: string, + inputFieldType: string, + entityFieldPath: string, + entityFieldType: string, +): string { + return ( + `Argument "${argumentName}" on field "${fieldCoords}" maps to nested @key "${keyFields}" on entity "${entityType}",` + + ` but input type "${inputType}" field "${inputFieldName}" has type "${inputFieldType}"` + + ` which does not match key field "${entityFieldPath}" of type "${entityFieldType}".` + ); +} + +export function nestedInputObjectMissingFieldErrorMessage( + argumentName: string, + fieldCoords: string, + keyFields: string, + entityType: string, + inputType: string, + missingFieldName: string, +): string { + return ( + `Argument "${argumentName}" on field "${fieldCoords}" maps to nested @key "${keyFields}" on entity "${entityType}",` + + ` but input type "${inputType}" is missing required key field "${missingFieldName}".` + ); +} + +export function nonInputArgumentCannotTargetCompositeKeyErrorMessage( + argumentName: string, + fieldCoords: string, + keyFields: string, + entityType: string, + argumentType: string, +): string { + return ( + `Argument "${argumentName}" on field "${fieldCoords}" uses @openfed__is(fields: "${keyFields}") targeting composite @key on entity "${entityType}",` + + ` but argument type "${argumentType}" does not provide nested fields for each key field.` + + ' Use separate arguments or an input object that matches the composite key shape.' + ); +} + export function listSizeInvalidSlicingArgumentErrorMessage( directiveCoords: DirectiveArgumentCoords, path: ArgumentName, diff --git a/composition/src/router-configuration/types.ts b/composition/src/router-configuration/types.ts index c731aa506e..eb56d586a9 100644 --- a/composition/src/router-configuration/types.ts +++ b/composition/src/router-configuration/types.ts @@ -86,6 +86,17 @@ export type RequiredFieldConfiguration = { disableEntityResolver?: boolean; }; +export type RequestScopedFieldConfig = { + fieldName: FieldName; + typeName: TypeName; + // L1 cache key used to store/lookup this field's value for the duration of a request. + // Format: "{subgraphName}.{key}" where `key` is the @openfed__requestScoped(key:) argument. + // All fields in the same subgraph declaring @openfed__requestScoped with the same key share + // the same L1 entry — the first one to resolve populates it, subsequent ones inject + // from it (subject to widening checks and alias-aware normalization). + l1Key: string; +}; + export type ConfigurationData = { fieldNames: Set; isRootNode: boolean; @@ -97,7 +108,88 @@ export type ConfigurationData = { provides?: RequiredFieldConfiguration[]; keys?: RequiredFieldConfiguration[]; requireFetchReasonsFieldNames?: Array; + requestScopedFields?: Array; requires?: RequiredFieldConfiguration[]; + // Entity caching configuration — attached during composition when subgraph schemas + // use entity caching directives. These are serialized into the router configuration + // and consumed by the router's entity cache module at runtime. + // + // entityCacheConfigurations: attached to the entity type's ConfigurationData (e.g., "Product") + // rootFieldCacheConfigurations: attached to the Query type's ConfigurationData + // cachePopulateConfigurations: attached to the Mutation/Subscription type's ConfigurationData + // cacheInvalidateConfigurations: attached to the Mutation/Subscription type's ConfigurationData + entityCacheConfigurations?: Array; + rootFieldCacheConfigurations?: Array; + cachePopulateConfigurations?: Array; + cacheInvalidateConfigurations?: Array; +}; + +// Extracted from @openfed__entityCache(maxAge: Int!, negativeCacheTTL: Int, includeHeaders: Boolean, partialCacheLoad: Boolean, shadowMode: Boolean) +// on OBJECT types. Defines per-entity cache TTL and behavior. +export type EntityCacheConfig = { + typeName: TypeName; + maxAgeSeconds: number; + // TTL (in seconds) for caching "not found" entity responses (entity returned null + // from _entities without errors). 0 disables negative caching; composition rejects + // negative values at validation time. + notFoundCacheTtlSeconds: number; + // When true, request headers are included in the cache key (useful for user-specific entities) + includeHeaders: boolean; + // When true, allows partial cache hits — the router fetches only missing entities from the subgraph + partialCacheLoad: boolean; + // When true, the cache runs in shadow mode — cache reads/writes happen but responses always come from the subgraph. + // Useful for warming caches or validating cache correctness without affecting production traffic. + shadowMode: boolean; +}; + +// Extracted from @openfed__queryCache(maxAge: Int!, includeHeaders: Boolean, shadowMode: Boolean) +// on Query fields. Tells the router which query fields can serve entities from cache. +export type RootFieldCacheConfig = { + fieldName: FieldName; + maxAgeSeconds: number; + includeHeaders: boolean; + shadowMode: boolean; + // The entity type this query field returns (must have @openfed__entityCache) + entityTypeName: TypeName; + // Maps query arguments to entity @key fields so the router can construct cache keys from query arguments. + // Empty for list-returning fields (cache reads are skipped; only cache writes/population apply). + entityKeyMappings: Array; +}; + +// Groups field mappings for a single entity type returned by a @openfed__queryCache field. +export type EntityKeyMappingConfig = { + entityTypeName: TypeName; + fieldMappings: Array; +}; + +// Maps a single query argument to an entity's @key field. +// Example: query { product(productId: ID!) @openfed__queryCache } with @openfed__is(fields: "id") on productId +// → entityKeyField: "id", argumentPath: ["productId"] +// When the argument name matches the @key field name, auto-mapping occurs without @openfed__is. +export type FieldMappingConfig = { + entityKeyField: FieldName; + argumentPath: Array; + isBatch?: boolean; +}; + +// Extracted from @openfed__cachePopulate(maxAge: Int) on Mutation/Subscription fields. +// Tells the router to populate the entity cache with the mutation's return value. +// maxAgeSeconds overrides the entity's default TTL when provided. +// entityTypeName identifies which cached entity this populate targets — derived from +// the field's return type, which composition validates must be an @openfed__entityCache-marked entity. +export type CachePopulateConfig = { + fieldName: FieldName; + operationType: string; + entityTypeName: TypeName; + maxAgeSeconds?: number; +}; + +// Extracted from @openfed__cacheInvalidate on Mutation/Subscription fields. +// Tells the router to evict the returned entity from the cache after the operation completes. +export type CacheInvalidateConfig = { + fieldName: FieldName; + operationType: string; + entityTypeName: TypeName; }; export type Costs = { diff --git a/composition/src/utils/string-constants.ts b/composition/src/utils/string-constants.ts index 92dacd6029..1c45b8b09e 100644 --- a/composition/src/utils/string-constants.ts +++ b/composition/src/utils/string-constants.ts @@ -10,6 +10,8 @@ export const AUTHENTICATED = 'authenticated'; export const ARGUMENT_DEFINITION_UPPER = 'ARGUMENT_DEFINITION'; export const BOOLEAN = 'boolean'; export const BOOLEAN_SCALAR = 'Boolean'; +export const CACHE_INVALIDATE = 'openfed__cacheInvalidate'; +export const CACHE_POPULATE = 'openfed__cachePopulate'; export const CHANNEL = 'channel'; export const CHANNELS = 'channels'; export const COMPOSE_DIRECTIVE = 'composeDirective'; @@ -41,6 +43,7 @@ export const EDFS_REDIS_PUBLISH = 'edfs__redisPublish'; export const EDFS_REDIS_SUBSCRIBE = 'edfs__redisSubscribe'; export const ENTITIES = 'entities'; export const ENTITIES_FIELD = '_entities'; +export const ENTITY_CACHE = 'openfed__entityCache'; export const ENTITY_UNION = '_Entity'; export const ENUM = 'Enum'; export const ENUM_UPPER = 'ENUM'; @@ -65,9 +68,10 @@ export const FROM = 'from'; export const HYPHEN_JOIN = `\n -`; export const ID_SCALAR = 'ID'; export const IMPORT = 'import'; -export const IN_UPPER = 'IN'; export const INACCESSIBLE = 'inaccessible'; +export const INCLUDE_HEADERS = 'includeHeaders'; export const INLINE_FRAGMENT = 'inlineFragment'; +export const IN_UPPER = 'IN'; export const INLINE_FRAGMENT_UPPER = 'INLINE_FRAGMENT'; export const INPUT = 'Input'; export const INPUT_FIELD = 'Input field'; @@ -79,6 +83,7 @@ export const INT_SCALAR = 'Int'; export const INTERFACE = `Interface`; export const INTERFACE_UPPER = 'INTERFACE'; export const INTERFACE_OBJECT = 'interfaceObject'; +export const IS = 'openfed__is'; export const KEY = 'key'; export const LEFT_PARENTHESIS = '('; export const LEVELS = 'levels'; @@ -88,9 +93,12 @@ export const LINK_IMPORT = 'link__Import'; export const LINK_PURPOSE = 'link__Purpose'; export const LIST = 'list'; export const LITERAL_AT = '@'; +export const LITERAL_OPEN_BRACE = '{'; export const LITERAL_SPACE = ' '; export const LITERAL_NEW_LINE = '\n'; export const LITERAL_PERIOD = '.'; +export const MAX_AGE = 'maxAge'; +export const NEGATIVE_CACHE_TTL = 'negativeCacheTTL'; export const NUMBER = 'number'; export const MUTATION = 'Mutation'; export const MUTATION_UPPER = 'MUTATION'; @@ -115,14 +123,17 @@ export const OVERRIDE = 'override'; export const PARENT_DEFINITION_DATA = 'parentDefinitionDataByTypeName'; export const PARENT_DEFINITION_DATA_MAP = 'parentDefinitionDataByParentTypeName'; export const PARENT_EXTENSION_DATA_MAP = 'parentExtensionDataByParentTypeName'; +export const PARTIAL_CACHE_LOAD = 'partialCacheLoad'; export const PROVIDER_ID = 'providerId'; export const PROVIDES = 'provides'; export const PUBLISH = 'publish'; export const QUERY = 'Query'; +export const QUERY_CACHE = 'openfed__queryCache'; export const QUERY_UPPER = 'QUERY'; export const QUOTATION_JOIN = `", "`; export const REASON = 'reason'; export const REQUEST = 'request'; +export const REQUEST_SCOPED = 'openfed__requestScoped'; export const REQUIRE_FETCH_REASONS = 'openfed__requireFetchReasons'; export const REQUIRE_ONE_SLICING_ARGUMENT = 'requireOneSlicingArgument'; export const REQUIRES = 'requires'; @@ -139,6 +150,7 @@ export const SELECTION_REPRESENTATION = ' { ... }'; export const SEMANTIC_NON_NULL = 'semanticNonNull'; export const SERVICE_OBJECT = '_Service'; export const SERVICE_FIELD = '_service'; +export const SHADOW_MODE = 'shadowMode'; export const SHAREABLE = 'shareable'; export const SIZED_FIELDS = 'sizedFields'; export const SLICING_ARGUMENTS = 'slicingArguments'; diff --git a/composition/src/v1/constants/constants.ts b/composition/src/v1/constants/constants.ts index a9139c23c8..e3ac1f539b 100644 --- a/composition/src/v1/constants/constants.ts +++ b/composition/src/v1/constants/constants.ts @@ -2,6 +2,8 @@ import { type DirectiveDefinitionNode } from 'graphql'; import { AUTHENTICATED, BOOLEAN_SCALAR, + CACHE_INVALIDATE, + CACHE_POPULATE, COMPOSE_DIRECTIVE, CONFIGURE_CHILD_DESCRIPTIONS, CONFIGURE_DESCRIPTION, @@ -15,6 +17,7 @@ import { EDFS_NATS_SUBSCRIBE, EDFS_REDIS_PUBLISH, EDFS_REDIS_SUBSCRIBE, + ENTITY_CACHE, EXTENDS, EXTERNAL, FIELD_SET_SCALAR, @@ -23,12 +26,15 @@ import { INACCESSIBLE, INT_SCALAR, INTERFACE_OBJECT, + IS, KEY, LINK, LIST_SIZE, ONE_OF, OVERRIDE, PROVIDES, + QUERY_CACHE, + REQUEST_SCOPED, REQUIRE_FETCH_REASONS, REQUIRES, REQUIRES_SCOPES, @@ -43,12 +49,15 @@ import { import { type DirectiveName } from '../../types/types'; import { AUTHENTICATED_DEFINITION, + CACHE_INVALIDATE_DEFINITION, + CACHE_POPULATE_DEFINITION, COMPOSE_DIRECTIVE_DEFINITION, CONFIGURE_CHILD_DESCRIPTIONS_DEFINITION, CONFIGURE_DESCRIPTION_DEFINITION, CONNECT_FIELD_RESOLVER_DEFINITION, COST_DEFINITION, DEPRECATED_DEFINITION, + ENTITY_CACHE_DEFINITION, EDFS_KAFKA_PUBLISH_DEFINITION, EDFS_KAFKA_SUBSCRIBE_DEFINITION, EDFS_NATS_PUBLISH_DEFINITION, @@ -60,12 +69,15 @@ import { EXTERNAL_DEFINITION, INACCESSIBLE_DEFINITION, INTERFACE_OBJECT_DEFINITION, + IS_DEFINITION, KEY_DEFINITION, LINK_DEFINITION, LIST_SIZE_DEFINITION, ONE_OF_DEFINITION, OVERRIDE_DEFINITION, PROVIDES_DEFINITION, + QUERY_CACHE_DEFINITION, + REQUEST_SCOPED_DEFINITION, REQUIRE_FETCH_REASONS_DEFINITION, REQUIRES_DEFINITION, REQUIRES_SCOPES_DEFINITION, @@ -81,6 +93,8 @@ export const DIRECTIVE_DEFINITION_BY_NAME: ReadonlyMap([ [AUTHENTICATED, AUTHENTICATED_DEFINITION], + [CACHE_INVALIDATE, CACHE_INVALIDATE_DEFINITION], + [CACHE_POPULATE, CACHE_POPULATE_DEFINITION], [COMPOSE_DIRECTIVE, COMPOSE_DIRECTIVE_DEFINITION], [CONFIGURE_DESCRIPTION, CONFIGURE_DESCRIPTION_DEFINITION], [CONFIGURE_CHILD_DESCRIPTIONS, CONFIGURE_CHILD_DESCRIPTIONS_DEFINITION], @@ -94,16 +108,20 @@ export const DIRECTIVE_DEFINITION_BY_NAME: ReadonlyMap(); + // Populated in Phase 1 of validateAndExtractEntityCachingConfigs(). + // Used as a lookup in Phase 2 to verify that @openfed__queryCache/@openfed__cacheInvalidate/@openfed__cachePopulate + // fields return entity types that have opted into caching. + entityCacheConfigByTypeName = new Map< + TypeName, + { + maxAgeSeconds: number; + notFoundCacheTtlSeconds: number; + includeHeaders: boolean; + partialCacheLoad: boolean; + shadowMode: boolean; + } + >(); errors = new Array(); entityDataByTypeName = new Map(); entityInterfaceDataByTypeName = new Map(); @@ -1132,7 +1203,7 @@ export class NormalizationFactory { if (weightArg.value.kind !== Kind.INT) { const directiveCoords = `@${directiveName}(${argNode.name.value}: ...)`; this.errors.push( - invalidDirectiveError(COST, directiveCoords, '1st', [ + invalidDirectiveError(COST, directiveCoords, FIRST_ORDINAL, [ invalidArgumentValueErrorMessage(print(weightArg.value), `@${COST}`, WEIGHT, 'Int!'), ]), ); @@ -3631,6 +3702,1652 @@ export class NormalizationFactory { } } + extractRequestScopedFields() { + // Gather fields annotated with @openfed__requestScoped across all types in this subgraph. + // A field is both a reader and writer of the coordinate L1 — no receiver/provider. + // Fields with the same `key` share the same L1 entry: whichever is resolved first + // populates it, subsequent ones inject from it. + type Collected = { + typeName: string; + fieldName: string; + fieldCoords: string; + key: string; + l1Key: string; + }; + const collected: Array = []; + const keyToCoordsList = new Map>(); + + for (const [, parentData] of this.parentDefinitionDataByTypeName) { + if (parentData.kind !== Kind.OBJECT_TYPE_DEFINITION && parentData.kind !== Kind.INTERFACE_TYPE_DEFINITION) { + continue; + } + const typeName = getParentTypeName(parentData); + for (const [fieldName, fieldData] of parentData.fieldDataByName) { + const directives = fieldData.directivesByName.get(REQUEST_SCOPED); + if (!directives || directives.length < 1) { + continue; + } + const directive = directives[0]; + const fieldCoords = `${typeName}.${fieldName}`; + // `key` is mandatory (enforced by directive definition validation upstream), + // but defend against malformed AST just in case. + let key: string | undefined; + if (directive.arguments) { + for (const arg of directive.arguments) { + if (arg.name.value === KEY && arg.value.kind === Kind.STRING) { + key = (arg.value as StringValueNode).value; + } + } + } + if (!key) { + continue; + } + const l1Key = `${this.subgraphName}.${key}`; + collected.push({ typeName, fieldName, fieldCoords, key, l1Key }); + const list = keyToCoordsList.get(key); + if (list) { + list.push(fieldCoords); + } else { + keyToCoordsList.set(key, [fieldCoords]); + } + } + } + + if (collected.length === 0) { + return; + } + + // Warn when a key is used on only one field — @openfed__requestScoped is meaningless + // unless ≥ 2 fields share the key (there'd be no second reader to benefit). + for (const [key, coordsList] of keyToCoordsList) { + if (coordsList.length < 2) { + this.warnings.push( + requestScopedSingleFieldWarning({ + subgraphName: this.subgraphName, + key, + fieldCoords: coordsList[0], + }), + ); + } + } + + // Group by type and attach to configurationData. + const byType = new Map>(); + for (const c of collected) { + const list = byType.get(c.typeName) ?? []; + list.push({ + fieldName: c.fieldName, + typeName: c.typeName, + l1Key: c.l1Key, + }); + byType.set(c.typeName, list); + } + for (const [typeName, fields] of byType) { + const configurationData = getValueOrDefault(this.configurationDataByTypeName, typeName, () => + newConfigurationData(false, typeName), + ); + configurationData.requestScopedFields = fields; + } + } + + // Reads an INT-typed argument off a directive node; returns undefined when the argument + // is absent or not an INT literal. Narrowing via `arg.value.kind === Kind.INT` is required + // before accessing `.value` — otherwise variables and other AST nodes silently coerce to NaN. + private extractCacheIntArg(directive: ConstDirectiveNode, argName: string): number | undefined { + if (!directive.arguments) { + return undefined; + } + for (const arg of directive.arguments) { + if (arg.name.value === argName && arg.value.kind === Kind.INT) { + return parseInt(arg.value.value, 10); + } + } + return undefined; + } + + // Reads a BOOLEAN-typed argument off a directive node; returns false when absent or non-boolean. + // The directive definitions default these flags to false, matching this fallback. + private extractCacheBoolArg(directive: ConstDirectiveNode, argName: string): boolean { + if (!directive.arguments) { + return false; + } + for (const arg of directive.arguments) { + if (arg.name.value === argName && arg.value.kind === Kind.BOOLEAN) { + return arg.value.value; + } + } + return false; + } + + // Returns the ConfigurationData entry for a type, creating it if missing. + // Cache attachment must never silently drop — if the entry doesn't exist yet it's because + // the type contributes nothing else to the router config (e.g., a Mutation type with only + // a single @openfed__cacheInvalidate field). Creating it on demand is the same pattern used by + // addValidKeyFieldSetConfigurations and extractRequestScopedFields. + private getCacheConfigurationData(typeName: string, isEntity: boolean): ConfigurationData { + return getValueOrDefault(this.configurationDataByTypeName, typeName, () => + newConfigurationData(isEntity, typeName), + ); + } + + /* + * Validates and extracts entity caching directive configurations from the subgraph schema. + * + * Entity caching allows the router to cache resolved entities (types with @key) in an external + * store (e.g., Redis) and serve subsequent requests from cache instead of re-fetching from subgraphs. + * + * Five directives work together to control caching behavior: + * + * @openfed__entityCache(maxAge: Int!) — on OBJECT types: marks an entity type as cacheable + * @openfed__queryCache(maxAge: Int!) — on Query fields: enables cache reads for a query that returns a cached entity + * @openfed__cacheInvalidate — on Mutation/Subscription fields: evicts the returned entity from cache + * @openfed__cachePopulate(maxAge: Int) — on Mutation/Subscription fields: writes the returned entity into cache + * @openfed__is(fields: String!) — on arguments: maps a query argument to an entity @key field for cache key construction + * + * Validation behavior is encoded in the entity-caching test suite: + * `tests/v1/directives/entity-caching.test.ts` and + * `tests/v1/directives/entity-cache-mapping-rules.test.ts`. + * + * @openfed__entityCache must be extracted first because the root-field directives validate that the + * return entity type has @openfed__entityCache via the entityCacheConfigByTypeName lookup. + * + * All ConfigurationData attachments are keyed by the renamed root type name from the iteration + * (e.g., "MyQuery" when the schema declares `schema { query: MyQuery }`) — never by the literal + * "Query"/"Mutation"/"Subscription" — to preserve renamed-root-type semantics. Attachment is + * direct (no buffer-then-attach step) so renamed types can't drift and configs can't silently drop. + */ + validateAndExtractEntityCachingConfigs() { + this.extractEntityCacheDirectives(); + this.processRootFieldCacheDirectives(); + } + + extractEntityCacheDirectives() { + for (const [typeName, parentData] of this.parentDefinitionDataByTypeName) { + if (parentData.kind !== Kind.OBJECT_TYPE_DEFINITION) { + continue; + } + const entityCacheDirectives = parentData.directivesByName.get(ENTITY_CACHE); + if (!entityCacheDirectives) { + continue; + } + if (!this.keyFieldSetDatasByTypeName.has(typeName)) { + this.errors.push( + invalidDirectiveError(ENTITY_CACHE, typeName, FIRST_ORDINAL, [entityCacheWithoutKeyErrorMessage(typeName)]), + ); + continue; + } + const directive = entityCacheDirectives[0]; + const maxAgeSeconds = this.extractCacheIntArg(directive, MAX_AGE) ?? 0; + const notFoundCacheTtlSeconds = this.extractCacheIntArg(directive, NEGATIVE_CACHE_TTL) ?? 0; + const includeHeaders = this.extractCacheBoolArg(directive, INCLUDE_HEADERS); + const partialCacheLoad = this.extractCacheBoolArg(directive, PARTIAL_CACHE_LOAD); + const shadowMode = this.extractCacheBoolArg(directive, SHADOW_MODE); + if (maxAgeSeconds <= 0) { + this.errors.push( + invalidDirectiveError(ENTITY_CACHE, typeName, FIRST_ORDINAL, [ + maxAgeNotPositiveIntegerErrorMessage(ENTITY_CACHE, maxAgeSeconds), + ]), + ); + continue; + } + if (notFoundCacheTtlSeconds < 0) { + this.errors.push( + invalidDirectiveError(ENTITY_CACHE, typeName, FIRST_ORDINAL, [ + negativeCacheTTLNotNonNegativeIntegerErrorMessage(ENTITY_CACHE, notFoundCacheTtlSeconds), + ]), + ); + continue; + } + const config: EntityCacheConfig = { + typeName, + maxAgeSeconds, + notFoundCacheTtlSeconds, + includeHeaders, + partialCacheLoad, + shadowMode, + }; + this.entityCacheConfigByTypeName.set(typeName, config); + const configData = this.getCacheConfigurationData(typeName, true); + if (!configData.entityCacheConfigurations) { + configData.entityCacheConfigurations = []; + } + configData.entityCacheConfigurations.push(config); + } + } + + processRootFieldCacheDirectives() { + for (const [parentTypeName, parentData] of this.parentDefinitionDataByTypeName) { + if (parentData.kind !== Kind.OBJECT_TYPE_DEFINITION) { + continue; + } + const operationType = this.getOperationTypeNodeForRootTypeName(parentTypeName); + if (!operationType) { + continue; + } + + for (const [fieldName, fieldData] of parentData.fieldDataByName) { + const fieldCoords = `${parentTypeName}.${fieldName}`; + const hasQueryCache = fieldData.directivesByName.has(QUERY_CACHE); + const hasCacheInvalidate = fieldData.directivesByName.has(CACHE_INVALIDATE); + const hasCachePopulate = fieldData.directivesByName.has(CACHE_POPULATE); + + if (hasCacheInvalidate && hasCachePopulate) { + this.errors.push( + invalidDirectiveError(CACHE_INVALIDATE, fieldCoords, FIRST_ORDINAL, [ + cacheInvalidateAndPopulateMutualExclusionErrorMessage(fieldCoords), + ]), + ); + continue; + } + + if (hasQueryCache) { + this.extractQueryCacheConfig(parentTypeName, fieldName, fieldData, operationType); + } + if (hasCacheInvalidate) { + this.extractCacheInvalidateConfig(parentTypeName, fieldName, fieldData, operationType); + } + if (hasCachePopulate) { + this.extractCachePopulateConfig(parentTypeName, fieldName, fieldData, operationType); + } + this.validateIsDirectivePlacement(fieldCoords, fieldData, hasQueryCache); + } + } + } + + extractQueryCacheConfig( + parentTypeName: string, + fieldName: string, + fieldData: FieldData, + operationType: OperationTypeNode, + ) { + const fieldCoords = `${parentTypeName}.${fieldName}`; + if (operationType !== OperationTypeNode.QUERY) { + this.errors.push( + invalidDirectiveError(QUERY_CACHE, fieldCoords, FIRST_ORDINAL, [ + queryCacheOnNonQueryFieldErrorMessage(fieldCoords), + ]), + ); + return; + } + const returnTypeName = getTypeNodeNamedTypeName(fieldData.node.type); + if (!this.keyFieldSetDatasByTypeName.has(returnTypeName)) { + this.errors.push( + invalidDirectiveError(QUERY_CACHE, fieldCoords, FIRST_ORDINAL, [ + queryCacheOnNonEntityReturnTypeErrorMessage(fieldCoords, returnTypeName), + ]), + ); + return; + } + const queryCacheDirective = fieldData.directivesByName.get(QUERY_CACHE)![0]; + const maxAgeSeconds = this.extractCacheIntArg(queryCacheDirective, MAX_AGE) ?? 0; + const includeHeaders = this.extractCacheBoolArg(queryCacheDirective, INCLUDE_HEADERS); + const shadowModeValue = this.extractCacheBoolArg(queryCacheDirective, SHADOW_MODE); + if (maxAgeSeconds <= 0) { + this.errors.push( + invalidDirectiveError(QUERY_CACHE, fieldCoords, FIRST_ORDINAL, [ + maxAgeNotPositiveIntegerErrorMessage(QUERY_CACHE, maxAgeSeconds), + ]), + ); + return; + } + + // Bug (a): the return entity must have @openfed__entityCache — otherwise there is no L1/L2 + // backing store for queryCache to read from. Warn and skip extraction. + // The warning is only actionable when the return type is an OBJECT — @openfed__entityCache is + // OBJECT-only (extractEntityCacheDirectives() skips interfaces/unions), so emitting the warning + // for an interface/union return would point the user at an impossible remediation. For those + // cases we skip the prereq check; the mapping pipeline handles the non-object path. + const returnTypeData = this.parentDefinitionDataByTypeName.get(returnTypeName); + const isObjectReturn = returnTypeData?.kind === Kind.OBJECT_TYPE_DEFINITION; + if (isObjectReturn && !this.entityCacheConfigByTypeName.has(returnTypeName)) { + this.warnings.push( + queryCacheReturnEntityMissingEntityCacheWarning({ + subgraphName: this.subgraphName, + fieldCoords, + entityType: returnTypeName, + }), + ); + return; + } + + const isListReturn = isTypeNodeListType(fieldData.node.type); + const keyFieldSets = this.keyFieldSetDatasByTypeName.get(returnTypeName); + const mappings = this.buildArgumentKeyMappings(fieldData, fieldCoords, returnTypeName, keyFieldSets, isListReturn); + + const configData = this.getCacheConfigurationData(parentTypeName, false); + if (!configData.rootFieldCacheConfigurations) { + configData.rootFieldCacheConfigurations = []; + } + configData.rootFieldCacheConfigurations.push({ + fieldName, + maxAgeSeconds, + includeHeaders, + shadowMode: shadowModeValue, + entityTypeName: returnTypeName, + entityKeyMappings: mappings, + }); + } + + extractCacheInvalidateConfig( + parentTypeName: string, + fieldName: string, + fieldData: FieldData, + operationType: OperationTypeNode, + ) { + const fieldCoords = `${parentTypeName}.${fieldName}`; + if (operationType !== OperationTypeNode.MUTATION && operationType !== OperationTypeNode.SUBSCRIPTION) { + this.errors.push( + invalidDirectiveError(CACHE_INVALIDATE, fieldCoords, FIRST_ORDINAL, [ + cacheInvalidateOnNonMutationSubscriptionFieldErrorMessage(fieldCoords), + ]), + ); + return; + } + const returnTypeName = getTypeNodeNamedTypeName(fieldData.node.type); + if (!this.keyFieldSetDatasByTypeName.has(returnTypeName) || !this.entityCacheConfigByTypeName.has(returnTypeName)) { + this.errors.push( + invalidDirectiveError(CACHE_INVALIDATE, fieldCoords, FIRST_ORDINAL, [ + cacheInvalidateOnNonEntityReturnTypeErrorMessage(fieldCoords, returnTypeName), + ]), + ); + return; + } + const configData = this.getCacheConfigurationData(parentTypeName, false); + if (!configData.cacheInvalidateConfigurations) { + configData.cacheInvalidateConfigurations = []; + } + configData.cacheInvalidateConfigurations.push({ + fieldName, + operationType: operationType === OperationTypeNode.MUTATION ? MUTATION : SUBSCRIPTION, + entityTypeName: returnTypeName, + }); + } + + extractCachePopulateConfig( + parentTypeName: string, + fieldName: string, + fieldData: FieldData, + operationType: OperationTypeNode, + ) { + const fieldCoords = `${parentTypeName}.${fieldName}`; + if (operationType !== OperationTypeNode.MUTATION && operationType !== OperationTypeNode.SUBSCRIPTION) { + this.errors.push( + invalidDirectiveError(CACHE_POPULATE, fieldCoords, FIRST_ORDINAL, [ + cachePopulateOnNonMutationSubscriptionFieldErrorMessage(fieldCoords), + ]), + ); + return; + } + const returnTypeName = getTypeNodeNamedTypeName(fieldData.node.type); + if (!this.keyFieldSetDatasByTypeName.has(returnTypeName) || !this.entityCacheConfigByTypeName.has(returnTypeName)) { + this.errors.push( + invalidDirectiveError(CACHE_POPULATE, fieldCoords, FIRST_ORDINAL, [ + cachePopulateOnNonEntityReturnTypeErrorMessage(fieldCoords, returnTypeName), + ]), + ); + return; + } + // maxAge is optional for @openfed__cachePopulate; when absent the router falls back to the entity's + // @openfed__entityCache TTL. When provided, it must be positive. + const cachePopulateDirective = fieldData.directivesByName.get(CACHE_POPULATE)![0]; + const maxAgeRaw = this.extractCacheIntArg(cachePopulateDirective, MAX_AGE); + let maxAgeSeconds: number | undefined; + if (maxAgeRaw !== undefined) { + if (maxAgeRaw <= 0) { + this.errors.push( + invalidDirectiveError(CACHE_POPULATE, fieldCoords, FIRST_ORDINAL, [ + maxAgeNotPositiveIntegerErrorMessage(CACHE_POPULATE, maxAgeRaw), + ]), + ); + return; + } + maxAgeSeconds = maxAgeRaw; + } + const configData = this.getCacheConfigurationData(parentTypeName, false); + if (!configData.cachePopulateConfigurations) { + configData.cachePopulateConfigurations = []; + } + configData.cachePopulateConfigurations.push({ + fieldName, + operationType: operationType === OperationTypeNode.MUTATION ? MUTATION : SUBSCRIPTION, + entityTypeName: returnTypeName, + maxAgeSeconds, + }); + } + + // Enforces the top-level placement rule for @openfed__is: the field must also declare @openfed__queryCache. + // Deeper @openfed__is validation (path resolution, composite decomposition, type checking) lives in + // buildArgumentKeyMappings. + validateIsDirectivePlacement(fieldCoords: string, fieldData: FieldData, hasQueryCache: boolean) { + if (hasQueryCache) { + return; + } + for (const [argumentName, argumentData] of fieldData.argumentDataByName) { + if (!argumentData.directivesByName.has(IS)) { + continue; + } + this.errors.push( + invalidDirectiveError(IS, `${fieldCoords}(${argumentName}: ...)`, FIRST_ORDINAL, [ + isWithoutQueryCacheErrorMessage(argumentName, fieldCoords), + ]), + ); + } + } + + // Extracts key field info from a key's DocumentNode AST. + // Returns an array of { path: "store.id", typeNode: TypeNode } for each leaf field. + extractKeyFieldInfos( + documentNode: DocumentNode, + entityTypeName: string, + ): Array<{ path: string; typeNode: TypeNode }> { + const result: Array<{ path: string; typeNode: TypeNode }> = []; + const operationDef = documentNode.definitions[0]; + if (!operationDef || !('selectionSet' in operationDef) || !operationDef.selectionSet) { + return result; + } + + const walkSelections = (selections: readonly any[], currentTypeName: string, pathPrefix: string) => { + for (const selection of selections) { + if (selection.kind !== Kind.FIELD) { + continue; + } + const fieldName = selection.name.value; + const fieldPath = pathPrefix ? `${pathPrefix}.${fieldName}` : fieldName; + + // Look up the field type on the current parent type + const parentData = this.parentDefinitionDataByTypeName.get(currentTypeName); + if (!parentData || !('fieldDataByName' in parentData)) { + continue; + } + const fieldData = parentData.fieldDataByName.get(fieldName); + if (!fieldData) { + continue; + } + + if (selection.selectionSet && selection.selectionSet.selections.length > 0) { + // Nested: recurse into the named type + const nestedTypeName = getTypeNodeNamedTypeName(fieldData.node.type); + walkSelections(selection.selectionSet.selections, nestedTypeName, fieldPath); + } else { + // Leaf field + result.push({ path: fieldPath, typeNode: fieldData.node.type }); + } + } + }; + + walkSelections(operationDef.selectionSet.selections, entityTypeName, ''); + return result; + } + + // Returns the named type name after stripping NonNull and List wrappers. + getNamedTypeName(typeNode: TypeNode): string { + if (typeNode.kind === Kind.NAMED_TYPE) { + return typeNode.name.value; + } + return this.getNamedTypeName(typeNode.type); + } + + // Unwraps one layer of list: [T!]! -> T!, [[T!]!]! -> [T!]! + unwrapListType(typeNode: TypeNode): TypeNode { + if (typeNode.kind === Kind.LIST_TYPE) { + return typeNode.type; + } + if (typeNode.kind === Kind.NON_NULL_TYPE) { + const inner = this.unwrapListType(typeNode.type); + // If inner changed (was a list), return the unwrapped version without non-null wrapper + if (inner !== typeNode.type) { + return inner; + } + } + return typeNode; + } + + // Compare named types (unwrapping NonNull wrappers only, not list wrappers). + namedTypesMatch(a: TypeNode, b: TypeNode): boolean { + return this.getNamedTypeName(a) === this.getNamedTypeName(b); + } + + // Check if both types have matching list structure. + listStructureMatches(a: TypeNode, b: TypeNode): boolean { + const aIsList = isTypeNodeListType(a); + const bIsList = isTypeNodeListType(b); + return aIsList === bIsList; + } + + // Structurally compare two TypeNodes: named type AND list/NonNull wrapping must match. + // Used at nested composite-key leaves where a printer-level mismatch (e.g., "[ID!]!" vs "ID") + // must be rejected even though the named type ("ID") agrees. + typesMatchIncludingListShape(expected: TypeNode, got: TypeNode): boolean { + if (expected.kind !== got.kind) { + return false; + } + if (expected.kind === Kind.NAMED_TYPE) { + return expected.name.value === (got as typeof expected).name.value; + } + if (expected.kind === Kind.NON_NULL_TYPE || expected.kind === Kind.LIST_TYPE) { + return this.typesMatchIncludingListShape(expected.type, (got as typeof expected).type); + } + return false; + } + + // Get @openfed__is field value from an argument's directives. + getIsFieldValue(argumentData: InputValueData): string | undefined { + const isDirectives = argumentData.directivesByName.get(IS); + if (!isDirectives || isDirectives.length < 1) { + return undefined; + } + const isDirective = isDirectives[0]; + if (isDirective.arguments) { + for (const arg of isDirective.arguments) { + if (arg.name.value === FIELDS && arg.value.kind === Kind.STRING) { + return (arg.value as StringValueNode).value; + } + } + } + return undefined; + } + + // Validates and builds nested input object mappings against key field infos. + // Returns field mappings or null on error (errors already pushed). + validateNestedInputObjectMapping( + argumentName: string, + fieldCoords: string, + entityTypeName: string, + keyFieldInfos: Array<{ path: string; typeNode: TypeNode }>, + normalizedFieldSet: string, + inputTypeName: string, + argumentPathPrefix: string[], + isBatch: boolean, + isNested: boolean, + entityKeyPathPrefix: string = '', + ): FieldMappingConfig[] | null { + const inputData = this.parentDefinitionDataByTypeName.get(inputTypeName); + if (!inputData || inputData.kind !== Kind.INPUT_OBJECT_TYPE_DEFINITION) { + if (isNested) { + // Mid-recursion the key demands a deeper selection (e.g. "store { id }"), but the + // input field type is scalar/unknown. Callers treat null as "error already pushed", + // so bailing silently here would discard the key without any diagnostic. + this.errors.push( + invalidDirectiveError(QUERY_CACHE, fieldCoords, FIRST_ORDINAL, [ + nestedKeyRequiresInputObjectErrorMessage( + argumentName, + fieldCoords, + normalizedFieldSet, + entityTypeName, + inputTypeName, + entityKeyPathPrefix, + ), + ]), + ); + } + return null; + } + + // Group key field infos by top-level field name for the current level + const topLevelGroups = new Map>(); + for (const info of keyFieldInfos) { + const dotIndex = info.path.indexOf(LITERAL_PERIOD); + const topField = dotIndex >= 0 ? info.path.substring(0, dotIndex) : info.path; + const restPath = dotIndex >= 0 ? info.path.substring(dotIndex + 1) : ''; + if (!topLevelGroups.has(topField)) { + topLevelGroups.set(topField, []); + } + topLevelGroups.get(topField)!.push({ ...info, restPath }); + } + + const fieldMappings: FieldMappingConfig[] = []; + + for (const [topField, infos] of topLevelGroups) { + const inputFieldData = inputData.inputValueDataByName.get(topField); + if (!inputFieldData) { + // Missing field in input type + if (isNested) { + this.errors.push( + invalidDirectiveError(QUERY_CACHE, fieldCoords, FIRST_ORDINAL, [ + nestedInputObjectMissingFieldErrorMessage( + argumentName, + fieldCoords, + normalizedFieldSet, + entityTypeName, + inputTypeName, + topField, + ), + ]), + ); + } else { + this.errors.push( + invalidDirectiveError(IS, `${fieldCoords}(${argumentName}: ...)`, FIRST_ORDINAL, [ + inputObjectCompositeMissingFieldErrorMessage( + argumentName, + fieldCoords, + normalizedFieldSet, + entityTypeName, + inputTypeName, + topField, + ), + ]), + ); + } + return null; + } + + const fullEntityKeyPath = entityKeyPathPrefix ? `${entityKeyPathPrefix}.${topField}` : topField; + const hasNestedFields = infos.some((i) => i.restPath !== ''); + if (hasNestedFields) { + // Recurse into nested input object + const nestedInfos = infos.map((i) => ({ path: i.restPath, typeNode: i.typeNode })); + const nestedInputTypeName = this.getNamedTypeName(inputFieldData.type); + const nestedMappings = this.validateNestedInputObjectMapping( + argumentName, + fieldCoords, + entityTypeName, + nestedInfos, + normalizedFieldSet, + nestedInputTypeName, + [...argumentPathPrefix, topField], + isBatch, + true, + fullEntityKeyPath, + ); + if (!nestedMappings) { + return null; + } + fieldMappings.push(...nestedMappings); + } else { + // Leaf: check type match — both named type AND list/NonNull wrapping must agree. + // Bug (c): prior code compared only named types, letting `[ID!]!` be satisfied by `ID`. + const keyTypeNode = infos[0].typeNode; + if (!this.typesMatchIncludingListShape(keyTypeNode, inputFieldData.type)) { + // Resolve the entity field's parent type for the error message + // We need to walk the full entity key path to find the parent of the leaf + const fullPath = entityKeyPathPrefix ? `${entityKeyPathPrefix}.${topField}` : topField; + const pathParts = fullPath.split(LITERAL_PERIOD); + let currentType = entityTypeName; + for (let i = 0; i < pathParts.length - 1; i++) { + const pd = this.parentDefinitionDataByTypeName.get(currentType); + if (pd && 'fieldDataByName' in pd) { + const fd = pd.fieldDataByName.get(pathParts[i]); + if (fd) { + currentType = getTypeNodeNamedTypeName(fd.node.type); + } + } + } + const entityFieldCoords = `${currentType}.${pathParts[pathParts.length - 1]}`; + if (isNested) { + this.errors.push( + invalidDirectiveError(QUERY_CACHE, fieldCoords, FIRST_ORDINAL, [ + nestedInputObjectTypeMismatchErrorMessage( + argumentName, + fieldCoords, + normalizedFieldSet, + entityTypeName, + inputTypeName, + topField, + printTypeNode(inputFieldData.node.type), + entityFieldCoords, + printTypeNode(keyTypeNode), + ), + ]), + ); + } else { + this.errors.push( + invalidDirectiveError(IS, `${fieldCoords}(${argumentName}: ...)`, FIRST_ORDINAL, [ + inputObjectCompositeTypeMismatchErrorMessage( + argumentName, + fieldCoords, + normalizedFieldSet, + entityTypeName, + inputTypeName, + topField, + printTypeNode(inputFieldData.node.type), + entityFieldCoords, + printTypeNode(keyTypeNode), + ), + ]), + ); + } + return null; + } + const mapping: FieldMappingConfig = { + entityKeyField: fullEntityKeyPath, + argumentPath: [...argumentPathPrefix, topField], + }; + if (isBatch) { + mapping.isBatch = true; + } + fieldMappings.push(mapping); + } + } + + return fieldMappings; + } + + // The main mapping builder. Evaluates each @key independently and emits all satisfiable keys. + buildArgumentKeyMappings( + fieldData: FieldData, + fieldCoords: string, + entityTypeName: string, + keyFieldSets: Map | undefined, + isListReturn: boolean, + ): EntityKeyMappingConfig[] { + if (!keyFieldSets || keyFieldSets.size === 0) { + return []; + } + + type ArgumentInfo = { + name: string; + data: InputValueData; + isFieldValue: string | undefined; // @openfed__is(fields: "...") value + isList: boolean; + typeNode: TypeNode; + }; + + const argumentInfos: ArgumentInfo[] = []; + for (const [argumentName, argumentData] of fieldData.argumentDataByName) { + argumentInfos.push({ + name: argumentName, + data: argumentData, + isFieldValue: this.getIsFieldValue(argumentData), + isList: isTypeNodeListType(argumentData.type), + typeNode: argumentData.type, + }); + } + + if (this.hasAnyExplicitIs(fieldData)) { + return this.buildExplicitMappings(fieldCoords, entityTypeName, keyFieldSets, isListReturn, argumentInfos); + } + return this.buildAutoMappings(fieldCoords, entityTypeName, keyFieldSets, isListReturn, argumentInfos); + } + + hasAnyExplicitIs(fieldData: FieldData): boolean { + for (const [, argumentData] of fieldData.argumentDataByName) { + const isDirectives = argumentData.directivesByName.get(IS); + if (isDirectives && isDirectives.length > 0) { + return true; + } + } + return false; + } + + buildExplicitMappings( + fieldCoords: string, + entityTypeName: string, + keyFieldSets: Map, + isListReturn: boolean, + argumentInfos: Array<{ + name: string; + data: InputValueData; + isFieldValue: string | undefined; + isList: boolean; + typeNode: TypeNode; + }>, + ): EntityKeyMappingConfig[] { + // Collect all @openfed__is field values and their infos across ALL keys + const allKeyFieldInfosByKey = new Map>(); + // Build a set of ALL key field paths across all keys + const allKeyFieldPaths = new Set(); + // Also build a map from field path -> key field info for type lookups + const fieldInfoByPath = new Map(); + // Track which fields exist on the entity (not necessarily key fields) + const entityFieldNames = new Set(); + const entityParentData = this.parentDefinitionDataByTypeName.get(entityTypeName); + if (entityParentData && 'fieldDataByName' in entityParentData) { + for (const fname of entityParentData.fieldDataByName.keys()) { + entityFieldNames.add(fname); + } + } + + for (const [normalizedFieldSet, keyData] of keyFieldSets) { + const infos = this.extractKeyFieldInfos(keyData.documentNode, entityTypeName); + allKeyFieldInfosByKey.set(normalizedFieldSet, infos); + for (const info of infos) { + allKeyFieldPaths.add(info.path); + fieldInfoByPath.set(info.path, { typeNode: info.typeNode }); + } + } + + // Process each argument with @openfed__is + const explicitMappings: Array<{ + argumentName: string; + isFieldValue: string; + argumentInfo: (typeof argumentInfos)[0]; + }> = []; + const compositeMappings: EntityKeyMappingConfig[] = []; + const mappedKeyFieldToArgumentName = new Map(); + + for (const argInfo of argumentInfos) { + if (!argInfo.isFieldValue) { + continue; + } + + const isFieldValue = argInfo.isFieldValue; + + // Check if @openfed__is targets multiple fields (composite key via input object) + const isCompositeIsSpec = isFieldValue.includes(LITERAL_SPACE); + + if (isCompositeIsSpec) { + const errorCount = this.errors.length; + const mappings = this.buildCompositeIsMapping(fieldCoords, entityTypeName, keyFieldSets, isListReturn, argInfo); + if (this.errors.length > errorCount) { + return []; + } + for (const mapping of mappings) { + for (const fieldMapping of mapping.fieldMappings) { + mappedKeyFieldToArgumentName.set(fieldMapping.entityKeyField, argInfo.name); + } + } + compositeMappings.push(...mappings); + continue; + } + + // Check if the field exists on the entity at all but is not a key field + const topLevelFieldName = isFieldValue.split(LITERAL_PERIOD)[0]; + if (!allKeyFieldPaths.has(isFieldValue)) { + if (entityFieldNames.has(topLevelFieldName) && !isFieldValue.includes(LITERAL_PERIOD)) { + // Field exists but is not a key field + this.errors.push( + invalidDirectiveError(IS, `${fieldCoords}(${argInfo.name}: ...)`, FIRST_ORDINAL, [ + nonKeyFieldSpecErrorMessage(argInfo.name, fieldCoords, isFieldValue, entityTypeName), + ]), + ); + } else { + this.errors.push( + invalidDirectiveError(IS, `${fieldCoords}(${argInfo.name}: ...)`, FIRST_ORDINAL, [ + isReferencesUnknownKeyFieldErrorMessage(isFieldValue, argInfo.name, fieldCoords, entityTypeName), + ]), + ); + } + return []; + } + + // Duplicate check + if (mappedKeyFieldToArgumentName.has(isFieldValue)) { + this.errors.push( + invalidDirectiveError(IS, `${fieldCoords}(${argInfo.name}: ...)`, FIRST_ORDINAL, [ + duplicateKeyFieldMappingErrorMessage(fieldCoords, isFieldValue), + ]), + ); + return []; + } + + const keyFieldTypeNode = fieldInfoByPath.get(isFieldValue)!.typeNode; + const argTypeNode = argInfo.typeNode; + + // Type checking + if (isListReturn) { + // Batch mode + if (isTypeNodeListType(keyFieldTypeNode)) { + // Key field is a list - need list-of-lists argument + if (!argInfo.isList) { + // Scalar arg to list key in batch + this.errors.push( + invalidDirectiveError(IS, `${fieldCoords}(${argInfo.name}: ...)`, FIRST_ORDINAL, [ + batchListValuedKeyRequiresNestedListsErrorMessage( + fieldCoords, + isFieldValue, + entityTypeName, + `a scalar tag of type "${printTypeNode(argTypeNode)}"`, + ), + ]), + ); + return []; + } + // List arg but is it list-of-lists? + const unwrapped = this.unwrapListType(argTypeNode); + if (!isTypeNodeListType(unwrapped)) { + // Single list, not list of lists + this.errors.push( + invalidDirectiveError(IS, `${fieldCoords}(${argInfo.name}: ...)`, FIRST_ORDINAL, [ + batchListValuedKeyRequiresNestedListsErrorMessage( + fieldCoords, + isFieldValue, + entityTypeName, + `a single tag list of type "${printTypeNode(argTypeNode)}"`, + ), + ]), + ); + return []; + } + // List of lists - check inner type matches + const innerType = this.unwrapListType(unwrapped); + if (!this.namedTypesMatch(innerType, keyFieldTypeNode)) { + this.errors.push( + invalidDirectiveError(IS, `${fieldCoords}(${argInfo.name}: ...)`, FIRST_ORDINAL, [ + explicitTypeMismatchErrorMessage( + argInfo.name, + fieldCoords, + printTypeNode(argTypeNode), + isFieldValue, + entityTypeName, + printTypeNode(keyFieldTypeNode), + ), + ]), + ); + return []; + } + } else { + // Key field is scalar - need list argument with matching element type + if (argInfo.isList) { + // Check element type + const unwrapped = this.unwrapListType(argTypeNode); + if (!this.namedTypesMatch(unwrapped, keyFieldTypeNode)) { + this.errors.push( + invalidDirectiveError(IS, `${fieldCoords}(${argInfo.name}: ...)`, FIRST_ORDINAL, [ + explicitTypeMismatchErrorMessage( + argInfo.name, + fieldCoords, + printTypeNode(argTypeNode), + isFieldValue, + entityTypeName, + printTypeNode(keyFieldTypeNode), + ), + ]), + ); + return []; + } + } else { + // Scalar arg in batch mode - could still be valid as a scalar @openfed__is, we'll check later + } + } + } else { + // Singular mode + const argIsList = argInfo.isList; + const keyIsList = isTypeNodeListType(keyFieldTypeNode); + + if (argIsList && !keyIsList) { + // List arg to scalar key on singular return + this.errors.push( + invalidDirectiveError(IS, `${fieldCoords}(${argInfo.name}: ...)`, FIRST_ORDINAL, [ + listArgumentToScalarKeySpecErrorMessage( + argInfo.name, + fieldCoords, + printTypeNode(argTypeNode), + isFieldValue, + entityTypeName, + printTypeNode(keyFieldTypeNode), + ), + ]), + ); + return []; + } + + if (!argIsList && keyIsList) { + // Scalar arg to list key on singular return + this.errors.push( + invalidDirectiveError(IS, `${fieldCoords}(${argInfo.name}: ...)`, FIRST_ORDINAL, [ + scalarArgumentToListKeySpecErrorMessage( + argInfo.name, + fieldCoords, + printTypeNode(argTypeNode), + isFieldValue, + entityTypeName, + printTypeNode(keyFieldTypeNode), + ), + ]), + ); + return []; + } + + // Named type comparison (handles both scalar-scalar and list-list) + if (!this.namedTypesMatch(argTypeNode, keyFieldTypeNode)) { + this.errors.push( + invalidDirectiveError(IS, `${fieldCoords}(${argInfo.name}: ...)`, FIRST_ORDINAL, [ + explicitTypeMismatchErrorMessage( + argInfo.name, + fieldCoords, + printTypeNode(argTypeNode), + isFieldValue, + entityTypeName, + printTypeNode(keyFieldTypeNode), + ), + ]), + ); + return []; + } + } + + // Bug (b): @openfed__is(fields: "X") on argument "X" duplicates what auto-mapping would produce. + // This is a lint/noise issue — mapping is still extracted. + // + // Only emit the warning when auto-mapping WOULD have produced the same mapping: + // - Singular return: auto-map requires matching list shape; we already verified named types + // and list shape above, so if arg/key list shape agrees auto-map would succeed. + // - List return: auto-map only batch-maps when the arg is a list AND the key field is scalar + // (argIsList && !keyIsList). When the key field is list-valued, auto-map skips the field + // (see buildAutoMappings: keyIsList path on isListReturn marks keyFullyMapped=false), so + // @openfed__is is REQUIRED and must not be flagged redundant. + if (argInfo.name === isFieldValue) { + const keyIsList = isTypeNodeListType(keyFieldTypeNode); + const argIsList = argInfo.isList; + let autoMapWouldProduceSameMapping: boolean; + if (!isListReturn) { + autoMapWouldProduceSameMapping = argIsList === keyIsList; + } else { + autoMapWouldProduceSameMapping = argIsList && !keyIsList; + } + if (autoMapWouldProduceSameMapping) { + this.warnings.push( + redundantIsDirectiveWarning({ + subgraphName: this.subgraphName, + argumentName: argInfo.name, + fieldCoords, + keyField: isFieldValue, + entityType: entityTypeName, + }), + ); + } + } + + mappedKeyFieldToArgumentName.set(isFieldValue, argInfo.name); + explicitMappings.push({ argumentName: argInfo.name, isFieldValue, argumentInfo: argInfo }); + } + + if (explicitMappings.length === 0) { + return compositeMappings; + } + + // Check for duplicate: argument name matches a key field that's already explicitly mapped + for (const argInfo of argumentInfos) { + if (argInfo.isFieldValue) { + continue; // Skip @openfed__is arguments + } + const sourceArgumentName = mappedKeyFieldToArgumentName.get(argInfo.name); + if (sourceArgumentName !== undefined) { + // This argument would auto-map to a key field that's already explicitly mapped. + // The source argument is looked up via the map because composite @openfed__is + // mappings register leaf key fields that no argument's isFieldValue equals. + this.errors.push( + invalidDirectiveError(IS, `${fieldCoords}(${sourceArgumentName}: ...)`, FIRST_ORDINAL, [ + duplicateKeyFieldMappingErrorMessage(fieldCoords, argInfo.name), + ]), + ); + return []; + } + } + + // Check for batch mode: all explicit mappings on list return + if (isListReturn) { + // Check for extra non-key arguments FIRST (not @openfed__is and not a key field in any key) + const extraArgs = argumentInfos.filter((a) => !a.isFieldValue && !allKeyFieldPaths.has(a.name)); + if (extraArgs.length > 0) { + const firstExplicit = explicitMappings[0]; + this.errors.push( + invalidDirectiveError(IS, `${fieldCoords}(${firstExplicit.argumentName}: ...)`, FIRST_ORDINAL, [ + explicitBatchAdditionalNonKeyArgumentErrorMessage( + fieldCoords, + firstExplicit.argumentName, + firstExplicit.isFieldValue, + entityTypeName, + extraArgs[0].name, + ), + ]), + ); + return []; + } + + // Check if all explicit args are scalars + const allScalar = explicitMappings.every((m) => !m.argumentInfo.isList); + const listMappings = explicitMappings.filter((m) => m.argumentInfo.isList); + + if (allScalar) { + this.errors.push( + invalidDirectiveError(IS, `${fieldCoords}(${explicitMappings[0].argumentName}: ...)`, FIRST_ORDINAL, [ + explicitScalarArgumentsCannotEstablishBatchMappingErrorMessage(fieldCoords, entityTypeName), + ]), + ); + return []; + } + + if (listMappings.length > 1) { + this.errors.push( + invalidDirectiveError(QUERY_CACHE, fieldCoords, FIRST_ORDINAL, [ + multipleListArgumentsBatchFactoryMessage(fieldCoords, entityTypeName), + ]), + ); + return []; + } + } + + // Check for extra non-key arguments globally (args not @openfed__is and not a key field in any key) + const globalExtraArgs = argumentInfos.filter((a) => !a.isFieldValue && !allKeyFieldPaths.has(a.name)); + if (globalExtraArgs.length > 0) { + if (!isListReturn) { + // Find which key the explicit mappings target + let targetKeyNormalized: string | undefined; + for (const [normalizedFieldSet] of keyFieldSets) { + const keyInfos = allKeyFieldInfosByKey.get(normalizedFieldSet)!; + const keyPaths = new Set(keyInfos.map((i) => i.path)); + if (explicitMappings.every((m) => keyPaths.has(m.isFieldValue))) { + targetKeyNormalized = normalizedFieldSet; + break; + } + } + + if (explicitMappings.length === 1 && targetKeyNormalized && !targetKeyNormalized.includes(LITERAL_SPACE)) { + this.errors.push( + invalidDirectiveError(IS, `${fieldCoords}(${explicitMappings[0].argumentName}: ...)`, FIRST_ORDINAL, [ + explicitSingularAdditionalNonKeyArgumentErrorMessage( + fieldCoords, + explicitMappings[0].argumentName, + explicitMappings[0].isFieldValue, + entityTypeName, + globalExtraArgs[0].name, + ), + ]), + ); + } else if (targetKeyNormalized) { + const isArgNames = explicitMappings.map((m) => m.argumentName); + this.errors.push( + invalidDirectiveError(IS, `${fieldCoords}(${isArgNames[0]}: ...)`, FIRST_ORDINAL, [ + explicitCompositeAdditionalNonKeyArgumentErrorMessage( + fieldCoords, + isArgNames[0], + isArgNames[1] || isArgNames[0], + targetKeyNormalized, + entityTypeName, + globalExtraArgs[0].name, + ), + ]), + ); + } + return []; + } else { + const firstExplicit = explicitMappings[0]; + this.errors.push( + invalidDirectiveError(IS, `${fieldCoords}(${firstExplicit.argumentName}: ...)`, FIRST_ORDINAL, [ + explicitBatchAdditionalNonKeyArgumentErrorMessage( + fieldCoords, + firstExplicit.argumentName, + firstExplicit.isFieldValue, + entityTypeName, + globalExtraArgs[0].name, + ), + ]), + ); + return []; + } + } + + // Now try to find satisfiable keys + const results: EntityKeyMappingConfig[] = []; + for (const normalizedFieldSet of keyFieldSets.keys()) { + const keyInfos = allKeyFieldInfosByKey.get(normalizedFieldSet)!; + const keyPaths = new Set(keyInfos.map((i) => i.path)); + + // Check which explicit mappings target this key + const explicitForThisKey = explicitMappings.filter((m) => keyPaths.has(m.isFieldValue)); + + // Check that ALL fields of this key are mapped (explicit or auto) + const autoMappedForKey: Array<{ argumentName: string; keyPath: string; argInfo: (typeof argumentInfos)[0] }> = []; + const unmappedFields: string[] = []; + let keyFullySatisfied = true; + + for (const info of keyInfos) { + // Is it covered by an explicit mapping? + if (explicitForThisKey.some((m) => m.isFieldValue === info.path)) { + continue; + } + // Try auto-mapping + const autoMapped = argumentInfos.find((a) => !a.isFieldValue && a.name === info.path); + if ( + autoMapped && + this.namedTypesMatch(autoMapped.typeNode, info.typeNode) && + isTypeNodeListType(autoMapped.typeNode) === isTypeNodeListType(info.typeNode) + ) { + autoMappedForKey.push({ argumentName: autoMapped.name, keyPath: info.path, argInfo: autoMapped }); + } else { + unmappedFields.push(info.path); + keyFullySatisfied = false; + } + } + + if (!keyFullySatisfied) { + // If this key has explicit mappings targeting it but is incomplete, error + if (explicitForThisKey.length > 0 && unmappedFields.length > 0) { + this.errors.push( + invalidDirectiveError(IS, `${fieldCoords}(${explicitForThisKey[0].argumentName}: ...)`, FIRST_ORDINAL, [ + explicitIncompleteCompositeKeyErrorMessage( + fieldCoords, + explicitForThisKey[0].argumentName, + explicitForThisKey[0].isFieldValue, + entityTypeName, + normalizedFieldSet, + unmappedFields[0], + ), + ]), + ); + return []; + } + continue; + } + + // Build field mappings in key field info order + const fieldMappings: FieldMappingConfig[] = []; + for (const info of keyInfos) { + const explicitMatch = explicitForThisKey.find((m) => m.isFieldValue === info.path); + if (explicitMatch) { + const mapping: FieldMappingConfig = { + entityKeyField: explicitMatch.isFieldValue, + argumentPath: [explicitMatch.argumentName], + }; + if (isListReturn && explicitMatch.argumentInfo.isList) { + mapping.isBatch = true; + } + fieldMappings.push(mapping); + continue; + } + const autoMatch = autoMappedForKey.find((a) => a.keyPath === info.path); + if (autoMatch) { + const mapping: FieldMappingConfig = { + entityKeyField: autoMatch.keyPath, + argumentPath: [autoMatch.argumentName], + }; + if (isListReturn && autoMatch.argInfo.isList) { + mapping.isBatch = true; + } + fieldMappings.push(mapping); + } + } + + if (fieldMappings.length > 0) { + results.push({ entityTypeName, fieldMappings }); + } + } + + // Each key remains its own EntityKeyMappingConfig — the router evaluates them + // independently (OR semantics). Do NOT merge single-field results. + return [...compositeMappings, ...results]; + } + + buildCompositeIsMapping( + fieldCoords: string, + entityTypeName: string, + keyFieldSets: Map, + isListReturn: boolean, + argInfo: { + name: string; + data: InputValueData; + isFieldValue: string | undefined; + isList: boolean; + typeNode: TypeNode; + }, + ): EntityKeyMappingConfig[] { + const isFieldValue = argInfo.isFieldValue!; + const { documentNode } = safeParse('{' + isFieldValue + '}'); + const normalizedIsFieldValue = documentNode ? getNormalizedFieldSet(documentNode) : isFieldValue; + + // Find the matching key + for (const [normalizedFieldSet, keyData] of keyFieldSets) { + if (normalizedFieldSet !== normalizedIsFieldValue) { + continue; + } + + const keyInfos = this.extractKeyFieldInfos(keyData.documentNode, entityTypeName); + const argTypeName = this.getNamedTypeName(argInfo.typeNode); + + // Check if argument is an input object type + const inputData = this.parentDefinitionDataByTypeName.get(argTypeName); + if (!inputData || inputData.kind !== Kind.INPUT_OBJECT_TYPE_DEFINITION) { + // Non-input argument targeting composite key + this.errors.push( + invalidDirectiveError(IS, `${fieldCoords}(${argInfo.name}: ...)`, FIRST_ORDINAL, [ + nonInputArgumentCannotTargetCompositeKeyErrorMessage( + argInfo.name, + fieldCoords, + isFieldValue, + entityTypeName, + printTypeNode(argInfo.typeNode), + ), + ]), + ); + return []; + } + + const isBatch = isListReturn && argInfo.isList; + const isNestedKey = normalizedFieldSet.includes(LITERAL_OPEN_BRACE); + + const fieldMappings = this.validateNestedInputObjectMapping( + argInfo.name, + fieldCoords, + entityTypeName, + keyInfos, + normalizedFieldSet, + argTypeName, + [argInfo.name], + isBatch, + isNestedKey, + ); + + if (!fieldMappings) { + return []; + } + + return [{ entityTypeName, fieldMappings }]; + } + + // Key not found + this.errors.push( + invalidDirectiveError(IS, `${fieldCoords}(${argInfo.name}: ...)`, FIRST_ORDINAL, [ + isReferencesUnknownKeyFieldErrorMessage(isFieldValue, argInfo.name, fieldCoords, entityTypeName), + ]), + ); + return []; + } + + invalidateAutoMappingWithExtraArgument( + argumentInfos: Array<{ name: string }>, + allKeyFieldPaths: Set, + mappedArgumentNames: Set, + isListReturn: boolean, + fieldCoords: string, + entityTypeName: string, + argumentName: string | undefined, + keyField: string | undefined, + emitWarning: boolean = true, + ): boolean { + const extraArgs = argumentInfos.filter((a) => !allKeyFieldPaths.has(a.name) && !mappedArgumentNames.has(a.name)); + if (extraArgs.length < 1 || !argumentName || !keyField) { + return false; + } + if (!emitWarning) { + return true; + } + if (isListReturn) { + this.warnings.push( + autoBatchAdditionalNonKeyArgumentWarning({ + subgraphName: this.subgraphName, + fieldCoords, + argumentName, + keyField, + entityType: entityTypeName, + extraArgument: extraArgs[0].name, + }), + ); + } else { + this.warnings.push( + autoMappingAdditionalNonKeyArgumentWarning({ + subgraphName: this.subgraphName, + argumentName, + fieldCoords, + keyField, + entityType: entityTypeName, + extraArgument: extraArgs[0].name, + }), + ); + } + return true; + } + + buildAutoMappings( + fieldCoords: string, + entityTypeName: string, + keyFieldSets: Map, + isListReturn: boolean, + argumentInfos: Array<{ + name: string; + data: InputValueData; + isFieldValue: string | undefined; + isList: boolean; + typeNode: TypeNode; + }>, + ): EntityKeyMappingConfig[] { + const results: EntityKeyMappingConfig[] = []; + let typeMismatchWarningEmitted = false; + + // Gather ALL key field paths across all keys to determine which args are "non-key" + const allKeyFieldPaths = new Set(); + for (const [, keyData] of keyFieldSets) { + const infos = this.extractKeyFieldInfos(keyData.documentNode, entityTypeName); + for (const info of infos) { + allKeyFieldPaths.add(info.path); + } + } + + // Try nested input object auto-mapping first: + // arguments whose named type is an input object matching a nested key structure. + for (const [normalizedFieldSet, keyData] of keyFieldSets) { + if (!normalizedFieldSet.includes(LITERAL_OPEN_BRACE)) { + continue; // Only for nested keys + } + + const keyInfos = this.extractKeyFieldInfos(keyData.documentNode, entityTypeName); + if (keyInfos.length === 0) { + continue; + } + + // Check if there's an argument whose name matches the top-level field of the key + // and whose type is an input object + const topFields = new Set(); + for (const info of keyInfos) { + const topField = info.path.split(LITERAL_PERIOD)[0]; + topFields.add(topField); + } + + // If there's exactly one top-level field and an argument with that name + if (topFields.size === 1) { + const topFieldName = [...topFields][0]; + const matchingArg = argumentInfos.find((a) => a.name === topFieldName); + if (matchingArg) { + const argTypeName = this.getNamedTypeName(matchingArg.typeNode); + const inputData = this.parentDefinitionDataByTypeName.get(argTypeName); + if (inputData && inputData.kind === Kind.INPUT_OBJECT_TYPE_DEFINITION) { + // Re-root key infos relative to the top field + const nestedInfos = keyInfos.map((info) => ({ + path: info.path.substring(topFieldName.length + 1), + typeNode: info.typeNode, + })); + + const isBatch = isListReturn && matchingArg.isList; + const fieldMappings = this.validateNestedInputObjectMapping( + matchingArg.name, + fieldCoords, + entityTypeName, + nestedInfos, + normalizedFieldSet, + argTypeName, + [matchingArg.name], + isBatch, + true, + topFieldName, + ); + + if (fieldMappings) { + if ( + this.invalidateAutoMappingWithExtraArgument( + argumentInfos, + allKeyFieldPaths, + new Set([matchingArg.name]), + isListReturn, + fieldCoords, + entityTypeName, + matchingArg.name, + fieldMappings[0]?.entityKeyField, + ) + ) { + results.length = 0; + continue; + } + results.push({ entityTypeName, fieldMappings }); + } + // Whether it succeeded or failed, we handled this key + continue; + } + } + } + } + + // Per-key independent evaluation for flat keys. + // Two classes of failure: + // (1) Per-key failure (type mismatch on a field) → continue to the next @key; earlier + // satisfiable @keys (including the nested ones above) are preserved. + // (2) Global-invalidation failure (extra non-key argument — singular OR batch rule violation) + // → clear ALL accumulated mappings and stop evaluating further keys. This preserves the + // pre-bug-(d) behavior where an extra non-key argument rejects the whole set because the + // cache key would be incomplete. + let globallyInvalidated = false; + for (const keyData of keyFieldSets.values()) { + if (globallyInvalidated) { + break; + } + const keyInfos = this.extractKeyFieldInfos(keyData.documentNode, entityTypeName); + if (keyInfos.length === 0) { + continue; + } + + const fieldMappings: FieldMappingConfig[] = []; + let keyFullyMapped = true; + let keyFailed = false; + let firstMatchedArg: string | undefined; + let firstMatchedKeyField: string | undefined; + let unmappedField: string | undefined; + let scalarMatchedOnListReturn = false; + + for (const keyInfo of keyInfos) { + const fieldName = keyInfo.path; + const matchingArg = argumentInfos.find((a) => a.name === fieldName); + + if (!matchingArg) { + keyFullyMapped = false; + unmappedField = fieldName; + continue; + } + + const argTypeNode = matchingArg.typeNode; + const keyTypeNode = keyInfo.typeNode; + const argIsList = matchingArg.isList; + const keyIsList = isTypeNodeListType(keyTypeNode); + + if (!this.namedTypesMatch(argTypeNode, keyTypeNode) || (argIsList !== keyIsList && !isListReturn)) { + if (!typeMismatchWarningEmitted) { + this.warnings.push( + autoMappingTypeMismatchWarning({ + subgraphName: this.subgraphName, + argumentName: matchingArg.name, + fieldCoords, + argumentType: printTypeNode(argTypeNode), + keyField: fieldName, + entityType: entityTypeName, + keyFieldType: printTypeNode(keyTypeNode), + }), + ); + typeMismatchWarningEmitted = true; + } + // Bug (d): a failed candidate on this @key must not abort the remaining @key alternatives. + // Mark this key as unmappable and let the outer loop move on to the next @key. + keyFullyMapped = false; + keyFailed = true; + break; + } + + if (!firstMatchedArg) { + firstMatchedArg = matchingArg.name; + firstMatchedKeyField = fieldName; + } + + if (isListReturn) { + if (argIsList) { + if (keyIsList) { + keyFullyMapped = false; + continue; + } + fieldMappings.push({ + entityKeyField: fieldName, + argumentPath: [matchingArg.name], + isBatch: true, + }); + } else { + // Scalar arg on list return - skip auto-mapping (no batch) + scalarMatchedOnListReturn = true; + keyFullyMapped = false; + continue; + } + } else { + fieldMappings.push({ + entityKeyField: fieldName, + argumentPath: [matchingArg.name], + }); + } + } + + // Bug (d): type mismatch on this @key aborted the inner loop — skip to the next @key + // without emitting further warnings or blocking other alternatives. + if (keyFailed) { + continue; + } + + // Check for extra non-key arguments (args not in ANY key across all keys) + const extraArgs = argumentInfos.filter((a) => !allKeyFieldPaths.has(a.name)); + + // On list return, if a scalar matched but was skipped and there are extra args, warn. + // Class (2): an extra non-key argument on a list-return field rejects the whole mapping set. + if ( + isListReturn && + scalarMatchedOnListReturn && + extraArgs.length > 0 && + firstMatchedArg && + firstMatchedKeyField + ) { + this.warnings.push( + autoBatchAdditionalNonKeyArgumentWarning({ + subgraphName: this.subgraphName, + fieldCoords, + argumentName: firstMatchedArg, + keyField: firstMatchedKeyField, + entityType: entityTypeName, + extraArgument: extraArgs[0].name, + }), + ); + // Class (2) global invalidation: clear accumulated results and stop evaluating further keys. + results.length = 0; + globallyInvalidated = true; + continue; + } + + if (!keyFullyMapped && fieldMappings.length > 0 && unmappedField) { + if (!isListReturn) { + this.warnings.push( + incompleteQueryCacheKeyMappingWarning({ + subgraphName: this.subgraphName, + fieldCoords, + entityType: entityTypeName, + unmappedKeyField: unmappedField, + }), + ); + } + continue; + } + + if (keyFullyMapped && fieldMappings.length > 0) { + if ( + this.invalidateAutoMappingWithExtraArgument( + argumentInfos, + allKeyFieldPaths, + new Set(fieldMappings.map((m) => m.argumentPath[0])), + isListReturn, + fieldCoords, + entityTypeName, + firstMatchedArg, + firstMatchedKeyField, + ) + ) { + // Class (2) global invalidation: an extra non-key argument on a fully-mapped key + // (list or singular return) must suppress auto-mapping across all @key alternatives, + // including earlier accumulated nested-key results. A per-key `continue` would leave + // mappings tied to a result set still filtered by an unkeyed argument — unsafe. + results.length = 0; + globallyInvalidated = true; + continue; + } + + results.push({ entityTypeName, fieldMappings }); + } + } + + // Each key remains its own EntityKeyMappingConfig — the router evaluates them + // independently (OR semantics). Do NOT merge single-field results. + return results; + } + getValidFlattenedDirectiveArray( directivesByName: Map, directiveCoords: string, @@ -3654,7 +5371,7 @@ export class NormalizationFactory { if (!handledDirectiveNames.has(directiveName)) { handledDirectiveNames.add(directiveName); this.errors.push( - invalidDirectiveError(directiveName, directiveCoords, '1st', [ + invalidDirectiveError(directiveName, directiveCoords, FIRST_ORDINAL, [ invalidRepeatedDirectiveErrorMessage(directiveName), ]), ); @@ -4251,6 +5968,8 @@ export class NormalizationFactory { this.addValidConditionalFieldSetConfigurations(); // this is where @key configurations are added to the ConfigurationData this.addValidKeyFieldSetConfigurations(); + // this is where @openfed__requestScoped configurations are added to the ConfigurationData + this.extractRequestScopedFields(); // Check that explicitly defined operations types are valid objects and that their fields are also valid for (const operationType of Object.values(OperationTypeNode)) { const operationTypeNode = this.schemaData.operationTypes.get(operationType); @@ -4288,6 +6007,11 @@ export class NormalizationFactory { this.errors.push(operationDefinitionError(operationTypeName, operationType, objectData.kind)); } } + // Extract and validate entity caching directives. This must run after the operation-type + // loop above so that operationTypeNodeByTypeName contains renamed root operation types + // (e.g. schema { query: MyQuery }); processRootFieldCacheDirectives() resolves root types + // through getOperationTypeNodeForRootTypeName(). + this.validateAndExtractEntityCachingConfigs(); for (const referencedTypeName of this.referencedTypeNames) { const parentData = this.parentDefinitionDataByTypeName.get(referencedTypeName); if (!parentData) { diff --git a/composition/src/v1/normalization/utils.ts b/composition/src/v1/normalization/utils.ts index 62b77eeac3..e7308a5bb6 100644 --- a/composition/src/v1/normalization/utils.ts +++ b/composition/src/v1/normalization/utils.ts @@ -45,16 +45,20 @@ import { type CompositeOutputData, type InputValueData } from '../../schema-buil import { getTypeNodeNamedTypeName } from '../../schema-building/ast'; import { AUTHENTICATED_DEFINITION_DATA, + CACHE_INVALIDATE_DEFINITION_DATA, + CACHE_POPULATE_DEFINITION_DATA, COMPOSE_DIRECTIVE_DEFINITION_DATA, CONFIGURE_CHILD_DESCRIPTIONS_DEFINITION_DATA, CONFIGURE_DESCRIPTION_DEFINITION_DATA, CONNECT_FIELD_RESOLVER_DEFINITION_DATA, COST_DEFINITION_DATA, DEPRECATED_DEFINITION_DATA, + ENTITY_CACHE_DEFINITION_DATA, EXTENDS_DEFINITION_DATA, EXTERNAL_DEFINITION_DATA, INACCESSIBLE_DEFINITION_DATA, INTERFACE_OBJECT_DEFINITION_DATA, + IS_DEFINITION_DATA, KAFKA_PUBLISH_DEFINITION_DATA, KAFKA_SUBSCRIBE_DEFINITION_DATA, KEY_DEFINITION_DATA, @@ -66,9 +70,11 @@ import { ONE_OF_DEFINITION_DATA, OVERRIDE_DEFINITION_DATA, PROVIDES_DEFINITION_DATA, + QUERY_CACHE_DEFINITION_DATA, REDIS_PUBLISH_DEFINITION_DATA, REDIS_SUBSCRIBE_DEFINITION_DATA, REQUIRE_FETCH_REASONS_DEFINITION_DATA, + REQUEST_SCOPED_DEFINITION_DATA, REQUIRES_DEFINITION_DATA, REQUIRES_SCOPES_DEFINITION_DATA, SEMANTIC_NON_NULL_DEFINITION_DATA, @@ -80,6 +86,8 @@ import { import { AS, AUTHENTICATED, + CACHE_INVALIDATE, + CACHE_POPULATE, COMPOSE_DIRECTIVE, CONFIGURE_CHILD_DESCRIPTIONS, CONFIGURE_DESCRIPTION, @@ -93,12 +101,14 @@ import { EDFS_NATS_SUBSCRIBE, EDFS_REDIS_PUBLISH, EDFS_REDIS_SUBSCRIBE, + ENTITY_CACHE, EXTENDS, EXTERNAL, FIELDS, IMPORT, INACCESSIBLE, INTERFACE_OBJECT, + IS, KEY, LINK, LIST_SIZE, @@ -109,6 +119,8 @@ import { OVERRIDE, PROVIDES, QUERY, + QUERY_CACHE, + REQUEST_SCOPED, REQUIRE_FETCH_REASONS, REQUIRES, REQUIRES_SCOPES, @@ -468,6 +480,8 @@ export function validateArgumentTemplateReferences( export function initializeDirectiveDefinitionDatas(): Map { return new Map([ [AUTHENTICATED, AUTHENTICATED_DEFINITION_DATA], + [CACHE_INVALIDATE, CACHE_INVALIDATE_DEFINITION_DATA], + [CACHE_POPULATE, CACHE_POPULATE_DEFINITION_DATA], [COMPOSE_DIRECTIVE, COMPOSE_DIRECTIVE_DEFINITION_DATA], [CONFIGURE_DESCRIPTION, CONFIGURE_DESCRIPTION_DEFINITION_DATA], [CONFIGURE_CHILD_DESCRIPTIONS, CONFIGURE_CHILD_DESCRIPTIONS_DEFINITION_DATA], @@ -481,16 +495,20 @@ export function initializeDirectiveDefinitionDatas(): Map new BatchNormalizer(params).batchNormalize(); +import { normalizeSubgraphFailure, normalizeSubgraphSuccess } from '../../utils/utils'; + +const version = ROUTER_COMPATIBILITY_VERSION_ONE; + +function subgraph(sdl: string, name = 'subgraph-a'): Subgraph { + return { name, url: '', definitions: parse(sdl) }; +} + +function getConfigForType(sg: Subgraph, typeName: string): ConfigurationData | undefined { + const result = batchNormalize({ subgraphs: [sg], version }) as BatchNormalizationSuccess; + expect(result.success).toBe(true); + const internal = result.internalSubgraphByName.get(sg.name); + expect(internal).toBeDefined(); + return internal!.configurationDataByTypeName.get(typeName as TypeName); +} + +describe('Entity caching fuzz tests', () => { + // ═══════════════════════════════════════════════════════════════════════════ + // @openfed__queryCache + @openfed__is mapping edge cases + // ═══════════════════════════════════════════════════════════════════════════ + + describe('@openfed__queryCache + @openfed__is edge cases', () => { + test('1. @openfed__queryCache on field with NO arguments — should succeed with empty mappings', () => { + // A Query field with @openfed__queryCache but zero arguments cannot construct a cache key. + // Expect: succeeds (cache population still works), empty mappings. + const config = getConfigForType( + subgraph(` + type Query { + latestProduct: Product @openfed__queryCache(maxAge: 30) + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + QUERY, + ); + expect(config).toBeDefined(); + expect(config!.rootFieldCacheConfigurations).toStrictEqual([ + { + fieldName: 'latestProduct', + maxAgeSeconds: 30, + includeHeaders: false, + shadowMode: false, + entityTypeName: 'Product', + entityKeyMappings: [], + }, + ] satisfies RootFieldCacheConfig[]); + }); + + test('2. @openfed__queryCache on field returning nullable entity (Product not Product!) — should succeed', () => { + // Nullable return type should still work — the entity type name is extracted + // by unwrapping NonNull wrappers. + const config = getConfigForType( + subgraph(` + type Query { + product(id: ID!): Product @openfed__queryCache(maxAge: 30) + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + QUERY, + ); + expect(config).toBeDefined(); + expect(config!.rootFieldCacheConfigurations).toHaveLength(1); + expect(config!.rootFieldCacheConfigurations![0].entityTypeName).toBe('Product'); + // Auto-mapping should still work + expect(config!.rootFieldCacheConfigurations![0].entityKeyMappings).toHaveLength(1); + }); + + test('3. @openfed__queryCache on field returning union type — should error (union is not an entity)', () => { + // A union type itself doesn't have @key, so it's not an entity. + // Expect: error about non-entity return type. + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Query { + item(id: ID!): Item @openfed__queryCache(maxAge: 30) + } + union Item = Product | Service + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + type Service @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + description: String! + } + `), + version, + ); + expect(errors).toHaveLength(1); + }); + + test('4. @openfed__queryCache on field returning interface type — should error (interface is not a keyed entity)', () => { + // An interface can't have @key in federation v1-style, so it's not an entity. + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Query { + node(id: ID!): Node @openfed__queryCache(maxAge: 30) + } + interface Node { + id: ID! + } + type Product implements Node @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + version, + ); + expect(errors).toHaveLength(1); + }); + + test('5. @openfed__is(fields: "id") on argument WITHOUT @openfed__queryCache — should error', () => { + // @openfed__is only makes sense for cache key construction. Without @openfed__queryCache, it's meaningless. + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Query { + product(pid: ID! @openfed__is(fields: "id")): Product + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + version, + ); + expect(errors).toHaveLength(1); + expect(errors[0]).toStrictEqual( + invalidDirectiveError(IS, 'Query.product(pid: ...)', FIRST_ORDINAL, [ + isWithoutQueryCacheErrorMessage('pid', 'Query.product'), + ]), + ); + }); + + test('6. @openfed__is(fields: "id id") — composition error about unknown @key field', () => { + // The "id id" fields value is a single field-set string. The field-set + // validator resolves it against @key(fields: "id") on Product and reports + // an unknown-key-field error rather than accepting a duplicate mapping. + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Query { + product(key: ProductKey! @openfed__is(fields: "id id")): Product @openfed__queryCache(maxAge: 30) + } + input ProductKey { + id: ID! + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + version, + ); + expect(errors).toHaveLength(1); + expect(errors[0].message).toContain( + '@openfed__is(fields: "id id") on argument "key" of field "Query.product" references unknown @key field "id id" on type "Product".', + ); + }); + }); + + // ═══════════════════════════════════════════════════════════════════════════ + // @openfed__entityCache edge cases + // ═══════════════════════════════════════════════════════════════════════════ + + describe('@openfed__entityCache edge cases', () => { + test('7. @openfed__entityCache on type with multiple @key directives — config should still have one entityCacheConfig', () => { + // Multiple @key directives on same type, single @openfed__entityCache. The entity has + // multiple ways to be identified, but only one cache TTL config. + const config = getConfigForType( + subgraph(` + type Query { product(id: ID!): Product } + type Product @key(fields: "id") @key(fields: "sku") @openfed__entityCache(maxAge: 60) { + id: ID! + sku: String! + name: String! + } + `), + 'Product', + ); + expect(config).toBeDefined(); + // Should have exactly one entityCacheConfig regardless of multiple keys + expect(config!.entityCacheConfigurations).toHaveLength(1); + expect(config!.entityCacheConfigurations![0].maxAgeSeconds).toBe(60); + }); + + test('8. @openfed__entityCache with very large maxAge (Int32 max) — should accept', () => { + // Very large TTL. GraphQL `Int` is 32-bit signed, so 2^31-1 = 2147483647 is the max. + // Previously this test used 999999999999, which is outside GraphQL Int range and would + // be rejected by the spec-compliant parser — shadowing the intent of the "large but valid + // TTL" check. + // Expect: succeeds, config has the exact value. + const config = getConfigForType( + subgraph(` + type Query { product(id: ID!): Product } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 2147483647) { + id: ID! + name: String! + } + `), + 'Product', + ); + expect(config).toBeDefined(); + expect(config!.entityCacheConfigurations).toHaveLength(1); + expect(config!.entityCacheConfigurations![0].maxAgeSeconds).toBe(2147483647); + }); + + test('9. @openfed__entityCache on type with ONLY unresolvable @key(resolvable: false) — should succeed', () => { + // An entity with only unresolvable keys still has @key, so @openfed__entityCache should be accepted. + // The router uses the key to construct cache keys even if it can't resolve the entity. + const { schema } = normalizeSubgraphSuccess( + subgraph(` + type Query { dummy: String! } + type Product @key(fields: "id", resolvable: false) @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + version, + ); + expect(schema).toBeDefined(); + }); + + test('10. Multiple @openfed__entityCache on same type — composition error (non-repeatable)', () => { + // @openfed__entityCache is not marked repeatable. Declaring it twice on + // the same type must produce the standard "not repeatable" composition + // error, not silently pick one TTL. + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Query { product(id: ID!): Product } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) @openfed__entityCache(maxAge: 120) { + id: ID! + name: String! + } + `), + version, + ); + expect(errors).toHaveLength(1); + expect(errors[0].message).toContain( + 'The definition for the directive "@openfed__entityCache" does not define it as repeatable, but it is declared more than once on these coordinates.', + ); + }); + }); + + // ═══════════════════════════════════════════════════════════════════════════ + // Multiple @key + @openfed__queryCache mapping edge cases + // ═══════════════════════════════════════════════════════════════════════════ + + describe('multiple @key + @openfed__queryCache mapping', () => { + test('11. Two @key directives, argument satisfies both — both keys should produce mappings', () => { + // @key(fields: "id") and @key(fields: "id sku") — argument "id" satisfies the first key fully. + // The second key needs both "id" and "sku", and only "id" is provided. + // Expect: one fully-mapped key (for "id"), the second key is incomplete so it's skipped. + const config = getConfigForType( + subgraph(` + type Query { + product(id: ID!): Product @openfed__queryCache(maxAge: 30) + } + type Product @key(fields: "id") @key(fields: "id sku") @openfed__entityCache(maxAge: 60) { + id: ID! + sku: String! + name: String! + } + `), + QUERY, + ); + expect(config).toBeDefined(); + const rfcs = config!.rootFieldCacheConfigurations!; + expect(rfcs).toHaveLength(1); + // The first key "id" should be fully satisfied + const fullMappings = rfcs[0].entityKeyMappings.filter((m) => m.fieldMappings.length > 0); + expect(fullMappings).toHaveLength(1); + // At least one mapping should map "id" to "id" + const hasIdMapping = fullMappings.some((m) => + m.fieldMappings.some((f) => f.entityKeyField === 'id' && f.argumentPath[0] === 'id'), + ); + expect(hasIdMapping).toBe(true); + }); + + // BUG: Two independent @key directives (@key(fields: "id") and @key(fields: "sku")) + // each produce a single-field EntityKeyMappingConfig. But buildAutoMappings() at lines + // 4921-4931 merges all single-field results into ONE EntityKeyMappingConfig with both + // field mappings. This makes the router treat them as a composite key (AND semantics: + // both "id" AND "sku" must match) instead of independent keys (OR semantics: either + // "id" OR "sku" can be used for a cache hit). The merge is wrong — independent keys + // should remain separate EntityKeyMappingConfig entries. + test('12. Two @key directives, arguments satisfy both fully — should produce two key mappings', () => { + const config = getConfigForType( + subgraph(` + type Query { + product(id: ID!, sku: String!): Product @openfed__queryCache(maxAge: 30) + } + type Product @key(fields: "id") @key(fields: "sku") @openfed__entityCache(maxAge: 60) { + id: ID! + sku: String! + name: String! + } + `), + QUERY, + ); + expect(config).toBeDefined(); + const mappings = config!.rootFieldCacheConfigurations![0].entityKeyMappings; + // Both keys should be fully satisfied as SEPARATE entries + expect(mappings).toHaveLength(2); + }); + }); + + // ═══════════════════════════════════════════════════════════════════════════ + // Nested key edge cases + // ═══════════════════════════════════════════════════════════════════════════ + + describe('nested key edge cases', () => { + test('13. @key(fields: "store { id }") with @openfed__is(fields: "store.id") on scalar arg', () => { + // Nested key path: "store.id" — the @openfed__is targets it with dot notation. + // Expect: succeeds, mapping has entityKeyField "store.id". + const config = getConfigForType( + subgraph(` + type Query { + product(storeId: ID! @openfed__is(fields: "store.id")): Product @openfed__queryCache(maxAge: 30) + } + type Product @key(fields: "store { id }") @openfed__entityCache(maxAge: 60) { + store: Store! + name: String! + } + type Store { + id: ID! + } + `), + QUERY, + ); + expect(config).toBeDefined(); + const mappings = config!.rootFieldCacheConfigurations![0].entityKeyMappings; + expect(mappings).toHaveLength(1); + expect(mappings[0].fieldMappings).toHaveLength(1); + expect(mappings[0].fieldMappings[0].entityKeyField).toBe('store.id'); + expect(mappings[0].fieldMappings[0].argumentPath).toStrictEqual(['storeId']); + }); + + test('14. @key with deeply nested field (3 levels)', () => { + // @key(fields: "a { b { c } }") — deep nesting. + // Expect: succeeds with key. + const { schema } = normalizeSubgraphSuccess( + subgraph(` + type Query { thing(id: ID!): Thing } + type Thing @key(fields: "a { b { c } }") @openfed__entityCache(maxAge: 60) { + a: A! + } + type A { + b: B! + } + type B { + c: ID! + } + `), + version, + ); + expect(schema).toBeDefined(); + }); + }); + + // ═══════════════════════════════════════════════════════════════════════════ + // @openfed__is with input objects + // ═══════════════════════════════════════════════════════════════════════════ + + describe('@openfed__is with input objects', () => { + test('15. @openfed__is(fields: "id sku") with input object having EXTRA fields — succeeds, extra field ignored', () => { + // Extra non-key fields on the input object are tolerated when the + // @openfed__is spec names only the key fields. The mapping is emitted + // exactly for "id" and "sku"; the "extra" field is not part of the + // cache key. Any future change that starts rejecting this case, or + // starts including "extra" in the mapping, must update this assertion. + const sg = subgraph(` + type Query { + product(key: ProductKey! @openfed__is(fields: "id sku")): Product @openfed__queryCache(maxAge: 30) + } + input ProductKey { + id: ID! + sku: String! + extra: String! + } + type Product @key(fields: "id sku") @openfed__entityCache(maxAge: 60) { + id: ID! + sku: String! + name: String! + } + `); + const result = batchNormalize({ subgraphs: [sg], version }); + expect(result.success).toBe(true); + const internal = (result as BatchNormalizationSuccess).internalSubgraphByName.get(sg.name); + const queryConfig = internal!.configurationDataByTypeName.get(QUERY as TypeName); + expect(queryConfig?.rootFieldCacheConfigurations).toEqual([ + { + fieldName: 'product', + maxAgeSeconds: 30, + includeHeaders: false, + shadowMode: false, + entityTypeName: 'Product', + entityKeyMappings: [ + { + entityTypeName: 'Product', + fieldMappings: [ + { entityKeyField: 'id', argumentPath: ['key', 'id'] }, + { entityKeyField: 'sku', argumentPath: ['key', 'sku'] }, + ], + }, + ], + }, + ]); + }); + + test('16. @openfed__is(fields: "id sku") with input object MISSING one field — composition error', () => { + // The input object is missing "sku", so the @openfed__is spec cannot be + // satisfied. This must produce an explicit error naming the missing field. + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Query { + product(key: ProductKey! @openfed__is(fields: "id sku")): Product @openfed__queryCache(maxAge: 30) + } + input ProductKey { + id: ID! + } + type Product @key(fields: "id sku") @openfed__entityCache(maxAge: 60) { + id: ID! + sku: String! + name: String! + } + `), + version, + ); + expect(errors).toHaveLength(1); + expect(errors[0].message).toContain( + 'Argument "key" on field "Query.product" uses @openfed__is(fields: "id sku") mapping to composite @key on entity "Product", but input type "ProductKey" is missing required key field "sku".', + ); + }); + }); + + // ═══════════════════════════════════════════════════════════════════════════ + // @openfed__requestScoped edge cases + // ═══════════════════════════════════════════════════════════════════════════ + + describe('@openfed__requestScoped edge cases', () => { + test('17. @openfed__requestScoped requires key — missing key is a failure', () => { + // key is mandatory. + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Query { + currentUser: User @openfed__requestScoped + user: User @openfed__requestScoped(key: "u") + } + type User @key(fields: "id") { + id: ID! + name: String! + } + `), + version, + ); + // The error is from the directive definition validation — key is required. + expect(errors).toHaveLength(1); + }); + + test('18. @openfed__requestScoped with ≥ 2 fields sharing the same key — no warning, l1Key subgraph-prefixed', () => { + const { warnings } = normalizeSubgraphSuccess( + subgraph(` + type Query { + me: User @openfed__requestScoped(key: "me") + } + type Article @key(fields: "id") { + id: ID! + viewer: User @openfed__requestScoped(key: "me") + } + type User @key(fields: "id") { + id: ID! + name: String! + } + `), + version, + ); + // No single-field warning because both fields declare key: "me" + expect(warnings).toHaveLength(0); + + const config = getConfigForType( + subgraph(` + type Query { + me: User @openfed__requestScoped(key: "me") + } + type Article @key(fields: "id") { + id: ID! + viewer: User @openfed__requestScoped(key: "me") + } + type User @key(fields: "id") { + id: ID! + name: String! + } + `), + QUERY, + ); + expect(config).toBeDefined(); + expect(config!.requestScopedFields).toBeDefined(); + expect(config!.requestScopedFields).toHaveLength(1); + expect(config!.requestScopedFields![0].l1Key).toBe('subgraph-a.me'); + }); + + test('19. @openfed__requestScoped on a non-entity type field — should succeed when ≥ 2 fields share the key', () => { + // @openfed__requestScoped is on FIELD_DEFINITION, works on any object type field. + const config = getConfigForType( + subgraph(` + type Query { + currentLocale: String @openfed__requestScoped(key: "locale") + } + type Article @key(fields: "id") { + id: ID! + articleLocale: String @openfed__requestScoped(key: "locale") + } + `), + QUERY, + ); + expect(config).toBeDefined(); + expect(config!.requestScopedFields).toBeDefined(); + expect(config!.requestScopedFields).toHaveLength(1); + expect(config!.requestScopedFields![0].fieldName).toBe('currentLocale'); + expect(config!.requestScopedFields![0].l1Key).toBe('subgraph-a.locale'); + }); + + test('20. @openfed__requestScoped with only one field declaring a key — warning emitted', () => { + // Single-field @openfed__requestScoped is meaningless (no second reader to benefit). + const { warnings } = normalizeSubgraphSuccess( + subgraph(` + type Query { + currentUser: User @openfed__requestScoped(key: "lonely") + } + type User @key(fields: "id") { + id: ID! + name: String! + } + `), + version, + ); + expect(warnings).toHaveLength(1); + expect(warnings[0]).toStrictEqual( + requestScopedSingleFieldWarning({ + subgraphName: 'subgraph-a', + key: 'lonely', + fieldCoords: 'Query.currentUser', + }), + ); + }); + + test('21. Multiple @openfed__requestScoped on same field — not repeatable, should fail', () => { + // @openfed__requestScoped is NOT repeatable. + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Query { + currentUser: User @openfed__requestScoped(key: "a") @openfed__requestScoped(key: "b") + } + type User @key(fields: "id") { + id: ID! + name: String! + } + `), + version, + ); + expect(errors).toHaveLength(1); + }); + }); + + // ═══════════════════════════════════════════════════════════════════════════ + // @openfed__cacheInvalidate / @openfed__cachePopulate edge cases + // ═══════════════════════════════════════════════════════════════════════════ + + describe('@openfed__cacheInvalidate/@openfed__cachePopulate edge cases', () => { + test('22. @openfed__cachePopulate(maxAge: -1) — should error', () => { + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Query { dummy: String! } + type Mutation { + createProduct(name: String!): Product @openfed__cachePopulate(maxAge: -1) + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + version, + ); + expect(errors).toHaveLength(1); + expect(errors[0]).toStrictEqual( + invalidDirectiveError(CACHE_POPULATE, 'Mutation.createProduct', FIRST_ORDINAL, [ + maxAgeNotPositiveIntegerErrorMessage(CACHE_POPULATE, -1), + ]), + ); + }); + + test('23. @openfed__cacheInvalidate returning a list type — should succeed', () => { + // Mutation returning [Product]! with @openfed__cacheInvalidate. The named type is still "Product". + // getTypeNodeNamedTypeName unwraps list and NonNull wrappers. + const { schema } = normalizeSubgraphSuccess( + subgraph(` + type Query { dummy: String! } + type Mutation { + deleteProducts(ids: [ID!]!): [Product!]! @openfed__cacheInvalidate + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + version, + ); + expect(schema).toBeDefined(); + }); + + test('24. @openfed__cacheInvalidate on Subscription field — should succeed', () => { + // The code allows both Mutation and Subscription for @openfed__cacheInvalidate. + const config = getConfigForType( + subgraph(` + type Query { dummy: String! } + type Subscription { + productDeleted: Product @openfed__cacheInvalidate + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + SUBSCRIPTION, + ); + expect(config).toBeDefined(); + expect(config!.cacheInvalidateConfigurations).toStrictEqual([ + { + fieldName: 'productDeleted', + operationType: SUBSCRIPTION, + entityTypeName: 'Product', + }, + ] satisfies CacheInvalidateConfig[]); + }); + + test('25. @openfed__cachePopulate on Subscription returning a non-entity type — should error', () => { + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Query { dummy: String! } + type Subscription { + eventOccurred: Event @openfed__cachePopulate + } + type Event { + id: ID! + message: String! + } + `), + version, + ); + expect(errors).toHaveLength(1); + expect(errors[0]).toStrictEqual( + invalidDirectiveError(CACHE_POPULATE, 'Subscription.eventOccurred', FIRST_ORDINAL, [ + cachePopulateOnNonEntityReturnTypeErrorMessage('Subscription.eventOccurred', 'Event'), + ]), + ); + }); + }); + + // ═══════════════════════════════════════════════════════════════════════════ + // Cross-directive interactions + // ═══════════════════════════════════════════════════════════════════════════ + + describe('cross-directive interactions', () => { + test('26. @openfed__queryCache + @openfed__entityCache on same field — @openfed__queryCache is on the Query field, @openfed__entityCache on the type', () => { + // This is the normal usage pattern, not actually on the "same field". + // Verify the combined config is correct. + const sg = subgraph(` + type Query { + product(id: ID!): Product @openfed__queryCache(maxAge: 30) + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `); + const result = batchNormalize({ subgraphs: [sg], version }) as BatchNormalizationSuccess; + expect(result.success).toBe(true); + const internal = result.internalSubgraphByName.get(sg.name)!; + + // Product type should have entityCacheConfig + const productConfig = internal.configurationDataByTypeName.get('Product' as TypeName); + expect(productConfig!.entityCacheConfigurations).toHaveLength(1); + expect(productConfig!.entityCacheConfigurations![0].maxAgeSeconds).toBe(60); + + // Query type should have rootFieldCacheConfig + const queryConfig = internal.configurationDataByTypeName.get(QUERY as TypeName); + expect(queryConfig!.rootFieldCacheConfigurations).toHaveLength(1); + expect(queryConfig!.rootFieldCacheConfigurations![0].maxAgeSeconds).toBe(30); + }); + + test('27. @openfed__entityCache + @openfed__requestScoped on same type — both should be present in config', () => { + // An entity can be both cacheable and have request-scoped fields. + // Two fields share the "session" key so no single-field warning. + const sg = subgraph(` + type Query { + user(id: ID!): User @openfed__queryCache(maxAge: 30) + activeSession: String @openfed__requestScoped(key: "session") + } + type User @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + currentSession: String @openfed__requestScoped(key: "session") + } + `); + const result = batchNormalize({ subgraphs: [sg], version }) as BatchNormalizationSuccess; + expect(result.success).toBe(true); + const internal = result.internalSubgraphByName.get(sg.name)!; + const userConfig = internal.configurationDataByTypeName.get('User' as TypeName); + expect(userConfig).toBeDefined(); + // Should have entity cache config + expect(userConfig!.entityCacheConfigurations).toHaveLength(1); + // Should have request-scoped fields + expect(userConfig!.requestScopedFields).toBeDefined(); + expect(userConfig!.requestScopedFields).toHaveLength(1); + expect(userConfig!.requestScopedFields![0].fieldName).toBe('currentSession'); + expect(userConfig!.requestScopedFields![0].l1Key).toBe('subgraph-a.session'); + }); + + test('28. Both @openfed__cachePopulate and @openfed__queryCache on same field — should this be rejected?', () => { + // @openfed__queryCache is only valid on Query fields, @openfed__cachePopulate only on Mutation/Subscription. + // They can't be on the same field since a field can only be on one root type. + // But what if someone puts @openfed__cachePopulate on a Query field? That's caught by rule 17. + // What about @openfed__queryCache on a Mutation field? That's caught by rule 4. + // So this combination is inherently impossible on the same field. + // Let's verify the error for @openfed__queryCache on Mutation with @openfed__cachePopulate: + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Query { dummy: String! } + type Mutation { + createProduct(name: String!): Product @openfed__queryCache(maxAge: 30) @openfed__cachePopulate + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + version, + ); + // Should error about @openfed__queryCache on non-Query field + expect(errors).toHaveLength(1); + }); + }); + + // ═══════════════════════════════════════════════════════════════════════════ + // Auto-mapping traps + // ═══════════════════════════════════════════════════════════════════════════ + + describe('auto-mapping traps', () => { + test('29. Argument named "id" with type [ID!]! (list) on singular return — should NOT auto-map', () => { + // The argument "id" matches the key field name "id", but the argument is a list + // while the return type is singular. For singular returns, a list argument can't + // map to a scalar key field (type mismatch). + const sg = subgraph(` + type Query { + product(id: [ID!]!): Product @openfed__queryCache(maxAge: 30) + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `); + const result = batchNormalize({ subgraphs: [sg], version }) as BatchNormalizationSuccess; + expect(result.success).toBe(true); + const internal = result.internalSubgraphByName.get(sg.name)!; + const queryConfig = internal.configurationDataByTypeName.get(QUERY as TypeName); + expect(queryConfig).toBeDefined(); + const rfcs = queryConfig!.rootFieldCacheConfigurations!; + expect(rfcs).toHaveLength(1); + // The mapping should be empty because [ID!]! can't map to scalar ID! on singular return + expect(rfcs[0].entityKeyMappings).toHaveLength(0); + }); + + test('30. Argument named "id" with nullable type ID mapping to key field id: ID! — should auto-map', () => { + // Nullability differences should be ignored per the mapping rules. + // Nullable ID arg → non-null ID! key field should still auto-map. + const config = getConfigForType( + subgraph(` + type Query { + product(id: ID): Product @openfed__queryCache(maxAge: 30) + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + QUERY, + ); + expect(config).toBeDefined(); + const mappings = config!.rootFieldCacheConfigurations![0].entityKeyMappings; + // Should auto-map despite nullability difference + expect(mappings).toHaveLength(1); + expect(mappings[0].fieldMappings).toHaveLength(1); + expect(mappings[0].fieldMappings[0].entityKeyField).toBe('id'); + }); + + test('31. Entity with @key(fields: "type") — "type" is a valid field name, should work', () => { + // "type" is a valid GraphQL field name that happens to be a keyword in some contexts. + // It should not conflict with __typename. + const config = getConfigForType( + subgraph(` + type Query { + product(type: String!): Product @openfed__queryCache(maxAge: 30) + } + type Product @key(fields: "type") @openfed__entityCache(maxAge: 60) { + type: String! + name: String! + } + `), + QUERY, + ); + expect(config).toBeDefined(); + const mappings = config!.rootFieldCacheConfigurations![0].entityKeyMappings; + expect(mappings).toHaveLength(1); + expect(mappings[0].fieldMappings[0].entityKeyField).toBe('type'); + }); + + test('32. Argument type mismatch: arg is String!, key field is ID! — should skip auto-mapping with warning', () => { + // Auto-mapping compares named types (unwrapping NonNull). String != ID. + // Expect: auto-mapping is skipped, warning emitted. + const { warnings } = normalizeSubgraphSuccess( + subgraph(` + type Query { + product(id: String!): Product @openfed__queryCache(maxAge: 30) + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + version, + ); + // Should produce a type mismatch warning + expect(warnings).toHaveLength(1); + }); + }); + + // ═══════════════════════════════════════════════════════════════════════════ + // Batch / list edge cases + // ═══════════════════════════════════════════════════════════════════════════ + + describe('batch / list edge cases', () => { + test('33. List return with list argument — should produce isBatch mapping', () => { + // products(ids: [ID!]!): [Product!]! with @openfed__queryCache — batch lookup. + // The argument "ids" doesn't match key field "id" by name, so we need @openfed__is. + const config = getConfigForType( + subgraph(` + type Query { + products(ids: [ID!]! @openfed__is(fields: "id")): [Product!]! @openfed__queryCache(maxAge: 30) + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + QUERY, + ); + expect(config).toBeDefined(); + const rfcs = config!.rootFieldCacheConfigurations!; + expect(rfcs).toHaveLength(1); + const mappings = rfcs[0].entityKeyMappings; + expect(mappings).toHaveLength(1); + expect(mappings[0].fieldMappings).toHaveLength(1); + expect(mappings[0].fieldMappings[0].isBatch).toBe(true); + }); + + test('34. List return with scalar argument — should not establish batch mapping', () => { + // products(category: String!): [Product!]! with @openfed__queryCache — scalar arg can't batch. + // Auto-mapping won't find "category" in @key(fields: "id"), so no mapping. + const config = getConfigForType( + subgraph(` + type Query { + products(category: String!): [Product!]! @openfed__queryCache(maxAge: 30) + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + QUERY, + ); + expect(config).toBeDefined(); + const rfcs = config!.rootFieldCacheConfigurations!; + expect(rfcs).toHaveLength(1); + // No mappings since "category" doesn't match any key field + expect(rfcs[0].entityKeyMappings).toHaveLength(0); + }); + + test('35. List return with auto-mapped list argument named "id" — should produce isBatch', () => { + // products(id: [ID!]!): [Product!]! — "id" matches key field "id", list arg, list return. + // Should auto-map with isBatch: true. + const config = getConfigForType( + subgraph(` + type Query { + products(id: [ID!]!): [Product!]! @openfed__queryCache(maxAge: 30) + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + QUERY, + ); + expect(config).toBeDefined(); + const rfcs = config!.rootFieldCacheConfigurations!; + expect(rfcs).toHaveLength(1); + const mappings = rfcs[0].entityKeyMappings; + expect(mappings).toHaveLength(1); + expect(mappings[0].fieldMappings[0].isBatch).toBe(true); + }); + }); + + // ═══════════════════════════════════════════════════════════════════════════ + // Phase 3 attachment edge cases + // ═══════════════════════════════════════════════════════════════════════════ + + describe('config attachment edge cases', () => { + test('36. @openfed__cachePopulate config goes to correct operation type (Mutation vs Subscription)', () => { + // Verify that @openfed__cachePopulate on Mutation goes to "Mutation" config and + // @openfed__cachePopulate on Subscription goes to "Subscription" config. + // BUG CHECK: The code in Phase 3 uses `cp.operationType` as the key into + // configurationDataByTypeName. The operationTypeString is set to "Mutation" + // or "Subscription" — but when operationType is SUBSCRIPTION, the string is set to + // "Subscription" only if the operationType is not MUTATION. + // Let's check: operationTypeString = operationType === OperationTypeNode.MUTATION ? MUTATION : SUBSCRIPTION + // This means for Query it would be "Subscription" — but Query fields with @openfed__cachePopulate + // are already rejected by rule 17. So this is fine for valid inputs. + + // Test Subscription specifically + const config = getConfigForType( + subgraph(` + type Query { dummy: String! } + type Subscription { + newProduct: Product @openfed__cachePopulate(maxAge: 120) + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + SUBSCRIPTION, + ); + expect(config).toBeDefined(); + expect(config!.cachePopulateConfigurations).toHaveLength(1); + expect(config!.cachePopulateConfigurations![0].operationType).toBe(SUBSCRIPTION); + expect(config!.cachePopulateConfigurations![0].maxAgeSeconds).toBe(120); + }); + + test('37. @openfed__cacheInvalidate config uses correct entityTypeName from return type', () => { + // Verify the entityTypeName is correctly set even when the return type is wrapped. + const config = getConfigForType( + subgraph(` + type Query { dummy: String! } + type Mutation { + deleteProduct(id: ID!): Product @openfed__cacheInvalidate + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + MUTATION, + ); + expect(config).toBeDefined(); + expect(config!.cacheInvalidateConfigurations).toHaveLength(1); + expect(config!.cacheInvalidateConfigurations![0].entityTypeName).toBe('Product'); + }); + + test('38. Multiple @openfed__queryCache fields on same Query type — all get configs', () => { + // Two different query fields with @openfed__queryCache returning different entities. + const config = getConfigForType( + subgraph(` + type Query { + product(id: ID!): Product @openfed__queryCache(maxAge: 30) + user(id: ID!): User @openfed__queryCache(maxAge: 45) + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + type User @key(fields: "id") @openfed__entityCache(maxAge: 90) { + id: ID! + name: String! + } + `), + QUERY, + ); + expect(config).toBeDefined(); + expect(config!.rootFieldCacheConfigurations).toHaveLength(2); + const fieldNames = config!.rootFieldCacheConfigurations!.map((r) => r.fieldName).sort(); + expect(fieldNames).toStrictEqual(['product', 'user']); + }); + + test('39. Multiple mutations with different cache directives — all get correct configs', () => { + const sg = subgraph(` + type Query { dummy: String! } + type Mutation { + updateProduct(id: ID!): Product @openfed__cacheInvalidate + createProduct(name: String!): Product @openfed__cachePopulate(maxAge: 30) + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `); + const result = batchNormalize({ subgraphs: [sg], version }) as BatchNormalizationSuccess; + expect(result.success).toBe(true); + const internal = result.internalSubgraphByName.get(sg.name)!; + const mutConfig = internal.configurationDataByTypeName.get(MUTATION as TypeName); + expect(mutConfig).toBeDefined(); + expect(mutConfig!.cacheInvalidateConfigurations).toHaveLength(1); + expect(mutConfig!.cacheInvalidateConfigurations![0].fieldName).toBe('updateProduct'); + expect(mutConfig!.cachePopulateConfigurations).toHaveLength(1); + expect(mutConfig!.cachePopulateConfigurations![0].fieldName).toBe('createProduct'); + }); + }); + + // ═══════════════════════════════════════════════════════════════════════════ + // Potential silent corruption scenarios + // ═══════════════════════════════════════════════════════════════════════════ + + describe('potential silent corruption', () => { + test('40. @openfed__entityCache without maxAge argument — should error (maxAge is required)', () => { + // If the directive definition makes maxAge required, parsing should fail. + // But if it somehow gets through, the code defaults maxAgeSeconds to 0 which would + // be caught by the <= 0 check. + const sg = subgraph(` + type Query { product(id: ID!): Product } + type Product @key(fields: "id") @openfed__entityCache { + id: ID! + name: String! + } + `); + const result = batchNormalize({ subgraphs: [sg], version }); + // Should fail because maxAge is required + expect(result.success).toBe(false); + }); + + test('41. @openfed__queryCache maxAge as float (3.5) — should be parsed as 0 and error', () => { + // maxAge is Int!, a float value should either fail parsing or be treated as 0. + const sg = subgraph(` + type Query { + product(id: ID!): Product @openfed__queryCache(maxAge: 3.5) + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `); + const result = batchNormalize({ subgraphs: [sg], version }); + // A float value for an Int! field should fail at some point + expect(result.success).toBe(false); + }); + + test('42. @openfed__is on argument of non-Query field without @openfed__queryCache — error about @openfed__is without @openfed__queryCache', () => { + // @openfed__is without @openfed__queryCache on a Mutation argument — should still error about @openfed__is placement. + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Query { dummy: String! } + type Mutation { + updateProduct(pid: ID! @openfed__is(fields: "id")): Product @openfed__cacheInvalidate + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + version, + ); + // Should have error about @openfed__is without @openfed__queryCache + expect(errors).toHaveLength(1); + }); + + test('43. @openfed__queryCache on field returning entity with @key but entity has NO fields matching any argument — empty mappings, no warning', () => { + // product(name: String!): Product — "name" is not a key field. + // Should succeed with empty mappings and no warning (this is already tested, just double-checking). + const { warnings } = normalizeSubgraphSuccess( + subgraph(` + type Query { + product(name: String!): Product @openfed__queryCache(maxAge: 30) + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + version, + ); + expect(warnings).toHaveLength(0); + }); + + test('44. @openfed__queryCache with very large maxAge but @openfed__entityCache with very small maxAge — no error about TTL mismatch', () => { + // The query cache TTL (3600) is much larger than the entity cache TTL (1). + // This means cached query results would reference entities that expired long ago. + // No validation exists for this — it's a logical error but not caught. + const config = getConfigForType( + subgraph(` + type Query { + product(id: ID!): Product @openfed__queryCache(maxAge: 3600) + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 1) { + id: ID! + name: String! + } + `), + QUERY, + ); + expect(config).toBeDefined(); + // Succeeds without warning — the router would serve stale query cache entries + // that reference long-expired entity cache entries. This is a potential foot-gun + // but not necessarily a bug — just worth noting. + expect(config!.rootFieldCacheConfigurations![0].maxAgeSeconds).toBe(3600); + }); + + test('45. @openfed__queryCache on field returning entity that exists only in another subgraph', () => { + // The entity type Product is defined in subgraph-b but not in subgraph-a. + // However, subgraph-a references it as a return type and adds @openfed__queryCache. + // Expectation updated (bug a fix): without @openfed__entityCache on Product, the + // queryCache config is NOT extracted — we warn the subgraph author that they need + // to either add @openfed__entityCache or remove @openfed__queryCache. + const sg = subgraph(` + type Query { + product(id: ID!): Product @openfed__queryCache(maxAge: 30) + } + type Product @key(fields: "id") { + id: ID! + } + `); + const config = getConfigForType(sg, QUERY); + expect(config).toBeDefined(); + expect(config!.rootFieldCacheConfigurations).toBeUndefined(); + }); + }); +}); diff --git a/composition/tests/v1/directives/entity-cache-mapping-rules.test.ts b/composition/tests/v1/directives/entity-cache-mapping-rules.test.ts new file mode 100644 index 0000000000..a12c18b840 --- /dev/null +++ b/composition/tests/v1/directives/entity-cache-mapping-rules.test.ts @@ -0,0 +1,3007 @@ +import { describe, expect, test } from 'vitest'; +import { + type ConfigurationData, + type BatchNormalizationSuccess, + FIRST_ORDINAL, + invalidDirectiveError, + IS, + parse, + QUERY, + QUERY_CACHE, + RootFieldCacheConfig, + ROUTER_COMPATIBILITY_VERSION_ONE, + type Subgraph, + type TypeName, +} from '../../../src'; +import { BatchNormalizer } from '../../../src'; + +// main refactored the free function batchNormalize() into the BatchNormalizer class; +// keep the old call shape for these tests (version is accepted and ignored). +const batchNormalize = (params: any) => new BatchNormalizer(params).batchNormalize(); +import { + duplicateKeyFieldMappingErrorMessage, + invalidRepeatedDirectiveErrorMessage, + isReferencesUnknownKeyFieldErrorMessage, + queryCacheOnNonEntityReturnTypeErrorMessage, + queryCacheOnNonQueryFieldErrorMessage, +} from '../../../src/errors/errors'; +import { + incompleteQueryCacheKeyMappingWarning, + queryCacheReturnEntityMissingEntityCacheWarning, + redundantIsDirectiveWarning, +} from '../../../src/v1/warnings/warnings'; +import { normalizeSubgraphFailure, normalizeSubgraphSuccess } from '../../utils/utils'; + +const version = ROUTER_COMPATIBILITY_VERSION_ONE; + +function subgraph(sdl: string, name = 'subgraph-a'): Subgraph { + return { name, url: '', definitions: parse(sdl) }; +} + +function getConfigForType(sg: Subgraph, typeName: string): ConfigurationData | undefined { + const result = batchNormalize({ subgraphs: [sg], version }) as BatchNormalizationSuccess; + expect(result.success).toBe(true); + const internal = result.internalSubgraphByName.get(sg.name); + expect(internal).toBeDefined(); + return internal!.configurationDataByTypeName.get(typeName as TypeName); +} + +function getSingleQueryRootFieldConfig(sdl: string, fieldName: string) { + const config = getConfigForType(subgraph(sdl), QUERY); + expect(config).toBeDefined(); + expect(config!.rootFieldCacheConfigurations).toBeDefined(); + expect(config!.rootFieldCacheConfigurations).toHaveLength(1); + expect(config!.rootFieldCacheConfigurations![0].fieldName).toBe(fieldName); + return config!.rootFieldCacheConfigurations![0]; +} + +function autoMappingTypeMismatchWarningMessage( + argumentName: string, + fieldCoords: string, + argumentType: string, + keyField: string, + entityType: string, + keyFieldType: string, +) { + return `Argument "${argumentName}" on field "${fieldCoords}" has type "${argumentType}" but @key field "${keyField}" on entity "${entityType}" has type "${keyFieldType}". Auto-mapping skipped due to type mismatch.`; +} + +function explicitTypeMismatchErrorMessage( + argumentName: string, + fieldCoords: string, + argumentType: string, + isField: string, + entityType: string, + keyFieldType: string, +) { + return `Argument "${argumentName}" on field "${fieldCoords}" has type "${argumentType}" but @openfed__is(fields: "${isField}") targets @key field "${isField}" of type "${keyFieldType}" on entity "${entityType}".`; +} + +function unknownKeyFieldSpecErrorMessage( + argumentName: string, + fieldCoords: string, + isField: string, + entityType: string, +) { + return `Argument "${argumentName}" on field "${fieldCoords}" uses @openfed__is(fields: "${isField}") but "${isField}" is not a field in any @key on entity "${entityType}".`; +} + +function nonKeyFieldSpecErrorMessage(argumentName: string, fieldCoords: string, isField: string, entityType: string) { + return `Argument "${argumentName}" on field "${fieldCoords}" uses @openfed__is(fields: "${isField}"), but "${isField}" is not a @key field on entity "${entityType}". @openfed__is can only target fields that are part of a @key.`; +} + +function listArgumentToScalarKeySpecErrorMessage( + argumentName: string, + fieldCoords: string, + argumentType: string, + isField: string, + entityType: string, + keyFieldType: string, +) { + return ( + `Argument "${argumentName}" on field "${fieldCoords}" has type "${argumentType}" but @openfed__is(fields: "${isField}") targets @key field "${isField}" of type "${keyFieldType}" on entity "${entityType}".` + + ' List arguments can only map to scalar key fields when the field returns a list of entities, or to list key fields when the key field itself is a list type.' + ); +} + +function scalarArgumentToListKeySpecErrorMessage( + argumentName: string, + fieldCoords: string, + argumentType: string, + isField: string, + entityType: string, + keyFieldType: string, +) { + return ( + `Argument "${argumentName}" on field "${fieldCoords}" has type "${argumentType}" but @openfed__is(fields: "${isField}") targets @key field "${isField}" of type "${keyFieldType}" on entity "${entityType}".` + + ' A scalar argument cannot map to a list key field.' + ); +} + +function implicitIncompleteCompositeKeyWarningMessage( + argumentName: string, + fieldCoords: string, + keyField: string, + entityType: string, + compositeKey: string, + missingField: string, +) { + return `Argument "${argumentName}" on field "${fieldCoords}" matches @key field "${keyField}" on entity "${entityType}", but composite @key "${compositeKey}" is incomplete because no argument maps to required key field "${missingField}". Auto-mapping skipped — all fields of a composite key must be mapped.`; +} + +function explicitIncompleteCompositeKeyErrorMessage( + fieldCoords: string, + argumentName: string, + mappedField: string, + entityType: string, + compositeKey: string, + missingField: string, +) { + return `Field "${fieldCoords}" has argument "${argumentName}" with @openfed__is mapping to @key field "${mappedField}" on entity "${entityType}", but composite @key "${compositeKey}" is incomplete because no argument maps to required key field "${missingField}".`; +} + +function autoMappingAdditionalNonKeyArgumentWarningMessage( + argumentName: string, + fieldCoords: string, + keyField: string, + entityType: string, + extraArgument: string, +) { + return `Argument "${argumentName}" on field "${fieldCoords}" matches @key field "${keyField}" on entity "${entityType}", but field has additional argument "${extraArgument}" which is not mapped to a key field. Auto-mapping skipped — all arguments must be key arguments because additional arguments may filter the response, making the cache key incomplete.`; +} + +function explicitSingularAdditionalNonKeyArgumentErrorMessage( + fieldCoords: string, + argumentName: string, + keyField: string, + entityType: string, + extraArgument: string, +) { + return `Field "${fieldCoords}" has argument "${argumentName}" with @openfed__is mapping to @key field "${keyField}" on entity "${entityType}", but also has additional argument "${extraArgument}" which is not mapped to a key field. All arguments must be key arguments — additional arguments may filter the response, making the cache key incomplete.`; +} + +function explicitCompositeAdditionalNonKeyArgumentErrorMessage( + fieldCoords: string, + firstArgument: string, + secondArgument: string, + compositeKey: string, + entityType: string, + extraArgument: string, +) { + return `Field "${fieldCoords}" has arguments "${firstArgument}" and "${secondArgument}" with @openfed__is mappings covering composite @key "${compositeKey}" on entity "${entityType}", but also has additional argument "${extraArgument}" which is not mapped to a key field. All arguments must be key arguments — additional arguments may filter the response, making the cache key incomplete.`; +} + +function batchListValuedKeyRequiresNestedListsErrorMessage( + fieldCoords: string, + isField: string, + entityType: string, + actualType: string, +) { + return `Field "${fieldCoords}" returns a list of entities, so cache lookup is a batch lookup and requires one key value per entity. Because @openfed__is(fields: "${isField}") targets list-valued @key field "${isField}" on entity "${entityType}", the argument must provide a list of tag lists (e.g., "[[String!]!]!"), not ${actualType}.`; +} + +function explicitBatchAdditionalNonKeyArgumentErrorMessage( + fieldCoords: string, + argumentName: string, + keyField: string, + entityType: string, + extraArgument: string, +) { + return `Field "${fieldCoords}" returns a list of entities, so cache lookup is a batch lookup and requires a single key input that determines the returned entities. Argument "${argumentName}" uses @openfed__is to map to @key field "${keyField}" on entity "${entityType}", but additional argument "${extraArgument}" is not mapped to a key field and may filter the response, so the batch key would be incomplete.`; +} + +function autoBatchAdditionalNonKeyArgumentWarningMessage( + fieldCoords: string, + argumentName: string, + keyField: string, + entityType: string, + extraArgument: string, +) { + return `Field "${fieldCoords}" returns a list of entities, so cache lookup is a batch lookup and requires a single key input that determines the returned entities. Argument "${argumentName}" matches @key field "${keyField}" on entity "${entityType}", but additional argument "${extraArgument}" is not mapped to a key field and may filter the response, so auto-mapping is skipped because the batch key would be incomplete.`; +} + +function explicitScalarArgumentsCannotEstablishBatchMappingErrorMessage(fieldCoords: string, entityType: string) { + return `Field "${fieldCoords}" returns a list of entities, so cache lookup is a batch lookup and requires one key value per entity. Scalar arguments with @openfed__is mapping to @key fields on entity "${entityType}" cannot provide a batch of keys, so they cannot establish cache key mappings for this field. Use list arguments for batch cache lookups.`; +} + +function multipleListArgumentsBatchFactoryMessage(fieldCoords: string, entityType: string) { + return ( + `Field "${fieldCoords}" has multiple list arguments mapping to @key fields on entity "${entityType}".` + + ' Batch cache lookups require a single list argument.' + + ' For composite keys, use a single list of input objects instead.' + ); +} + +function inputObjectCompositeTypeMismatchErrorMessage( + argumentName: string, + fieldCoords: string, + keyFields: string, + entityType: string, + inputType: string, + inputFieldName: string, + inputFieldType: string, + entityFieldPath: string, + entityFieldType: string, +) { + return ( + `Argument "${argumentName}" on field "${fieldCoords}" uses @openfed__is(fields: "${keyFields}") mapping to composite @key on entity "${entityType}",` + + ` but input type "${inputType}" field "${inputFieldName}" has type "${inputFieldType}"` + + ` which does not match key field "${entityFieldPath}" of type "${entityFieldType}".` + ); +} + +function inputObjectCompositeMissingFieldErrorMessage( + argumentName: string, + fieldCoords: string, + keyFields: string, + entityType: string, + inputType: string, + missingFieldName: string, +) { + return ( + `Argument "${argumentName}" on field "${fieldCoords}" uses @openfed__is(fields: "${keyFields}") mapping to composite @key on entity "${entityType}",` + + ` but input type "${inputType}" is missing required key field "${missingFieldName}".` + ); +} + +function nestedInputObjectTypeMismatchErrorMessage( + argumentName: string, + fieldCoords: string, + keyFields: string, + entityType: string, + inputType: string, + inputFieldName: string, + inputFieldType: string, + entityFieldPath: string, + entityFieldType: string, +) { + return ( + `Argument "${argumentName}" on field "${fieldCoords}" maps to nested @key "${keyFields}" on entity "${entityType}",` + + ` but input type "${inputType}" field "${inputFieldName}" has type "${inputFieldType}"` + + ` which does not match key field "${entityFieldPath}" of type "${entityFieldType}".` + ); +} + +function nestedInputObjectMissingFieldErrorMessage( + argumentName: string, + fieldCoords: string, + keyFields: string, + entityType: string, + inputType: string, + missingFieldName: string, +) { + return ( + `Argument "${argumentName}" on field "${fieldCoords}" maps to nested @key "${keyFields}" on entity "${entityType}",` + + ` but input type "${inputType}" is missing required key field "${missingFieldName}".` + ); +} + +function nonInputArgumentCannotTargetCompositeKeyErrorMessage( + argumentName: string, + fieldCoords: string, + keyFields: string, + entityType: string, + argumentType: string, +) { + return ( + `Argument "${argumentName}" on field "${fieldCoords}" uses @openfed__is(fields: "${keyFields}") targeting composite @key on entity "${entityType}",` + + ` but argument type "${argumentType}" does not provide nested fields for each key field.` + + ' Use separate arguments or an input object that matches the composite key shape.' + ); +} + +describe('Entity cache mapping rules tests', () => { + describe('message factory coverage', () => { + test('shared mapping-rule message factories produce the documented text', () => { + expect(queryCacheOnNonEntityReturnTypeErrorMessage('Query.product', 'Result')).toBe( + 'Field "Query.product" has @openfed__queryCache but returns non-entity type "Result". @openfed__queryCache requires the return type to be an entity with @key.', + ); + expect(queryCacheOnNonQueryFieldErrorMessage('Mutation.updateProduct')).toBe( + '@openfed__queryCache must only be defined on fields of the root query type; found on "Mutation.updateProduct".' + + ' Use @openfed__cachePopulate or @openfed__cacheInvalidate on mutation or subscription fields.', + ); + expect(invalidRepeatedDirectiveErrorMessage(QUERY_CACHE)).toBe( + 'The definition for the directive "@openfed__queryCache" does not define it as repeatable, but it is declared more than once on these coordinates.', + ); + expect(isReferencesUnknownKeyFieldErrorMessage('unknown', 'pid', 'Query.product', 'Product')).toBe( + '@openfed__is(fields: "unknown") on argument "pid" of field "Query.product" references unknown @key field "unknown" on type "Product".', + ); + expect(duplicateKeyFieldMappingErrorMessage('Query.product', 'id')).toBe( + 'Multiple arguments on field "Query.product" map to @key field "id".', + ); + expect(multipleListArgumentsBatchFactoryMessage('Query.products', 'Product')).toBe( + 'Field "Query.products" has multiple list arguments mapping to @key fields on entity "Product". Batch cache lookups require a single list argument. For composite keys, use a single list of input objects instead.', + ); + expect(autoMappingTypeMismatchWarningMessage('id', 'Query.product', 'String!', 'id', 'Product', 'ID!')).toBe( + 'Argument "id" on field "Query.product" has type "String!" but @key field "id" on entity "Product" has type "ID!". Auto-mapping skipped due to type mismatch.', + ); + expect(explicitTypeMismatchErrorMessage('pid', 'Query.product', 'String!', 'id', 'Product', 'ID!')).toBe( + 'Argument "pid" on field "Query.product" has type "String!" but @openfed__is(fields: "id") targets @key field "id" of type "ID!" on entity "Product".', + ); + expect(unknownKeyFieldSpecErrorMessage('pid', 'Query.product', 'unknown', 'Product')).toBe( + 'Argument "pid" on field "Query.product" uses @openfed__is(fields: "unknown") but "unknown" is not a field in any @key on entity "Product".', + ); + expect(nonKeyFieldSpecErrorMessage('pname', 'Query.product', 'name', 'Product')).toBe( + 'Argument "pname" on field "Query.product" uses @openfed__is(fields: "name"), but "name" is not a @key field on entity "Product". @openfed__is can only target fields that are part of a @key.', + ); + expect( + implicitIncompleteCompositeKeyWarningMessage('id', 'Query.product', 'id', 'Product', 'id region', 'region'), + ).toBe( + 'Argument "id" on field "Query.product" matches @key field "id" on entity "Product", but composite @key "id region" is incomplete because no argument maps to required key field "region". Auto-mapping skipped — all fields of a composite key must be mapped.', + ); + expect( + explicitBatchAdditionalNonKeyArgumentErrorMessage('Query.products', 'ids', 'id', 'Product', 'category'), + ).toBe( + 'Field "Query.products" returns a list of entities, so cache lookup is a batch lookup and requires a single key input that determines the returned entities. Argument "ids" uses @openfed__is to map to @key field "id" on entity "Product", but additional argument "category" is not mapped to a key field and may filter the response, so the batch key would be incomplete.', + ); + expect( + incompleteQueryCacheKeyMappingWarning({ + subgraphName: 'subgraph-a', + fieldCoords: 'Query.product', + entityType: 'Product', + unmappedKeyField: 'region', + }).message, + ).toBe( + 'Field "Query.product" has @openfed__queryCache returning "Product" but @key field "region" cannot be mapped to any argument. Cache reads are disabled for this field (cache writes/population still work). Add an argument named "region" or use @openfed__is(fields: "region") to enable cache reads.', + ); + }); + }); + + describe('prerequisite rules', () => { + test('rule 0a: error when @openfed__queryCache is declared on a field that returns a non-entity type', () => { + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Result { + success: Boolean! + } + + type Query { + product(id: ID!): Result @openfed__queryCache(maxAge: 30) + } + `), + version, + ); + + expect(errors).toHaveLength(1); + expect(errors[0]).toStrictEqual( + invalidDirectiveError(QUERY_CACHE, 'Query.product', FIRST_ORDINAL, [ + queryCacheOnNonEntityReturnTypeErrorMessage('Query.product', 'Result'), + ]), + ); + }); + + // Expectation updated to new correct behavior: @openfed__queryCache on a field returning + // a @key entity without @openfed__entityCache emits a warning and does NOT extract any + // queryCache config — there is no entity-cache backing store to point at. + test('rule 0b: @openfed__queryCache on a @key entity without @openfed__entityCache warns and extracts no config', () => { + const sdl = ` + type Product @key(fields: "id") { + id: ID! + name: String! + } + + type Query { + product(id: ID!): Product @openfed__queryCache(maxAge: 30) + } + `; + + const { warnings } = normalizeSubgraphSuccess(subgraph(sdl), version); + expect(warnings).toHaveLength(1); + expect(warnings[0]).toStrictEqual( + queryCacheReturnEntityMissingEntityCacheWarning({ + subgraphName: 'subgraph-a', + fieldCoords: 'Query.product', + entityType: 'Product', + }), + ); + + const config = getConfigForType(subgraph(sdl), QUERY); + expect(config).toBeDefined(); + expect(config!.rootFieldCacheConfigurations).toBeUndefined(); + }); + + test('rule 0b-positive: @openfed__queryCache on a @key entity WITH @openfed__entityCache extracts the config and emits no warning', () => { + const sdl = ` + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + + type Query { + product(id: ID!): Product @openfed__queryCache(maxAge: 30) + } + `; + + const { warnings } = normalizeSubgraphSuccess(subgraph(sdl), version); + expect(warnings).toHaveLength(0); + + const rootFieldConfig = getSingleQueryRootFieldConfig(sdl, 'product'); + expect(rootFieldConfig).toStrictEqual({ + fieldName: 'product', + maxAgeSeconds: 30, + includeHeaders: false, + shadowMode: false, + entityTypeName: 'Product', + entityKeyMappings: [ + { + entityTypeName: 'Product', + fieldMappings: [{ entityKeyField: 'id', argumentPath: ['id'] }], + }, + ], + } satisfies RootFieldCacheConfig); + }); + + test('rule 0c: error when @openfed__queryCache is declared on a non-Query root field', () => { + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Mutation { + updateProduct(id: ID!): Product @openfed__queryCache(maxAge: 30) + } + + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + version, + ); + + expect(errors).toHaveLength(1); + expect(errors[0]).toStrictEqual( + invalidDirectiveError(QUERY_CACHE, 'Mutation.updateProduct', FIRST_ORDINAL, [ + queryCacheOnNonQueryFieldErrorMessage('Mutation.updateProduct'), + ]), + ); + }); + + test('rule 0d: error when @openfed__queryCache is declared more than once on the same Query field', () => { + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + } + + type Query { + product(id: ID!): Product @openfed__queryCache(maxAge: 30) @openfed__queryCache(maxAge: 30) + } + `), + version, + ); + + expect(errors).toHaveLength(1); + expect(errors[0]).toStrictEqual( + invalidDirectiveError(QUERY_CACHE, 'Query.product', FIRST_ORDINAL, [ + invalidRepeatedDirectiveErrorMessage(QUERY_CACHE), + ]), + ); + }); + }); + + describe('singular return: auto-mapping', () => { + test('rule 1: exact scalar type match emits a single entity key mapping', () => { + const rootFieldConfig = getSingleQueryRootFieldConfig( + ` + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + + type Query { + product(id: ID!): Product @openfed__queryCache(maxAge: 30) + } + `, + 'product', + ); + + expect(rootFieldConfig.entityKeyMappings).toStrictEqual([ + { + entityTypeName: 'Product', + fieldMappings: [{ entityKeyField: 'id', argumentPath: ['id'] }], + }, + ]); + }); + + test('rule 2: String argument for an ID key field is skipped with an auto-mapping warning', () => { + const { warnings } = normalizeSubgraphSuccess( + subgraph(` + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + + type Query { + product(id: String!): Product @openfed__queryCache(maxAge: 30) + } + `), + version, + ); + + expect(warnings).toHaveLength(1); + expect(warnings[0].subgraph.name).toBe('subgraph-a'); + expect(warnings[0].message).toBe( + autoMappingTypeMismatchWarningMessage('id', 'Query.product', 'String!', 'id', 'Product', 'ID!'), + ); + }); + + test('rule 3: Int argument for an ID key field is skipped with an auto-mapping warning', () => { + const { warnings } = normalizeSubgraphSuccess( + subgraph(` + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + + type Query { + product(id: Int!): Product @openfed__queryCache(maxAge: 30) + } + `), + version, + ); + + expect(warnings).toHaveLength(1); + expect(warnings[0].message).toBe( + autoMappingTypeMismatchWarningMessage('id', 'Query.product', 'Int!', 'id', 'Product', 'ID!'), + ); + }); + + test('rule 4: Int argument for a String key field is skipped with an auto-mapping warning', () => { + const { warnings } = normalizeSubgraphSuccess( + subgraph(` + type Product @key(fields: "sku") @openfed__entityCache(maxAge: 60) { + sku: String! + name: String! + } + + type Query { + product(sku: Int!): Product @openfed__queryCache(maxAge: 30) + } + `), + version, + ); + + expect(warnings).toHaveLength(1); + expect(warnings[0].message).toBe( + autoMappingTypeMismatchWarningMessage('sku', 'Query.product', 'Int!', 'sku', 'Product', 'String!'), + ); + }); + + test('rule 5: exact enum type match emits a composite key mapping', () => { + const rootFieldConfig = getSingleQueryRootFieldConfig( + ` + enum Region { + US + EU + APAC + } + + type Product @key(fields: "id region") @openfed__entityCache(maxAge: 60) { + id: ID! + region: Region! + name: String! + } + + type Query { + product(id: ID!, region: Region!): Product @openfed__queryCache(maxAge: 30) + } + `, + 'product', + ); + + expect(rootFieldConfig.entityKeyMappings).toStrictEqual([ + { + entityTypeName: 'Product', + fieldMappings: [ + { entityKeyField: 'id', argumentPath: ['id'] }, + { entityKeyField: 'region', argumentPath: ['region'] }, + ], + }, + ]); + }); + + test('rule 6: enum auto-mapping is skipped when the argument enum differs from the key enum', () => { + const { warnings } = normalizeSubgraphSuccess( + subgraph(` + enum Region { + US + EU + } + + enum Zone { + NORTH + SOUTH + } + + type Product @key(fields: "region") @openfed__entityCache(maxAge: 60) { + region: Region! + name: String! + } + + type Query { + product(region: Zone!): Product @openfed__queryCache(maxAge: 30) + } + `), + version, + ); + + expect(warnings).toHaveLength(1); + expect(warnings[0].message).toBe( + autoMappingTypeMismatchWarningMessage('region', 'Query.product', 'Zone!', 'region', 'Product', 'Region!'), + ); + }); + + test('rule 7: enum-vs-scalar auto-mapping mismatch is skipped with a warning', () => { + const { warnings } = normalizeSubgraphSuccess( + subgraph(` + enum Status { + ACTIVE + INACTIVE + } + + type Product @key(fields: "status") @openfed__entityCache(maxAge: 60) { + status: Status! + name: String! + } + + type Query { + product(status: String!): Product @openfed__queryCache(maxAge: 30) + } + `), + version, + ); + + expect(warnings).toHaveLength(1); + expect(warnings[0].message).toBe( + autoMappingTypeMismatchWarningMessage('status', 'Query.product', 'String!', 'status', 'Product', 'Status!'), + ); + }); + + test('rule 8: exact custom scalar match emits a single entity key mapping', () => { + const rootFieldConfig = getSingleQueryRootFieldConfig( + ` + scalar UUID + + type Product @key(fields: "uid") @openfed__entityCache(maxAge: 60) { + uid: UUID! + name: String! + } + + type Query { + product(uid: UUID!): Product @openfed__queryCache(maxAge: 30) + } + `, + 'product', + ); + + expect(rootFieldConfig.entityKeyMappings).toStrictEqual([ + { + entityTypeName: 'Product', + fieldMappings: [{ entityKeyField: 'uid', argumentPath: ['uid'] }], + }, + ]); + }); + + test('rule 9: custom scalar auto-mapping is skipped when the argument scalar differs from the key scalar', () => { + const { warnings } = normalizeSubgraphSuccess( + subgraph(` + scalar UUID + scalar GUID + + type Product @key(fields: "uid") @openfed__entityCache(maxAge: 60) { + uid: UUID! + name: String! + } + + type Query { + product(uid: GUID!): Product @openfed__queryCache(maxAge: 30) + } + `), + version, + ); + + expect(warnings).toHaveLength(1); + expect(warnings[0].message).toBe( + autoMappingTypeMismatchWarningMessage('uid', 'Query.product', 'GUID!', 'uid', 'Product', 'UUID!'), + ); + }); + + test('rule 10: custom-scalar-vs-built-in-scalar auto-mapping mismatch is skipped with a warning', () => { + const { warnings } = normalizeSubgraphSuccess( + subgraph(` + scalar UUID + + type Product @key(fields: "uid") @openfed__entityCache(maxAge: 60) { + uid: UUID! + name: String! + } + + type Query { + product(uid: String!): Product @openfed__queryCache(maxAge: 30) + } + `), + version, + ); + + expect(warnings).toHaveLength(1); + expect(warnings[0].message).toBe( + autoMappingTypeMismatchWarningMessage('uid', 'Query.product', 'String!', 'uid', 'Product', 'UUID!'), + ); + }); + + test('rule 11: a nullable argument can map to a non-null key field when the named type matches', () => { + const rootFieldConfig = getSingleQueryRootFieldConfig( + ` + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + + type Query { + product(id: ID): Product @openfed__queryCache(maxAge: 30) + } + `, + 'product', + ); + + expect(rootFieldConfig.entityKeyMappings).toStrictEqual([ + { + entityTypeName: 'Product', + fieldMappings: [{ entityKeyField: 'id', argumentPath: ['id'] }], + }, + ]); + }); + + test('rule 12: a non-null argument can map to a nullable key field when the named type matches', () => { + const rootFieldConfig = getSingleQueryRootFieldConfig( + ` + type Product @key(fields: "sku") @openfed__entityCache(maxAge: 60) { + sku: String + name: String! + } + + type Query { + product(sku: String!): Product @openfed__queryCache(maxAge: 30) + } + `, + 'product', + ); + + expect(rootFieldConfig.entityKeyMappings).toStrictEqual([ + { + entityTypeName: 'Product', + fieldMappings: [{ entityKeyField: 'sku', argumentPath: ['sku'] }], + }, + ]); + }); + + test('rule 13: a list argument cannot auto-map to a scalar key field on a singular return', () => { + const { warnings } = normalizeSubgraphSuccess( + subgraph(` + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + + type Query { + product(id: [ID!]!): Product @openfed__queryCache(maxAge: 30) + } + `), + version, + ); + + expect(warnings).toHaveLength(1); + expect(warnings[0].message).toBe( + autoMappingTypeMismatchWarningMessage('id', 'Query.product', '[ID!]!', 'id', 'Product', 'ID!'), + ); + }); + + test('rule 13b: a list argument can auto-map to a list-valued key field on a singular return', () => { + const rootFieldConfig = getSingleQueryRootFieldConfig( + ` + type Product @key(fields: "tags") @openfed__entityCache(maxAge: 60) { + tags: [String!]! + name: String! + } + + type Query { + product(tags: [String!]!): Product @openfed__queryCache(maxAge: 30) + } + `, + 'product', + ); + + expect(rootFieldConfig.entityKeyMappings).toStrictEqual([ + { + entityTypeName: 'Product', + fieldMappings: [{ entityKeyField: 'tags', argumentPath: ['tags'] }], + }, + ]); + }); + + test('rule 25: a Boolean key field can be auto-mapped when the argument type is also Boolean', () => { + const rootFieldConfig = getSingleQueryRootFieldConfig( + ` + type Feature @key(fields: "name enabled") @openfed__entityCache(maxAge: 60) { + name: String! + enabled: Boolean! + } + + type Query { + feature(name: String!, enabled: Boolean!): Feature @openfed__queryCache(maxAge: 30) + } + `, + 'feature', + ); + + expect(rootFieldConfig.entityKeyMappings).toStrictEqual([ + { + entityTypeName: 'Feature', + fieldMappings: [ + { entityKeyField: 'enabled', argumentPath: ['enabled'] }, + { entityKeyField: 'name', argumentPath: ['name'] }, + ], + }, + ]); + }); + + test('rule 26: Float-vs-Int auto-mapping mismatch is skipped with a warning', () => { + const { warnings } = normalizeSubgraphSuccess( + subgraph(` + type Product @key(fields: "weight") @openfed__entityCache(maxAge: 60) { + weight: Float! + name: String! + } + + type Query { + product(weight: Int!): Product @openfed__queryCache(maxAge: 30) + } + `), + version, + ); + + expect(warnings).toHaveLength(1); + expect(warnings[0].message).toBe( + autoMappingTypeMismatchWarningMessage('weight', 'Query.product', 'Int!', 'weight', 'Product', 'Float!'), + ); + }); + + test('rule 27: if no key is satisfiable, composition emits no mappings and no warning', () => { + const { warnings } = normalizeSubgraphSuccess( + subgraph(` + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + + type Query { + product(name: String!): Product @openfed__queryCache(maxAge: 30) + } + `), + version, + ); + + expect(warnings).toHaveLength(0); + + const rootFieldConfig = getSingleQueryRootFieldConfig( + ` + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + + type Query { + product(name: String!): Product @openfed__queryCache(maxAge: 30) + } + `, + 'product', + ); + + expect(rootFieldConfig.entityKeyMappings).toStrictEqual([]); + }); + }); + + describe('singular return: explicit @openfed__is(fields: ...)', () => { + test('rule 14: explicit @openfed__is(fields: "id") maps a differently named argument to a scalar key field', () => { + const rootFieldConfig = getSingleQueryRootFieldConfig( + ` + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + + type Query { + product(pid: ID! @openfed__is(fields: "id")): Product @openfed__queryCache(maxAge: 30) + } + `, + 'product', + ); + + expect(rootFieldConfig.entityKeyMappings).toStrictEqual([ + { + entityTypeName: 'Product', + fieldMappings: [{ entityKeyField: 'id', argumentPath: ['pid'] }], + }, + ]); + }); + + test('rule 15: explicit @openfed__is(fields: "id") rejects a type mismatch instead of silently skipping it', () => { + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + + type Query { + product(pid: String! @openfed__is(fields: "id")): Product @openfed__queryCache(maxAge: 30) + } + `), + version, + ); + + expect(errors).toHaveLength(1); + expect(errors[0]).toStrictEqual( + invalidDirectiveError(IS, 'Query.product(pid: ...)', FIRST_ORDINAL, [ + explicitTypeMismatchErrorMessage('pid', 'Query.product', 'String!', 'id', 'Product', 'ID!'), + ]), + ); + }); + + test('rule 15a: explicit @openfed__is(fields: "unknown") errors when the target is not present in any @key', () => { + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + + type Query { + product(pid: ID! @openfed__is(fields: "unknown")): Product @openfed__queryCache(maxAge: 30) + } + `), + version, + ); + + expect(errors).toHaveLength(1); + expect(errors[0]).toStrictEqual( + invalidDirectiveError(IS, 'Query.product(pid: ...)', FIRST_ORDINAL, [ + isReferencesUnknownKeyFieldErrorMessage('unknown', 'pid', 'Query.product', 'Product'), + ]), + ); + }); + + test('rule 15a-i: explicit @openfed__is(fields: "name") errors when the target exists on the entity but is not part of any @key', () => { + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + + type Query { + product(pname: String! @openfed__is(fields: "name")): Product @openfed__queryCache(maxAge: 30) + } + `), + version, + ); + + expect(errors).toHaveLength(1); + expect(errors[0]).toStrictEqual( + invalidDirectiveError(IS, 'Query.product(pname: ...)', FIRST_ORDINAL, [ + nonKeyFieldSpecErrorMessage('pname', 'Query.product', 'name', 'Product'), + ]), + ); + }); + + test('rule 15a-ii: explicit @openfed__is cannot map two arguments to the same key field', () => { + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + + type Query { + product(pid: ID! @openfed__is(fields: "id"), altId: ID! @openfed__is(fields: "id")): Product @openfed__queryCache(maxAge: 30) + } + `), + version, + ); + + expect(errors).toHaveLength(1); + expect(errors[0]).toStrictEqual( + invalidDirectiveError(IS, 'Query.product(altId: ...)', FIRST_ORDINAL, [ + duplicateKeyFieldMappingErrorMessage('Query.product', 'id'), + ]), + ); + }); + + test('rule 15b: explicit @openfed__is accepts a nullable argument for a non-null key field when the named type matches', () => { + const rootFieldConfig = getSingleQueryRootFieldConfig( + ` + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + + type Query { + product(pid: ID @openfed__is(fields: "id")): Product @openfed__queryCache(maxAge: 30) + } + `, + 'product', + ); + + expect(rootFieldConfig.entityKeyMappings).toStrictEqual([ + { + entityTypeName: 'Product', + fieldMappings: [{ entityKeyField: 'id', argumentPath: ['pid'] }], + }, + ]); + }); + + test('rule 15c: explicit list argument cannot target a scalar key field on a singular return', () => { + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + + type Query { + product(pids: [ID!]! @openfed__is(fields: "id")): Product @openfed__queryCache(maxAge: 30) + } + `), + version, + ); + + expect(errors).toHaveLength(1); + expect(errors[0]).toStrictEqual( + invalidDirectiveError(IS, 'Query.product(pids: ...)', FIRST_ORDINAL, [ + listArgumentToScalarKeySpecErrorMessage('pids', 'Query.product', '[ID!]!', 'id', 'Product', 'ID!'), + ]), + ); + }); + + test('rule 15d: explicit list argument can target a list-valued key field on a singular return', () => { + const rootFieldConfig = getSingleQueryRootFieldConfig( + ` + type Product @key(fields: "tags") @openfed__entityCache(maxAge: 60) { + tags: [String!]! + name: String! + } + + type Query { + product(tags: [String!]! @openfed__is(fields: "tags")): Product @openfed__queryCache(maxAge: 30) + } + `, + 'product', + ); + + expect(rootFieldConfig.entityKeyMappings).toStrictEqual([ + { + entityTypeName: 'Product', + fieldMappings: [{ entityKeyField: 'tags', argumentPath: ['tags'] }], + }, + ]); + }); + + test('rule 15e: explicit list argument rejects a list-valued key field when the element types differ', () => { + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Product @key(fields: "tags") @openfed__entityCache(maxAge: 60) { + tags: [String!]! + name: String! + } + + type Query { + product(tags: [Int!]! @openfed__is(fields: "tags")): Product @openfed__queryCache(maxAge: 30) + } + `), + version, + ); + + expect(errors).toHaveLength(1); + expect(errors[0]).toStrictEqual( + invalidDirectiveError(IS, 'Query.product(tags: ...)', FIRST_ORDINAL, [ + explicitTypeMismatchErrorMessage('tags', 'Query.product', '[Int!]!', 'tags', 'Product', '[String!]!'), + ]), + ); + }); + + // Expectation updated (bug b fix): redundant @openfed__is(fields: "id") on argument "id" + // now emits a warning — auto-mapping produces the same result, so the directive is noise. + test('rule 28: redundant @openfed__is(fields: "id") on matching argument name emits a redundancy warning', () => { + const sdl = ` + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + + type Query { + product(id: ID! @openfed__is(fields: "id")): Product @openfed__queryCache(maxAge: 30) + } + `; + + const { warnings } = normalizeSubgraphSuccess(subgraph(sdl), version); + + expect(warnings).toHaveLength(1); + expect(warnings[0]).toStrictEqual( + redundantIsDirectiveWarning({ + subgraphName: 'subgraph-a', + argumentName: 'id', + fieldCoords: 'Query.product', + keyField: 'id', + entityType: 'Product', + }), + ); + + const rootFieldConfig = getSingleQueryRootFieldConfig(sdl, 'product'); + + expect(rootFieldConfig.entityKeyMappings).toStrictEqual([ + { + entityTypeName: 'Product', + fieldMappings: [{ entityKeyField: 'id', argumentPath: ['id'] }], + }, + ]); + }); + + test('rule 15f: explicit scalar argument cannot target a list-valued key field on a singular return', () => { + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Product @key(fields: "tags") @openfed__entityCache(maxAge: 60) { + tags: [String!]! + name: String! + } + + type Query { + product(tag: String! @openfed__is(fields: "tags")): Product @openfed__queryCache(maxAge: 30) + } + `), + version, + ); + + expect(errors).toHaveLength(1); + expect(errors[0]).toStrictEqual( + invalidDirectiveError(IS, 'Query.product(tag: ...)', FIRST_ORDINAL, [ + scalarArgumentToListKeySpecErrorMessage('tag', 'Query.product', 'String!', 'tags', 'Product', '[String!]!'), + ]), + ); + }); + }); + + describe('nested, composite, alternative, and unresolvable keys', () => { + test('rule 16: a nested key leaf can be targeted with explicit @openfed__is(fields: "store.id")', () => { + const rootFieldConfig = getSingleQueryRootFieldConfig( + ` + type Store { + id: ID! + } + + type Product @key(fields: "store { id }") @openfed__entityCache(maxAge: 60) { + store: Store! + name: String! + } + + type Query { + product(storeId: ID! @openfed__is(fields: "store.id")): Product @openfed__queryCache(maxAge: 30) + } + `, + 'product', + ); + + expect(rootFieldConfig.entityKeyMappings).toStrictEqual([ + { + entityTypeName: 'Product', + fieldMappings: [{ entityKeyField: 'store.id', argumentPath: ['storeId'] }], + }, + ]); + }); + + test('rule 17: explicit nested @openfed__is mapping rejects a type mismatch against the nested leaf field', () => { + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Store { + id: ID! + } + + type Product @key(fields: "store { id }") @openfed__entityCache(maxAge: 60) { + store: Store! + name: String! + } + + type Query { + product(storeId: Int! @openfed__is(fields: "store.id")): Product @openfed__queryCache(maxAge: 30) + } + `), + version, + ); + + expect(errors).toHaveLength(1); + expect(errors[0]).toStrictEqual( + invalidDirectiveError(IS, 'Query.product(storeId: ...)', FIRST_ORDINAL, [ + explicitTypeMismatchErrorMessage('storeId', 'Query.product', 'Int!', 'store.id', 'Product', 'ID!'), + ]), + ); + }); + + test('rule 18: a composite key emits a mapping when all fields are matched with correct types', () => { + const rootFieldConfig = getSingleQueryRootFieldConfig( + ` + type Product @key(fields: "id region") @openfed__entityCache(maxAge: 60) { + id: ID! + region: String! + name: String! + } + + type Query { + product(id: ID!, region: String!): Product @openfed__queryCache(maxAge: 30) + } + `, + 'product', + ); + + expect(rootFieldConfig.entityKeyMappings).toStrictEqual([ + { + entityTypeName: 'Product', + fieldMappings: [ + { entityKeyField: 'id', argumentPath: ['id'] }, + { entityKeyField: 'region', argumentPath: ['region'] }, + ], + }, + ]); + }); + + test('rule 19: if one composite-key argument has an auto-mapping type mismatch, the key becomes unsatisfiable', () => { + const { warnings } = normalizeSubgraphSuccess( + subgraph(` + type Product @key(fields: "id region") @openfed__entityCache(maxAge: 60) { + id: ID! + region: String! + name: String! + } + + type Query { + product(id: Int!, region: String!): Product @openfed__queryCache(maxAge: 30) + } + `), + version, + ); + + expect(warnings).toHaveLength(1); + expect(warnings[0].message).toBe( + autoMappingTypeMismatchWarningMessage('id', 'Query.product', 'Int!', 'id', 'Product', 'ID!'), + ); + }); + + test('rule 19b: implicit composite-key mapping is skipped when one required key field is missing', () => { + const { warnings } = normalizeSubgraphSuccess( + subgraph(` + type Product @key(fields: "id region") @openfed__entityCache(maxAge: 60) { + id: ID! + region: String! + name: String! + } + + type Query { + product(id: ID!): Product @openfed__queryCache(maxAge: 30) + } + `), + version, + ); + + expect(warnings).toHaveLength(1); + expect(warnings[0]).toStrictEqual( + incompleteQueryCacheKeyMappingWarning({ + subgraphName: 'subgraph-a', + fieldCoords: 'Query.product', + entityType: 'Product', + unmappedKeyField: 'region', + }), + ); + + const rootFieldConfig = getSingleQueryRootFieldConfig( + ` + type Product @key(fields: "id region") @openfed__entityCache(maxAge: 60) { + id: ID! + region: String! + name: String! + } + + type Query { + product(id: ID!): Product @openfed__queryCache(maxAge: 30) + } + `, + 'product', + ); + + expect(rootFieldConfig.entityKeyMappings).toStrictEqual([]); + }); + + test('rule 19c: explicit partial composite-key mapping fails when one required key field is still missing', () => { + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Product @key(fields: "id region") @openfed__entityCache(maxAge: 60) { + id: ID! + region: String! + name: String! + } + + type Query { + product(pid: ID! @openfed__is(fields: "id")): Product @openfed__queryCache(maxAge: 30) + } + `), + version, + ); + + expect(errors).toHaveLength(1); + expect(errors[0]).toStrictEqual( + invalidDirectiveError(IS, 'Query.product(pid: ...)', FIRST_ORDINAL, [ + explicitIncompleteCompositeKeyErrorMessage('Query.product', 'pid', 'id', 'Product', 'id region', 'region'), + ]), + ); + }); + + test('rule 19d: explicit mappings can satisfy all fields of a composite key', () => { + const rootFieldConfig = getSingleQueryRootFieldConfig( + ` + type Product @key(fields: "id region") @openfed__entityCache(maxAge: 60) { + id: ID! + region: String! + name: String! + } + + type Query { + product(pid: ID! @openfed__is(fields: "id"), area: String! @openfed__is(fields: "region")): Product @openfed__queryCache(maxAge: 30) + } + `, + 'product', + ); + + expect(rootFieldConfig.entityKeyMappings).toStrictEqual([ + { + entityTypeName: 'Product', + fieldMappings: [ + { entityKeyField: 'id', argumentPath: ['pid'] }, + { entityKeyField: 'region', argumentPath: ['area'] }, + ], + }, + ]); + }); + + test('rule 19e: explicit composite-key mappings reject a type mismatch on any mapped field', () => { + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Product @key(fields: "id region") @openfed__entityCache(maxAge: 60) { + id: ID! + region: String! + name: String! + } + + type Query { + product(pid: Int! @openfed__is(fields: "id"), area: String! @openfed__is(fields: "region")): Product @openfed__queryCache(maxAge: 30) + } + `), + version, + ); + + expect(errors).toHaveLength(1); + expect(errors[0]).toStrictEqual( + invalidDirectiveError(IS, 'Query.product(pid: ...)', FIRST_ORDINAL, [ + explicitTypeMismatchErrorMessage('pid', 'Query.product', 'Int!', 'id', 'Product', 'ID!'), + ]), + ); + }); + + test('rule 19f: multiple keys are evaluated independently and all satisfiable keys are emitted', () => { + const rootFieldConfig = getSingleQueryRootFieldConfig( + ` + type Product @key(fields: "id region") @key(fields: "sku") @openfed__entityCache(maxAge: 60) { + id: ID! + region: String! + sku: String! + name: String! + } + + type Query { + product(id: ID!, region: String!, sku: String!): Product @openfed__queryCache(maxAge: 30) + } + `, + 'product', + ); + + expect(rootFieldConfig.entityKeyMappings).toStrictEqual([ + { + entityTypeName: 'Product', + fieldMappings: [ + { entityKeyField: 'id', argumentPath: ['id'] }, + { entityKeyField: 'region', argumentPath: ['region'] }, + ], + }, + { + entityTypeName: 'Product', + fieldMappings: [{ entityKeyField: 'sku', argumentPath: ['sku'] }], + }, + ]); + }); + + test('rule 19g: implicit composite-key mapping is skipped when the field also has an extra non-key argument', () => { + const { warnings } = normalizeSubgraphSuccess( + subgraph(` + type Product @key(fields: "id region") @openfed__entityCache(maxAge: 60) { + id: ID! + region: String! + name: String! + } + + type Query { + product(id: ID!, region: String!, category: String!): Product @openfed__queryCache(maxAge: 30) + } + `), + version, + ); + + expect(warnings).toHaveLength(1); + expect(warnings[0].message).toBe( + autoMappingAdditionalNonKeyArgumentWarningMessage('id', 'Query.product', 'id', 'Product', 'category'), + ); + }); + + test('rule 19g-i: explicit composite-key mappings cannot coexist with an extra non-key argument on a singular return', () => { + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Product @key(fields: "id region") @openfed__entityCache(maxAge: 60) { + id: ID! + region: String! + name: String! + } + + type Query { + product( + pid: ID! @openfed__is(fields: "id") + area: String! @openfed__is(fields: "region") + category: String! + ): Product @openfed__queryCache(maxAge: 30) + } + `), + version, + ); + + expect(errors).toHaveLength(1); + expect(errors[0]).toStrictEqual( + invalidDirectiveError(IS, 'Query.product(pid: ...)', FIRST_ORDINAL, [ + explicitCompositeAdditionalNonKeyArgumentErrorMessage( + 'Query.product', + 'pid', + 'area', + 'id region', + 'Product', + 'category', + ), + ]), + ); + }); + + test('rule 20: if one alternative key is satisfiable, it is emitted without warning', () => { + const { warnings } = normalizeSubgraphSuccess( + subgraph(` + type Product @key(fields: "id") @key(fields: "sku") @openfed__entityCache(maxAge: 60) { + id: ID! + sku: String! + name: String! + } + + type Query { + product(sku: String!): Product @openfed__queryCache(maxAge: 30) + } + `), + version, + ); + + expect(warnings).toHaveLength(0); + + const rootFieldConfig = getSingleQueryRootFieldConfig( + ` + type Product @key(fields: "id") @key(fields: "sku") @openfed__entityCache(maxAge: 60) { + id: ID! + sku: String! + name: String! + } + + type Query { + product(sku: String!): Product @openfed__queryCache(maxAge: 30) + } + `, + 'product', + ); + + expect(rootFieldConfig.entityKeyMappings).toStrictEqual([ + { + entityTypeName: 'Product', + fieldMappings: [{ entityKeyField: 'sku', argumentPath: ['sku'] }], + }, + ]); + }); + + // Expectation updated to new correct behavior: a failed auto-map candidate on one @key + // must not abort evaluation of the remaining @key alternatives. The "sku" key still maps. + test('rule 21: an auto-mapping type mismatch on one @key does NOT block alternative-key mappings', () => { + const sdl = ` + type Product @key(fields: "id") @key(fields: "sku") @openfed__entityCache(maxAge: 60) { + id: ID! + sku: String! + name: String! + } + + type Query { + product(id: String!, sku: String!): Product @openfed__queryCache(maxAge: 30) + } + `; + + const { warnings } = normalizeSubgraphSuccess(subgraph(sdl), version); + + expect(warnings).toHaveLength(1); + expect(warnings[0].message).toBe( + autoMappingTypeMismatchWarningMessage('id', 'Query.product', 'String!', 'id', 'Product', 'ID!'), + ); + + const rootFieldConfig = getSingleQueryRootFieldConfig(sdl, 'product'); + + expect(rootFieldConfig.entityKeyMappings).toStrictEqual([ + { + entityTypeName: 'Product', + fieldMappings: [{ entityKeyField: 'sku', argumentPath: ['sku'] }], + }, + ]); + }); + + test('rule 22: flat and nested fields can be combined in one composite key mapping', () => { + const rootFieldConfig = getSingleQueryRootFieldConfig( + ` + type Store { + id: ID! + name: String! + } + + type Product @key(fields: "id store { id }") @openfed__entityCache(maxAge: 60) { + id: ID! + store: Store! + name: String! + } + + type Query { + product(id: ID!, storeId: ID! @openfed__is(fields: "store.id")): Product @openfed__queryCache(maxAge: 30) + } + `, + 'product', + ); + + expect(rootFieldConfig.entityKeyMappings).toStrictEqual([ + { + entityTypeName: 'Product', + fieldMappings: [ + { entityKeyField: 'id', argumentPath: ['id'] }, + { entityKeyField: 'store.id', argumentPath: ['storeId'] }, + ], + }, + ]); + }); + + test('rule 24: resolvable: false does not prevent other matching keys from being used', () => { + const rootFieldConfig = getSingleQueryRootFieldConfig( + ` + type Product @key(fields: "id") @key(fields: "sku", resolvable: false) @openfed__entityCache(maxAge: 60) { + id: ID! + sku: String! + name: String! + } + + type Query { + product(id: ID!): Product @openfed__queryCache(maxAge: 30) + } + `, + 'product', + ); + + expect(rootFieldConfig.entityKeyMappings).toStrictEqual([ + { + entityTypeName: 'Product', + fieldMappings: [{ entityKeyField: 'id', argumentPath: ['id'] }], + }, + ]); + }); + + test('rule 24b: resolvable: false keys still participate in auto-mapping', () => { + const rootFieldConfig = getSingleQueryRootFieldConfig( + ` + type Product @key(fields: "id") @key(fields: "sku", resolvable: false) @openfed__entityCache(maxAge: 60) { + id: ID! + sku: String! + name: String! + } + + type Query { + product(id: ID!, sku: String!): Product @openfed__queryCache(maxAge: 30) + } + `, + 'product', + ); + + // Each @key is an independent alternative (OR semantics), so two separate mappings are emitted. + expect(rootFieldConfig.entityKeyMappings).toStrictEqual([ + { + entityTypeName: 'Product', + fieldMappings: [{ entityKeyField: 'id', argumentPath: ['id'] }], + }, + { + entityTypeName: 'Product', + fieldMappings: [{ entityKeyField: 'sku', argumentPath: ['sku'] }], + }, + ]); + }); + + test('rule 24c: resolvable: false keys remain eligible for explicit @openfed__is mapping', () => { + const rootFieldConfig = getSingleQueryRootFieldConfig( + ` + type Product @key(fields: "id") @key(fields: "sku", resolvable: false) @openfed__entityCache(maxAge: 60) { + id: ID! + sku: String! + name: String! + } + + type Query { + product(id: ID!, productSku: String! @openfed__is(fields: "sku")): Product @openfed__queryCache(maxAge: 30) + } + `, + 'product', + ); + + // Each @key is an independent alternative (OR semantics), so two separate mappings are emitted. + expect(rootFieldConfig.entityKeyMappings).toStrictEqual([ + { + entityTypeName: 'Product', + fieldMappings: [{ entityKeyField: 'id', argumentPath: ['id'] }], + }, + { + entityTypeName: 'Product', + fieldMappings: [{ entityKeyField: 'sku', argumentPath: ['productSku'] }], + }, + ]); + }); + }); + + describe('nested keys', () => { + test('rule 23: a deeply nested @key leaf can be targeted with @openfed__is(fields: "a.b.c.value")', () => { + const rootFieldConfig = getSingleQueryRootFieldConfig( + ` + type C { + value: String! + } + + type B { + c: C! + } + + type A { + b: B! + } + + type Product @key(fields: "a { b { c { value } } }") @openfed__entityCache(maxAge: 60) { + a: A! + name: String! + } + + type Query { + product(val: String! @openfed__is(fields: "a.b.c.value")): Product @openfed__queryCache(maxAge: 30) + } + `, + 'product', + ); + + expect(rootFieldConfig.entityKeyMappings).toStrictEqual([ + { + entityTypeName: 'Product', + fieldMappings: [{ entityKeyField: 'a.b.c.value', argumentPath: ['val'] }], + }, + ]); + }); + + test('rule 23b: deeply nested @openfed__is mapping validates the leaf field type, not just the path string', () => { + const { errors } = normalizeSubgraphFailure( + subgraph(` + type C { + value: String! + } + + type B { + c: C! + } + + type A { + b: B! + } + + type Product @key(fields: "a { b { c { value } } }") @openfed__entityCache(maxAge: 60) { + a: A! + name: String! + } + + type Query { + product(val: Int! @openfed__is(fields: "a.b.c.value")): Product @openfed__queryCache(maxAge: 30) + } + `), + version, + ); + + expect(errors).toHaveLength(1); + expect(errors[0]).toStrictEqual( + invalidDirectiveError(IS, 'Query.product(val: ...)', FIRST_ORDINAL, [ + explicitTypeMismatchErrorMessage('val', 'Query.product', 'Int!', 'a.b.c.value', 'Product', 'String!'), + ]), + ); + }); + }); + + describe('list-return batch mappings', () => { + test('rule 29: a non-key scalar argument on a list-return field emits no mapping and no warning', () => { + const { warnings } = normalizeSubgraphSuccess( + subgraph(` + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + + type Query { + products(category: String!): [Product!]! @openfed__queryCache(maxAge: 30) + } + `), + version, + ); + + expect(warnings).toHaveLength(0); + + const rootFieldConfig = getSingleQueryRootFieldConfig( + ` + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + + type Query { + products(category: String!): [Product!]! @openfed__queryCache(maxAge: 30) + } + `, + 'products', + ); + + expect(rootFieldConfig.entityKeyMappings).toStrictEqual([]); + }); + + test('rule 29b: an explicit list argument establishes a batch cache mapping for a scalar key field', () => { + const rootFieldConfig = getSingleQueryRootFieldConfig( + ` + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + + type Query { + products(ids: [ID!]! @openfed__is(fields: "id")): [Product!]! @openfed__queryCache(maxAge: 30) + } + `, + 'products', + ); + + expect(rootFieldConfig.entityKeyMappings).toStrictEqual([ + { + entityTypeName: 'Product', + fieldMappings: [{ entityKeyField: 'id', argumentPath: ['ids'], isBatch: true }], + }, + ]); + }); + + test('rule 29c: an auto-mapped list argument establishes a batch cache mapping for a scalar key field', () => { + const rootFieldConfig = getSingleQueryRootFieldConfig( + ` + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + + type Query { + products(id: [ID!]!): [Product!]! @openfed__queryCache(maxAge: 30) + } + `, + 'products', + ); + + expect(rootFieldConfig.entityKeyMappings).toStrictEqual([ + { + entityTypeName: 'Product', + fieldMappings: [{ entityKeyField: 'id', argumentPath: ['id'], isBatch: true }], + }, + ]); + }); + + test('rule 29e: a composite batch key cannot use multiple separate list arguments', () => { + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Product @key(fields: "id sku") @openfed__entityCache(maxAge: 60) { + id: ID! + sku: String! + name: String! + } + + type Query { + products(ids: [ID!]! @openfed__is(fields: "id"), skus: [String!]! @openfed__is(fields: "sku")): [Product!]! @openfed__queryCache(maxAge: 30) + } + `), + version, + ); + + expect(errors).toHaveLength(1); + expect(errors[0]).toStrictEqual( + invalidDirectiveError(QUERY_CACHE, 'Query.products', FIRST_ORDINAL, [ + multipleListArgumentsBatchFactoryMessage('Query.products', 'Product'), + ]), + ); + }); + + test('rule 15g: list return plus a single list argument is not enough for a list-valued key field', () => { + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Product @key(fields: "tags") @openfed__entityCache(maxAge: 60) { + tags: [String!]! + name: String! + } + + type Query { + products(tags: [String!]! @openfed__is(fields: "tags")): [Product!]! @openfed__queryCache(maxAge: 30) + } + `), + version, + ); + + expect(errors).toHaveLength(1); + expect(errors[0]).toStrictEqual( + invalidDirectiveError(IS, 'Query.products(tags: ...)', FIRST_ORDINAL, [ + batchListValuedKeyRequiresNestedListsErrorMessage( + 'Query.products', + 'tags', + 'Product', + 'a single tag list of type "[String!]!"', + ), + ]), + ); + }); + + test('rule 15h: list return plus a scalar argument is not enough for a list-valued key field', () => { + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Product @key(fields: "tags") @openfed__entityCache(maxAge: 60) { + tags: [String!]! + name: String! + } + + type Query { + products(tag: String! @openfed__is(fields: "tags")): [Product!]! @openfed__queryCache(maxAge: 30) + } + `), + version, + ); + + expect(errors).toHaveLength(1); + expect(errors[0]).toStrictEqual( + invalidDirectiveError(IS, 'Query.products(tag: ...)', FIRST_ORDINAL, [ + batchListValuedKeyRequiresNestedListsErrorMessage( + 'Query.products', + 'tags', + 'Product', + 'a scalar tag of type "String!"', + ), + ]), + ); + }); + + test('rule 15i: list return plus a list-of-list argument can batch-map a list-valued key field', () => { + const rootFieldConfig = getSingleQueryRootFieldConfig( + ` + type Product @key(fields: "tags") @openfed__entityCache(maxAge: 60) { + tags: [String!]! + name: String! + } + + type Query { + products(tags: [[String!]!]! @openfed__is(fields: "tags")): [Product!]! @openfed__queryCache(maxAge: 30) + } + `, + 'products', + ); + + expect(rootFieldConfig.entityKeyMappings).toStrictEqual([ + { + entityTypeName: 'Product', + fieldMappings: [{ entityKeyField: 'tags', argumentPath: ['tags'], isBatch: true }], + }, + ]); + }); + + test('rule 29f: an explicit list-return batch mapping rejects type mismatches', () => { + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + + type Query { + products(ids: [String!]! @openfed__is(fields: "id")): [Product!]! @openfed__queryCache(maxAge: 30) + } + `), + version, + ); + + expect(errors).toHaveLength(1); + expect(errors[0]).toStrictEqual( + invalidDirectiveError(IS, 'Query.products(ids: ...)', FIRST_ORDINAL, [ + explicitTypeMismatchErrorMessage('ids', 'Query.products', '[String!]!', 'id', 'Product', 'ID!'), + ]), + ); + }); + + test('rule 29g: explicit batch mapping cannot coexist with an extra non-key list filter argument', () => { + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + + type Query { + products(ids: [ID!]! @openfed__is(fields: "id"), category: String!): [Product!]! @openfed__queryCache(maxAge: 30) + } + `), + version, + ); + + expect(errors).toHaveLength(1); + expect(errors[0]).toStrictEqual( + invalidDirectiveError(IS, 'Query.products(ids: ...)', FIRST_ORDINAL, [ + explicitBatchAdditionalNonKeyArgumentErrorMessage('Query.products', 'ids', 'id', 'Product', 'category'), + ]), + ); + }); + + test('rule 29h: auto batch mapping is skipped when the field also has an extra non-key argument', () => { + const { warnings } = normalizeSubgraphSuccess( + subgraph(` + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + + type Query { + products(id: [ID!]!, category: String!): [Product!]! @openfed__queryCache(maxAge: 30) + } + `), + version, + ); + + expect(warnings).toHaveLength(1); + expect(warnings[0].message).toBe( + autoBatchAdditionalNonKeyArgumentWarningMessage('Query.products', 'id', 'id', 'Product', 'category'), + ); + }); + + test('rule 29i: explicit scalar @openfed__is mappings cannot establish cache keys for a list-returning field', () => { + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Product @key(fields: "id region") @openfed__entityCache(maxAge: 60) { + id: ID! + region: String! + name: String! + } + + type Query { + products(pid: ID! @openfed__is(fields: "id"), area: String! @openfed__is(fields: "region")): [Product!]! @openfed__queryCache(maxAge: 30) + } + `), + version, + ); + + expect(errors).toHaveLength(1); + expect(errors[0]).toStrictEqual( + invalidDirectiveError(IS, 'Query.products(pid: ...)', FIRST_ORDINAL, [ + explicitScalarArgumentsCannotEstablishBatchMappingErrorMessage('Query.products', 'Product'), + ]), + ); + }); + + test('rule 29j: explicit @openfed__is plus an extra non-key argument is rejected on a list-return field', () => { + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + + type Query { + products(pid: ID! @openfed__is(fields: "id"), category: String!): [Product!]! @openfed__queryCache(maxAge: 30) + } + `), + version, + ); + + expect(errors).toHaveLength(1); + expect(errors[0]).toStrictEqual( + invalidDirectiveError(IS, 'Query.products(pid: ...)', FIRST_ORDINAL, [ + explicitBatchAdditionalNonKeyArgumentErrorMessage('Query.products', 'pid', 'id', 'Product', 'category'), + ]), + ); + }); + + test('rule 29k: auto-mapped key arguments are skipped on a list-return field when an extra non-key argument is present', () => { + const { warnings } = normalizeSubgraphSuccess( + subgraph(` + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + + type Query { + products(id: ID!, category: String!): [Product!]! @openfed__queryCache(maxAge: 30) + } + `), + version, + ); + + expect(warnings).toHaveLength(1); + expect(warnings[0].message).toBe( + autoBatchAdditionalNonKeyArgumentWarningMessage('Query.products', 'id', 'id', 'Product', 'category'), + ); + }); + }); + + describe('mixed key and non-key arguments on singular returns', () => { + test('rule 33: explicit @openfed__is plus an extra non-key argument is rejected on a singular return', () => { + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + + type Query { + product(pid: ID! @openfed__is(fields: "id"), category: String!): Product @openfed__queryCache(maxAge: 30) + } + `), + version, + ); + + expect(errors).toHaveLength(1); + expect(errors[0]).toStrictEqual( + invalidDirectiveError(IS, 'Query.product(pid: ...)', FIRST_ORDINAL, [ + explicitSingularAdditionalNonKeyArgumentErrorMessage('Query.product', 'pid', 'id', 'Product', 'category'), + ]), + ); + }); + + test('rule 33b: auto-mapped singular key is skipped when the field also has an extra non-key argument', () => { + const { warnings } = normalizeSubgraphSuccess( + subgraph(` + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + + type Query { + product(id: ID!, category: String!): Product @openfed__queryCache(maxAge: 30) + } + `), + version, + ); + + expect(warnings).toHaveLength(1); + expect(warnings[0].message).toBe( + autoMappingAdditionalNonKeyArgumentWarningMessage('id', 'Query.product', 'id', 'Product', 'category'), + ); + + const rootFieldConfig = getSingleQueryRootFieldConfig( + ` + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + + type Query { + product(id: ID!, category: String!): Product @openfed__queryCache(maxAge: 30) + } + `, + 'product', + ); + + expect(rootFieldConfig.entityKeyMappings).toStrictEqual([]); + }); + }); + + describe('input-object mappings', () => { + test('rule 29d-a: a flat singular argument cannot map to multiple key fields via @openfed__is(fields: "id sku")', () => { + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Product @key(fields: "id sku") @openfed__entityCache(maxAge: 60) { + id: ID! + sku: String! + name: String! + } + + type Query { + product(key: ID! @openfed__is(fields: "id sku")): Product @openfed__queryCache(maxAge: 30) + } + `), + version, + ); + + expect(errors).toHaveLength(1); + expect(errors[0]).toStrictEqual( + invalidDirectiveError(IS, 'Query.product(key: ...)', FIRST_ORDINAL, [ + nonInputArgumentCannotTargetCompositeKeyErrorMessage('key', 'Query.product', 'id sku', 'Product', 'ID!'), + ]), + ); + }); + + test('rule 29d: a list of input objects can map to a composite key via @openfed__is(fields: "id sku")', () => { + const rootFieldConfig = getSingleQueryRootFieldConfig( + ` + input ProductKeyInput { + id: ID! + sku: String! + } + + type Product @key(fields: "id sku") @openfed__entityCache(maxAge: 60) { + id: ID! + sku: String! + name: String! + } + + type Query { + products(keys: [ProductKeyInput!]! @openfed__is(fields: "id sku")): [Product!]! @openfed__queryCache(maxAge: 30) + } + `, + 'products', + ); + + expect(rootFieldConfig.entityKeyMappings).toStrictEqual([ + { + entityTypeName: 'Product', + fieldMappings: [ + { entityKeyField: 'id', argumentPath: ['keys', 'id'], isBatch: true }, + { entityKeyField: 'sku', argumentPath: ['keys', 'sku'], isBatch: true }, + ], + }, + ]); + }); + + test('rule 29d-ii: an input-object list argument without @openfed__is(fields: "...") does not auto-map to a composite key', () => { + const { warnings } = normalizeSubgraphSuccess( + subgraph(` + input ProductKeyInput { + id: ID! + sku: String! + } + + type Product @key(fields: "id sku") @openfed__entityCache(maxAge: 60) { + id: ID! + sku: String! + name: String! + } + + type Query { + products(keys: [ProductKeyInput!]!): [Product!]! @openfed__queryCache(maxAge: 30) + } + `), + version, + ); + + expect(warnings).toHaveLength(0); + + const rootFieldConfig = getSingleQueryRootFieldConfig( + ` + input ProductKeyInput { + id: ID! + sku: String! + } + + type Product @key(fields: "id sku") @openfed__entityCache(maxAge: 60) { + id: ID! + sku: String! + name: String! + } + + type Query { + products(keys: [ProductKeyInput!]!): [Product!]! @openfed__queryCache(maxAge: 30) + } + `, + 'products', + ); + + expect(rootFieldConfig.entityKeyMappings).toStrictEqual([]); + }); + + test('rule 29d-iii: @openfed__is(fields: "id sku") rejects input-object field type mismatches on list returns', () => { + const { errors } = normalizeSubgraphFailure( + subgraph(` + input ProductKeyInput { + id: String! + sku: String! + } + + type Product @key(fields: "id sku") @openfed__entityCache(maxAge: 60) { + id: ID! + sku: String! + name: String! + } + + type Query { + products(keys: [ProductKeyInput!]! @openfed__is(fields: "id sku")): [Product!]! @openfed__queryCache(maxAge: 30) + } + `), + version, + ); + + expect(errors).toHaveLength(1); + expect(errors[0]).toStrictEqual( + invalidDirectiveError(IS, 'Query.products(keys: ...)', FIRST_ORDINAL, [ + inputObjectCompositeTypeMismatchErrorMessage( + 'keys', + 'Query.products', + 'id sku', + 'Product', + 'ProductKeyInput', + 'id', + 'String!', + 'Product.id', + 'ID!', + ), + ]), + ); + }); + + test('rule 29d-iv: @openfed__is(fields: "id sku") rejects input objects that omit required key fields on list returns', () => { + const { errors } = normalizeSubgraphFailure( + subgraph(` + input ProductKeyInput { + id: ID! + } + + type Product @key(fields: "id sku") @openfed__entityCache(maxAge: 60) { + id: ID! + sku: String! + name: String! + } + + type Query { + products(keys: [ProductKeyInput!]! @openfed__is(fields: "id sku")): [Product!]! @openfed__queryCache(maxAge: 30) + } + `), + version, + ); + + expect(errors).toHaveLength(1); + expect(errors[0]).toStrictEqual( + invalidDirectiveError(IS, 'Query.products(keys: ...)', FIRST_ORDINAL, [ + inputObjectCompositeMissingFieldErrorMessage( + 'keys', + 'Query.products', + 'id sku', + 'Product', + 'ProductKeyInput', + 'sku', + ), + ]), + ); + }); + + test('rule 29d-v: a singular input object can map to a composite key via @openfed__is(fields: "id sku")', () => { + const rootFieldConfig = getSingleQueryRootFieldConfig( + ` + input ProductKeyInput { + id: ID! + sku: String! + } + + type Product @key(fields: "id sku") @openfed__entityCache(maxAge: 60) { + id: ID! + sku: String! + name: String! + } + + type Query { + product(key: ProductKeyInput! @openfed__is(fields: "id sku")): Product @openfed__queryCache(maxAge: 30) + } + `, + 'product', + ); + + expect(rootFieldConfig.entityKeyMappings).toStrictEqual([ + { + entityTypeName: 'Product', + fieldMappings: [ + { entityKeyField: 'id', argumentPath: ['key', 'id'] }, + { entityKeyField: 'sku', argumentPath: ['key', 'sku'] }, + ], + }, + ]); + }); + + test('rule 30: a nested input object can recursively auto-map to a nested key structure', () => { + const rootFieldConfig = getSingleQueryRootFieldConfig( + ` + type Location { + id: ID! + region: String! + } + + type Store { + id: ID! + location: Location! + } + + input LocationInput { + id: ID! + region: String! + } + + input StoreInput { + id: ID! + location: LocationInput! + } + + type Product @key(fields: "store { id location { id region } }") @openfed__entityCache(maxAge: 60) { + store: Store! + name: String! + } + + type Query { + product(store: StoreInput!): Product @openfed__queryCache(maxAge: 30) + } + `, + 'product', + ); + + expect(rootFieldConfig.entityKeyMappings).toStrictEqual([ + { + entityTypeName: 'Product', + fieldMappings: [ + { entityKeyField: 'store.id', argumentPath: ['store', 'id'] }, + { entityKeyField: 'store.location.id', argumentPath: ['store', 'location', 'id'] }, + { entityKeyField: 'store.location.region', argumentPath: ['store', 'location', 'region'] }, + ], + }, + ]); + }); + + test('rule 31: nested input-object mapping reports nested leaf type mismatches precisely', () => { + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Location { + id: ID! + region: String! + } + + type Store { + id: ID! + location: Location! + } + + input LocationInput { + id: Int! + region: String! + } + + input StoreInput { + id: ID! + location: LocationInput! + } + + type Product @key(fields: "store { id location { id region } }") @openfed__entityCache(maxAge: 60) { + store: Store! + name: String! + } + + type Query { + product(store: StoreInput!): Product @openfed__queryCache(maxAge: 30) + } + `), + version, + ); + + expect(errors).toHaveLength(1); + expect(errors[0]).toStrictEqual( + invalidDirectiveError(QUERY_CACHE, 'Query.product', FIRST_ORDINAL, [ + nestedInputObjectTypeMismatchErrorMessage( + 'store', + 'Query.product', + 'store { id location { id region } }', + 'Product', + 'LocationInput', + 'id', + 'Int!', + 'Location.id', + 'ID!', + ), + ]), + ); + }); + + test('rule 32: nested input-object mapping reports missing nested key fields precisely', () => { + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Location { + id: ID! + region: String! + } + + type Store { + id: ID! + location: Location! + } + + input LocationInput { + id: ID! + } + + input StoreInput { + id: ID! + location: LocationInput! + } + + type Product @key(fields: "store { id location { id region } }") @openfed__entityCache(maxAge: 60) { + store: Store! + name: String! + } + + type Query { + product(store: StoreInput!): Product @openfed__queryCache(maxAge: 30) + } + `), + version, + ); + + expect(errors).toHaveLength(1); + expect(errors[0]).toStrictEqual( + invalidDirectiveError(QUERY_CACHE, 'Query.product', FIRST_ORDINAL, [ + nestedInputObjectMissingFieldErrorMessage( + 'store', + 'Query.product', + 'store { id location { id region } }', + 'Product', + 'LocationInput', + 'region', + ), + ]), + ); + }); + + test('rule 36: redundant @openfed__is on an argument that already auto-maps emits a warning (mapping still extracted)', () => { + // Bug (b): `@openfed__is(fields: "id")` on argument `id` is redundant — auto-map would produce the same result. + const sdl = ` + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + + type Query { + product(id: ID! @openfed__is(fields: "id")): Product @openfed__queryCache(maxAge: 30) + } + `; + + const { warnings } = normalizeSubgraphSuccess(subgraph(sdl), version); + expect(warnings).toHaveLength(1); + expect(warnings[0]).toStrictEqual( + redundantIsDirectiveWarning({ + subgraphName: 'subgraph-a', + argumentName: 'id', + fieldCoords: 'Query.product', + keyField: 'id', + entityType: 'Product', + }), + ); + + // Mapping is still extracted — redundancy is a lint, not a correctness break. + const rootFieldConfig = getSingleQueryRootFieldConfig(sdl, 'product'); + expect(rootFieldConfig.entityKeyMappings).toStrictEqual([ + { + entityTypeName: 'Product', + fieldMappings: [{ entityKeyField: 'id', argumentPath: ['id'] }], + }, + ]); + }); + + test('rule 36-positive: @openfed__is renaming a differently-named argument to a key field is NOT redundant', () => { + // Sanity: when arg name differs from key field, @openfed__is is required and not a warning. + const sdl = ` + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + + type Query { + product(pid: ID! @openfed__is(fields: "id")): Product @openfed__queryCache(maxAge: 30) + } + `; + + const { warnings } = normalizeSubgraphSuccess(subgraph(sdl), version); + expect(warnings).toHaveLength(0); + + const rootFieldConfig = getSingleQueryRootFieldConfig(sdl, 'product'); + expect(rootFieldConfig.entityKeyMappings).toStrictEqual([ + { + entityTypeName: 'Product', + fieldMappings: [{ entityKeyField: 'id', argumentPath: ['pid'] }], + }, + ]); + }); + + test('rule 34: nested composite-key leaf checks list/NonNull wrapping in addition to named type', () => { + // Bug (c): key expects `[ID!]!` at the leaf; input has scalar `ID`. Old code only compared named types + // and silently accepted the shape mismatch. New code rejects it. + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Location { + id: [ID!]! + region: String! + } + + type Store { + id: ID! + location: Location! + } + + input LocationInput { + id: ID! + region: String! + } + + input StoreInput { + id: ID! + location: LocationInput! + } + + type Product @key(fields: "store { id location { id region } }") @openfed__entityCache(maxAge: 60) { + store: Store! + name: String! + } + + type Query { + product(store: StoreInput!): Product @openfed__queryCache(maxAge: 30) + } + `), + version, + ); + + expect(errors).toHaveLength(1); + expect(errors[0]).toStrictEqual( + invalidDirectiveError(QUERY_CACHE, 'Query.product', FIRST_ORDINAL, [ + nestedInputObjectTypeMismatchErrorMessage( + 'store', + 'Query.product', + 'store { id location { id region } }', + 'Product', + 'LocationInput', + 'id', + 'ID!', + 'Location.id', + '[ID!]!', + ), + ]), + ); + }); + + test('rule 34-positive: nested composite-key leaf with matching list shape succeeds', () => { + const sdl = ` + type Location { + id: [ID!]! + region: String! + } + + type Store { + id: ID! + location: Location! + } + + input LocationInput { + id: [ID!]! + region: String! + } + + input StoreInput { + id: ID! + location: LocationInput! + } + + type Product @key(fields: "store { id location { id region } }") @openfed__entityCache(maxAge: 60) { + store: Store! + name: String! + } + + type Query { + product(store: StoreInput!): Product @openfed__queryCache(maxAge: 30) + } + `; + + const { warnings } = normalizeSubgraphSuccess(subgraph(sdl), version); + expect(warnings).toHaveLength(0); + + const rootFieldConfig = getSingleQueryRootFieldConfig(sdl, 'product'); + expect(rootFieldConfig.entityKeyMappings).toStrictEqual([ + { + entityTypeName: 'Product', + fieldMappings: [ + { entityKeyField: 'store.id', argumentPath: ['store', 'id'] }, + { entityKeyField: 'store.location.id', argumentPath: ['store', 'location', 'id'] }, + { entityKeyField: 'store.location.region', argumentPath: ['store', 'location', 'region'] }, + ], + }, + ]); + }); + + test('rule 35: a failed auto-map on one @key does not abort evaluation of remaining @keys (missing arg)', () => { + // Bug (d): the first @key has no matching arg (region missing); the second @key still auto-maps. + const sdl = ` + type Product @key(fields: "id region") @key(fields: "sku") @openfed__entityCache(maxAge: 60) { + id: ID! + region: String! + sku: String! + name: String! + } + + type Query { + product(id: ID!, sku: String!): Product @openfed__queryCache(maxAge: 30) + } + `; + + const { warnings } = normalizeSubgraphSuccess(subgraph(sdl), version); + // Incomplete composite key warning for the "id region" key — NOT a fatal abort. + expect(warnings).toHaveLength(1); + expect(warnings[0]).toStrictEqual( + incompleteQueryCacheKeyMappingWarning({ + subgraphName: 'subgraph-a', + fieldCoords: 'Query.product', + entityType: 'Product', + unmappedKeyField: 'region', + }), + ); + + const rootFieldConfig = getSingleQueryRootFieldConfig(sdl, 'product'); + expect(rootFieldConfig.entityKeyMappings).toStrictEqual([ + { + entityTypeName: 'Product', + fieldMappings: [{ entityKeyField: 'sku', argumentPath: ['sku'] }], + }, + ]); + }); + + test('rule 35b: when NO @key auto-maps, no mappings are emitted', () => { + // Sanity: bug (d)'s "overall failure only if NO key auto-maps" — here both keys fail to map. + const sdl = ` + type Product @key(fields: "id") @key(fields: "sku") @openfed__entityCache(maxAge: 60) { + id: ID! + sku: String! + name: String! + } + + type Query { + product(foo: String!): Product @openfed__queryCache(maxAge: 30) + } + `; + + const rootFieldConfig = getSingleQueryRootFieldConfig(sdl, 'product'); + expect(rootFieldConfig.entityKeyMappings).toStrictEqual([]); + }); + + // Codex P1 #1 regression: the missing-@openfed__entityCache warning only applies to OBJECT + // returns. @openfed__entityCache is OBJECT-only, so flagging an interface/union return with + // the same remediation ("add @openfed__entityCache to the type") would be unactionable. + test('rule 37: @openfed__queryCache on an entity-interface return without @openfed__entityCache does not emit the missing-entityCache warning', () => { + const sdl = ` + interface Product @key(fields: "id") { + id: ID! + } + + type Book implements Product @key(fields: "id") { + id: ID! + title: String! + } + + type Query { + product(id: ID!): Product @openfed__queryCache(maxAge: 30) + } + `; + + const { warnings } = normalizeSubgraphSuccess(subgraph(sdl), version); + // Must NOT emit queryCacheReturnEntityMissingEntityCacheWarning for an interface return — + // users cannot add @openfed__entityCache to an interface. + for (const w of warnings) { + expect(w.message).not.toContain('has no @openfed__entityCache directive'); + } + }); + + test('rule 37b: @openfed__queryCache on a list-of-entity-interface return without @openfed__entityCache does not emit the missing-entityCache warning', () => { + const sdl = ` + interface Product @key(fields: "id") { + id: ID! + } + + type Book implements Product @key(fields: "id") { + id: ID! + title: String! + } + + type Query { + products(id: ID!): [Product!]! @openfed__queryCache(maxAge: 30) + } + `; + + const { warnings } = normalizeSubgraphSuccess(subgraph(sdl), version); + for (const w of warnings) { + expect(w.message).not.toContain('has no @openfed__entityCache directive'); + } + }); + + // Codex P1 #2 regression: on a list-return field with a list-valued key field, auto-mapping + // cannot batch-map (buildAutoMappings skips `argIsList && keyIsList` on list returns). The + // explicit @openfed__is is REQUIRED — redundantIsDirectiveWarning must not fire. + test('rule 38: @openfed__is is NOT redundant when the key field is list-valued on a list-return field', () => { + const sdl = ` + type Product @key(fields: "tags") @openfed__entityCache(maxAge: 60) { + tags: [String!]! + name: String! + } + + type Query { + products(tags: [[String!]!]! @openfed__is(fields: "tags")): [Product!]! @openfed__queryCache(maxAge: 30) + } + `; + + const { warnings } = normalizeSubgraphSuccess(subgraph(sdl), version); + // No redundancy warning — auto-map cannot reach the list-key path on a list return. + for (const w of warnings) { + expect(w.message).not.toContain('is redundant and can be removed'); + } + + const rootFieldConfig = getSingleQueryRootFieldConfig(sdl, 'products'); + expect(rootFieldConfig.entityKeyMappings).toStrictEqual([ + { + entityTypeName: 'Product', + fieldMappings: [{ entityKeyField: 'tags', argumentPath: ['tags'], isBatch: true }], + }, + ]); + }); + + // Codex P1 #3 regression: with one satisfiable nested @key AND one flat @key that hits the + // "extra non-key argument" global-invalidation path, NO auto-mapping may survive. The + // singular-return rule (extra non-key arg → reject whole set) must hold. + test('rule 39: an extra non-key argument globally invalidates all auto-mappings, including earlier nested-key results', () => { + const sdl = ` + input StoreInput { + id: ID! + region: String! + } + + type Product + @key(fields: "store { id region }") + @key(fields: "id") + @openfed__entityCache(maxAge: 60) { + id: ID! + store: StoreRef! + name: String! + } + + type StoreRef { + id: ID! + region: String! + } + + type Query { + product(store: StoreInput!, id: ID!, extra: String!): Product @openfed__queryCache(maxAge: 30) + } + `; + + const { warnings } = normalizeSubgraphSuccess(subgraph(sdl), version); + // One warning per invalidated key: the nested key warns first, then the flat key. + expect(warnings).toHaveLength(2); + expect(warnings[0].message).toBe( + autoMappingAdditionalNonKeyArgumentWarningMessage('store', 'Query.product', 'store.id', 'Product', 'extra'), + ); + expect(warnings[1].message).toBe( + autoMappingAdditionalNonKeyArgumentWarningMessage('id', 'Query.product', 'id', 'Product', 'store'), + ); + + // Crucial assertion: NO mappings survive — the nested-key success must not leak through. + const rootFieldConfig = getSingleQueryRootFieldConfig(sdl, 'product'); + expect(rootFieldConfig.entityKeyMappings).toStrictEqual([]); + }); + + // Codex P2 #2 regression: pinning pure-nullability-only mismatches for typesMatchIncludingListShape. + // The helper is used in buildExplicitMappings nested composite-key leaves, where strict list-shape + // comparison (including NonNull wrapping) applies — any nullability difference must be rejected. + test('rule 40: nested composite-key leaf rejects nullable-vs-non-null scalar mismatch (ID vs ID!)', () => { + // key leaf requires `ID!`, input supplies `ID` — must be rejected. + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Store { + id: ID! + region: String! + } + + input StoreInput { + id: ID + region: String! + } + + type Product @key(fields: "store { id region }") @openfed__entityCache(maxAge: 60) { + store: Store! + name: String! + } + + type Query { + product(store: StoreInput!): Product @openfed__queryCache(maxAge: 30) + } + `), + version, + ); + + expect(errors.length).toBeGreaterThan(0); + }); + + test('rule 40b: nested composite-key leaf rejects inner-list nullability mismatch ([ID]! vs [ID!]!)', () => { + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Store { + ids: [ID!]! + region: String! + } + + input StoreInput { + ids: [ID]! + region: String! + } + + type Product @key(fields: "store { ids region }") @openfed__entityCache(maxAge: 60) { + store: Store! + name: String! + } + + type Query { + product(store: StoreInput!): Product @openfed__queryCache(maxAge: 30) + } + `), + version, + ); + + expect(errors.length).toBeGreaterThan(0); + }); + + test('rule 40c: nested composite-key leaf rejects outer-list nullability mismatch ([ID!] vs [ID!]!)', () => { + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Store { + ids: [ID!]! + region: String! + } + + input StoreInput { + ids: [ID!] + region: String! + } + + type Product @key(fields: "store { ids region }") @openfed__entityCache(maxAge: 60) { + store: Store! + name: String! + } + + type Query { + product(store: StoreInput!): Product @openfed__queryCache(maxAge: 30) + } + `), + version, + ); + + expect(errors.length).toBeGreaterThan(0); + }); + }); +}); + +describe('Review regressions (PR #2944)', () => { + test('composite @openfed__is plus a plain argument named after a mapped leaf key field errors instead of crashing', () => { + const { errors } = normalizeSubgraphFailure( + subgraph(` + input ProductKey { + id: ID! + sku: String! + } + + type Product @key(fields: "id sku") @key(fields: "region") @openfed__entityCache(maxAge: 60) { + id: ID! + sku: String! + region: String! + name: String! + } + + type Query { + product( + key: ProductKey! @openfed__is(fields: "id sku") + regionArg: String! @openfed__is(fields: "region") + id: ID! + ): Product @openfed__queryCache(maxAge: 30) + } + `), + version, + ); + + expect(errors).toHaveLength(1); + expect(errors[0]).toStrictEqual( + invalidDirectiveError(IS, 'Query.product(key: ...)', FIRST_ORDINAL, [ + duplicateKeyFieldMappingErrorMessage('Query.product', 'id'), + ]), + ); + }); + + test('root field cache directives are extracted from renamed root operation types', () => { + const config = getConfigForType( + subgraph(` + schema { + query: MyQuery + } + + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + + type MyQuery { + product(id: ID!): Product @openfed__queryCache(maxAge: 30) + } + `), + 'MyQuery', + ); + + expect(config).toBeDefined(); + expect(config!.rootFieldCacheConfigurations).toBeDefined(); + expect(config!.rootFieldCacheConfigurations).toHaveLength(1); + expect(config!.rootFieldCacheConfigurations![0].fieldName).toBe('product'); + }); + + test('nested input-object auto-mapping with an extra non-key argument emits the additional-argument warning', () => { + const { warnings } = normalizeSubgraphSuccess( + subgraph(` + type Location { + id: ID! + } + + type Warehouse @key(fields: "location { id }") @openfed__entityCache(maxAge: 60) { + location: Location! + name: String! + } + + input LocationInput { + id: ID! + } + + type Query { + warehouse(location: LocationInput!, extra: String!): Warehouse @openfed__queryCache(maxAge: 30) + } + `), + version, + ); + + expect(warnings).toHaveLength(1); + expect(warnings[0].message).toBe( + autoMappingAdditionalNonKeyArgumentWarningMessage( + 'location', + 'Query.warehouse', + 'location.id', + 'Warehouse', + 'extra', + ), + ); + }); +}); diff --git a/composition/tests/v1/directives/entity-caching.test.ts b/composition/tests/v1/directives/entity-caching.test.ts new file mode 100644 index 0000000000..ca70960e4d --- /dev/null +++ b/composition/tests/v1/directives/entity-caching.test.ts @@ -0,0 +1,1604 @@ +import { describe, expect, test } from 'vitest'; +import { + BatchNormalizationSuccess, + CACHE_INVALIDATE, + CACHE_POPULATE, + CacheInvalidateConfig, + CachePopulateConfig, + DIRECTIVE_DEFINITION_BY_NAME, + ENTITY_CACHE, + EntityCacheConfig, + entityCacheWithoutKeyErrorMessage, + FIRST_ORDINAL, + invalidDirectiveError, + IS, + isReferencesUnknownKeyFieldErrorMessage, + isWithoutQueryCacheErrorMessage, + duplicateKeyFieldMappingErrorMessage, + maxAgeNotPositiveIntegerErrorMessage, + MUTATION, + parse, + QUERY, + QUERY_CACHE, + queryCacheOnNonEntityReturnTypeErrorMessage, + queryCacheOnNonQueryFieldErrorMessage, + REQUEST_SCOPED, + REQUEST_SCOPED_DEFINITION, + RootFieldCacheConfig, + ROUTER_COMPATIBILITY_VERSION_ONE, + Subgraph, + subgraphValidationError, + SUBSCRIPTION, + TypeName, + cacheInvalidateOnNonMutationSubscriptionFieldErrorMessage, + cacheInvalidateOnNonEntityReturnTypeErrorMessage, + cachePopulateOnNonMutationSubscriptionFieldErrorMessage, + cachePopulateOnNonEntityReturnTypeErrorMessage, + cacheInvalidateAndPopulateMutualExclusionErrorMessage, +} from '../../../src'; +import { SCHEMA_QUERY_DEFINITION } from '../utils/utils'; +import { BatchNormalizer } from '../../../src'; + +// main refactored the free function batchNormalize() into the BatchNormalizer class; +// keep the old call shape for these tests (version is accepted and ignored). +const batchNormalize = (params: any) => new BatchNormalizer(params).batchNormalize(); +import { + federateSubgraphsSuccess, + normalizeString, + normalizeSubgraphFailure, + normalizeSubgraphSuccess, + schemaToSortedNormalizedString, +} from '../../utils/utils'; + +const version = ROUTER_COMPATIBILITY_VERSION_ONE; + +// Helper: creates a Subgraph object from an inline SDL string. +// Keeps each test self-contained while avoiding repetitive boilerplate. +function subgraph(sdl: string, name = 'subgraph-a'): Subgraph { + return { name, url: '', definitions: parse(sdl) }; +} + +// Helper: runs batchNormalize and returns the ConfigurationData for a given type. +// Used by config-extraction tests that need to inspect the generated router configuration. +// Pins ROUTER_COMPATIBILITY_VERSION_ONE explicitly — relying on the default masks breakage +// when the default changes in the future. +function getConfigForType(sg: Subgraph, typeName: string): ConfigurationData | undefined { + const result = batchNormalize({ + subgraphs: [sg], + version: ROUTER_COMPATIBILITY_VERSION_ONE, + }) as BatchNormalizationSuccess; + expect(result.success).toBe(true); + const internal = result.internalSubgraphByName.get(sg.name); + expect(internal).toBeDefined(); + return internal!.configurationDataByTypeName.get(typeName as TypeName); +} + +describe('Entity caching directive tests', () => { + // ─── @openfed__entityCache ───────────────────────────────────────────────────────────── + // @openfed__entityCache marks an entity type as cacheable. It requires @key (so the router + // can construct cache keys) and a positive maxAge (TTL in seconds). + + describe('@openfed__entityCache', () => { + test('error: @openfed__entityCache without @key — the router needs @key fields to construct cache keys', () => { + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Query { product(id: ID!): Product } + # Product has @openfed__entityCache but no @key — there's no cache key to use + type Product @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + version, + ); + expect(errors).toHaveLength(1); + expect(errors[0]).toStrictEqual( + invalidDirectiveError(ENTITY_CACHE, 'Product', FIRST_ORDINAL, [entityCacheWithoutKeyErrorMessage('Product')]), + ); + }); + + test('error: maxAge of zero — TTL must be at least 1 second', () => { + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Query { product(id: ID!): Product } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 0) { + id: ID! + name: String! + } + `), + version, + ); + expect(errors).toHaveLength(1); + expect(errors[0]).toStrictEqual( + invalidDirectiveError(ENTITY_CACHE, 'Product', FIRST_ORDINAL, [ + maxAgeNotPositiveIntegerErrorMessage(ENTITY_CACHE, 0), + ]), + ); + }); + + test('error: negative maxAge', () => { + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Query { product(id: ID!): Product } + type Product @key(fields: "id") @openfed__entityCache(maxAge: -5) { + id: ID! + name: String! + } + `), + version, + ); + expect(errors).toHaveLength(1); + expect(errors[0]).toStrictEqual( + invalidDirectiveError(ENTITY_CACHE, 'Product', FIRST_ORDINAL, [ + maxAgeNotPositiveIntegerErrorMessage(ENTITY_CACHE, -5), + ]), + ); + }); + + test('success: valid @openfed__entityCache with @key normalizes without errors', () => { + const { schema } = normalizeSubgraphSuccess( + subgraph(` + type Query { product(id: ID!): Product } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + version, + ); + expect(schema).toBeDefined(); + }); + + test('config: @openfed__entityCache with defaults produces correct EntityCacheConfig', () => { + // Only maxAge is required; includeHeaders, partialCacheLoad, shadowMode default to false + const config = getConfigForType( + subgraph(` + type Query { product(id: ID!): Product } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + 'Product', + ); + expect(config).toBeDefined(); + expect(config!.entityCacheConfigurations).toStrictEqual([ + { + typeName: 'Product', + maxAgeSeconds: 60, + notFoundCacheTtlSeconds: 0, + includeHeaders: false, + partialCacheLoad: false, + shadowMode: false, + }, + ] satisfies EntityCacheConfig[]); + }); + + test('config: @openfed__entityCache with all options enabled', () => { + // includeHeaders: cache key includes request headers (user-specific caching) + // partialCacheLoad: fetch only missing entities from subgraph on partial cache hit + // shadowMode: cache reads/writes happen but responses always come from subgraph + const config = getConfigForType( + subgraph(` + type Query { product(id: ID!): Product } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 120, includeHeaders: true, partialCacheLoad: true, shadowMode: true) { + id: ID! + name: String! + } + `), + 'Product', + ); + expect(config).toBeDefined(); + expect(config!.entityCacheConfigurations).toStrictEqual([ + { + typeName: 'Product', + maxAgeSeconds: 120, + notFoundCacheTtlSeconds: 0, + includeHeaders: true, + partialCacheLoad: true, + shadowMode: true, + }, + ] satisfies EntityCacheConfig[]); + }); + + test('config: @openfed__entityCache negativeCacheTTL propagates to notFoundCacheTtlSeconds', () => { + // negativeCacheTTL caches "not found" entity responses (null from _entities without errors) + // for the specified TTL in seconds. 0 (default) disables negative caching. + const config = getConfigForType( + subgraph(` + type Query { product(id: ID!): Product } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 300, negativeCacheTTL: 10) { + id: ID! + name: String! + } + `), + 'Product', + ); + expect(config).toBeDefined(); + expect(config!.entityCacheConfigurations).toStrictEqual([ + { + typeName: 'Product', + maxAgeSeconds: 300, + notFoundCacheTtlSeconds: 10, + includeHeaders: false, + partialCacheLoad: false, + shadowMode: false, + }, + ] satisfies EntityCacheConfig[]); + }); + + test('error: @openfed__entityCache negativeCacheTTL must be non-negative', () => { + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Query { product(id: ID!): Product } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 300, negativeCacheTTL: -1) { + id: ID! + name: String! + } + `), + version, + ); + expect(errors).toBeDefined(); + expect(errors!.some((e) => e.message.includes('negativeCacheTTL must be a non-negative integer'))).toBe(true); + }); + }); + + // ─── @openfed__queryCache ────────────────────────────────────────────────────────────── + // @openfed__queryCache on a Query field tells the router to serve the returned entity from cache. + // The return type must be an entity with @openfed__entityCache. Query arguments are mapped to + // @key fields (automatically by name, or explicitly via @openfed__is) to construct cache keys. + + describe('@openfed__queryCache', () => { + test('error: @openfed__queryCache on a Mutation field — only Query fields support cache reads', () => { + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Query { dummy: String! } + type Mutation { + updateProduct(id: ID!): Product @openfed__queryCache(maxAge: 60) + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + version, + ); + expect(errors).toHaveLength(1); + expect(errors[0]).toStrictEqual( + invalidDirectiveError(QUERY_CACHE, 'Mutation.updateProduct', FIRST_ORDINAL, [ + queryCacheOnNonQueryFieldErrorMessage('Mutation.updateProduct'), + ]), + ); + }); + + test('error: return type is not a federation entity (no @key)', () => { + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Query { + product(id: ID!): Product @openfed__queryCache(maxAge: 60) + } + # Product has no @key — it's not an entity, so there's no cache key + type Product { + id: ID! + name: String! + } + `), + version, + ); + expect(errors).toHaveLength(1); + expect(errors[0]).toStrictEqual( + invalidDirectiveError(QUERY_CACHE, 'Query.product', FIRST_ORDINAL, [ + queryCacheOnNonEntityReturnTypeErrorMessage('Query.product', 'Product'), + ]), + ); + }); + + // Expectation updated (bug a fix): @openfed__queryCache on a @key entity without + // @openfed__entityCache warns and does NOT extract a queryCache config — the cache + // would have no entity-cache backing store. + test('warning: return entity omits @openfed__entityCache — queryCache config is NOT extracted', () => { + const config = getConfigForType( + subgraph(` + type Query { + product(id: ID!): Product @openfed__queryCache(maxAge: 60) + } + type Product @key(fields: "id") { + id: ID! + name: String! + } + `), + QUERY, + ); + expect(config).toBeDefined(); + expect(config!.rootFieldCacheConfigurations).toBeUndefined(); + }); + + test('error: maxAge of zero', () => { + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Query { + product(id: ID!): Product @openfed__queryCache(maxAge: 0) + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + version, + ); + expect(errors).toHaveLength(1); + expect(errors[0]).toStrictEqual( + invalidDirectiveError(QUERY_CACHE, 'Query.product', FIRST_ORDINAL, [ + maxAgeNotPositiveIntegerErrorMessage(QUERY_CACHE, 0), + ]), + ); + }); + + test("success: argument name doesn't match any @key field — no mappings and no warning", () => { + // No argument can satisfy the @key, so composition emits no cache-key mappings and stays silent. + const { warnings } = normalizeSubgraphSuccess( + subgraph(` + type Query { + product(name: String!): Product @openfed__queryCache(maxAge: 30) + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + version, + ); + expect(warnings).toHaveLength(0); + }); + + test('no warning for list return type — lists skip key mapping entirely', () => { + // List-returning fields can populate the cache with each entity in the response, + // but can't do key-based lookups, so missing key mappings are expected and not warned. + const { warnings } = normalizeSubgraphSuccess( + subgraph(` + type Query { + products: [Product] @openfed__queryCache(maxAge: 30) + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + version, + ); + expect(warnings).toHaveLength(0); + }); + + test('success: argument name matches @key field — auto-mapped without @openfed__is', () => { + // The "id" argument automatically maps to the @key(fields: "id") field + const { schema, warnings } = normalizeSubgraphSuccess( + subgraph(` + type Query { + product(id: ID!): Product @openfed__queryCache(maxAge: 30) + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + version, + ); + expect(schema).toBeDefined(); + expect(warnings).toHaveLength(0); + }); + + test('config: auto-mapped argument produces correct RootFieldCacheConfig', () => { + // product(id: ID!) with @key(fields: "id") → auto-maps "id" argument to "id" key field + const config = getConfigForType( + subgraph(` + type Query { + product(id: ID!): Product @openfed__queryCache(maxAge: 30) + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + QUERY, + ); + expect(config).toBeDefined(); + expect(config!.rootFieldCacheConfigurations).toStrictEqual([ + { + fieldName: 'product', + maxAgeSeconds: 30, + includeHeaders: false, + shadowMode: false, + entityTypeName: 'Product', + entityKeyMappings: [ + { + entityTypeName: 'Product', + fieldMappings: [{ entityKeyField: 'id', argumentPath: ['id'] }], + }, + ], + }, + ] satisfies RootFieldCacheConfig[]); + }); + + test('config: @openfed__queryCache with includeHeaders and shadowMode', () => { + const config = getConfigForType( + subgraph(` + type Query { + product(id: ID!): Product @openfed__queryCache(maxAge: 30, includeHeaders: true, shadowMode: true) + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + QUERY, + ); + expect(config).toBeDefined(); + expect(config!.rootFieldCacheConfigurations).toStrictEqual([ + { + fieldName: 'product', + maxAgeSeconds: 30, + includeHeaders: true, + shadowMode: true, + entityTypeName: 'Product', + entityKeyMappings: [ + { + entityTypeName: 'Product', + fieldMappings: [{ entityKeyField: 'id', argumentPath: ['id'] }], + }, + ], + }, + ] satisfies RootFieldCacheConfig[]); + }); + + test('config: auto-mapped composite @key produces multiple fieldMappings', () => { + const config = getConfigForType( + subgraph(` + type Query { + product(id: ID!, region: String!): Product @openfed__queryCache(maxAge: 30) + } + type Product @key(fields: "id region") @openfed__entityCache(maxAge: 60) { + id: ID! + region: String! + name: String! + } + `), + QUERY, + ); + expect(config).toBeDefined(); + expect(config!.rootFieldCacheConfigurations).toStrictEqual([ + { + fieldName: 'product', + maxAgeSeconds: 30, + includeHeaders: false, + shadowMode: false, + entityTypeName: 'Product', + entityKeyMappings: [ + { + entityTypeName: 'Product', + fieldMappings: [ + { entityKeyField: 'id', argumentPath: ['id'] }, + { entityKeyField: 'region', argumentPath: ['region'] }, + ], + }, + ], + }, + ] satisfies RootFieldCacheConfig[]); + }); + + test('config: nested auto-mapping is discarded when the field has an extra argument', () => { + const config = getConfigForType( + subgraph(` + type Query { + product(store: StoreKey!, filter: String): Product @openfed__queryCache(maxAge: 30) + } + type Product @key(fields: "store { id }") @openfed__entityCache(maxAge: 60) { + store: Store! + name: String! + } + type Store { + id: ID! + } + input StoreKey { + id: ID! + } + `), + QUERY, + ); + expect(config).toBeDefined(); + expect(config!.rootFieldCacheConfigurations).toStrictEqual([ + { + fieldName: 'product', + maxAgeSeconds: 30, + includeHeaders: false, + shadowMode: false, + entityTypeName: 'Product', + entityKeyMappings: [], + }, + ] satisfies RootFieldCacheConfig[]); + }); + + test('config: composite @key with mixed auto and @openfed__is mapping', () => { + const config = getConfigForType( + subgraph(` + type Query { + product(id: ID!, loc: String! @openfed__is(fields: "region")): Product @openfed__queryCache(maxAge: 30) + } + type Product @key(fields: "id region") @openfed__entityCache(maxAge: 60) { + id: ID! + region: String! + name: String! + } + `), + QUERY, + ); + expect(config).toBeDefined(); + const mappings = config!.rootFieldCacheConfigurations![0].entityKeyMappings[0].fieldMappings; + // Sort by entityKeyField so the assertion is order-independent without losing exhaustiveness. + const sorted = [...mappings].sort((a, b) => a.entityKeyField.localeCompare(b.entityKeyField)); + expect(sorted).toStrictEqual([ + { entityKeyField: 'id', argumentPath: ['id'] }, + { entityKeyField: 'region', argumentPath: ['loc'] }, + ]); + }); + }); + + // ─── @openfed__is ────────────────────────────────────────────────────────────────────── + // @openfed__is(fields: "keyField") on a query argument explicitly maps it to a @key field. + // Useful when the argument name differs from the key field name, + // e.g., product(pid: ID! @openfed__is(fields: "id")) maps "pid" to the @key field "id". + + describe('@openfed__is', () => { + test('error: @openfed__is without @openfed__queryCache on the field — @openfed__is only makes sense for cache key construction', () => { + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Query { + product(pid: ID! @openfed__is(fields: "id")): Product + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + version, + ); + expect(errors).toHaveLength(1); + expect(errors[0]).toStrictEqual( + invalidDirectiveError(IS, 'Query.product(pid: ...)', FIRST_ORDINAL, [ + isWithoutQueryCacheErrorMessage('pid', 'Query.product'), + ]), + ); + }); + + test('error: @openfed__is references a field not in @key', () => { + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Query { + product(pid: ID! @openfed__is(fields: "unknown")): Product @openfed__queryCache(maxAge: 30) + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + version, + ); + expect(errors).toHaveLength(1); + expect(errors[0]).toStrictEqual( + invalidDirectiveError(IS, 'Query.product(pid: ...)', FIRST_ORDINAL, [ + isReferencesUnknownKeyFieldErrorMessage('unknown', 'pid', 'Query.product', 'Product'), + ]), + ); + }); + + test('error: two arguments map to the same @key field — ambiguous cache key', () => { + // "id" auto-maps to @key field "id", then "otherId" also maps to "id" via @openfed__is + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Query { + product(id: ID!, otherId: ID! @openfed__is(fields: "id")): Product @openfed__queryCache(maxAge: 30) + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + version, + ); + expect(errors).toHaveLength(1); + expect(errors[0]).toStrictEqual( + invalidDirectiveError(IS, 'Query.product(otherId: ...)', FIRST_ORDINAL, [ + duplicateKeyFieldMappingErrorMessage('Query.product', 'id'), + ]), + ); + }); + + // Expectation updated (bug b fix): redundant @openfed__is(fields: "id") on argument + // named "id" now emits a warning (the directive duplicates the auto-map). + test('warning: redundant @openfed__is(fields: "id") on argument named "id" emits a redundancy warning', () => { + const { warnings } = normalizeSubgraphSuccess( + subgraph(` + type Query { + product(id: ID! @openfed__is(fields: "id")): Product @openfed__queryCache(maxAge: 30) + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + version, + ); + expect(warnings).toHaveLength(1); + expect(warnings[0].message).toBe( + `Argument "id" on field "Query.product" has @openfed__is(fields: "id"), but "id" already auto-maps to` + + ` @key field "id" on entity "Product". The @openfed__is directive is redundant and can be removed.`, + ); + }); + + test('success: @openfed__is maps differently-named argument to @key field', () => { + // "pid" doesn't match @key field "id", so @openfed__is(fields: "id") is required + const { schema, warnings } = normalizeSubgraphSuccess( + subgraph(` + type Query { + product(pid: ID! @openfed__is(fields: "id")): Product @openfed__queryCache(maxAge: 30) + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + version, + ); + expect(schema).toBeDefined(); + expect(warnings).toHaveLength(0); + }); + + test('config: @openfed__is mapping produces argumentPath with the original argument name', () => { + // product(pid: ID! @openfed__is(fields: "id")) → entityKeyField: "id", argumentPath: ["pid"] + const config = getConfigForType( + subgraph(` + type Query { + product(pid: ID! @openfed__is(fields: "id")): Product @openfed__queryCache(maxAge: 30) + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + QUERY, + ); + expect(config).toBeDefined(); + expect(config!.rootFieldCacheConfigurations).toStrictEqual([ + { + fieldName: 'product', + maxAgeSeconds: 30, + includeHeaders: false, + shadowMode: false, + entityTypeName: 'Product', + entityKeyMappings: [ + { + entityTypeName: 'Product', + fieldMappings: [{ entityKeyField: 'id', argumentPath: ['pid'] }], + }, + ], + }, + ] satisfies RootFieldCacheConfig[]); + }); + + test('config: @openfed__is can map scalar and composite keys on the same field', () => { + const config = getConfigForType( + subgraph(` + type Query { + product( + pid: ID! @openfed__is(fields: "id") + storeKey: ProductStoreKey! @openfed__is(fields: "store { id }") + ): Product @openfed__queryCache(maxAge: 30) + } + type Product @key(fields: "id") @key(fields: "store { id }") @openfed__entityCache(maxAge: 60) { + id: ID! + store: Store! + name: String! + } + type Store { + id: ID! + } + input ProductStoreKey { + store: StoreKey! + } + input StoreKey { + id: ID! + } + `), + QUERY, + ); + expect(config).toBeDefined(); + expect(config!.rootFieldCacheConfigurations).toStrictEqual([ + { + fieldName: 'product', + maxAgeSeconds: 30, + includeHeaders: false, + shadowMode: false, + entityTypeName: 'Product', + entityKeyMappings: [ + { + entityTypeName: 'Product', + fieldMappings: [{ entityKeyField: 'store.id', argumentPath: ['storeKey', 'store', 'id'] }], + }, + { + entityTypeName: 'Product', + fieldMappings: [{ entityKeyField: 'id', argumentPath: ['pid'] }], + }, + ], + }, + ] satisfies RootFieldCacheConfig[]); + }); + + test('config: composite @openfed__is matches reordered flat @key fields', () => { + const config = getConfigForType( + subgraph(` + type Query { + product(key: ProductKey! @openfed__is(fields: "sku id")): Product @openfed__queryCache(maxAge: 30) + } + type Product @key(fields: "id sku") @openfed__entityCache(maxAge: 60) { + id: ID! + sku: String! + name: String! + } + input ProductKey { + sku: String! + id: ID! + } + `), + QUERY, + ); + expect(config).toBeDefined(); + expect(config!.rootFieldCacheConfigurations).toStrictEqual([ + { + fieldName: 'product', + maxAgeSeconds: 30, + includeHeaders: false, + shadowMode: false, + entityTypeName: 'Product', + entityKeyMappings: [ + { + entityTypeName: 'Product', + fieldMappings: [ + { entityKeyField: 'id', argumentPath: ['key', 'id'] }, + { entityKeyField: 'sku', argumentPath: ['key', 'sku'] }, + ], + }, + ], + }, + ] satisfies RootFieldCacheConfig[]); + }); + + test('config: compound flat @key with @openfed__is on both args', () => { + const config = getConfigForType( + subgraph(` + type Query { + product(pid: ID! @openfed__is(fields: "id"), loc: String! @openfed__is(fields: "region")): Product @openfed__queryCache(maxAge: 30) + } + type Product @key(fields: "id region") @openfed__entityCache(maxAge: 60) { + id: ID! + region: String! + name: String! + } + `), + QUERY, + ); + expect(config).toBeDefined(); + const mappings = config!.rootFieldCacheConfigurations![0].entityKeyMappings[0].fieldMappings; + const sorted = [...mappings].sort((a, b) => a.entityKeyField.localeCompare(b.entityKeyField)); + expect(sorted).toStrictEqual([ + { entityKeyField: 'id', argumentPath: ['pid'] }, + { entityKeyField: 'region', argumentPath: ['loc'] }, + ]); + }); + + test('success: nested @key fields do not auto-map from unrelated flat arguments and emit no warning', () => { + const { warnings } = normalizeSubgraphSuccess( + subgraph(` + type Query { + product(storeId: ID!): Product @openfed__queryCache(maxAge: 30) + } + type Product @key(fields: "store { id }") @openfed__entityCache(maxAge: 60) { + store: Store! + name: String! + } + type Store { + id: ID! + } + `), + version, + ); + expect(warnings).toHaveLength(0); + }); + }); + + // ─── @openfed__cacheInvalidate ───────────────────────────────────────────────────────── + // @openfed__cacheInvalidate on a Mutation/Subscription field tells the router to evict the + // returned entity from the cache after the operation completes. + + describe('@openfed__cacheInvalidate', () => { + test('error: @openfed__cacheInvalidate on a Query field — eviction only applies to side-effect operations', () => { + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Query { + product(id: ID!): Product @openfed__cacheInvalidate + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + version, + ); + expect(errors).toHaveLength(1); + expect(errors[0]).toStrictEqual( + invalidDirectiveError(CACHE_INVALIDATE, 'Query.product', FIRST_ORDINAL, [ + cacheInvalidateOnNonMutationSubscriptionFieldErrorMessage('Query.product'), + ]), + ); + }); + + test('error: return type is not a cached entity — nothing to evict', () => { + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Query { dummy: String! } + type Mutation { + updateProduct(id: ID!): Result @openfed__cacheInvalidate + } + type Result { success: Boolean! } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + version, + ); + expect(errors).toHaveLength(1); + expect(errors[0]).toStrictEqual( + invalidDirectiveError(CACHE_INVALIDATE, 'Mutation.updateProduct', FIRST_ORDINAL, [ + cacheInvalidateOnNonEntityReturnTypeErrorMessage('Mutation.updateProduct', 'Result'), + ]), + ); + }); + + test('error: both @openfed__cacheInvalidate and @openfed__cachePopulate on same field — mutually exclusive', () => { + // A mutation can't both evict and write to the cache for the same entity + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Query { dummy: String! } + type Mutation { + updateProduct(id: ID!): Product @openfed__cacheInvalidate @openfed__cachePopulate + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + version, + ); + expect(errors).toHaveLength(1); + expect(errors[0]).toStrictEqual( + invalidDirectiveError(CACHE_INVALIDATE, 'Mutation.updateProduct', FIRST_ORDINAL, [ + cacheInvalidateAndPopulateMutualExclusionErrorMessage('Mutation.updateProduct'), + ]), + ); + }); + + test('success: @openfed__cacheInvalidate on Mutation returning a cached entity', () => { + const { schema } = normalizeSubgraphSuccess( + subgraph(` + type Query { dummy: String! } + type Mutation { + updateProduct(id: ID!): Product @openfed__cacheInvalidate + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + version, + ); + expect(schema).toBeDefined(); + }); + + test('config: produces CacheInvalidateConfig on the Mutation type', () => { + const config = getConfigForType( + subgraph(` + type Query { dummy: String! } + type Mutation { + updateProduct(id: ID!): Product @openfed__cacheInvalidate + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + MUTATION, + ); + expect(config).toBeDefined(); + expect(config!.cacheInvalidateConfigurations).toStrictEqual([ + { + fieldName: 'updateProduct', + operationType: MUTATION, + entityTypeName: 'Product', + }, + ] satisfies CacheInvalidateConfig[]); + }); + + test('success: @openfed__cacheInvalidate on Subscription returning a cached entity', () => { + const { schema } = normalizeSubgraphSuccess( + subgraph(` + type Query { dummy: String! } + type Subscription { + itemUpdated: Product @openfed__cacheInvalidate + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + version, + ); + expect(schema).toBeDefined(); + }); + + test('config: produces CacheInvalidateConfig on the Subscription type', () => { + const config = getConfigForType( + subgraph(` + type Query { dummy: String! } + type Subscription { + itemUpdated: Product @openfed__cacheInvalidate + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + SUBSCRIPTION, + ); + expect(config).toBeDefined(); + expect(config!.cacheInvalidateConfigurations).toStrictEqual([ + { + fieldName: 'itemUpdated', + operationType: SUBSCRIPTION, + entityTypeName: 'Product', + }, + ] satisfies CacheInvalidateConfig[]); + }); + + test('error: return entity has @key but no @openfed__entityCache — must opt into caching', () => { + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Query { dummy: String! } + type Mutation { + updateProduct(id: ID!): Product @openfed__cacheInvalidate + } + type Product @key(fields: "id") { + id: ID! + name: String! + } + `), + version, + ); + expect(errors).toHaveLength(1); + expect(errors[0]).toStrictEqual( + invalidDirectiveError(CACHE_INVALIDATE, 'Mutation.updateProduct', FIRST_ORDINAL, [ + cacheInvalidateOnNonEntityReturnTypeErrorMessage('Mutation.updateProduct', 'Product'), + ]), + ); + }); + }); + + // ─── @openfed__cachePopulate ─────────────────────────────────────────────────────────── + // @openfed__cachePopulate on a Mutation/Subscription field tells the router to write the + // returned entity into the cache. Optional maxAge overrides the entity's default TTL. + + describe('@openfed__cachePopulate', () => { + test('error: @openfed__cachePopulate on a Query field — population only applies to side-effect operations', () => { + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Query { + product(id: ID!): Product @openfed__cachePopulate + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + version, + ); + expect(errors).toHaveLength(1); + expect(errors[0]).toStrictEqual( + invalidDirectiveError(CACHE_POPULATE, 'Query.product', FIRST_ORDINAL, [ + cachePopulateOnNonMutationSubscriptionFieldErrorMessage('Query.product'), + ]), + ); + }); + + test('error: return type is not a cached entity — nothing to populate', () => { + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Query { dummy: String! } + type Mutation { + createProduct(name: String!): Result @openfed__cachePopulate + } + type Result { success: Boolean! } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + version, + ); + expect(errors).toHaveLength(1); + expect(errors[0]).toStrictEqual( + invalidDirectiveError(CACHE_POPULATE, 'Mutation.createProduct', FIRST_ORDINAL, [ + cachePopulateOnNonEntityReturnTypeErrorMessage('Mutation.createProduct', 'Result'), + ]), + ); + }); + + test('error: maxAge of zero — if provided, must be positive', () => { + const { errors } = normalizeSubgraphFailure( + subgraph(` + type Query { dummy: String! } + type Mutation { + createProduct(name: String!): Product @openfed__cachePopulate(maxAge: 0) + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + version, + ); + expect(errors).toHaveLength(1); + expect(errors[0]).toStrictEqual( + invalidDirectiveError(CACHE_POPULATE, 'Mutation.createProduct', FIRST_ORDINAL, [ + maxAgeNotPositiveIntegerErrorMessage(CACHE_POPULATE, 0), + ]), + ); + }); + + test('config: invalid maxAge does not produce a config (regression)', () => { + // Regression: invalid maxAge previously still pushed a config entry. + // Since composition now fails outright on maxAge: 0, assert the failure surface: + // exactly one error, and it is the invalidDirectiveError for @openfed__cachePopulate. + // The pre-fix bug was that validation failed but the config entry was still emitted + // — which is unobservable on the BatchNormalizationFailure public surface. Asserting + // the failure shape pins the precondition that guards the previously-leaky path. + const result = batchNormalize({ + subgraphs: [ + subgraph(` + type Query { dummy: String! } + type Mutation { + createProduct(name: String!): Product @openfed__cachePopulate(maxAge: 0) + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + ], + version: ROUTER_COMPATIBILITY_VERSION_ONE, + }); + expect(result.success).toBe(false); + if (result.success) return; + expect(result.errors).toHaveLength(1); + expect(result.errors[0]).toStrictEqual( + subgraphValidationError('subgraph-a', [ + invalidDirectiveError(CACHE_POPULATE, 'Mutation.createProduct', FIRST_ORDINAL, [ + maxAgeNotPositiveIntegerErrorMessage(CACHE_POPULATE, 0), + ]), + ]), + ); + }); + + test("success: @openfed__cachePopulate without maxAge — uses the entity's default TTL", () => { + const { schema } = normalizeSubgraphSuccess( + subgraph(` + type Query { dummy: String! } + type Mutation { + createProduct(name: String!): Product @openfed__cachePopulate + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + version, + ); + expect(schema).toBeDefined(); + }); + + test('success: @openfed__cachePopulate with explicit maxAge override', () => { + const { schema } = normalizeSubgraphSuccess( + subgraph(` + type Query { dummy: String! } + type Mutation { + createProduct(name: String!): Product @openfed__cachePopulate(maxAge: 120) + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + version, + ); + expect(schema).toBeDefined(); + }); + + test('config: without maxAge — maxAgeSeconds is undefined (falls back to entity default)', () => { + const config = getConfigForType( + subgraph(` + type Query { dummy: String! } + type Mutation { + createProduct(name: String!): Product @openfed__cachePopulate + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + MUTATION, + ); + expect(config).toBeDefined(); + expect(config!.cachePopulateConfigurations).toStrictEqual([ + { + fieldName: 'createProduct', + operationType: MUTATION, + entityTypeName: 'Product', + maxAgeSeconds: undefined, + }, + ] satisfies CachePopulateConfig[]); + }); + + test('config: with explicit maxAge override', () => { + const config = getConfigForType( + subgraph(` + type Query { dummy: String! } + type Mutation { + createProduct(name: String!): Product @openfed__cachePopulate(maxAge: 120) + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + MUTATION, + ); + expect(config).toBeDefined(); + expect(config!.cachePopulateConfigurations).toStrictEqual([ + { + fieldName: 'createProduct', + operationType: MUTATION, + entityTypeName: 'Product', + maxAgeSeconds: 120, + }, + ] satisfies CachePopulateConfig[]); + }); + + test('success: @openfed__cachePopulate on Subscription field', () => { + const { schema } = normalizeSubgraphSuccess( + subgraph(` + type Query { dummy: String! } + type Subscription { + itemCreated: Product @openfed__cachePopulate + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + version, + ); + expect(schema).toBeDefined(); + }); + + test('config: @openfed__cachePopulate on Subscription produces correct config', () => { + const config = getConfigForType( + subgraph(` + type Query { dummy: String! } + type Subscription { + itemCreated: Product @openfed__cachePopulate + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + SUBSCRIPTION, + ); + expect(config).toBeDefined(); + expect(config!.cachePopulateConfigurations).toStrictEqual([ + { + fieldName: 'itemCreated', + operationType: SUBSCRIPTION, + entityTypeName: 'Product', + maxAgeSeconds: undefined, + }, + ] satisfies CachePopulateConfig[]); + }); + }); + + // ─── Federation ─────────────────────────────────────────────────────────────── + // Entity caching directives are subgraph-local — they don't affect federation composition. + // The federated schema should contain the merged types without caching directive artifacts. + + describe('federation', () => { + test('caching directives on one subgraph compose cleanly with a non-caching subgraph', () => { + const cachingSubgraph = subgraph(` + type Query { + product(id: ID!): Product @openfed__queryCache(maxAge: 30) + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `); + const reviewsSubgraph = subgraph( + ` + type Query { + reviews(productId: ID!): [String!]! + } + type Product @key(fields: "id") { + id: ID! + } + `, + 'subgraph-b', + ); + + const { federatedGraphSchema, success } = federateSubgraphsSuccess([cachingSubgraph, reviewsSubgraph], version); + expect(success).toBe(true); + expect(schemaToSortedNormalizedString(federatedGraphSchema)).toBe( + normalizeString( + SCHEMA_QUERY_DEFINITION + + ` + type Product { + id: ID! + name: String! + } + + type Query { + product(id: ID!): Product + reviews(productId: ID!): [String!]! + } + `, + ), + ); + }); + + test('both subgraphs define @openfed__entityCache on the same entity with different TTLs', () => { + const subgraphA = subgraph(` + type Query { product(id: ID!): Product } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `); + const subgraphB = subgraph( + ` + type Query { productByPrice(price: Float!): Product } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 30) { + id: ID! + price: Float! + } + `, + 'subgraph-b', + ); + + const { federatedGraphSchema, success } = federateSubgraphsSuccess([subgraphA, subgraphB], version); + expect(success).toBe(true); + expect(schemaToSortedNormalizedString(federatedGraphSchema)).toBe( + normalizeString( + SCHEMA_QUERY_DEFINITION + + ` + type Product { + id: ID! + name: String! + price: Float! + } + + type Query { + product(id: ID!): Product + productByPrice(price: Float!): Product + } + `, + ), + ); + }); + }); + + // ─── edge cases ─────────────────────────────────────────────────────────────── + // Pin behavior for schema shapes that don't fit the happy-path assumptions in the + // validation method: renamed root types, @inaccessible entities, @key(resolvable: false), + // and @interfaceObject. These regressions are easy to introduce because they look like + // valid OBJECT_TYPE_DEFINITIONs at the AST level. + + describe('edge cases', () => { + // Composition supports `schema { query: MyQuery, mutation: MyMutation, subscription: MySubscription }`. + // Phase 2 captures parentTypeName from the iteration (which is the renamed name) and Phase 1/2 + // attach configs via parentTypeName — never via literal "Query"/"Mutation"/"Subscription". + // A regression here would silently drop every cache config when the schema renames a root type. + + test('config: @openfed__queryCache on a renamed Query root type attaches to the renamed type', () => { + const config = getConfigForType( + subgraph(` + schema { query: MyQuery } + type MyQuery { + product(id: ID!): Product @openfed__queryCache(maxAge: 30) + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + 'MyQuery', + ); + expect(config).toBeDefined(); + expect(config!.rootFieldCacheConfigurations).toStrictEqual([ + { + fieldName: 'product', + maxAgeSeconds: 30, + includeHeaders: false, + shadowMode: false, + entityTypeName: 'Product', + entityKeyMappings: [ + { + entityTypeName: 'Product', + fieldMappings: [{ entityKeyField: 'id', argumentPath: ['id'] }], + }, + ], + }, + ]); + }); + + test('config: @openfed__cachePopulate on a renamed Mutation root type attaches to the renamed type', () => { + const config = getConfigForType( + subgraph(` + schema { query: MyQuery, mutation: MyMutation } + type MyQuery { product(id: ID!): Product } + type MyMutation { + updateProduct(id: ID!, name: String!): Product @openfed__cachePopulate(maxAge: 120) + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + 'MyMutation', + ); + expect(config).toBeDefined(); + expect(config!.cachePopulateConfigurations).toStrictEqual([ + { + fieldName: 'updateProduct', + operationType: MUTATION, + entityTypeName: 'Product', + maxAgeSeconds: 120, + }, + ]); + }); + + test('config: @openfed__cacheInvalidate on a renamed Subscription root type attaches to the renamed type', () => { + const config = getConfigForType( + subgraph(` + schema { query: MyQuery, subscription: MySubscription } + type MyQuery { product(id: ID!): Product } + type MySubscription { + productDeleted: Product! @openfed__cacheInvalidate + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + 'MySubscription', + ); + expect(config).toBeDefined(); + expect(config!.cacheInvalidateConfigurations).toStrictEqual([ + { + fieldName: 'productDeleted', + operationType: SUBSCRIPTION, + entityTypeName: 'Product', + }, + ]); + }); + + // @key(resolvable: false) means "this subgraph references the entity but cannot resolve it + // by key from the entities federation field." @openfed__entityCache currently still applies because + // the @key is present — the router can still construct a cache key from the SDL. If we ever + // want to forbid this combination, change Phase 1's `keyFieldSetDatasByTypeName.has(typeName)` + // check to also require at least one resolvable key. + + test('config: @openfed__entityCache on a type with only @key(resolvable: false) is currently accepted', () => { + const config = getConfigForType( + subgraph(` + type Query { product(id: ID!): Product } + type Product @key(fields: "id", resolvable: false) @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + 'Product', + ); + expect(config).toBeDefined(); + expect(config!.entityCacheConfigurations).toStrictEqual([ + { + typeName: 'Product', + maxAgeSeconds: 60, + notFoundCacheTtlSeconds: 0, + includeHeaders: false, + partialCacheLoad: false, + shadowMode: false, + }, + ]); + }); + + // @interfaceObject types are OBJECT_TYPE_DEFINITIONs at the AST level (so Phase 1's filter + // accepts them) but the router treats them as interface representations. Their cache semantics + // aren't defined by the spec yet — pin the current behavior so a future change is intentional. + + test('config: @openfed__entityCache on an @interfaceObject type is currently accepted', () => { + const config = getConfigForType( + subgraph(` + type Query { product(id: ID!): Product } + type Product @key(fields: "id") @interfaceObject @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + 'Product', + ); + expect(config).toBeDefined(); + expect(config!.entityCacheConfigurations).toStrictEqual([ + { + typeName: 'Product', + maxAgeSeconds: 60, + notFoundCacheTtlSeconds: 0, + includeHeaders: false, + partialCacheLoad: false, + shadowMode: false, + }, + ]); + }); + }); + + // ─── @openfed__requestScoped registry membership ───────────────────────────────────────── + // The DIRECTIVE_DEFINITION_BY_NAME registry is the lookup used by normalization to resolve + // directive AST definitions by name. A missing entry silently breaks discovery. + describe('@openfed__requestScoped registry', () => { + test('DIRECTIVE_DEFINITION_BY_NAME[REQUEST_SCOPED] is the REQUEST_SCOPED_DEFINITION AST node', () => { + expect(DIRECTIVE_DEFINITION_BY_NAME.get(REQUEST_SCOPED)).toBe(REQUEST_SCOPED_DEFINITION); + }); + + test('success: @openfed__requestScoped directive is materialized in the normalized subgraph output', () => { + // The registry map DIRECTIVE_DEFINITION_BY_NAME is consumed by + // NormalizationFactory#addDirectiveDefinitionsToDocument when producing the normalized + // output: every directive name seen in the SDL (tracked in referencedDirectiveNames) + // is looked up in the registry, and the resolved AST node is set into + // directiveDefinitionByName. If REQUEST_SCOPED is missing from the registry, the + // resulting NormalizationSuccess.directiveDefinitionByName will NOT contain it — + // this assertion fails under that regression. + const { directiveDefinitionByName } = normalizeSubgraphSuccess( + subgraph(` + type Query { + product(id: ID!): Product + other(id: ID!): Product + } + type Product @key(fields: "id") { + id: ID! @openfed__requestScoped(key: "productId") + name: String! @openfed__requestScoped(key: "productName") + } + `), + version, + ); + expect(directiveDefinitionByName.has(REQUEST_SCOPED)).toBe(true); + expect(directiveDefinitionByName.get(REQUEST_SCOPED)).toBe(REQUEST_SCOPED_DEFINITION); + }); + }); + + // ─── Renamed root types ────────────────────────────────────────────────────── + // Regression coverage: when a subgraph explicitly renames its root operation types + // via `schema { query: MyQueryRoot mutation: MyMutationRoot }` (or via + // `extend schema { ... }`), cache directives on those root fields must be extracted. + // The first walker pass (`upsertDirectiveSchemaAndEntityDefinitions`) populates + // `operationTypeNodeByTypeName` from every `OperationTypeDefinition` node (inside + // SchemaDefinition and SchemaExtension), which runs before + // `validateAndExtractEntityCachingConfigs()`. If that walker population is ever + // removed or re-ordered, every cache config attached to renamed root types would + // silently drop. These tests pin that wiring. + describe('renamed root operation types', () => { + test('config: @openfed__queryCache on a renamed Query root is extracted', () => { + const config = getConfigForType( + subgraph(` + schema { query: MyQueryRoot } + type MyQueryRoot { + product(id: ID!): Product @openfed__queryCache(maxAge: 30) + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + 'MyQueryRoot', + ); + expect(config).toBeDefined(); + expect(config!.rootFieldCacheConfigurations).toStrictEqual([ + { + fieldName: 'product', + maxAgeSeconds: 30, + includeHeaders: false, + shadowMode: false, + entityTypeName: 'Product', + entityKeyMappings: [ + { + entityTypeName: 'Product', + fieldMappings: [{ entityKeyField: 'id', argumentPath: ['id'] }], + }, + ], + }, + ] satisfies RootFieldCacheConfig[]); + }); + + test('config: @openfed__queryCache on a renamed Query root via schema extension', () => { + const config = getConfigForType( + subgraph(` + extend schema { query: MyQueryRoot } + type MyQueryRoot { + product(id: ID!): Product @openfed__queryCache(maxAge: 30) + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + 'MyQueryRoot', + ); + expect(config).toBeDefined(); + expect(config!.rootFieldCacheConfigurations).toStrictEqual([ + { + fieldName: 'product', + maxAgeSeconds: 30, + includeHeaders: false, + shadowMode: false, + entityTypeName: 'Product', + entityKeyMappings: [ + { + entityTypeName: 'Product', + fieldMappings: [{ entityKeyField: 'id', argumentPath: ['id'] }], + }, + ], + }, + ] satisfies RootFieldCacheConfig[]); + }); + + test('config: @openfed__cacheInvalidate on a renamed Mutation root is extracted', () => { + const config = getConfigForType( + subgraph(` + schema { query: MyQueryRoot mutation: MyMutationRoot } + type MyQueryRoot { + product(id: ID!): Product + } + type MyMutationRoot { + deleteProduct(id: ID!): Product @openfed__cacheInvalidate + } + type Product @key(fields: "id") @openfed__entityCache(maxAge: 60) { + id: ID! + name: String! + } + `), + 'MyMutationRoot', + ); + expect(config).toBeDefined(); + expect(config!.cacheInvalidateConfigurations).toStrictEqual([ + { + fieldName: 'deleteProduct', + operationType: MUTATION, + entityTypeName: 'Product', + }, + ] satisfies CacheInvalidateConfig[]); + }); + }); +}); diff --git a/connect-go/gen/proto/wg/cosmo/node/v1/node.pb.go b/connect-go/gen/proto/wg/cosmo/node/v1/node.pb.go index 2df6fa273b..12b98d6c23 100644 --- a/connect-go/gen/proto/wg/cosmo/node/v1/node.pb.go +++ b/connect-go/gen/proto/wg/cosmo/node/v1/node.pb.go @@ -1070,8 +1070,15 @@ type DataSourceConfiguration struct { EntityInterfaces []*EntityInterfaceConfiguration `protobuf:"bytes,14,rep,name=entity_interfaces,json=entityInterfaces,proto3" json:"entity_interfaces,omitempty"` InterfaceObjects []*EntityInterfaceConfiguration `protobuf:"bytes,15,rep,name=interface_objects,json=interfaceObjects,proto3" json:"interface_objects,omitempty"` CostConfiguration *CostConfiguration `protobuf:"bytes,16,opt,name=cost_configuration,json=costConfiguration,proto3" json:"cost_configuration,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + // Entity caching configurations (from composition directives) + EntityCacheConfigurations []*EntityCacheConfiguration `protobuf:"bytes,17,rep,name=entity_cache_configurations,json=entityCacheConfigurations,proto3" json:"entity_cache_configurations,omitempty"` + RootFieldCacheConfigurations []*RootFieldCacheConfiguration `protobuf:"bytes,18,rep,name=root_field_cache_configurations,json=rootFieldCacheConfigurations,proto3" json:"root_field_cache_configurations,omitempty"` + CachePopulateConfigurations []*CachePopulateConfiguration `protobuf:"bytes,19,rep,name=cache_populate_configurations,json=cachePopulateConfigurations,proto3" json:"cache_populate_configurations,omitempty"` + CacheInvalidateConfigurations []*CacheInvalidateConfiguration `protobuf:"bytes,20,rep,name=cache_invalidate_configurations,json=cacheInvalidateConfigurations,proto3" json:"cache_invalidate_configurations,omitempty"` + // Request-scoped field configurations (from @openfed__requestScoped directive) + RequestScopedFields []*RequestScopedFieldConfiguration `protobuf:"bytes,21,rep,name=request_scoped_fields,json=requestScopedFields,proto3" json:"request_scoped_fields,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *DataSourceConfiguration) Reset() { @@ -1216,6 +1223,525 @@ func (x *DataSourceConfiguration) GetCostConfiguration() *CostConfiguration { return nil } +func (x *DataSourceConfiguration) GetEntityCacheConfigurations() []*EntityCacheConfiguration { + if x != nil { + return x.EntityCacheConfigurations + } + return nil +} + +func (x *DataSourceConfiguration) GetRootFieldCacheConfigurations() []*RootFieldCacheConfiguration { + if x != nil { + return x.RootFieldCacheConfigurations + } + return nil +} + +func (x *DataSourceConfiguration) GetCachePopulateConfigurations() []*CachePopulateConfiguration { + if x != nil { + return x.CachePopulateConfigurations + } + return nil +} + +func (x *DataSourceConfiguration) GetCacheInvalidateConfigurations() []*CacheInvalidateConfiguration { + if x != nil { + return x.CacheInvalidateConfigurations + } + return nil +} + +func (x *DataSourceConfiguration) GetRequestScopedFields() []*RequestScopedFieldConfiguration { + if x != nil { + return x.RequestScopedFields + } + return nil +} + +// Per-field declaration for @openfed__requestScoped. All fields in the same subgraph declaring +// @openfed__requestScoped(key: "X") share L1 key "{subgraphName}.X". The first field to resolve +// populates L1; subsequent fields with the same key inject from L1 and can skip their +// fetch when all required sub-fields are present. +type RequestScopedFieldConfiguration struct { + state protoimpl.MessageState `protogen:"open.v1"` + FieldName string `protobuf:"bytes,1,opt,name=field_name,json=fieldName,proto3" json:"field_name,omitempty"` + TypeName string `protobuf:"bytes,2,opt,name=type_name,json=typeName,proto3" json:"type_name,omitempty"` + L1Key string `protobuf:"bytes,3,opt,name=l1_key,json=l1Key,proto3" json:"l1_key,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RequestScopedFieldConfiguration) Reset() { + *x = RequestScopedFieldConfiguration{} + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RequestScopedFieldConfiguration) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RequestScopedFieldConfiguration) ProtoMessage() {} + +func (x *RequestScopedFieldConfiguration) ProtoReflect() protoreflect.Message { + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[12] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RequestScopedFieldConfiguration.ProtoReflect.Descriptor instead. +func (*RequestScopedFieldConfiguration) Descriptor() ([]byte, []int) { + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{12} +} + +func (x *RequestScopedFieldConfiguration) GetFieldName() string { + if x != nil { + return x.FieldName + } + return "" +} + +func (x *RequestScopedFieldConfiguration) GetTypeName() string { + if x != nil { + return x.TypeName + } + return "" +} + +func (x *RequestScopedFieldConfiguration) GetL1Key() string { + if x != nil { + return x.L1Key + } + return "" +} + +type EntityCacheConfiguration struct { + state protoimpl.MessageState `protogen:"open.v1"` + TypeName string `protobuf:"bytes,1,opt,name=type_name,json=typeName,proto3" json:"type_name,omitempty"` + // TTL for cached entity values. Required: composition rejects values <= 0, + // so omit (zero) does not occur in practice. Interpreted in seconds. + MaxAgeSeconds int64 `protobuf:"varint,2,opt,name=max_age_seconds,json=maxAgeSeconds,proto3" json:"max_age_seconds,omitempty"` + IncludeHeaders bool `protobuf:"varint,3,opt,name=include_headers,json=includeHeaders,proto3" json:"include_headers,omitempty"` + PartialCacheLoad bool `protobuf:"varint,4,opt,name=partial_cache_load,json=partialCacheLoad,proto3" json:"partial_cache_load,omitempty"` + ShadowMode bool `protobuf:"varint,5,opt,name=shadow_mode,json=shadowMode,proto3" json:"shadow_mode,omitempty"` + // TTL for caching "not found" entity responses (entity returned null from + // _entities without errors). Omit or 0 disables negative caching and null + // responses are not cached. Positive values are seconds. Composition rejects + // negative values at schema validation time. + NotFoundCacheTtlSeconds int64 `protobuf:"varint,6,opt,name=not_found_cache_ttl_seconds,json=notFoundCacheTtlSeconds,proto3" json:"not_found_cache_ttl_seconds,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *EntityCacheConfiguration) Reset() { + *x = EntityCacheConfiguration{} + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *EntityCacheConfiguration) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EntityCacheConfiguration) ProtoMessage() {} + +func (x *EntityCacheConfiguration) ProtoReflect() protoreflect.Message { + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[13] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EntityCacheConfiguration.ProtoReflect.Descriptor instead. +func (*EntityCacheConfiguration) Descriptor() ([]byte, []int) { + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{13} +} + +func (x *EntityCacheConfiguration) GetTypeName() string { + if x != nil { + return x.TypeName + } + return "" +} + +func (x *EntityCacheConfiguration) GetMaxAgeSeconds() int64 { + if x != nil { + return x.MaxAgeSeconds + } + return 0 +} + +func (x *EntityCacheConfiguration) GetIncludeHeaders() bool { + if x != nil { + return x.IncludeHeaders + } + return false +} + +func (x *EntityCacheConfiguration) GetPartialCacheLoad() bool { + if x != nil { + return x.PartialCacheLoad + } + return false +} + +func (x *EntityCacheConfiguration) GetShadowMode() bool { + if x != nil { + return x.ShadowMode + } + return false +} + +func (x *EntityCacheConfiguration) GetNotFoundCacheTtlSeconds() int64 { + if x != nil { + return x.NotFoundCacheTtlSeconds + } + return 0 +} + +type RootFieldCacheConfiguration struct { + state protoimpl.MessageState `protogen:"open.v1"` + FieldName string `protobuf:"bytes,1,opt,name=field_name,json=fieldName,proto3" json:"field_name,omitempty"` + // TTL for cached root-field responses. Required: composition rejects values + // <= 0. Interpreted in seconds. + MaxAgeSeconds int64 `protobuf:"varint,2,opt,name=max_age_seconds,json=maxAgeSeconds,proto3" json:"max_age_seconds,omitempty"` + IncludeHeaders bool `protobuf:"varint,3,opt,name=include_headers,json=includeHeaders,proto3" json:"include_headers,omitempty"` + ShadowMode bool `protobuf:"varint,4,opt,name=shadow_mode,json=shadowMode,proto3" json:"shadow_mode,omitempty"` + EntityTypeName string `protobuf:"bytes,5,opt,name=entity_type_name,json=entityTypeName,proto3" json:"entity_type_name,omitempty"` + EntityKeyMappings []*EntityKeyMapping `protobuf:"bytes,6,rep,name=entity_key_mappings,json=entityKeyMappings,proto3" json:"entity_key_mappings,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RootFieldCacheConfiguration) Reset() { + *x = RootFieldCacheConfiguration{} + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RootFieldCacheConfiguration) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RootFieldCacheConfiguration) ProtoMessage() {} + +func (x *RootFieldCacheConfiguration) ProtoReflect() protoreflect.Message { + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[14] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RootFieldCacheConfiguration.ProtoReflect.Descriptor instead. +func (*RootFieldCacheConfiguration) Descriptor() ([]byte, []int) { + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{14} +} + +func (x *RootFieldCacheConfiguration) GetFieldName() string { + if x != nil { + return x.FieldName + } + return "" +} + +func (x *RootFieldCacheConfiguration) GetMaxAgeSeconds() int64 { + if x != nil { + return x.MaxAgeSeconds + } + return 0 +} + +func (x *RootFieldCacheConfiguration) GetIncludeHeaders() bool { + if x != nil { + return x.IncludeHeaders + } + return false +} + +func (x *RootFieldCacheConfiguration) GetShadowMode() bool { + if x != nil { + return x.ShadowMode + } + return false +} + +func (x *RootFieldCacheConfiguration) GetEntityTypeName() string { + if x != nil { + return x.EntityTypeName + } + return "" +} + +func (x *RootFieldCacheConfiguration) GetEntityKeyMappings() []*EntityKeyMapping { + if x != nil { + return x.EntityKeyMappings + } + return nil +} + +type EntityKeyMapping struct { + state protoimpl.MessageState `protogen:"open.v1"` + EntityTypeName string `protobuf:"bytes,1,opt,name=entity_type_name,json=entityTypeName,proto3" json:"entity_type_name,omitempty"` + FieldMappings []*EntityCacheFieldMapping `protobuf:"bytes,2,rep,name=field_mappings,json=fieldMappings,proto3" json:"field_mappings,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *EntityKeyMapping) Reset() { + *x = EntityKeyMapping{} + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *EntityKeyMapping) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EntityKeyMapping) ProtoMessage() {} + +func (x *EntityKeyMapping) ProtoReflect() protoreflect.Message { + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[15] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EntityKeyMapping.ProtoReflect.Descriptor instead. +func (*EntityKeyMapping) Descriptor() ([]byte, []int) { + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{15} +} + +func (x *EntityKeyMapping) GetEntityTypeName() string { + if x != nil { + return x.EntityTypeName + } + return "" +} + +func (x *EntityKeyMapping) GetFieldMappings() []*EntityCacheFieldMapping { + if x != nil { + return x.FieldMappings + } + return nil +} + +type EntityCacheFieldMapping struct { + state protoimpl.MessageState `protogen:"open.v1"` + EntityKeyField string `protobuf:"bytes,1,opt,name=entity_key_field,json=entityKeyField,proto3" json:"entity_key_field,omitempty"` + ArgumentPath []string `protobuf:"bytes,2,rep,name=argument_path,json=argumentPath,proto3" json:"argument_path,omitempty"` + IsBatch bool `protobuf:"varint,3,opt,name=is_batch,json=isBatch,proto3" json:"is_batch,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *EntityCacheFieldMapping) Reset() { + *x = EntityCacheFieldMapping{} + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *EntityCacheFieldMapping) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EntityCacheFieldMapping) ProtoMessage() {} + +func (x *EntityCacheFieldMapping) ProtoReflect() protoreflect.Message { + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[16] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EntityCacheFieldMapping.ProtoReflect.Descriptor instead. +func (*EntityCacheFieldMapping) Descriptor() ([]byte, []int) { + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{16} +} + +func (x *EntityCacheFieldMapping) GetEntityKeyField() string { + if x != nil { + return x.EntityKeyField + } + return "" +} + +func (x *EntityCacheFieldMapping) GetArgumentPath() []string { + if x != nil { + return x.ArgumentPath + } + return nil +} + +func (x *EntityCacheFieldMapping) GetIsBatch() bool { + if x != nil { + return x.IsBatch + } + return false +} + +type CachePopulateConfiguration struct { + state protoimpl.MessageState `protogen:"open.v1"` + FieldName string `protobuf:"bytes,1,opt,name=field_name,json=fieldName,proto3" json:"field_name,omitempty"` + OperationType string `protobuf:"bytes,2,opt,name=operation_type,json=operationType,proto3" json:"operation_type,omitempty"` + // Optional override TTL for mutation/subscription populate writes. When omit, + // falls back to the target entity's max_age_seconds (for subscriptions) or + // the cache's default TTL (for mutations). Zero is treated as "no override". + // Composition rejects negative values. + MaxAgeSeconds *int64 `protobuf:"varint,3,opt,name=max_age_seconds,json=maxAgeSeconds,proto3,oneof" json:"max_age_seconds,omitempty"` + EntityTypeName string `protobuf:"bytes,4,opt,name=entity_type_name,json=entityTypeName,proto3" json:"entity_type_name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CachePopulateConfiguration) Reset() { + *x = CachePopulateConfiguration{} + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CachePopulateConfiguration) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CachePopulateConfiguration) ProtoMessage() {} + +func (x *CachePopulateConfiguration) ProtoReflect() protoreflect.Message { + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[17] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CachePopulateConfiguration.ProtoReflect.Descriptor instead. +func (*CachePopulateConfiguration) Descriptor() ([]byte, []int) { + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{17} +} + +func (x *CachePopulateConfiguration) GetFieldName() string { + if x != nil { + return x.FieldName + } + return "" +} + +func (x *CachePopulateConfiguration) GetOperationType() string { + if x != nil { + return x.OperationType + } + return "" +} + +func (x *CachePopulateConfiguration) GetMaxAgeSeconds() int64 { + if x != nil && x.MaxAgeSeconds != nil { + return *x.MaxAgeSeconds + } + return 0 +} + +func (x *CachePopulateConfiguration) GetEntityTypeName() string { + if x != nil { + return x.EntityTypeName + } + return "" +} + +type CacheInvalidateConfiguration struct { + state protoimpl.MessageState `protogen:"open.v1"` + FieldName string `protobuf:"bytes,1,opt,name=field_name,json=fieldName,proto3" json:"field_name,omitempty"` + OperationType string `protobuf:"bytes,2,opt,name=operation_type,json=operationType,proto3" json:"operation_type,omitempty"` + EntityTypeName string `protobuf:"bytes,3,opt,name=entity_type_name,json=entityTypeName,proto3" json:"entity_type_name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CacheInvalidateConfiguration) Reset() { + *x = CacheInvalidateConfiguration{} + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CacheInvalidateConfiguration) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CacheInvalidateConfiguration) ProtoMessage() {} + +func (x *CacheInvalidateConfiguration) ProtoReflect() protoreflect.Message { + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[18] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CacheInvalidateConfiguration.ProtoReflect.Descriptor instead. +func (*CacheInvalidateConfiguration) Descriptor() ([]byte, []int) { + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{18} +} + +func (x *CacheInvalidateConfiguration) GetFieldName() string { + if x != nil { + return x.FieldName + } + return "" +} + +func (x *CacheInvalidateConfiguration) GetOperationType() string { + if x != nil { + return x.OperationType + } + return "" +} + +func (x *CacheInvalidateConfiguration) GetEntityTypeName() string { + if x != nil { + return x.EntityTypeName + } + return "" +} + type CostConfiguration struct { state protoimpl.MessageState `protogen:"open.v1"` FieldWeights []*FieldWeightConfiguration `protobuf:"bytes,1,rep,name=field_weights,json=fieldWeights,proto3" json:"field_weights,omitempty"` @@ -1228,7 +1754,7 @@ type CostConfiguration struct { func (x *CostConfiguration) Reset() { *x = CostConfiguration{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[12] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1240,7 +1766,7 @@ func (x *CostConfiguration) String() string { func (*CostConfiguration) ProtoMessage() {} func (x *CostConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[12] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[19] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1253,7 +1779,7 @@ func (x *CostConfiguration) ProtoReflect() protoreflect.Message { // Deprecated: Use CostConfiguration.ProtoReflect.Descriptor instead. func (*CostConfiguration) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{12} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{19} } func (x *CostConfiguration) GetFieldWeights() []*FieldWeightConfiguration { @@ -1297,7 +1823,7 @@ type FieldWeightConfiguration struct { func (x *FieldWeightConfiguration) Reset() { *x = FieldWeightConfiguration{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[13] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1309,7 +1835,7 @@ func (x *FieldWeightConfiguration) String() string { func (*FieldWeightConfiguration) ProtoMessage() {} func (x *FieldWeightConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[13] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[20] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1322,7 +1848,7 @@ func (x *FieldWeightConfiguration) ProtoReflect() protoreflect.Message { // Deprecated: Use FieldWeightConfiguration.ProtoReflect.Descriptor instead. func (*FieldWeightConfiguration) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{13} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{20} } func (x *FieldWeightConfiguration) GetTypeName() string { @@ -1374,7 +1900,7 @@ type FieldListSizeConfiguration struct { func (x *FieldListSizeConfiguration) Reset() { *x = FieldListSizeConfiguration{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[14] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1386,7 +1912,7 @@ func (x *FieldListSizeConfiguration) String() string { func (*FieldListSizeConfiguration) ProtoMessage() {} func (x *FieldListSizeConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[14] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[21] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1399,7 +1925,7 @@ func (x *FieldListSizeConfiguration) ProtoReflect() protoreflect.Message { // Deprecated: Use FieldListSizeConfiguration.ProtoReflect.Descriptor instead. func (*FieldListSizeConfiguration) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{14} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{21} } func (x *FieldListSizeConfiguration) GetTypeName() string { @@ -1454,7 +1980,7 @@ type ArgumentConfiguration struct { func (x *ArgumentConfiguration) Reset() { *x = ArgumentConfiguration{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[15] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1466,7 +1992,7 @@ func (x *ArgumentConfiguration) String() string { func (*ArgumentConfiguration) ProtoMessage() {} func (x *ArgumentConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[15] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[22] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1479,7 +2005,7 @@ func (x *ArgumentConfiguration) ProtoReflect() protoreflect.Message { // Deprecated: Use ArgumentConfiguration.ProtoReflect.Descriptor instead. func (*ArgumentConfiguration) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{15} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{22} } func (x *ArgumentConfiguration) GetName() string { @@ -1505,7 +2031,7 @@ type Scopes struct { func (x *Scopes) Reset() { *x = Scopes{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[16] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1517,7 +2043,7 @@ func (x *Scopes) String() string { func (*Scopes) ProtoMessage() {} func (x *Scopes) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[16] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[23] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1530,7 +2056,7 @@ func (x *Scopes) ProtoReflect() protoreflect.Message { // Deprecated: Use Scopes.ProtoReflect.Descriptor instead. func (*Scopes) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{16} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{23} } func (x *Scopes) GetRequiredAndScopes() []string { @@ -1551,7 +2077,7 @@ type AuthorizationConfiguration struct { func (x *AuthorizationConfiguration) Reset() { *x = AuthorizationConfiguration{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[17] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1563,7 +2089,7 @@ func (x *AuthorizationConfiguration) String() string { func (*AuthorizationConfiguration) ProtoMessage() {} func (x *AuthorizationConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[17] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[24] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1576,7 +2102,7 @@ func (x *AuthorizationConfiguration) ProtoReflect() protoreflect.Message { // Deprecated: Use AuthorizationConfiguration.ProtoReflect.Descriptor instead. func (*AuthorizationConfiguration) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{17} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{24} } func (x *AuthorizationConfiguration) GetRequiresAuthentication() bool { @@ -1613,7 +2139,7 @@ type FieldConfiguration struct { func (x *FieldConfiguration) Reset() { *x = FieldConfiguration{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[18] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1625,7 +2151,7 @@ func (x *FieldConfiguration) String() string { func (*FieldConfiguration) ProtoMessage() {} func (x *FieldConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[18] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[25] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1638,7 +2164,7 @@ func (x *FieldConfiguration) ProtoReflect() protoreflect.Message { // Deprecated: Use FieldConfiguration.ProtoReflect.Descriptor instead. func (*FieldConfiguration) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{18} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{25} } func (x *FieldConfiguration) GetTypeName() string { @@ -1686,7 +2212,7 @@ type TypeConfiguration struct { func (x *TypeConfiguration) Reset() { *x = TypeConfiguration{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[19] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1698,7 +2224,7 @@ func (x *TypeConfiguration) String() string { func (*TypeConfiguration) ProtoMessage() {} func (x *TypeConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[19] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[26] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1711,7 +2237,7 @@ func (x *TypeConfiguration) ProtoReflect() protoreflect.Message { // Deprecated: Use TypeConfiguration.ProtoReflect.Descriptor instead. func (*TypeConfiguration) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{19} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{26} } func (x *TypeConfiguration) GetTypeName() string { @@ -1740,7 +2266,7 @@ type TypeField struct { func (x *TypeField) Reset() { *x = TypeField{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[20] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1752,7 +2278,7 @@ func (x *TypeField) String() string { func (*TypeField) ProtoMessage() {} func (x *TypeField) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[20] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[27] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1765,7 +2291,7 @@ func (x *TypeField) ProtoReflect() protoreflect.Message { // Deprecated: Use TypeField.ProtoReflect.Descriptor instead. func (*TypeField) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{20} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{27} } func (x *TypeField) GetTypeName() string { @@ -1806,7 +2332,7 @@ type FieldCoordinates struct { func (x *FieldCoordinates) Reset() { *x = FieldCoordinates{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[21] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1818,7 +2344,7 @@ func (x *FieldCoordinates) String() string { func (*FieldCoordinates) ProtoMessage() {} func (x *FieldCoordinates) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[21] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[28] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1831,7 +2357,7 @@ func (x *FieldCoordinates) ProtoReflect() protoreflect.Message { // Deprecated: Use FieldCoordinates.ProtoReflect.Descriptor instead. func (*FieldCoordinates) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{21} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{28} } func (x *FieldCoordinates) GetFieldName() string { @@ -1858,7 +2384,7 @@ type FieldSetCondition struct { func (x *FieldSetCondition) Reset() { *x = FieldSetCondition{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[22] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1870,7 +2396,7 @@ func (x *FieldSetCondition) String() string { func (*FieldSetCondition) ProtoMessage() {} func (x *FieldSetCondition) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[22] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[29] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1883,7 +2409,7 @@ func (x *FieldSetCondition) ProtoReflect() protoreflect.Message { // Deprecated: Use FieldSetCondition.ProtoReflect.Descriptor instead. func (*FieldSetCondition) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{22} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{29} } func (x *FieldSetCondition) GetFieldCoordinatesPath() []*FieldCoordinates { @@ -1913,7 +2439,7 @@ type RequiredField struct { func (x *RequiredField) Reset() { *x = RequiredField{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[23] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[30] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1925,7 +2451,7 @@ func (x *RequiredField) String() string { func (*RequiredField) ProtoMessage() {} func (x *RequiredField) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[23] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[30] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1938,7 +2464,7 @@ func (x *RequiredField) ProtoReflect() protoreflect.Message { // Deprecated: Use RequiredField.ProtoReflect.Descriptor instead. func (*RequiredField) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{23} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{30} } func (x *RequiredField) GetTypeName() string { @@ -1986,7 +2512,7 @@ type EntityInterfaceConfiguration struct { func (x *EntityInterfaceConfiguration) Reset() { *x = EntityInterfaceConfiguration{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[24] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1998,7 +2524,7 @@ func (x *EntityInterfaceConfiguration) String() string { func (*EntityInterfaceConfiguration) ProtoMessage() {} func (x *EntityInterfaceConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[24] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[31] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2011,7 +2537,7 @@ func (x *EntityInterfaceConfiguration) ProtoReflect() protoreflect.Message { // Deprecated: Use EntityInterfaceConfiguration.ProtoReflect.Descriptor instead. func (*EntityInterfaceConfiguration) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{24} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{31} } func (x *EntityInterfaceConfiguration) GetInterfaceTypeName() string { @@ -2054,7 +2580,7 @@ type FetchConfiguration struct { func (x *FetchConfiguration) Reset() { *x = FetchConfiguration{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[25] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[32] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2066,7 +2592,7 @@ func (x *FetchConfiguration) String() string { func (*FetchConfiguration) ProtoMessage() {} func (x *FetchConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[25] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[32] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2079,7 +2605,7 @@ func (x *FetchConfiguration) ProtoReflect() protoreflect.Message { // Deprecated: Use FetchConfiguration.ProtoReflect.Descriptor instead. func (*FetchConfiguration) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{25} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{32} } func (x *FetchConfiguration) GetUrl() *ConfigurationVariable { @@ -2163,7 +2689,7 @@ type StatusCodeTypeMapping struct { func (x *StatusCodeTypeMapping) Reset() { *x = StatusCodeTypeMapping{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[26] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[33] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2175,7 +2701,7 @@ func (x *StatusCodeTypeMapping) String() string { func (*StatusCodeTypeMapping) ProtoMessage() {} func (x *StatusCodeTypeMapping) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[26] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[33] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2188,7 +2714,7 @@ func (x *StatusCodeTypeMapping) ProtoReflect() protoreflect.Message { // Deprecated: Use StatusCodeTypeMapping.ProtoReflect.Descriptor instead. func (*StatusCodeTypeMapping) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{26} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{33} } func (x *StatusCodeTypeMapping) GetStatusCode() int64 { @@ -2226,7 +2752,7 @@ type DataSourceCustom_GraphQL struct { func (x *DataSourceCustom_GraphQL) Reset() { *x = DataSourceCustom_GraphQL{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[27] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[34] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2238,7 +2764,7 @@ func (x *DataSourceCustom_GraphQL) String() string { func (*DataSourceCustom_GraphQL) ProtoMessage() {} func (x *DataSourceCustom_GraphQL) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[27] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[34] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2251,7 +2777,7 @@ func (x *DataSourceCustom_GraphQL) ProtoReflect() protoreflect.Message { // Deprecated: Use DataSourceCustom_GraphQL.ProtoReflect.Descriptor instead. func (*DataSourceCustom_GraphQL) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{27} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{34} } func (x *DataSourceCustom_GraphQL) GetFetch() *FetchConfiguration { @@ -2307,7 +2833,7 @@ type GRPCConfiguration struct { func (x *GRPCConfiguration) Reset() { *x = GRPCConfiguration{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[28] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[35] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2319,7 +2845,7 @@ func (x *GRPCConfiguration) String() string { func (*GRPCConfiguration) ProtoMessage() {} func (x *GRPCConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[28] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[35] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2332,7 +2858,7 @@ func (x *GRPCConfiguration) ProtoReflect() protoreflect.Message { // Deprecated: Use GRPCConfiguration.ProtoReflect.Descriptor instead. func (*GRPCConfiguration) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{28} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{35} } func (x *GRPCConfiguration) GetMapping() *GRPCMapping { @@ -2366,7 +2892,7 @@ type ImageReference struct { func (x *ImageReference) Reset() { *x = ImageReference{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[29] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[36] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2378,7 +2904,7 @@ func (x *ImageReference) String() string { func (*ImageReference) ProtoMessage() {} func (x *ImageReference) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[29] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[36] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2391,7 +2917,7 @@ func (x *ImageReference) ProtoReflect() protoreflect.Message { // Deprecated: Use ImageReference.ProtoReflect.Descriptor instead. func (*ImageReference) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{29} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{36} } func (x *ImageReference) GetRepository() string { @@ -2421,7 +2947,7 @@ type PluginConfiguration struct { func (x *PluginConfiguration) Reset() { *x = PluginConfiguration{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[30] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[37] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2433,7 +2959,7 @@ func (x *PluginConfiguration) String() string { func (*PluginConfiguration) ProtoMessage() {} func (x *PluginConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[30] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[37] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2446,7 +2972,7 @@ func (x *PluginConfiguration) ProtoReflect() protoreflect.Message { // Deprecated: Use PluginConfiguration.ProtoReflect.Descriptor instead. func (*PluginConfiguration) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{30} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{37} } func (x *PluginConfiguration) GetName() string { @@ -2480,7 +3006,7 @@ type SSLConfiguration struct { func (x *SSLConfiguration) Reset() { *x = SSLConfiguration{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[31] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[38] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2492,7 +3018,7 @@ func (x *SSLConfiguration) String() string { func (*SSLConfiguration) ProtoMessage() {} func (x *SSLConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[31] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[38] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2505,7 +3031,7 @@ func (x *SSLConfiguration) ProtoReflect() protoreflect.Message { // Deprecated: Use SSLConfiguration.ProtoReflect.Descriptor instead. func (*SSLConfiguration) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{31} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{38} } func (x *SSLConfiguration) GetEnabled() bool { @@ -2538,7 +3064,7 @@ type GRPCMapping struct { func (x *GRPCMapping) Reset() { *x = GRPCMapping{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[32] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[39] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2550,7 +3076,7 @@ func (x *GRPCMapping) String() string { func (*GRPCMapping) ProtoMessage() {} func (x *GRPCMapping) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[32] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[39] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2563,7 +3089,7 @@ func (x *GRPCMapping) ProtoReflect() protoreflect.Message { // Deprecated: Use GRPCMapping.ProtoReflect.Descriptor instead. func (*GRPCMapping) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{32} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{39} } func (x *GRPCMapping) GetVersion() int32 { @@ -2634,7 +3160,7 @@ type LookupMapping struct { func (x *LookupMapping) Reset() { *x = LookupMapping{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[33] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[40] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2646,7 +3172,7 @@ func (x *LookupMapping) String() string { func (*LookupMapping) ProtoMessage() {} func (x *LookupMapping) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[33] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[40] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2659,7 +3185,7 @@ func (x *LookupMapping) ProtoReflect() protoreflect.Message { // Deprecated: Use LookupMapping.ProtoReflect.Descriptor instead. func (*LookupMapping) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{33} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{40} } func (x *LookupMapping) GetType() LookupType { @@ -2710,7 +3236,7 @@ type LookupFieldMapping struct { func (x *LookupFieldMapping) Reset() { *x = LookupFieldMapping{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[34] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[41] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2722,7 +3248,7 @@ func (x *LookupFieldMapping) String() string { func (*LookupFieldMapping) ProtoMessage() {} func (x *LookupFieldMapping) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[34] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[41] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2735,7 +3261,7 @@ func (x *LookupFieldMapping) ProtoReflect() protoreflect.Message { // Deprecated: Use LookupFieldMapping.ProtoReflect.Descriptor instead. func (*LookupFieldMapping) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{34} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{41} } func (x *LookupFieldMapping) GetType() string { @@ -2771,7 +3297,7 @@ type OperationMapping struct { func (x *OperationMapping) Reset() { *x = OperationMapping{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[35] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[42] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2783,7 +3309,7 @@ func (x *OperationMapping) String() string { func (*OperationMapping) ProtoMessage() {} func (x *OperationMapping) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[35] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[42] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2796,7 +3322,7 @@ func (x *OperationMapping) ProtoReflect() protoreflect.Message { // Deprecated: Use OperationMapping.ProtoReflect.Descriptor instead. func (*OperationMapping) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{35} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{42} } func (x *OperationMapping) GetType() OperationType { @@ -2857,7 +3383,7 @@ type EntityMapping struct { func (x *EntityMapping) Reset() { *x = EntityMapping{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[36] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[43] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2869,7 +3395,7 @@ func (x *EntityMapping) String() string { func (*EntityMapping) ProtoMessage() {} func (x *EntityMapping) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[36] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[43] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2882,7 +3408,7 @@ func (x *EntityMapping) ProtoReflect() protoreflect.Message { // Deprecated: Use EntityMapping.ProtoReflect.Descriptor instead. func (*EntityMapping) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{36} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{43} } func (x *EntityMapping) GetTypeName() string { @@ -2950,7 +3476,7 @@ type RequiredFieldMapping struct { func (x *RequiredFieldMapping) Reset() { *x = RequiredFieldMapping{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[37] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[44] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2962,7 +3488,7 @@ func (x *RequiredFieldMapping) String() string { func (*RequiredFieldMapping) ProtoMessage() {} func (x *RequiredFieldMapping) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[37] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[44] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2975,7 +3501,7 @@ func (x *RequiredFieldMapping) ProtoReflect() protoreflect.Message { // Deprecated: Use RequiredFieldMapping.ProtoReflect.Descriptor instead. func (*RequiredFieldMapping) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{37} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{44} } func (x *RequiredFieldMapping) GetFieldMapping() *FieldMapping { @@ -3019,7 +3545,7 @@ type TypeFieldMapping struct { func (x *TypeFieldMapping) Reset() { *x = TypeFieldMapping{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[38] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[45] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3031,7 +3557,7 @@ func (x *TypeFieldMapping) String() string { func (*TypeFieldMapping) ProtoMessage() {} func (x *TypeFieldMapping) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[38] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[45] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3044,7 +3570,7 @@ func (x *TypeFieldMapping) ProtoReflect() protoreflect.Message { // Deprecated: Use TypeFieldMapping.ProtoReflect.Descriptor instead. func (*TypeFieldMapping) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{38} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{45} } func (x *TypeFieldMapping) GetType() string { @@ -3076,7 +3602,7 @@ type FieldMapping struct { func (x *FieldMapping) Reset() { *x = FieldMapping{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[39] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[46] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3088,7 +3614,7 @@ func (x *FieldMapping) String() string { func (*FieldMapping) ProtoMessage() {} func (x *FieldMapping) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[39] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[46] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3101,7 +3627,7 @@ func (x *FieldMapping) ProtoReflect() protoreflect.Message { // Deprecated: Use FieldMapping.ProtoReflect.Descriptor instead. func (*FieldMapping) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{39} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{46} } func (x *FieldMapping) GetOriginal() string { @@ -3138,7 +3664,7 @@ type ArgumentMapping struct { func (x *ArgumentMapping) Reset() { *x = ArgumentMapping{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[40] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[47] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3150,7 +3676,7 @@ func (x *ArgumentMapping) String() string { func (*ArgumentMapping) ProtoMessage() {} func (x *ArgumentMapping) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[40] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[47] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3163,7 +3689,7 @@ func (x *ArgumentMapping) ProtoReflect() protoreflect.Message { // Deprecated: Use ArgumentMapping.ProtoReflect.Descriptor instead. func (*ArgumentMapping) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{40} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{47} } func (x *ArgumentMapping) GetOriginal() string { @@ -3190,7 +3716,7 @@ type EnumMapping struct { func (x *EnumMapping) Reset() { *x = EnumMapping{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[41] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[48] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3202,7 +3728,7 @@ func (x *EnumMapping) String() string { func (*EnumMapping) ProtoMessage() {} func (x *EnumMapping) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[41] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[48] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3215,7 +3741,7 @@ func (x *EnumMapping) ProtoReflect() protoreflect.Message { // Deprecated: Use EnumMapping.ProtoReflect.Descriptor instead. func (*EnumMapping) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{41} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{48} } func (x *EnumMapping) GetType() string { @@ -3242,7 +3768,7 @@ type EnumValueMapping struct { func (x *EnumValueMapping) Reset() { *x = EnumValueMapping{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[42] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[49] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3254,7 +3780,7 @@ func (x *EnumValueMapping) String() string { func (*EnumValueMapping) ProtoMessage() {} func (x *EnumValueMapping) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[42] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[49] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3267,7 +3793,7 @@ func (x *EnumValueMapping) ProtoReflect() protoreflect.Message { // Deprecated: Use EnumValueMapping.ProtoReflect.Descriptor instead. func (*EnumValueMapping) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{42} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{49} } func (x *EnumValueMapping) GetOriginal() string { @@ -3295,7 +3821,7 @@ type NatsStreamConfiguration struct { func (x *NatsStreamConfiguration) Reset() { *x = NatsStreamConfiguration{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[43] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[50] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3307,7 +3833,7 @@ func (x *NatsStreamConfiguration) String() string { func (*NatsStreamConfiguration) ProtoMessage() {} func (x *NatsStreamConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[43] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[50] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3320,7 +3846,7 @@ func (x *NatsStreamConfiguration) ProtoReflect() protoreflect.Message { // Deprecated: Use NatsStreamConfiguration.ProtoReflect.Descriptor instead. func (*NatsStreamConfiguration) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{43} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{50} } func (x *NatsStreamConfiguration) GetConsumerName() string { @@ -3355,7 +3881,7 @@ type NatsEventConfiguration struct { func (x *NatsEventConfiguration) Reset() { *x = NatsEventConfiguration{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[44] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[51] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3367,7 +3893,7 @@ func (x *NatsEventConfiguration) String() string { func (*NatsEventConfiguration) ProtoMessage() {} func (x *NatsEventConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[44] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[51] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3380,7 +3906,7 @@ func (x *NatsEventConfiguration) ProtoReflect() protoreflect.Message { // Deprecated: Use NatsEventConfiguration.ProtoReflect.Descriptor instead. func (*NatsEventConfiguration) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{44} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{51} } func (x *NatsEventConfiguration) GetEngineEventConfiguration() *EngineEventConfiguration { @@ -3414,7 +3940,7 @@ type KafkaEventConfiguration struct { func (x *KafkaEventConfiguration) Reset() { *x = KafkaEventConfiguration{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[45] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[52] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3426,7 +3952,7 @@ func (x *KafkaEventConfiguration) String() string { func (*KafkaEventConfiguration) ProtoMessage() {} func (x *KafkaEventConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[45] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[52] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3439,7 +3965,7 @@ func (x *KafkaEventConfiguration) ProtoReflect() protoreflect.Message { // Deprecated: Use KafkaEventConfiguration.ProtoReflect.Descriptor instead. func (*KafkaEventConfiguration) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{45} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{52} } func (x *KafkaEventConfiguration) GetEngineEventConfiguration() *EngineEventConfiguration { @@ -3466,7 +3992,7 @@ type RedisEventConfiguration struct { func (x *RedisEventConfiguration) Reset() { *x = RedisEventConfiguration{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[46] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[53] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3478,7 +4004,7 @@ func (x *RedisEventConfiguration) String() string { func (*RedisEventConfiguration) ProtoMessage() {} func (x *RedisEventConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[46] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[53] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3491,7 +4017,7 @@ func (x *RedisEventConfiguration) ProtoReflect() protoreflect.Message { // Deprecated: Use RedisEventConfiguration.ProtoReflect.Descriptor instead. func (*RedisEventConfiguration) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{46} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{53} } func (x *RedisEventConfiguration) GetEngineEventConfiguration() *EngineEventConfiguration { @@ -3520,7 +4046,7 @@ type EngineEventConfiguration struct { func (x *EngineEventConfiguration) Reset() { *x = EngineEventConfiguration{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[47] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[54] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3532,7 +4058,7 @@ func (x *EngineEventConfiguration) String() string { func (*EngineEventConfiguration) ProtoMessage() {} func (x *EngineEventConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[47] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[54] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3545,7 +4071,7 @@ func (x *EngineEventConfiguration) ProtoReflect() protoreflect.Message { // Deprecated: Use EngineEventConfiguration.ProtoReflect.Descriptor instead. func (*EngineEventConfiguration) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{47} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{54} } func (x *EngineEventConfiguration) GetProviderId() string { @@ -3587,7 +4113,7 @@ type DataSourceCustomEvents struct { func (x *DataSourceCustomEvents) Reset() { *x = DataSourceCustomEvents{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[48] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[55] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3599,7 +4125,7 @@ func (x *DataSourceCustomEvents) String() string { func (*DataSourceCustomEvents) ProtoMessage() {} func (x *DataSourceCustomEvents) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[48] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[55] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3612,7 +4138,7 @@ func (x *DataSourceCustomEvents) ProtoReflect() protoreflect.Message { // Deprecated: Use DataSourceCustomEvents.ProtoReflect.Descriptor instead. func (*DataSourceCustomEvents) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{48} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{55} } func (x *DataSourceCustomEvents) GetNats() []*NatsEventConfiguration { @@ -3645,7 +4171,7 @@ type DataSourceCustom_Static struct { func (x *DataSourceCustom_Static) Reset() { *x = DataSourceCustom_Static{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[49] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[56] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3657,7 +4183,7 @@ func (x *DataSourceCustom_Static) String() string { func (*DataSourceCustom_Static) ProtoMessage() {} func (x *DataSourceCustom_Static) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[49] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[56] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3670,7 +4196,7 @@ func (x *DataSourceCustom_Static) ProtoReflect() protoreflect.Message { // Deprecated: Use DataSourceCustom_Static.ProtoReflect.Descriptor instead. func (*DataSourceCustom_Static) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{49} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{56} } func (x *DataSourceCustom_Static) GetData() *ConfigurationVariable { @@ -3693,7 +4219,7 @@ type ConfigurationVariable struct { func (x *ConfigurationVariable) Reset() { *x = ConfigurationVariable{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[50] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[57] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3705,7 +4231,7 @@ func (x *ConfigurationVariable) String() string { func (*ConfigurationVariable) ProtoMessage() {} func (x *ConfigurationVariable) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[50] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[57] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3718,7 +4244,7 @@ func (x *ConfigurationVariable) ProtoReflect() protoreflect.Message { // Deprecated: Use ConfigurationVariable.ProtoReflect.Descriptor instead. func (*ConfigurationVariable) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{50} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{57} } func (x *ConfigurationVariable) GetKind() ConfigurationVariableKind { @@ -3766,7 +4292,7 @@ type DirectiveConfiguration struct { func (x *DirectiveConfiguration) Reset() { *x = DirectiveConfiguration{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[51] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[58] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3778,7 +4304,7 @@ func (x *DirectiveConfiguration) String() string { func (*DirectiveConfiguration) ProtoMessage() {} func (x *DirectiveConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[51] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[58] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3791,7 +4317,7 @@ func (x *DirectiveConfiguration) ProtoReflect() protoreflect.Message { // Deprecated: Use DirectiveConfiguration.ProtoReflect.Descriptor instead. func (*DirectiveConfiguration) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{51} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{58} } func (x *DirectiveConfiguration) GetDirectiveName() string { @@ -3818,7 +4344,7 @@ type URLQueryConfiguration struct { func (x *URLQueryConfiguration) Reset() { *x = URLQueryConfiguration{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[52] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[59] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3830,7 +4356,7 @@ func (x *URLQueryConfiguration) String() string { func (*URLQueryConfiguration) ProtoMessage() {} func (x *URLQueryConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[52] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[59] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3843,7 +4369,7 @@ func (x *URLQueryConfiguration) ProtoReflect() protoreflect.Message { // Deprecated: Use URLQueryConfiguration.ProtoReflect.Descriptor instead. func (*URLQueryConfiguration) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{52} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{59} } func (x *URLQueryConfiguration) GetName() string { @@ -3869,7 +4395,7 @@ type HTTPHeader struct { func (x *HTTPHeader) Reset() { *x = HTTPHeader{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[53] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[60] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3881,7 +4407,7 @@ func (x *HTTPHeader) String() string { func (*HTTPHeader) ProtoMessage() {} func (x *HTTPHeader) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[53] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[60] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3894,7 +4420,7 @@ func (x *HTTPHeader) ProtoReflect() protoreflect.Message { // Deprecated: Use HTTPHeader.ProtoReflect.Descriptor instead. func (*HTTPHeader) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{53} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{60} } func (x *HTTPHeader) GetValues() []*ConfigurationVariable { @@ -3915,7 +4441,7 @@ type MTLSConfiguration struct { func (x *MTLSConfiguration) Reset() { *x = MTLSConfiguration{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[54] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[61] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3927,7 +4453,7 @@ func (x *MTLSConfiguration) String() string { func (*MTLSConfiguration) ProtoMessage() {} func (x *MTLSConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[54] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[61] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3940,7 +4466,7 @@ func (x *MTLSConfiguration) ProtoReflect() protoreflect.Message { // Deprecated: Use MTLSConfiguration.ProtoReflect.Descriptor instead. func (*MTLSConfiguration) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{54} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{61} } func (x *MTLSConfiguration) GetKey() *ConfigurationVariable { @@ -3978,7 +4504,7 @@ type GraphQLSubscriptionConfiguration struct { func (x *GraphQLSubscriptionConfiguration) Reset() { *x = GraphQLSubscriptionConfiguration{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[55] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[62] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3990,7 +4516,7 @@ func (x *GraphQLSubscriptionConfiguration) String() string { func (*GraphQLSubscriptionConfiguration) ProtoMessage() {} func (x *GraphQLSubscriptionConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[55] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[62] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4003,7 +4529,7 @@ func (x *GraphQLSubscriptionConfiguration) ProtoReflect() protoreflect.Message { // Deprecated: Use GraphQLSubscriptionConfiguration.ProtoReflect.Descriptor instead. func (*GraphQLSubscriptionConfiguration) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{55} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{62} } func (x *GraphQLSubscriptionConfiguration) GetEnabled() bool { @@ -4051,7 +4577,7 @@ type GraphQLFederationConfiguration struct { func (x *GraphQLFederationConfiguration) Reset() { *x = GraphQLFederationConfiguration{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[56] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[63] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4063,7 +4589,7 @@ func (x *GraphQLFederationConfiguration) String() string { func (*GraphQLFederationConfiguration) ProtoMessage() {} func (x *GraphQLFederationConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[56] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[63] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4076,7 +4602,7 @@ func (x *GraphQLFederationConfiguration) ProtoReflect() protoreflect.Message { // Deprecated: Use GraphQLFederationConfiguration.ProtoReflect.Descriptor instead. func (*GraphQLFederationConfiguration) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{56} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{63} } func (x *GraphQLFederationConfiguration) GetEnabled() bool { @@ -4103,7 +4629,7 @@ type InternedString struct { func (x *InternedString) Reset() { *x = InternedString{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[57] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[64] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4115,7 +4641,7 @@ func (x *InternedString) String() string { func (*InternedString) ProtoMessage() {} func (x *InternedString) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[57] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[64] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4128,7 +4654,7 @@ func (x *InternedString) ProtoReflect() protoreflect.Message { // Deprecated: Use InternedString.ProtoReflect.Descriptor instead. func (*InternedString) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{57} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{64} } func (x *InternedString) GetKey() string { @@ -4148,7 +4674,7 @@ type SingleTypeField struct { func (x *SingleTypeField) Reset() { *x = SingleTypeField{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[58] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[65] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4160,7 +4686,7 @@ func (x *SingleTypeField) String() string { func (*SingleTypeField) ProtoMessage() {} func (x *SingleTypeField) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[58] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[65] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4173,7 +4699,7 @@ func (x *SingleTypeField) ProtoReflect() protoreflect.Message { // Deprecated: Use SingleTypeField.ProtoReflect.Descriptor instead. func (*SingleTypeField) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{58} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{65} } func (x *SingleTypeField) GetTypeName() string { @@ -4200,7 +4726,7 @@ type SubscriptionFieldCondition struct { func (x *SubscriptionFieldCondition) Reset() { *x = SubscriptionFieldCondition{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[59] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[66] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4212,7 +4738,7 @@ func (x *SubscriptionFieldCondition) String() string { func (*SubscriptionFieldCondition) ProtoMessage() {} func (x *SubscriptionFieldCondition) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[59] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[66] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4225,7 +4751,7 @@ func (x *SubscriptionFieldCondition) ProtoReflect() protoreflect.Message { // Deprecated: Use SubscriptionFieldCondition.ProtoReflect.Descriptor instead. func (*SubscriptionFieldCondition) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{59} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{66} } func (x *SubscriptionFieldCondition) GetFieldPath() []string { @@ -4254,7 +4780,7 @@ type SubscriptionFilterCondition struct { func (x *SubscriptionFilterCondition) Reset() { *x = SubscriptionFilterCondition{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[60] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[67] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4266,7 +4792,7 @@ func (x *SubscriptionFilterCondition) String() string { func (*SubscriptionFilterCondition) ProtoMessage() {} func (x *SubscriptionFilterCondition) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[60] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[67] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4279,7 +4805,7 @@ func (x *SubscriptionFilterCondition) ProtoReflect() protoreflect.Message { // Deprecated: Use SubscriptionFilterCondition.ProtoReflect.Descriptor instead. func (*SubscriptionFilterCondition) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{60} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{67} } func (x *SubscriptionFilterCondition) GetAnd() []*SubscriptionFilterCondition { @@ -4319,7 +4845,7 @@ type CacheWarmerOperations struct { func (x *CacheWarmerOperations) Reset() { *x = CacheWarmerOperations{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[61] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[68] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4331,7 +4857,7 @@ func (x *CacheWarmerOperations) String() string { func (*CacheWarmerOperations) ProtoMessage() {} func (x *CacheWarmerOperations) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[61] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[68] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4344,7 +4870,7 @@ func (x *CacheWarmerOperations) ProtoReflect() protoreflect.Message { // Deprecated: Use CacheWarmerOperations.ProtoReflect.Descriptor instead. func (*CacheWarmerOperations) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{61} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{68} } func (x *CacheWarmerOperations) GetOperations() []*Operation { @@ -4364,7 +4890,7 @@ type Operation struct { func (x *Operation) Reset() { *x = Operation{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[62] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[69] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4376,7 +4902,7 @@ func (x *Operation) String() string { func (*Operation) ProtoMessage() {} func (x *Operation) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[62] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[69] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4389,7 +4915,7 @@ func (x *Operation) ProtoReflect() protoreflect.Message { // Deprecated: Use Operation.ProtoReflect.Descriptor instead. func (*Operation) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{62} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{69} } func (x *Operation) GetRequest() *OperationRequest { @@ -4417,7 +4943,7 @@ type OperationRequest struct { func (x *OperationRequest) Reset() { *x = OperationRequest{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[63] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[70] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4429,7 +4955,7 @@ func (x *OperationRequest) String() string { func (*OperationRequest) ProtoMessage() {} func (x *OperationRequest) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[63] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[70] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4442,7 +4968,7 @@ func (x *OperationRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use OperationRequest.ProtoReflect.Descriptor instead. func (*OperationRequest) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{63} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{70} } func (x *OperationRequest) GetOperationName() string { @@ -4475,7 +5001,7 @@ type Extension struct { func (x *Extension) Reset() { *x = Extension{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[64] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[71] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4487,7 +5013,7 @@ func (x *Extension) String() string { func (*Extension) ProtoMessage() {} func (x *Extension) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[64] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[71] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4500,7 +5026,7 @@ func (x *Extension) ProtoReflect() protoreflect.Message { // Deprecated: Use Extension.ProtoReflect.Descriptor instead. func (*Extension) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{64} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{71} } func (x *Extension) GetPersistedQuery() *PersistedQuery { @@ -4520,7 +5046,7 @@ type PersistedQuery struct { func (x *PersistedQuery) Reset() { *x = PersistedQuery{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[65] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[72] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4532,7 +5058,7 @@ func (x *PersistedQuery) String() string { func (*PersistedQuery) ProtoMessage() {} func (x *PersistedQuery) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[65] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[72] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4545,7 +5071,7 @@ func (x *PersistedQuery) ProtoReflect() protoreflect.Message { // Deprecated: Use PersistedQuery.ProtoReflect.Descriptor instead. func (*PersistedQuery) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{65} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{72} } func (x *PersistedQuery) GetSha256Hash() string { @@ -4572,7 +5098,7 @@ type ClientInfo struct { func (x *ClientInfo) Reset() { *x = ClientInfo{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[66] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[73] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4584,7 +5110,7 @@ func (x *ClientInfo) String() string { func (*ClientInfo) ProtoMessage() {} func (x *ClientInfo) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[66] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[73] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4597,7 +5123,7 @@ func (x *ClientInfo) ProtoReflect() protoreflect.Message { // Deprecated: Use ClientInfo.ProtoReflect.Descriptor instead. func (*ClientInfo) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{66} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{73} } func (x *ClientInfo) GetName() string { @@ -4669,7 +5195,7 @@ const file_wg_cosmo_node_v1_node_proto_rawDesc = "" + "\x12StringStorageEntry\x12\x10\n" + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01B\x18\n" + - "\x16_graphql_client_schema\"\xce\b\n" + + "\x16_graphql_client_schema\"\x81\r\n" + "\x17DataSourceConfiguration\x124\n" + "\x04kind\x18\x01 \x01(\x0e2 .wg.cosmo.node.v1.DataSourceKindR\x04kind\x12:\n" + "\n" + @@ -4691,7 +5217,53 @@ const file_wg_cosmo_node_v1_node_proto_rawDesc = "" + "\rcustom_events\x18\r \x01(\v2(.wg.cosmo.node.v1.DataSourceCustomEventsR\fcustomEvents\x12[\n" + "\x11entity_interfaces\x18\x0e \x03(\v2..wg.cosmo.node.v1.EntityInterfaceConfigurationR\x10entityInterfaces\x12[\n" + "\x11interface_objects\x18\x0f \x03(\v2..wg.cosmo.node.v1.EntityInterfaceConfigurationR\x10interfaceObjects\x12R\n" + - "\x12cost_configuration\x18\x10 \x01(\v2#.wg.cosmo.node.v1.CostConfigurationR\x11costConfiguration\"\x98\x04\n" + + "\x12cost_configuration\x18\x10 \x01(\v2#.wg.cosmo.node.v1.CostConfigurationR\x11costConfiguration\x12j\n" + + "\x1bentity_cache_configurations\x18\x11 \x03(\v2*.wg.cosmo.node.v1.EntityCacheConfigurationR\x19entityCacheConfigurations\x12t\n" + + "\x1froot_field_cache_configurations\x18\x12 \x03(\v2-.wg.cosmo.node.v1.RootFieldCacheConfigurationR\x1crootFieldCacheConfigurations\x12p\n" + + "\x1dcache_populate_configurations\x18\x13 \x03(\v2,.wg.cosmo.node.v1.CachePopulateConfigurationR\x1bcachePopulateConfigurations\x12v\n" + + "\x1fcache_invalidate_configurations\x18\x14 \x03(\v2..wg.cosmo.node.v1.CacheInvalidateConfigurationR\x1dcacheInvalidateConfigurations\x12e\n" + + "\x15request_scoped_fields\x18\x15 \x03(\v21.wg.cosmo.node.v1.RequestScopedFieldConfigurationR\x13requestScopedFields\"\x88\x01\n" + + "\x1fRequestScopedFieldConfiguration\x12\x1d\n" + + "\n" + + "field_name\x18\x01 \x01(\tR\tfieldName\x12\x1b\n" + + "\ttype_name\x18\x02 \x01(\tR\btypeName\x12\x15\n" + + "\x06l1_key\x18\x03 \x01(\tR\x05l1KeyJ\x04\b\x04\x10\x05R\fresolve_from\"\xb1\x02\n" + + "\x18EntityCacheConfiguration\x12\x1b\n" + + "\ttype_name\x18\x01 \x01(\tR\btypeName\x12&\n" + + "\x0fmax_age_seconds\x18\x02 \x01(\x03R\rmaxAgeSeconds\x12'\n" + + "\x0finclude_headers\x18\x03 \x01(\bR\x0eincludeHeaders\x12,\n" + + "\x12partial_cache_load\x18\x04 \x01(\bR\x10partialCacheLoad\x12\x1f\n" + + "\vshadow_mode\x18\x05 \x01(\bR\n" + + "shadowMode\x12<\n" + + "\x1bnot_found_cache_ttl_seconds\x18\x06 \x01(\x03R\x17notFoundCacheTtlSecondsR\x1anegative_cache_ttl_seconds\"\xac\x02\n" + + "\x1bRootFieldCacheConfiguration\x12\x1d\n" + + "\n" + + "field_name\x18\x01 \x01(\tR\tfieldName\x12&\n" + + "\x0fmax_age_seconds\x18\x02 \x01(\x03R\rmaxAgeSeconds\x12'\n" + + "\x0finclude_headers\x18\x03 \x01(\bR\x0eincludeHeaders\x12\x1f\n" + + "\vshadow_mode\x18\x04 \x01(\bR\n" + + "shadowMode\x12(\n" + + "\x10entity_type_name\x18\x05 \x01(\tR\x0eentityTypeName\x12R\n" + + "\x13entity_key_mappings\x18\x06 \x03(\v2\".wg.cosmo.node.v1.EntityKeyMappingR\x11entityKeyMappings\"\x8e\x01\n" + + "\x10EntityKeyMapping\x12(\n" + + "\x10entity_type_name\x18\x01 \x01(\tR\x0eentityTypeName\x12P\n" + + "\x0efield_mappings\x18\x02 \x03(\v2).wg.cosmo.node.v1.EntityCacheFieldMappingR\rfieldMappings\"\x83\x01\n" + + "\x17EntityCacheFieldMapping\x12(\n" + + "\x10entity_key_field\x18\x01 \x01(\tR\x0eentityKeyField\x12#\n" + + "\rargument_path\x18\x02 \x03(\tR\fargumentPath\x12\x19\n" + + "\bis_batch\x18\x03 \x01(\bR\aisBatch\"\xcd\x01\n" + + "\x1aCachePopulateConfiguration\x12\x1d\n" + + "\n" + + "field_name\x18\x01 \x01(\tR\tfieldName\x12%\n" + + "\x0eoperation_type\x18\x02 \x01(\tR\roperationType\x12+\n" + + "\x0fmax_age_seconds\x18\x03 \x01(\x03H\x00R\rmaxAgeSeconds\x88\x01\x01\x12(\n" + + "\x10entity_type_name\x18\x04 \x01(\tR\x0eentityTypeNameB\x12\n" + + "\x10_max_age_seconds\"\x8e\x01\n" + + "\x1cCacheInvalidateConfiguration\x12\x1d\n" + + "\n" + + "field_name\x18\x01 \x01(\tR\tfieldName\x12%\n" + + "\x0eoperation_type\x18\x02 \x01(\tR\roperationType\x12(\n" + + "\x10entity_type_name\x18\x03 \x01(\tR\x0eentityTypeName\"\x98\x04\n" + "\x11CostConfiguration\x12O\n" + "\rfield_weights\x18\x01 \x03(\v2*.wg.cosmo.node.v1.FieldWeightConfigurationR\ffieldWeights\x12K\n" + "\n" + @@ -5030,7 +5602,7 @@ func file_wg_cosmo_node_v1_node_proto_rawDescGZIP() []byte { } var file_wg_cosmo_node_v1_node_proto_enumTypes = make([]protoimpl.EnumInfo, 8) -var file_wg_cosmo_node_v1_node_proto_msgTypes = make([]protoimpl.MessageInfo, 74) +var file_wg_cosmo_node_v1_node_proto_msgTypes = make([]protoimpl.MessageInfo, 81) var file_wg_cosmo_node_v1_node_proto_goTypes = []any{ (ArgumentRenderConfiguration)(0), // 0: wg.cosmo.node.v1.ArgumentRenderConfiguration (ArgumentSource)(0), // 1: wg.cosmo.node.v1.ArgumentSource @@ -5052,180 +5624,194 @@ var file_wg_cosmo_node_v1_node_proto_goTypes = []any{ (*SelfRegisterResponse)(nil), // 17: wg.cosmo.node.v1.SelfRegisterResponse (*EngineConfiguration)(nil), // 18: wg.cosmo.node.v1.EngineConfiguration (*DataSourceConfiguration)(nil), // 19: wg.cosmo.node.v1.DataSourceConfiguration - (*CostConfiguration)(nil), // 20: wg.cosmo.node.v1.CostConfiguration - (*FieldWeightConfiguration)(nil), // 21: wg.cosmo.node.v1.FieldWeightConfiguration - (*FieldListSizeConfiguration)(nil), // 22: wg.cosmo.node.v1.FieldListSizeConfiguration - (*ArgumentConfiguration)(nil), // 23: wg.cosmo.node.v1.ArgumentConfiguration - (*Scopes)(nil), // 24: wg.cosmo.node.v1.Scopes - (*AuthorizationConfiguration)(nil), // 25: wg.cosmo.node.v1.AuthorizationConfiguration - (*FieldConfiguration)(nil), // 26: wg.cosmo.node.v1.FieldConfiguration - (*TypeConfiguration)(nil), // 27: wg.cosmo.node.v1.TypeConfiguration - (*TypeField)(nil), // 28: wg.cosmo.node.v1.TypeField - (*FieldCoordinates)(nil), // 29: wg.cosmo.node.v1.FieldCoordinates - (*FieldSetCondition)(nil), // 30: wg.cosmo.node.v1.FieldSetCondition - (*RequiredField)(nil), // 31: wg.cosmo.node.v1.RequiredField - (*EntityInterfaceConfiguration)(nil), // 32: wg.cosmo.node.v1.EntityInterfaceConfiguration - (*FetchConfiguration)(nil), // 33: wg.cosmo.node.v1.FetchConfiguration - (*StatusCodeTypeMapping)(nil), // 34: wg.cosmo.node.v1.StatusCodeTypeMapping - (*DataSourceCustom_GraphQL)(nil), // 35: wg.cosmo.node.v1.DataSourceCustom_GraphQL - (*GRPCConfiguration)(nil), // 36: wg.cosmo.node.v1.GRPCConfiguration - (*ImageReference)(nil), // 37: wg.cosmo.node.v1.ImageReference - (*PluginConfiguration)(nil), // 38: wg.cosmo.node.v1.PluginConfiguration - (*SSLConfiguration)(nil), // 39: wg.cosmo.node.v1.SSLConfiguration - (*GRPCMapping)(nil), // 40: wg.cosmo.node.v1.GRPCMapping - (*LookupMapping)(nil), // 41: wg.cosmo.node.v1.LookupMapping - (*LookupFieldMapping)(nil), // 42: wg.cosmo.node.v1.LookupFieldMapping - (*OperationMapping)(nil), // 43: wg.cosmo.node.v1.OperationMapping - (*EntityMapping)(nil), // 44: wg.cosmo.node.v1.EntityMapping - (*RequiredFieldMapping)(nil), // 45: wg.cosmo.node.v1.RequiredFieldMapping - (*TypeFieldMapping)(nil), // 46: wg.cosmo.node.v1.TypeFieldMapping - (*FieldMapping)(nil), // 47: wg.cosmo.node.v1.FieldMapping - (*ArgumentMapping)(nil), // 48: wg.cosmo.node.v1.ArgumentMapping - (*EnumMapping)(nil), // 49: wg.cosmo.node.v1.EnumMapping - (*EnumValueMapping)(nil), // 50: wg.cosmo.node.v1.EnumValueMapping - (*NatsStreamConfiguration)(nil), // 51: wg.cosmo.node.v1.NatsStreamConfiguration - (*NatsEventConfiguration)(nil), // 52: wg.cosmo.node.v1.NatsEventConfiguration - (*KafkaEventConfiguration)(nil), // 53: wg.cosmo.node.v1.KafkaEventConfiguration - (*RedisEventConfiguration)(nil), // 54: wg.cosmo.node.v1.RedisEventConfiguration - (*EngineEventConfiguration)(nil), // 55: wg.cosmo.node.v1.EngineEventConfiguration - (*DataSourceCustomEvents)(nil), // 56: wg.cosmo.node.v1.DataSourceCustomEvents - (*DataSourceCustom_Static)(nil), // 57: wg.cosmo.node.v1.DataSourceCustom_Static - (*ConfigurationVariable)(nil), // 58: wg.cosmo.node.v1.ConfigurationVariable - (*DirectiveConfiguration)(nil), // 59: wg.cosmo.node.v1.DirectiveConfiguration - (*URLQueryConfiguration)(nil), // 60: wg.cosmo.node.v1.URLQueryConfiguration - (*HTTPHeader)(nil), // 61: wg.cosmo.node.v1.HTTPHeader - (*MTLSConfiguration)(nil), // 62: wg.cosmo.node.v1.MTLSConfiguration - (*GraphQLSubscriptionConfiguration)(nil), // 63: wg.cosmo.node.v1.GraphQLSubscriptionConfiguration - (*GraphQLFederationConfiguration)(nil), // 64: wg.cosmo.node.v1.GraphQLFederationConfiguration - (*InternedString)(nil), // 65: wg.cosmo.node.v1.InternedString - (*SingleTypeField)(nil), // 66: wg.cosmo.node.v1.SingleTypeField - (*SubscriptionFieldCondition)(nil), // 67: wg.cosmo.node.v1.SubscriptionFieldCondition - (*SubscriptionFilterCondition)(nil), // 68: wg.cosmo.node.v1.SubscriptionFilterCondition - (*CacheWarmerOperations)(nil), // 69: wg.cosmo.node.v1.CacheWarmerOperations - (*Operation)(nil), // 70: wg.cosmo.node.v1.Operation - (*OperationRequest)(nil), // 71: wg.cosmo.node.v1.OperationRequest - (*Extension)(nil), // 72: wg.cosmo.node.v1.Extension - (*PersistedQuery)(nil), // 73: wg.cosmo.node.v1.PersistedQuery - (*ClientInfo)(nil), // 74: wg.cosmo.node.v1.ClientInfo - nil, // 75: wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs.ConfigByFeatureFlagNameEntry - nil, // 76: wg.cosmo.node.v1.EngineConfiguration.StringStorageEntry - nil, // 77: wg.cosmo.node.v1.CostConfiguration.TypeWeightsEntry - nil, // 78: wg.cosmo.node.v1.CostConfiguration.DirectiveArgumentWeightsEntry - nil, // 79: wg.cosmo.node.v1.FieldWeightConfiguration.ArgumentWeightsEntry - nil, // 80: wg.cosmo.node.v1.FieldWeightConfiguration.DirectiveArgumentWeightsEntry - nil, // 81: wg.cosmo.node.v1.FetchConfiguration.HeaderEntry - (common.EnumStatusCode)(0), // 82: wg.cosmo.common.EnumStatusCode - (common.GraphQLSubscriptionProtocol)(0), // 83: wg.cosmo.common.GraphQLSubscriptionProtocol - (common.GraphQLWebsocketSubprotocol)(0), // 84: wg.cosmo.common.GraphQLWebsocketSubprotocol + (*RequestScopedFieldConfiguration)(nil), // 20: wg.cosmo.node.v1.RequestScopedFieldConfiguration + (*EntityCacheConfiguration)(nil), // 21: wg.cosmo.node.v1.EntityCacheConfiguration + (*RootFieldCacheConfiguration)(nil), // 22: wg.cosmo.node.v1.RootFieldCacheConfiguration + (*EntityKeyMapping)(nil), // 23: wg.cosmo.node.v1.EntityKeyMapping + (*EntityCacheFieldMapping)(nil), // 24: wg.cosmo.node.v1.EntityCacheFieldMapping + (*CachePopulateConfiguration)(nil), // 25: wg.cosmo.node.v1.CachePopulateConfiguration + (*CacheInvalidateConfiguration)(nil), // 26: wg.cosmo.node.v1.CacheInvalidateConfiguration + (*CostConfiguration)(nil), // 27: wg.cosmo.node.v1.CostConfiguration + (*FieldWeightConfiguration)(nil), // 28: wg.cosmo.node.v1.FieldWeightConfiguration + (*FieldListSizeConfiguration)(nil), // 29: wg.cosmo.node.v1.FieldListSizeConfiguration + (*ArgumentConfiguration)(nil), // 30: wg.cosmo.node.v1.ArgumentConfiguration + (*Scopes)(nil), // 31: wg.cosmo.node.v1.Scopes + (*AuthorizationConfiguration)(nil), // 32: wg.cosmo.node.v1.AuthorizationConfiguration + (*FieldConfiguration)(nil), // 33: wg.cosmo.node.v1.FieldConfiguration + (*TypeConfiguration)(nil), // 34: wg.cosmo.node.v1.TypeConfiguration + (*TypeField)(nil), // 35: wg.cosmo.node.v1.TypeField + (*FieldCoordinates)(nil), // 36: wg.cosmo.node.v1.FieldCoordinates + (*FieldSetCondition)(nil), // 37: wg.cosmo.node.v1.FieldSetCondition + (*RequiredField)(nil), // 38: wg.cosmo.node.v1.RequiredField + (*EntityInterfaceConfiguration)(nil), // 39: wg.cosmo.node.v1.EntityInterfaceConfiguration + (*FetchConfiguration)(nil), // 40: wg.cosmo.node.v1.FetchConfiguration + (*StatusCodeTypeMapping)(nil), // 41: wg.cosmo.node.v1.StatusCodeTypeMapping + (*DataSourceCustom_GraphQL)(nil), // 42: wg.cosmo.node.v1.DataSourceCustom_GraphQL + (*GRPCConfiguration)(nil), // 43: wg.cosmo.node.v1.GRPCConfiguration + (*ImageReference)(nil), // 44: wg.cosmo.node.v1.ImageReference + (*PluginConfiguration)(nil), // 45: wg.cosmo.node.v1.PluginConfiguration + (*SSLConfiguration)(nil), // 46: wg.cosmo.node.v1.SSLConfiguration + (*GRPCMapping)(nil), // 47: wg.cosmo.node.v1.GRPCMapping + (*LookupMapping)(nil), // 48: wg.cosmo.node.v1.LookupMapping + (*LookupFieldMapping)(nil), // 49: wg.cosmo.node.v1.LookupFieldMapping + (*OperationMapping)(nil), // 50: wg.cosmo.node.v1.OperationMapping + (*EntityMapping)(nil), // 51: wg.cosmo.node.v1.EntityMapping + (*RequiredFieldMapping)(nil), // 52: wg.cosmo.node.v1.RequiredFieldMapping + (*TypeFieldMapping)(nil), // 53: wg.cosmo.node.v1.TypeFieldMapping + (*FieldMapping)(nil), // 54: wg.cosmo.node.v1.FieldMapping + (*ArgumentMapping)(nil), // 55: wg.cosmo.node.v1.ArgumentMapping + (*EnumMapping)(nil), // 56: wg.cosmo.node.v1.EnumMapping + (*EnumValueMapping)(nil), // 57: wg.cosmo.node.v1.EnumValueMapping + (*NatsStreamConfiguration)(nil), // 58: wg.cosmo.node.v1.NatsStreamConfiguration + (*NatsEventConfiguration)(nil), // 59: wg.cosmo.node.v1.NatsEventConfiguration + (*KafkaEventConfiguration)(nil), // 60: wg.cosmo.node.v1.KafkaEventConfiguration + (*RedisEventConfiguration)(nil), // 61: wg.cosmo.node.v1.RedisEventConfiguration + (*EngineEventConfiguration)(nil), // 62: wg.cosmo.node.v1.EngineEventConfiguration + (*DataSourceCustomEvents)(nil), // 63: wg.cosmo.node.v1.DataSourceCustomEvents + (*DataSourceCustom_Static)(nil), // 64: wg.cosmo.node.v1.DataSourceCustom_Static + (*ConfigurationVariable)(nil), // 65: wg.cosmo.node.v1.ConfigurationVariable + (*DirectiveConfiguration)(nil), // 66: wg.cosmo.node.v1.DirectiveConfiguration + (*URLQueryConfiguration)(nil), // 67: wg.cosmo.node.v1.URLQueryConfiguration + (*HTTPHeader)(nil), // 68: wg.cosmo.node.v1.HTTPHeader + (*MTLSConfiguration)(nil), // 69: wg.cosmo.node.v1.MTLSConfiguration + (*GraphQLSubscriptionConfiguration)(nil), // 70: wg.cosmo.node.v1.GraphQLSubscriptionConfiguration + (*GraphQLFederationConfiguration)(nil), // 71: wg.cosmo.node.v1.GraphQLFederationConfiguration + (*InternedString)(nil), // 72: wg.cosmo.node.v1.InternedString + (*SingleTypeField)(nil), // 73: wg.cosmo.node.v1.SingleTypeField + (*SubscriptionFieldCondition)(nil), // 74: wg.cosmo.node.v1.SubscriptionFieldCondition + (*SubscriptionFilterCondition)(nil), // 75: wg.cosmo.node.v1.SubscriptionFilterCondition + (*CacheWarmerOperations)(nil), // 76: wg.cosmo.node.v1.CacheWarmerOperations + (*Operation)(nil), // 77: wg.cosmo.node.v1.Operation + (*OperationRequest)(nil), // 78: wg.cosmo.node.v1.OperationRequest + (*Extension)(nil), // 79: wg.cosmo.node.v1.Extension + (*PersistedQuery)(nil), // 80: wg.cosmo.node.v1.PersistedQuery + (*ClientInfo)(nil), // 81: wg.cosmo.node.v1.ClientInfo + nil, // 82: wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs.ConfigByFeatureFlagNameEntry + nil, // 83: wg.cosmo.node.v1.EngineConfiguration.StringStorageEntry + nil, // 84: wg.cosmo.node.v1.CostConfiguration.TypeWeightsEntry + nil, // 85: wg.cosmo.node.v1.CostConfiguration.DirectiveArgumentWeightsEntry + nil, // 86: wg.cosmo.node.v1.FieldWeightConfiguration.ArgumentWeightsEntry + nil, // 87: wg.cosmo.node.v1.FieldWeightConfiguration.DirectiveArgumentWeightsEntry + nil, // 88: wg.cosmo.node.v1.FetchConfiguration.HeaderEntry + (common.EnumStatusCode)(0), // 89: wg.cosmo.common.EnumStatusCode + (common.GraphQLSubscriptionProtocol)(0), // 90: wg.cosmo.common.GraphQLSubscriptionProtocol + (common.GraphQLWebsocketSubprotocol)(0), // 91: wg.cosmo.common.GraphQLWebsocketSubprotocol } var file_wg_cosmo_node_v1_node_proto_depIdxs = []int32{ - 75, // 0: wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs.config_by_feature_flag_name:type_name -> wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs.ConfigByFeatureFlagNameEntry + 82, // 0: wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs.config_by_feature_flag_name:type_name -> wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs.ConfigByFeatureFlagNameEntry 18, // 1: wg.cosmo.node.v1.FeatureFlagRouterExecutionConfig.engine_config:type_name -> wg.cosmo.node.v1.EngineConfiguration 8, // 2: wg.cosmo.node.v1.FeatureFlagRouterExecutionConfig.subgraphs:type_name -> wg.cosmo.node.v1.Subgraph 18, // 3: wg.cosmo.node.v1.RouterConfig.engine_config:type_name -> wg.cosmo.node.v1.EngineConfiguration 8, // 4: wg.cosmo.node.v1.RouterConfig.subgraphs:type_name -> wg.cosmo.node.v1.Subgraph 9, // 5: wg.cosmo.node.v1.RouterConfig.feature_flag_configs:type_name -> wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs - 82, // 6: wg.cosmo.node.v1.Response.code:type_name -> wg.cosmo.common.EnumStatusCode + 89, // 6: wg.cosmo.node.v1.Response.code:type_name -> wg.cosmo.common.EnumStatusCode 15, // 7: wg.cosmo.node.v1.RegistrationInfo.account_limits:type_name -> wg.cosmo.node.v1.AccountLimits 12, // 8: wg.cosmo.node.v1.SelfRegisterResponse.response:type_name -> wg.cosmo.node.v1.Response 14, // 9: wg.cosmo.node.v1.SelfRegisterResponse.registrationInfo:type_name -> wg.cosmo.node.v1.RegistrationInfo 19, // 10: wg.cosmo.node.v1.EngineConfiguration.datasource_configurations:type_name -> wg.cosmo.node.v1.DataSourceConfiguration - 26, // 11: wg.cosmo.node.v1.EngineConfiguration.field_configurations:type_name -> wg.cosmo.node.v1.FieldConfiguration - 27, // 12: wg.cosmo.node.v1.EngineConfiguration.type_configurations:type_name -> wg.cosmo.node.v1.TypeConfiguration - 76, // 13: wg.cosmo.node.v1.EngineConfiguration.string_storage:type_name -> wg.cosmo.node.v1.EngineConfiguration.StringStorageEntry + 33, // 11: wg.cosmo.node.v1.EngineConfiguration.field_configurations:type_name -> wg.cosmo.node.v1.FieldConfiguration + 34, // 12: wg.cosmo.node.v1.EngineConfiguration.type_configurations:type_name -> wg.cosmo.node.v1.TypeConfiguration + 83, // 13: wg.cosmo.node.v1.EngineConfiguration.string_storage:type_name -> wg.cosmo.node.v1.EngineConfiguration.StringStorageEntry 2, // 14: wg.cosmo.node.v1.DataSourceConfiguration.kind:type_name -> wg.cosmo.node.v1.DataSourceKind - 28, // 15: wg.cosmo.node.v1.DataSourceConfiguration.root_nodes:type_name -> wg.cosmo.node.v1.TypeField - 28, // 16: wg.cosmo.node.v1.DataSourceConfiguration.child_nodes:type_name -> wg.cosmo.node.v1.TypeField - 35, // 17: wg.cosmo.node.v1.DataSourceConfiguration.custom_graphql:type_name -> wg.cosmo.node.v1.DataSourceCustom_GraphQL - 57, // 18: wg.cosmo.node.v1.DataSourceConfiguration.custom_static:type_name -> wg.cosmo.node.v1.DataSourceCustom_Static - 59, // 19: wg.cosmo.node.v1.DataSourceConfiguration.directives:type_name -> wg.cosmo.node.v1.DirectiveConfiguration - 31, // 20: wg.cosmo.node.v1.DataSourceConfiguration.keys:type_name -> wg.cosmo.node.v1.RequiredField - 31, // 21: wg.cosmo.node.v1.DataSourceConfiguration.provides:type_name -> wg.cosmo.node.v1.RequiredField - 31, // 22: wg.cosmo.node.v1.DataSourceConfiguration.requires:type_name -> wg.cosmo.node.v1.RequiredField - 56, // 23: wg.cosmo.node.v1.DataSourceConfiguration.custom_events:type_name -> wg.cosmo.node.v1.DataSourceCustomEvents - 32, // 24: wg.cosmo.node.v1.DataSourceConfiguration.entity_interfaces:type_name -> wg.cosmo.node.v1.EntityInterfaceConfiguration - 32, // 25: wg.cosmo.node.v1.DataSourceConfiguration.interface_objects:type_name -> wg.cosmo.node.v1.EntityInterfaceConfiguration - 20, // 26: wg.cosmo.node.v1.DataSourceConfiguration.cost_configuration:type_name -> wg.cosmo.node.v1.CostConfiguration - 21, // 27: wg.cosmo.node.v1.CostConfiguration.field_weights:type_name -> wg.cosmo.node.v1.FieldWeightConfiguration - 22, // 28: wg.cosmo.node.v1.CostConfiguration.list_sizes:type_name -> wg.cosmo.node.v1.FieldListSizeConfiguration - 77, // 29: wg.cosmo.node.v1.CostConfiguration.type_weights:type_name -> wg.cosmo.node.v1.CostConfiguration.TypeWeightsEntry - 78, // 30: wg.cosmo.node.v1.CostConfiguration.directive_argument_weights:type_name -> wg.cosmo.node.v1.CostConfiguration.DirectiveArgumentWeightsEntry - 79, // 31: wg.cosmo.node.v1.FieldWeightConfiguration.argument_weights:type_name -> wg.cosmo.node.v1.FieldWeightConfiguration.ArgumentWeightsEntry - 80, // 32: wg.cosmo.node.v1.FieldWeightConfiguration.directive_argument_weights:type_name -> wg.cosmo.node.v1.FieldWeightConfiguration.DirectiveArgumentWeightsEntry - 1, // 33: wg.cosmo.node.v1.ArgumentConfiguration.source_type:type_name -> wg.cosmo.node.v1.ArgumentSource - 24, // 34: wg.cosmo.node.v1.AuthorizationConfiguration.required_or_scopes:type_name -> wg.cosmo.node.v1.Scopes - 24, // 35: wg.cosmo.node.v1.AuthorizationConfiguration.required_or_scopes_by_or:type_name -> wg.cosmo.node.v1.Scopes - 23, // 36: wg.cosmo.node.v1.FieldConfiguration.arguments_configuration:type_name -> wg.cosmo.node.v1.ArgumentConfiguration - 25, // 37: wg.cosmo.node.v1.FieldConfiguration.authorization_configuration:type_name -> wg.cosmo.node.v1.AuthorizationConfiguration - 68, // 38: wg.cosmo.node.v1.FieldConfiguration.subscription_filter_condition:type_name -> wg.cosmo.node.v1.SubscriptionFilterCondition - 29, // 39: wg.cosmo.node.v1.FieldSetCondition.field_coordinates_path:type_name -> wg.cosmo.node.v1.FieldCoordinates - 30, // 40: wg.cosmo.node.v1.RequiredField.conditions:type_name -> wg.cosmo.node.v1.FieldSetCondition - 58, // 41: wg.cosmo.node.v1.FetchConfiguration.url:type_name -> wg.cosmo.node.v1.ConfigurationVariable - 7, // 42: wg.cosmo.node.v1.FetchConfiguration.method:type_name -> wg.cosmo.node.v1.HTTPMethod - 81, // 43: wg.cosmo.node.v1.FetchConfiguration.header:type_name -> wg.cosmo.node.v1.FetchConfiguration.HeaderEntry - 58, // 44: wg.cosmo.node.v1.FetchConfiguration.body:type_name -> wg.cosmo.node.v1.ConfigurationVariable - 60, // 45: wg.cosmo.node.v1.FetchConfiguration.query:type_name -> wg.cosmo.node.v1.URLQueryConfiguration - 62, // 46: wg.cosmo.node.v1.FetchConfiguration.mtls:type_name -> wg.cosmo.node.v1.MTLSConfiguration - 58, // 47: wg.cosmo.node.v1.FetchConfiguration.base_url:type_name -> wg.cosmo.node.v1.ConfigurationVariable - 58, // 48: wg.cosmo.node.v1.FetchConfiguration.path:type_name -> wg.cosmo.node.v1.ConfigurationVariable - 58, // 49: wg.cosmo.node.v1.FetchConfiguration.http_proxy_url:type_name -> wg.cosmo.node.v1.ConfigurationVariable - 33, // 50: wg.cosmo.node.v1.DataSourceCustom_GraphQL.fetch:type_name -> wg.cosmo.node.v1.FetchConfiguration - 63, // 51: wg.cosmo.node.v1.DataSourceCustom_GraphQL.subscription:type_name -> wg.cosmo.node.v1.GraphQLSubscriptionConfiguration - 64, // 52: wg.cosmo.node.v1.DataSourceCustom_GraphQL.federation:type_name -> wg.cosmo.node.v1.GraphQLFederationConfiguration - 65, // 53: wg.cosmo.node.v1.DataSourceCustom_GraphQL.upstream_schema:type_name -> wg.cosmo.node.v1.InternedString - 66, // 54: wg.cosmo.node.v1.DataSourceCustom_GraphQL.custom_scalar_type_fields:type_name -> wg.cosmo.node.v1.SingleTypeField - 36, // 55: wg.cosmo.node.v1.DataSourceCustom_GraphQL.grpc:type_name -> wg.cosmo.node.v1.GRPCConfiguration - 40, // 56: wg.cosmo.node.v1.GRPCConfiguration.mapping:type_name -> wg.cosmo.node.v1.GRPCMapping - 38, // 57: wg.cosmo.node.v1.GRPCConfiguration.plugin:type_name -> wg.cosmo.node.v1.PluginConfiguration - 37, // 58: wg.cosmo.node.v1.PluginConfiguration.image_reference:type_name -> wg.cosmo.node.v1.ImageReference - 43, // 59: wg.cosmo.node.v1.GRPCMapping.operation_mappings:type_name -> wg.cosmo.node.v1.OperationMapping - 44, // 60: wg.cosmo.node.v1.GRPCMapping.entity_mappings:type_name -> wg.cosmo.node.v1.EntityMapping - 46, // 61: wg.cosmo.node.v1.GRPCMapping.type_field_mappings:type_name -> wg.cosmo.node.v1.TypeFieldMapping - 49, // 62: wg.cosmo.node.v1.GRPCMapping.enum_mappings:type_name -> wg.cosmo.node.v1.EnumMapping - 41, // 63: wg.cosmo.node.v1.GRPCMapping.resolve_mappings:type_name -> wg.cosmo.node.v1.LookupMapping - 3, // 64: wg.cosmo.node.v1.LookupMapping.type:type_name -> wg.cosmo.node.v1.LookupType - 42, // 65: wg.cosmo.node.v1.LookupMapping.lookup_mapping:type_name -> wg.cosmo.node.v1.LookupFieldMapping - 47, // 66: wg.cosmo.node.v1.LookupFieldMapping.field_mapping:type_name -> wg.cosmo.node.v1.FieldMapping - 4, // 67: wg.cosmo.node.v1.OperationMapping.type:type_name -> wg.cosmo.node.v1.OperationType - 45, // 68: wg.cosmo.node.v1.EntityMapping.required_field_mappings:type_name -> wg.cosmo.node.v1.RequiredFieldMapping - 47, // 69: wg.cosmo.node.v1.RequiredFieldMapping.field_mapping:type_name -> wg.cosmo.node.v1.FieldMapping - 47, // 70: wg.cosmo.node.v1.TypeFieldMapping.field_mappings:type_name -> wg.cosmo.node.v1.FieldMapping - 48, // 71: wg.cosmo.node.v1.FieldMapping.argument_mappings:type_name -> wg.cosmo.node.v1.ArgumentMapping - 50, // 72: wg.cosmo.node.v1.EnumMapping.values:type_name -> wg.cosmo.node.v1.EnumValueMapping - 55, // 73: wg.cosmo.node.v1.NatsEventConfiguration.engine_event_configuration:type_name -> wg.cosmo.node.v1.EngineEventConfiguration - 51, // 74: wg.cosmo.node.v1.NatsEventConfiguration.stream_configuration:type_name -> wg.cosmo.node.v1.NatsStreamConfiguration - 55, // 75: wg.cosmo.node.v1.KafkaEventConfiguration.engine_event_configuration:type_name -> wg.cosmo.node.v1.EngineEventConfiguration - 55, // 76: wg.cosmo.node.v1.RedisEventConfiguration.engine_event_configuration:type_name -> wg.cosmo.node.v1.EngineEventConfiguration - 5, // 77: wg.cosmo.node.v1.EngineEventConfiguration.type:type_name -> wg.cosmo.node.v1.EventType - 52, // 78: wg.cosmo.node.v1.DataSourceCustomEvents.nats:type_name -> wg.cosmo.node.v1.NatsEventConfiguration - 53, // 79: wg.cosmo.node.v1.DataSourceCustomEvents.kafka:type_name -> wg.cosmo.node.v1.KafkaEventConfiguration - 54, // 80: wg.cosmo.node.v1.DataSourceCustomEvents.redis:type_name -> wg.cosmo.node.v1.RedisEventConfiguration - 58, // 81: wg.cosmo.node.v1.DataSourceCustom_Static.data:type_name -> wg.cosmo.node.v1.ConfigurationVariable - 6, // 82: wg.cosmo.node.v1.ConfigurationVariable.kind:type_name -> wg.cosmo.node.v1.ConfigurationVariableKind - 58, // 83: wg.cosmo.node.v1.HTTPHeader.values:type_name -> wg.cosmo.node.v1.ConfigurationVariable - 58, // 84: wg.cosmo.node.v1.MTLSConfiguration.key:type_name -> wg.cosmo.node.v1.ConfigurationVariable - 58, // 85: wg.cosmo.node.v1.MTLSConfiguration.cert:type_name -> wg.cosmo.node.v1.ConfigurationVariable - 58, // 86: wg.cosmo.node.v1.GraphQLSubscriptionConfiguration.url:type_name -> wg.cosmo.node.v1.ConfigurationVariable - 83, // 87: wg.cosmo.node.v1.GraphQLSubscriptionConfiguration.protocol:type_name -> wg.cosmo.common.GraphQLSubscriptionProtocol - 84, // 88: wg.cosmo.node.v1.GraphQLSubscriptionConfiguration.websocketSubprotocol:type_name -> wg.cosmo.common.GraphQLWebsocketSubprotocol - 68, // 89: wg.cosmo.node.v1.SubscriptionFilterCondition.and:type_name -> wg.cosmo.node.v1.SubscriptionFilterCondition - 67, // 90: wg.cosmo.node.v1.SubscriptionFilterCondition.in:type_name -> wg.cosmo.node.v1.SubscriptionFieldCondition - 68, // 91: wg.cosmo.node.v1.SubscriptionFilterCondition.not:type_name -> wg.cosmo.node.v1.SubscriptionFilterCondition - 68, // 92: wg.cosmo.node.v1.SubscriptionFilterCondition.or:type_name -> wg.cosmo.node.v1.SubscriptionFilterCondition - 70, // 93: wg.cosmo.node.v1.CacheWarmerOperations.operations:type_name -> wg.cosmo.node.v1.Operation - 71, // 94: wg.cosmo.node.v1.Operation.request:type_name -> wg.cosmo.node.v1.OperationRequest - 74, // 95: wg.cosmo.node.v1.Operation.client:type_name -> wg.cosmo.node.v1.ClientInfo - 72, // 96: wg.cosmo.node.v1.OperationRequest.extensions:type_name -> wg.cosmo.node.v1.Extension - 73, // 97: wg.cosmo.node.v1.Extension.persisted_query:type_name -> wg.cosmo.node.v1.PersistedQuery - 10, // 98: wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs.ConfigByFeatureFlagNameEntry.value:type_name -> wg.cosmo.node.v1.FeatureFlagRouterExecutionConfig - 61, // 99: wg.cosmo.node.v1.FetchConfiguration.HeaderEntry.value:type_name -> wg.cosmo.node.v1.HTTPHeader - 16, // 100: wg.cosmo.node.v1.NodeService.SelfRegister:input_type -> wg.cosmo.node.v1.SelfRegisterRequest - 17, // 101: wg.cosmo.node.v1.NodeService.SelfRegister:output_type -> wg.cosmo.node.v1.SelfRegisterResponse - 101, // [101:102] is the sub-list for method output_type - 100, // [100:101] is the sub-list for method input_type - 100, // [100:100] is the sub-list for extension type_name - 100, // [100:100] is the sub-list for extension extendee - 0, // [0:100] is the sub-list for field type_name + 35, // 15: wg.cosmo.node.v1.DataSourceConfiguration.root_nodes:type_name -> wg.cosmo.node.v1.TypeField + 35, // 16: wg.cosmo.node.v1.DataSourceConfiguration.child_nodes:type_name -> wg.cosmo.node.v1.TypeField + 42, // 17: wg.cosmo.node.v1.DataSourceConfiguration.custom_graphql:type_name -> wg.cosmo.node.v1.DataSourceCustom_GraphQL + 64, // 18: wg.cosmo.node.v1.DataSourceConfiguration.custom_static:type_name -> wg.cosmo.node.v1.DataSourceCustom_Static + 66, // 19: wg.cosmo.node.v1.DataSourceConfiguration.directives:type_name -> wg.cosmo.node.v1.DirectiveConfiguration + 38, // 20: wg.cosmo.node.v1.DataSourceConfiguration.keys:type_name -> wg.cosmo.node.v1.RequiredField + 38, // 21: wg.cosmo.node.v1.DataSourceConfiguration.provides:type_name -> wg.cosmo.node.v1.RequiredField + 38, // 22: wg.cosmo.node.v1.DataSourceConfiguration.requires:type_name -> wg.cosmo.node.v1.RequiredField + 63, // 23: wg.cosmo.node.v1.DataSourceConfiguration.custom_events:type_name -> wg.cosmo.node.v1.DataSourceCustomEvents + 39, // 24: wg.cosmo.node.v1.DataSourceConfiguration.entity_interfaces:type_name -> wg.cosmo.node.v1.EntityInterfaceConfiguration + 39, // 25: wg.cosmo.node.v1.DataSourceConfiguration.interface_objects:type_name -> wg.cosmo.node.v1.EntityInterfaceConfiguration + 27, // 26: wg.cosmo.node.v1.DataSourceConfiguration.cost_configuration:type_name -> wg.cosmo.node.v1.CostConfiguration + 21, // 27: wg.cosmo.node.v1.DataSourceConfiguration.entity_cache_configurations:type_name -> wg.cosmo.node.v1.EntityCacheConfiguration + 22, // 28: wg.cosmo.node.v1.DataSourceConfiguration.root_field_cache_configurations:type_name -> wg.cosmo.node.v1.RootFieldCacheConfiguration + 25, // 29: wg.cosmo.node.v1.DataSourceConfiguration.cache_populate_configurations:type_name -> wg.cosmo.node.v1.CachePopulateConfiguration + 26, // 30: wg.cosmo.node.v1.DataSourceConfiguration.cache_invalidate_configurations:type_name -> wg.cosmo.node.v1.CacheInvalidateConfiguration + 20, // 31: wg.cosmo.node.v1.DataSourceConfiguration.request_scoped_fields:type_name -> wg.cosmo.node.v1.RequestScopedFieldConfiguration + 23, // 32: wg.cosmo.node.v1.RootFieldCacheConfiguration.entity_key_mappings:type_name -> wg.cosmo.node.v1.EntityKeyMapping + 24, // 33: wg.cosmo.node.v1.EntityKeyMapping.field_mappings:type_name -> wg.cosmo.node.v1.EntityCacheFieldMapping + 28, // 34: wg.cosmo.node.v1.CostConfiguration.field_weights:type_name -> wg.cosmo.node.v1.FieldWeightConfiguration + 29, // 35: wg.cosmo.node.v1.CostConfiguration.list_sizes:type_name -> wg.cosmo.node.v1.FieldListSizeConfiguration + 84, // 36: wg.cosmo.node.v1.CostConfiguration.type_weights:type_name -> wg.cosmo.node.v1.CostConfiguration.TypeWeightsEntry + 85, // 37: wg.cosmo.node.v1.CostConfiguration.directive_argument_weights:type_name -> wg.cosmo.node.v1.CostConfiguration.DirectiveArgumentWeightsEntry + 86, // 38: wg.cosmo.node.v1.FieldWeightConfiguration.argument_weights:type_name -> wg.cosmo.node.v1.FieldWeightConfiguration.ArgumentWeightsEntry + 87, // 39: wg.cosmo.node.v1.FieldWeightConfiguration.directive_argument_weights:type_name -> wg.cosmo.node.v1.FieldWeightConfiguration.DirectiveArgumentWeightsEntry + 1, // 40: wg.cosmo.node.v1.ArgumentConfiguration.source_type:type_name -> wg.cosmo.node.v1.ArgumentSource + 31, // 41: wg.cosmo.node.v1.AuthorizationConfiguration.required_or_scopes:type_name -> wg.cosmo.node.v1.Scopes + 31, // 42: wg.cosmo.node.v1.AuthorizationConfiguration.required_or_scopes_by_or:type_name -> wg.cosmo.node.v1.Scopes + 30, // 43: wg.cosmo.node.v1.FieldConfiguration.arguments_configuration:type_name -> wg.cosmo.node.v1.ArgumentConfiguration + 32, // 44: wg.cosmo.node.v1.FieldConfiguration.authorization_configuration:type_name -> wg.cosmo.node.v1.AuthorizationConfiguration + 75, // 45: wg.cosmo.node.v1.FieldConfiguration.subscription_filter_condition:type_name -> wg.cosmo.node.v1.SubscriptionFilterCondition + 36, // 46: wg.cosmo.node.v1.FieldSetCondition.field_coordinates_path:type_name -> wg.cosmo.node.v1.FieldCoordinates + 37, // 47: wg.cosmo.node.v1.RequiredField.conditions:type_name -> wg.cosmo.node.v1.FieldSetCondition + 65, // 48: wg.cosmo.node.v1.FetchConfiguration.url:type_name -> wg.cosmo.node.v1.ConfigurationVariable + 7, // 49: wg.cosmo.node.v1.FetchConfiguration.method:type_name -> wg.cosmo.node.v1.HTTPMethod + 88, // 50: wg.cosmo.node.v1.FetchConfiguration.header:type_name -> wg.cosmo.node.v1.FetchConfiguration.HeaderEntry + 65, // 51: wg.cosmo.node.v1.FetchConfiguration.body:type_name -> wg.cosmo.node.v1.ConfigurationVariable + 67, // 52: wg.cosmo.node.v1.FetchConfiguration.query:type_name -> wg.cosmo.node.v1.URLQueryConfiguration + 69, // 53: wg.cosmo.node.v1.FetchConfiguration.mtls:type_name -> wg.cosmo.node.v1.MTLSConfiguration + 65, // 54: wg.cosmo.node.v1.FetchConfiguration.base_url:type_name -> wg.cosmo.node.v1.ConfigurationVariable + 65, // 55: wg.cosmo.node.v1.FetchConfiguration.path:type_name -> wg.cosmo.node.v1.ConfigurationVariable + 65, // 56: wg.cosmo.node.v1.FetchConfiguration.http_proxy_url:type_name -> wg.cosmo.node.v1.ConfigurationVariable + 40, // 57: wg.cosmo.node.v1.DataSourceCustom_GraphQL.fetch:type_name -> wg.cosmo.node.v1.FetchConfiguration + 70, // 58: wg.cosmo.node.v1.DataSourceCustom_GraphQL.subscription:type_name -> wg.cosmo.node.v1.GraphQLSubscriptionConfiguration + 71, // 59: wg.cosmo.node.v1.DataSourceCustom_GraphQL.federation:type_name -> wg.cosmo.node.v1.GraphQLFederationConfiguration + 72, // 60: wg.cosmo.node.v1.DataSourceCustom_GraphQL.upstream_schema:type_name -> wg.cosmo.node.v1.InternedString + 73, // 61: wg.cosmo.node.v1.DataSourceCustom_GraphQL.custom_scalar_type_fields:type_name -> wg.cosmo.node.v1.SingleTypeField + 43, // 62: wg.cosmo.node.v1.DataSourceCustom_GraphQL.grpc:type_name -> wg.cosmo.node.v1.GRPCConfiguration + 47, // 63: wg.cosmo.node.v1.GRPCConfiguration.mapping:type_name -> wg.cosmo.node.v1.GRPCMapping + 45, // 64: wg.cosmo.node.v1.GRPCConfiguration.plugin:type_name -> wg.cosmo.node.v1.PluginConfiguration + 44, // 65: wg.cosmo.node.v1.PluginConfiguration.image_reference:type_name -> wg.cosmo.node.v1.ImageReference + 50, // 66: wg.cosmo.node.v1.GRPCMapping.operation_mappings:type_name -> wg.cosmo.node.v1.OperationMapping + 51, // 67: wg.cosmo.node.v1.GRPCMapping.entity_mappings:type_name -> wg.cosmo.node.v1.EntityMapping + 53, // 68: wg.cosmo.node.v1.GRPCMapping.type_field_mappings:type_name -> wg.cosmo.node.v1.TypeFieldMapping + 56, // 69: wg.cosmo.node.v1.GRPCMapping.enum_mappings:type_name -> wg.cosmo.node.v1.EnumMapping + 48, // 70: wg.cosmo.node.v1.GRPCMapping.resolve_mappings:type_name -> wg.cosmo.node.v1.LookupMapping + 3, // 71: wg.cosmo.node.v1.LookupMapping.type:type_name -> wg.cosmo.node.v1.LookupType + 49, // 72: wg.cosmo.node.v1.LookupMapping.lookup_mapping:type_name -> wg.cosmo.node.v1.LookupFieldMapping + 54, // 73: wg.cosmo.node.v1.LookupFieldMapping.field_mapping:type_name -> wg.cosmo.node.v1.FieldMapping + 4, // 74: wg.cosmo.node.v1.OperationMapping.type:type_name -> wg.cosmo.node.v1.OperationType + 52, // 75: wg.cosmo.node.v1.EntityMapping.required_field_mappings:type_name -> wg.cosmo.node.v1.RequiredFieldMapping + 54, // 76: wg.cosmo.node.v1.RequiredFieldMapping.field_mapping:type_name -> wg.cosmo.node.v1.FieldMapping + 54, // 77: wg.cosmo.node.v1.TypeFieldMapping.field_mappings:type_name -> wg.cosmo.node.v1.FieldMapping + 55, // 78: wg.cosmo.node.v1.FieldMapping.argument_mappings:type_name -> wg.cosmo.node.v1.ArgumentMapping + 57, // 79: wg.cosmo.node.v1.EnumMapping.values:type_name -> wg.cosmo.node.v1.EnumValueMapping + 62, // 80: wg.cosmo.node.v1.NatsEventConfiguration.engine_event_configuration:type_name -> wg.cosmo.node.v1.EngineEventConfiguration + 58, // 81: wg.cosmo.node.v1.NatsEventConfiguration.stream_configuration:type_name -> wg.cosmo.node.v1.NatsStreamConfiguration + 62, // 82: wg.cosmo.node.v1.KafkaEventConfiguration.engine_event_configuration:type_name -> wg.cosmo.node.v1.EngineEventConfiguration + 62, // 83: wg.cosmo.node.v1.RedisEventConfiguration.engine_event_configuration:type_name -> wg.cosmo.node.v1.EngineEventConfiguration + 5, // 84: wg.cosmo.node.v1.EngineEventConfiguration.type:type_name -> wg.cosmo.node.v1.EventType + 59, // 85: wg.cosmo.node.v1.DataSourceCustomEvents.nats:type_name -> wg.cosmo.node.v1.NatsEventConfiguration + 60, // 86: wg.cosmo.node.v1.DataSourceCustomEvents.kafka:type_name -> wg.cosmo.node.v1.KafkaEventConfiguration + 61, // 87: wg.cosmo.node.v1.DataSourceCustomEvents.redis:type_name -> wg.cosmo.node.v1.RedisEventConfiguration + 65, // 88: wg.cosmo.node.v1.DataSourceCustom_Static.data:type_name -> wg.cosmo.node.v1.ConfigurationVariable + 6, // 89: wg.cosmo.node.v1.ConfigurationVariable.kind:type_name -> wg.cosmo.node.v1.ConfigurationVariableKind + 65, // 90: wg.cosmo.node.v1.HTTPHeader.values:type_name -> wg.cosmo.node.v1.ConfigurationVariable + 65, // 91: wg.cosmo.node.v1.MTLSConfiguration.key:type_name -> wg.cosmo.node.v1.ConfigurationVariable + 65, // 92: wg.cosmo.node.v1.MTLSConfiguration.cert:type_name -> wg.cosmo.node.v1.ConfigurationVariable + 65, // 93: wg.cosmo.node.v1.GraphQLSubscriptionConfiguration.url:type_name -> wg.cosmo.node.v1.ConfigurationVariable + 90, // 94: wg.cosmo.node.v1.GraphQLSubscriptionConfiguration.protocol:type_name -> wg.cosmo.common.GraphQLSubscriptionProtocol + 91, // 95: wg.cosmo.node.v1.GraphQLSubscriptionConfiguration.websocketSubprotocol:type_name -> wg.cosmo.common.GraphQLWebsocketSubprotocol + 75, // 96: wg.cosmo.node.v1.SubscriptionFilterCondition.and:type_name -> wg.cosmo.node.v1.SubscriptionFilterCondition + 74, // 97: wg.cosmo.node.v1.SubscriptionFilterCondition.in:type_name -> wg.cosmo.node.v1.SubscriptionFieldCondition + 75, // 98: wg.cosmo.node.v1.SubscriptionFilterCondition.not:type_name -> wg.cosmo.node.v1.SubscriptionFilterCondition + 75, // 99: wg.cosmo.node.v1.SubscriptionFilterCondition.or:type_name -> wg.cosmo.node.v1.SubscriptionFilterCondition + 77, // 100: wg.cosmo.node.v1.CacheWarmerOperations.operations:type_name -> wg.cosmo.node.v1.Operation + 78, // 101: wg.cosmo.node.v1.Operation.request:type_name -> wg.cosmo.node.v1.OperationRequest + 81, // 102: wg.cosmo.node.v1.Operation.client:type_name -> wg.cosmo.node.v1.ClientInfo + 79, // 103: wg.cosmo.node.v1.OperationRequest.extensions:type_name -> wg.cosmo.node.v1.Extension + 80, // 104: wg.cosmo.node.v1.Extension.persisted_query:type_name -> wg.cosmo.node.v1.PersistedQuery + 10, // 105: wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs.ConfigByFeatureFlagNameEntry.value:type_name -> wg.cosmo.node.v1.FeatureFlagRouterExecutionConfig + 68, // 106: wg.cosmo.node.v1.FetchConfiguration.HeaderEntry.value:type_name -> wg.cosmo.node.v1.HTTPHeader + 16, // 107: wg.cosmo.node.v1.NodeService.SelfRegister:input_type -> wg.cosmo.node.v1.SelfRegisterRequest + 17, // 108: wg.cosmo.node.v1.NodeService.SelfRegister:output_type -> wg.cosmo.node.v1.SelfRegisterResponse + 108, // [108:109] is the sub-list for method output_type + 107, // [107:108] is the sub-list for method input_type + 107, // [107:107] is the sub-list for extension type_name + 107, // [107:107] is the sub-list for extension extendee + 0, // [0:107] is the sub-list for field type_name } func init() { file_wg_cosmo_node_v1_node_proto_init() } @@ -5237,20 +5823,21 @@ func file_wg_cosmo_node_v1_node_proto_init() { file_wg_cosmo_node_v1_node_proto_msgTypes[4].OneofWrappers = []any{} file_wg_cosmo_node_v1_node_proto_msgTypes[9].OneofWrappers = []any{} file_wg_cosmo_node_v1_node_proto_msgTypes[10].OneofWrappers = []any{} - file_wg_cosmo_node_v1_node_proto_msgTypes[13].OneofWrappers = []any{} - file_wg_cosmo_node_v1_node_proto_msgTypes[14].OneofWrappers = []any{} - file_wg_cosmo_node_v1_node_proto_msgTypes[18].OneofWrappers = []any{} + file_wg_cosmo_node_v1_node_proto_msgTypes[17].OneofWrappers = []any{} + file_wg_cosmo_node_v1_node_proto_msgTypes[20].OneofWrappers = []any{} + file_wg_cosmo_node_v1_node_proto_msgTypes[21].OneofWrappers = []any{} file_wg_cosmo_node_v1_node_proto_msgTypes[25].OneofWrappers = []any{} - file_wg_cosmo_node_v1_node_proto_msgTypes[30].OneofWrappers = []any{} - file_wg_cosmo_node_v1_node_proto_msgTypes[55].OneofWrappers = []any{} - file_wg_cosmo_node_v1_node_proto_msgTypes[60].OneofWrappers = []any{} + file_wg_cosmo_node_v1_node_proto_msgTypes[32].OneofWrappers = []any{} + file_wg_cosmo_node_v1_node_proto_msgTypes[37].OneofWrappers = []any{} + file_wg_cosmo_node_v1_node_proto_msgTypes[62].OneofWrappers = []any{} + file_wg_cosmo_node_v1_node_proto_msgTypes[67].OneofWrappers = []any{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_wg_cosmo_node_v1_node_proto_rawDesc), len(file_wg_cosmo_node_v1_node_proto_rawDesc)), NumEnums: 8, - NumMessages: 74, + NumMessages: 81, NumExtensions: 0, NumServices: 1, }, diff --git a/connect/src/wg/cosmo/node/v1/node_pb.ts b/connect/src/wg/cosmo/node/v1/node_pb.ts index b50794f361..d0c93abdba 100644 --- a/connect/src/wg/cosmo/node/v1/node_pb.ts +++ b/connect/src/wg/cosmo/node/v1/node_pb.ts @@ -843,6 +843,35 @@ export class DataSourceConfiguration extends Message { */ costConfiguration?: CostConfiguration; + /** + * Entity caching configurations (from composition directives) + * + * @generated from field: repeated wg.cosmo.node.v1.EntityCacheConfiguration entity_cache_configurations = 17; + */ + entityCacheConfigurations: EntityCacheConfiguration[] = []; + + /** + * @generated from field: repeated wg.cosmo.node.v1.RootFieldCacheConfiguration root_field_cache_configurations = 18; + */ + rootFieldCacheConfigurations: RootFieldCacheConfiguration[] = []; + + /** + * @generated from field: repeated wg.cosmo.node.v1.CachePopulateConfiguration cache_populate_configurations = 19; + */ + cachePopulateConfigurations: CachePopulateConfiguration[] = []; + + /** + * @generated from field: repeated wg.cosmo.node.v1.CacheInvalidateConfiguration cache_invalidate_configurations = 20; + */ + cacheInvalidateConfigurations: CacheInvalidateConfiguration[] = []; + + /** + * Request-scoped field configurations (from @openfed__requestScoped directive) + * + * @generated from field: repeated wg.cosmo.node.v1.RequestScopedFieldConfiguration request_scoped_fields = 21; + */ + requestScopedFields: RequestScopedFieldConfiguration[] = []; + constructor(data?: PartialMessage) { super(); proto3.util.initPartial(data, this); @@ -867,6 +896,11 @@ export class DataSourceConfiguration extends Message { { no: 14, name: "entity_interfaces", kind: "message", T: EntityInterfaceConfiguration, repeated: true }, { no: 15, name: "interface_objects", kind: "message", T: EntityInterfaceConfiguration, repeated: true }, { no: 16, name: "cost_configuration", kind: "message", T: CostConfiguration }, + { no: 17, name: "entity_cache_configurations", kind: "message", T: EntityCacheConfiguration, repeated: true }, + { no: 18, name: "root_field_cache_configurations", kind: "message", T: RootFieldCacheConfiguration, repeated: true }, + { no: 19, name: "cache_populate_configurations", kind: "message", T: CachePopulateConfiguration, repeated: true }, + { no: 20, name: "cache_invalidate_configurations", kind: "message", T: CacheInvalidateConfiguration, repeated: true }, + { no: 21, name: "request_scoped_fields", kind: "message", T: RequestScopedFieldConfiguration, repeated: true }, ]); static fromBinary(bytes: Uint8Array, options?: Partial): DataSourceConfiguration { @@ -886,6 +920,406 @@ export class DataSourceConfiguration extends Message { } } +/** + * Per-field declaration for @openfed__requestScoped. All fields in the same subgraph declaring + * @openfed__requestScoped(key: "X") share L1 key "{subgraphName}.X". The first field to resolve + * populates L1; subsequent fields with the same key inject from L1 and can skip their + * fetch when all required sub-fields are present. + * + * @generated from message wg.cosmo.node.v1.RequestScopedFieldConfiguration + */ +export class RequestScopedFieldConfiguration extends Message { + /** + * @generated from field: string field_name = 1; + */ + fieldName = ""; + + /** + * @generated from field: string type_name = 2; + */ + typeName = ""; + + /** + * @generated from field: string l1_key = 3; + */ + l1Key = ""; + + constructor(data?: PartialMessage) { + super(); + proto3.util.initPartial(data, this); + } + + static readonly runtime: typeof proto3 = proto3; + static readonly typeName = "wg.cosmo.node.v1.RequestScopedFieldConfiguration"; + static readonly fields: FieldList = proto3.util.newFieldList(() => [ + { no: 1, name: "field_name", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + { no: 2, name: "type_name", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + { no: 3, name: "l1_key", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + ]); + + static fromBinary(bytes: Uint8Array, options?: Partial): RequestScopedFieldConfiguration { + return new RequestScopedFieldConfiguration().fromBinary(bytes, options); + } + + static fromJson(jsonValue: JsonValue, options?: Partial): RequestScopedFieldConfiguration { + return new RequestScopedFieldConfiguration().fromJson(jsonValue, options); + } + + static fromJsonString(jsonString: string, options?: Partial): RequestScopedFieldConfiguration { + return new RequestScopedFieldConfiguration().fromJsonString(jsonString, options); + } + + static equals(a: RequestScopedFieldConfiguration | PlainMessage | undefined, b: RequestScopedFieldConfiguration | PlainMessage | undefined): boolean { + return proto3.util.equals(RequestScopedFieldConfiguration, a, b); + } +} + +/** + * @generated from message wg.cosmo.node.v1.EntityCacheConfiguration + */ +export class EntityCacheConfiguration extends Message { + /** + * @generated from field: string type_name = 1; + */ + typeName = ""; + + /** + * TTL for cached entity values. Required: composition rejects values <= 0, + * so omit (zero) does not occur in practice. Interpreted in seconds. + * + * @generated from field: int64 max_age_seconds = 2; + */ + maxAgeSeconds = protoInt64.zero; + + /** + * @generated from field: bool include_headers = 3; + */ + includeHeaders = false; + + /** + * @generated from field: bool partial_cache_load = 4; + */ + partialCacheLoad = false; + + /** + * @generated from field: bool shadow_mode = 5; + */ + shadowMode = false; + + /** + * TTL for caching "not found" entity responses (entity returned null from + * _entities without errors). Omit or 0 disables negative caching and null + * responses are not cached. Positive values are seconds. Composition rejects + * negative values at schema validation time. + * + * @generated from field: int64 not_found_cache_ttl_seconds = 6; + */ + notFoundCacheTtlSeconds = protoInt64.zero; + + constructor(data?: PartialMessage) { + super(); + proto3.util.initPartial(data, this); + } + + static readonly runtime: typeof proto3 = proto3; + static readonly typeName = "wg.cosmo.node.v1.EntityCacheConfiguration"; + static readonly fields: FieldList = proto3.util.newFieldList(() => [ + { no: 1, name: "type_name", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + { no: 2, name: "max_age_seconds", kind: "scalar", T: 3 /* ScalarType.INT64 */ }, + { no: 3, name: "include_headers", kind: "scalar", T: 8 /* ScalarType.BOOL */ }, + { no: 4, name: "partial_cache_load", kind: "scalar", T: 8 /* ScalarType.BOOL */ }, + { no: 5, name: "shadow_mode", kind: "scalar", T: 8 /* ScalarType.BOOL */ }, + { no: 6, name: "not_found_cache_ttl_seconds", kind: "scalar", T: 3 /* ScalarType.INT64 */ }, + ]); + + static fromBinary(bytes: Uint8Array, options?: Partial): EntityCacheConfiguration { + return new EntityCacheConfiguration().fromBinary(bytes, options); + } + + static fromJson(jsonValue: JsonValue, options?: Partial): EntityCacheConfiguration { + return new EntityCacheConfiguration().fromJson(jsonValue, options); + } + + static fromJsonString(jsonString: string, options?: Partial): EntityCacheConfiguration { + return new EntityCacheConfiguration().fromJsonString(jsonString, options); + } + + static equals(a: EntityCacheConfiguration | PlainMessage | undefined, b: EntityCacheConfiguration | PlainMessage | undefined): boolean { + return proto3.util.equals(EntityCacheConfiguration, a, b); + } +} + +/** + * @generated from message wg.cosmo.node.v1.RootFieldCacheConfiguration + */ +export class RootFieldCacheConfiguration extends Message { + /** + * @generated from field: string field_name = 1; + */ + fieldName = ""; + + /** + * TTL for cached root-field responses. Required: composition rejects values + * <= 0. Interpreted in seconds. + * + * @generated from field: int64 max_age_seconds = 2; + */ + maxAgeSeconds = protoInt64.zero; + + /** + * @generated from field: bool include_headers = 3; + */ + includeHeaders = false; + + /** + * @generated from field: bool shadow_mode = 4; + */ + shadowMode = false; + + /** + * @generated from field: string entity_type_name = 5; + */ + entityTypeName = ""; + + /** + * @generated from field: repeated wg.cosmo.node.v1.EntityKeyMapping entity_key_mappings = 6; + */ + entityKeyMappings: EntityKeyMapping[] = []; + + constructor(data?: PartialMessage) { + super(); + proto3.util.initPartial(data, this); + } + + static readonly runtime: typeof proto3 = proto3; + static readonly typeName = "wg.cosmo.node.v1.RootFieldCacheConfiguration"; + static readonly fields: FieldList = proto3.util.newFieldList(() => [ + { no: 1, name: "field_name", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + { no: 2, name: "max_age_seconds", kind: "scalar", T: 3 /* ScalarType.INT64 */ }, + { no: 3, name: "include_headers", kind: "scalar", T: 8 /* ScalarType.BOOL */ }, + { no: 4, name: "shadow_mode", kind: "scalar", T: 8 /* ScalarType.BOOL */ }, + { no: 5, name: "entity_type_name", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + { no: 6, name: "entity_key_mappings", kind: "message", T: EntityKeyMapping, repeated: true }, + ]); + + static fromBinary(bytes: Uint8Array, options?: Partial): RootFieldCacheConfiguration { + return new RootFieldCacheConfiguration().fromBinary(bytes, options); + } + + static fromJson(jsonValue: JsonValue, options?: Partial): RootFieldCacheConfiguration { + return new RootFieldCacheConfiguration().fromJson(jsonValue, options); + } + + static fromJsonString(jsonString: string, options?: Partial): RootFieldCacheConfiguration { + return new RootFieldCacheConfiguration().fromJsonString(jsonString, options); + } + + static equals(a: RootFieldCacheConfiguration | PlainMessage | undefined, b: RootFieldCacheConfiguration | PlainMessage | undefined): boolean { + return proto3.util.equals(RootFieldCacheConfiguration, a, b); + } +} + +/** + * @generated from message wg.cosmo.node.v1.EntityKeyMapping + */ +export class EntityKeyMapping extends Message { + /** + * @generated from field: string entity_type_name = 1; + */ + entityTypeName = ""; + + /** + * @generated from field: repeated wg.cosmo.node.v1.EntityCacheFieldMapping field_mappings = 2; + */ + fieldMappings: EntityCacheFieldMapping[] = []; + + constructor(data?: PartialMessage) { + super(); + proto3.util.initPartial(data, this); + } + + static readonly runtime: typeof proto3 = proto3; + static readonly typeName = "wg.cosmo.node.v1.EntityKeyMapping"; + static readonly fields: FieldList = proto3.util.newFieldList(() => [ + { no: 1, name: "entity_type_name", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + { no: 2, name: "field_mappings", kind: "message", T: EntityCacheFieldMapping, repeated: true }, + ]); + + static fromBinary(bytes: Uint8Array, options?: Partial): EntityKeyMapping { + return new EntityKeyMapping().fromBinary(bytes, options); + } + + static fromJson(jsonValue: JsonValue, options?: Partial): EntityKeyMapping { + return new EntityKeyMapping().fromJson(jsonValue, options); + } + + static fromJsonString(jsonString: string, options?: Partial): EntityKeyMapping { + return new EntityKeyMapping().fromJsonString(jsonString, options); + } + + static equals(a: EntityKeyMapping | PlainMessage | undefined, b: EntityKeyMapping | PlainMessage | undefined): boolean { + return proto3.util.equals(EntityKeyMapping, a, b); + } +} + +/** + * @generated from message wg.cosmo.node.v1.EntityCacheFieldMapping + */ +export class EntityCacheFieldMapping extends Message { + /** + * @generated from field: string entity_key_field = 1; + */ + entityKeyField = ""; + + /** + * @generated from field: repeated string argument_path = 2; + */ + argumentPath: string[] = []; + + /** + * @generated from field: bool is_batch = 3; + */ + isBatch = false; + + constructor(data?: PartialMessage) { + super(); + proto3.util.initPartial(data, this); + } + + static readonly runtime: typeof proto3 = proto3; + static readonly typeName = "wg.cosmo.node.v1.EntityCacheFieldMapping"; + static readonly fields: FieldList = proto3.util.newFieldList(() => [ + { no: 1, name: "entity_key_field", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + { no: 2, name: "argument_path", kind: "scalar", T: 9 /* ScalarType.STRING */, repeated: true }, + { no: 3, name: "is_batch", kind: "scalar", T: 8 /* ScalarType.BOOL */ }, + ]); + + static fromBinary(bytes: Uint8Array, options?: Partial): EntityCacheFieldMapping { + return new EntityCacheFieldMapping().fromBinary(bytes, options); + } + + static fromJson(jsonValue: JsonValue, options?: Partial): EntityCacheFieldMapping { + return new EntityCacheFieldMapping().fromJson(jsonValue, options); + } + + static fromJsonString(jsonString: string, options?: Partial): EntityCacheFieldMapping { + return new EntityCacheFieldMapping().fromJsonString(jsonString, options); + } + + static equals(a: EntityCacheFieldMapping | PlainMessage | undefined, b: EntityCacheFieldMapping | PlainMessage | undefined): boolean { + return proto3.util.equals(EntityCacheFieldMapping, a, b); + } +} + +/** + * @generated from message wg.cosmo.node.v1.CachePopulateConfiguration + */ +export class CachePopulateConfiguration extends Message { + /** + * @generated from field: string field_name = 1; + */ + fieldName = ""; + + /** + * @generated from field: string operation_type = 2; + */ + operationType = ""; + + /** + * Optional override TTL for mutation/subscription populate writes. When omit, + * falls back to the target entity's max_age_seconds (for subscriptions) or + * the cache's default TTL (for mutations). Zero is treated as "no override". + * Composition rejects negative values. + * + * @generated from field: optional int64 max_age_seconds = 3; + */ + maxAgeSeconds?: bigint; + + /** + * @generated from field: string entity_type_name = 4; + */ + entityTypeName = ""; + + constructor(data?: PartialMessage) { + super(); + proto3.util.initPartial(data, this); + } + + static readonly runtime: typeof proto3 = proto3; + static readonly typeName = "wg.cosmo.node.v1.CachePopulateConfiguration"; + static readonly fields: FieldList = proto3.util.newFieldList(() => [ + { no: 1, name: "field_name", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + { no: 2, name: "operation_type", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + { no: 3, name: "max_age_seconds", kind: "scalar", T: 3 /* ScalarType.INT64 */, opt: true }, + { no: 4, name: "entity_type_name", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + ]); + + static fromBinary(bytes: Uint8Array, options?: Partial): CachePopulateConfiguration { + return new CachePopulateConfiguration().fromBinary(bytes, options); + } + + static fromJson(jsonValue: JsonValue, options?: Partial): CachePopulateConfiguration { + return new CachePopulateConfiguration().fromJson(jsonValue, options); + } + + static fromJsonString(jsonString: string, options?: Partial): CachePopulateConfiguration { + return new CachePopulateConfiguration().fromJsonString(jsonString, options); + } + + static equals(a: CachePopulateConfiguration | PlainMessage | undefined, b: CachePopulateConfiguration | PlainMessage | undefined): boolean { + return proto3.util.equals(CachePopulateConfiguration, a, b); + } +} + +/** + * @generated from message wg.cosmo.node.v1.CacheInvalidateConfiguration + */ +export class CacheInvalidateConfiguration extends Message { + /** + * @generated from field: string field_name = 1; + */ + fieldName = ""; + + /** + * @generated from field: string operation_type = 2; + */ + operationType = ""; + + /** + * @generated from field: string entity_type_name = 3; + */ + entityTypeName = ""; + + constructor(data?: PartialMessage) { + super(); + proto3.util.initPartial(data, this); + } + + static readonly runtime: typeof proto3 = proto3; + static readonly typeName = "wg.cosmo.node.v1.CacheInvalidateConfiguration"; + static readonly fields: FieldList = proto3.util.newFieldList(() => [ + { no: 1, name: "field_name", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + { no: 2, name: "operation_type", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + { no: 3, name: "entity_type_name", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + ]); + + static fromBinary(bytes: Uint8Array, options?: Partial): CacheInvalidateConfiguration { + return new CacheInvalidateConfiguration().fromBinary(bytes, options); + } + + static fromJson(jsonValue: JsonValue, options?: Partial): CacheInvalidateConfiguration { + return new CacheInvalidateConfiguration().fromJson(jsonValue, options); + } + + static fromJsonString(jsonString: string, options?: Partial): CacheInvalidateConfiguration { + return new CacheInvalidateConfiguration().fromJsonString(jsonString, options); + } + + static equals(a: CacheInvalidateConfiguration | PlainMessage | undefined, b: CacheInvalidateConfiguration | PlainMessage | undefined): boolean { + return proto3.util.equals(CacheInvalidateConfiguration, a, b); + } +} + /** * @generated from message wg.cosmo.node.v1.CostConfiguration */ diff --git a/proto/wg/cosmo/node/v1/node.proto b/proto/wg/cosmo/node/v1/node.proto index af7bd79bb4..d1af4b179e 100644 --- a/proto/wg/cosmo/node/v1/node.proto +++ b/proto/wg/cosmo/node/v1/node.proto @@ -91,6 +91,80 @@ message DataSourceConfiguration { repeated EntityInterfaceConfiguration entity_interfaces = 14; repeated EntityInterfaceConfiguration interface_objects = 15; CostConfiguration cost_configuration = 16; + // Entity caching configurations (from composition directives) + repeated EntityCacheConfiguration entity_cache_configurations = 17; + repeated RootFieldCacheConfiguration root_field_cache_configurations = 18; + repeated CachePopulateConfiguration cache_populate_configurations = 19; + repeated CacheInvalidateConfiguration cache_invalidate_configurations = 20; + // Request-scoped field configurations (from @openfed__requestScoped directive) + repeated RequestScopedFieldConfiguration request_scoped_fields = 21; +} + +// Per-field declaration for @openfed__requestScoped. All fields in the same subgraph declaring +// @openfed__requestScoped(key: "X") share L1 key "{subgraphName}.X". The first field to resolve +// populates L1; subsequent fields with the same key inject from L1 and can skip their +// fetch when all required sub-fields are present. +message RequestScopedFieldConfiguration { + string field_name = 1; + string type_name = 2; + string l1_key = 3; + reserved 4; + reserved "resolve_from"; +} + +message EntityCacheConfiguration { + reserved "negative_cache_ttl_seconds"; + string type_name = 1; + // TTL for cached entity values. Required: composition rejects values <= 0, + // so omit (zero) does not occur in practice. Interpreted in seconds. + int64 max_age_seconds = 2; + bool include_headers = 3; + bool partial_cache_load = 4; + bool shadow_mode = 5; + // TTL for caching "not found" entity responses (entity returned null from + // _entities without errors). Omit or 0 disables negative caching and null + // responses are not cached. Positive values are seconds. Composition rejects + // negative values at schema validation time. + int64 not_found_cache_ttl_seconds = 6; +} + +message RootFieldCacheConfiguration { + string field_name = 1; + // TTL for cached root-field responses. Required: composition rejects values + // <= 0. Interpreted in seconds. + int64 max_age_seconds = 2; + bool include_headers = 3; + bool shadow_mode = 4; + string entity_type_name = 5; + repeated EntityKeyMapping entity_key_mappings = 6; +} + +message EntityKeyMapping { + string entity_type_name = 1; + repeated EntityCacheFieldMapping field_mappings = 2; +} + +message EntityCacheFieldMapping { + string entity_key_field = 1; + repeated string argument_path = 2; + bool is_batch = 3; +} + +message CachePopulateConfiguration { + string field_name = 1; + string operation_type = 2; + // Optional override TTL for mutation/subscription populate writes. When omit, + // falls back to the target entity's max_age_seconds (for subscriptions) or + // the cache's default TTL (for mutations). Zero is treated as "no override". + // Composition rejects negative values. + optional int64 max_age_seconds = 3; + string entity_type_name = 4; +} + +message CacheInvalidateConfiguration { + string field_name = 1; + string operation_type = 2; + string entity_type_name = 3; } message CostConfiguration { diff --git a/router/gen/proto/wg/cosmo/node/v1/node.pb.go b/router/gen/proto/wg/cosmo/node/v1/node.pb.go index 86f7dea5d7..f94ed4f1c0 100644 --- a/router/gen/proto/wg/cosmo/node/v1/node.pb.go +++ b/router/gen/proto/wg/cosmo/node/v1/node.pb.go @@ -1070,8 +1070,15 @@ type DataSourceConfiguration struct { EntityInterfaces []*EntityInterfaceConfiguration `protobuf:"bytes,14,rep,name=entity_interfaces,json=entityInterfaces,proto3" json:"entity_interfaces,omitempty"` InterfaceObjects []*EntityInterfaceConfiguration `protobuf:"bytes,15,rep,name=interface_objects,json=interfaceObjects,proto3" json:"interface_objects,omitempty"` CostConfiguration *CostConfiguration `protobuf:"bytes,16,opt,name=cost_configuration,json=costConfiguration,proto3" json:"cost_configuration,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + // Entity caching configurations (from composition directives) + EntityCacheConfigurations []*EntityCacheConfiguration `protobuf:"bytes,17,rep,name=entity_cache_configurations,json=entityCacheConfigurations,proto3" json:"entity_cache_configurations,omitempty"` + RootFieldCacheConfigurations []*RootFieldCacheConfiguration `protobuf:"bytes,18,rep,name=root_field_cache_configurations,json=rootFieldCacheConfigurations,proto3" json:"root_field_cache_configurations,omitempty"` + CachePopulateConfigurations []*CachePopulateConfiguration `protobuf:"bytes,19,rep,name=cache_populate_configurations,json=cachePopulateConfigurations,proto3" json:"cache_populate_configurations,omitempty"` + CacheInvalidateConfigurations []*CacheInvalidateConfiguration `protobuf:"bytes,20,rep,name=cache_invalidate_configurations,json=cacheInvalidateConfigurations,proto3" json:"cache_invalidate_configurations,omitempty"` + // Request-scoped field configurations (from @openfed__requestScoped directive) + RequestScopedFields []*RequestScopedFieldConfiguration `protobuf:"bytes,21,rep,name=request_scoped_fields,json=requestScopedFields,proto3" json:"request_scoped_fields,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *DataSourceConfiguration) Reset() { @@ -1216,6 +1223,525 @@ func (x *DataSourceConfiguration) GetCostConfiguration() *CostConfiguration { return nil } +func (x *DataSourceConfiguration) GetEntityCacheConfigurations() []*EntityCacheConfiguration { + if x != nil { + return x.EntityCacheConfigurations + } + return nil +} + +func (x *DataSourceConfiguration) GetRootFieldCacheConfigurations() []*RootFieldCacheConfiguration { + if x != nil { + return x.RootFieldCacheConfigurations + } + return nil +} + +func (x *DataSourceConfiguration) GetCachePopulateConfigurations() []*CachePopulateConfiguration { + if x != nil { + return x.CachePopulateConfigurations + } + return nil +} + +func (x *DataSourceConfiguration) GetCacheInvalidateConfigurations() []*CacheInvalidateConfiguration { + if x != nil { + return x.CacheInvalidateConfigurations + } + return nil +} + +func (x *DataSourceConfiguration) GetRequestScopedFields() []*RequestScopedFieldConfiguration { + if x != nil { + return x.RequestScopedFields + } + return nil +} + +// Per-field declaration for @openfed__requestScoped. All fields in the same subgraph declaring +// @openfed__requestScoped(key: "X") share L1 key "{subgraphName}.X". The first field to resolve +// populates L1; subsequent fields with the same key inject from L1 and can skip their +// fetch when all required sub-fields are present. +type RequestScopedFieldConfiguration struct { + state protoimpl.MessageState `protogen:"open.v1"` + FieldName string `protobuf:"bytes,1,opt,name=field_name,json=fieldName,proto3" json:"field_name,omitempty"` + TypeName string `protobuf:"bytes,2,opt,name=type_name,json=typeName,proto3" json:"type_name,omitempty"` + L1Key string `protobuf:"bytes,3,opt,name=l1_key,json=l1Key,proto3" json:"l1_key,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RequestScopedFieldConfiguration) Reset() { + *x = RequestScopedFieldConfiguration{} + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RequestScopedFieldConfiguration) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RequestScopedFieldConfiguration) ProtoMessage() {} + +func (x *RequestScopedFieldConfiguration) ProtoReflect() protoreflect.Message { + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[12] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RequestScopedFieldConfiguration.ProtoReflect.Descriptor instead. +func (*RequestScopedFieldConfiguration) Descriptor() ([]byte, []int) { + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{12} +} + +func (x *RequestScopedFieldConfiguration) GetFieldName() string { + if x != nil { + return x.FieldName + } + return "" +} + +func (x *RequestScopedFieldConfiguration) GetTypeName() string { + if x != nil { + return x.TypeName + } + return "" +} + +func (x *RequestScopedFieldConfiguration) GetL1Key() string { + if x != nil { + return x.L1Key + } + return "" +} + +type EntityCacheConfiguration struct { + state protoimpl.MessageState `protogen:"open.v1"` + TypeName string `protobuf:"bytes,1,opt,name=type_name,json=typeName,proto3" json:"type_name,omitempty"` + // TTL for cached entity values. Required: composition rejects values <= 0, + // so omit (zero) does not occur in practice. Interpreted in seconds. + MaxAgeSeconds int64 `protobuf:"varint,2,opt,name=max_age_seconds,json=maxAgeSeconds,proto3" json:"max_age_seconds,omitempty"` + IncludeHeaders bool `protobuf:"varint,3,opt,name=include_headers,json=includeHeaders,proto3" json:"include_headers,omitempty"` + PartialCacheLoad bool `protobuf:"varint,4,opt,name=partial_cache_load,json=partialCacheLoad,proto3" json:"partial_cache_load,omitempty"` + ShadowMode bool `protobuf:"varint,5,opt,name=shadow_mode,json=shadowMode,proto3" json:"shadow_mode,omitempty"` + // TTL for caching "not found" entity responses (entity returned null from + // _entities without errors). Omit or 0 disables negative caching and null + // responses are not cached. Positive values are seconds. Composition rejects + // negative values at schema validation time. + NotFoundCacheTtlSeconds int64 `protobuf:"varint,6,opt,name=not_found_cache_ttl_seconds,json=notFoundCacheTtlSeconds,proto3" json:"not_found_cache_ttl_seconds,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *EntityCacheConfiguration) Reset() { + *x = EntityCacheConfiguration{} + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *EntityCacheConfiguration) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EntityCacheConfiguration) ProtoMessage() {} + +func (x *EntityCacheConfiguration) ProtoReflect() protoreflect.Message { + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[13] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EntityCacheConfiguration.ProtoReflect.Descriptor instead. +func (*EntityCacheConfiguration) Descriptor() ([]byte, []int) { + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{13} +} + +func (x *EntityCacheConfiguration) GetTypeName() string { + if x != nil { + return x.TypeName + } + return "" +} + +func (x *EntityCacheConfiguration) GetMaxAgeSeconds() int64 { + if x != nil { + return x.MaxAgeSeconds + } + return 0 +} + +func (x *EntityCacheConfiguration) GetIncludeHeaders() bool { + if x != nil { + return x.IncludeHeaders + } + return false +} + +func (x *EntityCacheConfiguration) GetPartialCacheLoad() bool { + if x != nil { + return x.PartialCacheLoad + } + return false +} + +func (x *EntityCacheConfiguration) GetShadowMode() bool { + if x != nil { + return x.ShadowMode + } + return false +} + +func (x *EntityCacheConfiguration) GetNotFoundCacheTtlSeconds() int64 { + if x != nil { + return x.NotFoundCacheTtlSeconds + } + return 0 +} + +type RootFieldCacheConfiguration struct { + state protoimpl.MessageState `protogen:"open.v1"` + FieldName string `protobuf:"bytes,1,opt,name=field_name,json=fieldName,proto3" json:"field_name,omitempty"` + // TTL for cached root-field responses. Required: composition rejects values + // <= 0. Interpreted in seconds. + MaxAgeSeconds int64 `protobuf:"varint,2,opt,name=max_age_seconds,json=maxAgeSeconds,proto3" json:"max_age_seconds,omitempty"` + IncludeHeaders bool `protobuf:"varint,3,opt,name=include_headers,json=includeHeaders,proto3" json:"include_headers,omitempty"` + ShadowMode bool `protobuf:"varint,4,opt,name=shadow_mode,json=shadowMode,proto3" json:"shadow_mode,omitempty"` + EntityTypeName string `protobuf:"bytes,5,opt,name=entity_type_name,json=entityTypeName,proto3" json:"entity_type_name,omitempty"` + EntityKeyMappings []*EntityKeyMapping `protobuf:"bytes,6,rep,name=entity_key_mappings,json=entityKeyMappings,proto3" json:"entity_key_mappings,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RootFieldCacheConfiguration) Reset() { + *x = RootFieldCacheConfiguration{} + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RootFieldCacheConfiguration) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RootFieldCacheConfiguration) ProtoMessage() {} + +func (x *RootFieldCacheConfiguration) ProtoReflect() protoreflect.Message { + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[14] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RootFieldCacheConfiguration.ProtoReflect.Descriptor instead. +func (*RootFieldCacheConfiguration) Descriptor() ([]byte, []int) { + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{14} +} + +func (x *RootFieldCacheConfiguration) GetFieldName() string { + if x != nil { + return x.FieldName + } + return "" +} + +func (x *RootFieldCacheConfiguration) GetMaxAgeSeconds() int64 { + if x != nil { + return x.MaxAgeSeconds + } + return 0 +} + +func (x *RootFieldCacheConfiguration) GetIncludeHeaders() bool { + if x != nil { + return x.IncludeHeaders + } + return false +} + +func (x *RootFieldCacheConfiguration) GetShadowMode() bool { + if x != nil { + return x.ShadowMode + } + return false +} + +func (x *RootFieldCacheConfiguration) GetEntityTypeName() string { + if x != nil { + return x.EntityTypeName + } + return "" +} + +func (x *RootFieldCacheConfiguration) GetEntityKeyMappings() []*EntityKeyMapping { + if x != nil { + return x.EntityKeyMappings + } + return nil +} + +type EntityKeyMapping struct { + state protoimpl.MessageState `protogen:"open.v1"` + EntityTypeName string `protobuf:"bytes,1,opt,name=entity_type_name,json=entityTypeName,proto3" json:"entity_type_name,omitempty"` + FieldMappings []*EntityCacheFieldMapping `protobuf:"bytes,2,rep,name=field_mappings,json=fieldMappings,proto3" json:"field_mappings,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *EntityKeyMapping) Reset() { + *x = EntityKeyMapping{} + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *EntityKeyMapping) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EntityKeyMapping) ProtoMessage() {} + +func (x *EntityKeyMapping) ProtoReflect() protoreflect.Message { + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[15] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EntityKeyMapping.ProtoReflect.Descriptor instead. +func (*EntityKeyMapping) Descriptor() ([]byte, []int) { + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{15} +} + +func (x *EntityKeyMapping) GetEntityTypeName() string { + if x != nil { + return x.EntityTypeName + } + return "" +} + +func (x *EntityKeyMapping) GetFieldMappings() []*EntityCacheFieldMapping { + if x != nil { + return x.FieldMappings + } + return nil +} + +type EntityCacheFieldMapping struct { + state protoimpl.MessageState `protogen:"open.v1"` + EntityKeyField string `protobuf:"bytes,1,opt,name=entity_key_field,json=entityKeyField,proto3" json:"entity_key_field,omitempty"` + ArgumentPath []string `protobuf:"bytes,2,rep,name=argument_path,json=argumentPath,proto3" json:"argument_path,omitempty"` + IsBatch bool `protobuf:"varint,3,opt,name=is_batch,json=isBatch,proto3" json:"is_batch,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *EntityCacheFieldMapping) Reset() { + *x = EntityCacheFieldMapping{} + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *EntityCacheFieldMapping) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EntityCacheFieldMapping) ProtoMessage() {} + +func (x *EntityCacheFieldMapping) ProtoReflect() protoreflect.Message { + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[16] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EntityCacheFieldMapping.ProtoReflect.Descriptor instead. +func (*EntityCacheFieldMapping) Descriptor() ([]byte, []int) { + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{16} +} + +func (x *EntityCacheFieldMapping) GetEntityKeyField() string { + if x != nil { + return x.EntityKeyField + } + return "" +} + +func (x *EntityCacheFieldMapping) GetArgumentPath() []string { + if x != nil { + return x.ArgumentPath + } + return nil +} + +func (x *EntityCacheFieldMapping) GetIsBatch() bool { + if x != nil { + return x.IsBatch + } + return false +} + +type CachePopulateConfiguration struct { + state protoimpl.MessageState `protogen:"open.v1"` + FieldName string `protobuf:"bytes,1,opt,name=field_name,json=fieldName,proto3" json:"field_name,omitempty"` + OperationType string `protobuf:"bytes,2,opt,name=operation_type,json=operationType,proto3" json:"operation_type,omitempty"` + // Optional override TTL for mutation/subscription populate writes. When omit, + // falls back to the target entity's max_age_seconds (for subscriptions) or + // the cache's default TTL (for mutations). Zero is treated as "no override". + // Composition rejects negative values. + MaxAgeSeconds *int64 `protobuf:"varint,3,opt,name=max_age_seconds,json=maxAgeSeconds,proto3,oneof" json:"max_age_seconds,omitempty"` + EntityTypeName string `protobuf:"bytes,4,opt,name=entity_type_name,json=entityTypeName,proto3" json:"entity_type_name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CachePopulateConfiguration) Reset() { + *x = CachePopulateConfiguration{} + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CachePopulateConfiguration) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CachePopulateConfiguration) ProtoMessage() {} + +func (x *CachePopulateConfiguration) ProtoReflect() protoreflect.Message { + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[17] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CachePopulateConfiguration.ProtoReflect.Descriptor instead. +func (*CachePopulateConfiguration) Descriptor() ([]byte, []int) { + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{17} +} + +func (x *CachePopulateConfiguration) GetFieldName() string { + if x != nil { + return x.FieldName + } + return "" +} + +func (x *CachePopulateConfiguration) GetOperationType() string { + if x != nil { + return x.OperationType + } + return "" +} + +func (x *CachePopulateConfiguration) GetMaxAgeSeconds() int64 { + if x != nil && x.MaxAgeSeconds != nil { + return *x.MaxAgeSeconds + } + return 0 +} + +func (x *CachePopulateConfiguration) GetEntityTypeName() string { + if x != nil { + return x.EntityTypeName + } + return "" +} + +type CacheInvalidateConfiguration struct { + state protoimpl.MessageState `protogen:"open.v1"` + FieldName string `protobuf:"bytes,1,opt,name=field_name,json=fieldName,proto3" json:"field_name,omitempty"` + OperationType string `protobuf:"bytes,2,opt,name=operation_type,json=operationType,proto3" json:"operation_type,omitempty"` + EntityTypeName string `protobuf:"bytes,3,opt,name=entity_type_name,json=entityTypeName,proto3" json:"entity_type_name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CacheInvalidateConfiguration) Reset() { + *x = CacheInvalidateConfiguration{} + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CacheInvalidateConfiguration) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CacheInvalidateConfiguration) ProtoMessage() {} + +func (x *CacheInvalidateConfiguration) ProtoReflect() protoreflect.Message { + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[18] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CacheInvalidateConfiguration.ProtoReflect.Descriptor instead. +func (*CacheInvalidateConfiguration) Descriptor() ([]byte, []int) { + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{18} +} + +func (x *CacheInvalidateConfiguration) GetFieldName() string { + if x != nil { + return x.FieldName + } + return "" +} + +func (x *CacheInvalidateConfiguration) GetOperationType() string { + if x != nil { + return x.OperationType + } + return "" +} + +func (x *CacheInvalidateConfiguration) GetEntityTypeName() string { + if x != nil { + return x.EntityTypeName + } + return "" +} + type CostConfiguration struct { state protoimpl.MessageState `protogen:"open.v1"` FieldWeights []*FieldWeightConfiguration `protobuf:"bytes,1,rep,name=field_weights,json=fieldWeights,proto3" json:"field_weights,omitempty"` @@ -1228,7 +1754,7 @@ type CostConfiguration struct { func (x *CostConfiguration) Reset() { *x = CostConfiguration{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[12] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1240,7 +1766,7 @@ func (x *CostConfiguration) String() string { func (*CostConfiguration) ProtoMessage() {} func (x *CostConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[12] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[19] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1253,7 +1779,7 @@ func (x *CostConfiguration) ProtoReflect() protoreflect.Message { // Deprecated: Use CostConfiguration.ProtoReflect.Descriptor instead. func (*CostConfiguration) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{12} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{19} } func (x *CostConfiguration) GetFieldWeights() []*FieldWeightConfiguration { @@ -1297,7 +1823,7 @@ type FieldWeightConfiguration struct { func (x *FieldWeightConfiguration) Reset() { *x = FieldWeightConfiguration{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[13] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1309,7 +1835,7 @@ func (x *FieldWeightConfiguration) String() string { func (*FieldWeightConfiguration) ProtoMessage() {} func (x *FieldWeightConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[13] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[20] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1322,7 +1848,7 @@ func (x *FieldWeightConfiguration) ProtoReflect() protoreflect.Message { // Deprecated: Use FieldWeightConfiguration.ProtoReflect.Descriptor instead. func (*FieldWeightConfiguration) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{13} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{20} } func (x *FieldWeightConfiguration) GetTypeName() string { @@ -1374,7 +1900,7 @@ type FieldListSizeConfiguration struct { func (x *FieldListSizeConfiguration) Reset() { *x = FieldListSizeConfiguration{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[14] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1386,7 +1912,7 @@ func (x *FieldListSizeConfiguration) String() string { func (*FieldListSizeConfiguration) ProtoMessage() {} func (x *FieldListSizeConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[14] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[21] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1399,7 +1925,7 @@ func (x *FieldListSizeConfiguration) ProtoReflect() protoreflect.Message { // Deprecated: Use FieldListSizeConfiguration.ProtoReflect.Descriptor instead. func (*FieldListSizeConfiguration) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{14} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{21} } func (x *FieldListSizeConfiguration) GetTypeName() string { @@ -1454,7 +1980,7 @@ type ArgumentConfiguration struct { func (x *ArgumentConfiguration) Reset() { *x = ArgumentConfiguration{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[15] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1466,7 +1992,7 @@ func (x *ArgumentConfiguration) String() string { func (*ArgumentConfiguration) ProtoMessage() {} func (x *ArgumentConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[15] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[22] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1479,7 +2005,7 @@ func (x *ArgumentConfiguration) ProtoReflect() protoreflect.Message { // Deprecated: Use ArgumentConfiguration.ProtoReflect.Descriptor instead. func (*ArgumentConfiguration) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{15} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{22} } func (x *ArgumentConfiguration) GetName() string { @@ -1505,7 +2031,7 @@ type Scopes struct { func (x *Scopes) Reset() { *x = Scopes{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[16] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1517,7 +2043,7 @@ func (x *Scopes) String() string { func (*Scopes) ProtoMessage() {} func (x *Scopes) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[16] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[23] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1530,7 +2056,7 @@ func (x *Scopes) ProtoReflect() protoreflect.Message { // Deprecated: Use Scopes.ProtoReflect.Descriptor instead. func (*Scopes) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{16} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{23} } func (x *Scopes) GetRequiredAndScopes() []string { @@ -1551,7 +2077,7 @@ type AuthorizationConfiguration struct { func (x *AuthorizationConfiguration) Reset() { *x = AuthorizationConfiguration{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[17] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1563,7 +2089,7 @@ func (x *AuthorizationConfiguration) String() string { func (*AuthorizationConfiguration) ProtoMessage() {} func (x *AuthorizationConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[17] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[24] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1576,7 +2102,7 @@ func (x *AuthorizationConfiguration) ProtoReflect() protoreflect.Message { // Deprecated: Use AuthorizationConfiguration.ProtoReflect.Descriptor instead. func (*AuthorizationConfiguration) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{17} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{24} } func (x *AuthorizationConfiguration) GetRequiresAuthentication() bool { @@ -1613,7 +2139,7 @@ type FieldConfiguration struct { func (x *FieldConfiguration) Reset() { *x = FieldConfiguration{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[18] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1625,7 +2151,7 @@ func (x *FieldConfiguration) String() string { func (*FieldConfiguration) ProtoMessage() {} func (x *FieldConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[18] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[25] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1638,7 +2164,7 @@ func (x *FieldConfiguration) ProtoReflect() protoreflect.Message { // Deprecated: Use FieldConfiguration.ProtoReflect.Descriptor instead. func (*FieldConfiguration) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{18} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{25} } func (x *FieldConfiguration) GetTypeName() string { @@ -1686,7 +2212,7 @@ type TypeConfiguration struct { func (x *TypeConfiguration) Reset() { *x = TypeConfiguration{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[19] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1698,7 +2224,7 @@ func (x *TypeConfiguration) String() string { func (*TypeConfiguration) ProtoMessage() {} func (x *TypeConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[19] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[26] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1711,7 +2237,7 @@ func (x *TypeConfiguration) ProtoReflect() protoreflect.Message { // Deprecated: Use TypeConfiguration.ProtoReflect.Descriptor instead. func (*TypeConfiguration) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{19} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{26} } func (x *TypeConfiguration) GetTypeName() string { @@ -1740,7 +2266,7 @@ type TypeField struct { func (x *TypeField) Reset() { *x = TypeField{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[20] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1752,7 +2278,7 @@ func (x *TypeField) String() string { func (*TypeField) ProtoMessage() {} func (x *TypeField) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[20] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[27] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1765,7 +2291,7 @@ func (x *TypeField) ProtoReflect() protoreflect.Message { // Deprecated: Use TypeField.ProtoReflect.Descriptor instead. func (*TypeField) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{20} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{27} } func (x *TypeField) GetTypeName() string { @@ -1806,7 +2332,7 @@ type FieldCoordinates struct { func (x *FieldCoordinates) Reset() { *x = FieldCoordinates{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[21] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1818,7 +2344,7 @@ func (x *FieldCoordinates) String() string { func (*FieldCoordinates) ProtoMessage() {} func (x *FieldCoordinates) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[21] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[28] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1831,7 +2357,7 @@ func (x *FieldCoordinates) ProtoReflect() protoreflect.Message { // Deprecated: Use FieldCoordinates.ProtoReflect.Descriptor instead. func (*FieldCoordinates) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{21} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{28} } func (x *FieldCoordinates) GetFieldName() string { @@ -1858,7 +2384,7 @@ type FieldSetCondition struct { func (x *FieldSetCondition) Reset() { *x = FieldSetCondition{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[22] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1870,7 +2396,7 @@ func (x *FieldSetCondition) String() string { func (*FieldSetCondition) ProtoMessage() {} func (x *FieldSetCondition) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[22] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[29] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1883,7 +2409,7 @@ func (x *FieldSetCondition) ProtoReflect() protoreflect.Message { // Deprecated: Use FieldSetCondition.ProtoReflect.Descriptor instead. func (*FieldSetCondition) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{22} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{29} } func (x *FieldSetCondition) GetFieldCoordinatesPath() []*FieldCoordinates { @@ -1913,7 +2439,7 @@ type RequiredField struct { func (x *RequiredField) Reset() { *x = RequiredField{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[23] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[30] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1925,7 +2451,7 @@ func (x *RequiredField) String() string { func (*RequiredField) ProtoMessage() {} func (x *RequiredField) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[23] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[30] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1938,7 +2464,7 @@ func (x *RequiredField) ProtoReflect() protoreflect.Message { // Deprecated: Use RequiredField.ProtoReflect.Descriptor instead. func (*RequiredField) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{23} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{30} } func (x *RequiredField) GetTypeName() string { @@ -1986,7 +2512,7 @@ type EntityInterfaceConfiguration struct { func (x *EntityInterfaceConfiguration) Reset() { *x = EntityInterfaceConfiguration{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[24] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1998,7 +2524,7 @@ func (x *EntityInterfaceConfiguration) String() string { func (*EntityInterfaceConfiguration) ProtoMessage() {} func (x *EntityInterfaceConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[24] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[31] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2011,7 +2537,7 @@ func (x *EntityInterfaceConfiguration) ProtoReflect() protoreflect.Message { // Deprecated: Use EntityInterfaceConfiguration.ProtoReflect.Descriptor instead. func (*EntityInterfaceConfiguration) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{24} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{31} } func (x *EntityInterfaceConfiguration) GetInterfaceTypeName() string { @@ -2054,7 +2580,7 @@ type FetchConfiguration struct { func (x *FetchConfiguration) Reset() { *x = FetchConfiguration{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[25] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[32] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2066,7 +2592,7 @@ func (x *FetchConfiguration) String() string { func (*FetchConfiguration) ProtoMessage() {} func (x *FetchConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[25] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[32] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2079,7 +2605,7 @@ func (x *FetchConfiguration) ProtoReflect() protoreflect.Message { // Deprecated: Use FetchConfiguration.ProtoReflect.Descriptor instead. func (*FetchConfiguration) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{25} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{32} } func (x *FetchConfiguration) GetUrl() *ConfigurationVariable { @@ -2163,7 +2689,7 @@ type StatusCodeTypeMapping struct { func (x *StatusCodeTypeMapping) Reset() { *x = StatusCodeTypeMapping{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[26] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[33] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2175,7 +2701,7 @@ func (x *StatusCodeTypeMapping) String() string { func (*StatusCodeTypeMapping) ProtoMessage() {} func (x *StatusCodeTypeMapping) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[26] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[33] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2188,7 +2714,7 @@ func (x *StatusCodeTypeMapping) ProtoReflect() protoreflect.Message { // Deprecated: Use StatusCodeTypeMapping.ProtoReflect.Descriptor instead. func (*StatusCodeTypeMapping) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{26} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{33} } func (x *StatusCodeTypeMapping) GetStatusCode() int64 { @@ -2226,7 +2752,7 @@ type DataSourceCustom_GraphQL struct { func (x *DataSourceCustom_GraphQL) Reset() { *x = DataSourceCustom_GraphQL{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[27] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[34] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2238,7 +2764,7 @@ func (x *DataSourceCustom_GraphQL) String() string { func (*DataSourceCustom_GraphQL) ProtoMessage() {} func (x *DataSourceCustom_GraphQL) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[27] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[34] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2251,7 +2777,7 @@ func (x *DataSourceCustom_GraphQL) ProtoReflect() protoreflect.Message { // Deprecated: Use DataSourceCustom_GraphQL.ProtoReflect.Descriptor instead. func (*DataSourceCustom_GraphQL) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{27} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{34} } func (x *DataSourceCustom_GraphQL) GetFetch() *FetchConfiguration { @@ -2307,7 +2833,7 @@ type GRPCConfiguration struct { func (x *GRPCConfiguration) Reset() { *x = GRPCConfiguration{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[28] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[35] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2319,7 +2845,7 @@ func (x *GRPCConfiguration) String() string { func (*GRPCConfiguration) ProtoMessage() {} func (x *GRPCConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[28] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[35] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2332,7 +2858,7 @@ func (x *GRPCConfiguration) ProtoReflect() protoreflect.Message { // Deprecated: Use GRPCConfiguration.ProtoReflect.Descriptor instead. func (*GRPCConfiguration) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{28} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{35} } func (x *GRPCConfiguration) GetMapping() *GRPCMapping { @@ -2366,7 +2892,7 @@ type ImageReference struct { func (x *ImageReference) Reset() { *x = ImageReference{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[29] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[36] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2378,7 +2904,7 @@ func (x *ImageReference) String() string { func (*ImageReference) ProtoMessage() {} func (x *ImageReference) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[29] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[36] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2391,7 +2917,7 @@ func (x *ImageReference) ProtoReflect() protoreflect.Message { // Deprecated: Use ImageReference.ProtoReflect.Descriptor instead. func (*ImageReference) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{29} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{36} } func (x *ImageReference) GetRepository() string { @@ -2421,7 +2947,7 @@ type PluginConfiguration struct { func (x *PluginConfiguration) Reset() { *x = PluginConfiguration{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[30] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[37] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2433,7 +2959,7 @@ func (x *PluginConfiguration) String() string { func (*PluginConfiguration) ProtoMessage() {} func (x *PluginConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[30] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[37] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2446,7 +2972,7 @@ func (x *PluginConfiguration) ProtoReflect() protoreflect.Message { // Deprecated: Use PluginConfiguration.ProtoReflect.Descriptor instead. func (*PluginConfiguration) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{30} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{37} } func (x *PluginConfiguration) GetName() string { @@ -2480,7 +3006,7 @@ type SSLConfiguration struct { func (x *SSLConfiguration) Reset() { *x = SSLConfiguration{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[31] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[38] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2492,7 +3018,7 @@ func (x *SSLConfiguration) String() string { func (*SSLConfiguration) ProtoMessage() {} func (x *SSLConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[31] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[38] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2505,7 +3031,7 @@ func (x *SSLConfiguration) ProtoReflect() protoreflect.Message { // Deprecated: Use SSLConfiguration.ProtoReflect.Descriptor instead. func (*SSLConfiguration) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{31} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{38} } func (x *SSLConfiguration) GetEnabled() bool { @@ -2538,7 +3064,7 @@ type GRPCMapping struct { func (x *GRPCMapping) Reset() { *x = GRPCMapping{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[32] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[39] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2550,7 +3076,7 @@ func (x *GRPCMapping) String() string { func (*GRPCMapping) ProtoMessage() {} func (x *GRPCMapping) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[32] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[39] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2563,7 +3089,7 @@ func (x *GRPCMapping) ProtoReflect() protoreflect.Message { // Deprecated: Use GRPCMapping.ProtoReflect.Descriptor instead. func (*GRPCMapping) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{32} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{39} } func (x *GRPCMapping) GetVersion() int32 { @@ -2634,7 +3160,7 @@ type LookupMapping struct { func (x *LookupMapping) Reset() { *x = LookupMapping{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[33] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[40] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2646,7 +3172,7 @@ func (x *LookupMapping) String() string { func (*LookupMapping) ProtoMessage() {} func (x *LookupMapping) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[33] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[40] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2659,7 +3185,7 @@ func (x *LookupMapping) ProtoReflect() protoreflect.Message { // Deprecated: Use LookupMapping.ProtoReflect.Descriptor instead. func (*LookupMapping) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{33} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{40} } func (x *LookupMapping) GetType() LookupType { @@ -2710,7 +3236,7 @@ type LookupFieldMapping struct { func (x *LookupFieldMapping) Reset() { *x = LookupFieldMapping{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[34] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[41] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2722,7 +3248,7 @@ func (x *LookupFieldMapping) String() string { func (*LookupFieldMapping) ProtoMessage() {} func (x *LookupFieldMapping) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[34] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[41] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2735,7 +3261,7 @@ func (x *LookupFieldMapping) ProtoReflect() protoreflect.Message { // Deprecated: Use LookupFieldMapping.ProtoReflect.Descriptor instead. func (*LookupFieldMapping) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{34} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{41} } func (x *LookupFieldMapping) GetType() string { @@ -2771,7 +3297,7 @@ type OperationMapping struct { func (x *OperationMapping) Reset() { *x = OperationMapping{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[35] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[42] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2783,7 +3309,7 @@ func (x *OperationMapping) String() string { func (*OperationMapping) ProtoMessage() {} func (x *OperationMapping) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[35] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[42] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2796,7 +3322,7 @@ func (x *OperationMapping) ProtoReflect() protoreflect.Message { // Deprecated: Use OperationMapping.ProtoReflect.Descriptor instead. func (*OperationMapping) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{35} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{42} } func (x *OperationMapping) GetType() OperationType { @@ -2857,7 +3383,7 @@ type EntityMapping struct { func (x *EntityMapping) Reset() { *x = EntityMapping{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[36] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[43] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2869,7 +3395,7 @@ func (x *EntityMapping) String() string { func (*EntityMapping) ProtoMessage() {} func (x *EntityMapping) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[36] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[43] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2882,7 +3408,7 @@ func (x *EntityMapping) ProtoReflect() protoreflect.Message { // Deprecated: Use EntityMapping.ProtoReflect.Descriptor instead. func (*EntityMapping) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{36} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{43} } func (x *EntityMapping) GetTypeName() string { @@ -2950,7 +3476,7 @@ type RequiredFieldMapping struct { func (x *RequiredFieldMapping) Reset() { *x = RequiredFieldMapping{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[37] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[44] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2962,7 +3488,7 @@ func (x *RequiredFieldMapping) String() string { func (*RequiredFieldMapping) ProtoMessage() {} func (x *RequiredFieldMapping) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[37] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[44] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2975,7 +3501,7 @@ func (x *RequiredFieldMapping) ProtoReflect() protoreflect.Message { // Deprecated: Use RequiredFieldMapping.ProtoReflect.Descriptor instead. func (*RequiredFieldMapping) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{37} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{44} } func (x *RequiredFieldMapping) GetFieldMapping() *FieldMapping { @@ -3019,7 +3545,7 @@ type TypeFieldMapping struct { func (x *TypeFieldMapping) Reset() { *x = TypeFieldMapping{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[38] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[45] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3031,7 +3557,7 @@ func (x *TypeFieldMapping) String() string { func (*TypeFieldMapping) ProtoMessage() {} func (x *TypeFieldMapping) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[38] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[45] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3044,7 +3570,7 @@ func (x *TypeFieldMapping) ProtoReflect() protoreflect.Message { // Deprecated: Use TypeFieldMapping.ProtoReflect.Descriptor instead. func (*TypeFieldMapping) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{38} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{45} } func (x *TypeFieldMapping) GetType() string { @@ -3076,7 +3602,7 @@ type FieldMapping struct { func (x *FieldMapping) Reset() { *x = FieldMapping{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[39] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[46] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3088,7 +3614,7 @@ func (x *FieldMapping) String() string { func (*FieldMapping) ProtoMessage() {} func (x *FieldMapping) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[39] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[46] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3101,7 +3627,7 @@ func (x *FieldMapping) ProtoReflect() protoreflect.Message { // Deprecated: Use FieldMapping.ProtoReflect.Descriptor instead. func (*FieldMapping) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{39} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{46} } func (x *FieldMapping) GetOriginal() string { @@ -3138,7 +3664,7 @@ type ArgumentMapping struct { func (x *ArgumentMapping) Reset() { *x = ArgumentMapping{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[40] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[47] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3150,7 +3676,7 @@ func (x *ArgumentMapping) String() string { func (*ArgumentMapping) ProtoMessage() {} func (x *ArgumentMapping) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[40] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[47] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3163,7 +3689,7 @@ func (x *ArgumentMapping) ProtoReflect() protoreflect.Message { // Deprecated: Use ArgumentMapping.ProtoReflect.Descriptor instead. func (*ArgumentMapping) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{40} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{47} } func (x *ArgumentMapping) GetOriginal() string { @@ -3190,7 +3716,7 @@ type EnumMapping struct { func (x *EnumMapping) Reset() { *x = EnumMapping{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[41] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[48] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3202,7 +3728,7 @@ func (x *EnumMapping) String() string { func (*EnumMapping) ProtoMessage() {} func (x *EnumMapping) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[41] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[48] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3215,7 +3741,7 @@ func (x *EnumMapping) ProtoReflect() protoreflect.Message { // Deprecated: Use EnumMapping.ProtoReflect.Descriptor instead. func (*EnumMapping) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{41} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{48} } func (x *EnumMapping) GetType() string { @@ -3242,7 +3768,7 @@ type EnumValueMapping struct { func (x *EnumValueMapping) Reset() { *x = EnumValueMapping{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[42] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[49] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3254,7 +3780,7 @@ func (x *EnumValueMapping) String() string { func (*EnumValueMapping) ProtoMessage() {} func (x *EnumValueMapping) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[42] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[49] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3267,7 +3793,7 @@ func (x *EnumValueMapping) ProtoReflect() protoreflect.Message { // Deprecated: Use EnumValueMapping.ProtoReflect.Descriptor instead. func (*EnumValueMapping) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{42} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{49} } func (x *EnumValueMapping) GetOriginal() string { @@ -3295,7 +3821,7 @@ type NatsStreamConfiguration struct { func (x *NatsStreamConfiguration) Reset() { *x = NatsStreamConfiguration{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[43] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[50] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3307,7 +3833,7 @@ func (x *NatsStreamConfiguration) String() string { func (*NatsStreamConfiguration) ProtoMessage() {} func (x *NatsStreamConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[43] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[50] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3320,7 +3846,7 @@ func (x *NatsStreamConfiguration) ProtoReflect() protoreflect.Message { // Deprecated: Use NatsStreamConfiguration.ProtoReflect.Descriptor instead. func (*NatsStreamConfiguration) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{43} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{50} } func (x *NatsStreamConfiguration) GetConsumerName() string { @@ -3355,7 +3881,7 @@ type NatsEventConfiguration struct { func (x *NatsEventConfiguration) Reset() { *x = NatsEventConfiguration{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[44] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[51] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3367,7 +3893,7 @@ func (x *NatsEventConfiguration) String() string { func (*NatsEventConfiguration) ProtoMessage() {} func (x *NatsEventConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[44] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[51] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3380,7 +3906,7 @@ func (x *NatsEventConfiguration) ProtoReflect() protoreflect.Message { // Deprecated: Use NatsEventConfiguration.ProtoReflect.Descriptor instead. func (*NatsEventConfiguration) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{44} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{51} } func (x *NatsEventConfiguration) GetEngineEventConfiguration() *EngineEventConfiguration { @@ -3414,7 +3940,7 @@ type KafkaEventConfiguration struct { func (x *KafkaEventConfiguration) Reset() { *x = KafkaEventConfiguration{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[45] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[52] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3426,7 +3952,7 @@ func (x *KafkaEventConfiguration) String() string { func (*KafkaEventConfiguration) ProtoMessage() {} func (x *KafkaEventConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[45] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[52] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3439,7 +3965,7 @@ func (x *KafkaEventConfiguration) ProtoReflect() protoreflect.Message { // Deprecated: Use KafkaEventConfiguration.ProtoReflect.Descriptor instead. func (*KafkaEventConfiguration) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{45} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{52} } func (x *KafkaEventConfiguration) GetEngineEventConfiguration() *EngineEventConfiguration { @@ -3466,7 +3992,7 @@ type RedisEventConfiguration struct { func (x *RedisEventConfiguration) Reset() { *x = RedisEventConfiguration{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[46] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[53] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3478,7 +4004,7 @@ func (x *RedisEventConfiguration) String() string { func (*RedisEventConfiguration) ProtoMessage() {} func (x *RedisEventConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[46] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[53] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3491,7 +4017,7 @@ func (x *RedisEventConfiguration) ProtoReflect() protoreflect.Message { // Deprecated: Use RedisEventConfiguration.ProtoReflect.Descriptor instead. func (*RedisEventConfiguration) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{46} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{53} } func (x *RedisEventConfiguration) GetEngineEventConfiguration() *EngineEventConfiguration { @@ -3520,7 +4046,7 @@ type EngineEventConfiguration struct { func (x *EngineEventConfiguration) Reset() { *x = EngineEventConfiguration{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[47] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[54] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3532,7 +4058,7 @@ func (x *EngineEventConfiguration) String() string { func (*EngineEventConfiguration) ProtoMessage() {} func (x *EngineEventConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[47] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[54] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3545,7 +4071,7 @@ func (x *EngineEventConfiguration) ProtoReflect() protoreflect.Message { // Deprecated: Use EngineEventConfiguration.ProtoReflect.Descriptor instead. func (*EngineEventConfiguration) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{47} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{54} } func (x *EngineEventConfiguration) GetProviderId() string { @@ -3587,7 +4113,7 @@ type DataSourceCustomEvents struct { func (x *DataSourceCustomEvents) Reset() { *x = DataSourceCustomEvents{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[48] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[55] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3599,7 +4125,7 @@ func (x *DataSourceCustomEvents) String() string { func (*DataSourceCustomEvents) ProtoMessage() {} func (x *DataSourceCustomEvents) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[48] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[55] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3612,7 +4138,7 @@ func (x *DataSourceCustomEvents) ProtoReflect() protoreflect.Message { // Deprecated: Use DataSourceCustomEvents.ProtoReflect.Descriptor instead. func (*DataSourceCustomEvents) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{48} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{55} } func (x *DataSourceCustomEvents) GetNats() []*NatsEventConfiguration { @@ -3645,7 +4171,7 @@ type DataSourceCustom_Static struct { func (x *DataSourceCustom_Static) Reset() { *x = DataSourceCustom_Static{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[49] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[56] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3657,7 +4183,7 @@ func (x *DataSourceCustom_Static) String() string { func (*DataSourceCustom_Static) ProtoMessage() {} func (x *DataSourceCustom_Static) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[49] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[56] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3670,7 +4196,7 @@ func (x *DataSourceCustom_Static) ProtoReflect() protoreflect.Message { // Deprecated: Use DataSourceCustom_Static.ProtoReflect.Descriptor instead. func (*DataSourceCustom_Static) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{49} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{56} } func (x *DataSourceCustom_Static) GetData() *ConfigurationVariable { @@ -3693,7 +4219,7 @@ type ConfigurationVariable struct { func (x *ConfigurationVariable) Reset() { *x = ConfigurationVariable{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[50] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[57] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3705,7 +4231,7 @@ func (x *ConfigurationVariable) String() string { func (*ConfigurationVariable) ProtoMessage() {} func (x *ConfigurationVariable) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[50] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[57] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3718,7 +4244,7 @@ func (x *ConfigurationVariable) ProtoReflect() protoreflect.Message { // Deprecated: Use ConfigurationVariable.ProtoReflect.Descriptor instead. func (*ConfigurationVariable) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{50} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{57} } func (x *ConfigurationVariable) GetKind() ConfigurationVariableKind { @@ -3766,7 +4292,7 @@ type DirectiveConfiguration struct { func (x *DirectiveConfiguration) Reset() { *x = DirectiveConfiguration{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[51] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[58] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3778,7 +4304,7 @@ func (x *DirectiveConfiguration) String() string { func (*DirectiveConfiguration) ProtoMessage() {} func (x *DirectiveConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[51] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[58] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3791,7 +4317,7 @@ func (x *DirectiveConfiguration) ProtoReflect() protoreflect.Message { // Deprecated: Use DirectiveConfiguration.ProtoReflect.Descriptor instead. func (*DirectiveConfiguration) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{51} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{58} } func (x *DirectiveConfiguration) GetDirectiveName() string { @@ -3818,7 +4344,7 @@ type URLQueryConfiguration struct { func (x *URLQueryConfiguration) Reset() { *x = URLQueryConfiguration{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[52] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[59] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3830,7 +4356,7 @@ func (x *URLQueryConfiguration) String() string { func (*URLQueryConfiguration) ProtoMessage() {} func (x *URLQueryConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[52] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[59] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3843,7 +4369,7 @@ func (x *URLQueryConfiguration) ProtoReflect() protoreflect.Message { // Deprecated: Use URLQueryConfiguration.ProtoReflect.Descriptor instead. func (*URLQueryConfiguration) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{52} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{59} } func (x *URLQueryConfiguration) GetName() string { @@ -3869,7 +4395,7 @@ type HTTPHeader struct { func (x *HTTPHeader) Reset() { *x = HTTPHeader{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[53] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[60] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3881,7 +4407,7 @@ func (x *HTTPHeader) String() string { func (*HTTPHeader) ProtoMessage() {} func (x *HTTPHeader) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[53] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[60] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3894,7 +4420,7 @@ func (x *HTTPHeader) ProtoReflect() protoreflect.Message { // Deprecated: Use HTTPHeader.ProtoReflect.Descriptor instead. func (*HTTPHeader) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{53} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{60} } func (x *HTTPHeader) GetValues() []*ConfigurationVariable { @@ -3915,7 +4441,7 @@ type MTLSConfiguration struct { func (x *MTLSConfiguration) Reset() { *x = MTLSConfiguration{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[54] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[61] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3927,7 +4453,7 @@ func (x *MTLSConfiguration) String() string { func (*MTLSConfiguration) ProtoMessage() {} func (x *MTLSConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[54] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[61] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3940,7 +4466,7 @@ func (x *MTLSConfiguration) ProtoReflect() protoreflect.Message { // Deprecated: Use MTLSConfiguration.ProtoReflect.Descriptor instead. func (*MTLSConfiguration) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{54} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{61} } func (x *MTLSConfiguration) GetKey() *ConfigurationVariable { @@ -3978,7 +4504,7 @@ type GraphQLSubscriptionConfiguration struct { func (x *GraphQLSubscriptionConfiguration) Reset() { *x = GraphQLSubscriptionConfiguration{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[55] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[62] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3990,7 +4516,7 @@ func (x *GraphQLSubscriptionConfiguration) String() string { func (*GraphQLSubscriptionConfiguration) ProtoMessage() {} func (x *GraphQLSubscriptionConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[55] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[62] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4003,7 +4529,7 @@ func (x *GraphQLSubscriptionConfiguration) ProtoReflect() protoreflect.Message { // Deprecated: Use GraphQLSubscriptionConfiguration.ProtoReflect.Descriptor instead. func (*GraphQLSubscriptionConfiguration) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{55} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{62} } func (x *GraphQLSubscriptionConfiguration) GetEnabled() bool { @@ -4051,7 +4577,7 @@ type GraphQLFederationConfiguration struct { func (x *GraphQLFederationConfiguration) Reset() { *x = GraphQLFederationConfiguration{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[56] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[63] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4063,7 +4589,7 @@ func (x *GraphQLFederationConfiguration) String() string { func (*GraphQLFederationConfiguration) ProtoMessage() {} func (x *GraphQLFederationConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[56] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[63] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4076,7 +4602,7 @@ func (x *GraphQLFederationConfiguration) ProtoReflect() protoreflect.Message { // Deprecated: Use GraphQLFederationConfiguration.ProtoReflect.Descriptor instead. func (*GraphQLFederationConfiguration) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{56} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{63} } func (x *GraphQLFederationConfiguration) GetEnabled() bool { @@ -4103,7 +4629,7 @@ type InternedString struct { func (x *InternedString) Reset() { *x = InternedString{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[57] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[64] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4115,7 +4641,7 @@ func (x *InternedString) String() string { func (*InternedString) ProtoMessage() {} func (x *InternedString) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[57] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[64] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4128,7 +4654,7 @@ func (x *InternedString) ProtoReflect() protoreflect.Message { // Deprecated: Use InternedString.ProtoReflect.Descriptor instead. func (*InternedString) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{57} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{64} } func (x *InternedString) GetKey() string { @@ -4148,7 +4674,7 @@ type SingleTypeField struct { func (x *SingleTypeField) Reset() { *x = SingleTypeField{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[58] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[65] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4160,7 +4686,7 @@ func (x *SingleTypeField) String() string { func (*SingleTypeField) ProtoMessage() {} func (x *SingleTypeField) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[58] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[65] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4173,7 +4699,7 @@ func (x *SingleTypeField) ProtoReflect() protoreflect.Message { // Deprecated: Use SingleTypeField.ProtoReflect.Descriptor instead. func (*SingleTypeField) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{58} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{65} } func (x *SingleTypeField) GetTypeName() string { @@ -4200,7 +4726,7 @@ type SubscriptionFieldCondition struct { func (x *SubscriptionFieldCondition) Reset() { *x = SubscriptionFieldCondition{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[59] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[66] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4212,7 +4738,7 @@ func (x *SubscriptionFieldCondition) String() string { func (*SubscriptionFieldCondition) ProtoMessage() {} func (x *SubscriptionFieldCondition) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[59] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[66] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4225,7 +4751,7 @@ func (x *SubscriptionFieldCondition) ProtoReflect() protoreflect.Message { // Deprecated: Use SubscriptionFieldCondition.ProtoReflect.Descriptor instead. func (*SubscriptionFieldCondition) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{59} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{66} } func (x *SubscriptionFieldCondition) GetFieldPath() []string { @@ -4254,7 +4780,7 @@ type SubscriptionFilterCondition struct { func (x *SubscriptionFilterCondition) Reset() { *x = SubscriptionFilterCondition{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[60] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[67] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4266,7 +4792,7 @@ func (x *SubscriptionFilterCondition) String() string { func (*SubscriptionFilterCondition) ProtoMessage() {} func (x *SubscriptionFilterCondition) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[60] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[67] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4279,7 +4805,7 @@ func (x *SubscriptionFilterCondition) ProtoReflect() protoreflect.Message { // Deprecated: Use SubscriptionFilterCondition.ProtoReflect.Descriptor instead. func (*SubscriptionFilterCondition) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{60} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{67} } func (x *SubscriptionFilterCondition) GetAnd() []*SubscriptionFilterCondition { @@ -4319,7 +4845,7 @@ type CacheWarmerOperations struct { func (x *CacheWarmerOperations) Reset() { *x = CacheWarmerOperations{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[61] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[68] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4331,7 +4857,7 @@ func (x *CacheWarmerOperations) String() string { func (*CacheWarmerOperations) ProtoMessage() {} func (x *CacheWarmerOperations) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[61] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[68] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4344,7 +4870,7 @@ func (x *CacheWarmerOperations) ProtoReflect() protoreflect.Message { // Deprecated: Use CacheWarmerOperations.ProtoReflect.Descriptor instead. func (*CacheWarmerOperations) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{61} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{68} } func (x *CacheWarmerOperations) GetOperations() []*Operation { @@ -4364,7 +4890,7 @@ type Operation struct { func (x *Operation) Reset() { *x = Operation{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[62] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[69] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4376,7 +4902,7 @@ func (x *Operation) String() string { func (*Operation) ProtoMessage() {} func (x *Operation) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[62] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[69] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4389,7 +4915,7 @@ func (x *Operation) ProtoReflect() protoreflect.Message { // Deprecated: Use Operation.ProtoReflect.Descriptor instead. func (*Operation) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{62} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{69} } func (x *Operation) GetRequest() *OperationRequest { @@ -4417,7 +4943,7 @@ type OperationRequest struct { func (x *OperationRequest) Reset() { *x = OperationRequest{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[63] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[70] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4429,7 +4955,7 @@ func (x *OperationRequest) String() string { func (*OperationRequest) ProtoMessage() {} func (x *OperationRequest) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[63] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[70] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4442,7 +4968,7 @@ func (x *OperationRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use OperationRequest.ProtoReflect.Descriptor instead. func (*OperationRequest) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{63} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{70} } func (x *OperationRequest) GetOperationName() string { @@ -4475,7 +5001,7 @@ type Extension struct { func (x *Extension) Reset() { *x = Extension{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[64] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[71] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4487,7 +5013,7 @@ func (x *Extension) String() string { func (*Extension) ProtoMessage() {} func (x *Extension) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[64] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[71] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4500,7 +5026,7 @@ func (x *Extension) ProtoReflect() protoreflect.Message { // Deprecated: Use Extension.ProtoReflect.Descriptor instead. func (*Extension) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{64} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{71} } func (x *Extension) GetPersistedQuery() *PersistedQuery { @@ -4520,7 +5046,7 @@ type PersistedQuery struct { func (x *PersistedQuery) Reset() { *x = PersistedQuery{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[65] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[72] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4532,7 +5058,7 @@ func (x *PersistedQuery) String() string { func (*PersistedQuery) ProtoMessage() {} func (x *PersistedQuery) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[65] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[72] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4545,7 +5071,7 @@ func (x *PersistedQuery) ProtoReflect() protoreflect.Message { // Deprecated: Use PersistedQuery.ProtoReflect.Descriptor instead. func (*PersistedQuery) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{65} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{72} } func (x *PersistedQuery) GetSha256Hash() string { @@ -4572,7 +5098,7 @@ type ClientInfo struct { func (x *ClientInfo) Reset() { *x = ClientInfo{} - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[66] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[73] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4584,7 +5110,7 @@ func (x *ClientInfo) String() string { func (*ClientInfo) ProtoMessage() {} func (x *ClientInfo) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[66] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[73] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4597,7 +5123,7 @@ func (x *ClientInfo) ProtoReflect() protoreflect.Message { // Deprecated: Use ClientInfo.ProtoReflect.Descriptor instead. func (*ClientInfo) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{66} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{73} } func (x *ClientInfo) GetName() string { @@ -4669,7 +5195,7 @@ const file_wg_cosmo_node_v1_node_proto_rawDesc = "" + "\x12StringStorageEntry\x12\x10\n" + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01B\x18\n" + - "\x16_graphql_client_schema\"\xce\b\n" + + "\x16_graphql_client_schema\"\x81\r\n" + "\x17DataSourceConfiguration\x124\n" + "\x04kind\x18\x01 \x01(\x0e2 .wg.cosmo.node.v1.DataSourceKindR\x04kind\x12:\n" + "\n" + @@ -4691,7 +5217,53 @@ const file_wg_cosmo_node_v1_node_proto_rawDesc = "" + "\rcustom_events\x18\r \x01(\v2(.wg.cosmo.node.v1.DataSourceCustomEventsR\fcustomEvents\x12[\n" + "\x11entity_interfaces\x18\x0e \x03(\v2..wg.cosmo.node.v1.EntityInterfaceConfigurationR\x10entityInterfaces\x12[\n" + "\x11interface_objects\x18\x0f \x03(\v2..wg.cosmo.node.v1.EntityInterfaceConfigurationR\x10interfaceObjects\x12R\n" + - "\x12cost_configuration\x18\x10 \x01(\v2#.wg.cosmo.node.v1.CostConfigurationR\x11costConfiguration\"\x98\x04\n" + + "\x12cost_configuration\x18\x10 \x01(\v2#.wg.cosmo.node.v1.CostConfigurationR\x11costConfiguration\x12j\n" + + "\x1bentity_cache_configurations\x18\x11 \x03(\v2*.wg.cosmo.node.v1.EntityCacheConfigurationR\x19entityCacheConfigurations\x12t\n" + + "\x1froot_field_cache_configurations\x18\x12 \x03(\v2-.wg.cosmo.node.v1.RootFieldCacheConfigurationR\x1crootFieldCacheConfigurations\x12p\n" + + "\x1dcache_populate_configurations\x18\x13 \x03(\v2,.wg.cosmo.node.v1.CachePopulateConfigurationR\x1bcachePopulateConfigurations\x12v\n" + + "\x1fcache_invalidate_configurations\x18\x14 \x03(\v2..wg.cosmo.node.v1.CacheInvalidateConfigurationR\x1dcacheInvalidateConfigurations\x12e\n" + + "\x15request_scoped_fields\x18\x15 \x03(\v21.wg.cosmo.node.v1.RequestScopedFieldConfigurationR\x13requestScopedFields\"\x88\x01\n" + + "\x1fRequestScopedFieldConfiguration\x12\x1d\n" + + "\n" + + "field_name\x18\x01 \x01(\tR\tfieldName\x12\x1b\n" + + "\ttype_name\x18\x02 \x01(\tR\btypeName\x12\x15\n" + + "\x06l1_key\x18\x03 \x01(\tR\x05l1KeyJ\x04\b\x04\x10\x05R\fresolve_from\"\xb1\x02\n" + + "\x18EntityCacheConfiguration\x12\x1b\n" + + "\ttype_name\x18\x01 \x01(\tR\btypeName\x12&\n" + + "\x0fmax_age_seconds\x18\x02 \x01(\x03R\rmaxAgeSeconds\x12'\n" + + "\x0finclude_headers\x18\x03 \x01(\bR\x0eincludeHeaders\x12,\n" + + "\x12partial_cache_load\x18\x04 \x01(\bR\x10partialCacheLoad\x12\x1f\n" + + "\vshadow_mode\x18\x05 \x01(\bR\n" + + "shadowMode\x12<\n" + + "\x1bnot_found_cache_ttl_seconds\x18\x06 \x01(\x03R\x17notFoundCacheTtlSecondsR\x1anegative_cache_ttl_seconds\"\xac\x02\n" + + "\x1bRootFieldCacheConfiguration\x12\x1d\n" + + "\n" + + "field_name\x18\x01 \x01(\tR\tfieldName\x12&\n" + + "\x0fmax_age_seconds\x18\x02 \x01(\x03R\rmaxAgeSeconds\x12'\n" + + "\x0finclude_headers\x18\x03 \x01(\bR\x0eincludeHeaders\x12\x1f\n" + + "\vshadow_mode\x18\x04 \x01(\bR\n" + + "shadowMode\x12(\n" + + "\x10entity_type_name\x18\x05 \x01(\tR\x0eentityTypeName\x12R\n" + + "\x13entity_key_mappings\x18\x06 \x03(\v2\".wg.cosmo.node.v1.EntityKeyMappingR\x11entityKeyMappings\"\x8e\x01\n" + + "\x10EntityKeyMapping\x12(\n" + + "\x10entity_type_name\x18\x01 \x01(\tR\x0eentityTypeName\x12P\n" + + "\x0efield_mappings\x18\x02 \x03(\v2).wg.cosmo.node.v1.EntityCacheFieldMappingR\rfieldMappings\"\x83\x01\n" + + "\x17EntityCacheFieldMapping\x12(\n" + + "\x10entity_key_field\x18\x01 \x01(\tR\x0eentityKeyField\x12#\n" + + "\rargument_path\x18\x02 \x03(\tR\fargumentPath\x12\x19\n" + + "\bis_batch\x18\x03 \x01(\bR\aisBatch\"\xcd\x01\n" + + "\x1aCachePopulateConfiguration\x12\x1d\n" + + "\n" + + "field_name\x18\x01 \x01(\tR\tfieldName\x12%\n" + + "\x0eoperation_type\x18\x02 \x01(\tR\roperationType\x12+\n" + + "\x0fmax_age_seconds\x18\x03 \x01(\x03H\x00R\rmaxAgeSeconds\x88\x01\x01\x12(\n" + + "\x10entity_type_name\x18\x04 \x01(\tR\x0eentityTypeNameB\x12\n" + + "\x10_max_age_seconds\"\x8e\x01\n" + + "\x1cCacheInvalidateConfiguration\x12\x1d\n" + + "\n" + + "field_name\x18\x01 \x01(\tR\tfieldName\x12%\n" + + "\x0eoperation_type\x18\x02 \x01(\tR\roperationType\x12(\n" + + "\x10entity_type_name\x18\x03 \x01(\tR\x0eentityTypeName\"\x98\x04\n" + "\x11CostConfiguration\x12O\n" + "\rfield_weights\x18\x01 \x03(\v2*.wg.cosmo.node.v1.FieldWeightConfigurationR\ffieldWeights\x12K\n" + "\n" + @@ -5030,7 +5602,7 @@ func file_wg_cosmo_node_v1_node_proto_rawDescGZIP() []byte { } var file_wg_cosmo_node_v1_node_proto_enumTypes = make([]protoimpl.EnumInfo, 8) -var file_wg_cosmo_node_v1_node_proto_msgTypes = make([]protoimpl.MessageInfo, 74) +var file_wg_cosmo_node_v1_node_proto_msgTypes = make([]protoimpl.MessageInfo, 81) var file_wg_cosmo_node_v1_node_proto_goTypes = []any{ (ArgumentRenderConfiguration)(0), // 0: wg.cosmo.node.v1.ArgumentRenderConfiguration (ArgumentSource)(0), // 1: wg.cosmo.node.v1.ArgumentSource @@ -5052,180 +5624,194 @@ var file_wg_cosmo_node_v1_node_proto_goTypes = []any{ (*SelfRegisterResponse)(nil), // 17: wg.cosmo.node.v1.SelfRegisterResponse (*EngineConfiguration)(nil), // 18: wg.cosmo.node.v1.EngineConfiguration (*DataSourceConfiguration)(nil), // 19: wg.cosmo.node.v1.DataSourceConfiguration - (*CostConfiguration)(nil), // 20: wg.cosmo.node.v1.CostConfiguration - (*FieldWeightConfiguration)(nil), // 21: wg.cosmo.node.v1.FieldWeightConfiguration - (*FieldListSizeConfiguration)(nil), // 22: wg.cosmo.node.v1.FieldListSizeConfiguration - (*ArgumentConfiguration)(nil), // 23: wg.cosmo.node.v1.ArgumentConfiguration - (*Scopes)(nil), // 24: wg.cosmo.node.v1.Scopes - (*AuthorizationConfiguration)(nil), // 25: wg.cosmo.node.v1.AuthorizationConfiguration - (*FieldConfiguration)(nil), // 26: wg.cosmo.node.v1.FieldConfiguration - (*TypeConfiguration)(nil), // 27: wg.cosmo.node.v1.TypeConfiguration - (*TypeField)(nil), // 28: wg.cosmo.node.v1.TypeField - (*FieldCoordinates)(nil), // 29: wg.cosmo.node.v1.FieldCoordinates - (*FieldSetCondition)(nil), // 30: wg.cosmo.node.v1.FieldSetCondition - (*RequiredField)(nil), // 31: wg.cosmo.node.v1.RequiredField - (*EntityInterfaceConfiguration)(nil), // 32: wg.cosmo.node.v1.EntityInterfaceConfiguration - (*FetchConfiguration)(nil), // 33: wg.cosmo.node.v1.FetchConfiguration - (*StatusCodeTypeMapping)(nil), // 34: wg.cosmo.node.v1.StatusCodeTypeMapping - (*DataSourceCustom_GraphQL)(nil), // 35: wg.cosmo.node.v1.DataSourceCustom_GraphQL - (*GRPCConfiguration)(nil), // 36: wg.cosmo.node.v1.GRPCConfiguration - (*ImageReference)(nil), // 37: wg.cosmo.node.v1.ImageReference - (*PluginConfiguration)(nil), // 38: wg.cosmo.node.v1.PluginConfiguration - (*SSLConfiguration)(nil), // 39: wg.cosmo.node.v1.SSLConfiguration - (*GRPCMapping)(nil), // 40: wg.cosmo.node.v1.GRPCMapping - (*LookupMapping)(nil), // 41: wg.cosmo.node.v1.LookupMapping - (*LookupFieldMapping)(nil), // 42: wg.cosmo.node.v1.LookupFieldMapping - (*OperationMapping)(nil), // 43: wg.cosmo.node.v1.OperationMapping - (*EntityMapping)(nil), // 44: wg.cosmo.node.v1.EntityMapping - (*RequiredFieldMapping)(nil), // 45: wg.cosmo.node.v1.RequiredFieldMapping - (*TypeFieldMapping)(nil), // 46: wg.cosmo.node.v1.TypeFieldMapping - (*FieldMapping)(nil), // 47: wg.cosmo.node.v1.FieldMapping - (*ArgumentMapping)(nil), // 48: wg.cosmo.node.v1.ArgumentMapping - (*EnumMapping)(nil), // 49: wg.cosmo.node.v1.EnumMapping - (*EnumValueMapping)(nil), // 50: wg.cosmo.node.v1.EnumValueMapping - (*NatsStreamConfiguration)(nil), // 51: wg.cosmo.node.v1.NatsStreamConfiguration - (*NatsEventConfiguration)(nil), // 52: wg.cosmo.node.v1.NatsEventConfiguration - (*KafkaEventConfiguration)(nil), // 53: wg.cosmo.node.v1.KafkaEventConfiguration - (*RedisEventConfiguration)(nil), // 54: wg.cosmo.node.v1.RedisEventConfiguration - (*EngineEventConfiguration)(nil), // 55: wg.cosmo.node.v1.EngineEventConfiguration - (*DataSourceCustomEvents)(nil), // 56: wg.cosmo.node.v1.DataSourceCustomEvents - (*DataSourceCustom_Static)(nil), // 57: wg.cosmo.node.v1.DataSourceCustom_Static - (*ConfigurationVariable)(nil), // 58: wg.cosmo.node.v1.ConfigurationVariable - (*DirectiveConfiguration)(nil), // 59: wg.cosmo.node.v1.DirectiveConfiguration - (*URLQueryConfiguration)(nil), // 60: wg.cosmo.node.v1.URLQueryConfiguration - (*HTTPHeader)(nil), // 61: wg.cosmo.node.v1.HTTPHeader - (*MTLSConfiguration)(nil), // 62: wg.cosmo.node.v1.MTLSConfiguration - (*GraphQLSubscriptionConfiguration)(nil), // 63: wg.cosmo.node.v1.GraphQLSubscriptionConfiguration - (*GraphQLFederationConfiguration)(nil), // 64: wg.cosmo.node.v1.GraphQLFederationConfiguration - (*InternedString)(nil), // 65: wg.cosmo.node.v1.InternedString - (*SingleTypeField)(nil), // 66: wg.cosmo.node.v1.SingleTypeField - (*SubscriptionFieldCondition)(nil), // 67: wg.cosmo.node.v1.SubscriptionFieldCondition - (*SubscriptionFilterCondition)(nil), // 68: wg.cosmo.node.v1.SubscriptionFilterCondition - (*CacheWarmerOperations)(nil), // 69: wg.cosmo.node.v1.CacheWarmerOperations - (*Operation)(nil), // 70: wg.cosmo.node.v1.Operation - (*OperationRequest)(nil), // 71: wg.cosmo.node.v1.OperationRequest - (*Extension)(nil), // 72: wg.cosmo.node.v1.Extension - (*PersistedQuery)(nil), // 73: wg.cosmo.node.v1.PersistedQuery - (*ClientInfo)(nil), // 74: wg.cosmo.node.v1.ClientInfo - nil, // 75: wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs.ConfigByFeatureFlagNameEntry - nil, // 76: wg.cosmo.node.v1.EngineConfiguration.StringStorageEntry - nil, // 77: wg.cosmo.node.v1.CostConfiguration.TypeWeightsEntry - nil, // 78: wg.cosmo.node.v1.CostConfiguration.DirectiveArgumentWeightsEntry - nil, // 79: wg.cosmo.node.v1.FieldWeightConfiguration.ArgumentWeightsEntry - nil, // 80: wg.cosmo.node.v1.FieldWeightConfiguration.DirectiveArgumentWeightsEntry - nil, // 81: wg.cosmo.node.v1.FetchConfiguration.HeaderEntry - (common.EnumStatusCode)(0), // 82: wg.cosmo.common.EnumStatusCode - (common.GraphQLSubscriptionProtocol)(0), // 83: wg.cosmo.common.GraphQLSubscriptionProtocol - (common.GraphQLWebsocketSubprotocol)(0), // 84: wg.cosmo.common.GraphQLWebsocketSubprotocol + (*RequestScopedFieldConfiguration)(nil), // 20: wg.cosmo.node.v1.RequestScopedFieldConfiguration + (*EntityCacheConfiguration)(nil), // 21: wg.cosmo.node.v1.EntityCacheConfiguration + (*RootFieldCacheConfiguration)(nil), // 22: wg.cosmo.node.v1.RootFieldCacheConfiguration + (*EntityKeyMapping)(nil), // 23: wg.cosmo.node.v1.EntityKeyMapping + (*EntityCacheFieldMapping)(nil), // 24: wg.cosmo.node.v1.EntityCacheFieldMapping + (*CachePopulateConfiguration)(nil), // 25: wg.cosmo.node.v1.CachePopulateConfiguration + (*CacheInvalidateConfiguration)(nil), // 26: wg.cosmo.node.v1.CacheInvalidateConfiguration + (*CostConfiguration)(nil), // 27: wg.cosmo.node.v1.CostConfiguration + (*FieldWeightConfiguration)(nil), // 28: wg.cosmo.node.v1.FieldWeightConfiguration + (*FieldListSizeConfiguration)(nil), // 29: wg.cosmo.node.v1.FieldListSizeConfiguration + (*ArgumentConfiguration)(nil), // 30: wg.cosmo.node.v1.ArgumentConfiguration + (*Scopes)(nil), // 31: wg.cosmo.node.v1.Scopes + (*AuthorizationConfiguration)(nil), // 32: wg.cosmo.node.v1.AuthorizationConfiguration + (*FieldConfiguration)(nil), // 33: wg.cosmo.node.v1.FieldConfiguration + (*TypeConfiguration)(nil), // 34: wg.cosmo.node.v1.TypeConfiguration + (*TypeField)(nil), // 35: wg.cosmo.node.v1.TypeField + (*FieldCoordinates)(nil), // 36: wg.cosmo.node.v1.FieldCoordinates + (*FieldSetCondition)(nil), // 37: wg.cosmo.node.v1.FieldSetCondition + (*RequiredField)(nil), // 38: wg.cosmo.node.v1.RequiredField + (*EntityInterfaceConfiguration)(nil), // 39: wg.cosmo.node.v1.EntityInterfaceConfiguration + (*FetchConfiguration)(nil), // 40: wg.cosmo.node.v1.FetchConfiguration + (*StatusCodeTypeMapping)(nil), // 41: wg.cosmo.node.v1.StatusCodeTypeMapping + (*DataSourceCustom_GraphQL)(nil), // 42: wg.cosmo.node.v1.DataSourceCustom_GraphQL + (*GRPCConfiguration)(nil), // 43: wg.cosmo.node.v1.GRPCConfiguration + (*ImageReference)(nil), // 44: wg.cosmo.node.v1.ImageReference + (*PluginConfiguration)(nil), // 45: wg.cosmo.node.v1.PluginConfiguration + (*SSLConfiguration)(nil), // 46: wg.cosmo.node.v1.SSLConfiguration + (*GRPCMapping)(nil), // 47: wg.cosmo.node.v1.GRPCMapping + (*LookupMapping)(nil), // 48: wg.cosmo.node.v1.LookupMapping + (*LookupFieldMapping)(nil), // 49: wg.cosmo.node.v1.LookupFieldMapping + (*OperationMapping)(nil), // 50: wg.cosmo.node.v1.OperationMapping + (*EntityMapping)(nil), // 51: wg.cosmo.node.v1.EntityMapping + (*RequiredFieldMapping)(nil), // 52: wg.cosmo.node.v1.RequiredFieldMapping + (*TypeFieldMapping)(nil), // 53: wg.cosmo.node.v1.TypeFieldMapping + (*FieldMapping)(nil), // 54: wg.cosmo.node.v1.FieldMapping + (*ArgumentMapping)(nil), // 55: wg.cosmo.node.v1.ArgumentMapping + (*EnumMapping)(nil), // 56: wg.cosmo.node.v1.EnumMapping + (*EnumValueMapping)(nil), // 57: wg.cosmo.node.v1.EnumValueMapping + (*NatsStreamConfiguration)(nil), // 58: wg.cosmo.node.v1.NatsStreamConfiguration + (*NatsEventConfiguration)(nil), // 59: wg.cosmo.node.v1.NatsEventConfiguration + (*KafkaEventConfiguration)(nil), // 60: wg.cosmo.node.v1.KafkaEventConfiguration + (*RedisEventConfiguration)(nil), // 61: wg.cosmo.node.v1.RedisEventConfiguration + (*EngineEventConfiguration)(nil), // 62: wg.cosmo.node.v1.EngineEventConfiguration + (*DataSourceCustomEvents)(nil), // 63: wg.cosmo.node.v1.DataSourceCustomEvents + (*DataSourceCustom_Static)(nil), // 64: wg.cosmo.node.v1.DataSourceCustom_Static + (*ConfigurationVariable)(nil), // 65: wg.cosmo.node.v1.ConfigurationVariable + (*DirectiveConfiguration)(nil), // 66: wg.cosmo.node.v1.DirectiveConfiguration + (*URLQueryConfiguration)(nil), // 67: wg.cosmo.node.v1.URLQueryConfiguration + (*HTTPHeader)(nil), // 68: wg.cosmo.node.v1.HTTPHeader + (*MTLSConfiguration)(nil), // 69: wg.cosmo.node.v1.MTLSConfiguration + (*GraphQLSubscriptionConfiguration)(nil), // 70: wg.cosmo.node.v1.GraphQLSubscriptionConfiguration + (*GraphQLFederationConfiguration)(nil), // 71: wg.cosmo.node.v1.GraphQLFederationConfiguration + (*InternedString)(nil), // 72: wg.cosmo.node.v1.InternedString + (*SingleTypeField)(nil), // 73: wg.cosmo.node.v1.SingleTypeField + (*SubscriptionFieldCondition)(nil), // 74: wg.cosmo.node.v1.SubscriptionFieldCondition + (*SubscriptionFilterCondition)(nil), // 75: wg.cosmo.node.v1.SubscriptionFilterCondition + (*CacheWarmerOperations)(nil), // 76: wg.cosmo.node.v1.CacheWarmerOperations + (*Operation)(nil), // 77: wg.cosmo.node.v1.Operation + (*OperationRequest)(nil), // 78: wg.cosmo.node.v1.OperationRequest + (*Extension)(nil), // 79: wg.cosmo.node.v1.Extension + (*PersistedQuery)(nil), // 80: wg.cosmo.node.v1.PersistedQuery + (*ClientInfo)(nil), // 81: wg.cosmo.node.v1.ClientInfo + nil, // 82: wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs.ConfigByFeatureFlagNameEntry + nil, // 83: wg.cosmo.node.v1.EngineConfiguration.StringStorageEntry + nil, // 84: wg.cosmo.node.v1.CostConfiguration.TypeWeightsEntry + nil, // 85: wg.cosmo.node.v1.CostConfiguration.DirectiveArgumentWeightsEntry + nil, // 86: wg.cosmo.node.v1.FieldWeightConfiguration.ArgumentWeightsEntry + nil, // 87: wg.cosmo.node.v1.FieldWeightConfiguration.DirectiveArgumentWeightsEntry + nil, // 88: wg.cosmo.node.v1.FetchConfiguration.HeaderEntry + (common.EnumStatusCode)(0), // 89: wg.cosmo.common.EnumStatusCode + (common.GraphQLSubscriptionProtocol)(0), // 90: wg.cosmo.common.GraphQLSubscriptionProtocol + (common.GraphQLWebsocketSubprotocol)(0), // 91: wg.cosmo.common.GraphQLWebsocketSubprotocol } var file_wg_cosmo_node_v1_node_proto_depIdxs = []int32{ - 75, // 0: wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs.config_by_feature_flag_name:type_name -> wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs.ConfigByFeatureFlagNameEntry + 82, // 0: wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs.config_by_feature_flag_name:type_name -> wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs.ConfigByFeatureFlagNameEntry 18, // 1: wg.cosmo.node.v1.FeatureFlagRouterExecutionConfig.engine_config:type_name -> wg.cosmo.node.v1.EngineConfiguration 8, // 2: wg.cosmo.node.v1.FeatureFlagRouterExecutionConfig.subgraphs:type_name -> wg.cosmo.node.v1.Subgraph 18, // 3: wg.cosmo.node.v1.RouterConfig.engine_config:type_name -> wg.cosmo.node.v1.EngineConfiguration 8, // 4: wg.cosmo.node.v1.RouterConfig.subgraphs:type_name -> wg.cosmo.node.v1.Subgraph 9, // 5: wg.cosmo.node.v1.RouterConfig.feature_flag_configs:type_name -> wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs - 82, // 6: wg.cosmo.node.v1.Response.code:type_name -> wg.cosmo.common.EnumStatusCode + 89, // 6: wg.cosmo.node.v1.Response.code:type_name -> wg.cosmo.common.EnumStatusCode 15, // 7: wg.cosmo.node.v1.RegistrationInfo.account_limits:type_name -> wg.cosmo.node.v1.AccountLimits 12, // 8: wg.cosmo.node.v1.SelfRegisterResponse.response:type_name -> wg.cosmo.node.v1.Response 14, // 9: wg.cosmo.node.v1.SelfRegisterResponse.registrationInfo:type_name -> wg.cosmo.node.v1.RegistrationInfo 19, // 10: wg.cosmo.node.v1.EngineConfiguration.datasource_configurations:type_name -> wg.cosmo.node.v1.DataSourceConfiguration - 26, // 11: wg.cosmo.node.v1.EngineConfiguration.field_configurations:type_name -> wg.cosmo.node.v1.FieldConfiguration - 27, // 12: wg.cosmo.node.v1.EngineConfiguration.type_configurations:type_name -> wg.cosmo.node.v1.TypeConfiguration - 76, // 13: wg.cosmo.node.v1.EngineConfiguration.string_storage:type_name -> wg.cosmo.node.v1.EngineConfiguration.StringStorageEntry + 33, // 11: wg.cosmo.node.v1.EngineConfiguration.field_configurations:type_name -> wg.cosmo.node.v1.FieldConfiguration + 34, // 12: wg.cosmo.node.v1.EngineConfiguration.type_configurations:type_name -> wg.cosmo.node.v1.TypeConfiguration + 83, // 13: wg.cosmo.node.v1.EngineConfiguration.string_storage:type_name -> wg.cosmo.node.v1.EngineConfiguration.StringStorageEntry 2, // 14: wg.cosmo.node.v1.DataSourceConfiguration.kind:type_name -> wg.cosmo.node.v1.DataSourceKind - 28, // 15: wg.cosmo.node.v1.DataSourceConfiguration.root_nodes:type_name -> wg.cosmo.node.v1.TypeField - 28, // 16: wg.cosmo.node.v1.DataSourceConfiguration.child_nodes:type_name -> wg.cosmo.node.v1.TypeField - 35, // 17: wg.cosmo.node.v1.DataSourceConfiguration.custom_graphql:type_name -> wg.cosmo.node.v1.DataSourceCustom_GraphQL - 57, // 18: wg.cosmo.node.v1.DataSourceConfiguration.custom_static:type_name -> wg.cosmo.node.v1.DataSourceCustom_Static - 59, // 19: wg.cosmo.node.v1.DataSourceConfiguration.directives:type_name -> wg.cosmo.node.v1.DirectiveConfiguration - 31, // 20: wg.cosmo.node.v1.DataSourceConfiguration.keys:type_name -> wg.cosmo.node.v1.RequiredField - 31, // 21: wg.cosmo.node.v1.DataSourceConfiguration.provides:type_name -> wg.cosmo.node.v1.RequiredField - 31, // 22: wg.cosmo.node.v1.DataSourceConfiguration.requires:type_name -> wg.cosmo.node.v1.RequiredField - 56, // 23: wg.cosmo.node.v1.DataSourceConfiguration.custom_events:type_name -> wg.cosmo.node.v1.DataSourceCustomEvents - 32, // 24: wg.cosmo.node.v1.DataSourceConfiguration.entity_interfaces:type_name -> wg.cosmo.node.v1.EntityInterfaceConfiguration - 32, // 25: wg.cosmo.node.v1.DataSourceConfiguration.interface_objects:type_name -> wg.cosmo.node.v1.EntityInterfaceConfiguration - 20, // 26: wg.cosmo.node.v1.DataSourceConfiguration.cost_configuration:type_name -> wg.cosmo.node.v1.CostConfiguration - 21, // 27: wg.cosmo.node.v1.CostConfiguration.field_weights:type_name -> wg.cosmo.node.v1.FieldWeightConfiguration - 22, // 28: wg.cosmo.node.v1.CostConfiguration.list_sizes:type_name -> wg.cosmo.node.v1.FieldListSizeConfiguration - 77, // 29: wg.cosmo.node.v1.CostConfiguration.type_weights:type_name -> wg.cosmo.node.v1.CostConfiguration.TypeWeightsEntry - 78, // 30: wg.cosmo.node.v1.CostConfiguration.directive_argument_weights:type_name -> wg.cosmo.node.v1.CostConfiguration.DirectiveArgumentWeightsEntry - 79, // 31: wg.cosmo.node.v1.FieldWeightConfiguration.argument_weights:type_name -> wg.cosmo.node.v1.FieldWeightConfiguration.ArgumentWeightsEntry - 80, // 32: wg.cosmo.node.v1.FieldWeightConfiguration.directive_argument_weights:type_name -> wg.cosmo.node.v1.FieldWeightConfiguration.DirectiveArgumentWeightsEntry - 1, // 33: wg.cosmo.node.v1.ArgumentConfiguration.source_type:type_name -> wg.cosmo.node.v1.ArgumentSource - 24, // 34: wg.cosmo.node.v1.AuthorizationConfiguration.required_or_scopes:type_name -> wg.cosmo.node.v1.Scopes - 24, // 35: wg.cosmo.node.v1.AuthorizationConfiguration.required_or_scopes_by_or:type_name -> wg.cosmo.node.v1.Scopes - 23, // 36: wg.cosmo.node.v1.FieldConfiguration.arguments_configuration:type_name -> wg.cosmo.node.v1.ArgumentConfiguration - 25, // 37: wg.cosmo.node.v1.FieldConfiguration.authorization_configuration:type_name -> wg.cosmo.node.v1.AuthorizationConfiguration - 68, // 38: wg.cosmo.node.v1.FieldConfiguration.subscription_filter_condition:type_name -> wg.cosmo.node.v1.SubscriptionFilterCondition - 29, // 39: wg.cosmo.node.v1.FieldSetCondition.field_coordinates_path:type_name -> wg.cosmo.node.v1.FieldCoordinates - 30, // 40: wg.cosmo.node.v1.RequiredField.conditions:type_name -> wg.cosmo.node.v1.FieldSetCondition - 58, // 41: wg.cosmo.node.v1.FetchConfiguration.url:type_name -> wg.cosmo.node.v1.ConfigurationVariable - 7, // 42: wg.cosmo.node.v1.FetchConfiguration.method:type_name -> wg.cosmo.node.v1.HTTPMethod - 81, // 43: wg.cosmo.node.v1.FetchConfiguration.header:type_name -> wg.cosmo.node.v1.FetchConfiguration.HeaderEntry - 58, // 44: wg.cosmo.node.v1.FetchConfiguration.body:type_name -> wg.cosmo.node.v1.ConfigurationVariable - 60, // 45: wg.cosmo.node.v1.FetchConfiguration.query:type_name -> wg.cosmo.node.v1.URLQueryConfiguration - 62, // 46: wg.cosmo.node.v1.FetchConfiguration.mtls:type_name -> wg.cosmo.node.v1.MTLSConfiguration - 58, // 47: wg.cosmo.node.v1.FetchConfiguration.base_url:type_name -> wg.cosmo.node.v1.ConfigurationVariable - 58, // 48: wg.cosmo.node.v1.FetchConfiguration.path:type_name -> wg.cosmo.node.v1.ConfigurationVariable - 58, // 49: wg.cosmo.node.v1.FetchConfiguration.http_proxy_url:type_name -> wg.cosmo.node.v1.ConfigurationVariable - 33, // 50: wg.cosmo.node.v1.DataSourceCustom_GraphQL.fetch:type_name -> wg.cosmo.node.v1.FetchConfiguration - 63, // 51: wg.cosmo.node.v1.DataSourceCustom_GraphQL.subscription:type_name -> wg.cosmo.node.v1.GraphQLSubscriptionConfiguration - 64, // 52: wg.cosmo.node.v1.DataSourceCustom_GraphQL.federation:type_name -> wg.cosmo.node.v1.GraphQLFederationConfiguration - 65, // 53: wg.cosmo.node.v1.DataSourceCustom_GraphQL.upstream_schema:type_name -> wg.cosmo.node.v1.InternedString - 66, // 54: wg.cosmo.node.v1.DataSourceCustom_GraphQL.custom_scalar_type_fields:type_name -> wg.cosmo.node.v1.SingleTypeField - 36, // 55: wg.cosmo.node.v1.DataSourceCustom_GraphQL.grpc:type_name -> wg.cosmo.node.v1.GRPCConfiguration - 40, // 56: wg.cosmo.node.v1.GRPCConfiguration.mapping:type_name -> wg.cosmo.node.v1.GRPCMapping - 38, // 57: wg.cosmo.node.v1.GRPCConfiguration.plugin:type_name -> wg.cosmo.node.v1.PluginConfiguration - 37, // 58: wg.cosmo.node.v1.PluginConfiguration.image_reference:type_name -> wg.cosmo.node.v1.ImageReference - 43, // 59: wg.cosmo.node.v1.GRPCMapping.operation_mappings:type_name -> wg.cosmo.node.v1.OperationMapping - 44, // 60: wg.cosmo.node.v1.GRPCMapping.entity_mappings:type_name -> wg.cosmo.node.v1.EntityMapping - 46, // 61: wg.cosmo.node.v1.GRPCMapping.type_field_mappings:type_name -> wg.cosmo.node.v1.TypeFieldMapping - 49, // 62: wg.cosmo.node.v1.GRPCMapping.enum_mappings:type_name -> wg.cosmo.node.v1.EnumMapping - 41, // 63: wg.cosmo.node.v1.GRPCMapping.resolve_mappings:type_name -> wg.cosmo.node.v1.LookupMapping - 3, // 64: wg.cosmo.node.v1.LookupMapping.type:type_name -> wg.cosmo.node.v1.LookupType - 42, // 65: wg.cosmo.node.v1.LookupMapping.lookup_mapping:type_name -> wg.cosmo.node.v1.LookupFieldMapping - 47, // 66: wg.cosmo.node.v1.LookupFieldMapping.field_mapping:type_name -> wg.cosmo.node.v1.FieldMapping - 4, // 67: wg.cosmo.node.v1.OperationMapping.type:type_name -> wg.cosmo.node.v1.OperationType - 45, // 68: wg.cosmo.node.v1.EntityMapping.required_field_mappings:type_name -> wg.cosmo.node.v1.RequiredFieldMapping - 47, // 69: wg.cosmo.node.v1.RequiredFieldMapping.field_mapping:type_name -> wg.cosmo.node.v1.FieldMapping - 47, // 70: wg.cosmo.node.v1.TypeFieldMapping.field_mappings:type_name -> wg.cosmo.node.v1.FieldMapping - 48, // 71: wg.cosmo.node.v1.FieldMapping.argument_mappings:type_name -> wg.cosmo.node.v1.ArgumentMapping - 50, // 72: wg.cosmo.node.v1.EnumMapping.values:type_name -> wg.cosmo.node.v1.EnumValueMapping - 55, // 73: wg.cosmo.node.v1.NatsEventConfiguration.engine_event_configuration:type_name -> wg.cosmo.node.v1.EngineEventConfiguration - 51, // 74: wg.cosmo.node.v1.NatsEventConfiguration.stream_configuration:type_name -> wg.cosmo.node.v1.NatsStreamConfiguration - 55, // 75: wg.cosmo.node.v1.KafkaEventConfiguration.engine_event_configuration:type_name -> wg.cosmo.node.v1.EngineEventConfiguration - 55, // 76: wg.cosmo.node.v1.RedisEventConfiguration.engine_event_configuration:type_name -> wg.cosmo.node.v1.EngineEventConfiguration - 5, // 77: wg.cosmo.node.v1.EngineEventConfiguration.type:type_name -> wg.cosmo.node.v1.EventType - 52, // 78: wg.cosmo.node.v1.DataSourceCustomEvents.nats:type_name -> wg.cosmo.node.v1.NatsEventConfiguration - 53, // 79: wg.cosmo.node.v1.DataSourceCustomEvents.kafka:type_name -> wg.cosmo.node.v1.KafkaEventConfiguration - 54, // 80: wg.cosmo.node.v1.DataSourceCustomEvents.redis:type_name -> wg.cosmo.node.v1.RedisEventConfiguration - 58, // 81: wg.cosmo.node.v1.DataSourceCustom_Static.data:type_name -> wg.cosmo.node.v1.ConfigurationVariable - 6, // 82: wg.cosmo.node.v1.ConfigurationVariable.kind:type_name -> wg.cosmo.node.v1.ConfigurationVariableKind - 58, // 83: wg.cosmo.node.v1.HTTPHeader.values:type_name -> wg.cosmo.node.v1.ConfigurationVariable - 58, // 84: wg.cosmo.node.v1.MTLSConfiguration.key:type_name -> wg.cosmo.node.v1.ConfigurationVariable - 58, // 85: wg.cosmo.node.v1.MTLSConfiguration.cert:type_name -> wg.cosmo.node.v1.ConfigurationVariable - 58, // 86: wg.cosmo.node.v1.GraphQLSubscriptionConfiguration.url:type_name -> wg.cosmo.node.v1.ConfigurationVariable - 83, // 87: wg.cosmo.node.v1.GraphQLSubscriptionConfiguration.protocol:type_name -> wg.cosmo.common.GraphQLSubscriptionProtocol - 84, // 88: wg.cosmo.node.v1.GraphQLSubscriptionConfiguration.websocketSubprotocol:type_name -> wg.cosmo.common.GraphQLWebsocketSubprotocol - 68, // 89: wg.cosmo.node.v1.SubscriptionFilterCondition.and:type_name -> wg.cosmo.node.v1.SubscriptionFilterCondition - 67, // 90: wg.cosmo.node.v1.SubscriptionFilterCondition.in:type_name -> wg.cosmo.node.v1.SubscriptionFieldCondition - 68, // 91: wg.cosmo.node.v1.SubscriptionFilterCondition.not:type_name -> wg.cosmo.node.v1.SubscriptionFilterCondition - 68, // 92: wg.cosmo.node.v1.SubscriptionFilterCondition.or:type_name -> wg.cosmo.node.v1.SubscriptionFilterCondition - 70, // 93: wg.cosmo.node.v1.CacheWarmerOperations.operations:type_name -> wg.cosmo.node.v1.Operation - 71, // 94: wg.cosmo.node.v1.Operation.request:type_name -> wg.cosmo.node.v1.OperationRequest - 74, // 95: wg.cosmo.node.v1.Operation.client:type_name -> wg.cosmo.node.v1.ClientInfo - 72, // 96: wg.cosmo.node.v1.OperationRequest.extensions:type_name -> wg.cosmo.node.v1.Extension - 73, // 97: wg.cosmo.node.v1.Extension.persisted_query:type_name -> wg.cosmo.node.v1.PersistedQuery - 10, // 98: wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs.ConfigByFeatureFlagNameEntry.value:type_name -> wg.cosmo.node.v1.FeatureFlagRouterExecutionConfig - 61, // 99: wg.cosmo.node.v1.FetchConfiguration.HeaderEntry.value:type_name -> wg.cosmo.node.v1.HTTPHeader - 16, // 100: wg.cosmo.node.v1.NodeService.SelfRegister:input_type -> wg.cosmo.node.v1.SelfRegisterRequest - 17, // 101: wg.cosmo.node.v1.NodeService.SelfRegister:output_type -> wg.cosmo.node.v1.SelfRegisterResponse - 101, // [101:102] is the sub-list for method output_type - 100, // [100:101] is the sub-list for method input_type - 100, // [100:100] is the sub-list for extension type_name - 100, // [100:100] is the sub-list for extension extendee - 0, // [0:100] is the sub-list for field type_name + 35, // 15: wg.cosmo.node.v1.DataSourceConfiguration.root_nodes:type_name -> wg.cosmo.node.v1.TypeField + 35, // 16: wg.cosmo.node.v1.DataSourceConfiguration.child_nodes:type_name -> wg.cosmo.node.v1.TypeField + 42, // 17: wg.cosmo.node.v1.DataSourceConfiguration.custom_graphql:type_name -> wg.cosmo.node.v1.DataSourceCustom_GraphQL + 64, // 18: wg.cosmo.node.v1.DataSourceConfiguration.custom_static:type_name -> wg.cosmo.node.v1.DataSourceCustom_Static + 66, // 19: wg.cosmo.node.v1.DataSourceConfiguration.directives:type_name -> wg.cosmo.node.v1.DirectiveConfiguration + 38, // 20: wg.cosmo.node.v1.DataSourceConfiguration.keys:type_name -> wg.cosmo.node.v1.RequiredField + 38, // 21: wg.cosmo.node.v1.DataSourceConfiguration.provides:type_name -> wg.cosmo.node.v1.RequiredField + 38, // 22: wg.cosmo.node.v1.DataSourceConfiguration.requires:type_name -> wg.cosmo.node.v1.RequiredField + 63, // 23: wg.cosmo.node.v1.DataSourceConfiguration.custom_events:type_name -> wg.cosmo.node.v1.DataSourceCustomEvents + 39, // 24: wg.cosmo.node.v1.DataSourceConfiguration.entity_interfaces:type_name -> wg.cosmo.node.v1.EntityInterfaceConfiguration + 39, // 25: wg.cosmo.node.v1.DataSourceConfiguration.interface_objects:type_name -> wg.cosmo.node.v1.EntityInterfaceConfiguration + 27, // 26: wg.cosmo.node.v1.DataSourceConfiguration.cost_configuration:type_name -> wg.cosmo.node.v1.CostConfiguration + 21, // 27: wg.cosmo.node.v1.DataSourceConfiguration.entity_cache_configurations:type_name -> wg.cosmo.node.v1.EntityCacheConfiguration + 22, // 28: wg.cosmo.node.v1.DataSourceConfiguration.root_field_cache_configurations:type_name -> wg.cosmo.node.v1.RootFieldCacheConfiguration + 25, // 29: wg.cosmo.node.v1.DataSourceConfiguration.cache_populate_configurations:type_name -> wg.cosmo.node.v1.CachePopulateConfiguration + 26, // 30: wg.cosmo.node.v1.DataSourceConfiguration.cache_invalidate_configurations:type_name -> wg.cosmo.node.v1.CacheInvalidateConfiguration + 20, // 31: wg.cosmo.node.v1.DataSourceConfiguration.request_scoped_fields:type_name -> wg.cosmo.node.v1.RequestScopedFieldConfiguration + 23, // 32: wg.cosmo.node.v1.RootFieldCacheConfiguration.entity_key_mappings:type_name -> wg.cosmo.node.v1.EntityKeyMapping + 24, // 33: wg.cosmo.node.v1.EntityKeyMapping.field_mappings:type_name -> wg.cosmo.node.v1.EntityCacheFieldMapping + 28, // 34: wg.cosmo.node.v1.CostConfiguration.field_weights:type_name -> wg.cosmo.node.v1.FieldWeightConfiguration + 29, // 35: wg.cosmo.node.v1.CostConfiguration.list_sizes:type_name -> wg.cosmo.node.v1.FieldListSizeConfiguration + 84, // 36: wg.cosmo.node.v1.CostConfiguration.type_weights:type_name -> wg.cosmo.node.v1.CostConfiguration.TypeWeightsEntry + 85, // 37: wg.cosmo.node.v1.CostConfiguration.directive_argument_weights:type_name -> wg.cosmo.node.v1.CostConfiguration.DirectiveArgumentWeightsEntry + 86, // 38: wg.cosmo.node.v1.FieldWeightConfiguration.argument_weights:type_name -> wg.cosmo.node.v1.FieldWeightConfiguration.ArgumentWeightsEntry + 87, // 39: wg.cosmo.node.v1.FieldWeightConfiguration.directive_argument_weights:type_name -> wg.cosmo.node.v1.FieldWeightConfiguration.DirectiveArgumentWeightsEntry + 1, // 40: wg.cosmo.node.v1.ArgumentConfiguration.source_type:type_name -> wg.cosmo.node.v1.ArgumentSource + 31, // 41: wg.cosmo.node.v1.AuthorizationConfiguration.required_or_scopes:type_name -> wg.cosmo.node.v1.Scopes + 31, // 42: wg.cosmo.node.v1.AuthorizationConfiguration.required_or_scopes_by_or:type_name -> wg.cosmo.node.v1.Scopes + 30, // 43: wg.cosmo.node.v1.FieldConfiguration.arguments_configuration:type_name -> wg.cosmo.node.v1.ArgumentConfiguration + 32, // 44: wg.cosmo.node.v1.FieldConfiguration.authorization_configuration:type_name -> wg.cosmo.node.v1.AuthorizationConfiguration + 75, // 45: wg.cosmo.node.v1.FieldConfiguration.subscription_filter_condition:type_name -> wg.cosmo.node.v1.SubscriptionFilterCondition + 36, // 46: wg.cosmo.node.v1.FieldSetCondition.field_coordinates_path:type_name -> wg.cosmo.node.v1.FieldCoordinates + 37, // 47: wg.cosmo.node.v1.RequiredField.conditions:type_name -> wg.cosmo.node.v1.FieldSetCondition + 65, // 48: wg.cosmo.node.v1.FetchConfiguration.url:type_name -> wg.cosmo.node.v1.ConfigurationVariable + 7, // 49: wg.cosmo.node.v1.FetchConfiguration.method:type_name -> wg.cosmo.node.v1.HTTPMethod + 88, // 50: wg.cosmo.node.v1.FetchConfiguration.header:type_name -> wg.cosmo.node.v1.FetchConfiguration.HeaderEntry + 65, // 51: wg.cosmo.node.v1.FetchConfiguration.body:type_name -> wg.cosmo.node.v1.ConfigurationVariable + 67, // 52: wg.cosmo.node.v1.FetchConfiguration.query:type_name -> wg.cosmo.node.v1.URLQueryConfiguration + 69, // 53: wg.cosmo.node.v1.FetchConfiguration.mtls:type_name -> wg.cosmo.node.v1.MTLSConfiguration + 65, // 54: wg.cosmo.node.v1.FetchConfiguration.base_url:type_name -> wg.cosmo.node.v1.ConfigurationVariable + 65, // 55: wg.cosmo.node.v1.FetchConfiguration.path:type_name -> wg.cosmo.node.v1.ConfigurationVariable + 65, // 56: wg.cosmo.node.v1.FetchConfiguration.http_proxy_url:type_name -> wg.cosmo.node.v1.ConfigurationVariable + 40, // 57: wg.cosmo.node.v1.DataSourceCustom_GraphQL.fetch:type_name -> wg.cosmo.node.v1.FetchConfiguration + 70, // 58: wg.cosmo.node.v1.DataSourceCustom_GraphQL.subscription:type_name -> wg.cosmo.node.v1.GraphQLSubscriptionConfiguration + 71, // 59: wg.cosmo.node.v1.DataSourceCustom_GraphQL.federation:type_name -> wg.cosmo.node.v1.GraphQLFederationConfiguration + 72, // 60: wg.cosmo.node.v1.DataSourceCustom_GraphQL.upstream_schema:type_name -> wg.cosmo.node.v1.InternedString + 73, // 61: wg.cosmo.node.v1.DataSourceCustom_GraphQL.custom_scalar_type_fields:type_name -> wg.cosmo.node.v1.SingleTypeField + 43, // 62: wg.cosmo.node.v1.DataSourceCustom_GraphQL.grpc:type_name -> wg.cosmo.node.v1.GRPCConfiguration + 47, // 63: wg.cosmo.node.v1.GRPCConfiguration.mapping:type_name -> wg.cosmo.node.v1.GRPCMapping + 45, // 64: wg.cosmo.node.v1.GRPCConfiguration.plugin:type_name -> wg.cosmo.node.v1.PluginConfiguration + 44, // 65: wg.cosmo.node.v1.PluginConfiguration.image_reference:type_name -> wg.cosmo.node.v1.ImageReference + 50, // 66: wg.cosmo.node.v1.GRPCMapping.operation_mappings:type_name -> wg.cosmo.node.v1.OperationMapping + 51, // 67: wg.cosmo.node.v1.GRPCMapping.entity_mappings:type_name -> wg.cosmo.node.v1.EntityMapping + 53, // 68: wg.cosmo.node.v1.GRPCMapping.type_field_mappings:type_name -> wg.cosmo.node.v1.TypeFieldMapping + 56, // 69: wg.cosmo.node.v1.GRPCMapping.enum_mappings:type_name -> wg.cosmo.node.v1.EnumMapping + 48, // 70: wg.cosmo.node.v1.GRPCMapping.resolve_mappings:type_name -> wg.cosmo.node.v1.LookupMapping + 3, // 71: wg.cosmo.node.v1.LookupMapping.type:type_name -> wg.cosmo.node.v1.LookupType + 49, // 72: wg.cosmo.node.v1.LookupMapping.lookup_mapping:type_name -> wg.cosmo.node.v1.LookupFieldMapping + 54, // 73: wg.cosmo.node.v1.LookupFieldMapping.field_mapping:type_name -> wg.cosmo.node.v1.FieldMapping + 4, // 74: wg.cosmo.node.v1.OperationMapping.type:type_name -> wg.cosmo.node.v1.OperationType + 52, // 75: wg.cosmo.node.v1.EntityMapping.required_field_mappings:type_name -> wg.cosmo.node.v1.RequiredFieldMapping + 54, // 76: wg.cosmo.node.v1.RequiredFieldMapping.field_mapping:type_name -> wg.cosmo.node.v1.FieldMapping + 54, // 77: wg.cosmo.node.v1.TypeFieldMapping.field_mappings:type_name -> wg.cosmo.node.v1.FieldMapping + 55, // 78: wg.cosmo.node.v1.FieldMapping.argument_mappings:type_name -> wg.cosmo.node.v1.ArgumentMapping + 57, // 79: wg.cosmo.node.v1.EnumMapping.values:type_name -> wg.cosmo.node.v1.EnumValueMapping + 62, // 80: wg.cosmo.node.v1.NatsEventConfiguration.engine_event_configuration:type_name -> wg.cosmo.node.v1.EngineEventConfiguration + 58, // 81: wg.cosmo.node.v1.NatsEventConfiguration.stream_configuration:type_name -> wg.cosmo.node.v1.NatsStreamConfiguration + 62, // 82: wg.cosmo.node.v1.KafkaEventConfiguration.engine_event_configuration:type_name -> wg.cosmo.node.v1.EngineEventConfiguration + 62, // 83: wg.cosmo.node.v1.RedisEventConfiguration.engine_event_configuration:type_name -> wg.cosmo.node.v1.EngineEventConfiguration + 5, // 84: wg.cosmo.node.v1.EngineEventConfiguration.type:type_name -> wg.cosmo.node.v1.EventType + 59, // 85: wg.cosmo.node.v1.DataSourceCustomEvents.nats:type_name -> wg.cosmo.node.v1.NatsEventConfiguration + 60, // 86: wg.cosmo.node.v1.DataSourceCustomEvents.kafka:type_name -> wg.cosmo.node.v1.KafkaEventConfiguration + 61, // 87: wg.cosmo.node.v1.DataSourceCustomEvents.redis:type_name -> wg.cosmo.node.v1.RedisEventConfiguration + 65, // 88: wg.cosmo.node.v1.DataSourceCustom_Static.data:type_name -> wg.cosmo.node.v1.ConfigurationVariable + 6, // 89: wg.cosmo.node.v1.ConfigurationVariable.kind:type_name -> wg.cosmo.node.v1.ConfigurationVariableKind + 65, // 90: wg.cosmo.node.v1.HTTPHeader.values:type_name -> wg.cosmo.node.v1.ConfigurationVariable + 65, // 91: wg.cosmo.node.v1.MTLSConfiguration.key:type_name -> wg.cosmo.node.v1.ConfigurationVariable + 65, // 92: wg.cosmo.node.v1.MTLSConfiguration.cert:type_name -> wg.cosmo.node.v1.ConfigurationVariable + 65, // 93: wg.cosmo.node.v1.GraphQLSubscriptionConfiguration.url:type_name -> wg.cosmo.node.v1.ConfigurationVariable + 90, // 94: wg.cosmo.node.v1.GraphQLSubscriptionConfiguration.protocol:type_name -> wg.cosmo.common.GraphQLSubscriptionProtocol + 91, // 95: wg.cosmo.node.v1.GraphQLSubscriptionConfiguration.websocketSubprotocol:type_name -> wg.cosmo.common.GraphQLWebsocketSubprotocol + 75, // 96: wg.cosmo.node.v1.SubscriptionFilterCondition.and:type_name -> wg.cosmo.node.v1.SubscriptionFilterCondition + 74, // 97: wg.cosmo.node.v1.SubscriptionFilterCondition.in:type_name -> wg.cosmo.node.v1.SubscriptionFieldCondition + 75, // 98: wg.cosmo.node.v1.SubscriptionFilterCondition.not:type_name -> wg.cosmo.node.v1.SubscriptionFilterCondition + 75, // 99: wg.cosmo.node.v1.SubscriptionFilterCondition.or:type_name -> wg.cosmo.node.v1.SubscriptionFilterCondition + 77, // 100: wg.cosmo.node.v1.CacheWarmerOperations.operations:type_name -> wg.cosmo.node.v1.Operation + 78, // 101: wg.cosmo.node.v1.Operation.request:type_name -> wg.cosmo.node.v1.OperationRequest + 81, // 102: wg.cosmo.node.v1.Operation.client:type_name -> wg.cosmo.node.v1.ClientInfo + 79, // 103: wg.cosmo.node.v1.OperationRequest.extensions:type_name -> wg.cosmo.node.v1.Extension + 80, // 104: wg.cosmo.node.v1.Extension.persisted_query:type_name -> wg.cosmo.node.v1.PersistedQuery + 10, // 105: wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs.ConfigByFeatureFlagNameEntry.value:type_name -> wg.cosmo.node.v1.FeatureFlagRouterExecutionConfig + 68, // 106: wg.cosmo.node.v1.FetchConfiguration.HeaderEntry.value:type_name -> wg.cosmo.node.v1.HTTPHeader + 16, // 107: wg.cosmo.node.v1.NodeService.SelfRegister:input_type -> wg.cosmo.node.v1.SelfRegisterRequest + 17, // 108: wg.cosmo.node.v1.NodeService.SelfRegister:output_type -> wg.cosmo.node.v1.SelfRegisterResponse + 108, // [108:109] is the sub-list for method output_type + 107, // [107:108] is the sub-list for method input_type + 107, // [107:107] is the sub-list for extension type_name + 107, // [107:107] is the sub-list for extension extendee + 0, // [0:107] is the sub-list for field type_name } func init() { file_wg_cosmo_node_v1_node_proto_init() } @@ -5237,20 +5823,21 @@ func file_wg_cosmo_node_v1_node_proto_init() { file_wg_cosmo_node_v1_node_proto_msgTypes[4].OneofWrappers = []any{} file_wg_cosmo_node_v1_node_proto_msgTypes[9].OneofWrappers = []any{} file_wg_cosmo_node_v1_node_proto_msgTypes[10].OneofWrappers = []any{} - file_wg_cosmo_node_v1_node_proto_msgTypes[13].OneofWrappers = []any{} - file_wg_cosmo_node_v1_node_proto_msgTypes[14].OneofWrappers = []any{} - file_wg_cosmo_node_v1_node_proto_msgTypes[18].OneofWrappers = []any{} + file_wg_cosmo_node_v1_node_proto_msgTypes[17].OneofWrappers = []any{} + file_wg_cosmo_node_v1_node_proto_msgTypes[20].OneofWrappers = []any{} + file_wg_cosmo_node_v1_node_proto_msgTypes[21].OneofWrappers = []any{} file_wg_cosmo_node_v1_node_proto_msgTypes[25].OneofWrappers = []any{} - file_wg_cosmo_node_v1_node_proto_msgTypes[30].OneofWrappers = []any{} - file_wg_cosmo_node_v1_node_proto_msgTypes[55].OneofWrappers = []any{} - file_wg_cosmo_node_v1_node_proto_msgTypes[60].OneofWrappers = []any{} + file_wg_cosmo_node_v1_node_proto_msgTypes[32].OneofWrappers = []any{} + file_wg_cosmo_node_v1_node_proto_msgTypes[37].OneofWrappers = []any{} + file_wg_cosmo_node_v1_node_proto_msgTypes[62].OneofWrappers = []any{} + file_wg_cosmo_node_v1_node_proto_msgTypes[67].OneofWrappers = []any{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_wg_cosmo_node_v1_node_proto_rawDesc), len(file_wg_cosmo_node_v1_node_proto_rawDesc)), NumEnums: 8, - NumMessages: 74, + NumMessages: 81, NumExtensions: 0, NumServices: 1, }, diff --git a/shared/src/router-config/builder.ts b/shared/src/router-config/builder.ts index 6e231e3b0b..14f958b15e 100644 --- a/shared/src/router-config/builder.ts +++ b/shared/src/router-config/builder.ts @@ -208,8 +208,21 @@ export const buildRouterConfig = function (input: Input): RouterConfig { engineConfig, printSchemaWithDirectives(lexicographicSortSchema(subgraph.schema)), ); - const { childNodes, entityInterfaces, events, interfaceObjects, keys, provides, requires, rootNodes } = - configurationDatasToDataSourceConfiguration(subgraph.configurationDataByTypeName); + const { + childNodes, + entityInterfaces, + events, + interfaceObjects, + keys, + provides, + requestScopedFields, + requires, + rootNodes, + entityCacheConfigurations, + rootFieldCacheConfigurations, + cachePopulateConfigurations, + cacheInvalidateConfigurations, + } = configurationDatasToDataSourceConfiguration(subgraph.configurationDataByTypeName); let grcpConfig: GRPCConfiguration | undefined; @@ -320,9 +333,14 @@ export const buildRouterConfig = function (input: Input): RouterConfig { kind, overrideFieldPathFromAlias: true, provides, + requestScopedFields, requestTimeoutSeconds: BigInt(10), requires, rootNodes, + entityCacheConfigurations, + rootFieldCacheConfigurations, + cachePopulateConfigurations, + cacheInvalidateConfigurations, }); engineConfig.datasourceConfigurations.push(datasourceConfig); } diff --git a/shared/src/router-config/graphql-configuration.ts b/shared/src/router-config/graphql-configuration.ts index b7b633dba1..3be8673d2a 100644 --- a/shared/src/router-config/graphql-configuration.ts +++ b/shared/src/router-config/graphql-configuration.ts @@ -3,9 +3,14 @@ import { ArgumentConfiguration, ArgumentSource, AuthorizationConfiguration, + CacheInvalidateConfiguration, + CachePopulateConfiguration, DataSourceCustomEvents, EngineEventConfiguration, + EntityCacheConfiguration, + EntityCacheFieldMapping, EntityInterfaceConfiguration, + EntityKeyMapping, EventType, FieldConfiguration, FieldCoordinates, @@ -14,7 +19,9 @@ import { NatsEventConfiguration, NatsStreamConfiguration, RedisEventConfiguration, + RequestScopedFieldConfiguration, RequiredField, + RootFieldCacheConfiguration, Scopes, SubscriptionFieldCondition, SubscriptionFilterCondition, @@ -27,6 +34,7 @@ import { PROVIDER_TYPE_KAFKA, PROVIDER_TYPE_NATS, PROVIDER_TYPE_REDIS, + RequestScopedFieldConfig, RequiredFieldConfiguration, SubscriptionCondition, TypeName, @@ -41,6 +49,11 @@ export type DataSourceConfiguration = { requires: RequiredField[]; entityInterfaces: EntityInterfaceConfiguration[]; interfaceObjects: EntityInterfaceConfiguration[]; + requestScopedFields: RequestScopedFieldConfiguration[]; + entityCacheConfigurations: EntityCacheConfiguration[]; + rootFieldCacheConfigurations: RootFieldCacheConfiguration[]; + cachePopulateConfigurations: CachePopulateConfiguration[]; + cacheInvalidateConfigurations: CacheInvalidateConfiguration[]; }; function generateFieldSetConditions(requiredField: RequiredFieldConfiguration): Array | undefined { @@ -122,6 +135,11 @@ export function configurationDatasToDataSourceConfiguration( requires: [], entityInterfaces: [], interfaceObjects: [], + requestScopedFields: [], + entityCacheConfigurations: [], + rootFieldCacheConfigurations: [], + cachePopulateConfigurations: [], + cacheInvalidateConfigurations: [], }; for (const data of dataByTypeName.values()) { const typeName = data.typeName; @@ -214,6 +232,81 @@ export function configurationDatasToDataSourceConfiguration( output.events.nats.push(...natsEventConfigurations); output.events.kafka.push(...kafkaEventConfigurations); output.events.redis.push(...redisEventConfigurations); + if (data.entityCacheConfigurations) { + for (const ec of data.entityCacheConfigurations) { + output.entityCacheConfigurations.push( + new EntityCacheConfiguration({ + typeName: ec.typeName, + maxAgeSeconds: BigInt(ec.maxAgeSeconds), + notFoundCacheTtlSeconds: BigInt(ec.notFoundCacheTtlSeconds), + includeHeaders: ec.includeHeaders, + partialCacheLoad: ec.partialCacheLoad, + shadowMode: ec.shadowMode, + }), + ); + } + } + if (data.rootFieldCacheConfigurations) { + for (const rfc of data.rootFieldCacheConfigurations) { + output.rootFieldCacheConfigurations.push( + new RootFieldCacheConfiguration({ + fieldName: rfc.fieldName, + maxAgeSeconds: BigInt(rfc.maxAgeSeconds), + includeHeaders: rfc.includeHeaders, + shadowMode: rfc.shadowMode, + entityTypeName: rfc.entityTypeName, + entityKeyMappings: rfc.entityKeyMappings.map( + (m) => + new EntityKeyMapping({ + entityTypeName: m.entityTypeName, + fieldMappings: m.fieldMappings.map( + (fm) => + new EntityCacheFieldMapping({ + entityKeyField: fm.entityKeyField, + argumentPath: fm.argumentPath, + isBatch: fm.isBatch || false, + }), + ), + }), + ), + }), + ); + } + } + if (data.cachePopulateConfigurations) { + for (const cp of data.cachePopulateConfigurations) { + output.cachePopulateConfigurations.push( + new CachePopulateConfiguration({ + fieldName: cp.fieldName, + operationType: cp.operationType, + entityTypeName: cp.entityTypeName, + maxAgeSeconds: cp.maxAgeSeconds == null ? undefined : BigInt(cp.maxAgeSeconds), + }), + ); + } + } + if (data.cacheInvalidateConfigurations) { + for (const ci of data.cacheInvalidateConfigurations) { + output.cacheInvalidateConfigurations.push( + new CacheInvalidateConfiguration({ + fieldName: ci.fieldName, + operationType: ci.operationType, + entityTypeName: ci.entityTypeName, + }), + ); + } + } + if (data.requestScopedFields) { + for (const field of data.requestScopedFields) { + output.requestScopedFields.push( + new RequestScopedFieldConfiguration({ + fieldName: field.fieldName, + typeName: field.typeName, + l1Key: field.l1Key, + }), + ); + } + } } return output; } From 5ef33a681b2e9043abf7dac619ccb11b3212c6e8 Mon Sep 17 00:00:00 2001 From: Milinda Dias Date: Wed, 10 Jun 2026 20:10:04 +0530 Subject: [PATCH 2/7] feat(demo): entity caching demo subgraphs, cache-demo runner, and test subgraphs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extracted from jensneuse/entity-caching-v2 (PR #2777) — demo layer, stacked on the composition+proto PR. - cachegraph / cachegraph_ext / viewer: demo subgraphs exercising the caching directives (mutable data store, latency injector, auth profiles) - cmd/cache-demo: standalone cache-only runner (ports 4012-4014) - pkg/subgraphs/cachetest: the six deterministic subgraphs consumed by the router-tests entity_caching suite (articles, articlesmeta, details, inventory, items, viewer) - graph-cache-only.yaml + config-cache-only.json + Makefile compose targets Builds and tests green against the base router (no router changes required). Co-Authored-By: Claude Fable 5 --- demo/Makefile | 18 + demo/cmd/all/main.go | 6 + demo/cmd/cache-demo/main.go | 55 + demo/config-cache-only.json | 1 + demo/go.mod | 2 +- demo/graph-cache-only.yaml | 14 + demo/graph-cachetest.yaml | 26 + demo/graph.yaml | 4 + demo/pkg/injector/latency.go | 29 + demo/pkg/subgraphs/cachegraph/cachegraph.go | 12 + demo/pkg/subgraphs/cachegraph/generate.go | 2 + demo/pkg/subgraphs/cachegraph/gqlgen.yml | 55 + .../cachegraph/subgraph/auth_profiles.go | 12 + .../pkg/subgraphs/cachegraph/subgraph/data.go | 336 + .../cachegraph/subgraph/data_race_test.go | 160 + .../cachegraph/subgraph/data_test.go | 28 + .../cachegraph/subgraph/entity.resolvers.go | 66 + .../subgraph/generated/federation.go | 676 ++ .../subgraph/generated/generated.go | 10038 ++++++++++++++++ .../cachegraph/subgraph/model/models_gen.go | 104 + .../subgraphs/cachegraph/subgraph/resolver.go | 22 + .../cachegraph/subgraph/schema.graphqls | 138 + .../cachegraph/subgraph/schema.resolvers.go | 121 + .../cachegraph_ext/cachegraph_ext.go | 12 + demo/pkg/subgraphs/cachegraph_ext/generate.go | 2 + demo/pkg/subgraphs/cachegraph_ext/gqlgen.yml | 45 + .../subgraphs/cachegraph_ext/subgraph/data.go | 53 + .../subgraph/entity.resolvers.go | 38 + .../subgraph/generated/federation.go | 345 + .../subgraph/generated/federation.requires.go | 28 + .../subgraph/generated/generated.go | 5517 +++++++++ .../subgraph/model/models_gen.go | 34 + .../cachegraph_ext/subgraph/resolver.go | 3 + .../cachegraph_ext/subgraph/schema.graphqls | 34 + .../subgraph/schema.resolvers.go | 44 + .../subgraph/schema.resolvers_test.go | 29 + .../subgraphs/cachetest/articles/articles.go | 14 + .../subgraphs/cachetest/articles/generate.go | 3 + .../subgraphs/cachetest/articles/gqlgen.yml | 39 + .../cachetest/articles/subgraph/data.go | 66 + .../articles/subgraph/entity.resolvers.go | 42 + .../articles/subgraph/generated/federation.go | 345 + .../subgraph/generated/federation.requires.go | 35 + .../articles/subgraph/generated/generated.go | 5519 +++++++++ .../subgraph/generated/staticcheck.conf | 2 + .../articles/subgraph/model/models_gen.go | 36 + .../cachetest/articles/subgraph/resolver.go | 7 + .../articles/subgraph/schema.graphqls | 49 + .../articles/subgraph/schema.resolvers.go | 44 + .../cachetest/articlesmeta/articlesmeta.go | 14 + .../cachetest/articlesmeta/generate.go | 3 + .../cachetest/articlesmeta/gqlgen.yml | 33 + .../cachetest/articlesmeta/subgraph/data.go | 25 + .../articlesmeta/subgraph/entity.resolvers.go | 28 + .../subgraph/generated/federation.go | 234 + .../subgraph/generated/generated.go | 4529 +++++++ .../subgraph/generated/staticcheck.conf | 2 + .../articlesmeta/subgraph/model/models_gen.go | 15 + .../articlesmeta/subgraph/resolver.go | 7 + .../articlesmeta/subgraph/schema.graphqls | 12 + .../subgraphs/cachetest/details/details.go | 14 + .../subgraphs/cachetest/details/generate.go | 3 + .../subgraphs/cachetest/details/gqlgen.yml | 39 + .../cachetest/details/subgraph/data.go | 29 + .../details/subgraph/entity.resolvers.go | 41 + .../details/subgraph/generated/federation.go | 368 + .../details/subgraph/generated/generated.go | 5367 +++++++++ .../subgraph/generated/staticcheck.conf | 2 + .../details/subgraph/model/models_gen.go | 34 + .../cachetest/details/subgraph/resolver.go | 7 + .../details/subgraph/schema.graphqls | 34 + .../subgraphs/cachetest/inventory/generate.go | 3 + .../subgraphs/cachetest/inventory/gqlgen.yml | 39 + .../cachetest/inventory/inventory.go | 14 + .../cachetest/inventory/subgraph/data.go | 13 + .../inventory/subgraph/entity.resolvers.go | 25 + .../subgraph/generated/federation.go | 234 + .../inventory/subgraph/generated/generated.go | 4460 +++++++ .../inventory/subgraph/model/models_gen.go | 14 + .../cachetest/inventory/subgraph/resolver.go | 7 + .../inventory/subgraph/schema.graphqls | 18 + .../pkg/subgraphs/cachetest/items/generate.go | 3 + demo/pkg/subgraphs/cachetest/items/gqlgen.yml | 47 + demo/pkg/subgraphs/cachetest/items/items.go | 15 + .../cachetest/items/subgraph/data.go | 135 + .../items/subgraph/entity.resolvers.go | 52 + .../items/subgraph/generated/federation.go | 406 + .../items/subgraph/generated/generated.go | 7692 ++++++++++++ .../items/subgraph/generated/staticcheck.conf | 2 + .../items/subgraph/model/models_gen.go | 53 + .../cachetest/items/subgraph/resolver.go | 26 + .../cachetest/items/subgraph/schema.graphqls | 93 + .../items/subgraph/schema.resolvers.go | 180 + .../subgraphs/cachetest/viewer/generate.go | 3 + .../pkg/subgraphs/cachetest/viewer/gqlgen.yml | 39 + .../cachetest/viewer/subgraph/data.go | 13 + .../viewer/subgraph/entity.resolvers.go | 34 + .../viewer/subgraph/generated/federation.go | 288 + .../viewer/subgraph/generated/generated.go | 4837 ++++++++ .../subgraph/generated/staticcheck.conf | 2 + .../viewer/subgraph/model/models_gen.go | 21 + .../cachetest/viewer/subgraph/resolver.go | 7 + .../cachetest/viewer/subgraph/schema.graphqls | 24 + .../viewer/subgraph/schema.resolvers.go | 22 + demo/pkg/subgraphs/cachetest/viewer/viewer.go | 14 + demo/pkg/subgraphs/subgraphs.go | 43 +- demo/pkg/subgraphs/viewer/generate.go | 2 + demo/pkg/subgraphs/viewer/gqlgen.yml | 39 + demo/pkg/subgraphs/viewer/subgraph/context.go | 32 + demo/pkg/subgraphs/viewer/subgraph/data.go | 20 + .../viewer/subgraph/entity.resolvers.go | 33 + .../viewer/subgraph/generated/federation.go | 288 + .../viewer/subgraph/generated/generated.go | 4839 ++++++++ .../viewer/subgraph/model/models_gen.go | 21 + .../pkg/subgraphs/viewer/subgraph/resolver.go | 3 + .../subgraphs/viewer/subgraph/schema.graphqls | 26 + .../viewer/subgraph/schema.resolvers.go | 22 + demo/pkg/subgraphs/viewer/viewer.go | 30 + demo/router-cache-cp.yaml | 58 + demo/router-cache.yaml | 51 + 120 files changed, 59480 insertions(+), 12 deletions(-) create mode 100644 demo/cmd/cache-demo/main.go create mode 100644 demo/config-cache-only.json create mode 100644 demo/graph-cache-only.yaml create mode 100644 demo/graph-cachetest.yaml create mode 100644 demo/pkg/injector/latency.go create mode 100644 demo/pkg/subgraphs/cachegraph/cachegraph.go create mode 100644 demo/pkg/subgraphs/cachegraph/generate.go create mode 100644 demo/pkg/subgraphs/cachegraph/gqlgen.yml create mode 100644 demo/pkg/subgraphs/cachegraph/subgraph/auth_profiles.go create mode 100644 demo/pkg/subgraphs/cachegraph/subgraph/data.go create mode 100644 demo/pkg/subgraphs/cachegraph/subgraph/data_race_test.go create mode 100644 demo/pkg/subgraphs/cachegraph/subgraph/data_test.go create mode 100644 demo/pkg/subgraphs/cachegraph/subgraph/entity.resolvers.go create mode 100644 demo/pkg/subgraphs/cachegraph/subgraph/generated/federation.go create mode 100644 demo/pkg/subgraphs/cachegraph/subgraph/generated/generated.go create mode 100644 demo/pkg/subgraphs/cachegraph/subgraph/model/models_gen.go create mode 100644 demo/pkg/subgraphs/cachegraph/subgraph/resolver.go create mode 100644 demo/pkg/subgraphs/cachegraph/subgraph/schema.graphqls create mode 100644 demo/pkg/subgraphs/cachegraph/subgraph/schema.resolvers.go create mode 100644 demo/pkg/subgraphs/cachegraph_ext/cachegraph_ext.go create mode 100644 demo/pkg/subgraphs/cachegraph_ext/generate.go create mode 100644 demo/pkg/subgraphs/cachegraph_ext/gqlgen.yml create mode 100644 demo/pkg/subgraphs/cachegraph_ext/subgraph/data.go create mode 100644 demo/pkg/subgraphs/cachegraph_ext/subgraph/entity.resolvers.go create mode 100644 demo/pkg/subgraphs/cachegraph_ext/subgraph/generated/federation.go create mode 100644 demo/pkg/subgraphs/cachegraph_ext/subgraph/generated/federation.requires.go create mode 100644 demo/pkg/subgraphs/cachegraph_ext/subgraph/generated/generated.go create mode 100644 demo/pkg/subgraphs/cachegraph_ext/subgraph/model/models_gen.go create mode 100644 demo/pkg/subgraphs/cachegraph_ext/subgraph/resolver.go create mode 100644 demo/pkg/subgraphs/cachegraph_ext/subgraph/schema.graphqls create mode 100644 demo/pkg/subgraphs/cachegraph_ext/subgraph/schema.resolvers.go create mode 100644 demo/pkg/subgraphs/cachegraph_ext/subgraph/schema.resolvers_test.go create mode 100644 demo/pkg/subgraphs/cachetest/articles/articles.go create mode 100644 demo/pkg/subgraphs/cachetest/articles/generate.go create mode 100644 demo/pkg/subgraphs/cachetest/articles/gqlgen.yml create mode 100644 demo/pkg/subgraphs/cachetest/articles/subgraph/data.go create mode 100644 demo/pkg/subgraphs/cachetest/articles/subgraph/entity.resolvers.go create mode 100644 demo/pkg/subgraphs/cachetest/articles/subgraph/generated/federation.go create mode 100644 demo/pkg/subgraphs/cachetest/articles/subgraph/generated/federation.requires.go create mode 100644 demo/pkg/subgraphs/cachetest/articles/subgraph/generated/generated.go create mode 100644 demo/pkg/subgraphs/cachetest/articles/subgraph/generated/staticcheck.conf create mode 100644 demo/pkg/subgraphs/cachetest/articles/subgraph/model/models_gen.go create mode 100644 demo/pkg/subgraphs/cachetest/articles/subgraph/resolver.go create mode 100644 demo/pkg/subgraphs/cachetest/articles/subgraph/schema.graphqls create mode 100644 demo/pkg/subgraphs/cachetest/articles/subgraph/schema.resolvers.go create mode 100644 demo/pkg/subgraphs/cachetest/articlesmeta/articlesmeta.go create mode 100644 demo/pkg/subgraphs/cachetest/articlesmeta/generate.go create mode 100644 demo/pkg/subgraphs/cachetest/articlesmeta/gqlgen.yml create mode 100644 demo/pkg/subgraphs/cachetest/articlesmeta/subgraph/data.go create mode 100644 demo/pkg/subgraphs/cachetest/articlesmeta/subgraph/entity.resolvers.go create mode 100644 demo/pkg/subgraphs/cachetest/articlesmeta/subgraph/generated/federation.go create mode 100644 demo/pkg/subgraphs/cachetest/articlesmeta/subgraph/generated/generated.go create mode 100644 demo/pkg/subgraphs/cachetest/articlesmeta/subgraph/generated/staticcheck.conf create mode 100644 demo/pkg/subgraphs/cachetest/articlesmeta/subgraph/model/models_gen.go create mode 100644 demo/pkg/subgraphs/cachetest/articlesmeta/subgraph/resolver.go create mode 100644 demo/pkg/subgraphs/cachetest/articlesmeta/subgraph/schema.graphqls create mode 100644 demo/pkg/subgraphs/cachetest/details/details.go create mode 100644 demo/pkg/subgraphs/cachetest/details/generate.go create mode 100644 demo/pkg/subgraphs/cachetest/details/gqlgen.yml create mode 100644 demo/pkg/subgraphs/cachetest/details/subgraph/data.go create mode 100644 demo/pkg/subgraphs/cachetest/details/subgraph/entity.resolvers.go create mode 100644 demo/pkg/subgraphs/cachetest/details/subgraph/generated/federation.go create mode 100644 demo/pkg/subgraphs/cachetest/details/subgraph/generated/generated.go create mode 100644 demo/pkg/subgraphs/cachetest/details/subgraph/generated/staticcheck.conf create mode 100644 demo/pkg/subgraphs/cachetest/details/subgraph/model/models_gen.go create mode 100644 demo/pkg/subgraphs/cachetest/details/subgraph/resolver.go create mode 100644 demo/pkg/subgraphs/cachetest/details/subgraph/schema.graphqls create mode 100644 demo/pkg/subgraphs/cachetest/inventory/generate.go create mode 100644 demo/pkg/subgraphs/cachetest/inventory/gqlgen.yml create mode 100644 demo/pkg/subgraphs/cachetest/inventory/inventory.go create mode 100644 demo/pkg/subgraphs/cachetest/inventory/subgraph/data.go create mode 100644 demo/pkg/subgraphs/cachetest/inventory/subgraph/entity.resolvers.go create mode 100644 demo/pkg/subgraphs/cachetest/inventory/subgraph/generated/federation.go create mode 100644 demo/pkg/subgraphs/cachetest/inventory/subgraph/generated/generated.go create mode 100644 demo/pkg/subgraphs/cachetest/inventory/subgraph/model/models_gen.go create mode 100644 demo/pkg/subgraphs/cachetest/inventory/subgraph/resolver.go create mode 100644 demo/pkg/subgraphs/cachetest/inventory/subgraph/schema.graphqls create mode 100644 demo/pkg/subgraphs/cachetest/items/generate.go create mode 100644 demo/pkg/subgraphs/cachetest/items/gqlgen.yml create mode 100644 demo/pkg/subgraphs/cachetest/items/items.go create mode 100644 demo/pkg/subgraphs/cachetest/items/subgraph/data.go create mode 100644 demo/pkg/subgraphs/cachetest/items/subgraph/entity.resolvers.go create mode 100644 demo/pkg/subgraphs/cachetest/items/subgraph/generated/federation.go create mode 100644 demo/pkg/subgraphs/cachetest/items/subgraph/generated/generated.go create mode 100644 demo/pkg/subgraphs/cachetest/items/subgraph/generated/staticcheck.conf create mode 100644 demo/pkg/subgraphs/cachetest/items/subgraph/model/models_gen.go create mode 100644 demo/pkg/subgraphs/cachetest/items/subgraph/resolver.go create mode 100644 demo/pkg/subgraphs/cachetest/items/subgraph/schema.graphqls create mode 100644 demo/pkg/subgraphs/cachetest/items/subgraph/schema.resolvers.go create mode 100644 demo/pkg/subgraphs/cachetest/viewer/generate.go create mode 100644 demo/pkg/subgraphs/cachetest/viewer/gqlgen.yml create mode 100644 demo/pkg/subgraphs/cachetest/viewer/subgraph/data.go create mode 100644 demo/pkg/subgraphs/cachetest/viewer/subgraph/entity.resolvers.go create mode 100644 demo/pkg/subgraphs/cachetest/viewer/subgraph/generated/federation.go create mode 100644 demo/pkg/subgraphs/cachetest/viewer/subgraph/generated/generated.go create mode 100644 demo/pkg/subgraphs/cachetest/viewer/subgraph/generated/staticcheck.conf create mode 100644 demo/pkg/subgraphs/cachetest/viewer/subgraph/model/models_gen.go create mode 100644 demo/pkg/subgraphs/cachetest/viewer/subgraph/resolver.go create mode 100644 demo/pkg/subgraphs/cachetest/viewer/subgraph/schema.graphqls create mode 100644 demo/pkg/subgraphs/cachetest/viewer/subgraph/schema.resolvers.go create mode 100644 demo/pkg/subgraphs/cachetest/viewer/viewer.go create mode 100644 demo/pkg/subgraphs/viewer/generate.go create mode 100644 demo/pkg/subgraphs/viewer/gqlgen.yml create mode 100644 demo/pkg/subgraphs/viewer/subgraph/context.go create mode 100644 demo/pkg/subgraphs/viewer/subgraph/data.go create mode 100644 demo/pkg/subgraphs/viewer/subgraph/entity.resolvers.go create mode 100644 demo/pkg/subgraphs/viewer/subgraph/generated/federation.go create mode 100644 demo/pkg/subgraphs/viewer/subgraph/generated/generated.go create mode 100644 demo/pkg/subgraphs/viewer/subgraph/model/models_gen.go create mode 100644 demo/pkg/subgraphs/viewer/subgraph/resolver.go create mode 100644 demo/pkg/subgraphs/viewer/subgraph/schema.graphqls create mode 100644 demo/pkg/subgraphs/viewer/subgraph/schema.resolvers.go create mode 100644 demo/pkg/subgraphs/viewer/viewer.go create mode 100644 demo/router-cache-cp.yaml create mode 100644 demo/router-cache.yaml diff --git a/demo/Makefile b/demo/Makefile index 70121794e4..be393b097d 100644 --- a/demo/Makefile +++ b/demo/Makefile @@ -44,6 +44,9 @@ plugin-build-ci: plugin-build-ci-go-binary plugin-build-ci-bun-binary cp -a pkg/subgraphs/projects/bin/* ../router/plugins/projects/bin/ cp -a pkg/subgraphs/courses/bin/* ../router/plugins/courses/bin/ +compose-cache: + $(wgc_router_ci) compose -i ./graph-cache-only.yaml -o ./config-cache-only.json + standalone-compose: $(wgc_router) compose -i ./graph-with-standalone.yaml -o ./configWithStandalone.json pnpx prettier ./configWithStandalone.json -w @@ -57,3 +60,18 @@ build-manifest: build-manifest-integration: python3 build_manifest.py --router-config ./config.json --out ../router-tests/testenv/testdata/manifest --cleanup + +# Composes the entity caching integration test config consumed (go:embed) by +# router-tests/entitycaching. jq pretty-prints so regeneration diffs stay reviewable. +compose-cachetest: + $(wgc_router_ci) compose -i ./graph-cachetest.yaml -o ../router-tests/entitycaching/testdata/config.json + jq . ../router-tests/entitycaching/testdata/config.json > ../router-tests/entitycaching/testdata/config.json.tmp + mv ../router-tests/entitycaching/testdata/config.json.tmp ../router-tests/entitycaching/testdata/config.json + +generate-cachetest: + cd pkg/subgraphs/cachetest/items && go run github.com/99designs/gqlgen generate + cd pkg/subgraphs/cachetest/details && go run github.com/99designs/gqlgen generate + cd pkg/subgraphs/cachetest/inventory && go run github.com/99designs/gqlgen generate + cd pkg/subgraphs/cachetest/viewer && go run github.com/99designs/gqlgen generate + cd pkg/subgraphs/cachetest/articles && go run github.com/99designs/gqlgen generate + cd pkg/subgraphs/cachetest/articlesmeta && go run github.com/99designs/gqlgen generate diff --git a/demo/cmd/all/main.go b/demo/cmd/all/main.go index 0d885a0d95..4a3686901a 100644 --- a/demo/cmd/all/main.go +++ b/demo/cmd/all/main.go @@ -20,6 +20,9 @@ var ( mood = flag.Int("mood", 4008, "Port for mood subgraph") countries = flag.Int("countries", 4009, "Port for countries subgraph") productsFeatureSubgraph = flag.Int("products_fg", 4010, "Port for products feature subgraph") + cacheGraph = flag.Int("cachegraph", 4012, "Port for cachegraph subgraph") + cacheGraphExt = flag.Int("cachegraph_ext", 4013, "Port for cachegraph-ext subgraph") + viewerSubgraph = flag.Int("viewer", 4014, "Port for viewer subgraph") ) func main() { @@ -35,6 +38,9 @@ func main() { Mood: *mood, Countries: *countries, ProductsFG: *productsFeatureSubgraph, + CacheGraph: *cacheGraph, + CacheGraphExt: *cacheGraphExt, + Viewer: *viewerSubgraph, }, EnableDebug: *debug, GetPubSubName: func(name string) string { diff --git a/demo/cmd/cache-demo/main.go b/demo/cmd/cache-demo/main.go new file mode 100644 index 0000000000..f1ee16cc48 --- /dev/null +++ b/demo/cmd/cache-demo/main.go @@ -0,0 +1,55 @@ +// cache-demo runs only the cache-related subgraphs without requiring NATS. +package main + +import ( + "log" + "net/http" + "strconv" + + "github.com/99designs/gqlgen/graphql" + "github.com/99designs/gqlgen/graphql/handler" + "github.com/99designs/gqlgen/graphql/handler/transport" + "github.com/99designs/gqlgen/graphql/playground" + "golang.org/x/sync/errgroup" + + "github.com/wundergraph/cosmo/demo/pkg/injector" + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachegraph" + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachegraph_ext" + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/viewer" +) + +func main() { + servers := []*http.Server{ + gqlServer("cachegraph", 4012, cachegraph.NewSchema()), + gqlServer("cachegraph-ext", 4013, cachegraph_ext.NewSchema()), + viewerServer(4014), + } + + log.Println("Cache demo subgraphs starting (no NATS required):") + log.Println(" cachegraph: http://localhost:4012/") + log.Println(" cachegraph-ext: http://localhost:4013/") + log.Println(" viewer: http://localhost:4014/") + + g := new(errgroup.Group) + for _, srv := range servers { + g.Go(srv.ListenAndServe) + } + log.Fatal(g.Wait()) +} + +func gqlServer(name string, port int, schema graphql.ExecutableSchema) *http.Server { + srv := handler.New(schema) + srv.AddTransport(transport.POST{}) + srv.AddTransport(transport.GET{}) + mux := http.NewServeMux() + mux.Handle("/", playground.Handler(name, "/graphql")) + mux.Handle("/graphql", srv) + return &http.Server{Addr: ":" + strconv.Itoa(port), Handler: injector.Latency(injector.HTTP(mux))} +} + +func viewerServer(port int) *http.Server { + mux := http.NewServeMux() + mux.Handle("/", playground.Handler("viewer", "/graphql")) + mux.Handle("/graphql", viewer.NewHandler()) + return &http.Server{Addr: ":" + strconv.Itoa(port), Handler: injector.Latency(injector.HTTP(mux))} +} diff --git a/demo/config-cache-only.json b/demo/config-cache-only.json new file mode 100644 index 0000000000..eead639dc4 --- /dev/null +++ b/demo/config-cache-only.json @@ -0,0 +1 @@ +{"engineConfig":{"defaultFlushInterval":"500","datasourceConfigurations":[{"kind":"GRAPHQL","rootNodes":[{"typeName":"Query","fieldNames":["article","articles","articlesByIds","articleBySlug","listing","listings","venue","venues","userProfile","catalog","catalogs","metric"]},{"typeName":"Mutation","fieldNames":["updateArticle","createArticle","deleteListing"]},{"typeName":"UserProfile","fieldNames":["id","username","email","role"]},{"typeName":"Catalog","fieldNames":["id","name","category","itemCount"]},{"typeName":"Metric","fieldNames":["id","name","value","unit"]},{"typeName":"Personalized","fieldNames":["id"]},{"typeName":"Viewer","fieldNames":["id","recommendedArticles"]},{"typeName":"Article","fieldNames":["id","slug","title","body","authorName","publishedAt","tags"]},{"typeName":"Listing","fieldNames":["sellerId","sku","title","price","currency","inStock"]},{"typeName":"Venue","fieldNames":["address","name","capacity","city"]}],"childNodes":[{"typeName":"Address","fieldNames":["id"]}],"overrideFieldPathFromAlias":true,"customGraphql":{"fetch":{"url":{"staticVariableContent":"http://localhost:4012/graphql"},"method":"POST","body":{},"baseUrl":{},"path":{}},"subscription":{"enabled":true,"url":{"staticVariableContent":"http://localhost:4012/graphql"},"protocol":"GRAPHQL_SUBSCRIPTION_PROTOCOL_WS","websocketSubprotocol":"GRAPHQL_WEBSOCKET_SUBPROTOCOL_AUTO"},"federation":{"enabled":true,"serviceSdl":"extend schema\n @link(\n url: \"https://specs.apollo.dev/federation/v2.5\"\n import: [\"@key\"]\n )\n\ndirective @openfed__entityCache(\n maxAge: Int!\n includeHeaders: Boolean = false\n partialCacheLoad: Boolean = false\n shadowMode: Boolean = false\n) on OBJECT\n\ndirective @openfed__queryCache(\n maxAge: Int!\n includeHeaders: Boolean = false\n shadowMode: Boolean = false\n) on FIELD_DEFINITION\n\ndirective @openfed__cacheInvalidate on FIELD_DEFINITION\n\ndirective @openfed__cachePopulate(maxAge: Int) on FIELD_DEFINITION\n\ndirective @openfed__is(fields: String!) on ARGUMENT_DEFINITION\n\ntype Query {\n \"\"\"Simple key lookup\"\"\"\n article(id: ID!): Article @openfed__queryCache(maxAge: 120)\n \"\"\"List query\"\"\"\n articles: [Article!]! @openfed__queryCache(maxAge: 120)\n \"\"\"Batch lookup with @openfed__is\"\"\"\n articlesByIds(ids: [ID!]! @openfed__is(fields: \"id\")): [Article!]! @openfed__queryCache(maxAge: 120)\n \"\"\"Argument remapping via @openfed__is\"\"\"\n articleBySlug(slug: String! @openfed__is(fields: \"slug\")): Article @openfed__queryCache(maxAge: 120)\n\n \"\"\"Composite key lookup via input object with @openfed__is\"\"\"\n listing(key: ListingKey! @openfed__is(fields: \"sellerId sku\")): Listing @openfed__queryCache(maxAge: 60)\n \"\"\"List of all listings\"\"\"\n listings: [Listing!]! @openfed__queryCache(maxAge: 60)\n\n \"\"\"Nested key lookup with @openfed__is and input object\"\"\"\n venue(location: VenueLocationKey! @openfed__is(fields: \"address { id }\")): Venue @openfed__queryCache(maxAge: 180)\n \"\"\"List of all venues\"\"\"\n venues: [Venue!]! @openfed__queryCache(maxAge: 180)\n\n \"\"\"Per-user profile (cache varies by Authorization header)\"\"\"\n userProfile(id: ID!): UserProfile @openfed__queryCache(maxAge: 60, includeHeaders: true)\n\n \"\"\"Single catalog entry\"\"\"\n catalog(id: ID!): Catalog @openfed__queryCache(maxAge: 120)\n \"\"\"All catalog entries (for partial cache load testing)\"\"\"\n catalogs: [Catalog!]! @openfed__queryCache(maxAge: 120)\n\n \"\"\"Single metric (shadow mode - always fetches from subgraph, compares with cache)\"\"\"\n metric(id: ID!): Metric @openfed__queryCache(maxAge: 300, shadowMode: true)\n}\n\ntype Mutation {\n updateArticle(id: ID!, title: String!): Article @openfed__cacheInvalidate\n createArticle(title: String!, body: String!, authorName: String!): Article! @openfed__cachePopulate(maxAge: 30)\n deleteListing(key: ListingKey!): Listing @openfed__cacheInvalidate\n}\n\n\"\"\"Per-user caching: includeHeaders makes the cache key include a hash of forwarded headers (e.g. Authorization)\"\"\"\ntype UserProfile @key(fields: \"id\") @openfed__entityCache(maxAge: 60, includeHeaders: true) {\n id: ID!\n username: String!\n email: String!\n role: String!\n}\n\n\"\"\"Partial cache load: when some entities are cached and others aren't, only the missing ones are fetched\"\"\"\ntype Catalog @key(fields: \"id\") @openfed__entityCache(maxAge: 120, partialCacheLoad: true) {\n id: ID!\n name: String!\n category: String!\n itemCount: Int!\n}\n\n\"\"\"Shadow mode: always fetches from subgraph but compares with cache for staleness detection\"\"\"\ntype Metric @key(fields: \"id\") @openfed__entityCache(maxAge: 300, shadowMode: true) {\n id: ID!\n name: String!\n value: Float!\n unit: String!\n}\n\ninput ListingKey {\n sellerId: ID!\n sku: String!\n}\n\ninput VenueLocationKey {\n address: VenueAddressKey!\n}\n\ninput VenueAddressKey {\n id: ID!\n}\n\ninterface Personalized @key(fields: \"id\") {\n id: ID!\n}\n\ntype Viewer @key(fields: \"id\") {\n id: ID!\n recommendedArticles: [Article!]!\n}\n\ntype Article implements Personalized @key(fields: \"id\") @key(fields: \"slug\") @openfed__entityCache(maxAge: 120) {\n id: ID!\n slug: String!\n title: String!\n body: String!\n authorName: String!\n publishedAt: String!\n tags: [String!]!\n}\n\ntype Listing @key(fields: \"sellerId sku\") @openfed__entityCache(maxAge: 60) {\n sellerId: ID!\n sku: String!\n title: String!\n price: Float!\n currency: String!\n inStock: Boolean!\n}\n\ntype Address {\n id: ID!\n}\n\ntype Venue @key(fields: \"address { id }\") @openfed__entityCache(maxAge: 180) {\n address: Address!\n name: String!\n capacity: Int!\n city: String!\n}\n"},"upstreamSchema":{"key":"fabc39bc398d33faa5e52491a3a5aa91a8058d1f"}},"requestTimeoutSeconds":"10","id":"0","keys":[{"typeName":"UserProfile","selectionSet":"id"},{"typeName":"Catalog","selectionSet":"id"},{"typeName":"Metric","selectionSet":"id"},{"typeName":"Personalized","selectionSet":"id"},{"typeName":"Viewer","selectionSet":"id"},{"typeName":"Article","selectionSet":"id"},{"typeName":"Article","selectionSet":"slug"},{"typeName":"Listing","selectionSet":"sellerId sku"},{"typeName":"Venue","selectionSet":"address { id }"}],"entityInterfaces":[{"interfaceTypeName":"Personalized","concreteTypeNames":["Article"]}],"entityCacheConfigurations":[{"typeName":"UserProfile","maxAgeSeconds":"60","includeHeaders":true},{"typeName":"Catalog","maxAgeSeconds":"120","partialCacheLoad":true},{"typeName":"Metric","maxAgeSeconds":"300","shadowMode":true},{"typeName":"Article","maxAgeSeconds":"120"},{"typeName":"Listing","maxAgeSeconds":"60"},{"typeName":"Venue","maxAgeSeconds":"180"}],"rootFieldCacheConfigurations":[{"fieldName":"article","maxAgeSeconds":"120","entityTypeName":"Article","entityKeyMappings":[{"entityTypeName":"Article","fieldMappings":[{"entityKeyField":"id","argumentPath":["id"]}]}]},{"fieldName":"articles","maxAgeSeconds":"120","entityTypeName":"Article"},{"fieldName":"articlesByIds","maxAgeSeconds":"120","entityTypeName":"Article","entityKeyMappings":[{"entityTypeName":"Article","fieldMappings":[{"entityKeyField":"id","argumentPath":["ids"],"isBatch":true}]}]},{"fieldName":"articleBySlug","maxAgeSeconds":"120","entityTypeName":"Article","entityKeyMappings":[{"entityTypeName":"Article","fieldMappings":[{"entityKeyField":"slug","argumentPath":["slug"]}]}]},{"fieldName":"listing","maxAgeSeconds":"60","entityTypeName":"Listing","entityKeyMappings":[{"entityTypeName":"Listing","fieldMappings":[{"entityKeyField":"sellerId","argumentPath":["key","sellerId"]},{"entityKeyField":"sku","argumentPath":["key","sku"]}]}]},{"fieldName":"listings","maxAgeSeconds":"60","entityTypeName":"Listing"},{"fieldName":"venue","maxAgeSeconds":"180","entityTypeName":"Venue","entityKeyMappings":[{"entityTypeName":"Venue","fieldMappings":[{"entityKeyField":"address.id","argumentPath":["location","address","id"]}]}]},{"fieldName":"venues","maxAgeSeconds":"180","entityTypeName":"Venue"},{"fieldName":"userProfile","maxAgeSeconds":"60","includeHeaders":true,"entityTypeName":"UserProfile","entityKeyMappings":[{"entityTypeName":"UserProfile","fieldMappings":[{"entityKeyField":"id","argumentPath":["id"]}]}]},{"fieldName":"catalog","maxAgeSeconds":"120","entityTypeName":"Catalog","entityKeyMappings":[{"entityTypeName":"Catalog","fieldMappings":[{"entityKeyField":"id","argumentPath":["id"]}]}]},{"fieldName":"catalogs","maxAgeSeconds":"120","entityTypeName":"Catalog"},{"fieldName":"metric","maxAgeSeconds":"300","shadowMode":true,"entityTypeName":"Metric","entityKeyMappings":[{"entityTypeName":"Metric","fieldMappings":[{"entityKeyField":"id","argumentPath":["id"]}]}]}],"cachePopulateConfigurations":[{"fieldName":"createArticle","operationType":"Mutation","maxAgeSeconds":"30","entityTypeName":"Article"}],"cacheInvalidateConfigurations":[{"fieldName":"updateArticle","operationType":"Mutation","entityTypeName":"Article"},{"fieldName":"deleteListing","operationType":"Mutation","entityTypeName":"Listing"}]},{"kind":"GRAPHQL","rootNodes":[{"typeName":"Article","fieldNames":["id","viewCount","rating","reviewSummary","relatedArticles","personalizedRecommendation"],"externalFieldNames":["currentViewer"]},{"typeName":"Viewer","fieldNames":["id"],"externalFieldNames":["name"]},{"typeName":"Catalog","fieldNames":["id","description","lastUpdated"]}],"overrideFieldPathFromAlias":true,"customGraphql":{"fetch":{"url":{"staticVariableContent":"http://localhost:4013/graphql"},"method":"POST","body":{},"baseUrl":{},"path":{}},"subscription":{"enabled":true,"url":{"staticVariableContent":"http://localhost:4013/graphql"},"protocol":"GRAPHQL_SUBSCRIPTION_PROTOCOL_WS","websocketSubprotocol":"GRAPHQL_WEBSOCKET_SUBPROTOCOL_AUTO"},"federation":{"enabled":true,"serviceSdl":"extend schema\n @link(\n url: \"https://specs.apollo.dev/federation/v2.5\"\n import: [\"@key\", \"@external\", \"@requires\"]\n )\n\ndirective @openfed__entityCache(\n maxAge: Int!\n includeHeaders: Boolean = false\n partialCacheLoad: Boolean = false\n shadowMode: Boolean = false\n) on OBJECT\n\ntype Article @key(fields: \"id\") @openfed__entityCache(maxAge: 90) {\n id: ID!\n currentViewer: Viewer @external\n viewCount: Int!\n rating: Float!\n reviewSummary: String!\n relatedArticles: [Article!]!\n personalizedRecommendation: String! @requires(fields: \"currentViewer { id name }\")\n}\n\ntype Viewer @key(fields: \"id\") {\n id: ID!\n name: String! @external\n}\n\n\"\"\"Extends Catalog with description from a second subgraph (for partial cache load testing)\"\"\"\ntype Catalog @key(fields: \"id\") @openfed__entityCache(maxAge: 120, partialCacheLoad: true) {\n id: ID!\n description: String!\n lastUpdated: String!\n}\n"},"upstreamSchema":{"key":"a2cd2a1b7cb5ebae92f1c56df2d8c7d3a56d19e1"}},"requestTimeoutSeconds":"10","id":"1","keys":[{"typeName":"Article","selectionSet":"id"},{"typeName":"Viewer","selectionSet":"id"},{"typeName":"Catalog","selectionSet":"id"}],"requires":[{"typeName":"Article","fieldName":"personalizedRecommendation","selectionSet":"currentViewer { id name }"}],"entityCacheConfigurations":[{"typeName":"Article","maxAgeSeconds":"90"},{"typeName":"Catalog","maxAgeSeconds":"120","partialCacheLoad":true}]},{"kind":"GRAPHQL","rootNodes":[{"typeName":"Personalized","fieldNames":["id","currentViewer"]},{"typeName":"Viewer","fieldNames":["id","name","email"]},{"typeName":"Query","fieldNames":["currentViewer"]},{"typeName":"Article","fieldNames":["id","currentViewer"]}],"overrideFieldPathFromAlias":true,"customGraphql":{"fetch":{"url":{"staticVariableContent":"http://localhost:4014/graphql"},"method":"POST","body":{},"baseUrl":{},"path":{}},"subscription":{"enabled":true,"url":{"staticVariableContent":"http://localhost:4014/graphql"},"protocol":"GRAPHQL_SUBSCRIPTION_PROTOCOL_WS","websocketSubprotocol":"GRAPHQL_WEBSOCKET_SUBPROTOCOL_AUTO"},"federation":{"enabled":true,"serviceSdl":"extend schema\n @link(\n url: \"https://specs.apollo.dev/federation/v2.5\"\n import: [\"@key\", \"@interfaceObject\", \"@inaccessible\"]\n )\n\ndirective @openfed__requestScoped(key: String!) on FIELD_DEFINITION\n\n# Symmetric @openfed__requestScoped: both Query.currentViewer and Personalized.currentViewer\n# declare key: \"currentViewer\". Their L1 cache entry is \"viewer.currentViewer\".\n# Whichever is resolved first populates L1; subsequent fields with the same key\n# inject from L1 and skip the fetch.\ntype Personalized @key(fields: \"id\") @interfaceObject {\n id: ID!\n currentViewer: Viewer @inaccessible @openfed__requestScoped(key: \"currentViewer\")\n}\n\ntype Viewer @key(fields: \"id\") {\n id: ID!\n name: String!\n email: String!\n}\n\ntype Query {\n currentViewer: Viewer @openfed__requestScoped(key: \"currentViewer\")\n}\n"},"upstreamSchema":{"key":"9ee951b49b83d66e073d83402d78cd8078181571"}},"requestTimeoutSeconds":"10","id":"2","keys":[{"typeName":"Personalized","selectionSet":"id"},{"typeName":"Viewer","selectionSet":"id"},{"typeName":"Article","selectionSet":"id"}],"interfaceObjects":[{"interfaceTypeName":"Personalized","concreteTypeNames":["Article"]}],"requestScopedFields":[{"fieldName":"currentViewer","typeName":"Personalized","l1Key":"viewer.currentViewer"},{"fieldName":"currentViewer","typeName":"Query","l1Key":"viewer.currentViewer"}]}],"fieldConfigurations":[{"typeName":"Query","fieldName":"article","argumentsConfiguration":[{"name":"id","sourceType":"FIELD_ARGUMENT"}]},{"typeName":"Query","fieldName":"articlesByIds","argumentsConfiguration":[{"name":"ids","sourceType":"FIELD_ARGUMENT"}]},{"typeName":"Query","fieldName":"articleBySlug","argumentsConfiguration":[{"name":"slug","sourceType":"FIELD_ARGUMENT"}]},{"typeName":"Query","fieldName":"listing","argumentsConfiguration":[{"name":"key","sourceType":"FIELD_ARGUMENT"}]},{"typeName":"Query","fieldName":"venue","argumentsConfiguration":[{"name":"location","sourceType":"FIELD_ARGUMENT"}]},{"typeName":"Query","fieldName":"userProfile","argumentsConfiguration":[{"name":"id","sourceType":"FIELD_ARGUMENT"}]},{"typeName":"Query","fieldName":"catalog","argumentsConfiguration":[{"name":"id","sourceType":"FIELD_ARGUMENT"}]},{"typeName":"Query","fieldName":"metric","argumentsConfiguration":[{"name":"id","sourceType":"FIELD_ARGUMENT"}]},{"typeName":"Mutation","fieldName":"updateArticle","argumentsConfiguration":[{"name":"id","sourceType":"FIELD_ARGUMENT"},{"name":"title","sourceType":"FIELD_ARGUMENT"}]},{"typeName":"Mutation","fieldName":"createArticle","argumentsConfiguration":[{"name":"title","sourceType":"FIELD_ARGUMENT"},{"name":"body","sourceType":"FIELD_ARGUMENT"},{"name":"authorName","sourceType":"FIELD_ARGUMENT"}]},{"typeName":"Mutation","fieldName":"deleteListing","argumentsConfiguration":[{"name":"key","sourceType":"FIELD_ARGUMENT"}]}],"graphqlSchema":"schema {\n query: Query\n mutation: Mutation\n}\n\ndirective @inaccessible on ARGUMENT_DEFINITION | ENUM | ENUM_VALUE | FIELD_DEFINITION | INPUT_FIELD_DEFINITION | INPUT_OBJECT | INTERFACE | OBJECT | SCALAR | UNION\n\ntype Query {\n \"\"\"Simple key lookup\"\"\"\n article(id: ID!): Article\n \"\"\"List query\"\"\"\n articles: [Article!]!\n \"\"\"Batch lookup with @openfed__is\"\"\"\n articlesByIds(ids: [ID!]!): [Article!]!\n \"\"\"Argument remapping via @openfed__is\"\"\"\n articleBySlug(slug: String!): Article\n \"\"\"Composite key lookup via input object with @openfed__is\"\"\"\n listing(key: ListingKey!): Listing\n \"\"\"List of all listings\"\"\"\n listings: [Listing!]!\n \"\"\"Nested key lookup with @openfed__is and input object\"\"\"\n venue(location: VenueLocationKey!): Venue\n \"\"\"List of all venues\"\"\"\n venues: [Venue!]!\n \"\"\"Per-user profile (cache varies by Authorization header)\"\"\"\n userProfile(id: ID!): UserProfile\n \"\"\"Single catalog entry\"\"\"\n catalog(id: ID!): Catalog\n \"\"\"All catalog entries (for partial cache load testing)\"\"\"\n catalogs: [Catalog!]!\n \"\"\"\n Single metric (shadow mode - always fetches from subgraph, compares with cache)\n \"\"\"\n metric(id: ID!): Metric\n currentViewer: Viewer\n}\n\ntype Mutation {\n updateArticle(id: ID!, title: String!): Article\n createArticle(title: String!, body: String!, authorName: String!): Article!\n deleteListing(key: ListingKey!): Listing\n}\n\n\"\"\"\nPer-user caching: includeHeaders makes the cache key include a hash of forwarded headers (e.g. Authorization)\n\"\"\"\ntype UserProfile {\n id: ID!\n username: String!\n email: String!\n role: String!\n}\n\n\"\"\"\nPartial cache load: when some entities are cached and others aren't, only the missing ones are fetched\n\"\"\"\ntype Catalog {\n id: ID!\n name: String!\n category: String!\n itemCount: Int!\n description: String!\n lastUpdated: String!\n}\n\n\"\"\"\nShadow mode: always fetches from subgraph but compares with cache for staleness detection\n\"\"\"\ntype Metric {\n id: ID!\n name: String!\n value: Float!\n unit: String!\n}\n\ninput ListingKey {\n sellerId: ID!\n sku: String!\n}\n\ninput VenueLocationKey {\n address: VenueAddressKey!\n}\n\ninput VenueAddressKey {\n id: ID!\n}\n\ninterface Personalized {\n id: ID!\n currentViewer: Viewer @inaccessible\n}\n\ntype Viewer {\n id: ID!\n recommendedArticles: [Article!]!\n name: String!\n email: String!\n}\n\ntype Listing {\n sellerId: ID!\n sku: String!\n title: String!\n price: Float!\n currency: String!\n inStock: Boolean!\n}\n\ntype Address {\n id: ID!\n}\n\ntype Venue {\n address: Address!\n name: String!\n capacity: Int!\n city: String!\n}\n\ntype Article implements Personalized {\n id: ID!\n slug: String!\n title: String!\n body: String!\n authorName: String!\n publishedAt: String!\n tags: [String!]!\n currentViewer: Viewer\n viewCount: Int!\n rating: Float!\n reviewSummary: String!\n relatedArticles: [Article!]!\n personalizedRecommendation: String!\n}","stringStorage":{"fabc39bc398d33faa5e52491a3a5aa91a8058d1f":"schema {\n query: Query\n mutation: Mutation\n}\n\ndirective @key(fields: openfed__FieldSet!, resolvable: Boolean = true) repeatable on INTERFACE | OBJECT\n\ndirective @link(as: String, for: link__Purpose, import: [link__Import], url: String!) repeatable on SCHEMA\n\ndirective @openfed__cacheInvalidate on FIELD_DEFINITION\n\ndirective @openfed__cachePopulate(maxAge: Int) on FIELD_DEFINITION\n\ndirective @openfed__entityCache(includeHeaders: Boolean = false, maxAge: Int!, negativeCacheTTL: Int = 0, partialCacheLoad: Boolean = false, shadowMode: Boolean = false) on OBJECT\n\ndirective @openfed__is(fields: String!) on ARGUMENT_DEFINITION\n\ndirective @openfed__queryCache(includeHeaders: Boolean = false, maxAge: Int!, shadowMode: Boolean = false) on FIELD_DEFINITION\n\ntype Address {\n id: ID!\n}\n\ntype Article implements Personalized @key(fields: \"id\") @key(fields: \"slug\") @openfed__entityCache(maxAge: 120) {\n authorName: String!\n body: String!\n id: ID!\n publishedAt: String!\n slug: String!\n tags: [String!]!\n title: String!\n}\n\n\"\"\"\nPartial cache load: when some entities are cached and others aren't, only the missing ones are fetched\n\"\"\"\ntype Catalog @key(fields: \"id\") @openfed__entityCache(maxAge: 120, partialCacheLoad: true) {\n category: String!\n id: ID!\n itemCount: Int!\n name: String!\n}\n\ntype Listing @key(fields: \"sellerId sku\") @openfed__entityCache(maxAge: 60) {\n currency: String!\n inStock: Boolean!\n price: Float!\n sellerId: ID!\n sku: String!\n title: String!\n}\n\ninput ListingKey {\n sellerId: ID!\n sku: String!\n}\n\n\"\"\"\nShadow mode: always fetches from subgraph but compares with cache for staleness detection\n\"\"\"\ntype Metric @key(fields: \"id\") @openfed__entityCache(maxAge: 300, shadowMode: true) {\n id: ID!\n name: String!\n unit: String!\n value: Float!\n}\n\ntype Mutation {\n createArticle(authorName: String!, body: String!, title: String!): Article! @openfed__cachePopulate(maxAge: 30)\n deleteListing(key: ListingKey!): Listing @openfed__cacheInvalidate\n updateArticle(id: ID!, title: String!): Article @openfed__cacheInvalidate\n}\n\ninterface Personalized @key(fields: \"id\") {\n id: ID!\n}\n\ntype Query {\n \"\"\"Simple key lookup\"\"\"\n article(id: ID!): Article @openfed__queryCache(maxAge: 120)\n \"\"\"Argument remapping via @openfed__is\"\"\"\n articleBySlug(slug: String! @openfed__is(fields: \"slug\")): Article @openfed__queryCache(maxAge: 120)\n \"\"\"List query\"\"\"\n articles: [Article!]! @openfed__queryCache(maxAge: 120)\n \"\"\"Batch lookup with @openfed__is\"\"\"\n articlesByIds(ids: [ID!]! @openfed__is(fields: \"id\")): [Article!]! @openfed__queryCache(maxAge: 120)\n \"\"\"Single catalog entry\"\"\"\n catalog(id: ID!): Catalog @openfed__queryCache(maxAge: 120)\n \"\"\"All catalog entries (for partial cache load testing)\"\"\"\n catalogs: [Catalog!]! @openfed__queryCache(maxAge: 120)\n \"\"\"Composite key lookup via input object with @openfed__is\"\"\"\n listing(key: ListingKey! @openfed__is(fields: \"sellerId sku\")): Listing @openfed__queryCache(maxAge: 60)\n \"\"\"List of all listings\"\"\"\n listings: [Listing!]! @openfed__queryCache(maxAge: 60)\n \"\"\"\n Single metric (shadow mode - always fetches from subgraph, compares with cache)\n \"\"\"\n metric(id: ID!): Metric @openfed__queryCache(maxAge: 300, shadowMode: true)\n \"\"\"Per-user profile (cache varies by Authorization header)\"\"\"\n userProfile(id: ID!): UserProfile @openfed__queryCache(maxAge: 60, includeHeaders: true)\n \"\"\"Nested key lookup with @openfed__is and input object\"\"\"\n venue(location: VenueLocationKey! @openfed__is(fields: \"address { id }\")): Venue @openfed__queryCache(maxAge: 180)\n \"\"\"List of all venues\"\"\"\n venues: [Venue!]! @openfed__queryCache(maxAge: 180)\n}\n\n\"\"\"\nPer-user caching: includeHeaders makes the cache key include a hash of forwarded headers (e.g. Authorization)\n\"\"\"\ntype UserProfile @key(fields: \"id\") @openfed__entityCache(maxAge: 60, includeHeaders: true) {\n email: String!\n id: ID!\n role: String!\n username: String!\n}\n\ntype Venue @key(fields: \"address { id }\") @openfed__entityCache(maxAge: 180) {\n address: Address!\n capacity: Int!\n city: String!\n name: String!\n}\n\ninput VenueAddressKey {\n id: ID!\n}\n\ninput VenueLocationKey {\n address: VenueAddressKey!\n}\n\ntype Viewer @key(fields: \"id\") {\n id: ID!\n recommendedArticles: [Article!]!\n}\n\nscalar link__Import\n\nenum link__Purpose {\n EXECUTION\n SECURITY\n}\n\nscalar openfed__FieldSet","a2cd2a1b7cb5ebae92f1c56df2d8c7d3a56d19e1":"directive @external on FIELD_DEFINITION | OBJECT\n\ndirective @key(fields: openfed__FieldSet!, resolvable: Boolean = true) repeatable on INTERFACE | OBJECT\n\ndirective @link(as: String, for: link__Purpose, import: [link__Import], url: String!) repeatable on SCHEMA\n\ndirective @openfed__entityCache(includeHeaders: Boolean = false, maxAge: Int!, negativeCacheTTL: Int = 0, partialCacheLoad: Boolean = false, shadowMode: Boolean = false) on OBJECT\n\ndirective @requires(fields: openfed__FieldSet!) on FIELD_DEFINITION\n\ntype Article @key(fields: \"id\") @openfed__entityCache(maxAge: 90) {\n currentViewer: Viewer @external\n id: ID!\n personalizedRecommendation: String! @requires(fields: \"currentViewer { id name }\")\n rating: Float!\n relatedArticles: [Article!]!\n reviewSummary: String!\n viewCount: Int!\n}\n\n\"\"\"\nExtends Catalog with description from a second subgraph (for partial cache load testing)\n\"\"\"\ntype Catalog @key(fields: \"id\") @openfed__entityCache(maxAge: 120, partialCacheLoad: true) {\n description: String!\n id: ID!\n lastUpdated: String!\n}\n\ntype Viewer @key(fields: \"id\") {\n id: ID!\n name: String! @external\n}\n\nscalar link__Import\n\nenum link__Purpose {\n EXECUTION\n SECURITY\n}\n\nscalar openfed__FieldSet","9ee951b49b83d66e073d83402d78cd8078181571":"schema {\n query: Query\n}\n\ndirective @inaccessible on ARGUMENT_DEFINITION | ENUM | ENUM_VALUE | FIELD_DEFINITION | INPUT_FIELD_DEFINITION | INPUT_OBJECT | INTERFACE | OBJECT | SCALAR | UNION\n\ndirective @interfaceObject on OBJECT\n\ndirective @key(fields: openfed__FieldSet!, resolvable: Boolean = true) repeatable on INTERFACE | OBJECT\n\ndirective @link(as: String, for: link__Purpose, import: [link__Import], url: String!) repeatable on SCHEMA\n\ndirective @openfed__requestScoped(key: String!) on FIELD_DEFINITION\n\ntype Personalized @key(fields: \"id\") @interfaceObject {\n currentViewer: Viewer @inaccessible @openfed__requestScoped(key: \"currentViewer\")\n id: ID!\n}\n\ntype Query {\n currentViewer: Viewer @openfed__requestScoped(key: \"currentViewer\")\n}\n\ntype Viewer @key(fields: \"id\") {\n email: String!\n id: ID!\n name: String!\n}\n\nscalar link__Import\n\nenum link__Purpose {\n EXECUTION\n SECURITY\n}\n\nscalar openfed__FieldSet"},"graphqlClientSchema":"schema {\n query: Query\n mutation: Mutation\n}\n\ntype Query {\n \"\"\"Simple key lookup\"\"\"\n article(id: ID!): Article\n \"\"\"List query\"\"\"\n articles: [Article!]!\n \"\"\"Batch lookup with @openfed__is\"\"\"\n articlesByIds(ids: [ID!]!): [Article!]!\n \"\"\"Argument remapping via @openfed__is\"\"\"\n articleBySlug(slug: String!): Article\n \"\"\"Composite key lookup via input object with @openfed__is\"\"\"\n listing(key: ListingKey!): Listing\n \"\"\"List of all listings\"\"\"\n listings: [Listing!]!\n \"\"\"Nested key lookup with @openfed__is and input object\"\"\"\n venue(location: VenueLocationKey!): Venue\n \"\"\"List of all venues\"\"\"\n venues: [Venue!]!\n \"\"\"Per-user profile (cache varies by Authorization header)\"\"\"\n userProfile(id: ID!): UserProfile\n \"\"\"Single catalog entry\"\"\"\n catalog(id: ID!): Catalog\n \"\"\"All catalog entries (for partial cache load testing)\"\"\"\n catalogs: [Catalog!]!\n \"\"\"\n Single metric (shadow mode - always fetches from subgraph, compares with cache)\n \"\"\"\n metric(id: ID!): Metric\n currentViewer: Viewer\n}\n\ntype Mutation {\n updateArticle(id: ID!, title: String!): Article\n createArticle(title: String!, body: String!, authorName: String!): Article!\n deleteListing(key: ListingKey!): Listing\n}\n\n\"\"\"\nPer-user caching: includeHeaders makes the cache key include a hash of forwarded headers (e.g. Authorization)\n\"\"\"\ntype UserProfile {\n id: ID!\n username: String!\n email: String!\n role: String!\n}\n\n\"\"\"\nPartial cache load: when some entities are cached and others aren't, only the missing ones are fetched\n\"\"\"\ntype Catalog {\n id: ID!\n name: String!\n category: String!\n itemCount: Int!\n description: String!\n lastUpdated: String!\n}\n\n\"\"\"\nShadow mode: always fetches from subgraph but compares with cache for staleness detection\n\"\"\"\ntype Metric {\n id: ID!\n name: String!\n value: Float!\n unit: String!\n}\n\ninput ListingKey {\n sellerId: ID!\n sku: String!\n}\n\ninput VenueLocationKey {\n address: VenueAddressKey!\n}\n\ninput VenueAddressKey {\n id: ID!\n}\n\ninterface Personalized {\n id: ID!\n}\n\ntype Viewer {\n id: ID!\n recommendedArticles: [Article!]!\n name: String!\n email: String!\n}\n\ntype Listing {\n sellerId: ID!\n sku: String!\n title: String!\n price: Float!\n currency: String!\n inStock: Boolean!\n}\n\ntype Address {\n id: ID!\n}\n\ntype Venue {\n address: Address!\n name: String!\n capacity: Int!\n city: String!\n}\n\ntype Article implements Personalized {\n id: ID!\n slug: String!\n title: String!\n body: String!\n authorName: String!\n publishedAt: String!\n tags: [String!]!\n currentViewer: Viewer\n viewCount: Int!\n rating: Float!\n reviewSummary: String!\n relatedArticles: [Article!]!\n personalizedRecommendation: String!\n}"},"version":"00000000-0000-0000-0000-000000000000","subgraphs":[{"id":"0","name":"cachegraph","routingUrl":"http://localhost:4012/graphql"},{"id":"1","name":"cachegraph-ext","routingUrl":"http://localhost:4013/graphql"},{"id":"2","name":"viewer","routingUrl":"http://localhost:4014/graphql"}],"compatibilityVersion":"1:{{$COMPOSITION__VERSION}}"} \ No newline at end of file diff --git a/demo/go.mod b/demo/go.mod index d0d215ae24..5469cb860c 100644 --- a/demo/go.mod +++ b/demo/go.mod @@ -9,6 +9,7 @@ require ( github.com/nats-io/nats.go v1.35.0 github.com/ravilushqa/otelgqlgen v0.13.1 github.com/rs/cors v1.11.0 + github.com/stretchr/testify v1.11.1 github.com/vektah/gqlparser/v2 v2.5.30 github.com/wundergraph/cosmo/router v0.0.0-20260330183556-dc4388d100a4 github.com/wundergraph/cosmo/router-tests v0.0.0-20260330183556-dc4388d100a4 @@ -128,7 +129,6 @@ require ( github.com/sosodev/duration v1.3.1 // indirect github.com/spf13/cast v1.7.1 // indirect github.com/stretchr/objx v0.5.2 // indirect - github.com/stretchr/testify v1.11.1 // indirect github.com/tidwall/gjson v1.18.0 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.1 // indirect diff --git a/demo/graph-cache-only.yaml b/demo/graph-cache-only.yaml new file mode 100644 index 0000000000..bb44db59fd --- /dev/null +++ b/demo/graph-cache-only.yaml @@ -0,0 +1,14 @@ +version: 1 +subgraphs: + - name: cachegraph + routing_url: http://localhost:4012/graphql + schema: + file: ./pkg/subgraphs/cachegraph/subgraph/schema.graphqls + - name: cachegraph-ext + routing_url: http://localhost:4013/graphql + schema: + file: ./pkg/subgraphs/cachegraph_ext/subgraph/schema.graphqls + - name: viewer + routing_url: http://localhost:4014/graphql + schema: + file: ./pkg/subgraphs/viewer/subgraph/schema.graphqls diff --git a/demo/graph-cachetest.yaml b/demo/graph-cachetest.yaml new file mode 100644 index 0000000000..b08eaea031 --- /dev/null +++ b/demo/graph-cachetest.yaml @@ -0,0 +1,26 @@ +version: 1 +subgraphs: + - name: items + routing_url: http://items.entity-cache-test.local/graphql + schema: + file: ./pkg/subgraphs/cachetest/items/subgraph/schema.graphqls + - name: details + routing_url: http://details.entity-cache-test.local/graphql + schema: + file: ./pkg/subgraphs/cachetest/details/subgraph/schema.graphqls + - name: inventory + routing_url: http://inventory.entity-cache-test.local/graphql + schema: + file: ./pkg/subgraphs/cachetest/inventory/subgraph/schema.graphqls + - name: viewer + routing_url: http://viewer.entity-cache-test.local/graphql + schema: + file: ./pkg/subgraphs/cachetest/viewer/subgraph/schema.graphqls + - name: articles + routing_url: http://articles.entity-cache-test.local/graphql + schema: + file: ./pkg/subgraphs/cachetest/articles/subgraph/schema.graphqls + - name: articlesmeta + routing_url: http://articlesmeta.entity-cache-test.local/graphql + schema: + file: ./pkg/subgraphs/cachetest/articlesmeta/subgraph/schema.graphqls diff --git a/demo/graph.yaml b/demo/graph.yaml index 4782c1e3e1..62ebdce6e3 100644 --- a/demo/graph.yaml +++ b/demo/graph.yaml @@ -40,6 +40,10 @@ subgraphs: routing_url: http://localhost:4009/graphql schema: file: ./pkg/subgraphs/countries/subgraph/schema.graphqls + - name: cachegraph + routing_url: http://localhost:4012/graphql + schema: + file: ./pkg/subgraphs/cachegraph/subgraph/schema.graphqls - name: employeeupdated schema: file: ./pkg/subgraphs/employeeupdated/subgraph/schema.graphqls diff --git a/demo/pkg/injector/latency.go b/demo/pkg/injector/latency.go new file mode 100644 index 0000000000..ea4a6813ae --- /dev/null +++ b/demo/pkg/injector/latency.go @@ -0,0 +1,29 @@ +package injector + +import ( + "log" + "net/http" + "strconv" + "time" +) + +// ArtificialLatencyHeader lets the playground or any client inject fake latency +// into a demo subgraph response. Value is milliseconds as an integer, bounded +// at 10000. Intended for demos where local subgraphs are too fast to make +// caching benefits visible. +const ArtificialLatencyHeader = "X-Artificial-Latency" + +// Latency wraps a handler and sleeps for the number of milliseconds specified +// in the X-Artificial-Latency request header before passing the request down. +// Invalid values are silently ignored. +func Latency(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if v := r.Header.Get(ArtificialLatencyHeader); v != "" { + if ms, err := strconv.Atoi(v); err == nil && ms > 0 && ms <= 10000 { + log.Printf("[latency] %s %s sleep %dms prefix=%q", r.Method, r.Host, ms, r.Header.Get("X-WG-Cache-Key-Prefix")) + time.Sleep(time.Duration(ms) * time.Millisecond) + } + } + next.ServeHTTP(w, r) + }) +} diff --git a/demo/pkg/subgraphs/cachegraph/cachegraph.go b/demo/pkg/subgraphs/cachegraph/cachegraph.go new file mode 100644 index 0000000000..ba407cc9f9 --- /dev/null +++ b/demo/pkg/subgraphs/cachegraph/cachegraph.go @@ -0,0 +1,12 @@ +package cachegraph + +import ( + "github.com/99designs/gqlgen/graphql" + + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachegraph/subgraph" + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachegraph/subgraph/generated" +) + +func NewSchema() graphql.ExecutableSchema { + return generated.NewExecutableSchema(generated.Config{Resolvers: subgraph.NewResolver()}) +} diff --git a/demo/pkg/subgraphs/cachegraph/generate.go b/demo/pkg/subgraphs/cachegraph/generate.go new file mode 100644 index 0000000000..f2e485a8c2 --- /dev/null +++ b/demo/pkg/subgraphs/cachegraph/generate.go @@ -0,0 +1,2 @@ +//go:generate go run github.com/99designs/gqlgen generate +package cachegraph diff --git a/demo/pkg/subgraphs/cachegraph/gqlgen.yml b/demo/pkg/subgraphs/cachegraph/gqlgen.yml new file mode 100644 index 0000000000..07d1eeac61 --- /dev/null +++ b/demo/pkg/subgraphs/cachegraph/gqlgen.yml @@ -0,0 +1,55 @@ +# Where are all the schema files located? globs are supported eg src/**/*.graphqls +schema: + - subgraph/*.graphqls + +# Where should the generated server code go? +exec: + filename: subgraph/generated/generated.go + package: generated + +federation: + filename: subgraph/generated/federation.go + package: generated + version: 2 + options: + explicit_requires: true + +# Where should any generated models go? +model: + filename: subgraph/model/models_gen.go + package: model + +# Where should the resolver implementations go? +resolver: + layout: follow-schema + dir: subgraph + package: subgraph + +directives: + openfed__entityCache: + skip_runtime: true + openfed__queryCache: + skip_runtime: true + openfed__cacheInvalidate: + skip_runtime: true + openfed__cachePopulate: + skip_runtime: true + openfed__is: + skip_runtime: true + +models: + Viewer: + fields: + recommendedArticles: + resolver: true + ID: + model: + - github.com/99designs/gqlgen/graphql.ID + - github.com/99designs/gqlgen/graphql.Int + - github.com/99designs/gqlgen/graphql.Int64 + - github.com/99designs/gqlgen/graphql.Int32 + Int: + model: + - github.com/99designs/gqlgen/graphql.Int + - github.com/99designs/gqlgen/graphql.Int64 + - github.com/99designs/gqlgen/graphql.Int32 diff --git a/demo/pkg/subgraphs/cachegraph/subgraph/auth_profiles.go b/demo/pkg/subgraphs/cachegraph/subgraph/auth_profiles.go new file mode 100644 index 0000000000..9ce71737b0 --- /dev/null +++ b/demo/pkg/subgraphs/cachegraph/subgraph/auth_profiles.go @@ -0,0 +1,12 @@ +package subgraph + +// userProfileIDByAuthorizationToken maps the demo Authorization bearer tokens to +// user ids. Used by the UserProfile resolver to vary its response per caller so +// that @openfed__queryCache(includeHeaders: true) has a detectable signal. +// Kept in a separate file so gqlgen's regen of schema.resolvers.go does not +// touch it. +var userProfileIDByAuthorizationToken = map[string]string{ + "Bearer token-alice": "u1", + "Bearer token-bob": "u2", + "Bearer token-charlie": "u3", +} diff --git a/demo/pkg/subgraphs/cachegraph/subgraph/data.go b/demo/pkg/subgraphs/cachegraph/subgraph/data.go new file mode 100644 index 0000000000..aea537e503 --- /dev/null +++ b/demo/pkg/subgraphs/cachegraph/subgraph/data.go @@ -0,0 +1,336 @@ +package subgraph + +import ( + "fmt" + "sort" + "sync" + "time" + + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachegraph/subgraph/model" +) + +// defaultArticles is the seed data for a fresh article store. Each Resolver +// clones this so mutations are isolated per server instance. +var defaultArticles = []*model.Article{ + { + ID: "1", + Slug: "introduction-to-graphql-caching", + Title: "Introduction to GraphQL Caching", + Body: "Entity caching allows you to cache resolved entities at the subgraph level.", + AuthorName: "Alice", + PublishedAt: "2025-01-15T10:00:00Z", + Tags: []string{"graphql", "caching", "federation"}, + }, + { + ID: "2", + Slug: "advanced-federation-patterns", + Title: "Advanced Federation Patterns", + Body: "Learn how to use composite keys and nested keys in federation.", + AuthorName: "Bob", + PublishedAt: "2025-02-20T14:30:00Z", + Tags: []string{"federation", "advanced"}, + }, + { + ID: "3", + Slug: "cache-invalidation-strategies", + Title: "Cache Invalidation Strategies", + Body: "Explore different approaches to invalidating cached entities.", + AuthorName: "Charlie", + PublishedAt: "2025-03-10T09:00:00Z", + Tags: []string{"caching", "patterns"}, + }, + { + ID: "4", + Slug: "performance-tuning-with-entity-caching", + Title: "Performance Tuning with Entity Caching", + Body: "How to get the most out of entity caching in production.", + AuthorName: "Alice", + PublishedAt: "2025-04-01T11:00:00Z", + Tags: []string{"performance", "caching"}, + }, +} + +// recommendedArticlesByViewer is read-only seed data — different users get +// different recommendations. Shared across stores because it is never mutated. +var recommendedArticlesByViewer = map[string][]string{ + "v1": {"2", "3"}, // Alice → Advanced Federation + Cache Invalidation + "v2": {"1", "4"}, // Bob → Intro to Caching + Performance Tuning + "v3": {"1", "2", "3"}, // Charlie → all except Performance Tuning +} + +type listingKey struct { + SellerID string + SKU string +} + +// defaultListings is the seed data for a fresh listing store. +func defaultListings() map[listingKey]*model.Listing { + return map[listingKey]*model.Listing{ + {SellerID: "s1", SKU: "WIDGET-01"}: { + SellerID: "s1", + Sku: "WIDGET-01", + Title: "Premium Widget", + Price: 29.99, + Currency: "USD", + InStock: true, + }, + {SellerID: "s1", SKU: "GADGET-02"}: { + SellerID: "s1", + Sku: "GADGET-02", + Title: "Deluxe Gadget", + Price: 49.99, + Currency: "USD", + InStock: true, + }, + {SellerID: "s2", SKU: "GIZMO-01"}: { + SellerID: "s2", + Sku: "GIZMO-01", + Title: "Compact Gizmo", + Price: 19.50, + Currency: "EUR", + InStock: false, + }, + {SellerID: "s2", SKU: "THING-03"}: { + SellerID: "s2", + Sku: "THING-03", + Title: "Multi-Purpose Thing", + Price: 9.99, + Currency: "EUR", + InStock: true, + }, + } +} + +// articleStore is a mutex-guarded store for mutable article data. Used by the +// query, mutation, entity, and viewer resolvers. +type articleStore struct { + mu sync.RWMutex + articles []*model.Article +} + +func newArticleStore() *articleStore { + return &articleStore{articles: cloneArticles(defaultArticles)} +} + +func (s *articleStore) all() []*model.Article { + s.mu.RLock() + defer s.mu.RUnlock() + return cloneArticles(s.articles) +} + +func (s *articleStore) find(id string) *model.Article { + s.mu.RLock() + defer s.mu.RUnlock() + for _, a := range s.articles { + if a.ID == id { + return cloneArticle(a) + } + } + return nil +} + +func (s *articleStore) findBySlug(slug string) *model.Article { + s.mu.RLock() + defer s.mu.RUnlock() + for _, a := range s.articles { + if a.Slug == slug { + return cloneArticle(a) + } + } + return nil +} + +func (s *articleStore) byIDs(ids []string) []*model.Article { + idSet := make(map[string]struct{}, len(ids)) + for _, id := range ids { + idSet[id] = struct{}{} + } + s.mu.RLock() + defer s.mu.RUnlock() + var out []*model.Article + for _, a := range s.articles { + if _, ok := idSet[a.ID]; ok { + out = append(out, cloneArticle(a)) + } + } + return out +} + +func (s *articleStore) update(id, title string) *model.Article { + s.mu.Lock() + defer s.mu.Unlock() + for _, a := range s.articles { + if a.ID == id { + a.Title = title + return cloneArticle(a) + } + } + return nil +} + +func (s *articleStore) create(title, body, authorName string) *model.Article { + s.mu.Lock() + defer s.mu.Unlock() + id := fmt.Sprintf("%d", len(s.articles)+1) + a := &model.Article{ + ID: id, + Slug: "article-" + id, + Title: title, + Body: body, + AuthorName: authorName, + PublishedAt: time.Now().Format(time.RFC3339), + Tags: []string{}, + } + s.articles = append(s.articles, a) + return cloneArticle(a) +} + +func (s *articleStore) recommendedForViewer(viewerID string) []*model.Article { + ids := recommendedArticlesByViewer[viewerID] + if len(ids) == 0 { + return nil + } + s.mu.RLock() + defer s.mu.RUnlock() + var out []*model.Article + for _, id := range ids { + for _, a := range s.articles { + if a.ID == id { + out = append(out, cloneArticle(a)) + break + } + } + } + return out +} + +// listingStore is a mutex-guarded store for mutable listing data. +type listingStore struct { + mu sync.RWMutex + listings map[listingKey]*model.Listing +} + +func newListingStore() *listingStore { + return &listingStore{listings: defaultListings()} +} + +func (s *listingStore) get(sellerID, sku string) *model.Listing { + s.mu.RLock() + defer s.mu.RUnlock() + if l, ok := s.listings[listingKey{SellerID: sellerID, SKU: sku}]; ok { + return cloneListing(l) + } + return nil +} + +func (s *listingStore) all() []*model.Listing { + s.mu.RLock() + defer s.mu.RUnlock() + out := make([]*model.Listing, 0, len(s.listings)) + for _, l := range s.listings { + out = append(out, cloneListing(l)) + } + return out +} + +func (s *listingStore) delete(sellerID, sku string) *model.Listing { + k := listingKey{SellerID: sellerID, SKU: sku} + s.mu.Lock() + defer s.mu.Unlock() + l, ok := s.listings[k] + if !ok { + return nil + } + delete(s.listings, k) + return cloneListing(l) +} + +func cloneArticle(a *model.Article) *model.Article { + if a == nil { + return nil + } + c := *a + if a.Tags != nil { + c.Tags = append([]string(nil), a.Tags...) + } + return &c +} + +func cloneArticles(in []*model.Article) []*model.Article { + out := make([]*model.Article, len(in)) + for i, a := range in { + out[i] = cloneArticle(a) + } + return out +} + +func cloneListing(l *model.Listing) *model.Listing { + if l == nil { + return nil + } + c := *l + return &c +} + +// --- read-only seed data below (no writers) --- + +var venuesData = map[string]*model.Venue{ + "v1": { + Address: &model.Address{ID: "v1"}, + Name: "Grand Conference Hall", + Capacity: 500, + City: "Berlin", + }, + "v2": { + Address: &model.Address{ID: "v2"}, + Name: "Innovation Hub", + Capacity: 150, + City: "Munich", + }, + "v3": { + Address: &model.Address{ID: "v3"}, + Name: "Tech Campus Auditorium", + Capacity: 1000, + City: "Hamburg", + }, +} + +func allVenues() []*model.Venue { + out := make([]*model.Venue, 0, len(venuesData)) + for _, v := range venuesData { + out = append(out, v) + } + return out +} + +// UserProfile data — keyed by user ID, returns different data based on role +var userProfilesData = map[string]*model.UserProfile{ + "u1": {ID: "u1", Username: "alice", Email: "alice@example.com", Role: "admin"}, + "u2": {ID: "u2", Username: "bob", Email: "bob@example.com", Role: "editor"}, + "u3": {ID: "u3", Username: "charlie", Email: "charlie@example.com", Role: "viewer"}, +} + +// Catalog data — for partial cache load testing +var catalogsData = map[string]*model.Catalog{ + "c1": {ID: "c1", Name: "Electronics", Category: "tech", ItemCount: 342}, + "c2": {ID: "c2", Name: "Books", Category: "media", ItemCount: 1205}, + "c3": {ID: "c3", Name: "Clothing", Category: "fashion", ItemCount: 567}, +} + +func allCatalogs() []*model.Catalog { + out := make([]*model.Catalog, 0, len(catalogsData)) + for _, c := range catalogsData { + out = append(out, c) + } + sort.Slice(out, func(i, j int) bool { + return out[i].ID < out[j].ID + }) + return out +} + +// Metric data — for shadow mode testing +var metricsData = map[string]*model.Metric{ + "m1": {ID: "m1", Name: "requests_per_second", Value: 1523.7, Unit: "req/s"}, + "m2": {ID: "m2", Name: "error_rate", Value: 0.23, Unit: "percent"}, + "m3": {ID: "m3", Name: "p99_latency", Value: 42.5, Unit: "ms"}, +} diff --git a/demo/pkg/subgraphs/cachegraph/subgraph/data_race_test.go b/demo/pkg/subgraphs/cachegraph/subgraph/data_race_test.go new file mode 100644 index 0000000000..0898176ac3 --- /dev/null +++ b/demo/pkg/subgraphs/cachegraph/subgraph/data_race_test.go @@ -0,0 +1,160 @@ +package subgraph + +import ( + "context" + "fmt" + "sync" + "testing" + "time" + + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachegraph/subgraph/model" +) + +// TestArticleStoreNoRace hammers an articleStore with concurrent readers, +// writers, and deletions for ~100ms. Run with `go test -race` to catch any +// unsynchronized access. Failure with -race manifests as a runtime "DATA RACE" +// report, not a test-level assertion. +func TestArticleStoreNoRace(t *testing.T) { + t.Parallel() + + store := newArticleStore() + start := make(chan struct{}) + var deadline time.Time + + var wg sync.WaitGroup + for w := range 4 { + wg.Go(func() { + <-start + for i := 0; time.Now().Before(deadline); i++ { + _ = store.create( + fmt.Sprintf("writer-%d-%d", w, i), + "body", + "author", + ) + } + }) + } + + for range 4 { + wg.Go(func() { + <-start + for time.Now().Before(deadline) { + _ = store.all() + _ = store.find("1") + _ = store.byIDs([]string{"1", "2", "3"}) + _ = store.recommendedForViewer("v1") + } + }) + } + + for range 2 { + wg.Go(func() { + <-start + for time.Now().Before(deadline) { + _ = store.update("1", "updated-title") + } + }) + } + + deadline = time.Now().Add(100 * time.Millisecond) + close(start) + wg.Wait() +} + +// TestListingStoreNoRace hammers a single listingStore with concurrent +// readers and deletions for ~100ms. Run with `go test -race` to catch any +// unsynchronized access. +func TestListingStoreNoRace(t *testing.T) { + t.Parallel() + + store := newListingStore() + start := make(chan struct{}) + var deadline time.Time + + var wg sync.WaitGroup + for range 4 { + wg.Go(func() { + <-start + for time.Now().Before(deadline) { + _ = store.all() + _ = store.get("s1", "WIDGET-01") + _ = store.get("s2", "GIZMO-01") + } + }) + } + + // Writers: attempt to delete the same keys repeatedly on the shared store. + // Delete is idempotent once the key is gone, so the read paths still see a + // shrinking-then-empty map while concurrent iteration happens in all(). + for range 2 { + wg.Go(func() { + <-start + for time.Now().Before(deadline) { + _ = store.delete("s1", "WIDGET-01") + _ = store.delete("s1", "GADGET-02") + _ = store.delete("s2", "GIZMO-01") + _ = store.delete("s2", "THING-03") + } + }) + } + + deadline = time.Now().Add(100 * time.Millisecond) + close(start) + wg.Wait() +} + +// TestResolverPathNoRace drives concurrent read + write traffic through the +// generated gqlgen resolver layer (mutationResolver / queryResolver / +// viewerResolver) for ~100ms. This guards against regressions where a resolver +// bypasses the mutex-guarded stores (e.g. by reintroducing a package-level +// global). Run with `go test -race` to catch any unsynchronized access. +func TestResolverPathNoRace(t *testing.T) { + t.Parallel() + + root := NewResolver() + mut := &mutationResolver{root} + qry := &queryResolver{root} + vwr := &viewerResolver{root} + ctx := context.Background() + start := make(chan struct{}) + var deadline time.Time + + var wg sync.WaitGroup + + // Writers: exercise every mutation resolver. + for w := range 4 { + wg.Go(func() { + <-start + for i := 0; time.Now().Before(deadline); i++ { + _, _ = mut.CreateArticle( + ctx, + fmt.Sprintf("resolver-writer-%d-%d", w, i), + "body", + "author", + ) + _, _ = mut.UpdateArticle(ctx, "1", fmt.Sprintf("updated-%d-%d", w, i)) + _, _ = mut.DeleteListing(ctx, model.ListingKey{SellerID: "s1", Sku: "WIDGET-01"}) + } + }) + } + + // Readers: exercise every query resolver plus the viewer field resolver. + viewer := &model.Viewer{ID: "v1"} + for range 8 { + wg.Go(func() { + <-start + for time.Now().Before(deadline) { + _, _ = qry.Article(ctx, "1") + _, _ = qry.Articles(ctx) + _, _ = qry.ArticlesByIds(ctx, []string{"1", "2", "3"}) + _, _ = qry.Listing(ctx, model.ListingKey{SellerID: "s1", Sku: "WIDGET-01"}) + _, _ = qry.Listings(ctx) + _, _ = vwr.RecommendedArticles(ctx, viewer) + } + }) + } + + deadline = time.Now().Add(100 * time.Millisecond) + close(start) + wg.Wait() +} diff --git a/demo/pkg/subgraphs/cachegraph/subgraph/data_test.go b/demo/pkg/subgraphs/cachegraph/subgraph/data_test.go new file mode 100644 index 0000000000..1efa8b517c --- /dev/null +++ b/demo/pkg/subgraphs/cachegraph/subgraph/data_test.go @@ -0,0 +1,28 @@ +package subgraph + +import ( + "testing" +) + +func TestAllCatalogsReturnsStableIDOrder(t *testing.T) { + expected := []string{"c1", "c2", "c3"} + for attempt := 0; attempt < 200; attempt++ { + catalogs := allCatalogs() + + if len(catalogs) != len(expected) { + t.Fatalf("expected %d catalogs, got %d", len(expected), len(catalogs)) + } + + for index, id := range expected { + if catalogs[index].ID != id { + t.Fatalf( + "attempt %d: expected catalog %d to be %s, got %s", + attempt, + index, + id, + catalogs[index].ID, + ) + } + } + } +} diff --git a/demo/pkg/subgraphs/cachegraph/subgraph/entity.resolvers.go b/demo/pkg/subgraphs/cachegraph/subgraph/entity.resolvers.go new file mode 100644 index 0000000000..441bcaaffd --- /dev/null +++ b/demo/pkg/subgraphs/cachegraph/subgraph/entity.resolvers.go @@ -0,0 +1,66 @@ +package subgraph + +// 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.76 + +import ( + "context" + + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachegraph/subgraph/generated" + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachegraph/subgraph/model" +) + +// FindArticleByID is the resolver for the findArticleByID field. +func (r *entityResolver) FindArticleByID(ctx context.Context, id string) (*model.Article, error) { + return r.articles.find(id), nil +} + +// FindArticleBySlug is the resolver for the findArticleBySlug field. +func (r *entityResolver) FindArticleBySlug(ctx context.Context, slug string) (*model.Article, error) { + return r.articles.findBySlug(slug), nil +} + +// FindCatalogByID is the resolver for the findCatalogByID field. +func (r *entityResolver) FindCatalogByID(ctx context.Context, id string) (*model.Catalog, error) { + return catalogsData[id], nil +} + +// FindListingBySellerIDAndSku is the resolver for the findListingBySellerIDAndSku field. +func (r *entityResolver) FindListingBySellerIDAndSku(ctx context.Context, sellerID string, sku string) (*model.Listing, error) { + return r.listings.get(sellerID, sku), nil +} + +// FindMetricByID is the resolver for the findMetricByID field. +func (r *entityResolver) FindMetricByID(ctx context.Context, id string) (*model.Metric, error) { + return metricsData[id], nil +} + +// FindPersonalizedByID is the resolver for the findPersonalizedByID field. +// Returns the Article matching the ID (Article implements Personalized). +func (r *entityResolver) FindPersonalizedByID(ctx context.Context, id string) (model.Personalized, error) { + if a := r.articles.find(id); a != nil { + return a, nil + } + return nil, nil +} + +// FindUserProfileByID is the resolver for the findUserProfileByID field. +func (r *entityResolver) FindUserProfileByID(ctx context.Context, id string) (*model.UserProfile, error) { + return userProfilesData[id], nil +} + +// FindVenueByAddressID is the resolver for the findVenueByAddressID field. +func (r *entityResolver) FindVenueByAddressID(ctx context.Context, addressID string) (*model.Venue, error) { + return venuesData[addressID], nil +} + +// FindViewerByID is the resolver for the findViewerByID field. +func (r *entityResolver) FindViewerByID(ctx context.Context, id string) (*model.Viewer, error) { + return &model.Viewer{ID: id}, nil +} + +// Entity returns generated.EntityResolver implementation. +func (r *Resolver) Entity() generated.EntityResolver { return &entityResolver{r} } + +type entityResolver struct{ *Resolver } diff --git a/demo/pkg/subgraphs/cachegraph/subgraph/generated/federation.go b/demo/pkg/subgraphs/cachegraph/subgraph/generated/federation.go new file mode 100644 index 0000000000..2c3f3b1adf --- /dev/null +++ b/demo/pkg/subgraphs/cachegraph/subgraph/generated/federation.go @@ -0,0 +1,676 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package generated + +import ( + "context" + "errors" + "fmt" + "strings" + "sync" + + "github.com/99designs/gqlgen/plugin/federation/fedruntime" +) + +var ( + ErrUnknownType = errors.New("unknown type") + ErrTypeNotFound = errors.New("type not found") +) + +func (ec *executionContext) __resolve__service(ctx context.Context) (fedruntime.Service, error) { + if ec.DisableIntrospection { + return fedruntime.Service{}, errors.New("federated introspection disabled") + } + + var sdl []string + + for _, src := range sources { + if src.BuiltIn { + continue + } + sdl = append(sdl, src.Input) + } + + return fedruntime.Service{ + SDL: strings.Join(sdl, "\n"), + }, nil +} + +func (ec *executionContext) __resolve_entities(ctx context.Context, representations []map[string]any) []fedruntime.Entity { + list := make([]fedruntime.Entity, len(representations)) + + repsMap := ec.buildRepresentationGroups(ctx, representations) + + switch len(repsMap) { + case 0: + return list + case 1: + for typeName, reps := range repsMap { + ec.resolveEntityGroup(ctx, typeName, reps, list) + } + return list + default: + var g sync.WaitGroup + g.Add(len(repsMap)) + for typeName, reps := range repsMap { + go func(typeName string, reps []EntityWithIndex) { + ec.resolveEntityGroup(ctx, typeName, reps, list) + g.Done() + }(typeName, reps) + } + g.Wait() + return list + } +} + +type EntityWithIndex struct { + // The index in the original representation array + index int + entity EntityRepresentation +} + +// EntityRepresentation is the JSON representation of an entity sent by the Router +// used as the inputs for us to resolve. +// +// We make it a map because we know the top level JSON is always an object. +type EntityRepresentation map[string]any + +// We group entities by typename so that we can parallelize their resolution. +// This is particularly helpful when there are entity groups in multi mode. +func (ec *executionContext) buildRepresentationGroups( + ctx context.Context, + representations []map[string]any, +) map[string][]EntityWithIndex { + repsMap := make(map[string][]EntityWithIndex) + for i, rep := range representations { + typeName, ok := rep["__typename"].(string) + if !ok { + // If there is no __typename, we just skip the representation; + // we just won't be resolving these unknown types. + ec.Error(ctx, errors.New("__typename must be an existing string")) + continue + } + + repsMap[typeName] = append(repsMap[typeName], EntityWithIndex{ + index: i, + entity: rep, + }) + } + + return repsMap +} + +func (ec *executionContext) resolveEntityGroup( + ctx context.Context, + typeName string, + reps []EntityWithIndex, + list []fedruntime.Entity, +) { + if isMulti(typeName) { + err := ec.resolveManyEntities(ctx, typeName, reps, list) + if err != nil { + ec.Error(ctx, err) + } + } else { + // if there are multiple entities to resolve, parallelize (similar to + // graphql.FieldSet.Dispatch) + var e sync.WaitGroup + e.Add(len(reps)) + for i, rep := range reps { + i, rep := i, rep + go func(i int, rep EntityWithIndex) { + entity, err := ec.resolveEntity(ctx, typeName, rep.entity) + if err != nil { + ec.Error(ctx, err) + } else { + list[rep.index] = entity + } + e.Done() + }(i, rep) + } + e.Wait() + } +} + +func isMulti(typeName string) bool { + switch typeName { + default: + return false + } +} + +func (ec *executionContext) resolveEntity( + ctx context.Context, + typeName string, + rep EntityRepresentation, +) (e fedruntime.Entity, err error) { + // we need to do our own panic handling, because we may be called in a + // goroutine, where the usual panic handling can't catch us + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + } + }() + + switch typeName { + case "Article": + resolverName, err := entityResolverNameForArticle(ctx, rep) + if err != nil { + return nil, fmt.Errorf(`finding resolver for Entity "Article": %w`, err) + } + switch resolverName { + + case "findArticleByID": + id0, err := ec.unmarshalNID2string(ctx, rep["id"]) + if err != nil { + return nil, fmt.Errorf(`unmarshalling param 0 for findArticleByID(): %w`, err) + } + entity, err := ec.resolvers.Entity().FindArticleByID(ctx, id0) + if err != nil { + return nil, fmt.Errorf(`resolving Entity "Article": %w`, err) + } + + return entity, nil + case "findArticleBySlug": + id0, err := ec.unmarshalNString2string(ctx, rep["slug"]) + if err != nil { + return nil, fmt.Errorf(`unmarshalling param 0 for findArticleBySlug(): %w`, err) + } + entity, err := ec.resolvers.Entity().FindArticleBySlug(ctx, id0) + if err != nil { + return nil, fmt.Errorf(`resolving Entity "Article": %w`, err) + } + + return entity, nil + } + case "Catalog": + resolverName, err := entityResolverNameForCatalog(ctx, rep) + if err != nil { + return nil, fmt.Errorf(`finding resolver for Entity "Catalog": %w`, err) + } + switch resolverName { + + case "findCatalogByID": + id0, err := ec.unmarshalNID2string(ctx, rep["id"]) + if err != nil { + return nil, fmt.Errorf(`unmarshalling param 0 for findCatalogByID(): %w`, err) + } + entity, err := ec.resolvers.Entity().FindCatalogByID(ctx, id0) + if err != nil { + return nil, fmt.Errorf(`resolving Entity "Catalog": %w`, err) + } + + return entity, nil + } + case "Listing": + resolverName, err := entityResolverNameForListing(ctx, rep) + if err != nil { + return nil, fmt.Errorf(`finding resolver for Entity "Listing": %w`, err) + } + switch resolverName { + + case "findListingBySellerIDAndSku": + id0, err := ec.unmarshalNID2string(ctx, rep["sellerId"]) + if err != nil { + return nil, fmt.Errorf(`unmarshalling param 0 for findListingBySellerIDAndSku(): %w`, err) + } + id1, err := ec.unmarshalNString2string(ctx, rep["sku"]) + if err != nil { + return nil, fmt.Errorf(`unmarshalling param 1 for findListingBySellerIDAndSku(): %w`, err) + } + entity, err := ec.resolvers.Entity().FindListingBySellerIDAndSku(ctx, id0, id1) + if err != nil { + return nil, fmt.Errorf(`resolving Entity "Listing": %w`, err) + } + + return entity, nil + } + case "Metric": + resolverName, err := entityResolverNameForMetric(ctx, rep) + if err != nil { + return nil, fmt.Errorf(`finding resolver for Entity "Metric": %w`, err) + } + switch resolverName { + + case "findMetricByID": + id0, err := ec.unmarshalNID2string(ctx, rep["id"]) + if err != nil { + return nil, fmt.Errorf(`unmarshalling param 0 for findMetricByID(): %w`, err) + } + entity, err := ec.resolvers.Entity().FindMetricByID(ctx, id0) + if err != nil { + return nil, fmt.Errorf(`resolving Entity "Metric": %w`, err) + } + + return entity, nil + } + case "Personalized": + resolverName, err := entityResolverNameForPersonalized(ctx, rep) + if err != nil { + return nil, fmt.Errorf(`finding resolver for Entity "Personalized": %w`, err) + } + switch resolverName { + + case "findPersonalizedByID": + id0, err := ec.unmarshalNID2string(ctx, rep["id"]) + if err != nil { + return nil, fmt.Errorf(`unmarshalling param 0 for findPersonalizedByID(): %w`, err) + } + entity, err := ec.resolvers.Entity().FindPersonalizedByID(ctx, id0) + if err != nil { + return nil, fmt.Errorf(`resolving Entity "Personalized": %w`, err) + } + + return entity, nil + } + case "UserProfile": + resolverName, err := entityResolverNameForUserProfile(ctx, rep) + if err != nil { + return nil, fmt.Errorf(`finding resolver for Entity "UserProfile": %w`, err) + } + switch resolverName { + + case "findUserProfileByID": + id0, err := ec.unmarshalNID2string(ctx, rep["id"]) + if err != nil { + return nil, fmt.Errorf(`unmarshalling param 0 for findUserProfileByID(): %w`, err) + } + entity, err := ec.resolvers.Entity().FindUserProfileByID(ctx, id0) + if err != nil { + return nil, fmt.Errorf(`resolving Entity "UserProfile": %w`, err) + } + + return entity, nil + } + case "Venue": + resolverName, err := entityResolverNameForVenue(ctx, rep) + if err != nil { + return nil, fmt.Errorf(`finding resolver for Entity "Venue": %w`, err) + } + switch resolverName { + + case "findVenueByAddressID": + id0, err := ec.unmarshalNID2string(ctx, rep["address"].(map[string]any)["id"]) + if err != nil { + return nil, fmt.Errorf(`unmarshalling param 0 for findVenueByAddressID(): %w`, err) + } + entity, err := ec.resolvers.Entity().FindVenueByAddressID(ctx, id0) + if err != nil { + return nil, fmt.Errorf(`resolving Entity "Venue": %w`, err) + } + + return entity, nil + } + case "Viewer": + resolverName, err := entityResolverNameForViewer(ctx, rep) + if err != nil { + return nil, fmt.Errorf(`finding resolver for Entity "Viewer": %w`, err) + } + switch resolverName { + + case "findViewerByID": + id0, err := ec.unmarshalNID2string(ctx, rep["id"]) + if err != nil { + return nil, fmt.Errorf(`unmarshalling param 0 for findViewerByID(): %w`, err) + } + entity, err := ec.resolvers.Entity().FindViewerByID(ctx, id0) + if err != nil { + return nil, fmt.Errorf(`resolving Entity "Viewer": %w`, err) + } + + return entity, nil + } + + } + return nil, fmt.Errorf("%w: %s", ErrUnknownType, typeName) +} + +func (ec *executionContext) resolveManyEntities( + ctx context.Context, + typeName string, + reps []EntityWithIndex, + list []fedruntime.Entity, +) (err error) { + // we need to do our own panic handling, because we may be called in a + // goroutine, where the usual panic handling can't catch us + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + } + }() + + switch typeName { + + default: + return errors.New("unknown type: " + typeName) + } +} + +func entityResolverNameForArticle(ctx context.Context, rep EntityRepresentation) (string, error) { + // we collect errors because a later entity resolver may work fine + // when an entity has multiple keys + entityResolverErrs := []error{} + for { + var ( + m EntityRepresentation + val any + ok bool + ) + _ = val + // if all of the KeyFields values for this resolver are null, + // we shouldn't use use it + allNull := true + m = rep + val, ok = m["id"] + if !ok { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to missing Key Field \"id\" for Article", ErrTypeNotFound)) + break + } + if allNull { + allNull = val == nil + } + if allNull { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to all null value KeyFields for Article", ErrTypeNotFound)) + break + } + return "findArticleByID", nil + } + for { + var ( + m EntityRepresentation + val any + ok bool + ) + _ = val + // if all of the KeyFields values for this resolver are null, + // we shouldn't use use it + allNull := true + m = rep + val, ok = m["slug"] + if !ok { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to missing Key Field \"slug\" for Article", ErrTypeNotFound)) + break + } + if allNull { + allNull = val == nil + } + if allNull { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to all null value KeyFields for Article", ErrTypeNotFound)) + break + } + return "findArticleBySlug", nil + } + return "", fmt.Errorf("%w for Article due to %v", ErrTypeNotFound, + errors.Join(entityResolverErrs...).Error()) +} + +func entityResolverNameForCatalog(ctx context.Context, rep EntityRepresentation) (string, error) { + // we collect errors because a later entity resolver may work fine + // when an entity has multiple keys + entityResolverErrs := []error{} + for { + var ( + m EntityRepresentation + val any + ok bool + ) + _ = val + // if all of the KeyFields values for this resolver are null, + // we shouldn't use use it + allNull := true + m = rep + val, ok = m["id"] + if !ok { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to missing Key Field \"id\" for Catalog", ErrTypeNotFound)) + break + } + if allNull { + allNull = val == nil + } + if allNull { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to all null value KeyFields for Catalog", ErrTypeNotFound)) + break + } + return "findCatalogByID", nil + } + return "", fmt.Errorf("%w for Catalog due to %v", ErrTypeNotFound, + errors.Join(entityResolverErrs...).Error()) +} + +func entityResolverNameForListing(ctx context.Context, rep EntityRepresentation) (string, error) { + // we collect errors because a later entity resolver may work fine + // when an entity has multiple keys + entityResolverErrs := []error{} + for { + var ( + m EntityRepresentation + val any + ok bool + ) + _ = val + // if all of the KeyFields values for this resolver are null, + // we shouldn't use use it + allNull := true + m = rep + val, ok = m["sellerId"] + if !ok { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to missing Key Field \"sellerId\" for Listing", ErrTypeNotFound)) + break + } + if allNull { + allNull = val == nil + } + m = rep + val, ok = m["sku"] + if !ok { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to missing Key Field \"sku\" for Listing", ErrTypeNotFound)) + break + } + if allNull { + allNull = val == nil + } + if allNull { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to all null value KeyFields for Listing", ErrTypeNotFound)) + break + } + return "findListingBySellerIDAndSku", nil + } + return "", fmt.Errorf("%w for Listing due to %v", ErrTypeNotFound, + errors.Join(entityResolverErrs...).Error()) +} + +func entityResolverNameForMetric(ctx context.Context, rep EntityRepresentation) (string, error) { + // we collect errors because a later entity resolver may work fine + // when an entity has multiple keys + entityResolverErrs := []error{} + for { + var ( + m EntityRepresentation + val any + ok bool + ) + _ = val + // if all of the KeyFields values for this resolver are null, + // we shouldn't use use it + allNull := true + m = rep + val, ok = m["id"] + if !ok { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to missing Key Field \"id\" for Metric", ErrTypeNotFound)) + break + } + if allNull { + allNull = val == nil + } + if allNull { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to all null value KeyFields for Metric", ErrTypeNotFound)) + break + } + return "findMetricByID", nil + } + return "", fmt.Errorf("%w for Metric due to %v", ErrTypeNotFound, + errors.Join(entityResolverErrs...).Error()) +} + +func entityResolverNameForPersonalized(ctx context.Context, rep EntityRepresentation) (string, error) { + // we collect errors because a later entity resolver may work fine + // when an entity has multiple keys + entityResolverErrs := []error{} + for { + var ( + m EntityRepresentation + val any + ok bool + ) + _ = val + // if all of the KeyFields values for this resolver are null, + // we shouldn't use use it + allNull := true + m = rep + val, ok = m["id"] + if !ok { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to missing Key Field \"id\" for Personalized", ErrTypeNotFound)) + break + } + if allNull { + allNull = val == nil + } + if allNull { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to all null value KeyFields for Personalized", ErrTypeNotFound)) + break + } + return "findPersonalizedByID", nil + } + return "", fmt.Errorf("%w for Personalized due to %v", ErrTypeNotFound, + errors.Join(entityResolverErrs...).Error()) +} + +func entityResolverNameForUserProfile(ctx context.Context, rep EntityRepresentation) (string, error) { + // we collect errors because a later entity resolver may work fine + // when an entity has multiple keys + entityResolverErrs := []error{} + for { + var ( + m EntityRepresentation + val any + ok bool + ) + _ = val + // if all of the KeyFields values for this resolver are null, + // we shouldn't use use it + allNull := true + m = rep + val, ok = m["id"] + if !ok { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to missing Key Field \"id\" for UserProfile", ErrTypeNotFound)) + break + } + if allNull { + allNull = val == nil + } + if allNull { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to all null value KeyFields for UserProfile", ErrTypeNotFound)) + break + } + return "findUserProfileByID", nil + } + return "", fmt.Errorf("%w for UserProfile due to %v", ErrTypeNotFound, + errors.Join(entityResolverErrs...).Error()) +} + +func entityResolverNameForVenue(ctx context.Context, rep EntityRepresentation) (string, error) { + // we collect errors because a later entity resolver may work fine + // when an entity has multiple keys + entityResolverErrs := []error{} + for { + var ( + m EntityRepresentation + val any + ok bool + ) + _ = val + // if all of the KeyFields values for this resolver are null, + // we shouldn't use use it + allNull := true + m = rep + val, ok = m["address"] + if !ok { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to missing Key Field \"address\" for Venue", ErrTypeNotFound)) + break + } + if m, ok = val.(map[string]any); !ok { + // nested field value is not a map[string]interface so don't use it + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to nested Key Field \"address\" value not matching map[string]any for Venue", ErrTypeNotFound)) + break + } + val, ok = m["id"] + if !ok { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to missing Key Field \"id\" for Venue", ErrTypeNotFound)) + break + } + if allNull { + allNull = val == nil + } + if allNull { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to all null value KeyFields for Venue", ErrTypeNotFound)) + break + } + return "findVenueByAddressID", nil + } + return "", fmt.Errorf("%w for Venue due to %v", ErrTypeNotFound, + errors.Join(entityResolverErrs...).Error()) +} + +func entityResolverNameForViewer(ctx context.Context, rep EntityRepresentation) (string, error) { + // we collect errors because a later entity resolver may work fine + // when an entity has multiple keys + entityResolverErrs := []error{} + for { + var ( + m EntityRepresentation + val any + ok bool + ) + _ = val + // if all of the KeyFields values for this resolver are null, + // we shouldn't use use it + allNull := true + m = rep + val, ok = m["id"] + if !ok { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to missing Key Field \"id\" for Viewer", ErrTypeNotFound)) + break + } + if allNull { + allNull = val == nil + } + if allNull { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to all null value KeyFields for Viewer", ErrTypeNotFound)) + break + } + return "findViewerByID", nil + } + return "", fmt.Errorf("%w for Viewer due to %v", ErrTypeNotFound, + errors.Join(entityResolverErrs...).Error()) +} diff --git a/demo/pkg/subgraphs/cachegraph/subgraph/generated/generated.go b/demo/pkg/subgraphs/cachegraph/subgraph/generated/generated.go new file mode 100644 index 0000000000..b5eb54dc39 --- /dev/null +++ b/demo/pkg/subgraphs/cachegraph/subgraph/generated/generated.go @@ -0,0 +1,10038 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package generated + +import ( + "bytes" + "context" + "errors" + "fmt" + "strconv" + "sync" + "sync/atomic" + + "github.com/99designs/gqlgen/graphql" + "github.com/99designs/gqlgen/graphql/introspection" + "github.com/99designs/gqlgen/plugin/federation/fedruntime" + gqlparser "github.com/vektah/gqlparser/v2" + "github.com/vektah/gqlparser/v2/ast" + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachegraph/subgraph/model" +) + +// region ************************** generated!.gotpl ************************** + +// NewExecutableSchema creates an ExecutableSchema from the ResolverRoot interface. +func NewExecutableSchema(cfg Config) graphql.ExecutableSchema { + return &executableSchema{ + schema: cfg.Schema, + resolvers: cfg.Resolvers, + directives: cfg.Directives, + complexity: cfg.Complexity, + } +} + +type Config struct { + Schema *ast.Schema + Resolvers ResolverRoot + Directives DirectiveRoot + Complexity ComplexityRoot +} + +type ResolverRoot interface { + Entity() EntityResolver + Mutation() MutationResolver + Query() QueryResolver + Viewer() ViewerResolver +} + +type DirectiveRoot struct { +} + +type ComplexityRoot struct { + Address struct { + ID func(childComplexity int) int + } + + Article struct { + AuthorName func(childComplexity int) int + Body func(childComplexity int) int + ID func(childComplexity int) int + PublishedAt func(childComplexity int) int + Slug func(childComplexity int) int + Tags func(childComplexity int) int + Title func(childComplexity int) int + } + + Catalog struct { + Category func(childComplexity int) int + ID func(childComplexity int) int + ItemCount func(childComplexity int) int + Name func(childComplexity int) int + } + + Entity struct { + FindArticleByID func(childComplexity int, id string) int + FindArticleBySlug func(childComplexity int, slug string) int + FindCatalogByID func(childComplexity int, id string) int + FindListingBySellerIDAndSku func(childComplexity int, sellerID string, sku string) int + FindMetricByID func(childComplexity int, id string) int + FindPersonalizedByID func(childComplexity int, id string) int + FindUserProfileByID func(childComplexity int, id string) int + FindVenueByAddressID func(childComplexity int, addressID string) int + FindViewerByID func(childComplexity int, id string) int + } + + Listing struct { + Currency func(childComplexity int) int + InStock func(childComplexity int) int + Price func(childComplexity int) int + SellerID func(childComplexity int) int + Sku func(childComplexity int) int + Title func(childComplexity int) int + } + + Metric struct { + ID func(childComplexity int) int + Name func(childComplexity int) int + Unit func(childComplexity int) int + Value func(childComplexity int) int + } + + Mutation struct { + CreateArticle func(childComplexity int, title string, body string, authorName string) int + DeleteListing func(childComplexity int, key model.ListingKey) int + UpdateArticle func(childComplexity int, id string, title string) int + } + + Query struct { + Article func(childComplexity int, id string) int + ArticleBySlug func(childComplexity int, slug string) int + Articles func(childComplexity int) int + ArticlesByIds func(childComplexity int, ids []string) int + Catalog func(childComplexity int, id string) int + Catalogs func(childComplexity int) int + Listing func(childComplexity int, key model.ListingKey) int + Listings func(childComplexity int) int + Metric func(childComplexity int, id string) int + UserProfile func(childComplexity int, id string) int + Venue func(childComplexity int, location model.VenueLocationKey) int + Venues func(childComplexity int) int + __resolve__service func(childComplexity int) int + __resolve_entities func(childComplexity int, representations []map[string]any) int + } + + UserProfile struct { + Email func(childComplexity int) int + ID func(childComplexity int) int + Role func(childComplexity int) int + Username func(childComplexity int) int + } + + Venue struct { + Address func(childComplexity int) int + Capacity func(childComplexity int) int + City func(childComplexity int) int + Name func(childComplexity int) int + } + + Viewer struct { + ID func(childComplexity int) int + RecommendedArticles func(childComplexity int) int + } + + _Service struct { + SDL func(childComplexity int) int + } +} + +type EntityResolver interface { + FindArticleByID(ctx context.Context, id string) (*model.Article, error) + FindArticleBySlug(ctx context.Context, slug string) (*model.Article, error) + FindCatalogByID(ctx context.Context, id string) (*model.Catalog, error) + FindListingBySellerIDAndSku(ctx context.Context, sellerID string, sku string) (*model.Listing, error) + FindMetricByID(ctx context.Context, id string) (*model.Metric, error) + FindPersonalizedByID(ctx context.Context, id string) (model.Personalized, error) + FindUserProfileByID(ctx context.Context, id string) (*model.UserProfile, error) + FindVenueByAddressID(ctx context.Context, addressID string) (*model.Venue, error) + FindViewerByID(ctx context.Context, id string) (*model.Viewer, error) +} +type MutationResolver interface { + UpdateArticle(ctx context.Context, id string, title string) (*model.Article, error) + CreateArticle(ctx context.Context, title string, body string, authorName string) (*model.Article, error) + DeleteListing(ctx context.Context, key model.ListingKey) (*model.Listing, error) +} +type QueryResolver interface { + Article(ctx context.Context, id string) (*model.Article, error) + Articles(ctx context.Context) ([]*model.Article, error) + ArticlesByIds(ctx context.Context, ids []string) ([]*model.Article, error) + ArticleBySlug(ctx context.Context, slug string) (*model.Article, error) + Listing(ctx context.Context, key model.ListingKey) (*model.Listing, error) + Listings(ctx context.Context) ([]*model.Listing, error) + Venue(ctx context.Context, location model.VenueLocationKey) (*model.Venue, error) + Venues(ctx context.Context) ([]*model.Venue, error) + UserProfile(ctx context.Context, id string) (*model.UserProfile, error) + Catalog(ctx context.Context, id string) (*model.Catalog, error) + Catalogs(ctx context.Context) ([]*model.Catalog, error) + Metric(ctx context.Context, id string) (*model.Metric, error) +} +type ViewerResolver interface { + RecommendedArticles(ctx context.Context, obj *model.Viewer) ([]*model.Article, error) +} + +type executableSchema struct { + schema *ast.Schema + resolvers ResolverRoot + directives DirectiveRoot + complexity ComplexityRoot +} + +func (e *executableSchema) Schema() *ast.Schema { + if e.schema != nil { + return e.schema + } + return parsedSchema +} + +func (e *executableSchema) Complexity(ctx context.Context, typeName, field string, childComplexity int, rawArgs map[string]any) (int, bool) { + ec := executionContext{nil, e, 0, 0, nil} + _ = ec + switch typeName + "." + field { + + case "Address.id": + if e.complexity.Address.ID == nil { + break + } + + return e.complexity.Address.ID(childComplexity), true + + case "Article.authorName": + if e.complexity.Article.AuthorName == nil { + break + } + + return e.complexity.Article.AuthorName(childComplexity), true + + case "Article.body": + if e.complexity.Article.Body == nil { + break + } + + return e.complexity.Article.Body(childComplexity), true + + case "Article.id": + if e.complexity.Article.ID == nil { + break + } + + return e.complexity.Article.ID(childComplexity), true + + case "Article.publishedAt": + if e.complexity.Article.PublishedAt == nil { + break + } + + return e.complexity.Article.PublishedAt(childComplexity), true + + case "Article.slug": + if e.complexity.Article.Slug == nil { + break + } + + return e.complexity.Article.Slug(childComplexity), true + + case "Article.tags": + if e.complexity.Article.Tags == nil { + break + } + + return e.complexity.Article.Tags(childComplexity), true + + case "Article.title": + if e.complexity.Article.Title == nil { + break + } + + return e.complexity.Article.Title(childComplexity), true + + case "Catalog.category": + if e.complexity.Catalog.Category == nil { + break + } + + return e.complexity.Catalog.Category(childComplexity), true + + case "Catalog.id": + if e.complexity.Catalog.ID == nil { + break + } + + return e.complexity.Catalog.ID(childComplexity), true + + case "Catalog.itemCount": + if e.complexity.Catalog.ItemCount == nil { + break + } + + return e.complexity.Catalog.ItemCount(childComplexity), true + + case "Catalog.name": + if e.complexity.Catalog.Name == nil { + break + } + + return e.complexity.Catalog.Name(childComplexity), true + + case "Entity.findArticleByID": + if e.complexity.Entity.FindArticleByID == nil { + break + } + + args, err := ec.field_Entity_findArticleByID_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Entity.FindArticleByID(childComplexity, args["id"].(string)), true + + case "Entity.findArticleBySlug": + if e.complexity.Entity.FindArticleBySlug == nil { + break + } + + args, err := ec.field_Entity_findArticleBySlug_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Entity.FindArticleBySlug(childComplexity, args["slug"].(string)), true + + case "Entity.findCatalogByID": + if e.complexity.Entity.FindCatalogByID == nil { + break + } + + args, err := ec.field_Entity_findCatalogByID_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Entity.FindCatalogByID(childComplexity, args["id"].(string)), true + + case "Entity.findListingBySellerIDAndSku": + if e.complexity.Entity.FindListingBySellerIDAndSku == nil { + break + } + + args, err := ec.field_Entity_findListingBySellerIDAndSku_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Entity.FindListingBySellerIDAndSku(childComplexity, args["sellerID"].(string), args["sku"].(string)), true + + case "Entity.findMetricByID": + if e.complexity.Entity.FindMetricByID == nil { + break + } + + args, err := ec.field_Entity_findMetricByID_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Entity.FindMetricByID(childComplexity, args["id"].(string)), true + + case "Entity.findPersonalizedByID": + if e.complexity.Entity.FindPersonalizedByID == nil { + break + } + + args, err := ec.field_Entity_findPersonalizedByID_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Entity.FindPersonalizedByID(childComplexity, args["id"].(string)), true + + case "Entity.findUserProfileByID": + if e.complexity.Entity.FindUserProfileByID == nil { + break + } + + args, err := ec.field_Entity_findUserProfileByID_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Entity.FindUserProfileByID(childComplexity, args["id"].(string)), true + + case "Entity.findVenueByAddressID": + if e.complexity.Entity.FindVenueByAddressID == nil { + break + } + + args, err := ec.field_Entity_findVenueByAddressID_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Entity.FindVenueByAddressID(childComplexity, args["addressID"].(string)), true + + case "Entity.findViewerByID": + if e.complexity.Entity.FindViewerByID == nil { + break + } + + args, err := ec.field_Entity_findViewerByID_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Entity.FindViewerByID(childComplexity, args["id"].(string)), true + + case "Listing.currency": + if e.complexity.Listing.Currency == nil { + break + } + + return e.complexity.Listing.Currency(childComplexity), true + + case "Listing.inStock": + if e.complexity.Listing.InStock == nil { + break + } + + return e.complexity.Listing.InStock(childComplexity), true + + case "Listing.price": + if e.complexity.Listing.Price == nil { + break + } + + return e.complexity.Listing.Price(childComplexity), true + + case "Listing.sellerId": + if e.complexity.Listing.SellerID == nil { + break + } + + return e.complexity.Listing.SellerID(childComplexity), true + + case "Listing.sku": + if e.complexity.Listing.Sku == nil { + break + } + + return e.complexity.Listing.Sku(childComplexity), true + + case "Listing.title": + if e.complexity.Listing.Title == nil { + break + } + + return e.complexity.Listing.Title(childComplexity), true + + case "Metric.id": + if e.complexity.Metric.ID == nil { + break + } + + return e.complexity.Metric.ID(childComplexity), true + + case "Metric.name": + if e.complexity.Metric.Name == nil { + break + } + + return e.complexity.Metric.Name(childComplexity), true + + case "Metric.unit": + if e.complexity.Metric.Unit == nil { + break + } + + return e.complexity.Metric.Unit(childComplexity), true + + case "Metric.value": + if e.complexity.Metric.Value == nil { + break + } + + return e.complexity.Metric.Value(childComplexity), true + + case "Mutation.createArticle": + if e.complexity.Mutation.CreateArticle == nil { + break + } + + args, err := ec.field_Mutation_createArticle_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Mutation.CreateArticle(childComplexity, args["title"].(string), args["body"].(string), args["authorName"].(string)), true + + case "Mutation.deleteListing": + if e.complexity.Mutation.DeleteListing == nil { + break + } + + args, err := ec.field_Mutation_deleteListing_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Mutation.DeleteListing(childComplexity, args["key"].(model.ListingKey)), true + + case "Mutation.updateArticle": + if e.complexity.Mutation.UpdateArticle == nil { + break + } + + args, err := ec.field_Mutation_updateArticle_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Mutation.UpdateArticle(childComplexity, args["id"].(string), args["title"].(string)), true + + case "Query.article": + if e.complexity.Query.Article == nil { + break + } + + args, err := ec.field_Query_article_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.Article(childComplexity, args["id"].(string)), true + + case "Query.articleBySlug": + if e.complexity.Query.ArticleBySlug == nil { + break + } + + args, err := ec.field_Query_articleBySlug_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.ArticleBySlug(childComplexity, args["slug"].(string)), true + + case "Query.articles": + if e.complexity.Query.Articles == nil { + break + } + + return e.complexity.Query.Articles(childComplexity), true + + case "Query.articlesByIds": + if e.complexity.Query.ArticlesByIds == nil { + break + } + + args, err := ec.field_Query_articlesByIds_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.ArticlesByIds(childComplexity, args["ids"].([]string)), true + + case "Query.catalog": + if e.complexity.Query.Catalog == nil { + break + } + + args, err := ec.field_Query_catalog_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.Catalog(childComplexity, args["id"].(string)), true + + case "Query.catalogs": + if e.complexity.Query.Catalogs == nil { + break + } + + return e.complexity.Query.Catalogs(childComplexity), true + + case "Query.listing": + if e.complexity.Query.Listing == nil { + break + } + + args, err := ec.field_Query_listing_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.Listing(childComplexity, args["key"].(model.ListingKey)), true + + case "Query.listings": + if e.complexity.Query.Listings == nil { + break + } + + return e.complexity.Query.Listings(childComplexity), true + + case "Query.metric": + if e.complexity.Query.Metric == nil { + break + } + + args, err := ec.field_Query_metric_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.Metric(childComplexity, args["id"].(string)), true + + case "Query.userProfile": + if e.complexity.Query.UserProfile == nil { + break + } + + args, err := ec.field_Query_userProfile_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.UserProfile(childComplexity, args["id"].(string)), true + + case "Query.venue": + if e.complexity.Query.Venue == nil { + break + } + + args, err := ec.field_Query_venue_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.Venue(childComplexity, args["location"].(model.VenueLocationKey)), true + + case "Query.venues": + if e.complexity.Query.Venues == nil { + break + } + + return e.complexity.Query.Venues(childComplexity), true + + case "Query._service": + if e.complexity.Query.__resolve__service == nil { + break + } + + return e.complexity.Query.__resolve__service(childComplexity), true + + case "Query._entities": + if e.complexity.Query.__resolve_entities == nil { + break + } + + args, err := ec.field_Query__entities_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.__resolve_entities(childComplexity, args["representations"].([]map[string]any)), true + + case "UserProfile.email": + if e.complexity.UserProfile.Email == nil { + break + } + + return e.complexity.UserProfile.Email(childComplexity), true + + case "UserProfile.id": + if e.complexity.UserProfile.ID == nil { + break + } + + return e.complexity.UserProfile.ID(childComplexity), true + + case "UserProfile.role": + if e.complexity.UserProfile.Role == nil { + break + } + + return e.complexity.UserProfile.Role(childComplexity), true + + case "UserProfile.username": + if e.complexity.UserProfile.Username == nil { + break + } + + return e.complexity.UserProfile.Username(childComplexity), true + + case "Venue.address": + if e.complexity.Venue.Address == nil { + break + } + + return e.complexity.Venue.Address(childComplexity), true + + case "Venue.capacity": + if e.complexity.Venue.Capacity == nil { + break + } + + return e.complexity.Venue.Capacity(childComplexity), true + + case "Venue.city": + if e.complexity.Venue.City == nil { + break + } + + return e.complexity.Venue.City(childComplexity), true + + case "Venue.name": + if e.complexity.Venue.Name == nil { + break + } + + return e.complexity.Venue.Name(childComplexity), true + + case "Viewer.id": + if e.complexity.Viewer.ID == nil { + break + } + + return e.complexity.Viewer.ID(childComplexity), true + + case "Viewer.recommendedArticles": + if e.complexity.Viewer.RecommendedArticles == nil { + break + } + + return e.complexity.Viewer.RecommendedArticles(childComplexity), true + + case "_Service.sdl": + if e.complexity._Service.SDL == nil { + break + } + + return e.complexity._Service.SDL(childComplexity), true + + } + return 0, false +} + +func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { + opCtx := graphql.GetOperationContext(ctx) + ec := executionContext{opCtx, e, 0, 0, make(chan graphql.DeferredResult)} + inputUnmarshalMap := graphql.BuildUnmarshalerMap( + ec.unmarshalInputListingKey, + ec.unmarshalInputVenueAddressKey, + ec.unmarshalInputVenueLocationKey, + ) + first := true + + switch opCtx.Operation.Operation { + case ast.Query: + return func(ctx context.Context) *graphql.Response { + var response graphql.Response + var data graphql.Marshaler + if first { + first = false + ctx = graphql.WithUnmarshalerMap(ctx, inputUnmarshalMap) + data = ec._Query(ctx, opCtx.Operation.SelectionSet) + } else { + if atomic.LoadInt32(&ec.pendingDeferred) > 0 { + result := <-ec.deferredResults + atomic.AddInt32(&ec.pendingDeferred, -1) + data = result.Result + response.Path = result.Path + response.Label = result.Label + response.Errors = result.Errors + } else { + return nil + } + } + var buf bytes.Buffer + data.MarshalGQL(&buf) + response.Data = buf.Bytes() + if atomic.LoadInt32(&ec.deferred) > 0 { + hasNext := atomic.LoadInt32(&ec.pendingDeferred) > 0 + response.HasNext = &hasNext + } + + return &response + } + case ast.Mutation: + return func(ctx context.Context) *graphql.Response { + if !first { + return nil + } + first = false + ctx = graphql.WithUnmarshalerMap(ctx, inputUnmarshalMap) + data := ec._Mutation(ctx, opCtx.Operation.SelectionSet) + var buf bytes.Buffer + data.MarshalGQL(&buf) + + return &graphql.Response{ + Data: buf.Bytes(), + } + } + + default: + return graphql.OneShot(graphql.ErrorResponse(ctx, "unsupported GraphQL operation")) + } +} + +type executionContext struct { + *graphql.OperationContext + *executableSchema + deferred int32 + pendingDeferred int32 + deferredResults chan graphql.DeferredResult +} + +func (ec *executionContext) processDeferredGroup(dg graphql.DeferredGroup) { + atomic.AddInt32(&ec.pendingDeferred, 1) + go func() { + ctx := graphql.WithFreshResponseContext(dg.Context) + dg.FieldSet.Dispatch(ctx) + ds := graphql.DeferredResult{ + Path: dg.Path, + Label: dg.Label, + Result: dg.FieldSet, + Errors: graphql.GetErrors(ctx), + } + // null fields should bubble up + if dg.FieldSet.Invalids > 0 { + ds.Result = graphql.Null + } + ec.deferredResults <- ds + }() +} + +func (ec *executionContext) introspectSchema() (*introspection.Schema, error) { + if ec.DisableIntrospection { + return nil, errors.New("introspection disabled") + } + return introspection.WrapSchema(ec.Schema()), nil +} + +func (ec *executionContext) introspectType(name string) (*introspection.Type, error) { + if ec.DisableIntrospection { + return nil, errors.New("introspection disabled") + } + return introspection.WrapTypeFromDef(ec.Schema(), ec.Schema().Types[name]), nil +} + +var sources = []*ast.Source{ + {Name: "../schema.graphqls", Input: `extend schema + @link( + url: "https://specs.apollo.dev/federation/v2.5" + import: ["@key"] + ) + +directive @openfed__entityCache( + maxAge: Int! + includeHeaders: Boolean = false + partialCacheLoad: Boolean = false + shadowMode: Boolean = false +) on OBJECT + +directive @openfed__queryCache( + maxAge: Int! + includeHeaders: Boolean = false + shadowMode: Boolean = false +) on FIELD_DEFINITION + +directive @openfed__cacheInvalidate on FIELD_DEFINITION + +directive @openfed__cachePopulate(maxAge: Int) on FIELD_DEFINITION + +directive @openfed__is(fields: String!) on ARGUMENT_DEFINITION + +type Query { + """Simple key lookup""" + article(id: ID!): Article @openfed__queryCache(maxAge: 120) + """List query""" + articles: [Article!]! @openfed__queryCache(maxAge: 120) + """Batch lookup with @openfed__is""" + articlesByIds(ids: [ID!]! @openfed__is(fields: "id")): [Article!]! @openfed__queryCache(maxAge: 120) + """Argument remapping via @openfed__is""" + articleBySlug(slug: String! @openfed__is(fields: "slug")): Article @openfed__queryCache(maxAge: 120) + + """Composite key lookup via input object with @openfed__is""" + listing(key: ListingKey! @openfed__is(fields: "sellerId sku")): Listing @openfed__queryCache(maxAge: 60) + """List of all listings""" + listings: [Listing!]! @openfed__queryCache(maxAge: 60) + + """Nested key lookup with @openfed__is and input object""" + venue(location: VenueLocationKey! @openfed__is(fields: "address { id }")): Venue @openfed__queryCache(maxAge: 180) + """List of all venues""" + venues: [Venue!]! @openfed__queryCache(maxAge: 180) + + """Per-user profile (cache varies by Authorization header)""" + userProfile(id: ID!): UserProfile @openfed__queryCache(maxAge: 60, includeHeaders: true) + + """Single catalog entry""" + catalog(id: ID!): Catalog @openfed__queryCache(maxAge: 120) + """All catalog entries (for partial cache load testing)""" + catalogs: [Catalog!]! @openfed__queryCache(maxAge: 120) + + """Single metric (shadow mode - always fetches from subgraph, compares with cache)""" + metric(id: ID!): Metric @openfed__queryCache(maxAge: 300, shadowMode: true) +} + +type Mutation { + updateArticle(id: ID!, title: String!): Article @openfed__cacheInvalidate + createArticle(title: String!, body: String!, authorName: String!): Article! @openfed__cachePopulate(maxAge: 30) + deleteListing(key: ListingKey!): Listing @openfed__cacheInvalidate +} + +"""Per-user caching: includeHeaders makes the cache key include a hash of forwarded headers (e.g. Authorization)""" +type UserProfile @key(fields: "id") @openfed__entityCache(maxAge: 60, includeHeaders: true) { + id: ID! + username: String! + email: String! + role: String! +} + +"""Partial cache load: when some entities are cached and others aren't, only the missing ones are fetched""" +type Catalog @key(fields: "id") @openfed__entityCache(maxAge: 120, partialCacheLoad: true) { + id: ID! + name: String! + category: String! + itemCount: Int! +} + +"""Shadow mode: always fetches from subgraph but compares with cache for staleness detection""" +type Metric @key(fields: "id") @openfed__entityCache(maxAge: 300, shadowMode: true) { + id: ID! + name: String! + value: Float! + unit: String! +} + +input ListingKey { + sellerId: ID! + sku: String! +} + +input VenueLocationKey { + address: VenueAddressKey! +} + +input VenueAddressKey { + id: ID! +} + +interface Personalized @key(fields: "id") { + id: ID! +} + +type Viewer @key(fields: "id") { + id: ID! + recommendedArticles: [Article!]! +} + +type Article implements Personalized @key(fields: "id") @key(fields: "slug") @openfed__entityCache(maxAge: 120) { + id: ID! + slug: String! + title: String! + body: String! + authorName: String! + publishedAt: String! + tags: [String!]! +} + +type Listing @key(fields: "sellerId sku") @openfed__entityCache(maxAge: 60) { + sellerId: ID! + sku: String! + title: String! + price: Float! + currency: String! + inStock: Boolean! +} + +type Address { + id: ID! +} + +type Venue @key(fields: "address { id }") @openfed__entityCache(maxAge: 180) { + address: Address! + name: String! + capacity: Int! + city: String! +} +`, BuiltIn: false}, + {Name: "../../federation/directives.graphql", Input: ` + directive @authenticated on FIELD_DEFINITION | OBJECT | INTERFACE | SCALAR | ENUM + directive @composeDirective(name: String!) repeatable on SCHEMA + directive @extends on OBJECT | INTERFACE + directive @external on OBJECT | FIELD_DEFINITION + directive @key(fields: FieldSet!, resolvable: Boolean = true) repeatable on OBJECT | INTERFACE + directive @inaccessible on + | ARGUMENT_DEFINITION + | ENUM + | ENUM_VALUE + | FIELD_DEFINITION + | INPUT_FIELD_DEFINITION + | INPUT_OBJECT + | INTERFACE + | OBJECT + | SCALAR + | UNION + directive @interfaceObject on OBJECT + directive @link(import: [String!], url: String!) repeatable on SCHEMA + directive @override(from: String!, label: String) on FIELD_DEFINITION + directive @policy(policies: [[federation__Policy!]!]!) on + | FIELD_DEFINITION + | OBJECT + | INTERFACE + | SCALAR + | ENUM + directive @provides(fields: FieldSet!) on FIELD_DEFINITION + directive @requires(fields: FieldSet!) on FIELD_DEFINITION + directive @requiresScopes(scopes: [[federation__Scope!]!]!) on + | FIELD_DEFINITION + | OBJECT + | INTERFACE + | SCALAR + | ENUM + directive @shareable repeatable on FIELD_DEFINITION | OBJECT + directive @tag(name: String!) repeatable on + | ARGUMENT_DEFINITION + | ENUM + | ENUM_VALUE + | FIELD_DEFINITION + | INPUT_FIELD_DEFINITION + | INPUT_OBJECT + | INTERFACE + | OBJECT + | SCALAR + | UNION + scalar _Any + scalar FieldSet + scalar federation__Policy + scalar federation__Scope +`, BuiltIn: true}, + {Name: "../../federation/entity.graphql", Input: ` +# a union of all types that use the @key directive +union _Entity = Article | Catalog | Listing | Metric | UserProfile | Venue | Viewer + +# fake type to build resolver interfaces for users to implement +type Entity { + findArticleByID(id: ID!,): Article! + findArticleBySlug(slug: String!,): Article! + findCatalogByID(id: ID!,): Catalog! + findListingBySellerIDAndSku(sellerID: ID!,sku: String!,): Listing! + findMetricByID(id: ID!,): Metric! + findPersonalizedByID(id: ID!,): Personalized! + findUserProfileByID(id: ID!,): UserProfile! + findVenueByAddressID(addressID: ID!,): Venue! + findViewerByID(id: ID!,): Viewer! +} + +type _Service { + sdl: String +} + +extend type Query { + _entities(representations: [_Any!]!): [_Entity]! + _service: _Service! +} +`, BuiltIn: true}, +} +var parsedSchema = gqlparser.MustLoadSchema(sources...) + +// endregion ************************** generated!.gotpl ************************** + +// region ***************************** args.gotpl ***************************** + +func (ec *executionContext) field_Entity_findArticleByID_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Entity_findArticleByID_argsID(ctx, rawArgs) + if err != nil { + return nil, err + } + args["id"] = arg0 + return args, nil +} +func (ec *executionContext) field_Entity_findArticleByID_argsID( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["id"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + if tmp, ok := rawArgs["id"]; ok { + return ec.unmarshalNID2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Entity_findArticleBySlug_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Entity_findArticleBySlug_argsSlug(ctx, rawArgs) + if err != nil { + return nil, err + } + args["slug"] = arg0 + return args, nil +} +func (ec *executionContext) field_Entity_findArticleBySlug_argsSlug( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["slug"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("slug")) + if tmp, ok := rawArgs["slug"]; ok { + return ec.unmarshalNString2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Entity_findCatalogByID_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Entity_findCatalogByID_argsID(ctx, rawArgs) + if err != nil { + return nil, err + } + args["id"] = arg0 + return args, nil +} +func (ec *executionContext) field_Entity_findCatalogByID_argsID( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["id"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + if tmp, ok := rawArgs["id"]; ok { + return ec.unmarshalNID2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Entity_findListingBySellerIDAndSku_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Entity_findListingBySellerIDAndSku_argsSellerID(ctx, rawArgs) + if err != nil { + return nil, err + } + args["sellerID"] = arg0 + arg1, err := ec.field_Entity_findListingBySellerIDAndSku_argsSku(ctx, rawArgs) + if err != nil { + return nil, err + } + args["sku"] = arg1 + return args, nil +} +func (ec *executionContext) field_Entity_findListingBySellerIDAndSku_argsSellerID( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["sellerID"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("sellerID")) + if tmp, ok := rawArgs["sellerID"]; ok { + return ec.unmarshalNID2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Entity_findListingBySellerIDAndSku_argsSku( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["sku"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("sku")) + if tmp, ok := rawArgs["sku"]; ok { + return ec.unmarshalNString2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Entity_findMetricByID_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Entity_findMetricByID_argsID(ctx, rawArgs) + if err != nil { + return nil, err + } + args["id"] = arg0 + return args, nil +} +func (ec *executionContext) field_Entity_findMetricByID_argsID( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["id"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + if tmp, ok := rawArgs["id"]; ok { + return ec.unmarshalNID2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Entity_findPersonalizedByID_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Entity_findPersonalizedByID_argsID(ctx, rawArgs) + if err != nil { + return nil, err + } + args["id"] = arg0 + return args, nil +} +func (ec *executionContext) field_Entity_findPersonalizedByID_argsID( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["id"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + if tmp, ok := rawArgs["id"]; ok { + return ec.unmarshalNID2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Entity_findUserProfileByID_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Entity_findUserProfileByID_argsID(ctx, rawArgs) + if err != nil { + return nil, err + } + args["id"] = arg0 + return args, nil +} +func (ec *executionContext) field_Entity_findUserProfileByID_argsID( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["id"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + if tmp, ok := rawArgs["id"]; ok { + return ec.unmarshalNID2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Entity_findVenueByAddressID_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Entity_findVenueByAddressID_argsAddressID(ctx, rawArgs) + if err != nil { + return nil, err + } + args["addressID"] = arg0 + return args, nil +} +func (ec *executionContext) field_Entity_findVenueByAddressID_argsAddressID( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["addressID"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("addressID")) + if tmp, ok := rawArgs["addressID"]; ok { + return ec.unmarshalNID2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Entity_findViewerByID_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Entity_findViewerByID_argsID(ctx, rawArgs) + if err != nil { + return nil, err + } + args["id"] = arg0 + return args, nil +} +func (ec *executionContext) field_Entity_findViewerByID_argsID( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["id"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + if tmp, ok := rawArgs["id"]; ok { + return ec.unmarshalNID2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Mutation_createArticle_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Mutation_createArticle_argsTitle(ctx, rawArgs) + if err != nil { + return nil, err + } + args["title"] = arg0 + arg1, err := ec.field_Mutation_createArticle_argsBody(ctx, rawArgs) + if err != nil { + return nil, err + } + args["body"] = arg1 + arg2, err := ec.field_Mutation_createArticle_argsAuthorName(ctx, rawArgs) + if err != nil { + return nil, err + } + args["authorName"] = arg2 + return args, nil +} +func (ec *executionContext) field_Mutation_createArticle_argsTitle( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["title"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("title")) + if tmp, ok := rawArgs["title"]; ok { + return ec.unmarshalNString2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Mutation_createArticle_argsBody( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["body"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("body")) + if tmp, ok := rawArgs["body"]; ok { + return ec.unmarshalNString2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Mutation_createArticle_argsAuthorName( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["authorName"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("authorName")) + if tmp, ok := rawArgs["authorName"]; ok { + return ec.unmarshalNString2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Mutation_deleteListing_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Mutation_deleteListing_argsKey(ctx, rawArgs) + if err != nil { + return nil, err + } + args["key"] = arg0 + return args, nil +} +func (ec *executionContext) field_Mutation_deleteListing_argsKey( + ctx context.Context, + rawArgs map[string]any, +) (model.ListingKey, error) { + if _, ok := rawArgs["key"]; !ok { + var zeroVal model.ListingKey + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("key")) + if tmp, ok := rawArgs["key"]; ok { + return ec.unmarshalNListingKey2githubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐListingKey(ctx, tmp) + } + + var zeroVal model.ListingKey + return zeroVal, nil +} + +func (ec *executionContext) field_Mutation_updateArticle_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Mutation_updateArticle_argsID(ctx, rawArgs) + if err != nil { + return nil, err + } + args["id"] = arg0 + arg1, err := ec.field_Mutation_updateArticle_argsTitle(ctx, rawArgs) + if err != nil { + return nil, err + } + args["title"] = arg1 + return args, nil +} +func (ec *executionContext) field_Mutation_updateArticle_argsID( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["id"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + if tmp, ok := rawArgs["id"]; ok { + return ec.unmarshalNID2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Mutation_updateArticle_argsTitle( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["title"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("title")) + if tmp, ok := rawArgs["title"]; ok { + return ec.unmarshalNString2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Query___type_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Query___type_argsName(ctx, rawArgs) + if err != nil { + return nil, err + } + args["name"] = arg0 + return args, nil +} +func (ec *executionContext) field_Query___type_argsName( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["name"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("name")) + if tmp, ok := rawArgs["name"]; ok { + return ec.unmarshalNString2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Query__entities_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Query__entities_argsRepresentations(ctx, rawArgs) + if err != nil { + return nil, err + } + args["representations"] = arg0 + return args, nil +} +func (ec *executionContext) field_Query__entities_argsRepresentations( + ctx context.Context, + rawArgs map[string]any, +) ([]map[string]any, error) { + if _, ok := rawArgs["representations"]; !ok { + var zeroVal []map[string]any + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("representations")) + if tmp, ok := rawArgs["representations"]; ok { + return ec.unmarshalN_Any2ᚕmapᚄ(ctx, tmp) + } + + var zeroVal []map[string]any + return zeroVal, nil +} + +func (ec *executionContext) field_Query_articleBySlug_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Query_articleBySlug_argsSlug(ctx, rawArgs) + if err != nil { + return nil, err + } + args["slug"] = arg0 + return args, nil +} +func (ec *executionContext) field_Query_articleBySlug_argsSlug( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["slug"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("slug")) + if tmp, ok := rawArgs["slug"]; ok { + return ec.unmarshalNString2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Query_article_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Query_article_argsID(ctx, rawArgs) + if err != nil { + return nil, err + } + args["id"] = arg0 + return args, nil +} +func (ec *executionContext) field_Query_article_argsID( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["id"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + if tmp, ok := rawArgs["id"]; ok { + return ec.unmarshalNID2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Query_articlesByIds_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Query_articlesByIds_argsIds(ctx, rawArgs) + if err != nil { + return nil, err + } + args["ids"] = arg0 + return args, nil +} +func (ec *executionContext) field_Query_articlesByIds_argsIds( + ctx context.Context, + rawArgs map[string]any, +) ([]string, error) { + if _, ok := rawArgs["ids"]; !ok { + var zeroVal []string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("ids")) + if tmp, ok := rawArgs["ids"]; ok { + return ec.unmarshalNID2ᚕstringᚄ(ctx, tmp) + } + + var zeroVal []string + return zeroVal, nil +} + +func (ec *executionContext) field_Query_catalog_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Query_catalog_argsID(ctx, rawArgs) + if err != nil { + return nil, err + } + args["id"] = arg0 + return args, nil +} +func (ec *executionContext) field_Query_catalog_argsID( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["id"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + if tmp, ok := rawArgs["id"]; ok { + return ec.unmarshalNID2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Query_listing_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Query_listing_argsKey(ctx, rawArgs) + if err != nil { + return nil, err + } + args["key"] = arg0 + return args, nil +} +func (ec *executionContext) field_Query_listing_argsKey( + ctx context.Context, + rawArgs map[string]any, +) (model.ListingKey, error) { + if _, ok := rawArgs["key"]; !ok { + var zeroVal model.ListingKey + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("key")) + if tmp, ok := rawArgs["key"]; ok { + return ec.unmarshalNListingKey2githubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐListingKey(ctx, tmp) + } + + var zeroVal model.ListingKey + return zeroVal, nil +} + +func (ec *executionContext) field_Query_metric_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Query_metric_argsID(ctx, rawArgs) + if err != nil { + return nil, err + } + args["id"] = arg0 + return args, nil +} +func (ec *executionContext) field_Query_metric_argsID( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["id"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + if tmp, ok := rawArgs["id"]; ok { + return ec.unmarshalNID2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Query_userProfile_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Query_userProfile_argsID(ctx, rawArgs) + if err != nil { + return nil, err + } + args["id"] = arg0 + return args, nil +} +func (ec *executionContext) field_Query_userProfile_argsID( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["id"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + if tmp, ok := rawArgs["id"]; ok { + return ec.unmarshalNID2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Query_venue_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Query_venue_argsLocation(ctx, rawArgs) + if err != nil { + return nil, err + } + args["location"] = arg0 + return args, nil +} +func (ec *executionContext) field_Query_venue_argsLocation( + ctx context.Context, + rawArgs map[string]any, +) (model.VenueLocationKey, error) { + if _, ok := rawArgs["location"]; !ok { + var zeroVal model.VenueLocationKey + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("location")) + if tmp, ok := rawArgs["location"]; ok { + return ec.unmarshalNVenueLocationKey2githubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐVenueLocationKey(ctx, tmp) + } + + var zeroVal model.VenueLocationKey + return zeroVal, nil +} + +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 := ec.field___Directive_args_argsIncludeDeprecated(ctx, rawArgs) + if err != nil { + return nil, err + } + args["includeDeprecated"] = arg0 + return args, nil +} +func (ec *executionContext) field___Directive_args_argsIncludeDeprecated( + ctx context.Context, + rawArgs map[string]any, +) (*bool, error) { + if _, ok := rawArgs["includeDeprecated"]; !ok { + var zeroVal *bool + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("includeDeprecated")) + if tmp, ok := rawArgs["includeDeprecated"]; ok { + return ec.unmarshalOBoolean2ᚖbool(ctx, tmp) + } + + var zeroVal *bool + return zeroVal, nil +} + +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 := ec.field___Field_args_argsIncludeDeprecated(ctx, rawArgs) + if err != nil { + return nil, err + } + args["includeDeprecated"] = arg0 + return args, nil +} +func (ec *executionContext) field___Field_args_argsIncludeDeprecated( + ctx context.Context, + rawArgs map[string]any, +) (*bool, error) { + if _, ok := rawArgs["includeDeprecated"]; !ok { + var zeroVal *bool + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("includeDeprecated")) + if tmp, ok := rawArgs["includeDeprecated"]; ok { + return ec.unmarshalOBoolean2ᚖbool(ctx, tmp) + } + + var zeroVal *bool + return zeroVal, nil +} + +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 := ec.field___Type_enumValues_argsIncludeDeprecated(ctx, rawArgs) + if err != nil { + return nil, err + } + args["includeDeprecated"] = arg0 + return args, nil +} +func (ec *executionContext) field___Type_enumValues_argsIncludeDeprecated( + ctx context.Context, + rawArgs map[string]any, +) (bool, error) { + if _, ok := rawArgs["includeDeprecated"]; !ok { + var zeroVal bool + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("includeDeprecated")) + if tmp, ok := rawArgs["includeDeprecated"]; ok { + return ec.unmarshalOBoolean2bool(ctx, tmp) + } + + var zeroVal bool + return zeroVal, nil +} + +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 := ec.field___Type_fields_argsIncludeDeprecated(ctx, rawArgs) + if err != nil { + return nil, err + } + args["includeDeprecated"] = arg0 + return args, nil +} +func (ec *executionContext) field___Type_fields_argsIncludeDeprecated( + ctx context.Context, + rawArgs map[string]any, +) (bool, error) { + if _, ok := rawArgs["includeDeprecated"]; !ok { + var zeroVal bool + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("includeDeprecated")) + if tmp, ok := rawArgs["includeDeprecated"]; ok { + return ec.unmarshalOBoolean2bool(ctx, tmp) + } + + var zeroVal bool + return zeroVal, nil +} + +// endregion ***************************** args.gotpl ***************************** + +// region ************************** directives.gotpl ************************** + +// endregion ************************** directives.gotpl ************************** + +// region **************************** field.gotpl ***************************** + +func (ec *executionContext) _Address_id(ctx context.Context, field graphql.CollectedField, obj *model.Address) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Address_id(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Address_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Address", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Article_id(ctx context.Context, field graphql.CollectedField, obj *model.Article) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Article_id(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Article_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Article", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Article_slug(ctx context.Context, field graphql.CollectedField, obj *model.Article) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Article_slug(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Slug, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Article_slug(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Article", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Article_title(ctx context.Context, field graphql.CollectedField, obj *model.Article) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Article_title(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Title, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Article_title(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Article", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Article_body(ctx context.Context, field graphql.CollectedField, obj *model.Article) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Article_body(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Body, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Article_body(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Article", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Article_authorName(ctx context.Context, field graphql.CollectedField, obj *model.Article) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Article_authorName(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.AuthorName, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Article_authorName(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Article", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Article_publishedAt(ctx context.Context, field graphql.CollectedField, obj *model.Article) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Article_publishedAt(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.PublishedAt, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Article_publishedAt(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Article", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Article_tags(ctx context.Context, field graphql.CollectedField, obj *model.Article) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Article_tags(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Tags, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]string) + fc.Result = res + return ec.marshalNString2ᚕstringᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Article_tags(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Article", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Catalog_id(ctx context.Context, field graphql.CollectedField, obj *model.Catalog) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Catalog_id(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Catalog_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Catalog", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Catalog_name(ctx context.Context, field graphql.CollectedField, obj *model.Catalog) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Catalog_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Catalog_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Catalog", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Catalog_category(ctx context.Context, field graphql.CollectedField, obj *model.Catalog) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Catalog_category(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Category, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Catalog_category(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Catalog", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Catalog_itemCount(ctx context.Context, field graphql.CollectedField, obj *model.Catalog) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Catalog_itemCount(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.ItemCount, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Catalog_itemCount(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Catalog", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Entity_findArticleByID(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Entity_findArticleByID(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Entity().FindArticleByID(rctx, fc.Args["id"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*model.Article) + fc.Result = res + return ec.marshalNArticle2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐArticle(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Entity_findArticleByID(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Entity", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Article_id(ctx, field) + case "slug": + return ec.fieldContext_Article_slug(ctx, field) + case "title": + return ec.fieldContext_Article_title(ctx, field) + case "body": + return ec.fieldContext_Article_body(ctx, field) + case "authorName": + return ec.fieldContext_Article_authorName(ctx, field) + case "publishedAt": + return ec.fieldContext_Article_publishedAt(ctx, field) + case "tags": + return ec.fieldContext_Article_tags(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Article", field.Name) + }, + } + 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_Entity_findArticleByID_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Entity_findArticleBySlug(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Entity_findArticleBySlug(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Entity().FindArticleBySlug(rctx, fc.Args["slug"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*model.Article) + fc.Result = res + return ec.marshalNArticle2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐArticle(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Entity_findArticleBySlug(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Entity", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Article_id(ctx, field) + case "slug": + return ec.fieldContext_Article_slug(ctx, field) + case "title": + return ec.fieldContext_Article_title(ctx, field) + case "body": + return ec.fieldContext_Article_body(ctx, field) + case "authorName": + return ec.fieldContext_Article_authorName(ctx, field) + case "publishedAt": + return ec.fieldContext_Article_publishedAt(ctx, field) + case "tags": + return ec.fieldContext_Article_tags(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Article", field.Name) + }, + } + 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_Entity_findArticleBySlug_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Entity_findCatalogByID(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Entity_findCatalogByID(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Entity().FindCatalogByID(rctx, fc.Args["id"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*model.Catalog) + fc.Result = res + return ec.marshalNCatalog2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐCatalog(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Entity_findCatalogByID(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Entity", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Catalog_id(ctx, field) + case "name": + return ec.fieldContext_Catalog_name(ctx, field) + case "category": + return ec.fieldContext_Catalog_category(ctx, field) + case "itemCount": + return ec.fieldContext_Catalog_itemCount(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Catalog", field.Name) + }, + } + 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_Entity_findCatalogByID_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Entity_findListingBySellerIDAndSku(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Entity_findListingBySellerIDAndSku(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Entity().FindListingBySellerIDAndSku(rctx, fc.Args["sellerID"].(string), fc.Args["sku"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*model.Listing) + fc.Result = res + return ec.marshalNListing2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐListing(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Entity_findListingBySellerIDAndSku(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Entity", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "sellerId": + return ec.fieldContext_Listing_sellerId(ctx, field) + case "sku": + return ec.fieldContext_Listing_sku(ctx, field) + case "title": + return ec.fieldContext_Listing_title(ctx, field) + case "price": + return ec.fieldContext_Listing_price(ctx, field) + case "currency": + return ec.fieldContext_Listing_currency(ctx, field) + case "inStock": + return ec.fieldContext_Listing_inStock(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Listing", field.Name) + }, + } + 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_Entity_findListingBySellerIDAndSku_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Entity_findMetricByID(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Entity_findMetricByID(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Entity().FindMetricByID(rctx, fc.Args["id"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*model.Metric) + fc.Result = res + return ec.marshalNMetric2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐMetric(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Entity_findMetricByID(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Entity", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Metric_id(ctx, field) + case "name": + return ec.fieldContext_Metric_name(ctx, field) + case "value": + return ec.fieldContext_Metric_value(ctx, field) + case "unit": + return ec.fieldContext_Metric_unit(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Metric", field.Name) + }, + } + 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_Entity_findMetricByID_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Entity_findPersonalizedByID(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Entity_findPersonalizedByID(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Entity().FindPersonalizedByID(rctx, fc.Args["id"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(model.Personalized) + fc.Result = res + return ec.marshalNPersonalized2githubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐPersonalized(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Entity_findPersonalizedByID(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Entity", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("FieldContext.Child cannot be called on type INTERFACE") + }, + } + 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_Entity_findPersonalizedByID_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Entity_findUserProfileByID(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Entity_findUserProfileByID(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Entity().FindUserProfileByID(rctx, fc.Args["id"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*model.UserProfile) + fc.Result = res + return ec.marshalNUserProfile2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐUserProfile(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Entity_findUserProfileByID(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Entity", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_UserProfile_id(ctx, field) + case "username": + return ec.fieldContext_UserProfile_username(ctx, field) + case "email": + return ec.fieldContext_UserProfile_email(ctx, field) + case "role": + return ec.fieldContext_UserProfile_role(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type UserProfile", field.Name) + }, + } + 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_Entity_findUserProfileByID_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Entity_findVenueByAddressID(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Entity_findVenueByAddressID(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Entity().FindVenueByAddressID(rctx, fc.Args["addressID"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*model.Venue) + fc.Result = res + return ec.marshalNVenue2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐVenue(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Entity_findVenueByAddressID(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Entity", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "address": + return ec.fieldContext_Venue_address(ctx, field) + case "name": + return ec.fieldContext_Venue_name(ctx, field) + case "capacity": + return ec.fieldContext_Venue_capacity(ctx, field) + case "city": + return ec.fieldContext_Venue_city(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Venue", field.Name) + }, + } + 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_Entity_findVenueByAddressID_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Entity_findViewerByID(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Entity_findViewerByID(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Entity().FindViewerByID(rctx, fc.Args["id"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*model.Viewer) + fc.Result = res + return ec.marshalNViewer2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐViewer(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Entity_findViewerByID(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Entity", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Viewer_id(ctx, field) + case "recommendedArticles": + return ec.fieldContext_Viewer_recommendedArticles(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Viewer", field.Name) + }, + } + 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_Entity_findViewerByID_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Listing_sellerId(ctx context.Context, field graphql.CollectedField, obj *model.Listing) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Listing_sellerId(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.SellerID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Listing_sellerId(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Listing", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Listing_sku(ctx context.Context, field graphql.CollectedField, obj *model.Listing) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Listing_sku(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Sku, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Listing_sku(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Listing", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Listing_title(ctx context.Context, field graphql.CollectedField, obj *model.Listing) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Listing_title(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Title, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Listing_title(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Listing", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Listing_price(ctx context.Context, field graphql.CollectedField, obj *model.Listing) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Listing_price(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Price, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(float64) + fc.Result = res + return ec.marshalNFloat2float64(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Listing_price(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Listing", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Float does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Listing_currency(ctx context.Context, field graphql.CollectedField, obj *model.Listing) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Listing_currency(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Currency, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Listing_currency(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Listing", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Listing_inStock(ctx context.Context, field graphql.CollectedField, obj *model.Listing) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Listing_inStock(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.InStock, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Listing_inStock(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Listing", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Metric_id(ctx context.Context, field graphql.CollectedField, obj *model.Metric) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Metric_id(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Metric_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Metric", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Metric_name(ctx context.Context, field graphql.CollectedField, obj *model.Metric) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Metric_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Metric_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Metric", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Metric_value(ctx context.Context, field graphql.CollectedField, obj *model.Metric) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Metric_value(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Value, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(float64) + fc.Result = res + return ec.marshalNFloat2float64(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Metric_value(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Metric", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Float does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Metric_unit(ctx context.Context, field graphql.CollectedField, obj *model.Metric) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Metric_unit(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Unit, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Metric_unit(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Metric", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Mutation_updateArticle(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Mutation_updateArticle(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Mutation().UpdateArticle(rctx, fc.Args["id"].(string), fc.Args["title"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*model.Article) + fc.Result = res + return ec.marshalOArticle2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐArticle(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Mutation_updateArticle(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Mutation", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Article_id(ctx, field) + case "slug": + return ec.fieldContext_Article_slug(ctx, field) + case "title": + return ec.fieldContext_Article_title(ctx, field) + case "body": + return ec.fieldContext_Article_body(ctx, field) + case "authorName": + return ec.fieldContext_Article_authorName(ctx, field) + case "publishedAt": + return ec.fieldContext_Article_publishedAt(ctx, field) + case "tags": + return ec.fieldContext_Article_tags(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Article", field.Name) + }, + } + 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_Mutation_updateArticle_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Mutation_createArticle(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Mutation_createArticle(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Mutation().CreateArticle(rctx, fc.Args["title"].(string), fc.Args["body"].(string), fc.Args["authorName"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*model.Article) + fc.Result = res + return ec.marshalNArticle2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐArticle(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Mutation_createArticle(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Mutation", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Article_id(ctx, field) + case "slug": + return ec.fieldContext_Article_slug(ctx, field) + case "title": + return ec.fieldContext_Article_title(ctx, field) + case "body": + return ec.fieldContext_Article_body(ctx, field) + case "authorName": + return ec.fieldContext_Article_authorName(ctx, field) + case "publishedAt": + return ec.fieldContext_Article_publishedAt(ctx, field) + case "tags": + return ec.fieldContext_Article_tags(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Article", field.Name) + }, + } + 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_Mutation_createArticle_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Mutation_deleteListing(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Mutation_deleteListing(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Mutation().DeleteListing(rctx, fc.Args["key"].(model.ListingKey)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*model.Listing) + fc.Result = res + return ec.marshalOListing2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐListing(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Mutation_deleteListing(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Mutation", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "sellerId": + return ec.fieldContext_Listing_sellerId(ctx, field) + case "sku": + return ec.fieldContext_Listing_sku(ctx, field) + case "title": + return ec.fieldContext_Listing_title(ctx, field) + case "price": + return ec.fieldContext_Listing_price(ctx, field) + case "currency": + return ec.fieldContext_Listing_currency(ctx, field) + case "inStock": + return ec.fieldContext_Listing_inStock(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Listing", field.Name) + }, + } + 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_Mutation_deleteListing_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query_article(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query_article(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().Article(rctx, fc.Args["id"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*model.Article) + fc.Result = res + return ec.marshalOArticle2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐArticle(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query_article(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) { + switch field.Name { + case "id": + return ec.fieldContext_Article_id(ctx, field) + case "slug": + return ec.fieldContext_Article_slug(ctx, field) + case "title": + return ec.fieldContext_Article_title(ctx, field) + case "body": + return ec.fieldContext_Article_body(ctx, field) + case "authorName": + return ec.fieldContext_Article_authorName(ctx, field) + case "publishedAt": + return ec.fieldContext_Article_publishedAt(ctx, field) + case "tags": + return ec.fieldContext_Article_tags(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Article", field.Name) + }, + } + 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_article_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query_articles(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query_articles(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().Articles(rctx) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]*model.Article) + fc.Result = res + return ec.marshalNArticle2ᚕᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐArticleᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query_articles(_ 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) { + switch field.Name { + case "id": + return ec.fieldContext_Article_id(ctx, field) + case "slug": + return ec.fieldContext_Article_slug(ctx, field) + case "title": + return ec.fieldContext_Article_title(ctx, field) + case "body": + return ec.fieldContext_Article_body(ctx, field) + case "authorName": + return ec.fieldContext_Article_authorName(ctx, field) + case "publishedAt": + return ec.fieldContext_Article_publishedAt(ctx, field) + case "tags": + return ec.fieldContext_Article_tags(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Article", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Query_articlesByIds(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query_articlesByIds(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().ArticlesByIds(rctx, fc.Args["ids"].([]string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]*model.Article) + fc.Result = res + return ec.marshalNArticle2ᚕᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐArticleᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query_articlesByIds(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) { + switch field.Name { + case "id": + return ec.fieldContext_Article_id(ctx, field) + case "slug": + return ec.fieldContext_Article_slug(ctx, field) + case "title": + return ec.fieldContext_Article_title(ctx, field) + case "body": + return ec.fieldContext_Article_body(ctx, field) + case "authorName": + return ec.fieldContext_Article_authorName(ctx, field) + case "publishedAt": + return ec.fieldContext_Article_publishedAt(ctx, field) + case "tags": + return ec.fieldContext_Article_tags(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Article", field.Name) + }, + } + 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_articlesByIds_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query_articleBySlug(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query_articleBySlug(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().ArticleBySlug(rctx, fc.Args["slug"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*model.Article) + fc.Result = res + return ec.marshalOArticle2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐArticle(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query_articleBySlug(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) { + switch field.Name { + case "id": + return ec.fieldContext_Article_id(ctx, field) + case "slug": + return ec.fieldContext_Article_slug(ctx, field) + case "title": + return ec.fieldContext_Article_title(ctx, field) + case "body": + return ec.fieldContext_Article_body(ctx, field) + case "authorName": + return ec.fieldContext_Article_authorName(ctx, field) + case "publishedAt": + return ec.fieldContext_Article_publishedAt(ctx, field) + case "tags": + return ec.fieldContext_Article_tags(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Article", field.Name) + }, + } + 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_articleBySlug_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query_listing(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query_listing(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().Listing(rctx, fc.Args["key"].(model.ListingKey)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*model.Listing) + fc.Result = res + return ec.marshalOListing2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐListing(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query_listing(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) { + switch field.Name { + case "sellerId": + return ec.fieldContext_Listing_sellerId(ctx, field) + case "sku": + return ec.fieldContext_Listing_sku(ctx, field) + case "title": + return ec.fieldContext_Listing_title(ctx, field) + case "price": + return ec.fieldContext_Listing_price(ctx, field) + case "currency": + return ec.fieldContext_Listing_currency(ctx, field) + case "inStock": + return ec.fieldContext_Listing_inStock(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Listing", field.Name) + }, + } + 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_listing_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query_listings(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query_listings(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().Listings(rctx) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]*model.Listing) + fc.Result = res + return ec.marshalNListing2ᚕᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐListingᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query_listings(_ 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) { + switch field.Name { + case "sellerId": + return ec.fieldContext_Listing_sellerId(ctx, field) + case "sku": + return ec.fieldContext_Listing_sku(ctx, field) + case "title": + return ec.fieldContext_Listing_title(ctx, field) + case "price": + return ec.fieldContext_Listing_price(ctx, field) + case "currency": + return ec.fieldContext_Listing_currency(ctx, field) + case "inStock": + return ec.fieldContext_Listing_inStock(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Listing", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Query_venue(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query_venue(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().Venue(rctx, fc.Args["location"].(model.VenueLocationKey)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*model.Venue) + fc.Result = res + return ec.marshalOVenue2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐVenue(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query_venue(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) { + switch field.Name { + case "address": + return ec.fieldContext_Venue_address(ctx, field) + case "name": + return ec.fieldContext_Venue_name(ctx, field) + case "capacity": + return ec.fieldContext_Venue_capacity(ctx, field) + case "city": + return ec.fieldContext_Venue_city(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Venue", field.Name) + }, + } + 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_venue_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query_venues(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query_venues(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().Venues(rctx) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]*model.Venue) + fc.Result = res + return ec.marshalNVenue2ᚕᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐVenueᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query_venues(_ 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) { + switch field.Name { + case "address": + return ec.fieldContext_Venue_address(ctx, field) + case "name": + return ec.fieldContext_Venue_name(ctx, field) + case "capacity": + return ec.fieldContext_Venue_capacity(ctx, field) + case "city": + return ec.fieldContext_Venue_city(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Venue", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Query_userProfile(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query_userProfile(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().UserProfile(rctx, fc.Args["id"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*model.UserProfile) + fc.Result = res + return ec.marshalOUserProfile2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐUserProfile(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query_userProfile(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) { + switch field.Name { + case "id": + return ec.fieldContext_UserProfile_id(ctx, field) + case "username": + return ec.fieldContext_UserProfile_username(ctx, field) + case "email": + return ec.fieldContext_UserProfile_email(ctx, field) + case "role": + return ec.fieldContext_UserProfile_role(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type UserProfile", field.Name) + }, + } + 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_userProfile_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query_catalog(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query_catalog(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().Catalog(rctx, fc.Args["id"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*model.Catalog) + fc.Result = res + return ec.marshalOCatalog2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐCatalog(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query_catalog(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) { + switch field.Name { + case "id": + return ec.fieldContext_Catalog_id(ctx, field) + case "name": + return ec.fieldContext_Catalog_name(ctx, field) + case "category": + return ec.fieldContext_Catalog_category(ctx, field) + case "itemCount": + return ec.fieldContext_Catalog_itemCount(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Catalog", field.Name) + }, + } + 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_catalog_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query_catalogs(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query_catalogs(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().Catalogs(rctx) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]*model.Catalog) + fc.Result = res + return ec.marshalNCatalog2ᚕᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐCatalogᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query_catalogs(_ 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) { + switch field.Name { + case "id": + return ec.fieldContext_Catalog_id(ctx, field) + case "name": + return ec.fieldContext_Catalog_name(ctx, field) + case "category": + return ec.fieldContext_Catalog_category(ctx, field) + case "itemCount": + return ec.fieldContext_Catalog_itemCount(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Catalog", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Query_metric(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query_metric(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().Metric(rctx, fc.Args["id"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*model.Metric) + fc.Result = res + return ec.marshalOMetric2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐMetric(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query_metric(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) { + switch field.Name { + case "id": + return ec.fieldContext_Metric_id(ctx, field) + case "name": + return ec.fieldContext_Metric_name(ctx, field) + case "value": + return ec.fieldContext_Metric_value(ctx, field) + case "unit": + return ec.fieldContext_Metric_unit(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Metric", field.Name) + }, + } + 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_metric_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query__entities(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query__entities(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.__resolve_entities(ctx, fc.Args["representations"].([]map[string]any)), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]fedruntime.Entity) + fc.Result = res + return ec.marshalN_Entity2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐEntity(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query__entities(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type _Entity does not have child fields") + }, + } + 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__entities_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query__service(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query__service(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.__resolve__service(ctx) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(fedruntime.Service) + fc.Result = res + return ec.marshalN_Service2githubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐService(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query__service(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "sdl": + return ec.fieldContext__Service_sdl(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type _Service", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Query___type(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query___type(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.introspectType(fc.Args["name"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query___type(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + 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___type_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query___schema(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query___schema(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.introspectSchema() + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Schema) + fc.Result = res + return ec.marshalO__Schema2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐSchema(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query___schema(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "description": + return ec.fieldContext___Schema_description(ctx, field) + case "types": + return ec.fieldContext___Schema_types(ctx, field) + case "queryType": + return ec.fieldContext___Schema_queryType(ctx, field) + case "mutationType": + return ec.fieldContext___Schema_mutationType(ctx, field) + case "subscriptionType": + return ec.fieldContext___Schema_subscriptionType(ctx, field) + case "directives": + return ec.fieldContext___Schema_directives(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Schema", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _UserProfile_id(ctx context.Context, field graphql.CollectedField, obj *model.UserProfile) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_UserProfile_id(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_UserProfile_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "UserProfile", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _UserProfile_username(ctx context.Context, field graphql.CollectedField, obj *model.UserProfile) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_UserProfile_username(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Username, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_UserProfile_username(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "UserProfile", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _UserProfile_email(ctx context.Context, field graphql.CollectedField, obj *model.UserProfile) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_UserProfile_email(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Email, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_UserProfile_email(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "UserProfile", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _UserProfile_role(ctx context.Context, field graphql.CollectedField, obj *model.UserProfile) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_UserProfile_role(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Role, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_UserProfile_role(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "UserProfile", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Venue_address(ctx context.Context, field graphql.CollectedField, obj *model.Venue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Venue_address(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Address, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*model.Address) + fc.Result = res + return ec.marshalNAddress2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐAddress(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Venue_address(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Venue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Address_id(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Address", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Venue_name(ctx context.Context, field graphql.CollectedField, obj *model.Venue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Venue_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Venue_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Venue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Venue_capacity(ctx context.Context, field graphql.CollectedField, obj *model.Venue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Venue_capacity(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Capacity, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Venue_capacity(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Venue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Venue_city(ctx context.Context, field graphql.CollectedField, obj *model.Venue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Venue_city(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.City, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Venue_city(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Venue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Viewer_id(ctx context.Context, field graphql.CollectedField, obj *model.Viewer) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Viewer_id(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Viewer_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Viewer", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Viewer_recommendedArticles(ctx context.Context, field graphql.CollectedField, obj *model.Viewer) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Viewer_recommendedArticles(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Viewer().RecommendedArticles(rctx, obj) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]*model.Article) + fc.Result = res + return ec.marshalNArticle2ᚕᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐArticleᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Viewer_recommendedArticles(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Viewer", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Article_id(ctx, field) + case "slug": + return ec.fieldContext_Article_slug(ctx, field) + case "title": + return ec.fieldContext_Article_title(ctx, field) + case "body": + return ec.fieldContext_Article_body(ctx, field) + case "authorName": + return ec.fieldContext_Article_authorName(ctx, field) + case "publishedAt": + return ec.fieldContext_Article_publishedAt(ctx, field) + case "tags": + return ec.fieldContext_Article_tags(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Article", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) __Service_sdl(ctx context.Context, field graphql.CollectedField, obj *fedruntime.Service) (ret graphql.Marshaler) { + fc, err := ec.fieldContext__Service_sdl(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.SDL, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalOString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext__Service_sdl(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "_Service", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Directive_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Directive_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Directive_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Directive_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_isRepeatable(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Directive_isRepeatable(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsRepeatable, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Directive_isRepeatable(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_locations(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Directive_locations(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Locations, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]string) + fc.Result = res + return ec.marshalN__DirectiveLocation2ᚕstringᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Directive_locations(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type __DirectiveLocation does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_args(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Directive_args(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Args, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]introspection.InputValue) + fc.Result = res + return ec.marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Directive_args(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___InputValue_name(ctx, field) + case "description": + return ec.fieldContext___InputValue_description(ctx, field) + case "type": + return ec.fieldContext___InputValue_type(ctx, field) + case "defaultValue": + return ec.fieldContext___InputValue_defaultValue(ctx, field) + case "isDeprecated": + return ec.fieldContext___InputValue_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___InputValue_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __InputValue", field.Name) + }, + } + 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___Directive_args_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) ___EnumValue_name(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___EnumValue_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___EnumValue_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__EnumValue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___EnumValue_description(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___EnumValue_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___EnumValue_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__EnumValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___EnumValue_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___EnumValue_isDeprecated(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsDeprecated(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___EnumValue_isDeprecated(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__EnumValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___EnumValue_deprecationReason(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___EnumValue_deprecationReason(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.DeprecationReason(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___EnumValue_deprecationReason(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__EnumValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_args(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_args(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Args, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]introspection.InputValue) + fc.Result = res + return ec.marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_args(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___InputValue_name(ctx, field) + case "description": + return ec.fieldContext___InputValue_description(ctx, field) + case "type": + return ec.fieldContext___InputValue_type(ctx, field) + case "defaultValue": + return ec.fieldContext___InputValue_defaultValue(ctx, field) + case "isDeprecated": + return ec.fieldContext___InputValue_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___InputValue_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __InputValue", field.Name) + }, + } + 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___Field_args_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) ___Field_type(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_type(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Type, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_type(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_isDeprecated(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsDeprecated(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_isDeprecated(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_deprecationReason(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_deprecationReason(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.DeprecationReason(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_deprecationReason(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_name(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_description(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_type(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_type(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Type, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_type(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_defaultValue(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_defaultValue(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.DefaultValue, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_defaultValue(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_isDeprecated(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsDeprecated(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_isDeprecated(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_deprecationReason(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_deprecationReason(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.DeprecationReason(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_deprecationReason(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_types(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_types(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Types(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]introspection.Type) + fc.Result = res + return ec.marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_types(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_queryType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_queryType(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.QueryType(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_queryType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_mutationType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_mutationType(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.MutationType(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_mutationType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_subscriptionType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_subscriptionType(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.SubscriptionType(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_subscriptionType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_directives(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_directives(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Directives(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]introspection.Directive) + fc.Result = res + return ec.marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirectiveᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_directives(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___Directive_name(ctx, field) + case "description": + return ec.fieldContext___Directive_description(ctx, field) + case "isRepeatable": + return ec.fieldContext___Directive_isRepeatable(ctx, field) + case "locations": + return ec.fieldContext___Directive_locations(ctx, field) + case "args": + return ec.fieldContext___Directive_args(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Directive", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_kind(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_kind(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Kind(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalN__TypeKind2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_kind(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type __TypeKind does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_specifiedByURL(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_specifiedByURL(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.SpecifiedByURL(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_specifiedByURL(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_fields(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_fields(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Fields(fc.Args["includeDeprecated"].(bool)), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.Field) + fc.Result = res + return ec.marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐFieldᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_fields(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___Field_name(ctx, field) + case "description": + return ec.fieldContext___Field_description(ctx, field) + case "args": + return ec.fieldContext___Field_args(ctx, field) + case "type": + return ec.fieldContext___Field_type(ctx, field) + case "isDeprecated": + return ec.fieldContext___Field_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___Field_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Field", field.Name) + }, + } + 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_fields_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) ___Type_interfaces(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_interfaces(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Interfaces(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_interfaces(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_possibleTypes(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_possibleTypes(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.PossibleTypes(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_possibleTypes(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_enumValues(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_enumValues(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.EnumValues(fc.Args["includeDeprecated"].(bool)), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.EnumValue) + fc.Result = res + return ec.marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValueᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_enumValues(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___EnumValue_name(ctx, field) + case "description": + return ec.fieldContext___EnumValue_description(ctx, field) + case "isDeprecated": + return ec.fieldContext___EnumValue_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___EnumValue_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __EnumValue", field.Name) + }, + } + 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_enumValues_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) ___Type_inputFields(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_inputFields(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.InputFields(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.InputValue) + fc.Result = res + return ec.marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_inputFields(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___InputValue_name(ctx, field) + case "description": + return ec.fieldContext___InputValue_description(ctx, field) + case "type": + return ec.fieldContext___InputValue_type(ctx, field) + case "defaultValue": + return ec.fieldContext___InputValue_defaultValue(ctx, field) + case "isDeprecated": + return ec.fieldContext___InputValue_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___InputValue_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __InputValue", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_ofType(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_ofType(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.OfType(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_ofType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_isOneOf(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_isOneOf(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsOneOf(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalOBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_isOneOf(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +// endregion **************************** field.gotpl ***************************** + +// region **************************** input.gotpl ***************************** + +func (ec *executionContext) unmarshalInputListingKey(ctx context.Context, obj any) (model.ListingKey, error) { + var it model.ListingKey + asMap := map[string]any{} + for k, v := range obj.(map[string]any) { + asMap[k] = v + } + + fieldsInOrder := [...]string{"sellerId", "sku"} + for _, k := range fieldsInOrder { + v, ok := asMap[k] + if !ok { + continue + } + switch k { + case "sellerId": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("sellerId")) + data, err := ec.unmarshalNID2string(ctx, v) + if err != nil { + return it, err + } + it.SellerID = data + case "sku": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("sku")) + data, err := ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + it.Sku = data + } + } + + return it, nil +} + +func (ec *executionContext) unmarshalInputVenueAddressKey(ctx context.Context, obj any) (model.VenueAddressKey, error) { + var it model.VenueAddressKey + asMap := map[string]any{} + for k, v := range obj.(map[string]any) { + asMap[k] = v + } + + fieldsInOrder := [...]string{"id"} + for _, k := range fieldsInOrder { + v, ok := asMap[k] + if !ok { + continue + } + switch k { + case "id": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + data, err := ec.unmarshalNID2string(ctx, v) + if err != nil { + return it, err + } + it.ID = data + } + } + + return it, nil +} + +func (ec *executionContext) unmarshalInputVenueLocationKey(ctx context.Context, obj any) (model.VenueLocationKey, error) { + var it model.VenueLocationKey + asMap := map[string]any{} + for k, v := range obj.(map[string]any) { + asMap[k] = v + } + + fieldsInOrder := [...]string{"address"} + for _, k := range fieldsInOrder { + v, ok := asMap[k] + if !ok { + continue + } + switch k { + case "address": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("address")) + data, err := ec.unmarshalNVenueAddressKey2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐVenueAddressKey(ctx, v) + if err != nil { + return it, err + } + it.Address = data + } + } + + return it, nil +} + +// endregion **************************** input.gotpl ***************************** + +// region ************************** interface.gotpl *************************** + +func (ec *executionContext) _Personalized(ctx context.Context, sel ast.SelectionSet, obj model.Personalized) graphql.Marshaler { + switch obj := (obj).(type) { + case nil: + return graphql.Null + case model.Article: + return ec._Article(ctx, sel, &obj) + case *model.Article: + if obj == nil { + return graphql.Null + } + return ec._Article(ctx, sel, obj) + default: + panic(fmt.Errorf("unexpected type %T", obj)) + } +} + +func (ec *executionContext) __Entity(ctx context.Context, sel ast.SelectionSet, obj fedruntime.Entity) graphql.Marshaler { + switch obj := (obj).(type) { + case nil: + return graphql.Null + case model.Article: + return ec._Article(ctx, sel, &obj) + case *model.Article: + if obj == nil { + return graphql.Null + } + return ec._Article(ctx, sel, obj) + case model.Viewer: + return ec._Viewer(ctx, sel, &obj) + case *model.Viewer: + if obj == nil { + return graphql.Null + } + return ec._Viewer(ctx, sel, obj) + case model.Venue: + return ec._Venue(ctx, sel, &obj) + case *model.Venue: + if obj == nil { + return graphql.Null + } + return ec._Venue(ctx, sel, obj) + case model.UserProfile: + return ec._UserProfile(ctx, sel, &obj) + case *model.UserProfile: + if obj == nil { + return graphql.Null + } + return ec._UserProfile(ctx, sel, obj) + case model.Metric: + return ec._Metric(ctx, sel, &obj) + case *model.Metric: + if obj == nil { + return graphql.Null + } + return ec._Metric(ctx, sel, obj) + case model.Listing: + return ec._Listing(ctx, sel, &obj) + case *model.Listing: + if obj == nil { + return graphql.Null + } + return ec._Listing(ctx, sel, obj) + case model.Catalog: + return ec._Catalog(ctx, sel, &obj) + case *model.Catalog: + if obj == nil { + return graphql.Null + } + return ec._Catalog(ctx, sel, obj) + default: + panic(fmt.Errorf("unexpected type %T", obj)) + } +} + +// endregion ************************** interface.gotpl *************************** + +// region **************************** object.gotpl **************************** + +var addressImplementors = []string{"Address"} + +func (ec *executionContext) _Address(ctx context.Context, sel ast.SelectionSet, obj *model.Address) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, addressImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Address") + case "id": + out.Values[i] = ec._Address_id(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 + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var articleImplementors = []string{"Article", "Personalized", "_Entity"} + +func (ec *executionContext) _Article(ctx context.Context, sel ast.SelectionSet, obj *model.Article) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, articleImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Article") + case "id": + out.Values[i] = ec._Article_id(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "slug": + out.Values[i] = ec._Article_slug(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "title": + out.Values[i] = ec._Article_title(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "body": + out.Values[i] = ec._Article_body(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "authorName": + out.Values[i] = ec._Article_authorName(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "publishedAt": + out.Values[i] = ec._Article_publishedAt(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "tags": + out.Values[i] = ec._Article_tags(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 + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var catalogImplementors = []string{"Catalog", "_Entity"} + +func (ec *executionContext) _Catalog(ctx context.Context, sel ast.SelectionSet, obj *model.Catalog) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, catalogImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Catalog") + case "id": + out.Values[i] = ec._Catalog_id(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "name": + out.Values[i] = ec._Catalog_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "category": + out.Values[i] = ec._Catalog_category(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "itemCount": + out.Values[i] = ec._Catalog_itemCount(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 + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var entityImplementors = []string{"Entity"} + +func (ec *executionContext) _Entity(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, entityImplementors) + ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ + Object: "Entity", + }) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ + Object: field.Name, + Field: field, + }) + + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Entity") + case "findArticleByID": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Entity_findArticleByID(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "findArticleBySlug": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Entity_findArticleBySlug(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "findCatalogByID": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Entity_findCatalogByID(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "findListingBySellerIDAndSku": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Entity_findListingBySellerIDAndSku(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "findMetricByID": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Entity_findMetricByID(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "findPersonalizedByID": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Entity_findPersonalizedByID(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "findUserProfileByID": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Entity_findUserProfileByID(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "findVenueByAddressID": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Entity_findVenueByAddressID(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "findViewerByID": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Entity_findViewerByID(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var listingImplementors = []string{"Listing", "_Entity"} + +func (ec *executionContext) _Listing(ctx context.Context, sel ast.SelectionSet, obj *model.Listing) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, listingImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Listing") + case "sellerId": + out.Values[i] = ec._Listing_sellerId(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "sku": + out.Values[i] = ec._Listing_sku(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "title": + out.Values[i] = ec._Listing_title(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "price": + out.Values[i] = ec._Listing_price(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "currency": + out.Values[i] = ec._Listing_currency(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "inStock": + out.Values[i] = ec._Listing_inStock(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 + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var metricImplementors = []string{"Metric", "_Entity"} + +func (ec *executionContext) _Metric(ctx context.Context, sel ast.SelectionSet, obj *model.Metric) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, metricImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Metric") + case "id": + out.Values[i] = ec._Metric_id(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "name": + out.Values[i] = ec._Metric_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "value": + out.Values[i] = ec._Metric_value(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "unit": + out.Values[i] = ec._Metric_unit(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 + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var mutationImplementors = []string{"Mutation"} + +func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, mutationImplementors) + ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ + Object: "Mutation", + }) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ + Object: field.Name, + Field: field, + }) + + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Mutation") + case "updateArticle": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Mutation_updateArticle(ctx, field) + }) + case "createArticle": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Mutation_createArticle(ctx, field) + }) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "deleteListing": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Mutation_deleteListing(ctx, field) + }) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var queryImplementors = []string{"Query"} + +func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, queryImplementors) + ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ + Object: "Query", + }) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ + Object: field.Name, + Field: field, + }) + + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Query") + case "article": + field := field + + innerFunc := func(ctx context.Context, _ *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_article(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "articles": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_articles(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "articlesByIds": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_articlesByIds(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "articleBySlug": + field := field + + innerFunc := func(ctx context.Context, _ *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_articleBySlug(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "listing": + field := field + + innerFunc := func(ctx context.Context, _ *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_listing(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "listings": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_listings(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "venue": + field := field + + innerFunc := func(ctx context.Context, _ *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_venue(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "venues": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_venues(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "userProfile": + field := field + + innerFunc := func(ctx context.Context, _ *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_userProfile(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "catalog": + field := field + + innerFunc := func(ctx context.Context, _ *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_catalog(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "catalogs": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_catalogs(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "metric": + field := field + + innerFunc := func(ctx context.Context, _ *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_metric(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "_entities": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query__entities(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "_service": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query__service(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "__type": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Query___type(ctx, field) + }) + case "__schema": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Query___schema(ctx, field) + }) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var userProfileImplementors = []string{"UserProfile", "_Entity"} + +func (ec *executionContext) _UserProfile(ctx context.Context, sel ast.SelectionSet, obj *model.UserProfile) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, userProfileImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("UserProfile") + case "id": + out.Values[i] = ec._UserProfile_id(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "username": + out.Values[i] = ec._UserProfile_username(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "email": + out.Values[i] = ec._UserProfile_email(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "role": + out.Values[i] = ec._UserProfile_role(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 + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var venueImplementors = []string{"Venue", "_Entity"} + +func (ec *executionContext) _Venue(ctx context.Context, sel ast.SelectionSet, obj *model.Venue) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, venueImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Venue") + case "address": + out.Values[i] = ec._Venue_address(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "name": + out.Values[i] = ec._Venue_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "capacity": + out.Values[i] = ec._Venue_capacity(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "city": + out.Values[i] = ec._Venue_city(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 + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var viewerImplementors = []string{"Viewer", "_Entity"} + +func (ec *executionContext) _Viewer(ctx context.Context, sel ast.SelectionSet, obj *model.Viewer) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, viewerImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Viewer") + case "id": + out.Values[i] = ec._Viewer_id(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "recommendedArticles": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Viewer_recommendedArticles(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + if field.Deferrable != nil { + dfs, ok := deferred[field.Deferrable.Label] + di := 0 + if ok { + dfs.AddField(field) + di = len(dfs.Values) - 1 + } else { + dfs = graphql.NewFieldSet([]graphql.CollectedField{field}) + deferred[field.Deferrable.Label] = dfs + } + dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler { + return innerFunc(ctx, dfs) + }) + + // don't run the out.Concurrently() call below + out.Values[i] = graphql.Null + continue + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var _ServiceImplementors = []string{"_Service"} + +func (ec *executionContext) __Service(ctx context.Context, sel ast.SelectionSet, obj *fedruntime.Service) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, _ServiceImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("_Service") + case "sdl": + out.Values[i] = ec.__Service_sdl(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __DirectiveImplementors = []string{"__Directive"} + +func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionSet, obj *introspection.Directive) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __DirectiveImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__Directive") + case "name": + out.Values[i] = ec.___Directive_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "description": + out.Values[i] = ec.___Directive_description(ctx, field, obj) + case "isRepeatable": + out.Values[i] = ec.___Directive_isRepeatable(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "locations": + out.Values[i] = ec.___Directive_locations(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "args": + out.Values[i] = ec.___Directive_args(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 + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __EnumValueImplementors = []string{"__EnumValue"} + +func (ec *executionContext) ___EnumValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.EnumValue) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __EnumValueImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__EnumValue") + case "name": + out.Values[i] = ec.___EnumValue_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "description": + out.Values[i] = ec.___EnumValue_description(ctx, field, obj) + case "isDeprecated": + out.Values[i] = ec.___EnumValue_isDeprecated(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "deprecationReason": + out.Values[i] = ec.___EnumValue_deprecationReason(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __FieldImplementors = []string{"__Field"} + +func (ec *executionContext) ___Field(ctx context.Context, sel ast.SelectionSet, obj *introspection.Field) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __FieldImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__Field") + case "name": + out.Values[i] = ec.___Field_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "description": + out.Values[i] = ec.___Field_description(ctx, field, obj) + case "args": + out.Values[i] = ec.___Field_args(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "type": + out.Values[i] = ec.___Field_type(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "isDeprecated": + out.Values[i] = ec.___Field_isDeprecated(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "deprecationReason": + out.Values[i] = ec.___Field_deprecationReason(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __InputValueImplementors = []string{"__InputValue"} + +func (ec *executionContext) ___InputValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.InputValue) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __InputValueImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__InputValue") + case "name": + out.Values[i] = ec.___InputValue_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "description": + out.Values[i] = ec.___InputValue_description(ctx, field, obj) + case "type": + out.Values[i] = ec.___InputValue_type(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "defaultValue": + out.Values[i] = ec.___InputValue_defaultValue(ctx, field, obj) + case "isDeprecated": + out.Values[i] = ec.___InputValue_isDeprecated(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "deprecationReason": + out.Values[i] = ec.___InputValue_deprecationReason(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __SchemaImplementors = []string{"__Schema"} + +func (ec *executionContext) ___Schema(ctx context.Context, sel ast.SelectionSet, obj *introspection.Schema) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __SchemaImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__Schema") + case "description": + out.Values[i] = ec.___Schema_description(ctx, field, obj) + case "types": + out.Values[i] = ec.___Schema_types(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "queryType": + out.Values[i] = ec.___Schema_queryType(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "mutationType": + out.Values[i] = ec.___Schema_mutationType(ctx, field, obj) + case "subscriptionType": + out.Values[i] = ec.___Schema_subscriptionType(ctx, field, obj) + case "directives": + out.Values[i] = ec.___Schema_directives(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 + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __TypeImplementors = []string{"__Type"} + +func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, obj *introspection.Type) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __TypeImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__Type") + case "kind": + out.Values[i] = ec.___Type_kind(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "name": + out.Values[i] = ec.___Type_name(ctx, field, obj) + case "description": + out.Values[i] = ec.___Type_description(ctx, field, obj) + case "specifiedByURL": + out.Values[i] = ec.___Type_specifiedByURL(ctx, field, obj) + case "fields": + out.Values[i] = ec.___Type_fields(ctx, field, obj) + case "interfaces": + out.Values[i] = ec.___Type_interfaces(ctx, field, obj) + case "possibleTypes": + out.Values[i] = ec.___Type_possibleTypes(ctx, field, obj) + case "enumValues": + out.Values[i] = ec.___Type_enumValues(ctx, field, obj) + case "inputFields": + out.Values[i] = ec.___Type_inputFields(ctx, field, obj) + case "ofType": + out.Values[i] = ec.___Type_ofType(ctx, field, obj) + case "isOneOf": + out.Values[i] = ec.___Type_isOneOf(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +// endregion **************************** object.gotpl **************************** + +// region ***************************** type.gotpl ***************************** + +func (ec *executionContext) marshalNAddress2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐAddress(ctx context.Context, sel ast.SelectionSet, v *model.Address) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._Address(ctx, sel, v) +} + +func (ec *executionContext) marshalNArticle2githubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐArticle(ctx context.Context, sel ast.SelectionSet, v model.Article) graphql.Marshaler { + return ec._Article(ctx, sel, &v) +} + +func (ec *executionContext) marshalNArticle2ᚕᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐArticleᚄ(ctx context.Context, sel ast.SelectionSet, v []*model.Article) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalNArticle2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐArticle(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalNArticle2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐArticle(ctx context.Context, sel ast.SelectionSet, v *model.Article) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._Article(ctx, sel, v) +} + +func (ec *executionContext) unmarshalNBoolean2bool(ctx context.Context, v any) (bool, error) { + res, err := graphql.UnmarshalBoolean(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNBoolean2bool(ctx context.Context, sel ast.SelectionSet, v bool) graphql.Marshaler { + _ = sel + res := graphql.MarshalBoolean(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) marshalNCatalog2githubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐCatalog(ctx context.Context, sel ast.SelectionSet, v model.Catalog) graphql.Marshaler { + return ec._Catalog(ctx, sel, &v) +} + +func (ec *executionContext) marshalNCatalog2ᚕᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐCatalogᚄ(ctx context.Context, sel ast.SelectionSet, v []*model.Catalog) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalNCatalog2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐCatalog(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalNCatalog2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐCatalog(ctx context.Context, sel ast.SelectionSet, v *model.Catalog) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._Catalog(ctx, sel, v) +} + +func (ec *executionContext) unmarshalNFieldSet2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNFieldSet2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNFloat2float64(ctx context.Context, v any) (float64, error) { + res, err := graphql.UnmarshalFloatContext(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNFloat2float64(ctx context.Context, sel ast.SelectionSet, v float64) graphql.Marshaler { + _ = sel + res := graphql.MarshalFloatContext(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return graphql.WrapContextMarshaler(ctx, res) +} + +func (ec *executionContext) unmarshalNID2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalID(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNID2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalID(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNID2ᚕstringᚄ(ctx context.Context, v any) ([]string, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNID2string(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalNID2ᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v []string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNID2string(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalNInt2int(ctx context.Context, v any) (int, error) { + res, err := graphql.UnmarshalInt(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNInt2int(ctx context.Context, sel ast.SelectionSet, v int) graphql.Marshaler { + _ = sel + res := graphql.MarshalInt(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) marshalNListing2githubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐListing(ctx context.Context, sel ast.SelectionSet, v model.Listing) graphql.Marshaler { + return ec._Listing(ctx, sel, &v) +} + +func (ec *executionContext) marshalNListing2ᚕᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐListingᚄ(ctx context.Context, sel ast.SelectionSet, v []*model.Listing) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalNListing2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐListing(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalNListing2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐListing(ctx context.Context, sel ast.SelectionSet, v *model.Listing) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._Listing(ctx, sel, v) +} + +func (ec *executionContext) unmarshalNListingKey2githubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐListingKey(ctx context.Context, v any) (model.ListingKey, error) { + res, err := ec.unmarshalInputListingKey(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNMetric2githubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐMetric(ctx context.Context, sel ast.SelectionSet, v model.Metric) graphql.Marshaler { + return ec._Metric(ctx, sel, &v) +} + +func (ec *executionContext) marshalNMetric2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐMetric(ctx context.Context, sel ast.SelectionSet, v *model.Metric) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._Metric(ctx, sel, v) +} + +func (ec *executionContext) marshalNPersonalized2githubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐPersonalized(ctx context.Context, sel ast.SelectionSet, v model.Personalized) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._Personalized(ctx, sel, v) +} + +func (ec *executionContext) unmarshalNString2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNString2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNString2ᚕstringᚄ(ctx context.Context, v any) ([]string, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNString2string(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalNString2ᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v []string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNString2string(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalNUserProfile2githubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐUserProfile(ctx context.Context, sel ast.SelectionSet, v model.UserProfile) graphql.Marshaler { + return ec._UserProfile(ctx, sel, &v) +} + +func (ec *executionContext) marshalNUserProfile2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐUserProfile(ctx context.Context, sel ast.SelectionSet, v *model.UserProfile) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._UserProfile(ctx, sel, v) +} + +func (ec *executionContext) marshalNVenue2githubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐVenue(ctx context.Context, sel ast.SelectionSet, v model.Venue) graphql.Marshaler { + return ec._Venue(ctx, sel, &v) +} + +func (ec *executionContext) marshalNVenue2ᚕᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐVenueᚄ(ctx context.Context, sel ast.SelectionSet, v []*model.Venue) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalNVenue2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐVenue(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalNVenue2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐVenue(ctx context.Context, sel ast.SelectionSet, v *model.Venue) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._Venue(ctx, sel, v) +} + +func (ec *executionContext) unmarshalNVenueAddressKey2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐVenueAddressKey(ctx context.Context, v any) (*model.VenueAddressKey, error) { + res, err := ec.unmarshalInputVenueAddressKey(ctx, v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) unmarshalNVenueLocationKey2githubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐVenueLocationKey(ctx context.Context, v any) (model.VenueLocationKey, error) { + res, err := ec.unmarshalInputVenueLocationKey(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNViewer2githubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐViewer(ctx context.Context, sel ast.SelectionSet, v model.Viewer) graphql.Marshaler { + return ec._Viewer(ctx, sel, &v) +} + +func (ec *executionContext) marshalNViewer2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐViewer(ctx context.Context, sel ast.SelectionSet, v *model.Viewer) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._Viewer(ctx, sel, v) +} + +func (ec *executionContext) unmarshalN_Any2map(ctx context.Context, v any) (map[string]any, error) { + res, err := graphql.UnmarshalMap(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalN_Any2map(ctx context.Context, sel ast.SelectionSet, v map[string]any) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + _ = sel + res := graphql.MarshalMap(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalN_Any2ᚕmapᚄ(ctx context.Context, v any) ([]map[string]any, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([]map[string]any, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalN_Any2map(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalN_Any2ᚕmapᚄ(ctx context.Context, sel ast.SelectionSet, v []map[string]any) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalN_Any2map(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalN_Entity2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐEntity(ctx context.Context, sel ast.SelectionSet, v []fedruntime.Entity) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalO_Entity2githubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐEntity(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + return ret +} + +func (ec *executionContext) marshalN_Service2githubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐService(ctx context.Context, sel ast.SelectionSet, v fedruntime.Service) graphql.Marshaler { + return ec.__Service(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__Directive2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirective(ctx context.Context, sel ast.SelectionSet, v introspection.Directive) graphql.Marshaler { + return ec.___Directive(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirectiveᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.Directive) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__Directive2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirective(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalN__DirectiveLocation2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalN__DirectiveLocation2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalN__DirectiveLocation2ᚕstringᚄ(ctx context.Context, v any) ([]string, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalN__DirectiveLocation2string(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalN__DirectiveLocation2ᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v []string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__DirectiveLocation2string(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalN__EnumValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValue(ctx context.Context, sel ast.SelectionSet, v introspection.EnumValue) graphql.Marshaler { + return ec.___EnumValue(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__Field2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐField(ctx context.Context, sel ast.SelectionSet, v introspection.Field) graphql.Marshaler { + return ec.___Field(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__InputValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValue(ctx context.Context, sel ast.SelectionSet, v introspection.InputValue) graphql.Marshaler { + return ec.___InputValue(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.InputValue) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__InputValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValue(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +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) +} + +func (ec *executionContext) marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.Type) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__Type2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx context.Context, sel ast.SelectionSet, v *introspection.Type) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec.___Type(ctx, sel, v) +} + +func (ec *executionContext) unmarshalN__TypeKind2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalN__TypeKind2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNfederation__Policy2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNfederation__Policy2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNfederation__Policy2ᚕstringᚄ(ctx context.Context, v any) ([]string, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNfederation__Policy2string(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalNfederation__Policy2ᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v []string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNfederation__Policy2string(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalNfederation__Policy2ᚕᚕstringᚄ(ctx context.Context, v any) ([][]string, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([][]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNfederation__Policy2ᚕstringᚄ(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalNfederation__Policy2ᚕᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v [][]string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNfederation__Policy2ᚕstringᚄ(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalNfederation__Scope2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNfederation__Scope2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNfederation__Scope2ᚕstringᚄ(ctx context.Context, v any) ([]string, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNfederation__Scope2string(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalNfederation__Scope2ᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v []string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNfederation__Scope2string(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalNfederation__Scope2ᚕᚕstringᚄ(ctx context.Context, v any) ([][]string, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([][]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNfederation__Scope2ᚕstringᚄ(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalNfederation__Scope2ᚕᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v [][]string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNfederation__Scope2ᚕstringᚄ(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalOArticle2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐArticle(ctx context.Context, sel ast.SelectionSet, v *model.Article) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._Article(ctx, sel, v) +} + +func (ec *executionContext) unmarshalOBoolean2bool(ctx context.Context, v any) (bool, error) { + res, err := graphql.UnmarshalBoolean(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOBoolean2bool(ctx context.Context, sel ast.SelectionSet, v bool) graphql.Marshaler { + _ = sel + _ = ctx + res := graphql.MarshalBoolean(v) + return res +} + +func (ec *executionContext) unmarshalOBoolean2ᚖbool(ctx context.Context, v any) (*bool, error) { + if v == nil { + return nil, nil + } + res, err := graphql.UnmarshalBoolean(v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOBoolean2ᚖbool(ctx context.Context, sel ast.SelectionSet, v *bool) graphql.Marshaler { + if v == nil { + return graphql.Null + } + _ = sel + _ = ctx + res := graphql.MarshalBoolean(*v) + return res +} + +func (ec *executionContext) marshalOCatalog2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐCatalog(ctx context.Context, sel ast.SelectionSet, v *model.Catalog) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._Catalog(ctx, sel, v) +} + +func (ec *executionContext) unmarshalOInt2ᚖint(ctx context.Context, v any) (*int, error) { + if v == nil { + return nil, nil + } + res, err := graphql.UnmarshalInt(v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOInt2ᚖint(ctx context.Context, sel ast.SelectionSet, v *int) graphql.Marshaler { + if v == nil { + return graphql.Null + } + _ = sel + _ = ctx + res := graphql.MarshalInt(*v) + return res +} + +func (ec *executionContext) marshalOListing2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐListing(ctx context.Context, sel ast.SelectionSet, v *model.Listing) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._Listing(ctx, sel, v) +} + +func (ec *executionContext) marshalOMetric2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐMetric(ctx context.Context, sel ast.SelectionSet, v *model.Metric) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._Metric(ctx, sel, v) +} + +func (ec *executionContext) unmarshalOString2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOString2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + _ = ctx + res := graphql.MarshalString(v) + return res +} + +func (ec *executionContext) unmarshalOString2ᚕstringᚄ(ctx context.Context, v any) ([]string, error) { + if v == nil { + return nil, nil + } + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNString2string(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalOString2ᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v []string) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNString2string(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalOString2ᚖstring(ctx context.Context, v any) (*string, error) { + if v == nil { + return nil, nil + } + res, err := graphql.UnmarshalString(v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOString2ᚖstring(ctx context.Context, sel ast.SelectionSet, v *string) graphql.Marshaler { + if v == nil { + return graphql.Null + } + _ = sel + _ = ctx + res := graphql.MarshalString(*v) + return res +} + +func (ec *executionContext) marshalOUserProfile2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐUserProfile(ctx context.Context, sel ast.SelectionSet, v *model.UserProfile) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._UserProfile(ctx, sel, v) +} + +func (ec *executionContext) marshalOVenue2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraphᚋsubgraphᚋmodelᚐVenue(ctx context.Context, sel ast.SelectionSet, v *model.Venue) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._Venue(ctx, sel, v) +} + +func (ec *executionContext) marshalO_Entity2githubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐEntity(ctx context.Context, sel ast.SelectionSet, v fedruntime.Entity) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec.__Entity(ctx, sel, v) +} + +func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.EnumValue) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__EnumValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValue(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐFieldᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.Field) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__Field2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐField(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.InputValue) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__InputValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValue(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + 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 + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__Type2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +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 + } + return ec.___Type(ctx, sel, v) +} + +// endregion ***************************** type.gotpl ***************************** diff --git a/demo/pkg/subgraphs/cachegraph/subgraph/model/models_gen.go b/demo/pkg/subgraphs/cachegraph/subgraph/model/models_gen.go new file mode 100644 index 0000000000..f5cc949490 --- /dev/null +++ b/demo/pkg/subgraphs/cachegraph/subgraph/model/models_gen.go @@ -0,0 +1,104 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package model + +type Personalized interface { + IsEntity() + IsPersonalized() + GetID() string +} + +type Address struct { + ID string `json:"id"` +} + +type Article struct { + ID string `json:"id"` + Slug string `json:"slug"` + Title string `json:"title"` + Body string `json:"body"` + AuthorName string `json:"authorName"` + PublishedAt string `json:"publishedAt"` + Tags []string `json:"tags"` +} + +func (Article) IsPersonalized() {} +func (this Article) GetID() string { return this.ID } + +func (Article) IsEntity() {} + +// Partial cache load: when some entities are cached and others aren't, only the missing ones are fetched +type Catalog struct { + ID string `json:"id"` + Name string `json:"name"` + Category string `json:"category"` + ItemCount int `json:"itemCount"` +} + +func (Catalog) IsEntity() {} + +type Listing struct { + SellerID string `json:"sellerId"` + Sku string `json:"sku"` + Title string `json:"title"` + Price float64 `json:"price"` + Currency string `json:"currency"` + InStock bool `json:"inStock"` +} + +func (Listing) IsEntity() {} + +type ListingKey struct { + SellerID string `json:"sellerId"` + Sku string `json:"sku"` +} + +// Shadow mode: always fetches from subgraph but compares with cache for staleness detection +type Metric struct { + ID string `json:"id"` + Name string `json:"name"` + Value float64 `json:"value"` + Unit string `json:"unit"` +} + +func (Metric) IsEntity() {} + +type Mutation struct { +} + +type Query struct { +} + +// Per-user caching: includeHeaders makes the cache key include a hash of forwarded headers (e.g. Authorization) +type UserProfile struct { + ID string `json:"id"` + Username string `json:"username"` + Email string `json:"email"` + Role string `json:"role"` +} + +func (UserProfile) IsEntity() {} + +type Venue struct { + Address *Address `json:"address"` + Name string `json:"name"` + Capacity int `json:"capacity"` + City string `json:"city"` +} + +func (Venue) IsEntity() {} + +type VenueAddressKey struct { + ID string `json:"id"` +} + +type VenueLocationKey struct { + Address *VenueAddressKey `json:"address"` +} + +type Viewer struct { + ID string `json:"id"` + RecommendedArticles []*Article `json:"recommendedArticles"` +} + +func (Viewer) IsEntity() {} diff --git a/demo/pkg/subgraphs/cachegraph/subgraph/resolver.go b/demo/pkg/subgraphs/cachegraph/subgraph/resolver.go new file mode 100644 index 0000000000..ad863e02b2 --- /dev/null +++ b/demo/pkg/subgraphs/cachegraph/subgraph/resolver.go @@ -0,0 +1,22 @@ +package subgraph + +// This file will not be regenerated automatically. +// +// It serves as dependency injection for your app, add any dependencies you require here. + +// Resolver is the root gqlgen resolver. Each Resolver owns its own data stores +// so mutations are isolated per subgraph server instance and safe under +// concurrent request handling. +type Resolver struct { + articles *articleStore + listings *listingStore +} + +// NewResolver creates a Resolver with fresh, independent article and listing +// stores seeded from the default data. +func NewResolver() *Resolver { + return &Resolver{ + articles: newArticleStore(), + listings: newListingStore(), + } +} diff --git a/demo/pkg/subgraphs/cachegraph/subgraph/schema.graphqls b/demo/pkg/subgraphs/cachegraph/subgraph/schema.graphqls new file mode 100644 index 0000000000..7c2e3f31d5 --- /dev/null +++ b/demo/pkg/subgraphs/cachegraph/subgraph/schema.graphqls @@ -0,0 +1,138 @@ +extend schema + @link( + url: "https://specs.apollo.dev/federation/v2.5" + import: ["@key"] + ) + +directive @openfed__entityCache( + maxAge: Int! + includeHeaders: Boolean = false + partialCacheLoad: Boolean = false + shadowMode: Boolean = false +) on OBJECT + +directive @openfed__queryCache( + maxAge: Int! + includeHeaders: Boolean = false + shadowMode: Boolean = false +) on FIELD_DEFINITION + +directive @openfed__cacheInvalidate on FIELD_DEFINITION + +directive @openfed__cachePopulate(maxAge: Int) on FIELD_DEFINITION + +directive @openfed__is(fields: String!) on ARGUMENT_DEFINITION + +type Query { + """Simple key lookup""" + article(id: ID!): Article @openfed__queryCache(maxAge: 120) + """List query""" + articles: [Article!]! @openfed__queryCache(maxAge: 120) + """Batch lookup with @openfed__is""" + articlesByIds(ids: [ID!]! @openfed__is(fields: "id")): [Article!]! @openfed__queryCache(maxAge: 120) + """Argument remapping via @openfed__is""" + articleBySlug(slug: String! @openfed__is(fields: "slug")): Article @openfed__queryCache(maxAge: 120) + + """Composite key lookup via input object with @openfed__is""" + listing(key: ListingKey! @openfed__is(fields: "sellerId sku")): Listing @openfed__queryCache(maxAge: 60) + """List of all listings""" + listings: [Listing!]! @openfed__queryCache(maxAge: 60) + + """Nested key lookup with @openfed__is and input object""" + venue(location: VenueLocationKey! @openfed__is(fields: "address { id }")): Venue @openfed__queryCache(maxAge: 180) + """List of all venues""" + venues: [Venue!]! @openfed__queryCache(maxAge: 180) + + """Per-user profile (cache varies by Authorization header)""" + userProfile(id: ID!): UserProfile @openfed__queryCache(maxAge: 60, includeHeaders: true) + + """Single catalog entry""" + catalog(id: ID!): Catalog @openfed__queryCache(maxAge: 120) + """All catalog entries (for partial cache load testing)""" + catalogs: [Catalog!]! @openfed__queryCache(maxAge: 120) + + """Single metric (shadow mode - always fetches from subgraph, compares with cache)""" + metric(id: ID!): Metric @openfed__queryCache(maxAge: 300, shadowMode: true) +} + +type Mutation { + updateArticle(id: ID!, title: String!): Article @openfed__cacheInvalidate + createArticle(title: String!, body: String!, authorName: String!): Article! @openfed__cachePopulate(maxAge: 30) + deleteListing(key: ListingKey!): Listing @openfed__cacheInvalidate +} + +"""Per-user caching: includeHeaders makes the cache key include a hash of forwarded headers (e.g. Authorization)""" +type UserProfile @key(fields: "id") @openfed__entityCache(maxAge: 60, includeHeaders: true) { + id: ID! + username: String! + email: String! + role: String! +} + +"""Partial cache load: when some entities are cached and others aren't, only the missing ones are fetched""" +type Catalog @key(fields: "id") @openfed__entityCache(maxAge: 120, partialCacheLoad: true) { + id: ID! + name: String! + category: String! + itemCount: Int! +} + +"""Shadow mode: always fetches from subgraph but compares with cache for staleness detection""" +type Metric @key(fields: "id") @openfed__entityCache(maxAge: 300, shadowMode: true) { + id: ID! + name: String! + value: Float! + unit: String! +} + +input ListingKey { + sellerId: ID! + sku: String! +} + +input VenueLocationKey { + address: VenueAddressKey! +} + +input VenueAddressKey { + id: ID! +} + +interface Personalized @key(fields: "id") { + id: ID! +} + +type Viewer @key(fields: "id") { + id: ID! + recommendedArticles: [Article!]! +} + +type Article implements Personalized @key(fields: "id") @key(fields: "slug") @openfed__entityCache(maxAge: 120) { + id: ID! + slug: String! + title: String! + body: String! + authorName: String! + publishedAt: String! + tags: [String!]! +} + +type Listing @key(fields: "sellerId sku") @openfed__entityCache(maxAge: 60) { + sellerId: ID! + sku: String! + title: String! + price: Float! + currency: String! + inStock: Boolean! +} + +type Address { + id: ID! +} + +type Venue @key(fields: "address { id }") @openfed__entityCache(maxAge: 180) { + address: Address! + name: String! + capacity: Int! + city: String! +} diff --git a/demo/pkg/subgraphs/cachegraph/subgraph/schema.resolvers.go b/demo/pkg/subgraphs/cachegraph/subgraph/schema.resolvers.go new file mode 100644 index 0000000000..94bb2c59ee --- /dev/null +++ b/demo/pkg/subgraphs/cachegraph/subgraph/schema.resolvers.go @@ -0,0 +1,121 @@ +package subgraph + +// 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.76 + +import ( + "context" + "fmt" + + "github.com/wundergraph/cosmo/demo/pkg/injector" + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachegraph/subgraph/generated" + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachegraph/subgraph/model" +) + +// UpdateArticle is the resolver for the updateArticle field. +func (r *mutationResolver) UpdateArticle(ctx context.Context, id string, title string) (*model.Article, error) { + return r.articles.update(id, title), nil +} + +// CreateArticle is the resolver for the createArticle field. +func (r *mutationResolver) CreateArticle(ctx context.Context, title string, body string, authorName string) (*model.Article, error) { + return r.articles.create(title, body, authorName), nil +} + +// DeleteListing is the resolver for the deleteListing field. +func (r *mutationResolver) DeleteListing(ctx context.Context, key model.ListingKey) (*model.Listing, error) { + return r.listings.delete(key.SellerID, key.Sku), nil +} + +// Article is the resolver for the article field. +func (r *queryResolver) Article(ctx context.Context, id string) (*model.Article, error) { + return r.articles.find(id), nil +} + +// Articles is the resolver for the articles field. +func (r *queryResolver) Articles(ctx context.Context) ([]*model.Article, error) { + return r.articles.all(), nil +} + +// ArticlesByIds is the resolver for the articlesByIds field. +func (r *queryResolver) ArticlesByIds(ctx context.Context, ids []string) ([]*model.Article, error) { + return r.articles.byIDs(ids), nil +} + +// ArticleBySlug is the resolver for the articleBySlug field. +func (r *queryResolver) ArticleBySlug(ctx context.Context, slug string) (*model.Article, error) { + return r.articles.findBySlug(slug), nil +} + +// Listing is the resolver for the listing field. +func (r *queryResolver) Listing(ctx context.Context, key model.ListingKey) (*model.Listing, error) { + return r.listings.get(key.SellerID, key.Sku), nil +} + +// Listings is the resolver for the listings field. +func (r *queryResolver) Listings(ctx context.Context) ([]*model.Listing, error) { + return r.listings.all(), nil +} + +// Venue is the resolver for the venue field. +func (r *queryResolver) Venue(ctx context.Context, location model.VenueLocationKey) (*model.Venue, error) { + if location.Address == nil { + return nil, fmt.Errorf("location.address is required") + } + return venuesData[location.Address.ID], nil +} + +// Venues is the resolver for the venues field. +func (r *queryResolver) Venues(ctx context.Context) ([]*model.Venue, error) { + return allVenues(), nil +} + +// UserProfile is the resolver for the userProfile field. +// The schema declares @openfed__queryCache(includeHeaders: true) so the cache +// key varies by Authorization header. Mirror that on the response side: when a +// known bearer token is present, return that viewer's profile rather than the +// id-based lookup. Without this, different headers would produce identical +// responses and the cache-explorer + benchmark suites could not detect a +// header-variance regression. +func (r *queryResolver) UserProfile(ctx context.Context, id string) (*model.UserProfile, error) { + if hdr := injector.Header(ctx); hdr != nil { + if viewerID, ok := userProfileIDByAuthorizationToken[hdr.Get("Authorization")]; ok { + return userProfilesData[viewerID], nil + } + } + return userProfilesData[id], nil +} + +// Catalog is the resolver for the catalog field. +func (r *queryResolver) Catalog(ctx context.Context, id string) (*model.Catalog, error) { + return catalogsData[id], nil +} + +// Catalogs is the resolver for the catalogs field. +func (r *queryResolver) Catalogs(ctx context.Context) ([]*model.Catalog, error) { + return allCatalogs(), nil +} + +// Metric is the resolver for the metric field. +func (r *queryResolver) Metric(ctx context.Context, id string) (*model.Metric, error) { + return metricsData[id], nil +} + +// RecommendedArticles is the resolver for the recommendedArticles field. +func (r *viewerResolver) RecommendedArticles(ctx context.Context, obj *model.Viewer) ([]*model.Article, error) { + return r.articles.recommendedForViewer(obj.ID), nil +} + +// Mutation returns generated.MutationResolver implementation. +func (r *Resolver) Mutation() generated.MutationResolver { return &mutationResolver{r} } + +// Query returns generated.QueryResolver implementation. +func (r *Resolver) Query() generated.QueryResolver { return &queryResolver{r} } + +// Viewer returns generated.ViewerResolver implementation. +func (r *Resolver) Viewer() generated.ViewerResolver { return &viewerResolver{r} } + +type mutationResolver struct{ *Resolver } +type queryResolver struct{ *Resolver } +type viewerResolver struct{ *Resolver } diff --git a/demo/pkg/subgraphs/cachegraph_ext/cachegraph_ext.go b/demo/pkg/subgraphs/cachegraph_ext/cachegraph_ext.go new file mode 100644 index 0000000000..595a0cb998 --- /dev/null +++ b/demo/pkg/subgraphs/cachegraph_ext/cachegraph_ext.go @@ -0,0 +1,12 @@ +package cachegraph_ext + +import ( + "github.com/99designs/gqlgen/graphql" + + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachegraph_ext/subgraph" + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachegraph_ext/subgraph/generated" +) + +func NewSchema() graphql.ExecutableSchema { + return generated.NewExecutableSchema(generated.Config{Resolvers: &subgraph.Resolver{}}) +} diff --git a/demo/pkg/subgraphs/cachegraph_ext/generate.go b/demo/pkg/subgraphs/cachegraph_ext/generate.go new file mode 100644 index 0000000000..6c6a50910a --- /dev/null +++ b/demo/pkg/subgraphs/cachegraph_ext/generate.go @@ -0,0 +1,2 @@ +//go:generate go run github.com/99designs/gqlgen generate +package cachegraph_ext diff --git a/demo/pkg/subgraphs/cachegraph_ext/gqlgen.yml b/demo/pkg/subgraphs/cachegraph_ext/gqlgen.yml new file mode 100644 index 0000000000..10fdc955ab --- /dev/null +++ b/demo/pkg/subgraphs/cachegraph_ext/gqlgen.yml @@ -0,0 +1,45 @@ +schema: + - subgraph/*.graphqls + +exec: + filename: subgraph/generated/generated.go + package: generated + +federation: + filename: subgraph/generated/federation.go + package: generated + version: 2 + options: + explicit_requires: true + +model: + filename: subgraph/model/models_gen.go + package: model + +resolver: + layout: follow-schema + dir: subgraph + package: subgraph + +directives: + openfed__entityCache: + skip_runtime: true + +models: + Article: + fields: + relatedArticles: + resolver: true + personalizedRecommendation: + resolver: true + ID: + model: + - github.com/99designs/gqlgen/graphql.ID + - github.com/99designs/gqlgen/graphql.Int + - github.com/99designs/gqlgen/graphql.Int64 + - github.com/99designs/gqlgen/graphql.Int32 + Int: + model: + - github.com/99designs/gqlgen/graphql.Int + - github.com/99designs/gqlgen/graphql.Int64 + - github.com/99designs/gqlgen/graphql.Int32 diff --git a/demo/pkg/subgraphs/cachegraph_ext/subgraph/data.go b/demo/pkg/subgraphs/cachegraph_ext/subgraph/data.go new file mode 100644 index 0000000000..5d70108ab0 --- /dev/null +++ b/demo/pkg/subgraphs/cachegraph_ext/subgraph/data.go @@ -0,0 +1,53 @@ +package subgraph + +import "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachegraph_ext/subgraph/model" + +var articleExtensions = map[string]*articleExtData{ + "1": { + ViewCount: 12453, + Rating: 4.7, + ReviewSummary: "Excellent introduction to caching concepts. Clear examples.", + RelatedIDs: []string{"3", "4"}, + }, + "2": { + ViewCount: 8921, + Rating: 4.3, + ReviewSummary: "Deep dive into federation. Could use more diagrams.", + RelatedIDs: []string{"1", "3"}, + }, + "3": { + ViewCount: 15678, + Rating: 4.9, + ReviewSummary: "The definitive guide to cache invalidation. Must read.", + RelatedIDs: []string{"1", "4"}, + }, + "4": { + ViewCount: 6234, + Rating: 4.1, + ReviewSummary: "Practical tips for production caching. Solid advice.", + RelatedIDs: []string{"1", "2"}, + }, +} + +type articleExtData struct { + ViewCount int + Rating float64 + ReviewSummary string + RelatedIDs []string +} + +// Catalog extension data — description and lastUpdated from this subgraph +var catalogExtensions = map[string]*model.Catalog{ + "c1": {ID: "c1", Description: "Consumer electronics, gadgets, and accessories.", LastUpdated: "2025-03-15T08:00:00Z"}, + "c2": {ID: "c2", Description: "Fiction, non-fiction, technical books, and audiobooks.", LastUpdated: "2025-03-20T12:00:00Z"}, + "c3": {ID: "c3", Description: "Men's, women's, and children's apparel.", LastUpdated: "2025-03-25T16:00:00Z"}, +} + +func toArticle(id string, ext *articleExtData) *model.Article { + return &model.Article{ + ID: id, + ViewCount: ext.ViewCount, + Rating: ext.Rating, + ReviewSummary: ext.ReviewSummary, + } +} diff --git a/demo/pkg/subgraphs/cachegraph_ext/subgraph/entity.resolvers.go b/demo/pkg/subgraphs/cachegraph_ext/subgraph/entity.resolvers.go new file mode 100644 index 0000000000..092562c423 --- /dev/null +++ b/demo/pkg/subgraphs/cachegraph_ext/subgraph/entity.resolvers.go @@ -0,0 +1,38 @@ +package subgraph + +// 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.76 + +import ( + "context" + + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachegraph_ext/subgraph/generated" + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachegraph_ext/subgraph/model" +) + +// FindArticleByID is the resolver for the findArticleByID field. +func (r *entityResolver) FindArticleByID(ctx context.Context, id string) (*model.Article, error) { + ext := articleExtensions[id] + if ext == nil { + return nil, nil + } + return toArticle(id, ext), nil +} + +// FindCatalogByID is the resolver for the findCatalogByID field. +func (r *entityResolver) FindCatalogByID(ctx context.Context, id string) (*model.Catalog, error) { + return catalogExtensions[id], nil +} + +// FindViewerByID is the resolver for the findViewerByID field. +func (r *entityResolver) FindViewerByID(ctx context.Context, id string) (*model.Viewer, error) { + // cachegraph-ext doesn't own Viewer data — this is resolved by the viewer subgraph. + // Return nil to indicate this subgraph can't resolve this entity. + return nil, nil +} + +// Entity returns generated.EntityResolver implementation. +func (r *Resolver) Entity() generated.EntityResolver { return &entityResolver{r} } + +type entityResolver struct{ *Resolver } diff --git a/demo/pkg/subgraphs/cachegraph_ext/subgraph/generated/federation.go b/demo/pkg/subgraphs/cachegraph_ext/subgraph/generated/federation.go new file mode 100644 index 0000000000..9b0fe72594 --- /dev/null +++ b/demo/pkg/subgraphs/cachegraph_ext/subgraph/generated/federation.go @@ -0,0 +1,345 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package generated + +import ( + "context" + "errors" + "fmt" + "strings" + "sync" + + "github.com/99designs/gqlgen/plugin/federation/fedruntime" +) + +var ( + ErrUnknownType = errors.New("unknown type") + ErrTypeNotFound = errors.New("type not found") +) + +func (ec *executionContext) __resolve__service(ctx context.Context) (fedruntime.Service, error) { + if ec.DisableIntrospection { + return fedruntime.Service{}, errors.New("federated introspection disabled") + } + + var sdl []string + + for _, src := range sources { + if src.BuiltIn { + continue + } + sdl = append(sdl, src.Input) + } + + return fedruntime.Service{ + SDL: strings.Join(sdl, "\n"), + }, nil +} + +func (ec *executionContext) __resolve_entities(ctx context.Context, representations []map[string]any) []fedruntime.Entity { + list := make([]fedruntime.Entity, len(representations)) + + repsMap := ec.buildRepresentationGroups(ctx, representations) + + switch len(repsMap) { + case 0: + return list + case 1: + for typeName, reps := range repsMap { + ec.resolveEntityGroup(ctx, typeName, reps, list) + } + return list + default: + var g sync.WaitGroup + g.Add(len(repsMap)) + for typeName, reps := range repsMap { + go func(typeName string, reps []EntityWithIndex) { + ec.resolveEntityGroup(ctx, typeName, reps, list) + g.Done() + }(typeName, reps) + } + g.Wait() + return list + } +} + +type EntityWithIndex struct { + // The index in the original representation array + index int + entity EntityRepresentation +} + +// EntityRepresentation is the JSON representation of an entity sent by the Router +// used as the inputs for us to resolve. +// +// We make it a map because we know the top level JSON is always an object. +type EntityRepresentation map[string]any + +// We group entities by typename so that we can parallelize their resolution. +// This is particularly helpful when there are entity groups in multi mode. +func (ec *executionContext) buildRepresentationGroups( + ctx context.Context, + representations []map[string]any, +) map[string][]EntityWithIndex { + repsMap := make(map[string][]EntityWithIndex) + for i, rep := range representations { + typeName, ok := rep["__typename"].(string) + if !ok { + // If there is no __typename, we just skip the representation; + // we just won't be resolving these unknown types. + ec.Error(ctx, errors.New("__typename must be an existing string")) + continue + } + + repsMap[typeName] = append(repsMap[typeName], EntityWithIndex{ + index: i, + entity: rep, + }) + } + + return repsMap +} + +func (ec *executionContext) resolveEntityGroup( + ctx context.Context, + typeName string, + reps []EntityWithIndex, + list []fedruntime.Entity, +) { + if isMulti(typeName) { + err := ec.resolveManyEntities(ctx, typeName, reps, list) + if err != nil { + ec.Error(ctx, err) + } + } else { + // if there are multiple entities to resolve, parallelize (similar to + // graphql.FieldSet.Dispatch) + var e sync.WaitGroup + e.Add(len(reps)) + for i, rep := range reps { + i, rep := i, rep + go func(i int, rep EntityWithIndex) { + entity, err := ec.resolveEntity(ctx, typeName, rep.entity) + if err != nil { + ec.Error(ctx, err) + } else { + list[rep.index] = entity + } + e.Done() + }(i, rep) + } + e.Wait() + } +} + +func isMulti(typeName string) bool { + switch typeName { + default: + return false + } +} + +func (ec *executionContext) resolveEntity( + ctx context.Context, + typeName string, + rep EntityRepresentation, +) (e fedruntime.Entity, err error) { + // we need to do our own panic handling, because we may be called in a + // goroutine, where the usual panic handling can't catch us + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + } + }() + + switch typeName { + case "Article": + resolverName, err := entityResolverNameForArticle(ctx, rep) + if err != nil { + return nil, fmt.Errorf(`finding resolver for Entity "Article": %w`, err) + } + switch resolverName { + + case "findArticleByID": + id0, err := ec.unmarshalNID2string(ctx, rep["id"]) + if err != nil { + return nil, fmt.Errorf(`unmarshalling param 0 for findArticleByID(): %w`, err) + } + entity, err := ec.resolvers.Entity().FindArticleByID(ctx, id0) + if err != nil { + return nil, fmt.Errorf(`resolving Entity "Article": %w`, err) + } + err = ec.PopulateArticleRequires(ctx, entity, rep) + if err != nil { + return nil, fmt.Errorf(`populating requires for Entity "Article": %w`, err) + } + return entity, nil + } + case "Catalog": + resolverName, err := entityResolverNameForCatalog(ctx, rep) + if err != nil { + return nil, fmt.Errorf(`finding resolver for Entity "Catalog": %w`, err) + } + switch resolverName { + + case "findCatalogByID": + id0, err := ec.unmarshalNID2string(ctx, rep["id"]) + if err != nil { + return nil, fmt.Errorf(`unmarshalling param 0 for findCatalogByID(): %w`, err) + } + entity, err := ec.resolvers.Entity().FindCatalogByID(ctx, id0) + if err != nil { + return nil, fmt.Errorf(`resolving Entity "Catalog": %w`, err) + } + + return entity, nil + } + case "Viewer": + resolverName, err := entityResolverNameForViewer(ctx, rep) + if err != nil { + return nil, fmt.Errorf(`finding resolver for Entity "Viewer": %w`, err) + } + switch resolverName { + + case "findViewerByID": + id0, err := ec.unmarshalNID2string(ctx, rep["id"]) + if err != nil { + return nil, fmt.Errorf(`unmarshalling param 0 for findViewerByID(): %w`, err) + } + entity, err := ec.resolvers.Entity().FindViewerByID(ctx, id0) + if err != nil { + return nil, fmt.Errorf(`resolving Entity "Viewer": %w`, err) + } + + return entity, nil + } + + } + return nil, fmt.Errorf("%w: %s", ErrUnknownType, typeName) +} + +func (ec *executionContext) resolveManyEntities( + ctx context.Context, + typeName string, + reps []EntityWithIndex, + list []fedruntime.Entity, +) (err error) { + // we need to do our own panic handling, because we may be called in a + // goroutine, where the usual panic handling can't catch us + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + } + }() + + switch typeName { + + default: + return errors.New("unknown type: " + typeName) + } +} + +func entityResolverNameForArticle(ctx context.Context, rep EntityRepresentation) (string, error) { + // we collect errors because a later entity resolver may work fine + // when an entity has multiple keys + entityResolverErrs := []error{} + for { + var ( + m EntityRepresentation + val any + ok bool + ) + _ = val + // if all of the KeyFields values for this resolver are null, + // we shouldn't use use it + allNull := true + m = rep + val, ok = m["id"] + if !ok { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to missing Key Field \"id\" for Article", ErrTypeNotFound)) + break + } + if allNull { + allNull = val == nil + } + if allNull { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to all null value KeyFields for Article", ErrTypeNotFound)) + break + } + return "findArticleByID", nil + } + return "", fmt.Errorf("%w for Article due to %v", ErrTypeNotFound, + errors.Join(entityResolverErrs...).Error()) +} + +func entityResolverNameForCatalog(ctx context.Context, rep EntityRepresentation) (string, error) { + // we collect errors because a later entity resolver may work fine + // when an entity has multiple keys + entityResolverErrs := []error{} + for { + var ( + m EntityRepresentation + val any + ok bool + ) + _ = val + // if all of the KeyFields values for this resolver are null, + // we shouldn't use use it + allNull := true + m = rep + val, ok = m["id"] + if !ok { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to missing Key Field \"id\" for Catalog", ErrTypeNotFound)) + break + } + if allNull { + allNull = val == nil + } + if allNull { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to all null value KeyFields for Catalog", ErrTypeNotFound)) + break + } + return "findCatalogByID", nil + } + return "", fmt.Errorf("%w for Catalog due to %v", ErrTypeNotFound, + errors.Join(entityResolverErrs...).Error()) +} + +func entityResolverNameForViewer(ctx context.Context, rep EntityRepresentation) (string, error) { + // we collect errors because a later entity resolver may work fine + // when an entity has multiple keys + entityResolverErrs := []error{} + for { + var ( + m EntityRepresentation + val any + ok bool + ) + _ = val + // if all of the KeyFields values for this resolver are null, + // we shouldn't use use it + allNull := true + m = rep + val, ok = m["id"] + if !ok { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to missing Key Field \"id\" for Viewer", ErrTypeNotFound)) + break + } + if allNull { + allNull = val == nil + } + if allNull { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to all null value KeyFields for Viewer", ErrTypeNotFound)) + break + } + return "findViewerByID", nil + } + return "", fmt.Errorf("%w for Viewer due to %v", ErrTypeNotFound, + errors.Join(entityResolverErrs...).Error()) +} diff --git a/demo/pkg/subgraphs/cachegraph_ext/subgraph/generated/federation.requires.go b/demo/pkg/subgraphs/cachegraph_ext/subgraph/generated/federation.requires.go new file mode 100644 index 0000000000..cf9363a758 --- /dev/null +++ b/demo/pkg/subgraphs/cachegraph_ext/subgraph/generated/federation.requires.go @@ -0,0 +1,28 @@ +package generated + +import ( + "context" + + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachegraph_ext/subgraph/model" +) + +// PopulateArticleRequires is the requires populator for the Article entity. +func (ec *executionContext) PopulateArticleRequires(ctx context.Context, entity *model.Article, reps map[string]any) error { + cv, ok := reps["currentViewer"] + if !ok || cv == nil { + return nil + } + cvMap, ok := cv.(map[string]any) + if !ok { + return nil + } + viewer := &model.Viewer{} + if id, ok := cvMap["id"].(string); ok { + viewer.ID = id + } + if name, ok := cvMap["name"].(string); ok { + viewer.Name = name + } + entity.CurrentViewer = viewer + return nil +} diff --git a/demo/pkg/subgraphs/cachegraph_ext/subgraph/generated/generated.go b/demo/pkg/subgraphs/cachegraph_ext/subgraph/generated/generated.go new file mode 100644 index 0000000000..d1032d7adf --- /dev/null +++ b/demo/pkg/subgraphs/cachegraph_ext/subgraph/generated/generated.go @@ -0,0 +1,5517 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package generated + +import ( + "bytes" + "context" + "errors" + "fmt" + "strconv" + "sync" + "sync/atomic" + + "github.com/99designs/gqlgen/graphql" + "github.com/99designs/gqlgen/graphql/introspection" + "github.com/99designs/gqlgen/plugin/federation/fedruntime" + gqlparser "github.com/vektah/gqlparser/v2" + "github.com/vektah/gqlparser/v2/ast" + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachegraph_ext/subgraph/model" +) + +// region ************************** generated!.gotpl ************************** + +// NewExecutableSchema creates an ExecutableSchema from the ResolverRoot interface. +func NewExecutableSchema(cfg Config) graphql.ExecutableSchema { + return &executableSchema{ + schema: cfg.Schema, + resolvers: cfg.Resolvers, + directives: cfg.Directives, + complexity: cfg.Complexity, + } +} + +type Config struct { + Schema *ast.Schema + Resolvers ResolverRoot + Directives DirectiveRoot + Complexity ComplexityRoot +} + +type ResolverRoot interface { + Article() ArticleResolver + Entity() EntityResolver +} + +type DirectiveRoot struct { +} + +type ComplexityRoot struct { + Article struct { + CurrentViewer func(childComplexity int) int + ID func(childComplexity int) int + PersonalizedRecommendation func(childComplexity int) int + Rating func(childComplexity int) int + RelatedArticles func(childComplexity int) int + ReviewSummary func(childComplexity int) int + ViewCount func(childComplexity int) int + } + + Catalog struct { + Description func(childComplexity int) int + ID func(childComplexity int) int + LastUpdated func(childComplexity int) int + } + + Entity struct { + FindArticleByID func(childComplexity int, id string) int + FindCatalogByID func(childComplexity int, id string) int + FindViewerByID func(childComplexity int, id string) int + } + + Query struct { + __resolve__service func(childComplexity int) int + __resolve_entities func(childComplexity int, representations []map[string]any) int + } + + Viewer struct { + ID func(childComplexity int) int + Name func(childComplexity int) int + } + + _Service struct { + SDL func(childComplexity int) int + } +} + +type ArticleResolver interface { + RelatedArticles(ctx context.Context, obj *model.Article) ([]*model.Article, error) + PersonalizedRecommendation(ctx context.Context, obj *model.Article) (string, error) +} +type EntityResolver interface { + FindArticleByID(ctx context.Context, id string) (*model.Article, error) + FindCatalogByID(ctx context.Context, id string) (*model.Catalog, error) + FindViewerByID(ctx context.Context, id string) (*model.Viewer, error) +} + +type executableSchema struct { + schema *ast.Schema + resolvers ResolverRoot + directives DirectiveRoot + complexity ComplexityRoot +} + +func (e *executableSchema) Schema() *ast.Schema { + if e.schema != nil { + return e.schema + } + return parsedSchema +} + +func (e *executableSchema) Complexity(ctx context.Context, typeName, field string, childComplexity int, rawArgs map[string]any) (int, bool) { + ec := executionContext{nil, e, 0, 0, nil} + _ = ec + switch typeName + "." + field { + + case "Article.currentViewer": + if e.complexity.Article.CurrentViewer == nil { + break + } + + return e.complexity.Article.CurrentViewer(childComplexity), true + + case "Article.id": + if e.complexity.Article.ID == nil { + break + } + + return e.complexity.Article.ID(childComplexity), true + + case "Article.personalizedRecommendation": + if e.complexity.Article.PersonalizedRecommendation == nil { + break + } + + return e.complexity.Article.PersonalizedRecommendation(childComplexity), true + + case "Article.rating": + if e.complexity.Article.Rating == nil { + break + } + + return e.complexity.Article.Rating(childComplexity), true + + case "Article.relatedArticles": + if e.complexity.Article.RelatedArticles == nil { + break + } + + return e.complexity.Article.RelatedArticles(childComplexity), true + + case "Article.reviewSummary": + if e.complexity.Article.ReviewSummary == nil { + break + } + + return e.complexity.Article.ReviewSummary(childComplexity), true + + case "Article.viewCount": + if e.complexity.Article.ViewCount == nil { + break + } + + return e.complexity.Article.ViewCount(childComplexity), true + + case "Catalog.description": + if e.complexity.Catalog.Description == nil { + break + } + + return e.complexity.Catalog.Description(childComplexity), true + + case "Catalog.id": + if e.complexity.Catalog.ID == nil { + break + } + + return e.complexity.Catalog.ID(childComplexity), true + + case "Catalog.lastUpdated": + if e.complexity.Catalog.LastUpdated == nil { + break + } + + return e.complexity.Catalog.LastUpdated(childComplexity), true + + case "Entity.findArticleByID": + if e.complexity.Entity.FindArticleByID == nil { + break + } + + args, err := ec.field_Entity_findArticleByID_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Entity.FindArticleByID(childComplexity, args["id"].(string)), true + + case "Entity.findCatalogByID": + if e.complexity.Entity.FindCatalogByID == nil { + break + } + + args, err := ec.field_Entity_findCatalogByID_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Entity.FindCatalogByID(childComplexity, args["id"].(string)), true + + case "Entity.findViewerByID": + if e.complexity.Entity.FindViewerByID == nil { + break + } + + args, err := ec.field_Entity_findViewerByID_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Entity.FindViewerByID(childComplexity, args["id"].(string)), true + + case "Query._service": + if e.complexity.Query.__resolve__service == nil { + break + } + + return e.complexity.Query.__resolve__service(childComplexity), true + + case "Query._entities": + if e.complexity.Query.__resolve_entities == nil { + break + } + + args, err := ec.field_Query__entities_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.__resolve_entities(childComplexity, args["representations"].([]map[string]any)), true + + case "Viewer.id": + if e.complexity.Viewer.ID == nil { + break + } + + return e.complexity.Viewer.ID(childComplexity), true + + case "Viewer.name": + if e.complexity.Viewer.Name == nil { + break + } + + return e.complexity.Viewer.Name(childComplexity), true + + case "_Service.sdl": + if e.complexity._Service.SDL == nil { + break + } + + return e.complexity._Service.SDL(childComplexity), true + + } + return 0, false +} + +func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { + opCtx := graphql.GetOperationContext(ctx) + ec := executionContext{opCtx, e, 0, 0, make(chan graphql.DeferredResult)} + inputUnmarshalMap := graphql.BuildUnmarshalerMap() + first := true + + switch opCtx.Operation.Operation { + case ast.Query: + return func(ctx context.Context) *graphql.Response { + var response graphql.Response + var data graphql.Marshaler + if first { + first = false + ctx = graphql.WithUnmarshalerMap(ctx, inputUnmarshalMap) + data = ec._Query(ctx, opCtx.Operation.SelectionSet) + } else { + if atomic.LoadInt32(&ec.pendingDeferred) > 0 { + result := <-ec.deferredResults + atomic.AddInt32(&ec.pendingDeferred, -1) + data = result.Result + response.Path = result.Path + response.Label = result.Label + response.Errors = result.Errors + } else { + return nil + } + } + var buf bytes.Buffer + data.MarshalGQL(&buf) + response.Data = buf.Bytes() + if atomic.LoadInt32(&ec.deferred) > 0 { + hasNext := atomic.LoadInt32(&ec.pendingDeferred) > 0 + response.HasNext = &hasNext + } + + return &response + } + + default: + return graphql.OneShot(graphql.ErrorResponse(ctx, "unsupported GraphQL operation")) + } +} + +type executionContext struct { + *graphql.OperationContext + *executableSchema + deferred int32 + pendingDeferred int32 + deferredResults chan graphql.DeferredResult +} + +func (ec *executionContext) processDeferredGroup(dg graphql.DeferredGroup) { + atomic.AddInt32(&ec.pendingDeferred, 1) + go func() { + ctx := graphql.WithFreshResponseContext(dg.Context) + dg.FieldSet.Dispatch(ctx) + ds := graphql.DeferredResult{ + Path: dg.Path, + Label: dg.Label, + Result: dg.FieldSet, + Errors: graphql.GetErrors(ctx), + } + // null fields should bubble up + if dg.FieldSet.Invalids > 0 { + ds.Result = graphql.Null + } + ec.deferredResults <- ds + }() +} + +func (ec *executionContext) introspectSchema() (*introspection.Schema, error) { + if ec.DisableIntrospection { + return nil, errors.New("introspection disabled") + } + return introspection.WrapSchema(ec.Schema()), nil +} + +func (ec *executionContext) introspectType(name string) (*introspection.Type, error) { + if ec.DisableIntrospection { + return nil, errors.New("introspection disabled") + } + return introspection.WrapTypeFromDef(ec.Schema(), ec.Schema().Types[name]), nil +} + +var sources = []*ast.Source{ + {Name: "../schema.graphqls", Input: `extend schema + @link( + url: "https://specs.apollo.dev/federation/v2.5" + import: ["@key", "@external", "@requires"] + ) + +directive @openfed__entityCache( + maxAge: Int! + includeHeaders: Boolean = false + partialCacheLoad: Boolean = false + shadowMode: Boolean = false +) on OBJECT + +type Article @key(fields: "id") @openfed__entityCache(maxAge: 90) { + id: ID! + currentViewer: Viewer @external + viewCount: Int! + rating: Float! + reviewSummary: String! + relatedArticles: [Article!]! + personalizedRecommendation: String! @requires(fields: "currentViewer { id name }") +} + +type Viewer @key(fields: "id") { + id: ID! + name: String! @external +} + +"""Extends Catalog with description from a second subgraph (for partial cache load testing)""" +type Catalog @key(fields: "id") @openfed__entityCache(maxAge: 120, partialCacheLoad: true) { + id: ID! + description: String! + lastUpdated: String! +} +`, BuiltIn: false}, + {Name: "../../federation/directives.graphql", Input: ` + directive @authenticated on FIELD_DEFINITION | OBJECT | INTERFACE | SCALAR | ENUM + directive @composeDirective(name: String!) repeatable on SCHEMA + directive @extends on OBJECT | INTERFACE + directive @external on OBJECT | FIELD_DEFINITION + directive @key(fields: FieldSet!, resolvable: Boolean = true) repeatable on OBJECT | INTERFACE + directive @inaccessible on + | ARGUMENT_DEFINITION + | ENUM + | ENUM_VALUE + | FIELD_DEFINITION + | INPUT_FIELD_DEFINITION + | INPUT_OBJECT + | INTERFACE + | OBJECT + | SCALAR + | UNION + directive @interfaceObject on OBJECT + directive @link(import: [String!], url: String!) repeatable on SCHEMA + directive @override(from: String!, label: String) on FIELD_DEFINITION + directive @policy(policies: [[federation__Policy!]!]!) on + | FIELD_DEFINITION + | OBJECT + | INTERFACE + | SCALAR + | ENUM + directive @provides(fields: FieldSet!) on FIELD_DEFINITION + directive @requires(fields: FieldSet!) on FIELD_DEFINITION + directive @requiresScopes(scopes: [[federation__Scope!]!]!) on + | FIELD_DEFINITION + | OBJECT + | INTERFACE + | SCALAR + | ENUM + directive @shareable repeatable on FIELD_DEFINITION | OBJECT + directive @tag(name: String!) repeatable on + | ARGUMENT_DEFINITION + | ENUM + | ENUM_VALUE + | FIELD_DEFINITION + | INPUT_FIELD_DEFINITION + | INPUT_OBJECT + | INTERFACE + | OBJECT + | SCALAR + | UNION + scalar _Any + scalar FieldSet + scalar federation__Policy + scalar federation__Scope +`, BuiltIn: true}, + {Name: "../../federation/entity.graphql", Input: ` +# a union of all types that use the @key directive +union _Entity = Article | Catalog | Viewer + +# fake type to build resolver interfaces for users to implement +type Entity { + findArticleByID(id: ID!,): Article! + findCatalogByID(id: ID!,): Catalog! + findViewerByID(id: ID!,): Viewer! +} + +type _Service { + sdl: String +} + +extend type Query { + _entities(representations: [_Any!]!): [_Entity]! + _service: _Service! +} +`, BuiltIn: true}, +} +var parsedSchema = gqlparser.MustLoadSchema(sources...) + +// endregion ************************** generated!.gotpl ************************** + +// region ***************************** args.gotpl ***************************** + +func (ec *executionContext) field_Entity_findArticleByID_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Entity_findArticleByID_argsID(ctx, rawArgs) + if err != nil { + return nil, err + } + args["id"] = arg0 + return args, nil +} +func (ec *executionContext) field_Entity_findArticleByID_argsID( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["id"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + if tmp, ok := rawArgs["id"]; ok { + return ec.unmarshalNID2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Entity_findCatalogByID_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Entity_findCatalogByID_argsID(ctx, rawArgs) + if err != nil { + return nil, err + } + args["id"] = arg0 + return args, nil +} +func (ec *executionContext) field_Entity_findCatalogByID_argsID( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["id"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + if tmp, ok := rawArgs["id"]; ok { + return ec.unmarshalNID2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Entity_findViewerByID_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Entity_findViewerByID_argsID(ctx, rawArgs) + if err != nil { + return nil, err + } + args["id"] = arg0 + return args, nil +} +func (ec *executionContext) field_Entity_findViewerByID_argsID( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["id"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + if tmp, ok := rawArgs["id"]; ok { + return ec.unmarshalNID2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Query___type_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Query___type_argsName(ctx, rawArgs) + if err != nil { + return nil, err + } + args["name"] = arg0 + return args, nil +} +func (ec *executionContext) field_Query___type_argsName( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["name"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("name")) + if tmp, ok := rawArgs["name"]; ok { + return ec.unmarshalNString2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Query__entities_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Query__entities_argsRepresentations(ctx, rawArgs) + if err != nil { + return nil, err + } + args["representations"] = arg0 + return args, nil +} +func (ec *executionContext) field_Query__entities_argsRepresentations( + ctx context.Context, + rawArgs map[string]any, +) ([]map[string]any, error) { + if _, ok := rawArgs["representations"]; !ok { + var zeroVal []map[string]any + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("representations")) + if tmp, ok := rawArgs["representations"]; ok { + return ec.unmarshalN_Any2ᚕmapᚄ(ctx, tmp) + } + + var zeroVal []map[string]any + return zeroVal, nil +} + +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 := ec.field___Directive_args_argsIncludeDeprecated(ctx, rawArgs) + if err != nil { + return nil, err + } + args["includeDeprecated"] = arg0 + return args, nil +} +func (ec *executionContext) field___Directive_args_argsIncludeDeprecated( + ctx context.Context, + rawArgs map[string]any, +) (*bool, error) { + if _, ok := rawArgs["includeDeprecated"]; !ok { + var zeroVal *bool + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("includeDeprecated")) + if tmp, ok := rawArgs["includeDeprecated"]; ok { + return ec.unmarshalOBoolean2ᚖbool(ctx, tmp) + } + + var zeroVal *bool + return zeroVal, nil +} + +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 := ec.field___Field_args_argsIncludeDeprecated(ctx, rawArgs) + if err != nil { + return nil, err + } + args["includeDeprecated"] = arg0 + return args, nil +} +func (ec *executionContext) field___Field_args_argsIncludeDeprecated( + ctx context.Context, + rawArgs map[string]any, +) (*bool, error) { + if _, ok := rawArgs["includeDeprecated"]; !ok { + var zeroVal *bool + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("includeDeprecated")) + if tmp, ok := rawArgs["includeDeprecated"]; ok { + return ec.unmarshalOBoolean2ᚖbool(ctx, tmp) + } + + var zeroVal *bool + return zeroVal, nil +} + +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 := ec.field___Type_enumValues_argsIncludeDeprecated(ctx, rawArgs) + if err != nil { + return nil, err + } + args["includeDeprecated"] = arg0 + return args, nil +} +func (ec *executionContext) field___Type_enumValues_argsIncludeDeprecated( + ctx context.Context, + rawArgs map[string]any, +) (bool, error) { + if _, ok := rawArgs["includeDeprecated"]; !ok { + var zeroVal bool + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("includeDeprecated")) + if tmp, ok := rawArgs["includeDeprecated"]; ok { + return ec.unmarshalOBoolean2bool(ctx, tmp) + } + + var zeroVal bool + return zeroVal, nil +} + +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 := ec.field___Type_fields_argsIncludeDeprecated(ctx, rawArgs) + if err != nil { + return nil, err + } + args["includeDeprecated"] = arg0 + return args, nil +} +func (ec *executionContext) field___Type_fields_argsIncludeDeprecated( + ctx context.Context, + rawArgs map[string]any, +) (bool, error) { + if _, ok := rawArgs["includeDeprecated"]; !ok { + var zeroVal bool + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("includeDeprecated")) + if tmp, ok := rawArgs["includeDeprecated"]; ok { + return ec.unmarshalOBoolean2bool(ctx, tmp) + } + + var zeroVal bool + return zeroVal, nil +} + +// endregion ***************************** args.gotpl ***************************** + +// region ************************** directives.gotpl ************************** + +// endregion ************************** directives.gotpl ************************** + +// region **************************** field.gotpl ***************************** + +func (ec *executionContext) _Article_id(ctx context.Context, field graphql.CollectedField, obj *model.Article) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Article_id(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Article_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Article", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Article_currentViewer(ctx context.Context, field graphql.CollectedField, obj *model.Article) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Article_currentViewer(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.CurrentViewer, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*model.Viewer) + fc.Result = res + return ec.marshalOViewer2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraph_extᚋsubgraphᚋmodelᚐViewer(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Article_currentViewer(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Article", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Viewer_id(ctx, field) + case "name": + return ec.fieldContext_Viewer_name(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Viewer", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Article_viewCount(ctx context.Context, field graphql.CollectedField, obj *model.Article) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Article_viewCount(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.ViewCount, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Article_viewCount(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Article", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Article_rating(ctx context.Context, field graphql.CollectedField, obj *model.Article) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Article_rating(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Rating, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(float64) + fc.Result = res + return ec.marshalNFloat2float64(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Article_rating(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Article", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Float does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Article_reviewSummary(ctx context.Context, field graphql.CollectedField, obj *model.Article) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Article_reviewSummary(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.ReviewSummary, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Article_reviewSummary(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Article", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Article_relatedArticles(ctx context.Context, field graphql.CollectedField, obj *model.Article) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Article_relatedArticles(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Article().RelatedArticles(rctx, obj) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]*model.Article) + fc.Result = res + return ec.marshalNArticle2ᚕᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraph_extᚋsubgraphᚋmodelᚐArticleᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Article_relatedArticles(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Article", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Article_id(ctx, field) + case "currentViewer": + return ec.fieldContext_Article_currentViewer(ctx, field) + case "viewCount": + return ec.fieldContext_Article_viewCount(ctx, field) + case "rating": + return ec.fieldContext_Article_rating(ctx, field) + case "reviewSummary": + return ec.fieldContext_Article_reviewSummary(ctx, field) + case "relatedArticles": + return ec.fieldContext_Article_relatedArticles(ctx, field) + case "personalizedRecommendation": + return ec.fieldContext_Article_personalizedRecommendation(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Article", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Article_personalizedRecommendation(ctx context.Context, field graphql.CollectedField, obj *model.Article) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Article_personalizedRecommendation(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Article().PersonalizedRecommendation(rctx, obj) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Article_personalizedRecommendation(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Article", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Catalog_id(ctx context.Context, field graphql.CollectedField, obj *model.Catalog) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Catalog_id(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Catalog_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Catalog", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Catalog_description(ctx context.Context, field graphql.CollectedField, obj *model.Catalog) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Catalog_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Catalog_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Catalog", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Catalog_lastUpdated(ctx context.Context, field graphql.CollectedField, obj *model.Catalog) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Catalog_lastUpdated(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.LastUpdated, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Catalog_lastUpdated(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Catalog", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Entity_findArticleByID(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Entity_findArticleByID(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Entity().FindArticleByID(rctx, fc.Args["id"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*model.Article) + fc.Result = res + return ec.marshalNArticle2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraph_extᚋsubgraphᚋmodelᚐArticle(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Entity_findArticleByID(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Entity", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Article_id(ctx, field) + case "currentViewer": + return ec.fieldContext_Article_currentViewer(ctx, field) + case "viewCount": + return ec.fieldContext_Article_viewCount(ctx, field) + case "rating": + return ec.fieldContext_Article_rating(ctx, field) + case "reviewSummary": + return ec.fieldContext_Article_reviewSummary(ctx, field) + case "relatedArticles": + return ec.fieldContext_Article_relatedArticles(ctx, field) + case "personalizedRecommendation": + return ec.fieldContext_Article_personalizedRecommendation(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Article", field.Name) + }, + } + 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_Entity_findArticleByID_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Entity_findCatalogByID(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Entity_findCatalogByID(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Entity().FindCatalogByID(rctx, fc.Args["id"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*model.Catalog) + fc.Result = res + return ec.marshalNCatalog2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraph_extᚋsubgraphᚋmodelᚐCatalog(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Entity_findCatalogByID(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Entity", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Catalog_id(ctx, field) + case "description": + return ec.fieldContext_Catalog_description(ctx, field) + case "lastUpdated": + return ec.fieldContext_Catalog_lastUpdated(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Catalog", field.Name) + }, + } + 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_Entity_findCatalogByID_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Entity_findViewerByID(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Entity_findViewerByID(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Entity().FindViewerByID(rctx, fc.Args["id"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*model.Viewer) + fc.Result = res + return ec.marshalNViewer2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraph_extᚋsubgraphᚋmodelᚐViewer(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Entity_findViewerByID(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Entity", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Viewer_id(ctx, field) + case "name": + return ec.fieldContext_Viewer_name(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Viewer", field.Name) + }, + } + 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_Entity_findViewerByID_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query__entities(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query__entities(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.__resolve_entities(ctx, fc.Args["representations"].([]map[string]any)), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]fedruntime.Entity) + fc.Result = res + return ec.marshalN_Entity2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐEntity(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query__entities(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type _Entity does not have child fields") + }, + } + 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__entities_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query__service(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query__service(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.__resolve__service(ctx) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(fedruntime.Service) + fc.Result = res + return ec.marshalN_Service2githubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐService(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query__service(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "sdl": + return ec.fieldContext__Service_sdl(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type _Service", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Query___type(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query___type(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.introspectType(fc.Args["name"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query___type(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + 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___type_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query___schema(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query___schema(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.introspectSchema() + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Schema) + fc.Result = res + return ec.marshalO__Schema2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐSchema(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query___schema(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "description": + return ec.fieldContext___Schema_description(ctx, field) + case "types": + return ec.fieldContext___Schema_types(ctx, field) + case "queryType": + return ec.fieldContext___Schema_queryType(ctx, field) + case "mutationType": + return ec.fieldContext___Schema_mutationType(ctx, field) + case "subscriptionType": + return ec.fieldContext___Schema_subscriptionType(ctx, field) + case "directives": + return ec.fieldContext___Schema_directives(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Schema", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Viewer_id(ctx context.Context, field graphql.CollectedField, obj *model.Viewer) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Viewer_id(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Viewer_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Viewer", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Viewer_name(ctx context.Context, field graphql.CollectedField, obj *model.Viewer) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Viewer_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Viewer_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Viewer", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) __Service_sdl(ctx context.Context, field graphql.CollectedField, obj *fedruntime.Service) (ret graphql.Marshaler) { + fc, err := ec.fieldContext__Service_sdl(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.SDL, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalOString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext__Service_sdl(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "_Service", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Directive_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Directive_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Directive_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Directive_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_isRepeatable(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Directive_isRepeatable(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsRepeatable, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Directive_isRepeatable(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_locations(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Directive_locations(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Locations, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]string) + fc.Result = res + return ec.marshalN__DirectiveLocation2ᚕstringᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Directive_locations(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type __DirectiveLocation does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_args(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Directive_args(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Args, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]introspection.InputValue) + fc.Result = res + return ec.marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Directive_args(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___InputValue_name(ctx, field) + case "description": + return ec.fieldContext___InputValue_description(ctx, field) + case "type": + return ec.fieldContext___InputValue_type(ctx, field) + case "defaultValue": + return ec.fieldContext___InputValue_defaultValue(ctx, field) + case "isDeprecated": + return ec.fieldContext___InputValue_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___InputValue_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __InputValue", field.Name) + }, + } + 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___Directive_args_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) ___EnumValue_name(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___EnumValue_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___EnumValue_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__EnumValue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___EnumValue_description(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___EnumValue_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___EnumValue_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__EnumValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___EnumValue_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___EnumValue_isDeprecated(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsDeprecated(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___EnumValue_isDeprecated(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__EnumValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___EnumValue_deprecationReason(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___EnumValue_deprecationReason(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.DeprecationReason(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___EnumValue_deprecationReason(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__EnumValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_args(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_args(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Args, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]introspection.InputValue) + fc.Result = res + return ec.marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_args(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___InputValue_name(ctx, field) + case "description": + return ec.fieldContext___InputValue_description(ctx, field) + case "type": + return ec.fieldContext___InputValue_type(ctx, field) + case "defaultValue": + return ec.fieldContext___InputValue_defaultValue(ctx, field) + case "isDeprecated": + return ec.fieldContext___InputValue_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___InputValue_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __InputValue", field.Name) + }, + } + 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___Field_args_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) ___Field_type(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_type(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Type, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_type(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_isDeprecated(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsDeprecated(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_isDeprecated(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_deprecationReason(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_deprecationReason(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.DeprecationReason(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_deprecationReason(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_name(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_description(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_type(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_type(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Type, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_type(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_defaultValue(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_defaultValue(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.DefaultValue, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_defaultValue(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_isDeprecated(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsDeprecated(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_isDeprecated(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_deprecationReason(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_deprecationReason(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.DeprecationReason(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_deprecationReason(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_types(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_types(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Types(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]introspection.Type) + fc.Result = res + return ec.marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_types(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_queryType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_queryType(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.QueryType(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_queryType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_mutationType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_mutationType(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.MutationType(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_mutationType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_subscriptionType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_subscriptionType(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.SubscriptionType(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_subscriptionType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_directives(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_directives(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Directives(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]introspection.Directive) + fc.Result = res + return ec.marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirectiveᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_directives(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___Directive_name(ctx, field) + case "description": + return ec.fieldContext___Directive_description(ctx, field) + case "isRepeatable": + return ec.fieldContext___Directive_isRepeatable(ctx, field) + case "locations": + return ec.fieldContext___Directive_locations(ctx, field) + case "args": + return ec.fieldContext___Directive_args(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Directive", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_kind(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_kind(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Kind(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalN__TypeKind2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_kind(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type __TypeKind does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_specifiedByURL(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_specifiedByURL(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.SpecifiedByURL(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_specifiedByURL(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_fields(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_fields(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Fields(fc.Args["includeDeprecated"].(bool)), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.Field) + fc.Result = res + return ec.marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐFieldᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_fields(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___Field_name(ctx, field) + case "description": + return ec.fieldContext___Field_description(ctx, field) + case "args": + return ec.fieldContext___Field_args(ctx, field) + case "type": + return ec.fieldContext___Field_type(ctx, field) + case "isDeprecated": + return ec.fieldContext___Field_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___Field_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Field", field.Name) + }, + } + 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_fields_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) ___Type_interfaces(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_interfaces(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Interfaces(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_interfaces(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_possibleTypes(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_possibleTypes(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.PossibleTypes(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_possibleTypes(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_enumValues(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_enumValues(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.EnumValues(fc.Args["includeDeprecated"].(bool)), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.EnumValue) + fc.Result = res + return ec.marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValueᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_enumValues(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___EnumValue_name(ctx, field) + case "description": + return ec.fieldContext___EnumValue_description(ctx, field) + case "isDeprecated": + return ec.fieldContext___EnumValue_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___EnumValue_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __EnumValue", field.Name) + }, + } + 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_enumValues_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) ___Type_inputFields(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_inputFields(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.InputFields(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.InputValue) + fc.Result = res + return ec.marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_inputFields(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___InputValue_name(ctx, field) + case "description": + return ec.fieldContext___InputValue_description(ctx, field) + case "type": + return ec.fieldContext___InputValue_type(ctx, field) + case "defaultValue": + return ec.fieldContext___InputValue_defaultValue(ctx, field) + case "isDeprecated": + return ec.fieldContext___InputValue_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___InputValue_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __InputValue", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_ofType(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_ofType(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.OfType(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_ofType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_isOneOf(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_isOneOf(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsOneOf(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalOBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_isOneOf(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +// endregion **************************** field.gotpl ***************************** + +// region **************************** input.gotpl ***************************** + +// endregion **************************** input.gotpl ***************************** + +// region ************************** interface.gotpl *************************** + +func (ec *executionContext) __Entity(ctx context.Context, sel ast.SelectionSet, obj fedruntime.Entity) graphql.Marshaler { + switch obj := (obj).(type) { + case nil: + return graphql.Null + case model.Viewer: + return ec._Viewer(ctx, sel, &obj) + case *model.Viewer: + if obj == nil { + return graphql.Null + } + return ec._Viewer(ctx, sel, obj) + case model.Catalog: + return ec._Catalog(ctx, sel, &obj) + case *model.Catalog: + if obj == nil { + return graphql.Null + } + return ec._Catalog(ctx, sel, obj) + case model.Article: + return ec._Article(ctx, sel, &obj) + case *model.Article: + if obj == nil { + return graphql.Null + } + return ec._Article(ctx, sel, obj) + default: + panic(fmt.Errorf("unexpected type %T", obj)) + } +} + +// endregion ************************** interface.gotpl *************************** + +// region **************************** object.gotpl **************************** + +var articleImplementors = []string{"Article", "_Entity"} + +func (ec *executionContext) _Article(ctx context.Context, sel ast.SelectionSet, obj *model.Article) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, articleImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Article") + case "id": + out.Values[i] = ec._Article_id(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "currentViewer": + out.Values[i] = ec._Article_currentViewer(ctx, field, obj) + case "viewCount": + out.Values[i] = ec._Article_viewCount(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "rating": + out.Values[i] = ec._Article_rating(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "reviewSummary": + out.Values[i] = ec._Article_reviewSummary(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "relatedArticles": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Article_relatedArticles(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + if field.Deferrable != nil { + dfs, ok := deferred[field.Deferrable.Label] + di := 0 + if ok { + dfs.AddField(field) + di = len(dfs.Values) - 1 + } else { + dfs = graphql.NewFieldSet([]graphql.CollectedField{field}) + deferred[field.Deferrable.Label] = dfs + } + dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler { + return innerFunc(ctx, dfs) + }) + + // don't run the out.Concurrently() call below + out.Values[i] = graphql.Null + continue + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + case "personalizedRecommendation": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Article_personalizedRecommendation(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + if field.Deferrable != nil { + dfs, ok := deferred[field.Deferrable.Label] + di := 0 + if ok { + dfs.AddField(field) + di = len(dfs.Values) - 1 + } else { + dfs = graphql.NewFieldSet([]graphql.CollectedField{field}) + deferred[field.Deferrable.Label] = dfs + } + dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler { + return innerFunc(ctx, dfs) + }) + + // don't run the out.Concurrently() call below + out.Values[i] = graphql.Null + continue + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var catalogImplementors = []string{"Catalog", "_Entity"} + +func (ec *executionContext) _Catalog(ctx context.Context, sel ast.SelectionSet, obj *model.Catalog) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, catalogImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Catalog") + case "id": + out.Values[i] = ec._Catalog_id(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "description": + out.Values[i] = ec._Catalog_description(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "lastUpdated": + out.Values[i] = ec._Catalog_lastUpdated(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 + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var entityImplementors = []string{"Entity"} + +func (ec *executionContext) _Entity(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, entityImplementors) + ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ + Object: "Entity", + }) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ + Object: field.Name, + Field: field, + }) + + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Entity") + case "findArticleByID": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Entity_findArticleByID(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "findCatalogByID": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Entity_findCatalogByID(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "findViewerByID": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Entity_findViewerByID(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var queryImplementors = []string{"Query"} + +func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, queryImplementors) + ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ + Object: "Query", + }) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ + Object: field.Name, + Field: field, + }) + + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Query") + case "_entities": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query__entities(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "_service": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query__service(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "__type": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Query___type(ctx, field) + }) + case "__schema": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Query___schema(ctx, field) + }) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var viewerImplementors = []string{"Viewer", "_Entity"} + +func (ec *executionContext) _Viewer(ctx context.Context, sel ast.SelectionSet, obj *model.Viewer) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, viewerImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Viewer") + case "id": + out.Values[i] = ec._Viewer_id(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "name": + out.Values[i] = ec._Viewer_name(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 + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var _ServiceImplementors = []string{"_Service"} + +func (ec *executionContext) __Service(ctx context.Context, sel ast.SelectionSet, obj *fedruntime.Service) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, _ServiceImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("_Service") + case "sdl": + out.Values[i] = ec.__Service_sdl(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __DirectiveImplementors = []string{"__Directive"} + +func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionSet, obj *introspection.Directive) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __DirectiveImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__Directive") + case "name": + out.Values[i] = ec.___Directive_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "description": + out.Values[i] = ec.___Directive_description(ctx, field, obj) + case "isRepeatable": + out.Values[i] = ec.___Directive_isRepeatable(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "locations": + out.Values[i] = ec.___Directive_locations(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "args": + out.Values[i] = ec.___Directive_args(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 + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __EnumValueImplementors = []string{"__EnumValue"} + +func (ec *executionContext) ___EnumValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.EnumValue) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __EnumValueImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__EnumValue") + case "name": + out.Values[i] = ec.___EnumValue_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "description": + out.Values[i] = ec.___EnumValue_description(ctx, field, obj) + case "isDeprecated": + out.Values[i] = ec.___EnumValue_isDeprecated(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "deprecationReason": + out.Values[i] = ec.___EnumValue_deprecationReason(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __FieldImplementors = []string{"__Field"} + +func (ec *executionContext) ___Field(ctx context.Context, sel ast.SelectionSet, obj *introspection.Field) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __FieldImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__Field") + case "name": + out.Values[i] = ec.___Field_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "description": + out.Values[i] = ec.___Field_description(ctx, field, obj) + case "args": + out.Values[i] = ec.___Field_args(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "type": + out.Values[i] = ec.___Field_type(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "isDeprecated": + out.Values[i] = ec.___Field_isDeprecated(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "deprecationReason": + out.Values[i] = ec.___Field_deprecationReason(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __InputValueImplementors = []string{"__InputValue"} + +func (ec *executionContext) ___InputValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.InputValue) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __InputValueImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__InputValue") + case "name": + out.Values[i] = ec.___InputValue_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "description": + out.Values[i] = ec.___InputValue_description(ctx, field, obj) + case "type": + out.Values[i] = ec.___InputValue_type(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "defaultValue": + out.Values[i] = ec.___InputValue_defaultValue(ctx, field, obj) + case "isDeprecated": + out.Values[i] = ec.___InputValue_isDeprecated(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "deprecationReason": + out.Values[i] = ec.___InputValue_deprecationReason(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __SchemaImplementors = []string{"__Schema"} + +func (ec *executionContext) ___Schema(ctx context.Context, sel ast.SelectionSet, obj *introspection.Schema) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __SchemaImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__Schema") + case "description": + out.Values[i] = ec.___Schema_description(ctx, field, obj) + case "types": + out.Values[i] = ec.___Schema_types(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "queryType": + out.Values[i] = ec.___Schema_queryType(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "mutationType": + out.Values[i] = ec.___Schema_mutationType(ctx, field, obj) + case "subscriptionType": + out.Values[i] = ec.___Schema_subscriptionType(ctx, field, obj) + case "directives": + out.Values[i] = ec.___Schema_directives(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 + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __TypeImplementors = []string{"__Type"} + +func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, obj *introspection.Type) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __TypeImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__Type") + case "kind": + out.Values[i] = ec.___Type_kind(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "name": + out.Values[i] = ec.___Type_name(ctx, field, obj) + case "description": + out.Values[i] = ec.___Type_description(ctx, field, obj) + case "specifiedByURL": + out.Values[i] = ec.___Type_specifiedByURL(ctx, field, obj) + case "fields": + out.Values[i] = ec.___Type_fields(ctx, field, obj) + case "interfaces": + out.Values[i] = ec.___Type_interfaces(ctx, field, obj) + case "possibleTypes": + out.Values[i] = ec.___Type_possibleTypes(ctx, field, obj) + case "enumValues": + out.Values[i] = ec.___Type_enumValues(ctx, field, obj) + case "inputFields": + out.Values[i] = ec.___Type_inputFields(ctx, field, obj) + case "ofType": + out.Values[i] = ec.___Type_ofType(ctx, field, obj) + case "isOneOf": + out.Values[i] = ec.___Type_isOneOf(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +// endregion **************************** object.gotpl **************************** + +// region ***************************** type.gotpl ***************************** + +func (ec *executionContext) marshalNArticle2githubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraph_extᚋsubgraphᚋmodelᚐArticle(ctx context.Context, sel ast.SelectionSet, v model.Article) graphql.Marshaler { + return ec._Article(ctx, sel, &v) +} + +func (ec *executionContext) marshalNArticle2ᚕᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraph_extᚋsubgraphᚋmodelᚐArticleᚄ(ctx context.Context, sel ast.SelectionSet, v []*model.Article) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalNArticle2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraph_extᚋsubgraphᚋmodelᚐArticle(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalNArticle2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraph_extᚋsubgraphᚋmodelᚐArticle(ctx context.Context, sel ast.SelectionSet, v *model.Article) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._Article(ctx, sel, v) +} + +func (ec *executionContext) unmarshalNBoolean2bool(ctx context.Context, v any) (bool, error) { + res, err := graphql.UnmarshalBoolean(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNBoolean2bool(ctx context.Context, sel ast.SelectionSet, v bool) graphql.Marshaler { + _ = sel + res := graphql.MarshalBoolean(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) marshalNCatalog2githubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraph_extᚋsubgraphᚋmodelᚐCatalog(ctx context.Context, sel ast.SelectionSet, v model.Catalog) graphql.Marshaler { + return ec._Catalog(ctx, sel, &v) +} + +func (ec *executionContext) marshalNCatalog2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraph_extᚋsubgraphᚋmodelᚐCatalog(ctx context.Context, sel ast.SelectionSet, v *model.Catalog) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._Catalog(ctx, sel, v) +} + +func (ec *executionContext) unmarshalNFieldSet2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNFieldSet2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNFloat2float64(ctx context.Context, v any) (float64, error) { + res, err := graphql.UnmarshalFloatContext(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNFloat2float64(ctx context.Context, sel ast.SelectionSet, v float64) graphql.Marshaler { + _ = sel + res := graphql.MarshalFloatContext(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return graphql.WrapContextMarshaler(ctx, res) +} + +func (ec *executionContext) unmarshalNID2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalID(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNID2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalID(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNInt2int(ctx context.Context, v any) (int, error) { + res, err := graphql.UnmarshalInt(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNInt2int(ctx context.Context, sel ast.SelectionSet, v int) graphql.Marshaler { + _ = sel + res := graphql.MarshalInt(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNString2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNString2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) marshalNViewer2githubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraph_extᚋsubgraphᚋmodelᚐViewer(ctx context.Context, sel ast.SelectionSet, v model.Viewer) graphql.Marshaler { + return ec._Viewer(ctx, sel, &v) +} + +func (ec *executionContext) marshalNViewer2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraph_extᚋsubgraphᚋmodelᚐViewer(ctx context.Context, sel ast.SelectionSet, v *model.Viewer) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._Viewer(ctx, sel, v) +} + +func (ec *executionContext) unmarshalN_Any2map(ctx context.Context, v any) (map[string]any, error) { + res, err := graphql.UnmarshalMap(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalN_Any2map(ctx context.Context, sel ast.SelectionSet, v map[string]any) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + _ = sel + res := graphql.MarshalMap(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalN_Any2ᚕmapᚄ(ctx context.Context, v any) ([]map[string]any, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([]map[string]any, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalN_Any2map(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalN_Any2ᚕmapᚄ(ctx context.Context, sel ast.SelectionSet, v []map[string]any) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalN_Any2map(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalN_Entity2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐEntity(ctx context.Context, sel ast.SelectionSet, v []fedruntime.Entity) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalO_Entity2githubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐEntity(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + return ret +} + +func (ec *executionContext) marshalN_Service2githubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐService(ctx context.Context, sel ast.SelectionSet, v fedruntime.Service) graphql.Marshaler { + return ec.__Service(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__Directive2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirective(ctx context.Context, sel ast.SelectionSet, v introspection.Directive) graphql.Marshaler { + return ec.___Directive(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirectiveᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.Directive) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__Directive2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirective(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalN__DirectiveLocation2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalN__DirectiveLocation2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalN__DirectiveLocation2ᚕstringᚄ(ctx context.Context, v any) ([]string, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalN__DirectiveLocation2string(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalN__DirectiveLocation2ᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v []string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__DirectiveLocation2string(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalN__EnumValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValue(ctx context.Context, sel ast.SelectionSet, v introspection.EnumValue) graphql.Marshaler { + return ec.___EnumValue(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__Field2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐField(ctx context.Context, sel ast.SelectionSet, v introspection.Field) graphql.Marshaler { + return ec.___Field(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__InputValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValue(ctx context.Context, sel ast.SelectionSet, v introspection.InputValue) graphql.Marshaler { + return ec.___InputValue(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.InputValue) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__InputValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValue(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +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) +} + +func (ec *executionContext) marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.Type) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__Type2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx context.Context, sel ast.SelectionSet, v *introspection.Type) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec.___Type(ctx, sel, v) +} + +func (ec *executionContext) unmarshalN__TypeKind2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalN__TypeKind2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNfederation__Policy2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNfederation__Policy2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNfederation__Policy2ᚕstringᚄ(ctx context.Context, v any) ([]string, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNfederation__Policy2string(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalNfederation__Policy2ᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v []string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNfederation__Policy2string(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalNfederation__Policy2ᚕᚕstringᚄ(ctx context.Context, v any) ([][]string, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([][]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNfederation__Policy2ᚕstringᚄ(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalNfederation__Policy2ᚕᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v [][]string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNfederation__Policy2ᚕstringᚄ(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalNfederation__Scope2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNfederation__Scope2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNfederation__Scope2ᚕstringᚄ(ctx context.Context, v any) ([]string, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNfederation__Scope2string(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalNfederation__Scope2ᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v []string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNfederation__Scope2string(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalNfederation__Scope2ᚕᚕstringᚄ(ctx context.Context, v any) ([][]string, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([][]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNfederation__Scope2ᚕstringᚄ(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalNfederation__Scope2ᚕᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v [][]string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNfederation__Scope2ᚕstringᚄ(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalOBoolean2bool(ctx context.Context, v any) (bool, error) { + res, err := graphql.UnmarshalBoolean(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOBoolean2bool(ctx context.Context, sel ast.SelectionSet, v bool) graphql.Marshaler { + _ = sel + _ = ctx + res := graphql.MarshalBoolean(v) + return res +} + +func (ec *executionContext) unmarshalOBoolean2ᚖbool(ctx context.Context, v any) (*bool, error) { + if v == nil { + return nil, nil + } + res, err := graphql.UnmarshalBoolean(v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOBoolean2ᚖbool(ctx context.Context, sel ast.SelectionSet, v *bool) graphql.Marshaler { + if v == nil { + return graphql.Null + } + _ = sel + _ = ctx + res := graphql.MarshalBoolean(*v) + return res +} + +func (ec *executionContext) unmarshalOString2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOString2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + _ = ctx + res := graphql.MarshalString(v) + return res +} + +func (ec *executionContext) unmarshalOString2ᚕstringᚄ(ctx context.Context, v any) ([]string, error) { + if v == nil { + return nil, nil + } + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNString2string(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalOString2ᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v []string) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNString2string(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalOString2ᚖstring(ctx context.Context, v any) (*string, error) { + if v == nil { + return nil, nil + } + res, err := graphql.UnmarshalString(v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOString2ᚖstring(ctx context.Context, sel ast.SelectionSet, v *string) graphql.Marshaler { + if v == nil { + return graphql.Null + } + _ = sel + _ = ctx + res := graphql.MarshalString(*v) + return res +} + +func (ec *executionContext) marshalOViewer2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachegraph_extᚋsubgraphᚋmodelᚐViewer(ctx context.Context, sel ast.SelectionSet, v *model.Viewer) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._Viewer(ctx, sel, v) +} + +func (ec *executionContext) marshalO_Entity2githubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐEntity(ctx context.Context, sel ast.SelectionSet, v fedruntime.Entity) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec.__Entity(ctx, sel, v) +} + +func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.EnumValue) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__EnumValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValue(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐFieldᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.Field) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__Field2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐField(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.InputValue) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__InputValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValue(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + 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 + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__Type2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +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 + } + return ec.___Type(ctx, sel, v) +} + +// endregion ***************************** type.gotpl ***************************** diff --git a/demo/pkg/subgraphs/cachegraph_ext/subgraph/model/models_gen.go b/demo/pkg/subgraphs/cachegraph_ext/subgraph/model/models_gen.go new file mode 100644 index 0000000000..eda8f193c0 --- /dev/null +++ b/demo/pkg/subgraphs/cachegraph_ext/subgraph/model/models_gen.go @@ -0,0 +1,34 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package model + +type Article struct { + ID string `json:"id"` + CurrentViewer *Viewer `json:"currentViewer,omitempty"` + ViewCount int `json:"viewCount"` + Rating float64 `json:"rating"` + ReviewSummary string `json:"reviewSummary"` + RelatedArticles []*Article `json:"relatedArticles"` + PersonalizedRecommendation string `json:"personalizedRecommendation"` +} + +func (Article) IsEntity() {} + +// Extends Catalog with description from a second subgraph (for partial cache load testing) +type Catalog struct { + ID string `json:"id"` + Description string `json:"description"` + LastUpdated string `json:"lastUpdated"` +} + +func (Catalog) IsEntity() {} + +type Query struct { +} + +type Viewer struct { + ID string `json:"id"` + Name string `json:"name"` +} + +func (Viewer) IsEntity() {} diff --git a/demo/pkg/subgraphs/cachegraph_ext/subgraph/resolver.go b/demo/pkg/subgraphs/cachegraph_ext/subgraph/resolver.go new file mode 100644 index 0000000000..11329bb4a8 --- /dev/null +++ b/demo/pkg/subgraphs/cachegraph_ext/subgraph/resolver.go @@ -0,0 +1,3 @@ +package subgraph + +type Resolver struct{} diff --git a/demo/pkg/subgraphs/cachegraph_ext/subgraph/schema.graphqls b/demo/pkg/subgraphs/cachegraph_ext/subgraph/schema.graphqls new file mode 100644 index 0000000000..ee734f0c63 --- /dev/null +++ b/demo/pkg/subgraphs/cachegraph_ext/subgraph/schema.graphqls @@ -0,0 +1,34 @@ +extend schema + @link( + url: "https://specs.apollo.dev/federation/v2.5" + import: ["@key", "@external", "@requires"] + ) + +directive @openfed__entityCache( + maxAge: Int! + includeHeaders: Boolean = false + partialCacheLoad: Boolean = false + shadowMode: Boolean = false +) on OBJECT + +type Article @key(fields: "id") @openfed__entityCache(maxAge: 90) { + id: ID! + currentViewer: Viewer @external + viewCount: Int! + rating: Float! + reviewSummary: String! + relatedArticles: [Article!]! + personalizedRecommendation: String! @requires(fields: "currentViewer { id name }") +} + +type Viewer @key(fields: "id") { + id: ID! + name: String! @external +} + +"""Extends Catalog with description from a second subgraph (for partial cache load testing)""" +type Catalog @key(fields: "id") @openfed__entityCache(maxAge: 120, partialCacheLoad: true) { + id: ID! + description: String! + lastUpdated: String! +} diff --git a/demo/pkg/subgraphs/cachegraph_ext/subgraph/schema.resolvers.go b/demo/pkg/subgraphs/cachegraph_ext/subgraph/schema.resolvers.go new file mode 100644 index 0000000000..9cb5ba9ac4 --- /dev/null +++ b/demo/pkg/subgraphs/cachegraph_ext/subgraph/schema.resolvers.go @@ -0,0 +1,44 @@ +package subgraph + +// 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.76 + +import ( + "context" + "fmt" + + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachegraph_ext/subgraph/generated" + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachegraph_ext/subgraph/model" +) + +// RelatedArticles is the resolver for the relatedArticles field. +func (r *articleResolver) RelatedArticles(ctx context.Context, obj *model.Article) ([]*model.Article, error) { + ext := articleExtensions[obj.ID] + if ext == nil { + return nil, nil + } + related := make([]*model.Article, len(ext.RelatedIDs)) + for i, rid := range ext.RelatedIDs { + relatedExt := articleExtensions[rid] + if relatedExt == nil { + related[i] = &model.Article{ID: rid} + continue + } + related[i] = toArticle(rid, relatedExt) + } + return related, nil +} + +// PersonalizedRecommendation is the resolver for the personalizedRecommendation field. +func (r *articleResolver) PersonalizedRecommendation(ctx context.Context, obj *model.Article) (string, error) { + if obj.CurrentViewer == nil { + return "Sign in to get personalized recommendations.", nil + } + return fmt.Sprintf("Hey %s, based on your interests you'll love this article!", obj.CurrentViewer.Name), nil +} + +// Article returns generated.ArticleResolver implementation. +func (r *Resolver) Article() generated.ArticleResolver { return &articleResolver{r} } + +type articleResolver struct{ *Resolver } diff --git a/demo/pkg/subgraphs/cachegraph_ext/subgraph/schema.resolvers_test.go b/demo/pkg/subgraphs/cachegraph_ext/subgraph/schema.resolvers_test.go new file mode 100644 index 0000000000..e1ff750f85 --- /dev/null +++ b/demo/pkg/subgraphs/cachegraph_ext/subgraph/schema.resolvers_test.go @@ -0,0 +1,29 @@ +package subgraph + +import ( + "context" + "testing" + + "github.com/stretchr/testify/require" + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachegraph_ext/subgraph/model" +) + +func TestRelatedArticlesReturnsPopulatedArticleExtensions(t *testing.T) { + t.Parallel() + + r := &Resolver{} + + related, err := r.Article().RelatedArticles(context.Background(), &model.Article{ID: "1"}) + require.NoError(t, err) + require.Len(t, related, 2) + + require.Equal(t, "3", related[0].ID) + require.Equal(t, 15678, related[0].ViewCount) + require.Equal(t, 4.9, related[0].Rating) + require.Equal(t, "The definitive guide to cache invalidation. Must read.", related[0].ReviewSummary) + + require.Equal(t, "4", related[1].ID) + require.Equal(t, 6234, related[1].ViewCount) + require.Equal(t, 4.1, related[1].Rating) + require.Equal(t, "Practical tips for production caching. Solid advice.", related[1].ReviewSummary) +} diff --git a/demo/pkg/subgraphs/cachetest/articles/articles.go b/demo/pkg/subgraphs/cachetest/articles/articles.go new file mode 100644 index 0000000000..d043ca8472 --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/articles/articles.go @@ -0,0 +1,14 @@ +package articles + +import ( + "github.com/99designs/gqlgen/graphql" + + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachetest/articles/subgraph" + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachetest/articles/subgraph/generated" +) + +func NewSchema() graphql.ExecutableSchema { + return generated.NewExecutableSchema(generated.Config{ + Resolvers: &subgraph.Resolver{}, + }) +} diff --git a/demo/pkg/subgraphs/cachetest/articles/generate.go b/demo/pkg/subgraphs/cachetest/articles/generate.go new file mode 100644 index 0000000000..aab7bc94a8 --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/articles/generate.go @@ -0,0 +1,3 @@ +//go:generate go run github.com/99designs/gqlgen generate + +package articles diff --git a/demo/pkg/subgraphs/cachetest/articles/gqlgen.yml b/demo/pkg/subgraphs/cachetest/articles/gqlgen.yml new file mode 100644 index 0000000000..78cd6bc4bf --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/articles/gqlgen.yml @@ -0,0 +1,39 @@ +schema: + - subgraph/*.graphqls + +exec: + filename: subgraph/generated/generated.go + package: generated + +federation: + filename: subgraph/generated/federation.go + package: generated + version: 2 + options: + explicit_requires: true + +model: + filename: subgraph/model/models_gen.go + package: model + +resolver: + layout: follow-schema + dir: subgraph + package: subgraph + +models: + Article: + fields: + personalizedRecommendation: + resolver: true + ID: + model: + - github.com/99designs/gqlgen/graphql.ID + - github.com/99designs/gqlgen/graphql.Int + - github.com/99designs/gqlgen/graphql.Int64 + - github.com/99designs/gqlgen/graphql.Int32 + Int: + model: + - github.com/99designs/gqlgen/graphql.Int + - github.com/99designs/gqlgen/graphql.Int64 + - github.com/99designs/gqlgen/graphql.Int32 diff --git a/demo/pkg/subgraphs/cachetest/articles/subgraph/data.go b/demo/pkg/subgraphs/cachetest/articles/subgraph/data.go new file mode 100644 index 0000000000..b8b37f258a --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/articles/subgraph/data.go @@ -0,0 +1,66 @@ +package subgraph + +import "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachetest/articles/subgraph/model" + +type articleFixture struct { + Title string + Body string + Tags []string +} + +// articleFixtures keep article fields stable across entity resolutions so the +// synthetic entity-caching graph can model the same query shape repeatedly. +var articleFixtures = map[string]articleFixture{ + "a1": { + Title: "The Rise of Federated GraphQL", + Body: "Federated GraphQL lets teams split ownership while keeping one graph.", + Tags: []string{"federation", "graphql"}, + }, + "a2": { + Title: "Caching Strategies for Modern APIs", + Body: "Layered caching trades complexity for latency and load reduction.", + Tags: []string{"caching", "performance"}, + }, + "a3": { + Title: "A Practical Guide to @requestScoped", + Body: "@requestScoped deduplicates repeated field reads within one request.", + Tags: []string{"request-scoped", "graphql"}, + }, +} + +// relatedArticleIDs maps each article to its related articles. Used by the +// Article.relatedArticles resolver to enable nested-selection tests. +var relatedArticleIDs = map[string][]string{ + "a1": {"a2", "a3"}, + "a2": {"a1", "a3"}, + "a3": {"a1", "a2"}, +} + +func allArticleIDs() []string { + return []string{"a1", "a2", "a3"} +} + +// buildArticle returns a populated Article including relatedArticles (as +// stubs — downstream entity lookups re-resolve them if the query selects +// nested fields). +func buildArticle(id string) *model.Article { + fixture := articleFixtures[id] + relatedIDs := relatedArticleIDs[id] + related := make([]*model.Article, 0, len(relatedIDs)) + for _, rid := range relatedIDs { + relatedFixture := articleFixtures[rid] + related = append(related, &model.Article{ + ID: rid, + Title: relatedFixture.Title, + Body: relatedFixture.Body, + Tags: relatedFixture.Tags, + }) + } + return &model.Article{ + ID: id, + Title: fixture.Title, + Body: fixture.Body, + Tags: fixture.Tags, + RelatedArticles: related, + } +} diff --git a/demo/pkg/subgraphs/cachetest/articles/subgraph/entity.resolvers.go b/demo/pkg/subgraphs/cachetest/articles/subgraph/entity.resolvers.go new file mode 100644 index 0000000000..9c82f8893f --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/articles/subgraph/entity.resolvers.go @@ -0,0 +1,42 @@ +package subgraph + +// 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.76 + +import ( + "context" + + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachetest/articles/subgraph/generated" + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachetest/articles/subgraph/model" +) + +// FindArticleByID is the resolver for the findArticleByID field. +func (r *entityResolver) FindArticleByID(ctx context.Context, id string) (*model.Article, error) { + return buildArticle(id), nil +} + +// FindPersonalizedByID is the resolver for the findPersonalizedByID field. +func (r *entityResolver) FindPersonalizedByID(ctx context.Context, id string) (model.Personalized, error) { + // The articles subgraph declares Personalized as a plain interface with only the id key. + // The router never actually fetches _entities(Personalized) from this subgraph (that's the + // viewer subgraph's @interfaceObject). Returning an Article as the concrete type is a safe stub. + return buildArticle(id), nil +} + +// FindViewerByID is the resolver for the findViewerByID field. +func (r *entityResolver) FindViewerByID(ctx context.Context, id string) (*model.Viewer, error) { + return &model.Viewer{ + ID: id, + RecommendedArticles: []*model.Article{ + buildArticle("a1"), + buildArticle("a2"), + buildArticle("a3"), + }, + }, nil +} + +// Entity returns generated.EntityResolver implementation. +func (r *Resolver) Entity() generated.EntityResolver { return &entityResolver{r} } + +type entityResolver struct{ *Resolver } diff --git a/demo/pkg/subgraphs/cachetest/articles/subgraph/generated/federation.go b/demo/pkg/subgraphs/cachetest/articles/subgraph/generated/federation.go new file mode 100644 index 0000000000..6658afb637 --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/articles/subgraph/generated/federation.go @@ -0,0 +1,345 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package generated + +import ( + "context" + "errors" + "fmt" + "strings" + "sync" + + "github.com/99designs/gqlgen/plugin/federation/fedruntime" +) + +var ( + ErrUnknownType = errors.New("unknown type") + ErrTypeNotFound = errors.New("type not found") +) + +func (ec *executionContext) __resolve__service(ctx context.Context) (fedruntime.Service, error) { + if ec.DisableIntrospection { + return fedruntime.Service{}, errors.New("federated introspection disabled") + } + + var sdl []string + + for _, src := range sources { + if src.BuiltIn { + continue + } + sdl = append(sdl, src.Input) + } + + return fedruntime.Service{ + SDL: strings.Join(sdl, "\n"), + }, nil +} + +func (ec *executionContext) __resolve_entities(ctx context.Context, representations []map[string]any) []fedruntime.Entity { + list := make([]fedruntime.Entity, len(representations)) + + repsMap := ec.buildRepresentationGroups(ctx, representations) + + switch len(repsMap) { + case 0: + return list + case 1: + for typeName, reps := range repsMap { + ec.resolveEntityGroup(ctx, typeName, reps, list) + } + return list + default: + var g sync.WaitGroup + g.Add(len(repsMap)) + for typeName, reps := range repsMap { + go func(typeName string, reps []EntityWithIndex) { + ec.resolveEntityGroup(ctx, typeName, reps, list) + g.Done() + }(typeName, reps) + } + g.Wait() + return list + } +} + +type EntityWithIndex struct { + // The index in the original representation array + index int + entity EntityRepresentation +} + +// EntityRepresentation is the JSON representation of an entity sent by the Router +// used as the inputs for us to resolve. +// +// We make it a map because we know the top level JSON is always an object. +type EntityRepresentation map[string]any + +// We group entities by typename so that we can parallelize their resolution. +// This is particularly helpful when there are entity groups in multi mode. +func (ec *executionContext) buildRepresentationGroups( + ctx context.Context, + representations []map[string]any, +) map[string][]EntityWithIndex { + repsMap := make(map[string][]EntityWithIndex) + for i, rep := range representations { + typeName, ok := rep["__typename"].(string) + if !ok { + // If there is no __typename, we just skip the representation; + // we just won't be resolving these unknown types. + ec.Error(ctx, errors.New("__typename must be an existing string")) + continue + } + + repsMap[typeName] = append(repsMap[typeName], EntityWithIndex{ + index: i, + entity: rep, + }) + } + + return repsMap +} + +func (ec *executionContext) resolveEntityGroup( + ctx context.Context, + typeName string, + reps []EntityWithIndex, + list []fedruntime.Entity, +) { + if isMulti(typeName) { + err := ec.resolveManyEntities(ctx, typeName, reps, list) + if err != nil { + ec.Error(ctx, err) + } + } else { + // if there are multiple entities to resolve, parallelize (similar to + // graphql.FieldSet.Dispatch) + var e sync.WaitGroup + e.Add(len(reps)) + for i, rep := range reps { + i, rep := i, rep + go func(i int, rep EntityWithIndex) { + entity, err := ec.resolveEntity(ctx, typeName, rep.entity) + if err != nil { + ec.Error(ctx, err) + } else { + list[rep.index] = entity + } + e.Done() + }(i, rep) + } + e.Wait() + } +} + +func isMulti(typeName string) bool { + switch typeName { + default: + return false + } +} + +func (ec *executionContext) resolveEntity( + ctx context.Context, + typeName string, + rep EntityRepresentation, +) (e fedruntime.Entity, err error) { + // we need to do our own panic handling, because we may be called in a + // goroutine, where the usual panic handling can't catch us + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + } + }() + + switch typeName { + case "Article": + resolverName, err := entityResolverNameForArticle(ctx, rep) + if err != nil { + return nil, fmt.Errorf(`finding resolver for Entity "Article": %w`, err) + } + switch resolverName { + + case "findArticleByID": + id0, err := ec.unmarshalNID2string(ctx, rep["id"]) + if err != nil { + return nil, fmt.Errorf(`unmarshalling param 0 for findArticleByID(): %w`, err) + } + entity, err := ec.resolvers.Entity().FindArticleByID(ctx, id0) + if err != nil { + return nil, fmt.Errorf(`resolving Entity "Article": %w`, err) + } + err = ec.PopulateArticleRequires(ctx, entity, rep) + if err != nil { + return nil, fmt.Errorf(`populating requires for Entity "Article": %w`, err) + } + return entity, nil + } + case "Personalized": + resolverName, err := entityResolverNameForPersonalized(ctx, rep) + if err != nil { + return nil, fmt.Errorf(`finding resolver for Entity "Personalized": %w`, err) + } + switch resolverName { + + case "findPersonalizedByID": + id0, err := ec.unmarshalNID2string(ctx, rep["id"]) + if err != nil { + return nil, fmt.Errorf(`unmarshalling param 0 for findPersonalizedByID(): %w`, err) + } + entity, err := ec.resolvers.Entity().FindPersonalizedByID(ctx, id0) + if err != nil { + return nil, fmt.Errorf(`resolving Entity "Personalized": %w`, err) + } + + return entity, nil + } + case "Viewer": + resolverName, err := entityResolverNameForViewer(ctx, rep) + if err != nil { + return nil, fmt.Errorf(`finding resolver for Entity "Viewer": %w`, err) + } + switch resolverName { + + case "findViewerByID": + id0, err := ec.unmarshalNID2string(ctx, rep["id"]) + if err != nil { + return nil, fmt.Errorf(`unmarshalling param 0 for findViewerByID(): %w`, err) + } + entity, err := ec.resolvers.Entity().FindViewerByID(ctx, id0) + if err != nil { + return nil, fmt.Errorf(`resolving Entity "Viewer": %w`, err) + } + + return entity, nil + } + + } + return nil, fmt.Errorf("%w: %s", ErrUnknownType, typeName) +} + +func (ec *executionContext) resolveManyEntities( + ctx context.Context, + typeName string, + reps []EntityWithIndex, + list []fedruntime.Entity, +) (err error) { + // we need to do our own panic handling, because we may be called in a + // goroutine, where the usual panic handling can't catch us + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + } + }() + + switch typeName { + + default: + return errors.New("unknown type: " + typeName) + } +} + +func entityResolverNameForArticle(ctx context.Context, rep EntityRepresentation) (string, error) { + // we collect errors because a later entity resolver may work fine + // when an entity has multiple keys + entityResolverErrs := []error{} + for { + var ( + m EntityRepresentation + val any + ok bool + ) + _ = val + // if all of the KeyFields values for this resolver are null, + // we shouldn't use use it + allNull := true + m = rep + val, ok = m["id"] + if !ok { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to missing Key Field \"id\" for Article", ErrTypeNotFound)) + break + } + if allNull { + allNull = val == nil + } + if allNull { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to all null value KeyFields for Article", ErrTypeNotFound)) + break + } + return "findArticleByID", nil + } + return "", fmt.Errorf("%w for Article due to %v", ErrTypeNotFound, + errors.Join(entityResolverErrs...).Error()) +} + +func entityResolverNameForPersonalized(ctx context.Context, rep EntityRepresentation) (string, error) { + // we collect errors because a later entity resolver may work fine + // when an entity has multiple keys + entityResolverErrs := []error{} + for { + var ( + m EntityRepresentation + val any + ok bool + ) + _ = val + // if all of the KeyFields values for this resolver are null, + // we shouldn't use use it + allNull := true + m = rep + val, ok = m["id"] + if !ok { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to missing Key Field \"id\" for Personalized", ErrTypeNotFound)) + break + } + if allNull { + allNull = val == nil + } + if allNull { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to all null value KeyFields for Personalized", ErrTypeNotFound)) + break + } + return "findPersonalizedByID", nil + } + return "", fmt.Errorf("%w for Personalized due to %v", ErrTypeNotFound, + errors.Join(entityResolverErrs...).Error()) +} + +func entityResolverNameForViewer(ctx context.Context, rep EntityRepresentation) (string, error) { + // we collect errors because a later entity resolver may work fine + // when an entity has multiple keys + entityResolverErrs := []error{} + for { + var ( + m EntityRepresentation + val any + ok bool + ) + _ = val + // if all of the KeyFields values for this resolver are null, + // we shouldn't use use it + allNull := true + m = rep + val, ok = m["id"] + if !ok { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to missing Key Field \"id\" for Viewer", ErrTypeNotFound)) + break + } + if allNull { + allNull = val == nil + } + if allNull { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to all null value KeyFields for Viewer", ErrTypeNotFound)) + break + } + return "findViewerByID", nil + } + return "", fmt.Errorf("%w for Viewer due to %v", ErrTypeNotFound, + errors.Join(entityResolverErrs...).Error()) +} diff --git a/demo/pkg/subgraphs/cachetest/articles/subgraph/generated/federation.requires.go b/demo/pkg/subgraphs/cachetest/articles/subgraph/generated/federation.requires.go new file mode 100644 index 0000000000..040b03e725 --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/articles/subgraph/generated/federation.requires.go @@ -0,0 +1,35 @@ +package generated + +import ( + "context" + "fmt" + + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachetest/articles/subgraph/model" +) + +// PopulateArticleRequires is the requires populator for the Article entity. +func (ec *executionContext) PopulateArticleRequires(ctx context.Context, entity *model.Article, reps map[string]any) error { + rawViewer, ok := reps["currentViewer"] + if !ok || rawViewer == nil { + return nil + } + + viewerMap, ok := rawViewer.(map[string]any) + if !ok { + return fmt.Errorf("expected currentViewer to be an object, got %T", rawViewer) + } + + viewer := &model.Viewer{} + if id, ok := viewerMap["id"].(string); ok { + viewer.ID = id + } + if name, ok := viewerMap["name"].(string); ok { + viewer.Name = name + } + if email, ok := viewerMap["email"].(string); ok { + viewer.Email = email + } + + entity.CurrentViewer = viewer + return nil +} diff --git a/demo/pkg/subgraphs/cachetest/articles/subgraph/generated/generated.go b/demo/pkg/subgraphs/cachetest/articles/subgraph/generated/generated.go new file mode 100644 index 0000000000..026e2f563c --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/articles/subgraph/generated/generated.go @@ -0,0 +1,5519 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package generated + +import ( + "bytes" + "context" + "errors" + "fmt" + "strconv" + "sync" + "sync/atomic" + + "github.com/99designs/gqlgen/graphql" + "github.com/99designs/gqlgen/graphql/introspection" + "github.com/99designs/gqlgen/plugin/federation/fedruntime" + gqlparser "github.com/vektah/gqlparser/v2" + "github.com/vektah/gqlparser/v2/ast" + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachetest/articles/subgraph/model" +) + +// region ************************** generated!.gotpl ************************** + +// NewExecutableSchema creates an ExecutableSchema from the ResolverRoot interface. +func NewExecutableSchema(cfg Config) graphql.ExecutableSchema { + return &executableSchema{ + schema: cfg.Schema, + resolvers: cfg.Resolvers, + directives: cfg.Directives, + complexity: cfg.Complexity, + } +} + +type Config struct { + Schema *ast.Schema + Resolvers ResolverRoot + Directives DirectiveRoot + Complexity ComplexityRoot +} + +type ResolverRoot interface { + Article() ArticleResolver + Entity() EntityResolver + Query() QueryResolver +} + +type DirectiveRoot struct { +} + +type ComplexityRoot struct { + Article struct { + Body func(childComplexity int) int + CurrentViewer func(childComplexity int) int + ID func(childComplexity int) int + PersonalizedRecommendation func(childComplexity int) int + RelatedArticles func(childComplexity int) int + Tags func(childComplexity int) int + Title func(childComplexity int) int + } + + Entity struct { + FindArticleByID func(childComplexity int, id string) int + FindPersonalizedByID func(childComplexity int, id string) int + FindViewerByID func(childComplexity int, id string) int + } + + Query struct { + Articles func(childComplexity int) int + __resolve__service func(childComplexity int) int + __resolve_entities func(childComplexity int, representations []map[string]any) int + } + + Viewer struct { + Email func(childComplexity int) int + ID func(childComplexity int) int + Name func(childComplexity int) int + RecommendedArticles func(childComplexity int) int + } + + _Service struct { + SDL func(childComplexity int) int + } +} + +type ArticleResolver interface { + PersonalizedRecommendation(ctx context.Context, obj *model.Article) (string, error) +} +type EntityResolver interface { + FindArticleByID(ctx context.Context, id string) (*model.Article, error) + FindPersonalizedByID(ctx context.Context, id string) (model.Personalized, error) + FindViewerByID(ctx context.Context, id string) (*model.Viewer, error) +} +type QueryResolver interface { + Articles(ctx context.Context) ([]*model.Article, error) +} + +type executableSchema struct { + schema *ast.Schema + resolvers ResolverRoot + directives DirectiveRoot + complexity ComplexityRoot +} + +func (e *executableSchema) Schema() *ast.Schema { + if e.schema != nil { + return e.schema + } + return parsedSchema +} + +func (e *executableSchema) Complexity(ctx context.Context, typeName, field string, childComplexity int, rawArgs map[string]any) (int, bool) { + ec := executionContext{nil, e, 0, 0, nil} + _ = ec + switch typeName + "." + field { + + case "Article.body": + if e.complexity.Article.Body == nil { + break + } + + return e.complexity.Article.Body(childComplexity), true + + case "Article.currentViewer": + if e.complexity.Article.CurrentViewer == nil { + break + } + + return e.complexity.Article.CurrentViewer(childComplexity), true + + case "Article.id": + if e.complexity.Article.ID == nil { + break + } + + return e.complexity.Article.ID(childComplexity), true + + case "Article.personalizedRecommendation": + if e.complexity.Article.PersonalizedRecommendation == nil { + break + } + + return e.complexity.Article.PersonalizedRecommendation(childComplexity), true + + case "Article.relatedArticles": + if e.complexity.Article.RelatedArticles == nil { + break + } + + return e.complexity.Article.RelatedArticles(childComplexity), true + + case "Article.tags": + if e.complexity.Article.Tags == nil { + break + } + + return e.complexity.Article.Tags(childComplexity), true + + case "Article.title": + if e.complexity.Article.Title == nil { + break + } + + return e.complexity.Article.Title(childComplexity), true + + case "Entity.findArticleByID": + if e.complexity.Entity.FindArticleByID == nil { + break + } + + args, err := ec.field_Entity_findArticleByID_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Entity.FindArticleByID(childComplexity, args["id"].(string)), true + + case "Entity.findPersonalizedByID": + if e.complexity.Entity.FindPersonalizedByID == nil { + break + } + + args, err := ec.field_Entity_findPersonalizedByID_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Entity.FindPersonalizedByID(childComplexity, args["id"].(string)), true + + case "Entity.findViewerByID": + if e.complexity.Entity.FindViewerByID == nil { + break + } + + args, err := ec.field_Entity_findViewerByID_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Entity.FindViewerByID(childComplexity, args["id"].(string)), true + + case "Query.articles": + if e.complexity.Query.Articles == nil { + break + } + + return e.complexity.Query.Articles(childComplexity), true + + case "Query._service": + if e.complexity.Query.__resolve__service == nil { + break + } + + return e.complexity.Query.__resolve__service(childComplexity), true + + case "Query._entities": + if e.complexity.Query.__resolve_entities == nil { + break + } + + args, err := ec.field_Query__entities_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.__resolve_entities(childComplexity, args["representations"].([]map[string]any)), true + + case "Viewer.email": + if e.complexity.Viewer.Email == nil { + break + } + + return e.complexity.Viewer.Email(childComplexity), true + + case "Viewer.id": + if e.complexity.Viewer.ID == nil { + break + } + + return e.complexity.Viewer.ID(childComplexity), true + + case "Viewer.name": + if e.complexity.Viewer.Name == nil { + break + } + + return e.complexity.Viewer.Name(childComplexity), true + + case "Viewer.recommendedArticles": + if e.complexity.Viewer.RecommendedArticles == nil { + break + } + + return e.complexity.Viewer.RecommendedArticles(childComplexity), true + + case "_Service.sdl": + if e.complexity._Service.SDL == nil { + break + } + + return e.complexity._Service.SDL(childComplexity), true + + } + return 0, false +} + +func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { + opCtx := graphql.GetOperationContext(ctx) + ec := executionContext{opCtx, e, 0, 0, make(chan graphql.DeferredResult)} + inputUnmarshalMap := graphql.BuildUnmarshalerMap() + first := true + + switch opCtx.Operation.Operation { + case ast.Query: + return func(ctx context.Context) *graphql.Response { + var response graphql.Response + var data graphql.Marshaler + if first { + first = false + ctx = graphql.WithUnmarshalerMap(ctx, inputUnmarshalMap) + data = ec._Query(ctx, opCtx.Operation.SelectionSet) + } else { + if atomic.LoadInt32(&ec.pendingDeferred) > 0 { + result := <-ec.deferredResults + atomic.AddInt32(&ec.pendingDeferred, -1) + data = result.Result + response.Path = result.Path + response.Label = result.Label + response.Errors = result.Errors + } else { + return nil + } + } + var buf bytes.Buffer + data.MarshalGQL(&buf) + response.Data = buf.Bytes() + if atomic.LoadInt32(&ec.deferred) > 0 { + hasNext := atomic.LoadInt32(&ec.pendingDeferred) > 0 + response.HasNext = &hasNext + } + + return &response + } + + default: + return graphql.OneShot(graphql.ErrorResponse(ctx, "unsupported GraphQL operation")) + } +} + +type executionContext struct { + *graphql.OperationContext + *executableSchema + deferred int32 + pendingDeferred int32 + deferredResults chan graphql.DeferredResult +} + +func (ec *executionContext) processDeferredGroup(dg graphql.DeferredGroup) { + atomic.AddInt32(&ec.pendingDeferred, 1) + go func() { + ctx := graphql.WithFreshResponseContext(dg.Context) + dg.FieldSet.Dispatch(ctx) + ds := graphql.DeferredResult{ + Path: dg.Path, + Label: dg.Label, + Result: dg.FieldSet, + Errors: graphql.GetErrors(ctx), + } + // null fields should bubble up + if dg.FieldSet.Invalids > 0 { + ds.Result = graphql.Null + } + ec.deferredResults <- ds + }() +} + +func (ec *executionContext) introspectSchema() (*introspection.Schema, error) { + if ec.DisableIntrospection { + return nil, errors.New("introspection disabled") + } + return introspection.WrapSchema(ec.Schema()), nil +} + +func (ec *executionContext) introspectType(name string) (*introspection.Type, error) { + if ec.DisableIntrospection { + return nil, errors.New("introspection disabled") + } + return introspection.WrapTypeFromDef(ec.Schema(), ec.Schema().Types[name]), nil +} + +var sources = []*ast.Source{ + {Name: "../schema.graphqls", Input: `extend schema + @link( + url: "https://specs.apollo.dev/federation/v2.5" + import: ["@key", "@external", "@requires"] + ) + +type Query { + articles: [Article!]! +} + +interface Personalized @key(fields: "id") { + id: ID! +} + +# Extends Viewer with an edge back into articles land. +# The @key forces sequencing: the articles _entities fetch for +# recommendedArticles needs viewer.id from the prior viewer fetch, so the +# planner cannot parallelize it with the root Query.currentViewer call. +# +# name and email are declared @external because Article.personalizedRecommendation +# @requires references them. Composition fails without these declarations. +type Viewer @key(fields: "id") { + id: ID! + name: String! @external + email: String! @external + recommendedArticles: [Article!]! +} + +type Article implements Personalized @key(fields: "id") { + id: ID! + title: String! + body: String! + tags: [String!]! + # Article.currentViewer is provided by the viewer subgraph via the + # Personalized @interfaceObject. It is @external here so @requires can + # reference it. + currentViewer: Viewer @external + # @requires a WIDER selection ({id, name, email}) than the root query + # will ask for ({id, name}). This is the widening-miss trigger that the + # test asserts: the coordinate L1 was populated with {id, name}, so the + # follow-up _entities(Personalized) fetch fails the widening check and + # refetches the viewer subgraph. + personalizedRecommendation: String! + @requires(fields: "currentViewer { id name email }") + # relatedArticles enables nested selection of Article entities so tests + # can exercise @openfed__requestScoped deduplication across multiple nesting + # levels (Article.currentViewer selected inline at more than one depth). + relatedArticles: [Article!]! +} +`, BuiltIn: false}, + {Name: "../../federation/directives.graphql", Input: ` + directive @authenticated on FIELD_DEFINITION | OBJECT | INTERFACE | SCALAR | ENUM + directive @composeDirective(name: String!) repeatable on SCHEMA + directive @extends on OBJECT | INTERFACE + directive @external on OBJECT | FIELD_DEFINITION + directive @key(fields: FieldSet!, resolvable: Boolean = true) repeatable on OBJECT | INTERFACE + directive @inaccessible on + | ARGUMENT_DEFINITION + | ENUM + | ENUM_VALUE + | FIELD_DEFINITION + | INPUT_FIELD_DEFINITION + | INPUT_OBJECT + | INTERFACE + | OBJECT + | SCALAR + | UNION + directive @interfaceObject on OBJECT + directive @link(import: [String!], url: String!) repeatable on SCHEMA + directive @override(from: String!, label: String) on FIELD_DEFINITION + directive @policy(policies: [[federation__Policy!]!]!) on + | FIELD_DEFINITION + | OBJECT + | INTERFACE + | SCALAR + | ENUM + directive @provides(fields: FieldSet!) on FIELD_DEFINITION + directive @requires(fields: FieldSet!) on FIELD_DEFINITION + directive @requiresScopes(scopes: [[federation__Scope!]!]!) on + | FIELD_DEFINITION + | OBJECT + | INTERFACE + | SCALAR + | ENUM + directive @shareable repeatable on FIELD_DEFINITION | OBJECT + directive @tag(name: String!) repeatable on + | ARGUMENT_DEFINITION + | ENUM + | ENUM_VALUE + | FIELD_DEFINITION + | INPUT_FIELD_DEFINITION + | INPUT_OBJECT + | INTERFACE + | OBJECT + | SCALAR + | UNION + scalar _Any + scalar FieldSet + scalar federation__Policy + scalar federation__Scope +`, BuiltIn: true}, + {Name: "../../federation/entity.graphql", Input: ` +# a union of all types that use the @key directive +union _Entity = Article | Viewer + +# fake type to build resolver interfaces for users to implement +type Entity { + findArticleByID(id: ID!,): Article! + findPersonalizedByID(id: ID!,): Personalized! + findViewerByID(id: ID!,): Viewer! +} + +type _Service { + sdl: String +} + +extend type Query { + _entities(representations: [_Any!]!): [_Entity]! + _service: _Service! +} +`, BuiltIn: true}, +} +var parsedSchema = gqlparser.MustLoadSchema(sources...) + +// endregion ************************** generated!.gotpl ************************** + +// region ***************************** args.gotpl ***************************** + +func (ec *executionContext) field_Entity_findArticleByID_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Entity_findArticleByID_argsID(ctx, rawArgs) + if err != nil { + return nil, err + } + args["id"] = arg0 + return args, nil +} +func (ec *executionContext) field_Entity_findArticleByID_argsID( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["id"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + if tmp, ok := rawArgs["id"]; ok { + return ec.unmarshalNID2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Entity_findPersonalizedByID_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Entity_findPersonalizedByID_argsID(ctx, rawArgs) + if err != nil { + return nil, err + } + args["id"] = arg0 + return args, nil +} +func (ec *executionContext) field_Entity_findPersonalizedByID_argsID( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["id"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + if tmp, ok := rawArgs["id"]; ok { + return ec.unmarshalNID2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Entity_findViewerByID_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Entity_findViewerByID_argsID(ctx, rawArgs) + if err != nil { + return nil, err + } + args["id"] = arg0 + return args, nil +} +func (ec *executionContext) field_Entity_findViewerByID_argsID( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["id"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + if tmp, ok := rawArgs["id"]; ok { + return ec.unmarshalNID2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Query___type_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Query___type_argsName(ctx, rawArgs) + if err != nil { + return nil, err + } + args["name"] = arg0 + return args, nil +} +func (ec *executionContext) field_Query___type_argsName( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["name"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("name")) + if tmp, ok := rawArgs["name"]; ok { + return ec.unmarshalNString2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Query__entities_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Query__entities_argsRepresentations(ctx, rawArgs) + if err != nil { + return nil, err + } + args["representations"] = arg0 + return args, nil +} +func (ec *executionContext) field_Query__entities_argsRepresentations( + ctx context.Context, + rawArgs map[string]any, +) ([]map[string]any, error) { + if _, ok := rawArgs["representations"]; !ok { + var zeroVal []map[string]any + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("representations")) + if tmp, ok := rawArgs["representations"]; ok { + return ec.unmarshalN_Any2ᚕmapᚄ(ctx, tmp) + } + + var zeroVal []map[string]any + return zeroVal, nil +} + +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 := ec.field___Directive_args_argsIncludeDeprecated(ctx, rawArgs) + if err != nil { + return nil, err + } + args["includeDeprecated"] = arg0 + return args, nil +} +func (ec *executionContext) field___Directive_args_argsIncludeDeprecated( + ctx context.Context, + rawArgs map[string]any, +) (*bool, error) { + if _, ok := rawArgs["includeDeprecated"]; !ok { + var zeroVal *bool + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("includeDeprecated")) + if tmp, ok := rawArgs["includeDeprecated"]; ok { + return ec.unmarshalOBoolean2ᚖbool(ctx, tmp) + } + + var zeroVal *bool + return zeroVal, nil +} + +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 := ec.field___Field_args_argsIncludeDeprecated(ctx, rawArgs) + if err != nil { + return nil, err + } + args["includeDeprecated"] = arg0 + return args, nil +} +func (ec *executionContext) field___Field_args_argsIncludeDeprecated( + ctx context.Context, + rawArgs map[string]any, +) (*bool, error) { + if _, ok := rawArgs["includeDeprecated"]; !ok { + var zeroVal *bool + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("includeDeprecated")) + if tmp, ok := rawArgs["includeDeprecated"]; ok { + return ec.unmarshalOBoolean2ᚖbool(ctx, tmp) + } + + var zeroVal *bool + return zeroVal, nil +} + +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 := ec.field___Type_enumValues_argsIncludeDeprecated(ctx, rawArgs) + if err != nil { + return nil, err + } + args["includeDeprecated"] = arg0 + return args, nil +} +func (ec *executionContext) field___Type_enumValues_argsIncludeDeprecated( + ctx context.Context, + rawArgs map[string]any, +) (bool, error) { + if _, ok := rawArgs["includeDeprecated"]; !ok { + var zeroVal bool + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("includeDeprecated")) + if tmp, ok := rawArgs["includeDeprecated"]; ok { + return ec.unmarshalOBoolean2bool(ctx, tmp) + } + + var zeroVal bool + return zeroVal, nil +} + +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 := ec.field___Type_fields_argsIncludeDeprecated(ctx, rawArgs) + if err != nil { + return nil, err + } + args["includeDeprecated"] = arg0 + return args, nil +} +func (ec *executionContext) field___Type_fields_argsIncludeDeprecated( + ctx context.Context, + rawArgs map[string]any, +) (bool, error) { + if _, ok := rawArgs["includeDeprecated"]; !ok { + var zeroVal bool + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("includeDeprecated")) + if tmp, ok := rawArgs["includeDeprecated"]; ok { + return ec.unmarshalOBoolean2bool(ctx, tmp) + } + + var zeroVal bool + return zeroVal, nil +} + +// endregion ***************************** args.gotpl ***************************** + +// region ************************** directives.gotpl ************************** + +// endregion ************************** directives.gotpl ************************** + +// region **************************** field.gotpl ***************************** + +func (ec *executionContext) _Article_id(ctx context.Context, field graphql.CollectedField, obj *model.Article) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Article_id(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Article_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Article", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Article_title(ctx context.Context, field graphql.CollectedField, obj *model.Article) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Article_title(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Title, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Article_title(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Article", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Article_body(ctx context.Context, field graphql.CollectedField, obj *model.Article) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Article_body(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Body, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Article_body(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Article", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Article_tags(ctx context.Context, field graphql.CollectedField, obj *model.Article) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Article_tags(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Tags, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]string) + fc.Result = res + return ec.marshalNString2ᚕstringᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Article_tags(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Article", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Article_currentViewer(ctx context.Context, field graphql.CollectedField, obj *model.Article) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Article_currentViewer(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.CurrentViewer, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*model.Viewer) + fc.Result = res + return ec.marshalOViewer2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋarticlesᚋsubgraphᚋmodelᚐViewer(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Article_currentViewer(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Article", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Viewer_id(ctx, field) + case "name": + return ec.fieldContext_Viewer_name(ctx, field) + case "email": + return ec.fieldContext_Viewer_email(ctx, field) + case "recommendedArticles": + return ec.fieldContext_Viewer_recommendedArticles(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Viewer", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Article_personalizedRecommendation(ctx context.Context, field graphql.CollectedField, obj *model.Article) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Article_personalizedRecommendation(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Article().PersonalizedRecommendation(rctx, obj) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Article_personalizedRecommendation(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Article", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Article_relatedArticles(ctx context.Context, field graphql.CollectedField, obj *model.Article) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Article_relatedArticles(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.RelatedArticles, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]*model.Article) + fc.Result = res + return ec.marshalNArticle2ᚕᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋarticlesᚋsubgraphᚋmodelᚐArticleᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Article_relatedArticles(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Article", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Article_id(ctx, field) + case "title": + return ec.fieldContext_Article_title(ctx, field) + case "body": + return ec.fieldContext_Article_body(ctx, field) + case "tags": + return ec.fieldContext_Article_tags(ctx, field) + case "currentViewer": + return ec.fieldContext_Article_currentViewer(ctx, field) + case "personalizedRecommendation": + return ec.fieldContext_Article_personalizedRecommendation(ctx, field) + case "relatedArticles": + return ec.fieldContext_Article_relatedArticles(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Article", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Entity_findArticleByID(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Entity_findArticleByID(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Entity().FindArticleByID(rctx, fc.Args["id"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*model.Article) + fc.Result = res + return ec.marshalNArticle2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋarticlesᚋsubgraphᚋmodelᚐArticle(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Entity_findArticleByID(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Entity", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Article_id(ctx, field) + case "title": + return ec.fieldContext_Article_title(ctx, field) + case "body": + return ec.fieldContext_Article_body(ctx, field) + case "tags": + return ec.fieldContext_Article_tags(ctx, field) + case "currentViewer": + return ec.fieldContext_Article_currentViewer(ctx, field) + case "personalizedRecommendation": + return ec.fieldContext_Article_personalizedRecommendation(ctx, field) + case "relatedArticles": + return ec.fieldContext_Article_relatedArticles(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Article", field.Name) + }, + } + 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_Entity_findArticleByID_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Entity_findPersonalizedByID(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Entity_findPersonalizedByID(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Entity().FindPersonalizedByID(rctx, fc.Args["id"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(model.Personalized) + fc.Result = res + return ec.marshalNPersonalized2githubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋarticlesᚋsubgraphᚋmodelᚐPersonalized(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Entity_findPersonalizedByID(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Entity", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("FieldContext.Child cannot be called on type INTERFACE") + }, + } + 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_Entity_findPersonalizedByID_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Entity_findViewerByID(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Entity_findViewerByID(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Entity().FindViewerByID(rctx, fc.Args["id"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*model.Viewer) + fc.Result = res + return ec.marshalNViewer2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋarticlesᚋsubgraphᚋmodelᚐViewer(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Entity_findViewerByID(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Entity", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Viewer_id(ctx, field) + case "name": + return ec.fieldContext_Viewer_name(ctx, field) + case "email": + return ec.fieldContext_Viewer_email(ctx, field) + case "recommendedArticles": + return ec.fieldContext_Viewer_recommendedArticles(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Viewer", field.Name) + }, + } + 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_Entity_findViewerByID_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query_articles(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query_articles(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().Articles(rctx) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]*model.Article) + fc.Result = res + return ec.marshalNArticle2ᚕᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋarticlesᚋsubgraphᚋmodelᚐArticleᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query_articles(_ 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) { + switch field.Name { + case "id": + return ec.fieldContext_Article_id(ctx, field) + case "title": + return ec.fieldContext_Article_title(ctx, field) + case "body": + return ec.fieldContext_Article_body(ctx, field) + case "tags": + return ec.fieldContext_Article_tags(ctx, field) + case "currentViewer": + return ec.fieldContext_Article_currentViewer(ctx, field) + case "personalizedRecommendation": + return ec.fieldContext_Article_personalizedRecommendation(ctx, field) + case "relatedArticles": + return ec.fieldContext_Article_relatedArticles(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Article", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Query__entities(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query__entities(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.__resolve_entities(ctx, fc.Args["representations"].([]map[string]any)), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]fedruntime.Entity) + fc.Result = res + return ec.marshalN_Entity2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐEntity(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query__entities(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type _Entity does not have child fields") + }, + } + 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__entities_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query__service(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query__service(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.__resolve__service(ctx) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(fedruntime.Service) + fc.Result = res + return ec.marshalN_Service2githubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐService(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query__service(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "sdl": + return ec.fieldContext__Service_sdl(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type _Service", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Query___type(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query___type(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.introspectType(fc.Args["name"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query___type(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + 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___type_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query___schema(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query___schema(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.introspectSchema() + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Schema) + fc.Result = res + return ec.marshalO__Schema2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐSchema(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query___schema(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "description": + return ec.fieldContext___Schema_description(ctx, field) + case "types": + return ec.fieldContext___Schema_types(ctx, field) + case "queryType": + return ec.fieldContext___Schema_queryType(ctx, field) + case "mutationType": + return ec.fieldContext___Schema_mutationType(ctx, field) + case "subscriptionType": + return ec.fieldContext___Schema_subscriptionType(ctx, field) + case "directives": + return ec.fieldContext___Schema_directives(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Schema", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Viewer_id(ctx context.Context, field graphql.CollectedField, obj *model.Viewer) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Viewer_id(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Viewer_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Viewer", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Viewer_name(ctx context.Context, field graphql.CollectedField, obj *model.Viewer) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Viewer_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Viewer_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Viewer", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Viewer_email(ctx context.Context, field graphql.CollectedField, obj *model.Viewer) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Viewer_email(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Email, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Viewer_email(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Viewer", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Viewer_recommendedArticles(ctx context.Context, field graphql.CollectedField, obj *model.Viewer) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Viewer_recommendedArticles(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.RecommendedArticles, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]*model.Article) + fc.Result = res + return ec.marshalNArticle2ᚕᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋarticlesᚋsubgraphᚋmodelᚐArticleᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Viewer_recommendedArticles(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Viewer", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Article_id(ctx, field) + case "title": + return ec.fieldContext_Article_title(ctx, field) + case "body": + return ec.fieldContext_Article_body(ctx, field) + case "tags": + return ec.fieldContext_Article_tags(ctx, field) + case "currentViewer": + return ec.fieldContext_Article_currentViewer(ctx, field) + case "personalizedRecommendation": + return ec.fieldContext_Article_personalizedRecommendation(ctx, field) + case "relatedArticles": + return ec.fieldContext_Article_relatedArticles(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Article", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) __Service_sdl(ctx context.Context, field graphql.CollectedField, obj *fedruntime.Service) (ret graphql.Marshaler) { + fc, err := ec.fieldContext__Service_sdl(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.SDL, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalOString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext__Service_sdl(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "_Service", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Directive_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Directive_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Directive_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Directive_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_isRepeatable(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Directive_isRepeatable(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsRepeatable, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Directive_isRepeatable(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_locations(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Directive_locations(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Locations, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]string) + fc.Result = res + return ec.marshalN__DirectiveLocation2ᚕstringᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Directive_locations(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type __DirectiveLocation does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_args(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Directive_args(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Args, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]introspection.InputValue) + fc.Result = res + return ec.marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Directive_args(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___InputValue_name(ctx, field) + case "description": + return ec.fieldContext___InputValue_description(ctx, field) + case "type": + return ec.fieldContext___InputValue_type(ctx, field) + case "defaultValue": + return ec.fieldContext___InputValue_defaultValue(ctx, field) + case "isDeprecated": + return ec.fieldContext___InputValue_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___InputValue_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __InputValue", field.Name) + }, + } + 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___Directive_args_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) ___EnumValue_name(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___EnumValue_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___EnumValue_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__EnumValue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___EnumValue_description(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___EnumValue_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___EnumValue_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__EnumValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___EnumValue_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___EnumValue_isDeprecated(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsDeprecated(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___EnumValue_isDeprecated(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__EnumValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___EnumValue_deprecationReason(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___EnumValue_deprecationReason(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.DeprecationReason(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___EnumValue_deprecationReason(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__EnumValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_args(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_args(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Args, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]introspection.InputValue) + fc.Result = res + return ec.marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_args(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___InputValue_name(ctx, field) + case "description": + return ec.fieldContext___InputValue_description(ctx, field) + case "type": + return ec.fieldContext___InputValue_type(ctx, field) + case "defaultValue": + return ec.fieldContext___InputValue_defaultValue(ctx, field) + case "isDeprecated": + return ec.fieldContext___InputValue_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___InputValue_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __InputValue", field.Name) + }, + } + 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___Field_args_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) ___Field_type(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_type(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Type, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_type(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_isDeprecated(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsDeprecated(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_isDeprecated(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_deprecationReason(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_deprecationReason(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.DeprecationReason(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_deprecationReason(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_name(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_description(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_type(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_type(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Type, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_type(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_defaultValue(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_defaultValue(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.DefaultValue, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_defaultValue(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_isDeprecated(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsDeprecated(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_isDeprecated(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_deprecationReason(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_deprecationReason(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.DeprecationReason(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_deprecationReason(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_types(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_types(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Types(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]introspection.Type) + fc.Result = res + return ec.marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_types(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_queryType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_queryType(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.QueryType(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_queryType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_mutationType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_mutationType(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.MutationType(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_mutationType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_subscriptionType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_subscriptionType(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.SubscriptionType(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_subscriptionType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_directives(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_directives(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Directives(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]introspection.Directive) + fc.Result = res + return ec.marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirectiveᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_directives(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___Directive_name(ctx, field) + case "description": + return ec.fieldContext___Directive_description(ctx, field) + case "isRepeatable": + return ec.fieldContext___Directive_isRepeatable(ctx, field) + case "locations": + return ec.fieldContext___Directive_locations(ctx, field) + case "args": + return ec.fieldContext___Directive_args(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Directive", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_kind(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_kind(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Kind(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalN__TypeKind2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_kind(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type __TypeKind does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_specifiedByURL(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_specifiedByURL(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.SpecifiedByURL(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_specifiedByURL(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_fields(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_fields(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Fields(fc.Args["includeDeprecated"].(bool)), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.Field) + fc.Result = res + return ec.marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐFieldᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_fields(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___Field_name(ctx, field) + case "description": + return ec.fieldContext___Field_description(ctx, field) + case "args": + return ec.fieldContext___Field_args(ctx, field) + case "type": + return ec.fieldContext___Field_type(ctx, field) + case "isDeprecated": + return ec.fieldContext___Field_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___Field_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Field", field.Name) + }, + } + 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_fields_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) ___Type_interfaces(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_interfaces(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Interfaces(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_interfaces(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_possibleTypes(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_possibleTypes(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.PossibleTypes(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_possibleTypes(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_enumValues(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_enumValues(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.EnumValues(fc.Args["includeDeprecated"].(bool)), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.EnumValue) + fc.Result = res + return ec.marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValueᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_enumValues(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___EnumValue_name(ctx, field) + case "description": + return ec.fieldContext___EnumValue_description(ctx, field) + case "isDeprecated": + return ec.fieldContext___EnumValue_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___EnumValue_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __EnumValue", field.Name) + }, + } + 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_enumValues_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) ___Type_inputFields(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_inputFields(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.InputFields(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.InputValue) + fc.Result = res + return ec.marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_inputFields(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___InputValue_name(ctx, field) + case "description": + return ec.fieldContext___InputValue_description(ctx, field) + case "type": + return ec.fieldContext___InputValue_type(ctx, field) + case "defaultValue": + return ec.fieldContext___InputValue_defaultValue(ctx, field) + case "isDeprecated": + return ec.fieldContext___InputValue_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___InputValue_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __InputValue", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_ofType(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_ofType(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.OfType(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_ofType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_isOneOf(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_isOneOf(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsOneOf(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalOBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_isOneOf(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +// endregion **************************** field.gotpl ***************************** + +// region **************************** input.gotpl ***************************** + +// endregion **************************** input.gotpl ***************************** + +// region ************************** interface.gotpl *************************** + +func (ec *executionContext) _Personalized(ctx context.Context, sel ast.SelectionSet, obj model.Personalized) graphql.Marshaler { + switch obj := (obj).(type) { + case nil: + return graphql.Null + case model.Article: + return ec._Article(ctx, sel, &obj) + case *model.Article: + if obj == nil { + return graphql.Null + } + return ec._Article(ctx, sel, obj) + default: + panic(fmt.Errorf("unexpected type %T", obj)) + } +} + +func (ec *executionContext) __Entity(ctx context.Context, sel ast.SelectionSet, obj fedruntime.Entity) graphql.Marshaler { + switch obj := (obj).(type) { + case nil: + return graphql.Null + case model.Article: + return ec._Article(ctx, sel, &obj) + case *model.Article: + if obj == nil { + return graphql.Null + } + return ec._Article(ctx, sel, obj) + case model.Viewer: + return ec._Viewer(ctx, sel, &obj) + case *model.Viewer: + if obj == nil { + return graphql.Null + } + return ec._Viewer(ctx, sel, obj) + default: + panic(fmt.Errorf("unexpected type %T", obj)) + } +} + +// endregion ************************** interface.gotpl *************************** + +// region **************************** object.gotpl **************************** + +var articleImplementors = []string{"Article", "Personalized", "_Entity"} + +func (ec *executionContext) _Article(ctx context.Context, sel ast.SelectionSet, obj *model.Article) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, articleImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Article") + case "id": + out.Values[i] = ec._Article_id(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "title": + out.Values[i] = ec._Article_title(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "body": + out.Values[i] = ec._Article_body(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "tags": + out.Values[i] = ec._Article_tags(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "currentViewer": + out.Values[i] = ec._Article_currentViewer(ctx, field, obj) + case "personalizedRecommendation": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Article_personalizedRecommendation(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + if field.Deferrable != nil { + dfs, ok := deferred[field.Deferrable.Label] + di := 0 + if ok { + dfs.AddField(field) + di = len(dfs.Values) - 1 + } else { + dfs = graphql.NewFieldSet([]graphql.CollectedField{field}) + deferred[field.Deferrable.Label] = dfs + } + dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler { + return innerFunc(ctx, dfs) + }) + + // don't run the out.Concurrently() call below + out.Values[i] = graphql.Null + continue + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + case "relatedArticles": + out.Values[i] = ec._Article_relatedArticles(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var entityImplementors = []string{"Entity"} + +func (ec *executionContext) _Entity(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, entityImplementors) + ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ + Object: "Entity", + }) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ + Object: field.Name, + Field: field, + }) + + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Entity") + case "findArticleByID": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Entity_findArticleByID(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "findPersonalizedByID": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Entity_findPersonalizedByID(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "findViewerByID": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Entity_findViewerByID(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var queryImplementors = []string{"Query"} + +func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, queryImplementors) + ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ + Object: "Query", + }) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ + Object: field.Name, + Field: field, + }) + + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Query") + case "articles": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_articles(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "_entities": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query__entities(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "_service": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query__service(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "__type": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Query___type(ctx, field) + }) + case "__schema": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Query___schema(ctx, field) + }) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var viewerImplementors = []string{"Viewer", "_Entity"} + +func (ec *executionContext) _Viewer(ctx context.Context, sel ast.SelectionSet, obj *model.Viewer) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, viewerImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Viewer") + case "id": + out.Values[i] = ec._Viewer_id(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "name": + out.Values[i] = ec._Viewer_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "email": + out.Values[i] = ec._Viewer_email(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "recommendedArticles": + out.Values[i] = ec._Viewer_recommendedArticles(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 + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var _ServiceImplementors = []string{"_Service"} + +func (ec *executionContext) __Service(ctx context.Context, sel ast.SelectionSet, obj *fedruntime.Service) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, _ServiceImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("_Service") + case "sdl": + out.Values[i] = ec.__Service_sdl(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __DirectiveImplementors = []string{"__Directive"} + +func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionSet, obj *introspection.Directive) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __DirectiveImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__Directive") + case "name": + out.Values[i] = ec.___Directive_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "description": + out.Values[i] = ec.___Directive_description(ctx, field, obj) + case "isRepeatable": + out.Values[i] = ec.___Directive_isRepeatable(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "locations": + out.Values[i] = ec.___Directive_locations(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "args": + out.Values[i] = ec.___Directive_args(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 + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __EnumValueImplementors = []string{"__EnumValue"} + +func (ec *executionContext) ___EnumValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.EnumValue) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __EnumValueImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__EnumValue") + case "name": + out.Values[i] = ec.___EnumValue_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "description": + out.Values[i] = ec.___EnumValue_description(ctx, field, obj) + case "isDeprecated": + out.Values[i] = ec.___EnumValue_isDeprecated(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "deprecationReason": + out.Values[i] = ec.___EnumValue_deprecationReason(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __FieldImplementors = []string{"__Field"} + +func (ec *executionContext) ___Field(ctx context.Context, sel ast.SelectionSet, obj *introspection.Field) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __FieldImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__Field") + case "name": + out.Values[i] = ec.___Field_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "description": + out.Values[i] = ec.___Field_description(ctx, field, obj) + case "args": + out.Values[i] = ec.___Field_args(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "type": + out.Values[i] = ec.___Field_type(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "isDeprecated": + out.Values[i] = ec.___Field_isDeprecated(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "deprecationReason": + out.Values[i] = ec.___Field_deprecationReason(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __InputValueImplementors = []string{"__InputValue"} + +func (ec *executionContext) ___InputValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.InputValue) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __InputValueImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__InputValue") + case "name": + out.Values[i] = ec.___InputValue_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "description": + out.Values[i] = ec.___InputValue_description(ctx, field, obj) + case "type": + out.Values[i] = ec.___InputValue_type(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "defaultValue": + out.Values[i] = ec.___InputValue_defaultValue(ctx, field, obj) + case "isDeprecated": + out.Values[i] = ec.___InputValue_isDeprecated(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "deprecationReason": + out.Values[i] = ec.___InputValue_deprecationReason(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __SchemaImplementors = []string{"__Schema"} + +func (ec *executionContext) ___Schema(ctx context.Context, sel ast.SelectionSet, obj *introspection.Schema) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __SchemaImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__Schema") + case "description": + out.Values[i] = ec.___Schema_description(ctx, field, obj) + case "types": + out.Values[i] = ec.___Schema_types(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "queryType": + out.Values[i] = ec.___Schema_queryType(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "mutationType": + out.Values[i] = ec.___Schema_mutationType(ctx, field, obj) + case "subscriptionType": + out.Values[i] = ec.___Schema_subscriptionType(ctx, field, obj) + case "directives": + out.Values[i] = ec.___Schema_directives(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 + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __TypeImplementors = []string{"__Type"} + +func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, obj *introspection.Type) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __TypeImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__Type") + case "kind": + out.Values[i] = ec.___Type_kind(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "name": + out.Values[i] = ec.___Type_name(ctx, field, obj) + case "description": + out.Values[i] = ec.___Type_description(ctx, field, obj) + case "specifiedByURL": + out.Values[i] = ec.___Type_specifiedByURL(ctx, field, obj) + case "fields": + out.Values[i] = ec.___Type_fields(ctx, field, obj) + case "interfaces": + out.Values[i] = ec.___Type_interfaces(ctx, field, obj) + case "possibleTypes": + out.Values[i] = ec.___Type_possibleTypes(ctx, field, obj) + case "enumValues": + out.Values[i] = ec.___Type_enumValues(ctx, field, obj) + case "inputFields": + out.Values[i] = ec.___Type_inputFields(ctx, field, obj) + case "ofType": + out.Values[i] = ec.___Type_ofType(ctx, field, obj) + case "isOneOf": + out.Values[i] = ec.___Type_isOneOf(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +// endregion **************************** object.gotpl **************************** + +// region ***************************** type.gotpl ***************************** + +func (ec *executionContext) marshalNArticle2githubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋarticlesᚋsubgraphᚋmodelᚐArticle(ctx context.Context, sel ast.SelectionSet, v model.Article) graphql.Marshaler { + return ec._Article(ctx, sel, &v) +} + +func (ec *executionContext) marshalNArticle2ᚕᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋarticlesᚋsubgraphᚋmodelᚐArticleᚄ(ctx context.Context, sel ast.SelectionSet, v []*model.Article) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalNArticle2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋarticlesᚋsubgraphᚋmodelᚐArticle(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalNArticle2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋarticlesᚋsubgraphᚋmodelᚐArticle(ctx context.Context, sel ast.SelectionSet, v *model.Article) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._Article(ctx, sel, v) +} + +func (ec *executionContext) unmarshalNBoolean2bool(ctx context.Context, v any) (bool, error) { + res, err := graphql.UnmarshalBoolean(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNBoolean2bool(ctx context.Context, sel ast.SelectionSet, v bool) graphql.Marshaler { + _ = sel + res := graphql.MarshalBoolean(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNFieldSet2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNFieldSet2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNID2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalID(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNID2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalID(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) marshalNPersonalized2githubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋarticlesᚋsubgraphᚋmodelᚐPersonalized(ctx context.Context, sel ast.SelectionSet, v model.Personalized) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._Personalized(ctx, sel, v) +} + +func (ec *executionContext) unmarshalNString2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNString2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNString2ᚕstringᚄ(ctx context.Context, v any) ([]string, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNString2string(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalNString2ᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v []string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNString2string(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalNViewer2githubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋarticlesᚋsubgraphᚋmodelᚐViewer(ctx context.Context, sel ast.SelectionSet, v model.Viewer) graphql.Marshaler { + return ec._Viewer(ctx, sel, &v) +} + +func (ec *executionContext) marshalNViewer2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋarticlesᚋsubgraphᚋmodelᚐViewer(ctx context.Context, sel ast.SelectionSet, v *model.Viewer) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._Viewer(ctx, sel, v) +} + +func (ec *executionContext) unmarshalN_Any2map(ctx context.Context, v any) (map[string]any, error) { + res, err := graphql.UnmarshalMap(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalN_Any2map(ctx context.Context, sel ast.SelectionSet, v map[string]any) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + _ = sel + res := graphql.MarshalMap(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalN_Any2ᚕmapᚄ(ctx context.Context, v any) ([]map[string]any, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([]map[string]any, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalN_Any2map(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalN_Any2ᚕmapᚄ(ctx context.Context, sel ast.SelectionSet, v []map[string]any) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalN_Any2map(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalN_Entity2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐEntity(ctx context.Context, sel ast.SelectionSet, v []fedruntime.Entity) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalO_Entity2githubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐEntity(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + return ret +} + +func (ec *executionContext) marshalN_Service2githubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐService(ctx context.Context, sel ast.SelectionSet, v fedruntime.Service) graphql.Marshaler { + return ec.__Service(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__Directive2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirective(ctx context.Context, sel ast.SelectionSet, v introspection.Directive) graphql.Marshaler { + return ec.___Directive(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirectiveᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.Directive) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__Directive2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirective(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalN__DirectiveLocation2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalN__DirectiveLocation2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalN__DirectiveLocation2ᚕstringᚄ(ctx context.Context, v any) ([]string, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalN__DirectiveLocation2string(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalN__DirectiveLocation2ᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v []string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__DirectiveLocation2string(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalN__EnumValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValue(ctx context.Context, sel ast.SelectionSet, v introspection.EnumValue) graphql.Marshaler { + return ec.___EnumValue(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__Field2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐField(ctx context.Context, sel ast.SelectionSet, v introspection.Field) graphql.Marshaler { + return ec.___Field(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__InputValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValue(ctx context.Context, sel ast.SelectionSet, v introspection.InputValue) graphql.Marshaler { + return ec.___InputValue(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.InputValue) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__InputValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValue(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +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) +} + +func (ec *executionContext) marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.Type) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__Type2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx context.Context, sel ast.SelectionSet, v *introspection.Type) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec.___Type(ctx, sel, v) +} + +func (ec *executionContext) unmarshalN__TypeKind2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalN__TypeKind2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNfederation__Policy2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNfederation__Policy2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNfederation__Policy2ᚕstringᚄ(ctx context.Context, v any) ([]string, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNfederation__Policy2string(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalNfederation__Policy2ᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v []string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNfederation__Policy2string(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalNfederation__Policy2ᚕᚕstringᚄ(ctx context.Context, v any) ([][]string, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([][]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNfederation__Policy2ᚕstringᚄ(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalNfederation__Policy2ᚕᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v [][]string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNfederation__Policy2ᚕstringᚄ(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalNfederation__Scope2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNfederation__Scope2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNfederation__Scope2ᚕstringᚄ(ctx context.Context, v any) ([]string, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNfederation__Scope2string(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalNfederation__Scope2ᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v []string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNfederation__Scope2string(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalNfederation__Scope2ᚕᚕstringᚄ(ctx context.Context, v any) ([][]string, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([][]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNfederation__Scope2ᚕstringᚄ(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalNfederation__Scope2ᚕᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v [][]string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNfederation__Scope2ᚕstringᚄ(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalOBoolean2bool(ctx context.Context, v any) (bool, error) { + res, err := graphql.UnmarshalBoolean(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOBoolean2bool(ctx context.Context, sel ast.SelectionSet, v bool) graphql.Marshaler { + _ = sel + _ = ctx + res := graphql.MarshalBoolean(v) + return res +} + +func (ec *executionContext) unmarshalOBoolean2ᚖbool(ctx context.Context, v any) (*bool, error) { + if v == nil { + return nil, nil + } + res, err := graphql.UnmarshalBoolean(v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOBoolean2ᚖbool(ctx context.Context, sel ast.SelectionSet, v *bool) graphql.Marshaler { + if v == nil { + return graphql.Null + } + _ = sel + _ = ctx + res := graphql.MarshalBoolean(*v) + return res +} + +func (ec *executionContext) unmarshalOString2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOString2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + _ = ctx + res := graphql.MarshalString(v) + return res +} + +func (ec *executionContext) unmarshalOString2ᚕstringᚄ(ctx context.Context, v any) ([]string, error) { + if v == nil { + return nil, nil + } + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNString2string(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalOString2ᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v []string) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNString2string(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalOString2ᚖstring(ctx context.Context, v any) (*string, error) { + if v == nil { + return nil, nil + } + res, err := graphql.UnmarshalString(v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOString2ᚖstring(ctx context.Context, sel ast.SelectionSet, v *string) graphql.Marshaler { + if v == nil { + return graphql.Null + } + _ = sel + _ = ctx + res := graphql.MarshalString(*v) + return res +} + +func (ec *executionContext) marshalOViewer2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋarticlesᚋsubgraphᚋmodelᚐViewer(ctx context.Context, sel ast.SelectionSet, v *model.Viewer) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._Viewer(ctx, sel, v) +} + +func (ec *executionContext) marshalO_Entity2githubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐEntity(ctx context.Context, sel ast.SelectionSet, v fedruntime.Entity) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec.__Entity(ctx, sel, v) +} + +func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.EnumValue) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__EnumValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValue(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐFieldᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.Field) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__Field2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐField(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.InputValue) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__InputValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValue(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + 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 + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__Type2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +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 + } + return ec.___Type(ctx, sel, v) +} + +// endregion ***************************** type.gotpl ***************************** diff --git a/demo/pkg/subgraphs/cachetest/articles/subgraph/generated/staticcheck.conf b/demo/pkg/subgraphs/cachetest/articles/subgraph/generated/staticcheck.conf new file mode 100644 index 0000000000..582953a07e --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/articles/subgraph/generated/staticcheck.conf @@ -0,0 +1,2 @@ +# This is meant as a workaround to skip staticcheck checks for generated code +checks = ["all", "-SA4004", "-ST1000"] diff --git a/demo/pkg/subgraphs/cachetest/articles/subgraph/model/models_gen.go b/demo/pkg/subgraphs/cachetest/articles/subgraph/model/models_gen.go new file mode 100644 index 0000000000..71377788b6 --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/articles/subgraph/model/models_gen.go @@ -0,0 +1,36 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package model + +type Personalized interface { + IsEntity() + IsPersonalized() + GetID() string +} + +type Article struct { + ID string `json:"id"` + Title string `json:"title"` + Body string `json:"body"` + Tags []string `json:"tags"` + CurrentViewer *Viewer `json:"currentViewer,omitempty"` + PersonalizedRecommendation string `json:"personalizedRecommendation"` + RelatedArticles []*Article `json:"relatedArticles"` +} + +func (Article) IsPersonalized() {} +func (this Article) GetID() string { return this.ID } + +func (Article) IsEntity() {} + +type Query struct { +} + +type Viewer struct { + ID string `json:"id"` + Name string `json:"name"` + Email string `json:"email"` + RecommendedArticles []*Article `json:"recommendedArticles"` +} + +func (Viewer) IsEntity() {} diff --git a/demo/pkg/subgraphs/cachetest/articles/subgraph/resolver.go b/demo/pkg/subgraphs/cachetest/articles/subgraph/resolver.go new file mode 100644 index 0000000000..c1da1a4335 --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/articles/subgraph/resolver.go @@ -0,0 +1,7 @@ +package subgraph + +// This file will not be regenerated automatically. +// +// It serves as dependency injection for your app, add any dependencies you require here. + +type Resolver struct{} diff --git a/demo/pkg/subgraphs/cachetest/articles/subgraph/schema.graphqls b/demo/pkg/subgraphs/cachetest/articles/subgraph/schema.graphqls new file mode 100644 index 0000000000..1f25b3d917 --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/articles/subgraph/schema.graphqls @@ -0,0 +1,49 @@ +extend schema + @link( + url: "https://specs.apollo.dev/federation/v2.5" + import: ["@key", "@external", "@requires"] + ) + +type Query { + articles: [Article!]! +} + +interface Personalized @key(fields: "id") { + id: ID! +} + +# Extends Viewer with an edge back into articles land. +# The @key forces sequencing: the articles _entities fetch for +# recommendedArticles needs viewer.id from the prior viewer fetch, so the +# planner cannot parallelize it with the root Query.currentViewer call. +# +# name and email are declared @external because Article.personalizedRecommendation +# @requires references them. Composition fails without these declarations. +type Viewer @key(fields: "id") { + id: ID! + name: String! @external + email: String! @external + recommendedArticles: [Article!]! +} + +type Article implements Personalized @key(fields: "id") { + id: ID! + title: String! + body: String! + tags: [String!]! + # Article.currentViewer is provided by the viewer subgraph via the + # Personalized @interfaceObject. It is @external here so @requires can + # reference it. + currentViewer: Viewer @external + # @requires a WIDER selection ({id, name, email}) than the root query + # will ask for ({id, name}). This is the widening-miss trigger that the + # test asserts: the coordinate L1 was populated with {id, name}, so the + # follow-up _entities(Personalized) fetch fails the widening check and + # refetches the viewer subgraph. + personalizedRecommendation: String! + @requires(fields: "currentViewer { id name email }") + # relatedArticles enables nested selection of Article entities so tests + # can exercise @openfed__requestScoped deduplication across multiple nesting + # levels (Article.currentViewer selected inline at more than one depth). + relatedArticles: [Article!]! +} diff --git a/demo/pkg/subgraphs/cachetest/articles/subgraph/schema.resolvers.go b/demo/pkg/subgraphs/cachetest/articles/subgraph/schema.resolvers.go new file mode 100644 index 0000000000..2457bfb73d --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/articles/subgraph/schema.resolvers.go @@ -0,0 +1,44 @@ +package subgraph + +// 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.76 + +import ( + "context" + "fmt" + + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachetest/articles/subgraph/generated" + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachetest/articles/subgraph/model" +) + +// PersonalizedRecommendation is the resolver for the personalizedRecommendation field. +func (r *articleResolver) PersonalizedRecommendation(ctx context.Context, obj *model.Article) (string, error) { + // obj.Title is set by FindArticleByID (looked up from articleFixtures). + // obj.CurrentViewer is populated by PopulateArticleRequires from the + // @requires representation. Including email in the returned string lets + // the test assert that the wider {id, name, email} selection actually + // reached this resolver. + if obj.CurrentViewer == nil { + return "no viewer", nil + } + return fmt.Sprintf("%s, recommended for %s <%s>", obj.Title, obj.CurrentViewer.Name, obj.CurrentViewer.Email), nil +} + +// Articles is the resolver for the articles field. +func (r *queryResolver) Articles(ctx context.Context) ([]*model.Article, error) { + articles := make([]*model.Article, 0, len(articleFixtures)) + for _, id := range allArticleIDs() { + articles = append(articles, buildArticle(id)) + } + return articles, nil +} + +// Article returns generated.ArticleResolver implementation. +func (r *Resolver) Article() generated.ArticleResolver { return &articleResolver{r} } + +// Query returns generated.QueryResolver implementation. +func (r *Resolver) Query() generated.QueryResolver { return &queryResolver{r} } + +type articleResolver struct{ *Resolver } +type queryResolver struct{ *Resolver } diff --git a/demo/pkg/subgraphs/cachetest/articlesmeta/articlesmeta.go b/demo/pkg/subgraphs/cachetest/articlesmeta/articlesmeta.go new file mode 100644 index 0000000000..452c82bab1 --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/articlesmeta/articlesmeta.go @@ -0,0 +1,14 @@ +package articlesmeta + +import ( + "github.com/99designs/gqlgen/graphql" + + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachetest/articlesmeta/subgraph" + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachetest/articlesmeta/subgraph/generated" +) + +func NewSchema() graphql.ExecutableSchema { + return generated.NewExecutableSchema(generated.Config{ + Resolvers: &subgraph.Resolver{}, + }) +} diff --git a/demo/pkg/subgraphs/cachetest/articlesmeta/generate.go b/demo/pkg/subgraphs/cachetest/articlesmeta/generate.go new file mode 100644 index 0000000000..1a6605cfc8 --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/articlesmeta/generate.go @@ -0,0 +1,3 @@ +//go:generate go run github.com/99designs/gqlgen generate + +package articlesmeta diff --git a/demo/pkg/subgraphs/cachetest/articlesmeta/gqlgen.yml b/demo/pkg/subgraphs/cachetest/articlesmeta/gqlgen.yml new file mode 100644 index 0000000000..b4a796a814 --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/articlesmeta/gqlgen.yml @@ -0,0 +1,33 @@ +schema: + - subgraph/*.graphqls + +exec: + filename: subgraph/generated/generated.go + package: generated + +federation: + filename: subgraph/generated/federation.go + package: generated + version: 2 + +model: + filename: subgraph/model/models_gen.go + package: model + +resolver: + layout: follow-schema + dir: subgraph + package: subgraph + +models: + ID: + model: + - github.com/99designs/gqlgen/graphql.ID + - github.com/99designs/gqlgen/graphql.Int + - github.com/99designs/gqlgen/graphql.Int64 + - github.com/99designs/gqlgen/graphql.Int32 + Int: + model: + - github.com/99designs/gqlgen/graphql.Int + - github.com/99designs/gqlgen/graphql.Int64 + - github.com/99designs/gqlgen/graphql.Int32 diff --git a/demo/pkg/subgraphs/cachetest/articlesmeta/subgraph/data.go b/demo/pkg/subgraphs/cachetest/articlesmeta/subgraph/data.go new file mode 100644 index 0000000000..966312452e --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/articlesmeta/subgraph/data.go @@ -0,0 +1,25 @@ +package subgraph + +type articleMetaFixture struct { + ViewCount int + Rating float64 + ReviewSummary string +} + +var articleMetaFixtures = map[string]articleMetaFixture{ + "a1": { + ViewCount: 128, + Rating: 4.8, + ReviewSummary: "Strong overview of federation tradeoffs and rollout patterns.", + }, + "a2": { + ViewCount: 256, + Rating: 4.6, + ReviewSummary: "Practical caching patterns with clear latency examples.", + }, + "a3": { + ViewCount: 384, + Rating: 4.9, + ReviewSummary: "Concrete request-scoped guidance with useful caveats.", + }, +} diff --git a/demo/pkg/subgraphs/cachetest/articlesmeta/subgraph/entity.resolvers.go b/demo/pkg/subgraphs/cachetest/articlesmeta/subgraph/entity.resolvers.go new file mode 100644 index 0000000000..5b918101f4 --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/articlesmeta/subgraph/entity.resolvers.go @@ -0,0 +1,28 @@ +package subgraph + +// 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.76 + +import ( + "context" + + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachetest/articlesmeta/subgraph/generated" + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachetest/articlesmeta/subgraph/model" +) + +// FindArticleByID is the resolver for the findArticleByID field. +func (r *entityResolver) FindArticleByID(ctx context.Context, id string) (*model.Article, error) { + fixture := articleMetaFixtures[id] + return &model.Article{ + ID: id, + ViewCount: fixture.ViewCount, + Rating: fixture.Rating, + ReviewSummary: fixture.ReviewSummary, + }, nil +} + +// Entity returns generated.EntityResolver implementation. +func (r *Resolver) Entity() generated.EntityResolver { return &entityResolver{r} } + +type entityResolver struct{ *Resolver } diff --git a/demo/pkg/subgraphs/cachetest/articlesmeta/subgraph/generated/federation.go b/demo/pkg/subgraphs/cachetest/articlesmeta/subgraph/generated/federation.go new file mode 100644 index 0000000000..ab35491be7 --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/articlesmeta/subgraph/generated/federation.go @@ -0,0 +1,234 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package generated + +import ( + "context" + "errors" + "fmt" + "strings" + "sync" + + "github.com/99designs/gqlgen/plugin/federation/fedruntime" +) + +var ( + ErrUnknownType = errors.New("unknown type") + ErrTypeNotFound = errors.New("type not found") +) + +func (ec *executionContext) __resolve__service(ctx context.Context) (fedruntime.Service, error) { + if ec.DisableIntrospection { + return fedruntime.Service{}, errors.New("federated introspection disabled") + } + + var sdl []string + + for _, src := range sources { + if src.BuiltIn { + continue + } + sdl = append(sdl, src.Input) + } + + return fedruntime.Service{ + SDL: strings.Join(sdl, "\n"), + }, nil +} + +func (ec *executionContext) __resolve_entities(ctx context.Context, representations []map[string]any) []fedruntime.Entity { + list := make([]fedruntime.Entity, len(representations)) + + repsMap := ec.buildRepresentationGroups(ctx, representations) + + switch len(repsMap) { + case 0: + return list + case 1: + for typeName, reps := range repsMap { + ec.resolveEntityGroup(ctx, typeName, reps, list) + } + return list + default: + var g sync.WaitGroup + g.Add(len(repsMap)) + for typeName, reps := range repsMap { + go func(typeName string, reps []EntityWithIndex) { + ec.resolveEntityGroup(ctx, typeName, reps, list) + g.Done() + }(typeName, reps) + } + g.Wait() + return list + } +} + +type EntityWithIndex struct { + // The index in the original representation array + index int + entity EntityRepresentation +} + +// EntityRepresentation is the JSON representation of an entity sent by the Router +// used as the inputs for us to resolve. +// +// We make it a map because we know the top level JSON is always an object. +type EntityRepresentation map[string]any + +// We group entities by typename so that we can parallelize their resolution. +// This is particularly helpful when there are entity groups in multi mode. +func (ec *executionContext) buildRepresentationGroups( + ctx context.Context, + representations []map[string]any, +) map[string][]EntityWithIndex { + repsMap := make(map[string][]EntityWithIndex) + for i, rep := range representations { + typeName, ok := rep["__typename"].(string) + if !ok { + // If there is no __typename, we just skip the representation; + // we just won't be resolving these unknown types. + ec.Error(ctx, errors.New("__typename must be an existing string")) + continue + } + + repsMap[typeName] = append(repsMap[typeName], EntityWithIndex{ + index: i, + entity: rep, + }) + } + + return repsMap +} + +func (ec *executionContext) resolveEntityGroup( + ctx context.Context, + typeName string, + reps []EntityWithIndex, + list []fedruntime.Entity, +) { + if isMulti(typeName) { + err := ec.resolveManyEntities(ctx, typeName, reps, list) + if err != nil { + ec.Error(ctx, err) + } + } else { + // if there are multiple entities to resolve, parallelize (similar to + // graphql.FieldSet.Dispatch) + var e sync.WaitGroup + e.Add(len(reps)) + for i, rep := range reps { + i, rep := i, rep + go func(i int, rep EntityWithIndex) { + entity, err := ec.resolveEntity(ctx, typeName, rep.entity) + if err != nil { + ec.Error(ctx, err) + } else { + list[rep.index] = entity + } + e.Done() + }(i, rep) + } + e.Wait() + } +} + +func isMulti(typeName string) bool { + switch typeName { + default: + return false + } +} + +func (ec *executionContext) resolveEntity( + ctx context.Context, + typeName string, + rep EntityRepresentation, +) (e fedruntime.Entity, err error) { + // we need to do our own panic handling, because we may be called in a + // goroutine, where the usual panic handling can't catch us + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + } + }() + + switch typeName { + case "Article": + resolverName, err := entityResolverNameForArticle(ctx, rep) + if err != nil { + return nil, fmt.Errorf(`finding resolver for Entity "Article": %w`, err) + } + switch resolverName { + + case "findArticleByID": + id0, err := ec.unmarshalNID2string(ctx, rep["id"]) + if err != nil { + return nil, fmt.Errorf(`unmarshalling param 0 for findArticleByID(): %w`, err) + } + entity, err := ec.resolvers.Entity().FindArticleByID(ctx, id0) + if err != nil { + return nil, fmt.Errorf(`resolving Entity "Article": %w`, err) + } + + return entity, nil + } + + } + return nil, fmt.Errorf("%w: %s", ErrUnknownType, typeName) +} + +func (ec *executionContext) resolveManyEntities( + ctx context.Context, + typeName string, + reps []EntityWithIndex, + list []fedruntime.Entity, +) (err error) { + // we need to do our own panic handling, because we may be called in a + // goroutine, where the usual panic handling can't catch us + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + } + }() + + switch typeName { + + default: + return errors.New("unknown type: " + typeName) + } +} + +func entityResolverNameForArticle(ctx context.Context, rep EntityRepresentation) (string, error) { + // we collect errors because a later entity resolver may work fine + // when an entity has multiple keys + entityResolverErrs := []error{} + for { + var ( + m EntityRepresentation + val any + ok bool + ) + _ = val + // if all of the KeyFields values for this resolver are null, + // we shouldn't use use it + allNull := true + m = rep + val, ok = m["id"] + if !ok { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to missing Key Field \"id\" for Article", ErrTypeNotFound)) + break + } + if allNull { + allNull = val == nil + } + if allNull { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to all null value KeyFields for Article", ErrTypeNotFound)) + break + } + return "findArticleByID", nil + } + return "", fmt.Errorf("%w for Article due to %v", ErrTypeNotFound, + errors.Join(entityResolverErrs...).Error()) +} diff --git a/demo/pkg/subgraphs/cachetest/articlesmeta/subgraph/generated/generated.go b/demo/pkg/subgraphs/cachetest/articlesmeta/subgraph/generated/generated.go new file mode 100644 index 0000000000..614484a01e --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/articlesmeta/subgraph/generated/generated.go @@ -0,0 +1,4529 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package generated + +import ( + "bytes" + "context" + "errors" + "fmt" + "strconv" + "sync" + "sync/atomic" + + "github.com/99designs/gqlgen/graphql" + "github.com/99designs/gqlgen/graphql/introspection" + "github.com/99designs/gqlgen/plugin/federation/fedruntime" + gqlparser "github.com/vektah/gqlparser/v2" + "github.com/vektah/gqlparser/v2/ast" + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachetest/articlesmeta/subgraph/model" +) + +// region ************************** generated!.gotpl ************************** + +// NewExecutableSchema creates an ExecutableSchema from the ResolverRoot interface. +func NewExecutableSchema(cfg Config) graphql.ExecutableSchema { + return &executableSchema{ + schema: cfg.Schema, + resolvers: cfg.Resolvers, + directives: cfg.Directives, + complexity: cfg.Complexity, + } +} + +type Config struct { + Schema *ast.Schema + Resolvers ResolverRoot + Directives DirectiveRoot + Complexity ComplexityRoot +} + +type ResolverRoot interface { + Entity() EntityResolver +} + +type DirectiveRoot struct { +} + +type ComplexityRoot struct { + Article struct { + ID func(childComplexity int) int + Rating func(childComplexity int) int + ReviewSummary func(childComplexity int) int + ViewCount func(childComplexity int) int + } + + Entity struct { + FindArticleByID func(childComplexity int, id string) int + } + + Query struct { + __resolve__service func(childComplexity int) int + __resolve_entities func(childComplexity int, representations []map[string]any) int + } + + _Service struct { + SDL func(childComplexity int) int + } +} + +type EntityResolver interface { + FindArticleByID(ctx context.Context, id string) (*model.Article, error) +} + +type executableSchema struct { + schema *ast.Schema + resolvers ResolverRoot + directives DirectiveRoot + complexity ComplexityRoot +} + +func (e *executableSchema) Schema() *ast.Schema { + if e.schema != nil { + return e.schema + } + return parsedSchema +} + +func (e *executableSchema) Complexity(ctx context.Context, typeName, field string, childComplexity int, rawArgs map[string]any) (int, bool) { + ec := executionContext{nil, e, 0, 0, nil} + _ = ec + switch typeName + "." + field { + + case "Article.id": + if e.complexity.Article.ID == nil { + break + } + + return e.complexity.Article.ID(childComplexity), true + + case "Article.rating": + if e.complexity.Article.Rating == nil { + break + } + + return e.complexity.Article.Rating(childComplexity), true + + case "Article.reviewSummary": + if e.complexity.Article.ReviewSummary == nil { + break + } + + return e.complexity.Article.ReviewSummary(childComplexity), true + + case "Article.viewCount": + if e.complexity.Article.ViewCount == nil { + break + } + + return e.complexity.Article.ViewCount(childComplexity), true + + case "Entity.findArticleByID": + if e.complexity.Entity.FindArticleByID == nil { + break + } + + args, err := ec.field_Entity_findArticleByID_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Entity.FindArticleByID(childComplexity, args["id"].(string)), true + + case "Query._service": + if e.complexity.Query.__resolve__service == nil { + break + } + + return e.complexity.Query.__resolve__service(childComplexity), true + + case "Query._entities": + if e.complexity.Query.__resolve_entities == nil { + break + } + + args, err := ec.field_Query__entities_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.__resolve_entities(childComplexity, args["representations"].([]map[string]any)), true + + case "_Service.sdl": + if e.complexity._Service.SDL == nil { + break + } + + return e.complexity._Service.SDL(childComplexity), true + + } + return 0, false +} + +func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { + opCtx := graphql.GetOperationContext(ctx) + ec := executionContext{opCtx, e, 0, 0, make(chan graphql.DeferredResult)} + inputUnmarshalMap := graphql.BuildUnmarshalerMap() + first := true + + switch opCtx.Operation.Operation { + case ast.Query: + return func(ctx context.Context) *graphql.Response { + var response graphql.Response + var data graphql.Marshaler + if first { + first = false + ctx = graphql.WithUnmarshalerMap(ctx, inputUnmarshalMap) + data = ec._Query(ctx, opCtx.Operation.SelectionSet) + } else { + if atomic.LoadInt32(&ec.pendingDeferred) > 0 { + result := <-ec.deferredResults + atomic.AddInt32(&ec.pendingDeferred, -1) + data = result.Result + response.Path = result.Path + response.Label = result.Label + response.Errors = result.Errors + } else { + return nil + } + } + var buf bytes.Buffer + data.MarshalGQL(&buf) + response.Data = buf.Bytes() + if atomic.LoadInt32(&ec.deferred) > 0 { + hasNext := atomic.LoadInt32(&ec.pendingDeferred) > 0 + response.HasNext = &hasNext + } + + return &response + } + + default: + return graphql.OneShot(graphql.ErrorResponse(ctx, "unsupported GraphQL operation")) + } +} + +type executionContext struct { + *graphql.OperationContext + *executableSchema + deferred int32 + pendingDeferred int32 + deferredResults chan graphql.DeferredResult +} + +func (ec *executionContext) processDeferredGroup(dg graphql.DeferredGroup) { + atomic.AddInt32(&ec.pendingDeferred, 1) + go func() { + ctx := graphql.WithFreshResponseContext(dg.Context) + dg.FieldSet.Dispatch(ctx) + ds := graphql.DeferredResult{ + Path: dg.Path, + Label: dg.Label, + Result: dg.FieldSet, + Errors: graphql.GetErrors(ctx), + } + // null fields should bubble up + if dg.FieldSet.Invalids > 0 { + ds.Result = graphql.Null + } + ec.deferredResults <- ds + }() +} + +func (ec *executionContext) introspectSchema() (*introspection.Schema, error) { + if ec.DisableIntrospection { + return nil, errors.New("introspection disabled") + } + return introspection.WrapSchema(ec.Schema()), nil +} + +func (ec *executionContext) introspectType(name string) (*introspection.Type, error) { + if ec.DisableIntrospection { + return nil, errors.New("introspection disabled") + } + return introspection.WrapTypeFromDef(ec.Schema(), ec.Schema().Types[name]), nil +} + +var sources = []*ast.Source{ + {Name: "../schema.graphqls", Input: `extend schema + @link( + url: "https://specs.apollo.dev/federation/v2.5" + import: ["@key"] + ) + +type Article @key(fields: "id") { + id: ID! + viewCount: Int! + rating: Float! + reviewSummary: String! +} +`, BuiltIn: false}, + {Name: "../../federation/directives.graphql", Input: ` + directive @authenticated on FIELD_DEFINITION | OBJECT | INTERFACE | SCALAR | ENUM + directive @composeDirective(name: String!) repeatable on SCHEMA + directive @extends on OBJECT | INTERFACE + directive @external on OBJECT | FIELD_DEFINITION + directive @key(fields: FieldSet!, resolvable: Boolean = true) repeatable on OBJECT | INTERFACE + directive @inaccessible on + | ARGUMENT_DEFINITION + | ENUM + | ENUM_VALUE + | FIELD_DEFINITION + | INPUT_FIELD_DEFINITION + | INPUT_OBJECT + | INTERFACE + | OBJECT + | SCALAR + | UNION + directive @interfaceObject on OBJECT + directive @link(import: [String!], url: String!) repeatable on SCHEMA + directive @override(from: String!, label: String) on FIELD_DEFINITION + directive @policy(policies: [[federation__Policy!]!]!) on + | FIELD_DEFINITION + | OBJECT + | INTERFACE + | SCALAR + | ENUM + directive @provides(fields: FieldSet!) on FIELD_DEFINITION + directive @requires(fields: FieldSet!) on FIELD_DEFINITION + directive @requiresScopes(scopes: [[federation__Scope!]!]!) on + | FIELD_DEFINITION + | OBJECT + | INTERFACE + | SCALAR + | ENUM + directive @shareable repeatable on FIELD_DEFINITION | OBJECT + directive @tag(name: String!) repeatable on + | ARGUMENT_DEFINITION + | ENUM + | ENUM_VALUE + | FIELD_DEFINITION + | INPUT_FIELD_DEFINITION + | INPUT_OBJECT + | INTERFACE + | OBJECT + | SCALAR + | UNION + scalar _Any + scalar FieldSet + scalar federation__Policy + scalar federation__Scope +`, BuiltIn: true}, + {Name: "../../federation/entity.graphql", Input: ` +# a union of all types that use the @key directive +union _Entity = Article + +# fake type to build resolver interfaces for users to implement +type Entity { + findArticleByID(id: ID!,): Article! +} + +type _Service { + sdl: String +} + +extend type Query { + _entities(representations: [_Any!]!): [_Entity]! + _service: _Service! +} +`, BuiltIn: true}, +} +var parsedSchema = gqlparser.MustLoadSchema(sources...) + +// endregion ************************** generated!.gotpl ************************** + +// region ***************************** args.gotpl ***************************** + +func (ec *executionContext) field_Entity_findArticleByID_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Entity_findArticleByID_argsID(ctx, rawArgs) + if err != nil { + return nil, err + } + args["id"] = arg0 + return args, nil +} +func (ec *executionContext) field_Entity_findArticleByID_argsID( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["id"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + if tmp, ok := rawArgs["id"]; ok { + return ec.unmarshalNID2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Query___type_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Query___type_argsName(ctx, rawArgs) + if err != nil { + return nil, err + } + args["name"] = arg0 + return args, nil +} +func (ec *executionContext) field_Query___type_argsName( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["name"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("name")) + if tmp, ok := rawArgs["name"]; ok { + return ec.unmarshalNString2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Query__entities_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Query__entities_argsRepresentations(ctx, rawArgs) + if err != nil { + return nil, err + } + args["representations"] = arg0 + return args, nil +} +func (ec *executionContext) field_Query__entities_argsRepresentations( + ctx context.Context, + rawArgs map[string]any, +) ([]map[string]any, error) { + if _, ok := rawArgs["representations"]; !ok { + var zeroVal []map[string]any + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("representations")) + if tmp, ok := rawArgs["representations"]; ok { + return ec.unmarshalN_Any2ᚕmapᚄ(ctx, tmp) + } + + var zeroVal []map[string]any + return zeroVal, nil +} + +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 := ec.field___Directive_args_argsIncludeDeprecated(ctx, rawArgs) + if err != nil { + return nil, err + } + args["includeDeprecated"] = arg0 + return args, nil +} +func (ec *executionContext) field___Directive_args_argsIncludeDeprecated( + ctx context.Context, + rawArgs map[string]any, +) (*bool, error) { + if _, ok := rawArgs["includeDeprecated"]; !ok { + var zeroVal *bool + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("includeDeprecated")) + if tmp, ok := rawArgs["includeDeprecated"]; ok { + return ec.unmarshalOBoolean2ᚖbool(ctx, tmp) + } + + var zeroVal *bool + return zeroVal, nil +} + +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 := ec.field___Field_args_argsIncludeDeprecated(ctx, rawArgs) + if err != nil { + return nil, err + } + args["includeDeprecated"] = arg0 + return args, nil +} +func (ec *executionContext) field___Field_args_argsIncludeDeprecated( + ctx context.Context, + rawArgs map[string]any, +) (*bool, error) { + if _, ok := rawArgs["includeDeprecated"]; !ok { + var zeroVal *bool + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("includeDeprecated")) + if tmp, ok := rawArgs["includeDeprecated"]; ok { + return ec.unmarshalOBoolean2ᚖbool(ctx, tmp) + } + + var zeroVal *bool + return zeroVal, nil +} + +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 := ec.field___Type_enumValues_argsIncludeDeprecated(ctx, rawArgs) + if err != nil { + return nil, err + } + args["includeDeprecated"] = arg0 + return args, nil +} +func (ec *executionContext) field___Type_enumValues_argsIncludeDeprecated( + ctx context.Context, + rawArgs map[string]any, +) (bool, error) { + if _, ok := rawArgs["includeDeprecated"]; !ok { + var zeroVal bool + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("includeDeprecated")) + if tmp, ok := rawArgs["includeDeprecated"]; ok { + return ec.unmarshalOBoolean2bool(ctx, tmp) + } + + var zeroVal bool + return zeroVal, nil +} + +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 := ec.field___Type_fields_argsIncludeDeprecated(ctx, rawArgs) + if err != nil { + return nil, err + } + args["includeDeprecated"] = arg0 + return args, nil +} +func (ec *executionContext) field___Type_fields_argsIncludeDeprecated( + ctx context.Context, + rawArgs map[string]any, +) (bool, error) { + if _, ok := rawArgs["includeDeprecated"]; !ok { + var zeroVal bool + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("includeDeprecated")) + if tmp, ok := rawArgs["includeDeprecated"]; ok { + return ec.unmarshalOBoolean2bool(ctx, tmp) + } + + var zeroVal bool + return zeroVal, nil +} + +// endregion ***************************** args.gotpl ***************************** + +// region ************************** directives.gotpl ************************** + +// endregion ************************** directives.gotpl ************************** + +// region **************************** field.gotpl ***************************** + +func (ec *executionContext) _Article_id(ctx context.Context, field graphql.CollectedField, obj *model.Article) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Article_id(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Article_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Article", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Article_viewCount(ctx context.Context, field graphql.CollectedField, obj *model.Article) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Article_viewCount(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.ViewCount, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Article_viewCount(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Article", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Article_rating(ctx context.Context, field graphql.CollectedField, obj *model.Article) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Article_rating(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Rating, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(float64) + fc.Result = res + return ec.marshalNFloat2float64(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Article_rating(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Article", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Float does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Article_reviewSummary(ctx context.Context, field graphql.CollectedField, obj *model.Article) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Article_reviewSummary(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.ReviewSummary, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Article_reviewSummary(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Article", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Entity_findArticleByID(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Entity_findArticleByID(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Entity().FindArticleByID(rctx, fc.Args["id"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*model.Article) + fc.Result = res + return ec.marshalNArticle2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋarticlesmetaᚋsubgraphᚋmodelᚐArticle(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Entity_findArticleByID(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Entity", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Article_id(ctx, field) + case "viewCount": + return ec.fieldContext_Article_viewCount(ctx, field) + case "rating": + return ec.fieldContext_Article_rating(ctx, field) + case "reviewSummary": + return ec.fieldContext_Article_reviewSummary(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Article", field.Name) + }, + } + 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_Entity_findArticleByID_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query__entities(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query__entities(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.__resolve_entities(ctx, fc.Args["representations"].([]map[string]any)), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]fedruntime.Entity) + fc.Result = res + return ec.marshalN_Entity2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐEntity(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query__entities(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type _Entity does not have child fields") + }, + } + 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__entities_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query__service(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query__service(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.__resolve__service(ctx) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(fedruntime.Service) + fc.Result = res + return ec.marshalN_Service2githubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐService(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query__service(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "sdl": + return ec.fieldContext__Service_sdl(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type _Service", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Query___type(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query___type(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.introspectType(fc.Args["name"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query___type(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + 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___type_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query___schema(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query___schema(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.introspectSchema() + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Schema) + fc.Result = res + return ec.marshalO__Schema2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐSchema(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query___schema(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "description": + return ec.fieldContext___Schema_description(ctx, field) + case "types": + return ec.fieldContext___Schema_types(ctx, field) + case "queryType": + return ec.fieldContext___Schema_queryType(ctx, field) + case "mutationType": + return ec.fieldContext___Schema_mutationType(ctx, field) + case "subscriptionType": + return ec.fieldContext___Schema_subscriptionType(ctx, field) + case "directives": + return ec.fieldContext___Schema_directives(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Schema", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) __Service_sdl(ctx context.Context, field graphql.CollectedField, obj *fedruntime.Service) (ret graphql.Marshaler) { + fc, err := ec.fieldContext__Service_sdl(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.SDL, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalOString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext__Service_sdl(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "_Service", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Directive_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Directive_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Directive_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Directive_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_isRepeatable(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Directive_isRepeatable(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsRepeatable, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Directive_isRepeatable(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_locations(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Directive_locations(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Locations, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]string) + fc.Result = res + return ec.marshalN__DirectiveLocation2ᚕstringᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Directive_locations(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type __DirectiveLocation does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_args(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Directive_args(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Args, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]introspection.InputValue) + fc.Result = res + return ec.marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Directive_args(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___InputValue_name(ctx, field) + case "description": + return ec.fieldContext___InputValue_description(ctx, field) + case "type": + return ec.fieldContext___InputValue_type(ctx, field) + case "defaultValue": + return ec.fieldContext___InputValue_defaultValue(ctx, field) + case "isDeprecated": + return ec.fieldContext___InputValue_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___InputValue_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __InputValue", field.Name) + }, + } + 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___Directive_args_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) ___EnumValue_name(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___EnumValue_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___EnumValue_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__EnumValue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___EnumValue_description(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___EnumValue_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___EnumValue_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__EnumValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___EnumValue_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___EnumValue_isDeprecated(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsDeprecated(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___EnumValue_isDeprecated(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__EnumValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___EnumValue_deprecationReason(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___EnumValue_deprecationReason(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.DeprecationReason(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___EnumValue_deprecationReason(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__EnumValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_args(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_args(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Args, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]introspection.InputValue) + fc.Result = res + return ec.marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_args(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___InputValue_name(ctx, field) + case "description": + return ec.fieldContext___InputValue_description(ctx, field) + case "type": + return ec.fieldContext___InputValue_type(ctx, field) + case "defaultValue": + return ec.fieldContext___InputValue_defaultValue(ctx, field) + case "isDeprecated": + return ec.fieldContext___InputValue_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___InputValue_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __InputValue", field.Name) + }, + } + 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___Field_args_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) ___Field_type(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_type(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Type, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_type(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_isDeprecated(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsDeprecated(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_isDeprecated(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_deprecationReason(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_deprecationReason(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.DeprecationReason(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_deprecationReason(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_name(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_description(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_type(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_type(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Type, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_type(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_defaultValue(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_defaultValue(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.DefaultValue, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_defaultValue(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_isDeprecated(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsDeprecated(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_isDeprecated(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_deprecationReason(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_deprecationReason(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.DeprecationReason(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_deprecationReason(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_types(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_types(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Types(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]introspection.Type) + fc.Result = res + return ec.marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_types(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_queryType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_queryType(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.QueryType(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_queryType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_mutationType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_mutationType(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.MutationType(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_mutationType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_subscriptionType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_subscriptionType(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.SubscriptionType(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_subscriptionType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_directives(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_directives(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Directives(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]introspection.Directive) + fc.Result = res + return ec.marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirectiveᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_directives(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___Directive_name(ctx, field) + case "description": + return ec.fieldContext___Directive_description(ctx, field) + case "isRepeatable": + return ec.fieldContext___Directive_isRepeatable(ctx, field) + case "locations": + return ec.fieldContext___Directive_locations(ctx, field) + case "args": + return ec.fieldContext___Directive_args(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Directive", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_kind(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_kind(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Kind(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalN__TypeKind2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_kind(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type __TypeKind does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_specifiedByURL(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_specifiedByURL(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.SpecifiedByURL(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_specifiedByURL(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_fields(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_fields(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Fields(fc.Args["includeDeprecated"].(bool)), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.Field) + fc.Result = res + return ec.marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐFieldᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_fields(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___Field_name(ctx, field) + case "description": + return ec.fieldContext___Field_description(ctx, field) + case "args": + return ec.fieldContext___Field_args(ctx, field) + case "type": + return ec.fieldContext___Field_type(ctx, field) + case "isDeprecated": + return ec.fieldContext___Field_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___Field_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Field", field.Name) + }, + } + 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_fields_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) ___Type_interfaces(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_interfaces(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Interfaces(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_interfaces(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_possibleTypes(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_possibleTypes(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.PossibleTypes(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_possibleTypes(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_enumValues(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_enumValues(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.EnumValues(fc.Args["includeDeprecated"].(bool)), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.EnumValue) + fc.Result = res + return ec.marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValueᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_enumValues(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___EnumValue_name(ctx, field) + case "description": + return ec.fieldContext___EnumValue_description(ctx, field) + case "isDeprecated": + return ec.fieldContext___EnumValue_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___EnumValue_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __EnumValue", field.Name) + }, + } + 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_enumValues_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) ___Type_inputFields(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_inputFields(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.InputFields(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.InputValue) + fc.Result = res + return ec.marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_inputFields(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___InputValue_name(ctx, field) + case "description": + return ec.fieldContext___InputValue_description(ctx, field) + case "type": + return ec.fieldContext___InputValue_type(ctx, field) + case "defaultValue": + return ec.fieldContext___InputValue_defaultValue(ctx, field) + case "isDeprecated": + return ec.fieldContext___InputValue_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___InputValue_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __InputValue", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_ofType(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_ofType(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.OfType(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_ofType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_isOneOf(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_isOneOf(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsOneOf(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalOBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_isOneOf(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +// endregion **************************** field.gotpl ***************************** + +// region **************************** input.gotpl ***************************** + +// endregion **************************** input.gotpl ***************************** + +// region ************************** interface.gotpl *************************** + +func (ec *executionContext) __Entity(ctx context.Context, sel ast.SelectionSet, obj fedruntime.Entity) graphql.Marshaler { + switch obj := (obj).(type) { + case nil: + return graphql.Null + case model.Article: + return ec._Article(ctx, sel, &obj) + case *model.Article: + if obj == nil { + return graphql.Null + } + return ec._Article(ctx, sel, obj) + default: + panic(fmt.Errorf("unexpected type %T", obj)) + } +} + +// endregion ************************** interface.gotpl *************************** + +// region **************************** object.gotpl **************************** + +var articleImplementors = []string{"Article", "_Entity"} + +func (ec *executionContext) _Article(ctx context.Context, sel ast.SelectionSet, obj *model.Article) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, articleImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Article") + case "id": + out.Values[i] = ec._Article_id(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "viewCount": + out.Values[i] = ec._Article_viewCount(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "rating": + out.Values[i] = ec._Article_rating(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "reviewSummary": + out.Values[i] = ec._Article_reviewSummary(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 + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var entityImplementors = []string{"Entity"} + +func (ec *executionContext) _Entity(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, entityImplementors) + ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ + Object: "Entity", + }) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ + Object: field.Name, + Field: field, + }) + + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Entity") + case "findArticleByID": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Entity_findArticleByID(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var queryImplementors = []string{"Query"} + +func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, queryImplementors) + ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ + Object: "Query", + }) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ + Object: field.Name, + Field: field, + }) + + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Query") + case "_entities": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query__entities(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "_service": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query__service(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "__type": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Query___type(ctx, field) + }) + case "__schema": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Query___schema(ctx, field) + }) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var _ServiceImplementors = []string{"_Service"} + +func (ec *executionContext) __Service(ctx context.Context, sel ast.SelectionSet, obj *fedruntime.Service) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, _ServiceImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("_Service") + case "sdl": + out.Values[i] = ec.__Service_sdl(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __DirectiveImplementors = []string{"__Directive"} + +func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionSet, obj *introspection.Directive) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __DirectiveImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__Directive") + case "name": + out.Values[i] = ec.___Directive_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "description": + out.Values[i] = ec.___Directive_description(ctx, field, obj) + case "isRepeatable": + out.Values[i] = ec.___Directive_isRepeatable(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "locations": + out.Values[i] = ec.___Directive_locations(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "args": + out.Values[i] = ec.___Directive_args(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 + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __EnumValueImplementors = []string{"__EnumValue"} + +func (ec *executionContext) ___EnumValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.EnumValue) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __EnumValueImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__EnumValue") + case "name": + out.Values[i] = ec.___EnumValue_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "description": + out.Values[i] = ec.___EnumValue_description(ctx, field, obj) + case "isDeprecated": + out.Values[i] = ec.___EnumValue_isDeprecated(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "deprecationReason": + out.Values[i] = ec.___EnumValue_deprecationReason(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __FieldImplementors = []string{"__Field"} + +func (ec *executionContext) ___Field(ctx context.Context, sel ast.SelectionSet, obj *introspection.Field) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __FieldImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__Field") + case "name": + out.Values[i] = ec.___Field_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "description": + out.Values[i] = ec.___Field_description(ctx, field, obj) + case "args": + out.Values[i] = ec.___Field_args(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "type": + out.Values[i] = ec.___Field_type(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "isDeprecated": + out.Values[i] = ec.___Field_isDeprecated(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "deprecationReason": + out.Values[i] = ec.___Field_deprecationReason(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __InputValueImplementors = []string{"__InputValue"} + +func (ec *executionContext) ___InputValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.InputValue) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __InputValueImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__InputValue") + case "name": + out.Values[i] = ec.___InputValue_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "description": + out.Values[i] = ec.___InputValue_description(ctx, field, obj) + case "type": + out.Values[i] = ec.___InputValue_type(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "defaultValue": + out.Values[i] = ec.___InputValue_defaultValue(ctx, field, obj) + case "isDeprecated": + out.Values[i] = ec.___InputValue_isDeprecated(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "deprecationReason": + out.Values[i] = ec.___InputValue_deprecationReason(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __SchemaImplementors = []string{"__Schema"} + +func (ec *executionContext) ___Schema(ctx context.Context, sel ast.SelectionSet, obj *introspection.Schema) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __SchemaImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__Schema") + case "description": + out.Values[i] = ec.___Schema_description(ctx, field, obj) + case "types": + out.Values[i] = ec.___Schema_types(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "queryType": + out.Values[i] = ec.___Schema_queryType(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "mutationType": + out.Values[i] = ec.___Schema_mutationType(ctx, field, obj) + case "subscriptionType": + out.Values[i] = ec.___Schema_subscriptionType(ctx, field, obj) + case "directives": + out.Values[i] = ec.___Schema_directives(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 + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __TypeImplementors = []string{"__Type"} + +func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, obj *introspection.Type) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __TypeImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__Type") + case "kind": + out.Values[i] = ec.___Type_kind(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "name": + out.Values[i] = ec.___Type_name(ctx, field, obj) + case "description": + out.Values[i] = ec.___Type_description(ctx, field, obj) + case "specifiedByURL": + out.Values[i] = ec.___Type_specifiedByURL(ctx, field, obj) + case "fields": + out.Values[i] = ec.___Type_fields(ctx, field, obj) + case "interfaces": + out.Values[i] = ec.___Type_interfaces(ctx, field, obj) + case "possibleTypes": + out.Values[i] = ec.___Type_possibleTypes(ctx, field, obj) + case "enumValues": + out.Values[i] = ec.___Type_enumValues(ctx, field, obj) + case "inputFields": + out.Values[i] = ec.___Type_inputFields(ctx, field, obj) + case "ofType": + out.Values[i] = ec.___Type_ofType(ctx, field, obj) + case "isOneOf": + out.Values[i] = ec.___Type_isOneOf(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +// endregion **************************** object.gotpl **************************** + +// region ***************************** type.gotpl ***************************** + +func (ec *executionContext) marshalNArticle2githubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋarticlesmetaᚋsubgraphᚋmodelᚐArticle(ctx context.Context, sel ast.SelectionSet, v model.Article) graphql.Marshaler { + return ec._Article(ctx, sel, &v) +} + +func (ec *executionContext) marshalNArticle2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋarticlesmetaᚋsubgraphᚋmodelᚐArticle(ctx context.Context, sel ast.SelectionSet, v *model.Article) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._Article(ctx, sel, v) +} + +func (ec *executionContext) unmarshalNBoolean2bool(ctx context.Context, v any) (bool, error) { + res, err := graphql.UnmarshalBoolean(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNBoolean2bool(ctx context.Context, sel ast.SelectionSet, v bool) graphql.Marshaler { + _ = sel + res := graphql.MarshalBoolean(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNFieldSet2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNFieldSet2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNFloat2float64(ctx context.Context, v any) (float64, error) { + res, err := graphql.UnmarshalFloatContext(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNFloat2float64(ctx context.Context, sel ast.SelectionSet, v float64) graphql.Marshaler { + _ = sel + res := graphql.MarshalFloatContext(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return graphql.WrapContextMarshaler(ctx, res) +} + +func (ec *executionContext) unmarshalNID2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalID(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNID2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalID(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNInt2int(ctx context.Context, v any) (int, error) { + res, err := graphql.UnmarshalInt(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNInt2int(ctx context.Context, sel ast.SelectionSet, v int) graphql.Marshaler { + _ = sel + res := graphql.MarshalInt(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNString2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNString2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalN_Any2map(ctx context.Context, v any) (map[string]any, error) { + res, err := graphql.UnmarshalMap(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalN_Any2map(ctx context.Context, sel ast.SelectionSet, v map[string]any) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + _ = sel + res := graphql.MarshalMap(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalN_Any2ᚕmapᚄ(ctx context.Context, v any) ([]map[string]any, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([]map[string]any, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalN_Any2map(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalN_Any2ᚕmapᚄ(ctx context.Context, sel ast.SelectionSet, v []map[string]any) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalN_Any2map(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalN_Entity2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐEntity(ctx context.Context, sel ast.SelectionSet, v []fedruntime.Entity) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalO_Entity2githubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐEntity(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + return ret +} + +func (ec *executionContext) marshalN_Service2githubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐService(ctx context.Context, sel ast.SelectionSet, v fedruntime.Service) graphql.Marshaler { + return ec.__Service(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__Directive2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirective(ctx context.Context, sel ast.SelectionSet, v introspection.Directive) graphql.Marshaler { + return ec.___Directive(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirectiveᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.Directive) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__Directive2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirective(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalN__DirectiveLocation2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalN__DirectiveLocation2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalN__DirectiveLocation2ᚕstringᚄ(ctx context.Context, v any) ([]string, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalN__DirectiveLocation2string(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalN__DirectiveLocation2ᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v []string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__DirectiveLocation2string(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalN__EnumValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValue(ctx context.Context, sel ast.SelectionSet, v introspection.EnumValue) graphql.Marshaler { + return ec.___EnumValue(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__Field2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐField(ctx context.Context, sel ast.SelectionSet, v introspection.Field) graphql.Marshaler { + return ec.___Field(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__InputValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValue(ctx context.Context, sel ast.SelectionSet, v introspection.InputValue) graphql.Marshaler { + return ec.___InputValue(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.InputValue) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__InputValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValue(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +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) +} + +func (ec *executionContext) marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.Type) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__Type2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx context.Context, sel ast.SelectionSet, v *introspection.Type) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec.___Type(ctx, sel, v) +} + +func (ec *executionContext) unmarshalN__TypeKind2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalN__TypeKind2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNfederation__Policy2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNfederation__Policy2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNfederation__Policy2ᚕstringᚄ(ctx context.Context, v any) ([]string, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNfederation__Policy2string(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalNfederation__Policy2ᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v []string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNfederation__Policy2string(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalNfederation__Policy2ᚕᚕstringᚄ(ctx context.Context, v any) ([][]string, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([][]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNfederation__Policy2ᚕstringᚄ(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalNfederation__Policy2ᚕᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v [][]string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNfederation__Policy2ᚕstringᚄ(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalNfederation__Scope2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNfederation__Scope2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNfederation__Scope2ᚕstringᚄ(ctx context.Context, v any) ([]string, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNfederation__Scope2string(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalNfederation__Scope2ᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v []string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNfederation__Scope2string(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalNfederation__Scope2ᚕᚕstringᚄ(ctx context.Context, v any) ([][]string, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([][]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNfederation__Scope2ᚕstringᚄ(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalNfederation__Scope2ᚕᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v [][]string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNfederation__Scope2ᚕstringᚄ(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalOBoolean2bool(ctx context.Context, v any) (bool, error) { + res, err := graphql.UnmarshalBoolean(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOBoolean2bool(ctx context.Context, sel ast.SelectionSet, v bool) graphql.Marshaler { + _ = sel + _ = ctx + res := graphql.MarshalBoolean(v) + return res +} + +func (ec *executionContext) unmarshalOBoolean2ᚖbool(ctx context.Context, v any) (*bool, error) { + if v == nil { + return nil, nil + } + res, err := graphql.UnmarshalBoolean(v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOBoolean2ᚖbool(ctx context.Context, sel ast.SelectionSet, v *bool) graphql.Marshaler { + if v == nil { + return graphql.Null + } + _ = sel + _ = ctx + res := graphql.MarshalBoolean(*v) + return res +} + +func (ec *executionContext) unmarshalOString2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOString2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + _ = ctx + res := graphql.MarshalString(v) + return res +} + +func (ec *executionContext) unmarshalOString2ᚕstringᚄ(ctx context.Context, v any) ([]string, error) { + if v == nil { + return nil, nil + } + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNString2string(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalOString2ᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v []string) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNString2string(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalOString2ᚖstring(ctx context.Context, v any) (*string, error) { + if v == nil { + return nil, nil + } + res, err := graphql.UnmarshalString(v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOString2ᚖstring(ctx context.Context, sel ast.SelectionSet, v *string) graphql.Marshaler { + if v == nil { + return graphql.Null + } + _ = sel + _ = ctx + res := graphql.MarshalString(*v) + return res +} + +func (ec *executionContext) marshalO_Entity2githubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐEntity(ctx context.Context, sel ast.SelectionSet, v fedruntime.Entity) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec.__Entity(ctx, sel, v) +} + +func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.EnumValue) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__EnumValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValue(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐFieldᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.Field) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__Field2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐField(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.InputValue) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__InputValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValue(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + 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 + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__Type2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +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 + } + return ec.___Type(ctx, sel, v) +} + +// endregion ***************************** type.gotpl ***************************** diff --git a/demo/pkg/subgraphs/cachetest/articlesmeta/subgraph/generated/staticcheck.conf b/demo/pkg/subgraphs/cachetest/articlesmeta/subgraph/generated/staticcheck.conf new file mode 100644 index 0000000000..582953a07e --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/articlesmeta/subgraph/generated/staticcheck.conf @@ -0,0 +1,2 @@ +# This is meant as a workaround to skip staticcheck checks for generated code +checks = ["all", "-SA4004", "-ST1000"] diff --git a/demo/pkg/subgraphs/cachetest/articlesmeta/subgraph/model/models_gen.go b/demo/pkg/subgraphs/cachetest/articlesmeta/subgraph/model/models_gen.go new file mode 100644 index 0000000000..9cb075b6f5 --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/articlesmeta/subgraph/model/models_gen.go @@ -0,0 +1,15 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package model + +type Article struct { + ID string `json:"id"` + ViewCount int `json:"viewCount"` + Rating float64 `json:"rating"` + ReviewSummary string `json:"reviewSummary"` +} + +func (Article) IsEntity() {} + +type Query struct { +} diff --git a/demo/pkg/subgraphs/cachetest/articlesmeta/subgraph/resolver.go b/demo/pkg/subgraphs/cachetest/articlesmeta/subgraph/resolver.go new file mode 100644 index 0000000000..c1da1a4335 --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/articlesmeta/subgraph/resolver.go @@ -0,0 +1,7 @@ +package subgraph + +// This file will not be regenerated automatically. +// +// It serves as dependency injection for your app, add any dependencies you require here. + +type Resolver struct{} diff --git a/demo/pkg/subgraphs/cachetest/articlesmeta/subgraph/schema.graphqls b/demo/pkg/subgraphs/cachetest/articlesmeta/subgraph/schema.graphqls new file mode 100644 index 0000000000..9b382e2281 --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/articlesmeta/subgraph/schema.graphqls @@ -0,0 +1,12 @@ +extend schema + @link( + url: "https://specs.apollo.dev/federation/v2.5" + import: ["@key"] + ) + +type Article @key(fields: "id") { + id: ID! + viewCount: Int! + rating: Float! + reviewSummary: String! +} diff --git a/demo/pkg/subgraphs/cachetest/details/details.go b/demo/pkg/subgraphs/cachetest/details/details.go new file mode 100644 index 0000000000..f64ac352ef --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/details/details.go @@ -0,0 +1,14 @@ +package details + +import ( + "github.com/99designs/gqlgen/graphql" + + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachetest/details/subgraph" + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachetest/details/subgraph/generated" +) + +func NewSchema() graphql.ExecutableSchema { + return generated.NewExecutableSchema(generated.Config{ + Resolvers: &subgraph.Resolver{}, + }) +} diff --git a/demo/pkg/subgraphs/cachetest/details/generate.go b/demo/pkg/subgraphs/cachetest/details/generate.go new file mode 100644 index 0000000000..244aa22f21 --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/details/generate.go @@ -0,0 +1,3 @@ +//go:generate go run github.com/99designs/gqlgen generate + +package details diff --git a/demo/pkg/subgraphs/cachetest/details/gqlgen.yml b/demo/pkg/subgraphs/cachetest/details/gqlgen.yml new file mode 100644 index 0000000000..6fb37cff77 --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/details/gqlgen.yml @@ -0,0 +1,39 @@ +schema: + - subgraph/*.graphqls + +exec: + filename: subgraph/generated/generated.go + package: generated + +federation: + filename: subgraph/generated/federation.go + package: generated + version: 2 + options: + explicit_requires: true + +model: + filename: subgraph/model/models_gen.go + package: model + +resolver: + layout: follow-schema + dir: subgraph + package: subgraph + +directives: + openfed__entityCache: + skip_runtime: true + +models: + ID: + model: + - github.com/99designs/gqlgen/graphql.ID + - github.com/99designs/gqlgen/graphql.Int + - github.com/99designs/gqlgen/graphql.Int64 + - github.com/99designs/gqlgen/graphql.Int32 + Int: + model: + - github.com/99designs/gqlgen/graphql.Int + - github.com/99designs/gqlgen/graphql.Int64 + - github.com/99designs/gqlgen/graphql.Int32 diff --git a/demo/pkg/subgraphs/cachetest/details/subgraph/data.go b/demo/pkg/subgraphs/cachetest/details/subgraph/data.go new file mode 100644 index 0000000000..23418fff84 --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/details/subgraph/data.go @@ -0,0 +1,29 @@ +package subgraph + +import ( + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachetest/details/subgraph/model" +) + +// productKey creates a composite lookup key for Product entities. +func productKey(id, region string) string { return id + ":" + region } + +var ProductDetails = map[string]*model.Product{ + productKey("p1", "US"): {ID: "p1", Region: "US", Info: "Alpha product details for US market"}, + productKey("p2", "US"): {ID: "p2", Region: "US", Info: "Beta product details for US market"}, + productKey("p3", "EU"): {ID: "p3", Region: "EU", Info: "Gamma product details for EU market"}, + productKey("p4", "EU"): {ID: "p4", Region: "EU", Info: "Delta product details for EU market"}, +} + +var WarehouseDetails = map[string]*model.Warehouse{ + "w1": {Location: &model.Location{ID: "w1"}, Capacity: 1000}, + "w2": {Location: &model.Location{ID: "w2"}, Capacity: 500}, + "w3": {Location: &model.Location{ID: "w3"}, Capacity: 750}, +} + +var ItemDetails = map[string]*model.Item{ + "1": {ID: "1", Description: "A versatile widget for everyday use", Rating: 4.5, Tags: []string{"popular", "tools"}}, + "2": {ID: "2", Description: "A high-tech gadget with many features", Rating: 4.8, Tags: []string{"new", "electronics"}}, + "3": {ID: "3", Description: "A compact gizmo that fits in your pocket", Rating: 3.9, Tags: []string{"compact", "electronics"}}, + "4": {ID: "4", Description: "A mysterious doohickey of unknown purpose", Rating: 3.2, Tags: []string{"misc"}}, + "5": {ID: "5", Description: "An elaborate thingamajig for advanced users", Rating: 4.1, Tags: []string{"advanced", "misc"}}, +} diff --git a/demo/pkg/subgraphs/cachetest/details/subgraph/entity.resolvers.go b/demo/pkg/subgraphs/cachetest/details/subgraph/entity.resolvers.go new file mode 100644 index 0000000000..6d43b088ac --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/details/subgraph/entity.resolvers.go @@ -0,0 +1,41 @@ +package subgraph + +// 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.76 + +import ( + "context" + + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachetest/details/subgraph/generated" + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachetest/details/subgraph/model" +) + +// FindItemByID is the resolver for the findItemByID field. +func (r *entityResolver) FindItemByID(ctx context.Context, id string) (*model.Item, error) { + if item, ok := ItemDetails[id]; ok { + return item, nil + } + return nil, nil +} + +// FindProductByIDAndRegion is the resolver for the findProductByIDAndRegion field. +func (r *entityResolver) FindProductByIDAndRegion(ctx context.Context, id string, region string) (*model.Product, error) { + if p, ok := ProductDetails[productKey(id, region)]; ok { + return p, nil + } + return nil, nil +} + +// FindWarehouseByLocationID is the resolver for the findWarehouseByLocationID field. +func (r *entityResolver) FindWarehouseByLocationID(ctx context.Context, locationID string) (*model.Warehouse, error) { + if w, ok := WarehouseDetails[locationID]; ok { + return w, nil + } + return nil, nil +} + +// Entity returns generated.EntityResolver implementation. +func (r *Resolver) Entity() generated.EntityResolver { return &entityResolver{r} } + +type entityResolver struct{ *Resolver } diff --git a/demo/pkg/subgraphs/cachetest/details/subgraph/generated/federation.go b/demo/pkg/subgraphs/cachetest/details/subgraph/generated/federation.go new file mode 100644 index 0000000000..d75e9137d7 --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/details/subgraph/generated/federation.go @@ -0,0 +1,368 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package generated + +import ( + "context" + "errors" + "fmt" + "strings" + "sync" + + "github.com/99designs/gqlgen/plugin/federation/fedruntime" +) + +var ( + ErrUnknownType = errors.New("unknown type") + ErrTypeNotFound = errors.New("type not found") +) + +func (ec *executionContext) __resolve__service(ctx context.Context) (fedruntime.Service, error) { + if ec.DisableIntrospection { + return fedruntime.Service{}, errors.New("federated introspection disabled") + } + + var sdl []string + + for _, src := range sources { + if src.BuiltIn { + continue + } + sdl = append(sdl, src.Input) + } + + return fedruntime.Service{ + SDL: strings.Join(sdl, "\n"), + }, nil +} + +func (ec *executionContext) __resolve_entities(ctx context.Context, representations []map[string]any) []fedruntime.Entity { + list := make([]fedruntime.Entity, len(representations)) + + repsMap := ec.buildRepresentationGroups(ctx, representations) + + switch len(repsMap) { + case 0: + return list + case 1: + for typeName, reps := range repsMap { + ec.resolveEntityGroup(ctx, typeName, reps, list) + } + return list + default: + var g sync.WaitGroup + g.Add(len(repsMap)) + for typeName, reps := range repsMap { + go func(typeName string, reps []EntityWithIndex) { + ec.resolveEntityGroup(ctx, typeName, reps, list) + g.Done() + }(typeName, reps) + } + g.Wait() + return list + } +} + +type EntityWithIndex struct { + // The index in the original representation array + index int + entity EntityRepresentation +} + +// EntityRepresentation is the JSON representation of an entity sent by the Router +// used as the inputs for us to resolve. +// +// We make it a map because we know the top level JSON is always an object. +type EntityRepresentation map[string]any + +// We group entities by typename so that we can parallelize their resolution. +// This is particularly helpful when there are entity groups in multi mode. +func (ec *executionContext) buildRepresentationGroups( + ctx context.Context, + representations []map[string]any, +) map[string][]EntityWithIndex { + repsMap := make(map[string][]EntityWithIndex) + for i, rep := range representations { + typeName, ok := rep["__typename"].(string) + if !ok { + // If there is no __typename, we just skip the representation; + // we just won't be resolving these unknown types. + ec.Error(ctx, errors.New("__typename must be an existing string")) + continue + } + + repsMap[typeName] = append(repsMap[typeName], EntityWithIndex{ + index: i, + entity: rep, + }) + } + + return repsMap +} + +func (ec *executionContext) resolveEntityGroup( + ctx context.Context, + typeName string, + reps []EntityWithIndex, + list []fedruntime.Entity, +) { + if isMulti(typeName) { + err := ec.resolveManyEntities(ctx, typeName, reps, list) + if err != nil { + ec.Error(ctx, err) + } + } else { + // if there are multiple entities to resolve, parallelize (similar to + // graphql.FieldSet.Dispatch) + var e sync.WaitGroup + e.Add(len(reps)) + for i, rep := range reps { + i, rep := i, rep + go func(i int, rep EntityWithIndex) { + entity, err := ec.resolveEntity(ctx, typeName, rep.entity) + if err != nil { + ec.Error(ctx, err) + } else { + list[rep.index] = entity + } + e.Done() + }(i, rep) + } + e.Wait() + } +} + +func isMulti(typeName string) bool { + switch typeName { + default: + return false + } +} + +func (ec *executionContext) resolveEntity( + ctx context.Context, + typeName string, + rep EntityRepresentation, +) (e fedruntime.Entity, err error) { + // we need to do our own panic handling, because we may be called in a + // goroutine, where the usual panic handling can't catch us + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + } + }() + + switch typeName { + case "Item": + resolverName, err := entityResolverNameForItem(ctx, rep) + if err != nil { + return nil, fmt.Errorf(`finding resolver for Entity "Item": %w`, err) + } + switch resolverName { + + case "findItemByID": + id0, err := ec.unmarshalNID2string(ctx, rep["id"]) + if err != nil { + return nil, fmt.Errorf(`unmarshalling param 0 for findItemByID(): %w`, err) + } + entity, err := ec.resolvers.Entity().FindItemByID(ctx, id0) + if err != nil { + return nil, fmt.Errorf(`resolving Entity "Item": %w`, err) + } + + return entity, nil + } + case "Product": + resolverName, err := entityResolverNameForProduct(ctx, rep) + if err != nil { + return nil, fmt.Errorf(`finding resolver for Entity "Product": %w`, err) + } + switch resolverName { + + case "findProductByIDAndRegion": + id0, err := ec.unmarshalNID2string(ctx, rep["id"]) + if err != nil { + return nil, fmt.Errorf(`unmarshalling param 0 for findProductByIDAndRegion(): %w`, err) + } + id1, err := ec.unmarshalNString2string(ctx, rep["region"]) + if err != nil { + return nil, fmt.Errorf(`unmarshalling param 1 for findProductByIDAndRegion(): %w`, err) + } + entity, err := ec.resolvers.Entity().FindProductByIDAndRegion(ctx, id0, id1) + if err != nil { + return nil, fmt.Errorf(`resolving Entity "Product": %w`, err) + } + + return entity, nil + } + case "Warehouse": + resolverName, err := entityResolverNameForWarehouse(ctx, rep) + if err != nil { + return nil, fmt.Errorf(`finding resolver for Entity "Warehouse": %w`, err) + } + switch resolverName { + + case "findWarehouseByLocationID": + id0, err := ec.unmarshalNID2string(ctx, rep["location"].(map[string]any)["id"]) + if err != nil { + return nil, fmt.Errorf(`unmarshalling param 0 for findWarehouseByLocationID(): %w`, err) + } + entity, err := ec.resolvers.Entity().FindWarehouseByLocationID(ctx, id0) + if err != nil { + return nil, fmt.Errorf(`resolving Entity "Warehouse": %w`, err) + } + + return entity, nil + } + + } + return nil, fmt.Errorf("%w: %s", ErrUnknownType, typeName) +} + +func (ec *executionContext) resolveManyEntities( + ctx context.Context, + typeName string, + reps []EntityWithIndex, + list []fedruntime.Entity, +) (err error) { + // we need to do our own panic handling, because we may be called in a + // goroutine, where the usual panic handling can't catch us + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + } + }() + + switch typeName { + + default: + return errors.New("unknown type: " + typeName) + } +} + +func entityResolverNameForItem(ctx context.Context, rep EntityRepresentation) (string, error) { + // we collect errors because a later entity resolver may work fine + // when an entity has multiple keys + entityResolverErrs := []error{} + for { + var ( + m EntityRepresentation + val any + ok bool + ) + _ = val + // if all of the KeyFields values for this resolver are null, + // we shouldn't use use it + allNull := true + m = rep + val, ok = m["id"] + if !ok { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to missing Key Field \"id\" for Item", ErrTypeNotFound)) + break + } + if allNull { + allNull = val == nil + } + if allNull { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to all null value KeyFields for Item", ErrTypeNotFound)) + break + } + return "findItemByID", nil + } + return "", fmt.Errorf("%w for Item due to %v", ErrTypeNotFound, + errors.Join(entityResolverErrs...).Error()) +} + +func entityResolverNameForProduct(ctx context.Context, rep EntityRepresentation) (string, error) { + // we collect errors because a later entity resolver may work fine + // when an entity has multiple keys + entityResolverErrs := []error{} + for { + var ( + m EntityRepresentation + val any + ok bool + ) + _ = val + // if all of the KeyFields values for this resolver are null, + // we shouldn't use use it + allNull := true + m = rep + val, ok = m["id"] + if !ok { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to missing Key Field \"id\" for Product", ErrTypeNotFound)) + break + } + if allNull { + allNull = val == nil + } + m = rep + val, ok = m["region"] + if !ok { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to missing Key Field \"region\" for Product", ErrTypeNotFound)) + break + } + if allNull { + allNull = val == nil + } + if allNull { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to all null value KeyFields for Product", ErrTypeNotFound)) + break + } + return "findProductByIDAndRegion", nil + } + return "", fmt.Errorf("%w for Product due to %v", ErrTypeNotFound, + errors.Join(entityResolverErrs...).Error()) +} + +func entityResolverNameForWarehouse(ctx context.Context, rep EntityRepresentation) (string, error) { + // we collect errors because a later entity resolver may work fine + // when an entity has multiple keys + entityResolverErrs := []error{} + for { + var ( + m EntityRepresentation + val any + ok bool + ) + _ = val + // if all of the KeyFields values for this resolver are null, + // we shouldn't use use it + allNull := true + m = rep + val, ok = m["location"] + if !ok { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to missing Key Field \"location\" for Warehouse", ErrTypeNotFound)) + break + } + if m, ok = val.(map[string]any); !ok { + // nested field value is not a map[string]interface so don't use it + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to nested Key Field \"location\" value not matching map[string]any for Warehouse", ErrTypeNotFound)) + break + } + val, ok = m["id"] + if !ok { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to missing Key Field \"id\" for Warehouse", ErrTypeNotFound)) + break + } + if allNull { + allNull = val == nil + } + if allNull { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to all null value KeyFields for Warehouse", ErrTypeNotFound)) + break + } + return "findWarehouseByLocationID", nil + } + return "", fmt.Errorf("%w for Warehouse due to %v", ErrTypeNotFound, + errors.Join(entityResolverErrs...).Error()) +} diff --git a/demo/pkg/subgraphs/cachetest/details/subgraph/generated/generated.go b/demo/pkg/subgraphs/cachetest/details/subgraph/generated/generated.go new file mode 100644 index 0000000000..494f07651b --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/details/subgraph/generated/generated.go @@ -0,0 +1,5367 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package generated + +import ( + "bytes" + "context" + "errors" + "fmt" + "strconv" + "sync" + "sync/atomic" + + "github.com/99designs/gqlgen/graphql" + "github.com/99designs/gqlgen/graphql/introspection" + "github.com/99designs/gqlgen/plugin/federation/fedruntime" + gqlparser "github.com/vektah/gqlparser/v2" + "github.com/vektah/gqlparser/v2/ast" + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachetest/details/subgraph/model" +) + +// region ************************** generated!.gotpl ************************** + +// NewExecutableSchema creates an ExecutableSchema from the ResolverRoot interface. +func NewExecutableSchema(cfg Config) graphql.ExecutableSchema { + return &executableSchema{ + schema: cfg.Schema, + resolvers: cfg.Resolvers, + directives: cfg.Directives, + complexity: cfg.Complexity, + } +} + +type Config struct { + Schema *ast.Schema + Resolvers ResolverRoot + Directives DirectiveRoot + Complexity ComplexityRoot +} + +type ResolverRoot interface { + Entity() EntityResolver +} + +type DirectiveRoot struct { +} + +type ComplexityRoot struct { + Entity struct { + FindItemByID func(childComplexity int, id string) int + FindProductByIDAndRegion func(childComplexity int, id string, region string) int + FindWarehouseByLocationID func(childComplexity int, locationID string) int + } + + Item struct { + Description func(childComplexity int) int + ID func(childComplexity int) int + Rating func(childComplexity int) int + Tags func(childComplexity int) int + } + + Location struct { + ID func(childComplexity int) int + } + + Product struct { + ID func(childComplexity int) int + Info func(childComplexity int) int + Region func(childComplexity int) int + } + + Query struct { + __resolve__service func(childComplexity int) int + __resolve_entities func(childComplexity int, representations []map[string]any) int + } + + Warehouse struct { + Capacity func(childComplexity int) int + Location func(childComplexity int) int + } + + _Service struct { + SDL func(childComplexity int) int + } +} + +type EntityResolver interface { + FindItemByID(ctx context.Context, id string) (*model.Item, error) + FindProductByIDAndRegion(ctx context.Context, id string, region string) (*model.Product, error) + FindWarehouseByLocationID(ctx context.Context, locationID string) (*model.Warehouse, error) +} + +type executableSchema struct { + schema *ast.Schema + resolvers ResolverRoot + directives DirectiveRoot + complexity ComplexityRoot +} + +func (e *executableSchema) Schema() *ast.Schema { + if e.schema != nil { + return e.schema + } + return parsedSchema +} + +func (e *executableSchema) Complexity(ctx context.Context, typeName, field string, childComplexity int, rawArgs map[string]any) (int, bool) { + ec := executionContext{nil, e, 0, 0, nil} + _ = ec + switch typeName + "." + field { + + case "Entity.findItemByID": + if e.complexity.Entity.FindItemByID == nil { + break + } + + args, err := ec.field_Entity_findItemByID_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Entity.FindItemByID(childComplexity, args["id"].(string)), true + + case "Entity.findProductByIDAndRegion": + if e.complexity.Entity.FindProductByIDAndRegion == nil { + break + } + + args, err := ec.field_Entity_findProductByIDAndRegion_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Entity.FindProductByIDAndRegion(childComplexity, args["id"].(string), args["region"].(string)), true + + case "Entity.findWarehouseByLocationID": + if e.complexity.Entity.FindWarehouseByLocationID == nil { + break + } + + args, err := ec.field_Entity_findWarehouseByLocationID_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Entity.FindWarehouseByLocationID(childComplexity, args["locationID"].(string)), true + + case "Item.description": + if e.complexity.Item.Description == nil { + break + } + + return e.complexity.Item.Description(childComplexity), true + + case "Item.id": + if e.complexity.Item.ID == nil { + break + } + + return e.complexity.Item.ID(childComplexity), true + + case "Item.rating": + if e.complexity.Item.Rating == nil { + break + } + + return e.complexity.Item.Rating(childComplexity), true + + case "Item.tags": + if e.complexity.Item.Tags == nil { + break + } + + return e.complexity.Item.Tags(childComplexity), true + + case "Location.id": + if e.complexity.Location.ID == nil { + break + } + + return e.complexity.Location.ID(childComplexity), true + + case "Product.id": + if e.complexity.Product.ID == nil { + break + } + + return e.complexity.Product.ID(childComplexity), true + + case "Product.info": + if e.complexity.Product.Info == nil { + break + } + + return e.complexity.Product.Info(childComplexity), true + + case "Product.region": + if e.complexity.Product.Region == nil { + break + } + + return e.complexity.Product.Region(childComplexity), true + + case "Query._service": + if e.complexity.Query.__resolve__service == nil { + break + } + + return e.complexity.Query.__resolve__service(childComplexity), true + + case "Query._entities": + if e.complexity.Query.__resolve_entities == nil { + break + } + + args, err := ec.field_Query__entities_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.__resolve_entities(childComplexity, args["representations"].([]map[string]any)), true + + case "Warehouse.capacity": + if e.complexity.Warehouse.Capacity == nil { + break + } + + return e.complexity.Warehouse.Capacity(childComplexity), true + + case "Warehouse.location": + if e.complexity.Warehouse.Location == nil { + break + } + + return e.complexity.Warehouse.Location(childComplexity), true + + case "_Service.sdl": + if e.complexity._Service.SDL == nil { + break + } + + return e.complexity._Service.SDL(childComplexity), true + + } + return 0, false +} + +func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { + opCtx := graphql.GetOperationContext(ctx) + ec := executionContext{opCtx, e, 0, 0, make(chan graphql.DeferredResult)} + inputUnmarshalMap := graphql.BuildUnmarshalerMap() + first := true + + switch opCtx.Operation.Operation { + case ast.Query: + return func(ctx context.Context) *graphql.Response { + var response graphql.Response + var data graphql.Marshaler + if first { + first = false + ctx = graphql.WithUnmarshalerMap(ctx, inputUnmarshalMap) + data = ec._Query(ctx, opCtx.Operation.SelectionSet) + } else { + if atomic.LoadInt32(&ec.pendingDeferred) > 0 { + result := <-ec.deferredResults + atomic.AddInt32(&ec.pendingDeferred, -1) + data = result.Result + response.Path = result.Path + response.Label = result.Label + response.Errors = result.Errors + } else { + return nil + } + } + var buf bytes.Buffer + data.MarshalGQL(&buf) + response.Data = buf.Bytes() + if atomic.LoadInt32(&ec.deferred) > 0 { + hasNext := atomic.LoadInt32(&ec.pendingDeferred) > 0 + response.HasNext = &hasNext + } + + return &response + } + + default: + return graphql.OneShot(graphql.ErrorResponse(ctx, "unsupported GraphQL operation")) + } +} + +type executionContext struct { + *graphql.OperationContext + *executableSchema + deferred int32 + pendingDeferred int32 + deferredResults chan graphql.DeferredResult +} + +func (ec *executionContext) processDeferredGroup(dg graphql.DeferredGroup) { + atomic.AddInt32(&ec.pendingDeferred, 1) + go func() { + ctx := graphql.WithFreshResponseContext(dg.Context) + dg.FieldSet.Dispatch(ctx) + ds := graphql.DeferredResult{ + Path: dg.Path, + Label: dg.Label, + Result: dg.FieldSet, + Errors: graphql.GetErrors(ctx), + } + // null fields should bubble up + if dg.FieldSet.Invalids > 0 { + ds.Result = graphql.Null + } + ec.deferredResults <- ds + }() +} + +func (ec *executionContext) introspectSchema() (*introspection.Schema, error) { + if ec.DisableIntrospection { + return nil, errors.New("introspection disabled") + } + return introspection.WrapSchema(ec.Schema()), nil +} + +func (ec *executionContext) introspectType(name string) (*introspection.Type, error) { + if ec.DisableIntrospection { + return nil, errors.New("introspection disabled") + } + return introspection.WrapTypeFromDef(ec.Schema(), ec.Schema().Types[name]), nil +} + +var sources = []*ast.Source{ + {Name: "../schema.graphqls", Input: `extend schema + @link( + url: "https://specs.apollo.dev/federation/v2.5" + import: ["@key"] + ) + +directive @openfed__entityCache( + maxAge: Int! + includeHeaders: Boolean = false + partialCacheLoad: Boolean = false + shadowMode: Boolean = false +) on OBJECT + +type Item @key(fields: "id") @openfed__entityCache(maxAge: 300) { + id: ID! + description: String! + rating: Float! + tags: [String!]! +} + +type Product @key(fields: "id region") @openfed__entityCache(maxAge: 300) { + id: ID! + region: String! + info: String! +} + +type Location { + id: ID! +} + +type Warehouse @key(fields: "location { id }") @openfed__entityCache(maxAge: 300) { + location: Location! + capacity: Int! +} +`, BuiltIn: false}, + {Name: "../../federation/directives.graphql", Input: ` + directive @authenticated on FIELD_DEFINITION | OBJECT | INTERFACE | SCALAR | ENUM + directive @composeDirective(name: String!) repeatable on SCHEMA + directive @extends on OBJECT | INTERFACE + directive @external on OBJECT | FIELD_DEFINITION + directive @key(fields: FieldSet!, resolvable: Boolean = true) repeatable on OBJECT | INTERFACE + directive @inaccessible on + | ARGUMENT_DEFINITION + | ENUM + | ENUM_VALUE + | FIELD_DEFINITION + | INPUT_FIELD_DEFINITION + | INPUT_OBJECT + | INTERFACE + | OBJECT + | SCALAR + | UNION + directive @interfaceObject on OBJECT + directive @link(import: [String!], url: String!) repeatable on SCHEMA + directive @override(from: String!, label: String) on FIELD_DEFINITION + directive @policy(policies: [[federation__Policy!]!]!) on + | FIELD_DEFINITION + | OBJECT + | INTERFACE + | SCALAR + | ENUM + directive @provides(fields: FieldSet!) on FIELD_DEFINITION + directive @requires(fields: FieldSet!) on FIELD_DEFINITION + directive @requiresScopes(scopes: [[federation__Scope!]!]!) on + | FIELD_DEFINITION + | OBJECT + | INTERFACE + | SCALAR + | ENUM + directive @shareable repeatable on FIELD_DEFINITION | OBJECT + directive @tag(name: String!) repeatable on + | ARGUMENT_DEFINITION + | ENUM + | ENUM_VALUE + | FIELD_DEFINITION + | INPUT_FIELD_DEFINITION + | INPUT_OBJECT + | INTERFACE + | OBJECT + | SCALAR + | UNION + scalar _Any + scalar FieldSet + scalar federation__Policy + scalar federation__Scope +`, BuiltIn: true}, + {Name: "../../federation/entity.graphql", Input: ` +# a union of all types that use the @key directive +union _Entity = Item | Product | Warehouse + +# fake type to build resolver interfaces for users to implement +type Entity { + findItemByID(id: ID!,): Item! + findProductByIDAndRegion(id: ID!,region: String!,): Product! + findWarehouseByLocationID(locationID: ID!,): Warehouse! +} + +type _Service { + sdl: String +} + +extend type Query { + _entities(representations: [_Any!]!): [_Entity]! + _service: _Service! +} +`, BuiltIn: true}, +} +var parsedSchema = gqlparser.MustLoadSchema(sources...) + +// endregion ************************** generated!.gotpl ************************** + +// region ***************************** args.gotpl ***************************** + +func (ec *executionContext) field_Entity_findItemByID_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Entity_findItemByID_argsID(ctx, rawArgs) + if err != nil { + return nil, err + } + args["id"] = arg0 + return args, nil +} +func (ec *executionContext) field_Entity_findItemByID_argsID( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["id"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + if tmp, ok := rawArgs["id"]; ok { + return ec.unmarshalNID2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Entity_findProductByIDAndRegion_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Entity_findProductByIDAndRegion_argsID(ctx, rawArgs) + if err != nil { + return nil, err + } + args["id"] = arg0 + arg1, err := ec.field_Entity_findProductByIDAndRegion_argsRegion(ctx, rawArgs) + if err != nil { + return nil, err + } + args["region"] = arg1 + return args, nil +} +func (ec *executionContext) field_Entity_findProductByIDAndRegion_argsID( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["id"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + if tmp, ok := rawArgs["id"]; ok { + return ec.unmarshalNID2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Entity_findProductByIDAndRegion_argsRegion( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["region"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("region")) + if tmp, ok := rawArgs["region"]; ok { + return ec.unmarshalNString2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Entity_findWarehouseByLocationID_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Entity_findWarehouseByLocationID_argsLocationID(ctx, rawArgs) + if err != nil { + return nil, err + } + args["locationID"] = arg0 + return args, nil +} +func (ec *executionContext) field_Entity_findWarehouseByLocationID_argsLocationID( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["locationID"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("locationID")) + if tmp, ok := rawArgs["locationID"]; ok { + return ec.unmarshalNID2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Query___type_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Query___type_argsName(ctx, rawArgs) + if err != nil { + return nil, err + } + args["name"] = arg0 + return args, nil +} +func (ec *executionContext) field_Query___type_argsName( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["name"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("name")) + if tmp, ok := rawArgs["name"]; ok { + return ec.unmarshalNString2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Query__entities_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Query__entities_argsRepresentations(ctx, rawArgs) + if err != nil { + return nil, err + } + args["representations"] = arg0 + return args, nil +} +func (ec *executionContext) field_Query__entities_argsRepresentations( + ctx context.Context, + rawArgs map[string]any, +) ([]map[string]any, error) { + if _, ok := rawArgs["representations"]; !ok { + var zeroVal []map[string]any + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("representations")) + if tmp, ok := rawArgs["representations"]; ok { + return ec.unmarshalN_Any2ᚕmapᚄ(ctx, tmp) + } + + var zeroVal []map[string]any + return zeroVal, nil +} + +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 := ec.field___Directive_args_argsIncludeDeprecated(ctx, rawArgs) + if err != nil { + return nil, err + } + args["includeDeprecated"] = arg0 + return args, nil +} +func (ec *executionContext) field___Directive_args_argsIncludeDeprecated( + ctx context.Context, + rawArgs map[string]any, +) (*bool, error) { + if _, ok := rawArgs["includeDeprecated"]; !ok { + var zeroVal *bool + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("includeDeprecated")) + if tmp, ok := rawArgs["includeDeprecated"]; ok { + return ec.unmarshalOBoolean2ᚖbool(ctx, tmp) + } + + var zeroVal *bool + return zeroVal, nil +} + +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 := ec.field___Field_args_argsIncludeDeprecated(ctx, rawArgs) + if err != nil { + return nil, err + } + args["includeDeprecated"] = arg0 + return args, nil +} +func (ec *executionContext) field___Field_args_argsIncludeDeprecated( + ctx context.Context, + rawArgs map[string]any, +) (*bool, error) { + if _, ok := rawArgs["includeDeprecated"]; !ok { + var zeroVal *bool + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("includeDeprecated")) + if tmp, ok := rawArgs["includeDeprecated"]; ok { + return ec.unmarshalOBoolean2ᚖbool(ctx, tmp) + } + + var zeroVal *bool + return zeroVal, nil +} + +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 := ec.field___Type_enumValues_argsIncludeDeprecated(ctx, rawArgs) + if err != nil { + return nil, err + } + args["includeDeprecated"] = arg0 + return args, nil +} +func (ec *executionContext) field___Type_enumValues_argsIncludeDeprecated( + ctx context.Context, + rawArgs map[string]any, +) (bool, error) { + if _, ok := rawArgs["includeDeprecated"]; !ok { + var zeroVal bool + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("includeDeprecated")) + if tmp, ok := rawArgs["includeDeprecated"]; ok { + return ec.unmarshalOBoolean2bool(ctx, tmp) + } + + var zeroVal bool + return zeroVal, nil +} + +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 := ec.field___Type_fields_argsIncludeDeprecated(ctx, rawArgs) + if err != nil { + return nil, err + } + args["includeDeprecated"] = arg0 + return args, nil +} +func (ec *executionContext) field___Type_fields_argsIncludeDeprecated( + ctx context.Context, + rawArgs map[string]any, +) (bool, error) { + if _, ok := rawArgs["includeDeprecated"]; !ok { + var zeroVal bool + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("includeDeprecated")) + if tmp, ok := rawArgs["includeDeprecated"]; ok { + return ec.unmarshalOBoolean2bool(ctx, tmp) + } + + var zeroVal bool + return zeroVal, nil +} + +// endregion ***************************** args.gotpl ***************************** + +// region ************************** directives.gotpl ************************** + +// endregion ************************** directives.gotpl ************************** + +// region **************************** field.gotpl ***************************** + +func (ec *executionContext) _Entity_findItemByID(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Entity_findItemByID(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Entity().FindItemByID(rctx, fc.Args["id"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*model.Item) + fc.Result = res + return ec.marshalNItem2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋdetailsᚋsubgraphᚋmodelᚐItem(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Entity_findItemByID(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Entity", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Item_id(ctx, field) + case "description": + return ec.fieldContext_Item_description(ctx, field) + case "rating": + return ec.fieldContext_Item_rating(ctx, field) + case "tags": + return ec.fieldContext_Item_tags(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Item", field.Name) + }, + } + 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_Entity_findItemByID_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Entity_findProductByIDAndRegion(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Entity_findProductByIDAndRegion(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Entity().FindProductByIDAndRegion(rctx, fc.Args["id"].(string), fc.Args["region"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*model.Product) + fc.Result = res + return ec.marshalNProduct2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋdetailsᚋsubgraphᚋmodelᚐProduct(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Entity_findProductByIDAndRegion(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Entity", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Product_id(ctx, field) + case "region": + return ec.fieldContext_Product_region(ctx, field) + case "info": + return ec.fieldContext_Product_info(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Product", field.Name) + }, + } + 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_Entity_findProductByIDAndRegion_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Entity_findWarehouseByLocationID(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Entity_findWarehouseByLocationID(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Entity().FindWarehouseByLocationID(rctx, fc.Args["locationID"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*model.Warehouse) + fc.Result = res + return ec.marshalNWarehouse2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋdetailsᚋsubgraphᚋmodelᚐWarehouse(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Entity_findWarehouseByLocationID(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Entity", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "location": + return ec.fieldContext_Warehouse_location(ctx, field) + case "capacity": + return ec.fieldContext_Warehouse_capacity(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Warehouse", field.Name) + }, + } + 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_Entity_findWarehouseByLocationID_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Item_id(ctx context.Context, field graphql.CollectedField, obj *model.Item) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Item_id(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Item_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Item", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Item_description(ctx context.Context, field graphql.CollectedField, obj *model.Item) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Item_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Item_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Item", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Item_rating(ctx context.Context, field graphql.CollectedField, obj *model.Item) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Item_rating(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Rating, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(float64) + fc.Result = res + return ec.marshalNFloat2float64(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Item_rating(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Item", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Float does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Item_tags(ctx context.Context, field graphql.CollectedField, obj *model.Item) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Item_tags(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Tags, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]string) + fc.Result = res + return ec.marshalNString2ᚕstringᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Item_tags(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Item", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Location_id(ctx context.Context, field graphql.CollectedField, obj *model.Location) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Location_id(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Location_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Location", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Product_id(ctx context.Context, field graphql.CollectedField, obj *model.Product) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Product_id(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Product_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Product", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Product_region(ctx context.Context, field graphql.CollectedField, obj *model.Product) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Product_region(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Region, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Product_region(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Product", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Product_info(ctx context.Context, field graphql.CollectedField, obj *model.Product) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Product_info(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Info, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Product_info(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Product", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Query__entities(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query__entities(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.__resolve_entities(ctx, fc.Args["representations"].([]map[string]any)), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]fedruntime.Entity) + fc.Result = res + return ec.marshalN_Entity2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐEntity(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query__entities(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type _Entity does not have child fields") + }, + } + 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__entities_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query__service(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query__service(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.__resolve__service(ctx) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(fedruntime.Service) + fc.Result = res + return ec.marshalN_Service2githubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐService(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query__service(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "sdl": + return ec.fieldContext__Service_sdl(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type _Service", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Query___type(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query___type(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.introspectType(fc.Args["name"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query___type(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + 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___type_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query___schema(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query___schema(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.introspectSchema() + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Schema) + fc.Result = res + return ec.marshalO__Schema2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐSchema(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query___schema(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "description": + return ec.fieldContext___Schema_description(ctx, field) + case "types": + return ec.fieldContext___Schema_types(ctx, field) + case "queryType": + return ec.fieldContext___Schema_queryType(ctx, field) + case "mutationType": + return ec.fieldContext___Schema_mutationType(ctx, field) + case "subscriptionType": + return ec.fieldContext___Schema_subscriptionType(ctx, field) + case "directives": + return ec.fieldContext___Schema_directives(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Schema", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Warehouse_location(ctx context.Context, field graphql.CollectedField, obj *model.Warehouse) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Warehouse_location(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Location, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*model.Location) + fc.Result = res + return ec.marshalNLocation2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋdetailsᚋsubgraphᚋmodelᚐLocation(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Warehouse_location(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Warehouse", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Location_id(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Location", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Warehouse_capacity(ctx context.Context, field graphql.CollectedField, obj *model.Warehouse) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Warehouse_capacity(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Capacity, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Warehouse_capacity(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Warehouse", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) __Service_sdl(ctx context.Context, field graphql.CollectedField, obj *fedruntime.Service) (ret graphql.Marshaler) { + fc, err := ec.fieldContext__Service_sdl(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.SDL, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalOString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext__Service_sdl(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "_Service", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Directive_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Directive_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Directive_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Directive_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_isRepeatable(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Directive_isRepeatable(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsRepeatable, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Directive_isRepeatable(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_locations(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Directive_locations(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Locations, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]string) + fc.Result = res + return ec.marshalN__DirectiveLocation2ᚕstringᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Directive_locations(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type __DirectiveLocation does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_args(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Directive_args(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Args, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]introspection.InputValue) + fc.Result = res + return ec.marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Directive_args(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___InputValue_name(ctx, field) + case "description": + return ec.fieldContext___InputValue_description(ctx, field) + case "type": + return ec.fieldContext___InputValue_type(ctx, field) + case "defaultValue": + return ec.fieldContext___InputValue_defaultValue(ctx, field) + case "isDeprecated": + return ec.fieldContext___InputValue_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___InputValue_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __InputValue", field.Name) + }, + } + 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___Directive_args_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) ___EnumValue_name(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___EnumValue_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___EnumValue_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__EnumValue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___EnumValue_description(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___EnumValue_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___EnumValue_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__EnumValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___EnumValue_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___EnumValue_isDeprecated(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsDeprecated(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___EnumValue_isDeprecated(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__EnumValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___EnumValue_deprecationReason(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___EnumValue_deprecationReason(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.DeprecationReason(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___EnumValue_deprecationReason(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__EnumValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_args(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_args(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Args, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]introspection.InputValue) + fc.Result = res + return ec.marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_args(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___InputValue_name(ctx, field) + case "description": + return ec.fieldContext___InputValue_description(ctx, field) + case "type": + return ec.fieldContext___InputValue_type(ctx, field) + case "defaultValue": + return ec.fieldContext___InputValue_defaultValue(ctx, field) + case "isDeprecated": + return ec.fieldContext___InputValue_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___InputValue_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __InputValue", field.Name) + }, + } + 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___Field_args_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) ___Field_type(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_type(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Type, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_type(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_isDeprecated(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsDeprecated(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_isDeprecated(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_deprecationReason(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_deprecationReason(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.DeprecationReason(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_deprecationReason(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_name(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_description(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_type(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_type(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Type, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_type(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_defaultValue(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_defaultValue(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.DefaultValue, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_defaultValue(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_isDeprecated(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsDeprecated(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_isDeprecated(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_deprecationReason(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_deprecationReason(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.DeprecationReason(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_deprecationReason(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_types(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_types(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Types(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]introspection.Type) + fc.Result = res + return ec.marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_types(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_queryType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_queryType(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.QueryType(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_queryType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_mutationType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_mutationType(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.MutationType(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_mutationType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_subscriptionType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_subscriptionType(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.SubscriptionType(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_subscriptionType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_directives(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_directives(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Directives(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]introspection.Directive) + fc.Result = res + return ec.marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirectiveᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_directives(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___Directive_name(ctx, field) + case "description": + return ec.fieldContext___Directive_description(ctx, field) + case "isRepeatable": + return ec.fieldContext___Directive_isRepeatable(ctx, field) + case "locations": + return ec.fieldContext___Directive_locations(ctx, field) + case "args": + return ec.fieldContext___Directive_args(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Directive", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_kind(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_kind(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Kind(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalN__TypeKind2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_kind(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type __TypeKind does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_specifiedByURL(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_specifiedByURL(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.SpecifiedByURL(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_specifiedByURL(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_fields(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_fields(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Fields(fc.Args["includeDeprecated"].(bool)), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.Field) + fc.Result = res + return ec.marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐFieldᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_fields(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___Field_name(ctx, field) + case "description": + return ec.fieldContext___Field_description(ctx, field) + case "args": + return ec.fieldContext___Field_args(ctx, field) + case "type": + return ec.fieldContext___Field_type(ctx, field) + case "isDeprecated": + return ec.fieldContext___Field_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___Field_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Field", field.Name) + }, + } + 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_fields_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) ___Type_interfaces(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_interfaces(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Interfaces(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_interfaces(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_possibleTypes(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_possibleTypes(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.PossibleTypes(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_possibleTypes(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_enumValues(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_enumValues(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.EnumValues(fc.Args["includeDeprecated"].(bool)), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.EnumValue) + fc.Result = res + return ec.marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValueᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_enumValues(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___EnumValue_name(ctx, field) + case "description": + return ec.fieldContext___EnumValue_description(ctx, field) + case "isDeprecated": + return ec.fieldContext___EnumValue_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___EnumValue_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __EnumValue", field.Name) + }, + } + 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_enumValues_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) ___Type_inputFields(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_inputFields(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.InputFields(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.InputValue) + fc.Result = res + return ec.marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_inputFields(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___InputValue_name(ctx, field) + case "description": + return ec.fieldContext___InputValue_description(ctx, field) + case "type": + return ec.fieldContext___InputValue_type(ctx, field) + case "defaultValue": + return ec.fieldContext___InputValue_defaultValue(ctx, field) + case "isDeprecated": + return ec.fieldContext___InputValue_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___InputValue_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __InputValue", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_ofType(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_ofType(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.OfType(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_ofType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_isOneOf(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_isOneOf(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsOneOf(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalOBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_isOneOf(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +// endregion **************************** field.gotpl ***************************** + +// region **************************** input.gotpl ***************************** + +// endregion **************************** input.gotpl ***************************** + +// region ************************** interface.gotpl *************************** + +func (ec *executionContext) __Entity(ctx context.Context, sel ast.SelectionSet, obj fedruntime.Entity) graphql.Marshaler { + switch obj := (obj).(type) { + case nil: + return graphql.Null + case model.Warehouse: + return ec._Warehouse(ctx, sel, &obj) + case *model.Warehouse: + if obj == nil { + return graphql.Null + } + return ec._Warehouse(ctx, sel, obj) + case model.Product: + return ec._Product(ctx, sel, &obj) + case *model.Product: + if obj == nil { + return graphql.Null + } + return ec._Product(ctx, sel, obj) + case model.Item: + return ec._Item(ctx, sel, &obj) + case *model.Item: + if obj == nil { + return graphql.Null + } + return ec._Item(ctx, sel, obj) + default: + panic(fmt.Errorf("unexpected type %T", obj)) + } +} + +// endregion ************************** interface.gotpl *************************** + +// region **************************** object.gotpl **************************** + +var entityImplementors = []string{"Entity"} + +func (ec *executionContext) _Entity(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, entityImplementors) + ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ + Object: "Entity", + }) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ + Object: field.Name, + Field: field, + }) + + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Entity") + case "findItemByID": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Entity_findItemByID(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "findProductByIDAndRegion": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Entity_findProductByIDAndRegion(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "findWarehouseByLocationID": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Entity_findWarehouseByLocationID(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var itemImplementors = []string{"Item", "_Entity"} + +func (ec *executionContext) _Item(ctx context.Context, sel ast.SelectionSet, obj *model.Item) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, itemImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Item") + case "id": + out.Values[i] = ec._Item_id(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "description": + out.Values[i] = ec._Item_description(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "rating": + out.Values[i] = ec._Item_rating(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "tags": + out.Values[i] = ec._Item_tags(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 + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var locationImplementors = []string{"Location"} + +func (ec *executionContext) _Location(ctx context.Context, sel ast.SelectionSet, obj *model.Location) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, locationImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Location") + case "id": + out.Values[i] = ec._Location_id(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 + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var productImplementors = []string{"Product", "_Entity"} + +func (ec *executionContext) _Product(ctx context.Context, sel ast.SelectionSet, obj *model.Product) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, productImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Product") + case "id": + out.Values[i] = ec._Product_id(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "region": + out.Values[i] = ec._Product_region(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "info": + out.Values[i] = ec._Product_info(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 + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var queryImplementors = []string{"Query"} + +func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, queryImplementors) + ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ + Object: "Query", + }) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ + Object: field.Name, + Field: field, + }) + + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Query") + case "_entities": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query__entities(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "_service": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query__service(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "__type": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Query___type(ctx, field) + }) + case "__schema": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Query___schema(ctx, field) + }) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var warehouseImplementors = []string{"Warehouse", "_Entity"} + +func (ec *executionContext) _Warehouse(ctx context.Context, sel ast.SelectionSet, obj *model.Warehouse) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, warehouseImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Warehouse") + case "location": + out.Values[i] = ec._Warehouse_location(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "capacity": + out.Values[i] = ec._Warehouse_capacity(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 + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var _ServiceImplementors = []string{"_Service"} + +func (ec *executionContext) __Service(ctx context.Context, sel ast.SelectionSet, obj *fedruntime.Service) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, _ServiceImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("_Service") + case "sdl": + out.Values[i] = ec.__Service_sdl(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __DirectiveImplementors = []string{"__Directive"} + +func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionSet, obj *introspection.Directive) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __DirectiveImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__Directive") + case "name": + out.Values[i] = ec.___Directive_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "description": + out.Values[i] = ec.___Directive_description(ctx, field, obj) + case "isRepeatable": + out.Values[i] = ec.___Directive_isRepeatable(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "locations": + out.Values[i] = ec.___Directive_locations(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "args": + out.Values[i] = ec.___Directive_args(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 + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __EnumValueImplementors = []string{"__EnumValue"} + +func (ec *executionContext) ___EnumValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.EnumValue) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __EnumValueImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__EnumValue") + case "name": + out.Values[i] = ec.___EnumValue_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "description": + out.Values[i] = ec.___EnumValue_description(ctx, field, obj) + case "isDeprecated": + out.Values[i] = ec.___EnumValue_isDeprecated(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "deprecationReason": + out.Values[i] = ec.___EnumValue_deprecationReason(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __FieldImplementors = []string{"__Field"} + +func (ec *executionContext) ___Field(ctx context.Context, sel ast.SelectionSet, obj *introspection.Field) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __FieldImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__Field") + case "name": + out.Values[i] = ec.___Field_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "description": + out.Values[i] = ec.___Field_description(ctx, field, obj) + case "args": + out.Values[i] = ec.___Field_args(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "type": + out.Values[i] = ec.___Field_type(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "isDeprecated": + out.Values[i] = ec.___Field_isDeprecated(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "deprecationReason": + out.Values[i] = ec.___Field_deprecationReason(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __InputValueImplementors = []string{"__InputValue"} + +func (ec *executionContext) ___InputValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.InputValue) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __InputValueImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__InputValue") + case "name": + out.Values[i] = ec.___InputValue_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "description": + out.Values[i] = ec.___InputValue_description(ctx, field, obj) + case "type": + out.Values[i] = ec.___InputValue_type(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "defaultValue": + out.Values[i] = ec.___InputValue_defaultValue(ctx, field, obj) + case "isDeprecated": + out.Values[i] = ec.___InputValue_isDeprecated(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "deprecationReason": + out.Values[i] = ec.___InputValue_deprecationReason(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __SchemaImplementors = []string{"__Schema"} + +func (ec *executionContext) ___Schema(ctx context.Context, sel ast.SelectionSet, obj *introspection.Schema) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __SchemaImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__Schema") + case "description": + out.Values[i] = ec.___Schema_description(ctx, field, obj) + case "types": + out.Values[i] = ec.___Schema_types(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "queryType": + out.Values[i] = ec.___Schema_queryType(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "mutationType": + out.Values[i] = ec.___Schema_mutationType(ctx, field, obj) + case "subscriptionType": + out.Values[i] = ec.___Schema_subscriptionType(ctx, field, obj) + case "directives": + out.Values[i] = ec.___Schema_directives(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 + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __TypeImplementors = []string{"__Type"} + +func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, obj *introspection.Type) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __TypeImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__Type") + case "kind": + out.Values[i] = ec.___Type_kind(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "name": + out.Values[i] = ec.___Type_name(ctx, field, obj) + case "description": + out.Values[i] = ec.___Type_description(ctx, field, obj) + case "specifiedByURL": + out.Values[i] = ec.___Type_specifiedByURL(ctx, field, obj) + case "fields": + out.Values[i] = ec.___Type_fields(ctx, field, obj) + case "interfaces": + out.Values[i] = ec.___Type_interfaces(ctx, field, obj) + case "possibleTypes": + out.Values[i] = ec.___Type_possibleTypes(ctx, field, obj) + case "enumValues": + out.Values[i] = ec.___Type_enumValues(ctx, field, obj) + case "inputFields": + out.Values[i] = ec.___Type_inputFields(ctx, field, obj) + case "ofType": + out.Values[i] = ec.___Type_ofType(ctx, field, obj) + case "isOneOf": + out.Values[i] = ec.___Type_isOneOf(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +// endregion **************************** object.gotpl **************************** + +// region ***************************** type.gotpl ***************************** + +func (ec *executionContext) unmarshalNBoolean2bool(ctx context.Context, v any) (bool, error) { + res, err := graphql.UnmarshalBoolean(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNBoolean2bool(ctx context.Context, sel ast.SelectionSet, v bool) graphql.Marshaler { + _ = sel + res := graphql.MarshalBoolean(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNFieldSet2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNFieldSet2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNFloat2float64(ctx context.Context, v any) (float64, error) { + res, err := graphql.UnmarshalFloatContext(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNFloat2float64(ctx context.Context, sel ast.SelectionSet, v float64) graphql.Marshaler { + _ = sel + res := graphql.MarshalFloatContext(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return graphql.WrapContextMarshaler(ctx, res) +} + +func (ec *executionContext) unmarshalNID2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalID(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNID2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalID(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNInt2int(ctx context.Context, v any) (int, error) { + res, err := graphql.UnmarshalInt(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNInt2int(ctx context.Context, sel ast.SelectionSet, v int) graphql.Marshaler { + _ = sel + res := graphql.MarshalInt(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) marshalNItem2githubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋdetailsᚋsubgraphᚋmodelᚐItem(ctx context.Context, sel ast.SelectionSet, v model.Item) graphql.Marshaler { + return ec._Item(ctx, sel, &v) +} + +func (ec *executionContext) marshalNItem2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋdetailsᚋsubgraphᚋmodelᚐItem(ctx context.Context, sel ast.SelectionSet, v *model.Item) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._Item(ctx, sel, v) +} + +func (ec *executionContext) marshalNLocation2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋdetailsᚋsubgraphᚋmodelᚐLocation(ctx context.Context, sel ast.SelectionSet, v *model.Location) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._Location(ctx, sel, v) +} + +func (ec *executionContext) marshalNProduct2githubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋdetailsᚋsubgraphᚋmodelᚐProduct(ctx context.Context, sel ast.SelectionSet, v model.Product) graphql.Marshaler { + return ec._Product(ctx, sel, &v) +} + +func (ec *executionContext) marshalNProduct2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋdetailsᚋsubgraphᚋmodelᚐProduct(ctx context.Context, sel ast.SelectionSet, v *model.Product) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._Product(ctx, sel, v) +} + +func (ec *executionContext) unmarshalNString2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNString2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNString2ᚕstringᚄ(ctx context.Context, v any) ([]string, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNString2string(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalNString2ᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v []string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNString2string(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalNWarehouse2githubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋdetailsᚋsubgraphᚋmodelᚐWarehouse(ctx context.Context, sel ast.SelectionSet, v model.Warehouse) graphql.Marshaler { + return ec._Warehouse(ctx, sel, &v) +} + +func (ec *executionContext) marshalNWarehouse2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋdetailsᚋsubgraphᚋmodelᚐWarehouse(ctx context.Context, sel ast.SelectionSet, v *model.Warehouse) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._Warehouse(ctx, sel, v) +} + +func (ec *executionContext) unmarshalN_Any2map(ctx context.Context, v any) (map[string]any, error) { + res, err := graphql.UnmarshalMap(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalN_Any2map(ctx context.Context, sel ast.SelectionSet, v map[string]any) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + _ = sel + res := graphql.MarshalMap(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalN_Any2ᚕmapᚄ(ctx context.Context, v any) ([]map[string]any, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([]map[string]any, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalN_Any2map(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalN_Any2ᚕmapᚄ(ctx context.Context, sel ast.SelectionSet, v []map[string]any) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalN_Any2map(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalN_Entity2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐEntity(ctx context.Context, sel ast.SelectionSet, v []fedruntime.Entity) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalO_Entity2githubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐEntity(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + return ret +} + +func (ec *executionContext) marshalN_Service2githubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐService(ctx context.Context, sel ast.SelectionSet, v fedruntime.Service) graphql.Marshaler { + return ec.__Service(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__Directive2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirective(ctx context.Context, sel ast.SelectionSet, v introspection.Directive) graphql.Marshaler { + return ec.___Directive(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirectiveᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.Directive) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__Directive2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirective(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalN__DirectiveLocation2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalN__DirectiveLocation2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalN__DirectiveLocation2ᚕstringᚄ(ctx context.Context, v any) ([]string, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalN__DirectiveLocation2string(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalN__DirectiveLocation2ᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v []string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__DirectiveLocation2string(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalN__EnumValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValue(ctx context.Context, sel ast.SelectionSet, v introspection.EnumValue) graphql.Marshaler { + return ec.___EnumValue(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__Field2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐField(ctx context.Context, sel ast.SelectionSet, v introspection.Field) graphql.Marshaler { + return ec.___Field(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__InputValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValue(ctx context.Context, sel ast.SelectionSet, v introspection.InputValue) graphql.Marshaler { + return ec.___InputValue(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.InputValue) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__InputValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValue(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +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) +} + +func (ec *executionContext) marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.Type) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__Type2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx context.Context, sel ast.SelectionSet, v *introspection.Type) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec.___Type(ctx, sel, v) +} + +func (ec *executionContext) unmarshalN__TypeKind2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalN__TypeKind2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNfederation__Policy2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNfederation__Policy2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNfederation__Policy2ᚕstringᚄ(ctx context.Context, v any) ([]string, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNfederation__Policy2string(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalNfederation__Policy2ᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v []string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNfederation__Policy2string(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalNfederation__Policy2ᚕᚕstringᚄ(ctx context.Context, v any) ([][]string, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([][]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNfederation__Policy2ᚕstringᚄ(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalNfederation__Policy2ᚕᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v [][]string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNfederation__Policy2ᚕstringᚄ(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalNfederation__Scope2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNfederation__Scope2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNfederation__Scope2ᚕstringᚄ(ctx context.Context, v any) ([]string, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNfederation__Scope2string(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalNfederation__Scope2ᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v []string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNfederation__Scope2string(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalNfederation__Scope2ᚕᚕstringᚄ(ctx context.Context, v any) ([][]string, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([][]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNfederation__Scope2ᚕstringᚄ(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalNfederation__Scope2ᚕᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v [][]string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNfederation__Scope2ᚕstringᚄ(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalOBoolean2bool(ctx context.Context, v any) (bool, error) { + res, err := graphql.UnmarshalBoolean(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOBoolean2bool(ctx context.Context, sel ast.SelectionSet, v bool) graphql.Marshaler { + _ = sel + _ = ctx + res := graphql.MarshalBoolean(v) + return res +} + +func (ec *executionContext) unmarshalOBoolean2ᚖbool(ctx context.Context, v any) (*bool, error) { + if v == nil { + return nil, nil + } + res, err := graphql.UnmarshalBoolean(v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOBoolean2ᚖbool(ctx context.Context, sel ast.SelectionSet, v *bool) graphql.Marshaler { + if v == nil { + return graphql.Null + } + _ = sel + _ = ctx + res := graphql.MarshalBoolean(*v) + return res +} + +func (ec *executionContext) unmarshalOString2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOString2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + _ = ctx + res := graphql.MarshalString(v) + return res +} + +func (ec *executionContext) unmarshalOString2ᚕstringᚄ(ctx context.Context, v any) ([]string, error) { + if v == nil { + return nil, nil + } + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNString2string(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalOString2ᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v []string) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNString2string(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalOString2ᚖstring(ctx context.Context, v any) (*string, error) { + if v == nil { + return nil, nil + } + res, err := graphql.UnmarshalString(v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOString2ᚖstring(ctx context.Context, sel ast.SelectionSet, v *string) graphql.Marshaler { + if v == nil { + return graphql.Null + } + _ = sel + _ = ctx + res := graphql.MarshalString(*v) + return res +} + +func (ec *executionContext) marshalO_Entity2githubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐEntity(ctx context.Context, sel ast.SelectionSet, v fedruntime.Entity) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec.__Entity(ctx, sel, v) +} + +func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.EnumValue) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__EnumValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValue(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐFieldᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.Field) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__Field2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐField(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.InputValue) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__InputValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValue(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + 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 + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__Type2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +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 + } + return ec.___Type(ctx, sel, v) +} + +// endregion ***************************** type.gotpl ***************************** diff --git a/demo/pkg/subgraphs/cachetest/details/subgraph/generated/staticcheck.conf b/demo/pkg/subgraphs/cachetest/details/subgraph/generated/staticcheck.conf new file mode 100644 index 0000000000..582953a07e --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/details/subgraph/generated/staticcheck.conf @@ -0,0 +1,2 @@ +# This is meant as a workaround to skip staticcheck checks for generated code +checks = ["all", "-SA4004", "-ST1000"] diff --git a/demo/pkg/subgraphs/cachetest/details/subgraph/model/models_gen.go b/demo/pkg/subgraphs/cachetest/details/subgraph/model/models_gen.go new file mode 100644 index 0000000000..37c4142d26 --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/details/subgraph/model/models_gen.go @@ -0,0 +1,34 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package model + +type Item struct { + ID string `json:"id"` + Description string `json:"description"` + Rating float64 `json:"rating"` + Tags []string `json:"tags"` +} + +func (Item) IsEntity() {} + +type Location struct { + ID string `json:"id"` +} + +type Product struct { + ID string `json:"id"` + Region string `json:"region"` + Info string `json:"info"` +} + +func (Product) IsEntity() {} + +type Query struct { +} + +type Warehouse struct { + Location *Location `json:"location"` + Capacity int `json:"capacity"` +} + +func (Warehouse) IsEntity() {} diff --git a/demo/pkg/subgraphs/cachetest/details/subgraph/resolver.go b/demo/pkg/subgraphs/cachetest/details/subgraph/resolver.go new file mode 100644 index 0000000000..c1da1a4335 --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/details/subgraph/resolver.go @@ -0,0 +1,7 @@ +package subgraph + +// This file will not be regenerated automatically. +// +// It serves as dependency injection for your app, add any dependencies you require here. + +type Resolver struct{} diff --git a/demo/pkg/subgraphs/cachetest/details/subgraph/schema.graphqls b/demo/pkg/subgraphs/cachetest/details/subgraph/schema.graphqls new file mode 100644 index 0000000000..4d54164b0c --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/details/subgraph/schema.graphqls @@ -0,0 +1,34 @@ +extend schema + @link( + url: "https://specs.apollo.dev/federation/v2.5" + import: ["@key"] + ) + +directive @openfed__entityCache( + maxAge: Int! + includeHeaders: Boolean = false + partialCacheLoad: Boolean = false + shadowMode: Boolean = false +) on OBJECT + +type Item @key(fields: "id") @openfed__entityCache(maxAge: 300) { + id: ID! + description: String! + rating: Float! + tags: [String!]! +} + +type Product @key(fields: "id region") @openfed__entityCache(maxAge: 300) { + id: ID! + region: String! + info: String! +} + +type Location { + id: ID! +} + +type Warehouse @key(fields: "location { id }") @openfed__entityCache(maxAge: 300) { + location: Location! + capacity: Int! +} diff --git a/demo/pkg/subgraphs/cachetest/inventory/generate.go b/demo/pkg/subgraphs/cachetest/inventory/generate.go new file mode 100644 index 0000000000..af1dc70b37 --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/inventory/generate.go @@ -0,0 +1,3 @@ +//go:generate go run github.com/99designs/gqlgen generate + +package inventory diff --git a/demo/pkg/subgraphs/cachetest/inventory/gqlgen.yml b/demo/pkg/subgraphs/cachetest/inventory/gqlgen.yml new file mode 100644 index 0000000000..6fb37cff77 --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/inventory/gqlgen.yml @@ -0,0 +1,39 @@ +schema: + - subgraph/*.graphqls + +exec: + filename: subgraph/generated/generated.go + package: generated + +federation: + filename: subgraph/generated/federation.go + package: generated + version: 2 + options: + explicit_requires: true + +model: + filename: subgraph/model/models_gen.go + package: model + +resolver: + layout: follow-schema + dir: subgraph + package: subgraph + +directives: + openfed__entityCache: + skip_runtime: true + +models: + ID: + model: + - github.com/99designs/gqlgen/graphql.ID + - github.com/99designs/gqlgen/graphql.Int + - github.com/99designs/gqlgen/graphql.Int64 + - github.com/99designs/gqlgen/graphql.Int32 + Int: + model: + - github.com/99designs/gqlgen/graphql.Int + - github.com/99designs/gqlgen/graphql.Int64 + - github.com/99designs/gqlgen/graphql.Int32 diff --git a/demo/pkg/subgraphs/cachetest/inventory/inventory.go b/demo/pkg/subgraphs/cachetest/inventory/inventory.go new file mode 100644 index 0000000000..65b8ceb326 --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/inventory/inventory.go @@ -0,0 +1,14 @@ +package inventory + +import ( + "github.com/99designs/gqlgen/graphql" + + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachetest/inventory/subgraph" + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachetest/inventory/subgraph/generated" +) + +func NewSchema() graphql.ExecutableSchema { + return generated.NewExecutableSchema(generated.Config{ + Resolvers: &subgraph.Resolver{}, + }) +} diff --git a/demo/pkg/subgraphs/cachetest/inventory/subgraph/data.go b/demo/pkg/subgraphs/cachetest/inventory/subgraph/data.go new file mode 100644 index 0000000000..b22529066d --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/inventory/subgraph/data.go @@ -0,0 +1,13 @@ +package subgraph + +import ( + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachetest/inventory/subgraph/model" +) + +var ItemInventory = map[string]*model.Item{ + "1": {ID: "1", Available: true, Count: 100}, + "2": {ID: "2", Available: true, Count: 50}, + "3": {ID: "3", Available: false, Count: 0}, + "4": {ID: "4", Available: true, Count: 25}, + "5": {ID: "5", Available: true, Count: 10}, +} diff --git a/demo/pkg/subgraphs/cachetest/inventory/subgraph/entity.resolvers.go b/demo/pkg/subgraphs/cachetest/inventory/subgraph/entity.resolvers.go new file mode 100644 index 0000000000..b70004bc93 --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/inventory/subgraph/entity.resolvers.go @@ -0,0 +1,25 @@ +package subgraph + +// 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.76 + +import ( + "context" + + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachetest/inventory/subgraph/generated" + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachetest/inventory/subgraph/model" +) + +// FindItemByID is the resolver for the findItemByID field. +func (r *entityResolver) FindItemByID(ctx context.Context, id string) (*model.Item, error) { + if item, ok := ItemInventory[id]; ok { + return item, nil + } + return nil, nil +} + +// Entity returns generated.EntityResolver implementation. +func (r *Resolver) Entity() generated.EntityResolver { return &entityResolver{r} } + +type entityResolver struct{ *Resolver } diff --git a/demo/pkg/subgraphs/cachetest/inventory/subgraph/generated/federation.go b/demo/pkg/subgraphs/cachetest/inventory/subgraph/generated/federation.go new file mode 100644 index 0000000000..4fd9616459 --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/inventory/subgraph/generated/federation.go @@ -0,0 +1,234 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package generated + +import ( + "context" + "errors" + "fmt" + "strings" + "sync" + + "github.com/99designs/gqlgen/plugin/federation/fedruntime" +) + +var ( + ErrUnknownType = errors.New("unknown type") + ErrTypeNotFound = errors.New("type not found") +) + +func (ec *executionContext) __resolve__service(ctx context.Context) (fedruntime.Service, error) { + if ec.DisableIntrospection { + return fedruntime.Service{}, errors.New("federated introspection disabled") + } + + var sdl []string + + for _, src := range sources { + if src.BuiltIn { + continue + } + sdl = append(sdl, src.Input) + } + + return fedruntime.Service{ + SDL: strings.Join(sdl, "\n"), + }, nil +} + +func (ec *executionContext) __resolve_entities(ctx context.Context, representations []map[string]any) []fedruntime.Entity { + list := make([]fedruntime.Entity, len(representations)) + + repsMap := ec.buildRepresentationGroups(ctx, representations) + + switch len(repsMap) { + case 0: + return list + case 1: + for typeName, reps := range repsMap { + ec.resolveEntityGroup(ctx, typeName, reps, list) + } + return list + default: + var g sync.WaitGroup + g.Add(len(repsMap)) + for typeName, reps := range repsMap { + go func(typeName string, reps []EntityWithIndex) { + ec.resolveEntityGroup(ctx, typeName, reps, list) + g.Done() + }(typeName, reps) + } + g.Wait() + return list + } +} + +type EntityWithIndex struct { + // The index in the original representation array + index int + entity EntityRepresentation +} + +// EntityRepresentation is the JSON representation of an entity sent by the Router +// used as the inputs for us to resolve. +// +// We make it a map because we know the top level JSON is always an object. +type EntityRepresentation map[string]any + +// We group entities by typename so that we can parallelize their resolution. +// This is particularly helpful when there are entity groups in multi mode. +func (ec *executionContext) buildRepresentationGroups( + ctx context.Context, + representations []map[string]any, +) map[string][]EntityWithIndex { + repsMap := make(map[string][]EntityWithIndex) + for i, rep := range representations { + typeName, ok := rep["__typename"].(string) + if !ok { + // If there is no __typename, we just skip the representation; + // we just won't be resolving these unknown types. + ec.Error(ctx, errors.New("__typename must be an existing string")) + continue + } + + repsMap[typeName] = append(repsMap[typeName], EntityWithIndex{ + index: i, + entity: rep, + }) + } + + return repsMap +} + +func (ec *executionContext) resolveEntityGroup( + ctx context.Context, + typeName string, + reps []EntityWithIndex, + list []fedruntime.Entity, +) { + if isMulti(typeName) { + err := ec.resolveManyEntities(ctx, typeName, reps, list) + if err != nil { + ec.Error(ctx, err) + } + } else { + // if there are multiple entities to resolve, parallelize (similar to + // graphql.FieldSet.Dispatch) + var e sync.WaitGroup + e.Add(len(reps)) + for i, rep := range reps { + i, rep := i, rep + go func(i int, rep EntityWithIndex) { + entity, err := ec.resolveEntity(ctx, typeName, rep.entity) + if err != nil { + ec.Error(ctx, err) + } else { + list[rep.index] = entity + } + e.Done() + }(i, rep) + } + e.Wait() + } +} + +func isMulti(typeName string) bool { + switch typeName { + default: + return false + } +} + +func (ec *executionContext) resolveEntity( + ctx context.Context, + typeName string, + rep EntityRepresentation, +) (e fedruntime.Entity, err error) { + // we need to do our own panic handling, because we may be called in a + // goroutine, where the usual panic handling can't catch us + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + } + }() + + switch typeName { + case "Item": + resolverName, err := entityResolverNameForItem(ctx, rep) + if err != nil { + return nil, fmt.Errorf(`finding resolver for Entity "Item": %w`, err) + } + switch resolverName { + + case "findItemByID": + id0, err := ec.unmarshalNID2string(ctx, rep["id"]) + if err != nil { + return nil, fmt.Errorf(`unmarshalling param 0 for findItemByID(): %w`, err) + } + entity, err := ec.resolvers.Entity().FindItemByID(ctx, id0) + if err != nil { + return nil, fmt.Errorf(`resolving Entity "Item": %w`, err) + } + + return entity, nil + } + + } + return nil, fmt.Errorf("%w: %s", ErrUnknownType, typeName) +} + +func (ec *executionContext) resolveManyEntities( + ctx context.Context, + typeName string, + reps []EntityWithIndex, + list []fedruntime.Entity, +) (err error) { + // we need to do our own panic handling, because we may be called in a + // goroutine, where the usual panic handling can't catch us + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + } + }() + + switch typeName { + + default: + return errors.New("unknown type: " + typeName) + } +} + +func entityResolverNameForItem(ctx context.Context, rep EntityRepresentation) (string, error) { + // we collect errors because a later entity resolver may work fine + // when an entity has multiple keys + entityResolverErrs := []error{} + for { + var ( + m EntityRepresentation + val any + ok bool + ) + _ = val + // if all of the KeyFields values for this resolver are null, + // we shouldn't use use it + allNull := true + m = rep + val, ok = m["id"] + if !ok { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to missing Key Field \"id\" for Item", ErrTypeNotFound)) + break + } + if allNull { + allNull = val == nil + } + if allNull { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to all null value KeyFields for Item", ErrTypeNotFound)) + break + } + return "findItemByID", nil + } + return "", fmt.Errorf("%w for Item due to %v", ErrTypeNotFound, + errors.Join(entityResolverErrs...).Error()) +} diff --git a/demo/pkg/subgraphs/cachetest/inventory/subgraph/generated/generated.go b/demo/pkg/subgraphs/cachetest/inventory/subgraph/generated/generated.go new file mode 100644 index 0000000000..35c2954eaa --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/inventory/subgraph/generated/generated.go @@ -0,0 +1,4460 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package generated + +import ( + "bytes" + "context" + "errors" + "fmt" + "strconv" + "sync" + "sync/atomic" + + "github.com/99designs/gqlgen/graphql" + "github.com/99designs/gqlgen/graphql/introspection" + "github.com/99designs/gqlgen/plugin/federation/fedruntime" + gqlparser "github.com/vektah/gqlparser/v2" + "github.com/vektah/gqlparser/v2/ast" + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachetest/inventory/subgraph/model" +) + +// region ************************** generated!.gotpl ************************** + +// NewExecutableSchema creates an ExecutableSchema from the ResolverRoot interface. +func NewExecutableSchema(cfg Config) graphql.ExecutableSchema { + return &executableSchema{ + schema: cfg.Schema, + resolvers: cfg.Resolvers, + directives: cfg.Directives, + complexity: cfg.Complexity, + } +} + +type Config struct { + Schema *ast.Schema + Resolvers ResolverRoot + Directives DirectiveRoot + Complexity ComplexityRoot +} + +type ResolverRoot interface { + Entity() EntityResolver +} + +type DirectiveRoot struct { +} + +type ComplexityRoot struct { + Entity struct { + FindItemByID func(childComplexity int, id string) int + } + + Item struct { + Available func(childComplexity int) int + Count func(childComplexity int) int + ID func(childComplexity int) int + } + + Query struct { + __resolve__service func(childComplexity int) int + __resolve_entities func(childComplexity int, representations []map[string]any) int + } + + _Service struct { + SDL func(childComplexity int) int + } +} + +type EntityResolver interface { + FindItemByID(ctx context.Context, id string) (*model.Item, error) +} + +type executableSchema struct { + schema *ast.Schema + resolvers ResolverRoot + directives DirectiveRoot + complexity ComplexityRoot +} + +func (e *executableSchema) Schema() *ast.Schema { + if e.schema != nil { + return e.schema + } + return parsedSchema +} + +func (e *executableSchema) Complexity(ctx context.Context, typeName, field string, childComplexity int, rawArgs map[string]any) (int, bool) { + ec := executionContext{nil, e, 0, 0, nil} + _ = ec + switch typeName + "." + field { + + case "Entity.findItemByID": + if e.complexity.Entity.FindItemByID == nil { + break + } + + args, err := ec.field_Entity_findItemByID_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Entity.FindItemByID(childComplexity, args["id"].(string)), true + + case "Item.available": + if e.complexity.Item.Available == nil { + break + } + + return e.complexity.Item.Available(childComplexity), true + + case "Item.count": + if e.complexity.Item.Count == nil { + break + } + + return e.complexity.Item.Count(childComplexity), true + + case "Item.id": + if e.complexity.Item.ID == nil { + break + } + + return e.complexity.Item.ID(childComplexity), true + + case "Query._service": + if e.complexity.Query.__resolve__service == nil { + break + } + + return e.complexity.Query.__resolve__service(childComplexity), true + + case "Query._entities": + if e.complexity.Query.__resolve_entities == nil { + break + } + + args, err := ec.field_Query__entities_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.__resolve_entities(childComplexity, args["representations"].([]map[string]any)), true + + case "_Service.sdl": + if e.complexity._Service.SDL == nil { + break + } + + return e.complexity._Service.SDL(childComplexity), true + + } + return 0, false +} + +func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { + opCtx := graphql.GetOperationContext(ctx) + ec := executionContext{opCtx, e, 0, 0, make(chan graphql.DeferredResult)} + inputUnmarshalMap := graphql.BuildUnmarshalerMap() + first := true + + switch opCtx.Operation.Operation { + case ast.Query: + return func(ctx context.Context) *graphql.Response { + var response graphql.Response + var data graphql.Marshaler + if first { + first = false + ctx = graphql.WithUnmarshalerMap(ctx, inputUnmarshalMap) + data = ec._Query(ctx, opCtx.Operation.SelectionSet) + } else { + if atomic.LoadInt32(&ec.pendingDeferred) > 0 { + result := <-ec.deferredResults + atomic.AddInt32(&ec.pendingDeferred, -1) + data = result.Result + response.Path = result.Path + response.Label = result.Label + response.Errors = result.Errors + } else { + return nil + } + } + var buf bytes.Buffer + data.MarshalGQL(&buf) + response.Data = buf.Bytes() + if atomic.LoadInt32(&ec.deferred) > 0 { + hasNext := atomic.LoadInt32(&ec.pendingDeferred) > 0 + response.HasNext = &hasNext + } + + return &response + } + + default: + return graphql.OneShot(graphql.ErrorResponse(ctx, "unsupported GraphQL operation")) + } +} + +type executionContext struct { + *graphql.OperationContext + *executableSchema + deferred int32 + pendingDeferred int32 + deferredResults chan graphql.DeferredResult +} + +func (ec *executionContext) processDeferredGroup(dg graphql.DeferredGroup) { + atomic.AddInt32(&ec.pendingDeferred, 1) + go func() { + ctx := graphql.WithFreshResponseContext(dg.Context) + dg.FieldSet.Dispatch(ctx) + ds := graphql.DeferredResult{ + Path: dg.Path, + Label: dg.Label, + Result: dg.FieldSet, + Errors: graphql.GetErrors(ctx), + } + // null fields should bubble up + if dg.FieldSet.Invalids > 0 { + ds.Result = graphql.Null + } + ec.deferredResults <- ds + }() +} + +func (ec *executionContext) introspectSchema() (*introspection.Schema, error) { + if ec.DisableIntrospection { + return nil, errors.New("introspection disabled") + } + return introspection.WrapSchema(ec.Schema()), nil +} + +func (ec *executionContext) introspectType(name string) (*introspection.Type, error) { + if ec.DisableIntrospection { + return nil, errors.New("introspection disabled") + } + return introspection.WrapTypeFromDef(ec.Schema(), ec.Schema().Types[name]), nil +} + +var sources = []*ast.Source{ + {Name: "../schema.graphqls", Input: `extend schema + @link( + url: "https://specs.apollo.dev/federation/v2.5" + import: ["@key"] + ) + +directive @openfed__entityCache( + maxAge: Int! + includeHeaders: Boolean = false + partialCacheLoad: Boolean = false + shadowMode: Boolean = false +) on OBJECT + +type Item @key(fields: "id") @openfed__entityCache(maxAge: 300) { + id: ID! + available: Boolean! + count: Int! +} +`, BuiltIn: false}, + {Name: "../../federation/directives.graphql", Input: ` + directive @authenticated on FIELD_DEFINITION | OBJECT | INTERFACE | SCALAR | ENUM + directive @composeDirective(name: String!) repeatable on SCHEMA + directive @extends on OBJECT | INTERFACE + directive @external on OBJECT | FIELD_DEFINITION + directive @key(fields: FieldSet!, resolvable: Boolean = true) repeatable on OBJECT | INTERFACE + directive @inaccessible on + | ARGUMENT_DEFINITION + | ENUM + | ENUM_VALUE + | FIELD_DEFINITION + | INPUT_FIELD_DEFINITION + | INPUT_OBJECT + | INTERFACE + | OBJECT + | SCALAR + | UNION + directive @interfaceObject on OBJECT + directive @link(import: [String!], url: String!) repeatable on SCHEMA + directive @override(from: String!, label: String) on FIELD_DEFINITION + directive @policy(policies: [[federation__Policy!]!]!) on + | FIELD_DEFINITION + | OBJECT + | INTERFACE + | SCALAR + | ENUM + directive @provides(fields: FieldSet!) on FIELD_DEFINITION + directive @requires(fields: FieldSet!) on FIELD_DEFINITION + directive @requiresScopes(scopes: [[federation__Scope!]!]!) on + | FIELD_DEFINITION + | OBJECT + | INTERFACE + | SCALAR + | ENUM + directive @shareable repeatable on FIELD_DEFINITION | OBJECT + directive @tag(name: String!) repeatable on + | ARGUMENT_DEFINITION + | ENUM + | ENUM_VALUE + | FIELD_DEFINITION + | INPUT_FIELD_DEFINITION + | INPUT_OBJECT + | INTERFACE + | OBJECT + | SCALAR + | UNION + scalar _Any + scalar FieldSet + scalar federation__Policy + scalar federation__Scope +`, BuiltIn: true}, + {Name: "../../federation/entity.graphql", Input: ` +# a union of all types that use the @key directive +union _Entity = Item + +# fake type to build resolver interfaces for users to implement +type Entity { + findItemByID(id: ID!,): Item! +} + +type _Service { + sdl: String +} + +extend type Query { + _entities(representations: [_Any!]!): [_Entity]! + _service: _Service! +} +`, BuiltIn: true}, +} +var parsedSchema = gqlparser.MustLoadSchema(sources...) + +// endregion ************************** generated!.gotpl ************************** + +// region ***************************** args.gotpl ***************************** + +func (ec *executionContext) field_Entity_findItemByID_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Entity_findItemByID_argsID(ctx, rawArgs) + if err != nil { + return nil, err + } + args["id"] = arg0 + return args, nil +} +func (ec *executionContext) field_Entity_findItemByID_argsID( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["id"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + if tmp, ok := rawArgs["id"]; ok { + return ec.unmarshalNID2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Query___type_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Query___type_argsName(ctx, rawArgs) + if err != nil { + return nil, err + } + args["name"] = arg0 + return args, nil +} +func (ec *executionContext) field_Query___type_argsName( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["name"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("name")) + if tmp, ok := rawArgs["name"]; ok { + return ec.unmarshalNString2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Query__entities_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Query__entities_argsRepresentations(ctx, rawArgs) + if err != nil { + return nil, err + } + args["representations"] = arg0 + return args, nil +} +func (ec *executionContext) field_Query__entities_argsRepresentations( + ctx context.Context, + rawArgs map[string]any, +) ([]map[string]any, error) { + if _, ok := rawArgs["representations"]; !ok { + var zeroVal []map[string]any + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("representations")) + if tmp, ok := rawArgs["representations"]; ok { + return ec.unmarshalN_Any2ᚕmapᚄ(ctx, tmp) + } + + var zeroVal []map[string]any + return zeroVal, nil +} + +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 := ec.field___Directive_args_argsIncludeDeprecated(ctx, rawArgs) + if err != nil { + return nil, err + } + args["includeDeprecated"] = arg0 + return args, nil +} +func (ec *executionContext) field___Directive_args_argsIncludeDeprecated( + ctx context.Context, + rawArgs map[string]any, +) (*bool, error) { + if _, ok := rawArgs["includeDeprecated"]; !ok { + var zeroVal *bool + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("includeDeprecated")) + if tmp, ok := rawArgs["includeDeprecated"]; ok { + return ec.unmarshalOBoolean2ᚖbool(ctx, tmp) + } + + var zeroVal *bool + return zeroVal, nil +} + +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 := ec.field___Field_args_argsIncludeDeprecated(ctx, rawArgs) + if err != nil { + return nil, err + } + args["includeDeprecated"] = arg0 + return args, nil +} +func (ec *executionContext) field___Field_args_argsIncludeDeprecated( + ctx context.Context, + rawArgs map[string]any, +) (*bool, error) { + if _, ok := rawArgs["includeDeprecated"]; !ok { + var zeroVal *bool + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("includeDeprecated")) + if tmp, ok := rawArgs["includeDeprecated"]; ok { + return ec.unmarshalOBoolean2ᚖbool(ctx, tmp) + } + + var zeroVal *bool + return zeroVal, nil +} + +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 := ec.field___Type_enumValues_argsIncludeDeprecated(ctx, rawArgs) + if err != nil { + return nil, err + } + args["includeDeprecated"] = arg0 + return args, nil +} +func (ec *executionContext) field___Type_enumValues_argsIncludeDeprecated( + ctx context.Context, + rawArgs map[string]any, +) (bool, error) { + if _, ok := rawArgs["includeDeprecated"]; !ok { + var zeroVal bool + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("includeDeprecated")) + if tmp, ok := rawArgs["includeDeprecated"]; ok { + return ec.unmarshalOBoolean2bool(ctx, tmp) + } + + var zeroVal bool + return zeroVal, nil +} + +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 := ec.field___Type_fields_argsIncludeDeprecated(ctx, rawArgs) + if err != nil { + return nil, err + } + args["includeDeprecated"] = arg0 + return args, nil +} +func (ec *executionContext) field___Type_fields_argsIncludeDeprecated( + ctx context.Context, + rawArgs map[string]any, +) (bool, error) { + if _, ok := rawArgs["includeDeprecated"]; !ok { + var zeroVal bool + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("includeDeprecated")) + if tmp, ok := rawArgs["includeDeprecated"]; ok { + return ec.unmarshalOBoolean2bool(ctx, tmp) + } + + var zeroVal bool + return zeroVal, nil +} + +// endregion ***************************** args.gotpl ***************************** + +// region ************************** directives.gotpl ************************** + +// endregion ************************** directives.gotpl ************************** + +// region **************************** field.gotpl ***************************** + +func (ec *executionContext) _Entity_findItemByID(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Entity_findItemByID(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Entity().FindItemByID(rctx, fc.Args["id"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*model.Item) + fc.Result = res + return ec.marshalNItem2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋinventoryᚋsubgraphᚋmodelᚐItem(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Entity_findItemByID(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Entity", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Item_id(ctx, field) + case "available": + return ec.fieldContext_Item_available(ctx, field) + case "count": + return ec.fieldContext_Item_count(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Item", field.Name) + }, + } + 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_Entity_findItemByID_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Item_id(ctx context.Context, field graphql.CollectedField, obj *model.Item) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Item_id(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Item_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Item", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Item_available(ctx context.Context, field graphql.CollectedField, obj *model.Item) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Item_available(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Available, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Item_available(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Item", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Item_count(ctx context.Context, field graphql.CollectedField, obj *model.Item) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Item_count(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Count, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Item_count(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Item", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Query__entities(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query__entities(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.__resolve_entities(ctx, fc.Args["representations"].([]map[string]any)), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]fedruntime.Entity) + fc.Result = res + return ec.marshalN_Entity2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐEntity(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query__entities(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type _Entity does not have child fields") + }, + } + 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__entities_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query__service(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query__service(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.__resolve__service(ctx) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(fedruntime.Service) + fc.Result = res + return ec.marshalN_Service2githubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐService(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query__service(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "sdl": + return ec.fieldContext__Service_sdl(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type _Service", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Query___type(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query___type(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.introspectType(fc.Args["name"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query___type(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + 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___type_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query___schema(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query___schema(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.introspectSchema() + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Schema) + fc.Result = res + return ec.marshalO__Schema2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐSchema(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query___schema(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "description": + return ec.fieldContext___Schema_description(ctx, field) + case "types": + return ec.fieldContext___Schema_types(ctx, field) + case "queryType": + return ec.fieldContext___Schema_queryType(ctx, field) + case "mutationType": + return ec.fieldContext___Schema_mutationType(ctx, field) + case "subscriptionType": + return ec.fieldContext___Schema_subscriptionType(ctx, field) + case "directives": + return ec.fieldContext___Schema_directives(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Schema", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) __Service_sdl(ctx context.Context, field graphql.CollectedField, obj *fedruntime.Service) (ret graphql.Marshaler) { + fc, err := ec.fieldContext__Service_sdl(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.SDL, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalOString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext__Service_sdl(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "_Service", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Directive_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Directive_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Directive_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Directive_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_isRepeatable(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Directive_isRepeatable(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsRepeatable, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Directive_isRepeatable(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_locations(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Directive_locations(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Locations, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]string) + fc.Result = res + return ec.marshalN__DirectiveLocation2ᚕstringᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Directive_locations(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type __DirectiveLocation does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_args(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Directive_args(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Args, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]introspection.InputValue) + fc.Result = res + return ec.marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Directive_args(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___InputValue_name(ctx, field) + case "description": + return ec.fieldContext___InputValue_description(ctx, field) + case "type": + return ec.fieldContext___InputValue_type(ctx, field) + case "defaultValue": + return ec.fieldContext___InputValue_defaultValue(ctx, field) + case "isDeprecated": + return ec.fieldContext___InputValue_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___InputValue_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __InputValue", field.Name) + }, + } + 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___Directive_args_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) ___EnumValue_name(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___EnumValue_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___EnumValue_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__EnumValue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___EnumValue_description(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___EnumValue_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___EnumValue_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__EnumValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___EnumValue_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___EnumValue_isDeprecated(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsDeprecated(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___EnumValue_isDeprecated(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__EnumValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___EnumValue_deprecationReason(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___EnumValue_deprecationReason(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.DeprecationReason(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___EnumValue_deprecationReason(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__EnumValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_args(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_args(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Args, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]introspection.InputValue) + fc.Result = res + return ec.marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_args(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___InputValue_name(ctx, field) + case "description": + return ec.fieldContext___InputValue_description(ctx, field) + case "type": + return ec.fieldContext___InputValue_type(ctx, field) + case "defaultValue": + return ec.fieldContext___InputValue_defaultValue(ctx, field) + case "isDeprecated": + return ec.fieldContext___InputValue_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___InputValue_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __InputValue", field.Name) + }, + } + 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___Field_args_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) ___Field_type(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_type(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Type, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_type(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_isDeprecated(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsDeprecated(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_isDeprecated(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_deprecationReason(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_deprecationReason(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.DeprecationReason(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_deprecationReason(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_name(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_description(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_type(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_type(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Type, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_type(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_defaultValue(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_defaultValue(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.DefaultValue, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_defaultValue(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_isDeprecated(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsDeprecated(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_isDeprecated(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_deprecationReason(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_deprecationReason(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.DeprecationReason(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_deprecationReason(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_types(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_types(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Types(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]introspection.Type) + fc.Result = res + return ec.marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_types(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_queryType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_queryType(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.QueryType(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_queryType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_mutationType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_mutationType(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.MutationType(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_mutationType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_subscriptionType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_subscriptionType(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.SubscriptionType(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_subscriptionType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_directives(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_directives(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Directives(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]introspection.Directive) + fc.Result = res + return ec.marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirectiveᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_directives(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___Directive_name(ctx, field) + case "description": + return ec.fieldContext___Directive_description(ctx, field) + case "isRepeatable": + return ec.fieldContext___Directive_isRepeatable(ctx, field) + case "locations": + return ec.fieldContext___Directive_locations(ctx, field) + case "args": + return ec.fieldContext___Directive_args(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Directive", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_kind(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_kind(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Kind(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalN__TypeKind2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_kind(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type __TypeKind does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_specifiedByURL(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_specifiedByURL(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.SpecifiedByURL(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_specifiedByURL(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_fields(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_fields(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Fields(fc.Args["includeDeprecated"].(bool)), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.Field) + fc.Result = res + return ec.marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐFieldᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_fields(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___Field_name(ctx, field) + case "description": + return ec.fieldContext___Field_description(ctx, field) + case "args": + return ec.fieldContext___Field_args(ctx, field) + case "type": + return ec.fieldContext___Field_type(ctx, field) + case "isDeprecated": + return ec.fieldContext___Field_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___Field_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Field", field.Name) + }, + } + 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_fields_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) ___Type_interfaces(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_interfaces(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Interfaces(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_interfaces(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_possibleTypes(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_possibleTypes(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.PossibleTypes(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_possibleTypes(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_enumValues(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_enumValues(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.EnumValues(fc.Args["includeDeprecated"].(bool)), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.EnumValue) + fc.Result = res + return ec.marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValueᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_enumValues(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___EnumValue_name(ctx, field) + case "description": + return ec.fieldContext___EnumValue_description(ctx, field) + case "isDeprecated": + return ec.fieldContext___EnumValue_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___EnumValue_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __EnumValue", field.Name) + }, + } + 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_enumValues_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) ___Type_inputFields(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_inputFields(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.InputFields(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.InputValue) + fc.Result = res + return ec.marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_inputFields(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___InputValue_name(ctx, field) + case "description": + return ec.fieldContext___InputValue_description(ctx, field) + case "type": + return ec.fieldContext___InputValue_type(ctx, field) + case "defaultValue": + return ec.fieldContext___InputValue_defaultValue(ctx, field) + case "isDeprecated": + return ec.fieldContext___InputValue_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___InputValue_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __InputValue", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_ofType(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_ofType(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.OfType(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_ofType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_isOneOf(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_isOneOf(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsOneOf(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalOBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_isOneOf(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +// endregion **************************** field.gotpl ***************************** + +// region **************************** input.gotpl ***************************** + +// endregion **************************** input.gotpl ***************************** + +// region ************************** interface.gotpl *************************** + +func (ec *executionContext) __Entity(ctx context.Context, sel ast.SelectionSet, obj fedruntime.Entity) graphql.Marshaler { + switch obj := (obj).(type) { + case nil: + return graphql.Null + case model.Item: + return ec._Item(ctx, sel, &obj) + case *model.Item: + if obj == nil { + return graphql.Null + } + return ec._Item(ctx, sel, obj) + default: + panic(fmt.Errorf("unexpected type %T", obj)) + } +} + +// endregion ************************** interface.gotpl *************************** + +// region **************************** object.gotpl **************************** + +var entityImplementors = []string{"Entity"} + +func (ec *executionContext) _Entity(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, entityImplementors) + ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ + Object: "Entity", + }) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ + Object: field.Name, + Field: field, + }) + + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Entity") + case "findItemByID": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Entity_findItemByID(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var itemImplementors = []string{"Item", "_Entity"} + +func (ec *executionContext) _Item(ctx context.Context, sel ast.SelectionSet, obj *model.Item) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, itemImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Item") + case "id": + out.Values[i] = ec._Item_id(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "available": + out.Values[i] = ec._Item_available(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "count": + out.Values[i] = ec._Item_count(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 + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var queryImplementors = []string{"Query"} + +func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, queryImplementors) + ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ + Object: "Query", + }) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ + Object: field.Name, + Field: field, + }) + + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Query") + case "_entities": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query__entities(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "_service": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query__service(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "__type": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Query___type(ctx, field) + }) + case "__schema": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Query___schema(ctx, field) + }) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var _ServiceImplementors = []string{"_Service"} + +func (ec *executionContext) __Service(ctx context.Context, sel ast.SelectionSet, obj *fedruntime.Service) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, _ServiceImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("_Service") + case "sdl": + out.Values[i] = ec.__Service_sdl(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __DirectiveImplementors = []string{"__Directive"} + +func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionSet, obj *introspection.Directive) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __DirectiveImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__Directive") + case "name": + out.Values[i] = ec.___Directive_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "description": + out.Values[i] = ec.___Directive_description(ctx, field, obj) + case "isRepeatable": + out.Values[i] = ec.___Directive_isRepeatable(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "locations": + out.Values[i] = ec.___Directive_locations(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "args": + out.Values[i] = ec.___Directive_args(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 + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __EnumValueImplementors = []string{"__EnumValue"} + +func (ec *executionContext) ___EnumValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.EnumValue) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __EnumValueImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__EnumValue") + case "name": + out.Values[i] = ec.___EnumValue_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "description": + out.Values[i] = ec.___EnumValue_description(ctx, field, obj) + case "isDeprecated": + out.Values[i] = ec.___EnumValue_isDeprecated(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "deprecationReason": + out.Values[i] = ec.___EnumValue_deprecationReason(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __FieldImplementors = []string{"__Field"} + +func (ec *executionContext) ___Field(ctx context.Context, sel ast.SelectionSet, obj *introspection.Field) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __FieldImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__Field") + case "name": + out.Values[i] = ec.___Field_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "description": + out.Values[i] = ec.___Field_description(ctx, field, obj) + case "args": + out.Values[i] = ec.___Field_args(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "type": + out.Values[i] = ec.___Field_type(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "isDeprecated": + out.Values[i] = ec.___Field_isDeprecated(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "deprecationReason": + out.Values[i] = ec.___Field_deprecationReason(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __InputValueImplementors = []string{"__InputValue"} + +func (ec *executionContext) ___InputValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.InputValue) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __InputValueImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__InputValue") + case "name": + out.Values[i] = ec.___InputValue_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "description": + out.Values[i] = ec.___InputValue_description(ctx, field, obj) + case "type": + out.Values[i] = ec.___InputValue_type(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "defaultValue": + out.Values[i] = ec.___InputValue_defaultValue(ctx, field, obj) + case "isDeprecated": + out.Values[i] = ec.___InputValue_isDeprecated(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "deprecationReason": + out.Values[i] = ec.___InputValue_deprecationReason(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __SchemaImplementors = []string{"__Schema"} + +func (ec *executionContext) ___Schema(ctx context.Context, sel ast.SelectionSet, obj *introspection.Schema) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __SchemaImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__Schema") + case "description": + out.Values[i] = ec.___Schema_description(ctx, field, obj) + case "types": + out.Values[i] = ec.___Schema_types(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "queryType": + out.Values[i] = ec.___Schema_queryType(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "mutationType": + out.Values[i] = ec.___Schema_mutationType(ctx, field, obj) + case "subscriptionType": + out.Values[i] = ec.___Schema_subscriptionType(ctx, field, obj) + case "directives": + out.Values[i] = ec.___Schema_directives(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 + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __TypeImplementors = []string{"__Type"} + +func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, obj *introspection.Type) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __TypeImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__Type") + case "kind": + out.Values[i] = ec.___Type_kind(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "name": + out.Values[i] = ec.___Type_name(ctx, field, obj) + case "description": + out.Values[i] = ec.___Type_description(ctx, field, obj) + case "specifiedByURL": + out.Values[i] = ec.___Type_specifiedByURL(ctx, field, obj) + case "fields": + out.Values[i] = ec.___Type_fields(ctx, field, obj) + case "interfaces": + out.Values[i] = ec.___Type_interfaces(ctx, field, obj) + case "possibleTypes": + out.Values[i] = ec.___Type_possibleTypes(ctx, field, obj) + case "enumValues": + out.Values[i] = ec.___Type_enumValues(ctx, field, obj) + case "inputFields": + out.Values[i] = ec.___Type_inputFields(ctx, field, obj) + case "ofType": + out.Values[i] = ec.___Type_ofType(ctx, field, obj) + case "isOneOf": + out.Values[i] = ec.___Type_isOneOf(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +// endregion **************************** object.gotpl **************************** + +// region ***************************** type.gotpl ***************************** + +func (ec *executionContext) unmarshalNBoolean2bool(ctx context.Context, v any) (bool, error) { + res, err := graphql.UnmarshalBoolean(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNBoolean2bool(ctx context.Context, sel ast.SelectionSet, v bool) graphql.Marshaler { + _ = sel + res := graphql.MarshalBoolean(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNFieldSet2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNFieldSet2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNID2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalID(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNID2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalID(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNInt2int(ctx context.Context, v any) (int, error) { + res, err := graphql.UnmarshalInt(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNInt2int(ctx context.Context, sel ast.SelectionSet, v int) graphql.Marshaler { + _ = sel + res := graphql.MarshalInt(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) marshalNItem2githubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋinventoryᚋsubgraphᚋmodelᚐItem(ctx context.Context, sel ast.SelectionSet, v model.Item) graphql.Marshaler { + return ec._Item(ctx, sel, &v) +} + +func (ec *executionContext) marshalNItem2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋinventoryᚋsubgraphᚋmodelᚐItem(ctx context.Context, sel ast.SelectionSet, v *model.Item) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._Item(ctx, sel, v) +} + +func (ec *executionContext) unmarshalNString2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNString2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalN_Any2map(ctx context.Context, v any) (map[string]any, error) { + res, err := graphql.UnmarshalMap(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalN_Any2map(ctx context.Context, sel ast.SelectionSet, v map[string]any) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + _ = sel + res := graphql.MarshalMap(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalN_Any2ᚕmapᚄ(ctx context.Context, v any) ([]map[string]any, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([]map[string]any, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalN_Any2map(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalN_Any2ᚕmapᚄ(ctx context.Context, sel ast.SelectionSet, v []map[string]any) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalN_Any2map(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalN_Entity2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐEntity(ctx context.Context, sel ast.SelectionSet, v []fedruntime.Entity) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalO_Entity2githubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐEntity(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + return ret +} + +func (ec *executionContext) marshalN_Service2githubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐService(ctx context.Context, sel ast.SelectionSet, v fedruntime.Service) graphql.Marshaler { + return ec.__Service(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__Directive2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirective(ctx context.Context, sel ast.SelectionSet, v introspection.Directive) graphql.Marshaler { + return ec.___Directive(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirectiveᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.Directive) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__Directive2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirective(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalN__DirectiveLocation2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalN__DirectiveLocation2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalN__DirectiveLocation2ᚕstringᚄ(ctx context.Context, v any) ([]string, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalN__DirectiveLocation2string(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalN__DirectiveLocation2ᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v []string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__DirectiveLocation2string(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalN__EnumValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValue(ctx context.Context, sel ast.SelectionSet, v introspection.EnumValue) graphql.Marshaler { + return ec.___EnumValue(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__Field2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐField(ctx context.Context, sel ast.SelectionSet, v introspection.Field) graphql.Marshaler { + return ec.___Field(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__InputValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValue(ctx context.Context, sel ast.SelectionSet, v introspection.InputValue) graphql.Marshaler { + return ec.___InputValue(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.InputValue) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__InputValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValue(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +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) +} + +func (ec *executionContext) marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.Type) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__Type2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx context.Context, sel ast.SelectionSet, v *introspection.Type) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec.___Type(ctx, sel, v) +} + +func (ec *executionContext) unmarshalN__TypeKind2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalN__TypeKind2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNfederation__Policy2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNfederation__Policy2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNfederation__Policy2ᚕstringᚄ(ctx context.Context, v any) ([]string, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNfederation__Policy2string(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalNfederation__Policy2ᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v []string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNfederation__Policy2string(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalNfederation__Policy2ᚕᚕstringᚄ(ctx context.Context, v any) ([][]string, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([][]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNfederation__Policy2ᚕstringᚄ(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalNfederation__Policy2ᚕᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v [][]string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNfederation__Policy2ᚕstringᚄ(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalNfederation__Scope2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNfederation__Scope2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNfederation__Scope2ᚕstringᚄ(ctx context.Context, v any) ([]string, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNfederation__Scope2string(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalNfederation__Scope2ᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v []string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNfederation__Scope2string(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalNfederation__Scope2ᚕᚕstringᚄ(ctx context.Context, v any) ([][]string, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([][]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNfederation__Scope2ᚕstringᚄ(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalNfederation__Scope2ᚕᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v [][]string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNfederation__Scope2ᚕstringᚄ(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalOBoolean2bool(ctx context.Context, v any) (bool, error) { + res, err := graphql.UnmarshalBoolean(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOBoolean2bool(ctx context.Context, sel ast.SelectionSet, v bool) graphql.Marshaler { + _ = sel + _ = ctx + res := graphql.MarshalBoolean(v) + return res +} + +func (ec *executionContext) unmarshalOBoolean2ᚖbool(ctx context.Context, v any) (*bool, error) { + if v == nil { + return nil, nil + } + res, err := graphql.UnmarshalBoolean(v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOBoolean2ᚖbool(ctx context.Context, sel ast.SelectionSet, v *bool) graphql.Marshaler { + if v == nil { + return graphql.Null + } + _ = sel + _ = ctx + res := graphql.MarshalBoolean(*v) + return res +} + +func (ec *executionContext) unmarshalOString2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOString2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + _ = ctx + res := graphql.MarshalString(v) + return res +} + +func (ec *executionContext) unmarshalOString2ᚕstringᚄ(ctx context.Context, v any) ([]string, error) { + if v == nil { + return nil, nil + } + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNString2string(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalOString2ᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v []string) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNString2string(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalOString2ᚖstring(ctx context.Context, v any) (*string, error) { + if v == nil { + return nil, nil + } + res, err := graphql.UnmarshalString(v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOString2ᚖstring(ctx context.Context, sel ast.SelectionSet, v *string) graphql.Marshaler { + if v == nil { + return graphql.Null + } + _ = sel + _ = ctx + res := graphql.MarshalString(*v) + return res +} + +func (ec *executionContext) marshalO_Entity2githubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐEntity(ctx context.Context, sel ast.SelectionSet, v fedruntime.Entity) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec.__Entity(ctx, sel, v) +} + +func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.EnumValue) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__EnumValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValue(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐFieldᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.Field) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__Field2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐField(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.InputValue) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__InputValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValue(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + 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 + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__Type2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +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 + } + return ec.___Type(ctx, sel, v) +} + +// endregion ***************************** type.gotpl ***************************** diff --git a/demo/pkg/subgraphs/cachetest/inventory/subgraph/model/models_gen.go b/demo/pkg/subgraphs/cachetest/inventory/subgraph/model/models_gen.go new file mode 100644 index 0000000000..1d6357e34c --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/inventory/subgraph/model/models_gen.go @@ -0,0 +1,14 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package model + +type Item struct { + ID string `json:"id"` + Available bool `json:"available"` + Count int `json:"count"` +} + +func (Item) IsEntity() {} + +type Query struct { +} diff --git a/demo/pkg/subgraphs/cachetest/inventory/subgraph/resolver.go b/demo/pkg/subgraphs/cachetest/inventory/subgraph/resolver.go new file mode 100644 index 0000000000..c1da1a4335 --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/inventory/subgraph/resolver.go @@ -0,0 +1,7 @@ +package subgraph + +// This file will not be regenerated automatically. +// +// It serves as dependency injection for your app, add any dependencies you require here. + +type Resolver struct{} diff --git a/demo/pkg/subgraphs/cachetest/inventory/subgraph/schema.graphqls b/demo/pkg/subgraphs/cachetest/inventory/subgraph/schema.graphqls new file mode 100644 index 0000000000..23b424d859 --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/inventory/subgraph/schema.graphqls @@ -0,0 +1,18 @@ +extend schema + @link( + url: "https://specs.apollo.dev/federation/v2.5" + import: ["@key"] + ) + +directive @openfed__entityCache( + maxAge: Int! + includeHeaders: Boolean = false + partialCacheLoad: Boolean = false + shadowMode: Boolean = false +) on OBJECT + +type Item @key(fields: "id") @openfed__entityCache(maxAge: 300) { + id: ID! + available: Boolean! + count: Int! +} diff --git a/demo/pkg/subgraphs/cachetest/items/generate.go b/demo/pkg/subgraphs/cachetest/items/generate.go new file mode 100644 index 0000000000..89d17e5530 --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/items/generate.go @@ -0,0 +1,3 @@ +//go:generate go run github.com/99designs/gqlgen generate + +package items diff --git a/demo/pkg/subgraphs/cachetest/items/gqlgen.yml b/demo/pkg/subgraphs/cachetest/items/gqlgen.yml new file mode 100644 index 0000000000..b2d7bf59ba --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/items/gqlgen.yml @@ -0,0 +1,47 @@ +schema: + - subgraph/*.graphqls + +exec: + filename: subgraph/generated/generated.go + package: generated + +federation: + filename: subgraph/generated/federation.go + package: generated + version: 2 + options: + explicit_requires: true + +model: + filename: subgraph/model/models_gen.go + package: model + +resolver: + layout: follow-schema + dir: subgraph + package: subgraph + +directives: + openfed__entityCache: + skip_runtime: true + openfed__queryCache: + skip_runtime: true + openfed__cacheInvalidate: + skip_runtime: true + openfed__cachePopulate: + skip_runtime: true + openfed__is: + skip_runtime: true + +models: + ID: + model: + - github.com/99designs/gqlgen/graphql.ID + - github.com/99designs/gqlgen/graphql.Int + - github.com/99designs/gqlgen/graphql.Int64 + - github.com/99designs/gqlgen/graphql.Int32 + Int: + model: + - github.com/99designs/gqlgen/graphql.Int + - github.com/99designs/gqlgen/graphql.Int64 + - github.com/99designs/gqlgen/graphql.Int32 diff --git a/demo/pkg/subgraphs/cachetest/items/items.go b/demo/pkg/subgraphs/cachetest/items/items.go new file mode 100644 index 0000000000..03dba7b634 --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/items/items.go @@ -0,0 +1,15 @@ +package items + +import ( + "github.com/99designs/gqlgen/graphql" + + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachetest/items/subgraph" + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachetest/items/subgraph/generated" + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachetest/items/subgraph/model" +) + +func NewSchema(itemUpdatedCh chan *model.Item, itemCreatedCh chan *model.Item) graphql.ExecutableSchema { + return generated.NewExecutableSchema(generated.Config{ + Resolvers: subgraph.NewResolver(itemUpdatedCh, itemCreatedCh), + }) +} diff --git a/demo/pkg/subgraphs/cachetest/items/subgraph/data.go b/demo/pkg/subgraphs/cachetest/items/subgraph/data.go new file mode 100644 index 0000000000..5a5c463bb1 --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/items/subgraph/data.go @@ -0,0 +1,135 @@ +package subgraph + +import ( + "fmt" + "sync" + "sync/atomic" + + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachetest/items/subgraph/model" +) + +var nextID atomic.Int64 + +func init() { + nextID.Store(5) +} + +// defaultItems is the seed data for a fresh item store. Each Resolver clones +// this into its own store so mutations are isolated between parallel tests. +var defaultItems = []*model.Item{ + {ID: "1", Name: "Widget", Category: "tools"}, + {ID: "2", Name: "Gadget", Category: "electronics"}, + {ID: "3", Name: "Gizmo", Category: "electronics"}, + {ID: "4", Name: "Doohickey", Category: "misc"}, + {ID: "5", Name: "Thingamajig", Category: "misc"}, +} + +var Products = []*model.Product{ + {ID: "p1", Region: "US", Sku: "SKU-001", Name: "Alpha"}, + {ID: "p2", Region: "US", Sku: "SKU-002", Name: "Beta"}, + {ID: "p3", Region: "EU", Sku: "SKU-003", Name: "Gamma"}, + {ID: "p4", Region: "EU", Sku: "SKU-004", Name: "Delta"}, +} + +var Warehouses = []*model.Warehouse{ + {Location: &model.Location{ID: "w1"}, Name: "Main Depot"}, + {Location: &model.Location{ID: "w2"}, Name: "East Hub"}, + {Location: &model.Location{ID: "w3"}, Name: "West Hub"}, +} + +// itemStore is a per-resolver mutable Item store. Tests create one per +// subgraph server so mutations in one test don't affect parallel tests. +type itemStore struct { + mu sync.RWMutex + items []*model.Item +} + +func newItemStore() *itemStore { + return &itemStore{items: cloneItems(defaultItems)} +} + +func (s *itemStore) all() []*model.Item { + s.mu.RLock() + defer s.mu.RUnlock() + return cloneItems(s.items) +} + +func (s *itemStore) find(id string) *model.Item { + s.mu.RLock() + defer s.mu.RUnlock() + for _, it := range s.items { + if it.ID == id { + return cloneItem(it) + } + } + return nil +} + +func (s *itemStore) byIDs(ids []string) []*model.Item { + s.mu.RLock() + defer s.mu.RUnlock() + var out []*model.Item + for _, id := range ids { + for _, it := range s.items { + if it.ID == id { + out = append(out, cloneItem(it)) + break + } + } + } + return out +} + +func (s *itemStore) update(id, name string) (*model.Item, bool) { + s.mu.Lock() + defer s.mu.Unlock() + for _, it := range s.items { + if it.ID == id { + it.Name = name + return cloneItem(it), true + } + } + return nil, false +} + +func (s *itemStore) delete(id string) (*model.Item, bool) { + s.mu.Lock() + defer s.mu.Unlock() + for i, it := range s.items { + if it.ID == id { + removed := cloneItem(it) + s.items = append(s.items[:i], s.items[i+1:]...) + return removed, true + } + } + return nil, false +} + +func (s *itemStore) create(name, category string) *model.Item { + id := atomicNextID() + s.mu.Lock() + defer s.mu.Unlock() + it := &model.Item{ID: id, Name: name, Category: category} + s.items = append(s.items, it) + return cloneItem(it) +} + +func atomicNextID() string { + return fmt.Sprintf("%d", nextID.Add(1)) +} + +func cloneItem(it *model.Item) *model.Item { + if it == nil { + return nil + } + c := *it + return &c +} + +func cloneItems(in []*model.Item) []*model.Item { + out := make([]*model.Item, len(in)) + for i, it := range in { + out[i] = cloneItem(it) + } + return out +} diff --git a/demo/pkg/subgraphs/cachetest/items/subgraph/entity.resolvers.go b/demo/pkg/subgraphs/cachetest/items/subgraph/entity.resolvers.go new file mode 100644 index 0000000000..a88ffa1fb5 --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/items/subgraph/entity.resolvers.go @@ -0,0 +1,52 @@ +package subgraph + +// 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.76 + +import ( + "context" + + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachetest/items/subgraph/generated" + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachetest/items/subgraph/model" +) + +// FindItemByID is the resolver for the findItemByID field. +func (r *entityResolver) FindItemByID(ctx context.Context, id string) (*model.Item, error) { + return r.Store.find(id), nil +} + +// FindProductByIDAndRegion is the resolver for the findProductByIDAndRegion field. +func (r *entityResolver) FindProductByIDAndRegion(ctx context.Context, id string, region string) (*model.Product, error) { + for _, p := range Products { + if p.ID == id && p.Region == region { + return p, nil + } + } + return nil, nil +} + +// FindProductBySku is the resolver for the findProductBySku field. +func (r *entityResolver) FindProductBySku(ctx context.Context, sku string) (*model.Product, error) { + for _, p := range Products { + if p.Sku == sku { + return p, nil + } + } + return nil, nil +} + +// FindWarehouseByLocationID is the resolver for the findWarehouseByLocationID field. +func (r *entityResolver) FindWarehouseByLocationID(ctx context.Context, locationID string) (*model.Warehouse, error) { + for _, w := range Warehouses { + if w.Location.ID == locationID { + return w, nil + } + } + return nil, nil +} + +// Entity returns generated.EntityResolver implementation. +func (r *Resolver) Entity() generated.EntityResolver { return &entityResolver{r} } + +type entityResolver struct{ *Resolver } diff --git a/demo/pkg/subgraphs/cachetest/items/subgraph/generated/federation.go b/demo/pkg/subgraphs/cachetest/items/subgraph/generated/federation.go new file mode 100644 index 0000000000..036c32b5dd --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/items/subgraph/generated/federation.go @@ -0,0 +1,406 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package generated + +import ( + "context" + "errors" + "fmt" + "strings" + "sync" + + "github.com/99designs/gqlgen/plugin/federation/fedruntime" +) + +var ( + ErrUnknownType = errors.New("unknown type") + ErrTypeNotFound = errors.New("type not found") +) + +func (ec *executionContext) __resolve__service(ctx context.Context) (fedruntime.Service, error) { + if ec.DisableIntrospection { + return fedruntime.Service{}, errors.New("federated introspection disabled") + } + + var sdl []string + + for _, src := range sources { + if src.BuiltIn { + continue + } + sdl = append(sdl, src.Input) + } + + return fedruntime.Service{ + SDL: strings.Join(sdl, "\n"), + }, nil +} + +func (ec *executionContext) __resolve_entities(ctx context.Context, representations []map[string]any) []fedruntime.Entity { + list := make([]fedruntime.Entity, len(representations)) + + repsMap := ec.buildRepresentationGroups(ctx, representations) + + switch len(repsMap) { + case 0: + return list + case 1: + for typeName, reps := range repsMap { + ec.resolveEntityGroup(ctx, typeName, reps, list) + } + return list + default: + var g sync.WaitGroup + g.Add(len(repsMap)) + for typeName, reps := range repsMap { + go func(typeName string, reps []EntityWithIndex) { + ec.resolveEntityGroup(ctx, typeName, reps, list) + g.Done() + }(typeName, reps) + } + g.Wait() + return list + } +} + +type EntityWithIndex struct { + // The index in the original representation array + index int + entity EntityRepresentation +} + +// EntityRepresentation is the JSON representation of an entity sent by the Router +// used as the inputs for us to resolve. +// +// We make it a map because we know the top level JSON is always an object. +type EntityRepresentation map[string]any + +// We group entities by typename so that we can parallelize their resolution. +// This is particularly helpful when there are entity groups in multi mode. +func (ec *executionContext) buildRepresentationGroups( + ctx context.Context, + representations []map[string]any, +) map[string][]EntityWithIndex { + repsMap := make(map[string][]EntityWithIndex) + for i, rep := range representations { + typeName, ok := rep["__typename"].(string) + if !ok { + // If there is no __typename, we just skip the representation; + // we just won't be resolving these unknown types. + ec.Error(ctx, errors.New("__typename must be an existing string")) + continue + } + + repsMap[typeName] = append(repsMap[typeName], EntityWithIndex{ + index: i, + entity: rep, + }) + } + + return repsMap +} + +func (ec *executionContext) resolveEntityGroup( + ctx context.Context, + typeName string, + reps []EntityWithIndex, + list []fedruntime.Entity, +) { + if isMulti(typeName) { + err := ec.resolveManyEntities(ctx, typeName, reps, list) + if err != nil { + ec.Error(ctx, err) + } + } else { + // if there are multiple entities to resolve, parallelize (similar to + // graphql.FieldSet.Dispatch) + var e sync.WaitGroup + e.Add(len(reps)) + for i, rep := range reps { + i, rep := i, rep + go func(i int, rep EntityWithIndex) { + entity, err := ec.resolveEntity(ctx, typeName, rep.entity) + if err != nil { + ec.Error(ctx, err) + } else { + list[rep.index] = entity + } + e.Done() + }(i, rep) + } + e.Wait() + } +} + +func isMulti(typeName string) bool { + switch typeName { + default: + return false + } +} + +func (ec *executionContext) resolveEntity( + ctx context.Context, + typeName string, + rep EntityRepresentation, +) (e fedruntime.Entity, err error) { + // we need to do our own panic handling, because we may be called in a + // goroutine, where the usual panic handling can't catch us + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + } + }() + + switch typeName { + case "Item": + resolverName, err := entityResolverNameForItem(ctx, rep) + if err != nil { + return nil, fmt.Errorf(`finding resolver for Entity "Item": %w`, err) + } + switch resolverName { + + case "findItemByID": + id0, err := ec.unmarshalNID2string(ctx, rep["id"]) + if err != nil { + return nil, fmt.Errorf(`unmarshalling param 0 for findItemByID(): %w`, err) + } + entity, err := ec.resolvers.Entity().FindItemByID(ctx, id0) + if err != nil { + return nil, fmt.Errorf(`resolving Entity "Item": %w`, err) + } + + return entity, nil + } + case "Product": + resolverName, err := entityResolverNameForProduct(ctx, rep) + if err != nil { + return nil, fmt.Errorf(`finding resolver for Entity "Product": %w`, err) + } + switch resolverName { + + case "findProductByIDAndRegion": + id0, err := ec.unmarshalNID2string(ctx, rep["id"]) + if err != nil { + return nil, fmt.Errorf(`unmarshalling param 0 for findProductByIDAndRegion(): %w`, err) + } + id1, err := ec.unmarshalNString2string(ctx, rep["region"]) + if err != nil { + return nil, fmt.Errorf(`unmarshalling param 1 for findProductByIDAndRegion(): %w`, err) + } + entity, err := ec.resolvers.Entity().FindProductByIDAndRegion(ctx, id0, id1) + if err != nil { + return nil, fmt.Errorf(`resolving Entity "Product": %w`, err) + } + + return entity, nil + case "findProductBySku": + id0, err := ec.unmarshalNString2string(ctx, rep["sku"]) + if err != nil { + return nil, fmt.Errorf(`unmarshalling param 0 for findProductBySku(): %w`, err) + } + entity, err := ec.resolvers.Entity().FindProductBySku(ctx, id0) + if err != nil { + return nil, fmt.Errorf(`resolving Entity "Product": %w`, err) + } + + return entity, nil + } + case "Warehouse": + resolverName, err := entityResolverNameForWarehouse(ctx, rep) + if err != nil { + return nil, fmt.Errorf(`finding resolver for Entity "Warehouse": %w`, err) + } + switch resolverName { + + case "findWarehouseByLocationID": + id0, err := ec.unmarshalNID2string(ctx, rep["location"].(map[string]any)["id"]) + if err != nil { + return nil, fmt.Errorf(`unmarshalling param 0 for findWarehouseByLocationID(): %w`, err) + } + entity, err := ec.resolvers.Entity().FindWarehouseByLocationID(ctx, id0) + if err != nil { + return nil, fmt.Errorf(`resolving Entity "Warehouse": %w`, err) + } + + return entity, nil + } + + } + return nil, fmt.Errorf("%w: %s", ErrUnknownType, typeName) +} + +func (ec *executionContext) resolveManyEntities( + ctx context.Context, + typeName string, + reps []EntityWithIndex, + list []fedruntime.Entity, +) (err error) { + // we need to do our own panic handling, because we may be called in a + // goroutine, where the usual panic handling can't catch us + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + } + }() + + switch typeName { + + default: + return errors.New("unknown type: " + typeName) + } +} + +func entityResolverNameForItem(ctx context.Context, rep EntityRepresentation) (string, error) { + // we collect errors because a later entity resolver may work fine + // when an entity has multiple keys + entityResolverErrs := []error{} + for { + var ( + m EntityRepresentation + val any + ok bool + ) + _ = val + // if all of the KeyFields values for this resolver are null, + // we shouldn't use use it + allNull := true + m = rep + val, ok = m["id"] + if !ok { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to missing Key Field \"id\" for Item", ErrTypeNotFound)) + break + } + if allNull { + allNull = val == nil + } + if allNull { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to all null value KeyFields for Item", ErrTypeNotFound)) + break + } + return "findItemByID", nil + } + return "", fmt.Errorf("%w for Item due to %v", ErrTypeNotFound, + errors.Join(entityResolverErrs...).Error()) +} + +func entityResolverNameForProduct(ctx context.Context, rep EntityRepresentation) (string, error) { + // we collect errors because a later entity resolver may work fine + // when an entity has multiple keys + entityResolverErrs := []error{} + for { + var ( + m EntityRepresentation + val any + ok bool + ) + _ = val + // if all of the KeyFields values for this resolver are null, + // we shouldn't use use it + allNull := true + m = rep + val, ok = m["id"] + if !ok { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to missing Key Field \"id\" for Product", ErrTypeNotFound)) + break + } + if allNull { + allNull = val == nil + } + m = rep + val, ok = m["region"] + if !ok { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to missing Key Field \"region\" for Product", ErrTypeNotFound)) + break + } + if allNull { + allNull = val == nil + } + if allNull { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to all null value KeyFields for Product", ErrTypeNotFound)) + break + } + return "findProductByIDAndRegion", nil + } + for { + var ( + m EntityRepresentation + val any + ok bool + ) + _ = val + // if all of the KeyFields values for this resolver are null, + // we shouldn't use use it + allNull := true + m = rep + val, ok = m["sku"] + if !ok { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to missing Key Field \"sku\" for Product", ErrTypeNotFound)) + break + } + if allNull { + allNull = val == nil + } + if allNull { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to all null value KeyFields for Product", ErrTypeNotFound)) + break + } + return "findProductBySku", nil + } + return "", fmt.Errorf("%w for Product due to %v", ErrTypeNotFound, + errors.Join(entityResolverErrs...).Error()) +} + +func entityResolverNameForWarehouse(ctx context.Context, rep EntityRepresentation) (string, error) { + // we collect errors because a later entity resolver may work fine + // when an entity has multiple keys + entityResolverErrs := []error{} + for { + var ( + m EntityRepresentation + val any + ok bool + ) + _ = val + // if all of the KeyFields values for this resolver are null, + // we shouldn't use use it + allNull := true + m = rep + val, ok = m["location"] + if !ok { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to missing Key Field \"location\" for Warehouse", ErrTypeNotFound)) + break + } + if m, ok = val.(map[string]any); !ok { + // nested field value is not a map[string]interface so don't use it + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to nested Key Field \"location\" value not matching map[string]any for Warehouse", ErrTypeNotFound)) + break + } + val, ok = m["id"] + if !ok { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to missing Key Field \"id\" for Warehouse", ErrTypeNotFound)) + break + } + if allNull { + allNull = val == nil + } + if allNull { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to all null value KeyFields for Warehouse", ErrTypeNotFound)) + break + } + return "findWarehouseByLocationID", nil + } + return "", fmt.Errorf("%w for Warehouse due to %v", ErrTypeNotFound, + errors.Join(entityResolverErrs...).Error()) +} diff --git a/demo/pkg/subgraphs/cachetest/items/subgraph/generated/generated.go b/demo/pkg/subgraphs/cachetest/items/subgraph/generated/generated.go new file mode 100644 index 0000000000..02c0ac6b79 --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/items/subgraph/generated/generated.go @@ -0,0 +1,7692 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package generated + +import ( + "bytes" + "context" + "errors" + "fmt" + "io" + "strconv" + "sync" + "sync/atomic" + + "github.com/99designs/gqlgen/graphql" + "github.com/99designs/gqlgen/graphql/introspection" + "github.com/99designs/gqlgen/plugin/federation/fedruntime" + gqlparser "github.com/vektah/gqlparser/v2" + "github.com/vektah/gqlparser/v2/ast" + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachetest/items/subgraph/model" +) + +// region ************************** generated!.gotpl ************************** + +// NewExecutableSchema creates an ExecutableSchema from the ResolverRoot interface. +func NewExecutableSchema(cfg Config) graphql.ExecutableSchema { + return &executableSchema{ + schema: cfg.Schema, + resolvers: cfg.Resolvers, + directives: cfg.Directives, + complexity: cfg.Complexity, + } +} + +type Config struct { + Schema *ast.Schema + Resolvers ResolverRoot + Directives DirectiveRoot + Complexity ComplexityRoot +} + +type ResolverRoot interface { + Entity() EntityResolver + Mutation() MutationResolver + Query() QueryResolver + Subscription() SubscriptionResolver +} + +type DirectiveRoot struct { +} + +type ComplexityRoot struct { + Entity struct { + FindItemByID func(childComplexity int, id string) int + FindProductByIDAndRegion func(childComplexity int, id string, region string) int + FindProductBySku func(childComplexity int, sku string) int + FindWarehouseByLocationID func(childComplexity int, locationID string) int + } + + Item struct { + Category func(childComplexity int) int + ID func(childComplexity int) int + Name func(childComplexity int) int + } + + Location struct { + ID func(childComplexity int) int + } + + Mutation struct { + CreateItem func(childComplexity int, name string, category string) int + DeleteItem func(childComplexity int, id string) int + DeleteProduct func(childComplexity int, id string, region string) int + UpdateItem func(childComplexity int, id string, name string) int + } + + Product struct { + ID func(childComplexity int) int + Name func(childComplexity int) int + Region func(childComplexity int) int + Sku func(childComplexity int) int + } + + Query struct { + Item func(childComplexity int, id string) int + ItemByPid func(childComplexity int, pid string) int + Items func(childComplexity int) int + ItemsByIds func(childComplexity int, ids []string) int + Product func(childComplexity int, id string, region string) int + ProductByKey func(childComplexity int, key model.ProductKeyInput) int + ProductByName func(childComplexity int, name string) int + ProductBySku func(childComplexity int, sku string) int + Warehouse func(childComplexity int, locationID string) int + WarehouseByInput func(childComplexity int, input model.WarehouseLocationInput) int + __resolve__service func(childComplexity int) int + __resolve_entities func(childComplexity int, representations []map[string]any) int + } + + Subscription struct { + ItemCreated func(childComplexity int) int + ItemUpdated func(childComplexity int) int + } + + Warehouse struct { + Location func(childComplexity int) int + Name func(childComplexity int) int + } + + _Service struct { + SDL func(childComplexity int) int + } +} + +type EntityResolver interface { + FindItemByID(ctx context.Context, id string) (*model.Item, error) + FindProductByIDAndRegion(ctx context.Context, id string, region string) (*model.Product, error) + FindProductBySku(ctx context.Context, sku string) (*model.Product, error) + FindWarehouseByLocationID(ctx context.Context, locationID string) (*model.Warehouse, error) +} +type MutationResolver interface { + UpdateItem(ctx context.Context, id string, name string) (*model.Item, error) + DeleteItem(ctx context.Context, id string) (*model.Item, error) + CreateItem(ctx context.Context, name string, category string) (*model.Item, error) + DeleteProduct(ctx context.Context, id string, region string) (*model.Product, error) +} +type QueryResolver interface { + Item(ctx context.Context, id string) (*model.Item, error) + ItemByPid(ctx context.Context, pid string) (*model.Item, error) + Items(ctx context.Context) ([]*model.Item, error) + ItemsByIds(ctx context.Context, ids []string) ([]*model.Item, error) + Product(ctx context.Context, id string, region string) (*model.Product, error) + ProductBySku(ctx context.Context, sku string) (*model.Product, error) + ProductByName(ctx context.Context, name string) (*model.Product, error) + ProductByKey(ctx context.Context, key model.ProductKeyInput) (*model.Product, error) + Warehouse(ctx context.Context, locationID string) (*model.Warehouse, error) + WarehouseByInput(ctx context.Context, input model.WarehouseLocationInput) (*model.Warehouse, error) +} +type SubscriptionResolver interface { + ItemUpdated(ctx context.Context) (<-chan *model.Item, error) + ItemCreated(ctx context.Context) (<-chan *model.Item, error) +} + +type executableSchema struct { + schema *ast.Schema + resolvers ResolverRoot + directives DirectiveRoot + complexity ComplexityRoot +} + +func (e *executableSchema) Schema() *ast.Schema { + if e.schema != nil { + return e.schema + } + return parsedSchema +} + +func (e *executableSchema) Complexity(ctx context.Context, typeName, field string, childComplexity int, rawArgs map[string]any) (int, bool) { + ec := executionContext{nil, e, 0, 0, nil} + _ = ec + switch typeName + "." + field { + + case "Entity.findItemByID": + if e.complexity.Entity.FindItemByID == nil { + break + } + + args, err := ec.field_Entity_findItemByID_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Entity.FindItemByID(childComplexity, args["id"].(string)), true + + case "Entity.findProductByIDAndRegion": + if e.complexity.Entity.FindProductByIDAndRegion == nil { + break + } + + args, err := ec.field_Entity_findProductByIDAndRegion_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Entity.FindProductByIDAndRegion(childComplexity, args["id"].(string), args["region"].(string)), true + + case "Entity.findProductBySku": + if e.complexity.Entity.FindProductBySku == nil { + break + } + + args, err := ec.field_Entity_findProductBySku_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Entity.FindProductBySku(childComplexity, args["sku"].(string)), true + + case "Entity.findWarehouseByLocationID": + if e.complexity.Entity.FindWarehouseByLocationID == nil { + break + } + + args, err := ec.field_Entity_findWarehouseByLocationID_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Entity.FindWarehouseByLocationID(childComplexity, args["locationID"].(string)), true + + case "Item.category": + if e.complexity.Item.Category == nil { + break + } + + return e.complexity.Item.Category(childComplexity), true + + case "Item.id": + if e.complexity.Item.ID == nil { + break + } + + return e.complexity.Item.ID(childComplexity), true + + case "Item.name": + if e.complexity.Item.Name == nil { + break + } + + return e.complexity.Item.Name(childComplexity), true + + case "Location.id": + if e.complexity.Location.ID == nil { + break + } + + return e.complexity.Location.ID(childComplexity), true + + case "Mutation.createItem": + if e.complexity.Mutation.CreateItem == nil { + break + } + + args, err := ec.field_Mutation_createItem_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Mutation.CreateItem(childComplexity, args["name"].(string), args["category"].(string)), true + + case "Mutation.deleteItem": + if e.complexity.Mutation.DeleteItem == nil { + break + } + + args, err := ec.field_Mutation_deleteItem_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Mutation.DeleteItem(childComplexity, args["id"].(string)), true + + case "Mutation.deleteProduct": + if e.complexity.Mutation.DeleteProduct == nil { + break + } + + args, err := ec.field_Mutation_deleteProduct_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Mutation.DeleteProduct(childComplexity, args["id"].(string), args["region"].(string)), true + + case "Mutation.updateItem": + if e.complexity.Mutation.UpdateItem == nil { + break + } + + args, err := ec.field_Mutation_updateItem_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Mutation.UpdateItem(childComplexity, args["id"].(string), args["name"].(string)), true + + case "Product.id": + if e.complexity.Product.ID == nil { + break + } + + return e.complexity.Product.ID(childComplexity), true + + case "Product.name": + if e.complexity.Product.Name == nil { + break + } + + return e.complexity.Product.Name(childComplexity), true + + case "Product.region": + if e.complexity.Product.Region == nil { + break + } + + return e.complexity.Product.Region(childComplexity), true + + case "Product.sku": + if e.complexity.Product.Sku == nil { + break + } + + return e.complexity.Product.Sku(childComplexity), true + + case "Query.item": + if e.complexity.Query.Item == nil { + break + } + + args, err := ec.field_Query_item_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.Item(childComplexity, args["id"].(string)), true + + case "Query.itemByPid": + if e.complexity.Query.ItemByPid == nil { + break + } + + args, err := ec.field_Query_itemByPid_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.ItemByPid(childComplexity, args["pid"].(string)), true + + case "Query.items": + if e.complexity.Query.Items == nil { + break + } + + return e.complexity.Query.Items(childComplexity), true + + case "Query.itemsByIds": + if e.complexity.Query.ItemsByIds == nil { + break + } + + args, err := ec.field_Query_itemsByIds_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.ItemsByIds(childComplexity, args["ids"].([]string)), true + + case "Query.product": + if e.complexity.Query.Product == nil { + break + } + + args, err := ec.field_Query_product_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.Product(childComplexity, args["id"].(string), args["region"].(string)), true + + case "Query.productByKey": + if e.complexity.Query.ProductByKey == nil { + break + } + + args, err := ec.field_Query_productByKey_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.ProductByKey(childComplexity, args["key"].(model.ProductKeyInput)), true + + case "Query.productByName": + if e.complexity.Query.ProductByName == nil { + break + } + + args, err := ec.field_Query_productByName_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.ProductByName(childComplexity, args["name"].(string)), true + + case "Query.productBySku": + if e.complexity.Query.ProductBySku == nil { + break + } + + args, err := ec.field_Query_productBySku_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.ProductBySku(childComplexity, args["sku"].(string)), true + + case "Query.warehouse": + if e.complexity.Query.Warehouse == nil { + break + } + + args, err := ec.field_Query_warehouse_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.Warehouse(childComplexity, args["locationId"].(string)), true + + case "Query.warehouseByInput": + if e.complexity.Query.WarehouseByInput == nil { + break + } + + args, err := ec.field_Query_warehouseByInput_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.WarehouseByInput(childComplexity, args["input"].(model.WarehouseLocationInput)), true + + case "Query._service": + if e.complexity.Query.__resolve__service == nil { + break + } + + return e.complexity.Query.__resolve__service(childComplexity), true + + case "Query._entities": + if e.complexity.Query.__resolve_entities == nil { + break + } + + args, err := ec.field_Query__entities_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.__resolve_entities(childComplexity, args["representations"].([]map[string]any)), true + + case "Subscription.itemCreated": + if e.complexity.Subscription.ItemCreated == nil { + break + } + + return e.complexity.Subscription.ItemCreated(childComplexity), true + + case "Subscription.itemUpdated": + if e.complexity.Subscription.ItemUpdated == nil { + break + } + + return e.complexity.Subscription.ItemUpdated(childComplexity), true + + case "Warehouse.location": + if e.complexity.Warehouse.Location == nil { + break + } + + return e.complexity.Warehouse.Location(childComplexity), true + + case "Warehouse.name": + if e.complexity.Warehouse.Name == nil { + break + } + + return e.complexity.Warehouse.Name(childComplexity), true + + case "_Service.sdl": + if e.complexity._Service.SDL == nil { + break + } + + return e.complexity._Service.SDL(childComplexity), true + + } + return 0, false +} + +func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { + opCtx := graphql.GetOperationContext(ctx) + ec := executionContext{opCtx, e, 0, 0, make(chan graphql.DeferredResult)} + inputUnmarshalMap := graphql.BuildUnmarshalerMap( + ec.unmarshalInputProductKeyInput, + ec.unmarshalInputWarehouseLocationInput, + ec.unmarshalInputWarehouseLocationKeyInput, + ) + first := true + + switch opCtx.Operation.Operation { + case ast.Query: + return func(ctx context.Context) *graphql.Response { + var response graphql.Response + var data graphql.Marshaler + if first { + first = false + ctx = graphql.WithUnmarshalerMap(ctx, inputUnmarshalMap) + data = ec._Query(ctx, opCtx.Operation.SelectionSet) + } else { + if atomic.LoadInt32(&ec.pendingDeferred) > 0 { + result := <-ec.deferredResults + atomic.AddInt32(&ec.pendingDeferred, -1) + data = result.Result + response.Path = result.Path + response.Label = result.Label + response.Errors = result.Errors + } else { + return nil + } + } + var buf bytes.Buffer + data.MarshalGQL(&buf) + response.Data = buf.Bytes() + if atomic.LoadInt32(&ec.deferred) > 0 { + hasNext := atomic.LoadInt32(&ec.pendingDeferred) > 0 + response.HasNext = &hasNext + } + + return &response + } + case ast.Mutation: + return func(ctx context.Context) *graphql.Response { + if !first { + return nil + } + first = false + ctx = graphql.WithUnmarshalerMap(ctx, inputUnmarshalMap) + data := ec._Mutation(ctx, opCtx.Operation.SelectionSet) + var buf bytes.Buffer + data.MarshalGQL(&buf) + + return &graphql.Response{ + Data: buf.Bytes(), + } + } + case ast.Subscription: + next := ec._Subscription(ctx, opCtx.Operation.SelectionSet) + + var buf bytes.Buffer + return func(ctx context.Context) *graphql.Response { + buf.Reset() + data := next(ctx) + + if data == nil { + return nil + } + data.MarshalGQL(&buf) + + return &graphql.Response{ + Data: buf.Bytes(), + } + } + + default: + return graphql.OneShot(graphql.ErrorResponse(ctx, "unsupported GraphQL operation")) + } +} + +type executionContext struct { + *graphql.OperationContext + *executableSchema + deferred int32 + pendingDeferred int32 + deferredResults chan graphql.DeferredResult +} + +func (ec *executionContext) processDeferredGroup(dg graphql.DeferredGroup) { + atomic.AddInt32(&ec.pendingDeferred, 1) + go func() { + ctx := graphql.WithFreshResponseContext(dg.Context) + dg.FieldSet.Dispatch(ctx) + ds := graphql.DeferredResult{ + Path: dg.Path, + Label: dg.Label, + Result: dg.FieldSet, + Errors: graphql.GetErrors(ctx), + } + // null fields should bubble up + if dg.FieldSet.Invalids > 0 { + ds.Result = graphql.Null + } + ec.deferredResults <- ds + }() +} + +func (ec *executionContext) introspectSchema() (*introspection.Schema, error) { + if ec.DisableIntrospection { + return nil, errors.New("introspection disabled") + } + return introspection.WrapSchema(ec.Schema()), nil +} + +func (ec *executionContext) introspectType(name string) (*introspection.Type, error) { + if ec.DisableIntrospection { + return nil, errors.New("introspection disabled") + } + return introspection.WrapTypeFromDef(ec.Schema(), ec.Schema().Types[name]), nil +} + +var sources = []*ast.Source{ + {Name: "../schema.graphqls", Input: `extend schema + @link( + url: "https://specs.apollo.dev/federation/v2.5" + import: ["@key"] + ) + +directive @openfed__entityCache( + maxAge: Int! + negativeCacheTTL: Int = 0 + includeHeaders: Boolean = false + partialCacheLoad: Boolean = false + shadowMode: Boolean = false +) on OBJECT + +directive @openfed__queryCache( + maxAge: Int! + includeHeaders: Boolean = false + shadowMode: Boolean = false +) on FIELD_DEFINITION + +directive @openfed__cacheInvalidate on FIELD_DEFINITION + +directive @openfed__cachePopulate(maxAge: Int) on FIELD_DEFINITION + +directive @openfed__is(fields: String!) on ARGUMENT_DEFINITION + +type Query { + item(id: ID!): Item @openfed__queryCache(maxAge: 300) + itemByPid(pid: ID! @openfed__is(fields: "id")): Item @openfed__queryCache(maxAge: 300) + items: [Item!]! @openfed__queryCache(maxAge: 300) + itemsByIds(ids: [ID!]! @openfed__is(fields: "id")): [Item!]! @openfed__queryCache(maxAge: 300) + product(id: ID!, region: String!): Product @openfed__queryCache(maxAge: 300) + productBySku(sku: String!): Product @openfed__queryCache(maxAge: 300) + productByName(name: String!): Product @openfed__queryCache(maxAge: 300) + productByKey(key: ProductKeyInput! @openfed__is(fields: "id region")): Product @openfed__queryCache(maxAge: 300) + warehouse(locationId: ID! @openfed__is(fields: "location.id")): Warehouse @openfed__queryCache(maxAge: 300) + # warehouseByInput exercises the same nested @key as ` + "`" + `warehouse` + "`" + ` but reaches it + # via an input object using GraphQL selection syntax in @openfed__is. This produces the + # multi-hop argumentPath ["input","location","id"] instead of the scalar + # ["locationId"]. Captures the red state where input-object → nested-key + # cache writes don't persist (cache lookup uses correct key but never hits). + warehouseByInput(input: WarehouseLocationInput! @openfed__is(fields: "location { id }")): Warehouse @openfed__queryCache(maxAge: 300) +} + +input ProductKeyInput { + id: ID! + region: String! +} + +input WarehouseLocationInput { + location: WarehouseLocationKeyInput! +} + +input WarehouseLocationKeyInput { + id: ID! +} + +type Mutation { + updateItem(id: ID!, name: String!): Item @openfed__cacheInvalidate + deleteItem(id: ID!): Item @openfed__cacheInvalidate + createItem(name: String!, category: String!): Item! @openfed__cachePopulate(maxAge: 60) + # deleteProduct invalidates a composite-key entity (Product @key("id region")). + # Used to pin behavior for cache invalidation when the entity uses a composite + # @key — a separate code path from the simple id-only key in deleteItem. + deleteProduct(id: ID!, region: String!): Product @openfed__cacheInvalidate +} + +type Subscription { + itemUpdated: Item @openfed__cacheInvalidate + itemCreated: Item @openfed__cachePopulate +} + +type Item @key(fields: "id") @openfed__entityCache(maxAge: 300, negativeCacheTTL: 30) { + id: ID! + name: String! + category: String! +} + +type Product @key(fields: "id region") @key(fields: "sku") @openfed__entityCache(maxAge: 300) { + id: ID! + region: String! + sku: String! + name: String! +} + +type Location { + id: ID! +} + +type Warehouse @key(fields: "location { id }") @openfed__entityCache(maxAge: 300) { + location: Location! + name: String! +} +`, BuiltIn: false}, + {Name: "../../federation/directives.graphql", Input: ` + directive @authenticated on FIELD_DEFINITION | OBJECT | INTERFACE | SCALAR | ENUM + directive @composeDirective(name: String!) repeatable on SCHEMA + directive @extends on OBJECT | INTERFACE + directive @external on OBJECT | FIELD_DEFINITION + directive @key(fields: FieldSet!, resolvable: Boolean = true) repeatable on OBJECT | INTERFACE + directive @inaccessible on + | ARGUMENT_DEFINITION + | ENUM + | ENUM_VALUE + | FIELD_DEFINITION + | INPUT_FIELD_DEFINITION + | INPUT_OBJECT + | INTERFACE + | OBJECT + | SCALAR + | UNION + directive @interfaceObject on OBJECT + directive @link(import: [String!], url: String!) repeatable on SCHEMA + directive @override(from: String!, label: String) on FIELD_DEFINITION + directive @policy(policies: [[federation__Policy!]!]!) on + | FIELD_DEFINITION + | OBJECT + | INTERFACE + | SCALAR + | ENUM + directive @provides(fields: FieldSet!) on FIELD_DEFINITION + directive @requires(fields: FieldSet!) on FIELD_DEFINITION + directive @requiresScopes(scopes: [[federation__Scope!]!]!) on + | FIELD_DEFINITION + | OBJECT + | INTERFACE + | SCALAR + | ENUM + directive @shareable repeatable on FIELD_DEFINITION | OBJECT + directive @tag(name: String!) repeatable on + | ARGUMENT_DEFINITION + | ENUM + | ENUM_VALUE + | FIELD_DEFINITION + | INPUT_FIELD_DEFINITION + | INPUT_OBJECT + | INTERFACE + | OBJECT + | SCALAR + | UNION + scalar _Any + scalar FieldSet + scalar federation__Policy + scalar federation__Scope +`, BuiltIn: true}, + {Name: "../../federation/entity.graphql", Input: ` +# a union of all types that use the @key directive +union _Entity = Item | Product | Warehouse + +# fake type to build resolver interfaces for users to implement +type Entity { + findItemByID(id: ID!,): Item! + findProductByIDAndRegion(id: ID!,region: String!,): Product! + findProductBySku(sku: String!,): Product! + findWarehouseByLocationID(locationID: ID!,): Warehouse! +} + +type _Service { + sdl: String +} + +extend type Query { + _entities(representations: [_Any!]!): [_Entity]! + _service: _Service! +} +`, BuiltIn: true}, +} +var parsedSchema = gqlparser.MustLoadSchema(sources...) + +// endregion ************************** generated!.gotpl ************************** + +// region ***************************** args.gotpl ***************************** + +func (ec *executionContext) field_Entity_findItemByID_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Entity_findItemByID_argsID(ctx, rawArgs) + if err != nil { + return nil, err + } + args["id"] = arg0 + return args, nil +} +func (ec *executionContext) field_Entity_findItemByID_argsID( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["id"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + if tmp, ok := rawArgs["id"]; ok { + return ec.unmarshalNID2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Entity_findProductByIDAndRegion_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Entity_findProductByIDAndRegion_argsID(ctx, rawArgs) + if err != nil { + return nil, err + } + args["id"] = arg0 + arg1, err := ec.field_Entity_findProductByIDAndRegion_argsRegion(ctx, rawArgs) + if err != nil { + return nil, err + } + args["region"] = arg1 + return args, nil +} +func (ec *executionContext) field_Entity_findProductByIDAndRegion_argsID( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["id"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + if tmp, ok := rawArgs["id"]; ok { + return ec.unmarshalNID2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Entity_findProductByIDAndRegion_argsRegion( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["region"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("region")) + if tmp, ok := rawArgs["region"]; ok { + return ec.unmarshalNString2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Entity_findProductBySku_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Entity_findProductBySku_argsSku(ctx, rawArgs) + if err != nil { + return nil, err + } + args["sku"] = arg0 + return args, nil +} +func (ec *executionContext) field_Entity_findProductBySku_argsSku( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["sku"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("sku")) + if tmp, ok := rawArgs["sku"]; ok { + return ec.unmarshalNString2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Entity_findWarehouseByLocationID_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Entity_findWarehouseByLocationID_argsLocationID(ctx, rawArgs) + if err != nil { + return nil, err + } + args["locationID"] = arg0 + return args, nil +} +func (ec *executionContext) field_Entity_findWarehouseByLocationID_argsLocationID( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["locationID"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("locationID")) + if tmp, ok := rawArgs["locationID"]; ok { + return ec.unmarshalNID2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Mutation_createItem_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Mutation_createItem_argsName(ctx, rawArgs) + if err != nil { + return nil, err + } + args["name"] = arg0 + arg1, err := ec.field_Mutation_createItem_argsCategory(ctx, rawArgs) + if err != nil { + return nil, err + } + args["category"] = arg1 + return args, nil +} +func (ec *executionContext) field_Mutation_createItem_argsName( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["name"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("name")) + if tmp, ok := rawArgs["name"]; ok { + return ec.unmarshalNString2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Mutation_createItem_argsCategory( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["category"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("category")) + if tmp, ok := rawArgs["category"]; ok { + return ec.unmarshalNString2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Mutation_deleteItem_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Mutation_deleteItem_argsID(ctx, rawArgs) + if err != nil { + return nil, err + } + args["id"] = arg0 + return args, nil +} +func (ec *executionContext) field_Mutation_deleteItem_argsID( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["id"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + if tmp, ok := rawArgs["id"]; ok { + return ec.unmarshalNID2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Mutation_deleteProduct_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Mutation_deleteProduct_argsID(ctx, rawArgs) + if err != nil { + return nil, err + } + args["id"] = arg0 + arg1, err := ec.field_Mutation_deleteProduct_argsRegion(ctx, rawArgs) + if err != nil { + return nil, err + } + args["region"] = arg1 + return args, nil +} +func (ec *executionContext) field_Mutation_deleteProduct_argsID( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["id"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + if tmp, ok := rawArgs["id"]; ok { + return ec.unmarshalNID2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Mutation_deleteProduct_argsRegion( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["region"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("region")) + if tmp, ok := rawArgs["region"]; ok { + return ec.unmarshalNString2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Mutation_updateItem_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Mutation_updateItem_argsID(ctx, rawArgs) + if err != nil { + return nil, err + } + args["id"] = arg0 + arg1, err := ec.field_Mutation_updateItem_argsName(ctx, rawArgs) + if err != nil { + return nil, err + } + args["name"] = arg1 + return args, nil +} +func (ec *executionContext) field_Mutation_updateItem_argsID( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["id"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + if tmp, ok := rawArgs["id"]; ok { + return ec.unmarshalNID2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Mutation_updateItem_argsName( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["name"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("name")) + if tmp, ok := rawArgs["name"]; ok { + return ec.unmarshalNString2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Query___type_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Query___type_argsName(ctx, rawArgs) + if err != nil { + return nil, err + } + args["name"] = arg0 + return args, nil +} +func (ec *executionContext) field_Query___type_argsName( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["name"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("name")) + if tmp, ok := rawArgs["name"]; ok { + return ec.unmarshalNString2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Query__entities_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Query__entities_argsRepresentations(ctx, rawArgs) + if err != nil { + return nil, err + } + args["representations"] = arg0 + return args, nil +} +func (ec *executionContext) field_Query__entities_argsRepresentations( + ctx context.Context, + rawArgs map[string]any, +) ([]map[string]any, error) { + if _, ok := rawArgs["representations"]; !ok { + var zeroVal []map[string]any + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("representations")) + if tmp, ok := rawArgs["representations"]; ok { + return ec.unmarshalN_Any2ᚕmapᚄ(ctx, tmp) + } + + var zeroVal []map[string]any + return zeroVal, nil +} + +func (ec *executionContext) field_Query_itemByPid_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Query_itemByPid_argsPid(ctx, rawArgs) + if err != nil { + return nil, err + } + args["pid"] = arg0 + return args, nil +} +func (ec *executionContext) field_Query_itemByPid_argsPid( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["pid"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("pid")) + if tmp, ok := rawArgs["pid"]; ok { + return ec.unmarshalNID2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Query_item_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Query_item_argsID(ctx, rawArgs) + if err != nil { + return nil, err + } + args["id"] = arg0 + return args, nil +} +func (ec *executionContext) field_Query_item_argsID( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["id"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + if tmp, ok := rawArgs["id"]; ok { + return ec.unmarshalNID2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Query_itemsByIds_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Query_itemsByIds_argsIds(ctx, rawArgs) + if err != nil { + return nil, err + } + args["ids"] = arg0 + return args, nil +} +func (ec *executionContext) field_Query_itemsByIds_argsIds( + ctx context.Context, + rawArgs map[string]any, +) ([]string, error) { + if _, ok := rawArgs["ids"]; !ok { + var zeroVal []string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("ids")) + if tmp, ok := rawArgs["ids"]; ok { + return ec.unmarshalNID2ᚕstringᚄ(ctx, tmp) + } + + var zeroVal []string + return zeroVal, nil +} + +func (ec *executionContext) field_Query_productByKey_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Query_productByKey_argsKey(ctx, rawArgs) + if err != nil { + return nil, err + } + args["key"] = arg0 + return args, nil +} +func (ec *executionContext) field_Query_productByKey_argsKey( + ctx context.Context, + rawArgs map[string]any, +) (model.ProductKeyInput, error) { + if _, ok := rawArgs["key"]; !ok { + var zeroVal model.ProductKeyInput + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("key")) + if tmp, ok := rawArgs["key"]; ok { + return ec.unmarshalNProductKeyInput2githubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋitemsᚋsubgraphᚋmodelᚐProductKeyInput(ctx, tmp) + } + + var zeroVal model.ProductKeyInput + return zeroVal, nil +} + +func (ec *executionContext) field_Query_productByName_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Query_productByName_argsName(ctx, rawArgs) + if err != nil { + return nil, err + } + args["name"] = arg0 + return args, nil +} +func (ec *executionContext) field_Query_productByName_argsName( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["name"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("name")) + if tmp, ok := rawArgs["name"]; ok { + return ec.unmarshalNString2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Query_productBySku_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Query_productBySku_argsSku(ctx, rawArgs) + if err != nil { + return nil, err + } + args["sku"] = arg0 + return args, nil +} +func (ec *executionContext) field_Query_productBySku_argsSku( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["sku"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("sku")) + if tmp, ok := rawArgs["sku"]; ok { + return ec.unmarshalNString2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Query_product_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Query_product_argsID(ctx, rawArgs) + if err != nil { + return nil, err + } + args["id"] = arg0 + arg1, err := ec.field_Query_product_argsRegion(ctx, rawArgs) + if err != nil { + return nil, err + } + args["region"] = arg1 + return args, nil +} +func (ec *executionContext) field_Query_product_argsID( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["id"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + if tmp, ok := rawArgs["id"]; ok { + return ec.unmarshalNID2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Query_product_argsRegion( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["region"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("region")) + if tmp, ok := rawArgs["region"]; ok { + return ec.unmarshalNString2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Query_warehouseByInput_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Query_warehouseByInput_argsInput(ctx, rawArgs) + if err != nil { + return nil, err + } + args["input"] = arg0 + return args, nil +} +func (ec *executionContext) field_Query_warehouseByInput_argsInput( + ctx context.Context, + rawArgs map[string]any, +) (model.WarehouseLocationInput, error) { + if _, ok := rawArgs["input"]; !ok { + var zeroVal model.WarehouseLocationInput + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("input")) + if tmp, ok := rawArgs["input"]; ok { + return ec.unmarshalNWarehouseLocationInput2githubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋitemsᚋsubgraphᚋmodelᚐWarehouseLocationInput(ctx, tmp) + } + + var zeroVal model.WarehouseLocationInput + return zeroVal, nil +} + +func (ec *executionContext) field_Query_warehouse_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Query_warehouse_argsLocationID(ctx, rawArgs) + if err != nil { + return nil, err + } + args["locationId"] = arg0 + return args, nil +} +func (ec *executionContext) field_Query_warehouse_argsLocationID( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["locationId"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("locationId")) + if tmp, ok := rawArgs["locationId"]; ok { + return ec.unmarshalNID2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +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 := ec.field___Directive_args_argsIncludeDeprecated(ctx, rawArgs) + if err != nil { + return nil, err + } + args["includeDeprecated"] = arg0 + return args, nil +} +func (ec *executionContext) field___Directive_args_argsIncludeDeprecated( + ctx context.Context, + rawArgs map[string]any, +) (*bool, error) { + if _, ok := rawArgs["includeDeprecated"]; !ok { + var zeroVal *bool + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("includeDeprecated")) + if tmp, ok := rawArgs["includeDeprecated"]; ok { + return ec.unmarshalOBoolean2ᚖbool(ctx, tmp) + } + + var zeroVal *bool + return zeroVal, nil +} + +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 := ec.field___Field_args_argsIncludeDeprecated(ctx, rawArgs) + if err != nil { + return nil, err + } + args["includeDeprecated"] = arg0 + return args, nil +} +func (ec *executionContext) field___Field_args_argsIncludeDeprecated( + ctx context.Context, + rawArgs map[string]any, +) (*bool, error) { + if _, ok := rawArgs["includeDeprecated"]; !ok { + var zeroVal *bool + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("includeDeprecated")) + if tmp, ok := rawArgs["includeDeprecated"]; ok { + return ec.unmarshalOBoolean2ᚖbool(ctx, tmp) + } + + var zeroVal *bool + return zeroVal, nil +} + +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 := ec.field___Type_enumValues_argsIncludeDeprecated(ctx, rawArgs) + if err != nil { + return nil, err + } + args["includeDeprecated"] = arg0 + return args, nil +} +func (ec *executionContext) field___Type_enumValues_argsIncludeDeprecated( + ctx context.Context, + rawArgs map[string]any, +) (bool, error) { + if _, ok := rawArgs["includeDeprecated"]; !ok { + var zeroVal bool + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("includeDeprecated")) + if tmp, ok := rawArgs["includeDeprecated"]; ok { + return ec.unmarshalOBoolean2bool(ctx, tmp) + } + + var zeroVal bool + return zeroVal, nil +} + +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 := ec.field___Type_fields_argsIncludeDeprecated(ctx, rawArgs) + if err != nil { + return nil, err + } + args["includeDeprecated"] = arg0 + return args, nil +} +func (ec *executionContext) field___Type_fields_argsIncludeDeprecated( + ctx context.Context, + rawArgs map[string]any, +) (bool, error) { + if _, ok := rawArgs["includeDeprecated"]; !ok { + var zeroVal bool + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("includeDeprecated")) + if tmp, ok := rawArgs["includeDeprecated"]; ok { + return ec.unmarshalOBoolean2bool(ctx, tmp) + } + + var zeroVal bool + return zeroVal, nil +} + +// endregion ***************************** args.gotpl ***************************** + +// region ************************** directives.gotpl ************************** + +// endregion ************************** directives.gotpl ************************** + +// region **************************** field.gotpl ***************************** + +func (ec *executionContext) _Entity_findItemByID(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Entity_findItemByID(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Entity().FindItemByID(rctx, fc.Args["id"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*model.Item) + fc.Result = res + return ec.marshalNItem2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋitemsᚋsubgraphᚋmodelᚐItem(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Entity_findItemByID(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Entity", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Item_id(ctx, field) + case "name": + return ec.fieldContext_Item_name(ctx, field) + case "category": + return ec.fieldContext_Item_category(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Item", field.Name) + }, + } + 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_Entity_findItemByID_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Entity_findProductByIDAndRegion(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Entity_findProductByIDAndRegion(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Entity().FindProductByIDAndRegion(rctx, fc.Args["id"].(string), fc.Args["region"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*model.Product) + fc.Result = res + return ec.marshalNProduct2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋitemsᚋsubgraphᚋmodelᚐProduct(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Entity_findProductByIDAndRegion(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Entity", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Product_id(ctx, field) + case "region": + return ec.fieldContext_Product_region(ctx, field) + case "sku": + return ec.fieldContext_Product_sku(ctx, field) + case "name": + return ec.fieldContext_Product_name(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Product", field.Name) + }, + } + 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_Entity_findProductByIDAndRegion_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Entity_findProductBySku(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Entity_findProductBySku(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Entity().FindProductBySku(rctx, fc.Args["sku"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*model.Product) + fc.Result = res + return ec.marshalNProduct2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋitemsᚋsubgraphᚋmodelᚐProduct(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Entity_findProductBySku(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Entity", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Product_id(ctx, field) + case "region": + return ec.fieldContext_Product_region(ctx, field) + case "sku": + return ec.fieldContext_Product_sku(ctx, field) + case "name": + return ec.fieldContext_Product_name(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Product", field.Name) + }, + } + 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_Entity_findProductBySku_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Entity_findWarehouseByLocationID(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Entity_findWarehouseByLocationID(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Entity().FindWarehouseByLocationID(rctx, fc.Args["locationID"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*model.Warehouse) + fc.Result = res + return ec.marshalNWarehouse2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋitemsᚋsubgraphᚋmodelᚐWarehouse(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Entity_findWarehouseByLocationID(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Entity", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "location": + return ec.fieldContext_Warehouse_location(ctx, field) + case "name": + return ec.fieldContext_Warehouse_name(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Warehouse", field.Name) + }, + } + 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_Entity_findWarehouseByLocationID_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Item_id(ctx context.Context, field graphql.CollectedField, obj *model.Item) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Item_id(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Item_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Item", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Item_name(ctx context.Context, field graphql.CollectedField, obj *model.Item) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Item_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Item_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Item", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Item_category(ctx context.Context, field graphql.CollectedField, obj *model.Item) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Item_category(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Category, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Item_category(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Item", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Location_id(ctx context.Context, field graphql.CollectedField, obj *model.Location) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Location_id(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Location_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Location", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Mutation_updateItem(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Mutation_updateItem(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Mutation().UpdateItem(rctx, fc.Args["id"].(string), fc.Args["name"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*model.Item) + fc.Result = res + return ec.marshalOItem2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋitemsᚋsubgraphᚋmodelᚐItem(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Mutation_updateItem(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Mutation", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Item_id(ctx, field) + case "name": + return ec.fieldContext_Item_name(ctx, field) + case "category": + return ec.fieldContext_Item_category(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Item", field.Name) + }, + } + 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_Mutation_updateItem_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Mutation_deleteItem(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Mutation_deleteItem(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Mutation().DeleteItem(rctx, fc.Args["id"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*model.Item) + fc.Result = res + return ec.marshalOItem2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋitemsᚋsubgraphᚋmodelᚐItem(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Mutation_deleteItem(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Mutation", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Item_id(ctx, field) + case "name": + return ec.fieldContext_Item_name(ctx, field) + case "category": + return ec.fieldContext_Item_category(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Item", field.Name) + }, + } + 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_Mutation_deleteItem_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Mutation_createItem(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Mutation_createItem(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Mutation().CreateItem(rctx, fc.Args["name"].(string), fc.Args["category"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*model.Item) + fc.Result = res + return ec.marshalNItem2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋitemsᚋsubgraphᚋmodelᚐItem(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Mutation_createItem(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Mutation", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Item_id(ctx, field) + case "name": + return ec.fieldContext_Item_name(ctx, field) + case "category": + return ec.fieldContext_Item_category(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Item", field.Name) + }, + } + 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_Mutation_createItem_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Mutation_deleteProduct(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Mutation_deleteProduct(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Mutation().DeleteProduct(rctx, fc.Args["id"].(string), fc.Args["region"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*model.Product) + fc.Result = res + return ec.marshalOProduct2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋitemsᚋsubgraphᚋmodelᚐProduct(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Mutation_deleteProduct(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Mutation", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Product_id(ctx, field) + case "region": + return ec.fieldContext_Product_region(ctx, field) + case "sku": + return ec.fieldContext_Product_sku(ctx, field) + case "name": + return ec.fieldContext_Product_name(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Product", field.Name) + }, + } + 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_Mutation_deleteProduct_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Product_id(ctx context.Context, field graphql.CollectedField, obj *model.Product) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Product_id(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Product_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Product", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Product_region(ctx context.Context, field graphql.CollectedField, obj *model.Product) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Product_region(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Region, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Product_region(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Product", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Product_sku(ctx context.Context, field graphql.CollectedField, obj *model.Product) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Product_sku(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Sku, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Product_sku(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Product", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Product_name(ctx context.Context, field graphql.CollectedField, obj *model.Product) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Product_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Product_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Product", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Query_item(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query_item(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().Item(rctx, fc.Args["id"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*model.Item) + fc.Result = res + return ec.marshalOItem2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋitemsᚋsubgraphᚋmodelᚐItem(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query_item(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) { + switch field.Name { + case "id": + return ec.fieldContext_Item_id(ctx, field) + case "name": + return ec.fieldContext_Item_name(ctx, field) + case "category": + return ec.fieldContext_Item_category(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Item", field.Name) + }, + } + 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_item_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query_itemByPid(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query_itemByPid(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().ItemByPid(rctx, fc.Args["pid"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*model.Item) + fc.Result = res + return ec.marshalOItem2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋitemsᚋsubgraphᚋmodelᚐItem(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query_itemByPid(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) { + switch field.Name { + case "id": + return ec.fieldContext_Item_id(ctx, field) + case "name": + return ec.fieldContext_Item_name(ctx, field) + case "category": + return ec.fieldContext_Item_category(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Item", field.Name) + }, + } + 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_itemByPid_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query_items(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query_items(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().Items(rctx) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]*model.Item) + fc.Result = res + return ec.marshalNItem2ᚕᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋitemsᚋsubgraphᚋmodelᚐItemᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query_items(_ 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) { + switch field.Name { + case "id": + return ec.fieldContext_Item_id(ctx, field) + case "name": + return ec.fieldContext_Item_name(ctx, field) + case "category": + return ec.fieldContext_Item_category(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Item", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Query_itemsByIds(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query_itemsByIds(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().ItemsByIds(rctx, fc.Args["ids"].([]string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]*model.Item) + fc.Result = res + return ec.marshalNItem2ᚕᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋitemsᚋsubgraphᚋmodelᚐItemᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query_itemsByIds(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) { + switch field.Name { + case "id": + return ec.fieldContext_Item_id(ctx, field) + case "name": + return ec.fieldContext_Item_name(ctx, field) + case "category": + return ec.fieldContext_Item_category(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Item", field.Name) + }, + } + 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_itemsByIds_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query_product(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query_product(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().Product(rctx, fc.Args["id"].(string), fc.Args["region"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*model.Product) + fc.Result = res + return ec.marshalOProduct2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋitemsᚋsubgraphᚋmodelᚐProduct(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query_product(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) { + switch field.Name { + case "id": + return ec.fieldContext_Product_id(ctx, field) + case "region": + return ec.fieldContext_Product_region(ctx, field) + case "sku": + return ec.fieldContext_Product_sku(ctx, field) + case "name": + return ec.fieldContext_Product_name(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Product", field.Name) + }, + } + 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_product_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query_productBySku(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query_productBySku(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().ProductBySku(rctx, fc.Args["sku"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*model.Product) + fc.Result = res + return ec.marshalOProduct2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋitemsᚋsubgraphᚋmodelᚐProduct(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query_productBySku(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) { + switch field.Name { + case "id": + return ec.fieldContext_Product_id(ctx, field) + case "region": + return ec.fieldContext_Product_region(ctx, field) + case "sku": + return ec.fieldContext_Product_sku(ctx, field) + case "name": + return ec.fieldContext_Product_name(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Product", field.Name) + }, + } + 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_productBySku_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query_productByName(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query_productByName(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().ProductByName(rctx, fc.Args["name"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*model.Product) + fc.Result = res + return ec.marshalOProduct2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋitemsᚋsubgraphᚋmodelᚐProduct(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query_productByName(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) { + switch field.Name { + case "id": + return ec.fieldContext_Product_id(ctx, field) + case "region": + return ec.fieldContext_Product_region(ctx, field) + case "sku": + return ec.fieldContext_Product_sku(ctx, field) + case "name": + return ec.fieldContext_Product_name(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Product", field.Name) + }, + } + 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_productByName_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query_productByKey(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query_productByKey(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().ProductByKey(rctx, fc.Args["key"].(model.ProductKeyInput)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*model.Product) + fc.Result = res + return ec.marshalOProduct2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋitemsᚋsubgraphᚋmodelᚐProduct(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query_productByKey(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) { + switch field.Name { + case "id": + return ec.fieldContext_Product_id(ctx, field) + case "region": + return ec.fieldContext_Product_region(ctx, field) + case "sku": + return ec.fieldContext_Product_sku(ctx, field) + case "name": + return ec.fieldContext_Product_name(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Product", field.Name) + }, + } + 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_productByKey_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query_warehouse(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query_warehouse(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().Warehouse(rctx, fc.Args["locationId"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*model.Warehouse) + fc.Result = res + return ec.marshalOWarehouse2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋitemsᚋsubgraphᚋmodelᚐWarehouse(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query_warehouse(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) { + switch field.Name { + case "location": + return ec.fieldContext_Warehouse_location(ctx, field) + case "name": + return ec.fieldContext_Warehouse_name(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Warehouse", field.Name) + }, + } + 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_warehouse_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query_warehouseByInput(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query_warehouseByInput(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().WarehouseByInput(rctx, fc.Args["input"].(model.WarehouseLocationInput)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*model.Warehouse) + fc.Result = res + return ec.marshalOWarehouse2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋitemsᚋsubgraphᚋmodelᚐWarehouse(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query_warehouseByInput(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) { + switch field.Name { + case "location": + return ec.fieldContext_Warehouse_location(ctx, field) + case "name": + return ec.fieldContext_Warehouse_name(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Warehouse", field.Name) + }, + } + 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_warehouseByInput_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query__entities(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query__entities(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.__resolve_entities(ctx, fc.Args["representations"].([]map[string]any)), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]fedruntime.Entity) + fc.Result = res + return ec.marshalN_Entity2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐEntity(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query__entities(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type _Entity does not have child fields") + }, + } + 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__entities_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query__service(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query__service(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.__resolve__service(ctx) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(fedruntime.Service) + fc.Result = res + return ec.marshalN_Service2githubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐService(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query__service(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "sdl": + return ec.fieldContext__Service_sdl(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type _Service", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Query___type(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query___type(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.introspectType(fc.Args["name"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query___type(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + 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___type_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query___schema(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query___schema(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.introspectSchema() + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Schema) + fc.Result = res + return ec.marshalO__Schema2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐSchema(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query___schema(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "description": + return ec.fieldContext___Schema_description(ctx, field) + case "types": + return ec.fieldContext___Schema_types(ctx, field) + case "queryType": + return ec.fieldContext___Schema_queryType(ctx, field) + case "mutationType": + return ec.fieldContext___Schema_mutationType(ctx, field) + case "subscriptionType": + return ec.fieldContext___Schema_subscriptionType(ctx, field) + case "directives": + return ec.fieldContext___Schema_directives(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Schema", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Subscription_itemUpdated(ctx context.Context, field graphql.CollectedField) (ret func(ctx context.Context) graphql.Marshaler) { + fc, err := ec.fieldContext_Subscription_itemUpdated(ctx, field) + if err != nil { + return nil + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Subscription().ItemUpdated(rctx) + }) + if err != nil { + ec.Error(ctx, err) + return nil + } + if resTmp == nil { + return nil + } + return func(ctx context.Context) graphql.Marshaler { + select { + case res, ok := <-resTmp.(<-chan *model.Item): + if !ok { + return nil + } + return graphql.WriterFunc(func(w io.Writer) { + w.Write([]byte{'{'}) + graphql.MarshalString(field.Alias).MarshalGQL(w) + w.Write([]byte{':'}) + ec.marshalOItem2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋitemsᚋsubgraphᚋmodelᚐItem(ctx, field.Selections, res).MarshalGQL(w) + w.Write([]byte{'}'}) + }) + case <-ctx.Done(): + return nil + } + } +} + +func (ec *executionContext) fieldContext_Subscription_itemUpdated(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Subscription", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Item_id(ctx, field) + case "name": + return ec.fieldContext_Item_name(ctx, field) + case "category": + return ec.fieldContext_Item_category(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Item", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Subscription_itemCreated(ctx context.Context, field graphql.CollectedField) (ret func(ctx context.Context) graphql.Marshaler) { + fc, err := ec.fieldContext_Subscription_itemCreated(ctx, field) + if err != nil { + return nil + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Subscription().ItemCreated(rctx) + }) + if err != nil { + ec.Error(ctx, err) + return nil + } + if resTmp == nil { + return nil + } + return func(ctx context.Context) graphql.Marshaler { + select { + case res, ok := <-resTmp.(<-chan *model.Item): + if !ok { + return nil + } + return graphql.WriterFunc(func(w io.Writer) { + w.Write([]byte{'{'}) + graphql.MarshalString(field.Alias).MarshalGQL(w) + w.Write([]byte{':'}) + ec.marshalOItem2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋitemsᚋsubgraphᚋmodelᚐItem(ctx, field.Selections, res).MarshalGQL(w) + w.Write([]byte{'}'}) + }) + case <-ctx.Done(): + return nil + } + } +} + +func (ec *executionContext) fieldContext_Subscription_itemCreated(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Subscription", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Item_id(ctx, field) + case "name": + return ec.fieldContext_Item_name(ctx, field) + case "category": + return ec.fieldContext_Item_category(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Item", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Warehouse_location(ctx context.Context, field graphql.CollectedField, obj *model.Warehouse) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Warehouse_location(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Location, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*model.Location) + fc.Result = res + return ec.marshalNLocation2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋitemsᚋsubgraphᚋmodelᚐLocation(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Warehouse_location(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Warehouse", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Location_id(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Location", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Warehouse_name(ctx context.Context, field graphql.CollectedField, obj *model.Warehouse) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Warehouse_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Warehouse_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Warehouse", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) __Service_sdl(ctx context.Context, field graphql.CollectedField, obj *fedruntime.Service) (ret graphql.Marshaler) { + fc, err := ec.fieldContext__Service_sdl(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.SDL, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalOString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext__Service_sdl(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "_Service", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Directive_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Directive_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Directive_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Directive_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_isRepeatable(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Directive_isRepeatable(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsRepeatable, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Directive_isRepeatable(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_locations(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Directive_locations(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Locations, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]string) + fc.Result = res + return ec.marshalN__DirectiveLocation2ᚕstringᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Directive_locations(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type __DirectiveLocation does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_args(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Directive_args(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Args, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]introspection.InputValue) + fc.Result = res + return ec.marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Directive_args(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___InputValue_name(ctx, field) + case "description": + return ec.fieldContext___InputValue_description(ctx, field) + case "type": + return ec.fieldContext___InputValue_type(ctx, field) + case "defaultValue": + return ec.fieldContext___InputValue_defaultValue(ctx, field) + case "isDeprecated": + return ec.fieldContext___InputValue_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___InputValue_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __InputValue", field.Name) + }, + } + 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___Directive_args_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) ___EnumValue_name(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___EnumValue_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___EnumValue_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__EnumValue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___EnumValue_description(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___EnumValue_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___EnumValue_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__EnumValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___EnumValue_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___EnumValue_isDeprecated(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsDeprecated(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___EnumValue_isDeprecated(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__EnumValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___EnumValue_deprecationReason(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___EnumValue_deprecationReason(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.DeprecationReason(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___EnumValue_deprecationReason(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__EnumValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_args(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_args(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Args, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]introspection.InputValue) + fc.Result = res + return ec.marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_args(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___InputValue_name(ctx, field) + case "description": + return ec.fieldContext___InputValue_description(ctx, field) + case "type": + return ec.fieldContext___InputValue_type(ctx, field) + case "defaultValue": + return ec.fieldContext___InputValue_defaultValue(ctx, field) + case "isDeprecated": + return ec.fieldContext___InputValue_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___InputValue_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __InputValue", field.Name) + }, + } + 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___Field_args_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) ___Field_type(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_type(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Type, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_type(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_isDeprecated(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsDeprecated(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_isDeprecated(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_deprecationReason(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_deprecationReason(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.DeprecationReason(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_deprecationReason(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_name(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_description(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_type(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_type(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Type, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_type(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_defaultValue(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_defaultValue(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.DefaultValue, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_defaultValue(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_isDeprecated(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsDeprecated(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_isDeprecated(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_deprecationReason(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_deprecationReason(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.DeprecationReason(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_deprecationReason(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_types(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_types(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Types(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]introspection.Type) + fc.Result = res + return ec.marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_types(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_queryType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_queryType(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.QueryType(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_queryType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_mutationType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_mutationType(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.MutationType(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_mutationType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_subscriptionType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_subscriptionType(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.SubscriptionType(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_subscriptionType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_directives(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_directives(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Directives(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]introspection.Directive) + fc.Result = res + return ec.marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirectiveᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_directives(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___Directive_name(ctx, field) + case "description": + return ec.fieldContext___Directive_description(ctx, field) + case "isRepeatable": + return ec.fieldContext___Directive_isRepeatable(ctx, field) + case "locations": + return ec.fieldContext___Directive_locations(ctx, field) + case "args": + return ec.fieldContext___Directive_args(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Directive", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_kind(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_kind(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Kind(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalN__TypeKind2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_kind(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type __TypeKind does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_specifiedByURL(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_specifiedByURL(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.SpecifiedByURL(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_specifiedByURL(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_fields(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_fields(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Fields(fc.Args["includeDeprecated"].(bool)), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.Field) + fc.Result = res + return ec.marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐFieldᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_fields(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___Field_name(ctx, field) + case "description": + return ec.fieldContext___Field_description(ctx, field) + case "args": + return ec.fieldContext___Field_args(ctx, field) + case "type": + return ec.fieldContext___Field_type(ctx, field) + case "isDeprecated": + return ec.fieldContext___Field_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___Field_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Field", field.Name) + }, + } + 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_fields_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) ___Type_interfaces(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_interfaces(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Interfaces(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_interfaces(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_possibleTypes(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_possibleTypes(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.PossibleTypes(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_possibleTypes(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_enumValues(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_enumValues(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.EnumValues(fc.Args["includeDeprecated"].(bool)), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.EnumValue) + fc.Result = res + return ec.marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValueᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_enumValues(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___EnumValue_name(ctx, field) + case "description": + return ec.fieldContext___EnumValue_description(ctx, field) + case "isDeprecated": + return ec.fieldContext___EnumValue_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___EnumValue_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __EnumValue", field.Name) + }, + } + 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_enumValues_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) ___Type_inputFields(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_inputFields(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.InputFields(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.InputValue) + fc.Result = res + return ec.marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_inputFields(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___InputValue_name(ctx, field) + case "description": + return ec.fieldContext___InputValue_description(ctx, field) + case "type": + return ec.fieldContext___InputValue_type(ctx, field) + case "defaultValue": + return ec.fieldContext___InputValue_defaultValue(ctx, field) + case "isDeprecated": + return ec.fieldContext___InputValue_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___InputValue_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __InputValue", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_ofType(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_ofType(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.OfType(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_ofType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_isOneOf(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_isOneOf(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsOneOf(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalOBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_isOneOf(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +// endregion **************************** field.gotpl ***************************** + +// region **************************** input.gotpl ***************************** + +func (ec *executionContext) unmarshalInputProductKeyInput(ctx context.Context, obj any) (model.ProductKeyInput, error) { + var it model.ProductKeyInput + asMap := map[string]any{} + for k, v := range obj.(map[string]any) { + asMap[k] = v + } + + fieldsInOrder := [...]string{"id", "region"} + for _, k := range fieldsInOrder { + v, ok := asMap[k] + if !ok { + continue + } + switch k { + case "id": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + data, err := ec.unmarshalNID2string(ctx, v) + if err != nil { + return it, err + } + it.ID = data + case "region": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("region")) + data, err := ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + it.Region = data + } + } + + return it, nil +} + +func (ec *executionContext) unmarshalInputWarehouseLocationInput(ctx context.Context, obj any) (model.WarehouseLocationInput, error) { + var it model.WarehouseLocationInput + asMap := map[string]any{} + for k, v := range obj.(map[string]any) { + asMap[k] = v + } + + fieldsInOrder := [...]string{"location"} + for _, k := range fieldsInOrder { + v, ok := asMap[k] + if !ok { + continue + } + switch k { + case "location": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("location")) + data, err := ec.unmarshalNWarehouseLocationKeyInput2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋitemsᚋsubgraphᚋmodelᚐWarehouseLocationKeyInput(ctx, v) + if err != nil { + return it, err + } + it.Location = data + } + } + + return it, nil +} + +func (ec *executionContext) unmarshalInputWarehouseLocationKeyInput(ctx context.Context, obj any) (model.WarehouseLocationKeyInput, error) { + var it model.WarehouseLocationKeyInput + asMap := map[string]any{} + for k, v := range obj.(map[string]any) { + asMap[k] = v + } + + fieldsInOrder := [...]string{"id"} + for _, k := range fieldsInOrder { + v, ok := asMap[k] + if !ok { + continue + } + switch k { + case "id": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + data, err := ec.unmarshalNID2string(ctx, v) + if err != nil { + return it, err + } + it.ID = data + } + } + + return it, nil +} + +// endregion **************************** input.gotpl ***************************** + +// region ************************** interface.gotpl *************************** + +func (ec *executionContext) __Entity(ctx context.Context, sel ast.SelectionSet, obj fedruntime.Entity) graphql.Marshaler { + switch obj := (obj).(type) { + case nil: + return graphql.Null + case model.Warehouse: + return ec._Warehouse(ctx, sel, &obj) + case *model.Warehouse: + if obj == nil { + return graphql.Null + } + return ec._Warehouse(ctx, sel, obj) + case model.Product: + return ec._Product(ctx, sel, &obj) + case *model.Product: + if obj == nil { + return graphql.Null + } + return ec._Product(ctx, sel, obj) + case model.Item: + return ec._Item(ctx, sel, &obj) + case *model.Item: + if obj == nil { + return graphql.Null + } + return ec._Item(ctx, sel, obj) + default: + panic(fmt.Errorf("unexpected type %T", obj)) + } +} + +// endregion ************************** interface.gotpl *************************** + +// region **************************** object.gotpl **************************** + +var entityImplementors = []string{"Entity"} + +func (ec *executionContext) _Entity(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, entityImplementors) + ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ + Object: "Entity", + }) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ + Object: field.Name, + Field: field, + }) + + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Entity") + case "findItemByID": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Entity_findItemByID(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "findProductByIDAndRegion": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Entity_findProductByIDAndRegion(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "findProductBySku": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Entity_findProductBySku(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "findWarehouseByLocationID": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Entity_findWarehouseByLocationID(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var itemImplementors = []string{"Item", "_Entity"} + +func (ec *executionContext) _Item(ctx context.Context, sel ast.SelectionSet, obj *model.Item) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, itemImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Item") + case "id": + out.Values[i] = ec._Item_id(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "name": + out.Values[i] = ec._Item_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "category": + out.Values[i] = ec._Item_category(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 + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var locationImplementors = []string{"Location"} + +func (ec *executionContext) _Location(ctx context.Context, sel ast.SelectionSet, obj *model.Location) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, locationImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Location") + case "id": + out.Values[i] = ec._Location_id(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 + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var mutationImplementors = []string{"Mutation"} + +func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, mutationImplementors) + ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ + Object: "Mutation", + }) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ + Object: field.Name, + Field: field, + }) + + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Mutation") + case "updateItem": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Mutation_updateItem(ctx, field) + }) + case "deleteItem": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Mutation_deleteItem(ctx, field) + }) + case "createItem": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Mutation_createItem(ctx, field) + }) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "deleteProduct": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Mutation_deleteProduct(ctx, field) + }) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var productImplementors = []string{"Product", "_Entity"} + +func (ec *executionContext) _Product(ctx context.Context, sel ast.SelectionSet, obj *model.Product) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, productImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Product") + case "id": + out.Values[i] = ec._Product_id(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "region": + out.Values[i] = ec._Product_region(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "sku": + out.Values[i] = ec._Product_sku(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "name": + out.Values[i] = ec._Product_name(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 + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var queryImplementors = []string{"Query"} + +func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, queryImplementors) + ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ + Object: "Query", + }) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ + Object: field.Name, + Field: field, + }) + + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Query") + case "item": + field := field + + innerFunc := func(ctx context.Context, _ *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_item(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "itemByPid": + field := field + + innerFunc := func(ctx context.Context, _ *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_itemByPid(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "items": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_items(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "itemsByIds": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_itemsByIds(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "product": + field := field + + innerFunc := func(ctx context.Context, _ *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_product(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "productBySku": + field := field + + innerFunc := func(ctx context.Context, _ *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_productBySku(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "productByName": + field := field + + innerFunc := func(ctx context.Context, _ *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_productByName(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "productByKey": + field := field + + innerFunc := func(ctx context.Context, _ *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_productByKey(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "warehouse": + field := field + + innerFunc := func(ctx context.Context, _ *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_warehouse(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "warehouseByInput": + field := field + + innerFunc := func(ctx context.Context, _ *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_warehouseByInput(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "_entities": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query__entities(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "_service": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query__service(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "__type": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Query___type(ctx, field) + }) + case "__schema": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Query___schema(ctx, field) + }) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var subscriptionImplementors = []string{"Subscription"} + +func (ec *executionContext) _Subscription(ctx context.Context, sel ast.SelectionSet) func(ctx context.Context) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, subscriptionImplementors) + ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ + Object: "Subscription", + }) + if len(fields) != 1 { + ec.Errorf(ctx, "must subscribe to exactly one stream") + return nil + } + + switch fields[0].Name { + case "itemUpdated": + return ec._Subscription_itemUpdated(ctx, fields[0]) + case "itemCreated": + return ec._Subscription_itemCreated(ctx, fields[0]) + default: + panic("unknown field " + strconv.Quote(fields[0].Name)) + } +} + +var warehouseImplementors = []string{"Warehouse", "_Entity"} + +func (ec *executionContext) _Warehouse(ctx context.Context, sel ast.SelectionSet, obj *model.Warehouse) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, warehouseImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Warehouse") + case "location": + out.Values[i] = ec._Warehouse_location(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "name": + out.Values[i] = ec._Warehouse_name(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 + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var _ServiceImplementors = []string{"_Service"} + +func (ec *executionContext) __Service(ctx context.Context, sel ast.SelectionSet, obj *fedruntime.Service) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, _ServiceImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("_Service") + case "sdl": + out.Values[i] = ec.__Service_sdl(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __DirectiveImplementors = []string{"__Directive"} + +func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionSet, obj *introspection.Directive) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __DirectiveImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__Directive") + case "name": + out.Values[i] = ec.___Directive_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "description": + out.Values[i] = ec.___Directive_description(ctx, field, obj) + case "isRepeatable": + out.Values[i] = ec.___Directive_isRepeatable(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "locations": + out.Values[i] = ec.___Directive_locations(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "args": + out.Values[i] = ec.___Directive_args(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 + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __EnumValueImplementors = []string{"__EnumValue"} + +func (ec *executionContext) ___EnumValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.EnumValue) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __EnumValueImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__EnumValue") + case "name": + out.Values[i] = ec.___EnumValue_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "description": + out.Values[i] = ec.___EnumValue_description(ctx, field, obj) + case "isDeprecated": + out.Values[i] = ec.___EnumValue_isDeprecated(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "deprecationReason": + out.Values[i] = ec.___EnumValue_deprecationReason(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __FieldImplementors = []string{"__Field"} + +func (ec *executionContext) ___Field(ctx context.Context, sel ast.SelectionSet, obj *introspection.Field) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __FieldImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__Field") + case "name": + out.Values[i] = ec.___Field_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "description": + out.Values[i] = ec.___Field_description(ctx, field, obj) + case "args": + out.Values[i] = ec.___Field_args(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "type": + out.Values[i] = ec.___Field_type(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "isDeprecated": + out.Values[i] = ec.___Field_isDeprecated(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "deprecationReason": + out.Values[i] = ec.___Field_deprecationReason(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __InputValueImplementors = []string{"__InputValue"} + +func (ec *executionContext) ___InputValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.InputValue) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __InputValueImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__InputValue") + case "name": + out.Values[i] = ec.___InputValue_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "description": + out.Values[i] = ec.___InputValue_description(ctx, field, obj) + case "type": + out.Values[i] = ec.___InputValue_type(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "defaultValue": + out.Values[i] = ec.___InputValue_defaultValue(ctx, field, obj) + case "isDeprecated": + out.Values[i] = ec.___InputValue_isDeprecated(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "deprecationReason": + out.Values[i] = ec.___InputValue_deprecationReason(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __SchemaImplementors = []string{"__Schema"} + +func (ec *executionContext) ___Schema(ctx context.Context, sel ast.SelectionSet, obj *introspection.Schema) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __SchemaImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__Schema") + case "description": + out.Values[i] = ec.___Schema_description(ctx, field, obj) + case "types": + out.Values[i] = ec.___Schema_types(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "queryType": + out.Values[i] = ec.___Schema_queryType(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "mutationType": + out.Values[i] = ec.___Schema_mutationType(ctx, field, obj) + case "subscriptionType": + out.Values[i] = ec.___Schema_subscriptionType(ctx, field, obj) + case "directives": + out.Values[i] = ec.___Schema_directives(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 + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __TypeImplementors = []string{"__Type"} + +func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, obj *introspection.Type) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __TypeImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__Type") + case "kind": + out.Values[i] = ec.___Type_kind(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "name": + out.Values[i] = ec.___Type_name(ctx, field, obj) + case "description": + out.Values[i] = ec.___Type_description(ctx, field, obj) + case "specifiedByURL": + out.Values[i] = ec.___Type_specifiedByURL(ctx, field, obj) + case "fields": + out.Values[i] = ec.___Type_fields(ctx, field, obj) + case "interfaces": + out.Values[i] = ec.___Type_interfaces(ctx, field, obj) + case "possibleTypes": + out.Values[i] = ec.___Type_possibleTypes(ctx, field, obj) + case "enumValues": + out.Values[i] = ec.___Type_enumValues(ctx, field, obj) + case "inputFields": + out.Values[i] = ec.___Type_inputFields(ctx, field, obj) + case "ofType": + out.Values[i] = ec.___Type_ofType(ctx, field, obj) + case "isOneOf": + out.Values[i] = ec.___Type_isOneOf(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +// endregion **************************** object.gotpl **************************** + +// region ***************************** type.gotpl ***************************** + +func (ec *executionContext) unmarshalNBoolean2bool(ctx context.Context, v any) (bool, error) { + res, err := graphql.UnmarshalBoolean(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNBoolean2bool(ctx context.Context, sel ast.SelectionSet, v bool) graphql.Marshaler { + _ = sel + res := graphql.MarshalBoolean(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNFieldSet2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNFieldSet2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNID2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalID(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNID2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalID(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNID2ᚕstringᚄ(ctx context.Context, v any) ([]string, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNID2string(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalNID2ᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v []string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNID2string(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalNInt2int(ctx context.Context, v any) (int, error) { + res, err := graphql.UnmarshalInt(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNInt2int(ctx context.Context, sel ast.SelectionSet, v int) graphql.Marshaler { + _ = sel + res := graphql.MarshalInt(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) marshalNItem2githubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋitemsᚋsubgraphᚋmodelᚐItem(ctx context.Context, sel ast.SelectionSet, v model.Item) graphql.Marshaler { + return ec._Item(ctx, sel, &v) +} + +func (ec *executionContext) marshalNItem2ᚕᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋitemsᚋsubgraphᚋmodelᚐItemᚄ(ctx context.Context, sel ast.SelectionSet, v []*model.Item) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalNItem2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋitemsᚋsubgraphᚋmodelᚐItem(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalNItem2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋitemsᚋsubgraphᚋmodelᚐItem(ctx context.Context, sel ast.SelectionSet, v *model.Item) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._Item(ctx, sel, v) +} + +func (ec *executionContext) marshalNLocation2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋitemsᚋsubgraphᚋmodelᚐLocation(ctx context.Context, sel ast.SelectionSet, v *model.Location) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._Location(ctx, sel, v) +} + +func (ec *executionContext) marshalNProduct2githubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋitemsᚋsubgraphᚋmodelᚐProduct(ctx context.Context, sel ast.SelectionSet, v model.Product) graphql.Marshaler { + return ec._Product(ctx, sel, &v) +} + +func (ec *executionContext) marshalNProduct2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋitemsᚋsubgraphᚋmodelᚐProduct(ctx context.Context, sel ast.SelectionSet, v *model.Product) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._Product(ctx, sel, v) +} + +func (ec *executionContext) unmarshalNProductKeyInput2githubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋitemsᚋsubgraphᚋmodelᚐProductKeyInput(ctx context.Context, v any) (model.ProductKeyInput, error) { + res, err := ec.unmarshalInputProductKeyInput(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) unmarshalNString2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNString2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) marshalNWarehouse2githubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋitemsᚋsubgraphᚋmodelᚐWarehouse(ctx context.Context, sel ast.SelectionSet, v model.Warehouse) graphql.Marshaler { + return ec._Warehouse(ctx, sel, &v) +} + +func (ec *executionContext) marshalNWarehouse2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋitemsᚋsubgraphᚋmodelᚐWarehouse(ctx context.Context, sel ast.SelectionSet, v *model.Warehouse) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._Warehouse(ctx, sel, v) +} + +func (ec *executionContext) unmarshalNWarehouseLocationInput2githubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋitemsᚋsubgraphᚋmodelᚐWarehouseLocationInput(ctx context.Context, v any) (model.WarehouseLocationInput, error) { + res, err := ec.unmarshalInputWarehouseLocationInput(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) unmarshalNWarehouseLocationKeyInput2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋitemsᚋsubgraphᚋmodelᚐWarehouseLocationKeyInput(ctx context.Context, v any) (*model.WarehouseLocationKeyInput, error) { + res, err := ec.unmarshalInputWarehouseLocationKeyInput(ctx, v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) unmarshalN_Any2map(ctx context.Context, v any) (map[string]any, error) { + res, err := graphql.UnmarshalMap(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalN_Any2map(ctx context.Context, sel ast.SelectionSet, v map[string]any) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + _ = sel + res := graphql.MarshalMap(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalN_Any2ᚕmapᚄ(ctx context.Context, v any) ([]map[string]any, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([]map[string]any, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalN_Any2map(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalN_Any2ᚕmapᚄ(ctx context.Context, sel ast.SelectionSet, v []map[string]any) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalN_Any2map(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalN_Entity2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐEntity(ctx context.Context, sel ast.SelectionSet, v []fedruntime.Entity) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalO_Entity2githubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐEntity(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + return ret +} + +func (ec *executionContext) marshalN_Service2githubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐService(ctx context.Context, sel ast.SelectionSet, v fedruntime.Service) graphql.Marshaler { + return ec.__Service(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__Directive2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirective(ctx context.Context, sel ast.SelectionSet, v introspection.Directive) graphql.Marshaler { + return ec.___Directive(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirectiveᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.Directive) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__Directive2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirective(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalN__DirectiveLocation2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalN__DirectiveLocation2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalN__DirectiveLocation2ᚕstringᚄ(ctx context.Context, v any) ([]string, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalN__DirectiveLocation2string(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalN__DirectiveLocation2ᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v []string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__DirectiveLocation2string(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalN__EnumValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValue(ctx context.Context, sel ast.SelectionSet, v introspection.EnumValue) graphql.Marshaler { + return ec.___EnumValue(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__Field2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐField(ctx context.Context, sel ast.SelectionSet, v introspection.Field) graphql.Marshaler { + return ec.___Field(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__InputValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValue(ctx context.Context, sel ast.SelectionSet, v introspection.InputValue) graphql.Marshaler { + return ec.___InputValue(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.InputValue) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__InputValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValue(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +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) +} + +func (ec *executionContext) marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.Type) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__Type2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx context.Context, sel ast.SelectionSet, v *introspection.Type) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec.___Type(ctx, sel, v) +} + +func (ec *executionContext) unmarshalN__TypeKind2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalN__TypeKind2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNfederation__Policy2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNfederation__Policy2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNfederation__Policy2ᚕstringᚄ(ctx context.Context, v any) ([]string, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNfederation__Policy2string(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalNfederation__Policy2ᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v []string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNfederation__Policy2string(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalNfederation__Policy2ᚕᚕstringᚄ(ctx context.Context, v any) ([][]string, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([][]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNfederation__Policy2ᚕstringᚄ(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalNfederation__Policy2ᚕᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v [][]string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNfederation__Policy2ᚕstringᚄ(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalNfederation__Scope2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNfederation__Scope2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNfederation__Scope2ᚕstringᚄ(ctx context.Context, v any) ([]string, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNfederation__Scope2string(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalNfederation__Scope2ᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v []string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNfederation__Scope2string(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalNfederation__Scope2ᚕᚕstringᚄ(ctx context.Context, v any) ([][]string, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([][]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNfederation__Scope2ᚕstringᚄ(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalNfederation__Scope2ᚕᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v [][]string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNfederation__Scope2ᚕstringᚄ(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalOBoolean2bool(ctx context.Context, v any) (bool, error) { + res, err := graphql.UnmarshalBoolean(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOBoolean2bool(ctx context.Context, sel ast.SelectionSet, v bool) graphql.Marshaler { + _ = sel + _ = ctx + res := graphql.MarshalBoolean(v) + return res +} + +func (ec *executionContext) unmarshalOBoolean2ᚖbool(ctx context.Context, v any) (*bool, error) { + if v == nil { + return nil, nil + } + res, err := graphql.UnmarshalBoolean(v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOBoolean2ᚖbool(ctx context.Context, sel ast.SelectionSet, v *bool) graphql.Marshaler { + if v == nil { + return graphql.Null + } + _ = sel + _ = ctx + res := graphql.MarshalBoolean(*v) + return res +} + +func (ec *executionContext) unmarshalOInt2ᚖint(ctx context.Context, v any) (*int, error) { + if v == nil { + return nil, nil + } + res, err := graphql.UnmarshalInt(v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOInt2ᚖint(ctx context.Context, sel ast.SelectionSet, v *int) graphql.Marshaler { + if v == nil { + return graphql.Null + } + _ = sel + _ = ctx + res := graphql.MarshalInt(*v) + return res +} + +func (ec *executionContext) marshalOItem2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋitemsᚋsubgraphᚋmodelᚐItem(ctx context.Context, sel ast.SelectionSet, v *model.Item) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._Item(ctx, sel, v) +} + +func (ec *executionContext) marshalOProduct2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋitemsᚋsubgraphᚋmodelᚐProduct(ctx context.Context, sel ast.SelectionSet, v *model.Product) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._Product(ctx, sel, v) +} + +func (ec *executionContext) unmarshalOString2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOString2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + _ = ctx + res := graphql.MarshalString(v) + return res +} + +func (ec *executionContext) unmarshalOString2ᚕstringᚄ(ctx context.Context, v any) ([]string, error) { + if v == nil { + return nil, nil + } + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNString2string(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalOString2ᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v []string) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNString2string(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalOString2ᚖstring(ctx context.Context, v any) (*string, error) { + if v == nil { + return nil, nil + } + res, err := graphql.UnmarshalString(v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOString2ᚖstring(ctx context.Context, sel ast.SelectionSet, v *string) graphql.Marshaler { + if v == nil { + return graphql.Null + } + _ = sel + _ = ctx + res := graphql.MarshalString(*v) + return res +} + +func (ec *executionContext) marshalOWarehouse2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋitemsᚋsubgraphᚋmodelᚐWarehouse(ctx context.Context, sel ast.SelectionSet, v *model.Warehouse) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._Warehouse(ctx, sel, v) +} + +func (ec *executionContext) marshalO_Entity2githubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐEntity(ctx context.Context, sel ast.SelectionSet, v fedruntime.Entity) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec.__Entity(ctx, sel, v) +} + +func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.EnumValue) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__EnumValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValue(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐFieldᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.Field) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__Field2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐField(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.InputValue) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__InputValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValue(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + 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 + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__Type2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +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 + } + return ec.___Type(ctx, sel, v) +} + +// endregion ***************************** type.gotpl ***************************** diff --git a/demo/pkg/subgraphs/cachetest/items/subgraph/generated/staticcheck.conf b/demo/pkg/subgraphs/cachetest/items/subgraph/generated/staticcheck.conf new file mode 100644 index 0000000000..582953a07e --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/items/subgraph/generated/staticcheck.conf @@ -0,0 +1,2 @@ +# This is meant as a workaround to skip staticcheck checks for generated code +checks = ["all", "-SA4004", "-ST1000"] diff --git a/demo/pkg/subgraphs/cachetest/items/subgraph/model/models_gen.go b/demo/pkg/subgraphs/cachetest/items/subgraph/model/models_gen.go new file mode 100644 index 0000000000..8c4908fb17 --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/items/subgraph/model/models_gen.go @@ -0,0 +1,53 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package model + +type Item struct { + ID string `json:"id"` + Name string `json:"name"` + Category string `json:"category"` +} + +func (Item) IsEntity() {} + +type Location struct { + ID string `json:"id"` +} + +type Mutation struct { +} + +type Product struct { + ID string `json:"id"` + Region string `json:"region"` + Sku string `json:"sku"` + Name string `json:"name"` +} + +func (Product) IsEntity() {} + +type ProductKeyInput struct { + ID string `json:"id"` + Region string `json:"region"` +} + +type Query struct { +} + +type Subscription struct { +} + +type Warehouse struct { + Location *Location `json:"location"` + Name string `json:"name"` +} + +func (Warehouse) IsEntity() {} + +type WarehouseLocationInput struct { + Location *WarehouseLocationKeyInput `json:"location"` +} + +type WarehouseLocationKeyInput struct { + ID string `json:"id"` +} diff --git a/demo/pkg/subgraphs/cachetest/items/subgraph/resolver.go b/demo/pkg/subgraphs/cachetest/items/subgraph/resolver.go new file mode 100644 index 0000000000..f2754769bc --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/items/subgraph/resolver.go @@ -0,0 +1,26 @@ +package subgraph + +import ( + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachetest/items/subgraph/model" +) + +type Resolver struct { + ItemUpdatedCh chan *model.Item + ItemCreatedCh chan *model.Item + + // Store is a per-resolver Item store. Each subgraph server constructs a + // fresh Resolver (and thus a fresh Store) so mutations in one test do not + // leak into parallel tests. + Store *itemStore +} + +// NewResolver constructs a Resolver with a freshly seeded Item store and the +// subscription channels. Tests should call NewResolver (via NewSchema) rather +// than instantiating Resolver directly so the store is always non-nil. +func NewResolver(itemUpdatedCh chan *model.Item, itemCreatedCh chan *model.Item) *Resolver { + return &Resolver{ + ItemUpdatedCh: itemUpdatedCh, + ItemCreatedCh: itemCreatedCh, + Store: newItemStore(), + } +} diff --git a/demo/pkg/subgraphs/cachetest/items/subgraph/schema.graphqls b/demo/pkg/subgraphs/cachetest/items/subgraph/schema.graphqls new file mode 100644 index 0000000000..b584e904aa --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/items/subgraph/schema.graphqls @@ -0,0 +1,93 @@ +extend schema + @link( + url: "https://specs.apollo.dev/federation/v2.5" + import: ["@key"] + ) + +directive @openfed__entityCache( + maxAge: Int! + negativeCacheTTL: Int = 0 + includeHeaders: Boolean = false + partialCacheLoad: Boolean = false + shadowMode: Boolean = false +) on OBJECT + +directive @openfed__queryCache( + maxAge: Int! + includeHeaders: Boolean = false + shadowMode: Boolean = false +) on FIELD_DEFINITION + +directive @openfed__cacheInvalidate on FIELD_DEFINITION + +directive @openfed__cachePopulate(maxAge: Int) on FIELD_DEFINITION + +directive @openfed__is(fields: String!) on ARGUMENT_DEFINITION + +type Query { + item(id: ID!): Item @openfed__queryCache(maxAge: 300) + itemByPid(pid: ID! @openfed__is(fields: "id")): Item @openfed__queryCache(maxAge: 300) + items: [Item!]! @openfed__queryCache(maxAge: 300) + itemsByIds(ids: [ID!]! @openfed__is(fields: "id")): [Item!]! @openfed__queryCache(maxAge: 300) + product(id: ID!, region: String!): Product @openfed__queryCache(maxAge: 300) + productBySku(sku: String!): Product @openfed__queryCache(maxAge: 300) + productByName(name: String!): Product @openfed__queryCache(maxAge: 300) + productByKey(key: ProductKeyInput! @openfed__is(fields: "id region")): Product @openfed__queryCache(maxAge: 300) + warehouse(locationId: ID! @openfed__is(fields: "location.id")): Warehouse @openfed__queryCache(maxAge: 300) + # warehouseByInput exercises the same nested @key as `warehouse` but reaches it + # via an input object using GraphQL selection syntax in @openfed__is. This produces the + # multi-hop argumentPath ["input","location","id"] instead of the scalar + # ["locationId"]. Captures the red state where input-object → nested-key + # cache writes don't persist (cache lookup uses correct key but never hits). + warehouseByInput(input: WarehouseLocationInput! @openfed__is(fields: "location { id }")): Warehouse @openfed__queryCache(maxAge: 300) +} + +input ProductKeyInput { + id: ID! + region: String! +} + +input WarehouseLocationInput { + location: WarehouseLocationKeyInput! +} + +input WarehouseLocationKeyInput { + id: ID! +} + +type Mutation { + updateItem(id: ID!, name: String!): Item @openfed__cacheInvalidate + deleteItem(id: ID!): Item @openfed__cacheInvalidate + createItem(name: String!, category: String!): Item! @openfed__cachePopulate(maxAge: 60) + # deleteProduct invalidates a composite-key entity (Product @key("id region")). + # Used to pin behavior for cache invalidation when the entity uses a composite + # @key — a separate code path from the simple id-only key in deleteItem. + deleteProduct(id: ID!, region: String!): Product @openfed__cacheInvalidate +} + +type Subscription { + itemUpdated: Item @openfed__cacheInvalidate + itemCreated: Item @openfed__cachePopulate +} + +type Item @key(fields: "id") @openfed__entityCache(maxAge: 300, negativeCacheTTL: 30) { + id: ID! + name: String! + category: String! +} + +type Product @key(fields: "id region") @key(fields: "sku") @openfed__entityCache(maxAge: 300) { + id: ID! + region: String! + sku: String! + name: String! +} + +type Location { + id: ID! +} + +type Warehouse @key(fields: "location { id }") @openfed__entityCache(maxAge: 300) { + location: Location! + name: String! +} diff --git a/demo/pkg/subgraphs/cachetest/items/subgraph/schema.resolvers.go b/demo/pkg/subgraphs/cachetest/items/subgraph/schema.resolvers.go new file mode 100644 index 0000000000..b4a35e728c --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/items/subgraph/schema.resolvers.go @@ -0,0 +1,180 @@ +package subgraph + +// 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.76 + +import ( + "context" + "fmt" + + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachetest/items/subgraph/generated" + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachetest/items/subgraph/model" +) + +// UpdateItem is the resolver for the updateItem field. +// It persists the new name to the per-resolver store and publishes the +// updated entity on the itemUpdated subscription channel so subscription-based +// @cacheInvalidate flows can be exercised end-to-end in tests. +func (r *mutationResolver) UpdateItem(ctx context.Context, id string, name string) (*model.Item, error) { + updated, ok := r.Store.update(id, name) + if !ok { + return nil, fmt.Errorf("item %s not found", id) + } + if r.ItemUpdatedCh != nil { + select { + case r.ItemUpdatedCh <- updated: + default: + } + } + return updated, nil +} + +// DeleteItem is the resolver for the deleteItem field. +// It removes the item from the per-resolver store and publishes the deleted +// entity on the itemUpdated subscription channel so tests can verify the +// downstream cache-invalidate pipeline. +func (r *mutationResolver) DeleteItem(ctx context.Context, id string) (*model.Item, error) { + deleted, ok := r.Store.delete(id) + if !ok { + return nil, fmt.Errorf("item %s not found", id) + } + if r.ItemUpdatedCh != nil { + select { + case r.ItemUpdatedCh <- deleted: + default: + } + } + return deleted, nil +} + +// CreateItem is the resolver for the createItem field. +// It persists the new item to the per-resolver store and publishes it on the +// itemCreated subscription channel so @cachePopulate subscription flows get a +// real event to populate the cache from. +func (r *mutationResolver) CreateItem(ctx context.Context, name string, category string) (*model.Item, error) { + created := r.Store.create(name, category) + if r.ItemCreatedCh != nil { + select { + case r.ItemCreatedCh <- created: + default: + } + } + return created, nil +} + +// DeleteProduct is the resolver for the deleteProduct field. +// Returns the matching Product without removing it from the in-memory data, so +// tests can verify @cacheInvalidate clears the cache without simulating durable +// deletion in the subgraph. +func (r *mutationResolver) DeleteProduct(ctx context.Context, id string, region string) (*model.Product, error) { + for _, p := range Products { + if p.ID == id && p.Region == region { + return p, nil + } + } + return nil, fmt.Errorf("product %s/%s not found", id, region) +} + +// Item is the resolver for the item field. +func (r *queryResolver) Item(ctx context.Context, id string) (*model.Item, error) { + return r.Store.find(id), nil +} + +// ItemByPid is the resolver for the itemByPid field. +func (r *queryResolver) ItemByPid(ctx context.Context, pid string) (*model.Item, error) { + return r.Store.find(pid), nil +} + +// Items is the resolver for the items field. +func (r *queryResolver) Items(ctx context.Context) ([]*model.Item, error) { + return r.Store.all(), nil +} + +// ItemsByIds is the resolver for the itemsByIds field. +func (r *queryResolver) ItemsByIds(ctx context.Context, ids []string) ([]*model.Item, error) { + return r.Store.byIDs(ids), nil +} + +// Product is the resolver for the product field. +func (r *queryResolver) Product(ctx context.Context, id string, region string) (*model.Product, error) { + for _, p := range Products { + if p.ID == id && p.Region == region { + return p, nil + } + } + return nil, nil +} + +// ProductBySku is the resolver for the productBySku field. +func (r *queryResolver) ProductBySku(ctx context.Context, sku string) (*model.Product, error) { + for _, p := range Products { + if p.Sku == sku { + return p, nil + } + } + return nil, nil +} + +// ProductByName is the resolver for the productByName field. +func (r *queryResolver) ProductByName(ctx context.Context, name string) (*model.Product, error) { + for _, p := range Products { + if p.Name == name { + return p, nil + } + } + return nil, nil +} + +// ProductByKey is the resolver for the productByKey field. +func (r *queryResolver) ProductByKey(ctx context.Context, key model.ProductKeyInput) (*model.Product, error) { + for _, p := range Products { + if p.ID == key.ID && p.Region == key.Region { + return p, nil + } + } + return nil, nil +} + +// Warehouse is the resolver for the warehouse field. +func (r *queryResolver) Warehouse(ctx context.Context, locationID string) (*model.Warehouse, error) { + for _, w := range Warehouses { + if w.Location.ID == locationID { + return w, nil + } + } + return nil, nil +} + +// WarehouseByInput is the resolver for the warehouseByInput field. +func (r *queryResolver) WarehouseByInput(ctx context.Context, input model.WarehouseLocationInput) (*model.Warehouse, error) { + for _, w := range Warehouses { + if w.Location.ID == input.Location.ID { + return w, nil + } + } + return nil, nil +} + +// ItemUpdated is the resolver for the itemUpdated field. +func (r *subscriptionResolver) ItemUpdated(ctx context.Context) (<-chan *model.Item, error) { + return r.ItemUpdatedCh, nil +} + +// ItemCreated is the resolver for the itemCreated field. +func (r *subscriptionResolver) ItemCreated(ctx context.Context) (<-chan *model.Item, error) { + return r.ItemCreatedCh, nil +} + +// Mutation returns generated.MutationResolver implementation. +func (r *Resolver) Mutation() generated.MutationResolver { return &mutationResolver{r} } + +// Query returns generated.QueryResolver implementation. +func (r *Resolver) Query() generated.QueryResolver { return &queryResolver{r} } + +// Subscription returns generated.SubscriptionResolver implementation. +func (r *Resolver) Subscription() generated.SubscriptionResolver { return &subscriptionResolver{r} } + +type mutationResolver struct{ *Resolver } +type queryResolver struct{ *Resolver } +type subscriptionResolver struct{ *Resolver } diff --git a/demo/pkg/subgraphs/cachetest/viewer/generate.go b/demo/pkg/subgraphs/cachetest/viewer/generate.go new file mode 100644 index 0000000000..f83456a6c1 --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/viewer/generate.go @@ -0,0 +1,3 @@ +//go:generate go run github.com/99designs/gqlgen generate + +package viewer diff --git a/demo/pkg/subgraphs/cachetest/viewer/gqlgen.yml b/demo/pkg/subgraphs/cachetest/viewer/gqlgen.yml new file mode 100644 index 0000000000..10a0850b0e --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/viewer/gqlgen.yml @@ -0,0 +1,39 @@ +schema: + - subgraph/*.graphqls + +exec: + filename: subgraph/generated/generated.go + package: generated + +federation: + filename: subgraph/generated/federation.go + package: generated + version: 2 + options: + explicit_requires: true + +model: + filename: subgraph/model/models_gen.go + package: model + +resolver: + layout: follow-schema + dir: subgraph + package: subgraph + +directives: + openfed__requestScoped: + skip_runtime: true + +models: + ID: + model: + - github.com/99designs/gqlgen/graphql.ID + - github.com/99designs/gqlgen/graphql.Int + - github.com/99designs/gqlgen/graphql.Int64 + - github.com/99designs/gqlgen/graphql.Int32 + Int: + model: + - github.com/99designs/gqlgen/graphql.Int + - github.com/99designs/gqlgen/graphql.Int64 + - github.com/99designs/gqlgen/graphql.Int32 diff --git a/demo/pkg/subgraphs/cachetest/viewer/subgraph/data.go b/demo/pkg/subgraphs/cachetest/viewer/subgraph/data.go new file mode 100644 index 0000000000..27102b67ad --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/viewer/subgraph/data.go @@ -0,0 +1,13 @@ +package subgraph + +import "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachetest/viewer/subgraph/model" + +// defaultViewer returns a fresh Viewer instance. Returning a new pointer on +// each call prevents accidental aliasing between concurrent resolvers. +func defaultViewer() *model.Viewer { + return &model.Viewer{ + ID: "v1", + Name: "Alice", + Email: "alice@example.com", + } +} diff --git a/demo/pkg/subgraphs/cachetest/viewer/subgraph/entity.resolvers.go b/demo/pkg/subgraphs/cachetest/viewer/subgraph/entity.resolvers.go new file mode 100644 index 0000000000..b253aff338 --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/viewer/subgraph/entity.resolvers.go @@ -0,0 +1,34 @@ +package subgraph + +// 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.76 + +import ( + "context" + + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachetest/viewer/subgraph/generated" + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachetest/viewer/subgraph/model" +) + +// FindPersonalizedByID is the resolver for the findPersonalizedByID field. +func (r *entityResolver) FindPersonalizedByID(ctx context.Context, id string) (*model.Personalized, error) { + // @interfaceObject resolver: returns currentViewer for any entity implementing Personalized. + // The concrete type (e.g. Article) is irrelevant — currentViewer comes from the request context. + return &model.Personalized{ + ID: id, + CurrentViewer: defaultViewer(), + }, nil +} + +// FindViewerByID is the resolver for the findViewerByID field. +func (r *entityResolver) FindViewerByID(ctx context.Context, id string) (*model.Viewer, error) { + v := defaultViewer() + v.ID = id + return v, nil +} + +// Entity returns generated.EntityResolver implementation. +func (r *Resolver) Entity() generated.EntityResolver { return &entityResolver{r} } + +type entityResolver struct{ *Resolver } diff --git a/demo/pkg/subgraphs/cachetest/viewer/subgraph/generated/federation.go b/demo/pkg/subgraphs/cachetest/viewer/subgraph/generated/federation.go new file mode 100644 index 0000000000..2556c88ac5 --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/viewer/subgraph/generated/federation.go @@ -0,0 +1,288 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package generated + +import ( + "context" + "errors" + "fmt" + "strings" + "sync" + + "github.com/99designs/gqlgen/plugin/federation/fedruntime" +) + +var ( + ErrUnknownType = errors.New("unknown type") + ErrTypeNotFound = errors.New("type not found") +) + +func (ec *executionContext) __resolve__service(ctx context.Context) (fedruntime.Service, error) { + if ec.DisableIntrospection { + return fedruntime.Service{}, errors.New("federated introspection disabled") + } + + var sdl []string + + for _, src := range sources { + if src.BuiltIn { + continue + } + sdl = append(sdl, src.Input) + } + + return fedruntime.Service{ + SDL: strings.Join(sdl, "\n"), + }, nil +} + +func (ec *executionContext) __resolve_entities(ctx context.Context, representations []map[string]any) []fedruntime.Entity { + list := make([]fedruntime.Entity, len(representations)) + + repsMap := ec.buildRepresentationGroups(ctx, representations) + + switch len(repsMap) { + case 0: + return list + case 1: + for typeName, reps := range repsMap { + ec.resolveEntityGroup(ctx, typeName, reps, list) + } + return list + default: + var g sync.WaitGroup + g.Add(len(repsMap)) + for typeName, reps := range repsMap { + go func(typeName string, reps []EntityWithIndex) { + ec.resolveEntityGroup(ctx, typeName, reps, list) + g.Done() + }(typeName, reps) + } + g.Wait() + return list + } +} + +type EntityWithIndex struct { + // The index in the original representation array + index int + entity EntityRepresentation +} + +// EntityRepresentation is the JSON representation of an entity sent by the Router +// used as the inputs for us to resolve. +// +// We make it a map because we know the top level JSON is always an object. +type EntityRepresentation map[string]any + +// We group entities by typename so that we can parallelize their resolution. +// This is particularly helpful when there are entity groups in multi mode. +func (ec *executionContext) buildRepresentationGroups( + ctx context.Context, + representations []map[string]any, +) map[string][]EntityWithIndex { + repsMap := make(map[string][]EntityWithIndex) + for i, rep := range representations { + typeName, ok := rep["__typename"].(string) + if !ok { + // If there is no __typename, we just skip the representation; + // we just won't be resolving these unknown types. + ec.Error(ctx, errors.New("__typename must be an existing string")) + continue + } + + repsMap[typeName] = append(repsMap[typeName], EntityWithIndex{ + index: i, + entity: rep, + }) + } + + return repsMap +} + +func (ec *executionContext) resolveEntityGroup( + ctx context.Context, + typeName string, + reps []EntityWithIndex, + list []fedruntime.Entity, +) { + if isMulti(typeName) { + err := ec.resolveManyEntities(ctx, typeName, reps, list) + if err != nil { + ec.Error(ctx, err) + } + } else { + // if there are multiple entities to resolve, parallelize (similar to + // graphql.FieldSet.Dispatch) + var e sync.WaitGroup + e.Add(len(reps)) + for i, rep := range reps { + i, rep := i, rep + go func(i int, rep EntityWithIndex) { + entity, err := ec.resolveEntity(ctx, typeName, rep.entity) + if err != nil { + ec.Error(ctx, err) + } else { + list[rep.index] = entity + } + e.Done() + }(i, rep) + } + e.Wait() + } +} + +func isMulti(typeName string) bool { + switch typeName { + default: + return false + } +} + +func (ec *executionContext) resolveEntity( + ctx context.Context, + typeName string, + rep EntityRepresentation, +) (e fedruntime.Entity, err error) { + // we need to do our own panic handling, because we may be called in a + // goroutine, where the usual panic handling can't catch us + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + } + }() + + switch typeName { + case "Personalized": + resolverName, err := entityResolverNameForPersonalized(ctx, rep) + if err != nil { + return nil, fmt.Errorf(`finding resolver for Entity "Personalized": %w`, err) + } + switch resolverName { + + case "findPersonalizedByID": + id0, err := ec.unmarshalNID2string(ctx, rep["id"]) + if err != nil { + return nil, fmt.Errorf(`unmarshalling param 0 for findPersonalizedByID(): %w`, err) + } + entity, err := ec.resolvers.Entity().FindPersonalizedByID(ctx, id0) + if err != nil { + return nil, fmt.Errorf(`resolving Entity "Personalized": %w`, err) + } + + return entity, nil + } + case "Viewer": + resolverName, err := entityResolverNameForViewer(ctx, rep) + if err != nil { + return nil, fmt.Errorf(`finding resolver for Entity "Viewer": %w`, err) + } + switch resolverName { + + case "findViewerByID": + id0, err := ec.unmarshalNID2string(ctx, rep["id"]) + if err != nil { + return nil, fmt.Errorf(`unmarshalling param 0 for findViewerByID(): %w`, err) + } + entity, err := ec.resolvers.Entity().FindViewerByID(ctx, id0) + if err != nil { + return nil, fmt.Errorf(`resolving Entity "Viewer": %w`, err) + } + + return entity, nil + } + + } + return nil, fmt.Errorf("%w: %s", ErrUnknownType, typeName) +} + +func (ec *executionContext) resolveManyEntities( + ctx context.Context, + typeName string, + reps []EntityWithIndex, + list []fedruntime.Entity, +) (err error) { + // we need to do our own panic handling, because we may be called in a + // goroutine, where the usual panic handling can't catch us + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + } + }() + + switch typeName { + + default: + return errors.New("unknown type: " + typeName) + } +} + +func entityResolverNameForPersonalized(ctx context.Context, rep EntityRepresentation) (string, error) { + // we collect errors because a later entity resolver may work fine + // when an entity has multiple keys + entityResolverErrs := []error{} + for { + var ( + m EntityRepresentation + val any + ok bool + ) + _ = val + // if all of the KeyFields values for this resolver are null, + // we shouldn't use use it + allNull := true + m = rep + val, ok = m["id"] + if !ok { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to missing Key Field \"id\" for Personalized", ErrTypeNotFound)) + break + } + if allNull { + allNull = val == nil + } + if allNull { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to all null value KeyFields for Personalized", ErrTypeNotFound)) + break + } + return "findPersonalizedByID", nil + } + return "", fmt.Errorf("%w for Personalized due to %v", ErrTypeNotFound, + errors.Join(entityResolverErrs...).Error()) +} + +func entityResolverNameForViewer(ctx context.Context, rep EntityRepresentation) (string, error) { + // we collect errors because a later entity resolver may work fine + // when an entity has multiple keys + entityResolverErrs := []error{} + for { + var ( + m EntityRepresentation + val any + ok bool + ) + _ = val + // if all of the KeyFields values for this resolver are null, + // we shouldn't use use it + allNull := true + m = rep + val, ok = m["id"] + if !ok { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to missing Key Field \"id\" for Viewer", ErrTypeNotFound)) + break + } + if allNull { + allNull = val == nil + } + if allNull { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to all null value KeyFields for Viewer", ErrTypeNotFound)) + break + } + return "findViewerByID", nil + } + return "", fmt.Errorf("%w for Viewer due to %v", ErrTypeNotFound, + errors.Join(entityResolverErrs...).Error()) +} diff --git a/demo/pkg/subgraphs/cachetest/viewer/subgraph/generated/generated.go b/demo/pkg/subgraphs/cachetest/viewer/subgraph/generated/generated.go new file mode 100644 index 0000000000..28136c0652 --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/viewer/subgraph/generated/generated.go @@ -0,0 +1,4837 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package generated + +import ( + "bytes" + "context" + "errors" + "fmt" + "strconv" + "sync" + "sync/atomic" + + "github.com/99designs/gqlgen/graphql" + "github.com/99designs/gqlgen/graphql/introspection" + "github.com/99designs/gqlgen/plugin/federation/fedruntime" + gqlparser "github.com/vektah/gqlparser/v2" + "github.com/vektah/gqlparser/v2/ast" + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachetest/viewer/subgraph/model" +) + +// region ************************** generated!.gotpl ************************** + +// NewExecutableSchema creates an ExecutableSchema from the ResolverRoot interface. +func NewExecutableSchema(cfg Config) graphql.ExecutableSchema { + return &executableSchema{ + schema: cfg.Schema, + resolvers: cfg.Resolvers, + directives: cfg.Directives, + complexity: cfg.Complexity, + } +} + +type Config struct { + Schema *ast.Schema + Resolvers ResolverRoot + Directives DirectiveRoot + Complexity ComplexityRoot +} + +type ResolverRoot interface { + Entity() EntityResolver + Query() QueryResolver +} + +type DirectiveRoot struct { +} + +type ComplexityRoot struct { + Entity struct { + FindPersonalizedByID func(childComplexity int, id string) int + FindViewerByID func(childComplexity int, id string) int + } + + Personalized struct { + CurrentViewer func(childComplexity int) int + ID func(childComplexity int) int + } + + Query struct { + CurrentViewer func(childComplexity int) int + __resolve__service func(childComplexity int) int + __resolve_entities func(childComplexity int, representations []map[string]any) int + } + + Viewer struct { + Email func(childComplexity int) int + ID func(childComplexity int) int + Name func(childComplexity int) int + } + + _Service struct { + SDL func(childComplexity int) int + } +} + +type EntityResolver interface { + FindPersonalizedByID(ctx context.Context, id string) (*model.Personalized, error) + FindViewerByID(ctx context.Context, id string) (*model.Viewer, error) +} +type QueryResolver interface { + CurrentViewer(ctx context.Context) (*model.Viewer, error) +} + +type executableSchema struct { + schema *ast.Schema + resolvers ResolverRoot + directives DirectiveRoot + complexity ComplexityRoot +} + +func (e *executableSchema) Schema() *ast.Schema { + if e.schema != nil { + return e.schema + } + return parsedSchema +} + +func (e *executableSchema) Complexity(ctx context.Context, typeName, field string, childComplexity int, rawArgs map[string]any) (int, bool) { + ec := executionContext{nil, e, 0, 0, nil} + _ = ec + switch typeName + "." + field { + + case "Entity.findPersonalizedByID": + if e.complexity.Entity.FindPersonalizedByID == nil { + break + } + + args, err := ec.field_Entity_findPersonalizedByID_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Entity.FindPersonalizedByID(childComplexity, args["id"].(string)), true + + case "Entity.findViewerByID": + if e.complexity.Entity.FindViewerByID == nil { + break + } + + args, err := ec.field_Entity_findViewerByID_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Entity.FindViewerByID(childComplexity, args["id"].(string)), true + + case "Personalized.currentViewer": + if e.complexity.Personalized.CurrentViewer == nil { + break + } + + return e.complexity.Personalized.CurrentViewer(childComplexity), true + + case "Personalized.id": + if e.complexity.Personalized.ID == nil { + break + } + + return e.complexity.Personalized.ID(childComplexity), true + + case "Query.currentViewer": + if e.complexity.Query.CurrentViewer == nil { + break + } + + return e.complexity.Query.CurrentViewer(childComplexity), true + + case "Query._service": + if e.complexity.Query.__resolve__service == nil { + break + } + + return e.complexity.Query.__resolve__service(childComplexity), true + + case "Query._entities": + if e.complexity.Query.__resolve_entities == nil { + break + } + + args, err := ec.field_Query__entities_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.__resolve_entities(childComplexity, args["representations"].([]map[string]any)), true + + case "Viewer.email": + if e.complexity.Viewer.Email == nil { + break + } + + return e.complexity.Viewer.Email(childComplexity), true + + case "Viewer.id": + if e.complexity.Viewer.ID == nil { + break + } + + return e.complexity.Viewer.ID(childComplexity), true + + case "Viewer.name": + if e.complexity.Viewer.Name == nil { + break + } + + return e.complexity.Viewer.Name(childComplexity), true + + case "_Service.sdl": + if e.complexity._Service.SDL == nil { + break + } + + return e.complexity._Service.SDL(childComplexity), true + + } + return 0, false +} + +func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { + opCtx := graphql.GetOperationContext(ctx) + ec := executionContext{opCtx, e, 0, 0, make(chan graphql.DeferredResult)} + inputUnmarshalMap := graphql.BuildUnmarshalerMap() + first := true + + switch opCtx.Operation.Operation { + case ast.Query: + return func(ctx context.Context) *graphql.Response { + var response graphql.Response + var data graphql.Marshaler + if first { + first = false + ctx = graphql.WithUnmarshalerMap(ctx, inputUnmarshalMap) + data = ec._Query(ctx, opCtx.Operation.SelectionSet) + } else { + if atomic.LoadInt32(&ec.pendingDeferred) > 0 { + result := <-ec.deferredResults + atomic.AddInt32(&ec.pendingDeferred, -1) + data = result.Result + response.Path = result.Path + response.Label = result.Label + response.Errors = result.Errors + } else { + return nil + } + } + var buf bytes.Buffer + data.MarshalGQL(&buf) + response.Data = buf.Bytes() + if atomic.LoadInt32(&ec.deferred) > 0 { + hasNext := atomic.LoadInt32(&ec.pendingDeferred) > 0 + response.HasNext = &hasNext + } + + return &response + } + + default: + return graphql.OneShot(graphql.ErrorResponse(ctx, "unsupported GraphQL operation")) + } +} + +type executionContext struct { + *graphql.OperationContext + *executableSchema + deferred int32 + pendingDeferred int32 + deferredResults chan graphql.DeferredResult +} + +func (ec *executionContext) processDeferredGroup(dg graphql.DeferredGroup) { + atomic.AddInt32(&ec.pendingDeferred, 1) + go func() { + ctx := graphql.WithFreshResponseContext(dg.Context) + dg.FieldSet.Dispatch(ctx) + ds := graphql.DeferredResult{ + Path: dg.Path, + Label: dg.Label, + Result: dg.FieldSet, + Errors: graphql.GetErrors(ctx), + } + // null fields should bubble up + if dg.FieldSet.Invalids > 0 { + ds.Result = graphql.Null + } + ec.deferredResults <- ds + }() +} + +func (ec *executionContext) introspectSchema() (*introspection.Schema, error) { + if ec.DisableIntrospection { + return nil, errors.New("introspection disabled") + } + return introspection.WrapSchema(ec.Schema()), nil +} + +func (ec *executionContext) introspectType(name string) (*introspection.Type, error) { + if ec.DisableIntrospection { + return nil, errors.New("introspection disabled") + } + return introspection.WrapTypeFromDef(ec.Schema(), ec.Schema().Types[name]), nil +} + +var sources = []*ast.Source{ + {Name: "../schema.graphqls", Input: `extend schema + @link( + url: "https://specs.apollo.dev/federation/v2.5" + import: ["@key", "@interfaceObject", "@inaccessible"] + ) + +directive @openfed__requestScoped(key: String!) on FIELD_DEFINITION + +type Viewer @key(fields: "id") { + id: ID! + name: String! + email: String! +} + +# Symmetric @openfed__requestScoped: Query.currentViewer and Personalized.currentViewer +# share key "currentViewer" so they read/write the same L1 coordinate cache entry. +type Personalized @key(fields: "id") @interfaceObject { + id: ID! + currentViewer: Viewer @inaccessible @openfed__requestScoped(key: "currentViewer") +} + +type Query { + currentViewer: Viewer @openfed__requestScoped(key: "currentViewer") +} +`, BuiltIn: false}, + {Name: "../../federation/directives.graphql", Input: ` + directive @authenticated on FIELD_DEFINITION | OBJECT | INTERFACE | SCALAR | ENUM + directive @composeDirective(name: String!) repeatable on SCHEMA + directive @extends on OBJECT | INTERFACE + directive @external on OBJECT | FIELD_DEFINITION + directive @key(fields: FieldSet!, resolvable: Boolean = true) repeatable on OBJECT | INTERFACE + directive @inaccessible on + | ARGUMENT_DEFINITION + | ENUM + | ENUM_VALUE + | FIELD_DEFINITION + | INPUT_FIELD_DEFINITION + | INPUT_OBJECT + | INTERFACE + | OBJECT + | SCALAR + | UNION + directive @interfaceObject on OBJECT + directive @link(import: [String!], url: String!) repeatable on SCHEMA + directive @override(from: String!, label: String) on FIELD_DEFINITION + directive @policy(policies: [[federation__Policy!]!]!) on + | FIELD_DEFINITION + | OBJECT + | INTERFACE + | SCALAR + | ENUM + directive @provides(fields: FieldSet!) on FIELD_DEFINITION + directive @requires(fields: FieldSet!) on FIELD_DEFINITION + directive @requiresScopes(scopes: [[federation__Scope!]!]!) on + | FIELD_DEFINITION + | OBJECT + | INTERFACE + | SCALAR + | ENUM + directive @shareable repeatable on FIELD_DEFINITION | OBJECT + directive @tag(name: String!) repeatable on + | ARGUMENT_DEFINITION + | ENUM + | ENUM_VALUE + | FIELD_DEFINITION + | INPUT_FIELD_DEFINITION + | INPUT_OBJECT + | INTERFACE + | OBJECT + | SCALAR + | UNION + scalar _Any + scalar FieldSet + scalar federation__Policy + scalar federation__Scope +`, BuiltIn: true}, + {Name: "../../federation/entity.graphql", Input: ` +# a union of all types that use the @key directive +union _Entity = Personalized | Viewer + +# fake type to build resolver interfaces for users to implement +type Entity { + findPersonalizedByID(id: ID!,): Personalized! + findViewerByID(id: ID!,): Viewer! +} + +type _Service { + sdl: String +} + +extend type Query { + _entities(representations: [_Any!]!): [_Entity]! + _service: _Service! +} +`, BuiltIn: true}, +} +var parsedSchema = gqlparser.MustLoadSchema(sources...) + +// endregion ************************** generated!.gotpl ************************** + +// region ***************************** args.gotpl ***************************** + +func (ec *executionContext) field_Entity_findPersonalizedByID_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Entity_findPersonalizedByID_argsID(ctx, rawArgs) + if err != nil { + return nil, err + } + args["id"] = arg0 + return args, nil +} +func (ec *executionContext) field_Entity_findPersonalizedByID_argsID( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["id"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + if tmp, ok := rawArgs["id"]; ok { + return ec.unmarshalNID2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Entity_findViewerByID_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Entity_findViewerByID_argsID(ctx, rawArgs) + if err != nil { + return nil, err + } + args["id"] = arg0 + return args, nil +} +func (ec *executionContext) field_Entity_findViewerByID_argsID( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["id"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + if tmp, ok := rawArgs["id"]; ok { + return ec.unmarshalNID2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Query___type_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Query___type_argsName(ctx, rawArgs) + if err != nil { + return nil, err + } + args["name"] = arg0 + return args, nil +} +func (ec *executionContext) field_Query___type_argsName( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["name"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("name")) + if tmp, ok := rawArgs["name"]; ok { + return ec.unmarshalNString2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Query__entities_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Query__entities_argsRepresentations(ctx, rawArgs) + if err != nil { + return nil, err + } + args["representations"] = arg0 + return args, nil +} +func (ec *executionContext) field_Query__entities_argsRepresentations( + ctx context.Context, + rawArgs map[string]any, +) ([]map[string]any, error) { + if _, ok := rawArgs["representations"]; !ok { + var zeroVal []map[string]any + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("representations")) + if tmp, ok := rawArgs["representations"]; ok { + return ec.unmarshalN_Any2ᚕmapᚄ(ctx, tmp) + } + + var zeroVal []map[string]any + return zeroVal, nil +} + +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 := ec.field___Directive_args_argsIncludeDeprecated(ctx, rawArgs) + if err != nil { + return nil, err + } + args["includeDeprecated"] = arg0 + return args, nil +} +func (ec *executionContext) field___Directive_args_argsIncludeDeprecated( + ctx context.Context, + rawArgs map[string]any, +) (*bool, error) { + if _, ok := rawArgs["includeDeprecated"]; !ok { + var zeroVal *bool + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("includeDeprecated")) + if tmp, ok := rawArgs["includeDeprecated"]; ok { + return ec.unmarshalOBoolean2ᚖbool(ctx, tmp) + } + + var zeroVal *bool + return zeroVal, nil +} + +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 := ec.field___Field_args_argsIncludeDeprecated(ctx, rawArgs) + if err != nil { + return nil, err + } + args["includeDeprecated"] = arg0 + return args, nil +} +func (ec *executionContext) field___Field_args_argsIncludeDeprecated( + ctx context.Context, + rawArgs map[string]any, +) (*bool, error) { + if _, ok := rawArgs["includeDeprecated"]; !ok { + var zeroVal *bool + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("includeDeprecated")) + if tmp, ok := rawArgs["includeDeprecated"]; ok { + return ec.unmarshalOBoolean2ᚖbool(ctx, tmp) + } + + var zeroVal *bool + return zeroVal, nil +} + +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 := ec.field___Type_enumValues_argsIncludeDeprecated(ctx, rawArgs) + if err != nil { + return nil, err + } + args["includeDeprecated"] = arg0 + return args, nil +} +func (ec *executionContext) field___Type_enumValues_argsIncludeDeprecated( + ctx context.Context, + rawArgs map[string]any, +) (bool, error) { + if _, ok := rawArgs["includeDeprecated"]; !ok { + var zeroVal bool + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("includeDeprecated")) + if tmp, ok := rawArgs["includeDeprecated"]; ok { + return ec.unmarshalOBoolean2bool(ctx, tmp) + } + + var zeroVal bool + return zeroVal, nil +} + +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 := ec.field___Type_fields_argsIncludeDeprecated(ctx, rawArgs) + if err != nil { + return nil, err + } + args["includeDeprecated"] = arg0 + return args, nil +} +func (ec *executionContext) field___Type_fields_argsIncludeDeprecated( + ctx context.Context, + rawArgs map[string]any, +) (bool, error) { + if _, ok := rawArgs["includeDeprecated"]; !ok { + var zeroVal bool + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("includeDeprecated")) + if tmp, ok := rawArgs["includeDeprecated"]; ok { + return ec.unmarshalOBoolean2bool(ctx, tmp) + } + + var zeroVal bool + return zeroVal, nil +} + +// endregion ***************************** args.gotpl ***************************** + +// region ************************** directives.gotpl ************************** + +// endregion ************************** directives.gotpl ************************** + +// region **************************** field.gotpl ***************************** + +func (ec *executionContext) _Entity_findPersonalizedByID(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Entity_findPersonalizedByID(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Entity().FindPersonalizedByID(rctx, fc.Args["id"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*model.Personalized) + fc.Result = res + return ec.marshalNPersonalized2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋviewerᚋsubgraphᚋmodelᚐPersonalized(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Entity_findPersonalizedByID(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Entity", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Personalized_id(ctx, field) + case "currentViewer": + return ec.fieldContext_Personalized_currentViewer(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Personalized", field.Name) + }, + } + 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_Entity_findPersonalizedByID_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Entity_findViewerByID(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Entity_findViewerByID(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Entity().FindViewerByID(rctx, fc.Args["id"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*model.Viewer) + fc.Result = res + return ec.marshalNViewer2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋviewerᚋsubgraphᚋmodelᚐViewer(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Entity_findViewerByID(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Entity", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Viewer_id(ctx, field) + case "name": + return ec.fieldContext_Viewer_name(ctx, field) + case "email": + return ec.fieldContext_Viewer_email(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Viewer", field.Name) + }, + } + 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_Entity_findViewerByID_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Personalized_id(ctx context.Context, field graphql.CollectedField, obj *model.Personalized) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Personalized_id(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Personalized_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Personalized", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Personalized_currentViewer(ctx context.Context, field graphql.CollectedField, obj *model.Personalized) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Personalized_currentViewer(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.CurrentViewer, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*model.Viewer) + fc.Result = res + return ec.marshalOViewer2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋviewerᚋsubgraphᚋmodelᚐViewer(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Personalized_currentViewer(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Personalized", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Viewer_id(ctx, field) + case "name": + return ec.fieldContext_Viewer_name(ctx, field) + case "email": + return ec.fieldContext_Viewer_email(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Viewer", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Query_currentViewer(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query_currentViewer(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().CurrentViewer(rctx) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*model.Viewer) + fc.Result = res + return ec.marshalOViewer2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋviewerᚋsubgraphᚋmodelᚐViewer(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query_currentViewer(_ 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) { + switch field.Name { + case "id": + return ec.fieldContext_Viewer_id(ctx, field) + case "name": + return ec.fieldContext_Viewer_name(ctx, field) + case "email": + return ec.fieldContext_Viewer_email(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Viewer", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Query__entities(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query__entities(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.__resolve_entities(ctx, fc.Args["representations"].([]map[string]any)), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]fedruntime.Entity) + fc.Result = res + return ec.marshalN_Entity2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐEntity(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query__entities(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type _Entity does not have child fields") + }, + } + 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__entities_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query__service(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query__service(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.__resolve__service(ctx) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(fedruntime.Service) + fc.Result = res + return ec.marshalN_Service2githubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐService(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query__service(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "sdl": + return ec.fieldContext__Service_sdl(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type _Service", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Query___type(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query___type(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.introspectType(fc.Args["name"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query___type(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + 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___type_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query___schema(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query___schema(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.introspectSchema() + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Schema) + fc.Result = res + return ec.marshalO__Schema2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐSchema(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query___schema(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "description": + return ec.fieldContext___Schema_description(ctx, field) + case "types": + return ec.fieldContext___Schema_types(ctx, field) + case "queryType": + return ec.fieldContext___Schema_queryType(ctx, field) + case "mutationType": + return ec.fieldContext___Schema_mutationType(ctx, field) + case "subscriptionType": + return ec.fieldContext___Schema_subscriptionType(ctx, field) + case "directives": + return ec.fieldContext___Schema_directives(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Schema", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Viewer_id(ctx context.Context, field graphql.CollectedField, obj *model.Viewer) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Viewer_id(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Viewer_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Viewer", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Viewer_name(ctx context.Context, field graphql.CollectedField, obj *model.Viewer) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Viewer_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Viewer_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Viewer", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Viewer_email(ctx context.Context, field graphql.CollectedField, obj *model.Viewer) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Viewer_email(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Email, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Viewer_email(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Viewer", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) __Service_sdl(ctx context.Context, field graphql.CollectedField, obj *fedruntime.Service) (ret graphql.Marshaler) { + fc, err := ec.fieldContext__Service_sdl(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.SDL, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalOString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext__Service_sdl(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "_Service", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Directive_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Directive_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Directive_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Directive_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_isRepeatable(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Directive_isRepeatable(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsRepeatable, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Directive_isRepeatable(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_locations(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Directive_locations(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Locations, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]string) + fc.Result = res + return ec.marshalN__DirectiveLocation2ᚕstringᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Directive_locations(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type __DirectiveLocation does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_args(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Directive_args(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Args, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]introspection.InputValue) + fc.Result = res + return ec.marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Directive_args(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___InputValue_name(ctx, field) + case "description": + return ec.fieldContext___InputValue_description(ctx, field) + case "type": + return ec.fieldContext___InputValue_type(ctx, field) + case "defaultValue": + return ec.fieldContext___InputValue_defaultValue(ctx, field) + case "isDeprecated": + return ec.fieldContext___InputValue_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___InputValue_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __InputValue", field.Name) + }, + } + 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___Directive_args_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) ___EnumValue_name(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___EnumValue_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___EnumValue_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__EnumValue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___EnumValue_description(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___EnumValue_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___EnumValue_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__EnumValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___EnumValue_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___EnumValue_isDeprecated(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsDeprecated(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___EnumValue_isDeprecated(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__EnumValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___EnumValue_deprecationReason(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___EnumValue_deprecationReason(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.DeprecationReason(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___EnumValue_deprecationReason(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__EnumValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_args(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_args(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Args, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]introspection.InputValue) + fc.Result = res + return ec.marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_args(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___InputValue_name(ctx, field) + case "description": + return ec.fieldContext___InputValue_description(ctx, field) + case "type": + return ec.fieldContext___InputValue_type(ctx, field) + case "defaultValue": + return ec.fieldContext___InputValue_defaultValue(ctx, field) + case "isDeprecated": + return ec.fieldContext___InputValue_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___InputValue_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __InputValue", field.Name) + }, + } + 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___Field_args_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) ___Field_type(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_type(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Type, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_type(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_isDeprecated(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsDeprecated(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_isDeprecated(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_deprecationReason(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_deprecationReason(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.DeprecationReason(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_deprecationReason(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_name(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_description(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_type(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_type(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Type, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_type(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_defaultValue(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_defaultValue(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.DefaultValue, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_defaultValue(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_isDeprecated(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsDeprecated(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_isDeprecated(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_deprecationReason(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_deprecationReason(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.DeprecationReason(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_deprecationReason(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_types(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_types(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Types(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]introspection.Type) + fc.Result = res + return ec.marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_types(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_queryType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_queryType(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.QueryType(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_queryType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_mutationType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_mutationType(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.MutationType(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_mutationType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_subscriptionType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_subscriptionType(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.SubscriptionType(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_subscriptionType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_directives(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_directives(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Directives(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]introspection.Directive) + fc.Result = res + return ec.marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirectiveᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_directives(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___Directive_name(ctx, field) + case "description": + return ec.fieldContext___Directive_description(ctx, field) + case "isRepeatable": + return ec.fieldContext___Directive_isRepeatable(ctx, field) + case "locations": + return ec.fieldContext___Directive_locations(ctx, field) + case "args": + return ec.fieldContext___Directive_args(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Directive", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_kind(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_kind(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Kind(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalN__TypeKind2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_kind(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type __TypeKind does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_specifiedByURL(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_specifiedByURL(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.SpecifiedByURL(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_specifiedByURL(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_fields(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_fields(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Fields(fc.Args["includeDeprecated"].(bool)), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.Field) + fc.Result = res + return ec.marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐFieldᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_fields(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___Field_name(ctx, field) + case "description": + return ec.fieldContext___Field_description(ctx, field) + case "args": + return ec.fieldContext___Field_args(ctx, field) + case "type": + return ec.fieldContext___Field_type(ctx, field) + case "isDeprecated": + return ec.fieldContext___Field_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___Field_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Field", field.Name) + }, + } + 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_fields_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) ___Type_interfaces(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_interfaces(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Interfaces(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_interfaces(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_possibleTypes(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_possibleTypes(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.PossibleTypes(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_possibleTypes(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_enumValues(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_enumValues(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.EnumValues(fc.Args["includeDeprecated"].(bool)), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.EnumValue) + fc.Result = res + return ec.marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValueᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_enumValues(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___EnumValue_name(ctx, field) + case "description": + return ec.fieldContext___EnumValue_description(ctx, field) + case "isDeprecated": + return ec.fieldContext___EnumValue_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___EnumValue_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __EnumValue", field.Name) + }, + } + 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_enumValues_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) ___Type_inputFields(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_inputFields(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.InputFields(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.InputValue) + fc.Result = res + return ec.marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_inputFields(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___InputValue_name(ctx, field) + case "description": + return ec.fieldContext___InputValue_description(ctx, field) + case "type": + return ec.fieldContext___InputValue_type(ctx, field) + case "defaultValue": + return ec.fieldContext___InputValue_defaultValue(ctx, field) + case "isDeprecated": + return ec.fieldContext___InputValue_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___InputValue_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __InputValue", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_ofType(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_ofType(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.OfType(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_ofType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_isOneOf(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_isOneOf(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsOneOf(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalOBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_isOneOf(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +// endregion **************************** field.gotpl ***************************** + +// region **************************** input.gotpl ***************************** + +// endregion **************************** input.gotpl ***************************** + +// region ************************** interface.gotpl *************************** + +func (ec *executionContext) __Entity(ctx context.Context, sel ast.SelectionSet, obj fedruntime.Entity) graphql.Marshaler { + switch obj := (obj).(type) { + case nil: + return graphql.Null + case model.Viewer: + return ec._Viewer(ctx, sel, &obj) + case *model.Viewer: + if obj == nil { + return graphql.Null + } + return ec._Viewer(ctx, sel, obj) + case model.Personalized: + return ec._Personalized(ctx, sel, &obj) + case *model.Personalized: + if obj == nil { + return graphql.Null + } + return ec._Personalized(ctx, sel, obj) + default: + panic(fmt.Errorf("unexpected type %T", obj)) + } +} + +// endregion ************************** interface.gotpl *************************** + +// region **************************** object.gotpl **************************** + +var entityImplementors = []string{"Entity"} + +func (ec *executionContext) _Entity(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, entityImplementors) + ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ + Object: "Entity", + }) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ + Object: field.Name, + Field: field, + }) + + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Entity") + case "findPersonalizedByID": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Entity_findPersonalizedByID(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "findViewerByID": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Entity_findViewerByID(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var personalizedImplementors = []string{"Personalized", "_Entity"} + +func (ec *executionContext) _Personalized(ctx context.Context, sel ast.SelectionSet, obj *model.Personalized) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, personalizedImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Personalized") + case "id": + out.Values[i] = ec._Personalized_id(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "currentViewer": + out.Values[i] = ec._Personalized_currentViewer(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var queryImplementors = []string{"Query"} + +func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, queryImplementors) + ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ + Object: "Query", + }) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ + Object: field.Name, + Field: field, + }) + + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Query") + case "currentViewer": + field := field + + innerFunc := func(ctx context.Context, _ *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_currentViewer(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "_entities": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query__entities(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "_service": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query__service(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "__type": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Query___type(ctx, field) + }) + case "__schema": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Query___schema(ctx, field) + }) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var viewerImplementors = []string{"Viewer", "_Entity"} + +func (ec *executionContext) _Viewer(ctx context.Context, sel ast.SelectionSet, obj *model.Viewer) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, viewerImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Viewer") + case "id": + out.Values[i] = ec._Viewer_id(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "name": + out.Values[i] = ec._Viewer_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "email": + out.Values[i] = ec._Viewer_email(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 + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var _ServiceImplementors = []string{"_Service"} + +func (ec *executionContext) __Service(ctx context.Context, sel ast.SelectionSet, obj *fedruntime.Service) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, _ServiceImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("_Service") + case "sdl": + out.Values[i] = ec.__Service_sdl(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __DirectiveImplementors = []string{"__Directive"} + +func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionSet, obj *introspection.Directive) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __DirectiveImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__Directive") + case "name": + out.Values[i] = ec.___Directive_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "description": + out.Values[i] = ec.___Directive_description(ctx, field, obj) + case "isRepeatable": + out.Values[i] = ec.___Directive_isRepeatable(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "locations": + out.Values[i] = ec.___Directive_locations(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "args": + out.Values[i] = ec.___Directive_args(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 + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __EnumValueImplementors = []string{"__EnumValue"} + +func (ec *executionContext) ___EnumValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.EnumValue) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __EnumValueImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__EnumValue") + case "name": + out.Values[i] = ec.___EnumValue_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "description": + out.Values[i] = ec.___EnumValue_description(ctx, field, obj) + case "isDeprecated": + out.Values[i] = ec.___EnumValue_isDeprecated(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "deprecationReason": + out.Values[i] = ec.___EnumValue_deprecationReason(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __FieldImplementors = []string{"__Field"} + +func (ec *executionContext) ___Field(ctx context.Context, sel ast.SelectionSet, obj *introspection.Field) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __FieldImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__Field") + case "name": + out.Values[i] = ec.___Field_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "description": + out.Values[i] = ec.___Field_description(ctx, field, obj) + case "args": + out.Values[i] = ec.___Field_args(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "type": + out.Values[i] = ec.___Field_type(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "isDeprecated": + out.Values[i] = ec.___Field_isDeprecated(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "deprecationReason": + out.Values[i] = ec.___Field_deprecationReason(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __InputValueImplementors = []string{"__InputValue"} + +func (ec *executionContext) ___InputValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.InputValue) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __InputValueImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__InputValue") + case "name": + out.Values[i] = ec.___InputValue_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "description": + out.Values[i] = ec.___InputValue_description(ctx, field, obj) + case "type": + out.Values[i] = ec.___InputValue_type(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "defaultValue": + out.Values[i] = ec.___InputValue_defaultValue(ctx, field, obj) + case "isDeprecated": + out.Values[i] = ec.___InputValue_isDeprecated(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "deprecationReason": + out.Values[i] = ec.___InputValue_deprecationReason(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __SchemaImplementors = []string{"__Schema"} + +func (ec *executionContext) ___Schema(ctx context.Context, sel ast.SelectionSet, obj *introspection.Schema) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __SchemaImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__Schema") + case "description": + out.Values[i] = ec.___Schema_description(ctx, field, obj) + case "types": + out.Values[i] = ec.___Schema_types(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "queryType": + out.Values[i] = ec.___Schema_queryType(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "mutationType": + out.Values[i] = ec.___Schema_mutationType(ctx, field, obj) + case "subscriptionType": + out.Values[i] = ec.___Schema_subscriptionType(ctx, field, obj) + case "directives": + out.Values[i] = ec.___Schema_directives(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 + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __TypeImplementors = []string{"__Type"} + +func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, obj *introspection.Type) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __TypeImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__Type") + case "kind": + out.Values[i] = ec.___Type_kind(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "name": + out.Values[i] = ec.___Type_name(ctx, field, obj) + case "description": + out.Values[i] = ec.___Type_description(ctx, field, obj) + case "specifiedByURL": + out.Values[i] = ec.___Type_specifiedByURL(ctx, field, obj) + case "fields": + out.Values[i] = ec.___Type_fields(ctx, field, obj) + case "interfaces": + out.Values[i] = ec.___Type_interfaces(ctx, field, obj) + case "possibleTypes": + out.Values[i] = ec.___Type_possibleTypes(ctx, field, obj) + case "enumValues": + out.Values[i] = ec.___Type_enumValues(ctx, field, obj) + case "inputFields": + out.Values[i] = ec.___Type_inputFields(ctx, field, obj) + case "ofType": + out.Values[i] = ec.___Type_ofType(ctx, field, obj) + case "isOneOf": + out.Values[i] = ec.___Type_isOneOf(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +// endregion **************************** object.gotpl **************************** + +// region ***************************** type.gotpl ***************************** + +func (ec *executionContext) unmarshalNBoolean2bool(ctx context.Context, v any) (bool, error) { + res, err := graphql.UnmarshalBoolean(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNBoolean2bool(ctx context.Context, sel ast.SelectionSet, v bool) graphql.Marshaler { + _ = sel + res := graphql.MarshalBoolean(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNFieldSet2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNFieldSet2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNID2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalID(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNID2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalID(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) marshalNPersonalized2githubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋviewerᚋsubgraphᚋmodelᚐPersonalized(ctx context.Context, sel ast.SelectionSet, v model.Personalized) graphql.Marshaler { + return ec._Personalized(ctx, sel, &v) +} + +func (ec *executionContext) marshalNPersonalized2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋviewerᚋsubgraphᚋmodelᚐPersonalized(ctx context.Context, sel ast.SelectionSet, v *model.Personalized) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._Personalized(ctx, sel, v) +} + +func (ec *executionContext) unmarshalNString2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNString2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) marshalNViewer2githubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋviewerᚋsubgraphᚋmodelᚐViewer(ctx context.Context, sel ast.SelectionSet, v model.Viewer) graphql.Marshaler { + return ec._Viewer(ctx, sel, &v) +} + +func (ec *executionContext) marshalNViewer2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋviewerᚋsubgraphᚋmodelᚐViewer(ctx context.Context, sel ast.SelectionSet, v *model.Viewer) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._Viewer(ctx, sel, v) +} + +func (ec *executionContext) unmarshalN_Any2map(ctx context.Context, v any) (map[string]any, error) { + res, err := graphql.UnmarshalMap(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalN_Any2map(ctx context.Context, sel ast.SelectionSet, v map[string]any) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + _ = sel + res := graphql.MarshalMap(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalN_Any2ᚕmapᚄ(ctx context.Context, v any) ([]map[string]any, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([]map[string]any, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalN_Any2map(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalN_Any2ᚕmapᚄ(ctx context.Context, sel ast.SelectionSet, v []map[string]any) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalN_Any2map(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalN_Entity2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐEntity(ctx context.Context, sel ast.SelectionSet, v []fedruntime.Entity) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalO_Entity2githubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐEntity(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + return ret +} + +func (ec *executionContext) marshalN_Service2githubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐService(ctx context.Context, sel ast.SelectionSet, v fedruntime.Service) graphql.Marshaler { + return ec.__Service(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__Directive2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirective(ctx context.Context, sel ast.SelectionSet, v introspection.Directive) graphql.Marshaler { + return ec.___Directive(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirectiveᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.Directive) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__Directive2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirective(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalN__DirectiveLocation2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalN__DirectiveLocation2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalN__DirectiveLocation2ᚕstringᚄ(ctx context.Context, v any) ([]string, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalN__DirectiveLocation2string(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalN__DirectiveLocation2ᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v []string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__DirectiveLocation2string(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalN__EnumValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValue(ctx context.Context, sel ast.SelectionSet, v introspection.EnumValue) graphql.Marshaler { + return ec.___EnumValue(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__Field2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐField(ctx context.Context, sel ast.SelectionSet, v introspection.Field) graphql.Marshaler { + return ec.___Field(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__InputValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValue(ctx context.Context, sel ast.SelectionSet, v introspection.InputValue) graphql.Marshaler { + return ec.___InputValue(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.InputValue) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__InputValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValue(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +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) +} + +func (ec *executionContext) marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.Type) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__Type2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx context.Context, sel ast.SelectionSet, v *introspection.Type) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec.___Type(ctx, sel, v) +} + +func (ec *executionContext) unmarshalN__TypeKind2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalN__TypeKind2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNfederation__Policy2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNfederation__Policy2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNfederation__Policy2ᚕstringᚄ(ctx context.Context, v any) ([]string, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNfederation__Policy2string(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalNfederation__Policy2ᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v []string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNfederation__Policy2string(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalNfederation__Policy2ᚕᚕstringᚄ(ctx context.Context, v any) ([][]string, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([][]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNfederation__Policy2ᚕstringᚄ(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalNfederation__Policy2ᚕᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v [][]string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNfederation__Policy2ᚕstringᚄ(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalNfederation__Scope2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNfederation__Scope2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNfederation__Scope2ᚕstringᚄ(ctx context.Context, v any) ([]string, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNfederation__Scope2string(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalNfederation__Scope2ᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v []string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNfederation__Scope2string(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalNfederation__Scope2ᚕᚕstringᚄ(ctx context.Context, v any) ([][]string, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([][]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNfederation__Scope2ᚕstringᚄ(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalNfederation__Scope2ᚕᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v [][]string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNfederation__Scope2ᚕstringᚄ(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalOBoolean2bool(ctx context.Context, v any) (bool, error) { + res, err := graphql.UnmarshalBoolean(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOBoolean2bool(ctx context.Context, sel ast.SelectionSet, v bool) graphql.Marshaler { + _ = sel + _ = ctx + res := graphql.MarshalBoolean(v) + return res +} + +func (ec *executionContext) unmarshalOBoolean2ᚖbool(ctx context.Context, v any) (*bool, error) { + if v == nil { + return nil, nil + } + res, err := graphql.UnmarshalBoolean(v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOBoolean2ᚖbool(ctx context.Context, sel ast.SelectionSet, v *bool) graphql.Marshaler { + if v == nil { + return graphql.Null + } + _ = sel + _ = ctx + res := graphql.MarshalBoolean(*v) + return res +} + +func (ec *executionContext) unmarshalOString2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOString2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + _ = ctx + res := graphql.MarshalString(v) + return res +} + +func (ec *executionContext) unmarshalOString2ᚕstringᚄ(ctx context.Context, v any) ([]string, error) { + if v == nil { + return nil, nil + } + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNString2string(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalOString2ᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v []string) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNString2string(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalOString2ᚖstring(ctx context.Context, v any) (*string, error) { + if v == nil { + return nil, nil + } + res, err := graphql.UnmarshalString(v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOString2ᚖstring(ctx context.Context, sel ast.SelectionSet, v *string) graphql.Marshaler { + if v == nil { + return graphql.Null + } + _ = sel + _ = ctx + res := graphql.MarshalString(*v) + return res +} + +func (ec *executionContext) marshalOViewer2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋcachetestᚋviewerᚋsubgraphᚋmodelᚐViewer(ctx context.Context, sel ast.SelectionSet, v *model.Viewer) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._Viewer(ctx, sel, v) +} + +func (ec *executionContext) marshalO_Entity2githubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐEntity(ctx context.Context, sel ast.SelectionSet, v fedruntime.Entity) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec.__Entity(ctx, sel, v) +} + +func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.EnumValue) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__EnumValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValue(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐFieldᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.Field) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__Field2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐField(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.InputValue) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__InputValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValue(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + 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 + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__Type2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +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 + } + return ec.___Type(ctx, sel, v) +} + +// endregion ***************************** type.gotpl ***************************** diff --git a/demo/pkg/subgraphs/cachetest/viewer/subgraph/generated/staticcheck.conf b/demo/pkg/subgraphs/cachetest/viewer/subgraph/generated/staticcheck.conf new file mode 100644 index 0000000000..582953a07e --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/viewer/subgraph/generated/staticcheck.conf @@ -0,0 +1,2 @@ +# This is meant as a workaround to skip staticcheck checks for generated code +checks = ["all", "-SA4004", "-ST1000"] diff --git a/demo/pkg/subgraphs/cachetest/viewer/subgraph/model/models_gen.go b/demo/pkg/subgraphs/cachetest/viewer/subgraph/model/models_gen.go new file mode 100644 index 0000000000..85acb9e6a7 --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/viewer/subgraph/model/models_gen.go @@ -0,0 +1,21 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package model + +type Personalized struct { + ID string `json:"id"` + CurrentViewer *Viewer `json:"currentViewer,omitempty"` +} + +func (Personalized) IsEntity() {} + +type Query struct { +} + +type Viewer struct { + ID string `json:"id"` + Name string `json:"name"` + Email string `json:"email"` +} + +func (Viewer) IsEntity() {} diff --git a/demo/pkg/subgraphs/cachetest/viewer/subgraph/resolver.go b/demo/pkg/subgraphs/cachetest/viewer/subgraph/resolver.go new file mode 100644 index 0000000000..c1da1a4335 --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/viewer/subgraph/resolver.go @@ -0,0 +1,7 @@ +package subgraph + +// This file will not be regenerated automatically. +// +// It serves as dependency injection for your app, add any dependencies you require here. + +type Resolver struct{} diff --git a/demo/pkg/subgraphs/cachetest/viewer/subgraph/schema.graphqls b/demo/pkg/subgraphs/cachetest/viewer/subgraph/schema.graphqls new file mode 100644 index 0000000000..1c71175536 --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/viewer/subgraph/schema.graphqls @@ -0,0 +1,24 @@ +extend schema + @link( + url: "https://specs.apollo.dev/federation/v2.5" + import: ["@key", "@interfaceObject", "@inaccessible"] + ) + +directive @openfed__requestScoped(key: String!) on FIELD_DEFINITION + +type Viewer @key(fields: "id") { + id: ID! + name: String! + email: String! +} + +# Symmetric @openfed__requestScoped: Query.currentViewer and Personalized.currentViewer +# share key "currentViewer" so they read/write the same L1 coordinate cache entry. +type Personalized @key(fields: "id") @interfaceObject { + id: ID! + currentViewer: Viewer @inaccessible @openfed__requestScoped(key: "currentViewer") +} + +type Query { + currentViewer: Viewer @openfed__requestScoped(key: "currentViewer") +} diff --git a/demo/pkg/subgraphs/cachetest/viewer/subgraph/schema.resolvers.go b/demo/pkg/subgraphs/cachetest/viewer/subgraph/schema.resolvers.go new file mode 100644 index 0000000000..f62818b546 --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/viewer/subgraph/schema.resolvers.go @@ -0,0 +1,22 @@ +package subgraph + +// 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.76 + +import ( + "context" + + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachetest/viewer/subgraph/generated" + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachetest/viewer/subgraph/model" +) + +// CurrentViewer is the resolver for the currentViewer field. +func (r *queryResolver) CurrentViewer(ctx context.Context) (*model.Viewer, error) { + return defaultViewer(), nil +} + +// Query returns generated.QueryResolver implementation. +func (r *Resolver) Query() generated.QueryResolver { return &queryResolver{r} } + +type queryResolver struct{ *Resolver } diff --git a/demo/pkg/subgraphs/cachetest/viewer/viewer.go b/demo/pkg/subgraphs/cachetest/viewer/viewer.go new file mode 100644 index 0000000000..2acccebc7a --- /dev/null +++ b/demo/pkg/subgraphs/cachetest/viewer/viewer.go @@ -0,0 +1,14 @@ +package viewer + +import ( + "github.com/99designs/gqlgen/graphql" + + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachetest/viewer/subgraph" + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachetest/viewer/subgraph/generated" +) + +func NewSchema() graphql.ExecutableSchema { + return generated.NewExecutableSchema(generated.Config{ + Resolvers: &subgraph.Resolver{}, + }) +} diff --git a/demo/pkg/subgraphs/subgraphs.go b/demo/pkg/subgraphs/subgraphs.go index 44764f14bd..1c00384c69 100644 --- a/demo/pkg/subgraphs/subgraphs.go +++ b/demo/pkg/subgraphs/subgraphs.go @@ -12,7 +12,10 @@ import ( "os" "strconv" + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachegraph" + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachegraph_ext" "github.com/wundergraph/cosmo/demo/pkg/subgraphs/products_fg" + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/viewer" "github.com/wundergraph/cosmo/router/core" rmetric "github.com/wundergraph/cosmo/router/pkg/metric" "github.com/wundergraph/cosmo/router/pkg/pubsub/datasource" @@ -51,15 +54,18 @@ const ( ) type Ports struct { - Employees int - Family int - Hobbies int - Products int - ProductsFG int - Test1 int - Availability int - Mood int - Countries int + Employees int + Family int + Hobbies int + Products int + ProductsFG int + Test1 int + Availability int + Mood int + Countries int + CacheGraph int + CacheGraphExt int + Viewer int } func (p *Ports) AsArray() []int { @@ -73,6 +79,9 @@ func (p *Ports) AsArray() []int { p.Availability, p.Mood, p.Countries, + p.CacheGraph, + p.CacheGraphExt, + p.Viewer, } } @@ -152,7 +161,7 @@ func newServer(name string, enableDebug bool, port int, schema graphql.Executabl })) return &http.Server{ Addr: ":" + strconv.Itoa(port), - Handler: injector.HTTP(mux), + Handler: injector.Latency(injector.HTTP(mux)), } } @@ -160,7 +169,7 @@ func subgraphHandler(schema graphql.ExecutableSchema) http.Handler { srv := NewDemoServer(schema) mux := http.NewServeMux() mux.Handle("/graphql", srv) - return injector.HTTP(mux) + return injector.Latency(injector.HTTP(mux)) } type SubgraphOptions struct { @@ -279,6 +288,18 @@ func New(ctx context.Context, config *Config) (*Subgraphs, error) { if srv := newServer("countries", config.EnableDebug, config.Ports.Countries, countries.NewSchema(natsPubSubByProviderID)); srv != nil { servers = append(servers, srv) } + if srv := newServer("cachegraph", config.EnableDebug, config.Ports.CacheGraph, cachegraph.NewSchema()); srv != nil { + servers = append(servers, srv) + } + if srv := newServer("cachegraph-ext", config.EnableDebug, config.Ports.CacheGraphExt, cachegraph_ext.NewSchema()); srv != nil { + servers = append(servers, srv) + } + if config.Ports.Viewer != 0 { + servers = append(servers, &http.Server{ + Addr: ":" + strconv.Itoa(config.Ports.Viewer), + Handler: injector.Latency(injector.HTTP(viewer.NewHandler())), + }) + } return &Subgraphs{ servers: servers, ports: config.Ports, diff --git a/demo/pkg/subgraphs/viewer/generate.go b/demo/pkg/subgraphs/viewer/generate.go new file mode 100644 index 0000000000..d3f0642e72 --- /dev/null +++ b/demo/pkg/subgraphs/viewer/generate.go @@ -0,0 +1,2 @@ +//go:generate go run github.com/99designs/gqlgen generate +package viewer diff --git a/demo/pkg/subgraphs/viewer/gqlgen.yml b/demo/pkg/subgraphs/viewer/gqlgen.yml new file mode 100644 index 0000000000..fbdda3219e --- /dev/null +++ b/demo/pkg/subgraphs/viewer/gqlgen.yml @@ -0,0 +1,39 @@ +schema: + - subgraph/*.graphqls + +exec: + filename: subgraph/generated/generated.go + package: generated + +federation: + filename: subgraph/generated/federation.go + package: generated + version: 2 + options: + explicit_requires: true + +model: + filename: subgraph/model/models_gen.go + package: model + +directives: + openfed__requestScoped: + skip_runtime: true + +resolver: + layout: follow-schema + dir: subgraph + package: subgraph + +models: + ID: + model: + - github.com/99designs/gqlgen/graphql.ID + - github.com/99designs/gqlgen/graphql.Int + - github.com/99designs/gqlgen/graphql.Int64 + - github.com/99designs/gqlgen/graphql.Int32 + Int: + model: + - github.com/99designs/gqlgen/graphql.Int + - github.com/99designs/gqlgen/graphql.Int64 + - github.com/99designs/gqlgen/graphql.Int32 diff --git a/demo/pkg/subgraphs/viewer/subgraph/context.go b/demo/pkg/subgraphs/viewer/subgraph/context.go new file mode 100644 index 0000000000..d5a6732454 --- /dev/null +++ b/demo/pkg/subgraphs/viewer/subgraph/context.go @@ -0,0 +1,32 @@ +package subgraph + +import ( + "context" + "net/http" + + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/viewer/subgraph/model" +) + +// viewerFromContext extracts the current viewer from the request's Authorization header. +func viewerFromContext(ctx context.Context) *model.Viewer { + gc := ctx.Value(httpRequestKey{}) + if gc == nil { + return defaultViewer + } + r, ok := gc.(*http.Request) + if !ok { + return defaultViewer + } + auth := r.Header.Get("Authorization") + if v, found := viewersByToken[auth]; found { + return v + } + return defaultViewer +} + +type httpRequestKey struct{} + +// WithHTTPRequest stores the HTTP request in context for resolver access. +func WithHTTPRequest(ctx context.Context, r *http.Request) context.Context { + return context.WithValue(ctx, httpRequestKey{}, r) +} diff --git a/demo/pkg/subgraphs/viewer/subgraph/data.go b/demo/pkg/subgraphs/viewer/subgraph/data.go new file mode 100644 index 0000000000..5ec1f0dfd5 --- /dev/null +++ b/demo/pkg/subgraphs/viewer/subgraph/data.go @@ -0,0 +1,20 @@ +package subgraph + +import "github.com/wundergraph/cosmo/demo/pkg/subgraphs/viewer/subgraph/model" + +// Viewers keyed by auth token +var viewersByToken = map[string]*model.Viewer{ + "Bearer token-alice": {ID: "v1", Name: "Alice", Email: "alice@example.com"}, + "Bearer token-bob": {ID: "v2", Name: "Bob", Email: "bob@example.com"}, + "Bearer token-charlie": {ID: "v3", Name: "Charlie", Email: "charlie@example.com"}, +} + +// Viewers keyed by ID (for entity resolution) +var viewersByID = map[string]*model.Viewer{ + "v1": {ID: "v1", Name: "Alice", Email: "alice@example.com"}, + "v2": {ID: "v2", Name: "Bob", Email: "bob@example.com"}, + "v3": {ID: "v3", Name: "Charlie", Email: "charlie@example.com"}, +} + +// Default viewer when no auth token is provided +var defaultViewer = &model.Viewer{ID: "v0", Name: "Anonymous", Email: "anonymous@example.com"} diff --git a/demo/pkg/subgraphs/viewer/subgraph/entity.resolvers.go b/demo/pkg/subgraphs/viewer/subgraph/entity.resolvers.go new file mode 100644 index 0000000000..ca3c972428 --- /dev/null +++ b/demo/pkg/subgraphs/viewer/subgraph/entity.resolvers.go @@ -0,0 +1,33 @@ +package subgraph + +// 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.76 + +import ( + "context" + + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/viewer/subgraph/generated" + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/viewer/subgraph/model" +) + +// FindPersonalizedByID is the resolver for the findPersonalizedByID field. +func (r *entityResolver) FindPersonalizedByID(ctx context.Context, id string) (*model.Personalized, error) { + // The @interfaceObject resolver: returns currentViewer for any entity implementing Personalized. + // The entity's actual type (Article, etc.) doesn't matter — the viewer is from the auth context. + viewer := viewerFromContext(ctx) + return &model.Personalized{ + ID: id, + CurrentViewer: viewer, + }, nil +} + +// FindViewerByID is the resolver for the findViewerByID field. +func (r *entityResolver) FindViewerByID(ctx context.Context, id string) (*model.Viewer, error) { + return viewersByID[id], nil +} + +// Entity returns generated.EntityResolver implementation. +func (r *Resolver) Entity() generated.EntityResolver { return &entityResolver{r} } + +type entityResolver struct{ *Resolver } diff --git a/demo/pkg/subgraphs/viewer/subgraph/generated/federation.go b/demo/pkg/subgraphs/viewer/subgraph/generated/federation.go new file mode 100644 index 0000000000..2556c88ac5 --- /dev/null +++ b/demo/pkg/subgraphs/viewer/subgraph/generated/federation.go @@ -0,0 +1,288 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package generated + +import ( + "context" + "errors" + "fmt" + "strings" + "sync" + + "github.com/99designs/gqlgen/plugin/federation/fedruntime" +) + +var ( + ErrUnknownType = errors.New("unknown type") + ErrTypeNotFound = errors.New("type not found") +) + +func (ec *executionContext) __resolve__service(ctx context.Context) (fedruntime.Service, error) { + if ec.DisableIntrospection { + return fedruntime.Service{}, errors.New("federated introspection disabled") + } + + var sdl []string + + for _, src := range sources { + if src.BuiltIn { + continue + } + sdl = append(sdl, src.Input) + } + + return fedruntime.Service{ + SDL: strings.Join(sdl, "\n"), + }, nil +} + +func (ec *executionContext) __resolve_entities(ctx context.Context, representations []map[string]any) []fedruntime.Entity { + list := make([]fedruntime.Entity, len(representations)) + + repsMap := ec.buildRepresentationGroups(ctx, representations) + + switch len(repsMap) { + case 0: + return list + case 1: + for typeName, reps := range repsMap { + ec.resolveEntityGroup(ctx, typeName, reps, list) + } + return list + default: + var g sync.WaitGroup + g.Add(len(repsMap)) + for typeName, reps := range repsMap { + go func(typeName string, reps []EntityWithIndex) { + ec.resolveEntityGroup(ctx, typeName, reps, list) + g.Done() + }(typeName, reps) + } + g.Wait() + return list + } +} + +type EntityWithIndex struct { + // The index in the original representation array + index int + entity EntityRepresentation +} + +// EntityRepresentation is the JSON representation of an entity sent by the Router +// used as the inputs for us to resolve. +// +// We make it a map because we know the top level JSON is always an object. +type EntityRepresentation map[string]any + +// We group entities by typename so that we can parallelize their resolution. +// This is particularly helpful when there are entity groups in multi mode. +func (ec *executionContext) buildRepresentationGroups( + ctx context.Context, + representations []map[string]any, +) map[string][]EntityWithIndex { + repsMap := make(map[string][]EntityWithIndex) + for i, rep := range representations { + typeName, ok := rep["__typename"].(string) + if !ok { + // If there is no __typename, we just skip the representation; + // we just won't be resolving these unknown types. + ec.Error(ctx, errors.New("__typename must be an existing string")) + continue + } + + repsMap[typeName] = append(repsMap[typeName], EntityWithIndex{ + index: i, + entity: rep, + }) + } + + return repsMap +} + +func (ec *executionContext) resolveEntityGroup( + ctx context.Context, + typeName string, + reps []EntityWithIndex, + list []fedruntime.Entity, +) { + if isMulti(typeName) { + err := ec.resolveManyEntities(ctx, typeName, reps, list) + if err != nil { + ec.Error(ctx, err) + } + } else { + // if there are multiple entities to resolve, parallelize (similar to + // graphql.FieldSet.Dispatch) + var e sync.WaitGroup + e.Add(len(reps)) + for i, rep := range reps { + i, rep := i, rep + go func(i int, rep EntityWithIndex) { + entity, err := ec.resolveEntity(ctx, typeName, rep.entity) + if err != nil { + ec.Error(ctx, err) + } else { + list[rep.index] = entity + } + e.Done() + }(i, rep) + } + e.Wait() + } +} + +func isMulti(typeName string) bool { + switch typeName { + default: + return false + } +} + +func (ec *executionContext) resolveEntity( + ctx context.Context, + typeName string, + rep EntityRepresentation, +) (e fedruntime.Entity, err error) { + // we need to do our own panic handling, because we may be called in a + // goroutine, where the usual panic handling can't catch us + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + } + }() + + switch typeName { + case "Personalized": + resolverName, err := entityResolverNameForPersonalized(ctx, rep) + if err != nil { + return nil, fmt.Errorf(`finding resolver for Entity "Personalized": %w`, err) + } + switch resolverName { + + case "findPersonalizedByID": + id0, err := ec.unmarshalNID2string(ctx, rep["id"]) + if err != nil { + return nil, fmt.Errorf(`unmarshalling param 0 for findPersonalizedByID(): %w`, err) + } + entity, err := ec.resolvers.Entity().FindPersonalizedByID(ctx, id0) + if err != nil { + return nil, fmt.Errorf(`resolving Entity "Personalized": %w`, err) + } + + return entity, nil + } + case "Viewer": + resolverName, err := entityResolverNameForViewer(ctx, rep) + if err != nil { + return nil, fmt.Errorf(`finding resolver for Entity "Viewer": %w`, err) + } + switch resolverName { + + case "findViewerByID": + id0, err := ec.unmarshalNID2string(ctx, rep["id"]) + if err != nil { + return nil, fmt.Errorf(`unmarshalling param 0 for findViewerByID(): %w`, err) + } + entity, err := ec.resolvers.Entity().FindViewerByID(ctx, id0) + if err != nil { + return nil, fmt.Errorf(`resolving Entity "Viewer": %w`, err) + } + + return entity, nil + } + + } + return nil, fmt.Errorf("%w: %s", ErrUnknownType, typeName) +} + +func (ec *executionContext) resolveManyEntities( + ctx context.Context, + typeName string, + reps []EntityWithIndex, + list []fedruntime.Entity, +) (err error) { + // we need to do our own panic handling, because we may be called in a + // goroutine, where the usual panic handling can't catch us + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + } + }() + + switch typeName { + + default: + return errors.New("unknown type: " + typeName) + } +} + +func entityResolverNameForPersonalized(ctx context.Context, rep EntityRepresentation) (string, error) { + // we collect errors because a later entity resolver may work fine + // when an entity has multiple keys + entityResolverErrs := []error{} + for { + var ( + m EntityRepresentation + val any + ok bool + ) + _ = val + // if all of the KeyFields values for this resolver are null, + // we shouldn't use use it + allNull := true + m = rep + val, ok = m["id"] + if !ok { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to missing Key Field \"id\" for Personalized", ErrTypeNotFound)) + break + } + if allNull { + allNull = val == nil + } + if allNull { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to all null value KeyFields for Personalized", ErrTypeNotFound)) + break + } + return "findPersonalizedByID", nil + } + return "", fmt.Errorf("%w for Personalized due to %v", ErrTypeNotFound, + errors.Join(entityResolverErrs...).Error()) +} + +func entityResolverNameForViewer(ctx context.Context, rep EntityRepresentation) (string, error) { + // we collect errors because a later entity resolver may work fine + // when an entity has multiple keys + entityResolverErrs := []error{} + for { + var ( + m EntityRepresentation + val any + ok bool + ) + _ = val + // if all of the KeyFields values for this resolver are null, + // we shouldn't use use it + allNull := true + m = rep + val, ok = m["id"] + if !ok { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to missing Key Field \"id\" for Viewer", ErrTypeNotFound)) + break + } + if allNull { + allNull = val == nil + } + if allNull { + entityResolverErrs = append(entityResolverErrs, + fmt.Errorf("%w due to all null value KeyFields for Viewer", ErrTypeNotFound)) + break + } + return "findViewerByID", nil + } + return "", fmt.Errorf("%w for Viewer due to %v", ErrTypeNotFound, + errors.Join(entityResolverErrs...).Error()) +} diff --git a/demo/pkg/subgraphs/viewer/subgraph/generated/generated.go b/demo/pkg/subgraphs/viewer/subgraph/generated/generated.go new file mode 100644 index 0000000000..46446bfc99 --- /dev/null +++ b/demo/pkg/subgraphs/viewer/subgraph/generated/generated.go @@ -0,0 +1,4839 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package generated + +import ( + "bytes" + "context" + "errors" + "fmt" + "strconv" + "sync" + "sync/atomic" + + "github.com/99designs/gqlgen/graphql" + "github.com/99designs/gqlgen/graphql/introspection" + "github.com/99designs/gqlgen/plugin/federation/fedruntime" + gqlparser "github.com/vektah/gqlparser/v2" + "github.com/vektah/gqlparser/v2/ast" + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/viewer/subgraph/model" +) + +// region ************************** generated!.gotpl ************************** + +// NewExecutableSchema creates an ExecutableSchema from the ResolverRoot interface. +func NewExecutableSchema(cfg Config) graphql.ExecutableSchema { + return &executableSchema{ + schema: cfg.Schema, + resolvers: cfg.Resolvers, + directives: cfg.Directives, + complexity: cfg.Complexity, + } +} + +type Config struct { + Schema *ast.Schema + Resolvers ResolverRoot + Directives DirectiveRoot + Complexity ComplexityRoot +} + +type ResolverRoot interface { + Entity() EntityResolver + Query() QueryResolver +} + +type DirectiveRoot struct { +} + +type ComplexityRoot struct { + Entity struct { + FindPersonalizedByID func(childComplexity int, id string) int + FindViewerByID func(childComplexity int, id string) int + } + + Personalized struct { + CurrentViewer func(childComplexity int) int + ID func(childComplexity int) int + } + + Query struct { + CurrentViewer func(childComplexity int) int + __resolve__service func(childComplexity int) int + __resolve_entities func(childComplexity int, representations []map[string]any) int + } + + Viewer struct { + Email func(childComplexity int) int + ID func(childComplexity int) int + Name func(childComplexity int) int + } + + _Service struct { + SDL func(childComplexity int) int + } +} + +type EntityResolver interface { + FindPersonalizedByID(ctx context.Context, id string) (*model.Personalized, error) + FindViewerByID(ctx context.Context, id string) (*model.Viewer, error) +} +type QueryResolver interface { + CurrentViewer(ctx context.Context) (*model.Viewer, error) +} + +type executableSchema struct { + schema *ast.Schema + resolvers ResolverRoot + directives DirectiveRoot + complexity ComplexityRoot +} + +func (e *executableSchema) Schema() *ast.Schema { + if e.schema != nil { + return e.schema + } + return parsedSchema +} + +func (e *executableSchema) Complexity(ctx context.Context, typeName, field string, childComplexity int, rawArgs map[string]any) (int, bool) { + ec := executionContext{nil, e, 0, 0, nil} + _ = ec + switch typeName + "." + field { + + case "Entity.findPersonalizedByID": + if e.complexity.Entity.FindPersonalizedByID == nil { + break + } + + args, err := ec.field_Entity_findPersonalizedByID_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Entity.FindPersonalizedByID(childComplexity, args["id"].(string)), true + + case "Entity.findViewerByID": + if e.complexity.Entity.FindViewerByID == nil { + break + } + + args, err := ec.field_Entity_findViewerByID_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Entity.FindViewerByID(childComplexity, args["id"].(string)), true + + case "Personalized.currentViewer": + if e.complexity.Personalized.CurrentViewer == nil { + break + } + + return e.complexity.Personalized.CurrentViewer(childComplexity), true + + case "Personalized.id": + if e.complexity.Personalized.ID == nil { + break + } + + return e.complexity.Personalized.ID(childComplexity), true + + case "Query.currentViewer": + if e.complexity.Query.CurrentViewer == nil { + break + } + + return e.complexity.Query.CurrentViewer(childComplexity), true + + case "Query._service": + if e.complexity.Query.__resolve__service == nil { + break + } + + return e.complexity.Query.__resolve__service(childComplexity), true + + case "Query._entities": + if e.complexity.Query.__resolve_entities == nil { + break + } + + args, err := ec.field_Query__entities_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.__resolve_entities(childComplexity, args["representations"].([]map[string]any)), true + + case "Viewer.email": + if e.complexity.Viewer.Email == nil { + break + } + + return e.complexity.Viewer.Email(childComplexity), true + + case "Viewer.id": + if e.complexity.Viewer.ID == nil { + break + } + + return e.complexity.Viewer.ID(childComplexity), true + + case "Viewer.name": + if e.complexity.Viewer.Name == nil { + break + } + + return e.complexity.Viewer.Name(childComplexity), true + + case "_Service.sdl": + if e.complexity._Service.SDL == nil { + break + } + + return e.complexity._Service.SDL(childComplexity), true + + } + return 0, false +} + +func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { + opCtx := graphql.GetOperationContext(ctx) + ec := executionContext{opCtx, e, 0, 0, make(chan graphql.DeferredResult)} + inputUnmarshalMap := graphql.BuildUnmarshalerMap() + first := true + + switch opCtx.Operation.Operation { + case ast.Query: + return func(ctx context.Context) *graphql.Response { + var response graphql.Response + var data graphql.Marshaler + if first { + first = false + ctx = graphql.WithUnmarshalerMap(ctx, inputUnmarshalMap) + data = ec._Query(ctx, opCtx.Operation.SelectionSet) + } else { + if atomic.LoadInt32(&ec.pendingDeferred) > 0 { + result := <-ec.deferredResults + atomic.AddInt32(&ec.pendingDeferred, -1) + data = result.Result + response.Path = result.Path + response.Label = result.Label + response.Errors = result.Errors + } else { + return nil + } + } + var buf bytes.Buffer + data.MarshalGQL(&buf) + response.Data = buf.Bytes() + if atomic.LoadInt32(&ec.deferred) > 0 { + hasNext := atomic.LoadInt32(&ec.pendingDeferred) > 0 + response.HasNext = &hasNext + } + + return &response + } + + default: + return graphql.OneShot(graphql.ErrorResponse(ctx, "unsupported GraphQL operation")) + } +} + +type executionContext struct { + *graphql.OperationContext + *executableSchema + deferred int32 + pendingDeferred int32 + deferredResults chan graphql.DeferredResult +} + +func (ec *executionContext) processDeferredGroup(dg graphql.DeferredGroup) { + atomic.AddInt32(&ec.pendingDeferred, 1) + go func() { + ctx := graphql.WithFreshResponseContext(dg.Context) + dg.FieldSet.Dispatch(ctx) + ds := graphql.DeferredResult{ + Path: dg.Path, + Label: dg.Label, + Result: dg.FieldSet, + Errors: graphql.GetErrors(ctx), + } + // null fields should bubble up + if dg.FieldSet.Invalids > 0 { + ds.Result = graphql.Null + } + ec.deferredResults <- ds + }() +} + +func (ec *executionContext) introspectSchema() (*introspection.Schema, error) { + if ec.DisableIntrospection { + return nil, errors.New("introspection disabled") + } + return introspection.WrapSchema(ec.Schema()), nil +} + +func (ec *executionContext) introspectType(name string) (*introspection.Type, error) { + if ec.DisableIntrospection { + return nil, errors.New("introspection disabled") + } + return introspection.WrapTypeFromDef(ec.Schema(), ec.Schema().Types[name]), nil +} + +var sources = []*ast.Source{ + {Name: "../schema.graphqls", Input: `extend schema + @link( + url: "https://specs.apollo.dev/federation/v2.5" + import: ["@key", "@interfaceObject", "@inaccessible"] + ) + +directive @openfed__requestScoped(key: String!) on FIELD_DEFINITION + +# Symmetric @openfed__requestScoped: both Query.currentViewer and Personalized.currentViewer +# declare key: "currentViewer". Their L1 cache entry is "viewer.currentViewer". +# Whichever is resolved first populates L1; subsequent fields with the same key +# inject from L1 and skip the fetch. +type Personalized @key(fields: "id") @interfaceObject { + id: ID! + currentViewer: Viewer @inaccessible @openfed__requestScoped(key: "currentViewer") +} + +type Viewer @key(fields: "id") { + id: ID! + name: String! + email: String! +} + +type Query { + currentViewer: Viewer @openfed__requestScoped(key: "currentViewer") +} +`, BuiltIn: false}, + {Name: "../../federation/directives.graphql", Input: ` + directive @authenticated on FIELD_DEFINITION | OBJECT | INTERFACE | SCALAR | ENUM + directive @composeDirective(name: String!) repeatable on SCHEMA + directive @extends on OBJECT | INTERFACE + directive @external on OBJECT | FIELD_DEFINITION + directive @key(fields: FieldSet!, resolvable: Boolean = true) repeatable on OBJECT | INTERFACE + directive @inaccessible on + | ARGUMENT_DEFINITION + | ENUM + | ENUM_VALUE + | FIELD_DEFINITION + | INPUT_FIELD_DEFINITION + | INPUT_OBJECT + | INTERFACE + | OBJECT + | SCALAR + | UNION + directive @interfaceObject on OBJECT + directive @link(import: [String!], url: String!) repeatable on SCHEMA + directive @override(from: String!, label: String) on FIELD_DEFINITION + directive @policy(policies: [[federation__Policy!]!]!) on + | FIELD_DEFINITION + | OBJECT + | INTERFACE + | SCALAR + | ENUM + directive @provides(fields: FieldSet!) on FIELD_DEFINITION + directive @requires(fields: FieldSet!) on FIELD_DEFINITION + directive @requiresScopes(scopes: [[federation__Scope!]!]!) on + | FIELD_DEFINITION + | OBJECT + | INTERFACE + | SCALAR + | ENUM + directive @shareable repeatable on FIELD_DEFINITION | OBJECT + directive @tag(name: String!) repeatable on + | ARGUMENT_DEFINITION + | ENUM + | ENUM_VALUE + | FIELD_DEFINITION + | INPUT_FIELD_DEFINITION + | INPUT_OBJECT + | INTERFACE + | OBJECT + | SCALAR + | UNION + scalar _Any + scalar FieldSet + scalar federation__Policy + scalar federation__Scope +`, BuiltIn: true}, + {Name: "../../federation/entity.graphql", Input: ` +# a union of all types that use the @key directive +union _Entity = Personalized | Viewer + +# fake type to build resolver interfaces for users to implement +type Entity { + findPersonalizedByID(id: ID!,): Personalized! + findViewerByID(id: ID!,): Viewer! +} + +type _Service { + sdl: String +} + +extend type Query { + _entities(representations: [_Any!]!): [_Entity]! + _service: _Service! +} +`, BuiltIn: true}, +} +var parsedSchema = gqlparser.MustLoadSchema(sources...) + +// endregion ************************** generated!.gotpl ************************** + +// region ***************************** args.gotpl ***************************** + +func (ec *executionContext) field_Entity_findPersonalizedByID_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Entity_findPersonalizedByID_argsID(ctx, rawArgs) + if err != nil { + return nil, err + } + args["id"] = arg0 + return args, nil +} +func (ec *executionContext) field_Entity_findPersonalizedByID_argsID( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["id"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + if tmp, ok := rawArgs["id"]; ok { + return ec.unmarshalNID2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Entity_findViewerByID_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Entity_findViewerByID_argsID(ctx, rawArgs) + if err != nil { + return nil, err + } + args["id"] = arg0 + return args, nil +} +func (ec *executionContext) field_Entity_findViewerByID_argsID( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["id"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + if tmp, ok := rawArgs["id"]; ok { + return ec.unmarshalNID2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Query___type_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Query___type_argsName(ctx, rawArgs) + if err != nil { + return nil, err + } + args["name"] = arg0 + return args, nil +} +func (ec *executionContext) field_Query___type_argsName( + ctx context.Context, + rawArgs map[string]any, +) (string, error) { + if _, ok := rawArgs["name"]; !ok { + var zeroVal string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("name")) + if tmp, ok := rawArgs["name"]; ok { + return ec.unmarshalNString2string(ctx, tmp) + } + + var zeroVal string + return zeroVal, nil +} + +func (ec *executionContext) field_Query__entities_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Query__entities_argsRepresentations(ctx, rawArgs) + if err != nil { + return nil, err + } + args["representations"] = arg0 + return args, nil +} +func (ec *executionContext) field_Query__entities_argsRepresentations( + ctx context.Context, + rawArgs map[string]any, +) ([]map[string]any, error) { + if _, ok := rawArgs["representations"]; !ok { + var zeroVal []map[string]any + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("representations")) + if tmp, ok := rawArgs["representations"]; ok { + return ec.unmarshalN_Any2ᚕmapᚄ(ctx, tmp) + } + + var zeroVal []map[string]any + return zeroVal, nil +} + +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 := ec.field___Directive_args_argsIncludeDeprecated(ctx, rawArgs) + if err != nil { + return nil, err + } + args["includeDeprecated"] = arg0 + return args, nil +} +func (ec *executionContext) field___Directive_args_argsIncludeDeprecated( + ctx context.Context, + rawArgs map[string]any, +) (*bool, error) { + if _, ok := rawArgs["includeDeprecated"]; !ok { + var zeroVal *bool + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("includeDeprecated")) + if tmp, ok := rawArgs["includeDeprecated"]; ok { + return ec.unmarshalOBoolean2ᚖbool(ctx, tmp) + } + + var zeroVal *bool + return zeroVal, nil +} + +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 := ec.field___Field_args_argsIncludeDeprecated(ctx, rawArgs) + if err != nil { + return nil, err + } + args["includeDeprecated"] = arg0 + return args, nil +} +func (ec *executionContext) field___Field_args_argsIncludeDeprecated( + ctx context.Context, + rawArgs map[string]any, +) (*bool, error) { + if _, ok := rawArgs["includeDeprecated"]; !ok { + var zeroVal *bool + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("includeDeprecated")) + if tmp, ok := rawArgs["includeDeprecated"]; ok { + return ec.unmarshalOBoolean2ᚖbool(ctx, tmp) + } + + var zeroVal *bool + return zeroVal, nil +} + +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 := ec.field___Type_enumValues_argsIncludeDeprecated(ctx, rawArgs) + if err != nil { + return nil, err + } + args["includeDeprecated"] = arg0 + return args, nil +} +func (ec *executionContext) field___Type_enumValues_argsIncludeDeprecated( + ctx context.Context, + rawArgs map[string]any, +) (bool, error) { + if _, ok := rawArgs["includeDeprecated"]; !ok { + var zeroVal bool + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("includeDeprecated")) + if tmp, ok := rawArgs["includeDeprecated"]; ok { + return ec.unmarshalOBoolean2bool(ctx, tmp) + } + + var zeroVal bool + return zeroVal, nil +} + +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 := ec.field___Type_fields_argsIncludeDeprecated(ctx, rawArgs) + if err != nil { + return nil, err + } + args["includeDeprecated"] = arg0 + return args, nil +} +func (ec *executionContext) field___Type_fields_argsIncludeDeprecated( + ctx context.Context, + rawArgs map[string]any, +) (bool, error) { + if _, ok := rawArgs["includeDeprecated"]; !ok { + var zeroVal bool + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("includeDeprecated")) + if tmp, ok := rawArgs["includeDeprecated"]; ok { + return ec.unmarshalOBoolean2bool(ctx, tmp) + } + + var zeroVal bool + return zeroVal, nil +} + +// endregion ***************************** args.gotpl ***************************** + +// region ************************** directives.gotpl ************************** + +// endregion ************************** directives.gotpl ************************** + +// region **************************** field.gotpl ***************************** + +func (ec *executionContext) _Entity_findPersonalizedByID(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Entity_findPersonalizedByID(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Entity().FindPersonalizedByID(rctx, fc.Args["id"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*model.Personalized) + fc.Result = res + return ec.marshalNPersonalized2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋviewerᚋsubgraphᚋmodelᚐPersonalized(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Entity_findPersonalizedByID(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Entity", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Personalized_id(ctx, field) + case "currentViewer": + return ec.fieldContext_Personalized_currentViewer(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Personalized", field.Name) + }, + } + 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_Entity_findPersonalizedByID_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Entity_findViewerByID(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Entity_findViewerByID(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Entity().FindViewerByID(rctx, fc.Args["id"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*model.Viewer) + fc.Result = res + return ec.marshalNViewer2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋviewerᚋsubgraphᚋmodelᚐViewer(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Entity_findViewerByID(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Entity", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Viewer_id(ctx, field) + case "name": + return ec.fieldContext_Viewer_name(ctx, field) + case "email": + return ec.fieldContext_Viewer_email(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Viewer", field.Name) + }, + } + 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_Entity_findViewerByID_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Personalized_id(ctx context.Context, field graphql.CollectedField, obj *model.Personalized) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Personalized_id(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Personalized_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Personalized", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Personalized_currentViewer(ctx context.Context, field graphql.CollectedField, obj *model.Personalized) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Personalized_currentViewer(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.CurrentViewer, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*model.Viewer) + fc.Result = res + return ec.marshalOViewer2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋviewerᚋsubgraphᚋmodelᚐViewer(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Personalized_currentViewer(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Personalized", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Viewer_id(ctx, field) + case "name": + return ec.fieldContext_Viewer_name(ctx, field) + case "email": + return ec.fieldContext_Viewer_email(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Viewer", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Query_currentViewer(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query_currentViewer(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().CurrentViewer(rctx) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*model.Viewer) + fc.Result = res + return ec.marshalOViewer2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋviewerᚋsubgraphᚋmodelᚐViewer(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query_currentViewer(_ 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) { + switch field.Name { + case "id": + return ec.fieldContext_Viewer_id(ctx, field) + case "name": + return ec.fieldContext_Viewer_name(ctx, field) + case "email": + return ec.fieldContext_Viewer_email(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Viewer", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Query__entities(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query__entities(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.__resolve_entities(ctx, fc.Args["representations"].([]map[string]any)), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]fedruntime.Entity) + fc.Result = res + return ec.marshalN_Entity2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐEntity(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query__entities(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type _Entity does not have child fields") + }, + } + 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__entities_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query__service(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query__service(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.__resolve__service(ctx) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(fedruntime.Service) + fc.Result = res + return ec.marshalN_Service2githubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐService(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query__service(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "sdl": + return ec.fieldContext__Service_sdl(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type _Service", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Query___type(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query___type(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.introspectType(fc.Args["name"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query___type(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + 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___type_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query___schema(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query___schema(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.introspectSchema() + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Schema) + fc.Result = res + return ec.marshalO__Schema2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐSchema(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query___schema(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "description": + return ec.fieldContext___Schema_description(ctx, field) + case "types": + return ec.fieldContext___Schema_types(ctx, field) + case "queryType": + return ec.fieldContext___Schema_queryType(ctx, field) + case "mutationType": + return ec.fieldContext___Schema_mutationType(ctx, field) + case "subscriptionType": + return ec.fieldContext___Schema_subscriptionType(ctx, field) + case "directives": + return ec.fieldContext___Schema_directives(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Schema", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Viewer_id(ctx context.Context, field graphql.CollectedField, obj *model.Viewer) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Viewer_id(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Viewer_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Viewer", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Viewer_name(ctx context.Context, field graphql.CollectedField, obj *model.Viewer) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Viewer_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Viewer_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Viewer", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Viewer_email(ctx context.Context, field graphql.CollectedField, obj *model.Viewer) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Viewer_email(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Email, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Viewer_email(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Viewer", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) __Service_sdl(ctx context.Context, field graphql.CollectedField, obj *fedruntime.Service) (ret graphql.Marshaler) { + fc, err := ec.fieldContext__Service_sdl(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.SDL, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalOString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext__Service_sdl(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "_Service", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Directive_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Directive_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Directive_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Directive_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_isRepeatable(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Directive_isRepeatable(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsRepeatable, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Directive_isRepeatable(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_locations(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Directive_locations(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Locations, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]string) + fc.Result = res + return ec.marshalN__DirectiveLocation2ᚕstringᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Directive_locations(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type __DirectiveLocation does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_args(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Directive_args(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Args, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]introspection.InputValue) + fc.Result = res + return ec.marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Directive_args(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___InputValue_name(ctx, field) + case "description": + return ec.fieldContext___InputValue_description(ctx, field) + case "type": + return ec.fieldContext___InputValue_type(ctx, field) + case "defaultValue": + return ec.fieldContext___InputValue_defaultValue(ctx, field) + case "isDeprecated": + return ec.fieldContext___InputValue_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___InputValue_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __InputValue", field.Name) + }, + } + 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___Directive_args_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) ___EnumValue_name(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___EnumValue_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___EnumValue_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__EnumValue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___EnumValue_description(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___EnumValue_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___EnumValue_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__EnumValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___EnumValue_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___EnumValue_isDeprecated(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsDeprecated(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___EnumValue_isDeprecated(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__EnumValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___EnumValue_deprecationReason(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___EnumValue_deprecationReason(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.DeprecationReason(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___EnumValue_deprecationReason(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__EnumValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_args(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_args(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Args, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]introspection.InputValue) + fc.Result = res + return ec.marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_args(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___InputValue_name(ctx, field) + case "description": + return ec.fieldContext___InputValue_description(ctx, field) + case "type": + return ec.fieldContext___InputValue_type(ctx, field) + case "defaultValue": + return ec.fieldContext___InputValue_defaultValue(ctx, field) + case "isDeprecated": + return ec.fieldContext___InputValue_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___InputValue_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __InputValue", field.Name) + }, + } + 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___Field_args_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) ___Field_type(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_type(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Type, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_type(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_isDeprecated(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsDeprecated(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_isDeprecated(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_deprecationReason(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_deprecationReason(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.DeprecationReason(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_deprecationReason(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_name(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_description(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_type(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_type(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Type, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_type(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_defaultValue(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_defaultValue(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.DefaultValue, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_defaultValue(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_isDeprecated(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsDeprecated(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_isDeprecated(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_deprecationReason(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_deprecationReason(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.DeprecationReason(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_deprecationReason(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_types(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_types(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Types(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]introspection.Type) + fc.Result = res + return ec.marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_types(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_queryType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_queryType(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.QueryType(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_queryType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_mutationType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_mutationType(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.MutationType(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_mutationType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_subscriptionType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_subscriptionType(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.SubscriptionType(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_subscriptionType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_directives(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_directives(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Directives(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]introspection.Directive) + fc.Result = res + return ec.marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirectiveᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_directives(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___Directive_name(ctx, field) + case "description": + return ec.fieldContext___Directive_description(ctx, field) + case "isRepeatable": + return ec.fieldContext___Directive_isRepeatable(ctx, field) + case "locations": + return ec.fieldContext___Directive_locations(ctx, field) + case "args": + return ec.fieldContext___Directive_args(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Directive", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_kind(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_kind(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Kind(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalN__TypeKind2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_kind(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type __TypeKind does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_specifiedByURL(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_specifiedByURL(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.SpecifiedByURL(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_specifiedByURL(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_fields(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_fields(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Fields(fc.Args["includeDeprecated"].(bool)), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.Field) + fc.Result = res + return ec.marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐFieldᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_fields(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___Field_name(ctx, field) + case "description": + return ec.fieldContext___Field_description(ctx, field) + case "args": + return ec.fieldContext___Field_args(ctx, field) + case "type": + return ec.fieldContext___Field_type(ctx, field) + case "isDeprecated": + return ec.fieldContext___Field_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___Field_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Field", field.Name) + }, + } + 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_fields_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) ___Type_interfaces(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_interfaces(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Interfaces(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_interfaces(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_possibleTypes(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_possibleTypes(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.PossibleTypes(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_possibleTypes(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_enumValues(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_enumValues(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.EnumValues(fc.Args["includeDeprecated"].(bool)), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.EnumValue) + fc.Result = res + return ec.marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValueᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_enumValues(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___EnumValue_name(ctx, field) + case "description": + return ec.fieldContext___EnumValue_description(ctx, field) + case "isDeprecated": + return ec.fieldContext___EnumValue_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___EnumValue_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __EnumValue", field.Name) + }, + } + 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_enumValues_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) ___Type_inputFields(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_inputFields(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.InputFields(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.InputValue) + fc.Result = res + return ec.marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_inputFields(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___InputValue_name(ctx, field) + case "description": + return ec.fieldContext___InputValue_description(ctx, field) + case "type": + return ec.fieldContext___InputValue_type(ctx, field) + case "defaultValue": + return ec.fieldContext___InputValue_defaultValue(ctx, field) + case "isDeprecated": + return ec.fieldContext___InputValue_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___InputValue_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __InputValue", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_ofType(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_ofType(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.OfType(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_ofType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_isOneOf(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_isOneOf(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsOneOf(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalOBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_isOneOf(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +// endregion **************************** field.gotpl ***************************** + +// region **************************** input.gotpl ***************************** + +// endregion **************************** input.gotpl ***************************** + +// region ************************** interface.gotpl *************************** + +func (ec *executionContext) __Entity(ctx context.Context, sel ast.SelectionSet, obj fedruntime.Entity) graphql.Marshaler { + switch obj := (obj).(type) { + case nil: + return graphql.Null + case model.Viewer: + return ec._Viewer(ctx, sel, &obj) + case *model.Viewer: + if obj == nil { + return graphql.Null + } + return ec._Viewer(ctx, sel, obj) + case model.Personalized: + return ec._Personalized(ctx, sel, &obj) + case *model.Personalized: + if obj == nil { + return graphql.Null + } + return ec._Personalized(ctx, sel, obj) + default: + panic(fmt.Errorf("unexpected type %T", obj)) + } +} + +// endregion ************************** interface.gotpl *************************** + +// region **************************** object.gotpl **************************** + +var entityImplementors = []string{"Entity"} + +func (ec *executionContext) _Entity(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, entityImplementors) + ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ + Object: "Entity", + }) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ + Object: field.Name, + Field: field, + }) + + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Entity") + case "findPersonalizedByID": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Entity_findPersonalizedByID(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "findViewerByID": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Entity_findViewerByID(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var personalizedImplementors = []string{"Personalized", "_Entity"} + +func (ec *executionContext) _Personalized(ctx context.Context, sel ast.SelectionSet, obj *model.Personalized) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, personalizedImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Personalized") + case "id": + out.Values[i] = ec._Personalized_id(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "currentViewer": + out.Values[i] = ec._Personalized_currentViewer(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var queryImplementors = []string{"Query"} + +func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, queryImplementors) + ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ + Object: "Query", + }) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ + Object: field.Name, + Field: field, + }) + + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Query") + case "currentViewer": + field := field + + innerFunc := func(ctx context.Context, _ *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_currentViewer(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "_entities": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query__entities(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "_service": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query__service(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "__type": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Query___type(ctx, field) + }) + case "__schema": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Query___schema(ctx, field) + }) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var viewerImplementors = []string{"Viewer", "_Entity"} + +func (ec *executionContext) _Viewer(ctx context.Context, sel ast.SelectionSet, obj *model.Viewer) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, viewerImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Viewer") + case "id": + out.Values[i] = ec._Viewer_id(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "name": + out.Values[i] = ec._Viewer_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "email": + out.Values[i] = ec._Viewer_email(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 + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var _ServiceImplementors = []string{"_Service"} + +func (ec *executionContext) __Service(ctx context.Context, sel ast.SelectionSet, obj *fedruntime.Service) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, _ServiceImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("_Service") + case "sdl": + out.Values[i] = ec.__Service_sdl(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __DirectiveImplementors = []string{"__Directive"} + +func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionSet, obj *introspection.Directive) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __DirectiveImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__Directive") + case "name": + out.Values[i] = ec.___Directive_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "description": + out.Values[i] = ec.___Directive_description(ctx, field, obj) + case "isRepeatable": + out.Values[i] = ec.___Directive_isRepeatable(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "locations": + out.Values[i] = ec.___Directive_locations(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "args": + out.Values[i] = ec.___Directive_args(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 + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __EnumValueImplementors = []string{"__EnumValue"} + +func (ec *executionContext) ___EnumValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.EnumValue) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __EnumValueImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__EnumValue") + case "name": + out.Values[i] = ec.___EnumValue_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "description": + out.Values[i] = ec.___EnumValue_description(ctx, field, obj) + case "isDeprecated": + out.Values[i] = ec.___EnumValue_isDeprecated(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "deprecationReason": + out.Values[i] = ec.___EnumValue_deprecationReason(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __FieldImplementors = []string{"__Field"} + +func (ec *executionContext) ___Field(ctx context.Context, sel ast.SelectionSet, obj *introspection.Field) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __FieldImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__Field") + case "name": + out.Values[i] = ec.___Field_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "description": + out.Values[i] = ec.___Field_description(ctx, field, obj) + case "args": + out.Values[i] = ec.___Field_args(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "type": + out.Values[i] = ec.___Field_type(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "isDeprecated": + out.Values[i] = ec.___Field_isDeprecated(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "deprecationReason": + out.Values[i] = ec.___Field_deprecationReason(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __InputValueImplementors = []string{"__InputValue"} + +func (ec *executionContext) ___InputValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.InputValue) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __InputValueImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__InputValue") + case "name": + out.Values[i] = ec.___InputValue_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "description": + out.Values[i] = ec.___InputValue_description(ctx, field, obj) + case "type": + out.Values[i] = ec.___InputValue_type(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "defaultValue": + out.Values[i] = ec.___InputValue_defaultValue(ctx, field, obj) + case "isDeprecated": + out.Values[i] = ec.___InputValue_isDeprecated(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "deprecationReason": + out.Values[i] = ec.___InputValue_deprecationReason(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __SchemaImplementors = []string{"__Schema"} + +func (ec *executionContext) ___Schema(ctx context.Context, sel ast.SelectionSet, obj *introspection.Schema) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __SchemaImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__Schema") + case "description": + out.Values[i] = ec.___Schema_description(ctx, field, obj) + case "types": + out.Values[i] = ec.___Schema_types(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "queryType": + out.Values[i] = ec.___Schema_queryType(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "mutationType": + out.Values[i] = ec.___Schema_mutationType(ctx, field, obj) + case "subscriptionType": + out.Values[i] = ec.___Schema_subscriptionType(ctx, field, obj) + case "directives": + out.Values[i] = ec.___Schema_directives(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 + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __TypeImplementors = []string{"__Type"} + +func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, obj *introspection.Type) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __TypeImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__Type") + case "kind": + out.Values[i] = ec.___Type_kind(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "name": + out.Values[i] = ec.___Type_name(ctx, field, obj) + case "description": + out.Values[i] = ec.___Type_description(ctx, field, obj) + case "specifiedByURL": + out.Values[i] = ec.___Type_specifiedByURL(ctx, field, obj) + case "fields": + out.Values[i] = ec.___Type_fields(ctx, field, obj) + case "interfaces": + out.Values[i] = ec.___Type_interfaces(ctx, field, obj) + case "possibleTypes": + out.Values[i] = ec.___Type_possibleTypes(ctx, field, obj) + case "enumValues": + out.Values[i] = ec.___Type_enumValues(ctx, field, obj) + case "inputFields": + out.Values[i] = ec.___Type_inputFields(ctx, field, obj) + case "ofType": + out.Values[i] = ec.___Type_ofType(ctx, field, obj) + case "isOneOf": + out.Values[i] = ec.___Type_isOneOf(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +// endregion **************************** object.gotpl **************************** + +// region ***************************** type.gotpl ***************************** + +func (ec *executionContext) unmarshalNBoolean2bool(ctx context.Context, v any) (bool, error) { + res, err := graphql.UnmarshalBoolean(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNBoolean2bool(ctx context.Context, sel ast.SelectionSet, v bool) graphql.Marshaler { + _ = sel + res := graphql.MarshalBoolean(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNFieldSet2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNFieldSet2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNID2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalID(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNID2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalID(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) marshalNPersonalized2githubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋviewerᚋsubgraphᚋmodelᚐPersonalized(ctx context.Context, sel ast.SelectionSet, v model.Personalized) graphql.Marshaler { + return ec._Personalized(ctx, sel, &v) +} + +func (ec *executionContext) marshalNPersonalized2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋviewerᚋsubgraphᚋmodelᚐPersonalized(ctx context.Context, sel ast.SelectionSet, v *model.Personalized) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._Personalized(ctx, sel, v) +} + +func (ec *executionContext) unmarshalNString2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNString2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) marshalNViewer2githubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋviewerᚋsubgraphᚋmodelᚐViewer(ctx context.Context, sel ast.SelectionSet, v model.Viewer) graphql.Marshaler { + return ec._Viewer(ctx, sel, &v) +} + +func (ec *executionContext) marshalNViewer2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋviewerᚋsubgraphᚋmodelᚐViewer(ctx context.Context, sel ast.SelectionSet, v *model.Viewer) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._Viewer(ctx, sel, v) +} + +func (ec *executionContext) unmarshalN_Any2map(ctx context.Context, v any) (map[string]any, error) { + res, err := graphql.UnmarshalMap(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalN_Any2map(ctx context.Context, sel ast.SelectionSet, v map[string]any) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + _ = sel + res := graphql.MarshalMap(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalN_Any2ᚕmapᚄ(ctx context.Context, v any) ([]map[string]any, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([]map[string]any, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalN_Any2map(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalN_Any2ᚕmapᚄ(ctx context.Context, sel ast.SelectionSet, v []map[string]any) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalN_Any2map(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalN_Entity2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐEntity(ctx context.Context, sel ast.SelectionSet, v []fedruntime.Entity) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalO_Entity2githubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐEntity(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + return ret +} + +func (ec *executionContext) marshalN_Service2githubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐService(ctx context.Context, sel ast.SelectionSet, v fedruntime.Service) graphql.Marshaler { + return ec.__Service(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__Directive2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirective(ctx context.Context, sel ast.SelectionSet, v introspection.Directive) graphql.Marshaler { + return ec.___Directive(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirectiveᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.Directive) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__Directive2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirective(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalN__DirectiveLocation2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalN__DirectiveLocation2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalN__DirectiveLocation2ᚕstringᚄ(ctx context.Context, v any) ([]string, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalN__DirectiveLocation2string(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalN__DirectiveLocation2ᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v []string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__DirectiveLocation2string(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalN__EnumValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValue(ctx context.Context, sel ast.SelectionSet, v introspection.EnumValue) graphql.Marshaler { + return ec.___EnumValue(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__Field2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐField(ctx context.Context, sel ast.SelectionSet, v introspection.Field) graphql.Marshaler { + return ec.___Field(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__InputValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValue(ctx context.Context, sel ast.SelectionSet, v introspection.InputValue) graphql.Marshaler { + return ec.___InputValue(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.InputValue) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__InputValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValue(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +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) +} + +func (ec *executionContext) marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.Type) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__Type2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx context.Context, sel ast.SelectionSet, v *introspection.Type) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec.___Type(ctx, sel, v) +} + +func (ec *executionContext) unmarshalN__TypeKind2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalN__TypeKind2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNfederation__Policy2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNfederation__Policy2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNfederation__Policy2ᚕstringᚄ(ctx context.Context, v any) ([]string, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNfederation__Policy2string(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalNfederation__Policy2ᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v []string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNfederation__Policy2string(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalNfederation__Policy2ᚕᚕstringᚄ(ctx context.Context, v any) ([][]string, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([][]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNfederation__Policy2ᚕstringᚄ(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalNfederation__Policy2ᚕᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v [][]string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNfederation__Policy2ᚕstringᚄ(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalNfederation__Scope2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNfederation__Scope2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNfederation__Scope2ᚕstringᚄ(ctx context.Context, v any) ([]string, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNfederation__Scope2string(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalNfederation__Scope2ᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v []string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNfederation__Scope2string(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalNfederation__Scope2ᚕᚕstringᚄ(ctx context.Context, v any) ([][]string, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([][]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNfederation__Scope2ᚕstringᚄ(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalNfederation__Scope2ᚕᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v [][]string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNfederation__Scope2ᚕstringᚄ(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalOBoolean2bool(ctx context.Context, v any) (bool, error) { + res, err := graphql.UnmarshalBoolean(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOBoolean2bool(ctx context.Context, sel ast.SelectionSet, v bool) graphql.Marshaler { + _ = sel + _ = ctx + res := graphql.MarshalBoolean(v) + return res +} + +func (ec *executionContext) unmarshalOBoolean2ᚖbool(ctx context.Context, v any) (*bool, error) { + if v == nil { + return nil, nil + } + res, err := graphql.UnmarshalBoolean(v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOBoolean2ᚖbool(ctx context.Context, sel ast.SelectionSet, v *bool) graphql.Marshaler { + if v == nil { + return graphql.Null + } + _ = sel + _ = ctx + res := graphql.MarshalBoolean(*v) + return res +} + +func (ec *executionContext) unmarshalOString2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOString2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + _ = ctx + res := graphql.MarshalString(v) + return res +} + +func (ec *executionContext) unmarshalOString2ᚕstringᚄ(ctx context.Context, v any) ([]string, error) { + if v == nil { + return nil, nil + } + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNString2string(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalOString2ᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v []string) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNString2string(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalOString2ᚖstring(ctx context.Context, v any) (*string, error) { + if v == nil { + return nil, nil + } + res, err := graphql.UnmarshalString(v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOString2ᚖstring(ctx context.Context, sel ast.SelectionSet, v *string) graphql.Marshaler { + if v == nil { + return graphql.Null + } + _ = sel + _ = ctx + res := graphql.MarshalString(*v) + return res +} + +func (ec *executionContext) marshalOViewer2ᚖgithubᚗcomᚋwundergraphᚋcosmoᚋdemoᚋpkgᚋsubgraphsᚋviewerᚋsubgraphᚋmodelᚐViewer(ctx context.Context, sel ast.SelectionSet, v *model.Viewer) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._Viewer(ctx, sel, v) +} + +func (ec *executionContext) marshalO_Entity2githubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐEntity(ctx context.Context, sel ast.SelectionSet, v fedruntime.Entity) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec.__Entity(ctx, sel, v) +} + +func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.EnumValue) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__EnumValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValue(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐFieldᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.Field) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__Field2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐField(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.InputValue) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__InputValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValue(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + 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 + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__Type2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +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 + } + return ec.___Type(ctx, sel, v) +} + +// endregion ***************************** type.gotpl ***************************** diff --git a/demo/pkg/subgraphs/viewer/subgraph/model/models_gen.go b/demo/pkg/subgraphs/viewer/subgraph/model/models_gen.go new file mode 100644 index 0000000000..85acb9e6a7 --- /dev/null +++ b/demo/pkg/subgraphs/viewer/subgraph/model/models_gen.go @@ -0,0 +1,21 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package model + +type Personalized struct { + ID string `json:"id"` + CurrentViewer *Viewer `json:"currentViewer,omitempty"` +} + +func (Personalized) IsEntity() {} + +type Query struct { +} + +type Viewer struct { + ID string `json:"id"` + Name string `json:"name"` + Email string `json:"email"` +} + +func (Viewer) IsEntity() {} diff --git a/demo/pkg/subgraphs/viewer/subgraph/resolver.go b/demo/pkg/subgraphs/viewer/subgraph/resolver.go new file mode 100644 index 0000000000..11329bb4a8 --- /dev/null +++ b/demo/pkg/subgraphs/viewer/subgraph/resolver.go @@ -0,0 +1,3 @@ +package subgraph + +type Resolver struct{} diff --git a/demo/pkg/subgraphs/viewer/subgraph/schema.graphqls b/demo/pkg/subgraphs/viewer/subgraph/schema.graphqls new file mode 100644 index 0000000000..1f41af7e2f --- /dev/null +++ b/demo/pkg/subgraphs/viewer/subgraph/schema.graphqls @@ -0,0 +1,26 @@ +extend schema + @link( + url: "https://specs.apollo.dev/federation/v2.5" + import: ["@key", "@interfaceObject", "@inaccessible"] + ) + +directive @openfed__requestScoped(key: String!) on FIELD_DEFINITION + +# Symmetric @openfed__requestScoped: both Query.currentViewer and Personalized.currentViewer +# declare key: "currentViewer". Their L1 cache entry is "viewer.currentViewer". +# Whichever is resolved first populates L1; subsequent fields with the same key +# inject from L1 and skip the fetch. +type Personalized @key(fields: "id") @interfaceObject { + id: ID! + currentViewer: Viewer @inaccessible @openfed__requestScoped(key: "currentViewer") +} + +type Viewer @key(fields: "id") { + id: ID! + name: String! + email: String! +} + +type Query { + currentViewer: Viewer @openfed__requestScoped(key: "currentViewer") +} diff --git a/demo/pkg/subgraphs/viewer/subgraph/schema.resolvers.go b/demo/pkg/subgraphs/viewer/subgraph/schema.resolvers.go new file mode 100644 index 0000000000..2d1cb6acce --- /dev/null +++ b/demo/pkg/subgraphs/viewer/subgraph/schema.resolvers.go @@ -0,0 +1,22 @@ +package subgraph + +// 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.76 + +import ( + "context" + + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/viewer/subgraph/generated" + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/viewer/subgraph/model" +) + +// CurrentViewer is the resolver for the currentViewer field. +func (r *queryResolver) CurrentViewer(ctx context.Context) (*model.Viewer, error) { + return viewerFromContext(ctx), nil +} + +// Query returns generated.QueryResolver implementation. +func (r *Resolver) Query() generated.QueryResolver { return &queryResolver{r} } + +type queryResolver struct{ *Resolver } diff --git a/demo/pkg/subgraphs/viewer/viewer.go b/demo/pkg/subgraphs/viewer/viewer.go new file mode 100644 index 0000000000..05cee0b164 --- /dev/null +++ b/demo/pkg/subgraphs/viewer/viewer.go @@ -0,0 +1,30 @@ +package viewer + +import ( + "net/http" + + "github.com/99designs/gqlgen/graphql" + "github.com/99designs/gqlgen/graphql/handler" + "github.com/99designs/gqlgen/graphql/handler/transport" + + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/viewer/subgraph" + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/viewer/subgraph/generated" +) + +func NewSchema() graphql.ExecutableSchema { + return generated.NewExecutableSchema(generated.Config{Resolvers: &subgraph.Resolver{}}) +} + +// NewHandler creates an HTTP handler that injects the request into context +// so resolvers can access the Authorization header. +func NewHandler() http.Handler { + schema := NewSchema() + srv := handler.New(schema) + srv.AddTransport(transport.POST{}) + srv.AddTransport(transport.GET{}) + + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + ctx := subgraph.WithHTTPRequest(r.Context(), r) + srv.ServeHTTP(w, r.WithContext(ctx)) + }) +} diff --git a/demo/router-cache-cp.yaml b/demo/router-cache-cp.yaml new file mode 100644 index 0000000000..7d312743bc --- /dev/null +++ b/demo/router-cache-cp.yaml @@ -0,0 +1,58 @@ +version: "1" + +# Connected to the local control plane — no execution_config.file. +# graph.token injected via GRAPH_API_TOKEN env var. + +storage_providers: + redis: + - id: "default" + urls: + - "redis://localhost:6379/2" + cluster_enabled: false + +entity_caching: + enabled: true + l1: + enabled: true + max_size: "100MB" + l2: + enabled: true + storage: + provider_id: "default" + key_prefix: "cosmo_entity_cache" + circuit_breaker: + enabled: false + +headers: + subgraphs: + cachegraph: + request: + - op: propagate + named: Authorization + - op: propagate + named: X-Artificial-Latency + cachegraph-ext: + request: + - op: propagate + named: X-Artificial-Latency + viewer: + request: + - op: propagate + named: Authorization + - op: propagate + named: X-Artificial-Latency + +# Needed because the demo cachegraph subgraphs use a non-standard header to inject +# synthetic latency for visible cache effect. All WG-standard headers (X-WG-Trace, +# X-WG-Token, X-WG-Disable-Entity-Cache*, etc.) are appended to AllowHeaders by the +# router automatically, so they do not need to be listed here. +cors: + allow_headers: + - X-Artificial-Latency + +log_level: debug +dev_mode: true +listen_addr: "localhost:3002" +playground: + enabled: true + path: "/" diff --git a/demo/router-cache.yaml b/demo/router-cache.yaml new file mode 100644 index 0000000000..4ec1e1fbce --- /dev/null +++ b/demo/router-cache.yaml @@ -0,0 +1,51 @@ +version: "1" + +execution_config: + file: + path: "../demo/config-cache-only.json" + +storage_providers: + memory: + - id: "default" + max_size: "100MB" + +entity_caching: + enabled: true + l1: + enabled: true + l2: + enabled: true + storage: + provider_id: "default" + key_prefix: "cosmo_entity_cache" + circuit_breaker: + enabled: false + +headers: + subgraphs: + cachegraph: + request: + - op: propagate + named: Authorization + - op: propagate + named: X-Artificial-Latency + cachegraph-ext: + request: + - op: propagate + named: X-Artificial-Latency + viewer: + request: + - op: propagate + named: Authorization + - op: propagate + named: X-Artificial-Latency + +graph: + token: "" + +log_level: debug +dev_mode: true +listen_addr: "localhost:3002" +playground: + enabled: true + path: "/" From 6f0c9157743775b6aab78d8a6ff620b6e8586d77 Mon Sep 17 00:00:00 2001 From: Milinda Dias Date: Wed, 10 Jun 2026 20:21:16 +0530 Subject: [PATCH 3/7] feat(router): entity caching with L1/L2, shadow mode, and per-request cache controls MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extracted from jensneuse/entity-caching-v2 (PR #2777) — router layer, stacked on the demo PR. Entity cache OTEL/Prometheus metrics are split into the next PR. - router/pkg/entitycache: in-memory L1, Redis L2, circuit breaker - router/core: factoryresolver mapping of proto cache config to planner metadata, graph server wiring, per-request cache-control headers (incl. WS subscriptions), EntityCacheKeyInterceptor module hook - graphql-go-tools pinned to 63fa1c88 (PR #1259 + v2.4.4 merged via entity-caching-v244-merge branch) — this also moves astjson to the caching arena rework (MergeValuesWithPath now returns 2 values; flushwriter adapted) - router-tests/entity_caching: integration suite consuming demo's cachetest subgraphs; config composed via wgc (composition-go was removed on main), testdata/config.json regenerated with main's composition - subscription-overhaul adaptation shims from the old base were dropped in favor of main's versions (websocket, flushwriter, executor, updater, mocks) Co-Authored-By: Claude Fable 5 --- .../entity_caching_standard_subgraphs_test.go | 291 ++ .../entitycaching/entitycaching_test.go | 2670 +++++++++++++++++ router-tests/entitycaching/harness_test.go | 523 ++++ router-tests/entitycaching/redis_test.go | 123 + router-tests/entitycaching/setup_test.go | 17 + .../entitycaching/testdata/config.json | 930 ++++++ router-tests/go.mod | 11 +- router-tests/go.sum | 12 +- router-tests/protocol/testdata/tracing.json | 52 + router-tests/testenv/testenv.go | 32 + router/core/executor.go | 78 +- router/core/executor_entity_cache_test.go | 200 ++ router/core/factoryresolver.go | 174 +- .../core/factoryresolver_entity_cache_test.go | 224 ++ router/core/factoryresolver_test.go | 55 + router/core/flushwriter.go | 2 +- router/core/graph_server.go | 179 +- router/core/graphql_handler.go | 71 + .../graphql_handler_caching_options_test.go | 172 ++ router/core/modules.go | 10 + router/core/router.go | 140 + router/core/router_config.go | 4 + router/core/router_entity_cache_test.go | 170 ++ router/core/supervisor_instance.go | 1 + router/core/websocket.go | 1 + router/go.mod | 6 +- router/go.sum | 12 +- router/pkg/config/config.go | 100 + router/pkg/config/config.schema.json | 147 + router/pkg/config/config_test.go | 212 ++ .../pkg/config/testdata/config_defaults.json | 21 + router/pkg/config/testdata/config_full.json | 21 + router/pkg/entitycache/circuit_breaker.go | 162 + .../pkg/entitycache/circuit_breaker_test.go | 373 +++ router/pkg/entitycache/memory.go | 128 + router/pkg/entitycache/memory_test.go | 274 ++ router/pkg/entitycache/redis.go | 86 + router/pkg/entitycache/redis_test.go | 191 ++ .../schemausage_bench_test.go | 2 +- .../graphqlschemausage/schemausage_test.go | 2 +- 40 files changed, 7822 insertions(+), 57 deletions(-) create mode 100644 router-tests/entity_caching_standard_subgraphs_test.go create mode 100644 router-tests/entitycaching/entitycaching_test.go create mode 100644 router-tests/entitycaching/harness_test.go create mode 100644 router-tests/entitycaching/redis_test.go create mode 100644 router-tests/entitycaching/setup_test.go create mode 100644 router-tests/entitycaching/testdata/config.json create mode 100644 router/core/executor_entity_cache_test.go create mode 100644 router/core/factoryresolver_entity_cache_test.go create mode 100644 router/core/factoryresolver_test.go create mode 100644 router/core/graphql_handler_caching_options_test.go create mode 100644 router/core/router_entity_cache_test.go create mode 100644 router/pkg/entitycache/circuit_breaker.go create mode 100644 router/pkg/entitycache/circuit_breaker_test.go create mode 100644 router/pkg/entitycache/memory.go create mode 100644 router/pkg/entitycache/memory_test.go create mode 100644 router/pkg/entitycache/redis.go create mode 100644 router/pkg/entitycache/redis_test.go diff --git a/router-tests/entity_caching_standard_subgraphs_test.go b/router-tests/entity_caching_standard_subgraphs_test.go new file mode 100644 index 0000000000..b39e63ca46 --- /dev/null +++ b/router-tests/entity_caching_standard_subgraphs_test.go @@ -0,0 +1,291 @@ +package integration + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/wundergraph/cosmo/router-tests/testenv" + "github.com/wundergraph/cosmo/router/core" + nodev1 "github.com/wundergraph/cosmo/router/gen/proto/wg/cosmo/node/v1" + "github.com/wundergraph/cosmo/router/pkg/config" + "github.com/wundergraph/cosmo/router/pkg/entitycache" + "github.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve" +) + +func newEntityMemoryCache(t *testing.T) *entitycache.MemoryEntityCache { + t.Helper() + c, err := entitycache.NewMemoryEntityCache(10 * 1024 * 1024) // 10MB for tests + require.NoError(t, err) + t.Cleanup(func() { _ = c.Close() }) + return c +} + +// entityCachingConfig returns RouterOptions that enable entity caching with +// the given MemoryEntityCache as the default L2 cache. +func entityCachingConfig(cache *entitycache.MemoryEntityCache) []core.Option { + return []core.Option{ + core.WithEntityCaching(config.EntityCachingConfiguration{ + Enabled: true, + L1: config.EntityCachingL1Configuration{ + Enabled: true, + }, + L2: config.EntityCachingL2Configuration{ + Enabled: true, + }, + }), + core.WithEntityCacheInstances(map[string]resolve.LoaderCache{ + "default": cache, + }), + } +} + +// addEntityCacheConfig adds entity cache configuration to all datasources +// in the router config with the given TTL in seconds. +func addEntityCacheConfig(routerConfig *nodev1.RouterConfig, ttlSeconds int64) { + for _, ds := range routerConfig.EngineConfig.DatasourceConfigurations { + for _, key := range ds.Keys { + if key.DisableEntityResolver { + continue + } + ds.EntityCacheConfigurations = append(ds.EntityCacheConfigurations, &nodev1.EntityCacheConfiguration{ + TypeName: key.TypeName, + MaxAgeSeconds: ttlSeconds, + }) + } + } +} + +func TestEntityCaching(t *testing.T) { + t.Parallel() + + // Cross-subgraph query: employee root from employees subgraph, + // products field resolved by products subgraph via _entities. + // Entity caching intercepts the _entities call. + const crossSubgraphQuery = `{ employee(id: 1) { id products } }` + + t.Run("basic L2 miss then hit", func(t *testing.T) { + t.Parallel() + + cache := newEntityMemoryCache(t) + testenv.Run(t, &testenv.Config{ + RouterOptions: entityCachingConfig(cache), + ModifyRouterConfig: func(routerConfig *nodev1.RouterConfig) { + addEntityCacheConfig(routerConfig, 300) + }, + }, func(t *testing.T, xEnv *testenv.Environment) { + // First request: cache miss, both employees and products subgraphs called + res := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{Query: crossSubgraphQuery}) + require.Contains(t, res.Body, `"products"`) + + productsCountAfterFirst := xEnv.SubgraphRequestCount.Products.Load() + require.Equal(t, int64(1), productsCountAfterFirst) + + // Second request: entity cache hit, products subgraph NOT called again + res2 := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{Query: crossSubgraphQuery}) + require.Equal(t, res.Body, res2.Body) + require.Equal(t, int64(1), xEnv.SubgraphRequestCount.Products.Load()) + }) + }) + + t.Run("different entities produce separate cache entries", func(t *testing.T) { + t.Parallel() + + cache := newEntityMemoryCache(t) + testenv.Run(t, &testenv.Config{ + RouterOptions: entityCachingConfig(cache), + ModifyRouterConfig: func(routerConfig *nodev1.RouterConfig) { + addEntityCacheConfig(routerConfig, 300) + }, + }, func(t *testing.T, xEnv *testenv.Environment) { + // Fetch employee 1 products + res1 := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ employee(id: 1) { id products } }`, + }) + require.Contains(t, res1.Body, `"products"`) + + // Fetch employee 3 products (different entity — cache miss) + res2 := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ employee(id: 3) { id products } }`, + }) + require.Contains(t, res2.Body, `"products"`) + + // Products subgraph called twice (once per distinct employee) + require.Equal(t, int64(2), xEnv.SubgraphRequestCount.Products.Load()) + + // Now re-fetch employee 1 — should be cached + res3 := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ employee(id: 1) { id products } }`, + }) + require.Equal(t, res1.Body, res3.Body) + require.Equal(t, int64(2), xEnv.SubgraphRequestCount.Products.Load()) + }) + }) + + t.Run("multi-subgraph entity caching", func(t *testing.T) { + t.Parallel() + + cache := newEntityMemoryCache(t) + testenv.Run(t, &testenv.Config{ + RouterOptions: entityCachingConfig(cache), + ModifyRouterConfig: func(routerConfig *nodev1.RouterConfig) { + addEntityCacheConfig(routerConfig, 300) + }, + }, func(t *testing.T, xEnv *testenv.Environment) { + // First query hits products subgraph via _entities + res := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ employee(id: 1) { id products } }`, + }) + require.Contains(t, res.Body, `"products"`) + require.Equal(t, int64(1), xEnv.SubgraphRequestCount.Products.Load()) + + // Second query hits availability subgraph via _entities + res2 := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ employee(id: 1) { id isAvailable } }`, + }) + require.Contains(t, res2.Body, `"isAvailable"`) + require.Equal(t, int64(1), xEnv.SubgraphRequestCount.Availability.Load()) + + // Re-fetch both: products and availability should be cached + xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ employee(id: 1) { id products } }`, + }) + xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ employee(id: 1) { id isAvailable } }`, + }) + require.Equal(t, int64(1), xEnv.SubgraphRequestCount.Products.Load()) + require.Equal(t, int64(1), xEnv.SubgraphRequestCount.Availability.Load()) + }) + }) + + t.Run("per-subgraph cache name routes to separate instances", func(t *testing.T) { + t.Parallel() + + defaultCache := newEntityMemoryCache(t) + customCache := newEntityMemoryCache(t) + + testenv.Run(t, &testenv.Config{ + RouterOptions: []core.Option{ + core.WithEntityCaching(config.EntityCachingConfiguration{ + Enabled: true, + L1: config.EntityCachingL1Configuration{Enabled: true}, + L2: config.EntityCachingL2Configuration{Enabled: true}, + SubgraphCacheOverrides: []config.EntityCachingSubgraphCacheOverride{ + { + Name: "products", + Entities: []config.EntityCachingEntityConfig{ + {Type: "Employee", StorageProviderID: "custom"}, + }, + }, + }, + }), + core.WithEntityCacheInstances(map[string]resolve.LoaderCache{ + "default": defaultCache, + "custom": customCache, + }), + }, + ModifyRouterConfig: func(routerConfig *nodev1.RouterConfig) { + addEntityCacheConfig(routerConfig, 300) + }, + }, func(t *testing.T, xEnv *testenv.Environment) { + res := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: crossSubgraphQuery, + }) + require.Contains(t, res.Body, `"products"`) + + // The custom cache should have entries (Employee on products routed to "custom") + require.Equal(t, 1, customCache.Len()) + }) + }) + + t.Run("shadow mode always fetches from subgraph", func(t *testing.T) { + t.Parallel() + + cache := newEntityMemoryCache(t) + testenv.Run(t, &testenv.Config{ + RouterOptions: entityCachingConfig(cache), + ModifyRouterConfig: func(routerConfig *nodev1.RouterConfig) { + for _, ds := range routerConfig.EngineConfig.DatasourceConfigurations { + for _, key := range ds.Keys { + if key.DisableEntityResolver { + continue + } + ds.EntityCacheConfigurations = append(ds.EntityCacheConfigurations, &nodev1.EntityCacheConfiguration{ + TypeName: key.TypeName, + MaxAgeSeconds: 300, + ShadowMode: true, + }) + } + } + }, + }, func(t *testing.T, xEnv *testenv.Environment) { + // First request + res := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{Query: crossSubgraphQuery}) + require.Contains(t, res.Body, `"products"`) + productsFirst := xEnv.SubgraphRequestCount.Products.Load() + + // Second request: in shadow mode, subgraph ALWAYS called + xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{Query: crossSubgraphQuery}) + require.Equal(t, productsFirst+1, xEnv.SubgraphRequestCount.Products.Load()) + }) + }) + + t.Run("list query with caching", func(t *testing.T) { + t.Parallel() + + cache := newEntityMemoryCache(t) + testenv.Run(t, &testenv.Config{ + RouterOptions: entityCachingConfig(cache), + ModifyRouterConfig: func(routerConfig *nodev1.RouterConfig) { + addEntityCacheConfig(routerConfig, 300) + }, + }, func(t *testing.T, xEnv *testenv.Environment) { + // List query that fetches multiple employees with cross-subgraph products + query := `{ employees { id products } }` + res := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{Query: query}) + require.Contains(t, res.Body, `"employees"`) + productsFirst := xEnv.SubgraphRequestCount.Products.Load() + require.Equal(t, int64(1), productsFirst) + + // Second list query: all _entities calls should be cached + res2 := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{Query: query}) + require.Equal(t, res.Body, res2.Body) + require.Equal(t, int64(1), xEnv.SubgraphRequestCount.Products.Load()) + }) + }) + + t.Run("disabled caching does not cache", func(t *testing.T) { + t.Parallel() + + testenv.Run(t, &testenv.Config{ + // No entity caching options + }, func(t *testing.T, xEnv *testenv.Environment) { + res := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{Query: crossSubgraphQuery}) + require.Contains(t, res.Body, `"products"`) + productsFirst := xEnv.SubgraphRequestCount.Products.Load() + + // Second request: products subgraph called again (no caching) + xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{Query: crossSubgraphQuery}) + require.Equal(t, productsFirst+1, xEnv.SubgraphRequestCount.Products.Load()) + }) + }) + + t.Run("cache entries written to L2", func(t *testing.T) { + t.Parallel() + + cache := newEntityMemoryCache(t) + testenv.Run(t, &testenv.Config{ + RouterOptions: entityCachingConfig(cache), + ModifyRouterConfig: func(routerConfig *nodev1.RouterConfig) { + addEntityCacheConfig(routerConfig, 300) + }, + }, func(t *testing.T, xEnv *testenv.Environment) { + require.Equal(t, 0, cache.Len()) + + xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{Query: crossSubgraphQuery}) + + // After first request, cache should have entries + require.Equal(t, 1, cache.Len()) + }) + }) +} diff --git a/router-tests/entitycaching/entitycaching_test.go b/router-tests/entitycaching/entitycaching_test.go new file mode 100644 index 0000000000..44092bdce0 --- /dev/null +++ b/router-tests/entitycaching/entitycaching_test.go @@ -0,0 +1,2670 @@ +package entitycaching + +import ( + "encoding/json" + "net/http" + "sync/atomic" + "testing" + "time" + + "github.com/stretchr/testify/require" + + itemsModel "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachetest/items/subgraph/model" + "github.com/wundergraph/cosmo/router-tests/testenv" + "github.com/wundergraph/cosmo/router/core" + nodev1 "github.com/wundergraph/cosmo/router/gen/proto/wg/cosmo/node/v1" + "github.com/wundergraph/cosmo/router/pkg/config" + "github.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve" +) + +func TestEntityCaching(t *testing.T) { + t.Parallel() + + t.Run("L2/basic miss then hit", func(t *testing.T) { + t.Parallel() + + servers, counters := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + cache := newMemoryCache(t) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: entityCachingL2OnlyOptions(cache), + }, func(t *testing.T, xEnv *testenv.Environment) { + req := testenv.GraphQLRequest{ + Query: `{ item(id: "1") { id name description } }`, + } + res := xEnv.MakeGraphQLRequestOK(req) + require.Equal(t, `{"data":{"item":{"id":"1","name":"Widget","description":"A versatile widget for everyday use"}}}`, res.Body) + + detailsAfterFirst := counters.details.Load() + require.Equal(t, int64(1), detailsAfterFirst) + + res2 := xEnv.MakeGraphQLRequestOK(req) + require.Equal(t, `{"data":{"item":{"id":"1","name":"Widget","description":"A versatile widget for everyday use"}}}`, res2.Body) + + // Details subgraph should NOT be called again (cache hit) + require.Equal(t, int64(1), counters.details.Load()) + }) + }) + + t.Run("L2/different entities use separate entries", func(t *testing.T) { + t.Parallel() + + servers, _ := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + cache := newMemoryCache(t) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: entityCachingL2OnlyOptions(cache), + }, func(t *testing.T, xEnv *testenv.Environment) { + reqItem1 := testenv.GraphQLRequest{ + Query: `{ item(id: "1") { id name description } }`, + } + res1 := xEnv.MakeGraphQLRequestOK(reqItem1) + require.Equal(t, `{"data":{"item":{"id":"1","name":"Widget","description":"A versatile widget for everyday use"}}}`, res1.Body) + + res2 := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ item(id: "2") { id name description } }`, + }) + require.Equal(t, `{"data":{"item":{"id":"2","name":"Gadget","description":"A high-tech gadget with many features"}}}`, res2.Body) + + // Both entities should produce cache entries + require.Equal(t, 2, cache.Len()) + + // Re-fetch id:"1" — verify response correctness + res3 := xEnv.MakeGraphQLRequestOK(reqItem1) + require.Equal(t, `{"data":{"item":{"id":"1","name":"Widget","description":"A versatile widget for everyday use"}}}`, res3.Body) + }) + }) + + t.Run("L2/list query caching", func(t *testing.T) { + t.Parallel() + + servers, counters := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + cache := newMemoryCache(t) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: entityCachingL2OnlyOptions(cache), + }, func(t *testing.T, xEnv *testenv.Environment) { + req := testenv.GraphQLRequest{ + Query: `{ items { id description rating } }`, + } + res := xEnv.MakeGraphQLRequestOK(req) + require.Contains(t, res.Body, `"description"`) + require.Contains(t, res.Body, `"rating"`) + + detailsAfterFirst := counters.details.Load() + require.Equal(t, int64(1), detailsAfterFirst) + + res2 := xEnv.MakeGraphQLRequestOK(req) + require.Equal(t, res.Body, res2.Body) + require.Equal(t, int64(1), counters.details.Load()) + }) + }) + + t.Run("L2/cache entries are written", func(t *testing.T) { + t.Parallel() + + servers, _ := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + cache := newMemoryCache(t) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: entityCachingL2OnlyOptions(cache), + }, func(t *testing.T, xEnv *testenv.Environment) { + require.Equal(t, 0, cache.Len()) + + xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ item(id: "1") { id description } }`, + }) + + require.Equal(t, 1, cache.Len()) + }) + }) + + t.Run("L2/disabled caching does not cache", func(t *testing.T) { + t.Parallel() + + servers, counters := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + ModifyRouterConfig: func(routerConfig *nodev1.RouterConfig) { + clearEntityCacheConfigs(routerConfig) + }, + }, func(t *testing.T, xEnv *testenv.Environment) { + req := testenv.GraphQLRequest{ + Query: `{ item(id: "1") { id name description } }`, + } + xEnv.MakeGraphQLRequestOK(req) + detailsFirst := counters.details.Load() + require.Equal(t, int64(1), detailsFirst) + + xEnv.MakeGraphQLRequestOK(req) + // Details subgraph called again (no caching) + require.Equal(t, int64(2), counters.details.Load()) + }) + }) + + t.Run("L2/multi-subgraph caching", func(t *testing.T) { + t.Parallel() + + servers, counters := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + cache := newMemoryCache(t) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: entityCachingL2OnlyOptions(cache), + }, func(t *testing.T, xEnv *testenv.Environment) { + // Fetch description (from details subgraph) + xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ item(id: "1") { id description } }`, + }) + detailsAfterFirst := counters.details.Load() + require.Equal(t, int64(1), detailsAfterFirst) + + // Fetch available (from inventory subgraph) + xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ item(id: "1") { id available } }`, + }) + inventoryAfterFirst := counters.inventory.Load() + require.Equal(t, int64(1), inventoryAfterFirst) + + // Re-fetch both: should be cached + xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ item(id: "1") { id description } }`, + }) + xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ item(id: "1") { id available } }`, + }) + + require.Equal(t, detailsAfterFirst, counters.details.Load()) + require.Equal(t, inventoryAfterFirst, counters.inventory.Load()) + }) + }) + + t.Run("L2/cross-subgraph combined query", func(t *testing.T) { + t.Parallel() + + servers, counters := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + cache := newMemoryCache(t) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: entityCachingL2OnlyOptions(cache), + }, func(t *testing.T, xEnv *testenv.Environment) { + req := testenv.GraphQLRequest{ + Query: `{ item(id: "1") { id name description available } }`, + } + res := xEnv.MakeGraphQLRequestOK(req) + require.Equal(t, `{"data":{"item":{"id":"1","name":"Widget","description":"A versatile widget for everyday use","available":true}}}`, res.Body) + + detailsAfterFirst := counters.details.Load() + inventoryAfterFirst := counters.inventory.Load() + + res2 := xEnv.MakeGraphQLRequestOK(req) + require.Equal(t, `{"data":{"item":{"id":"1","name":"Widget","description":"A versatile widget for everyday use","available":true}}}`, res2.Body) + + require.Equal(t, detailsAfterFirst, counters.details.Load()) + require.Equal(t, inventoryAfterFirst, counters.inventory.Load()) + }) + }) + + t.Run("Shadow/always fetches", func(t *testing.T) { + t.Parallel() + + servers, counters := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + cache := newMemoryCache(t) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: entityCachingOptions(cache), + ModifyRouterConfig: func(routerConfig *nodev1.RouterConfig) { + setEntityCacheShadowMode(routerConfig, true) + }, + }, func(t *testing.T, xEnv *testenv.Environment) { + req := testenv.GraphQLRequest{ + Query: `{ item(id: "1") { id name description } }`, + } + xEnv.MakeGraphQLRequestOK(req) + detailsFirst := counters.details.Load() + + xEnv.MakeGraphQLRequestOK(req) + // Shadow mode: subgraph ALWAYS called, but cache is populated + require.Equal(t, detailsFirst+1, counters.details.Load()) + require.Equal(t, 1, cache.Len()) + }) + }) + + t.Run("L2/partial cache load", func(t *testing.T) { + t.Parallel() + + servers, counters := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + cache := newMemoryCache(t) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: entityCachingL2OnlyOptions(cache), + ModifyRouterConfig: func(routerConfig *nodev1.RouterConfig) { + setEntityCachePartialLoad(routerConfig, true) + }, + }, func(t *testing.T, xEnv *testenv.Environment) { + // Warm cache for id:"1" — this populates one entity entry in L2. + xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ item(id: "1") { id description } }`, + }) + detailsAfterWarm := counters.details.Load() + require.Equal(t, int64(1), detailsAfterWarm) + require.GreaterOrEqual(t, cache.Len(), 1, + "warm-up must populate at least one L2 entity entry before the partial-load path is exercised") + cacheLenAfterWarm := cache.Len() + + // List query: id:"1" served from cache, other IDs fetched from + // details. With L2 disabled the warm-up wouldn't have written + // anything, so this assertion of exactly one additional details + // call only holds when partial-load actually reads from L2. + xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ items { id description } }`, + }) + require.Equal(t, detailsAfterWarm+1, counters.details.Load(), + "partial-load must fetch only the uncached entities; one extra details call expected") + + // After the list query every entity is cached. + require.Greater(t, cache.Len(), cacheLenAfterWarm, + "partial-load must write the newly-fetched entities back to L2 so subsequent reads are served from cache") + + // Repeat list query: all entities now cached → no additional details call. + detailsBeforeRepeat := counters.details.Load() + xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ items { id description } }`, + }) + require.Equal(t, detailsBeforeRepeat, counters.details.Load(), + "repeat list query must be served entirely from cache — this fails if L2 is off") + }) + }) + + t.Run("L2/TTL expiry", func(t *testing.T) { + t.Parallel() + + servers, counters := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + cache := newMemoryCache(t) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: entityCachingL2OnlyOptions(cache), + ModifyRouterConfig: func(routerConfig *nodev1.RouterConfig) { + setEntityCacheTTL(routerConfig, 1) + }, + }, func(t *testing.T, xEnv *testenv.Environment) { + req := testenv.GraphQLRequest{ + Query: `{ item(id: "1") { id description } }`, + } + xEnv.MakeGraphQLRequestOK(req) + detailsAfterFirst := counters.details.Load() + + // Immediately, should be cached + xEnv.MakeGraphQLRequestOK(req) + require.Equal(t, detailsAfterFirst, counters.details.Load()) + + // Wait for TTL expiry + time.Sleep(1500 * time.Millisecond) + + // After expiry, cache miss + xEnv.MakeGraphQLRequestOK(req) + require.Equal(t, detailsAfterFirst+1, counters.details.Load()) + }) + }) + + t.Run("L2/per-subgraph cache name", func(t *testing.T) { + t.Parallel() + + servers, _ := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + defaultCache := newMemoryCache(t) + customCache := newMemoryCache(t) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: entityCachingOptionsWithSubgraphConfig( + map[string]resolve.LoaderCache{ + "default": defaultCache, + "custom": customCache, + }, + []config.EntityCachingSubgraphCacheOverride{ + { + Name: "details", + Entities: []config.EntityCachingEntityConfig{ + {Type: "Item", StorageProviderID: "custom"}, + }, + }, + }, + ), + }, func(t *testing.T, xEnv *testenv.Environment) { + xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ item(id: "1") { id description } }`, + }) + + require.Equal(t, 1, customCache.Len()) + }) + }) + + t.Run("L2/include headers varies cache key", func(t *testing.T) { + t.Parallel() + + servers, counters := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + cache := newMemoryCache(t) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: append( + entityCachingL2OnlyOptions(cache), + core.WithHeaderRules(config.HeaderRules{ + All: &config.GlobalHeaderRule{ + Request: []*config.RequestHeaderRule{ + { + Operation: config.HeaderRuleOperationPropagate, + Named: "X-Tenant", + }, + }, + }, + }), + ), + ModifyRouterConfig: func(routerConfig *nodev1.RouterConfig) { + setEntityCacheIncludeHeaders(routerConfig, true) + }, + }, func(t *testing.T, xEnv *testenv.Environment) { + // Request with header A + xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ item(id: "1") { id description } }`, + Header: map[string][]string{"X-Tenant": {"A"}}, + }) + detailsAfterA := counters.details.Load() + + // Request with header B — different cache key, miss + xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ item(id: "1") { id description } }`, + Header: map[string][]string{"X-Tenant": {"B"}}, + }) + detailsAfterB := counters.details.Load() + require.Equal(t, detailsAfterA+1, detailsAfterB) + + // Request with header A again — should hit + xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ item(id: "1") { id description } }`, + Header: map[string][]string{"X-Tenant": {"A"}}, + }) + require.Equal(t, detailsAfterB, counters.details.Load()) + }) + }) + + t.Run("L2/negative TTL caches not-found response within window", func(t *testing.T) { + // Exercises the entity-level not-found cache: items subgraph has an id + // that details subgraph does NOT have. On first fetch, details' + // _entities resolver returns null for that key. With notFoundCacheTtl + // set, the router caches the null result so the second fetch skips the + // details subgraph. Verifying via counters.details (rather than + // counters.items) is the signal the reviewer asked for: the items + // subgraph is always called in this flow, so only the details counter + // distinguishes a not-found cache hit from a miss. + t.Parallel() + + servers, counters := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + cache := newMemoryCache(t) + + // Create an item in items-subgraph via mutation, but details-subgraph + // has no record for the new id — entity hydration will return null. + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: entityCachingL2OnlyOptions(cache), + ModifyRouterConfig: func(routerConfig *nodev1.RouterConfig) { + setNotFoundCacheTTL(routerConfig, 60) + }, + }, func(t *testing.T, xEnv *testenv.Environment) { + // Reserve a new id by creating the item in items-subgraph. + createRes := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `mutation { createItem(name: "Ghost", category: "phantom") { id } }`, + }) + var created struct { + Data struct { + CreateItem struct { + ID string `json:"id"` + } `json:"createItem"` + } `json:"data"` + } + require.NoError(t, json.Unmarshal([]byte(createRes.Body), &created)) + require.NotEmpty(t, created.Data.CreateItem.ID) + newID := created.Data.CreateItem.ID + + req := testenv.GraphQLRequest{ + Query: `{ item(id: "` + newID + `") { id description } }`, + } + // First query: items returns the new entity, details returns null. + // The details subgraph IS called once. + xEnv.MakeGraphQLRequestOK(req) + require.Equal(t, int64(1), counters.details.Load(), + "first request must hit the details entity subgraph for the not-found hydration") + + // Second query: with notFoundCacheTtl, the null entity is cached, + // so details is NOT called again. With L2 disabled this counter + // would grow to 2. + xEnv.MakeGraphQLRequestOK(req) + require.Equal(t, int64(1), counters.details.Load(), + "not-found cache must short-circuit the details subgraph; with L2 disabled this counter would be 2") + }) + }) + + t.Run("L2/root field caching with key mapping", func(t *testing.T) { + t.Parallel() + + servers, counters := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + cache := newMemoryCache(t) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: entityCachingL2OnlyOptions(cache), + }, func(t *testing.T, xEnv *testenv.Environment) { + req := testenv.GraphQLRequest{ + Query: `{ item(id: "1") { id name description } }`, + } + // Cross-subgraph query to trigger both root-field and entity caching. + res := xEnv.MakeGraphQLRequestOK(req) + require.Equal(t, `{"data":{"item":{"id":"1","name":"Widget","description":"A versatile widget for everyday use"}}}`, res.Body) + + itemsAfterFirst := counters.items.Load() + detailsAfterFirst := counters.details.Load() + require.Equal(t, int64(1), itemsAfterFirst) + require.Equal(t, int64(1), detailsAfterFirst) + require.GreaterOrEqual(t, cache.Len(), 1) + + // Same query — both root-field (items) AND entity (details) caches + // must hit. Asserting on counters.items specifically is what the + // reviewer asked for: the previous form only checked details and + // so would pass even if @queryCache were completely ignored. + res2 := xEnv.MakeGraphQLRequestOK(req) + require.Equal(t, `{"data":{"item":{"id":"1","name":"Widget","description":"A versatile widget for everyday use"}}}`, res2.Body) + require.Equal(t, itemsAfterFirst, counters.items.Load(), + "root-field cache hit: items subgraph must NOT be re-fetched; with @queryCache ignored this counter would be 2") + require.Equal(t, detailsAfterFirst, counters.details.Load(), + "entity cache hit: details subgraph must NOT be re-fetched") + }) + }) + + t.Run("L2/root field list caching", func(t *testing.T) { + t.Parallel() + + servers, counters := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + cache := newMemoryCache(t) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: entityCachingL2OnlyOptions(cache), + }, func(t *testing.T, xEnv *testenv.Environment) { + req := testenv.GraphQLRequest{ + Query: `{ items { id name description } }`, + } + // Cross-subgraph list query: exercises both the root-field cache + // on the items subgraph and the per-entity cache on details. + res := xEnv.MakeGraphQLRequestOK(req) + require.Contains(t, res.Body, `"Widget"`) + require.Contains(t, res.Body, `"description"`) + + itemsAfterFirst := counters.items.Load() + detailsAfterFirst := counters.details.Load() + require.Equal(t, int64(1), itemsAfterFirst) + require.Equal(t, int64(1), detailsAfterFirst) + + // 5 entity entries (one per item) + 1 root field L2 entry. + require.Equal(t, 6, cache.Len()) + + // Same query — both root-field AND entity caches must hit. + // Asserting counters.items (not only details) is what the reviewer + // asked for: with @queryCache ignored, items would be refetched. + res2 := xEnv.MakeGraphQLRequestOK(req) + require.Equal(t, res.Body, res2.Body) + require.Equal(t, itemsAfterFirst, counters.items.Load(), + "root-field cache hit: items subgraph must NOT be re-fetched") + require.Equal(t, detailsAfterFirst, counters.details.Load(), + "entity cache hit: details subgraph must NOT be re-fetched") + }) + }) + + t.Run("L2/root field different args use different cache keys", func(t *testing.T) { + t.Parallel() + + servers, counters := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + cache := newMemoryCache(t) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: entityCachingL2OnlyOptions(cache), + }, func(t *testing.T, xEnv *testenv.Environment) { + // Different arguments must produce different cache keys (two entries). + xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ item(id: "1") { id name } }`, + }) + xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ item(id: "2") { id name } }`, + }) + require.Equal(t, int64(2), counters.items.Load()) + require.GreaterOrEqual(t, cache.Len(), 2, + "each distinct args tuple must produce its own cache entry") + + // Repeat both calls — each must be a cache hit, so items counter + // stays at 2. With @queryCache ignored (or L2 disabled) items + // would climb to 4. + xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ item(id: "1") { id name } }`, + }) + xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ item(id: "2") { id name } }`, + }) + require.Equal(t, int64(2), counters.items.Load(), + "repeat calls must be cache hits on the items root field; with L2 disabled this would be 4") + }) + }) + + t.Run("Shadow/query cache always fetches", func(t *testing.T) { + t.Parallel() + + servers, counters := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + cache := newMemoryCache(t) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: entityCachingOptions(cache), + ModifyRouterConfig: func(routerConfig *nodev1.RouterConfig) { + setQueryCacheShadowMode(routerConfig, true) + }, + }, func(t *testing.T, xEnv *testenv.Environment) { + req := testenv.GraphQLRequest{ + Query: `{ item(id: "1") { id name } }`, + } + xEnv.MakeGraphQLRequestOK(req) + itemsFirst := counters.items.Load() + // Shadow mode MUST populate the cache even though it does not read + // from it — that's the whole point. Without L2, cache.Len() stays + // at 0 and this assertion fails. + require.GreaterOrEqual(t, cache.Len(), 1, + "shadow mode must still WRITE the root-field entry to L2") + + // Shadow mode: items subgraph is called on the second request too. + xEnv.MakeGraphQLRequestOK(req) + require.Equal(t, itemsFirst+1, counters.items.Load(), + "shadow mode must always fetch from the items subgraph") + }) + }) + + t.Run("L2/mutation invalidates cache", func(t *testing.T) { + t.Parallel() + + servers, counters := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + cache := newMemoryCache(t) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: entityCachingL2OnlyOptions(cache), + }, func(t *testing.T, xEnv *testenv.Environment) { + req := testenv.GraphQLRequest{ + Query: `{ item(id: "1") { id name description } }`, + } + // Warm cache + xEnv.MakeGraphQLRequestOK(req) + detailsAfterWarm := counters.details.Load() + + // Verify cache hit + xEnv.MakeGraphQLRequestOK(req) + require.Equal(t, detailsAfterWarm, counters.details.Load()) + + // Mutation triggers @cacheInvalidate + xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `mutation { updateItem(id: "1", name: "Updated Widget") { id name } }`, + }) + + // After invalidation, cache miss → details subgraph called again + xEnv.MakeGraphQLRequestOK(req) + require.Equal(t, detailsAfterWarm+1, counters.details.Load()) + }) + }) + + t.Run("L2/mutation populates cache", func(t *testing.T) { + t.Parallel() + + servers, counters := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + cache := newMemoryCache(t) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: entityCachingL2OnlyOptions(cache), + }, func(t *testing.T, xEnv *testenv.Environment) { + lenBefore := cache.Len() + + // createItem has @cachePopulate(maxAge: 60). The mutation response + // body alone isn't a caching signal — we need to verify the L2 was + // actually written and that a follow-up read hits cache. + res := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `mutation { createItem(name: "Foobar", category: "test") { id name category } }`, + }) + require.Contains(t, res.Body, `"Foobar"`) + + // @cachePopulate MUST have added at least one entry to L2. With + // L2.Enabled=false, lenAfter stays at lenBefore. + require.Greater(t, cache.Len(), lenBefore, + "@cachePopulate must write the mutation result to L2") + + // Extract the newly-created id and verify a follow-up read by id + // is served from cache (items subgraph not called again). + var body struct { + Data struct { + CreateItem struct { + ID string `json:"id"` + } `json:"createItem"` + } `json:"data"` + } + require.NoError(t, json.Unmarshal([]byte(res.Body), &body)) + newID := body.Data.CreateItem.ID + require.NotEmpty(t, newID) + + itemsAfterMutation := counters.items.Load() + readRes := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ item(id: "` + newID + `") { id name category } }`, + }) + require.Equal(t, + `{"data":{"item":{"id":"`+newID+`","name":"Foobar","category":"test"}}}`, + readRes.Body) + require.Equal(t, itemsAfterMutation, counters.items.Load(), + "follow-up read must be a cache hit (items subgraph not called); with L2 disabled this counter would be itemsAfterMutation+1") + }) + }) + + // Tests that the full circuit breaker lifecycle keeps requests working: + // cache healthy → cache breaks → breaker opens → cache recovers → breaker closes. + // At every phase, GraphQL queries must return correct data. The subgraph call + // counter proves whether the response came from cache (counter unchanged) or + // from a subgraph fetch (counter incremented). + t.Run("L2/circuit breaker degrades gracefully on cache failure", func(t *testing.T) { + t.Parallel() + + servers, counters := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + + cache := newControllableCache(t) + cooldown := 100 * time.Millisecond + opts, cb := entityCachingOptionsWithCircuitBreakerRef(cache, 2, cooldown) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: opts, + }, func(t *testing.T, xEnv *testenv.Environment) { + const query = `{ item(id: "1") { id name description } }` + const expected = `{"data":{"item":{"id":"1","name":"Widget","description":"A versatile widget for everyday use"}}}` + + // Phase 1: Cache is healthy. First request populates cache. + res := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{Query: query}) + require.Equal(t, expected, res.Body) + detailsAfterFirst := counters.details.Load() + require.Equal(t, int64(1), detailsAfterFirst) + + // Second request should be a cache hit — subgraph counter stays the same. + res = xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{Query: query}) + require.Equal(t, expected, res.Body) + require.Equal(t, detailsAfterFirst, counters.details.Load(), "expected cache hit: details counter should not change") + + // Phase 2: Cache starts failing. Breaker is still closed, so it tries the cache + // and gets errors. Requests still succeed via subgraph fallback. + cache.SetFailing(true) + for range 2 { + res = xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{Query: query}) + require.Equal(t, expected, res.Body) + } + require.True(t, cb.IsOpen(), "breaker should be open after 2 consecutive failures") + + // Phase 3: Breaker is open — cache is bypassed entirely. + // Subgraph counter should increase with every request. + counterBefore := counters.details.Load() + res = xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{Query: query}) + require.Equal(t, expected, res.Body) + require.Equal(t, counterBefore+1, counters.details.Load(), "expected subgraph fetch when breaker is open") + + // Phase 4: Cache recovers. Wait for cooldown so breaker transitions to half-open. + cache.SetFailing(false) + time.Sleep(cooldown + 50*time.Millisecond) + + // The next request is the half-open probe. It should succeed and close the breaker. + res = xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{Query: query}) + require.Equal(t, expected, res.Body) + require.False(t, cb.IsOpen(), "breaker should be closed after successful probe") + + // Phase 5: Cache works again. Verify we get a cache hit. + detailsBefore := counters.details.Load() + res = xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{Query: query}) + require.Equal(t, expected, res.Body) + require.Equal(t, detailsBefore, counters.details.Load(), "expected cache hit after recovery") + }) + }) + + // Focused test for the half-open → closed transition. + // Trips the breaker, waits for cooldown, then verifies that one successful + // probe closes the breaker and the cache resumes normal operation. + t.Run("L2/circuit breaker recovers after cooldown", func(t *testing.T) { + t.Parallel() + + servers, counters := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + + cache := newControllableCache(t) + cooldown := 100 * time.Millisecond + cache.SetFailing(true) // Start broken + + opts, cb := entityCachingOptionsWithCircuitBreakerRef(cache, 2, cooldown) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: opts, + }, func(t *testing.T, xEnv *testenv.Environment) { + const query = `{ item(id: "1") { id name description } }` + const expected = `{"data":{"item":{"id":"1","name":"Widget","description":"A versatile widget for everyday use"}}}` + + // Trip the breaker: 2 failures while closed. + for range 2 { + res := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{Query: query}) + require.Equal(t, expected, res.Body) + } + require.True(t, cb.IsOpen(), "breaker should be open after threshold failures") + + // Fix the cache and wait for cooldown. + cache.SetFailing(false) + time.Sleep(cooldown + 50*time.Millisecond) + + // Probe request: succeeds, closes the breaker, populates cache. + res := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{Query: query}) + require.Equal(t, expected, res.Body) + require.False(t, cb.IsOpen(), "breaker should be closed after successful probe") + + // Next request should be a cache hit — subgraph not called. + detailsBefore := counters.details.Load() + res = xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{Query: query}) + require.Equal(t, expected, res.Body) + require.Equal(t, detailsBefore, counters.details.Load(), "expected cache hit after recovery") + }) + }) + + t.Run("L2/subscription invalidates cache", func(t *testing.T) { + t.Parallel() + + servers, counters := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + cache := newMemoryCache(t) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: entityCachingL2OnlyOptions(cache), + }, func(t *testing.T, xEnv *testenv.Environment) { + req := testenv.GraphQLRequest{ + Query: `{ item(id: "1") { id name description } }`, + } + // Warm cache + res := xEnv.MakeGraphQLRequestOK(req) + require.Equal(t, `{"data":{"item":{"id":"1","name":"Widget","description":"A versatile widget for everyday use"}}}`, res.Body) + + detailsAfterWarm := counters.details.Load() + + // Verify cache hit + xEnv.MakeGraphQLRequestOK(req) + require.Equal(t, detailsAfterWarm, counters.details.Load()) + + // Start subscription via WebSocket (itemUpdated has @cacheInvalidate) + conn := xEnv.InitGraphQLWebSocketConnection(nil, nil, nil) + + err := testenv.WSWriteJSON(t, conn, testenv.WebSocketMessage{ + ID: "1", + Type: "subscribe", + // Select ONLY key fields so the engine uses SubscriptionCacheModeInvalidate. + // Selecting non-key fields would cause SubscriptionCacheModePopulate instead. + Payload: []byte(`{"query":"subscription { itemUpdated { id } }"}`), + }) + require.NoError(t, err) + + // Push event in background after subscription is established + go func() { + xEnv.WaitForSubscriptionCount(1, 5*time.Second) + servers.itemUpdatedCh <- &itemsModel.Item{ID: "1", Name: "Updated Widget", Category: "tools"} + }() + + // Read subscription event + var msg testenv.WebSocketMessage + err = testenv.WSReadJSON(t, conn, &msg) + require.NoError(t, err) + require.Equal(t, "next", msg.Type) + require.Contains(t, string(msg.Payload), `"itemUpdated"`) + + // Close subscription + require.NoError(t, conn.Close()) + xEnv.WaitForSubscriptionCount(0, 5*time.Second) + + // After invalidation, cache miss → details subgraph called again + xEnv.MakeGraphQLRequestOK(req) + require.Equal(t, detailsAfterWarm+1, counters.details.Load()) + }) + }) + + t.Run("L2/subscription populate config carries entity type name", func(t *testing.T) { + // Regression test for the composition->router pipeline carrying entityTypeName + // end-to-end on @cachePopulate configs. Before this was wired: + // - composition wrote CachePopulateConfig without entityTypeName + // - router compensated by expanding subscription populate across every + // cached entity in the subgraph (semantically ambiguous, wrong config) + // Now the field carries the specific target entity — router looks it up directly. + // + // If composition is reverted, entityTypeName is empty, the router skips the + // populate setup, and the follow-up subscription_populates_cache test goes red. + t.Parallel() + + servers, _ := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + cache := newMemoryCache(t) + + var itemCreatedPopulate *nodev1.CachePopulateConfiguration + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: entityCachingL2OnlyOptions(cache), + ModifyRouterConfig: func(rc *nodev1.RouterConfig) { + for _, ds := range rc.EngineConfig.DatasourceConfigurations { + for _, cp := range ds.CachePopulateConfigurations { + if cp.OperationType == "Subscription" && cp.FieldName == "itemCreated" { + itemCreatedPopulate = cp + } + } + } + }, + }, func(t *testing.T, xEnv *testenv.Environment) { + require.NotNil(t, itemCreatedPopulate, + "expected a CachePopulateConfiguration for subscription itemCreated") + require.Equal(t, "Item", itemCreatedPopulate.EntityTypeName, + "@cachePopulate must carry the target entity type name through the pipeline") + }) + }) + + t.Run("L2/subscription populates cache", func(t *testing.T) { + t.Parallel() + + servers, _ := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + cache := newMemoryCache(t) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: entityCachingL2OnlyOptions(cache), + }, func(t *testing.T, xEnv *testenv.Environment) { + // Start subscription via WebSocket (itemCreated has @cachePopulate) + conn := xEnv.InitGraphQLWebSocketConnection(nil, nil, nil) + + err := testenv.WSWriteJSON(t, conn, testenv.WebSocketMessage{ + ID: "1", + Type: "subscribe", + Payload: []byte(`{"query":"subscription { itemCreated { id name category } }"}`), + }) + require.NoError(t, err) + + // Push event in background after subscription is established + go func() { + xEnv.WaitForSubscriptionCount(1, 5*time.Second) + servers.itemCreatedCh <- &itemsModel.Item{ID: "99", Name: "New Item", Category: "test"} + }() + + // Read subscription event + var msg testenv.WebSocketMessage + err = testenv.WSReadJSON(t, conn, &msg) + require.NoError(t, err) + require.Equal(t, "next", msg.Type) + require.Contains(t, string(msg.Payload), `"itemCreated"`) + require.Contains(t, string(msg.Payload), `"New Item"`) + + // Close subscription + require.NoError(t, conn.Close()) + xEnv.WaitForSubscriptionCount(0, 5*time.Second) + + // @cachePopulate should have written the entity data to L2 cache + require.Equal(t, 1, cache.Len()) + }) + }) + + t.Run("L2/extensions invalidate cache", func(t *testing.T) { + t.Parallel() + + var extensionFlag atomic.Bool + servers, counters := startSubgraphServersWithMiddleware(t, extensionInvalidationMiddleware(&extensionFlag)) + configJSON := buildConfigJSON(servers) + cache := newMemoryCache(t) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: entityCachingL2OnlyOptions(cache), + }, func(t *testing.T, xEnv *testenv.Environment) { + // Warm cache with extension OFF + res := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ item(id: "1") { id name description } }`, + }) + require.Equal(t, `{"data":{"item":{"id":"1","name":"Widget","description":"A versatile widget for everyday use"}}}`, res.Body) + + detailsAfterWarm := counters.details.Load() + + // Verify cache hit + xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ item(id: "1") { id name description } }`, + }) + require.Equal(t, detailsAfterWarm, counters.details.Load()) + + // Enable extension: details responses will now include cacheInvalidation for Item id:"1" + extensionFlag.Store(true) + + // Make a request that hits details subgraph for a DIFFERENT entity. + // This triggers the details middleware which adds the extension for id:"1". + xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ item(id: "2") { id name description } }`, + }) + + // Disable extension for the final query + extensionFlag.Store(false) + + // Query id:"1" again — should be cache miss because extension invalidated it + xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ item(id: "1") { id name description } }`, + }) + require.Equal(t, detailsAfterWarm+2, counters.details.Load()) + }) + }) + + t.Run("L2/mutation populate writes to cache", func(t *testing.T) { + t.Parallel() + + servers, counters := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + cache := newMemoryCache(t) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: entityCachingL2OnlyOptions(cache), + }, func(t *testing.T, xEnv *testenv.Environment) { + // createItem has @cachePopulate(maxAge: 60). The truthful signal is + // that the follow-up read-by-id is served from cache — i.e. the + // items subgraph is NOT called again for the newly created entity. + // + // Checking cache.Len() growth is insufficient: there is a known + // router-Go bug where @cachePopulate writes still land in L2 even + // when L2.Enabled=false, so size-based assertions pass under a + // feature-disabled run. The items-counter read-path check below is + // the assertion that fails when caching is actually off. + createRes := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `mutation { createItem(name: "Foobar", category: "test") { id name category } }`, + }) + var created struct { + Data struct { + CreateItem struct { + ID string `json:"id"` + } `json:"createItem"` + } `json:"data"` + } + require.NoError(t, json.Unmarshal([]byte(createRes.Body), &created)) + require.NotEmpty(t, created.Data.CreateItem.ID) + + itemsAfterCreate := counters.items.Load() + + // Read the just-created entity by its @key. If @cachePopulate wrote + // to L2, the items root-field subgraph must NOT be re-fetched. + // With L2 disabled this counter would grow to itemsAfterCreate+1. + xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ item(id: "` + created.Data.CreateItem.ID + `") { id name category } }`, + }) + require.Equal(t, itemsAfterCreate, counters.items.Load(), + "@cachePopulate must write the entity to L2 so the read-by-id is a cache hit; with L2 disabled this counter would be itemsAfterCreate+1") + }) + }) + + t.Run("Regression/mutation cache populate does not write when L2 is disabled", func(t *testing.T) { + t.Parallel() + + servers, counters := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + cache := newMemoryCache(t) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: []core.Option{ + core.WithEntityCaching(config.EntityCachingConfiguration{ + Enabled: true, + L1: config.EntityCachingL1Configuration{ + Enabled: true, + }, + L2: config.EntityCachingL2Configuration{ + Enabled: false, + }, + }), + core.WithEntityCacheInstances(map[string]resolve.LoaderCache{ + "default": cache, + }), + }, + }, func(t *testing.T, xEnv *testenv.Environment) { + lenBefore := cache.Len() + + createRes := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `mutation { createItem(name: "NoL2Populate", category: "disabled") { id name category } }`, + }) + require.Contains(t, createRes.Body, `"NoL2Populate"`) + + var created struct { + Data struct { + CreateItem struct { + ID string `json:"id"` + } `json:"createItem"` + } `json:"data"` + } + require.NoError(t, json.Unmarshal([]byte(createRes.Body), &created)) + require.NotEmpty(t, created.Data.CreateItem.ID) + + require.Equal(t, lenBefore, cache.Len(), + "@cachePopulate must not write to L2 when router L2 caching is disabled") + + itemsAfterCreate := counters.items.Load() + readRes := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ item(id: "` + created.Data.CreateItem.ID + `") { id name category } }`, + }) + require.Equal(t, + `{"data":{"item":{"id":"`+created.Data.CreateItem.ID+`","name":"NoL2Populate","category":"disabled"}}}`, + readRes.Body) + require.Equal(t, itemsAfterCreate+1, counters.items.Load(), + "with L2 disabled, the follow-up read must miss cache and refetch from the items subgraph") + }) + }) + + t.Run("L2/delete mutation invalidates cache", func(t *testing.T) { + t.Parallel() + + servers, counters := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + cache := newMemoryCache(t) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: entityCachingL2OnlyOptions(cache), + }, func(t *testing.T, xEnv *testenv.Environment) { + // Warm cache: first request populates both the root-field L2 entry and + // the Item entity L2 entry. + xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ item(id: "1") { id name description } }`, + }) + itemsAfterWarm := counters.items.Load() + detailsAfterWarm := counters.details.Load() + require.Greater(t, cache.Len(), 0, + "warm-up must populate at least one cache entry") + + // Second identical request must be a cache hit: neither the items + // (root-field) subgraph nor the details (entity) subgraph is called. + xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ item(id: "1") { id name description } }`, + }) + require.Equal(t, itemsAfterWarm, counters.items.Load(), + "pre-invalidate read must be a cache hit on the items root-field subgraph") + require.Equal(t, detailsAfterWarm, counters.details.Load(), + "pre-invalidate read must be a cache hit on the details entity subgraph") + + // Delete triggers @cacheInvalidate. The mutation itself hits the items + // subgraph to run the resolver, so we capture the counter AFTER the + // mutation and assert on the delta from the subsequent read. + xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `mutation { deleteItem(id: "1") { id name } }`, + }) + itemsAfterMutation := counters.items.Load() + + // After invalidation, the read MUST miss the cache and re-hit the + // items subgraph. The store has persisted the delete, so `item(id:"1")` + // now returns null and no downstream entity fetch to the details + // subgraph happens — but the root-field cache-miss alone is enough + // to prove @cacheInvalidate fired. + res := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ item(id: "1") { id name description } }`, + }) + require.Equal(t, `{"data":{"item":null}}`, res.Body, + "post-delete read must return null since the store now lacks id=1") + require.Equal(t, itemsAfterMutation+1, counters.items.Load(), + "post-invalidate read must refetch from items subgraph; equal count means the cache entry survived the invalidate") + }) + }) + + t.Run("Combined/L1 deduplicates with warm L2", func(t *testing.T) { + t.Parallel() + + servers, counters := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + cache := newMemoryCache(t) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: entityCachingOptions(cache), + }, func(t *testing.T, xEnv *testenv.Environment) { + // Query same entity via two aliases — L1 should deduplicate + res := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ + a: item(id: "1") { id name description } + b: item(id: "1") { id name description } + }`, + }) + require.Contains(t, res.Body, `"a"`) + require.Contains(t, res.Body, `"b"`) + + // Details subgraph called only once (L1 dedup within single request) + require.Equal(t, int64(1), counters.details.Load()) + + // L2 receives two writes — one per alias — because graphql-go-tools + // PR #1259 commit 2427062b1f ("bulk L2 Set") writes each resolved + // field result to L2 independently rather than dedup-on-key at + // write time. Ristretto-backed Len() counts each Set() that admits + // a new entry, and the same key set twice can both admit when the + // reads in between race the asynchronous admission. The L1 dedup + // still saves the subgraph call (asserted above); only the L2 + // bookkeeping doubled. + require.Equal(t, 2, cache.Len()) + }) + }) + + t.Run("L2/@is directive cache key mapping", func(t *testing.T) { + t.Parallel() + + servers, counters := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + cache := newMemoryCache(t) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: entityCachingL2OnlyOptions(cache), + }, func(t *testing.T, xEnv *testenv.Environment) { + // Query using @is-mapped argument (pid maps to @key field "id") + // Include cross-subgraph field (description from details) to trigger entity caching + req := testenv.GraphQLRequest{ + Query: `{ itemByPid(pid: "1") { id name description } }`, + } + res := xEnv.MakeGraphQLRequestOK(req) + require.Equal(t, `{"data":{"itemByPid":{"id":"1","name":"Widget","description":"A versatile widget for everyday use"}}}`, res.Body) + + detailsAfterFirst := counters.details.Load() + require.Equal(t, int64(1), detailsAfterFirst) + + // Same query again — entity cache hit (details subgraph not called again) + res2 := xEnv.MakeGraphQLRequestOK(req) + require.Equal(t, `{"data":{"itemByPid":{"id":"1","name":"Widget","description":"A versatile widget for everyday use"}}}`, res2.Body) + require.Equal(t, int64(1), counters.details.Load()) + + // Different pid — entity cache miss for this entity + res3 := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ itemByPid(pid: "2") { id name description } }`, + }) + require.Equal(t, `{"data":{"itemByPid":{"id":"2","name":"Gadget","description":"A high-tech gadget with many features"}}}`, res3.Body) + require.Equal(t, int64(2), counters.details.Load()) + }) + }) + + t.Run("Shadow/with failing cache", func(t *testing.T) { + t.Parallel() + + servers, counters := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: entityCachingOptions(&FailingEntityCache{}), + ModifyRouterConfig: func(routerConfig *nodev1.RouterConfig) { + setEntityCacheShadowMode(routerConfig, true) + }, + }, func(t *testing.T, xEnv *testenv.Environment) { + req := testenv.GraphQLRequest{ + Query: `{ item(id: "1") { id name description } }`, + } + // Shadow mode + failing cache: every request must still resolve + // end-to-end via the subgraphs. The signal is that BOTH calls hit + // the details subgraph — shadow mode never serves from cache, even + // when the cache is working. With cache failures on top, the only + // data source is the subgraph, so the counter must tick on every + // call. With shadow mode disabled (reads-from-cache), the cache + // error would either short-circuit or fail the request; so this + // counter-based assertion is the truthful shadow-mode signal. + res := xEnv.MakeGraphQLRequestOK(req) + require.Equal(t, `{"data":{"item":{"id":"1","name":"Widget","description":"A versatile widget for everyday use"}}}`, res.Body) + detailsAfterFirst := counters.details.Load() + require.Equal(t, int64(1), detailsAfterFirst) + + res2 := xEnv.MakeGraphQLRequestOK(req) + require.Equal(t, `{"data":{"item":{"id":"1","name":"Widget","description":"A versatile widget for everyday use"}}}`, res2.Body) + require.Equal(t, int64(2), counters.details.Load(), + "shadow mode must refetch from details on every request even when the cache is failing") + }) + }) + + t.Run("L2/negative TTL expires and refetches", func(t *testing.T) { + // Companion to negative_cache_caches_null: asserts the not-found entity + // cache also EXPIRES after its configured TTL. Like the sister test, the + // signal is counters.details (the entity-hydration subgraph) because + // items-subgraph is always called for the root field. The TTL is set + // to 1s; after sleeping >1s, the third request MUST re-hit details. + t.Parallel() + + servers, counters := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + cache := newMemoryCache(t) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: entityCachingL2OnlyOptions(cache), + ModifyRouterConfig: func(routerConfig *nodev1.RouterConfig) { + setNotFoundCacheTTL(routerConfig, 1) // 1 second not-found cache TTL + }, + }, func(t *testing.T, xEnv *testenv.Environment) { + // Create an item in items-subgraph; details-subgraph has no record + // for the new id, so entity hydration returns null there. + createRes := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `mutation { createItem(name: "Phantom", category: "void") { id } }`, + }) + var created struct { + Data struct { + CreateItem struct { + ID string `json:"id"` + } `json:"createItem"` + } `json:"data"` + } + require.NoError(t, json.Unmarshal([]byte(createRes.Body), &created)) + newID := created.Data.CreateItem.ID + require.NotEmpty(t, newID) + + req := testenv.GraphQLRequest{ + Query: `{ item(id: "` + newID + `") { id description } }`, + } + // First call: details hit once, null entity cached under its key. + xEnv.MakeGraphQLRequestOK(req) + require.Equal(t, int64(1), counters.details.Load(), + "first request must hit details for the not-found hydration") + + // Immediate re-request: not-found cache hit, details skipped. + xEnv.MakeGraphQLRequestOK(req) + require.Equal(t, int64(1), counters.details.Load(), + "immediate re-request must be a not-found cache hit") + + // Wait past TTL. + time.Sleep(1500 * time.Millisecond) + + // After expiry the not-found entry must be gone, so details is + // re-hit. Without TTL expiry (or with L2 off) this counter would + // stay at 1 or climb on every call respectively. + xEnv.MakeGraphQLRequestOK(req) + require.Equal(t, int64(2), counters.details.Load(), + "after not-found TTL expiry, the next request must re-hit details exactly once") + }) + }) + + t.Run("L2/negative TTL falls back to positive TTL when unset", func(t *testing.T) { + // Regression guard against the new negativeCacheTTL field clobbering + // the two existing code paths. + // With notFoundCacheTtlSeconds unset (directive default 0) on the + // details subgraph's Item, + // both pre-existing behaviors must hold: + // (1) not-found entity fetches are NOT negatively cached — + // a second request for a missing id re-hits details. + // (2) found-entity positive caching (maxAge: 300) still works — + // a second request for a known id serves from cache. + // Signals: counters.details climbs on each not-found request, + // then stays flat on a repeated known-id request. + t.Parallel() + + servers, counters := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + cache := newMemoryCache(t) + + // Deliberately do NOT call setNotFoundCacheTTL — leave the field at + // its zero default to exercise the unset-fallback path. + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: entityCachingL2OnlyOptions(cache), + }, func(t *testing.T, xEnv *testenv.Environment) { + // Create an id that exists in items-subgraph but not in details. + createRes := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `mutation { createItem(name: "Missing", category: "void") { id } }`, + }) + var created struct { + Data struct { + CreateItem struct { + ID string `json:"id"` + } `json:"createItem"` + } `json:"data"` + } + require.NoError(t, json.Unmarshal([]byte(createRes.Body), &created)) + newID := created.Data.CreateItem.ID + require.NotEmpty(t, newID) + + missingReq := testenv.GraphQLRequest{ + Query: `{ item(id: "` + newID + `") { id description } }`, + } + // First not-found request: details is hit once. + xEnv.MakeGraphQLRequestOK(missingReq) + require.Equal(t, int64(1), counters.details.Load(), + "first not-found request must hit details") + + // Second not-found request: negative cache is OFF, so details + // must be hit again. With a negative-TTL leak here, this would + // stay at 1. + xEnv.MakeGraphQLRequestOK(missingReq) + require.Equal(t, int64(2), counters.details.Load(), + "without notFoundCacheTtlSeconds, not-found results must NOT be cached; details must re-hit") + + // Positive-TTL sanity check: a known id must still be entity-cached. + foundReq := testenv.GraphQLRequest{ + Query: `{ item(id: "1") { id description } }`, + } + xEnv.MakeGraphQLRequestOK(foundReq) + detailsAfterFoundFirst := counters.details.Load() + require.Equal(t, int64(3), detailsAfterFoundFirst, + "first request for a known id must hit details once") + + xEnv.MakeGraphQLRequestOK(foundReq) + require.Equal(t, detailsAfterFoundFirst, counters.details.Load(), + "positive-TTL entity cache must hit on the second request for a known id") + }) + }) + + t.Run("L2/partial cache load with multiple warm entities", func(t *testing.T) { + t.Parallel() + + servers, counters := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + cache := newMemoryCache(t) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: entityCachingL2OnlyOptions(cache), + ModifyRouterConfig: func(routerConfig *nodev1.RouterConfig) { + setEntityCachePartialLoad(routerConfig, true) + }, + }, func(t *testing.T, xEnv *testenv.Environment) { + // Warm cache for id:"1" and id:"2" + xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ item(id: "1") { id description } }`, + }) + xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ item(id: "2") { id description } }`, + }) + detailsAfterWarm := counters.details.Load() + require.Equal(t, int64(2), detailsAfterWarm) + require.Equal(t, 2, cache.Len()) + + // List query: id:"1" and id:"2" cached, rest fetched from subgraph + res := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ items { id description } }`, + }) + require.Contains(t, res.Body, `"description"`) + + // Details should be called once more for the remaining uncached items + require.Equal(t, detailsAfterWarm+1, counters.details.Load()) + }) + }) + + t.Run("L2/query cache include headers", func(t *testing.T) { + t.Parallel() + + servers, counters := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + cache := newMemoryCache(t) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: append( + entityCachingL2OnlyOptions(cache), + core.WithHeaderRules(config.HeaderRules{ + All: &config.GlobalHeaderRule{ + Request: []*config.RequestHeaderRule{ + { + Operation: config.HeaderRuleOperationPropagate, + Named: "X-Tenant", + }, + }, + }, + }), + ), + ModifyRouterConfig: func(routerConfig *nodev1.RouterConfig) { + // @queryCache includeHeaders varies the root field cache key by request headers + setQueryCacheIncludeHeaders(routerConfig, true) + // Also set entity cache includeHeaders so entity resolution cache key varies too + setEntityCacheIncludeHeaders(routerConfig, true) + }, + }, func(t *testing.T, xEnv *testenv.Environment) { + // Request with header A — entity resolution calls details subgraph + xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ item(id: "1") { id name description } }`, + Header: map[string][]string{"X-Tenant": {"A"}}, + }) + detailsAfterA := counters.details.Load() + require.Equal(t, int64(1), detailsAfterA) + + // Same query, header A — entity cache hit (details not called) + xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ item(id: "1") { id name description } }`, + Header: map[string][]string{"X-Tenant": {"A"}}, + }) + require.Equal(t, detailsAfterA, counters.details.Load()) + + // Same query, header B — different cache key, details called again + xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ item(id: "1") { id name description } }`, + Header: map[string][]string{"X-Tenant": {"B"}}, + }) + require.Equal(t, detailsAfterA+1, counters.details.Load()) + }) + }) + + t.Run("L2/cache populate maxAge override", func(t *testing.T) { + t.Parallel() + + servers, counters := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + cache := newMemoryCache(t) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: entityCachingL2OnlyOptions(cache), + ModifyRouterConfig: func(routerConfig *nodev1.RouterConfig) { + // Override @cachePopulate(maxAge:60) down to 1 second. + setCachePopulateTTL(routerConfig, 1) + }, + }, func(t *testing.T, xEnv *testenv.Environment) { + lenBefore := cache.Len() + + // createItem has @cachePopulate. The mutation must write the new + // Item to L2 under the short (1s) override TTL. + res := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `mutation { createItem(name: "ShortLived", category: "test") { id name category } }`, + }) + require.Contains(t, res.Body, `"ShortLived"`) + + // Cache MUST have grown — proves @cachePopulate actually ran. + // With L2.Enabled=false, this assertion fails. + require.Greater(t, cache.Len(), lenBefore, + "@cachePopulate must write to L2 even under the maxAge override") + + var body struct { + Data struct { + CreateItem struct { + ID string `json:"id"` + } `json:"createItem"` + } `json:"data"` + } + require.NoError(t, json.Unmarshal([]byte(res.Body), &body)) + newID := body.Data.CreateItem.ID + require.NotEmpty(t, newID) + + // Immediately after the mutation the entity is in L2 with a 1s TTL: + // a follow-up read hits cache (items subgraph not called). + itemsAfterMutation := counters.items.Load() + xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ item(id: "` + newID + `") { id name } }`, + }) + require.Equal(t, itemsAfterMutation, counters.items.Load(), + "immediate follow-up read must hit the populated L2 entry") + + // Wait past the 1s override TTL. The entry must have expired, so + // a subsequent read now MUST re-hit the items subgraph. This is + // the truthful proof that the maxAge override fired: without the + // override (60s default), the counter would still not tick. + time.Sleep(1500 * time.Millisecond) + + itemsBeforeExpiredRead := counters.items.Load() + xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ item(id: "` + newID + `") { id name } }`, + }) + require.Equal(t, itemsBeforeExpiredRead+1, counters.items.Load(), + "after the 1s override TTL expires, the read must refetch from items; unchanged counter means the override was ignored") + }) + }) + + // --- Mapping rule coverage tests --- + + t.Run("L2/batch list argument cache keys", func(t *testing.T) { + t.Parallel() + + servers, counters := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + cache := newMemoryCache(t) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: entityCachingL2OnlyOptions(cache), + }, func(t *testing.T, xEnv *testenv.Environment) { + // itemsByIds uses @is(fields: "id") with a list argument → batch cache lookup. + // Each element in the ids list maps to one entity cache key. + req := testenv.GraphQLRequest{ + Query: `{ itemsByIds(ids: ["1", "2"]) { id name description } }`, + } + res := xEnv.MakeGraphQLRequestOK(req) + require.Contains(t, res.Body, `"Widget"`) + require.Contains(t, res.Body, `"Gadget"`) + require.Contains(t, res.Body, `"description"`) + + detailsAfterFirst := counters.details.Load() + require.Equal(t, int64(1), detailsAfterFirst) + + // Two entities fetched → two cache entries + require.Equal(t, 2, cache.Len()) + + // Same query again → all entities served from cache + res2 := xEnv.MakeGraphQLRequestOK(req) + require.Equal(t, res.Body, res2.Body) + require.Equal(t, detailsAfterFirst, counters.details.Load()) + }) + }) + + t.Run("L2/batch list partial cache hit", func(t *testing.T) { + t.Parallel() + + servers, counters := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + cache := newMemoryCache(t) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: entityCachingL2OnlyOptions(cache), + }, func(t *testing.T, xEnv *testenv.Environment) { + // Warm cache for id:"1" only + xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ item(id: "1") { id name description } }`, + }) + detailsAfterWarm := counters.details.Load() + require.Equal(t, 1, cache.Len()) + + // Batch query for ids ["1", "3"] — id:"1" is cached, id:"3" is not + res := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ itemsByIds(ids: ["1", "3"]) { id name description } }`, + }) + require.Contains(t, res.Body, `"Widget"`) + require.Contains(t, res.Body, `"Gizmo"`) + + // Details subgraph should be called again for the uncached entity + require.Greater(t, counters.details.Load(), detailsAfterWarm) + }) + }) + + t.Run("L2/composite key auto mapping", func(t *testing.T) { + t.Parallel() + + servers, counters := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + cache := newMemoryCache(t) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: entityCachingL2OnlyOptions(cache), + }, func(t *testing.T, xEnv *testenv.Environment) { + // product(id, region) auto-maps both args to @key(fields: "id region"). + // The cache key includes both id AND region. + req := testenv.GraphQLRequest{ + Query: `{ product(id: "p1", region: "US") { id region name info } }`, + } + res := xEnv.MakeGraphQLRequestOK(req) + require.Equal(t, `{"data":{"product":{"id":"p1","region":"US","name":"Alpha","info":"Alpha product details for US market"}}}`, res.Body) + + detailsAfterFirst := counters.details.Load() + require.Equal(t, int64(1), detailsAfterFirst) + + // Same composite key → cache hit + res2 := xEnv.MakeGraphQLRequestOK(req) + require.Equal(t, res.Body, res2.Body) + require.Equal(t, detailsAfterFirst, counters.details.Load()) + + // Same id, different region → cache miss (different composite key) + res3 := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ product(id: "p3", region: "EU") { id region name info } }`, + }) + require.Contains(t, res3.Body, `"Gamma"`) + require.Equal(t, detailsAfterFirst+1, counters.details.Load()) + }) + }) + + t.Run("L2/multiple keys with one satisfiable", func(t *testing.T) { + t.Parallel() + + servers, counters := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + cache := newMemoryCache(t) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: entityCachingL2OnlyOptions(cache), + }, func(t *testing.T, xEnv *testenv.Environment) { + // Product has @key(fields: "id region") and @key(fields: "sku"). + // productBySku only provides sku → only the sku key is satisfiable. + req := testenv.GraphQLRequest{ + Query: `{ productBySku(sku: "SKU-001") { id region sku name info } }`, + } + res := xEnv.MakeGraphQLRequestOK(req) + require.Contains(t, res.Body, `"Alpha"`) + require.Contains(t, res.Body, `"SKU-001"`) + require.Contains(t, res.Body, `"info"`) + + detailsAfterFirst := counters.details.Load() + require.Equal(t, int64(1), detailsAfterFirst) + + // Same sku → cache hit + res2 := xEnv.MakeGraphQLRequestOK(req) + require.Equal(t, res.Body, res2.Body) + require.Equal(t, detailsAfterFirst, counters.details.Load()) + + // Different sku → cache miss + xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ productBySku(sku: "SKU-003") { id region sku name info } }`, + }) + require.Equal(t, detailsAfterFirst+1, counters.details.Load()) + }) + }) + + t.Run("L2/no key match leaves root field uncached", func(t *testing.T) { + t.Parallel() + + servers, counters := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + cache := newMemoryCache(t) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: entityCachingL2OnlyOptions(cache), + }, func(t *testing.T, xEnv *testenv.Environment) { + // productByName(name) — "name" doesn't match any @key field. + // No entity key mapping is emitted, so no per-entity cache keys + // are constructed from the argument. Entity caching via _entities + // still works (the details subgraph result is cached by entity key), + // but the root field itself does not produce a query cache mapping. + req := testenv.GraphQLRequest{ + Query: `{ productByName(name: "Alpha") { id region name info } }`, + } + res := xEnv.MakeGraphQLRequestOK(req) + require.Contains(t, res.Body, `"Alpha"`) + require.Contains(t, res.Body, `"info"`) + + detailsAfterFirst := counters.details.Load() + require.Equal(t, int64(1), detailsAfterFirst) + + // Entity caching from _entities still works — details cached + res2 := xEnv.MakeGraphQLRequestOK(req) + require.Equal(t, res.Body, res2.Body) + require.Equal(t, detailsAfterFirst, counters.details.Load()) + }) + }) + + t.Run("L2/composite key input object via @is", func(t *testing.T) { + t.Parallel() + + servers, counters := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + cache := newMemoryCache(t) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: entityCachingL2OnlyOptions(cache), + }, func(t *testing.T, xEnv *testenv.Environment) { + // productByKey uses an input object argument with @is(fields: "id region"). + // The composition decomposes this into argumentPath ["key","id"] and ["key","region"], + // mapping input object fields to the composite @key(fields: "id region"). + req := testenv.GraphQLRequest{ + Query: `query($k: ProductKeyInput!) { productByKey(key: $k) { id region name info } }`, + Variables: []byte(`{"k": {"id": "p1", "region": "US"}}`), + } + res := xEnv.MakeGraphQLRequestOK(req) + require.Equal(t, `{"data":{"productByKey":{"id":"p1","region":"US","name":"Alpha","info":"Alpha product details for US market"}}}`, res.Body) + + detailsAfterFirst := counters.details.Load() + require.Equal(t, int64(1), detailsAfterFirst) + + // Same input object → cache hit + res2 := xEnv.MakeGraphQLRequestOK(req) + require.Equal(t, res.Body, res2.Body) + require.Equal(t, detailsAfterFirst, counters.details.Load()) + + // Different input object → cache miss + req2 := testenv.GraphQLRequest{ + Query: `query($k: ProductKeyInput!) { productByKey(key: $k) { id region name info } }`, + Variables: []byte(`{"k": {"id": "p3", "region": "EU"}}`), + } + res3 := xEnv.MakeGraphQLRequestOK(req2) + require.Contains(t, res3.Body, `"Gamma"`) + require.Equal(t, detailsAfterFirst+1, counters.details.Load()) + }) + }) + + t.Run("L2/nested key via @is directive", func(t *testing.T) { + t.Parallel() + + servers, counters := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + cache := newMemoryCache(t) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: entityCachingL2OnlyOptions(cache), + }, func(t *testing.T, xEnv *testenv.Environment) { + // warehouse(locationId) uses @is(fields: "location.id") to map a scalar + // argument to the nested key path @key(fields: "location { id }"). + req := testenv.GraphQLRequest{ + Query: `{ warehouse(locationId: "w1") { location { id } name capacity } }`, + } + res := xEnv.MakeGraphQLRequestOK(req) + require.Contains(t, res.Body, `"Main Depot"`) + require.Contains(t, res.Body, `"capacity"`) + + detailsAfterFirst := counters.details.Load() + require.Equal(t, int64(1), detailsAfterFirst) + + // Same nested key → cache hit + res2 := xEnv.MakeGraphQLRequestOK(req) + require.Equal(t, res.Body, res2.Body) + require.Equal(t, detailsAfterFirst, counters.details.Load()) + + // Different location → cache miss + xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ warehouse(locationId: "w2") { location { id } name capacity } }`, + }) + require.Equal(t, detailsAfterFirst+1, counters.details.Load()) + }) + }) + + t.Run("L2/single-subgraph composite key input object", func(t *testing.T) { + t.Parallel() + + servers, counters := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + cache := newMemoryCache(t) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: entityCachingL2OnlyOptions(cache), + }, func(t *testing.T, xEnv *testenv.Environment) { + // productByKey uses an input object argument with @is(fields: "id region"). + // Querying only items-subgraph fields (id, region, name) verifies that + // RemapVariables correctly handles nested argument paths in a single-subgraph + // setup where no entity fetch is needed. + req := testenv.GraphQLRequest{ + Query: `query($k: ProductKeyInput!) { productByKey(key: $k) { id region name } }`, + Variables: []byte(`{"k": {"id": "p1", "region": "US"}}`), + } + res := xEnv.MakeGraphQLRequestOK(req) + require.Equal(t, `{"data":{"productByKey":{"id":"p1","region":"US","name":"Alpha"}}}`, res.Body) + + itemsAfterFirst := counters.items.Load() + require.Equal(t, int64(1), itemsAfterFirst) + + // Same input object → cache hit, items subgraph NOT called again + res2 := xEnv.MakeGraphQLRequestOK(req) + require.Equal(t, res.Body, res2.Body) + require.Equal(t, itemsAfterFirst, counters.items.Load()) + }) + }) + + // request_scoped_field_deduplication establishes the baseline behavior for + // entity resolution deduplication. Without @requestScoped, the details + // subgraph is called exactly once for a list query (all entities are + // batched into a single _entities call). The L2 cache then serves + // subsequent identical requests without calling the subgraph again. + // + // When @requestScoped support is added (subgraph schemas declare + // @requestScoped, composition produces requestScopedFields in config.json, + // and the planner generates RequestScopedExports/Hints), this test should + // be extended to verify that the details subgraph is called fewer times + // across multiple entity batches within a single request. + t.Run("L2/list entity batch caches across requests", func(t *testing.T) { + t.Parallel() + + servers, counters := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + cache := newMemoryCache(t) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: entityCachingL2OnlyOptions(cache), + }, func(t *testing.T, xEnv *testenv.Environment) { + // Query a list of items. Each item triggers entity resolution to + // the details subgraph for description, batched into one _entities call. + req := testenv.GraphQLRequest{ + Query: `{ items { id name description } }`, + } + + res := xEnv.MakeGraphQLRequestOK(req) + require.Contains(t, res.Body, `"description"`) + require.Contains(t, res.Body, `"Widget"`) + + // Baseline: details subgraph called exactly once (one batch) + require.Equal(t, int64(1), counters.details.Load(), + "details should be called once for the entity batch") + + // Second identical request: L2 cache hit, no subgraph calls + res2 := xEnv.MakeGraphQLRequestOK(req) + require.Equal(t, res.Body, res2.Body) + require.Equal(t, int64(1), counters.details.Load(), + "details should not be called again (L2 cache hit)") + }) + }) + + // field_widening_across_requests verifies that when a cached entity has + // a subset of fields (e.g., description only), a subsequent request + // asking for additional fields from the same subgraph (e.g., description + // + rating) correctly fetches the wider field set from the subgraph. + t.Run("L2/field widening across requests", func(t *testing.T) { + t.Parallel() + + servers, counters := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + cache := newMemoryCache(t) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: entityCachingL2OnlyOptions(cache), + }, func(t *testing.T, xEnv *testenv.Environment) { + // Request 1: fetch only description from details subgraph + res1 := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ item(id: "1") { id name description } }`, + }) + require.Equal(t, `{"data":{"item":{"id":"1","name":"Widget","description":"A versatile widget for everyday use"}}}`, res1.Body) + detailsAfterFirst := counters.details.Load() + require.Equal(t, int64(1), detailsAfterFirst) + + // Request 2: fetch description + rating (wider field set from same subgraph). + // The cache key includes the field selection, so this is a cache miss + // for the entity resolution to details. The subgraph must be called again. + res2 := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ item(id: "1") { id name description rating } }`, + }) + require.Contains(t, res2.Body, `"description"`) + require.Contains(t, res2.Body, `"rating"`) + require.Contains(t, res2.Body, `"Widget"`) + + // Details subgraph called again because wider field set is a different cache key + require.Equal(t, detailsAfterFirst+1, counters.details.Load(), + "details should be called again for the wider field set") + + // Request 3: repeat the wider query — should now be a cache hit + res3 := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ item(id: "1") { id name description rating } }`, + }) + require.Equal(t, res2.Body, res3.Body) + require.Equal(t, detailsAfterFirst+1, counters.details.Load(), + "wider field set should be cached after second fetch") + }) + }) + + // batch_partial_hit_with_extension_fields verifies that batch queries + // correctly handle partial cache hits when entity extension fields + // (from the details subgraph) are involved. Entities with cached + // extension data are served from cache; uncached entities trigger a + // subgraph fetch only for the missing ones. + t.Run("L2/batch partial hit with extension fields", func(t *testing.T) { + t.Parallel() + + servers, counters := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + cache := newMemoryCache(t) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: entityCachingL2OnlyOptions(cache), + }, func(t *testing.T, xEnv *testenv.Environment) { + // Warm cache: fetch extension fields for entity 1 and entity 2 + xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ itemsByIds(ids: ["1", "2"]) { id name description } }`, + }) + detailsAfterWarm := counters.details.Load() + require.Equal(t, int64(1), detailsAfterWarm) + require.Equal(t, 2, cache.Len()) + + // Batch query for entities [1, 2, 3]: entities 1 and 2 have cached + // extension data from details, entity 3 does not. + res := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ itemsByIds(ids: ["1", "2", "3"]) { id name description } }`, + }) + require.Contains(t, res.Body, `"Widget"`) + require.Contains(t, res.Body, `"Gadget"`) + require.Contains(t, res.Body, `"Gizmo"`) + require.Contains(t, res.Body, `"description"`) + + // Details subgraph called again for the uncached entity (id:"3") + require.Greater(t, counters.details.Load(), detailsAfterWarm, + "details should be called for uncached entity 3") + + // All three entities now cached + require.Equal(t, 3, cache.Len()) + + // Repeat the batch query — all entities cached, no more subgraph calls + detailsBeforeRepeat := counters.details.Load() + res2 := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ itemsByIds(ids: ["1", "2", "3"]) { id name description } }`, + }) + require.Equal(t, res.Body, res2.Body) + require.Equal(t, detailsBeforeRepeat, counters.details.Load(), + "all entities should be served from cache") + }) + }) + + t.Run("L2/batch entity key per-element caching", func(t *testing.T) { + t.Parallel() + + servers, counters := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + cache := newMemoryCache(t) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: entityCachingL2OnlyOptions(cache), + }, func(t *testing.T, xEnv *testenv.Environment) { + req := testenv.GraphQLRequest{ + Query: `{ itemsByIds(ids: ["1", "2"]) { id name description } }`, + } + + // Request 1: both subgraphs called (items for root field, details for entity) + res := xEnv.MakeGraphQLRequestOK(req) + require.Contains(t, res.Body, `"Widget"`) + require.Contains(t, res.Body, `"Gadget"`) + require.Contains(t, res.Body, `"description"`) + + itemsAfterFirst := counters.items.Load() + detailsAfterFirst := counters.details.Load() + require.Equal(t, int64(1), itemsAfterFirst) + require.Equal(t, int64(1), detailsAfterFirst) + + // Per-element cache entries: 2 entity keys (one per id) + require.Equal(t, 2, cache.Len()) + + // Request 2: identical query — batch entity keys hit, no subgraph calls + res2 := xEnv.MakeGraphQLRequestOK(req) + require.Equal(t, res.Body, res2.Body) + + // Items subgraph should NOT be called again (batch entity key cache hit) + require.Equal(t, itemsAfterFirst, counters.items.Load()) + // Details subgraph should NOT be called again (entity cache hit) + require.Equal(t, detailsAfterFirst, counters.details.Load()) + }) + }) + + // request_scoped_widening_refetch asserts the TARGET behavior for + // @requestScoped coordinate L1 caching: no matter how many sites within a + // single request read a @requestScoped field with the same key, the + // underlying subgraph should be fetched EXACTLY ONCE. + // + // This test is currently expected to FAIL. Under the present implementation + // the planner writes L1 with the narrow root selection ({id, name}) and a + // later sequentially-dependent read needs the wider selection + // ({id, name, email}) via @requires. The widening check in + // validateItemHasRequiredData sees that email is missing and triggers a + // refetch against the viewer subgraph, so counters.viewer is 2, not 1. + // + // The fix will either (a) teach the planner to pre-plan the wider union of + // selections up-front so the root fetch already carries {id, name, email}, + // or (b) teach the L1 layer to widen its stored entry when a later read + // asks for a superset of fields. Either way, once the fix lands this test + // should pass unchanged. + // + // Schema setup (see subgraphs/viewer + subgraphs/articles): + // + // viewer subgraph: + // Query.currentViewer @requestScoped(key: "currentViewer") + // Personalized.currentViewer @requestScoped(key: "currentViewer") + // Viewer { id, name, email } + // + // articles subgraph: + // Viewer { recommendedArticles } (extends viewer entity) + // Article implements Personalized { + // personalizedRecommendation: String! + // @requires(fields: "currentViewer { id name email }") + // } + // + // Query under test: + // + // { + // currentViewer { id name + // recommendedArticles { + // id title + // personalizedRecommendation + // } + // } + // } + t.Run("L1/request-scoped widening refetch", func(t *testing.T) { + t.Parallel() + + servers, counters := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: entityCachingL1OnlyOptions(), + }, func(t *testing.T, xEnv *testenv.Environment) { + req := testenv.GraphQLRequest{ + Query: `{ + currentViewer { + id + name + recommendedArticles { + id + title + personalizedRecommendation + } + } + }`, + } + res := xEnv.MakeGraphQLRequestOK(req) + // personalizedRecommendation formats "for <>" — asserting the + // email shows up proves the wider {id,name,email} selection actually + // reached the articles subgraph via @requires, i.e. the widening + // refetch really happened. + require.Equal(t, + `{"data":{"currentViewer":{"id":"v1","name":"Alice","recommendedArticles":[`+ + `{"id":"a1","title":"The Rise of Federated GraphQL","personalizedRecommendation":"The Rise of Federated GraphQL, recommended for Alice "},`+ + `{"id":"a2","title":"Caching Strategies for Modern APIs","personalizedRecommendation":"Caching Strategies for Modern APIs, recommended for Alice "},`+ + `{"id":"a3","title":"A Practical Guide to @requestScoped","personalizedRecommendation":"A Practical Guide to @requestScoped, recommended for Alice "}`+ + `]}}}`, + res.Body) + + // Target behavior: viewer should be fetched EXACTLY ONCE no matter + // how many @requestScoped reads happen within the request. + // + // Currently fails (actual == 2) because the root fetch carries only + // {id, name} and the later @requires-driven Personalized._entities + // fetch needs {id, name, email} — the widening check misses and + // refetches the viewer subgraph. See the test's header comment. + require.Equal(t, int64(1), counters.viewer.Load(), + "viewer must be fetched exactly once per request regardless of "+ + "how many @requestScoped reads share the same key") + + require.Equal(t, int64(2), counters.articles.Load(), + "articles is called twice: once for Viewer._entities (recommendedArticles), "+ + "once for Article._entities (personalizedRecommendation after @requires)") + }) + }) + + // Exercise the same @requestScoped key at the root, nested Article.currentViewer, + // and relatedArticles.currentViewer sites. L1 should let the first fetch populate + // the coordinate cache so the viewer subgraph is fetched once. + t.Run("L1/request-scoped nested dedup", func(t *testing.T) { + t.Parallel() + + servers, counters := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: entityCachingL1OnlyOptions(), + }, func(t *testing.T, xEnv *testenv.Environment) { + req := testenv.GraphQLRequest{ + Query: `{ + currentViewer { + id + name + email + recommendedArticles { + id + title + currentViewer { + id + name + email + } + relatedArticles { + id + title + currentViewer { + id + name + email + } + } + } + } + }`, + } + res := xEnv.MakeGraphQLRequestOK(req) + // Sanity: the query resolved successfully and the viewer data is + // identical at every site (proves the @requestScoped dedup is at + // least returning consistent data, even if it made too many fetches). + require.Contains(t, res.Body, `"currentViewer":{"id":"v1","name":"Alice","email":"alice@example.com"}`) + require.Contains(t, res.Body, `"recommendedArticles"`) + require.Contains(t, res.Body, `"relatedArticles"`) + + // Target behavior: the viewer subgraph is hit EXACTLY ONCE regardless + // of how many Article.currentViewer sites exist in the query. The root + // Query.currentViewer fetch populates the L1 coordinate cache under + // key "currentViewer", and every subsequent read at any nesting depth + // must inject from L1 without launching a new subgraph fetch. + require.Equal(t, int64(1), counters.viewer.Load(), + "viewer must be fetched exactly once per request regardless of "+ + "how many nesting levels select Article.currentViewer inline "+ + "(currently fails: the planner launches BatchEntity viewer fetches "+ + "for deeper Article.currentViewer sites in parallel with the L1 "+ + "injection check, paying the subgraph round-trip unnecessarily)") + }) + }) + + // Inverse of L1/request-scoped nested dedup: when the coordinate L1 cache + // is disabled, every Article.currentViewer site must issue its own BatchEntity + // fetch to the viewer subgraph. Without this counter-assertion, the dedup + // test above could silently turn into a no-op if the planner ever started + // merging the three selection sites on its own. + t.Run("L1-disabled/request-scoped nested no-dedup baseline", func(t *testing.T) { + t.Parallel() + + servers, counters := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: entityCachingDisabledOptions(), + }, func(t *testing.T, xEnv *testenv.Environment) { + req := testenv.GraphQLRequest{ + Query: `{ + currentViewer { + id + name + email + recommendedArticles { + id + title + currentViewer { + id + name + email + } + relatedArticles { + id + title + currentViewer { + id + name + email + } + } + } + } + }`, + } + res := xEnv.MakeGraphQLRequestOK(req) + require.Contains(t, res.Body, `"currentViewer":{"id":"v1","name":"Alice","email":"alice@example.com"}`) + + // Without L1 coordinate caching, the viewer subgraph is hit three times: + // 1. Root Query.currentViewer + // 2. Viewer._entities for recommendedArticles[].currentViewer (batched) + // 3. Viewer._entities for relatedArticles[].currentViewer (batched) + require.Equal(t, int64(3), counters.viewer.Load(), + "with L1 disabled, each Article.currentViewer site must hit the "+ + "viewer subgraph; if this ever drops below 3 the companion dedup "+ + "test is no longer proving anything") + }) + }) + + t.Run("Regression/complex viewer/articles query shape has no errors", func(t *testing.T) { + t.Parallel() + + servers, _ := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + cache := newMemoryCache(t) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: entityCachingOptions(cache), + }, func(t *testing.T, xEnv *testenv.Environment) { + req := testenv.GraphQLRequest{ + Query: `query ViewerArticles { + articles { + id + title + body + relatedArticles { + ...ArticleFields + relatedArticles { + ...ArticleFields + relatedArticles { + ...ArticleFields + } + } + } + } + currentViewer { + id + name + email + recommendedArticles { + ...ArticleFields + relatedArticles { + ...ArticleFields + relatedArticles { + ...ArticleFields + } + } + } + } + } + + fragment ArticleFields on Article { + id + title + tags + viewCount + rating + reviewSummary + personalizedRecommendation + currentViewer { + id + name + email + } + }`, + } + + for i := range 3 { + res := xEnv.MakeGraphQLRequestOK(req) + require.NotContains(t, res.Body, `"errors"`, "iteration %d: expected query to execute without GraphQL errors", i) + require.Contains(t, res.Body, `"articles"`, "iteration %d: expected articles payload", i) + require.Contains(t, res.Body, `"currentViewer"`, "iteration %d: expected currentViewer payload", i) + } + }) + }) + + t.Run("Regression/complex viewer/articles cached matches uncached", func(t *testing.T) { + t.Parallel() + + servers, _ := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + cache := newMemoryCache(t) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: entityCachingOptions(cache), + }, func(t *testing.T, xEnv *testenv.Environment) { + req := testenv.GraphQLRequest{ + Query: `query ViewerArticles { + articles { + id + title + body + relatedArticles { + ...ArticleFields + relatedArticles { + ...ArticleFields + relatedArticles { + ...ArticleFields + } + } + } + } + currentViewer { + id + name + email + recommendedArticles { + ...ArticleFields + relatedArticles { + ...ArticleFields + relatedArticles { + ...ArticleFields + } + } + } + } + } + + fragment ArticleFields on Article { + id + title + tags + viewCount + rating + reviewSummary + personalizedRecommendation + currentViewer { + id + name + email + } + }`, + } + + // Warm cache. + xEnv.MakeGraphQLRequestOK(req) + + cachedRes := xEnv.MakeGraphQLRequestOK(req) + require.NotContains(t, cachedRes.Body, `"errors"`) + + uncachedReq := req + uncachedReq.Header = http.Header{ + "X-WG-Disable-Entity-Cache": []string{"true"}, + } + uncachedRes := xEnv.MakeGraphQLRequestOK(uncachedReq) + require.NotContains(t, uncachedRes.Body, `"errors"`) + + require.Equal(t, uncachedRes.Body, cachedRes.Body) + }) + }) + + // Regression test for the arena pointer bug: exportRequestScopedFields must + // copy values before storing in requestScopedL1. Without the copy, stored + // pointers become dangling when the goroutine arena is reused on subsequent + // requests, causing crashes or corrupted data. + t.Run("Regression/repeated complex query does not panic", func(t *testing.T) { + t.Parallel() + + servers, _ := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + cache := newMemoryCache(t) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: entityCachingOptions(cache), + }, func(t *testing.T, xEnv *testenv.Environment) { + // A query that exercises entity fetching across multiple subgraphs + // (items + details + inventory). Repeated execution triggers arena + // reuse which would crash if exported values were not copied. + req := testenv.GraphQLRequest{ + Query: `{ item(id: "1") { id name description rating tags available count } }`, + } + for i := range 5 { + res := xEnv.MakeGraphQLRequestOK(req) + require.Contains(t, res.Body, `"Widget"`, "iteration %d: expected Widget in response", i) + require.Contains(t, res.Body, `"description"`, "iteration %d: expected description in response", i) + require.Contains(t, res.Body, `"available"`, "iteration %d: expected available in response", i) + } + }) + }) + + // Companion to mutation_populate_writes_to_cache. Both tests pin the same + // @cachePopulate read-after-write contract on a Mutation: the returned + // entity must land in L2 so the next `item(id: ...)` read is a cache hit. + // This variant keeps the RED_-style explicit response-body assertion as + // a second signal — the body assertion alone is not a truthful caching + // signal (the items store persists the new item regardless), but the + // counters.items no-growth assertion is. + // + // Historically the mutation_populate_* tests only verified the mutation + // responded; the read-path effect was added after review round 1. + t.Run("L2/cache populate writes entity for subsequent read", func(t *testing.T) { + t.Parallel() + + servers, counters := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + cache := newMemoryCache(t) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: entityCachingL2OnlyOptions(cache), + }, func(t *testing.T, xEnv *testenv.Environment) { + // createItem has @cachePopulate(maxAge: 60). The mutation must populate L2 + // with the returned Item entity under its @key("id") cache key. + createRes := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `mutation { createItem(name: "PopulatedItem", category: "populate") { id name category } }`, + }) + require.Contains(t, createRes.Body, `"PopulatedItem"`) + + // Extract the new id from the response — `nextID` is shared across the + // parallel test suite, so we can't predict it. + var idMatch struct { + Data struct { + CreateItem struct { + ID string `json:"id"` + Name string `json:"name"` + Category string `json:"category"` + } `json:"createItem"` + } `json:"data"` + } + require.NoError(t, json.Unmarshal([]byte(createRes.Body), &idMatch)) + newID := idMatch.Data.CreateItem.ID + require.NotEmpty(t, newID, "createItem must return a non-empty id") + + itemsAfterCreate := counters.items.Load() + + // Read the just-created entity by its key. If @cachePopulate wrote to L2, + // the items subgraph must NOT be called again. The items store now persists + // createItem results (see items subgraph data.go), so the response body is + // correct either way — the truthful signal is the items-counter: cache hit + // leaves it unchanged, cache miss grows it by one. + readRes := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ item(id: "` + newID + `") { id name category } }`, + }) + require.Equal(t, + `{"data":{"item":{"id":"`+newID+`","name":"PopulatedItem","category":"populate"}}}`, + readRes.Body) + require.Equal(t, itemsAfterCreate, counters.items.Load(), + "@cachePopulate must write the entity to L2 so the read-by-id is served from cache") + }) + }) + + // Regression test: @cacheInvalidate clears an entity cached under a composite @key. + // + // `delete_mutation_invalidates_cache` already covers the simple id-only case + // (Item @key("id")). This test pins the composite-key path via Product + // @key("id region") + deleteProduct(id, region) @cacheInvalidate. + // + // The cache-demo failure of an apparently equivalent scenario turned out to be + // a test-script artifact (mutable subgraph state caused warm-up to return null, + // which prevented the cache write). The router-side composite-key invalidate + // path itself works correctly — this test pins that contract. + t.Run("L2/cache invalidates composite key", func(t *testing.T) { + t.Parallel() + + servers, counters := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + cache := newMemoryCache(t) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: entityCachingL2OnlyOptions(cache), + }, func(t *testing.T, xEnv *testenv.Environment) { + warmReq := testenv.GraphQLRequest{ + Query: `{ product(id: "p1", region: "US") { id region sku name } }`, + } + // 1. Warm the cache for product (id=p1, region=US) + xEnv.MakeGraphQLRequestOK(warmReq) + itemsAfterWarm := counters.items.Load() + + // 2. Re-read — must be a cache hit + xEnv.MakeGraphQLRequestOK(warmReq) + require.Equal(t, itemsAfterWarm, counters.items.Load(), + "composite-key entity must be cached after warm-up") + + // 3. Invalidate via deleteProduct. The mutation itself hits the items subgraph + // to execute the resolver — so we capture the counter AFTER the mutation and + // only assert on the delta from the subsequent read. + delRes := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `mutation { deleteProduct(id: "p1", region: "US") { id region } }`, + }) + require.Contains(t, delRes.Body, `"deleteProduct"`) + itemsAfterMutation := counters.items.Load() + + // 4. Read again — composite-key cache MUST be cleared, items subgraph + // MUST be hit one more time. Currently fails: counter unchanged → @cacheInvalidate + // did not evict the composite-key entity, so the read is still a cache hit. + xEnv.MakeGraphQLRequestOK(warmReq) + require.Equal(t, itemsAfterMutation+1, counters.items.Load(), + "@cacheInvalidate on Mutation returning composite-key entity must clear the L2 entry; the post-invalidate read must re-fetch from subgraph") + }) + }) + + // RED test: nested @key reached via input object @is(fields: "location { id }") + // + // `warehouse(locationId: ID! @is(fields: "location.id"))` (scalar arg with dot notation) + // already passes — see "nested_key_via_is_directive" above. + // + // `warehouseByInput(input: WarehouseLocationInput! @is(fields: "location { id }"))` is + // the same nested @key reached via a multi-hop argument path. Composition produces + // the same `entityKeyField: "location.id"` plus `argumentPath: ["input","location","id"]`. + // The router's loader must walk the input-object path to construct the cache key. + // + // Discovered in cache-demo manual testing: cache lookup fires with the right key but + // every call shows l2_miss and the entity is never written. Pinning the failure here + // so the loader fix can land with a regression test. + t.Run("L2/nested key via input object @is directive", func(t *testing.T) { + t.Parallel() + + servers, counters := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + cache := newMemoryCache(t) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: entityCachingL2OnlyOptions(cache), + }, func(t *testing.T, xEnv *testenv.Environment) { + // IMPORTANT: this query does NOT select the @key field (`location { id }`). + // Reproduces the cache-demo Venue failure where queries that omit the + // key field from the selection set prevent the cache write — the router's + // entity write path derives the cache key from the response payload + // instead of from the argument values that were already used to build + // the lookup key. + // + // Compare to "nested_key_via_is_directive" above, which selects + // `location { id }` and passes — that test masks this bug because the + // key value happens to be in the response payload. + req := testenv.GraphQLRequest{ + Query: `{ warehouseByInput(input: { location: { id: "w1" } }) { name } }`, + } + res := xEnv.MakeGraphQLRequestOK(req) + require.Equal(t, `{"data":{"warehouseByInput":{"name":"Main Depot"}}}`, res.Body) + + itemsAfterFirst := counters.items.Load() + require.Equal(t, int64(1), itemsAfterFirst, "first call must hit the items subgraph") + + // Same nested key via input object → MUST be a cache hit. Currently fails: + // the items subgraph is called a second time despite the L2 lookup running + // with the structurally correct key, because the cache write path can't + // reconstruct the entity key from a response that doesn't contain the + // key field. + res2 := xEnv.MakeGraphQLRequestOK(req) + require.Equal(t, res.Body, res2.Body) + require.Equal(t, itemsAfterFirst, counters.items.Load(), + "input-object → nested-key cache write must persist when @key field is not selected; second call must NOT re-hit subgraph") + }) + }) + + // REGRESSION: a SingleFetch served entirely from L2 cache must report + // `load_skipped: true` in the request trace. Previously the resolveSingle + // path didn't set LoadSkipped on cache-hit branches even though the bulk + // parallel path already did, so observability reported `false` on fetches + // that demonstrably never called the subgraph. + t.Run("Trace/root field cache hit reports load_skipped", func(t *testing.T) { + t.Parallel() + + servers, _ := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + cache := newMemoryCache(t) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: entityCachingOptions(cache), + }, func(t *testing.T, xEnv *testenv.Environment) { + // Warm the cache. + xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ item(id: "1") { id description } }`, + }) + + // Second call with tracing enabled — assert load_skipped == true on the fetch. + res := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `{ item(id: "1") { id description } }`, + Header: map[string][]string{"X-WG-Trace": {"true"}}, + }) + var body struct { + Extensions struct { + Trace struct { + Fetches map[string]any `json:"fetches"` + } `json:"trace"` + } `json:"extensions"` + } + require.NoError(t, json.Unmarshal([]byte(res.Body), &body)) + + // Walk the fetch tree and find any Single fetch with load_skipped=true. + var anyLoadSkipped bool + var visit func(node any) + visit = func(node any) { + m, ok := node.(map[string]any) + if !ok { + return + } + if m["kind"] == "Single" { + if fetch, ok := m["fetch"].(map[string]any); ok { + if trace, ok := fetch["trace"].(map[string]any); ok { + if ls, _ := trace["load_skipped"].(bool); ls { + anyLoadSkipped = true + } + } + } + } + if children, ok := m["children"].([]any); ok { + for _, c := range children { + visit(c) + } + } + } + visit(map[string]any(body.Extensions.Trace.Fetches)) + require.True(t, anyLoadSkipped, + "trace must report load_skipped=true on the cache-hit fetch") + }) + }) + + // REGRESSION: includeHeaders=true with NO header forwarded must still produce a + // stable cache key — write and read paths must agree on the prefix. Previously + // the WRITE path dropped the prefix when headerHash==0 while the READ path + // always built "0:..." → every read missed. + t.Run("L2/include headers still caches when no header is forwarded", func(t *testing.T) { + t.Parallel() + + servers, counters := startSubgraphServers(t) + configJSON := buildConfigJSON(servers) + cache := newMemoryCache(t) + + testenv.Run(t, &testenv.Config{ + RouterConfigJSONTemplate: configJSON, + RouterOptions: append( + entityCachingL2OnlyOptions(cache), + core.WithHeaderRules(config.HeaderRules{ + All: &config.GlobalHeaderRule{ + Request: []*config.RequestHeaderRule{ + { + Operation: config.HeaderRuleOperationPropagate, + Named: "X-Tenant", + }, + }, + }, + }), + ), + ModifyRouterConfig: func(routerConfig *nodev1.RouterConfig) { + setEntityCacheIncludeHeaders(routerConfig, true) + }, + }, func(t *testing.T, xEnv *testenv.Environment) { + req := testenv.GraphQLRequest{ + Query: `{ item(id: "1") { id description } }`, + // No X-Tenant header sent — SubgraphHeadersBuilder returns hash=0. + } + + // First call: cache miss → subgraph fetch. + xEnv.MakeGraphQLRequestOK(req) + detailsAfterFirst := counters.details.Load() + require.Equal(t, int64(1), detailsAfterFirst) + + // Second call (same query, still no header): MUST be a cache hit. Counter + // stays at 1. Previously failed because write key {json} ≠ read key 0:{json}. + xEnv.MakeGraphQLRequestOK(req) + require.Equal(t, detailsAfterFirst, counters.details.Load(), + "includeHeaders=true with no header forwarded must produce a stable cache key; second call must hit cache") + }) + }) +} diff --git a/router-tests/entitycaching/harness_test.go b/router-tests/entitycaching/harness_test.go new file mode 100644 index 0000000000..0ac4a4c425 --- /dev/null +++ b/router-tests/entitycaching/harness_test.go @@ -0,0 +1,523 @@ +package entitycaching + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + "net/http/httptest" + "strings" + "sync/atomic" + "testing" + "time" + + "github.com/99designs/gqlgen/graphql/handler" + "github.com/99designs/gqlgen/graphql/handler/transport" + "github.com/alicebob/miniredis/v2" + "github.com/redis/go-redis/v9" + "github.com/stretchr/testify/require" + + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachetest/articles" + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachetest/articlesmeta" + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachetest/details" + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachetest/inventory" + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachetest/items" + itemsModel "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachetest/items/subgraph/model" + "github.com/wundergraph/cosmo/demo/pkg/subgraphs/cachetest/viewer" + "github.com/wundergraph/cosmo/router/core" + nodev1 "github.com/wundergraph/cosmo/router/gen/proto/wg/cosmo/node/v1" + "github.com/wundergraph/cosmo/router/pkg/config" + "github.com/wundergraph/cosmo/router/pkg/entitycache" + "github.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve" +) + +type requestCounters struct { + items atomic.Int64 + details atomic.Int64 + inventory atomic.Int64 + viewer atomic.Int64 + articles atomic.Int64 + articlesMeta atomic.Int64 +} + +func countingMiddleware(counter *atomic.Int64, next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + counter.Add(1) + next.ServeHTTP(w, r) + }) +} + +type subgraphServers struct { + items *httptest.Server + details *httptest.Server + inventory *httptest.Server + viewer *httptest.Server + articles *httptest.Server + articlesMeta *httptest.Server + // Subscription channels for the items subgraph. + itemUpdatedCh chan *itemsModel.Item + itemCreatedCh chan *itemsModel.Item +} + +func startSubgraphServers(t *testing.T) (*subgraphServers, *requestCounters) { + t.Helper() + + counters := &requestCounters{} + itemUpdatedCh := make(chan *itemsModel.Item, 1) + itemCreatedCh := make(chan *itemsModel.Item, 1) + + itemsSchema := items.NewSchema(itemUpdatedCh, itemCreatedCh) + itemsHandler := handler.New(itemsSchema) + itemsHandler.AddTransport(transport.POST{}) + itemsHandler.AddTransport(transport.Websocket{ + KeepAlivePingInterval: 10 * time.Second, + }) + + detailsSchema := details.NewSchema() + detailsHandler := handler.New(detailsSchema) + detailsHandler.AddTransport(transport.POST{}) + + inventorySchema := inventory.NewSchema() + inventoryHandler := handler.New(inventorySchema) + inventoryHandler.AddTransport(transport.POST{}) + + viewerSchema := viewer.NewSchema() + viewerHandler := handler.New(viewerSchema) + viewerHandler.AddTransport(transport.POST{}) + + articlesSchema := articles.NewSchema() + articlesHandler := handler.New(articlesSchema) + articlesHandler.AddTransport(transport.POST{}) + + articlesMetaSchema := articlesmeta.NewSchema() + articlesMetaHandler := handler.New(articlesMetaSchema) + articlesMetaHandler.AddTransport(transport.POST{}) + + itemsSrv := httptest.NewServer(countingMiddleware(&counters.items, itemsHandler)) + t.Cleanup(itemsSrv.Close) + + detailsSrv := httptest.NewServer(countingMiddleware(&counters.details, detailsHandler)) + t.Cleanup(detailsSrv.Close) + + inventorySrv := httptest.NewServer(countingMiddleware(&counters.inventory, inventoryHandler)) + t.Cleanup(inventorySrv.Close) + + viewerSrv := httptest.NewServer(countingMiddleware(&counters.viewer, viewerHandler)) + t.Cleanup(viewerSrv.Close) + + articlesSrv := httptest.NewServer(countingMiddleware(&counters.articles, articlesHandler)) + t.Cleanup(articlesSrv.Close) + + articlesMetaSrv := httptest.NewServer(countingMiddleware(&counters.articlesMeta, articlesMetaHandler)) + t.Cleanup(articlesMetaSrv.Close) + + return &subgraphServers{ + items: itemsSrv, + details: detailsSrv, + inventory: inventorySrv, + viewer: viewerSrv, + articles: articlesSrv, + articlesMeta: articlesMetaSrv, + itemUpdatedCh: itemUpdatedCh, + itemCreatedCh: itemCreatedCh, + }, counters +} + +func startSubgraphServersWithMiddleware(t *testing.T, mw func(http.Handler) http.Handler) (*subgraphServers, *requestCounters) { + t.Helper() + + counters := &requestCounters{} + itemUpdatedCh := make(chan *itemsModel.Item, 1) + itemCreatedCh := make(chan *itemsModel.Item, 1) + + itemsSchema := items.NewSchema(itemUpdatedCh, itemCreatedCh) + itemsHandler := handler.New(itemsSchema) + itemsHandler.AddTransport(transport.POST{}) + itemsHandler.AddTransport(transport.Websocket{ + KeepAlivePingInterval: 10 * time.Second, + }) + + detailsSchema := details.NewSchema() + detailsHandler := handler.New(detailsSchema) + detailsHandler.AddTransport(transport.POST{}) + + inventorySchema := inventory.NewSchema() + inventoryHandler := handler.New(inventorySchema) + inventoryHandler.AddTransport(transport.POST{}) + + viewerSchema := viewer.NewSchema() + viewerHandler := handler.New(viewerSchema) + viewerHandler.AddTransport(transport.POST{}) + + articlesSchema := articles.NewSchema() + articlesHandler := handler.New(articlesSchema) + articlesHandler.AddTransport(transport.POST{}) + + articlesMetaSchema := articlesmeta.NewSchema() + articlesMetaHandler := handler.New(articlesMetaSchema) + articlesMetaHandler.AddTransport(transport.POST{}) + + var detailsWrapped http.Handler = detailsHandler + if mw != nil { + detailsWrapped = mw(detailsHandler) + } + + itemsSrv := httptest.NewServer(countingMiddleware(&counters.items, itemsHandler)) + t.Cleanup(itemsSrv.Close) + + detailsSrv := httptest.NewServer(countingMiddleware(&counters.details, detailsWrapped)) + t.Cleanup(detailsSrv.Close) + + inventorySrv := httptest.NewServer(countingMiddleware(&counters.inventory, inventoryHandler)) + t.Cleanup(inventorySrv.Close) + + viewerSrv := httptest.NewServer(countingMiddleware(&counters.viewer, viewerHandler)) + t.Cleanup(viewerSrv.Close) + + articlesSrv := httptest.NewServer(countingMiddleware(&counters.articles, articlesHandler)) + t.Cleanup(articlesSrv.Close) + + articlesMetaSrv := httptest.NewServer(countingMiddleware(&counters.articlesMeta, articlesMetaHandler)) + t.Cleanup(articlesMetaSrv.Close) + + return &subgraphServers{ + items: itemsSrv, + details: detailsSrv, + inventory: inventorySrv, + viewer: viewerSrv, + articles: articlesSrv, + articlesMeta: articlesMetaSrv, + itemUpdatedCh: itemUpdatedCh, + itemCreatedCh: itemCreatedCh, + }, counters +} + +func TestStartSubgraphServersWithMiddlewareBuildsCompleteConfig(t *testing.T) { + t.Parallel() + + servers, _ := startSubgraphServersWithMiddleware(t, nil) + require.NotNil(t, servers.articlesMeta) + require.NotPanics(t, func() { + _ = buildConfigJSON(servers) + }) +} + +func buildConfigJSON(servers *subgraphServers) string { + replaced := configJSONTemplate + replaced = strings.ReplaceAll(replaced, itemsPlaceholderURL, servers.items.URL) + replaced = strings.ReplaceAll(replaced, detailsPlaceholderURL, servers.details.URL) + replaced = strings.ReplaceAll(replaced, inventoryPlaceholderURL, servers.inventory.URL) + replaced = strings.ReplaceAll(replaced, viewerPlaceholderURL, servers.viewer.URL) + replaced = strings.ReplaceAll(replaced, articlesPlaceholderURL, servers.articles.URL) + replaced = strings.ReplaceAll(replaced, articlesMetaPlaceholderURL, servers.articlesMeta.URL) + return replaced +} + +func entityCachingOptions(cache resolve.LoaderCache) []core.Option { + return []core.Option{ + core.WithEntityCaching(config.EntityCachingConfiguration{ + Enabled: true, + L1: config.EntityCachingL1Configuration{ + Enabled: true, + }, + L2: config.EntityCachingL2Configuration{ + Enabled: true, + }, + }), + core.WithEntityCacheInstances(map[string]resolve.LoaderCache{ + "default": cache, + }), + } +} + +// entityCachingL1OnlyOptions enables only the per-request L1 cache. +// Use in subtests named L1/... so the assertion depends on L1 behavior alone, +// not on L2 coincidentally helping. +func entityCachingL1OnlyOptions() []core.Option { + return []core.Option{ + core.WithEntityCaching(config.EntityCachingConfiguration{ + Enabled: true, + L1: config.EntityCachingL1Configuration{ + Enabled: true, + }, + L2: config.EntityCachingL2Configuration{ + Enabled: false, + }, + }), + } +} + +// entityCachingL2OnlyOptions enables only the cross-request L2 cache. +// Use in subtests named L2/... so the assertion depends on L2 behavior alone. +func entityCachingL2OnlyOptions(cache resolve.LoaderCache) []core.Option { + return []core.Option{ + core.WithEntityCaching(config.EntityCachingConfiguration{ + Enabled: true, + L1: config.EntityCachingL1Configuration{ + Enabled: false, + }, + L2: config.EntityCachingL2Configuration{ + Enabled: true, + }, + }), + core.WithEntityCacheInstances(map[string]resolve.LoaderCache{ + "default": cache, + }), + } +} + +// entityCachingDisabledOptions turns both layers off. +// Use as the baseline for inverse "L1 disabled → N calls" assertions. +func entityCachingDisabledOptions() []core.Option { + return []core.Option{ + core.WithEntityCaching(config.EntityCachingConfiguration{ + Enabled: true, + L1: config.EntityCachingL1Configuration{ + Enabled: false, + }, + L2: config.EntityCachingL2Configuration{ + Enabled: false, + }, + }), + } +} + +// clearEntityCacheConfigs removes all entity cache configs from the router config. +func clearEntityCacheConfigs(rc *nodev1.RouterConfig) { + for _, ds := range rc.EngineConfig.DatasourceConfigurations { + ds.EntityCacheConfigurations = nil + ds.RootFieldCacheConfigurations = nil + ds.CacheInvalidateConfigurations = nil + ds.CachePopulateConfigurations = nil + } +} + +// setEntityCacheTTL overrides MaxAgeSeconds on all entity cache configs. +func setEntityCacheTTL(rc *nodev1.RouterConfig, ttl int64) { + for _, ds := range rc.EngineConfig.DatasourceConfigurations { + for _, ec := range ds.EntityCacheConfigurations { + ec.MaxAgeSeconds = ttl + } + } +} + +// setEntityCacheShadowMode sets ShadowMode on all entity cache configs. +func setEntityCacheShadowMode(rc *nodev1.RouterConfig, enabled bool) { + for _, ds := range rc.EngineConfig.DatasourceConfigurations { + for _, ec := range ds.EntityCacheConfigurations { + ec.ShadowMode = enabled + } + } +} + +// setEntityCachePartialLoad sets PartialCacheLoad on all entity cache configs. +func setEntityCachePartialLoad(rc *nodev1.RouterConfig, enabled bool) { + for _, ds := range rc.EngineConfig.DatasourceConfigurations { + for _, ec := range ds.EntityCacheConfigurations { + ec.PartialCacheLoad = enabled + } + } +} + +// setEntityCacheIncludeHeaders sets IncludeHeaders on all entity cache configs. +func setEntityCacheIncludeHeaders(rc *nodev1.RouterConfig, enabled bool) { + for _, ds := range rc.EngineConfig.DatasourceConfigurations { + for _, ec := range ds.EntityCacheConfigurations { + ec.IncludeHeaders = enabled + } + } +} + +// setNotFoundCacheTTL sets NotFoundCacheTtlSeconds on all entity cache configs. +func setNotFoundCacheTTL(rc *nodev1.RouterConfig, ttl int64) { + for _, ds := range rc.EngineConfig.DatasourceConfigurations { + for _, ec := range ds.EntityCacheConfigurations { + ec.NotFoundCacheTtlSeconds = ttl + } + } +} + +// setQueryCacheShadowMode sets ShadowMode on all root field cache configs. +func setQueryCacheShadowMode(rc *nodev1.RouterConfig, enabled bool) { + for _, ds := range rc.EngineConfig.DatasourceConfigurations { + for _, rfc := range ds.RootFieldCacheConfigurations { + rfc.ShadowMode = enabled + } + } +} + +// setQueryCacheIncludeHeaders sets IncludeHeaders on all root field cache configs. +func setQueryCacheIncludeHeaders(rc *nodev1.RouterConfig, enabled bool) { + for _, ds := range rc.EngineConfig.DatasourceConfigurations { + for _, rfc := range ds.RootFieldCacheConfigurations { + rfc.IncludeHeaders = enabled + } + } +} + +// setCachePopulateTTL overrides MaxAgeSeconds on all cache populate configs. +func setCachePopulateTTL(rc *nodev1.RouterConfig, ttl int64) { + for _, ds := range rc.EngineConfig.DatasourceConfigurations { + for _, cp := range ds.CachePopulateConfigurations { + cp.MaxAgeSeconds = &ttl + } + } +} + +// FailingEntityCache implements resolve.LoaderCache and always returns errors. +type FailingEntityCache struct{} + +var _ resolve.LoaderCache = (*FailingEntityCache)(nil) + +func (f *FailingEntityCache) Get(_ context.Context, keys []string) ([]*resolve.CacheEntry, error) { + return nil, errCacheFailed +} + +func (f *FailingEntityCache) Set(_ context.Context, _ []*resolve.CacheEntry) error { + return errCacheFailed +} + +func (f *FailingEntityCache) Delete(_ context.Context, _ []string) error { + return errCacheFailed +} + +var errCacheFailed = &cacheFailed{} + +type cacheFailed struct{} + +func (c *cacheFailed) Error() string { + return "entity cache operation failed" +} + +// ControllableCache wraps a MemoryEntityCache but can be toggled to fail on demand. +// Use SetFailing(true) to simulate a Redis outage mid-test. +type ControllableCache struct { + inner *entitycache.MemoryEntityCache + failing atomic.Bool +} + +func newControllableCache(t *testing.T) *ControllableCache { + t.Helper() + cache, err := entitycache.NewMemoryEntityCache(10 * 1024 * 1024) + require.NoError(t, err) + t.Cleanup(func() { _ = cache.Close() }) + return &ControllableCache{inner: cache} +} + +func (c *ControllableCache) SetFailing(v bool) { c.failing.Store(v) } + +func (c *ControllableCache) Get(ctx context.Context, keys []string) ([]*resolve.CacheEntry, error) { + if c.failing.Load() { + return nil, errCacheFailed + } + return c.inner.Get(ctx, keys) +} + +func (c *ControllableCache) Set(ctx context.Context, entries []*resolve.CacheEntry) error { + if c.failing.Load() { + return errCacheFailed + } + return c.inner.Set(ctx, entries) +} + +func (c *ControllableCache) Delete(ctx context.Context, keys []string) error { + if c.failing.Load() { + return errCacheFailed + } + return c.inner.Delete(ctx, keys) +} + +// entityCachingOptionsWithCircuitBreakerRef returns L2-only router options with +// a CircuitBreakerCache so tests can inspect its state. +func entityCachingOptionsWithCircuitBreakerRef(cache resolve.LoaderCache, threshold int, cooldown time.Duration) ([]core.Option, *entitycache.CircuitBreakerCache) { + cb := entitycache.NewCircuitBreakerCache(cache, entitycache.CircuitBreakerConfig{ + Enabled: true, + FailureThreshold: threshold, + CooldownPeriod: cooldown, + }) + return entityCachingL2OnlyOptions(cb), cb +} + +// entityCachingOptionsWithSubgraphConfig returns L2-only router options with +// per-subgraph cache routing. +func entityCachingOptionsWithSubgraphConfig(caches map[string]resolve.LoaderCache, subgraphs []config.EntityCachingSubgraphCacheOverride) []core.Option { + return []core.Option{ + core.WithEntityCaching(config.EntityCachingConfiguration{ + Enabled: true, + L1: config.EntityCachingL1Configuration{ + Enabled: false, + }, + L2: config.EntityCachingL2Configuration{ + Enabled: true, + }, + SubgraphCacheOverrides: subgraphs, + }), + core.WithEntityCacheInstances(caches), + } +} + +// newMemoryCache is a convenience wrapper. +func newMemoryCache(t *testing.T) *entitycache.MemoryEntityCache { + t.Helper() + c, err := entitycache.NewMemoryEntityCache(10 * 1024 * 1024) // 10MB for tests + require.NoError(t, err) + t.Cleanup(func() { _ = c.Close() }) + return c +} + +// newTestRedisCache creates a miniredis-backed cache for testing. +func newTestRedisCache(t *testing.T) (*entitycache.RedisEntityCache, *miniredis.Miniredis) { + t.Helper() + mr := miniredis.RunT(t) + client := redis.NewClient(&redis.Options{Addr: mr.Addr()}) + t.Cleanup(func() { client.Close() }) + return entitycache.NewRedisEntityCache(client, "test"), mr +} + +// extensionInvalidationMiddleware returns an HTTP middleware that injects +// a cacheInvalidation extension into the subgraph response when the flag is set. +// Format: {"extensions":{"cacheInvalidation":{"keys":[{"typename":"Item","key":{"id":"1"}}]}}} +func extensionInvalidationMiddleware(flag *atomic.Bool) func(http.Handler) http.Handler { + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if !flag.Load() { + next.ServeHTTP(w, r) + return + } + // Capture the response. + rec := httptest.NewRecorder() + next.ServeHTTP(rec, r) + + body := rec.Body.Bytes() + var resp map[string]json.RawMessage + if err := json.Unmarshal(body, &resp); err != nil { + // Pass through on unmarshal error. + for k, v := range rec.Header() { + w.Header()[k] = v + } + w.WriteHeader(rec.Code) + _, _ = w.Write(body) + return + } + + // Inject cacheInvalidation extension. + ext := map[string]any{ + "cacheInvalidation": map[string]any{ + "keys": []map[string]any{ + {"typename": "Item", "key": map[string]any{"id": "1"}}, + }, + }, + } + extBytes, _ := json.Marshal(ext) + resp["extensions"] = extBytes + modified, _ := json.Marshal(resp) + + for k, v := range rec.Header() { + w.Header()[k] = v + } + w.Header().Set("Content-Length", fmt.Sprintf("%d", len(modified))) + w.WriteHeader(rec.Code) + _, _ = w.Write(modified) + }) + } +} diff --git a/router-tests/entitycaching/redis_test.go b/router-tests/entitycaching/redis_test.go new file mode 100644 index 0000000000..0a8323f230 --- /dev/null +++ b/router-tests/entitycaching/redis_test.go @@ -0,0 +1,123 @@ +package entitycaching + +import ( + "testing" + "time" + + "github.com/stretchr/testify/require" + + "github.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve" +) + +func TestRedis(t *testing.T) { + t.Parallel() + + t.Run("basic_miss_then_hit", func(t *testing.T) { + t.Parallel() + + cache, _ := newTestRedisCache(t) + ctx := t.Context() + + // Get miss + entries, err := cache.Get(ctx, []string{"key1"}) + require.NoError(t, err) + require.Len(t, entries, 1) + require.Nil(t, entries[0]) + + // Set + err = cache.Set(ctx, []*resolve.CacheEntry{ + {Key: "key1", Value: []byte(`{"id":"1","name":"Widget"}`), TTL: 300 * time.Second}, + }) + require.NoError(t, err) + + // Get hit + entries, err = cache.Get(ctx, []string{"key1"}) + require.NoError(t, err) + require.Len(t, entries, 1) + require.NotNil(t, entries[0]) + require.Equal(t, "key1", entries[0].Key) + require.Equal(t, `{"id":"1","name":"Widget"}`, string(entries[0].Value)) + }) + + t.Run("batch_operations", func(t *testing.T) { + t.Parallel() + + cache, _ := newTestRedisCache(t) + ctx := t.Context() + + // Batch Set + err := cache.Set(ctx, []*resolve.CacheEntry{ + {Key: "a", Value: []byte(`{"id":"1"}`), TTL: 300 * time.Second}, + {Key: "b", Value: []byte(`{"id":"2"}`), TTL: 300 * time.Second}, + {Key: "c", Value: []byte(`{"id":"3"}`), TTL: 300 * time.Second}, + }) + require.NoError(t, err) + + // Batch Get (MGet) + entries, err := cache.Get(ctx, []string{"a", "b", "c", "d"}) + require.NoError(t, err) + require.Len(t, entries, 4) + require.NotNil(t, entries[0]) + require.Equal(t, `{"id":"1"}`, string(entries[0].Value)) + require.NotNil(t, entries[1]) + require.Equal(t, `{"id":"2"}`, string(entries[1].Value)) + require.NotNil(t, entries[2]) + require.Equal(t, `{"id":"3"}`, string(entries[2].Value)) + require.Nil(t, entries[3]) // "d" not set + }) + + t.Run("ttl_expiry", func(t *testing.T) { + t.Parallel() + + cache, mr := newTestRedisCache(t) + ctx := t.Context() + + err := cache.Set(ctx, []*resolve.CacheEntry{ + {Key: "expiring", Value: []byte(`{"ttl":"test"}`), TTL: 1 * time.Second}, + }) + require.NoError(t, err) + + // Verify it's there + entries, err := cache.Get(ctx, []string{"expiring"}) + require.NoError(t, err) + require.NotNil(t, entries[0]) + + // Fast-forward time + mr.FastForward(2 * time.Second) + + // Should be expired + entries, err = cache.Get(ctx, []string{"expiring"}) + require.NoError(t, err) + require.Nil(t, entries[0]) + }) + + t.Run("delete", func(t *testing.T) { + t.Parallel() + + cache, _ := newTestRedisCache(t) + ctx := t.Context() + + // Set entries + err := cache.Set(ctx, []*resolve.CacheEntry{ + {Key: "del1", Value: []byte(`{"a":"1"}`), TTL: 300 * time.Second}, + {Key: "del2", Value: []byte(`{"b":"2"}`), TTL: 300 * time.Second}, + }) + require.NoError(t, err) + + // Verify present + entries, err := cache.Get(ctx, []string{"del1", "del2"}) + require.NoError(t, err) + require.NotNil(t, entries[0]) + require.NotNil(t, entries[1]) + + // Delete one + err = cache.Delete(ctx, []string{"del1"}) + require.NoError(t, err) + + // Verify deleted + entries, err = cache.Get(ctx, []string{"del1", "del2"}) + require.NoError(t, err) + require.Nil(t, entries[0]) + require.NotNil(t, entries[1]) + }) +} diff --git a/router-tests/entitycaching/setup_test.go b/router-tests/entitycaching/setup_test.go new file mode 100644 index 0000000000..32148ab950 --- /dev/null +++ b/router-tests/entitycaching/setup_test.go @@ -0,0 +1,17 @@ +package entitycaching + +import ( + _ "embed" +) + +//go:embed testdata/config.json +var configJSONTemplate string + +const ( + itemsPlaceholderURL = "http://items.entity-cache-test.local/graphql" + detailsPlaceholderURL = "http://details.entity-cache-test.local/graphql" + inventoryPlaceholderURL = "http://inventory.entity-cache-test.local/graphql" + viewerPlaceholderURL = "http://viewer.entity-cache-test.local/graphql" + articlesPlaceholderURL = "http://articles.entity-cache-test.local/graphql" + articlesMetaPlaceholderURL = "http://articlesmeta.entity-cache-test.local/graphql" +) diff --git a/router-tests/entitycaching/testdata/config.json b/router-tests/entitycaching/testdata/config.json new file mode 100644 index 0000000000..1d08d91dd8 --- /dev/null +++ b/router-tests/entitycaching/testdata/config.json @@ -0,0 +1,930 @@ +{ + "engineConfig": { + "defaultFlushInterval": "500", + "datasourceConfigurations": [ + { + "kind": "GRAPHQL", + "rootNodes": [ + { + "typeName": "Query", + "fieldNames": [ + "item", + "itemByPid", + "items", + "itemsByIds", + "product", + "productBySku", + "productByName", + "productByKey", + "warehouse", + "warehouseByInput" + ] + }, + { + "typeName": "Mutation", + "fieldNames": [ + "updateItem", + "deleteItem", + "createItem", + "deleteProduct" + ] + }, + { + "typeName": "Subscription", + "fieldNames": [ + "itemUpdated", + "itemCreated" + ] + }, + { + "typeName": "Item", + "fieldNames": [ + "id", + "name", + "category" + ] + }, + { + "typeName": "Product", + "fieldNames": [ + "id", + "region", + "sku", + "name" + ] + }, + { + "typeName": "Warehouse", + "fieldNames": [ + "location", + "name" + ] + } + ], + "childNodes": [ + { + "typeName": "Location", + "fieldNames": [ + "id" + ] + } + ], + "overrideFieldPathFromAlias": true, + "customGraphql": { + "fetch": { + "url": { + "staticVariableContent": "http://items.entity-cache-test.local/graphql" + }, + "method": "POST", + "body": {}, + "baseUrl": {}, + "path": {} + }, + "subscription": { + "enabled": true, + "url": { + "staticVariableContent": "http://items.entity-cache-test.local/graphql" + }, + "protocol": "GRAPHQL_SUBSCRIPTION_PROTOCOL_WS", + "websocketSubprotocol": "GRAPHQL_WEBSOCKET_SUBPROTOCOL_AUTO" + }, + "federation": { + "enabled": true, + "serviceSdl": "extend schema\n @link(\n url: \"https://specs.apollo.dev/federation/v2.5\"\n import: [\"@key\"]\n )\n\ndirective @openfed__entityCache(\n maxAge: Int!\n negativeCacheTTL: Int = 0\n includeHeaders: Boolean = false\n partialCacheLoad: Boolean = false\n shadowMode: Boolean = false\n) on OBJECT\n\ndirective @openfed__queryCache(\n maxAge: Int!\n includeHeaders: Boolean = false\n shadowMode: Boolean = false\n) on FIELD_DEFINITION\n\ndirective @openfed__cacheInvalidate on FIELD_DEFINITION\n\ndirective @openfed__cachePopulate(maxAge: Int) on FIELD_DEFINITION\n\ndirective @openfed__is(fields: String!) on ARGUMENT_DEFINITION\n\ntype Query {\n item(id: ID!): Item @openfed__queryCache(maxAge: 300)\n itemByPid(pid: ID! @openfed__is(fields: \"id\")): Item @openfed__queryCache(maxAge: 300)\n items: [Item!]! @openfed__queryCache(maxAge: 300)\n itemsByIds(ids: [ID!]! @openfed__is(fields: \"id\")): [Item!]! @openfed__queryCache(maxAge: 300)\n product(id: ID!, region: String!): Product @openfed__queryCache(maxAge: 300)\n productBySku(sku: String!): Product @openfed__queryCache(maxAge: 300)\n productByName(name: String!): Product @openfed__queryCache(maxAge: 300)\n productByKey(key: ProductKeyInput! @openfed__is(fields: \"id region\")): Product @openfed__queryCache(maxAge: 300)\n warehouse(locationId: ID! @openfed__is(fields: \"location.id\")): Warehouse @openfed__queryCache(maxAge: 300)\n # warehouseByInput exercises the same nested @key as `warehouse` but reaches it\n # via an input object using GraphQL selection syntax in @openfed__is. This produces the\n # multi-hop argumentPath [\"input\",\"location\",\"id\"] instead of the scalar\n # [\"locationId\"]. Captures the red state where input-object → nested-key\n # cache writes don't persist (cache lookup uses correct key but never hits).\n warehouseByInput(input: WarehouseLocationInput! @openfed__is(fields: \"location { id }\")): Warehouse @openfed__queryCache(maxAge: 300)\n}\n\ninput ProductKeyInput {\n id: ID!\n region: String!\n}\n\ninput WarehouseLocationInput {\n location: WarehouseLocationKeyInput!\n}\n\ninput WarehouseLocationKeyInput {\n id: ID!\n}\n\ntype Mutation {\n updateItem(id: ID!, name: String!): Item @openfed__cacheInvalidate\n deleteItem(id: ID!): Item @openfed__cacheInvalidate\n createItem(name: String!, category: String!): Item! @openfed__cachePopulate(maxAge: 60)\n # deleteProduct invalidates a composite-key entity (Product @key(\"id region\")).\n # Used to pin behavior for cache invalidation when the entity uses a composite\n # @key — a separate code path from the simple id-only key in deleteItem.\n deleteProduct(id: ID!, region: String!): Product @openfed__cacheInvalidate\n}\n\ntype Subscription {\n itemUpdated: Item @openfed__cacheInvalidate\n itemCreated: Item @openfed__cachePopulate\n}\n\ntype Item @key(fields: \"id\") @openfed__entityCache(maxAge: 300, negativeCacheTTL: 30) {\n id: ID!\n name: String!\n category: String!\n}\n\ntype Product @key(fields: \"id region\") @key(fields: \"sku\") @openfed__entityCache(maxAge: 300) {\n id: ID!\n region: String!\n sku: String!\n name: String!\n}\n\ntype Location {\n id: ID!\n}\n\ntype Warehouse @key(fields: \"location { id }\") @openfed__entityCache(maxAge: 300) {\n location: Location!\n name: String!\n}\n" + }, + "upstreamSchema": { + "key": "bd938246cff0199909aca1d5df40d042d917c954" + } + }, + "requestTimeoutSeconds": "10", + "id": "0", + "keys": [ + { + "typeName": "Item", + "selectionSet": "id" + }, + { + "typeName": "Product", + "selectionSet": "id region" + }, + { + "typeName": "Product", + "selectionSet": "sku" + }, + { + "typeName": "Warehouse", + "selectionSet": "location { id }" + } + ], + "entityCacheConfigurations": [ + { + "typeName": "Item", + "maxAgeSeconds": "300", + "notFoundCacheTtlSeconds": "30" + }, + { + "typeName": "Product", + "maxAgeSeconds": "300" + }, + { + "typeName": "Warehouse", + "maxAgeSeconds": "300" + } + ], + "rootFieldCacheConfigurations": [ + { + "fieldName": "item", + "maxAgeSeconds": "300", + "entityTypeName": "Item", + "entityKeyMappings": [ + { + "entityTypeName": "Item", + "fieldMappings": [ + { + "entityKeyField": "id", + "argumentPath": [ + "id" + ] + } + ] + } + ] + }, + { + "fieldName": "itemByPid", + "maxAgeSeconds": "300", + "entityTypeName": "Item", + "entityKeyMappings": [ + { + "entityTypeName": "Item", + "fieldMappings": [ + { + "entityKeyField": "id", + "argumentPath": [ + "pid" + ] + } + ] + } + ] + }, + { + "fieldName": "items", + "maxAgeSeconds": "300", + "entityTypeName": "Item" + }, + { + "fieldName": "itemsByIds", + "maxAgeSeconds": "300", + "entityTypeName": "Item", + "entityKeyMappings": [ + { + "entityTypeName": "Item", + "fieldMappings": [ + { + "entityKeyField": "id", + "argumentPath": [ + "ids" + ], + "isBatch": true + } + ] + } + ] + }, + { + "fieldName": "product", + "maxAgeSeconds": "300", + "entityTypeName": "Product", + "entityKeyMappings": [ + { + "entityTypeName": "Product", + "fieldMappings": [ + { + "entityKeyField": "id", + "argumentPath": [ + "id" + ] + }, + { + "entityKeyField": "region", + "argumentPath": [ + "region" + ] + } + ] + } + ] + }, + { + "fieldName": "productBySku", + "maxAgeSeconds": "300", + "entityTypeName": "Product", + "entityKeyMappings": [ + { + "entityTypeName": "Product", + "fieldMappings": [ + { + "entityKeyField": "sku", + "argumentPath": [ + "sku" + ] + } + ] + } + ] + }, + { + "fieldName": "productByName", + "maxAgeSeconds": "300", + "entityTypeName": "Product" + }, + { + "fieldName": "productByKey", + "maxAgeSeconds": "300", + "entityTypeName": "Product", + "entityKeyMappings": [ + { + "entityTypeName": "Product", + "fieldMappings": [ + { + "entityKeyField": "id", + "argumentPath": [ + "key", + "id" + ] + }, + { + "entityKeyField": "region", + "argumentPath": [ + "key", + "region" + ] + } + ] + } + ] + }, + { + "fieldName": "warehouse", + "maxAgeSeconds": "300", + "entityTypeName": "Warehouse", + "entityKeyMappings": [ + { + "entityTypeName": "Warehouse", + "fieldMappings": [ + { + "entityKeyField": "location.id", + "argumentPath": [ + "locationId" + ] + } + ] + } + ] + }, + { + "fieldName": "warehouseByInput", + "maxAgeSeconds": "300", + "entityTypeName": "Warehouse", + "entityKeyMappings": [ + { + "entityTypeName": "Warehouse", + "fieldMappings": [ + { + "entityKeyField": "location.id", + "argumentPath": [ + "input", + "location", + "id" + ] + } + ] + } + ] + } + ], + "cachePopulateConfigurations": [ + { + "fieldName": "createItem", + "operationType": "Mutation", + "maxAgeSeconds": "60", + "entityTypeName": "Item" + }, + { + "fieldName": "itemCreated", + "operationType": "Subscription", + "entityTypeName": "Item" + } + ], + "cacheInvalidateConfigurations": [ + { + "fieldName": "updateItem", + "operationType": "Mutation", + "entityTypeName": "Item" + }, + { + "fieldName": "deleteItem", + "operationType": "Mutation", + "entityTypeName": "Item" + }, + { + "fieldName": "deleteProduct", + "operationType": "Mutation", + "entityTypeName": "Product" + }, + { + "fieldName": "itemUpdated", + "operationType": "Subscription", + "entityTypeName": "Item" + } + ] + }, + { + "kind": "GRAPHQL", + "rootNodes": [ + { + "typeName": "Item", + "fieldNames": [ + "id", + "description", + "rating", + "tags" + ] + }, + { + "typeName": "Product", + "fieldNames": [ + "id", + "region", + "info" + ] + }, + { + "typeName": "Warehouse", + "fieldNames": [ + "location", + "capacity" + ] + } + ], + "childNodes": [ + { + "typeName": "Location", + "fieldNames": [ + "id" + ] + } + ], + "overrideFieldPathFromAlias": true, + "customGraphql": { + "fetch": { + "url": { + "staticVariableContent": "http://details.entity-cache-test.local/graphql" + }, + "method": "POST", + "body": {}, + "baseUrl": {}, + "path": {} + }, + "subscription": { + "enabled": true, + "url": { + "staticVariableContent": "http://details.entity-cache-test.local/graphql" + }, + "protocol": "GRAPHQL_SUBSCRIPTION_PROTOCOL_WS", + "websocketSubprotocol": "GRAPHQL_WEBSOCKET_SUBPROTOCOL_AUTO" + }, + "federation": { + "enabled": true, + "serviceSdl": "extend schema\n @link(\n url: \"https://specs.apollo.dev/federation/v2.5\"\n import: [\"@key\"]\n )\n\ndirective @openfed__entityCache(\n maxAge: Int!\n includeHeaders: Boolean = false\n partialCacheLoad: Boolean = false\n shadowMode: Boolean = false\n) on OBJECT\n\ntype Item @key(fields: \"id\") @openfed__entityCache(maxAge: 300) {\n id: ID!\n description: String!\n rating: Float!\n tags: [String!]!\n}\n\ntype Product @key(fields: \"id region\") @openfed__entityCache(maxAge: 300) {\n id: ID!\n region: String!\n info: String!\n}\n\ntype Location {\n id: ID!\n}\n\ntype Warehouse @key(fields: \"location { id }\") @openfed__entityCache(maxAge: 300) {\n location: Location!\n capacity: Int!\n}\n" + }, + "upstreamSchema": { + "key": "c155dbdb80b10cafddd0f1f0379b57532dc3dcc7" + } + }, + "requestTimeoutSeconds": "10", + "id": "1", + "keys": [ + { + "typeName": "Item", + "selectionSet": "id" + }, + { + "typeName": "Product", + "selectionSet": "id region" + }, + { + "typeName": "Warehouse", + "selectionSet": "location { id }" + } + ], + "entityCacheConfigurations": [ + { + "typeName": "Item", + "maxAgeSeconds": "300" + }, + { + "typeName": "Product", + "maxAgeSeconds": "300" + }, + { + "typeName": "Warehouse", + "maxAgeSeconds": "300" + } + ] + }, + { + "kind": "GRAPHQL", + "rootNodes": [ + { + "typeName": "Item", + "fieldNames": [ + "id", + "available", + "count" + ] + } + ], + "overrideFieldPathFromAlias": true, + "customGraphql": { + "fetch": { + "url": { + "staticVariableContent": "http://inventory.entity-cache-test.local/graphql" + }, + "method": "POST", + "body": {}, + "baseUrl": {}, + "path": {} + }, + "subscription": { + "enabled": true, + "url": { + "staticVariableContent": "http://inventory.entity-cache-test.local/graphql" + }, + "protocol": "GRAPHQL_SUBSCRIPTION_PROTOCOL_WS", + "websocketSubprotocol": "GRAPHQL_WEBSOCKET_SUBPROTOCOL_AUTO" + }, + "federation": { + "enabled": true, + "serviceSdl": "extend schema\n @link(\n url: \"https://specs.apollo.dev/federation/v2.5\"\n import: [\"@key\"]\n )\n\ndirective @openfed__entityCache(\n maxAge: Int!\n includeHeaders: Boolean = false\n partialCacheLoad: Boolean = false\n shadowMode: Boolean = false\n) on OBJECT\n\ntype Item @key(fields: \"id\") @openfed__entityCache(maxAge: 300) {\n id: ID!\n available: Boolean!\n count: Int!\n}\n" + }, + "upstreamSchema": { + "key": "f39f668358c7d91881c7b4b68f5387d7f18b9aad" + } + }, + "requestTimeoutSeconds": "10", + "id": "2", + "keys": [ + { + "typeName": "Item", + "selectionSet": "id" + } + ], + "entityCacheConfigurations": [ + { + "typeName": "Item", + "maxAgeSeconds": "300" + } + ] + }, + { + "kind": "GRAPHQL", + "rootNodes": [ + { + "typeName": "Viewer", + "fieldNames": [ + "id", + "name", + "email" + ] + }, + { + "typeName": "Personalized", + "fieldNames": [ + "id", + "currentViewer" + ] + }, + { + "typeName": "Query", + "fieldNames": [ + "currentViewer" + ] + }, + { + "typeName": "Article", + "fieldNames": [ + "id", + "currentViewer" + ] + } + ], + "overrideFieldPathFromAlias": true, + "customGraphql": { + "fetch": { + "url": { + "staticVariableContent": "http://viewer.entity-cache-test.local/graphql" + }, + "method": "POST", + "body": {}, + "baseUrl": {}, + "path": {} + }, + "subscription": { + "enabled": true, + "url": { + "staticVariableContent": "http://viewer.entity-cache-test.local/graphql" + }, + "protocol": "GRAPHQL_SUBSCRIPTION_PROTOCOL_WS", + "websocketSubprotocol": "GRAPHQL_WEBSOCKET_SUBPROTOCOL_AUTO" + }, + "federation": { + "enabled": true, + "serviceSdl": "extend schema\n @link(\n url: \"https://specs.apollo.dev/federation/v2.5\"\n import: [\"@key\", \"@interfaceObject\", \"@inaccessible\"]\n )\n\ndirective @openfed__requestScoped(key: String!) on FIELD_DEFINITION\n\ntype Viewer @key(fields: \"id\") {\n id: ID!\n name: String!\n email: String!\n}\n\n# Symmetric @openfed__requestScoped: Query.currentViewer and Personalized.currentViewer\n# share key \"currentViewer\" so they read/write the same L1 coordinate cache entry.\ntype Personalized @key(fields: \"id\") @interfaceObject {\n id: ID!\n currentViewer: Viewer @inaccessible @openfed__requestScoped(key: \"currentViewer\")\n}\n\ntype Query {\n currentViewer: Viewer @openfed__requestScoped(key: \"currentViewer\")\n}\n" + }, + "upstreamSchema": { + "key": "9ee951b49b83d66e073d83402d78cd8078181571" + } + }, + "requestTimeoutSeconds": "10", + "id": "3", + "keys": [ + { + "typeName": "Viewer", + "selectionSet": "id" + }, + { + "typeName": "Personalized", + "selectionSet": "id" + }, + { + "typeName": "Article", + "selectionSet": "id" + } + ], + "interfaceObjects": [ + { + "interfaceTypeName": "Personalized", + "concreteTypeNames": [ + "Article" + ] + } + ], + "requestScopedFields": [ + { + "fieldName": "currentViewer", + "typeName": "Personalized", + "l1Key": "viewer.currentViewer" + }, + { + "fieldName": "currentViewer", + "typeName": "Query", + "l1Key": "viewer.currentViewer" + } + ] + }, + { + "kind": "GRAPHQL", + "rootNodes": [ + { + "typeName": "Query", + "fieldNames": [ + "articles" + ] + }, + { + "typeName": "Personalized", + "fieldNames": [ + "id" + ] + }, + { + "typeName": "Viewer", + "fieldNames": [ + "id", + "recommendedArticles" + ], + "externalFieldNames": [ + "name", + "email" + ] + }, + { + "typeName": "Article", + "fieldNames": [ + "id", + "title", + "body", + "tags", + "personalizedRecommendation", + "relatedArticles" + ], + "externalFieldNames": [ + "currentViewer" + ] + } + ], + "overrideFieldPathFromAlias": true, + "customGraphql": { + "fetch": { + "url": { + "staticVariableContent": "http://articles.entity-cache-test.local/graphql" + }, + "method": "POST", + "body": {}, + "baseUrl": {}, + "path": {} + }, + "subscription": { + "enabled": true, + "url": { + "staticVariableContent": "http://articles.entity-cache-test.local/graphql" + }, + "protocol": "GRAPHQL_SUBSCRIPTION_PROTOCOL_WS", + "websocketSubprotocol": "GRAPHQL_WEBSOCKET_SUBPROTOCOL_AUTO" + }, + "federation": { + "enabled": true, + "serviceSdl": "extend schema\n @link(\n url: \"https://specs.apollo.dev/federation/v2.5\"\n import: [\"@key\", \"@external\", \"@requires\"]\n )\n\ntype Query {\n articles: [Article!]!\n}\n\ninterface Personalized @key(fields: \"id\") {\n id: ID!\n}\n\n# Extends Viewer with an edge back into articles land.\n# The @key forces sequencing: the articles _entities fetch for\n# recommendedArticles needs viewer.id from the prior viewer fetch, so the\n# planner cannot parallelize it with the root Query.currentViewer call.\n#\n# name and email are declared @external because Article.personalizedRecommendation\n# @requires references them. Composition fails without these declarations.\ntype Viewer @key(fields: \"id\") {\n id: ID!\n name: String! @external\n email: String! @external\n recommendedArticles: [Article!]!\n}\n\ntype Article implements Personalized @key(fields: \"id\") {\n id: ID!\n title: String!\n body: String!\n tags: [String!]!\n # Article.currentViewer is provided by the viewer subgraph via the\n # Personalized @interfaceObject. It is @external here so @requires can\n # reference it.\n currentViewer: Viewer @external\n # @requires a WIDER selection ({id, name, email}) than the root query\n # will ask for ({id, name}). This is the widening-miss trigger that the\n # test asserts: the coordinate L1 was populated with {id, name}, so the\n # follow-up _entities(Personalized) fetch fails the widening check and\n # refetches the viewer subgraph.\n personalizedRecommendation: String!\n @requires(fields: \"currentViewer { id name email }\")\n # relatedArticles enables nested selection of Article entities so tests\n # can exercise @openfed__requestScoped deduplication across multiple nesting\n # levels (Article.currentViewer selected inline at more than one depth).\n relatedArticles: [Article!]!\n}\n" + }, + "upstreamSchema": { + "key": "cf1e444bb26e20ccce317dd20e2f8da88671c87d" + } + }, + "requestTimeoutSeconds": "10", + "id": "4", + "keys": [ + { + "typeName": "Personalized", + "selectionSet": "id" + }, + { + "typeName": "Viewer", + "selectionSet": "id" + }, + { + "typeName": "Article", + "selectionSet": "id" + } + ], + "requires": [ + { + "typeName": "Article", + "fieldName": "personalizedRecommendation", + "selectionSet": "currentViewer { email id name }" + } + ], + "entityInterfaces": [ + { + "interfaceTypeName": "Personalized", + "concreteTypeNames": [ + "Article" + ] + } + ] + }, + { + "kind": "GRAPHQL", + "rootNodes": [ + { + "typeName": "Article", + "fieldNames": [ + "id", + "viewCount", + "rating", + "reviewSummary" + ] + } + ], + "overrideFieldPathFromAlias": true, + "customGraphql": { + "fetch": { + "url": { + "staticVariableContent": "http://articlesmeta.entity-cache-test.local/graphql" + }, + "method": "POST", + "body": {}, + "baseUrl": {}, + "path": {} + }, + "subscription": { + "enabled": true, + "url": { + "staticVariableContent": "http://articlesmeta.entity-cache-test.local/graphql" + }, + "protocol": "GRAPHQL_SUBSCRIPTION_PROTOCOL_WS", + "websocketSubprotocol": "GRAPHQL_WEBSOCKET_SUBPROTOCOL_AUTO" + }, + "federation": { + "enabled": true, + "serviceSdl": "extend schema\n @link(\n url: \"https://specs.apollo.dev/federation/v2.5\"\n import: [\"@key\"]\n )\n\ntype Article @key(fields: \"id\") {\n id: ID!\n viewCount: Int!\n rating: Float!\n reviewSummary: String!\n}\n" + }, + "upstreamSchema": { + "key": "26317d3464ef1d47aa8354694ea00cc787b1caef" + } + }, + "requestTimeoutSeconds": "10", + "id": "5", + "keys": [ + { + "typeName": "Article", + "selectionSet": "id" + } + ] + } + ], + "fieldConfigurations": [ + { + "typeName": "Query", + "fieldName": "item", + "argumentsConfiguration": [ + { + "name": "id", + "sourceType": "FIELD_ARGUMENT" + } + ] + }, + { + "typeName": "Query", + "fieldName": "itemByPid", + "argumentsConfiguration": [ + { + "name": "pid", + "sourceType": "FIELD_ARGUMENT" + } + ] + }, + { + "typeName": "Query", + "fieldName": "itemsByIds", + "argumentsConfiguration": [ + { + "name": "ids", + "sourceType": "FIELD_ARGUMENT" + } + ] + }, + { + "typeName": "Query", + "fieldName": "product", + "argumentsConfiguration": [ + { + "name": "id", + "sourceType": "FIELD_ARGUMENT" + }, + { + "name": "region", + "sourceType": "FIELD_ARGUMENT" + } + ] + }, + { + "typeName": "Query", + "fieldName": "productBySku", + "argumentsConfiguration": [ + { + "name": "sku", + "sourceType": "FIELD_ARGUMENT" + } + ] + }, + { + "typeName": "Query", + "fieldName": "productByName", + "argumentsConfiguration": [ + { + "name": "name", + "sourceType": "FIELD_ARGUMENT" + } + ] + }, + { + "typeName": "Query", + "fieldName": "productByKey", + "argumentsConfiguration": [ + { + "name": "key", + "sourceType": "FIELD_ARGUMENT" + } + ] + }, + { + "typeName": "Query", + "fieldName": "warehouse", + "argumentsConfiguration": [ + { + "name": "locationId", + "sourceType": "FIELD_ARGUMENT" + } + ] + }, + { + "typeName": "Query", + "fieldName": "warehouseByInput", + "argumentsConfiguration": [ + { + "name": "input", + "sourceType": "FIELD_ARGUMENT" + } + ] + }, + { + "typeName": "Mutation", + "fieldName": "updateItem", + "argumentsConfiguration": [ + { + "name": "id", + "sourceType": "FIELD_ARGUMENT" + }, + { + "name": "name", + "sourceType": "FIELD_ARGUMENT" + } + ] + }, + { + "typeName": "Mutation", + "fieldName": "deleteItem", + "argumentsConfiguration": [ + { + "name": "id", + "sourceType": "FIELD_ARGUMENT" + } + ] + }, + { + "typeName": "Mutation", + "fieldName": "createItem", + "argumentsConfiguration": [ + { + "name": "name", + "sourceType": "FIELD_ARGUMENT" + }, + { + "name": "category", + "sourceType": "FIELD_ARGUMENT" + } + ] + }, + { + "typeName": "Mutation", + "fieldName": "deleteProduct", + "argumentsConfiguration": [ + { + "name": "id", + "sourceType": "FIELD_ARGUMENT" + }, + { + "name": "region", + "sourceType": "FIELD_ARGUMENT" + } + ] + } + ], + "graphqlSchema": "schema {\n query: Query\n mutation: Mutation\n subscription: Subscription\n}\n\ndirective @inaccessible on ARGUMENT_DEFINITION | ENUM | ENUM_VALUE | FIELD_DEFINITION | INPUT_FIELD_DEFINITION | INPUT_OBJECT | INTERFACE | OBJECT | SCALAR | UNION\n\ntype Query {\n item(id: ID!): Item\n itemByPid(pid: ID!): Item\n items: [Item!]!\n itemsByIds(ids: [ID!]!): [Item!]!\n product(id: ID!, region: String!): Product\n productBySku(sku: String!): Product\n productByName(name: String!): Product\n productByKey(key: ProductKeyInput!): Product\n warehouse(locationId: ID!): Warehouse\n warehouseByInput(input: WarehouseLocationInput!): Warehouse\n currentViewer: Viewer\n articles: [Article!]!\n}\n\ninput ProductKeyInput {\n id: ID!\n region: String!\n}\n\ninput WarehouseLocationInput {\n location: WarehouseLocationKeyInput!\n}\n\ninput WarehouseLocationKeyInput {\n id: ID!\n}\n\ntype Mutation {\n updateItem(id: ID!, name: String!): Item\n deleteItem(id: ID!): Item\n createItem(name: String!, category: String!): Item!\n deleteProduct(id: ID!, region: String!): Product\n}\n\ntype Subscription {\n itemUpdated: Item\n itemCreated: Item\n}\n\ntype Item {\n id: ID!\n name: String!\n category: String!\n description: String!\n rating: Float!\n tags: [String!]!\n available: Boolean!\n count: Int!\n}\n\ntype Product {\n id: ID!\n region: String!\n sku: String!\n name: String!\n info: String!\n}\n\ntype Location {\n id: ID!\n}\n\ntype Warehouse {\n location: Location!\n name: String!\n capacity: Int!\n}\n\ntype Viewer {\n id: ID!\n name: String!\n email: String!\n recommendedArticles: [Article!]!\n}\n\ninterface Personalized {\n id: ID!\n currentViewer: Viewer @inaccessible\n}\n\ntype Article implements Personalized {\n id: ID!\n title: String!\n body: String!\n tags: [String!]!\n currentViewer: Viewer\n personalizedRecommendation: String!\n relatedArticles: [Article!]!\n viewCount: Int!\n rating: Float!\n reviewSummary: String!\n}", + "stringStorage": { + "bd938246cff0199909aca1d5df40d042d917c954": "schema {\n query: Query\n mutation: Mutation\n subscription: Subscription\n}\n\ndirective @key(fields: openfed__FieldSet!, resolvable: Boolean = true) repeatable on INTERFACE | OBJECT\n\ndirective @link(as: String, for: link__Purpose, import: [link__Import], url: String!) repeatable on SCHEMA\n\ndirective @openfed__cacheInvalidate on FIELD_DEFINITION\n\ndirective @openfed__cachePopulate(maxAge: Int) on FIELD_DEFINITION\n\ndirective @openfed__entityCache(includeHeaders: Boolean = false, maxAge: Int!, negativeCacheTTL: Int = 0, partialCacheLoad: Boolean = false, shadowMode: Boolean = false) on OBJECT\n\ndirective @openfed__is(fields: String!) on ARGUMENT_DEFINITION\n\ndirective @openfed__queryCache(includeHeaders: Boolean = false, maxAge: Int!, shadowMode: Boolean = false) on FIELD_DEFINITION\n\ntype Item @key(fields: \"id\") @openfed__entityCache(maxAge: 300, negativeCacheTTL: 30) {\n category: String!\n id: ID!\n name: String!\n}\n\ntype Location {\n id: ID!\n}\n\ntype Mutation {\n createItem(category: String!, name: String!): Item! @openfed__cachePopulate(maxAge: 60)\n deleteItem(id: ID!): Item @openfed__cacheInvalidate\n deleteProduct(id: ID!, region: String!): Product @openfed__cacheInvalidate\n updateItem(id: ID!, name: String!): Item @openfed__cacheInvalidate\n}\n\ntype Product @key(fields: \"id region\") @key(fields: \"sku\") @openfed__entityCache(maxAge: 300) {\n id: ID!\n name: String!\n region: String!\n sku: String!\n}\n\ninput ProductKeyInput {\n id: ID!\n region: String!\n}\n\ntype Query {\n item(id: ID!): Item @openfed__queryCache(maxAge: 300)\n itemByPid(pid: ID! @openfed__is(fields: \"id\")): Item @openfed__queryCache(maxAge: 300)\n items: [Item!]! @openfed__queryCache(maxAge: 300)\n itemsByIds(ids: [ID!]! @openfed__is(fields: \"id\")): [Item!]! @openfed__queryCache(maxAge: 300)\n product(id: ID!, region: String!): Product @openfed__queryCache(maxAge: 300)\n productByKey(key: ProductKeyInput! @openfed__is(fields: \"id region\")): Product @openfed__queryCache(maxAge: 300)\n productByName(name: String!): Product @openfed__queryCache(maxAge: 300)\n productBySku(sku: String!): Product @openfed__queryCache(maxAge: 300)\n warehouse(locationId: ID! @openfed__is(fields: \"location.id\")): Warehouse @openfed__queryCache(maxAge: 300)\n warehouseByInput(input: WarehouseLocationInput! @openfed__is(fields: \"location { id }\")): Warehouse @openfed__queryCache(maxAge: 300)\n}\n\ntype Subscription {\n itemCreated: Item @openfed__cachePopulate\n itemUpdated: Item @openfed__cacheInvalidate\n}\n\ntype Warehouse @key(fields: \"location { id }\") @openfed__entityCache(maxAge: 300) {\n location: Location!\n name: String!\n}\n\ninput WarehouseLocationInput {\n location: WarehouseLocationKeyInput!\n}\n\ninput WarehouseLocationKeyInput {\n id: ID!\n}\n\nscalar link__Import\n\nenum link__Purpose {\n EXECUTION\n SECURITY\n}\n\nscalar openfed__FieldSet", + "c155dbdb80b10cafddd0f1f0379b57532dc3dcc7": "directive @key(fields: openfed__FieldSet!, resolvable: Boolean = true) repeatable on INTERFACE | OBJECT\n\ndirective @link(as: String, for: link__Purpose, import: [link__Import], url: String!) repeatable on SCHEMA\n\ndirective @openfed__entityCache(includeHeaders: Boolean = false, maxAge: Int!, negativeCacheTTL: Int = 0, partialCacheLoad: Boolean = false, shadowMode: Boolean = false) on OBJECT\n\ntype Item @key(fields: \"id\") @openfed__entityCache(maxAge: 300) {\n description: String!\n id: ID!\n rating: Float!\n tags: [String!]!\n}\n\ntype Location {\n id: ID!\n}\n\ntype Product @key(fields: \"id region\") @openfed__entityCache(maxAge: 300) {\n id: ID!\n info: String!\n region: String!\n}\n\ntype Warehouse @key(fields: \"location { id }\") @openfed__entityCache(maxAge: 300) {\n capacity: Int!\n location: Location!\n}\n\nscalar link__Import\n\nenum link__Purpose {\n EXECUTION\n SECURITY\n}\n\nscalar openfed__FieldSet", + "f39f668358c7d91881c7b4b68f5387d7f18b9aad": "directive @key(fields: openfed__FieldSet!, resolvable: Boolean = true) repeatable on INTERFACE | OBJECT\n\ndirective @link(as: String, for: link__Purpose, import: [link__Import], url: String!) repeatable on SCHEMA\n\ndirective @openfed__entityCache(includeHeaders: Boolean = false, maxAge: Int!, negativeCacheTTL: Int = 0, partialCacheLoad: Boolean = false, shadowMode: Boolean = false) on OBJECT\n\ntype Item @key(fields: \"id\") @openfed__entityCache(maxAge: 300) {\n available: Boolean!\n count: Int!\n id: ID!\n}\n\nscalar link__Import\n\nenum link__Purpose {\n EXECUTION\n SECURITY\n}\n\nscalar openfed__FieldSet", + "9ee951b49b83d66e073d83402d78cd8078181571": "schema {\n query: Query\n}\n\ndirective @inaccessible on ARGUMENT_DEFINITION | ENUM | ENUM_VALUE | FIELD_DEFINITION | INPUT_FIELD_DEFINITION | INPUT_OBJECT | INTERFACE | OBJECT | SCALAR | UNION\n\ndirective @interfaceObject on OBJECT\n\ndirective @key(fields: openfed__FieldSet!, resolvable: Boolean = true) repeatable on INTERFACE | OBJECT\n\ndirective @link(as: String, for: link__Purpose, import: [link__Import], url: String!) repeatable on SCHEMA\n\ndirective @openfed__requestScoped(key: String!) on FIELD_DEFINITION\n\ntype Personalized @key(fields: \"id\") @interfaceObject {\n currentViewer: Viewer @inaccessible @openfed__requestScoped(key: \"currentViewer\")\n id: ID!\n}\n\ntype Query {\n currentViewer: Viewer @openfed__requestScoped(key: \"currentViewer\")\n}\n\ntype Viewer @key(fields: \"id\") {\n email: String!\n id: ID!\n name: String!\n}\n\nscalar link__Import\n\nenum link__Purpose {\n EXECUTION\n SECURITY\n}\n\nscalar openfed__FieldSet", + "cf1e444bb26e20ccce317dd20e2f8da88671c87d": "schema {\n query: Query\n}\n\ndirective @external on FIELD_DEFINITION | OBJECT\n\ndirective @key(fields: openfed__FieldSet!, resolvable: Boolean = true) repeatable on INTERFACE | OBJECT\n\ndirective @link(as: String, for: link__Purpose, import: [link__Import], url: String!) repeatable on SCHEMA\n\ndirective @requires(fields: openfed__FieldSet!) on FIELD_DEFINITION\n\ntype Article implements Personalized @key(fields: \"id\") {\n body: String!\n currentViewer: Viewer @external\n id: ID!\n personalizedRecommendation: String! @requires(fields: \"currentViewer { id name email }\")\n relatedArticles: [Article!]!\n tags: [String!]!\n title: String!\n}\n\ninterface Personalized @key(fields: \"id\") {\n id: ID!\n}\n\ntype Query {\n articles: [Article!]!\n}\n\ntype Viewer @key(fields: \"id\") {\n email: String! @external\n id: ID!\n name: String! @external\n recommendedArticles: [Article!]!\n}\n\nscalar link__Import\n\nenum link__Purpose {\n EXECUTION\n SECURITY\n}\n\nscalar openfed__FieldSet", + "26317d3464ef1d47aa8354694ea00cc787b1caef": "directive @key(fields: openfed__FieldSet!, resolvable: Boolean = true) repeatable on INTERFACE | OBJECT\n\ndirective @link(as: String, for: link__Purpose, import: [link__Import], url: String!) repeatable on SCHEMA\n\ntype Article @key(fields: \"id\") {\n id: ID!\n rating: Float!\n reviewSummary: String!\n viewCount: Int!\n}\n\nscalar link__Import\n\nenum link__Purpose {\n EXECUTION\n SECURITY\n}\n\nscalar openfed__FieldSet" + }, + "graphqlClientSchema": "schema {\n query: Query\n mutation: Mutation\n subscription: Subscription\n}\n\ntype Query {\n item(id: ID!): Item\n itemByPid(pid: ID!): Item\n items: [Item!]!\n itemsByIds(ids: [ID!]!): [Item!]!\n product(id: ID!, region: String!): Product\n productBySku(sku: String!): Product\n productByName(name: String!): Product\n productByKey(key: ProductKeyInput!): Product\n warehouse(locationId: ID!): Warehouse\n warehouseByInput(input: WarehouseLocationInput!): Warehouse\n currentViewer: Viewer\n articles: [Article!]!\n}\n\ninput ProductKeyInput {\n id: ID!\n region: String!\n}\n\ninput WarehouseLocationInput {\n location: WarehouseLocationKeyInput!\n}\n\ninput WarehouseLocationKeyInput {\n id: ID!\n}\n\ntype Mutation {\n updateItem(id: ID!, name: String!): Item\n deleteItem(id: ID!): Item\n createItem(name: String!, category: String!): Item!\n deleteProduct(id: ID!, region: String!): Product\n}\n\ntype Subscription {\n itemUpdated: Item\n itemCreated: Item\n}\n\ntype Item {\n id: ID!\n name: String!\n category: String!\n description: String!\n rating: Float!\n tags: [String!]!\n available: Boolean!\n count: Int!\n}\n\ntype Product {\n id: ID!\n region: String!\n sku: String!\n name: String!\n info: String!\n}\n\ntype Location {\n id: ID!\n}\n\ntype Warehouse {\n location: Location!\n name: String!\n capacity: Int!\n}\n\ntype Viewer {\n id: ID!\n name: String!\n email: String!\n recommendedArticles: [Article!]!\n}\n\ninterface Personalized {\n id: ID!\n}\n\ntype Article implements Personalized {\n id: ID!\n title: String!\n body: String!\n tags: [String!]!\n currentViewer: Viewer\n personalizedRecommendation: String!\n relatedArticles: [Article!]!\n viewCount: Int!\n rating: Float!\n reviewSummary: String!\n}" + }, + "version": "00000000-0000-0000-0000-000000000000", + "subgraphs": [ + { + "id": "0", + "name": "items", + "routingUrl": "http://items.entity-cache-test.local/graphql" + }, + { + "id": "1", + "name": "details", + "routingUrl": "http://details.entity-cache-test.local/graphql" + }, + { + "id": "2", + "name": "inventory", + "routingUrl": "http://inventory.entity-cache-test.local/graphql" + }, + { + "id": "3", + "name": "viewer", + "routingUrl": "http://viewer.entity-cache-test.local/graphql" + }, + { + "id": "4", + "name": "articles", + "routingUrl": "http://articles.entity-cache-test.local/graphql" + }, + { + "id": "5", + "name": "articlesmeta", + "routingUrl": "http://articlesmeta.entity-cache-test.local/graphql" + } + ], + "compatibilityVersion": "1:{{$COMPOSITION__VERSION}}" +} diff --git a/router-tests/go.mod b/router-tests/go.mod index b81cc273f6..f201dc5743 100644 --- a/router-tests/go.mod +++ b/router-tests/go.mod @@ -4,7 +4,9 @@ go 1.25.0 require ( connectrpc.com/connect v1.19.1 + github.com/99designs/gqlgen v0.17.76 github.com/MicahParks/jwkset v0.11.0 + github.com/alicebob/miniredis/v2 v2.34.0 github.com/buger/jsonparser v1.1.2 github.com/cloudflare/backoff v0.0.0-20240920015135-e46b80a3a7d0 github.com/golang-jwt/jwt/v5 v5.3.0 @@ -25,13 +27,13 @@ require ( github.com/stretchr/testify v1.11.1 github.com/twmb/franz-go v1.16.1 github.com/twmb/franz-go/pkg/kadm v1.11.0 - github.com/wundergraph/astjson v1.1.0 + github.com/wundergraph/astjson v1.1.1-0.20260419105127-f600d161463f github.com/wundergraph/cosmo/demo v0.0.0-20260323091151-a7de617c31d0 github.com/wundergraph/cosmo/demo/pkg/subgraphs/projects v0.0.0-20250715110703-10f2e5f9c79e github.com/wundergraph/cosmo/router v0.0.0-20260330183556-dc4388d100a4 github.com/wundergraph/cosmo/router-plugin v0.0.0-20250808194725-de123ba1c65e github.com/wundergraph/cosmo/speedtrap v0.0.0-00010101000000-000000000000 - github.com/wundergraph/graphql-go-tools/v2 v2.4.4 + github.com/wundergraph/graphql-go-tools/v2 v2.4.5-0.20260610161004-63fa1c88eaea go.opentelemetry.io/otel v1.43.0 go.opentelemetry.io/otel/sdk v1.43.0 go.opentelemetry.io/otel/sdk/metric v1.43.0 @@ -48,10 +50,10 @@ require ( require ( connectrpc.com/vanguard v0.3.0 // indirect - github.com/99designs/gqlgen v0.17.76 // indirect github.com/KimMachineGun/automemlimit v0.6.1 // indirect github.com/MicahParks/keyfunc/v3 v3.6.2 // indirect github.com/agnivade/levenshtein v1.2.1 // indirect + github.com/alicebob/gopher-json v0.0.0-20230218143504-906a9b012302 // indirect github.com/andybalholm/brotli v1.1.0 // indirect github.com/antithesishq/antithesis-sdk-go v0.6.0-default-no-op // indirect github.com/bahlo/generic-list-go v0.2.0 // indirect @@ -164,9 +166,10 @@ require ( github.com/vbatts/tar-split v0.12.1 // indirect github.com/vektah/gqlparser/v2 v2.5.30 // indirect github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect - github.com/wundergraph/go-arena v1.1.0 // indirect + github.com/wundergraph/go-arena v1.2.0 // indirect github.com/xrash/smetrics v0.0.0-20250705151800-55b8f293f342 // indirect github.com/yosida95/uritemplate/v3 v3.0.2 // indirect + github.com/yuin/gopher-lua v1.1.1 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.68.0 // indirect diff --git a/router-tests/go.sum b/router-tests/go.sum index 12a78bfb31..9949d2135b 100644 --- a/router-tests/go.sum +++ b/router-tests/go.sum @@ -377,12 +377,12 @@ github.com/vektah/gqlparser/v2 v2.5.30 h1:EqLwGAFLIzt1wpx1IPpY67DwUujF1OfzgEyDsL github.com/vektah/gqlparser/v2 v2.5.30/go.mod h1:D1/VCZtV3LPnQrcPBeR/q5jkSQIPti0uYCP/RI0gIeo= github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc= github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw= -github.com/wundergraph/astjson v1.1.0 h1:xORDosrZ87zQFJwNGe/HIHXqzpdHOFmqWgykCLVL040= -github.com/wundergraph/astjson v1.1.0/go.mod h1:h12D/dxxnedtLzsKyBLK7/Oe4TAoGpRVC9nDpDrZSWw= -github.com/wundergraph/go-arena v1.1.0 h1:9+wSRkJAkA2vbYHp6s8tEGhPViRGQNGXqPHT0QzhdIc= -github.com/wundergraph/go-arena v1.1.0/go.mod h1:ROOysEHWJjLQ8FSfNxZCziagb7Qw2nXY3/vgKRh7eWw= -github.com/wundergraph/graphql-go-tools/v2 v2.4.4 h1:VCvS9bku4ie7+St3+H5SNuVz6dtQiDKujqQ439yrMBM= -github.com/wundergraph/graphql-go-tools/v2 v2.4.4/go.mod h1:7ljNHLrBOoOszCk4ir4Z+O6Yrf+vwBBmxjwqM3imVgA= +github.com/wundergraph/astjson v1.1.1-0.20260419105127-f600d161463f h1:MoVoeMlgY9Ej1aoF3Y/kniBZ8pv+WfIA3YSCnPBh+6M= +github.com/wundergraph/astjson v1.1.1-0.20260419105127-f600d161463f/go.mod h1:uHSJv7uowLN/nIPvkTFqUDt1sXk4qQU0KNwHfwfDcQE= +github.com/wundergraph/go-arena v1.2.0 h1:6MlhEy0NBY3Z+BuK3rj0F9YoT3bM0SlahGkzK0lKRZ4= +github.com/wundergraph/go-arena v1.2.0/go.mod h1:ROOysEHWJjLQ8FSfNxZCziagb7Qw2nXY3/vgKRh7eWw= +github.com/wundergraph/graphql-go-tools/v2 v2.4.5-0.20260610161004-63fa1c88eaea h1:ACjZjX87K3ADlFy54YrwZ/UPCugKL56/DtQNWB5EGeU= +github.com/wundergraph/graphql-go-tools/v2 v2.4.5-0.20260610161004-63fa1c88eaea/go.mod h1:3NuqY1nBh7g4IkytYazmT6RHg/giCsdZpmX0NkpayNs= github.com/xrash/smetrics v0.0.0-20250705151800-55b8f293f342 h1:FnBeRrxr7OU4VvAzt5X7s6266i6cSVkkFPS0TuXWbIg= github.com/xrash/smetrics v0.0.0-20250705151800-55b8f293f342/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4= diff --git a/router-tests/protocol/testdata/tracing.json b/router-tests/protocol/testdata/tracing.json index ff47debcfa..a27ef045e4 100644 --- a/router-tests/protocol/testdata/tracing.json +++ b/router-tests/protocol/testdata/tracing.json @@ -674,6 +674,19 @@ "duration_since_start_nanoseconds": 1, "duration_since_start_pretty": "1ns" } + }, + "cache_trace": { + "duration_since_start_nanoseconds": 1, + "duration_since_start_pretty": "1ns", + "duration_nanoseconds": 1, + "duration_pretty": "1ns", + "l1_enabled": false, + "l2_enabled": false, + "entity_count": 0, + "l1_hit": 0, + "l1_miss": 0, + "l2_hit": 0, + "l2_miss": 0 } } } @@ -1050,6 +1063,19 @@ "duration_since_start_nanoseconds": 1, "duration_since_start_pretty": "1ns" } + }, + "cache_trace": { + "duration_since_start_nanoseconds": 1, + "duration_since_start_pretty": "1ns", + "duration_nanoseconds": 1, + "duration_pretty": "1ns", + "l1_enabled": false, + "l2_enabled": false, + "entity_count": 0, + "l1_hit": 0, + "l1_miss": 0, + "l2_hit": 0, + "l2_miss": 0 } } } @@ -1676,6 +1702,19 @@ "duration_since_start_nanoseconds": 1, "duration_since_start_pretty": "1ns" } + }, + "cache_trace": { + "duration_since_start_nanoseconds": 1, + "duration_since_start_pretty": "1ns", + "duration_nanoseconds": 1, + "duration_pretty": "1ns", + "l1_enabled": false, + "l2_enabled": false, + "entity_count": 0, + "l1_hit": 0, + "l1_miss": 0, + "l2_hit": 0, + "l2_miss": 0 } } } @@ -2005,6 +2044,19 @@ "duration_since_start_nanoseconds": 1, "duration_since_start_pretty": "1ns" } + }, + "cache_trace": { + "duration_since_start_nanoseconds": 1, + "duration_since_start_pretty": "1ns", + "duration_nanoseconds": 1, + "duration_pretty": "1ns", + "l1_enabled": false, + "l2_enabled": false, + "entity_count": 0, + "l1_hit": 0, + "l1_miss": 0, + "l2_hit": 0, + "l2_miss": 0 } } } diff --git a/router-tests/testenv/testenv.go b/router-tests/testenv/testenv.go index 4d4799e6a1..8f3ae62e78 100644 --- a/router-tests/testenv/testenv.go +++ b/router-tests/testenv/testenv.go @@ -746,6 +746,22 @@ func CreateTestSupervisorEnv(t testing.TB, cfg *Config) (*Environment, error) { retryClient.RetryMax = 10 retryClient.RetryWaitMin = 100 * time.Millisecond retryClient.HTTPClient = httpClient + // Retry on HTTP 501. The router itself never returns 501 for GraphQL requests — + // the only way to see 501 from the router URL is Go's net/http server emitting + // isUnsupportedTEError during request parsing before any handler runs. Under + // heavy parallel-subtest load this has been observed at ~0.05% rate, enough to + // surface as a flake in CI. Retrying is safe because a legitimate router 501 + // is not possible in this suite. + defaultCheckRetry := retryClient.CheckRetry + retryClient.CheckRetry = func(ctx context.Context, resp *http.Response, err error) (bool, error) { + if resp != nil && resp.StatusCode == http.StatusNotImplemented { + return true, nil + } + if defaultCheckRetry != nil { + return defaultCheckRetry(ctx, resp, err) + } + return retryablehttp.DefaultRetryPolicy(ctx, resp, err) + } client = retryClient.StandardClient() } @@ -1172,6 +1188,22 @@ func CreateTestEnv(t testing.TB, cfg *Config) (*Environment, error) { retryClient.RetryMax = 10 retryClient.RetryWaitMin = 100 * time.Millisecond retryClient.HTTPClient = httpClient + // Retry on HTTP 501. The router itself never returns 501 for GraphQL requests — + // the only way to see 501 from the router URL is Go's net/http server emitting + // isUnsupportedTEError during request parsing before any handler runs. Under + // heavy parallel-subtest load this has been observed at ~0.05% rate, enough to + // surface as a flake in CI. Retrying is safe because a legitimate router 501 + // is not possible in this suite. + defaultCheckRetry := retryClient.CheckRetry + retryClient.CheckRetry = func(ctx context.Context, resp *http.Response, err error) (bool, error) { + if resp != nil && resp.StatusCode == http.StatusNotImplemented { + return true, nil + } + if defaultCheckRetry != nil { + return defaultCheckRetry(ctx, resp, err) + } + return retryablehttp.DefaultRetryPolicy(ctx, resp, err) + } client = retryClient.StandardClient() } diff --git a/router/core/executor.go b/router/core/executor.go index 785aaadb6c..a05abe8269 100644 --- a/router/core/executor.go +++ b/router/core/executor.go @@ -62,10 +62,12 @@ type ExecutorBuildOptions struct { TraceClientRequired bool PluginsEnabled bool InstanceData InstanceData + EntityCacheInstances map[string]resolve.LoaderCache + EntityCachingConfig *config.EntityCachingConfiguration } func (b *ExecutorConfigurationBuilder) Build(ctx context.Context, opts *ExecutorBuildOptions) (*Executor, []pubsub_datasource.Provider, error) { - planConfig, providers, err := b.buildPlannerConfiguration(ctx, opts.EngineConfig, opts.Subgraphs, opts.RouterEngineConfig, opts.PluginsEnabled) + planConfig, providers, err := b.buildPlannerConfiguration(ctx, opts.EngineConfig, opts.Subgraphs, opts.RouterEngineConfig, opts.PluginsEnabled, opts.EntityCachingConfig) if err != nil { return nil, nil, fmt.Errorf("failed to build planner configuration: %w", err) } @@ -91,6 +93,8 @@ func (b *ExecutorConfigurationBuilder) Build(ctx context.Context, opts *Executor ValidateRequiredExternalFields: opts.RouterEngineConfig.Execution.ValidateRequiredExternalFields, SetDeduplicationShardCountToGOMAXPROCS: true, AllowCustomExtensionProperties: opts.RouterEngineConfig.SubgraphExtensionPropagation.Enabled, + Caches: opts.EntityCacheInstances, + EntityCacheConfigs: buildEntityCacheInvalidationConfigs(opts.EntityCachingConfig, opts.Subgraphs, opts.EngineConfig, b.logger), } if opts.ApolloCompatibilityFlags.ValueCompletion.Enabled { @@ -215,7 +219,7 @@ func (b *ExecutorConfigurationBuilder) Build(ctx context.Context, opts *Executor }, providers, nil } -func (b *ExecutorConfigurationBuilder) buildPlannerConfiguration(ctx context.Context, engineConfig *nodev1.EngineConfiguration, subgraphs []*nodev1.Subgraph, routerEngineCfg *RouterEngineConfiguration, pluginsEnabled bool) (*plan.Configuration, []pubsub_datasource.Provider, error) { +func (b *ExecutorConfigurationBuilder) buildPlannerConfiguration(ctx context.Context, engineConfig *nodev1.EngineConfiguration, subgraphs []*nodev1.Subgraph, routerEngineCfg *RouterEngineConfiguration, pluginsEnabled bool, entityCachingConfig *config.EntityCachingConfiguration) (*plan.Configuration, []pubsub_datasource.Provider, error) { // this loader is used to take the engine config and create a plan config // the plan config is what the engine uses to turn a GraphQL Request into an execution plan // the plan config is stateful as it carries connection pools and other things @@ -231,6 +235,7 @@ func (b *ExecutorConfigurationBuilder) buildPlannerConfiguration(ctx context.Con routerEngineCfg.Execution.EnableNetPoll, b.instanceData, ), b.logger, b.subscriptionHooks) + loader.entityCachingConfig = entityCachingConfig // this generates the plan config using the data source factories from the config package planConfig, providers, err := loader.Load(engineConfig, subgraphs, routerEngineCfg, pluginsEnabled) @@ -264,3 +269,72 @@ func (b *ExecutorConfigurationBuilder) buildPlannerConfiguration(ctx context.Con return planConfig, providers, nil } + +func buildEntityCacheInvalidationConfigs( + cfg *config.EntityCachingConfiguration, + subgraphs []*nodev1.Subgraph, + engineConfig *nodev1.EngineConfiguration, + logger *zap.Logger, +) map[string]map[string]*resolve.EntityCacheInvalidationConfig { + if cfg == nil || !cfg.Enabled || len(engineConfig.GetDatasourceConfigurations()) == 0 { + return nil + } + result := make(map[string]map[string]*resolve.EntityCacheInvalidationConfig) + for _, ds := range engineConfig.GetDatasourceConfigurations() { + subgraphName := subgraphNameByID(subgraphs, ds.GetId()) + if subgraphName == "" { + // Datasource ID doesn't match any known subgraph — skip instead of + // bucketing under "" which would collide across datasources and + // produce a wrong cache lookup downstream. + if logger != nil { + logger.Warn("entity caching: skipping datasource with unknown subgraph id", + zap.String("datasource_id", ds.GetId())) + } + continue + } + for _, ec := range ds.GetEntityCacheConfigurations() { + if _, ok := result[subgraphName]; !ok { + result[subgraphName] = make(map[string]*resolve.EntityCacheInvalidationConfig) + } + result[subgraphName][ec.GetTypeName()] = &resolve.EntityCacheInvalidationConfig{ + CacheName: resolveEntityCacheProviderID(cfg, subgraphName, ec.GetTypeName()), + IncludeSubgraphHeaderPrefix: ec.GetIncludeHeaders(), + } + } + } + if len(result) == 0 { + return nil + } + return result +} + +func subgraphNameByID(subgraphs []*nodev1.Subgraph, id string) string { + for _, sg := range subgraphs { + if sg.Id == id { + return sg.Name + } + } + return "" +} + +func resolveEntityCacheProviderID(cfg *config.EntityCachingConfiguration, subgraphName, typeName string) string { + if cfg == nil { + return "default" + } + for _, sg := range cfg.SubgraphCacheOverrides { + if sg.Name == subgraphName { + // Tier 1: entity-level override + for _, e := range sg.Entities { + if e.Type == typeName && e.StorageProviderID != "" { + return e.StorageProviderID + } + } + // Tier 2: subgraph-level override + if sg.StorageProviderID != "" { + return sg.StorageProviderID + } + } + } + // Tier 3: global default + return "default" +} diff --git a/router/core/executor_entity_cache_test.go b/router/core/executor_entity_cache_test.go new file mode 100644 index 0000000000..e4c39f2898 --- /dev/null +++ b/router/core/executor_entity_cache_test.go @@ -0,0 +1,200 @@ +package core + +import ( + "testing" + + "github.com/stretchr/testify/require" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" + "go.uber.org/zap/zaptest/observer" + + nodev1 "github.com/wundergraph/cosmo/router/gen/proto/wg/cosmo/node/v1" + "github.com/wundergraph/cosmo/router/pkg/config" + "github.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve" +) + +func TestResolveEntityCacheProviderID(t *testing.T) { + t.Parallel() + cfg := &config.EntityCachingConfiguration{ + SubgraphCacheOverrides: []config.EntityCachingSubgraphCacheOverride{ + { + Name: "products", + StorageProviderID: "sg-redis", + Entities: []config.EntityCachingEntityConfig{ + {Type: "Product", StorageProviderID: "entity-redis"}, + }, + }, + { + Name: "reviews", + StorageProviderID: "reviews-redis", + }, + }, + } + + t.Run("default_fallback", func(t *testing.T) { + t.Parallel() + result := resolveEntityCacheProviderID(cfg, "unknown-subgraph", "AnyType") + require.Equal(t, "default", result) + }) + + t.Run("subgraph_level_match", func(t *testing.T) { + t.Parallel() + result := resolveEntityCacheProviderID(cfg, "reviews", "Review") + require.Equal(t, "reviews-redis", result) + }) + + t.Run("entity_level_match", func(t *testing.T) { + t.Parallel() + result := resolveEntityCacheProviderID(cfg, "products", "Product") + require.Equal(t, "entity-redis", result) + }) + + t.Run("entity_takes_precedence_over_subgraph", func(t *testing.T) { + t.Parallel() + // "products" subgraph has sg-redis, but Product entity has entity-redis + result := resolveEntityCacheProviderID(cfg, "products", "Product") + require.Equal(t, "entity-redis", result) + }) + + t.Run("no_entity_match_falls_to_subgraph", func(t *testing.T) { + t.Parallel() + result := resolveEntityCacheProviderID(cfg, "products", "Category") + require.Equal(t, "sg-redis", result) + }) +} + +func TestSubgraphNameByID(t *testing.T) { + t.Parallel() + subgraphs := []*nodev1.Subgraph{ + {Id: "sg-1", Name: "products"}, + {Id: "sg-2", Name: "reviews"}, + } + + t.Run("found", func(t *testing.T) { + t.Parallel() + result := subgraphNameByID(subgraphs, "sg-1") + require.Equal(t, "products", result) + }) + + t.Run("not_found", func(t *testing.T) { + t.Parallel() + result := subgraphNameByID(subgraphs, "sg-unknown") + require.Equal(t, "", result) + }) +} + +func TestBuildEntityCacheInvalidationConfigs(t *testing.T) { + t.Parallel() + t.Run("nil_config", func(t *testing.T) { + t.Parallel() + result := buildEntityCacheInvalidationConfigs(nil, nil, &nodev1.EngineConfiguration{}, zap.NewNop()) + require.Nil(t, result) + }) + + t.Run("disabled", func(t *testing.T) { + t.Parallel() + cfg := &config.EntityCachingConfiguration{Enabled: false} + result := buildEntityCacheInvalidationConfigs(cfg, nil, &nodev1.EngineConfiguration{}, zap.NewNop()) + require.Nil(t, result) + }) + + t.Run("no_datasources", func(t *testing.T) { + t.Parallel() + cfg := &config.EntityCachingConfiguration{Enabled: true} + result := buildEntityCacheInvalidationConfigs(cfg, nil, &nodev1.EngineConfiguration{}, zap.NewNop()) + require.Nil(t, result) + }) + + t.Run("skips_datasource_with_unknown_subgraph_id", func(t *testing.T) { + t.Parallel() + core, observed := observer.New(zapcore.WarnLevel) + logger := zap.New(core) + cfg := &config.EntityCachingConfiguration{Enabled: true} + subgraphs := []*nodev1.Subgraph{ + {Id: "ds-known", Name: "products"}, + } + engineConfig := &nodev1.EngineConfiguration{ + DatasourceConfigurations: []*nodev1.DataSourceConfiguration{ + { + Id: "ds-unknown", // no matching subgraph + EntityCacheConfigurations: []*nodev1.EntityCacheConfiguration{ + {TypeName: "Mystery", MaxAgeSeconds: 60}, + }, + }, + { + Id: "ds-known", + EntityCacheConfigurations: []*nodev1.EntityCacheConfiguration{ + {TypeName: "Product", MaxAgeSeconds: 60}, + }, + }, + }, + } + + result := buildEntityCacheInvalidationConfigs(cfg, subgraphs, engineConfig, logger) + + // Known subgraph is present, unknown is skipped (not bucketed under ""). + require.Equal(t, map[string]map[string]*resolve.EntityCacheInvalidationConfig{ + "products": { + "Product": {CacheName: "default", IncludeSubgraphHeaderPrefix: false}, + }, + }, result) + + // And a single warning was emitted for the unknown datasource ID. + entries := observed.FilterMessage("entity caching: skipping datasource with unknown subgraph id").All() + require.Len(t, entries, 1) + require.Equal(t, "ds-unknown", entries[0].ContextMap()["datasource_id"]) + }) + + t.Run("builds_correct_map", func(t *testing.T) { + t.Parallel() + cfg := &config.EntityCachingConfiguration{ + Enabled: true, + SubgraphCacheOverrides: []config.EntityCachingSubgraphCacheOverride{ + { + Name: "products", + StorageProviderID: "custom-redis", + }, + }, + } + subgraphs := []*nodev1.Subgraph{ + {Id: "ds-1", Name: "products"}, + {Id: "ds-2", Name: "reviews"}, + } + engineConfig := &nodev1.EngineConfiguration{ + DatasourceConfigurations: []*nodev1.DataSourceConfiguration{ + { + Id: "ds-1", + EntityCacheConfigurations: []*nodev1.EntityCacheConfiguration{ + {TypeName: "Product", MaxAgeSeconds: 60, IncludeHeaders: true}, + }, + }, + { + Id: "ds-2", + EntityCacheConfigurations: []*nodev1.EntityCacheConfiguration{ + {TypeName: "Review", MaxAgeSeconds: 30}, + }, + }, + }, + } + + result := buildEntityCacheInvalidationConfigs(cfg, subgraphs, engineConfig, zap.NewNop()) + require.NotNil(t, result) + require.Len(t, result, 2) + + // products subgraph, Product type -> custom-redis + require.Contains(t, result, "products") + require.Contains(t, result["products"], "Product") + require.Equal(t, &resolve.EntityCacheInvalidationConfig{ + CacheName: "custom-redis", + IncludeSubgraphHeaderPrefix: true, + }, result["products"]["Product"]) + + // reviews subgraph, Review type -> default + require.Contains(t, result, "reviews") + require.Contains(t, result["reviews"], "Review") + require.Equal(t, &resolve.EntityCacheInvalidationConfig{ + CacheName: "default", + IncludeSubgraphHeaderPrefix: false, + }, result["reviews"]["Review"]) + }) +} diff --git a/router/core/factoryresolver.go b/router/core/factoryresolver.go index d0a94d9a51..b1545140c6 100644 --- a/router/core/factoryresolver.go +++ b/router/core/factoryresolver.go @@ -6,7 +6,6 @@ import ( "fmt" "net/http" "net/url" - "slices" "time" "github.com/buger/jsonparser" @@ -29,6 +28,13 @@ import ( "github.com/wundergraph/graphql-go-tools/v2/pkg/engine/plan" ) +// Proto operation_type string values from the composition layer. +// CachePopulateConfiguration and CacheInvalidateConfiguration use these title-case strings +// (distinct from the router's internal lowercase OperationType constants in context.go). +const ( + protoOperationTypeSubscription = "Subscription" +) + // Loader translates the protobuf-based router engine configuration into a // plan.Configuration consumed by the GraphQL engine planner. It resolves // data source factories (HTTP, gRPC, pub/sub) for each subgraph through the @@ -38,8 +44,10 @@ type Loader struct { ctx context.Context resolver FactoryResolver subscriptionHooks subscriptionHooks - includeInfo bool - logger *zap.Logger + // includeInfo controls whether additional information like type usage and field usage is included in the plan de + includeInfo bool + logger *zap.Logger + entityCachingConfig *config.EntityCachingConfiguration } type InstanceData struct { @@ -347,6 +355,7 @@ func (l *Loader) Load(engineConfig *nodev1.EngineConfiguration, subgraphs []*nod for _, in := range engineConfig.DatasourceConfigurations { var out plan.DataSource + dataSourceName := l.subgraphName(subgraphs, in.Id) switch in.Kind { case nodev1.DataSourceKind_STATIC: @@ -358,7 +367,7 @@ func (l *Loader) Load(engineConfig *nodev1.EngineConfiguration, subgraphs []*nod out, err = plan.NewDataSourceConfiguration[staticdatasource.Configuration]( in.Id, factory, - l.dataSourceMetaData(in), + l.dataSourceMetaData(in, dataSourceName), staticdatasource.Configuration{ Data: config.LoadStringVariable(in.CustomStatic.Data), }, @@ -481,8 +490,6 @@ func (l *Loader) Load(engineConfig *nodev1.EngineConfiguration, subgraphs []*nod return nil, providers, fmt.Errorf("error creating custom configuration for data source %s: %w", in.Id, err) } - dataSourceName := l.subgraphName(subgraphs, in.Id) - factory, err := l.resolver.ResolveGraphqlFactory(dataSourceName) if err != nil { return nil, providers, err @@ -492,7 +499,7 @@ func (l *Loader) Load(engineConfig *nodev1.EngineConfiguration, subgraphs []*nod in.Id, dataSourceName, factory, - l.dataSourceMetaData(in), + l.dataSourceMetaData(in, dataSourceName), customConfiguration, ) if err != nil { @@ -502,7 +509,7 @@ func (l *Loader) Load(engineConfig *nodev1.EngineConfiguration, subgraphs []*nod case nodev1.DataSourceKind_PUBSUB: pubSubDS = append(pubSubDS, pubsub.DataSourceConfigurationWithMetadata{ Configuration: in, - Metadata: l.dataSourceMetaData(in), + Metadata: l.dataSourceMetaData(in, dataSourceName), }) default: return nil, providers, fmt.Errorf("unknown data source type %q", in.Kind) @@ -566,19 +573,11 @@ func (l *Loader) Load(engineConfig *nodev1.EngineConfiguration, subgraphs []*nod } func (l *Loader) subgraphName(subgraphs []*nodev1.Subgraph, dataSourceID string) string { - i := slices.IndexFunc(subgraphs, func(s *nodev1.Subgraph) bool { - return s.Id == dataSourceID - }) - - if i != -1 { - return subgraphs[i].Name - } - - return "" + return subgraphNameByID(subgraphs, dataSourceID) } // dataSourceMetaData converts a protobuf configuration into the planner's DataSourceMetadata. -func (l *Loader) dataSourceMetaData(in *nodev1.DataSourceConfiguration) *plan.DataSourceMetadata { +func (l *Loader) dataSourceMetaData(in *nodev1.DataSourceConfiguration, subgraphName string) *plan.DataSourceMetadata { var d plan.DirectiveConfigurations = make([]plan.DirectiveConfiguration, 0, len(in.Directives)) out := &plan.DataSourceMetadata{ @@ -674,6 +673,134 @@ func (l *Loader) dataSourceMetaData(in *nodev1.DataSourceConfiguration) *plan.Da }) } + // Entity caching configurations + for _, ec := range in.EntityCacheConfigurations { + cacheName := resolveEntityCacheProviderID(l.entityCachingConfig, subgraphName, ec.TypeName) + out.FederationMetaData.EntityCaching = append(out.FederationMetaData.EntityCaching, plan.EntityCacheConfiguration{ + TypeName: ec.TypeName, + CacheName: cacheName, + TTL: time.Duration(ec.MaxAgeSeconds) * time.Second, + NegativeCacheTTL: time.Duration(ec.NotFoundCacheTtlSeconds) * time.Second, + IncludeSubgraphHeaderPrefix: ec.IncludeHeaders, + EnablePartialCacheLoad: ec.PartialCacheLoad, + ShadowMode: ec.ShadowMode, + }) + } + + // Root field cache configurations + for _, rfc := range in.RootFieldCacheConfigurations { + cacheName := resolveEntityCacheProviderID(l.entityCachingConfig, subgraphName, rfc.EntityTypeName) + var mappings []plan.EntityKeyMapping + for _, m := range rfc.EntityKeyMappings { + var fieldMappings []plan.FieldMapping + for _, fm := range m.FieldMappings { + fieldMappings = append(fieldMappings, plan.FieldMapping{ + EntityKeyField: fm.EntityKeyField, + ArgumentPath: fm.ArgumentPath, + ArgumentIsEntityKey: fm.IsBatch, + }) + } + mappings = append(mappings, plan.EntityKeyMapping{ + EntityTypeName: m.EntityTypeName, + FieldMappings: fieldMappings, + }) + } + rootTypeName := rootTypeNameForField(in.RootNodes, rfc.FieldName) + out.FederationMetaData.RootFieldCaching = append(out.FederationMetaData.RootFieldCaching, plan.RootFieldCacheConfiguration{ + TypeName: rootTypeName, + FieldName: rfc.FieldName, + CacheName: cacheName, + TTL: time.Duration(rfc.MaxAgeSeconds) * time.Second, + IncludeSubgraphHeaderPrefix: rfc.IncludeHeaders, + ShadowMode: rfc.ShadowMode, + EntityKeyMappings: mappings, + }) + } + + // Mutation/subscription cache populate + for _, cp := range in.CachePopulateConfigurations { + if cp.OperationType == protoOperationTypeSubscription { + var targetEntity *nodev1.EntityCacheConfiguration + for _, ec := range in.EntityCacheConfigurations { + if ec.TypeName == cp.EntityTypeName { + targetEntity = ec + break + } + } + if targetEntity == nil { + continue + } + ttl := time.Duration(targetEntity.MaxAgeSeconds) * time.Second + if cp.MaxAgeSeconds != nil { + ttl = time.Duration(*cp.MaxAgeSeconds) * time.Second + } + cacheName := resolveEntityCacheProviderID(l.entityCachingConfig, subgraphName, targetEntity.TypeName) + out.FederationMetaData.SubscriptionEntityPopulation = append( + out.FederationMetaData.SubscriptionEntityPopulation, + plan.SubscriptionEntityPopulationConfiguration{ + TypeName: targetEntity.TypeName, + FieldName: cp.FieldName, + CacheName: cacheName, + TTL: ttl, + IncludeSubgraphHeaderPrefix: targetEntity.IncludeHeaders, + }, + ) + } else { + // @cachePopulate(maxAge:) — when set, override the entity's default TTL on + // mutation-time writes. Without this, the populate path falls back to the + // cache implementation's default TTL. + var mutationTTL time.Duration + if cp.MaxAgeSeconds != nil { + mutationTTL = time.Duration(*cp.MaxAgeSeconds) * time.Second + } + out.FederationMetaData.MutationFieldCaching = append(out.FederationMetaData.MutationFieldCaching, plan.MutationFieldCacheConfiguration{ + FieldName: cp.FieldName, + EnableEntityL2CachePopulation: true, + TTL: mutationTTL, + }) + } + } + + // Mutation/subscription cache invalidation + for _, ci := range in.CacheInvalidateConfigurations { + if ci.OperationType == protoOperationTypeSubscription { + cacheName := resolveEntityCacheProviderID(l.entityCachingConfig, subgraphName, ci.EntityTypeName) + var includeHeaders bool + for _, ec := range in.EntityCacheConfigurations { + if ec.TypeName == ci.EntityTypeName { + includeHeaders = ec.IncludeHeaders + break + } + } + out.FederationMetaData.SubscriptionEntityPopulation = append( + out.FederationMetaData.SubscriptionEntityPopulation, + plan.SubscriptionEntityPopulationConfiguration{ + TypeName: ci.EntityTypeName, + FieldName: ci.FieldName, + CacheName: cacheName, + IncludeSubgraphHeaderPrefix: includeHeaders, + EnableInvalidationOnKeyOnly: true, + }, + ) + } else { + out.FederationMetaData.MutationCacheInvalidation = append(out.FederationMetaData.MutationCacheInvalidation, plan.MutationCacheInvalidationConfiguration{ + FieldName: ci.FieldName, + EntityTypeName: ci.EntityTypeName, + }) + } + } + + // Request-scoped field configurations. Every field annotated with @requestScoped + // in the subgraph is both a potential reader and writer of the coordinate L1 under + // its L1Key. The planner emits both a hint (read) and an export (write) for each. + for _, rsf := range in.RequestScopedFields { + out.FederationMetaData.RequestScopedFields = append(out.FederationMetaData.RequestScopedFields, plan.RequestScopedField{ + FieldName: rsf.FieldName, + TypeName: rsf.TypeName, + L1Key: rsf.L1Key, + }) + } + // Costs costConfig := in.GetCostConfiguration() if costConfig == nil { @@ -723,6 +850,17 @@ func (l *Loader) dataSourceMetaData(in *nodev1.DataSourceConfiguration) *plan.Da return out } +func rootTypeNameForField(rootNodes []*nodev1.TypeField, fieldName string) string { + for _, node := range rootNodes { + for _, fn := range node.FieldNames { + if fn == fieldName { + return node.TypeName + } + } + } + return "" +} + func (l *Loader) fieldHasAuthorizationRule(fieldConfiguration *nodev1.FieldConfiguration) bool { if fieldConfiguration == nil { return false diff --git a/router/core/factoryresolver_entity_cache_test.go b/router/core/factoryresolver_entity_cache_test.go new file mode 100644 index 0000000000..7960cf5d53 --- /dev/null +++ b/router/core/factoryresolver_entity_cache_test.go @@ -0,0 +1,224 @@ +package core + +import ( + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + nodev1 "github.com/wundergraph/cosmo/router/gen/proto/wg/cosmo/node/v1" + "github.com/wundergraph/cosmo/router/pkg/config" + "github.com/wundergraph/graphql-go-tools/v2/pkg/engine/plan" +) + +func TestDataSourceMetaDataMapsNegativeEntityCacheTTL(t *testing.T) { + t.Parallel() + + loader := &Loader{ + entityCachingConfig: &config.EntityCachingConfiguration{Enabled: true}, + } + + meta := loader.dataSourceMetaData(&nodev1.DataSourceConfiguration{ + EntityCacheConfigurations: []*nodev1.EntityCacheConfiguration{ + { + TypeName: "Item", + MaxAgeSeconds: 300, + NotFoundCacheTtlSeconds: 15, + IncludeHeaders: true, + PartialCacheLoad: true, + ShadowMode: true, + }, + }, + }, "items") + + require.Len(t, meta.FederationMetaData.EntityCaching, 1) + + cfg := meta.FederationMetaData.EntityCaching[0] + require.Equal(t, "Item", cfg.TypeName) + require.Equal(t, "default", cfg.CacheName) + require.Equal(t, 300*time.Second, cfg.TTL) + require.Equal(t, 15*time.Second, cfg.NegativeCacheTTL) + require.True(t, cfg.IncludeSubgraphHeaderPrefix) + require.True(t, cfg.EnablePartialCacheLoad) + require.True(t, cfg.ShadowMode) +} + +func TestDataSourceMetaDataMapsRootFieldMutationSubscriptionAndRequestScopedCacheConfig(t *testing.T) { + t.Parallel() + + mutationTTL := int64(15) + loader := &Loader{ + entityCachingConfig: &config.EntityCachingConfiguration{ + Enabled: true, + L2: config.EntityCachingL2Configuration{ + Enabled: true, + Storage: config.EntityCachingL2StorageConfig{ + ProviderID: "memory-default", + }, + }, + SubgraphCacheOverrides: []config.EntityCachingSubgraphCacheOverride{ + { + Name: "items", + Entities: []config.EntityCachingEntityConfig{ + {Type: "Item", StorageProviderID: "memory-items"}, + }, + }, + }, + }, + } + + meta := loader.dataSourceMetaData(&nodev1.DataSourceConfiguration{ + RootNodes: []*nodev1.TypeField{ + {TypeName: "Query", FieldNames: []string{"item"}}, + {TypeName: "Mutation", FieldNames: []string{"createItem", "deleteItem"}}, + {TypeName: "Subscription", FieldNames: []string{"itemCreated", "itemDeleted"}}, + }, + EntityCacheConfigurations: []*nodev1.EntityCacheConfiguration{ + { + TypeName: "Item", + MaxAgeSeconds: 60, + IncludeHeaders: true, + }, + }, + RootFieldCacheConfigurations: []*nodev1.RootFieldCacheConfiguration{ + { + FieldName: "item", + EntityTypeName: "Item", + MaxAgeSeconds: 30, + IncludeHeaders: true, + ShadowMode: true, + EntityKeyMappings: []*nodev1.EntityKeyMapping{ + { + EntityTypeName: "Item", + FieldMappings: []*nodev1.EntityCacheFieldMapping{ + { + EntityKeyField: "id", + ArgumentPath: []string{"id"}, + IsBatch: true, + }, + }, + }, + }, + }, + }, + CachePopulateConfigurations: []*nodev1.CachePopulateConfiguration{ + { + FieldName: "createItem", + EntityTypeName: "Item", + OperationType: "Mutation", + MaxAgeSeconds: &mutationTTL, + }, + { + FieldName: "itemCreated", + EntityTypeName: "Item", + OperationType: "Subscription", + }, + }, + CacheInvalidateConfigurations: []*nodev1.CacheInvalidateConfiguration{ + { + FieldName: "deleteItem", + EntityTypeName: "Item", + OperationType: "Mutation", + }, + { + FieldName: "itemDeleted", + EntityTypeName: "Item", + OperationType: "Subscription", + }, + }, + RequestScopedFields: []*nodev1.RequestScopedFieldConfiguration{ + { + FieldName: "currentViewer", + TypeName: "Query", + L1Key: "items.currentViewer", + }, + }, + }, "items") + + require.Len(t, meta.FederationMetaData.RootFieldCaching, 1) + rootCfg := meta.FederationMetaData.RootFieldCaching[0] + require.Equal(t, "Query", rootCfg.TypeName) + require.Equal(t, "item", rootCfg.FieldName) + require.Equal(t, "memory-items", rootCfg.CacheName) + require.Equal(t, 30*time.Second, rootCfg.TTL) + require.True(t, rootCfg.IncludeSubgraphHeaderPrefix) + require.True(t, rootCfg.ShadowMode) + require.Len(t, rootCfg.EntityKeyMappings, 1) + require.Len(t, rootCfg.EntityKeyMappings[0].FieldMappings, 1) + require.Equal(t, "id", rootCfg.EntityKeyMappings[0].FieldMappings[0].EntityKeyField) + require.Equal(t, []string{"id"}, rootCfg.EntityKeyMappings[0].FieldMappings[0].ArgumentPath) + require.True(t, rootCfg.EntityKeyMappings[0].FieldMappings[0].ArgumentIsEntityKey) + + require.Len(t, meta.FederationMetaData.MutationFieldCaching, 1) + require.Equal(t, "createItem", meta.FederationMetaData.MutationFieldCaching[0].FieldName) + require.True(t, meta.FederationMetaData.MutationFieldCaching[0].EnableEntityL2CachePopulation) + require.Equal(t, 15*time.Second, meta.FederationMetaData.MutationFieldCaching[0].TTL) + + require.Len(t, meta.FederationMetaData.MutationCacheInvalidation, 1) + require.Equal(t, "deleteItem", meta.FederationMetaData.MutationCacheInvalidation[0].FieldName) + require.Equal(t, "Item", meta.FederationMetaData.MutationCacheInvalidation[0].EntityTypeName) + + require.Len(t, meta.FederationMetaData.SubscriptionEntityPopulation, 2) + require.Equal(t, "itemCreated", meta.FederationMetaData.SubscriptionEntityPopulation[0].FieldName) + require.Equal(t, "memory-items", meta.FederationMetaData.SubscriptionEntityPopulation[0].CacheName) + require.Equal(t, 60*time.Second, meta.FederationMetaData.SubscriptionEntityPopulation[0].TTL) + require.True(t, meta.FederationMetaData.SubscriptionEntityPopulation[0].IncludeSubgraphHeaderPrefix) + require.False(t, meta.FederationMetaData.SubscriptionEntityPopulation[0].EnableInvalidationOnKeyOnly) + + require.Equal(t, "itemDeleted", meta.FederationMetaData.SubscriptionEntityPopulation[1].FieldName) + require.Equal(t, "memory-items", meta.FederationMetaData.SubscriptionEntityPopulation[1].CacheName) + require.True(t, meta.FederationMetaData.SubscriptionEntityPopulation[1].IncludeSubgraphHeaderPrefix) + require.True(t, meta.FederationMetaData.SubscriptionEntityPopulation[1].EnableInvalidationOnKeyOnly) + + require.Len(t, meta.FederationMetaData.RequestScopedFields, 1) + require.Equal(t, plan.RequestScopedField{ + FieldName: "currentViewer", + TypeName: "Query", + L1Key: "items.currentViewer", + }, meta.FederationMetaData.RequestScopedFields[0]) +} + +func TestRootTypeNameForField(t *testing.T) { + t.Parallel() + + t.Run("field found in Query type", func(t *testing.T) { + t.Parallel() + rootNodes := []*nodev1.TypeField{ + {TypeName: "Query", FieldNames: []string{"user", "users"}}, + {TypeName: "Mutation", FieldNames: []string{"createUser"}}, + } + assert.Equal(t, "Query", rootTypeNameForField(rootNodes, "user")) + }) + + t.Run("field found in Mutation type", func(t *testing.T) { + t.Parallel() + rootNodes := []*nodev1.TypeField{ + {TypeName: "Query", FieldNames: []string{"user"}}, + {TypeName: "Mutation", FieldNames: []string{"createUser", "deleteUser"}}, + } + assert.Equal(t, "Mutation", rootTypeNameForField(rootNodes, "createUser")) + }) + + t.Run("field not found", func(t *testing.T) { + t.Parallel() + rootNodes := []*nodev1.TypeField{ + {TypeName: "Query", FieldNames: []string{"user"}}, + {TypeName: "Mutation", FieldNames: []string{"createUser"}}, + } + assert.Equal(t, "", rootTypeNameForField(rootNodes, "nonExistent")) + }) + + t.Run("empty root nodes", func(t *testing.T) { + t.Parallel() + assert.Equal(t, "", rootTypeNameForField(nil, "user")) + }) + + t.Run("field in renamed query type", func(t *testing.T) { + t.Parallel() + rootNodes := []*nodev1.TypeField{ + {TypeName: "RootQuery", FieldNames: []string{"user", "products"}}, + } + assert.Equal(t, "RootQuery", rootTypeNameForField(rootNodes, "products")) + }) +} diff --git a/router/core/factoryresolver_test.go b/router/core/factoryresolver_test.go new file mode 100644 index 0000000000..0e7b778ba6 --- /dev/null +++ b/router/core/factoryresolver_test.go @@ -0,0 +1,55 @@ +package core + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + nodev1 "github.com/wundergraph/cosmo/router/gen/proto/wg/cosmo/node/v1" + "github.com/wundergraph/graphql-go-tools/v2/pkg/engine/plan" +) + +func TestDataSourceMetaData_RequestScopedFields(t *testing.T) { + l := &Loader{} + + in := &nodev1.DataSourceConfiguration{ + RequestScopedFields: []*nodev1.RequestScopedFieldConfiguration{ + { + FieldName: "currentUser", + TypeName: "Query", + L1Key: "viewer.user", + }, + { + FieldName: "currentUser", + TypeName: "Personalized", + L1Key: "viewer.user", + }, + }, + } + + out := l.dataSourceMetaData(in, "test-subgraph") + + assert.Len(t, out.FederationMetaData.RequestScopedFields, 2) + + assert.Equal(t, plan.RequestScopedField{ + FieldName: "currentUser", + TypeName: "Query", + L1Key: "viewer.user", + }, out.FederationMetaData.RequestScopedFields[0]) + + assert.Equal(t, plan.RequestScopedField{ + FieldName: "currentUser", + TypeName: "Personalized", + L1Key: "viewer.user", + }, out.FederationMetaData.RequestScopedFields[1]) +} + +func TestDataSourceMetaData_RequestScopedFields_Empty(t *testing.T) { + l := &Loader{} + + in := &nodev1.DataSourceConfiguration{} + + out := l.dataSourceMetaData(in, "test-subgraph") + + assert.Nil(t, out.FederationMetaData.RequestScopedFields) +} diff --git a/router/core/flushwriter.go b/router/core/flushwriter.go index 6d39f32dc8..322e1fc4a2 100644 --- a/router/core/flushwriter.go +++ b/router/core/flushwriter.go @@ -220,7 +220,7 @@ func wrapMultipartMessage(resp []byte, wrapPayload bool) ([]byte, error) { if err != nil { return nil, err } - respValue, _, err := astjson.MergeValuesWithPath(nil, payloadWrapper, respValuePreMerge, "payload") + respValue, err := astjson.MergeValuesWithPath(nil, payloadWrapper, respValuePreMerge, "payload") if err != nil { return nil, err } diff --git a/router/core/graph_server.go b/router/core/graph_server.go index 2d6be1f8fc..fcd0faf3d1 100644 --- a/router/core/graph_server.go +++ b/router/core/graph_server.go @@ -10,7 +10,9 @@ import ( "net/http" "net/url" "path/filepath" + "reflect" "runtime" + "sort" "strings" "sync" "time" @@ -59,8 +61,8 @@ import ( "github.com/wundergraph/cosmo/router/pkg/slowplancache" "github.com/wundergraph/cosmo/router/pkg/statistics" rtrace "github.com/wundergraph/cosmo/router/pkg/trace" - "github.com/wundergraph/graphql-go-tools/v2/pkg/astparser" + "github.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve" ) const ( @@ -98,18 +100,20 @@ type ( inFlightRequests *atomic.Uint64 // graphMuxList contains all graph muxes of this graph server. // It's keyed by mux name (feature flag name or empty string for base graph). - graphMuxList map[string]*graphMux - graphMuxListLock sync.Mutex - runtimeMetrics *rmetric.RuntimeMetrics - otlpEngineMetrics *rmetric.EngineMetrics - prometheusEngineMetrics *rmetric.EngineMetrics - connectionMetrics *rmetric.ConnectionMetrics - instanceData InstanceData - pubSubProviders []datasource.Provider - traceDialer *TraceDialer - connector *grpcconnector.Connector - circuitBreakerManager *circuit.Manager - headerPropagation *HeaderPropagation + graphMuxList map[string]*graphMux + graphMuxListLock sync.Mutex + runtimeMetrics *rmetric.RuntimeMetrics + otlpEngineMetrics *rmetric.EngineMetrics + prometheusEngineMetrics *rmetric.EngineMetrics + connectionMetrics *rmetric.ConnectionMetrics + instanceData InstanceData + pubSubProviders []datasource.Provider + traceDialer *TraceDialer + connector *grpcconnector.Connector + circuitBreakerManager *circuit.Manager + headerPropagation *HeaderPropagation + entityCacheInstances map[string]resolve.LoaderCache + entityCacheKeyInterceptors []EntityCacheKeyInterceptor } ) @@ -226,8 +230,23 @@ func newGraphServer(routerCtx context.Context, r *Router, response *routerconfig HostName: r.hostName, ListenAddress: r.listenAddr, }, - storageProviders: &r.storageProviders, - headerPropagation: r.headerPropagation, + storageProviders: &r.storageProviders, + headerPropagation: r.headerPropagation, + entityCacheKeyInterceptors: r.entityCacheKeyInterceptors, + } + + entityCacheInstances, err := r.buildEntityCacheInstances() + if err != nil { + return nil, fmt.Errorf("failed to build entity cache instances: %w", err) + } + s.entityCacheInstances = entityCacheInstances + + if entityCacheInstances != nil && r.entityCachingConfig.Enabled { + s.logEntityCacheOverrideIssues( + &r.entityCachingConfig, + response.Config.GetSubgraphs(), + response.Config.GetEngineConfig(), + ) } baseOtelAttributes := []attribute.KeyValue{ @@ -661,6 +680,53 @@ func (s *graphServer) setupEngineStatistics(baseAttributes []attribute.KeyValue) return nil } +// logEntityCacheOverrideIssues walks the entity caching overrides and emits +// warnings for references to unknown subgraphs or unknown entity types. It is +// non-fatal by design (void+log): startup continues regardless. Renaming from +// "validate*" to "log*" reflects this shape — it does not gate router startup. +func (s *graphServer) logEntityCacheOverrideIssues( + cfg *config.EntityCachingConfiguration, + configSubgraphs []*nodev1.Subgraph, + engineConfig *nodev1.EngineConfiguration, +) { + // Build lookup: subgraph name set + subgraphNames := make(map[string]bool, len(configSubgraphs)) + for _, sg := range configSubgraphs { + subgraphNames[sg.Name] = true + } + + // Build lookup: subgraph name → set of entity type names + // Datasources are keyed by ID, not name — map via subgraphNameByID + entityTypesBySubgraph := make(map[string]map[string]bool) + for _, ds := range engineConfig.DatasourceConfigurations { + sgName := subgraphNameByID(configSubgraphs, ds.Id) + if sgName == "" { + continue + } + if entityTypesBySubgraph[sgName] == nil { + entityTypesBySubgraph[sgName] = make(map[string]bool) + } + for _, ec := range ds.EntityCacheConfigurations { + entityTypesBySubgraph[sgName][ec.TypeName] = true + } + } + + for _, override := range cfg.SubgraphCacheOverrides { + if !subgraphNames[override.Name] { + s.logger.Warn("entity caching: subgraph_cache_overrides references unknown subgraph", + zap.String("subgraph", override.Name)) + continue + } + for _, entity := range override.Entities { + if entities := entityTypesBySubgraph[override.Name]; entities == nil || !entities[entity.Type] { + s.logger.Warn("entity caching: subgraph_cache_overrides references unknown entity type", + zap.String("subgraph", override.Name), + zap.String("entity_type", entity.Type)) + } + } + } +} + type graphMux struct { ctx context.Context cancel context.CancelFunc @@ -686,6 +752,65 @@ type graphMux struct { prometheusMetricsExporter *graphqlmetrics.PrometheusMetricsExporter } +type cacheMetricSource interface { + Metrics() *ristretto.Metrics + MaxSizeBytes() int64 +} + +type cacheMetricRegistration struct { + cacheType string + maxCost int64 + metrics *ristretto.Metrics +} + +func entityCacheMetricRegistrations(caches map[string]cacheMetricSource) []cacheMetricRegistration { + if len(caches) == 0 { + return nil + } + + type cacheGroup struct { + source cacheMetricSource + names []string + } + + grouped := make(map[uintptr]*cacheGroup, len(caches)) + for name, source := range caches { + if source == nil || source.Metrics() == nil || source.MaxSizeBytes() <= 0 { + continue + } + id := reflect.ValueOf(source).Pointer() + group := grouped[id] + if group == nil { + group = &cacheGroup{source: source} + grouped[id] = group + } + group.names = append(group.names, name) + } + + registrations := make([]cacheMetricRegistration, 0, len(grouped)) + for _, group := range grouped { + sort.Strings(group.names) + name := group.names[0] + for _, candidate := range group.names { + if candidate != "default" { + name = candidate + break + } + } + registrations = append(registrations, cacheMetricRegistration{ + cacheType: "entity_" + name, + maxCost: group.source.MaxSizeBytes(), + metrics: group.source.Metrics(), + }) + } + + sort.Slice(registrations, func(i, j int) bool { + return registrations[i].cacheType < registrations[j].cacheType + }) + + return registrations +} + // buildOperationCaches creates the caches for the graph mux. // The caches are created based on the engine configuration. func (s *graphMux) buildOperationCaches(srv *graphServer) (computeSha256 bool, err error) { @@ -929,6 +1054,18 @@ func (s *graphMux) configureCacheMetrics(srv *graphServer, baseOtelAttributes [] metricInfos = append(metricInfos, rmetric.NewCacheMetricInfo("query_hash", srv.engineExecutionConfiguration.OperationHashCacheSize, s.operationHashCache.Metrics)) } + entityMetricSources := make(map[string]cacheMetricSource) + for name, cache := range srv.entityCacheInstances { + source, ok := cache.(cacheMetricSource) + if !ok { + continue + } + entityMetricSources[name] = source + } + for _, registration := range entityCacheMetricRegistrations(entityMetricSources) { + metricInfos = append(metricInfos, rmetric.NewCacheMetricInfo(registration.cacheType, registration.maxCost, registration.metrics)) + } + if s.otelCacheMetrics != nil { if err := s.otelCacheMetrics.RegisterObservers(metricInfos); err != nil { return fmt.Errorf("failed to register observer for OTLP cache metrics: %w", err) @@ -1479,6 +1616,8 @@ func (s *graphServer) buildGraphMux( HeartbeatInterval: s.subscriptionHeartbeatInterval, PluginsEnabled: s.plugins.Enabled, InstanceData: s.instanceData, + EntityCacheInstances: s.entityCacheInstances, + EntityCachingConfig: &s.entityCachingConfig, }, ) if err != nil { @@ -1747,6 +1886,16 @@ func (s *graphServer) buildGraphMux( handlerOpts.ApolloSubscriptionMultipartPrintBoundary = s.apolloCompatibilityFlags.SubscriptionMultipartPrintBoundary.Enabled } + if s.entityCachingConfig.Enabled { + handlerOpts.EntityCaching = EntityCachingHandlerOptions{ + L1Enabled: s.entityCachingConfig.L1.Enabled, + L2Enabled: s.entityCachingConfig.L2.Enabled, + GlobalKeyPrefix: s.entityCachingConfig.GlobalCacheKeyPrefix, + KeyInterceptors: s.entityCacheKeyInterceptors, + } + // TODO: Add entity analytics exporter to handler options here once analytics pipeline is implemented (see ENTITY_CACHE_ANALYTICS.md). + } + graphqlHandler := NewGraphQLHandler(handlerOpts) executor.Resolver.SetAsyncErrorWriter(graphqlHandler) diff --git a/router/core/graphql_handler.go b/router/core/graphql_handler.go index f02817e8ac..76b1e195d4 100644 --- a/router/core/graphql_handler.go +++ b/router/core/graphql_handler.go @@ -85,6 +85,16 @@ type HandlerOptions struct { ApolloSubscriptionMultipartPrintBoundary bool HeaderPropagation *HeaderPropagation + + EntityCaching EntityCachingHandlerOptions +} + +// EntityCachingHandlerOptions groups all entity caching configuration passed to the GraphQL handler. +type EntityCachingHandlerOptions struct { + L1Enabled bool + L2Enabled bool + GlobalKeyPrefix string + KeyInterceptors []EntityCacheKeyInterceptor } func NewGraphQLHandler(opts HandlerOptions) *GraphQLHandler { @@ -106,6 +116,7 @@ func NewGraphQLHandler(opts HandlerOptions) *GraphQLHandler { engineLoaderHooks: opts.EngineLoaderHooks, apolloSubscriptionMultipartPrintBoundary: opts.ApolloSubscriptionMultipartPrintBoundary, headerPropagation: opts.HeaderPropagation, + entityCaching: opts.EntityCaching, } return graphQLHandler } @@ -138,6 +149,8 @@ type GraphQLHandler struct { enableCostResponseHeaders bool apolloSubscriptionMultipartPrintBoundary bool + + entityCaching EntityCachingHandlerOptions } func (h *GraphQLHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { @@ -163,6 +176,7 @@ func (h *GraphQLHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { resolveCtx.InitialPayload = reqCtx.operation.initialPayload resolveCtx.Extensions = reqCtx.operation.extensions resolveCtx.ExecutionOptions = reqCtx.operation.executionOptions + resolveCtx.ExecutionOptions.Caching = h.cachingOptions(reqCtx) if h.headerPropagation != nil { resolveCtx.SubgraphHeadersBuilder = SubgraphHeadersBuilder( @@ -586,3 +600,60 @@ func (h *GraphQLHandler) setDebugCacheHeaders(w http.ResponseWriter, opCtx *oper } } } + +const ( + disableEntityCacheHeader = "X-WG-Disable-Entity-Cache" + disableEntityCacheL1Header = "X-WG-Disable-Entity-Cache-L1" + disableEntityCacheL2Header = "X-WG-Disable-Entity-Cache-L2" + cacheKeyPrefixHeader = "X-WG-Cache-Key-Prefix" +) + +func (h *GraphQLHandler) cachingOptions(reqCtx *requestContext) resolve.CachingOptions { + enableL1 := h.entityCaching.L1Enabled + enableL2 := h.entityCaching.L2Enabled + globalKeyPrefix := h.entityCaching.GlobalKeyPrefix + + // Allow per-request cache control headers only when tracing is authorized + // (dev mode or valid studio request token). This prevents production abuse. + if reqCtx.operation.traceOptions.Enable { + if reqCtx.request.Header.Get(disableEntityCacheHeader) == "true" { + enableL1 = false + enableL2 = false + } else { + if reqCtx.request.Header.Get(disableEntityCacheL1Header) == "true" { + enableL1 = false + } + if reqCtx.request.Header.Get(disableEntityCacheL2Header) == "true" { + enableL2 = false + } + } + if prefix := reqCtx.request.Header.Get(cacheKeyPrefixHeader); prefix != "" { + if globalKeyPrefix != "" { + globalKeyPrefix = prefix + ":" + globalKeyPrefix + } else { + globalKeyPrefix = prefix + } + } + } + + return resolve.CachingOptions{ + EnableL1Cache: enableL1, + EnableL2Cache: enableL2, + EnableCacheAnalytics: false, + GlobalCacheKeyPrefix: globalKeyPrefix, + L2CacheKeyInterceptor: h.buildL2CacheKeyInterceptor(reqCtx), + } +} + +func (h *GraphQLHandler) buildL2CacheKeyInterceptor(reqCtx *requestContext) resolve.L2CacheKeyInterceptor { + if len(h.entityCaching.KeyInterceptors) == 0 { + return nil + } + return func(ctx context.Context, key string, info resolve.L2CacheKeyInterceptorInfo) string { + keys := [][]byte{[]byte(key)} + for _, interceptor := range h.entityCaching.KeyInterceptors { + keys = interceptor.OnEntityCacheKeys(keys, reqCtx) + } + return string(keys[0]) + } +} diff --git a/router/core/graphql_handler_caching_options_test.go b/router/core/graphql_handler_caching_options_test.go new file mode 100644 index 0000000000..705fc7e3e8 --- /dev/null +++ b/router/core/graphql_handler_caching_options_test.go @@ -0,0 +1,172 @@ +package core + +import ( + "net/http" + "net/http/httptest" + "testing" + + "github.com/stretchr/testify/require" + "github.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve" +) + +func newCachingOptionsHandler(entity EntityCachingHandlerOptions) *GraphQLHandler { + return &GraphQLHandler{entityCaching: entity} +} + +func newCachingOptionsReqCtx(t *testing.T, traceEnabled bool, headers map[string]string) *requestContext { + t.Helper() + req := httptest.NewRequest(http.MethodPost, "/graphql", nil) + for k, v := range headers { + req.Header.Set(k, v) + } + return &requestContext{ + request: req, + operation: &operationContext{ + traceOptions: resolve.TraceOptions{Enable: traceEnabled}, + }, + } +} + +func TestGraphQLHandler_cachingOptions_DefaultsFromHandler(t *testing.T) { + t.Parallel() + h := newCachingOptionsHandler(EntityCachingHandlerOptions{ + L1Enabled: true, + L2Enabled: true, + GlobalKeyPrefix: "router-a", + }) + reqCtx := newCachingOptionsReqCtx(t, false, nil) + + opts := h.cachingOptions(reqCtx) + require.Equal(t, resolve.CachingOptions{ + EnableL1Cache: true, + EnableL2Cache: true, + EnableCacheAnalytics: false, + GlobalCacheKeyPrefix: "router-a", + L2CacheKeyInterceptor: nil, + }, opts) +} + +func TestGraphQLHandler_cachingOptions_DisableCacheHeaderIgnoredWithoutTracing(t *testing.T) { + t.Parallel() + h := newCachingOptionsHandler(EntityCachingHandlerOptions{ + L1Enabled: true, + L2Enabled: true, + }) + // Tracing NOT enabled — headers should be ignored. + reqCtx := newCachingOptionsReqCtx(t, false, map[string]string{ + disableEntityCacheHeader: "true", + disableEntityCacheL1Header: "true", + disableEntityCacheL2Header: "true", + cacheKeyPrefixHeader: "ignored", + }) + + opts := h.cachingOptions(reqCtx) + require.Equal(t, resolve.CachingOptions{ + EnableL1Cache: true, + EnableL2Cache: true, + EnableCacheAnalytics: false, + GlobalCacheKeyPrefix: "", + L2CacheKeyInterceptor: nil, + }, opts) +} + +func TestGraphQLHandler_cachingOptions_DisableAllWithTracing(t *testing.T) { + t.Parallel() + h := newCachingOptionsHandler(EntityCachingHandlerOptions{ + L1Enabled: true, + L2Enabled: true, + }) + reqCtx := newCachingOptionsReqCtx(t, true, map[string]string{ + disableEntityCacheHeader: "true", + }) + + opts := h.cachingOptions(reqCtx) + require.Equal(t, resolve.CachingOptions{ + EnableL1Cache: false, + EnableL2Cache: false, + EnableCacheAnalytics: false, + GlobalCacheKeyPrefix: "", + L2CacheKeyInterceptor: nil, + }, opts) +} + +func TestGraphQLHandler_cachingOptions_DisableL1Only(t *testing.T) { + t.Parallel() + h := newCachingOptionsHandler(EntityCachingHandlerOptions{ + L1Enabled: true, + L2Enabled: true, + }) + reqCtx := newCachingOptionsReqCtx(t, true, map[string]string{ + disableEntityCacheL1Header: "true", + }) + + opts := h.cachingOptions(reqCtx) + require.Equal(t, resolve.CachingOptions{ + EnableL1Cache: false, + EnableL2Cache: true, + EnableCacheAnalytics: false, + GlobalCacheKeyPrefix: "", + L2CacheKeyInterceptor: nil, + }, opts) +} + +func TestGraphQLHandler_cachingOptions_DisableL2Only(t *testing.T) { + t.Parallel() + h := newCachingOptionsHandler(EntityCachingHandlerOptions{ + L1Enabled: true, + L2Enabled: true, + }) + reqCtx := newCachingOptionsReqCtx(t, true, map[string]string{ + disableEntityCacheL2Header: "true", + }) + + opts := h.cachingOptions(reqCtx) + require.Equal(t, resolve.CachingOptions{ + EnableL1Cache: true, + EnableL2Cache: false, + EnableCacheAnalytics: false, + GlobalCacheKeyPrefix: "", + L2CacheKeyInterceptor: nil, + }, opts) +} + +func TestGraphQLHandler_cachingOptions_CacheKeyPrefixPrependsToGlobal(t *testing.T) { + t.Parallel() + h := newCachingOptionsHandler(EntityCachingHandlerOptions{ + L1Enabled: true, + L2Enabled: true, + GlobalKeyPrefix: "base", + }) + reqCtx := newCachingOptionsReqCtx(t, true, map[string]string{ + cacheKeyPrefixHeader: "req-42", + }) + + opts := h.cachingOptions(reqCtx) + require.Equal(t, resolve.CachingOptions{ + EnableL1Cache: true, + EnableL2Cache: true, + EnableCacheAnalytics: false, + GlobalCacheKeyPrefix: "req-42:base", + L2CacheKeyInterceptor: nil, + }, opts) +} + +func TestGraphQLHandler_cachingOptions_CacheKeyPrefixReplacesEmptyGlobal(t *testing.T) { + t.Parallel() + h := newCachingOptionsHandler(EntityCachingHandlerOptions{ + L1Enabled: true, + L2Enabled: true, + }) + reqCtx := newCachingOptionsReqCtx(t, true, map[string]string{ + cacheKeyPrefixHeader: "standalone", + }) + + opts := h.cachingOptions(reqCtx) + require.Equal(t, resolve.CachingOptions{ + EnableL1Cache: true, + EnableL2Cache: true, + EnableCacheAnalytics: false, + GlobalCacheKeyPrefix: "standalone", + L2CacheKeyInterceptor: nil, + }, opts) +} diff --git a/router/core/modules.go b/router/core/modules.go index a05ac63683..e528bcfb3f 100644 --- a/router/core/modules.go +++ b/router/core/modules.go @@ -155,6 +155,16 @@ type SpanNameFormatterProvider interface { WrapSpanNameFormatter(next SpanNameFormatterFunc) SpanNameFormatterFunc } +// EntityCacheKeyInterceptor allows custom modules to transform entity cache keys +// before they are used for L2 cache operations. +type EntityCacheKeyInterceptor interface { + // OnEntityCacheKeys transforms a batch of cache keys for an entity cache operation. + // Each key is a JSON-encoded entity key or root field key. + // Returns the transformed keys in the same order. The returned slice must have + // the same length as the input slice. + OnEntityCacheKeys(keys [][]byte, ctx RequestContext) [][]byte +} + // Provisioner is called before the server starts // It allows you to initialize your module, e.g., create a database connection // or load a configuration file. diff --git a/router/core/router.go b/router/core/router.go index 4dd2f64b54..22f2b8a547 100644 --- a/router/core/router.go +++ b/router/core/router.go @@ -6,6 +6,7 @@ import ( "crypto/x509" "errors" "fmt" + "io" "net" "net/http" "net/url" @@ -51,6 +52,7 @@ import ( "github.com/wundergraph/cosmo/router/pkg/controlplane/configpoller" "github.com/wundergraph/cosmo/router/pkg/controlplane/selfregister" "github.com/wundergraph/cosmo/router/pkg/cors" + "github.com/wundergraph/cosmo/router/pkg/entitycache" "github.com/wundergraph/cosmo/router/pkg/execution_config" "github.com/wundergraph/cosmo/router/pkg/health" "github.com/wundergraph/cosmo/router/pkg/mcpserver" @@ -60,6 +62,7 @@ import ( rtrace "github.com/wundergraph/cosmo/router/pkg/trace" "github.com/wundergraph/cosmo/router/pkg/trace/attributeprocessor" "github.com/wundergraph/cosmo/router/pkg/watcher" + "github.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve" "github.com/wundergraph/graphql-go-tools/v2/pkg/netpoll" ) @@ -347,6 +350,11 @@ func NewRouter(ctx context.Context, opts ...Option) (*Router, error) { "x-wg-token", "x-wg-skip-loader", "x-wg-include-query-plan", + // Required for the studio playground's Cache Explorer (cache-mode dropdown) + "x-wg-disable-entity-cache", + "x-wg-disable-entity-cache-l1", + "x-wg-disable-entity-cache-l2", + "x-wg-cache-key-prefix", // Required for Trace Context propagation "traceparent", "tracestate", @@ -766,6 +774,10 @@ func (r *Router) initModules(ctx context.Context) error { r.subscriptionHooks.onReceiveEvents.handlers = append(r.subscriptionHooks.onReceiveEvents.handlers, handler.OnReceiveEvents) } + if interceptor, ok := moduleInstance.(EntityCacheKeyInterceptor); ok { + r.entityCacheKeyInterceptors = append(r.entityCacheKeyInterceptors, interceptor) + } + r.modules = append(r.modules, moduleInstance) r.logger.Info("Module registered", @@ -959,6 +971,8 @@ func (r *Router) bootstrap(ctx context.Context) error { r.logger.Info("GraphQL schema coverage metrics enabled") } + // TODO: Add entity analytics exporter setup here once the analytics pipeline is implemented (see ENTITY_CACHE_ANALYTICS.md). + // Create Prometheus metrics exporter for schema field usage // Note: This is separate from the Prometheus meter provider which handles OTEL metrics // This exporter is specifically for schema field usage tracking via the Prometheus sink @@ -1468,6 +1482,111 @@ func (r *Router) buildConfigPoller(registry *ProviderRegistry) error { return nil } +// buildEntityCacheInstances creates Redis-backed LoaderCache instances from storage providers +// based on the entity caching configuration. If pre-seeded instances are set (via WithEntityCacheInstances), +// those are returned directly. +func (r *Router) buildEntityCacheInstances() (map[string]resolve.LoaderCache, error) { + if r.entityCacheInstances != nil { + return r.entityCacheInstances, nil + } + if !r.entityCachingConfig.Enabled || !r.entityCachingConfig.L2.Enabled { + return nil, nil + } + + caches := make(map[string]resolve.LoaderCache) + l2Cfg := r.entityCachingConfig.L2 + + // Build default cache from l2.storage.provider_id. Store it under both the + // literal "default" key (used when no override matches) and under its real + // provider_id so an override that redirects to the same backend reuses the + // same instance instead of allocating a second one. + if l2Cfg.Storage.ProviderID != "" { + cache, err := r.buildSingleEntityCache(l2Cfg.Storage.ProviderID, l2Cfg) + if err != nil { + return nil, fmt.Errorf("entity caching default provider: %w", err) + } + caches["default"] = cache + caches[l2Cfg.Storage.ProviderID] = cache + } + + // Build per-subgraph/entity caches from subgraph_cache_overrides + for _, sg := range r.entityCachingConfig.SubgraphCacheOverrides { + // Collect unique provider IDs from subgraph-level and entity-level overrides + providerIDs := make(map[string]string) // providerID → context (for error messages) + if sg.StorageProviderID != "" && sg.StorageProviderID != "default" { + providerIDs[sg.StorageProviderID] = sg.Name + } + for _, entity := range sg.Entities { + if entity.StorageProviderID != "" && entity.StorageProviderID != "default" { + providerIDs[entity.StorageProviderID] = sg.Name + "." + entity.Type + } + } + for providerID, context := range providerIDs { + if _, exists := caches[providerID]; exists { + // Already built (either as the default cache's provider alias + // or from an earlier override); reuse the same instance. + continue + } + cache, err := r.buildSingleEntityCache(providerID, l2Cfg) + if err != nil { + return nil, fmt.Errorf("entity caching provider %q for %s: %w", + providerID, context, err) + } + caches[providerID] = cache + } + } + + return caches, nil +} + +// buildSingleEntityCache creates a cache backed by either Redis or memory, with optional circuit breaker wrapping. +func (r *Router) buildSingleEntityCache(providerID string, l2Cfg config.EntityCachingL2Configuration) (resolve.LoaderCache, error) { + var cache resolve.LoaderCache + if memProvider, ok := r.findMemoryProvider(providerID); ok { + mc, err := entitycache.NewMemoryEntityCache(int64(memProvider.MaxSize)) + if err != nil { + return nil, fmt.Errorf("creating memory cache: %w", err) + } + cache = mc + } else { + client, err := r.buildRedisClient(providerID) + if err != nil { + return nil, err + } + cache = entitycache.NewRedisEntityCache(client, l2Cfg.Storage.KeyPrefix) + } + if l2Cfg.CircuitBreaker.Enabled { + cache = entitycache.NewCircuitBreakerCache(cache, entitycache.CircuitBreakerConfig{ + Enabled: true, + FailureThreshold: l2Cfg.CircuitBreaker.FailureThreshold, + CooldownPeriod: l2Cfg.CircuitBreaker.CooldownPeriod, + }) + } + return cache, nil +} + +func (r *Router) buildRedisClient(providerID string) (rd.RDCloser, error) { + for _, provider := range r.storageProviders.Redis { + if provider.ID == providerID { + return rd.NewRedisCloser(&rd.RedisCloserOptions{ + Logger: r.logger, + URLs: provider.URLs, + ClusterEnabled: provider.ClusterEnabled, + }) + } + } + return nil, fmt.Errorf("storage provider %q not found in storage_providers (checked redis, memory)", providerID) +} + +func (r *Router) findMemoryProvider(providerID string) (*config.MemoryStorageProvider, bool) { + for i := range r.storageProviders.Memory { + if r.storageProviders.Memory[i].ID == providerID { + return &r.storageProviders.Memory[i], true + } + } + return nil, false +} + // Start starts the router. It does block until the router has been initialized. After that the server is listening // on a separate goroutine. The server can be shutdown with Router.Shutdown(). Not safe for concurrent use. // During initialization, the router will register itself with the control plane and poll the config from the CDN @@ -1913,6 +2032,15 @@ func (r *Router) Shutdown(ctx context.Context) error { r.pqlStore.Close() } + // Close entity cache instances that implement io.Closer (e.g. ristretto-backed MemoryEntityCache). + for _, cache := range r.entityCacheInstances { + if closer, ok := cache.(io.Closer); ok { + if closeErr := closer.Close(); closeErr != nil { + err.Append(fmt.Errorf("failed to close entity cache: %w", closeErr)) + } + } + } + r.usage.Close() wg.Wait() @@ -2507,6 +2635,18 @@ func WithStorageProviders(cfg config.StorageProviders) Option { } } +func WithEntityCaching(cfg config.EntityCachingConfiguration) Option { + return func(r *Router) { + r.entityCachingConfig = cfg + } +} + +func WithEntityCacheInstances(caches map[string]resolve.LoaderCache) Option { + return func(r *Router) { + r.entityCacheInstances = caches + } +} + func WithClientHeader(cfg config.ClientHeader) Option { return func(r *Router) { r.clientHeader = cfg diff --git a/router/core/router_config.go b/router/core/router_config.go index 6b380ede12..f64220082e 100644 --- a/router/core/router_config.go +++ b/router/core/router_config.go @@ -20,6 +20,7 @@ import ( rmetric "github.com/wundergraph/cosmo/router/pkg/metric" "github.com/wundergraph/cosmo/router/pkg/pubsub/datasource" rtrace "github.com/wundergraph/cosmo/router/pkg/trace" + "github.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve" "go.opentelemetry.io/otel/propagation" sdkmetric "go.opentelemetry.io/otel/sdk/metric" sdktrace "go.opentelemetry.io/otel/sdk/trace" @@ -153,6 +154,9 @@ type Config struct { grpcPluginDialOptions []grpc.DialOption tracingAttributes []config.CustomAttribute subscriptionHooks subscriptionHooks + entityCachingConfig config.EntityCachingConfiguration + entityCacheInstances map[string]resolve.LoaderCache + entityCacheKeyInterceptors []EntityCacheKeyInterceptor } // Usage returns an anonymized version of the config for usage tracking diff --git a/router/core/router_entity_cache_test.go b/router/core/router_entity_cache_test.go new file mode 100644 index 0000000000..20cc98e791 --- /dev/null +++ b/router/core/router_entity_cache_test.go @@ -0,0 +1,170 @@ +package core + +import ( + "testing" + "time" + + ristretto "github.com/dgraph-io/ristretto/v2" + "github.com/stretchr/testify/require" + "go.uber.org/zap" + + "github.com/wundergraph/cosmo/router/pkg/config" + "github.com/wundergraph/cosmo/router/pkg/entitycache" +) + +// TestBuildEntityCacheInstances_ReusesDefaultCacheForSameProviderID verifies +// that when an override points at the same provider_id as l2.storage.provider_id, +// no second cache instance is allocated. The default entry and the provider_id +// entry must resolve to the same *MemoryEntityCache pointer. +func TestBuildEntityCacheInstances_ReusesDefaultCacheForSameProviderID(t *testing.T) { + t.Parallel() + + r := &Router{ + Config: Config{ + logger: zap.NewNop(), + entityCachingConfig: config.EntityCachingConfiguration{ + Enabled: true, + L2: config.EntityCachingL2Configuration{ + Enabled: true, + Storage: config.EntityCachingL2StorageConfig{ + ProviderID: "memory-1", + }, + }, + SubgraphCacheOverrides: []config.EntityCachingSubgraphCacheOverride{ + { + Name: "products", + StorageProviderID: "memory-1", // same as the default + }, + }, + }, + storageProviders: config.StorageProviders{ + Memory: []config.MemoryStorageProvider{ + {ID: "memory-1", MaxSize: config.BytesString(1024 * 1024)}, + }, + }, + }, + } + + caches, err := r.buildEntityCacheInstances() + require.NoError(t, err) + require.Len(t, caches, 2, "expected exactly two keys: default and memory-1") + + defaultCache, ok := caches["default"] + require.True(t, ok, `missing "default" entry`) + namedCache, ok := caches["memory-1"] + require.True(t, ok, `missing "memory-1" entry`) + require.Same(t, defaultCache, namedCache, + "default cache and same-provider-id override must share the same instance") +} + +// TestBuildEntityCacheInstances_DistinctProviderIDs verifies that overrides +// pointing at a different provider still allocate their own cache instance. +func TestBuildEntityCacheInstances_DistinctProviderIDs(t *testing.T) { + t.Parallel() + + r := &Router{ + Config: Config{ + logger: zap.NewNop(), + entityCachingConfig: config.EntityCachingConfiguration{ + Enabled: true, + L2: config.EntityCachingL2Configuration{ + Enabled: true, + Storage: config.EntityCachingL2StorageConfig{ + ProviderID: "memory-1", + }, + }, + SubgraphCacheOverrides: []config.EntityCachingSubgraphCacheOverride{ + { + Name: "products", + StorageProviderID: "memory-2", + }, + }, + }, + storageProviders: config.StorageProviders{ + Memory: []config.MemoryStorageProvider{ + {ID: "memory-1", MaxSize: config.BytesString(1024 * 1024)}, + {ID: "memory-2", MaxSize: config.BytesString(2 * 1024 * 1024)}, + }, + }, + }, + } + + caches, err := r.buildEntityCacheInstances() + require.NoError(t, err) + require.Len(t, caches, 3, "expected three keys: default, memory-1 alias, memory-2 override") + require.NotSame(t, caches["memory-1"], caches["memory-2"], + "distinct provider ids must yield distinct cache instances") + require.Same(t, caches["default"], caches["memory-1"], + "default alias must point at the memory-1 instance") +} + +func TestBuildEntityCacheInstances_DisabledReturnsNil(t *testing.T) { + t.Parallel() + + r := &Router{ + Config: Config{ + logger: zap.NewNop(), + entityCachingConfig: config.EntityCachingConfiguration{ + Enabled: false, + }, + }, + } + + caches, err := r.buildEntityCacheInstances() + require.NoError(t, err) + require.Nil(t, caches) +} + +func TestBuildSingleEntityCache_WrapsMemoryProviderWithCircuitBreaker(t *testing.T) { + t.Parallel() + + r := &Router{ + Config: Config{ + logger: zap.NewNop(), + storageProviders: config.StorageProviders{ + Memory: []config.MemoryStorageProvider{ + {ID: "memory-1", MaxSize: config.BytesString(2048)}, + }, + }, + }, + } + + cache, err := r.buildSingleEntityCache("memory-1", config.EntityCachingL2Configuration{ + CircuitBreaker: config.EntityCachingCircuitBreakerConfig{ + Enabled: true, + FailureThreshold: 3, + CooldownPeriod: time.Second, + }, + }) + require.NoError(t, err) + + breaker, ok := cache.(*entitycache.CircuitBreakerCache) + require.True(t, ok, "expected circuit breaker wrapper") + + metricsProvider, ok := any(breaker).(interface { + Metrics() *ristretto.Metrics + MaxSizeBytes() int64 + }) + require.True(t, ok, "wrapped cache should expose metrics accessors") + require.NotNil(t, metricsProvider.Metrics()) + require.EqualValues(t, 2048, metricsProvider.MaxSizeBytes()) +} + +func TestFindMemoryProvider_ReturnsFalseForUnknownProvider(t *testing.T) { + t.Parallel() + + r := &Router{ + Config: Config{ + logger: zap.NewNop(), + storageProviders: config.StorageProviders{ + Memory: []config.MemoryStorageProvider{ + {ID: "memory-1", MaxSize: config.BytesString(1024)}, + }, + }, + }, + } + + provider, ok := r.findMemoryProvider("missing") + require.False(t, ok) + require.Nil(t, provider) +} diff --git a/router/core/supervisor_instance.go b/router/core/supervisor_instance.go index d6a29db483..565883ec95 100644 --- a/router/core/supervisor_instance.go +++ b/router/core/supervisor_instance.go @@ -219,6 +219,7 @@ func optionsFromResources(logger *zap.Logger, config *config.Config, reloadPersi WithApolloCompatibilityFlagsConfig(config.ApolloCompatibilityFlags), WithApolloRouterCompatibilityFlags(config.ApolloRouterCompatibilityFlags), WithStorageProviders(config.StorageProviders), + WithEntityCaching(config.EntityCaching), WithGraphQLPath(config.GraphQLPath), WithModulesConfig(config.Modules), WithGracePeriod(config.GracePeriod), diff --git a/router/core/websocket.go b/router/core/websocket.go index 95f83864b6..293cd3d7a3 100644 --- a/router/core/websocket.go +++ b/router/core/websocket.go @@ -1102,6 +1102,7 @@ func (h *WebSocketConnectionHandler) executeSubscription(registration *Subscript resolveCtx.TracingOptions = operationCtx.traceOptions resolveCtx.Extensions = operationCtx.extensions resolveCtx.ExecutionOptions = operationCtx.executionOptions + resolveCtx.ExecutionOptions.Caching = h.graphqlHandler.cachingOptions(reqContext) if operationCtx.initialPayload != nil { resolveCtx.InitialPayload = operationCtx.initialPayload diff --git a/router/go.mod b/router/go.mod index 1d099273e3..ea0473cae8 100644 --- a/router/go.mod +++ b/router/go.mod @@ -31,7 +31,7 @@ require ( github.com/tidwall/gjson v1.18.0 github.com/tidwall/sjson v1.2.5 github.com/twmb/franz-go v1.16.1 - github.com/wundergraph/graphql-go-tools/v2 v2.4.4 + github.com/wundergraph/graphql-go-tools/v2 v2.4.5-0.20260610161004-63fa1c88eaea // Do not upgrade, it renames attributes we rely on go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.68.0 go.opentelemetry.io/contrib/propagators/b3 v1.43.0 @@ -82,8 +82,8 @@ require ( github.com/prometheus/otlptranslator v1.0.0 github.com/santhosh-tekuri/jsonschema/v6 v6.0.1 github.com/tonglil/opentelemetry-go-datadog-propagator v0.1.3 - github.com/wundergraph/astjson v1.1.0 - github.com/wundergraph/go-arena v1.1.0 + github.com/wundergraph/astjson v1.1.1-0.20260419105127-f600d161463f + github.com/wundergraph/go-arena v1.2.0 go.uber.org/goleak v1.3.0 go.uber.org/ratelimit v0.3.1 golang.org/x/exp v0.0.0-20250813145105-42675adae3e6 diff --git a/router/go.sum b/router/go.sum index c0bb919835..ed70b5f879 100644 --- a/router/go.sum +++ b/router/go.sum @@ -329,12 +329,12 @@ github.com/vbatts/tar-split v0.12.1 h1:CqKoORW7BUWBe7UL/iqTVvkTBOF8UvOMKOIZykxnn github.com/vbatts/tar-split v0.12.1/go.mod h1:eF6B6i6ftWQcDqEn3/iGFRFRo8cBIMSJVOpnNdfTMFA= github.com/vektah/gqlparser/v2 v2.5.30 h1:EqLwGAFLIzt1wpx1IPpY67DwUujF1OfzgEyDsLrN6kE= github.com/vektah/gqlparser/v2 v2.5.30/go.mod h1:D1/VCZtV3LPnQrcPBeR/q5jkSQIPti0uYCP/RI0gIeo= -github.com/wundergraph/astjson v1.1.0 h1:xORDosrZ87zQFJwNGe/HIHXqzpdHOFmqWgykCLVL040= -github.com/wundergraph/astjson v1.1.0/go.mod h1:h12D/dxxnedtLzsKyBLK7/Oe4TAoGpRVC9nDpDrZSWw= -github.com/wundergraph/go-arena v1.1.0 h1:9+wSRkJAkA2vbYHp6s8tEGhPViRGQNGXqPHT0QzhdIc= -github.com/wundergraph/go-arena v1.1.0/go.mod h1:ROOysEHWJjLQ8FSfNxZCziagb7Qw2nXY3/vgKRh7eWw= -github.com/wundergraph/graphql-go-tools/v2 v2.4.4 h1:VCvS9bku4ie7+St3+H5SNuVz6dtQiDKujqQ439yrMBM= -github.com/wundergraph/graphql-go-tools/v2 v2.4.4/go.mod h1:7ljNHLrBOoOszCk4ir4Z+O6Yrf+vwBBmxjwqM3imVgA= +github.com/wundergraph/astjson v1.1.1-0.20260419105127-f600d161463f h1:MoVoeMlgY9Ej1aoF3Y/kniBZ8pv+WfIA3YSCnPBh+6M= +github.com/wundergraph/astjson v1.1.1-0.20260419105127-f600d161463f/go.mod h1:uHSJv7uowLN/nIPvkTFqUDt1sXk4qQU0KNwHfwfDcQE= +github.com/wundergraph/go-arena v1.2.0 h1:6MlhEy0NBY3Z+BuK3rj0F9YoT3bM0SlahGkzK0lKRZ4= +github.com/wundergraph/go-arena v1.2.0/go.mod h1:ROOysEHWJjLQ8FSfNxZCziagb7Qw2nXY3/vgKRh7eWw= +github.com/wundergraph/graphql-go-tools/v2 v2.4.5-0.20260610161004-63fa1c88eaea h1:ACjZjX87K3ADlFy54YrwZ/UPCugKL56/DtQNWB5EGeU= +github.com/wundergraph/graphql-go-tools/v2 v2.4.5-0.20260610161004-63fa1c88eaea/go.mod h1:3NuqY1nBh7g4IkytYazmT6RHg/giCsdZpmX0NkpayNs= github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4= github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4= github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M= diff --git a/router/pkg/config/config.go b/router/pkg/config/config.go index faec91db69..8311568672 100644 --- a/router/pkg/config/config.go +++ b/router/pkg/config/config.go @@ -1017,9 +1017,15 @@ type StorageProviders struct { S3 []S3StorageProvider `yaml:"s3,omitempty" envPrefix:"S3_"` CDN []CDNStorageProvider `yaml:"cdn,omitempty" envPrefix:"CDN_"` Redis []RedisStorageProvider `yaml:"redis,omitempty" envPrefix:"REDIS_"` + Memory []MemoryStorageProvider `yaml:"memory,omitempty" envPrefix:"MEMORY_"` FileSystem []FileSystemStorageProvider `yaml:"file_system,omitempty" envPrefix:"FS_"` } +type MemoryStorageProvider struct { + ID string `yaml:"id,omitempty" env:"STORAGE_PROVIDER_MEMORY_ID"` + MaxSize BytesString `yaml:"max_size" envDefault:"100MB" env:"STORAGE_PROVIDER_MEMORY_MAX_SIZE"` +} + type PersistedOperationsStorageConfig struct { ProviderID string `yaml:"provider_id,omitempty" env:"PERSISTED_OPERATIONS_STORAGE_PROVIDER_ID"` ObjectPrefix string `yaml:"object_prefix,omitempty" env:"PERSISTED_OPERATIONS_STORAGE_OBJECT_PREFIX"` @@ -1148,6 +1154,46 @@ type AutomaticPersistedQueriesConfig struct { Storage AutomaticPersistedQueriesStorageConfig `yaml:"storage"` } +type EntityCachingConfiguration struct { + Enabled bool `yaml:"enabled" envDefault:"false" env:"ENTITY_CACHING_ENABLED"` + GlobalCacheKeyPrefix string `yaml:"global_cache_key_prefix,omitempty" env:"ENTITY_CACHING_GLOBAL_CACHE_KEY_PREFIX"` + L1 EntityCachingL1Configuration `yaml:"l1"` + L2 EntityCachingL2Configuration `yaml:"l2"` + SubgraphCacheOverrides []EntityCachingSubgraphCacheOverride `yaml:"subgraph_cache_overrides,omitempty"` +} + +type EntityCachingL1Configuration struct { + Enabled bool `yaml:"enabled" envDefault:"true" env:"ENTITY_CACHING_L1_ENABLED"` +} + +type EntityCachingL2Configuration struct { + Enabled bool `yaml:"enabled" envDefault:"true" env:"ENTITY_CACHING_L2_ENABLED"` + Storage EntityCachingL2StorageConfig `yaml:"storage"` + CircuitBreaker EntityCachingCircuitBreakerConfig `yaml:"circuit_breaker"` +} + +type EntityCachingL2StorageConfig struct { + ProviderID string `yaml:"provider_id,omitempty" env:"ENTITY_CACHING_L2_STORAGE_PROVIDER_ID"` + KeyPrefix string `yaml:"key_prefix,omitempty" envDefault:"cosmo_entity_cache" env:"ENTITY_CACHING_L2_STORAGE_KEY_PREFIX"` +} + +type EntityCachingCircuitBreakerConfig struct { + Enabled bool `yaml:"enabled" envDefault:"false" env:"ENTITY_CACHING_L2_CIRCUIT_BREAKER_ENABLED"` + FailureThreshold int `yaml:"failure_threshold" envDefault:"5" env:"ENTITY_CACHING_L2_CIRCUIT_BREAKER_FAILURE_THRESHOLD"` + CooldownPeriod time.Duration `yaml:"cooldown_period" envDefault:"10s" env:"ENTITY_CACHING_L2_CIRCUIT_BREAKER_COOLDOWN_PERIOD"` +} + +type EntityCachingSubgraphCacheOverride struct { + Name string `yaml:"name"` + StorageProviderID string `yaml:"storage_provider_id,omitempty"` + Entities []EntityCachingEntityConfig `yaml:"entities,omitempty"` +} + +type EntityCachingEntityConfig struct { + Type string `yaml:"type"` + StorageProviderID string `yaml:"storage_provider_id,omitempty" envDefault:""` +} + type AccessLogsConfig struct { Enabled bool `yaml:"enabled" env:"ACCESS_LOGS_ENABLED" envDefault:"true"` Level string `yaml:"level" env:"ACCESS_LOGS_LEVEL" envDefault:"info"` @@ -1419,6 +1465,7 @@ type Config struct { SubgraphExtensionPropagation SubgraphExtensionPropagationConfiguration `yaml:"subgraph_extension_propagation" envPrefix:"SUBGRAPH_EXTENSION_PROPAGATION_"` StorageProviders StorageProviders `yaml:"storage_providers" envPrefix:"STORAGE_PROVIDER_"` + EntityCaching EntityCachingConfiguration `yaml:"entity_caching,omitempty"` ExecutionConfig ExecutionConfig `yaml:"execution_config"` SplitConfigPoller SplitConfigPollerRules `yaml:"split_config_poller" envPrefix:"SPLIT_CONFIG_POLLER_"` PersistedOperationsConfig PersistedOperationsConfig `yaml:"persisted_operations" envPrefix:"PERSISTED_OPERATIONS_"` @@ -1572,5 +1619,58 @@ func LoadConfig(configFilePaths []string) (*LoadResult, error) { cfg.Config.SubgraphErrorPropagation.AllowedExtensionFields = unique.SliceElements(append(cfg.Config.SubgraphErrorPropagation.AllowedExtensionFields, "code", "stacktrace")) } + if err := validateMemoryProviderUsage(&cfg.Config); err != nil { + return nil, err + } + return cfg, nil } + +// validateMemoryProviderUsage ensures memory storage providers are only used for entity caching. +// Memory providers are in-process caches (Ristretto) that don't support the object storage semantics +// required by persisted operations, execution config, APQ, MCP, and ConnectRPC. +func validateMemoryProviderUsage(cfg *Config) error { + memoryIDs := make(map[string]bool, len(cfg.StorageProviders.Memory)) + for _, m := range cfg.StorageProviders.Memory { + memoryIDs[m.ID] = true + } + if len(memoryIDs) == 0 { + return nil + } + + type providerRef struct { + id string + feature string + } + + var refs []providerRef + if id := cfg.PersistedOperationsConfig.Storage.ProviderID; id != "" { + refs = append(refs, providerRef{id, "persisted_operations.storage"}) + } + if id := cfg.AutomaticPersistedQueries.Storage.ProviderID; id != "" { + refs = append(refs, providerRef{id, "automatic_persisted_queries.storage"}) + } + if id := cfg.ExecutionConfig.Storage.ProviderID; id != "" { + refs = append(refs, providerRef{id, "execution_config.storage"}) + } + if id := cfg.ExecutionConfig.FallbackStorage.ProviderID; id != "" { + refs = append(refs, providerRef{id, "execution_config.fallback_storage"}) + } + if id := cfg.MCP.Storage.ProviderID; id != "" { + refs = append(refs, providerRef{id, "mcp.storage"}) + } + if id := cfg.ConnectRPC.Storage.ProviderID; id != "" { + refs = append(refs, providerRef{id, "connect_rpc.storage"}) + } + + var errs error + for _, ref := range refs { + if memoryIDs[ref.id] { + errs = errors.Join(errs, fmt.Errorf( + "memory storage provider %q cannot be used for %s: memory providers are only supported for entity caching (entity_caching.l2.storage or subgraph_cache_overrides)", + ref.id, ref.feature, + )) + } + } + return errs +} diff --git a/router/pkg/config/config.schema.json b/router/pkg/config/config.schema.json index 7b4ead7123..d6f87c6adc 100644 --- a/router/pkg/config/config.schema.json +++ b/router/pkg/config/config.schema.json @@ -135,6 +135,29 @@ } } } + }, + "memory": { + "type": "array", + "description": "In-process memory cache using Ristretto. Memory providers can only be used for entity caching (entity_caching.l2.storage or subgraph_cache_overrides). They cannot be used for persisted operations, execution config, APQ, MCP, or ConnectRPC storage. Useful for development, testing, or single-instance deployments.", + "items": { + "type": "object", + "required": [ + "id" + ], + "additionalProperties": false, + "properties": { + "id": { + "type": "string", + "description": "The provider ID. The provider ID is used to identify the provider in the configuration." + }, + "max_size": { + "type": "string", + "format": "bytes-string", + "description": "Maximum cache size. Supports human-readable byte strings (e.g., '100MB', '1GB'). Default: 100MB.", + "default": "100MB" + } + } + } } } }, @@ -311,6 +334,130 @@ } } }, + "entity_caching": { + "type": "object", + "additionalProperties": false, + "description": "Entity caching stores resolved entities in a multi-layer cache (L1 per-request, L2 cross-request) to avoid redundant subgraph fetches.", + "properties": { + "enabled": { + "type": "boolean", + "description": "Global enable/disable flag for entity caching. When false, neither L1 nor L2 caching is available.", + "default": false + }, + "global_cache_key_prefix": { + "type": "string", + "description": "Prefix prepended to all L2 cache keys. Can be used e.g. when the Redis instance is shared across multiple use cases." + }, + "l1": { + "type": "object", + "additionalProperties": false, + "description": "L1 is an in-memory per-request cache. It deduplicates entity fetches within a single request.", + "properties": { + "enabled": { + "type": "boolean", + "description": "Enable/disable L1 per-request in-memory cache.", + "default": true + } + } + }, + "l2": { + "type": "object", + "additionalProperties": false, + "description": "L2 is a cross-request cache shared across all requests. Supports Redis and in-memory (Ristretto) backends.", + "properties": { + "enabled": { + "type": "boolean", + "description": "Enable/disable L2 external cache.", + "default": true + }, + "storage": { + "type": "object", + "additionalProperties": false, + "description": "Storage backend configuration for L2 cache.", + "properties": { + "provider_id": { + "type": "string", + "description": "References a storage_providers.redis or storage_providers.memory entry by ID." + }, + "key_prefix": { + "type": "string", + "description": "Prefix for all entity cache keys in the storage backend.", + "default": "cosmo_entity_cache" + } + } + }, + "circuit_breaker": { + "type": "object", + "additionalProperties": false, + "description": "Circuit breaker for L2 cache operations. Protects against cascading latency when the cache backend is slow or unavailable.", + "properties": { + "enabled": { + "type": "boolean", + "description": "Enable/disable the L2 circuit breaker.", + "default": false + }, + "failure_threshold": { + "type": "integer", + "description": "Number of consecutive L2 operation failures that trips the breaker.", + "default": 5, + "minimum": 1 + }, + "cooldown_period": { + "type": "string", + "description": "How long the breaker stays open before allowing a probe request. Specified as a duration string (e.g., '10s', '1m').", + "default": "10s", + "duration": { + "minimum": "1s" + } + } + } + } + } + }, + "subgraph_cache_overrides": { + "type": "array", + "description": "Per-subgraph storage provider overrides. Resolution order: entity-level override > subgraph-level override > global default.", + "items": { + "type": "object", + "required": [ + "name" + ], + "additionalProperties": false, + "properties": { + "name": { + "type": "string", + "description": "Subgraph name (must match a subgraph in the router config)." + }, + "storage_provider_id": { + "type": "string", + "description": "Storage provider for all entities in this subgraph (unless overridden per-entity). References a storage_providers.redis or storage_providers.memory entry by ID." + }, + "entities": { + "type": "array", + "description": "Per-entity storage provider overrides within this subgraph.", + "items": { + "type": "object", + "required": [ + "type" + ], + "additionalProperties": false, + "properties": { + "type": { + "type": "string", + "description": "Entity type name (must be a type with @entityCache in this subgraph)." + }, + "storage_provider_id": { + "type": "string", + "description": "Storage provider for this specific entity type. Overrides the subgraph-level storage_provider_id." + } + } + } + } + } + } + } + } + }, "execution_config": { "type": "object", "description": "The configuration for the execution config. You can load the execution config from the local file system or from a storage provider.", diff --git a/router/pkg/config/config_test.go b/router/pkg/config/config_test.go index 00cb69de18..0107a8a11e 100644 --- a/router/pkg/config/config_test.go +++ b/router/pkg/config/config_test.go @@ -2131,6 +2131,218 @@ security: }) } +func TestMemoryProviderOnlyForEntityCaching(t *testing.T) { + t.Parallel() + + t.Run("memory provider allowed for entity caching", func(t *testing.T) { + t.Parallel() + f := createTempFileFromFixture(t, ` +version: "1" + +storage_providers: + memory: + - id: "in-memory" + max_size: "100MB" + +entity_caching: + enabled: true + l2: + storage: + provider_id: "in-memory" +`) + _, err := LoadConfig([]string{f}) + require.NoError(t, err) + }) + + t.Run("memory provider max_size rejects invalid bytes string", func(t *testing.T) { + t.Parallel() + f := createTempFileFromFixture(t, ` +version: "1" + +storage_providers: + memory: + - id: "in-memory" + max_size: "not-a-byte-string" + +entity_caching: + enabled: true + l2: + storage: + provider_id: "in-memory" +`) + _, err := LoadConfig([]string{f}) + // Invalid bytes strings are caught by the BytesString YAML unmarshaler + // before json-schema validation runs, so the user-facing error surfaces + // as a parse error rather than a schema error. Either shape proves the + // value is rejected; assert only that the error path mentions the parse + // failure. + require.Error(t, err) + require.Contains(t, err.Error(), "bytes string") + }) + + t.Run("config schema annotates memory max_size as bytes-string", func(t *testing.T) { + t.Parallel() + // The JSON schema itself does not enforce "bytes-string" (not a standard + // format), but the annotation is documented and surfaces in tooling that + // generates docs/IDE completions. Guard against accidental removal. + var schemaMap map[string]any + require.NoError(t, yaml.Unmarshal(JSONSchema, &schemaMap)) + topProps := schemaMap["properties"].(map[string]any) + storage := topProps["storage_providers"].(map[string]any) + storageProps := storage["properties"].(map[string]any) + memory := storageProps["memory"].(map[string]any) + items := memory["items"].(map[string]any) + itemProps := items["properties"].(map[string]any) + maxSize := itemProps["max_size"].(map[string]any) + require.Equal(t, "bytes-string", maxSize["format"]) + }) + + t.Run("memory provider rejected for persisted_operations", func(t *testing.T) { + t.Parallel() + f := createTempFileFromFixture(t, ` +version: "1" + +storage_providers: + memory: + - id: "in-memory" + max_size: "100MB" + +persisted_operations: + storage: + provider_id: "in-memory" + object_prefix: "ops" +`) + _, err := LoadConfig([]string{f}) + require.EqualError(t, err, `memory storage provider "in-memory" cannot be used for persisted_operations.storage: memory providers are only supported for entity caching (entity_caching.l2.storage or subgraph_cache_overrides)`) + }) + + t.Run("memory provider rejected for automatic_persisted_queries", func(t *testing.T) { + t.Parallel() + f := createTempFileFromFixture(t, ` +version: "1" + +storage_providers: + memory: + - id: "in-memory" + max_size: "100MB" + +automatic_persisted_queries: + enabled: true + storage: + provider_id: "in-memory" + object_prefix: "apq" +`) + _, err := LoadConfig([]string{f}) + require.EqualError(t, err, `memory storage provider "in-memory" cannot be used for automatic_persisted_queries.storage: memory providers are only supported for entity caching (entity_caching.l2.storage or subgraph_cache_overrides)`) + }) + + t.Run("memory provider rejected for execution_config storage", func(t *testing.T) { + t.Parallel() + f := createTempFileFromFixture(t, ` +version: "1" + +storage_providers: + memory: + - id: "in-memory" + max_size: "100MB" + +execution_config: + storage: + provider_id: "in-memory" + object_path: "/config.json" +`) + _, err := LoadConfig([]string{f}) + require.EqualError(t, err, `memory storage provider "in-memory" cannot be used for execution_config.storage: memory providers are only supported for entity caching (entity_caching.l2.storage or subgraph_cache_overrides)`) + }) + + t.Run("memory provider rejected for connect_rpc storage", func(t *testing.T) { + t.Parallel() + f := createTempFileFromFixture(t, ` +version: "1" + +storage_providers: + memory: + - id: "in-memory" + max_size: "100MB" + +connect_rpc: + enabled: true + storage: + provider_id: "in-memory" + graphql_endpoint: "http://localhost:3002/graphql" +`) + _, err := LoadConfig([]string{f}) + require.EqualError(t, err, `memory storage provider "in-memory" cannot be used for connect_rpc.storage: memory providers are only supported for entity caching (entity_caching.l2.storage or subgraph_cache_overrides)`) + }) + + t.Run("memory provider rejected for mcp storage", func(t *testing.T) { + t.Parallel() + f := createTempFileFromFixture(t, ` +version: "1" + +storage_providers: + memory: + - id: "in-memory" + max_size: "100MB" + +mcp: + enabled: true + storage: + provider_id: "in-memory" +`) + _, err := LoadConfig([]string{f}) + require.EqualError(t, err, `memory storage provider "in-memory" cannot be used for mcp.storage: memory providers are only supported for entity caching (entity_caching.l2.storage or subgraph_cache_overrides)`) + }) + + t.Run("non-memory provider allowed everywhere", func(t *testing.T) { + t.Parallel() + f := createTempFileFromFixture(t, ` +version: "1" + +storage_providers: + memory: + - id: "in-memory" + max_size: "100MB" + redis: + - id: "my-redis" + urls: + - "redis://localhost:6379" + +persisted_operations: + storage: + provider_id: "my-redis" + object_prefix: "ops" +`) + _, err := LoadConfig([]string{f}) + require.NoError(t, err) + }) + + t.Run("multiple violations reported together", func(t *testing.T) { + t.Parallel() + f := createTempFileFromFixture(t, ` +version: "1" + +storage_providers: + memory: + - id: "in-memory" + max_size: "100MB" + +persisted_operations: + storage: + provider_id: "in-memory" + object_prefix: "ops" + +automatic_persisted_queries: + enabled: true + storage: + provider_id: "in-memory" + object_prefix: "apq" +`) + _, err := LoadConfig([]string{f}) + require.EqualError(t, err, `memory storage provider "in-memory" cannot be used for persisted_operations.storage: memory providers are only supported for entity caching (entity_caching.l2.storage or subgraph_cache_overrides)`+"\n"+`memory storage provider "in-memory" cannot be used for automatic_persisted_queries.storage: memory providers are only supported for entity caching (entity_caching.l2.storage or subgraph_cache_overrides)`) + }) +} + func TestPQLManifestConfig(t *testing.T) { t.Run("defaults", func(t *testing.T) { t.Parallel() diff --git a/router/pkg/config/testdata/config_defaults.json b/router/pkg/config/testdata/config_defaults.json index 3475e2cc11..c8454d01f6 100644 --- a/router/pkg/config/testdata/config_defaults.json +++ b/router/pkg/config/testdata/config_defaults.json @@ -549,8 +549,29 @@ "S3": null, "CDN": null, "Redis": null, + "Memory": null, "FileSystem": null }, + "EntityCaching": { + "Enabled": false, + "GlobalCacheKeyPrefix": "", + "L1": { + "Enabled": true + }, + "L2": { + "Enabled": true, + "Storage": { + "ProviderID": "", + "KeyPrefix": "cosmo_entity_cache" + }, + "CircuitBreaker": { + "Enabled": false, + "FailureThreshold": 5, + "CooldownPeriod": 10000000000 + } + }, + "SubgraphCacheOverrides": null + }, "ExecutionConfig": { "File": { "Path": "", diff --git a/router/pkg/config/testdata/config_full.json b/router/pkg/config/testdata/config_full.json index 3a3849cdfb..0c057d6f02 100644 --- a/router/pkg/config/testdata/config_full.json +++ b/router/pkg/config/testdata/config_full.json @@ -1023,6 +1023,7 @@ "ClusterEnabled": false } ], + "Memory": null, "FileSystem": [ { "ID": "mcp", @@ -1030,6 +1031,26 @@ } ] }, + "EntityCaching": { + "Enabled": false, + "GlobalCacheKeyPrefix": "", + "L1": { + "Enabled": true + }, + "L2": { + "Enabled": true, + "Storage": { + "ProviderID": "", + "KeyPrefix": "cosmo_entity_cache" + }, + "CircuitBreaker": { + "Enabled": false, + "FailureThreshold": 5, + "CooldownPeriod": 10000000000 + } + }, + "SubgraphCacheOverrides": null + }, "ExecutionConfig": { "File": { "Path": "", diff --git a/router/pkg/entitycache/circuit_breaker.go b/router/pkg/entitycache/circuit_breaker.go new file mode 100644 index 0000000000..9203b13fd2 --- /dev/null +++ b/router/pkg/entitycache/circuit_breaker.go @@ -0,0 +1,162 @@ +package entitycache + +import ( + "context" + "io" + "sync/atomic" + "time" + + ristretto "github.com/dgraph-io/ristretto/v2" + "github.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve" +) + +var _ resolve.LoaderCache = (*CircuitBreakerCache)(nil) +var _ io.Closer = (*CircuitBreakerCache)(nil) + +const ( + stateClosed int32 = 0 + stateOpen int32 = 1 + stateHalfOpen int32 = 2 +) + +// CircuitBreakerConfig holds the configuration for a cache circuit breaker. +type CircuitBreakerConfig struct { + Enabled bool + FailureThreshold int + CooldownPeriod time.Duration +} + +// CircuitBreakerCache wraps a LoaderCache with circuit breaker protection. +// When the underlying cache fails repeatedly (FailureThreshold consecutive failures), +// the breaker opens and all cache operations return nil/no-op, falling back to subgraph fetches. +// After CooldownPeriod, one probe request is allowed through (half-open state). +type CircuitBreakerCache struct { + cache resolve.LoaderCache + failureThreshold int32 + cooldownPeriod time.Duration + + state atomic.Int32 + consecutiveFails atomic.Int32 + lastStateChange atomic.Int64 // unix nanos +} + +// NewCircuitBreakerCache wraps the given cache with circuit breaker logic. +func NewCircuitBreakerCache(cache resolve.LoaderCache, cfg CircuitBreakerConfig) *CircuitBreakerCache { + cb := &CircuitBreakerCache{ + cache: cache, + failureThreshold: int32(cfg.FailureThreshold), + cooldownPeriod: cfg.CooldownPeriod, + } + cb.lastStateChange.Store(time.Now().UnixNano()) + return cb +} + +// IsOpen returns true if the circuit breaker is in the open state. +func (cb *CircuitBreakerCache) IsOpen() bool { + return cb.state.Load() == stateOpen +} + +func (cb *CircuitBreakerCache) Get(ctx context.Context, keys []string) ([]*resolve.CacheEntry, error) { + if !cb.allowRequest() { + return make([]*resolve.CacheEntry, len(keys)), nil + } + entries, err := cb.cache.Get(ctx, keys) + cb.recordResult(err) + if err != nil { + return make([]*resolve.CacheEntry, len(keys)), nil + } + return entries, nil +} + +func (cb *CircuitBreakerCache) Set(ctx context.Context, entries []*resolve.CacheEntry) error { + if !cb.allowRequest() { + return nil + } + err := cb.cache.Set(ctx, entries) + cb.recordResult(err) + return nil +} + +func (cb *CircuitBreakerCache) Delete(ctx context.Context, keys []string) error { + if !cb.allowRequest() { + return nil + } + err := cb.cache.Delete(ctx, keys) + cb.recordResult(err) + return nil +} + +func (cb *CircuitBreakerCache) allowRequest() bool { + switch cb.state.Load() { + case stateClosed: + return true + case stateOpen: + if time.Since(time.Unix(0, cb.lastStateChange.Load())) >= cb.cooldownPeriod { + // Transition to half-open: allow one probe + if cb.state.CompareAndSwap(stateOpen, stateHalfOpen) { + cb.lastStateChange.Store(time.Now().UnixNano()) + return true + } + } + return false + case stateHalfOpen: + // Only one probe at a time; additional requests are rejected + return false + } + return true +} + +func (cb *CircuitBreakerCache) recordResult(err error) { + if err == nil { + cb.onSuccess() + } else { + cb.onFailure() + } +} + +func (cb *CircuitBreakerCache) onSuccess() { + cb.consecutiveFails.Store(0) + state := cb.state.Load() + if state == stateHalfOpen { + cb.state.Store(stateClosed) + cb.lastStateChange.Store(time.Now().UnixNano()) + } +} + +func (cb *CircuitBreakerCache) onFailure() { + fails := cb.consecutiveFails.Add(1) + state := cb.state.Load() + if state == stateHalfOpen { + cb.state.Store(stateOpen) + cb.lastStateChange.Store(time.Now().UnixNano()) + return + } + if state == stateClosed && fails >= cb.failureThreshold { + cb.state.Store(stateOpen) + cb.lastStateChange.Store(time.Now().UnixNano()) + cb.consecutiveFails.Store(0) + } +} + +func (cb *CircuitBreakerCache) Close() error { + if closer, ok := cb.cache.(io.Closer); ok { + return closer.Close() + } + return nil +} + +func (cb *CircuitBreakerCache) Metrics() *ristretto.Metrics { + provider, ok := cb.cache.(interface{ Metrics() *ristretto.Metrics }) + if !ok { + return nil + } + return provider.Metrics() +} + +func (cb *CircuitBreakerCache) MaxSizeBytes() int64 { + provider, ok := cb.cache.(interface{ MaxSizeBytes() int64 }) + if !ok { + return 0 + } + return provider.MaxSizeBytes() +} diff --git a/router/pkg/entitycache/circuit_breaker_test.go b/router/pkg/entitycache/circuit_breaker_test.go new file mode 100644 index 0000000000..d471f8eb16 --- /dev/null +++ b/router/pkg/entitycache/circuit_breaker_test.go @@ -0,0 +1,373 @@ +package entitycache + +import ( + "context" + "errors" + "sync" + "sync/atomic" + "testing" + "time" + + "github.com/alicebob/miniredis/v2" + "github.com/redis/go-redis/v9" + "github.com/stretchr/testify/require" + "github.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve" +) + +var errFakeCache = errors.New("cache unavailable") + +// fakeCache is a test double that can be configured to fail. +type fakeCache struct { + shouldFail atomic.Bool + getCalls atomic.Int32 + setCalls atomic.Int32 + delCalls atomic.Int32 +} + +func (f *fakeCache) Get(_ context.Context, keys []string) ([]*resolve.CacheEntry, error) { + f.getCalls.Add(1) + if f.shouldFail.Load() { + return nil, errFakeCache + } + return make([]*resolve.CacheEntry, len(keys)), nil +} + +func (f *fakeCache) Set(_ context.Context, _ []*resolve.CacheEntry) error { + f.setCalls.Add(1) + if f.shouldFail.Load() { + return errFakeCache + } + return nil +} + +func (f *fakeCache) Delete(_ context.Context, _ []string) error { + f.delCalls.Add(1) + if f.shouldFail.Load() { + return errFakeCache + } + return nil +} + +func newTestBreaker(inner *fakeCache, threshold int, cooldown time.Duration) *CircuitBreakerCache { + return NewCircuitBreakerCache(inner, CircuitBreakerConfig{ + Enabled: true, + FailureThreshold: threshold, + CooldownPeriod: cooldown, + }) +} + +func TestCircuitBreakerCache_ClosedState_PassThrough(t *testing.T) { + inner := &fakeCache{} + cb := newTestBreaker(inner, 5, time.Minute) + + entries, err := cb.Get(context.Background(), []string{"a", "b"}) + require.NoError(t, err) + require.Len(t, entries, 2) + require.Equal(t, int32(1), inner.getCalls.Load()) + + err = cb.Set(context.Background(), []*resolve.CacheEntry{{Key: "a", Value: []byte("v"), TTL: time.Second}}) + require.NoError(t, err) + require.Equal(t, int32(1), inner.setCalls.Load()) + + err = cb.Delete(context.Background(), []string{"a"}) + require.NoError(t, err) + require.Equal(t, int32(1), inner.delCalls.Load()) + + require.False(t, cb.IsOpen()) +} + +func TestCircuitBreakerCache_OpensAfterThreshold(t *testing.T) { + inner := &fakeCache{} + inner.shouldFail.Store(true) + cb := newTestBreaker(inner, 3, time.Minute) + + ctx := context.Background() + + // 3 consecutive failures should trip the breaker + for range 3 { + _, _ = cb.Get(ctx, []string{"a"}) + } + require.True(t, cb.IsOpen()) + + // Subsequent calls should not reach the inner cache + callsBefore := inner.getCalls.Load() + entries, err := cb.Get(ctx, []string{"a"}) + require.NoError(t, err) + require.Len(t, entries, 1) + require.Nil(t, entries[0]) + require.Equal(t, callsBefore, inner.getCalls.Load()) +} + +func TestCircuitBreakerCache_SetDeleteSkippedWhenOpen(t *testing.T) { + inner := &fakeCache{} + inner.shouldFail.Store(true) + cb := newTestBreaker(inner, 2, time.Minute) + + ctx := context.Background() + + // Trip the breaker + for range 2 { + _, _ = cb.Get(ctx, []string{"a"}) + } + require.True(t, cb.IsOpen()) + + setBefore := inner.setCalls.Load() + delBefore := inner.delCalls.Load() + + err := cb.Set(ctx, []*resolve.CacheEntry{{Key: "a", TTL: time.Second}}) + require.NoError(t, err) + require.Equal(t, setBefore, inner.setCalls.Load()) + + err = cb.Delete(ctx, []string{"a"}) + require.NoError(t, err) + require.Equal(t, delBefore, inner.delCalls.Load()) +} + +func TestCircuitBreakerCache_HalfOpenProbeSuccess(t *testing.T) { + inner := &fakeCache{} + inner.shouldFail.Store(true) + cb := newTestBreaker(inner, 2, 10*time.Millisecond) + + ctx := context.Background() + + // Trip the breaker + for range 2 { + _, _ = cb.Get(ctx, []string{"a"}) + } + require.True(t, cb.IsOpen()) + + // Wait for cooldown + time.Sleep(15 * time.Millisecond) + + // Fix the cache + inner.shouldFail.Store(false) + + // Probe request should go through and close the breaker + _, err := cb.Get(ctx, []string{"a"}) + require.NoError(t, err) + require.False(t, cb.IsOpen()) + + // Normal operations should work again + _, err = cb.Get(ctx, []string{"b"}) + require.NoError(t, err) +} + +func TestCircuitBreakerCache_HalfOpenProbeFailure(t *testing.T) { + inner := &fakeCache{} + inner.shouldFail.Store(true) + cb := newTestBreaker(inner, 2, 10*time.Millisecond) + + ctx := context.Background() + + // Trip the breaker + for range 2 { + _, _ = cb.Get(ctx, []string{"a"}) + } + require.True(t, cb.IsOpen()) + + // Wait for cooldown + time.Sleep(15 * time.Millisecond) + + // Probe request fails — breaker stays open + _, err := cb.Get(ctx, []string{"a"}) + require.NoError(t, err) // Circuit breaker swallows the error + require.True(t, cb.IsOpen()) +} + +func TestCircuitBreakerCache_SuccessResetsFailureCount(t *testing.T) { + inner := &fakeCache{} + cb := newTestBreaker(inner, 3, time.Minute) + + ctx := context.Background() + + // 2 failures, then 1 success, then 2 more failures — should NOT trip + inner.shouldFail.Store(true) + _, _ = cb.Get(ctx, []string{"a"}) + _, _ = cb.Get(ctx, []string{"a"}) + + inner.shouldFail.Store(false) + _, _ = cb.Get(ctx, []string{"a"}) + + inner.shouldFail.Store(true) + _, _ = cb.Get(ctx, []string{"a"}) + _, _ = cb.Get(ctx, []string{"a"}) + + require.False(t, cb.IsOpen()) +} + +func TestCircuitBreakerCache_NeverErrorsToCallers(t *testing.T) { + inner := &fakeCache{} + inner.shouldFail.Store(true) + cb := newTestBreaker(inner, 100, time.Minute) + + ctx := context.Background() + + // Even when inner cache fails, circuit breaker never returns errors + entries, err := cb.Get(ctx, []string{"a"}) + require.NoError(t, err) + require.Len(t, entries, 1) + + err = cb.Set(ctx, []*resolve.CacheEntry{{Key: "a", TTL: time.Second}}) + require.NoError(t, err) + + err = cb.Delete(ctx, []string{"a"}) + require.NoError(t, err) +} + +func TestCircuitBreakerCache_Close_DelegatesToInner(t *testing.T) { + mr := miniredis.RunT(t) + client := redis.NewClient(&redis.Options{Addr: mr.Addr()}) + inner := NewRedisEntityCache(client, "test") + cb := newTestBreaker(&fakeCache{}, 3, time.Minute) + // Replace the inner cache with one that implements io.Closer + cb.cache = inner + + err := cb.Close() + require.NoError(t, err) + + // After closing, the inner Redis cache should be closed + _, err = inner.Get(context.Background(), []string{"key"}) + require.Error(t, err) +} + +func TestCircuitBreakerCache_Close_NoopWhenInnerNotCloser(t *testing.T) { + inner := &fakeCache{} + cb := newTestBreaker(inner, 3, time.Minute) + + err := cb.Close() + require.NoError(t, err) +} + +// TestCircuitBreakerCache_ConcurrentFailuresTripOnce verifies that under +// concurrent failure traffic the breaker opens, and that it only opens once +// (the state machine is safe under contention). Run with -race. +func TestCircuitBreakerCache_ConcurrentFailuresTripOnce(t *testing.T) { + t.Parallel() + + inner := &fakeCache{} + inner.shouldFail.Store(true) + const threshold = 5 + cb := newTestBreaker(inner, threshold, time.Minute) + + ctx := context.Background() + const goroutines = 16 + const callsPerGoroutine = 50 + + var wg sync.WaitGroup + for range goroutines { + wg.Add(1) + go func() { + defer wg.Done() + for range callsPerGoroutine { + _, _ = cb.Get(ctx, []string{"k"}) + } + }() + } + wg.Wait() + + // Breaker must have opened (many failures, all above threshold). + require.True(t, cb.IsOpen()) + + // Once open, most calls must have short-circuited and never touched inner. + // Because multiple goroutines can race past allowRequest before the first + // failing Set transitions state, some failures still hit inner after the + // breaker opens — but the total inner calls must be vastly less than the + // total surface of goroutines*callsPerGoroutine. + total := int32(goroutines * callsPerGoroutine) + require.Less(t, inner.getCalls.Load(), total, + "breaker should short-circuit after opening, not let all calls through") +} + +// TestCircuitBreakerCache_ConcurrentHalfOpenProbeCloses verifies that when +// the breaker is half-open and many goroutines race, at least one probe +// reaches inner and the successful probe closes the breaker. The stricter +// "exactly one probe" invariant is not asserted here because once the probe +// succeeds and the breaker closes, subsequent goroutines also reach inner. +func TestCircuitBreakerCache_ConcurrentHalfOpenProbeCloses(t *testing.T) { + t.Parallel() + + inner := &fakeCache{} + inner.shouldFail.Store(true) + cb := newTestBreaker(inner, 2, 5*time.Millisecond) + + ctx := context.Background() + + // Trip the breaker. + for range 2 { + _, _ = cb.Get(ctx, []string{"k"}) + } + require.True(t, cb.IsOpen()) + + // Freeze the inner call count; block the inner cache from failing so the + // half-open probe can succeed. Wait past cooldown, then fire many goroutines + // concurrently. Exactly one of them is allowed to reach inner (the probe). + inner.shouldFail.Store(false) + time.Sleep(10 * time.Millisecond) + + callsBefore := inner.getCalls.Load() + + const goroutines = 32 + var wg sync.WaitGroup + for range goroutines { + wg.Add(1) + go func() { + defer wg.Done() + _, _ = cb.Get(ctx, []string{"k"}) + }() + } + wg.Wait() + + // After the first probe succeeds the breaker closes, so later-arriving + // calls will also reach inner. The strict invariant is that the very first + // transition from open→half-open admitted only one probe. We verify the + // state is now closed and that the probe path was exercised. + require.False(t, cb.IsOpen(), "successful probe must close the breaker") + require.Greater(t, inner.getCalls.Load(), callsBefore, + "at least the probe must have reached inner after cooldown") +} + +// TestCircuitBreakerCache_ConcurrentMixedSuccessFailure stresses the state +// machine with interleaved successes and failures across goroutines. The +// only invariant we assert is that the breaker never panics, the state field +// stays within the three known values, and Close is safe to call at the end. +func TestCircuitBreakerCache_ConcurrentMixedSuccessFailure(t *testing.T) { + t.Parallel() + + inner := &fakeCache{} + cb := newTestBreaker(inner, 10, time.Millisecond) + + ctx := context.Background() + const goroutines = 8 + + var wg sync.WaitGroup + // Goroutines that toggle inner's failure mode. + for i := range goroutines { + wg.Add(1) + go func(seed int) { + defer wg.Done() + for j := range 100 { + inner.shouldFail.Store((seed+j)%3 == 0) + } + }(i) + } + // Goroutines that hammer the breaker's public surface. + for range goroutines { + wg.Add(1) + go func() { + defer wg.Done() + for range 100 { + _, _ = cb.Get(ctx, []string{"x"}) + _ = cb.Set(ctx, []*resolve.CacheEntry{{Key: "x", Value: []byte("v"), TTL: time.Second}}) + _ = cb.Delete(ctx, []string{"x"}) + } + }() + } + wg.Wait() + + // Sanity: state must be one of the three defined values. + state := cb.state.Load() + require.True(t, state == stateClosed || state == stateOpen || state == stateHalfOpen, + "breaker state escaped the valid set: got %d", state) + + require.NoError(t, cb.Close()) +} diff --git a/router/pkg/entitycache/memory.go b/router/pkg/entitycache/memory.go new file mode 100644 index 0000000000..0499fa0c14 --- /dev/null +++ b/router/pkg/entitycache/memory.go @@ -0,0 +1,128 @@ +package entitycache + +import ( + "context" + "fmt" + "sync/atomic" + "time" + + ristretto "github.com/dgraph-io/ristretto/v2" + "github.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve" +) + +var _ resolve.LoaderCache = (*MemoryEntityCache)(nil) + +type MemoryEntityCache struct { + cache *ristretto.Cache[string, []byte] + len atomic.Int64 + maxSizeBytes int64 +} + +func NewMemoryEntityCache(maxSizeBytes int64) (*MemoryEntityCache, error) { + if maxSizeBytes <= 0 { + return nil, fmt.Errorf("maxSizeBytes must be positive, got %d", maxSizeBytes) + } + // NumCounters should be ~10x the expected number of items. + // Assuming an average entry size of ~1KB. + numCounters := max((maxSizeBytes/1024)*10, 1000) + m := &MemoryEntityCache{maxSizeBytes: maxSizeBytes} + cache, err := ristretto.NewCache(&ristretto.Config[string, []byte]{ + NumCounters: numCounters, + MaxCost: maxSizeBytes, + BufferItems: 64, + IgnoreInternalCost: true, + Metrics: true, + OnEvict: func(item *ristretto.Item[[]byte]) { + m.len.Add(-1) + }, + }) + if err != nil { + return nil, fmt.Errorf("creating ristretto cache: %w", err) + } + m.cache = cache + return m, nil +} + +func (c *MemoryEntityCache) Get(_ context.Context, keys []string) ([]*resolve.CacheEntry, error) { + if len(keys) == 0 { + return nil, nil + } + entries := make([]*resolve.CacheEntry, len(keys)) + for i, k := range keys { + val, ok := c.cache.Get(k) + if !ok { + continue + } + var remainingTTL time.Duration + if ttl, found := c.cache.GetTTL(k); found && ttl > 0 { + remainingTTL = ttl + } + entries[i] = &resolve.CacheEntry{ + Key: k, + Value: val, + RemainingTTL: remainingTTL, + } + } + return entries, nil +} + +func (c *MemoryEntityCache) Set(_ context.Context, entries []*resolve.CacheEntry) error { + if len(entries) == 0 { + return nil + } + for _, entry := range entries { + if entry == nil { + continue + } + // Negative TTL means "no expiration" per the LoaderCache contract. + // Ristretto treats ttl<=0 as no expiration, so clamp negatives to 0. + ttl := entry.TTL + if ttl < 0 { + ttl = 0 + } + // Check if key already exists (update vs new entry) + _, exists := c.cache.Get(entry.Key) + if c.cache.SetWithTTL(entry.Key, entry.Value, int64(len(entry.Value)), ttl) && !exists { + c.len.Add(1) + } + } + c.cache.Wait() + return nil +} + +func (c *MemoryEntityCache) Delete(_ context.Context, keys []string) error { + if len(keys) == 0 { + return nil + } + for _, k := range keys { + if _, ok := c.cache.Get(k); ok { + c.cache.Del(k) + c.len.Add(-1) + } + } + return nil +} + +// Len returns the approximate number of items in the cache. +// This is intended for use in tests only. The count may drift +// under heavy concurrent access due to races between Get/Set/Delete +// and the asynchronous eviction callback. +// Ristretto metrics don't cover Delete, so we keep a manual counter. +func (c *MemoryEntityCache) Len() int { + return int(c.len.Load()) +} + +// Metrics returns the underlying ristretto metrics for exporter wiring. +// Exposes hits, misses, keys added/updated/evicted, cost added/evicted. +func (c *MemoryEntityCache) Metrics() *ristretto.Metrics { + return c.cache.Metrics +} + +func (c *MemoryEntityCache) MaxSizeBytes() int64 { + return c.maxSizeBytes +} + +func (c *MemoryEntityCache) Close() error { + c.cache.Close() + return nil +} diff --git a/router/pkg/entitycache/memory_test.go b/router/pkg/entitycache/memory_test.go new file mode 100644 index 0000000000..059fe98262 --- /dev/null +++ b/router/pkg/entitycache/memory_test.go @@ -0,0 +1,274 @@ +package entitycache + +import ( + "context" + "sync" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve" +) + +const testCacheSize = 10 * 1024 * 1024 // 10MB + +func newTestCache(t *testing.T) *MemoryEntityCache { + t.Helper() + c, err := NewMemoryEntityCache(testCacheSize) + require.NoError(t, err) + t.Cleanup(func() { _ = c.Close() }) + return c +} + +func TestMemoryEntityCache_GetMiss(t *testing.T) { + c := newTestCache(t) + entries, err := c.Get(context.Background(), []string{"key1", "key2"}) + require.NoError(t, err) + require.Len(t, entries, 2) + assert.Nil(t, entries[0]) + assert.Nil(t, entries[1]) +} + +func TestMemoryEntityCache_SetThenGet(t *testing.T) { + c := newTestCache(t) + ctx := context.Background() + err := c.Set(ctx, []*resolve.CacheEntry{ + {Key: "k1", Value: []byte("v1"), TTL: 5 * time.Second}, + {Key: "k2", Value: []byte("v2"), TTL: 5 * time.Second}, + }) + require.NoError(t, err) + + entries, err := c.Get(ctx, []string{"k1", "k2"}) + require.NoError(t, err) + require.Len(t, entries, 2) + assert.Equal(t, []byte("v1"), entries[0].Value) + assert.Equal(t, []byte("v2"), entries[1].Value) +} + +func TestMemoryEntityCache_PartialHit(t *testing.T) { + c := newTestCache(t) + ctx := context.Background() + require.NoError(t, c.Set(ctx, []*resolve.CacheEntry{ + {Key: "k1", Value: []byte("v1"), TTL: 5 * time.Second}, + })) + + entries, err := c.Get(ctx, []string{"k1", "k2"}) + require.NoError(t, err) + require.Len(t, entries, 2) + assert.NotNil(t, entries[0]) + assert.Nil(t, entries[1]) +} + +func TestMemoryEntityCache_Delete(t *testing.T) { + c := newTestCache(t) + ctx := context.Background() + require.NoError(t, c.Set(ctx, []*resolve.CacheEntry{ + {Key: "k1", Value: []byte("v1"), TTL: 5 * time.Second}, + })) + + require.NoError(t, c.Delete(ctx, []string{"k1"})) + + entries, err := c.Get(ctx, []string{"k1"}) + require.NoError(t, err) + assert.Nil(t, entries[0]) +} + +func TestMemoryEntityCache_DeleteNonexistent(t *testing.T) { + c := newTestCache(t) + err := c.Delete(context.Background(), []string{"nonexistent"}) + require.NoError(t, err) +} + +func TestMemoryEntityCache_TTLExpiry(t *testing.T) { + c := newTestCache(t) + ctx := context.Background() + require.NoError(t, c.Set(ctx, []*resolve.CacheEntry{ + {Key: "k1", Value: []byte("v1"), TTL: 50 * time.Millisecond}, + })) + + // Should be present immediately + entries, err := c.Get(ctx, []string{"k1"}) + require.NoError(t, err) + assert.NotNil(t, entries[0]) + + // Wait for expiry — ristretto's TTL cleanup ticker runs periodically + require.Eventually(t, func() bool { + entries, err = c.Get(ctx, []string{"k1"}) + return err == nil && entries[0] == nil + }, 2*time.Second, 50*time.Millisecond) +} + +func TestMemoryEntityCache_Overwrite(t *testing.T) { + c := newTestCache(t) + ctx := context.Background() + require.NoError(t, c.Set(ctx, []*resolve.CacheEntry{ + {Key: "k1", Value: []byte("v1"), TTL: 5 * time.Second}, + })) + require.NoError(t, c.Set(ctx, []*resolve.CacheEntry{ + {Key: "k1", Value: []byte("v2"), TTL: 5 * time.Second}, + })) + + entries, err := c.Get(ctx, []string{"k1"}) + require.NoError(t, err) + assert.Equal(t, []byte("v2"), entries[0].Value) +} + +func TestMemoryEntityCache_EmptyBatch(t *testing.T) { + c := newTestCache(t) + ctx := context.Background() + + entries, err := c.Get(ctx, nil) + require.NoError(t, err) + assert.Nil(t, entries) + + require.NoError(t, c.Set(ctx, nil)) + require.NoError(t, c.Delete(ctx, nil)) +} + +func TestMemoryEntityCache_NilEntriesInSet(t *testing.T) { + c := newTestCache(t) + err := c.Set(context.Background(), []*resolve.CacheEntry{ + nil, + {Key: "k1", Value: []byte("v1"), TTL: 5 * time.Second}, + nil, + }) + require.NoError(t, err) + + entries, err := c.Get(context.Background(), []string{"k1"}) + require.NoError(t, err) + assert.NotNil(t, entries[0]) +} + +func TestMemoryEntityCache_ConcurrentAccess(t *testing.T) { + c := newTestCache(t) + ctx := context.Background() + var wg sync.WaitGroup + + var firstErrOnce sync.Once + var firstErr error + recordErr := func(err error) { + if err == nil { + return + } + firstErrOnce.Do(func() { firstErr = err }) + } + + for i := range 10 { + wg.Add(1) + go func(n int) { + defer wg.Done() + key := "key" + string(rune('0'+n)) + recordErr(c.Set(ctx, []*resolve.CacheEntry{ + {Key: key, Value: []byte("val"), TTL: 5 * time.Second}, + })) + _, err := c.Get(ctx, []string{key}) + recordErr(err) + recordErr(c.Delete(ctx, []string{key})) + }(i) + } + wg.Wait() + require.NoError(t, firstErr) +} + +func TestMemoryEntityCache_NoExpiryWithZeroTTL(t *testing.T) { + c := newTestCache(t) + ctx := context.Background() + require.NoError(t, c.Set(ctx, []*resolve.CacheEntry{ + {Key: "k1", Value: []byte("v1")}, + })) + + // Should still be present (no expiry) + time.Sleep(10 * time.Millisecond) + entries, err := c.Get(ctx, []string{"k1"}) + require.NoError(t, err) + assert.NotNil(t, entries[0]) +} + +func TestMemoryEntityCache_RemainingTTL(t *testing.T) { + c := newTestCache(t) + ctx := context.Background() + require.NoError(t, c.Set(ctx, []*resolve.CacheEntry{ + {Key: "k1", Value: []byte("v1"), TTL: 5 * time.Second}, + })) + + entries, err := c.Get(ctx, []string{"k1"}) + require.NoError(t, err) + require.NotNil(t, entries[0]) + assert.True(t, entries[0].RemainingTTL > 0) + assert.True(t, entries[0].RemainingTTL <= 5*time.Second) +} + +func TestMemoryEntityCache_InvalidMaxSize(t *testing.T) { + _, err := NewMemoryEntityCache(0) + require.Error(t, err) + + _, err = NewMemoryEntityCache(-1) + require.Error(t, err) +} + +func TestMemoryEntityCache_EvictsWhenFull(t *testing.T) { + // Create a tiny cache (1KB) + c, err := NewMemoryEntityCache(1024) + require.NoError(t, err) + t.Cleanup(func() { _ = c.Close() }) + + ctx := context.Background() + // Fill with entries larger than cache capacity + val := make([]byte, 512) + for i := range len(val) { + val[i] = byte(i % 256) + } + const totalKeys = 10 + for i := range totalKeys { + key := "key" + string(rune('A'+i)) + require.NoError(t, c.Set(ctx, []*resolve.CacheEntry{ + {Key: key, Value: val, TTL: 5 * time.Second}, + })) + } + + // Ristretto's admission policy and sampled counters make the exact number + // of survivors non-deterministic. With 1KB MaxCost and 512B entries the + // cache CANNOT hold all 10 entries, and in practice rarely holds the full + // theoretical 2. Assert the upper bound (eviction happened) and the lower + // bound (the cache isn't completely empty). Flush outstanding async work + // via cache.Wait() to stabilize before measuring. + c.cache.Wait() + + hitCount := 0 + for i := range totalKeys { + key := "key" + string(rune('A'+i)) + entries, err := c.Get(ctx, []string{key}) + require.NoError(t, err) + if entries[0] != nil { + hitCount++ + } + } + + // With 1KB max and 512B entries, at most ~2 can coexist. Admission may + // evict entries we just wrote before we read, so the lower bound is 0 — + // the only invariant we care about is that not ALL 10 survive. + assert.LessOrEqual(t, hitCount, 2, "cache must evict to stay within MaxCost") + assert.Less(t, hitCount, totalKeys, "cache must evict at least some entries") +} + +func TestMemoryEntityCache_Close(t *testing.T) { + c, err := NewMemoryEntityCache(testCacheSize) + require.NoError(t, err) + + ctx := context.Background() + require.NoError(t, c.Set(ctx, []*resolve.CacheEntry{ + {Key: "k1", Value: []byte("v1"), TTL: 5 * time.Second}, + })) + + c.Close() + + // After close, Get returns zero values without panicking. The post-close + // path may return nil entries or an empty slice; either is acceptable so + // long as the call doesn't panic and no entry is resurrected. + entries, err := c.Get(ctx, []string{"k1"}) + require.NoError(t, err) + if len(entries) > 0 { + assert.Nil(t, entries[0]) + } +} diff --git a/router/pkg/entitycache/redis.go b/router/pkg/entitycache/redis.go new file mode 100644 index 0000000000..89c0ee8690 --- /dev/null +++ b/router/pkg/entitycache/redis.go @@ -0,0 +1,86 @@ +package entitycache + +import ( + "context" + "io" + + "github.com/redis/go-redis/v9" + "github.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve" +) + +var _ resolve.LoaderCache = (*RedisEntityCache)(nil) +var _ io.Closer = (*RedisEntityCache)(nil) + +type RedisEntityCache struct { + client redis.UniversalClient + keyPrefix string +} + +func NewRedisEntityCache(client redis.UniversalClient, keyPrefix string) *RedisEntityCache { + return &RedisEntityCache{client: client, keyPrefix: keyPrefix} +} + +func (c *RedisEntityCache) Get(ctx context.Context, keys []string) ([]*resolve.CacheEntry, error) { + if len(keys) == 0 { + return nil, nil + } + prefixedKeys := make([]string, len(keys)) + for i, k := range keys { + prefixedKeys[i] = c.keyPrefix + ":" + k + } + vals, err := c.client.MGet(ctx, prefixedKeys...).Result() + if err != nil { + return nil, err + } + entries := make([]*resolve.CacheEntry, len(keys)) + for i, val := range vals { + if val == nil { + continue + } + str, ok := val.(string) + if !ok { + continue + } + entries[i] = &resolve.CacheEntry{ + Key: keys[i], + Value: []byte(str), + } + } + return entries, nil +} + +func (c *RedisEntityCache) Set(ctx context.Context, entries []*resolve.CacheEntry) error { + if len(entries) == 0 { + return nil + } + pipe := c.client.Pipeline() + for _, entry := range entries { + if entry == nil { + continue + } + // Per LoaderCache contract: TTL<=0 means no expiration; for go-redis + // passing 0 (redis.KeepTTL is -1) tells the server to omit EX/PX. + ttl := entry.TTL + if ttl < 0 { + ttl = 0 + } + pipe.Set(ctx, c.keyPrefix+":"+entry.Key, entry.Value, ttl) + } + _, err := pipe.Exec(ctx) + return err +} + +func (c *RedisEntityCache) Delete(ctx context.Context, keys []string) error { + if len(keys) == 0 { + return nil + } + prefixedKeys := make([]string, len(keys)) + for i, k := range keys { + prefixedKeys[i] = c.keyPrefix + ":" + k + } + return c.client.Del(ctx, prefixedKeys...).Err() +} + +func (c *RedisEntityCache) Close() error { + return c.client.Close() +} diff --git a/router/pkg/entitycache/redis_test.go b/router/pkg/entitycache/redis_test.go new file mode 100644 index 0000000000..50f68792bf --- /dev/null +++ b/router/pkg/entitycache/redis_test.go @@ -0,0 +1,191 @@ +package entitycache + +import ( + "context" + "testing" + "time" + + "github.com/alicebob/miniredis/v2" + "github.com/redis/go-redis/v9" + "github.com/stretchr/testify/require" + "github.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve" +) + +func newTestRedisCache(t *testing.T, prefix string) (*RedisEntityCache, *miniredis.Miniredis) { + t.Helper() + mr := miniredis.RunT(t) + client := redis.NewClient(&redis.Options{Addr: mr.Addr()}) + t.Cleanup(func() { client.Close() }) + return NewRedisEntityCache(client, prefix), mr +} + +func TestRedisEntityCache_ConstructorStoresKeyPrefix(t *testing.T) { + t.Parallel() + cache, _ := newTestRedisCache(t, "test") + require.NotNil(t, cache) + require.Equal(t, "test", cache.keyPrefix) +} + +func TestRedisEntityCache_GetReturnsNilForMissingKey(t *testing.T) { + t.Parallel() + cache, _ := newTestRedisCache(t, "pfx") + ctx := context.Background() + + entries, err := cache.Get(ctx, []string{"nonexistent"}) + require.NoError(t, err) + require.Len(t, entries, 1) + require.Nil(t, entries[0]) +} + +func TestRedisEntityCache_GetReturnsValueForExistingKey(t *testing.T) { + t.Parallel() + cache, mr := newTestRedisCache(t, "pfx") + ctx := context.Background() + + // Pre-populate directly via miniredis + require.NoError(t, mr.Set("pfx:mykey", "myvalue")) + + entries, err := cache.Get(ctx, []string{"mykey"}) + require.NoError(t, err) + require.Len(t, entries, 1) + require.NotNil(t, entries[0]) + require.Equal(t, "mykey", entries[0].Key) + require.Equal(t, []byte("myvalue"), entries[0].Value) +} + +func TestRedisEntityCache_SetThenGetReturnsStoredValues(t *testing.T) { + t.Parallel() + cache, _ := newTestRedisCache(t, "pfx") + ctx := context.Background() + + err := cache.Set(ctx, []*resolve.CacheEntry{ + {Key: "k1", Value: []byte("v1"), TTL: time.Minute}, + {Key: "k2", Value: []byte("v2"), TTL: time.Minute}, + }) + require.NoError(t, err) + + entries, err := cache.Get(ctx, []string{"k1", "k2"}) + require.NoError(t, err) + require.Len(t, entries, 2) + require.Equal(t, []byte("v1"), entries[0].Value) + require.Equal(t, []byte("v2"), entries[1].Value) +} + +func TestRedisEntityCache_KeyExpiresAfterTTL(t *testing.T) { + t.Parallel() + cache, mr := newTestRedisCache(t, "pfx") + ctx := context.Background() + + err := cache.Set(ctx, []*resolve.CacheEntry{ + {Key: "ephemeral", Value: []byte("gone-soon"), TTL: 5 * time.Second}, + }) + require.NoError(t, err) + + // Key exists before expiry + entries, err := cache.Get(ctx, []string{"ephemeral"}) + require.NoError(t, err) + require.NotNil(t, entries[0]) + + // Fast-forward past TTL + mr.FastForward(6 * time.Second) + + entries, err = cache.Get(ctx, []string{"ephemeral"}) + require.NoError(t, err) + require.Nil(t, entries[0]) +} + +func TestRedisEntityCache_DeleteRemovesKey(t *testing.T) { + t.Parallel() + cache, _ := newTestRedisCache(t, "pfx") + ctx := context.Background() + + err := cache.Set(ctx, []*resolve.CacheEntry{ + {Key: "delme", Value: []byte("val"), TTL: time.Minute}, + }) + require.NoError(t, err) + + err = cache.Delete(ctx, []string{"delme"}) + require.NoError(t, err) + + entries, err := cache.Get(ctx, []string{"delme"}) + require.NoError(t, err) + require.Nil(t, entries[0]) +} + +func TestRedisEntityCache_KeyPrefixAppliedToStoredKey(t *testing.T) { + t.Parallel() + cache, mr := newTestRedisCache(t, "myprefix") + ctx := context.Background() + + err := cache.Set(ctx, []*resolve.CacheEntry{ + {Key: "item", Value: []byte("data"), TTL: time.Minute}, + }) + require.NoError(t, err) + + // The key in Redis should be prefixed + require.True(t, mr.Exists("myprefix:item")) + + // The raw key without prefix should not exist + require.False(t, mr.Exists("item")) +} + +func TestRedisEntityCache_GetWithEmptyKeysReturnsNil(t *testing.T) { + t.Parallel() + cache, _ := newTestRedisCache(t, "pfx") + ctx := context.Background() + + entries, err := cache.Get(ctx, []string{}) + require.NoError(t, err) + require.Nil(t, entries) +} + +func TestRedisEntityCache_SetWithEmptyEntriesIsNoop(t *testing.T) { + t.Parallel() + cache, _ := newTestRedisCache(t, "pfx") + ctx := context.Background() + + err := cache.Set(ctx, []*resolve.CacheEntry{}) + require.NoError(t, err) +} + +func TestRedisEntityCache_DeleteWithEmptyKeysIsNoop(t *testing.T) { + t.Parallel() + cache, _ := newTestRedisCache(t, "pfx") + ctx := context.Background() + + err := cache.Delete(ctx, []string{}) + require.NoError(t, err) +} + +func TestRedisEntityCache_GetAfterCloseReturnsError(t *testing.T) { + t.Parallel() + mr := miniredis.RunT(t) + client := redis.NewClient(&redis.Options{Addr: mr.Addr()}) + cache := NewRedisEntityCache(client, "test") + + err := cache.Close() + require.NoError(t, err) + + // After closing, operations should fail + _, err = cache.Get(context.Background(), []string{"key"}) + require.Error(t, err) +} + +// TestRedisEntityCache_SetAndDeleteAfterCloseReturnError verifies the same +// post-close semantics for the mutating operations: Set and Delete must also +// surface an error instead of silently succeeding against a closed client. +func TestRedisEntityCache_SetAndDeleteAfterCloseReturnError(t *testing.T) { + t.Parallel() + mr := miniredis.RunT(t) + client := redis.NewClient(&redis.Options{Addr: mr.Addr()}) + cache := NewRedisEntityCache(client, "test") + + require.NoError(t, cache.Close()) + + err := cache.Set(context.Background(), + []*resolve.CacheEntry{{Key: "k", Value: []byte("v"), TTL: time.Minute}}) + require.Error(t, err, "Set on closed client must return error") + + err = cache.Delete(context.Background(), []string{"k"}) + require.Error(t, err, "Delete on closed client must return error") +} diff --git a/router/pkg/graphqlschemausage/schemausage_bench_test.go b/router/pkg/graphqlschemausage/schemausage_bench_test.go index 1acca645dc..639fc50240 100644 --- a/router/pkg/graphqlschemausage/schemausage_bench_test.go +++ b/router/pkg/graphqlschemausage/schemausage_bench_test.go @@ -98,7 +98,7 @@ func setupBenchmark(b *testing.B) (plan.Plan, *ast.Document, *ast.Document, *ast inputVariables, err := astjson.ParseBytes(op.Input.Variables) require.NoError(b, err) - merged, _, err := astjson.MergeValues(nil, vars, inputVariables) + merged, err := astjson.MergeValues(nil, vars, inputVariables) require.NoError(b, err) return generatedPlan, &op, &def, merged diff --git a/router/pkg/graphqlschemausage/schemausage_test.go b/router/pkg/graphqlschemausage/schemausage_test.go index cb93fbfbe8..88fea46bbd 100644 --- a/router/pkg/graphqlschemausage/schemausage_test.go +++ b/router/pkg/graphqlschemausage/schemausage_test.go @@ -208,7 +208,7 @@ func TestGetSchemaUsageInfo(t *testing.T) { inputVariables, err := astjson.ParseBytes(op.Input.Variables) assert.NoError(t, err) - merged, _, err := astjson.MergeValues(arena.NewMonotonicArena(), vars, inputVariables) + merged, err := astjson.MergeValues(arena.NewMonotonicArena(), vars, inputVariables) assert.NoError(t, err) fieldUsageInfo := GetTypeFieldUsageInfo(generatedPlan) From 3b98867ff8b81f37d7310b7d44c894c894ec4019 Mon Sep 17 00:00:00 2001 From: Milinda Dias Date: Mon, 22 Jun 2026 23:17:16 +0530 Subject: [PATCH 4/7] fix(router): adapt entity-caching wiring to new proto format The queryCache-directive rework nests all entity-caching config under a single EntityCachingConfiguration on DataSourceConfiguration, and renames RootFieldCacheConfiguration -> QueryCacheConfiguration and RequestScopedFieldConfiguration -> RequestScopedConfiguration. Route the router config builder through DataSourceConfiguration.GetEntityCachingConfiguration() and its typed getters, and handle CachePopulateConfiguration.max_age_seconds now being a plain int64 (was optional *int64). --- router/core/executor.go | 2 +- router/core/factoryresolver.go | 22 +++++++++++----------- router/core/graph_server.go | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/router/core/executor.go b/router/core/executor.go index 5027517087..e2a78cba73 100644 --- a/router/core/executor.go +++ b/router/core/executor.go @@ -293,7 +293,7 @@ func buildEntityCacheInvalidationConfigs( } continue } - for _, ec := range ds.GetEntityCacheConfigurations() { + for _, ec := range ds.GetEntityCachingConfiguration().GetEntityCache() { if _, ok := result[subgraphName]; !ok { result[subgraphName] = make(map[string]*resolve.EntityCacheInvalidationConfig) } diff --git a/router/core/factoryresolver.go b/router/core/factoryresolver.go index b1545140c6..944ba941d7 100644 --- a/router/core/factoryresolver.go +++ b/router/core/factoryresolver.go @@ -674,7 +674,7 @@ func (l *Loader) dataSourceMetaData(in *nodev1.DataSourceConfiguration, subgraph } // Entity caching configurations - for _, ec := range in.EntityCacheConfigurations { + for _, ec := range in.GetEntityCachingConfiguration().GetEntityCache() { cacheName := resolveEntityCacheProviderID(l.entityCachingConfig, subgraphName, ec.TypeName) out.FederationMetaData.EntityCaching = append(out.FederationMetaData.EntityCaching, plan.EntityCacheConfiguration{ TypeName: ec.TypeName, @@ -688,7 +688,7 @@ func (l *Loader) dataSourceMetaData(in *nodev1.DataSourceConfiguration, subgraph } // Root field cache configurations - for _, rfc := range in.RootFieldCacheConfigurations { + for _, rfc := range in.GetEntityCachingConfiguration().GetQueryCacheConfigurations() { cacheName := resolveEntityCacheProviderID(l.entityCachingConfig, subgraphName, rfc.EntityTypeName) var mappings []plan.EntityKeyMapping for _, m := range rfc.EntityKeyMappings { @@ -718,10 +718,10 @@ func (l *Loader) dataSourceMetaData(in *nodev1.DataSourceConfiguration, subgraph } // Mutation/subscription cache populate - for _, cp := range in.CachePopulateConfigurations { + for _, cp := range in.GetEntityCachingConfiguration().GetCachePopulateConfigurations() { if cp.OperationType == protoOperationTypeSubscription { var targetEntity *nodev1.EntityCacheConfiguration - for _, ec := range in.EntityCacheConfigurations { + for _, ec := range in.GetEntityCachingConfiguration().GetEntityCache() { if ec.TypeName == cp.EntityTypeName { targetEntity = ec break @@ -731,8 +731,8 @@ func (l *Loader) dataSourceMetaData(in *nodev1.DataSourceConfiguration, subgraph continue } ttl := time.Duration(targetEntity.MaxAgeSeconds) * time.Second - if cp.MaxAgeSeconds != nil { - ttl = time.Duration(*cp.MaxAgeSeconds) * time.Second + if cp.MaxAgeSeconds != 0 { + ttl = time.Duration(cp.MaxAgeSeconds) * time.Second } cacheName := resolveEntityCacheProviderID(l.entityCachingConfig, subgraphName, targetEntity.TypeName) out.FederationMetaData.SubscriptionEntityPopulation = append( @@ -750,8 +750,8 @@ func (l *Loader) dataSourceMetaData(in *nodev1.DataSourceConfiguration, subgraph // mutation-time writes. Without this, the populate path falls back to the // cache implementation's default TTL. var mutationTTL time.Duration - if cp.MaxAgeSeconds != nil { - mutationTTL = time.Duration(*cp.MaxAgeSeconds) * time.Second + if cp.MaxAgeSeconds != 0 { + mutationTTL = time.Duration(cp.MaxAgeSeconds) * time.Second } out.FederationMetaData.MutationFieldCaching = append(out.FederationMetaData.MutationFieldCaching, plan.MutationFieldCacheConfiguration{ FieldName: cp.FieldName, @@ -762,11 +762,11 @@ func (l *Loader) dataSourceMetaData(in *nodev1.DataSourceConfiguration, subgraph } // Mutation/subscription cache invalidation - for _, ci := range in.CacheInvalidateConfigurations { + for _, ci := range in.GetEntityCachingConfiguration().GetCacheInvalidateConfigurations() { if ci.OperationType == protoOperationTypeSubscription { cacheName := resolveEntityCacheProviderID(l.entityCachingConfig, subgraphName, ci.EntityTypeName) var includeHeaders bool - for _, ec := range in.EntityCacheConfigurations { + for _, ec := range in.GetEntityCachingConfiguration().GetEntityCache() { if ec.TypeName == ci.EntityTypeName { includeHeaders = ec.IncludeHeaders break @@ -793,7 +793,7 @@ func (l *Loader) dataSourceMetaData(in *nodev1.DataSourceConfiguration, subgraph // Request-scoped field configurations. Every field annotated with @requestScoped // in the subgraph is both a potential reader and writer of the coordinate L1 under // its L1Key. The planner emits both a hint (read) and an export (write) for each. - for _, rsf := range in.RequestScopedFields { + for _, rsf := range in.GetEntityCachingConfiguration().GetRequestScopedConfigurations() { out.FederationMetaData.RequestScopedFields = append(out.FederationMetaData.RequestScopedFields, plan.RequestScopedField{ FieldName: rsf.FieldName, TypeName: rsf.TypeName, diff --git a/router/core/graph_server.go b/router/core/graph_server.go index feef44dcb6..edfff2434b 100644 --- a/router/core/graph_server.go +++ b/router/core/graph_server.go @@ -719,7 +719,7 @@ func (s *graphServer) logEntityCacheOverrideIssues( if entityTypesBySubgraph[sgName] == nil { entityTypesBySubgraph[sgName] = make(map[string]bool) } - for _, ec := range ds.EntityCacheConfigurations { + for _, ec := range ds.GetEntityCachingConfiguration().GetEntityCache() { entityTypesBySubgraph[sgName][ec.TypeName] = true } } From 0de2aeb18dd7f1d49b4119d2158ba9c0a7e57d6f Mon Sep 17 00:00:00 2001 From: Milinda Dias Date: Mon, 22 Jun 2026 23:29:36 +0530 Subject: [PATCH 5/7] chore(router): temporarily no-op IgnoreImplementingTypeWeights The entity-caching graphql-go-tools fork pinned by this branch predates plan.Configuration.IgnoreImplementingTypeWeights (added in released v2.5.0), while the released v2.5.0 lacks the entity-cache resolve.LoaderCache/CacheEntry APIs this branch needs. Guard the CostControl assignment with a TODO until the entity-caching fork is rebased onto v2.5.0; the toggle is a no-op until then. --- router/core/executor.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/router/core/executor.go b/router/core/executor.go index e2a78cba73..aa088102f4 100644 --- a/router/core/executor.go +++ b/router/core/executor.go @@ -265,7 +265,11 @@ func (b *ExecutorConfigurationBuilder) buildPlannerConfiguration(ctx context.Con if routerEngineCfg.CostControl != nil && routerEngineCfg.CostControl.Enabled { planConfig.ComputeCosts = true planConfig.StaticCostDefaultListSize = routerEngineCfg.CostControl.EstimatedListSize - planConfig.IgnoreImplementingTypeWeights = routerEngineCfg.CostControl.IgnoreImplementingTypeWeights + // TODO(entity-caching): the entity-caching graphql-go-tools fork pinned by this + // branch (v2.4.5-0.20260610...) predates plan.Configuration.IgnoreImplementingTypeWeights, + // which only exists in released v2.5.0. Restore this assignment once the fork is + // rebased onto v2.5.0. Until then this CostControl toggle is a no-op. + // planConfig.IgnoreImplementingTypeWeights = routerEngineCfg.CostControl.IgnoreImplementingTypeWeights } return planConfig, providers, nil From 87db18e697bf39f9677307bafc699a8dada1d539 Mon Sep 17 00:00:00 2001 From: Milinda Dias Date: Mon, 22 Jun 2026 23:29:46 +0530 Subject: [PATCH 6/7] test(router): adapt entity-caching tests to new proto format Nest entity-caching test fixtures under DataSourceConfiguration.EntityCachingConfiguration, rename RootFieldCacheConfiguration->QueryCacheConfiguration and RequestScopedFieldConfiguration->RequestScopedConfiguration, and pass CachePopulateConfiguration.max_age_seconds as a plain int64 (was *int64). --- .../entity_caching_standard_subgraphs_test.go | 10 +- .../entitycaching/entitycaching_test.go | 2 +- router-tests/entitycaching/harness_test.go | 23 ++-- router/core/executor_entity_cache_test.go | 24 ++-- .../core/factoryresolver_entity_cache_test.go | 120 +++++++++--------- router/core/factoryresolver_test.go | 22 ++-- 6 files changed, 109 insertions(+), 92 deletions(-) diff --git a/router-tests/entity_caching_standard_subgraphs_test.go b/router-tests/entity_caching_standard_subgraphs_test.go index b39e63ca46..e63a18166e 100644 --- a/router-tests/entity_caching_standard_subgraphs_test.go +++ b/router-tests/entity_caching_standard_subgraphs_test.go @@ -48,7 +48,10 @@ func addEntityCacheConfig(routerConfig *nodev1.RouterConfig, ttlSeconds int64) { if key.DisableEntityResolver { continue } - ds.EntityCacheConfigurations = append(ds.EntityCacheConfigurations, &nodev1.EntityCacheConfiguration{ + if ds.EntityCachingConfiguration == nil { + ds.EntityCachingConfiguration = &nodev1.EntityCachingConfiguration{} + } + ds.EntityCachingConfiguration.EntityCache = append(ds.EntityCachingConfiguration.EntityCache, &nodev1.EntityCacheConfiguration{ TypeName: key.TypeName, MaxAgeSeconds: ttlSeconds, }) @@ -210,7 +213,10 @@ func TestEntityCaching(t *testing.T) { if key.DisableEntityResolver { continue } - ds.EntityCacheConfigurations = append(ds.EntityCacheConfigurations, &nodev1.EntityCacheConfiguration{ + if ds.EntityCachingConfiguration == nil { + ds.EntityCachingConfiguration = &nodev1.EntityCachingConfiguration{} + } + ds.EntityCachingConfiguration.EntityCache = append(ds.EntityCachingConfiguration.EntityCache, &nodev1.EntityCacheConfiguration{ TypeName: key.TypeName, MaxAgeSeconds: 300, ShadowMode: true, diff --git a/router-tests/entitycaching/entitycaching_test.go b/router-tests/entitycaching/entitycaching_test.go index 44092bdce0..42c962743d 100644 --- a/router-tests/entitycaching/entitycaching_test.go +++ b/router-tests/entitycaching/entitycaching_test.go @@ -888,7 +888,7 @@ func TestEntityCaching(t *testing.T) { RouterOptions: entityCachingL2OnlyOptions(cache), ModifyRouterConfig: func(rc *nodev1.RouterConfig) { for _, ds := range rc.EngineConfig.DatasourceConfigurations { - for _, cp := range ds.CachePopulateConfigurations { + for _, cp := range ds.GetEntityCachingConfiguration().GetCachePopulateConfigurations() { if cp.OperationType == "Subscription" && cp.FieldName == "itemCreated" { itemCreatedPopulate = cp } diff --git a/router-tests/entitycaching/harness_test.go b/router-tests/entitycaching/harness_test.go index 0ac4a4c425..f0a291c559 100644 --- a/router-tests/entitycaching/harness_test.go +++ b/router-tests/entitycaching/harness_test.go @@ -285,17 +285,14 @@ func entityCachingDisabledOptions() []core.Option { // clearEntityCacheConfigs removes all entity cache configs from the router config. func clearEntityCacheConfigs(rc *nodev1.RouterConfig) { for _, ds := range rc.EngineConfig.DatasourceConfigurations { - ds.EntityCacheConfigurations = nil - ds.RootFieldCacheConfigurations = nil - ds.CacheInvalidateConfigurations = nil - ds.CachePopulateConfigurations = nil + ds.EntityCachingConfiguration = nil } } // setEntityCacheTTL overrides MaxAgeSeconds on all entity cache configs. func setEntityCacheTTL(rc *nodev1.RouterConfig, ttl int64) { for _, ds := range rc.EngineConfig.DatasourceConfigurations { - for _, ec := range ds.EntityCacheConfigurations { + for _, ec := range ds.GetEntityCachingConfiguration().GetEntityCache() { ec.MaxAgeSeconds = ttl } } @@ -304,7 +301,7 @@ func setEntityCacheTTL(rc *nodev1.RouterConfig, ttl int64) { // setEntityCacheShadowMode sets ShadowMode on all entity cache configs. func setEntityCacheShadowMode(rc *nodev1.RouterConfig, enabled bool) { for _, ds := range rc.EngineConfig.DatasourceConfigurations { - for _, ec := range ds.EntityCacheConfigurations { + for _, ec := range ds.GetEntityCachingConfiguration().GetEntityCache() { ec.ShadowMode = enabled } } @@ -313,7 +310,7 @@ func setEntityCacheShadowMode(rc *nodev1.RouterConfig, enabled bool) { // setEntityCachePartialLoad sets PartialCacheLoad on all entity cache configs. func setEntityCachePartialLoad(rc *nodev1.RouterConfig, enabled bool) { for _, ds := range rc.EngineConfig.DatasourceConfigurations { - for _, ec := range ds.EntityCacheConfigurations { + for _, ec := range ds.GetEntityCachingConfiguration().GetEntityCache() { ec.PartialCacheLoad = enabled } } @@ -322,7 +319,7 @@ func setEntityCachePartialLoad(rc *nodev1.RouterConfig, enabled bool) { // setEntityCacheIncludeHeaders sets IncludeHeaders on all entity cache configs. func setEntityCacheIncludeHeaders(rc *nodev1.RouterConfig, enabled bool) { for _, ds := range rc.EngineConfig.DatasourceConfigurations { - for _, ec := range ds.EntityCacheConfigurations { + for _, ec := range ds.GetEntityCachingConfiguration().GetEntityCache() { ec.IncludeHeaders = enabled } } @@ -331,7 +328,7 @@ func setEntityCacheIncludeHeaders(rc *nodev1.RouterConfig, enabled bool) { // setNotFoundCacheTTL sets NotFoundCacheTtlSeconds on all entity cache configs. func setNotFoundCacheTTL(rc *nodev1.RouterConfig, ttl int64) { for _, ds := range rc.EngineConfig.DatasourceConfigurations { - for _, ec := range ds.EntityCacheConfigurations { + for _, ec := range ds.GetEntityCachingConfiguration().GetEntityCache() { ec.NotFoundCacheTtlSeconds = ttl } } @@ -340,7 +337,7 @@ func setNotFoundCacheTTL(rc *nodev1.RouterConfig, ttl int64) { // setQueryCacheShadowMode sets ShadowMode on all root field cache configs. func setQueryCacheShadowMode(rc *nodev1.RouterConfig, enabled bool) { for _, ds := range rc.EngineConfig.DatasourceConfigurations { - for _, rfc := range ds.RootFieldCacheConfigurations { + for _, rfc := range ds.GetEntityCachingConfiguration().GetQueryCacheConfigurations() { rfc.ShadowMode = enabled } } @@ -349,7 +346,7 @@ func setQueryCacheShadowMode(rc *nodev1.RouterConfig, enabled bool) { // setQueryCacheIncludeHeaders sets IncludeHeaders on all root field cache configs. func setQueryCacheIncludeHeaders(rc *nodev1.RouterConfig, enabled bool) { for _, ds := range rc.EngineConfig.DatasourceConfigurations { - for _, rfc := range ds.RootFieldCacheConfigurations { + for _, rfc := range ds.GetEntityCachingConfiguration().GetQueryCacheConfigurations() { rfc.IncludeHeaders = enabled } } @@ -358,8 +355,8 @@ func setQueryCacheIncludeHeaders(rc *nodev1.RouterConfig, enabled bool) { // setCachePopulateTTL overrides MaxAgeSeconds on all cache populate configs. func setCachePopulateTTL(rc *nodev1.RouterConfig, ttl int64) { for _, ds := range rc.EngineConfig.DatasourceConfigurations { - for _, cp := range ds.CachePopulateConfigurations { - cp.MaxAgeSeconds = &ttl + for _, cp := range ds.GetEntityCachingConfiguration().GetCachePopulateConfigurations() { + cp.MaxAgeSeconds = ttl } } } diff --git a/router/core/executor_entity_cache_test.go b/router/core/executor_entity_cache_test.go index e4c39f2898..a8d4ba8db4 100644 --- a/router/core/executor_entity_cache_test.go +++ b/router/core/executor_entity_cache_test.go @@ -117,14 +117,18 @@ func TestBuildEntityCacheInvalidationConfigs(t *testing.T) { DatasourceConfigurations: []*nodev1.DataSourceConfiguration{ { Id: "ds-unknown", // no matching subgraph - EntityCacheConfigurations: []*nodev1.EntityCacheConfiguration{ - {TypeName: "Mystery", MaxAgeSeconds: 60}, + EntityCachingConfiguration: &nodev1.EntityCachingConfiguration{ + EntityCache: []*nodev1.EntityCacheConfiguration{ + {TypeName: "Mystery", MaxAgeSeconds: 60}, + }, }, }, { Id: "ds-known", - EntityCacheConfigurations: []*nodev1.EntityCacheConfiguration{ - {TypeName: "Product", MaxAgeSeconds: 60}, + EntityCachingConfiguration: &nodev1.EntityCachingConfiguration{ + EntityCache: []*nodev1.EntityCacheConfiguration{ + {TypeName: "Product", MaxAgeSeconds: 60}, + }, }, }, }, @@ -164,14 +168,18 @@ func TestBuildEntityCacheInvalidationConfigs(t *testing.T) { DatasourceConfigurations: []*nodev1.DataSourceConfiguration{ { Id: "ds-1", - EntityCacheConfigurations: []*nodev1.EntityCacheConfiguration{ - {TypeName: "Product", MaxAgeSeconds: 60, IncludeHeaders: true}, + EntityCachingConfiguration: &nodev1.EntityCachingConfiguration{ + EntityCache: []*nodev1.EntityCacheConfiguration{ + {TypeName: "Product", MaxAgeSeconds: 60, IncludeHeaders: true}, + }, }, }, { Id: "ds-2", - EntityCacheConfigurations: []*nodev1.EntityCacheConfiguration{ - {TypeName: "Review", MaxAgeSeconds: 30}, + EntityCachingConfiguration: &nodev1.EntityCachingConfiguration{ + EntityCache: []*nodev1.EntityCacheConfiguration{ + {TypeName: "Review", MaxAgeSeconds: 30}, + }, }, }, }, diff --git a/router/core/factoryresolver_entity_cache_test.go b/router/core/factoryresolver_entity_cache_test.go index 7960cf5d53..143ff8d242 100644 --- a/router/core/factoryresolver_entity_cache_test.go +++ b/router/core/factoryresolver_entity_cache_test.go @@ -20,14 +20,16 @@ func TestDataSourceMetaDataMapsNegativeEntityCacheTTL(t *testing.T) { } meta := loader.dataSourceMetaData(&nodev1.DataSourceConfiguration{ - EntityCacheConfigurations: []*nodev1.EntityCacheConfiguration{ - { - TypeName: "Item", - MaxAgeSeconds: 300, - NotFoundCacheTtlSeconds: 15, - IncludeHeaders: true, - PartialCacheLoad: true, - ShadowMode: true, + EntityCachingConfiguration: &nodev1.EntityCachingConfiguration{ + EntityCache: []*nodev1.EntityCacheConfiguration{ + { + TypeName: "Item", + MaxAgeSeconds: 300, + NotFoundCacheTtlSeconds: 15, + IncludeHeaders: true, + PartialCacheLoad: true, + ShadowMode: true, + }, }, }, }, "items") @@ -74,64 +76,66 @@ func TestDataSourceMetaDataMapsRootFieldMutationSubscriptionAndRequestScopedCach {TypeName: "Mutation", FieldNames: []string{"createItem", "deleteItem"}}, {TypeName: "Subscription", FieldNames: []string{"itemCreated", "itemDeleted"}}, }, - EntityCacheConfigurations: []*nodev1.EntityCacheConfiguration{ - { - TypeName: "Item", - MaxAgeSeconds: 60, - IncludeHeaders: true, + EntityCachingConfiguration: &nodev1.EntityCachingConfiguration{ + EntityCache: []*nodev1.EntityCacheConfiguration{ + { + TypeName: "Item", + MaxAgeSeconds: 60, + IncludeHeaders: true, + }, }, - }, - RootFieldCacheConfigurations: []*nodev1.RootFieldCacheConfiguration{ - { - FieldName: "item", - EntityTypeName: "Item", - MaxAgeSeconds: 30, - IncludeHeaders: true, - ShadowMode: true, - EntityKeyMappings: []*nodev1.EntityKeyMapping{ - { - EntityTypeName: "Item", - FieldMappings: []*nodev1.EntityCacheFieldMapping{ - { - EntityKeyField: "id", - ArgumentPath: []string{"id"}, - IsBatch: true, + QueryCacheConfigurations: []*nodev1.QueryCacheConfiguration{ + { + FieldName: "item", + EntityTypeName: "Item", + MaxAgeSeconds: 30, + IncludeHeaders: true, + ShadowMode: true, + EntityKeyMappings: []*nodev1.EntityKeyMapping{ + { + EntityTypeName: "Item", + FieldMappings: []*nodev1.EntityCacheFieldMapping{ + { + EntityKeyField: "id", + ArgumentPath: []string{"id"}, + IsBatch: true, + }, }, }, }, }, }, - }, - CachePopulateConfigurations: []*nodev1.CachePopulateConfiguration{ - { - FieldName: "createItem", - EntityTypeName: "Item", - OperationType: "Mutation", - MaxAgeSeconds: &mutationTTL, - }, - { - FieldName: "itemCreated", - EntityTypeName: "Item", - OperationType: "Subscription", - }, - }, - CacheInvalidateConfigurations: []*nodev1.CacheInvalidateConfiguration{ - { - FieldName: "deleteItem", - EntityTypeName: "Item", - OperationType: "Mutation", + CachePopulateConfigurations: []*nodev1.CachePopulateConfiguration{ + { + FieldName: "createItem", + EntityTypeName: "Item", + OperationType: "Mutation", + MaxAgeSeconds: mutationTTL, + }, + { + FieldName: "itemCreated", + EntityTypeName: "Item", + OperationType: "Subscription", + }, }, - { - FieldName: "itemDeleted", - EntityTypeName: "Item", - OperationType: "Subscription", + CacheInvalidateConfigurations: []*nodev1.CacheInvalidateConfiguration{ + { + FieldName: "deleteItem", + EntityTypeName: "Item", + OperationType: "Mutation", + }, + { + FieldName: "itemDeleted", + EntityTypeName: "Item", + OperationType: "Subscription", + }, }, - }, - RequestScopedFields: []*nodev1.RequestScopedFieldConfiguration{ - { - FieldName: "currentViewer", - TypeName: "Query", - L1Key: "items.currentViewer", + RequestScopedConfigurations: []*nodev1.RequestScopedConfiguration{ + { + FieldName: "currentViewer", + TypeName: "Query", + L1Key: "items.currentViewer", + }, }, }, }, "items") diff --git a/router/core/factoryresolver_test.go b/router/core/factoryresolver_test.go index 0e7b778ba6..1afd785242 100644 --- a/router/core/factoryresolver_test.go +++ b/router/core/factoryresolver_test.go @@ -13,16 +13,18 @@ func TestDataSourceMetaData_RequestScopedFields(t *testing.T) { l := &Loader{} in := &nodev1.DataSourceConfiguration{ - RequestScopedFields: []*nodev1.RequestScopedFieldConfiguration{ - { - FieldName: "currentUser", - TypeName: "Query", - L1Key: "viewer.user", - }, - { - FieldName: "currentUser", - TypeName: "Personalized", - L1Key: "viewer.user", + EntityCachingConfiguration: &nodev1.EntityCachingConfiguration{ + RequestScopedConfigurations: []*nodev1.RequestScopedConfiguration{ + { + FieldName: "currentUser", + TypeName: "Query", + L1Key: "viewer.user", + }, + { + FieldName: "currentUser", + TypeName: "Personalized", + L1Key: "viewer.user", + }, }, }, } From 9a6df7b58e6798f43fe9dcda106a0a0331a565fd Mon Sep 17 00:00:00 2001 From: Milinda Dias Date: Wed, 1 Jul 2026 16:55:05 +0530 Subject: [PATCH 7/7] fix(entity-caching): rename EntityCachingConfiguration.entity_cache to entity_cache_configurations Align the proto field with origin/main (entity_cache_configurations). The old name serialized to JSON as entityCache, so the router silently dropped the control-plane's entity caching config on unmarshal. Regenerated Go/TS bindings and updated all GetEntityCache() consumers in the router core and tests. --- connect-go/gen/proto/wg/cosmo/node/v1/node.pb.go | 14 +++++++------- connect/src/wg/cosmo/node/v1/node_pb.ts | 6 +++--- proto/wg/cosmo/node/v1/node.proto | 2 +- router-tests/entitycaching/harness_test.go | 10 +++++----- router/core/executor.go | 2 +- router/core/factoryresolver.go | 6 +++--- router/core/graph_server.go | 2 +- router/gen/proto/wg/cosmo/node/v1/node.pb.go | 14 +++++++------- shared/src/router-config/builder.ts | 2 +- 9 files changed, 29 insertions(+), 29 deletions(-) diff --git a/connect-go/gen/proto/wg/cosmo/node/v1/node.pb.go b/connect-go/gen/proto/wg/cosmo/node/v1/node.pb.go index b3258918fc..e0a0783232 100644 --- a/connect-go/gen/proto/wg/cosmo/node/v1/node.pb.go +++ b/connect-go/gen/proto/wg/cosmo/node/v1/node.pb.go @@ -1229,7 +1229,7 @@ func (x *DataSourceConfiguration) GetEntityCachingConfiguration() *EntityCaching type EntityCachingConfiguration struct { state protoimpl.MessageState `protogen:"open.v1"` // Per-entity cache configurations (from @openfed__entityCache directive) - EntityCache []*EntityCacheConfiguration `protobuf:"bytes,1,rep,name=entity_cache,json=entityCache,proto3" json:"entity_cache,omitempty"` + EntityCacheConfigurations []*EntityCacheConfiguration `protobuf:"bytes,1,rep,name=entity_cache_configurations,json=entityCacheConfigurations,proto3" json:"entity_cache_configurations,omitempty"` // Per-Mutation/Subscription-field cache eviction configs (from @openfed__cacheInvalidate) CacheInvalidateConfigurations []*CacheInvalidateConfiguration `protobuf:"bytes,2,rep,name=cache_invalidate_configurations,json=cacheInvalidateConfigurations,proto3" json:"cache_invalidate_configurations,omitempty"` // Per-Mutation/Subscription-field cache population configs (from @openfed__cachePopulate) @@ -1272,9 +1272,9 @@ func (*EntityCachingConfiguration) Descriptor() ([]byte, []int) { return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{12} } -func (x *EntityCachingConfiguration) GetEntityCache() []*EntityCacheConfiguration { +func (x *EntityCachingConfiguration) GetEntityCacheConfigurations() []*EntityCacheConfiguration { if x != nil { - return x.EntityCache + return x.EntityCacheConfigurations } return nil } @@ -5271,9 +5271,9 @@ const file_wg_cosmo_node_v1_node_proto_rawDesc = "" + "\x11entity_interfaces\x18\x0e \x03(\v2..wg.cosmo.node.v1.EntityInterfaceConfigurationR\x10entityInterfaces\x12[\n" + "\x11interface_objects\x18\x0f \x03(\v2..wg.cosmo.node.v1.EntityInterfaceConfigurationR\x10interfaceObjects\x12R\n" + "\x12cost_configuration\x18\x10 \x01(\v2#.wg.cosmo.node.v1.CostConfigurationR\x11costConfiguration\x12n\n" + - "\x1centity_caching_configuration\x18\x11 \x01(\v2,.wg.cosmo.node.v1.EntityCachingConfigurationR\x1aentityCachingConfiguration\"\xb0\x04\n" + - "\x1aEntityCachingConfiguration\x12M\n" + - "\fentity_cache\x18\x01 \x03(\v2*.wg.cosmo.node.v1.EntityCacheConfigurationR\ventityCache\x12v\n" + + "\x1centity_caching_configuration\x18\x11 \x01(\v2,.wg.cosmo.node.v1.EntityCachingConfigurationR\x1aentityCachingConfiguration\"\xcd\x04\n" + + "\x1aEntityCachingConfiguration\x12j\n" + + "\x1bentity_cache_configurations\x18\x01 \x03(\v2*.wg.cosmo.node.v1.EntityCacheConfigurationR\x19entityCacheConfigurations\x12v\n" + "\x1fcache_invalidate_configurations\x18\x02 \x03(\v2..wg.cosmo.node.v1.CacheInvalidateConfigurationR\x1dcacheInvalidateConfigurations\x12p\n" + "\x1dcache_populate_configurations\x18\x03 \x03(\v2,.wg.cosmo.node.v1.CachePopulateConfigurationR\x1bcachePopulateConfigurations\x12p\n" + "\x1drequest_scoped_configurations\x18\x04 \x03(\v2,.wg.cosmo.node.v1.RequestScopedConfigurationR\x1brequestScopedConfigurations\x12g\n" + @@ -5781,7 +5781,7 @@ var file_wg_cosmo_node_v1_node_proto_depIdxs = []int32{ 40, // 25: wg.cosmo.node.v1.DataSourceConfiguration.interface_objects:type_name -> wg.cosmo.node.v1.EntityInterfaceConfiguration 28, // 26: wg.cosmo.node.v1.DataSourceConfiguration.cost_configuration:type_name -> wg.cosmo.node.v1.CostConfiguration 20, // 27: wg.cosmo.node.v1.DataSourceConfiguration.entity_caching_configuration:type_name -> wg.cosmo.node.v1.EntityCachingConfiguration - 21, // 28: wg.cosmo.node.v1.EntityCachingConfiguration.entity_cache:type_name -> wg.cosmo.node.v1.EntityCacheConfiguration + 21, // 28: wg.cosmo.node.v1.EntityCachingConfiguration.entity_cache_configurations:type_name -> wg.cosmo.node.v1.EntityCacheConfiguration 22, // 29: wg.cosmo.node.v1.EntityCachingConfiguration.cache_invalidate_configurations:type_name -> wg.cosmo.node.v1.CacheInvalidateConfiguration 23, // 30: wg.cosmo.node.v1.EntityCachingConfiguration.cache_populate_configurations:type_name -> wg.cosmo.node.v1.CachePopulateConfiguration 24, // 31: wg.cosmo.node.v1.EntityCachingConfiguration.request_scoped_configurations:type_name -> wg.cosmo.node.v1.RequestScopedConfiguration diff --git a/connect/src/wg/cosmo/node/v1/node_pb.ts b/connect/src/wg/cosmo/node/v1/node_pb.ts index eeb8b45d25..b3e12f5d20 100644 --- a/connect/src/wg/cosmo/node/v1/node_pb.ts +++ b/connect/src/wg/cosmo/node/v1/node_pb.ts @@ -903,9 +903,9 @@ export class EntityCachingConfiguration extends Message [ - { no: 1, name: "entity_cache", kind: "message", T: EntityCacheConfiguration, repeated: true }, + { no: 1, name: "entity_cache_configurations", kind: "message", T: EntityCacheConfiguration, repeated: true }, { no: 2, name: "cache_invalidate_configurations", kind: "message", T: CacheInvalidateConfiguration, repeated: true }, { no: 3, name: "cache_populate_configurations", kind: "message", T: CachePopulateConfiguration, repeated: true }, { no: 4, name: "request_scoped_configurations", kind: "message", T: RequestScopedConfiguration, repeated: true }, diff --git a/proto/wg/cosmo/node/v1/node.proto b/proto/wg/cosmo/node/v1/node.proto index 048ee4aaee..9a2cdee563 100644 --- a/proto/wg/cosmo/node/v1/node.proto +++ b/proto/wg/cosmo/node/v1/node.proto @@ -98,7 +98,7 @@ message DataSourceConfiguration { // Entity caching configuration for a subgraph data source. message EntityCachingConfiguration { // Per-entity cache configurations (from @openfed__entityCache directive) - repeated EntityCacheConfiguration entity_cache = 1; + repeated EntityCacheConfiguration entity_cache_configurations = 1; // Per-Mutation/Subscription-field cache eviction configs (from @openfed__cacheInvalidate) repeated CacheInvalidateConfiguration cache_invalidate_configurations = 2; // Per-Mutation/Subscription-field cache population configs (from @openfed__cachePopulate) diff --git a/router-tests/entitycaching/harness_test.go b/router-tests/entitycaching/harness_test.go index f0a291c559..4ccb77d5b0 100644 --- a/router-tests/entitycaching/harness_test.go +++ b/router-tests/entitycaching/harness_test.go @@ -292,7 +292,7 @@ func clearEntityCacheConfigs(rc *nodev1.RouterConfig) { // setEntityCacheTTL overrides MaxAgeSeconds on all entity cache configs. func setEntityCacheTTL(rc *nodev1.RouterConfig, ttl int64) { for _, ds := range rc.EngineConfig.DatasourceConfigurations { - for _, ec := range ds.GetEntityCachingConfiguration().GetEntityCache() { + for _, ec := range ds.GetEntityCachingConfiguration().GetEntityCacheConfigurations() { ec.MaxAgeSeconds = ttl } } @@ -301,7 +301,7 @@ func setEntityCacheTTL(rc *nodev1.RouterConfig, ttl int64) { // setEntityCacheShadowMode sets ShadowMode on all entity cache configs. func setEntityCacheShadowMode(rc *nodev1.RouterConfig, enabled bool) { for _, ds := range rc.EngineConfig.DatasourceConfigurations { - for _, ec := range ds.GetEntityCachingConfiguration().GetEntityCache() { + for _, ec := range ds.GetEntityCachingConfiguration().GetEntityCacheConfigurations() { ec.ShadowMode = enabled } } @@ -310,7 +310,7 @@ func setEntityCacheShadowMode(rc *nodev1.RouterConfig, enabled bool) { // setEntityCachePartialLoad sets PartialCacheLoad on all entity cache configs. func setEntityCachePartialLoad(rc *nodev1.RouterConfig, enabled bool) { for _, ds := range rc.EngineConfig.DatasourceConfigurations { - for _, ec := range ds.GetEntityCachingConfiguration().GetEntityCache() { + for _, ec := range ds.GetEntityCachingConfiguration().GetEntityCacheConfigurations() { ec.PartialCacheLoad = enabled } } @@ -319,7 +319,7 @@ func setEntityCachePartialLoad(rc *nodev1.RouterConfig, enabled bool) { // setEntityCacheIncludeHeaders sets IncludeHeaders on all entity cache configs. func setEntityCacheIncludeHeaders(rc *nodev1.RouterConfig, enabled bool) { for _, ds := range rc.EngineConfig.DatasourceConfigurations { - for _, ec := range ds.GetEntityCachingConfiguration().GetEntityCache() { + for _, ec := range ds.GetEntityCachingConfiguration().GetEntityCacheConfigurations() { ec.IncludeHeaders = enabled } } @@ -328,7 +328,7 @@ func setEntityCacheIncludeHeaders(rc *nodev1.RouterConfig, enabled bool) { // setNotFoundCacheTTL sets NotFoundCacheTtlSeconds on all entity cache configs. func setNotFoundCacheTTL(rc *nodev1.RouterConfig, ttl int64) { for _, ds := range rc.EngineConfig.DatasourceConfigurations { - for _, ec := range ds.GetEntityCachingConfiguration().GetEntityCache() { + for _, ec := range ds.GetEntityCachingConfiguration().GetEntityCacheConfigurations() { ec.NotFoundCacheTtlSeconds = ttl } } diff --git a/router/core/executor.go b/router/core/executor.go index aa088102f4..ce64fa9335 100644 --- a/router/core/executor.go +++ b/router/core/executor.go @@ -297,7 +297,7 @@ func buildEntityCacheInvalidationConfigs( } continue } - for _, ec := range ds.GetEntityCachingConfiguration().GetEntityCache() { + for _, ec := range ds.GetEntityCachingConfiguration().GetEntityCacheConfigurations() { if _, ok := result[subgraphName]; !ok { result[subgraphName] = make(map[string]*resolve.EntityCacheInvalidationConfig) } diff --git a/router/core/factoryresolver.go b/router/core/factoryresolver.go index 944ba941d7..2260727b1f 100644 --- a/router/core/factoryresolver.go +++ b/router/core/factoryresolver.go @@ -674,7 +674,7 @@ func (l *Loader) dataSourceMetaData(in *nodev1.DataSourceConfiguration, subgraph } // Entity caching configurations - for _, ec := range in.GetEntityCachingConfiguration().GetEntityCache() { + for _, ec := range in.GetEntityCachingConfiguration().GetEntityCacheConfigurations() { cacheName := resolveEntityCacheProviderID(l.entityCachingConfig, subgraphName, ec.TypeName) out.FederationMetaData.EntityCaching = append(out.FederationMetaData.EntityCaching, plan.EntityCacheConfiguration{ TypeName: ec.TypeName, @@ -721,7 +721,7 @@ func (l *Loader) dataSourceMetaData(in *nodev1.DataSourceConfiguration, subgraph for _, cp := range in.GetEntityCachingConfiguration().GetCachePopulateConfigurations() { if cp.OperationType == protoOperationTypeSubscription { var targetEntity *nodev1.EntityCacheConfiguration - for _, ec := range in.GetEntityCachingConfiguration().GetEntityCache() { + for _, ec := range in.GetEntityCachingConfiguration().GetEntityCacheConfigurations() { if ec.TypeName == cp.EntityTypeName { targetEntity = ec break @@ -766,7 +766,7 @@ func (l *Loader) dataSourceMetaData(in *nodev1.DataSourceConfiguration, subgraph if ci.OperationType == protoOperationTypeSubscription { cacheName := resolveEntityCacheProviderID(l.entityCachingConfig, subgraphName, ci.EntityTypeName) var includeHeaders bool - for _, ec := range in.GetEntityCachingConfiguration().GetEntityCache() { + for _, ec := range in.GetEntityCachingConfiguration().GetEntityCacheConfigurations() { if ec.TypeName == ci.EntityTypeName { includeHeaders = ec.IncludeHeaders break diff --git a/router/core/graph_server.go b/router/core/graph_server.go index edfff2434b..8198584992 100644 --- a/router/core/graph_server.go +++ b/router/core/graph_server.go @@ -719,7 +719,7 @@ func (s *graphServer) logEntityCacheOverrideIssues( if entityTypesBySubgraph[sgName] == nil { entityTypesBySubgraph[sgName] = make(map[string]bool) } - for _, ec := range ds.GetEntityCachingConfiguration().GetEntityCache() { + for _, ec := range ds.GetEntityCachingConfiguration().GetEntityCacheConfigurations() { entityTypesBySubgraph[sgName][ec.TypeName] = true } } diff --git a/router/gen/proto/wg/cosmo/node/v1/node.pb.go b/router/gen/proto/wg/cosmo/node/v1/node.pb.go index 079e93000e..31a9203c75 100644 --- a/router/gen/proto/wg/cosmo/node/v1/node.pb.go +++ b/router/gen/proto/wg/cosmo/node/v1/node.pb.go @@ -1229,7 +1229,7 @@ func (x *DataSourceConfiguration) GetEntityCachingConfiguration() *EntityCaching type EntityCachingConfiguration struct { state protoimpl.MessageState `protogen:"open.v1"` // Per-entity cache configurations (from @openfed__entityCache directive) - EntityCache []*EntityCacheConfiguration `protobuf:"bytes,1,rep,name=entity_cache,json=entityCache,proto3" json:"entity_cache,omitempty"` + EntityCacheConfigurations []*EntityCacheConfiguration `protobuf:"bytes,1,rep,name=entity_cache_configurations,json=entityCacheConfigurations,proto3" json:"entity_cache_configurations,omitempty"` // Per-Mutation/Subscription-field cache eviction configs (from @openfed__cacheInvalidate) CacheInvalidateConfigurations []*CacheInvalidateConfiguration `protobuf:"bytes,2,rep,name=cache_invalidate_configurations,json=cacheInvalidateConfigurations,proto3" json:"cache_invalidate_configurations,omitempty"` // Per-Mutation/Subscription-field cache population configs (from @openfed__cachePopulate) @@ -1272,9 +1272,9 @@ func (*EntityCachingConfiguration) Descriptor() ([]byte, []int) { return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{12} } -func (x *EntityCachingConfiguration) GetEntityCache() []*EntityCacheConfiguration { +func (x *EntityCachingConfiguration) GetEntityCacheConfigurations() []*EntityCacheConfiguration { if x != nil { - return x.EntityCache + return x.EntityCacheConfigurations } return nil } @@ -5271,9 +5271,9 @@ const file_wg_cosmo_node_v1_node_proto_rawDesc = "" + "\x11entity_interfaces\x18\x0e \x03(\v2..wg.cosmo.node.v1.EntityInterfaceConfigurationR\x10entityInterfaces\x12[\n" + "\x11interface_objects\x18\x0f \x03(\v2..wg.cosmo.node.v1.EntityInterfaceConfigurationR\x10interfaceObjects\x12R\n" + "\x12cost_configuration\x18\x10 \x01(\v2#.wg.cosmo.node.v1.CostConfigurationR\x11costConfiguration\x12n\n" + - "\x1centity_caching_configuration\x18\x11 \x01(\v2,.wg.cosmo.node.v1.EntityCachingConfigurationR\x1aentityCachingConfiguration\"\xb0\x04\n" + - "\x1aEntityCachingConfiguration\x12M\n" + - "\fentity_cache\x18\x01 \x03(\v2*.wg.cosmo.node.v1.EntityCacheConfigurationR\ventityCache\x12v\n" + + "\x1centity_caching_configuration\x18\x11 \x01(\v2,.wg.cosmo.node.v1.EntityCachingConfigurationR\x1aentityCachingConfiguration\"\xcd\x04\n" + + "\x1aEntityCachingConfiguration\x12j\n" + + "\x1bentity_cache_configurations\x18\x01 \x03(\v2*.wg.cosmo.node.v1.EntityCacheConfigurationR\x19entityCacheConfigurations\x12v\n" + "\x1fcache_invalidate_configurations\x18\x02 \x03(\v2..wg.cosmo.node.v1.CacheInvalidateConfigurationR\x1dcacheInvalidateConfigurations\x12p\n" + "\x1dcache_populate_configurations\x18\x03 \x03(\v2,.wg.cosmo.node.v1.CachePopulateConfigurationR\x1bcachePopulateConfigurations\x12p\n" + "\x1drequest_scoped_configurations\x18\x04 \x03(\v2,.wg.cosmo.node.v1.RequestScopedConfigurationR\x1brequestScopedConfigurations\x12g\n" + @@ -5781,7 +5781,7 @@ var file_wg_cosmo_node_v1_node_proto_depIdxs = []int32{ 40, // 25: wg.cosmo.node.v1.DataSourceConfiguration.interface_objects:type_name -> wg.cosmo.node.v1.EntityInterfaceConfiguration 28, // 26: wg.cosmo.node.v1.DataSourceConfiguration.cost_configuration:type_name -> wg.cosmo.node.v1.CostConfiguration 20, // 27: wg.cosmo.node.v1.DataSourceConfiguration.entity_caching_configuration:type_name -> wg.cosmo.node.v1.EntityCachingConfiguration - 21, // 28: wg.cosmo.node.v1.EntityCachingConfiguration.entity_cache:type_name -> wg.cosmo.node.v1.EntityCacheConfiguration + 21, // 28: wg.cosmo.node.v1.EntityCachingConfiguration.entity_cache_configurations:type_name -> wg.cosmo.node.v1.EntityCacheConfiguration 22, // 29: wg.cosmo.node.v1.EntityCachingConfiguration.cache_invalidate_configurations:type_name -> wg.cosmo.node.v1.CacheInvalidateConfiguration 23, // 30: wg.cosmo.node.v1.EntityCachingConfiguration.cache_populate_configurations:type_name -> wg.cosmo.node.v1.CachePopulateConfiguration 24, // 31: wg.cosmo.node.v1.EntityCachingConfiguration.request_scoped_configurations:type_name -> wg.cosmo.node.v1.RequestScopedConfiguration diff --git a/shared/src/router-config/builder.ts b/shared/src/router-config/builder.ts index c7ce0c4b8f..11af983068 100644 --- a/shared/src/router-config/builder.ts +++ b/shared/src/router-config/builder.ts @@ -136,7 +136,7 @@ function extractEntityCachingConfiguration( return new EntityCachingConfiguration({ cacheInvalidateConfigurations, cachePopulateConfigurations, - entityCache: entityCacheConfigurations, + entityCacheConfigurations, }); } }