diff --git a/v2/pkg/ast/ast_selection.go b/v2/pkg/ast/ast_selection.go index 0c7b643c8..2ef6a482b 100644 --- a/v2/pkg/ast/ast_selection.go +++ b/v2/pkg/ast/ast_selection.go @@ -212,6 +212,18 @@ func (d *Document) SelectionSetHasFieldSelectionWithExactName(set int, name []by return false, InvalidRef } +// SelectionSetFieldRefs returns a list of field refs in the selection set. +// It traverses through the field selections of the selection set and returns the actual field refs. +func (d *Document) SelectionSetFieldRefs(set int) (refs []int) { + for _, selectionRef := range d.SelectionSets[set].SelectionRefs { + if d.Selections[selectionRef].Kind == SelectionKindField { + refs = append(refs, d.Selections[selectionRef].Ref) + } + } + return +} + +// SelectionSetFieldSelections returns a list of field selection refs in the selection set. func (d *Document) SelectionSetFieldSelections(set int) (refs []int) { for _, selectionRef := range d.SelectionSets[set].SelectionRefs { if d.Selections[selectionRef].Kind == SelectionKindField { diff --git a/v2/pkg/astvisitor/visitor.go b/v2/pkg/astvisitor/visitor.go index 86f284c72..3f0beeb6e 100644 --- a/v2/pkg/astvisitor/visitor.go +++ b/v2/pkg/astvisitor/visitor.go @@ -4021,6 +4021,7 @@ func (w *Walker) FieldDefinitionDirectiveArgumentValueByName(field int, directiv } // InRootField returns true if the current field is a root field. +// This helper function can be used in EnterField and LeaveField. func (w *Walker) InRootField() bool { return w.CurrentKind == ast.NodeKindField && len(w.Ancestors) == 2 && diff --git a/v2/pkg/engine/datasource/grpc_datasource/compiler.go b/v2/pkg/engine/datasource/grpc_datasource/compiler.go index a22e6a6b9..a9261ee13 100644 --- a/v2/pkg/engine/datasource/grpc_datasource/compiler.go +++ b/v2/pkg/engine/datasource/grpc_datasource/compiler.go @@ -625,9 +625,7 @@ func (p *RPCCompiler) buildProtoMessageWithContext(inputMessage Message, rpcMess if err != nil { return nil, err } - - // Set the context and args fields - p.setMessageValue(rootMessage, contextSchemaField.Name, protoref.ValueOfList(contextList)) + // Set the args field p.setMessageValue(rootMessage, argsRPCField.Name, protoref.ValueOfMessage(args)) return rootMessage, nil @@ -736,7 +734,7 @@ func (p *RPCCompiler) resolveDataForPath(messsage protoref.Message, path ast.Pat switch fd.Kind() { case protoref.MessageKind: if fd.IsList() { - return []protoref.Value{field} + return []protoref.Value{protoref.ValueOfList(field.List())} } return p.resolveDataForPath(field.Message(), path[1:]) @@ -835,8 +833,33 @@ func (p *RPCCompiler) newEmptyListMessageByName(msg protoref.Message, name strin return msg.Mutable(msg.Descriptor().Fields().ByName(protoref.Name(name))).List() } -func (p *RPCCompiler) setMessageValue(message protoref.Message, fieldName string, value protoref.Value) { +func (p *RPCCompiler) setMessageValue(message protoref.Message, fieldName string, value protoref.Value) error { + fd := message.Descriptor().Fields().ByName(protoref.Name(fieldName)) + if fd == nil { + return fmt.Errorf("field %s not found in message %s", fieldName, message.Descriptor().Name()) + } + + // If we are setting a list value here, we need to create a copy of the list + // because the field descriptor is included in the type check, so we cannot asign it using `Set` directly. + if fd.IsList() { + list := message.Mutable(fd).List() + source, ok := value.Interface().(protoref.List) + if !ok { + return fmt.Errorf("value is not a list") + } + + p.copyListValues(source, list) + return nil + } + message.Set(message.Descriptor().Fields().ByName(protoref.Name(fieldName)), value) + return nil +} + +func (p *RPCCompiler) copyListValues(source protoref.List, destination protoref.List) { + for i := range source.Len() { + destination.Append(source.Get(i)) + } } // buildProtoMessage recursively builds a protobuf message from an RPCMessage definition diff --git a/v2/pkg/engine/datasource/grpc_datasource/execution_plan.go b/v2/pkg/engine/datasource/grpc_datasource/execution_plan.go index e7b486280..d1f20f304 100644 --- a/v2/pkg/engine/datasource/grpc_datasource/execution_plan.go +++ b/v2/pkg/engine/datasource/grpc_datasource/execution_plan.go @@ -1,6 +1,7 @@ package grpcdatasource import ( + "errors" "fmt" "slices" "strings" @@ -8,6 +9,7 @@ import ( "github.com/wundergraph/graphql-go-tools/v2/pkg/ast" "github.com/wundergraph/graphql-go-tools/v2/pkg/astvisitor" "github.com/wundergraph/graphql-go-tools/v2/pkg/engine/plan" + "github.com/wundergraph/graphql-go-tools/v2/pkg/internal/unsafebytes" ) const ( @@ -60,7 +62,7 @@ type RPCExecutionPlan struct { } // CallKind is the type of call operation to perform. -type CallKind int +type CallKind uint8 const ( // CallKindStandard is a basic fetch operation. @@ -147,12 +149,8 @@ func (r *RPCMessage) AppendTypeNameField(typeName string) { type RPCFieldSelectionSet map[string]RPCFields // Add adds a field selection set to the map -func (r RPCFieldSelectionSet) Add(fragmentName string, field RPCField) { - if r[fragmentName] == nil { - r[fragmentName] = make(RPCFields, 0) - } - - r[fragmentName] = append(r[fragmentName], field) +func (r RPCFieldSelectionSet) Add(fragmentName string, field ...RPCField) { + r[fragmentName] = append(r[fragmentName], field...) } // SelectFieldsForTypes returns the fields for the given valid types. @@ -718,6 +716,83 @@ func (r *rpcPlanningContext) buildInputMessageField(typeRef int, fieldName, json return field, nil } +// buildFieldMessage builds a message from a field definition. +// It handles complex and composite types. +func (r *rpcPlanningContext) buildFieldMessage(fieldTypeNode ast.Node, fieldRef int) (*RPCMessage, error) { + field := r.operation.Fields[fieldRef] + if !field.HasSelections { + return nil, fmt.Errorf("unable to build field message: field %s has no selections", r.operation.FieldAliasOrNameString(fieldRef)) + } + + fieldRefs := make([]int, 0) + inlineFragmentRefs := make([]int, 0) + selections := r.operation.SelectionSets[field.SelectionSet].SelectionRefs + for i := range selections { + selection := r.operation.Selections[selections[i]] + switch selection.Kind { + case ast.SelectionKindField: + fieldRefs = append(fieldRefs, selection.Ref) + case ast.SelectionKindInlineFragment: + inlineFragmentRefs = append(inlineFragmentRefs, selection.Ref) + } + } + + message := &RPCMessage{ + Name: fieldTypeNode.NameString(r.definition), + } + + if compositeType := r.getCompositeType(fieldTypeNode); compositeType != OneOfTypeNone { + memberTypes, err := r.getMemberTypes(fieldTypeNode) + if err != nil { + return nil, err + } + message.MemberTypes = memberTypes + message.OneOfType = compositeType + } + + for _, inlineFragmentRef := range inlineFragmentRefs { + selectionSetRef, ok := r.operation.InlineFragmentSelectionSet(inlineFragmentRef) + if !ok { + continue + } + + typeName := r.operation.InlineFragmentTypeConditionNameString(inlineFragmentRef) + inlineFragmentTypeNode, found := r.definition.NodeByNameStr(typeName) + if !found { + return nil, fmt.Errorf("unable to resolve type node for inline fragment %s", typeName) + } + + fields, err := r.buildCompositeFields(inlineFragmentTypeNode, fragmentSelection{ + typeName: typeName, + selectionSetRef: selectionSetRef, + }) + + if err != nil { + return nil, err + } + + if message.FieldSelectionSet == nil { + message.FieldSelectionSet = make(RPCFieldSelectionSet) + } + + message.FieldSelectionSet.Add(typeName, fields...) + } + + for _, fieldRef := range fieldRefs { + if r.isFieldResolver(fieldRef, false) { + continue + } + + field, err := r.buildRequiredField(fieldTypeNode, fieldRef) + if err != nil { + return nil, err + } + message.Fields = append(message.Fields, field) + } + + return message, nil +} + // resolveServiceName resolves the service name for a given subgraph name. func (r *rpcPlanningContext) resolveServiceName(subgraphName string) string { if r.mapping == nil || r.mapping.Service == "" { @@ -727,20 +802,99 @@ func (r *rpcPlanningContext) resolveServiceName(subgraphName string) string { return r.mapping.Service } -type resolvedField struct { +type resolverField struct { callerRef int - parentTypeRef int + parentTypeNode ast.Node fieldRef int fieldDefinitionTypeRef int fieldsSelectionSetRef int responsePath ast.Path - contextFields []contextField - fieldArguments []fieldArgument + contextFields []contextField + fieldArguments []fieldArgument + fragmentSelections []fragmentSelection + fragmentType OneOfType + memberTypes []string +} + +type fragmentSelection struct { + typeName string + selectionSetRef int +} + +// enterResolverCompositeSelectionSet handles logic when entering a composite selection set for a given field resolver. +// It appends the inline fragment selections to the resolved field and sets the fragment type. +func (r *rpcPlanningContext) enterResolverCompositeSelectionSet(oneOfType OneOfType, selectionSetRef int, resolvedField *resolverField) { + resolvedField.fieldsSelectionSetRef = ast.InvalidRef + resolvedField.fragmentType = oneOfType + + // In case of an interface we can select individual fields from the interface without having to use an inline fragment. + if len(r.operation.SelectionSetFieldRefs(selectionSetRef)) > 0 { + resolvedField.fieldsSelectionSetRef = selectionSetRef + } + + inlineFragSelections := r.operation.SelectionSetInlineFragmentSelections(selectionSetRef) + if len(inlineFragSelections) == 0 { + return + } + + for _, inlineFragSelectionRef := range inlineFragSelections { + inlineFragRef := r.operation.Selections[inlineFragSelectionRef].Ref + inlinFragSelectionSetRef, ok := r.operation.InlineFragmentSelectionSet(inlineFragRef) + if !ok { + continue + } + + resolvedField.fragmentSelections = append(resolvedField.fragmentSelections, fragmentSelection{ + typeName: r.operation.InlineFragmentTypeConditionNameString(inlineFragRef), + selectionSetRef: inlinFragSelectionSetRef, + }) + } +} + +// isFieldResolver checks if a field is a field resolver. +func (r *rpcPlanningContext) isFieldResolver(fieldRef int, isRootField bool) bool { + if isRootField { + return false + } + + return len(r.operation.FieldArguments(fieldRef)) > 0 +} + +// getCompositeType checks whether the node is an interface or union type. +// It returns OneOfTypeNone for non-composite types. +func (r *rpcPlanningContext) getCompositeType(node ast.Node) OneOfType { + switch node.Kind { + case ast.NodeKindInterfaceTypeDefinition: + return OneOfTypeInterface + case ast.NodeKindUnionTypeDefinition: + return OneOfTypeUnion + default: + return OneOfTypeNone + } +} + +func (r *rpcPlanningContext) getMemberTypes(node ast.Node) ([]string, error) { + switch node.Kind { + case ast.NodeKindInterfaceTypeDefinition: + memberTypes, ok := r.definition.InterfaceTypeDefinitionImplementedByObjectWithNames(node.Ref) + if !ok { + return nil, fmt.Errorf("interface type %s is not implemented by any object", r.definition.InterfaceTypeDefinitionNameString(node.Ref)) + } + return memberTypes, nil + case ast.NodeKindUnionTypeDefinition: + memberTypes, ok := r.definition.UnionTypeDefinitionMemberTypeNames(node.Ref) + if !ok { + return nil, fmt.Errorf("union type %s is not defined", r.definition.UnionTypeDefinitionNameString(node.Ref)) + } + return memberTypes, nil + default: + return nil, fmt.Errorf("invalid node kind: %s", node.Kind) + } } // setResolvedField sets the resolved field for a given field definition reference. -func (r *rpcPlanningContext) setResolvedField(walker *astvisitor.Walker, fieldDefRef int, fieldArgs []int, fieldPath ast.Path, resolvedField *resolvedField) error { +func (r *rpcPlanningContext) setResolvedField(walker *astvisitor.Walker, fieldDefRef int, fieldArgs []int, fieldPath ast.Path, resolvedField *resolverField) error { // We need to resolve the context fields for the given field definition reference. contextFields, err := r.resolveContextFields(walker, fieldDefRef) if err != nil { @@ -832,7 +986,7 @@ func (r *rpcPlanningContext) getFieldsFromFieldResolverDirective(parentNode ast. defer walker.Release() v := newRequiredFieldsVisitor(walker, &RPCMessage{}, r) - if err := v.visitRequiredFields(r.definition, parentNode.NameString(r.definition), fieldsString); err != nil { + if err := v.visitWithDefaults(r.definition, parentNode.NameString(r.definition), fieldsString); err != nil { return nil, err } @@ -890,38 +1044,176 @@ func (r *rpcPlanningContext) filterIDFieldsFunc(o ast.ObjectTypeDefinition, fiel type resolveRPCCallConfig struct { resolveConfig *ResolveRPCTypeField - resolvedField *resolvedField + resolvedField *resolverField contextMessage *RPCMessage fieldArgsMessage *RPCMessage } -func (r *rpcPlanningContext) resolveRequiredFields(typeName string, requiredFieldSelection int) (*RPCMessage, error) { - walker := astvisitor.WalkerFromPool() - defer walker.Release() +// buildFieldResolverTypeMessage builds the message for a given field resolver type. +// When a field resolver returns a complex or composite type, we need to build a message for the type. +func (r *rpcPlanningContext) buildFieldResolverTypeMessage(typeName string, resolverField *resolverField) (*RPCMessage, error) { message := &RPCMessage{ - Name: typeName, + Name: typeName, + OneOfType: resolverField.fragmentType, + MemberTypes: resolverField.memberTypes, } - rfv := newRequiredFieldsVisitor(walker, message, r) - if err := rfv.visitWithMemberTypes(r.definition, typeName, r.operation.SelectionSetFieldSetString(requiredFieldSelection), nil); err != nil { - return nil, err + // field resolvers which return a non scalar type must have a selection set. + // If we don't have a selection set we return an error. + if len(resolverField.fragmentSelections) == 0 && resolverField.fieldsSelectionSetRef == ast.InvalidRef { + return nil, errors.New("unable to resolve required fields: no fields selection set found") + } + + // If the resolved field returns a composite type we need to handle the selection set for the inline fragment. + if len(resolverField.fragmentSelections) > 0 { + message.FieldSelectionSet = make(RPCFieldSelectionSet, len(resolverField.fragmentSelections)) + + for _, fragmentSelection := range resolverField.fragmentSelections { + inlineFragmentTypeNode, found := r.definition.NodeByNameStr(fragmentSelection.typeName) + if !found { + return nil, fmt.Errorf("unable to build composite field: underlying fragment type node not found for type %s", fragmentSelection.typeName) + } + + fields, err := r.buildCompositeFields(inlineFragmentTypeNode, fragmentSelection) + if err != nil { + return nil, err + } + + message.FieldSelectionSet[fragmentSelection.typeName] = fields + } + } + + if resolverField.fieldsSelectionSetRef == ast.InvalidRef { + return message, nil + } + + // If the resolved field does not return a composite type we handle the selection set for the required field. + parentTypeNode, found := r.definition.NodeByNameStr(typeName) + if !found { + return nil, fmt.Errorf("parent type node not found for type %s", typeName) + } + + fieldRefs := r.operation.SelectionSetFieldRefs(resolverField.fieldsSelectionSetRef) + message.Fields = make(RPCFields, 0, len(fieldRefs)) + + for _, fieldRef := range fieldRefs { + if r.isFieldResolver(fieldRef, false) { + continue + } + + if message.Fields.Exists(r.operation.FieldNameString(fieldRef), "") { + continue + } + + field, err := r.buildRequiredField(parentTypeNode, fieldRef) + if err != nil { + return nil, err + } + + message.Fields = append(message.Fields, field) } + + message.Fields = slices.Clip(message.Fields) return message, nil } +func (r *rpcPlanningContext) buildRequiredField(typeNode ast.Node, fieldRef int) (RPCField, error) { + fieldName := r.operation.FieldNameString(fieldRef) + fieldDef, found := r.definition.NodeFieldDefinitionByName(typeNode, r.operation.FieldNameBytes(fieldRef)) + if !found { + return RPCField{}, fmt.Errorf("unable to build required field: field definition not found for field %s", fieldName) + } + + field, err := r.buildField(typeNode, fieldDef, r.operation.FieldNameString(fieldRef), "") + if err != nil { + return RPCField{}, err + } + + // If the field is a message type and has selections, we need to build a nested message. + if field.ProtoTypeName == DataTypeMessage && r.operation.FieldHasSelections(fieldRef) { + fieldTypeNode, found := r.definition.ResolveNodeFromTypeRef(r.definition.FieldDefinitionType(fieldDef)) + if !found { + return RPCField{}, fmt.Errorf("unable to build required field: unable to resolve field type node for field %s", fieldName) + } + + message, err := r.buildFieldMessage(fieldTypeNode, fieldRef) + if err != nil { + return RPCField{}, err + } + + field.Message = message + } + + return field, nil +} + +// buildCompositeFields creates fields for a given inline fragment node and its selection set. +// It returns a list of fields that have been composed from the inputs. +func (r *rpcPlanningContext) buildCompositeFields(inlineFragmentNode ast.Node, fragmentSelection fragmentSelection) ([]RPCField, error) { + fieldRefs := r.operation.SelectionSetFieldRefs(fragmentSelection.selectionSetRef) + result := make([]RPCField, 0, len(fieldRefs)) + + for _, fieldRef := range fieldRefs { + if r.isFieldResolver(fieldRef, false) { + continue + } + + fieldDef := r.fieldDefinitionRefForType(r.operation.FieldNameString(fieldRef), fragmentSelection.typeName) + if fieldDef == ast.InvalidRef { + return nil, fmt.Errorf("unable to build composite field: field definition not found for field %s", r.operation.FieldNameString(fieldRef)) + } + + field, err := r.buildField(inlineFragmentNode, fieldDef, r.operation.FieldNameString(fieldRef), "") + if err != nil { + return nil, err + } + + if field.ProtoTypeName == DataTypeMessage && r.operation.FieldHasSelections(fieldRef) { + fieldTypeNode, found := r.definition.ResolveNodeFromTypeRef(r.definition.FieldDefinitionType(fieldDef)) + if !found { + return nil, fmt.Errorf("unable to build composite field: unable to resolve field type node for field %s", r.operation.FieldNameString(fieldRef)) + } + + message, err := r.buildFieldMessage(fieldTypeNode, fieldRef) + if err != nil { + return nil, err + } + + field.Message = message + } + + result = append(result, field) + } + return result, nil +} + +func (r *rpcPlanningContext) fieldDefinitionRefForType(fieldName, typeName string) int { + node, found := r.definition.NodeByNameStr(typeName) + if !found { + return ast.InvalidRef + } + + if ref, found := r.definition.NodeFieldDefinitionByName(node, unsafebytes.StringToBytes(fieldName)); found { + return ref + } + + return ast.InvalidRef + +} + // createResolverRPCCalls creates a new call for each resolved field. -func (r *rpcPlanningContext) createResolverRPCCalls(subgraphName string, resolvedFields []resolvedField) ([]RPCCall, error) { +func (r *rpcPlanningContext) createResolverRPCCalls(subgraphName string, resolvedFields []resolverField) ([]RPCCall, error) { // We need to create a new call for each resolved field. calls := make([]RPCCall, 0, len(resolvedFields)) for _, resolvedField := range resolvedFields { resolveConfig := r.mapping.FindResolveTypeFieldMapping( - r.definition.ObjectTypeDefinitionNameString(resolvedField.parentTypeRef), + resolvedField.parentTypeNode.NameString(r.definition), r.operation.FieldNameString(resolvedField.fieldRef), ) if resolveConfig == nil { - return nil, fmt.Errorf("resolve config not found for type: %s, field: %s", r.definition.ResolveTypeNameString(resolvedField.parentTypeRef), r.operation.FieldAliasString(resolvedField.fieldRef)) + return nil, fmt.Errorf("resolve config not found for type: %s, field: %s", r.definition.NodeNameString(resolvedField.parentTypeNode), r.operation.FieldAliasString(resolvedField.fieldRef)) } contextMessage := &RPCMessage{ @@ -947,13 +1239,9 @@ func (r *rpcPlanningContext) createResolverRPCCalls(subgraphName string, resolve contextMessage.Fields = make(RPCFields, len(resolvedField.contextFields)) for i := range resolvedField.contextFields { - typeDefNode, found := r.definition.NodeByNameStr(r.definition.ResolveTypeNameString(resolvedField.parentTypeRef)) - if !found { - return nil, fmt.Errorf("type definition node not found for type: %s", r.definition.ResolveTypeNameString(resolvedField.parentTypeRef)) - } field, err := r.buildField( - typeDefNode, + resolvedField.parentTypeNode, resolvedField.contextFields[i].fieldRef, r.definition.FieldDefinitionNameString(resolvedField.contextFields[i].fieldRef), "", @@ -1002,9 +1290,9 @@ func (r *rpcPlanningContext) newResolveRPCCall(config *resolveRPCCallConfig) (RP var responseFieldsMessage *RPCMessage if dataType == DataTypeMessage { var err error - responseFieldsMessage, err = r.resolveRequiredFields( + responseFieldsMessage, err = r.buildFieldResolverTypeMessage( r.definition.ResolveTypeNameString(underlyingTypeRef), - resolvedField.fieldsSelectionSetRef, + resolvedField, ) if err != nil { diff --git a/v2/pkg/engine/datasource/grpc_datasource/execution_plan_federation_test.go b/v2/pkg/engine/datasource/grpc_datasource/execution_plan_federation_test.go index 21d0a8615..7f19058c3 100644 --- a/v2/pkg/engine/datasource/grpc_datasource/execution_plan_federation_test.go +++ b/v2/pkg/engine/datasource/grpc_datasource/execution_plan_federation_test.go @@ -862,6 +862,127 @@ func TestEntityKeys(t *testing.T) { }, }, }, + { + name: "Should create an execution plan for an entity lookup with a key field and nested field", + query: `query EntityLookup($representations: [_Any!]!) { _entities(representations: $representations) { ... on User { __typename id name address { street } } } }`, + schema: testFederationSchemaString(` + type Query { + _entities(representations: [_Any!]!): [_Entity]! + } + type User @key(fields: "id") { + id: ID! + name: String! + address: Address! + } + + type Address { + id: ID! + street: String! + } + `, []string{"User"}), + mapping: &GRPCMapping{ + Service: "Products", + EntityRPCs: map[string][]EntityRPCConfig{ + "User": { + { + Key: "id", + RPCConfig: RPCConfig{ + RPC: "LookupUserById", + Request: "LookupUserByIdRequest", + Response: "LookupUserByIdResponse", + }, + }, + }, + }, + }, + federationConfigs: plan.FederationFieldConfigurations{ + { + TypeName: "User", + SelectionSet: "id", + }, + }, + + expectedPlan: &RPCExecutionPlan{ + Calls: []RPCCall{ + { + ServiceName: "Products", + MethodName: "LookupUserById", + Kind: CallKindEntity, + // Define the structure of the request message + Request: RPCMessage{ + Name: "LookupUserByIdRequest", + Fields: []RPCField{ + { + Name: "keys", + ProtoTypeName: DataTypeMessage, + Repeated: true, + JSONPath: "representations", + Message: &RPCMessage{ + Name: "LookupUserByIdKey", + MemberTypes: []string{"User"}, + Fields: []RPCField{ + { + Name: "id", + ProtoTypeName: DataTypeString, + JSONPath: "id", + }, + }, + }, + }, + }, + }, + // Define the structure of the response message + Response: RPCMessage{ + Name: "LookupUserByIdResponse", + Fields: []RPCField{ + { + Name: "result", + ProtoTypeName: DataTypeMessage, + Repeated: true, + JSONPath: "_entities", + Message: &RPCMessage{ + Name: "User", + Fields: []RPCField{ + { + Name: "__typename", + ProtoTypeName: DataTypeString, + JSONPath: "__typename", + StaticValue: "User", + }, + { + Name: "id", + ProtoTypeName: DataTypeString, + JSONPath: "id", + }, + { + Name: "name", + ProtoTypeName: DataTypeString, + JSONPath: "name", + }, + { + Name: "address", + ProtoTypeName: DataTypeMessage, + JSONPath: "address", + Message: &RPCMessage{ + Name: "Address", + Fields: []RPCField{ + { + Name: "street", + ProtoTypeName: DataTypeString, + JSONPath: "street", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, } for _, tt := range tests { @@ -1323,6 +1444,649 @@ func TestEntityLookupWithFieldResolvers(t *testing.T) { } } +func TestEntityLookupWithFieldResolvers_WithCompositeTypes(t *testing.T) { + t.Parallel() + tests := []struct { + name string + query string + expectedPlan *RPCExecutionPlan + mapping *GRPCMapping + federationConfigs plan.FederationFieldConfigurations + }{ + { + name: "Should create an execution plan for an entity lookup with a field resolver returning interface type", + query: `query EntityLookupWithInterface($representations: [_Any!]!, $includeDetails: Boolean!) { _entities(representations: $representations) { ... on Product { __typename id name mascotRecommendation(includeDetails: $includeDetails) { ... on Cat { name meowVolume } ... on Dog { name barkVolume } } } } }`, + mapping: testMapping(), + federationConfigs: plan.FederationFieldConfigurations{ + { + TypeName: "Product", + SelectionSet: "id", + }, + }, + expectedPlan: &RPCExecutionPlan{ + Calls: []RPCCall{ + { + ServiceName: "Products", + MethodName: "LookupProductById", + Kind: CallKindEntity, + Request: RPCMessage{ + Name: "LookupProductByIdRequest", + Fields: []RPCField{ + { + Name: "keys", + ProtoTypeName: DataTypeMessage, + Repeated: true, + JSONPath: "representations", + Message: &RPCMessage{ + Name: "LookupProductByIdKey", + MemberTypes: []string{"Product"}, + Fields: []RPCField{ + { + Name: "id", + ProtoTypeName: DataTypeString, + JSONPath: "id", + }, + }, + }, + }, + }, + }, + Response: RPCMessage{ + Name: "LookupProductByIdResponse", + Fields: []RPCField{ + { + Name: "result", + ProtoTypeName: DataTypeMessage, + Repeated: true, + JSONPath: "_entities", + Message: &RPCMessage{ + Name: "Product", + Fields: []RPCField{ + { + Name: "__typename", + ProtoTypeName: DataTypeString, + JSONPath: "__typename", + StaticValue: "Product", + }, + { + Name: "id", + ProtoTypeName: DataTypeString, + JSONPath: "id", + }, + { + Name: "name", + ProtoTypeName: DataTypeString, + JSONPath: "name", + }, + }, + }, + }, + }, + }, + }, + { + ServiceName: "Products", + MethodName: "ResolveProductMascotRecommendation", + Kind: CallKindResolve, + DependentCalls: []int{0}, + ResponsePath: buildPath("_entities.mascotRecommendation"), + Request: RPCMessage{ + Name: "ResolveProductMascotRecommendationRequest", + Fields: []RPCField{ + { + Name: "context", + ProtoTypeName: DataTypeMessage, + JSONPath: "", + Repeated: true, + Message: &RPCMessage{ + Name: "ResolveProductMascotRecommendationContext", + Fields: []RPCField{ + { + Name: "id", + ProtoTypeName: DataTypeString, + JSONPath: "id", + ResolvePath: buildPath("result.id"), + }, + { + Name: "name", + ProtoTypeName: DataTypeString, + JSONPath: "name", + ResolvePath: buildPath("result.name"), + }, + }, + }, + }, + { + Name: "field_args", + ProtoTypeName: DataTypeMessage, + JSONPath: "", + Message: &RPCMessage{ + Name: "ResolveProductMascotRecommendationArgs", + Fields: []RPCField{ + { + Name: "include_details", + ProtoTypeName: DataTypeBool, + JSONPath: "includeDetails", + }, + }, + }, + }, + }, + }, + Response: RPCMessage{ + Name: "ResolveProductMascotRecommendationResponse", + Fields: []RPCField{ + { + Name: "result", + ProtoTypeName: DataTypeMessage, + JSONPath: "result", + Repeated: true, + Message: &RPCMessage{ + Name: "ResolveProductMascotRecommendationResult", + Fields: []RPCField{ + { + Name: "mascot_recommendation", + ProtoTypeName: DataTypeMessage, + JSONPath: "mascotRecommendation", + Optional: true, + Message: &RPCMessage{ + Name: "Animal", + OneOfType: OneOfTypeInterface, + MemberTypes: []string{"Cat", "Dog"}, + FieldSelectionSet: RPCFieldSelectionSet{ + "Cat": { + { + Name: "name", + ProtoTypeName: DataTypeString, + JSONPath: "name", + }, + { + Name: "meow_volume", + ProtoTypeName: DataTypeInt32, + JSONPath: "meowVolume", + }, + }, + "Dog": { + { + Name: "name", + ProtoTypeName: DataTypeString, + JSONPath: "name", + }, + { + Name: "bark_volume", + ProtoTypeName: DataTypeInt32, + JSONPath: "barkVolume", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + { + name: "Should create an execution plan for an entity lookup with a field resolver returning union type", + query: `query EntityLookupWithUnion($representations: [_Any!]!, $checkAvailability: Boolean!) { _entities(representations: $representations) { ... on Product { __typename id name stockStatus(checkAvailability: $checkAvailability) { ... on ActionSuccess { message timestamp } ... on ActionError { message code } } } } }`, + mapping: testMapping(), + federationConfigs: plan.FederationFieldConfigurations{ + { + TypeName: "Product", + SelectionSet: "id", + }, + }, + expectedPlan: &RPCExecutionPlan{ + Calls: []RPCCall{ + { + ServiceName: "Products", + MethodName: "LookupProductById", + Kind: CallKindEntity, + Request: RPCMessage{ + Name: "LookupProductByIdRequest", + Fields: []RPCField{ + { + Name: "keys", + ProtoTypeName: DataTypeMessage, + Repeated: true, + JSONPath: "representations", + Message: &RPCMessage{ + Name: "LookupProductByIdKey", + MemberTypes: []string{"Product"}, + Fields: []RPCField{ + { + Name: "id", + ProtoTypeName: DataTypeString, + JSONPath: "id", + }, + }, + }, + }, + }, + }, + Response: RPCMessage{ + Name: "LookupProductByIdResponse", + Fields: []RPCField{ + { + Name: "result", + ProtoTypeName: DataTypeMessage, + Repeated: true, + JSONPath: "_entities", + Message: &RPCMessage{ + Name: "Product", + Fields: []RPCField{ + { + Name: "__typename", + ProtoTypeName: DataTypeString, + JSONPath: "__typename", + StaticValue: "Product", + }, + { + Name: "id", + ProtoTypeName: DataTypeString, + JSONPath: "id", + }, + { + Name: "name", + ProtoTypeName: DataTypeString, + JSONPath: "name", + }, + }, + }, + }, + }, + }, + }, + { + ServiceName: "Products", + MethodName: "ResolveProductStockStatus", + Kind: CallKindResolve, + DependentCalls: []int{0}, + ResponsePath: buildPath("_entities.stockStatus"), + Request: RPCMessage{ + Name: "ResolveProductStockStatusRequest", + Fields: []RPCField{ + { + Name: "context", + ProtoTypeName: DataTypeMessage, + JSONPath: "", + Repeated: true, + Message: &RPCMessage{ + Name: "ResolveProductStockStatusContext", + Fields: []RPCField{ + { + Name: "id", + ProtoTypeName: DataTypeString, + JSONPath: "id", + ResolvePath: buildPath("result.id"), + }, + { + Name: "name", + ProtoTypeName: DataTypeString, + JSONPath: "name", + ResolvePath: buildPath("result.name"), + }, + { + Name: "price", + ProtoTypeName: DataTypeDouble, + JSONPath: "price", + ResolvePath: buildPath("result.price"), + }, + }, + }, + }, + { + Name: "field_args", + ProtoTypeName: DataTypeMessage, + JSONPath: "", + Message: &RPCMessage{ + Name: "ResolveProductStockStatusArgs", + Fields: []RPCField{ + { + Name: "check_availability", + ProtoTypeName: DataTypeBool, + JSONPath: "checkAvailability", + }, + }, + }, + }, + }, + }, + Response: RPCMessage{ + Name: "ResolveProductStockStatusResponse", + Fields: []RPCField{ + { + Name: "result", + ProtoTypeName: DataTypeMessage, + JSONPath: "result", + Repeated: true, + Message: &RPCMessage{ + Name: "ResolveProductStockStatusResult", + Fields: []RPCField{ + { + Name: "stock_status", + ProtoTypeName: DataTypeMessage, + JSONPath: "stockStatus", + Message: &RPCMessage{ + Name: "ActionResult", + OneOfType: OneOfTypeUnion, + MemberTypes: []string{"ActionSuccess", "ActionError"}, + FieldSelectionSet: RPCFieldSelectionSet{ + "ActionSuccess": { + { + Name: "message", + ProtoTypeName: DataTypeString, + JSONPath: "message", + }, + { + Name: "timestamp", + ProtoTypeName: DataTypeString, + JSONPath: "timestamp", + }, + }, + "ActionError": { + { + Name: "message", + ProtoTypeName: DataTypeString, + JSONPath: "message", + }, + { + Name: "code", + ProtoTypeName: DataTypeString, + JSONPath: "code", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + { + name: "Should create an execution plan for an entity lookup with a field resolver returning nested composite types", + query: `query EntityLookupWithNested($representations: [_Any!]!, $includeExtended: Boolean!) { _entities(representations: $representations) { ... on Product { __typename id name price productDetails(includeExtended: $includeExtended) { id description recommendedPet { ... on Cat { name meowVolume } ... on Dog { name barkVolume } } reviewSummary { ... on ActionSuccess { message timestamp } ... on ActionError { message code } } } } } }`, + mapping: testMapping(), + federationConfigs: plan.FederationFieldConfigurations{ + { + TypeName: "Product", + SelectionSet: "id", + }, + }, + expectedPlan: &RPCExecutionPlan{ + Calls: []RPCCall{ + { + ServiceName: "Products", + MethodName: "LookupProductById", + Kind: CallKindEntity, + Request: RPCMessage{ + Name: "LookupProductByIdRequest", + Fields: []RPCField{ + { + Name: "keys", + ProtoTypeName: DataTypeMessage, + Repeated: true, + JSONPath: "representations", + Message: &RPCMessage{ + Name: "LookupProductByIdKey", + MemberTypes: []string{"Product"}, + Fields: []RPCField{ + { + Name: "id", + ProtoTypeName: DataTypeString, + JSONPath: "id", + }, + }, + }, + }, + }, + }, + Response: RPCMessage{ + Name: "LookupProductByIdResponse", + Fields: []RPCField{ + { + Name: "result", + ProtoTypeName: DataTypeMessage, + Repeated: true, + JSONPath: "_entities", + Message: &RPCMessage{ + Name: "Product", + Fields: []RPCField{ + { + Name: "__typename", + ProtoTypeName: DataTypeString, + JSONPath: "__typename", + StaticValue: "Product", + }, + { + Name: "id", + ProtoTypeName: DataTypeString, + JSONPath: "id", + }, + { + Name: "name", + ProtoTypeName: DataTypeString, + JSONPath: "name", + }, + { + Name: "price", + ProtoTypeName: DataTypeDouble, + JSONPath: "price", + }, + }, + }, + }, + }, + }, + }, + { + ServiceName: "Products", + MethodName: "ResolveProductProductDetails", + Kind: CallKindResolve, + DependentCalls: []int{0}, + ResponsePath: buildPath("_entities.productDetails"), + Request: RPCMessage{ + Name: "ResolveProductProductDetailsRequest", + Fields: []RPCField{ + { + Name: "context", + ProtoTypeName: DataTypeMessage, + JSONPath: "", + Repeated: true, + Message: &RPCMessage{ + Name: "ResolveProductProductDetailsContext", + Fields: []RPCField{ + { + Name: "id", + ProtoTypeName: DataTypeString, + JSONPath: "id", + ResolvePath: buildPath("result.id"), + }, + { + Name: "name", + ProtoTypeName: DataTypeString, + JSONPath: "name", + ResolvePath: buildPath("result.name"), + }, + { + Name: "price", + ProtoTypeName: DataTypeDouble, + JSONPath: "price", + ResolvePath: buildPath("result.price"), + }, + }, + }, + }, + { + Name: "field_args", + ProtoTypeName: DataTypeMessage, + JSONPath: "", + Message: &RPCMessage{ + Name: "ResolveProductProductDetailsArgs", + Fields: []RPCField{ + { + Name: "include_extended", + ProtoTypeName: DataTypeBool, + JSONPath: "includeExtended", + }, + }, + }, + }, + }, + }, + Response: RPCMessage{ + Name: "ResolveProductProductDetailsResponse", + Fields: []RPCField{ + { + Name: "result", + ProtoTypeName: DataTypeMessage, + JSONPath: "result", + Repeated: true, + Message: &RPCMessage{ + Name: "ResolveProductProductDetailsResult", + Fields: []RPCField{ + { + Name: "product_details", + ProtoTypeName: DataTypeMessage, + JSONPath: "productDetails", + Optional: true, + Message: &RPCMessage{ + Name: "ProductDetails", + Fields: []RPCField{ + { + Name: "id", + ProtoTypeName: DataTypeString, + JSONPath: "id", + }, + { + Name: "description", + ProtoTypeName: DataTypeString, + JSONPath: "description", + }, + { + Name: "recommended_pet", + ProtoTypeName: DataTypeMessage, + JSONPath: "recommendedPet", + Message: &RPCMessage{ + Name: "Animal", + OneOfType: OneOfTypeInterface, + MemberTypes: []string{"Cat", "Dog"}, + FieldSelectionSet: RPCFieldSelectionSet{ + "Cat": { + { + Name: "name", + ProtoTypeName: DataTypeString, + JSONPath: "name", + }, + { + Name: "meow_volume", + ProtoTypeName: DataTypeInt32, + JSONPath: "meowVolume", + }, + }, + "Dog": { + { + Name: "name", + ProtoTypeName: DataTypeString, + JSONPath: "name", + }, + { + Name: "bark_volume", + ProtoTypeName: DataTypeInt32, + JSONPath: "barkVolume", + }, + }, + }, + }, + }, + { + Name: "review_summary", + ProtoTypeName: DataTypeMessage, + JSONPath: "reviewSummary", + Message: &RPCMessage{ + Name: "ActionResult", + OneOfType: OneOfTypeUnion, + MemberTypes: []string{"ActionSuccess", "ActionError"}, + FieldSelectionSet: RPCFieldSelectionSet{ + "ActionSuccess": { + { + Name: "message", + ProtoTypeName: DataTypeString, + JSONPath: "message", + }, + { + Name: "timestamp", + ProtoTypeName: DataTypeString, + JSONPath: "timestamp", + }, + }, + "ActionError": { + { + Name: "message", + ProtoTypeName: DataTypeString, + JSONPath: "message", + }, + { + Name: "code", + ProtoTypeName: DataTypeString, + JSONPath: "code", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + // Parse the GraphQL schema + schemaDoc := grpctest.MustGraphQLSchema(t) + + // Parse the GraphQL query + queryDoc, report := astparser.ParseGraphqlDocumentString(tt.query) + if report.HasErrors() { + t.Fatalf("failed to parse query: %s", report.Error()) + } + + planner, err := NewPlanner("Products", tt.mapping, tt.federationConfigs) + if err != nil { + t.Fatalf("failed to create planner: %s", err) + } + plan, err := planner.PlanOperation(&queryDoc, &schemaDoc) + if err != nil { + t.Fatalf("failed to plan operation: %s", err) + } + + diff := cmp.Diff(tt.expectedPlan, plan) + if diff != "" { + t.Fatalf("execution plan mismatch: %s", diff) + } + }) + } +} + func runFederationTest(t *testing.T, tt struct { name string query string diff --git a/v2/pkg/engine/datasource/grpc_datasource/execution_plan_field_resolvers_test.go b/v2/pkg/engine/datasource/grpc_datasource/execution_plan_field_resolvers_test.go index a07573ba9..5f702f6ff 100644 --- a/v2/pkg/engine/datasource/grpc_datasource/execution_plan_field_resolvers_test.go +++ b/v2/pkg/engine/datasource/grpc_datasource/execution_plan_field_resolvers_test.go @@ -2,6 +2,11 @@ package grpcdatasource import ( "testing" + + "github.com/wundergraph/graphql-go-tools/v2/pkg/ast" + "github.com/wundergraph/graphql-go-tools/v2/pkg/astvalidation" + "github.com/wundergraph/graphql-go-tools/v2/pkg/internal/unsafeparser" + "github.com/wundergraph/graphql-go-tools/v2/pkg/operationreport" ) func TestExecutionPlanFieldResolvers(t *testing.T) { @@ -14,7 +19,7 @@ func TestExecutionPlanFieldResolvers(t *testing.T) { }{ { name: "Should create an execution plan for a query with a field resolver", - query: "query CategoriesWithFieldResolvers($whoop: ProductCountFilter) { categories { id name kind productCount(filters: $whoop) } }", + query: "query CategoriesWithFieldResolvers($whoop: ProductCountFilter) { categories { id productCount(filters: $whoop) name kind } }", expectedPlan: &RPCExecutionPlan{ Calls: []RPCCall{ { @@ -892,3 +897,1724 @@ func TestExecutionPlanFieldResolvers(t *testing.T) { }) } } + +func TestExecutionPlanFieldResolvers_WithNestedResolvers(t *testing.T) { + t.Parallel() + tests := []struct { + name string + query string + expectedPlan *RPCExecutionPlan + expectedError string + }{ + { + name: "Should create an execution plan for a query with nested field resolvers", + query: "query CategoriesWithNestedResolvers($metricType: String, $baseline: Float!) { categories { categoryMetrics(metricType: $metricType) { id normalizedScore(baseline: $baseline) metricType value } } }", + expectedPlan: &RPCExecutionPlan{ + Calls: []RPCCall{ + { + ServiceName: "Products", + MethodName: "QueryCategories", + Request: RPCMessage{ + Name: "QueryCategoriesRequest", + }, + Response: RPCMessage{ + Name: "QueryCategoriesResponse", + Fields: []RPCField{ + { + Name: "categories", + ProtoTypeName: DataTypeMessage, + JSONPath: "categories", + Repeated: true, + Message: &RPCMessage{ + Name: "Category", + Fields: []RPCField{}, + }, + }, + }, + }, + }, + { + DependentCalls: []int{0}, + ServiceName: "Products", + MethodName: "ResolveCategoryCategoryMetrics", + Kind: CallKindResolve, + ResponsePath: buildPath("categories.categoryMetrics"), + Request: RPCMessage{ + Name: "ResolveCategoryCategoryMetricsRequest", + Fields: []RPCField{ + { + Name: "context", + ProtoTypeName: DataTypeMessage, + Repeated: true, + Message: &RPCMessage{ + Name: "ResolveCategoryCategoryMetricsContext", + Fields: []RPCField{ + { + Name: "id", + ProtoTypeName: DataTypeString, + JSONPath: "id", + ResolvePath: buildPath("categories.id"), + }, + { + Name: "name", + ProtoTypeName: DataTypeString, + JSONPath: "name", + ResolvePath: buildPath("categories.name"), + }, + }, + }, + }, + { + Name: "field_args", + ProtoTypeName: DataTypeMessage, + Message: &RPCMessage{ + Name: "ResolveCategoryCategoryMetricsArgs", + Fields: []RPCField{ + { + Name: "metric_type", + ProtoTypeName: DataTypeString, + JSONPath: "metricType", + }, + }, + }, + }, + }, + }, + Response: RPCMessage{ + Name: "ResolveCategoryCategoryMetricsResponse", + Fields: []RPCField{ + { + Name: "result", + ProtoTypeName: DataTypeMessage, + JSONPath: "result", + Repeated: true, + Message: &RPCMessage{ + Name: "ResolveCategoryCategoryMetricsResult", + Fields: []RPCField{ + { + Name: "category_metrics", + ProtoTypeName: DataTypeMessage, + JSONPath: "categoryMetrics", + Optional: true, + Message: &RPCMessage{ + Name: "CategoryMetrics", + Fields: []RPCField{ + { + Name: "id", + ProtoTypeName: DataTypeString, + JSONPath: "id", + }, + { + Name: "metric_type", + ProtoTypeName: DataTypeString, + JSONPath: "metricType", + }, + { + Name: "value", + ProtoTypeName: DataTypeDouble, + JSONPath: "value", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + { + DependentCalls: []int{1}, + ServiceName: "Products", + MethodName: "ResolveCategoryMetricsNormalizedScore", + Kind: CallKindResolve, + ResponsePath: buildPath("categories.categoryMetrics.normalizedScore"), + Request: RPCMessage{ + Name: "ResolveCategoryMetricsNormalizedScoreRequest", + Fields: []RPCField{ + { + Name: "context", + ProtoTypeName: DataTypeMessage, + Repeated: true, + Message: &RPCMessage{ + Name: "ResolveCategoryMetricsNormalizedScoreContext", + Fields: []RPCField{ + { + Name: "id", + ProtoTypeName: DataTypeString, + JSONPath: "id", + ResolvePath: buildPath("categories.categoryMetrics.id"), + }, + { + Name: "value", + ProtoTypeName: DataTypeDouble, + JSONPath: "value", + ResolvePath: buildPath("categories.categoryMetrics.value"), + }, + { + Name: "metric_type", + ProtoTypeName: DataTypeString, + JSONPath: "metricType", + ResolvePath: buildPath("categories.categoryMetrics.metricType"), + }, + }, + }, + }, + { + Name: "field_args", + ProtoTypeName: DataTypeMessage, + Message: &RPCMessage{ + Name: "ResolveCategoryMetricsNormalizedScoreArgs", + Fields: []RPCField{ + { + Name: "baseline", + ProtoTypeName: DataTypeDouble, + JSONPath: "baseline", + }, + }, + }, + }, + }, + }, + Response: RPCMessage{ + Name: "ResolveCategoryMetricsNormalizedScoreResponse", + Fields: []RPCField{ + { + Name: "result", + ProtoTypeName: DataTypeMessage, + JSONPath: "result", + Repeated: true, + Message: &RPCMessage{ + Name: "ResolveCategoryMetricsNormalizedScoreResult", + Fields: []RPCField{ + { + Name: "normalized_score", + ProtoTypeName: DataTypeDouble, + JSONPath: "normalizedScore", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + runTest(t, testCase{ + query: tt.query, + expectedPlan: tt.expectedPlan, + expectedError: tt.expectedError, + }) + }) + } +} + +func TestExecutionPlanFieldResolvers_WithCompositeTypes(t *testing.T) { + t.Parallel() + tests := []struct { + name string + query string + expectedPlan *RPCExecutionPlan + expectedError string + }{ + { + name: "Should create an execution plan for a query with interface type", + query: "query CategoriesWithNestedResolvers($includeVolume: Boolean!) { categories { mascot(includeVolume: $includeVolume) { ... on Cat { name } ... on Dog { name } } } }", + expectedPlan: &RPCExecutionPlan{ + Calls: []RPCCall{ + { + ServiceName: "Products", + MethodName: "QueryCategories", + Request: RPCMessage{ + Name: "QueryCategoriesRequest", + }, + Response: RPCMessage{ + Name: "QueryCategoriesResponse", + Fields: []RPCField{ + { + Name: "categories", + ProtoTypeName: DataTypeMessage, + JSONPath: "categories", + Repeated: true, + Message: &RPCMessage{ + Name: "Category", + Fields: []RPCField{}, + }, + }, + }, + }, + }, + { + DependentCalls: []int{0}, + ServiceName: "Products", + MethodName: "ResolveCategoryMascot", + Kind: CallKindResolve, + ResponsePath: buildPath("categories.mascot"), + Request: RPCMessage{ + Name: "ResolveCategoryMascotRequest", + Fields: []RPCField{ + { + Name: "context", + ProtoTypeName: DataTypeMessage, + Repeated: true, + Message: &RPCMessage{ + Name: "ResolveCategoryMascotContext", + Fields: []RPCField{ + { + Name: "id", + ProtoTypeName: DataTypeString, + JSONPath: "id", + ResolvePath: buildPath("categories.id"), + }, + { + Name: "kind", + ProtoTypeName: DataTypeEnum, + JSONPath: "kind", + EnumName: "CategoryKind", + ResolvePath: buildPath("categories.kind"), + }, + }, + }, + }, + { + Name: "field_args", + ProtoTypeName: DataTypeMessage, + Message: &RPCMessage{ + Name: "ResolveCategoryMascotArgs", + Fields: []RPCField{ + { + Name: "include_volume", + ProtoTypeName: DataTypeBool, + JSONPath: "includeVolume", + }, + }, + }, + }, + }, + }, + Response: RPCMessage{ + Name: "ResolveCategoryMascotResponse", + Fields: []RPCField{ + { + Name: "result", + ProtoTypeName: DataTypeMessage, + JSONPath: "result", + Repeated: true, + Message: &RPCMessage{ + Name: "ResolveCategoryMascotResult", + Fields: []RPCField{ + { + Name: "mascot", + ProtoTypeName: DataTypeMessage, + JSONPath: "mascot", + Optional: true, + Message: &RPCMessage{ + Name: "Animal", + OneOfType: OneOfTypeInterface, + MemberTypes: []string{"Cat", "Dog"}, + FieldSelectionSet: RPCFieldSelectionSet{ + "Cat": { + { + Name: "name", + ProtoTypeName: DataTypeString, + JSONPath: "name", + }, + }, + "Dog": { + { + Name: "name", + ProtoTypeName: DataTypeString, + JSONPath: "name", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + { + name: "Should create an execution plan for a query with union type", + query: "query CategoriesWithUnionResolver($checkHealth: Boolean!) { categories { categoryStatus(checkHealth: $checkHealth) { ... on ActionSuccess { message timestamp } ... on ActionError { message code } } } }", + expectedPlan: &RPCExecutionPlan{ + Calls: []RPCCall{ + { + ServiceName: "Products", + MethodName: "QueryCategories", + Request: RPCMessage{ + Name: "QueryCategoriesRequest", + }, + Response: RPCMessage{ + Name: "QueryCategoriesResponse", + Fields: []RPCField{ + { + Name: "categories", + ProtoTypeName: DataTypeMessage, + JSONPath: "categories", + Repeated: true, + Message: &RPCMessage{ + Name: "Category", + Fields: []RPCField{}, + }, + }, + }, + }, + }, + { + DependentCalls: []int{0}, + ServiceName: "Products", + MethodName: "ResolveCategoryCategoryStatus", + Kind: CallKindResolve, + ResponsePath: buildPath("categories.categoryStatus"), + Request: RPCMessage{ + Name: "ResolveCategoryCategoryStatusRequest", + Fields: []RPCField{ + { + Name: "context", + ProtoTypeName: DataTypeMessage, + Repeated: true, + Message: &RPCMessage{ + Name: "ResolveCategoryCategoryStatusContext", + Fields: []RPCField{ + { + Name: "id", + ProtoTypeName: DataTypeString, + JSONPath: "id", + ResolvePath: buildPath("categories.id"), + }, + { + Name: "name", + ProtoTypeName: DataTypeString, + JSONPath: "name", + ResolvePath: buildPath("categories.name"), + }, + }, + }, + }, + { + Name: "field_args", + ProtoTypeName: DataTypeMessage, + Message: &RPCMessage{ + Name: "ResolveCategoryCategoryStatusArgs", + Fields: []RPCField{ + { + Name: "check_health", + ProtoTypeName: DataTypeBool, + JSONPath: "checkHealth", + }, + }, + }, + }, + }, + }, + Response: RPCMessage{ + Name: "ResolveCategoryCategoryStatusResponse", + Fields: []RPCField{ + { + Name: "result", + ProtoTypeName: DataTypeMessage, + JSONPath: "result", + Repeated: true, + Message: &RPCMessage{ + Name: "ResolveCategoryCategoryStatusResult", + Fields: []RPCField{ + { + Name: "category_status", + ProtoTypeName: DataTypeMessage, + JSONPath: "categoryStatus", + Message: &RPCMessage{ + Name: "ActionResult", + OneOfType: OneOfTypeUnion, + MemberTypes: []string{"ActionSuccess", "ActionError"}, + FieldSelectionSet: RPCFieldSelectionSet{ + "ActionSuccess": { + { + Name: "message", + ProtoTypeName: DataTypeString, + JSONPath: "message", + }, + { + Name: "timestamp", + ProtoTypeName: DataTypeString, + JSONPath: "timestamp", + }, + }, + "ActionError": { + { + Name: "message", + ProtoTypeName: DataTypeString, + JSONPath: "message", + }, + { + Name: "code", + ProtoTypeName: DataTypeString, + JSONPath: "code", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + { + name: "Should create an execution plan for a query with nested interface type", + query: "query TestContainersWithInterface($includeExtended: Boolean!) { testContainers { id name details(includeExtended: $includeExtended) { id summary pet { ... on Cat { name meowVolume } ... on Dog { name barkVolume } } } } }", + expectedPlan: &RPCExecutionPlan{ + Calls: []RPCCall{ + { + ServiceName: "Products", + MethodName: "QueryTestContainers", + Request: RPCMessage{ + Name: "QueryTestContainersRequest", + }, + Response: RPCMessage{ + Name: "QueryTestContainersResponse", + Fields: []RPCField{ + { + Name: "test_containers", + ProtoTypeName: DataTypeMessage, + JSONPath: "testContainers", + Repeated: true, + Message: &RPCMessage{ + Name: "TestContainer", + Fields: []RPCField{ + { + Name: "id", + ProtoTypeName: DataTypeString, + JSONPath: "id", + }, + { + Name: "name", + ProtoTypeName: DataTypeString, + JSONPath: "name", + }, + }, + }, + }, + }, + }, + }, + { + DependentCalls: []int{0}, + ServiceName: "Products", + MethodName: "ResolveTestContainerDetails", + Kind: CallKindResolve, + ResponsePath: buildPath("testContainers.details"), + Request: RPCMessage{ + Name: "ResolveTestContainerDetailsRequest", + Fields: []RPCField{ + { + Name: "context", + ProtoTypeName: DataTypeMessage, + Repeated: true, + Message: &RPCMessage{ + Name: "ResolveTestContainerDetailsContext", + Fields: []RPCField{ + { + Name: "id", + ProtoTypeName: DataTypeString, + JSONPath: "id", + ResolvePath: buildPath("test_containers.id"), + }, + { + Name: "name", + ProtoTypeName: DataTypeString, + JSONPath: "name", + ResolvePath: buildPath("test_containers.name"), + }, + }, + }, + }, + { + Name: "field_args", + ProtoTypeName: DataTypeMessage, + Message: &RPCMessage{ + Name: "ResolveTestContainerDetailsArgs", + Fields: []RPCField{ + { + Name: "include_extended", + ProtoTypeName: DataTypeBool, + JSONPath: "includeExtended", + }, + }, + }, + }, + }, + }, + Response: RPCMessage{ + Name: "ResolveTestContainerDetailsResponse", + Fields: []RPCField{ + { + Name: "result", + ProtoTypeName: DataTypeMessage, + JSONPath: "result", + Repeated: true, + Message: &RPCMessage{ + Name: "ResolveTestContainerDetailsResult", + Fields: []RPCField{ + { + Name: "details", + ProtoTypeName: DataTypeMessage, + JSONPath: "details", + Optional: true, + Message: &RPCMessage{ + Name: "TestDetails", + Fields: []RPCField{ + { + Name: "id", + ProtoTypeName: DataTypeString, + JSONPath: "id", + }, + { + Name: "summary", + ProtoTypeName: DataTypeString, + JSONPath: "summary", + }, + { + Name: "pet", + ProtoTypeName: DataTypeMessage, + JSONPath: "pet", + Message: &RPCMessage{ + Name: "Animal", + OneOfType: OneOfTypeInterface, + MemberTypes: []string{"Cat", "Dog"}, + FieldSelectionSet: RPCFieldSelectionSet{ + "Cat": { + { + Name: "name", + ProtoTypeName: DataTypeString, + JSONPath: "name", + }, + { + Name: "meow_volume", + ProtoTypeName: DataTypeInt32, + JSONPath: "meowVolume", + }, + }, + "Dog": { + { + Name: "name", + ProtoTypeName: DataTypeString, + JSONPath: "name", + }, + { + Name: "bark_volume", + ProtoTypeName: DataTypeInt32, + JSONPath: "barkVolume", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + { + name: "Should create an execution plan for a query with nested union type", + query: "query TestContainersWithUnion($includeExtended: Boolean!) { testContainers { id name details(includeExtended: $includeExtended) { id summary status { ... on ActionSuccess { message timestamp } ... on ActionError { message code } } } } }", + expectedPlan: &RPCExecutionPlan{ + Calls: []RPCCall{ + { + ServiceName: "Products", + MethodName: "QueryTestContainers", + Request: RPCMessage{ + Name: "QueryTestContainersRequest", + }, + Response: RPCMessage{ + Name: "QueryTestContainersResponse", + Fields: []RPCField{ + { + Name: "test_containers", + ProtoTypeName: DataTypeMessage, + JSONPath: "testContainers", + Repeated: true, + Message: &RPCMessage{ + Name: "TestContainer", + Fields: []RPCField{ + { + Name: "id", + ProtoTypeName: DataTypeString, + JSONPath: "id", + }, + { + Name: "name", + ProtoTypeName: DataTypeString, + JSONPath: "name", + }, + }, + }, + }, + }, + }, + }, + { + DependentCalls: []int{0}, + ServiceName: "Products", + MethodName: "ResolveTestContainerDetails", + Kind: CallKindResolve, + ResponsePath: buildPath("testContainers.details"), + Request: RPCMessage{ + Name: "ResolveTestContainerDetailsRequest", + Fields: []RPCField{ + { + Name: "context", + ProtoTypeName: DataTypeMessage, + Repeated: true, + Message: &RPCMessage{ + Name: "ResolveTestContainerDetailsContext", + Fields: []RPCField{ + { + Name: "id", + ProtoTypeName: DataTypeString, + JSONPath: "id", + ResolvePath: buildPath("test_containers.id"), + }, + { + Name: "name", + ProtoTypeName: DataTypeString, + JSONPath: "name", + ResolvePath: buildPath("test_containers.name"), + }, + }, + }, + }, + { + Name: "field_args", + ProtoTypeName: DataTypeMessage, + Message: &RPCMessage{ + Name: "ResolveTestContainerDetailsArgs", + Fields: []RPCField{ + { + Name: "include_extended", + ProtoTypeName: DataTypeBool, + JSONPath: "includeExtended", + }, + }, + }, + }, + }, + }, + Response: RPCMessage{ + Name: "ResolveTestContainerDetailsResponse", + Fields: []RPCField{ + { + Name: "result", + ProtoTypeName: DataTypeMessage, + JSONPath: "result", + Repeated: true, + Message: &RPCMessage{ + Name: "ResolveTestContainerDetailsResult", + Fields: []RPCField{ + { + Name: "details", + ProtoTypeName: DataTypeMessage, + JSONPath: "details", + Optional: true, + Message: &RPCMessage{ + Name: "TestDetails", + Fields: []RPCField{ + { + Name: "id", + ProtoTypeName: DataTypeString, + JSONPath: "id", + }, + { + Name: "summary", + ProtoTypeName: DataTypeString, + JSONPath: "summary", + }, + { + Name: "status", + ProtoTypeName: DataTypeMessage, + JSONPath: "status", + Message: &RPCMessage{ + Name: "ActionResult", + OneOfType: OneOfTypeUnion, + MemberTypes: []string{"ActionSuccess", "ActionError"}, + FieldSelectionSet: RPCFieldSelectionSet{ + "ActionSuccess": { + { + Name: "message", + ProtoTypeName: DataTypeString, + JSONPath: "message", + }, + { + Name: "timestamp", + ProtoTypeName: DataTypeString, + JSONPath: "timestamp", + }, + }, + "ActionError": { + { + Name: "message", + ProtoTypeName: DataTypeString, + JSONPath: "message", + }, + { + Name: "code", + ProtoTypeName: DataTypeString, + JSONPath: "code", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + { + name: "Should create an execution plan for a query with both nested interface and union types", + query: "query TestContainersWithBoth($includeExtended: Boolean!) { testContainers { id name details(includeExtended: $includeExtended) { id summary pet { ... on Cat { name meowVolume } ... on Dog { name barkVolume } } status { ... on ActionSuccess { message timestamp } ... on ActionError { message code } } } } }", + expectedPlan: &RPCExecutionPlan{ + Calls: []RPCCall{ + { + ServiceName: "Products", + MethodName: "QueryTestContainers", + Request: RPCMessage{ + Name: "QueryTestContainersRequest", + }, + Response: RPCMessage{ + Name: "QueryTestContainersResponse", + Fields: []RPCField{ + { + Name: "test_containers", + ProtoTypeName: DataTypeMessage, + JSONPath: "testContainers", + Repeated: true, + Message: &RPCMessage{ + Name: "TestContainer", + Fields: []RPCField{ + { + Name: "id", + ProtoTypeName: DataTypeString, + JSONPath: "id", + }, + { + Name: "name", + ProtoTypeName: DataTypeString, + JSONPath: "name", + }, + }, + }, + }, + }, + }, + }, + { + DependentCalls: []int{0}, + ServiceName: "Products", + MethodName: "ResolveTestContainerDetails", + Kind: CallKindResolve, + ResponsePath: buildPath("testContainers.details"), + Request: RPCMessage{ + Name: "ResolveTestContainerDetailsRequest", + Fields: []RPCField{ + { + Name: "context", + ProtoTypeName: DataTypeMessage, + Repeated: true, + Message: &RPCMessage{ + Name: "ResolveTestContainerDetailsContext", + Fields: []RPCField{ + { + Name: "id", + ProtoTypeName: DataTypeString, + JSONPath: "id", + ResolvePath: buildPath("test_containers.id"), + }, + { + Name: "name", + ProtoTypeName: DataTypeString, + JSONPath: "name", + ResolvePath: buildPath("test_containers.name"), + }, + }, + }, + }, + { + Name: "field_args", + ProtoTypeName: DataTypeMessage, + Message: &RPCMessage{ + Name: "ResolveTestContainerDetailsArgs", + Fields: []RPCField{ + { + Name: "include_extended", + ProtoTypeName: DataTypeBool, + JSONPath: "includeExtended", + }, + }, + }, + }, + }, + }, + Response: RPCMessage{ + Name: "ResolveTestContainerDetailsResponse", + Fields: []RPCField{ + { + Name: "result", + ProtoTypeName: DataTypeMessage, + JSONPath: "result", + Repeated: true, + Message: &RPCMessage{ + Name: "ResolveTestContainerDetailsResult", + Fields: []RPCField{ + { + Name: "details", + ProtoTypeName: DataTypeMessage, + JSONPath: "details", + Optional: true, + Message: &RPCMessage{ + Name: "TestDetails", + Fields: []RPCField{ + { + Name: "id", + ProtoTypeName: DataTypeString, + JSONPath: "id", + }, + { + Name: "summary", + ProtoTypeName: DataTypeString, + JSONPath: "summary", + }, + { + Name: "pet", + ProtoTypeName: DataTypeMessage, + JSONPath: "pet", + Message: &RPCMessage{ + Name: "Animal", + OneOfType: OneOfTypeInterface, + MemberTypes: []string{"Cat", "Dog"}, + FieldSelectionSet: RPCFieldSelectionSet{ + "Cat": { + { + Name: "name", + ProtoTypeName: DataTypeString, + JSONPath: "name", + }, + { + Name: "meow_volume", + ProtoTypeName: DataTypeInt32, + JSONPath: "meowVolume", + }, + }, + "Dog": { + { + Name: "name", + ProtoTypeName: DataTypeString, + JSONPath: "name", + }, + { + Name: "bark_volume", + ProtoTypeName: DataTypeInt32, + JSONPath: "barkVolume", + }, + }, + }, + }, + }, + { + Name: "status", + ProtoTypeName: DataTypeMessage, + JSONPath: "status", + Message: &RPCMessage{ + Name: "ActionResult", + OneOfType: OneOfTypeUnion, + MemberTypes: []string{"ActionSuccess", "ActionError"}, + FieldSelectionSet: RPCFieldSelectionSet{ + "ActionSuccess": { + { + Name: "message", + ProtoTypeName: DataTypeString, + JSONPath: "message", + }, + { + Name: "timestamp", + ProtoTypeName: DataTypeString, + JSONPath: "timestamp", + }, + }, + "ActionError": { + { + Name: "message", + ProtoTypeName: DataTypeString, + JSONPath: "message", + }, + { + Name: "code", + ProtoTypeName: DataTypeString, + JSONPath: "code", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + { + name: "Should create an execution plan for a query with nested selection in an interface with inline fragments", + query: "query TestContainersWithInterface($includeExtended: Boolean!) { testContainers { id name details(includeExtended: $includeExtended) { id summary pet { ... on Cat { id name owner { name contact { email } } breed { name characteristics { temperament } } } ... on Dog { id name owner { name contact { phone } } breed { origin characteristics { size } } } } } } }", + expectedPlan: &RPCExecutionPlan{ + Calls: []RPCCall{ + { + ServiceName: "Products", + MethodName: "QueryTestContainers", + Request: RPCMessage{ + Name: "QueryTestContainersRequest", + }, + Response: RPCMessage{ + Name: "QueryTestContainersResponse", + Fields: []RPCField{ + { + Name: "test_containers", + ProtoTypeName: DataTypeMessage, + JSONPath: "testContainers", + Repeated: true, + Message: &RPCMessage{ + Name: "TestContainer", + Fields: []RPCField{ + { + Name: "id", + ProtoTypeName: DataTypeString, + JSONPath: "id", + }, + { + Name: "name", + ProtoTypeName: DataTypeString, + JSONPath: "name", + }, + }, + }, + }, + }, + }, + }, + { + DependentCalls: []int{0}, + ServiceName: "Products", + MethodName: "ResolveTestContainerDetails", + Kind: CallKindResolve, + ResponsePath: buildPath("testContainers.details"), + Request: RPCMessage{ + Name: "ResolveTestContainerDetailsRequest", + Fields: []RPCField{ + { + Name: "context", + ProtoTypeName: DataTypeMessage, + Repeated: true, + Message: &RPCMessage{ + Name: "ResolveTestContainerDetailsContext", + Fields: []RPCField{ + { + Name: "id", + ProtoTypeName: DataTypeString, + JSONPath: "id", + ResolvePath: buildPath("test_containers.id"), + }, + { + Name: "name", + ProtoTypeName: DataTypeString, + JSONPath: "name", + ResolvePath: buildPath("test_containers.name"), + }, + }, + }, + }, + { + Name: "field_args", + ProtoTypeName: DataTypeMessage, + Message: &RPCMessage{ + Name: "ResolveTestContainerDetailsArgs", + Fields: []RPCField{ + { + Name: "include_extended", + ProtoTypeName: DataTypeBool, + JSONPath: "includeExtended", + }, + }, + }, + }, + }, + }, + Response: RPCMessage{ + Name: "ResolveTestContainerDetailsResponse", + Fields: []RPCField{ + { + Name: "result", + ProtoTypeName: DataTypeMessage, + JSONPath: "result", + Repeated: true, + Message: &RPCMessage{ + Name: "ResolveTestContainerDetailsResult", + Fields: []RPCField{ + { + Name: "details", + ProtoTypeName: DataTypeMessage, + JSONPath: "details", + Optional: true, + Message: &RPCMessage{ + Name: "TestDetails", + Fields: []RPCField{ + { + Name: "id", + ProtoTypeName: DataTypeString, + JSONPath: "id", + }, + { + Name: "summary", + ProtoTypeName: DataTypeString, + JSONPath: "summary", + }, + { + Name: "pet", + ProtoTypeName: DataTypeMessage, + JSONPath: "pet", + Message: &RPCMessage{ + Name: "Animal", + OneOfType: OneOfTypeInterface, + MemberTypes: []string{"Cat", "Dog"}, + FieldSelectionSet: RPCFieldSelectionSet{ + "Cat": { + { + Name: "id", + ProtoTypeName: DataTypeString, + JSONPath: "id", + }, + { + Name: "name", + ProtoTypeName: DataTypeString, + JSONPath: "name", + }, + { + Name: "owner", + ProtoTypeName: DataTypeMessage, + JSONPath: "owner", + Message: &RPCMessage{ + Name: "Owner", + Fields: []RPCField{ + { + Name: "name", + ProtoTypeName: DataTypeString, + JSONPath: "name", + }, + { + Name: "contact", + ProtoTypeName: DataTypeMessage, + JSONPath: "contact", + Message: &RPCMessage{ + Name: "ContactInfo", + Fields: []RPCField{ + { + Name: "email", + ProtoTypeName: DataTypeString, + JSONPath: "email", + }, + }, + }, + }, + }, + }, + }, + { + Name: "breed", + ProtoTypeName: DataTypeMessage, + JSONPath: "breed", + Message: &RPCMessage{ + Name: "CatBreed", + Fields: []RPCField{ + { + Name: "name", + ProtoTypeName: DataTypeString, + JSONPath: "name", + }, + { + Name: "characteristics", + ProtoTypeName: DataTypeMessage, + JSONPath: "characteristics", + Message: &RPCMessage{ + Name: "BreedCharacteristics", + Fields: []RPCField{ + { + Name: "temperament", + ProtoTypeName: DataTypeString, + JSONPath: "temperament", + }, + }, + }, + }, + }, + }, + }, + }, + "Dog": { + { + Name: "id", + ProtoTypeName: DataTypeString, + JSONPath: "id", + }, + { + Name: "name", + ProtoTypeName: DataTypeString, + JSONPath: "name", + }, + { + Name: "owner", + ProtoTypeName: DataTypeMessage, + JSONPath: "owner", + Message: &RPCMessage{ + Name: "Owner", + Fields: []RPCField{ + { + Name: "name", + ProtoTypeName: DataTypeString, + JSONPath: "name", + }, + { + Name: "contact", + ProtoTypeName: DataTypeMessage, + JSONPath: "contact", + Message: &RPCMessage{ + Name: "ContactInfo", + Fields: []RPCField{ + { + Name: "phone", + ProtoTypeName: DataTypeString, + JSONPath: "phone", + }, + }, + }, + }, + }, + }, + }, + { + Name: "breed", + ProtoTypeName: DataTypeMessage, + JSONPath: "breed", + Message: &RPCMessage{ + Name: "DogBreed", + Fields: []RPCField{ + { + Name: "origin", + ProtoTypeName: DataTypeString, + JSONPath: "origin", + }, + { + Name: "characteristics", + ProtoTypeName: DataTypeMessage, + JSONPath: "characteristics", + Message: &RPCMessage{ + Name: "BreedCharacteristics", + Fields: []RPCField{ + { + Name: "size", + ProtoTypeName: DataTypeString, + JSONPath: "size", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + runTest(t, testCase{ + query: tt.query, + expectedPlan: tt.expectedPlan, + expectedError: tt.expectedError, + }) + }) + } +} + +func TestExecutionPlanFieldResolvers_CustomSchemas(t *testing.T) { + t.Parallel() + tests := []struct { + name string + operation string + schema ast.Document + subgraphName string + mapping *GRPCMapping + expectedPlan *RPCExecutionPlan + expectedError string + }{ + { + name: "Should not include nested resolvers in composite type selection set when building the execution plan", + subgraphName: "Foo", + operation: ` + query FooQuery($foo: String!, $baz: String!) { + foo { + fooResolver(foo: $foo) { + ... on Baz { + bazResolver(baz: $baz) + } + } + } + }`, + schema: schemaWithNestedResolverAndCompositeType(t), + mapping: mappingWithNestedResolverAndCompositeType(t), + expectedPlan: &RPCExecutionPlan{ + Calls: []RPCCall{ + { + ServiceName: "Foo", + MethodName: "QueryFoo", + Request: RPCMessage{ + Name: "QueryFooRequest", + }, + Response: RPCMessage{ + Name: "QueryFooResponse", + Fields: []RPCField{ + { + Name: "foo", + ProtoTypeName: DataTypeMessage, + JSONPath: "foo", + Message: &RPCMessage{ + Name: "Foo", + Fields: RPCFields{}, + }, + }, + }, + }, + }, + { + Kind: CallKindResolve, + DependentCalls: []int{0}, + ResponsePath: buildPath("foo.fooResolver"), + ServiceName: "Foo", + MethodName: "ResolveFooFooResolver", + Request: RPCMessage{ + Name: "ResolveFooFooResolverRequest", + Fields: []RPCField{ + { + Name: "context", + ProtoTypeName: DataTypeMessage, + Repeated: true, + Message: &RPCMessage{ + Name: "ResolveFooFooResolverContext", + Fields: []RPCField{ + { + Name: "id", + ProtoTypeName: DataTypeString, + JSONPath: "id", + ResolvePath: buildPath("foo.id"), + }, + }, + }, + }, + { + Name: "field_args", + ProtoTypeName: DataTypeMessage, + Message: &RPCMessage{ + Name: "ResolveFooFooResolverArgs", + Fields: []RPCField{ + { + Name: "foo", + ProtoTypeName: DataTypeString, + JSONPath: "foo", + }, + }, + }, + }, + }, + }, + Response: RPCMessage{ + Name: "ResolveFooFooResolverResponse", + Fields: []RPCField{ + { + Name: "result", + ProtoTypeName: DataTypeMessage, + Repeated: true, + JSONPath: "result", + Message: &RPCMessage{ + Name: "ResolveFooFooResolverResult", + Fields: RPCFields{ + { + Name: "foo_resolver", + ProtoTypeName: DataTypeMessage, + JSONPath: "fooResolver", + Message: &RPCMessage{ + Name: "Bar", + FieldSelectionSet: RPCFieldSelectionSet{"Baz": {}}, + OneOfType: OneOfTypeInterface, + MemberTypes: []string{"Baz"}, + }, + }, + }, + }, + }, + }, + }, + }, + { + Kind: CallKindResolve, + DependentCalls: []int{1}, + ResponsePath: buildPath("foo.fooResolver.bazResolver"), + ServiceName: "Foo", + MethodName: "ResolveBazBazResolver", + Request: RPCMessage{ + Name: "ResolveBazBazResolverRequest", + Fields: []RPCField{ + { + Name: "context", + ProtoTypeName: DataTypeMessage, + Repeated: true, + Message: &RPCMessage{ + Name: "ResolveBazBazResolverContext", + Fields: []RPCField{ + { + Name: "id", + ProtoTypeName: DataTypeString, + JSONPath: "id", + ResolvePath: buildPath("foo.fooResolver.id"), + }, + }, + }, + }, + { + Name: "field_args", + ProtoTypeName: DataTypeMessage, + Message: &RPCMessage{ + Name: "ResolveBazBazResolverArgs", + Fields: []RPCField{ + { + Name: "baz", + ProtoTypeName: DataTypeString, + JSONPath: "baz", + }, + }, + }, + }, + }, + }, + Response: RPCMessage{ + Name: "ResolveBazBazResolverResponse", + Fields: []RPCField{ + { + Name: "result", + ProtoTypeName: DataTypeMessage, + Repeated: true, + JSONPath: "result", + Message: &RPCMessage{ + Name: "ResolveBazBazResolverResult", + Fields: RPCFields{ + { + Name: "baz_resolver", + ProtoTypeName: DataTypeString, + JSONPath: "bazResolver", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + { + name: "Should correctly include typename field when providing empty selection set", + subgraphName: "Foo", + operation: ` + query FooQuery($foo: String!, $baz: String!) { + foo { + fooResolver(foo: $foo) { + __typename + } + } + }`, + schema: schemaWithNestedResolverAndCompositeType(t), + mapping: mappingWithNestedResolverAndCompositeType(t), + expectedPlan: &RPCExecutionPlan{ + Calls: []RPCCall{ + { + ServiceName: "Foo", + MethodName: "QueryFoo", + Request: RPCMessage{ + Name: "QueryFooRequest", + }, + Response: RPCMessage{ + Name: "QueryFooResponse", + Fields: []RPCField{ + { + Name: "foo", + ProtoTypeName: DataTypeMessage, + JSONPath: "foo", + Message: &RPCMessage{ + Name: "Foo", + Fields: RPCFields{}, + }, + }, + }, + }, + }, + { + Kind: CallKindResolve, + DependentCalls: []int{0}, + ResponsePath: buildPath("foo.fooResolver"), + ServiceName: "Foo", + MethodName: "ResolveFooFooResolver", + Request: RPCMessage{ + Name: "ResolveFooFooResolverRequest", + Fields: []RPCField{ + { + Name: "context", + ProtoTypeName: DataTypeMessage, + Repeated: true, + Message: &RPCMessage{ + Name: "ResolveFooFooResolverContext", + Fields: []RPCField{ + { + Name: "id", + ProtoTypeName: DataTypeString, + JSONPath: "id", + ResolvePath: buildPath("foo.id"), + }, + }, + }, + }, + { + Name: "field_args", + ProtoTypeName: DataTypeMessage, + Message: &RPCMessage{ + Name: "ResolveFooFooResolverArgs", + Fields: []RPCField{ + { + Name: "foo", + ProtoTypeName: DataTypeString, + JSONPath: "foo", + }, + }, + }, + }, + }, + }, + Response: RPCMessage{ + Name: "ResolveFooFooResolverResponse", + Fields: []RPCField{ + { + Name: "result", + ProtoTypeName: DataTypeMessage, + Repeated: true, + JSONPath: "result", + Message: &RPCMessage{ + Name: "ResolveFooFooResolverResult", + Fields: RPCFields{ + { + Name: "foo_resolver", + ProtoTypeName: DataTypeMessage, + JSONPath: "fooResolver", + Message: &RPCMessage{ + Name: "Bar", + OneOfType: OneOfTypeInterface, + MemberTypes: []string{"Baz"}, + Fields: RPCFields{ + { + Name: "__typename", + ProtoTypeName: DataTypeString, + JSONPath: "__typename", + StaticValue: "Bar", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + } + + for _, tt := range tests { + operation := unsafeparser.ParseGraphqlDocumentString(tt.operation) + + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + runTestWithConfig(t, testCase{ + expectedPlan: tt.expectedPlan, + expectedError: tt.expectedError, + }, testConfig{ + subgraphName: tt.subgraphName, + mapping: tt.mapping, + schemaDoc: tt.schema, + operationDoc: operation, + }) + }) + } +} + +func schemaWithNestedResolverAndCompositeType(t *testing.T) ast.Document { + schema := ` + +scalar connect__FieldSet +directive @connect__fieldResolver(context: connect__FieldSet!) on FIELD_DEFINITION + +schema { + query: Query +} + +type Foo { + id: ID! + fooResolver(foo: String!): Bar! @connect__fieldResolver(context: "id") +} + +interface Bar { + id: ID! +} + +type Baz implements Bar { + id: ID! + bazResolver(baz: String!): String! @connect__fieldResolver(context: "id") +} + +type Query { + foo: Foo! +}` + doc := unsafeparser.ParseGraphqlDocumentStringWithBaseSchema(schema) + + report := &operationreport.Report{} + astvalidation.DefaultDefinitionValidator().Validate(&doc, report) + if report.HasErrors() { + t.Fatalf("failed to validate schema: %s", report.Error()) + } + + return doc +} + +func mappingWithNestedResolverAndCompositeType(_ *testing.T) *GRPCMapping { + return &GRPCMapping{ + Service: "Foo", + QueryRPCs: RPCConfigMap[RPCConfig]{ + "foo": { + RPC: "QueryFoo", + Request: "QueryFooRequest", + Response: "QueryFooResponse", + }, + }, + Fields: map[string]FieldMap{ + "Query": { + "foo": { + TargetName: "foo", + }, + }, + "Foo": { + "id": { + TargetName: "id", + }, + "fooResolver": { + TargetName: "foo_resolver", + }, + }, + "Baz": { + "id": { + TargetName: "id", + }, + "bazResolver": { + TargetName: "baz_resolver", + }, + }, + "Bar": { + "id": { + TargetName: "id", + }, + }, + }, + ResolveRPCs: RPCConfigMap[ResolveRPCMapping]{ + "Foo": { + "fooResolver": { + FieldMappingData: FieldMapData{ + TargetName: "foo_resolver", + ArgumentMappings: FieldArgumentMap{ + "foo": "foo", + }, + }, + RPC: "ResolveFooFooResolver", + Request: "ResolveFooFooResolverRequest", + Response: "ResolveFooFooResolverResponse", + }, + }, + "Baz": { + "bazResolver": { + FieldMappingData: FieldMapData{ + TargetName: "baz_resolver", + ArgumentMappings: FieldArgumentMap{ + "baz": "baz", + }, + }, + RPC: "ResolveBazBazResolver", + Request: "ResolveBazBazResolverRequest", + Response: "ResolveBazBazResolverResponse", + }, + }, + }, + } +} diff --git a/v2/pkg/engine/datasource/grpc_datasource/execution_plan_test.go b/v2/pkg/engine/datasource/grpc_datasource/execution_plan_test.go index 760a3e786..94c22cdc4 100644 --- a/v2/pkg/engine/datasource/grpc_datasource/execution_plan_test.go +++ b/v2/pkg/engine/datasource/grpc_datasource/execution_plan_test.go @@ -1,7 +1,6 @@ package grpcdatasource import ( - "strings" "testing" "github.com/google/go-cmp/cmp" @@ -9,9 +8,10 @@ import ( "github.com/wundergraph/graphql-go-tools/v2/pkg/ast" "github.com/wundergraph/graphql-go-tools/v2/pkg/astparser" + "github.com/wundergraph/graphql-go-tools/v2/pkg/asttransform" "github.com/wundergraph/graphql-go-tools/v2/pkg/astvalidation" "github.com/wundergraph/graphql-go-tools/v2/pkg/grpctest" - "github.com/wundergraph/graphql-go-tools/v2/pkg/operationreport" + "github.com/wundergraph/graphql-go-tools/v2/pkg/internal/unsafeparser" ) type testCase struct { @@ -20,22 +20,20 @@ type testCase struct { expectedError string } -func runTest(t *testing.T, testCase testCase) { - // Parse the GraphQL schema - schemaDoc := grpctest.MustGraphQLSchema(t) - - // Parse the GraphQL query - queryDoc, report := astparser.ParseGraphqlDocumentString(testCase.query) - if report.HasErrors() { - t.Fatalf("failed to parse query: %s", report.Error()) - } +type testConfig struct { + subgraphName string + mapping *GRPCMapping + schemaDoc ast.Document + operationDoc ast.Document +} +func runTestWithConfig(t *testing.T, testCase testCase, testConfig testConfig) { rpcPlanVisitor := newRPCPlanVisitor(rpcPlanVisitorConfig{ - subgraphName: "Products", - mapping: testMapping(), + subgraphName: testConfig.subgraphName, + mapping: testConfig.mapping, }) - plan, err := rpcPlanVisitor.PlanOperation(&queryDoc, &schemaDoc) + plan, err := rpcPlanVisitor.PlanOperation(&testConfig.operationDoc, &testConfig.schemaDoc) if err != nil { require.NotEmpty(t, testCase.expectedError, "expected error to be empty, got: %s", err.Error()) @@ -50,6 +48,24 @@ func runTest(t *testing.T, testCase testCase) { } } +func runTest(t *testing.T, testCase testCase) { + // Parse the GraphQL schema + schemaDoc := grpctest.MustGraphQLSchema(t) + + // Parse the GraphQL query + queryDoc, report := astparser.ParseGraphqlDocumentString(testCase.query) + if report.HasErrors() { + t.Fatalf("failed to parse query: %s", report.Error()) + } + + runTestWithConfig(t, testCase, testConfig{ + subgraphName: "Products", + mapping: testMapping(), + schemaDoc: schemaDoc, + operationDoc: queryDoc, + }) +} + // buildPath builds a path from a string which is a dot-separated list of field names. func buildPath(path string) ast.Path { b := make([]byte, len(path)) @@ -86,7 +102,7 @@ func TestQueryExecutionPlans(t *testing.T) { }{ { name: "Should include typename when requested", - query: `query UsersWithTypename { users { __typename id name } }`, + query: `query UsersWithTypename { users { __typename id __typename name } }`, mapping: testMapping(), expectedPlan: &RPCExecutionPlan{ Calls: []RPCCall{ @@ -1139,6 +1155,137 @@ func TestQueryExecutionPlans(t *testing.T) { } } +func TestQueryExecutionPlans_WithConfig(t *testing.T) { + t.Parallel() + tests := []struct { + name string + operation string + schema ast.Document + subgraphName string + mapping *GRPCMapping + expectedPlan *RPCExecutionPlan + expectedError string + }{ + { + name: "Should create an execution plan for a query with duplicated and nested fields", + operation: ` + query DuplicatedAndNestedFieldsQuery { + users { + __typename + id + __typename + name + address { + street + } + } + }`, + schema: testSchema(t, ` + type Query { + users: [User!]! + } + + type User { + id: ID! + name: String! + address: Address! + } + + type Address { + street: String! + }`), + subgraphName: "Products", + mapping: &GRPCMapping{ + Service: "Products", + QueryRPCs: map[string]RPCConfig{ + "users": { + RPC: "QueryUsers", + Request: "QueryUsersRequest", + Response: "QueryUsersResponse", + }, + }, + // No need to define fields as we don't have camel case in any of them. + }, + expectedPlan: &RPCExecutionPlan{ + Calls: []RPCCall{ + { + ServiceName: "Products", + MethodName: "QueryUsers", + Request: RPCMessage{ + Name: "QueryUsersRequest", + }, + Response: RPCMessage{ + Name: "QueryUsersResponse", + Fields: []RPCField{ + { + Name: "users", + ProtoTypeName: DataTypeMessage, + Repeated: true, + JSONPath: "users", + Message: &RPCMessage{ + Name: "User", + Fields: []RPCField{ + { + Name: "__typename", + ProtoTypeName: DataTypeString, + JSONPath: "__typename", + StaticValue: "User", + }, + { + Name: "id", + ProtoTypeName: DataTypeString, + JSONPath: "id", + }, + { + Name: "name", + ProtoTypeName: DataTypeString, + JSONPath: "name", + }, + { + Name: "address", + ProtoTypeName: DataTypeMessage, + JSONPath: "address", + Message: &RPCMessage{ + Name: "Address", + Fields: []RPCField{ + { + Name: "street", + ProtoTypeName: DataTypeString, + JSONPath: "street", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + + runTestWithConfig(t, testCase{ + + query: tt.operation, + expectedPlan: tt.expectedPlan, + expectedError: tt.expectedError, + }, testConfig{ + subgraphName: tt.subgraphName, + mapping: tt.mapping, + schemaDoc: tt.schema, + operationDoc: unsafeparser.ParseGraphqlDocumentString(tt.operation), + }) + }) + } +} + func TestProductExecutionPlan(t *testing.T) { t.Parallel() tests := []struct { @@ -1349,53 +1496,12 @@ func TestProductExecutionPlan(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { t.Parallel() - report := &operationreport.Report{} - // Parse the GraphQL schema - schemaDoc := grpctest.MustGraphQLSchema(t) - - astvalidation.DefaultDefinitionValidator().Validate(&schemaDoc, report) - if report.HasErrors() { - t.Fatalf("failed to validate schema: %s", report.Error()) - } - - // Parse the GraphQL query - queryDoc, queryReport := astparser.ParseGraphqlDocumentString(tt.query) - if queryReport.HasErrors() { - t.Fatalf("failed to parse query: %s", queryReport.Error()) - } - - astvalidation.DefaultOperationValidator().Validate(&queryDoc, &schemaDoc, report) - if report.HasErrors() { - t.Fatalf("failed to validate query: %s", report.Error()) - } - planner, err := NewPlanner("Products", testMapping(), nil) - if err != nil { - t.Fatalf("failed to create planner: %s", err) - } - outPlan, err := planner.PlanOperation(&queryDoc, &schemaDoc) - if err != nil { - t.Fatalf("failed to plan operation: %s", err) - } - - if tt.expectedError != "" { - if err == nil { - t.Fatalf("expected error, got nil") - } - if !strings.Contains(err.Error(), tt.expectedError) { - t.Fatalf("expected error to contain %q, got %q", tt.expectedError, err.Error()) - } - return - } - - if err != nil { - t.Fatalf("unexpected error: %s", err) - } - - diff := cmp.Diff(tt.expectedPlan, outPlan) - if diff != "" { - t.Fatalf("execution plan mismatch: %s", diff) - } + runTest(t, testCase{ + query: tt.query, + expectedPlan: tt.expectedPlan, + expectedError: tt.expectedError, + }) }) } } @@ -2459,55 +2565,34 @@ func TestProductExecutionPlanWithAliases(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { t.Parallel() - report := &operationreport.Report{} - // Parse the GraphQL schema - schemaDoc := grpctest.MustGraphQLSchema(t) - - astvalidation.DefaultDefinitionValidator().Validate(&schemaDoc, report) - if report.HasErrors() { - t.Fatalf("failed to validate schema: %s", report.Error()) - } - // Parse the GraphQL query - queryDoc, queryReport := astparser.ParseGraphqlDocumentString(tt.query) - if queryReport.HasErrors() { - t.Fatalf("failed to parse query: %s", queryReport.Error()) - } - - astvalidation.DefaultOperationValidator().Validate(&queryDoc, &schemaDoc, report) - if report.HasErrors() { - t.Fatalf("failed to validate query: %s", report.Error()) - } + runTest(t, testCase{ + query: tt.query, + expectedPlan: tt.expectedPlan, + expectedError: tt.expectedError, + }) + }) + } - planner, err := NewPlanner("Products", testMapping(), nil) - if err != nil { - t.Fatalf("failed to create planner: %s", err) - } +} - outPlan, err := planner.PlanOperation(&queryDoc, &schemaDoc) - if err != nil { - t.Fatalf("failed to plan operation: %s", err) - } +func testSchema(t *testing.T, schema string) ast.Document { + t.Helper() - if tt.expectedError != "" { - if err == nil { - t.Fatalf("expected error, got nil") - } - if !strings.Contains(err.Error(), tt.expectedError) { - t.Fatalf("expected error to contain %q, got %q", tt.expectedError, err.Error()) - } - return - } + doc, report := astparser.ParseGraphqlDocumentString(schema) + if report.HasErrors() { + t.Fatalf("failed to parse schema: %s", report.Error()) + } - if err != nil { - t.Fatalf("unexpected error: %s", err) - } + if err := asttransform.MergeDefinitionWithBaseSchema(&doc); err != nil { + t.Fatalf("failed to merge schema: %s", err) + } - diff := cmp.Diff(tt.expectedPlan, outPlan) - if diff != "" { - t.Fatalf("execution plan mismatch: %s", diff) - } - }) + astvalidation.DefaultDefinitionValidator().Validate(&doc, &report) + if report.HasErrors() { + t.Fatalf("failed to validate schema: %s", report.Error()) } + return doc + } diff --git a/v2/pkg/engine/datasource/grpc_datasource/execution_plan_visitor.go b/v2/pkg/engine/datasource/grpc_datasource/execution_plan_visitor.go index 6fbc030b9..307bba52b 100644 --- a/v2/pkg/engine/datasource/grpc_datasource/execution_plan_visitor.go +++ b/v2/pkg/engine/datasource/grpc_datasource/execution_plan_visitor.go @@ -54,9 +54,9 @@ type rpcPlanVisitor struct { currentCall *RPCCall currentCallID int - parentCallID int - resolvedFieldIndex int - resolvedFields []resolvedField + parentCallID int + fieldResolverAncestors stack[int] + resolverFields []resolverField fieldPath ast.Path } @@ -72,15 +72,15 @@ type rpcPlanVisitorConfig struct { func newRPCPlanVisitor(config rpcPlanVisitorConfig) *rpcPlanVisitor { walker := astvisitor.NewWalker(48) visitor := &rpcPlanVisitor{ - walker: &walker, - plan: &RPCExecutionPlan{}, - subgraphName: cases.Title(language.Und, cases.NoLower).String(config.subgraphName), - mapping: config.mapping, - operationFieldRef: ast.InvalidRef, - resolvedFields: make([]resolvedField, 0), - parentCallID: ast.InvalidRef, - resolvedFieldIndex: ast.InvalidRef, - fieldPath: make(ast.Path, 0), + walker: &walker, + plan: &RPCExecutionPlan{}, + subgraphName: cases.Title(language.Und, cases.NoLower).String(config.subgraphName), + mapping: config.mapping, + operationFieldRef: ast.InvalidRef, + resolverFields: make([]resolverField, 0), + parentCallID: ast.InvalidRef, + fieldResolverAncestors: newStack[int](0), + fieldPath: make(ast.Path, 0), } walker.RegisterDocumentVisitor(visitor) @@ -112,18 +112,18 @@ func (r *rpcPlanVisitor) EnterDocument(operation *ast.Document, definition *ast. // LeaveDocument implements astvisitor.DocumentVisitor. func (r *rpcPlanVisitor) LeaveDocument(_, _ *ast.Document) { - if len(r.resolvedFields) == 0 { + if len(r.resolverFields) == 0 { return } - calls, err := r.planCtx.createResolverRPCCalls(r.subgraphName, r.resolvedFields) + calls, err := r.planCtx.createResolverRPCCalls(r.subgraphName, r.resolverFields) if err != nil { r.walker.StopWithInternalErr(err) return } r.plan.Calls = append(r.plan.Calls, calls...) - r.resolvedFields = nil + r.resolverFields = nil } // EnterOperationDefinition implements astvisitor.EnterOperationDefinitionVisitor. @@ -197,10 +197,25 @@ func (r *rpcPlanVisitor) EnterSelectionSet(ref int) { } // If we are inside of a resolved field that selects multiple fields, we get all the fields from the input and pass them to the required fields visitor. - if r.resolvedFieldIndex != ast.InvalidRef { - // TODO: handle nested resolved fields. - r.resolvedFields[r.resolvedFieldIndex].fieldsSelectionSetRef = ref - r.walker.SkipNode() + if r.fieldResolverAncestors.len() > 0 { + if r.walker.Ancestor().Kind == ast.NodeKindInlineFragment { + return + } + + resolverFieldAncestor := r.fieldResolverAncestors.peek() + if compositType := r.planCtx.getCompositeType(r.walker.EnclosingTypeDefinition); compositType != OneOfTypeNone { + memberTypes, err := r.planCtx.getMemberTypes(r.walker.EnclosingTypeDefinition) + if err != nil { + r.walker.StopWithInternalErr(err) + return + } + resolvedField := &r.resolverFields[resolverFieldAncestor] + resolvedField.memberTypes = memberTypes + r.planCtx.enterResolverCompositeSelectionSet(compositType, ref, resolvedField) + return + } + + r.resolverFields[resolverFieldAncestor].fieldsSelectionSetRef = ref return } @@ -333,13 +348,7 @@ func (r *rpcPlanVisitor) EnterField(ref int) { return } - // prevent duplicate fields - fieldAlias := r.operation.FieldAliasString(ref) - if r.planInfo.currentResponseMessage.Fields.Exists(fieldName, fieldAlias) { - return - } - - fd, ok := r.walker.FieldDefinition(ref) + fieldDefRef, ok := r.walker.FieldDefinition(ref) if !ok { r.walker.Report.AddExternalError(operationreport.ExternalError{ Message: fmt.Sprintf("Field %s not found in definition %s", r.operation.FieldNameString(ref), r.walker.EnclosingTypeDefinition.NameString(r.definition)), @@ -347,34 +356,28 @@ func (r *rpcPlanVisitor) EnterField(ref int) { return } - // Field arguments for non root types will be handled as resolver calls. - // We need to make sure to handle a hierarchy of arguments in order to perform parallel calls in order to retrieve the data. - // TODO: this needs to be available for both visitors and added to the plancontext - if fieldArgs := r.operation.FieldArguments(ref); !inRootField && len(fieldArgs) > 0 { - // We don't want to add fields from the selection set to the actual call - resolvedField := resolvedField{ - callerRef: r.parentCallID, - parentTypeRef: r.walker.EnclosingTypeDefinition.Ref, - fieldRef: ref, - responsePath: r.walker.Path[1:].WithoutInlineFragmentNames().WithFieldNameItem(r.operation.FieldAliasOrNameBytes(ref)), - fieldDefinitionTypeRef: r.definition.FieldDefinitionType(fd), - } - - if err := r.planCtx.setResolvedField(r.walker, fd, fieldArgs, r.fieldPath, &resolvedField); err != nil { - r.walker.StopWithInternalErr(err) - return - } + // If the field is a field resolver, we need to handle it later in a separate resolver call. + // We only store the information about the field and create the call later. + if r.planCtx.isFieldResolver(ref, inRootField) { + r.enterFieldResolver(ref, fieldDefRef) + return + } - r.resolvedFields = append(r.resolvedFields, resolvedField) - r.resolvedFieldIndex = len(r.resolvedFields) - 1 - r.fieldPath = r.fieldPath.WithFieldNameItem(r.operation.FieldNameBytes(ref)) + // Check if the field is inside of a resolver call. + if r.fieldResolverAncestors.len() > 0 { + // We don't want to call LeaveField here because we ignore the field entirely. + r.walker.SkipNode() + return + } - // In case of nested fields with arguments, we need to increment the related call ID. - r.parentCallID++ + // prevent duplicate fields + fieldAlias := r.operation.FieldAliasString(ref) + if r.planInfo.currentResponseMessage.Fields.Exists(fieldName, fieldAlias) { + r.walker.SkipNode() return } - field, err := r.planCtx.buildField(r.walker.EnclosingTypeDefinition, fd, fieldName, fieldAlias) + field, err := r.planCtx.buildField(r.walker.EnclosingTypeDefinition, fieldDefRef, fieldName, fieldAlias) if err != nil { r.walker.StopWithInternalErr(err) return @@ -405,23 +408,37 @@ func (r *rpcPlanVisitor) EnterField(ref int) { // LeaveField implements astvisitor.FieldVisitor. func (r *rpcPlanVisitor) LeaveField(ref int) { r.fieldPath = r.fieldPath.RemoveLastItem() - r.resolvedFieldIndex = ast.InvalidRef + inRootField := r.walker.InRootField() + + if inRootField { + // Leaving a root field means the current RPC call is complete. + // Add the current call to the plan and reset the call state. + r.finalizeCall() + // RPC call is done, we can return. + return + } + + if r.planCtx.isFieldResolver(ref, inRootField) { + // Pop the field resolver ancestor only when leaving a field resolver field. + r.fieldResolverAncestors.pop() - // If we are not in the operation field, we can increment the response field index. - if !r.walker.InRootField() { // If the field has arguments, we need to decrement the related call ID. // This is because we can also have nested arguments, which require the underlying field to be resolved // by values provided by the parent call. - if r.operation.FieldHasArguments(ref) { - r.parentCallID-- - } + r.parentCallID-- - r.planInfo.currentResponseFieldIndex++ + // We handle field resolvers differently, so we don't want to increment the response field index. return } + // If we are not in the operation field, we can increment the response field index. + r.planInfo.currentResponseFieldIndex++ +} + +// finalizeCall finalizes the current call and resets the current call. +func (r *rpcPlanVisitor) finalizeCall() { r.plan.Calls[r.currentCallID] = *r.currentCall - r.currentCall = &RPCCall{} + r.currentCall = nil r.currentCallID++ if r.currentCallID < len(r.operationFieldRefs) { @@ -430,3 +447,32 @@ func (r *rpcPlanVisitor) LeaveField(ref int) { r.planInfo.currentResponseFieldIndex = 0 } + +// enterFieldResolver enters a field resolver. +// ref is the field reference in the operation document. +// fieldDefRef is the field definition reference in the definition document. +func (r *rpcPlanVisitor) enterFieldResolver(ref int, fieldDefRef int) { + // Field arguments for non root types will be handled as resolver calls. + // We need to make sure to handle a hierarchy of arguments in order to perform parallel calls in order to retrieve the data. + fieldArgs := r.operation.FieldArguments(ref) + // We don't want to add fields from the selection set to the actual call + resolvedField := resolverField{ + callerRef: r.parentCallID, + parentTypeNode: r.walker.EnclosingTypeDefinition, + fieldRef: ref, + responsePath: r.walker.Path[1:].WithoutInlineFragmentNames().WithFieldNameItem(r.operation.FieldAliasOrNameBytes(ref)), + fieldDefinitionTypeRef: r.definition.FieldDefinitionType(fieldDefRef), + } + + if err := r.planCtx.setResolvedField(r.walker, fieldDefRef, fieldArgs, r.fieldPath, &resolvedField); err != nil { + r.walker.StopWithInternalErr(err) + return + } + + r.resolverFields = append(r.resolverFields, resolvedField) + r.fieldResolverAncestors.push(len(r.resolverFields) - 1) + r.fieldPath = r.fieldPath.WithFieldNameItem(r.operation.FieldNameBytes(ref)) + + // In case of nested fields with arguments, we need to increment the related call ID. + r.parentCallID++ +} diff --git a/v2/pkg/engine/datasource/grpc_datasource/execution_plan_visitor_federation.go b/v2/pkg/engine/datasource/grpc_datasource/execution_plan_visitor_federation.go index ef0a2644f..d0b0ddbbb 100644 --- a/v2/pkg/engine/datasource/grpc_datasource/execution_plan_visitor_federation.go +++ b/v2/pkg/engine/datasource/grpc_datasource/execution_plan_visitor_federation.go @@ -50,9 +50,9 @@ type rpcPlanVisitorFederation struct { subgraphName string currentCall *RPCCall - parentCallID int - resolvedFieldIndex int - resolvedFields []resolvedField + parentCallID int + fieldResolverAncestors stack[int] + resolvedFields []resolverField fieldPath ast.Path } @@ -68,11 +68,11 @@ func newRPCPlanVisitorFederation(config rpcPlanVisitorConfig) *rpcPlanVisitorFed entityRootFieldRef: ast.InvalidRef, entityInlineFragmentRef: ast.InvalidRef, }, - federationConfigData: parseFederationConfigData(config.federationConfigs), - resolvedFields: make([]resolvedField, 0), - resolvedFieldIndex: ast.InvalidRef, - parentCallID: ast.InvalidRef, - fieldPath: ast.Path{}.WithFieldNameItem([]byte("result")), + federationConfigData: parseFederationConfigData(config.federationConfigs), + resolvedFields: make([]resolverField, 0), + fieldResolverAncestors: newStack[int](0), + parentCallID: ast.InvalidRef, + fieldPath: ast.Path{}.WithFieldNameItem([]byte("result")), } walker.RegisterDocumentVisitor(visitor) @@ -187,9 +187,28 @@ func (r *rpcPlanVisitorFederation) EnterSelectionSet(ref int) { } // If we are inside of a resolved field that selects multiple fields, we get all the fields from the input and pass them to the required fields visitor. - if r.resolvedFieldIndex != ast.InvalidRef { - r.resolvedFields[r.resolvedFieldIndex].fieldsSelectionSetRef = ref - r.walker.SkipNode() + if r.fieldResolverAncestors.len() > 0 { + if r.walker.Ancestor().Kind == ast.NodeKindInlineFragment { + return + } + + resolvedFieldAncestor := r.fieldResolverAncestors.peek() + if compositType := r.planCtx.getCompositeType(r.walker.EnclosingTypeDefinition); compositType != OneOfTypeNone { + memberTypes, err := r.planCtx.getMemberTypes(r.walker.EnclosingTypeDefinition) + if err != nil { + r.walker.StopWithInternalErr(err) + return + } + resolvedField := &r.resolvedFields[resolvedFieldAncestor] + + resolvedField.memberTypes = memberTypes + resolvedField.fieldsSelectionSetRef = ast.InvalidRef + + r.planCtx.enterResolverCompositeSelectionSet(compositType, ref, resolvedField) + return + } + + r.resolvedFields[resolvedFieldAncestor].fieldsSelectionSetRef = ref return } @@ -202,14 +221,16 @@ func (r *rpcPlanVisitorFederation) EnterSelectionSet(ref int) { r.planInfo.currentResponseMessage.Fields[r.planInfo.currentResponseFieldIndex].Message = r.planCtx.newMessageFromSelectionSet(r.walker.EnclosingTypeDefinition, ref) } - if r.IsEntityInlineFragment(r.walker.Ancestor()) { - r.planInfo.currentResponseMessage.Fields[r.planInfo.currentResponseFieldIndex].Message.AppendTypeNameField(r.entityInfo.typeName) - } - // Add the current response message to the ancestors and set the current response message to the current field message r.planInfo.responseMessageAncestors = append(r.planInfo.responseMessageAncestors, r.planInfo.currentResponseMessage) r.planInfo.currentResponseMessage = r.planInfo.currentResponseMessage.Fields[r.planInfo.currentResponseFieldIndex].Message + // Ensure that the entity inline fragment message has a typename field, + // to map the json data after receiving the response. + if r.IsEntityInlineFragment(r.walker.Ancestor()) { + r.planInfo.currentResponseMessage.AppendTypeNameField(r.entityInfo.typeName) + } + // Check if the ancestor type is a composite type (interface or union) // and set the oneof type and member types. if err := r.handleCompositeType(r.walker.Ancestor()); err != nil { @@ -224,7 +245,8 @@ func (r *rpcPlanVisitorFederation) EnterSelectionSet(ref int) { // when leaving the selection set. r.planInfo.responseFieldIndexAncestors = append(r.planInfo.responseFieldIndexAncestors, r.planInfo.currentResponseFieldIndex) - r.planInfo.currentResponseFieldIndex = 0 // reset the field index for the current selection set + // Reset the field index for the current selection set to the length of the current response message fields. + r.planInfo.currentResponseFieldIndex = len(r.planInfo.currentResponseMessage.Fields) } func (r *rpcPlanVisitorFederation) handleCompositeType(node ast.Node) error { @@ -302,14 +324,7 @@ func (r *rpcPlanVisitorFederation) EnterField(ref int) { return } - // prevent duplicate fields - fieldAlias := r.operation.FieldAliasString(ref) - if r.planInfo.currentResponseMessage.Fields.Exists(fieldName, fieldAlias) { - r.fieldPath = r.fieldPath.WithFieldNameItem([]byte{}) - return - } - - fd, ok := r.walker.FieldDefinition(ref) + fieldDefRef, ok := r.walker.FieldDefinition(ref) if !ok { r.walker.Report.AddExternalError(operationreport.ExternalError{ Message: fmt.Sprintf("Field %s not found in definition %s", r.operation.FieldNameString(ref), r.walker.EnclosingTypeDefinition.NameString(r.definition)), @@ -317,31 +332,28 @@ func (r *rpcPlanVisitorFederation) EnterField(ref int) { return } - if fieldArgs := r.operation.FieldArguments(ref); !inRootField && len(fieldArgs) > 0 { - // We don't want to add fields from the selection set to the actual call - resolvedField := resolvedField{ - callerRef: r.parentCallID, - parentTypeRef: r.walker.EnclosingTypeDefinition.Ref, - fieldRef: ref, - responsePath: r.walker.Path[1:].WithoutInlineFragmentNames().WithFieldNameItem(r.operation.FieldAliasOrNameBytes(ref)), - fieldDefinitionTypeRef: r.definition.FieldDefinitionType(fd), - } - - if err := r.planCtx.setResolvedField(r.walker, fd, fieldArgs, r.fieldPath, &resolvedField); err != nil { - r.walker.StopWithInternalErr(err) - return - } + // If the field is a field resolver, we need to handle it later in a separate resolver call. + // We only store the information about the field and create the call later. + if r.planCtx.isFieldResolver(ref, inRootField) { + r.enterFieldResolver(ref, fieldDefRef) + return + } - r.resolvedFields = append(r.resolvedFields, resolvedField) - r.resolvedFieldIndex = len(r.resolvedFields) - 1 - r.fieldPath = r.fieldPath.WithFieldNameItem(r.operation.FieldNameBytes(ref)) + // Check if the field is inside of a resolver call. + if r.fieldResolverAncestors.len() > 0 { + // We don't want to call LeaveField here because we ignore the field entirely. + r.walker.SkipNode() + return + } - // In case of nested fields with arguments, we need to increment the related call ID. - r.parentCallID++ + // prevent duplicate fields + fieldAlias := r.operation.FieldAliasString(ref) + if r.planInfo.currentResponseMessage.Fields.Exists(fieldName, fieldAlias) { + r.walker.SkipNode() return } - field, err := r.planCtx.buildField(r.walker.EnclosingTypeDefinition, fd, fieldName, fieldAlias) + field, err := r.planCtx.buildField(r.walker.EnclosingTypeDefinition, fieldDefRef, fieldName, fieldAlias) if err != nil { r.walker.StopWithInternalErr(err) return @@ -372,21 +384,56 @@ func (r *rpcPlanVisitorFederation) EnterField(ref int) { // LeaveField implements astvisitor.FieldVisitor. func (r *rpcPlanVisitorFederation) LeaveField(ref int) { r.fieldPath = r.fieldPath.RemoveLastItem() - r.resolvedFieldIndex = ast.InvalidRef - // If we are not in the operation field, we can increment the response field index. - if !r.walker.InRootField() { + + inRootField := r.walker.InRootField() + if inRootField { + return + } + + if r.planCtx.isFieldResolver(ref, inRootField) { + // Pop the field resolver ancestor only when leaving a field resolver field. + r.fieldResolverAncestors.pop() + // If the field has arguments, we need to decrement the related call ID. // This is because we can also have nested arguments, which require the underlying field to be resolved // by values provided by the parent call. - if r.operation.FieldHasArguments(ref) { - r.parentCallID-- - } + r.parentCallID-- + + // We handle field resolvers differently, so we don't want to increment the response field index. + return + } + + // If we are not in the operation field, we can increment the response field index. + r.planInfo.currentResponseFieldIndex++ +} - r.planInfo.currentResponseFieldIndex++ +// enterFieldResolver enters a field resolver. +// ref is the field reference in the operation document. +// fieldDefRef is the field definition reference in the definition document. +func (r *rpcPlanVisitorFederation) enterFieldResolver(ref int, fieldDefRef int) { + // Field arguments for non root types will be handled as resolver calls. + // We need to make sure to handle a hierarchy of arguments in order to perform parallel calls in order to retrieve the data. + fieldArgs := r.operation.FieldArguments(ref) + // We don't want to add fields from the selection set to the actual call + resolvedField := resolverField{ + callerRef: r.parentCallID, + parentTypeNode: r.walker.EnclosingTypeDefinition, + fieldRef: ref, + responsePath: r.walker.Path[1:].WithoutInlineFragmentNames().WithFieldNameItem(r.operation.FieldAliasOrNameBytes(ref)), + fieldDefinitionTypeRef: r.definition.FieldDefinitionType(fieldDefRef), + } + + if err := r.planCtx.setResolvedField(r.walker, fieldDefRef, fieldArgs, r.fieldPath, &resolvedField); err != nil { + r.walker.StopWithInternalErr(err) return } - r.planInfo.currentResponseFieldIndex = 0 + r.resolvedFields = append(r.resolvedFields, resolvedField) + r.fieldResolverAncestors.push(len(r.resolvedFields) - 1) + r.fieldPath = r.fieldPath.WithFieldNameItem(r.operation.FieldNameBytes(ref)) + + // In case of nested fields with arguments, we need to increment the related call ID. + r.parentCallID++ } func (r *rpcPlanVisitorFederation) resolveEntityInformation(inlineFragmentRef int, fc federationConfigData) error { @@ -426,7 +473,7 @@ func (r *rpcPlanVisitorFederation) scaffoldEntityLookup(fc federationConfigData) defer walker.Release() requiredFieldsVisitor := newRequiredFieldsVisitor(walker, keyFieldMessage, r.planCtx) - err := requiredFieldsVisitor.visitRequiredFields(r.definition, fc.entityTypeName, fc.keyFields) + err := requiredFieldsVisitor.visitWithDefaults(r.definition, fc.entityTypeName, fc.keyFields) if err != nil { r.walker.StopWithInternalErr(err) return diff --git a/v2/pkg/engine/datasource/grpc_datasource/grpc_datasource.go b/v2/pkg/engine/datasource/grpc_datasource/grpc_datasource.go index 8a196cbc6..cb114c014 100644 --- a/v2/pkg/engine/datasource/grpc_datasource/grpc_datasource.go +++ b/v2/pkg/engine/datasource/grpc_datasource/grpc_datasource.go @@ -149,9 +149,8 @@ func (d *DataSource) Load(ctx context.Context, input []byte, out *bytes.Buffer) } if err := errGrp.Wait(); err != nil { - out.Write(builder.writeErrorBytes(err)) failed = true - return nil + return err } for _, result := range results { @@ -169,7 +168,8 @@ func (d *DataSource) Load(ctx context.Context, input []byte, out *bytes.Buffer) return nil }); err != nil || failed { - return err + out.Write(builder.writeErrorBytes(err)) + return nil } data := builder.toDataObject(root) diff --git a/v2/pkg/engine/datasource/grpc_datasource/grpc_datasource_test.go b/v2/pkg/engine/datasource/grpc_datasource/grpc_datasource_test.go index 8191b5b08..76da7be5d 100644 --- a/v2/pkg/engine/datasource/grpc_datasource/grpc_datasource_test.go +++ b/v2/pkg/engine/datasource/grpc_datasource/grpc_datasource_test.go @@ -3758,6 +3758,307 @@ func Test_DataSource_Load_WithEntity_Calls(t *testing.T) { } } +func Test_DataSource_Load_WithEntity_Calls_WithCompositeTypes(t *testing.T) { + conn, cleanup := setupTestGRPCServer(t) + t.Cleanup(cleanup) + + type graphqlError struct { + Message string `json:"message"` + } + type graphqlResponse struct { + Data map[string]interface{} `json:"data"` + Errors []graphqlError `json:"errors,omitempty"` + } + + testCases := []struct { + name string + query string + vars string + federationConfigs plan.FederationFieldConfigurations + validate func(t *testing.T, data map[string]interface{}) + validateError func(t *testing.T, errData []graphqlError) + }{ + { + name: "Query Product with field resolver returning interface type", + query: `query($representations: [_Any!]!, $includeDetails: Boolean!) { _entities(representations: $representations) { ...on Product { __typename id name mascotRecommendation(includeDetails: $includeDetails) { ... on Cat { __typename name meowVolume } ... on Dog { __typename name barkVolume } } } } }`, + vars: `{ + "variables": { + "representations": [ + {"__typename":"Product","id":"1"}, + {"__typename":"Product","id":"2"}, + {"__typename":"Product","id":"3"} + ], + "includeDetails": true + } + }`, + federationConfigs: plan.FederationFieldConfigurations{ + { + TypeName: "Product", + SelectionSet: "id", + }, + }, + validate: func(t *testing.T, data map[string]interface{}) { + require.NotEmpty(t, data) + + entities, ok := data["_entities"].([]interface{}) + require.True(t, ok, "_entities should be an array") + require.NotEmpty(t, entities, "_entities should not be empty") + require.Len(t, entities, 3, "Should return 3 entities") + + for index, entity := range entities { + entity, ok := entity.(map[string]interface{}) + require.True(t, ok, "entity should be an object") + productID := index + 1 + + require.Equal(t, fmt.Sprintf("%d", productID), entity["id"]) + require.Equal(t, fmt.Sprintf("Product %d", productID), entity["name"]) + + mascot, ok := entity["mascotRecommendation"].(map[string]interface{}) + require.True(t, ok, "mascotRecommendation should be an object") + + // Alternates between Cat and Dog based on index + if index%2 == 0 { + // Should be Cat + typename, ok := mascot["__typename"].(string) + require.True(t, ok, "__typename should be present") + require.Equal(t, "Cat", typename) + + require.Contains(t, mascot, "name") + require.Contains(t, mascot["name"], "MascotCat") + + // Validate meowVolume field + require.Contains(t, mascot, "meowVolume") + meowVolume, ok := mascot["meowVolume"].(float64) + require.True(t, ok, "meowVolume should be a number") + require.Greater(t, meowVolume, float64(0), "meowVolume should be greater than 0") + } else { + // Should be Dog + typename, ok := mascot["__typename"].(string) + require.True(t, ok, "__typename should be present") + require.Equal(t, "Dog", typename) + + require.Contains(t, mascot, "name") + require.Contains(t, mascot["name"], "MascotDog") + + // Validate barkVolume field + require.Contains(t, mascot, "barkVolume") + barkVolume, ok := mascot["barkVolume"].(float64) + require.True(t, ok, "barkVolume should be a number") + require.Greater(t, barkVolume, float64(0), "barkVolume should be greater than 0") + } + } + }, + validateError: func(t *testing.T, errorData []graphqlError) { + require.Empty(t, errorData) + }, + }, + { + name: "Query Product with field resolver returning union type", + query: `query($representations: [_Any!]!, $checkAvailability: Boolean!) { _entities(representations: $representations) { ...on Product { __typename id name stockStatus(checkAvailability: $checkAvailability) { ... on ActionSuccess { __typename message timestamp } ... on ActionError { __typename message code } } } } }`, + vars: `{ + "variables": { + "representations": [ + {"__typename":"Product","id":"1"}, + {"__typename":"Product","id":"2"}, + {"__typename":"Product","id":"3"} + ], + "checkAvailability": false + } + }`, + federationConfigs: plan.FederationFieldConfigurations{ + { + TypeName: "Product", + SelectionSet: "id", + }, + }, + validate: func(t *testing.T, data map[string]interface{}) { + require.NotEmpty(t, data) + + entities, ok := data["_entities"].([]interface{}) + require.True(t, ok, "_entities should be an array") + require.NotEmpty(t, entities, "_entities should not be empty") + require.Len(t, entities, 3, "Should return 3 entities") + + for index, entity := range entities { + entity, ok := entity.(map[string]interface{}) + require.True(t, ok, "entity should be an object") + productID := index + 1 + + require.Equal(t, fmt.Sprintf("%d", productID), entity["id"]) + require.Equal(t, fmt.Sprintf("Product %d", productID), entity["name"]) + + stockStatus, ok := entity["stockStatus"].(map[string]interface{}) + require.True(t, ok, "stockStatus should be an object") + + // With checkAvailability: false, all should be success + typename, ok := stockStatus["__typename"].(string) + require.True(t, ok, "__typename should be present") + require.Equal(t, "ActionSuccess", typename) + + require.Contains(t, stockStatus, "message") + require.Contains(t, stockStatus, "timestamp") + + message, ok := stockStatus["message"].(string) + require.True(t, ok, "message should be a string") + require.Contains(t, message, "in stock and available") + + timestamp, ok := stockStatus["timestamp"].(string) + require.True(t, ok, "timestamp should be a string") + require.NotEmpty(t, timestamp) + } + }, + validateError: func(t *testing.T, errorData []graphqlError) { + require.Empty(t, errorData) + }, + }, + { + name: "Query Product with field resolver returning nested composite types", + query: `query($representations: [_Any!]!, $includeExtended: Boolean!) { _entities(representations: $representations) { ...on Product { __typename id name price productDetails(includeExtended: $includeExtended) { id description recommendedPet { __typename ... on Cat { name meowVolume } ... on Dog { name barkVolume } } reviewSummary { __typename ... on ActionSuccess { message timestamp } ... on ActionError { message code } } } } } }`, + vars: `{ + "variables": { + "representations": [ + {"__typename":"Product","id":"1"}, + {"__typename":"Product","id":"2"} + ], + "includeExtended": false + } + }`, + federationConfigs: plan.FederationFieldConfigurations{ + { + TypeName: "Product", + SelectionSet: "id", + }, + }, + validate: func(t *testing.T, data map[string]interface{}) { + require.NotEmpty(t, data) + + entities, ok := data["_entities"].([]interface{}) + require.True(t, ok, "_entities should be an array") + require.NotEmpty(t, entities, "_entities should not be empty") + require.Len(t, entities, 2, "Should return 2 entities") + + for index, entity := range entities { + entity, ok := entity.(map[string]interface{}) + require.True(t, ok, "entity should be an object") + productID := index + 1 + + require.Equal(t, fmt.Sprintf("%d", productID), entity["id"]) + require.Equal(t, fmt.Sprintf("Product %d", productID), entity["name"]) + + details, ok := entity["productDetails"].(map[string]interface{}) + require.True(t, ok, "productDetails should be an object") + + require.Contains(t, details, "id") + require.Contains(t, details, "description") + require.Contains(t, details["description"], "Standard details") + + // Check recommendedPet (interface) + pet, ok := details["recommendedPet"].(map[string]interface{}) + require.True(t, ok, "recommendedPet should be an object") + + // Alternates between Cat and Dog + if index%2 == 0 { + // Should be Cat + petTypename, ok := pet["__typename"].(string) + require.True(t, ok, "pet __typename should be present") + require.Equal(t, "Cat", petTypename) + + require.Contains(t, pet, "name") + require.Contains(t, pet["name"], "RecommendedCat") + + // Validate meowVolume field + require.Contains(t, pet, "meowVolume") + meowVolume, ok := pet["meowVolume"].(float64) + require.True(t, ok, "meowVolume should be a number") + require.Greater(t, meowVolume, float64(0), "meowVolume should be greater than 0") + } else { + // Should be Dog + petTypename, ok := pet["__typename"].(string) + require.True(t, ok, "pet __typename should be present") + require.Equal(t, "Dog", petTypename) + + require.Contains(t, pet, "name") + require.Contains(t, pet["name"], "RecommendedDog") + + // Validate barkVolume field + require.Contains(t, pet, "barkVolume") + barkVolume, ok := pet["barkVolume"].(float64) + require.True(t, ok, "barkVolume should be a number") + require.Greater(t, barkVolume, float64(0), "barkVolume should be greater than 0") + } + + // Check reviewSummary (union) + reviewSummary, ok := details["reviewSummary"].(map[string]interface{}) + require.True(t, ok, "reviewSummary should be an object") + + // With includeExtended: false and low prices, should be success + reviewTypename, ok := reviewSummary["__typename"].(string) + require.True(t, ok, "reviewSummary __typename should be present") + require.Equal(t, "ActionSuccess", reviewTypename) + + require.Contains(t, reviewSummary, "message") + require.Contains(t, reviewSummary, "timestamp") + + message, ok := reviewSummary["message"].(string) + require.True(t, ok, "message should be a string") + require.Contains(t, message, "positive reviews") + + timestamp, ok := reviewSummary["timestamp"].(string) + require.True(t, ok, "timestamp should be a string") + require.NotEmpty(t, timestamp) + } + }, + validateError: func(t *testing.T, errorData []graphqlError) { + require.Empty(t, errorData) + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + // Parse the GraphQL schema + schemaDoc := grpctest.MustGraphQLSchema(t) + + // Parse the GraphQL query + queryDoc, report := astparser.ParseGraphqlDocumentString(tc.query) + if report.HasErrors() { + t.Fatalf("failed to parse query: %s", report.Error()) + } + + compiler, err := NewProtoCompiler(grpctest.MustProtoSchema(t), testMapping()) + if err != nil { + t.Fatalf("failed to compile proto: %v", err) + } + + // Create the datasource + ds, err := NewDataSource(conn, DataSourceConfig{ + Operation: &queryDoc, + Definition: &schemaDoc, + SubgraphName: "Products", + Mapping: testMapping(), + Compiler: compiler, + FederationConfigs: tc.federationConfigs, + }) + require.NoError(t, err) + + // Execute the query through our datasource + output := new(bytes.Buffer) + input := fmt.Sprintf(`{"query":%q,"body":%s}`, tc.query, tc.vars) + err = ds.Load(context.Background(), []byte(input), output) + require.NoError(t, err) + + // Parse the response + var resp graphqlResponse + + err = json.Unmarshal(output.Bytes(), &resp) + require.NoError(t, err, "Failed to unmarshal response") + + tc.validate(t, resp.Data) + tc.validateError(t, resp.Errors) + }) + } +} + func Test_Datasource_Load_WithFieldResolvers(t *testing.T) { conn, cleanup := setupTestGRPCServer(t) t.Cleanup(cleanup) @@ -3898,6 +4199,346 @@ func Test_Datasource_Load_WithFieldResolvers(t *testing.T) { require.Empty(t, errData) }, }, + { + name: "Query with field resolvers and Interface type", + query: "query CategoriesWithInterfaceType($includeVolume: Boolean!) { categories { kind mascot(includeVolume: $includeVolume) { ... on Cat { name } ... on Dog { name } } } }", + vars: `{"variables":{"includeVolume":true}}`, + validate: func(t *testing.T, data map[string]interface{}) { + require.NotEmpty(t, data) + + categories, ok := data["categories"].([]interface{}) + require.True(t, ok, "categories should be an array") + require.NotEmpty(t, categories, "categories should not be empty") + + for _, category := range categories { + category, ok := category.(map[string]interface{}) + require.True(t, ok, "category should be an object") + require.NotEmpty(t, category["kind"]) + if category["kind"] == "OTHER" { + require.Empty(t, category["mascot"]) + continue + } + + require.NotEmpty(t, category["mascot"]) + mascot, ok := category["mascot"].(map[string]interface{}) + require.True(t, ok, "mascot should be an object") + require.NotEmpty(t, mascot["name"]) + } + }, + validateError: func(t *testing.T, errData []graphqlError) { + require.Empty(t, errData) + }, + }, + { + name: "Query with field resolvers and Union type", + query: "query CategoriesWithUnionType($checkHealth: Boolean!) { categories { id name categoryStatus(checkHealth: $checkHealth) { ... on ActionSuccess { message timestamp } ... on ActionError { message code } } } }", + vars: `{"variables":{"checkHealth":true}}`, + validate: func(t *testing.T, data map[string]interface{}) { + require.NotEmpty(t, data) + + categories, ok := data["categories"].([]interface{}) + require.True(t, ok, "categories should be an array") + require.NotEmpty(t, categories, "categories should not be empty") + require.Len(t, categories, 4, "Should return 4 categories") + + // Based on mockservice.go implementation: + // - If checkHealth && i%3 == 0, returns ActionError + // - Otherwise, returns ActionSuccess + for i, category := range categories { + category, ok := category.(map[string]interface{}) + require.True(t, ok, "category should be an object") + require.NotEmpty(t, category["id"]) + require.NotEmpty(t, category["name"]) + require.NotEmpty(t, category["categoryStatus"]) + + categoryStatus, ok := category["categoryStatus"].(map[string]interface{}) + require.True(t, ok, "categoryStatus should be an object") + + if i%3 == 0 { + // Should be ActionError + require.NotEmpty(t, categoryStatus["message"], "ActionError should have message") + require.NotEmpty(t, categoryStatus["code"], "ActionError should have code") + require.Empty(t, categoryStatus["timestamp"], "ActionError should not have timestamp") + require.Contains(t, categoryStatus["message"], "Health check failed", "ActionError message should contain 'Health check failed'") + require.Equal(t, "HEALTH_CHECK_FAILED", categoryStatus["code"], "ActionError code should be HEALTH_CHECK_FAILED") + } else { + // Should be ActionSuccess + require.NotEmpty(t, categoryStatus["message"], "ActionSuccess should have message") + require.NotEmpty(t, categoryStatus["timestamp"], "ActionSuccess should have timestamp") + require.Empty(t, categoryStatus["code"], "ActionSuccess should not have code") + require.Contains(t, categoryStatus["message"], "is healthy", "ActionSuccess message should contain 'is healthy'") + require.Equal(t, "2024-01-01T00:00:00Z", categoryStatus["timestamp"], "ActionSuccess timestamp should match") + } + } + }, + validateError: func(t *testing.T, errData []graphqlError) { + require.Empty(t, errData) + }, + }, + { + name: "Query with nested field resolver returning interface type", + query: "query TestContainersWithInterface($includeExtended: Boolean!) { testContainers { id name details(includeExtended: $includeExtended) { id summary pet { ... on Cat { name meowVolume } ... on Dog { name barkVolume } } } } }", + vars: `{"variables":{"includeExtended":false}}`, + validate: func(t *testing.T, data map[string]interface{}) { + require.NotEmpty(t, data) + + containers, ok := data["testContainers"].([]interface{}) + require.True(t, ok, "testContainers should be an array") + require.NotEmpty(t, containers, "testContainers should not be empty") + require.Len(t, containers, 3, "Should return 3 test containers") + + // Based on mockservice.go implementation: + // - Even indices (0, 2) return Cat + // - Odd indices (1) return Dog + for i, container := range containers { + container, ok := container.(map[string]interface{}) + require.True(t, ok, "container should be an object") + require.NotEmpty(t, container["id"]) + require.NotEmpty(t, container["name"]) + require.NotEmpty(t, container["details"]) + + details, ok := container["details"].(map[string]interface{}) + require.True(t, ok, "details should be an object") + require.NotEmpty(t, details["id"]) + require.NotEmpty(t, details["summary"]) + require.NotEmpty(t, details["pet"]) + + pet, ok := details["pet"].(map[string]interface{}) + require.True(t, ok, "pet should be an object") + require.NotEmpty(t, pet["name"]) + + if i%2 == 0 { + // Should be Cat + require.NotEmpty(t, pet["meowVolume"], "Cat should have meowVolume") + require.Empty(t, pet["barkVolume"], "Cat should not have barkVolume") + require.Contains(t, pet["name"], "TestCat", "Cat name should contain 'TestCat'") + } else { + // Should be Dog + require.NotEmpty(t, pet["barkVolume"], "Dog should have barkVolume") + require.Empty(t, pet["meowVolume"], "Dog should not have meowVolume") + require.Contains(t, pet["name"], "TestDog", "Dog name should contain 'TestDog'") + } + } + }, + validateError: func(t *testing.T, errData []graphqlError) { + require.Empty(t, errData) + }, + }, + { + name: "Query with nested field resolver returning union type", + query: "query TestContainersWithUnion($includeExtended: Boolean!) { testContainers { id name details(includeExtended: $includeExtended) { id summary status { ... on ActionSuccess { message timestamp } ... on ActionError { message code } } } } }", + vars: `{"variables":{"includeExtended":true}}`, + validate: func(t *testing.T, data map[string]interface{}) { + require.NotEmpty(t, data) + + containers, ok := data["testContainers"].([]interface{}) + require.True(t, ok, "testContainers should be an array") + require.NotEmpty(t, containers, "testContainers should not be empty") + require.Len(t, containers, 3, "Should return 3 test containers") + + // Based on mockservice.go implementation: + // - When includeExtended=true && i%3 == 0, returns ActionError + // - Otherwise, returns ActionSuccess + for i, container := range containers { + container, ok := container.(map[string]interface{}) + require.True(t, ok, "container should be an object") + require.NotEmpty(t, container["id"]) + require.NotEmpty(t, container["name"]) + require.NotEmpty(t, container["details"]) + + details, ok := container["details"].(map[string]interface{}) + require.True(t, ok, "details should be an object") + require.NotEmpty(t, details["id"]) + require.NotEmpty(t, details["summary"]) + require.Contains(t, details["summary"], "Extended summary", "Summary should contain 'Extended summary'") + require.NotEmpty(t, details["status"]) + + status, ok := details["status"].(map[string]interface{}) + require.True(t, ok, "status should be an object") + + if i%3 == 0 { + // Should be ActionError + require.NotEmpty(t, status["message"], "ActionError should have message") + require.NotEmpty(t, status["code"], "ActionError should have code") + require.Empty(t, status["timestamp"], "ActionError should not have timestamp") + require.Contains(t, status["message"], "Extended check failed", "ActionError message should contain 'Extended check failed'") + require.Equal(t, "EXTENDED_CHECK_FAILED", status["code"], "ActionError code should be EXTENDED_CHECK_FAILED") + } else { + // Should be ActionSuccess + require.NotEmpty(t, status["message"], "ActionSuccess should have message") + require.NotEmpty(t, status["timestamp"], "ActionSuccess should have timestamp") + require.Empty(t, status["code"], "ActionSuccess should not have code") + require.Contains(t, status["message"], "details loaded successfully", "ActionSuccess message should contain 'details loaded successfully'") + require.Equal(t, "2024-01-01T12:00:00Z", status["timestamp"], "ActionSuccess timestamp should match") + } + } + }, + validateError: func(t *testing.T, errData []graphqlError) { + require.Empty(t, errData) + }, + }, + { + name: "Query with nested field resolver returning both interface and union types", + query: "query TestContainersWithBoth($includeExtended: Boolean!) { testContainers { id name details(includeExtended: $includeExtended) { id summary pet { ... on Cat { name meowVolume } ... on Dog { name barkVolume } } status { ... on ActionSuccess { message timestamp } ... on ActionError { message code } } } } }", + vars: `{"variables":{"includeExtended":true}}`, + validate: func(t *testing.T, data map[string]interface{}) { + require.NotEmpty(t, data) + + containers, ok := data["testContainers"].([]interface{}) + require.True(t, ok, "testContainers should be an array") + require.NotEmpty(t, containers, "testContainers should not be empty") + require.Len(t, containers, 3, "Should return 3 test containers") + + // Validate both pet (interface) and status (union) fields + for i, container := range containers { + container, ok := container.(map[string]interface{}) + require.True(t, ok, "container should be an object") + require.NotEmpty(t, container["id"]) + require.NotEmpty(t, container["name"]) + require.NotEmpty(t, container["details"]) + + details, ok := container["details"].(map[string]interface{}) + require.True(t, ok, "details should be an object") + require.NotEmpty(t, details["id"]) + require.NotEmpty(t, details["summary"]) + require.NotEmpty(t, details["pet"]) + require.NotEmpty(t, details["status"]) + + // Validate pet (Animal interface) + pet, ok := details["pet"].(map[string]interface{}) + require.True(t, ok, "pet should be an object") + require.NotEmpty(t, pet["name"]) + + if i%2 == 0 { + // Should be Cat + require.NotEmpty(t, pet["meowVolume"], "Cat should have meowVolume") + require.Empty(t, pet["barkVolume"], "Cat should not have barkVolume") + require.Contains(t, pet["name"], "TestCat", "Cat name should contain 'TestCat'") + } else { + // Should be Dog + require.NotEmpty(t, pet["barkVolume"], "Dog should have barkVolume") + require.Empty(t, pet["meowVolume"], "Dog should not have meowVolume") + require.Contains(t, pet["name"], "TestDog", "Dog name should contain 'TestDog'") + } + + // Validate status (ActionResult union) + status, ok := details["status"].(map[string]interface{}) + require.True(t, ok, "status should be an object") + + if i%3 == 0 { + // Should be ActionError + require.NotEmpty(t, status["message"], "ActionError should have message") + require.NotEmpty(t, status["code"], "ActionError should have code") + require.Empty(t, status["timestamp"], "ActionError should not have timestamp") + require.Contains(t, status["message"], "Extended check failed", "ActionError message should contain 'Extended check failed'") + require.Equal(t, "EXTENDED_CHECK_FAILED", status["code"], "ActionError code should be EXTENDED_CHECK_FAILED") + } else { + // Should be ActionSuccess + require.NotEmpty(t, status["message"], "ActionSuccess should have message") + require.NotEmpty(t, status["timestamp"], "ActionSuccess should have timestamp") + require.Empty(t, status["code"], "ActionSuccess should not have code") + require.Contains(t, status["message"], "details loaded successfully", "ActionSuccess message should contain 'details loaded successfully'") + require.Equal(t, "2024-01-01T12:00:00Z", status["timestamp"], "ActionSuccess timestamp should match") + } + } + }, + validateError: func(t *testing.T, errData []graphqlError) { + require.Empty(t, errData) + }, + }, + { + name: "Query with nested field resolver returning interface with deeply nested fields", + query: "query TestContainersWithInterface($includeExtended: Boolean!) { testContainers { id name details(includeExtended: $includeExtended) { id summary pet { ... on Cat { id name owner { name contact { email } } breed { name characteristics { temperament } } } ... on Dog { id name owner { name contact { phone } } breed { origin characteristics { size } } } } } } }", + vars: `{"variables":{"includeExtended":false}}`, + validate: func(t *testing.T, data map[string]interface{}) { + require.NotEmpty(t, data) + + containers, ok := data["testContainers"].([]interface{}) + require.True(t, ok, "testContainers should be an array") + require.NotEmpty(t, containers, "testContainers should not be empty") + require.Len(t, containers, 3, "Should return 3 test containers") + + // Based on mockservice_resolve.go implementation: + // - Even indices (0, 2) return Cat with owner and breed details + // - Odd indices (1) return Dog with owner and breed details + for i, container := range containers { + container, ok := container.(map[string]interface{}) + require.True(t, ok, "container should be an object") + require.NotEmpty(t, container["id"]) + require.NotEmpty(t, container["name"]) + require.NotEmpty(t, container["details"]) + + details, ok := container["details"].(map[string]interface{}) + require.True(t, ok, "details should be an object") + require.NotEmpty(t, details["id"]) + require.NotEmpty(t, details["summary"]) + require.NotEmpty(t, details["pet"]) + + pet, ok := details["pet"].(map[string]interface{}) + require.True(t, ok, "pet should be an object") + require.NotEmpty(t, pet["id"]) + require.NotEmpty(t, pet["name"]) + + // Validate owner exists + owner, ok := pet["owner"].(map[string]interface{}) + require.True(t, ok, "owner should be an object") + require.NotEmpty(t, owner["name"]) + + // Validate contact exists + contact, ok := owner["contact"].(map[string]interface{}) + require.True(t, ok, "contact should be an object") + + // Validate breed exists + breed, ok := pet["breed"].(map[string]interface{}) + require.True(t, ok, "breed should be an object") + + // Validate characteristics exists + characteristics, ok := breed["characteristics"].(map[string]interface{}) + require.True(t, ok, "characteristics should be an object") + + if i%2 == 0 { + // Should be Cat + require.Contains(t, pet["name"], "TestCat", "Cat name should contain 'TestCat'") + require.Contains(t, owner["name"], "OwnerTestCat", "Cat owner name should contain 'OwnerTestCat'") + + // Cat should have email in contact + require.NotEmpty(t, contact["email"], "Cat owner should have email") + require.Equal(t, "owner-test-cat@example.com", contact["email"], "Cat owner email should match") + require.Empty(t, contact["phone"], "Cat query should not have phone") + + // Cat breed should have name and temperament in characteristics + require.NotEmpty(t, breed["name"], "Cat breed should have name") + require.Contains(t, breed["name"], "BreedTestCat", "Cat breed name should contain 'BreedTestCat'") + require.Empty(t, breed["origin"], "Cat query should not have breed origin") + + require.NotEmpty(t, characteristics["temperament"], "Cat breed should have temperament") + require.Equal(t, "Curious", characteristics["temperament"], "Cat breed temperament should be 'Curious'") + require.Empty(t, characteristics["size"], "Cat query should not have breed size") + } else { + // Should be Dog + require.Contains(t, pet["name"], "TestDog", "Dog name should contain 'TestDog'") + require.Contains(t, owner["name"], "OwnerTestDog", "Dog owner name should contain 'OwnerTestDog'") + + // Dog should have phone in contact + require.NotEmpty(t, contact["phone"], "Dog owner should have phone") + require.Equal(t, "555-666-7777", contact["phone"], "Dog owner phone should match") + require.Empty(t, contact["email"], "Dog query should not have email") + + // Dog breed should have origin and size in characteristics + require.NotEmpty(t, breed["origin"], "Dog breed should have origin") + require.Equal(t, "England", breed["origin"], "Dog breed origin should be 'England'") + require.Empty(t, breed["name"], "Dog query should not have breed name") + + require.NotEmpty(t, characteristics["size"], "Dog breed should have size") + require.Equal(t, "Medium", characteristics["size"], "Dog breed size should be 'Medium'") + require.Empty(t, characteristics["temperament"], "Dog query should not have breed temperament") + } + } + }, + validateError: func(t *testing.T, errData []graphqlError) { + require.Empty(t, errData) + }, + }, } for _, tc := range testCases { diff --git a/v2/pkg/engine/datasource/grpc_datasource/mapping_test_helper.go b/v2/pkg/engine/datasource/grpc_datasource/mapping_test_helper.go index 148cd51dc..c8b63d09c 100644 --- a/v2/pkg/engine/datasource/grpc_datasource/mapping_test_helper.go +++ b/v2/pkg/engine/datasource/grpc_datasource/mapping_test_helper.go @@ -154,6 +154,16 @@ func testMapping() *GRPCMapping { Request: "QueryBulkSearchBlogPostsRequest", Response: "QueryBulkSearchBlogPostsResponse", }, + "testContainer": { + RPC: "QueryTestContainer", + Request: "QueryTestContainerRequest", + Response: "QueryTestContainerResponse", + }, + "testContainers": { + RPC: "QueryTestContainers", + Request: "QueryTestContainersRequest", + Response: "QueryTestContainersResponse", + }, }, MutationRPCs: RPCConfigMap[RPCConfig]{ "createUser": { @@ -253,6 +263,41 @@ func testMapping() *GRPCMapping { Request: "ResolveCategoryCategoryMetricsRequest", Response: "ResolveCategoryCategoryMetricsResponse", }, + "mascot": { + FieldMappingData: FieldMapData{ + TargetName: "mascot", + ArgumentMappings: FieldArgumentMap{ + "includeVolume": "include_volume", + }, + }, + RPC: "ResolveCategoryMascot", + Request: "ResolveCategoryMascotRequest", + Response: "ResolveCategoryMascotResponse", + }, + "categoryStatus": { + FieldMappingData: FieldMapData{ + TargetName: "category_status", + ArgumentMappings: FieldArgumentMap{ + "checkHealth": "check_health", + }, + }, + RPC: "ResolveCategoryCategoryStatus", + Request: "ResolveCategoryCategoryStatusRequest", + Response: "ResolveCategoryCategoryStatusResponse", + }, + }, + "CategoryMetrics": { + "normalizedScore": { + FieldMappingData: FieldMapData{ + TargetName: "normalized_score", + ArgumentMappings: FieldArgumentMap{ + "baseline": "baseline", + }, + }, + RPC: "ResolveCategoryMetricsNormalizedScore", + Request: "ResolveCategoryMetricsNormalizedScoreRequest", + Response: "ResolveCategoryMetricsNormalizedScoreResponse", + }, }, "Product": { "shippingEstimate": { @@ -277,6 +322,39 @@ func testMapping() *GRPCMapping { Request: "ResolveProductRecommendedCategoryRequest", Response: "ResolveProductRecommendedCategoryResponse", }, + "mascotRecommendation": { + FieldMappingData: FieldMapData{ + TargetName: "mascot_recommendation", + ArgumentMappings: FieldArgumentMap{ + "includeDetails": "include_details", + }, + }, + RPC: "ResolveProductMascotRecommendation", + Request: "ResolveProductMascotRecommendationRequest", + Response: "ResolveProductMascotRecommendationResponse", + }, + "stockStatus": { + FieldMappingData: FieldMapData{ + TargetName: "stock_status", + ArgumentMappings: FieldArgumentMap{ + "checkAvailability": "check_availability", + }, + }, + RPC: "ResolveProductStockStatus", + Request: "ResolveProductStockStatusRequest", + Response: "ResolveProductStockStatusResponse", + }, + "productDetails": { + FieldMappingData: FieldMapData{ + TargetName: "product_details", + ArgumentMappings: FieldArgumentMap{ + "includeExtended": "include_extended", + }, + }, + RPC: "ResolveProductProductDetails", + Request: "ResolveProductProductDetailsRequest", + Response: "ResolveProductProductDetailsResponse", + }, }, "Subcategory": { "itemCount": { @@ -291,6 +369,19 @@ func testMapping() *GRPCMapping { Response: "ResolveSubcategoryItemCountResponse", }, }, + "TestContainer": { + "details": { + FieldMappingData: FieldMapData{ + TargetName: "details", + ArgumentMappings: FieldArgumentMap{ + "includeExtended": "include_extended", + }, + }, + RPC: "ResolveTestContainerDetails", + Request: "ResolveTestContainerDetailsRequest", + Response: "ResolveTestContainerDetailsResponse", + }, + }, }, EntityRPCs: map[string][]EntityRPCConfig{ "Product": { @@ -481,6 +572,15 @@ func testMapping() *GRPCMapping { "filters": "filters", }, }, + "testContainer": { + TargetName: "test_container", + ArgumentMappings: FieldArgumentMap{ + "id": "id", + }, + }, + "testContainers": { + TargetName: "test_containers", + }, }, "Mutation": { "createUser": { @@ -581,6 +681,38 @@ func testMapping() *GRPCMapping { "maxPrice": "max_price", }, }, + "mascotRecommendation": { + TargetName: "mascot_recommendation", + ArgumentMappings: FieldArgumentMap{ + "includeDetails": "include_details", + }, + }, + "stockStatus": { + TargetName: "stock_status", + ArgumentMappings: FieldArgumentMap{ + "checkAvailability": "check_availability", + }, + }, + "productDetails": { + TargetName: "product_details", + ArgumentMappings: FieldArgumentMap{ + "includeExtended": "include_extended", + }, + }, + }, + "ProductDetails": { + "id": { + TargetName: "id", + }, + "description": { + TargetName: "description", + }, + "reviewSummary": { + TargetName: "review_summary", + }, + "recommendedPet": { + TargetName: "recommended_pet", + }, }, "Storage": { "id": { @@ -796,6 +928,18 @@ func testMapping() *GRPCMapping { "metricType": "metric_type", }, }, + "mascot": { + TargetName: "mascot", + ArgumentMappings: FieldArgumentMap{ + "includeVolume": "include_volume", + }, + }, + "categoryStatus": { + TargetName: "category_status", + ArgumentMappings: FieldArgumentMap{ + "checkHealth": "check_health", + }, + }, }, "Subcategory": { "id": { @@ -833,6 +977,15 @@ func testMapping() *GRPCMapping { "categoryId": { TargetName: "category_id", }, + "normalizedScore": { + TargetName: "normalized_score", + ArgumentMappings: FieldArgumentMap{ + "baseline": "baseline", + }, + }, + "relatedCategory": { + TargetName: "related_category", + }, }, "Cat": { "id": { @@ -847,6 +1000,12 @@ func testMapping() *GRPCMapping { "meowVolume": { TargetName: "meow_volume", }, + "owner": { + TargetName: "owner", + }, + "breed": { + TargetName: "breed", + }, }, "Dog": { "id": { @@ -861,6 +1020,87 @@ func testMapping() *GRPCMapping { "barkVolume": { TargetName: "bark_volume", }, + "owner": { + TargetName: "owner", + }, + "breed": { + TargetName: "breed", + }, + }, + "Owner": { + "id": { + TargetName: "id", + }, + "name": { + TargetName: "name", + }, + "contact": { + TargetName: "contact", + }, + }, + "ContactInfo": { + "email": { + TargetName: "email", + }, + "phone": { + TargetName: "phone", + }, + "address": { + TargetName: "address", + }, + }, + "Address": { + "street": { + TargetName: "street", + }, + "city": { + TargetName: "city", + }, + "country": { + TargetName: "country", + }, + "zipCode": { + TargetName: "zip_code", + }, + }, + "CatBreed": { + "id": { + TargetName: "id", + }, + "name": { + TargetName: "name", + }, + "origin": { + TargetName: "origin", + }, + "characteristics": { + TargetName: "characteristics", + }, + }, + "DogBreed": { + "id": { + TargetName: "id", + }, + "name": { + TargetName: "name", + }, + "origin": { + TargetName: "origin", + }, + "characteristics": { + TargetName: "characteristics", + }, + }, + "BreedCharacteristics": { + "size": { + TargetName: "size", + }, + "temperament": { + TargetName: "temperament", + }, + "lifespan": { + TargetName: "lifespan", + }, }, "ActionSuccess": { "message": { @@ -878,6 +1118,37 @@ func testMapping() *GRPCMapping { TargetName: "code", }, }, + "TestContainer": { + "id": { + TargetName: "id", + }, + "name": { + TargetName: "name", + }, + "description": { + TargetName: "description", + }, + "details": { + TargetName: "details", + ArgumentMappings: FieldArgumentMap{ + "includeExtended": "include_extended", + }, + }, + }, + "TestDetails": { + "id": { + TargetName: "id", + }, + "summary": { + TargetName: "summary", + }, + "pet": { + TargetName: "pet", + }, + "status": { + TargetName: "status", + }, + }, "SearchInput": { "query": { TargetName: "query", @@ -1224,4 +1495,5 @@ func testMapping() *GRPCMapping { }, }, } + } diff --git a/v2/pkg/engine/datasource/grpc_datasource/required_fields_visitor.go b/v2/pkg/engine/datasource/grpc_datasource/required_fields_visitor.go index c78f4ea6a..42c132ec2 100644 --- a/v2/pkg/engine/datasource/grpc_datasource/required_fields_visitor.go +++ b/v2/pkg/engine/datasource/grpc_datasource/required_fields_visitor.go @@ -7,9 +7,15 @@ import ( "github.com/wundergraph/graphql-go-tools/v2/pkg/ast" "github.com/wundergraph/graphql-go-tools/v2/pkg/astvisitor" "github.com/wundergraph/graphql-go-tools/v2/pkg/engine/plan" - "github.com/wundergraph/graphql-go-tools/v2/pkg/operationreport" ) +type requiredFieldVisitorConfig struct { + // includeMemberType indicates if the member type should be included in the message. + includeMemberType bool + // skipFieldResolvers indicates if the field resolvers should be skipped. + skipFieldResolvers bool +} + // requiredFieldsVisitor is a visitor that visits the required fields of a message. type requiredFieldsVisitor struct { operation *ast.Document @@ -22,6 +28,8 @@ type requiredFieldsVisitor struct { planCtx *rpcPlanningContext messageAncestors []*RPCMessage + + skipFieldResolvers bool } // newRequiredFieldsVisitor creates a new requiredFieldsVisitor. @@ -42,20 +50,30 @@ func newRequiredFieldsVisitor(walker *astvisitor.Walker, message *RPCMessage, pl return visitor } -// visitRequiredFields visits the required fields of a message. +// visitWithDefaults visits the required fields of a message. // It creates a new document with the required fields and walks it. // To achieve that we create a fragment with the required fields and walk it. -func (r *requiredFieldsVisitor) visitRequiredFields(definition *ast.Document, typeName, requiredFields string) error { - return r.visitWithMemberTypes(definition, typeName, requiredFields, []string{typeName}) +func (r *requiredFieldsVisitor) visitWithDefaults(definition *ast.Document, typeName, requiredFields string) error { + return r.visit(definition, typeName, requiredFields, requiredFieldVisitorConfig{ + includeMemberType: true, + skipFieldResolvers: false, + }) } -func (r *requiredFieldsVisitor) visitWithMemberTypes(definition *ast.Document, typeName, requiredFields string, memberTypes []string) error { +// visit visits the required fields of a message. +// The function can be provided with options to customize the visitor. +func (r *requiredFieldsVisitor) visit(definition *ast.Document, typeName, requiredFields string, options requiredFieldVisitorConfig) error { doc, report := plan.RequiredFieldsFragment(typeName, requiredFields, false) if report.HasErrors() { return report } - r.message.MemberTypes = memberTypes + if options.includeMemberType { + r.message.MemberTypes = []string{typeName} + } + + r.skipFieldResolvers = options.skipFieldResolvers + r.walker.Walk(doc, definition, report) if report.HasErrors() { return report @@ -124,9 +142,12 @@ func (r *requiredFieldsVisitor) EnterField(ref int) { fd, ok := r.walker.FieldDefinition(ref) if !ok { - r.walker.Report.AddExternalError(operationreport.ExternalError{ - Message: fmt.Sprintf("Field %s not found in definition %s", fieldName, r.walker.EnclosingTypeDefinition.NameString(r.definition)), - }) + r.walker.StopWithInternalErr(fmt.Errorf("RequiredFieldsVisitor: field definition not found for field %s", fieldName)) + return + } + + if r.planCtx.isFieldResolver(ref, r.walker.InRootField()) && r.skipFieldResolvers { + r.walker.SkipNode() return } diff --git a/v2/pkg/engine/datasource/grpc_datasource/util.go b/v2/pkg/engine/datasource/grpc_datasource/util.go index 1a6a1f55d..48dc37d44 100644 --- a/v2/pkg/engine/datasource/grpc_datasource/util.go +++ b/v2/pkg/engine/datasource/grpc_datasource/util.go @@ -8,3 +8,42 @@ func initializeSlice[T any](len int, zero T) []T { } return s } + +// stack is a generic LIFO (Last In First Out) data structure that stores elements of type T. +type stack[T any] []T + +// newStack creates and returns a new empty stack for elements of type T. +func newStack[T any](size int) stack[T] { + return make(stack[T], 0, size) +} + +// push adds a new element to the top of the stack. +func (a *stack[T]) push(value T) { + *a = append(*a, value) +} + +// pop removes the top element from the stack. +// If the stack is empty, this operation is a no-op. +func (a *stack[T]) pop() { + if a.len() == 0 { + return + } + + *a = (*a)[:len(*a)-1] +} + +// peek returns the top element of the stack without removing it. +// Note: This function will panic if called on an empty stack. +func (a *stack[T]) peek() T { + return (*a)[len(*a)-1] +} + +// len returns the number of elements currently in the stack. +func (a *stack[T]) len() int { + return len(*a) +} + +// capacity returns the capacity of the stack. +func (a *stack[T]) capacity() int { + return cap(*a) +} diff --git a/v2/pkg/engine/datasource/grpc_datasource/util_test.go b/v2/pkg/engine/datasource/grpc_datasource/util_test.go new file mode 100644 index 000000000..6257b0dfe --- /dev/null +++ b/v2/pkg/engine/datasource/grpc_datasource/util_test.go @@ -0,0 +1,220 @@ +package grpcdatasource + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestStack(t *testing.T) { + t.Run("basic push pop and peek operations", func(t *testing.T) { + s := newStack[int](10) + s.push(1) + s.push(2) + s.push(3) + require.Equal(t, 10, s.capacity()) + require.Equal(t, 3, s.len()) + s.pop() + require.Equal(t, 2, s.len()) + require.Equal(t, 2, s.peek()) + require.Equal(t, 2, s.len()) + }) + + t.Run("empty stack", func(t *testing.T) { + s := newStack[int](5) + require.Equal(t, 0, s.len()) + require.Equal(t, 5, s.capacity()) + + // Pop on empty stack should not panic (documented as no-op) + s.pop() + require.Equal(t, 0, s.len()) + + // Peek on empty stack should panic (documented behavior) + require.Panics(t, func() { + s.peek() + }) + }) + + t.Run("push and pop to empty", func(t *testing.T) { + s := newStack[int](5) + s.push(10) + s.push(20) + s.push(30) + require.Equal(t, 3, s.len()) + require.Equal(t, 30, s.peek()) + + s.pop() + require.Equal(t, 2, s.len()) + require.Equal(t, 20, s.peek()) + + s.pop() + require.Equal(t, 1, s.len()) + require.Equal(t, 10, s.peek()) + + s.pop() + require.Equal(t, 0, s.len()) + + // After popping all elements, peek should panic + require.Panics(t, func() { + s.peek() + }) + }) + + t.Run("push after pop", func(t *testing.T) { + s := newStack[int](10) + s.push(1) + s.push(2) + s.push(3) + require.Equal(t, 3, s.len()) + + s.pop() + require.Equal(t, 2, s.len()) + + s.push(4) + require.Equal(t, 3, s.len()) + require.Equal(t, 4, s.peek()) + }) + + t.Run("fill to capacity and beyond", func(t *testing.T) { + s := newStack[int](3) + s.push(1) + s.push(2) + s.push(3) + require.Equal(t, 3, s.len()) + require.Equal(t, 3, s.capacity()) + + // Push beyond initial capacity (should grow) + s.push(4) + require.Equal(t, 4, s.len()) + require.Greater(t, s.capacity(), 3) + require.Equal(t, 4, s.peek()) + }) + + t.Run("LIFO order verification", func(t *testing.T) { + s := newStack[int](10) + for i := 1; i <= 5; i++ { + s.push(i) + } + + // Verify LIFO order + require.Equal(t, 5, s.peek()) + s.pop() + require.Equal(t, 4, s.peek()) + s.pop() + require.Equal(t, 3, s.peek()) + s.pop() + require.Equal(t, 2, s.peek()) + s.pop() + require.Equal(t, 1, s.peek()) + s.pop() + require.Equal(t, 0, s.len()) + }) + + t.Run("peek does not modify stack", func(t *testing.T) { + s := newStack[int](5) + s.push(100) + s.push(200) + + // Multiple peeks should return same value and not change length + for i := 0; i < 5; i++ { + require.Equal(t, 200, s.peek()) + require.Equal(t, 2, s.len()) + } + }) + + t.Run("stack with string type", func(t *testing.T) { + s := newStack[string](5) + s.push("hello") + s.push("world") + s.push("test") + + require.Equal(t, 3, s.len()) + require.Equal(t, "test", s.peek()) + + s.pop() + require.Equal(t, "world", s.peek()) + + s.pop() + require.Equal(t, "hello", s.peek()) + }) + + t.Run("stack with struct type", func(t *testing.T) { + type testStruct struct { + id int + name string + } + + s := newStack[testStruct](5) + s.push(testStruct{id: 1, name: "first"}) + s.push(testStruct{id: 2, name: "second"}) + + require.Equal(t, 2, s.len()) + top := s.peek() + require.Equal(t, 2, top.id) + require.Equal(t, "second", top.name) + + s.pop() + top = s.peek() + require.Equal(t, 1, top.id) + require.Equal(t, "first", top.name) + }) + + t.Run("large number of operations", func(t *testing.T) { + s := newStack[int](10) + + // Push 100 items + for i := 0; i < 100; i++ { + s.push(i) + } + require.Equal(t, 100, s.len()) + require.Equal(t, 99, s.peek()) + + // Pop 50 items + for i := 0; i < 50; i++ { + s.pop() + } + require.Equal(t, 50, s.len()) + require.Equal(t, 49, s.peek()) + + // Push 25 more items + for i := 100; i < 125; i++ { + s.push(i) + } + require.Equal(t, 75, s.len()) + require.Equal(t, 124, s.peek()) + }) + + t.Run("alternating push and pop", func(t *testing.T) { + s := newStack[int](5) + + s.push(1) + require.Equal(t, 1, s.len()) + + s.pop() + require.Equal(t, 0, s.len()) + + s.push(2) + s.push(3) + require.Equal(t, 2, s.len()) + + s.pop() + require.Equal(t, 1, s.len()) + require.Equal(t, 2, s.peek()) + + s.push(4) + s.push(5) + require.Equal(t, 3, s.len()) + require.Equal(t, 5, s.peek()) + }) + + t.Run("zero capacity stack", func(t *testing.T) { + s := newStack[int](0) + require.Equal(t, 0, s.len()) + require.Equal(t, 0, s.capacity()) + + // Should still be able to push (will grow) + s.push(42) + require.Equal(t, 1, s.len()) + require.Equal(t, 42, s.peek()) + }) +} diff --git a/v2/pkg/grpctest/mapping/mapping.go b/v2/pkg/grpctest/mapping/mapping.go index 6397adc31..5acef534d 100644 --- a/v2/pkg/grpctest/mapping/mapping.go +++ b/v2/pkg/grpctest/mapping/mapping.go @@ -161,6 +161,16 @@ func DefaultGRPCMapping() *grpcdatasource.GRPCMapping { Request: "QueryBulkSearchBlogPostsRequest", Response: "QueryBulkSearchBlogPostsResponse", }, + "testContainer": { + RPC: "QueryTestContainer", + Request: "QueryTestContainerRequest", + Response: "QueryTestContainerResponse", + }, + "testContainers": { + RPC: "QueryTestContainers", + Request: "QueryTestContainersRequest", + Response: "QueryTestContainersResponse", + }, }, MutationRPCs: grpcdatasource.RPCConfigMap[grpcdatasource.RPCConfig]{ "createUser": { @@ -260,6 +270,41 @@ func DefaultGRPCMapping() *grpcdatasource.GRPCMapping { Request: "ResolveCategoryCategoryMetricsRequest", Response: "ResolveCategoryCategoryMetricsResponse", }, + "mascot": { + FieldMappingData: grpcdatasource.FieldMapData{ + TargetName: "mascot", + ArgumentMappings: grpcdatasource.FieldArgumentMap{ + "includeVolume": "include_volume", + }, + }, + RPC: "ResolveCategoryMascot", + Request: "ResolveCategoryMascotRequest", + Response: "ResolveCategoryMascotResponse", + }, + "categoryStatus": { + FieldMappingData: grpcdatasource.FieldMapData{ + TargetName: "category_status", + ArgumentMappings: grpcdatasource.FieldArgumentMap{ + "checkHealth": "check_health", + }, + }, + RPC: "ResolveCategoryCategoryStatus", + Request: "ResolveCategoryCategoryStatusRequest", + Response: "ResolveCategoryCategoryStatusResponse", + }, + }, + "CategoryMetrics": { + "normalizedScore": { + FieldMappingData: grpcdatasource.FieldMapData{ + TargetName: "normalized_score", + ArgumentMappings: grpcdatasource.FieldArgumentMap{ + "baseline": "baseline", + }, + }, + RPC: "ResolveCategoryMetricsNormalizedScore", + Request: "ResolveCategoryMetricsNormalizedScoreRequest", + Response: "ResolveCategoryMetricsNormalizedScoreResponse", + }, }, "Product": { "shippingEstimate": { @@ -284,6 +329,39 @@ func DefaultGRPCMapping() *grpcdatasource.GRPCMapping { Request: "ResolveProductRecommendedCategoryRequest", Response: "ResolveProductRecommendedCategoryResponse", }, + "mascotRecommendation": { + FieldMappingData: grpcdatasource.FieldMapData{ + TargetName: "mascot_recommendation", + ArgumentMappings: grpcdatasource.FieldArgumentMap{ + "includeDetails": "include_details", + }, + }, + RPC: "ResolveProductMascotRecommendation", + Request: "ResolveProductMascotRecommendationRequest", + Response: "ResolveProductMascotRecommendationResponse", + }, + "stockStatus": { + FieldMappingData: grpcdatasource.FieldMapData{ + TargetName: "stock_status", + ArgumentMappings: grpcdatasource.FieldArgumentMap{ + "checkAvailability": "check_availability", + }, + }, + RPC: "ResolveProductStockStatus", + Request: "ResolveProductStockStatusRequest", + Response: "ResolveProductStockStatusResponse", + }, + "productDetails": { + FieldMappingData: grpcdatasource.FieldMapData{ + TargetName: "product_details", + ArgumentMappings: grpcdatasource.FieldArgumentMap{ + "includeExtended": "include_extended", + }, + }, + RPC: "ResolveProductProductDetails", + Request: "ResolveProductProductDetailsRequest", + Response: "ResolveProductProductDetailsResponse", + }, }, "Subcategory": { "itemCount": { @@ -298,6 +376,19 @@ func DefaultGRPCMapping() *grpcdatasource.GRPCMapping { Response: "ResolveSubcategoryItemCountResponse", }, }, + "TestContainer": { + "details": { + FieldMappingData: grpcdatasource.FieldMapData{ + TargetName: "details", + ArgumentMappings: grpcdatasource.FieldArgumentMap{ + "includeExtended": "include_extended", + }, + }, + RPC: "ResolveTestContainerDetails", + Request: "ResolveTestContainerDetailsRequest", + Response: "ResolveTestContainerDetailsResponse", + }, + }, }, EntityRPCs: map[string][]grpcdatasource.EntityRPCConfig{ "Product": { @@ -488,6 +579,15 @@ func DefaultGRPCMapping() *grpcdatasource.GRPCMapping { "filters": "filters", }, }, + "testContainer": { + TargetName: "test_container", + ArgumentMappings: grpcdatasource.FieldArgumentMap{ + "id": "id", + }, + }, + "testContainers": { + TargetName: "test_containers", + }, }, "Mutation": { "createUser": { @@ -588,6 +688,38 @@ func DefaultGRPCMapping() *grpcdatasource.GRPCMapping { "maxPrice": "max_price", }, }, + "mascotRecommendation": { + TargetName: "mascot_recommendation", + ArgumentMappings: grpcdatasource.FieldArgumentMap{ + "includeDetails": "include_details", + }, + }, + "stockStatus": { + TargetName: "stock_status", + ArgumentMappings: grpcdatasource.FieldArgumentMap{ + "checkAvailability": "check_availability", + }, + }, + "productDetails": { + TargetName: "product_details", + ArgumentMappings: grpcdatasource.FieldArgumentMap{ + "includeExtended": "include_extended", + }, + }, + }, + "ProductDetails": { + "id": { + TargetName: "id", + }, + "description": { + TargetName: "description", + }, + "reviewSummary": { + TargetName: "review_summary", + }, + "recommendedPet": { + TargetName: "recommended_pet", + }, }, "Storage": { "id": { @@ -803,6 +935,18 @@ func DefaultGRPCMapping() *grpcdatasource.GRPCMapping { "metricType": "metric_type", }, }, + "mascot": { + TargetName: "mascot", + ArgumentMappings: grpcdatasource.FieldArgumentMap{ + "includeVolume": "include_volume", + }, + }, + "categoryStatus": { + TargetName: "category_status", + ArgumentMappings: grpcdatasource.FieldArgumentMap{ + "checkHealth": "check_health", + }, + }, }, "Subcategory": { "id": { @@ -840,6 +984,15 @@ func DefaultGRPCMapping() *grpcdatasource.GRPCMapping { "categoryId": { TargetName: "category_id", }, + "normalizedScore": { + TargetName: "normalized_score", + ArgumentMappings: grpcdatasource.FieldArgumentMap{ + "baseline": "baseline", + }, + }, + "relatedCategory": { + TargetName: "related_category", + }, }, "Cat": { "id": { @@ -854,6 +1007,12 @@ func DefaultGRPCMapping() *grpcdatasource.GRPCMapping { "meowVolume": { TargetName: "meow_volume", }, + "owner": { + TargetName: "owner", + }, + "breed": { + TargetName: "breed", + }, }, "Dog": { "id": { @@ -868,6 +1027,87 @@ func DefaultGRPCMapping() *grpcdatasource.GRPCMapping { "barkVolume": { TargetName: "bark_volume", }, + "owner": { + TargetName: "owner", + }, + "breed": { + TargetName: "breed", + }, + }, + "Owner": { + "id": { + TargetName: "id", + }, + "name": { + TargetName: "name", + }, + "contact": { + TargetName: "contact", + }, + }, + "ContactInfo": { + "email": { + TargetName: "email", + }, + "phone": { + TargetName: "phone", + }, + "address": { + TargetName: "address", + }, + }, + "Address": { + "street": { + TargetName: "street", + }, + "city": { + TargetName: "city", + }, + "country": { + TargetName: "country", + }, + "zipCode": { + TargetName: "zip_code", + }, + }, + "CatBreed": { + "id": { + TargetName: "id", + }, + "name": { + TargetName: "name", + }, + "origin": { + TargetName: "origin", + }, + "characteristics": { + TargetName: "characteristics", + }, + }, + "DogBreed": { + "id": { + TargetName: "id", + }, + "name": { + TargetName: "name", + }, + "origin": { + TargetName: "origin", + }, + "characteristics": { + TargetName: "characteristics", + }, + }, + "BreedCharacteristics": { + "size": { + TargetName: "size", + }, + "temperament": { + TargetName: "temperament", + }, + "lifespan": { + TargetName: "lifespan", + }, }, "ActionSuccess": { "message": { @@ -885,6 +1125,37 @@ func DefaultGRPCMapping() *grpcdatasource.GRPCMapping { TargetName: "code", }, }, + "TestContainer": { + "id": { + TargetName: "id", + }, + "name": { + TargetName: "name", + }, + "description": { + TargetName: "description", + }, + "details": { + TargetName: "details", + ArgumentMappings: grpcdatasource.FieldArgumentMap{ + "includeExtended": "include_extended", + }, + }, + }, + "TestDetails": { + "id": { + TargetName: "id", + }, + "summary": { + TargetName: "summary", + }, + "pet": { + TargetName: "pet", + }, + "status": { + TargetName: "status", + }, + }, "SearchInput": { "query": { TargetName: "query", diff --git a/v2/pkg/grpctest/mockservice.go b/v2/pkg/grpctest/mockservice.go index 3a50d1c1f..ae9d45ffb 100644 --- a/v2/pkg/grpctest/mockservice.go +++ b/v2/pkg/grpctest/mockservice.go @@ -1,9 +1,8 @@ package grpctest import ( - context "context" + "context" "fmt" - "math" "math/rand" "strconv" @@ -20,639 +19,34 @@ type MockService struct { productv1.UnimplementedProductServiceServer } -// ResolveProductRecommendedCategory implements productv1.ProductServiceServer. -func (s *MockService) ResolveProductRecommendedCategory(_ context.Context, req *productv1.ResolveProductRecommendedCategoryRequest) (*productv1.ResolveProductRecommendedCategoryResponse, error) { - results := make([]*productv1.ResolveProductRecommendedCategoryResult, 0, len(req.GetContext())) +// QueryTestContainer implements productv1.ProductServiceServer. +func (s *MockService) QueryTestContainer(_ context.Context, req *productv1.QueryTestContainerRequest) (*productv1.QueryTestContainerResponse, error) { + id := req.GetId() - maxPrice := int32(0) - if req.GetFieldArgs() != nil { - maxPrice = req.GetFieldArgs().GetMaxPrice() - } - - for _, ctx := range req.GetContext() { - // Return nil for products with high price to test optional return - if maxPrice > 0 && ctx.GetPrice() > float64(maxPrice) { - results = append(results, &productv1.ResolveProductRecommendedCategoryResult{ - RecommendedCategory: nil, - }) - } else { - // Create a recommended category based on product context - var categoryKind productv1.CategoryKind - if ctx.GetPrice() < 50 { - categoryKind = productv1.CategoryKind_CATEGORY_KIND_BOOK - } else if ctx.GetPrice() < 200 { - categoryKind = productv1.CategoryKind_CATEGORY_KIND_ELECTRONICS - } else { - categoryKind = productv1.CategoryKind_CATEGORY_KIND_FURNITURE - } - - results = append(results, &productv1.ResolveProductRecommendedCategoryResult{ - RecommendedCategory: &productv1.Category{ - Id: fmt.Sprintf("recommended-cat-%s", ctx.GetId()), - Name: fmt.Sprintf("Recommended for %s", ctx.GetName()), - Kind: categoryKind, - Subcategories: createSubcategories(fmt.Sprintf("recommended-cat-%s", ctx.GetId()), categoryKind, 2), - }, - }) - } - } - - resp := &productv1.ResolveProductRecommendedCategoryResponse{ - Result: results, - } - - return resp, nil -} - -// ResolveProductShippingEstimate implements productv1.ProductServiceServer. -func (s *MockService) ResolveProductShippingEstimate(_ context.Context, req *productv1.ResolveProductShippingEstimateRequest) (*productv1.ResolveProductShippingEstimateResponse, error) { - results := make([]*productv1.ResolveProductShippingEstimateResult, 0, len(req.GetContext())) - - for _, ctx := range req.GetContext() { - // Base shipping cost calculation - baseCost := ctx.GetPrice() * 0.1 // 10% of product price - - // Add weight-based cost if input provided - if req.GetFieldArgs() != nil && req.GetFieldArgs().GetInput() != nil { - input := req.GetFieldArgs().GetInput() - - // Add weight cost - weightCost := float64(input.GetWeight()) * 2.5 - baseCost += weightCost - - // Add expedited shipping cost - if input.GetExpedited() != nil && input.GetExpedited().GetValue() { - baseCost *= 1.5 // 50% surcharge for expedited - } - - // Add destination-based cost - destination := input.GetDestination() - switch destination { - case productv1.ShippingDestination_SHIPPING_DESTINATION_INTERNATIONAL: - baseCost += 25.0 - case productv1.ShippingDestination_SHIPPING_DESTINATION_EXPRESS: - baseCost += 10.0 - case productv1.ShippingDestination_SHIPPING_DESTINATION_DOMESTIC: - // No additional cost for domestic shipping - } - } - - results = append(results, &productv1.ResolveProductShippingEstimateResult{ - ShippingEstimate: baseCost, - }) - } - - resp := &productv1.ResolveProductShippingEstimateResponse{ - Result: results, - } - - return resp, nil -} - -// ResolveCategoryCategoryMetrics implements productv1.ProductServiceServer. -func (s *MockService) ResolveCategoryCategoryMetrics(_ context.Context, req *productv1.ResolveCategoryCategoryMetricsRequest) (*productv1.ResolveCategoryCategoryMetricsResponse, error) { - results := make([]*productv1.ResolveCategoryCategoryMetricsResult, 0, len(req.GetContext())) - - metricType := "" - if req.GetFieldArgs() != nil { - metricType = req.GetFieldArgs().GetMetricType() - } - - for i, ctx := range req.GetContext() { - // Return nil for certain metric types to test optional return - if metricType == "unavailable" { - results = append(results, &productv1.ResolveCategoryCategoryMetricsResult{ - CategoryMetrics: nil, - }) - } else { - results = append(results, &productv1.ResolveCategoryCategoryMetricsResult{ - CategoryMetrics: &productv1.CategoryMetrics{ - Id: fmt.Sprintf("metrics-%s-%d", ctx.GetId(), i), - MetricType: metricType, - Value: float64(i*25 + 100), // Different values based on index - Timestamp: "2024-01-01T00:00:00Z", - CategoryId: ctx.GetId(), - }, - }) - } - } - - resp := &productv1.ResolveCategoryCategoryMetricsResponse{ - Result: results, - } - - return resp, nil -} - -// ResolveCategoryPopularityScore implements productv1.ProductServiceServer. -func (s *MockService) ResolveCategoryPopularityScore(_ context.Context, req *productv1.ResolveCategoryPopularityScoreRequest) (*productv1.ResolveCategoryPopularityScoreResponse, error) { - results := make([]*productv1.ResolveCategoryPopularityScoreResult, 0, len(req.GetContext())) - - threshold := req.GetFieldArgs().GetThreshold() - - baseScore := 50 - for range req.GetContext() { - if int(threshold.GetValue()) > baseScore { - results = append(results, &productv1.ResolveCategoryPopularityScoreResult{ - PopularityScore: nil, - }) - } else { - results = append(results, &productv1.ResolveCategoryPopularityScoreResult{ - PopularityScore: &wrapperspb.Int32Value{Value: int32(baseScore)}, - }) - } - } - - resp := &productv1.ResolveCategoryPopularityScoreResponse{ - Result: results, - } - - return resp, nil -} - -// ResolveSubcategoryItemCount implements productv1.ProductServiceServer. -func (s *MockService) ResolveSubcategoryItemCount(_ context.Context, req *productv1.ResolveSubcategoryItemCountRequest) (*productv1.ResolveSubcategoryItemCountResponse, error) { - results := make([]*productv1.ResolveSubcategoryItemCountResult, 0, len(req.GetContext())) - for i := range req.GetContext() { - results = append(results, &productv1.ResolveSubcategoryItemCountResult{ - ItemCount: int32(i * 10), // Different multiplier to distinguish from productCount - }) - } - - resp := &productv1.ResolveSubcategoryItemCountResponse{ - Result: results, - } - - return resp, nil -} - -// ResolveCategoryProductCount implements productv1.ProductServiceServer. -func (s *MockService) ResolveCategoryProductCount(_ context.Context, req *productv1.ResolveCategoryProductCountRequest) (*productv1.ResolveCategoryProductCountResponse, error) { - results := make([]*productv1.ResolveCategoryProductCountResult, 0, len(req.GetContext())) - for i := range req.GetContext() { - results = append(results, &productv1.ResolveCategoryProductCountResult{ - ProductCount: int32(i), - }) - } - - resp := &productv1.ResolveCategoryProductCountResponse{ - Result: results, - } - - return resp, nil -} - -// LookupWarehouseById implements productv1.ProductServiceServer. -func (s *MockService) LookupWarehouseById(ctx context.Context, in *productv1.LookupWarehouseByIdRequest) (*productv1.LookupWarehouseByIdResponse, error) { - var results []*productv1.Warehouse - - // Special requirement: return one less item than requested to test error handling - // This deliberately breaks the normal pattern of returning the same number of items as keys - keys := in.GetKeys() - if len(keys) == 0 { - return &productv1.LookupWarehouseByIdResponse{ - Result: results, - }, nil - } - - // Return all items except the last one to test error scenarios - for i, input := range keys { - // Skip the last item to create an intentional mismatch - if i == len(keys)-1 { - break - } - - warehouseId := input.GetId() - results = append(results, &productv1.Warehouse{ - Id: warehouseId, - Name: fmt.Sprintf("Warehouse %s", warehouseId), - Location: fmt.Sprintf("Location %d", rand.Intn(100)), - }) - } - - return &productv1.LookupWarehouseByIdResponse{ - Result: results, - }, nil -} - -// Helper function to create subcategories for a category -func createSubcategories(categoryId string, kind productv1.CategoryKind, count int) *productv1.ListOfSubcategory { - if count <= 0 { - return &productv1.ListOfSubcategory{ - List: &productv1.ListOfSubcategory_List{ - Items: []*productv1.Subcategory{}, - }, - } - } - - subcategories := make([]*productv1.Subcategory, 0, count) - for j := 1; j <= count; j++ { - subcategories = append(subcategories, &productv1.Subcategory{ - Id: fmt.Sprintf("%s-subcategory-%d", categoryId, j), - Name: fmt.Sprintf("%s Subcategory %d", kind.String(), j), - Description: &wrapperspb.StringValue{Value: fmt.Sprintf("Subcategory %d for %s", j, categoryId)}, - IsActive: true, - }) - } - - return &productv1.ListOfSubcategory{ - List: &productv1.ListOfSubcategory_List{ - Items: subcategories, - }, - } -} - -// Helper functions to convert input types to output types -func convertCategoryInputsToCategories(inputs []*productv1.CategoryInput) []*productv1.Category { - if inputs == nil { - return nil - } - results := make([]*productv1.Category, len(inputs)) - for i, input := range inputs { - results[i] = &productv1.Category{ - Id: fmt.Sprintf("cat-input-%d", i), - Name: input.GetName(), - Kind: input.GetKind(), - Subcategories: createSubcategories(fmt.Sprintf("cat-input-%d", i), input.GetKind(), i+1), - } - } - return results -} - -func convertCategoryInputListToCategories(inputs *productv1.ListOfCategoryInput) []*productv1.Category { - if inputs == nil || inputs.List == nil || inputs.List.Items == nil { - return nil - } - results := make([]*productv1.Category, len(inputs.List.Items)) - for i, input := range inputs.List.Items { - results[i] = &productv1.Category{ - Id: fmt.Sprintf("cat-list-input-%d", i), - Name: input.GetName(), - Kind: input.GetKind(), - Subcategories: createSubcategories(fmt.Sprintf("cat-list-input-%d", i), input.GetKind(), i+1), - } - } - return results -} - -func convertUserInputsToUsers(inputs *productv1.ListOfUserInput) []*productv1.User { - if inputs == nil || inputs.List == nil || inputs.List.Items == nil { - return nil - } - results := make([]*productv1.User, len(inputs.List.Items)) - for i, input := range inputs.List.Items { - results[i] = &productv1.User{ - Id: fmt.Sprintf("user-input-%d", i), - Name: input.GetName(), - } - } - return results -} - -func convertNestedUserInputsToUsers(nestedInputs *productv1.ListOfListOfUserInput) *productv1.ListOfListOfUser { - if nestedInputs == nil || nestedInputs.List == nil { - return &productv1.ListOfListOfUser{ - List: &productv1.ListOfListOfUser_List{ - Items: []*productv1.ListOfUser{}, - }, - } - } - - results := make([]*productv1.ListOfUser, len(nestedInputs.List.Items)) - for i, userList := range nestedInputs.List.Items { - users := make([]*productv1.User, len(userList.List.Items)) - for j, userInput := range userList.List.Items { - users[j] = &productv1.User{ - Id: fmt.Sprintf("nested-user-%d-%d", i, j), - Name: userInput.GetName(), - } - } - results[i] = &productv1.ListOfUser{ - List: &productv1.ListOfUser_List{ - Items: users, - }, - } - } - - return &productv1.ListOfListOfUser{ - List: &productv1.ListOfListOfUser_List{ - Items: results, - }, - } -} - -func convertNestedCategoryInputsToCategories(nestedInputs *productv1.ListOfListOfCategoryInput) *productv1.ListOfListOfCategory { - if nestedInputs == nil || nestedInputs.List == nil { - return &productv1.ListOfListOfCategory{ - List: &productv1.ListOfListOfCategory_List{ - Items: []*productv1.ListOfCategory{}, - }, - } - } - - results := make([]*productv1.ListOfCategory, len(nestedInputs.List.Items)) - for i, categoryList := range nestedInputs.List.Items { - categories := make([]*productv1.Category, len(categoryList.List.Items)) - for j, categoryInput := range categoryList.List.Items { - categories[j] = &productv1.Category{ - Id: fmt.Sprintf("nested-cat-%d-%d", i, j), - Name: categoryInput.GetName(), - Kind: categoryInput.GetKind(), - Subcategories: createSubcategories(fmt.Sprintf("nested-cat-%d-%d", i, j), categoryInput.GetKind(), j+1), - } - } - results[i] = &productv1.ListOfCategory{ - List: &productv1.ListOfCategory_List{ - Items: categories, - }, - } - } - - return &productv1.ListOfListOfCategory{ - List: &productv1.ListOfListOfCategory_List{ - Items: results, + return &productv1.QueryTestContainerResponse{ + TestContainer: &productv1.TestContainer{ + Id: id, + Name: fmt.Sprintf("TestContainer-%s", id), + Description: &wrapperspb.StringValue{Value: fmt.Sprintf("Description for TestContainer %s", id)}, }, - } -} - -// MutationCreateNullableFieldsType implements productv1.ProductServiceServer. -func (s *MockService) MutationCreateNullableFieldsType(ctx context.Context, in *productv1.MutationCreateNullableFieldsTypeRequest) (*productv1.MutationCreateNullableFieldsTypeResponse, error) { - input := in.GetInput() - - // Create a new NullableFieldsType from the input - result := &productv1.NullableFieldsType{ - Id: fmt.Sprintf("nullable-%d", rand.Intn(1000)), - Name: input.GetName(), - RequiredString: input.GetRequiredString(), - RequiredInt: input.GetRequiredInt(), - } - - // Handle optional fields - copy from input if they exist - if input.OptionalString != nil { - result.OptionalString = &wrapperspb.StringValue{Value: input.OptionalString.GetValue()} - } - if input.OptionalInt != nil { - result.OptionalInt = &wrapperspb.Int32Value{Value: input.OptionalInt.GetValue()} - } - if input.OptionalFloat != nil { - result.OptionalFloat = &wrapperspb.DoubleValue{Value: input.OptionalFloat.GetValue()} - } - if input.OptionalBoolean != nil { - result.OptionalBoolean = &wrapperspb.BoolValue{Value: input.OptionalBoolean.GetValue()} - } - - return &productv1.MutationCreateNullableFieldsTypeResponse{ - CreateNullableFieldsType: result, - }, nil -} - -// MutationUpdateNullableFieldsType implements productv1.ProductServiceServer. -func (s *MockService) MutationUpdateNullableFieldsType(ctx context.Context, in *productv1.MutationUpdateNullableFieldsTypeRequest) (*productv1.MutationUpdateNullableFieldsTypeResponse, error) { - id := in.GetId() - input := in.GetInput() - - // Return nil if trying to update a non-existent ID - if id == "non-existent" { - return &productv1.MutationUpdateNullableFieldsTypeResponse{ - UpdateNullableFieldsType: nil, - }, nil - } - - // Create updated NullableFieldsType - result := &productv1.NullableFieldsType{ - Id: id, - Name: input.GetName(), - RequiredString: input.GetRequiredString(), - RequiredInt: input.GetRequiredInt(), - } - - // Handle optional fields - copy from input if they exist - if input.OptionalString != nil { - result.OptionalString = &wrapperspb.StringValue{Value: input.OptionalString.GetValue()} - } - if input.OptionalInt != nil { - result.OptionalInt = &wrapperspb.Int32Value{Value: input.OptionalInt.GetValue()} - } - if input.OptionalFloat != nil { - result.OptionalFloat = &wrapperspb.DoubleValue{Value: input.OptionalFloat.GetValue()} - } - if input.OptionalBoolean != nil { - result.OptionalBoolean = &wrapperspb.BoolValue{Value: input.OptionalBoolean.GetValue()} - } - - return &productv1.MutationUpdateNullableFieldsTypeResponse{ - UpdateNullableFieldsType: result, - }, nil -} - -// QueryAllNullableFieldsTypes implements productv1.ProductServiceServer. -func (s *MockService) QueryAllNullableFieldsTypes(ctx context.Context, in *productv1.QueryAllNullableFieldsTypesRequest) (*productv1.QueryAllNullableFieldsTypesResponse, error) { - var results []*productv1.NullableFieldsType - - // Create a variety of test data with different nullable field combinations - - // Entry 1: All fields populated - results = append(results, &productv1.NullableFieldsType{ - Id: "nullable-1", - Name: "Full Data Entry", - OptionalString: &wrapperspb.StringValue{Value: "Optional String Value"}, - OptionalInt: &wrapperspb.Int32Value{Value: 42}, - OptionalFloat: &wrapperspb.DoubleValue{Value: math.MaxFloat64}, - OptionalBoolean: &wrapperspb.BoolValue{Value: true}, - RequiredString: "Required String 1", - RequiredInt: 100, - }) - - // Entry 2: Some nullable fields are null - results = append(results, &productv1.NullableFieldsType{ - Id: "nullable-2", - Name: "Partial Data Entry", - OptionalString: &wrapperspb.StringValue{Value: "Only string is set"}, - OptionalInt: nil, // null - OptionalFloat: nil, // null - OptionalBoolean: &wrapperspb.BoolValue{Value: false}, - RequiredString: "Required String 2", - RequiredInt: 200, - }) - - // Entry 3: All nullable fields are null - results = append(results, &productv1.NullableFieldsType{ - Id: "nullable-3", - Name: "Minimal Data Entry", - OptionalString: nil, // null - OptionalInt: nil, // null - OptionalFloat: nil, // null - OptionalBoolean: nil, // null - RequiredString: "Required String 3", - RequiredInt: 300, - }) - - return &productv1.QueryAllNullableFieldsTypesResponse{ - AllNullableFieldsTypes: results, - }, nil -} - -// QueryNullableFieldsType implements productv1.ProductServiceServer. -func (s *MockService) QueryNullableFieldsType(ctx context.Context, in *productv1.QueryNullableFieldsTypeRequest) (*productv1.QueryNullableFieldsTypeResponse, error) { - // Return a single NullableFieldsType with mixed null/non-null values - result := &productv1.NullableFieldsType{ - Id: "nullable-default", - Name: "Default Nullable Fields Type", - OptionalString: &wrapperspb.StringValue{Value: "Default optional string"}, - OptionalInt: &wrapperspb.Int32Value{Value: 777}, - OptionalFloat: nil, // null - OptionalBoolean: &wrapperspb.BoolValue{Value: true}, - RequiredString: "Default required string", - RequiredInt: 999, - } - - return &productv1.QueryNullableFieldsTypeResponse{ - NullableFieldsType: result, - }, nil -} - -// QueryNullableFieldsTypeById implements productv1.ProductServiceServer. -func (s *MockService) QueryNullableFieldsTypeById(ctx context.Context, in *productv1.QueryNullableFieldsTypeByIdRequest) (*productv1.QueryNullableFieldsTypeByIdResponse, error) { - id := in.GetId() - - // Return null for specific test IDs - if id == "not-found" || id == "null-test" { - return &productv1.QueryNullableFieldsTypeByIdResponse{ - NullableFieldsTypeById: nil, - }, nil - } - - // Create different test data based on ID - var result *productv1.NullableFieldsType - - switch id { - case "full-data": - result = &productv1.NullableFieldsType{ - Id: id, - Name: "Full Data by ID", - OptionalString: &wrapperspb.StringValue{Value: "All fields populated"}, - OptionalInt: &wrapperspb.Int32Value{Value: 123}, - OptionalFloat: &wrapperspb.DoubleValue{Value: 12.34}, - OptionalBoolean: &wrapperspb.BoolValue{Value: false}, - RequiredString: "Required by ID", - RequiredInt: 456, - } - case "partial-data": - result = &productv1.NullableFieldsType{ - Id: id, - Name: "Partial Data by ID", - OptionalString: nil, // null - OptionalInt: &wrapperspb.Int32Value{Value: 789}, - OptionalFloat: nil, // null - OptionalBoolean: &wrapperspb.BoolValue{Value: true}, - RequiredString: "Partial required by ID", - RequiredInt: 321, - } - case "minimal-data": - result = &productv1.NullableFieldsType{ - Id: id, - Name: "Minimal Data by ID", - OptionalString: nil, // null - OptionalInt: nil, // null - OptionalFloat: nil, // null - OptionalBoolean: nil, // null - RequiredString: "Only required fields", - RequiredInt: 111, - } - default: - // Generic response for any other ID - result = &productv1.NullableFieldsType{ - Id: id, - Name: fmt.Sprintf("Nullable Type %s", id), - OptionalString: &wrapperspb.StringValue{Value: fmt.Sprintf("Optional for %s", id)}, - OptionalInt: &wrapperspb.Int32Value{Value: int32(len(id) * 10)}, - OptionalFloat: &wrapperspb.DoubleValue{Value: float64(len(id)) * 1.5}, - OptionalBoolean: &wrapperspb.BoolValue{Value: len(id)%2 == 0}, - RequiredString: fmt.Sprintf("Required for %s", id), - RequiredInt: int32(len(id) * 100), - } - } - - return &productv1.QueryNullableFieldsTypeByIdResponse{ - NullableFieldsTypeById: result, }, nil } -// QueryNullableFieldsTypeWithFilter implements productv1.ProductServiceServer. -func (s *MockService) QueryNullableFieldsTypeWithFilter(ctx context.Context, in *productv1.QueryNullableFieldsTypeWithFilterRequest) (*productv1.QueryNullableFieldsTypeWithFilterResponse, error) { - filter := in.GetFilter() - var results []*productv1.NullableFieldsType - - // If no filter provided, return empty results - if filter == nil { - return &productv1.QueryNullableFieldsTypeWithFilterResponse{ - NullableFieldsTypeWithFilter: results, - }, nil - } - - // Create test data based on filter criteria - nameFilter := "" - if filter.Name != nil { - nameFilter = filter.Name.GetValue() - } - - optionalStringFilter := "" - if filter.OptionalString != nil { - optionalStringFilter = filter.OptionalString.GetValue() - } - - includeNulls := false - if filter.IncludeNulls != nil { - includeNulls = filter.IncludeNulls.GetValue() - } +// QueryTestContainers implements productv1.ProductServiceServer. +func (s *MockService) QueryTestContainers(_ context.Context, _ *productv1.QueryTestContainersRequest) (*productv1.QueryTestContainersResponse, error) { + var containers []*productv1.TestContainer - // Generate filtered results + // Generate 3 test containers for i := 1; i <= 3; i++ { - var optionalString *wrapperspb.StringValue - var optionalInt *wrapperspb.Int32Value - var optionalFloat *wrapperspb.DoubleValue - var optionalBoolean *wrapperspb.BoolValue - - // Vary the nullable fields based on includeNulls and index - if includeNulls || i%2 == 1 { - if optionalStringFilter != "" { - optionalString = &wrapperspb.StringValue{Value: optionalStringFilter} - } else { - optionalString = &wrapperspb.StringValue{Value: fmt.Sprintf("Filtered string %d", i)} - } - } - - if includeNulls || i%3 != 0 { - optionalInt = &wrapperspb.Int32Value{Value: int32(i * 100)} - } - - if includeNulls || i%2 == 0 { - optionalFloat = &wrapperspb.DoubleValue{Value: float64(i) * 10.5} - } - - if includeNulls || i%4 != 0 { - optionalBoolean = &wrapperspb.BoolValue{Value: i%2 == 0} - } - - name := fmt.Sprintf("Filtered Item %d", i) - if nameFilter != "" { - name = fmt.Sprintf("%s - %d", nameFilter, i) - } - - results = append(results, &productv1.NullableFieldsType{ - Id: fmt.Sprintf("filtered-%d", i), - Name: name, - OptionalString: optionalString, - OptionalInt: optionalInt, - OptionalFloat: optionalFloat, - OptionalBoolean: optionalBoolean, - RequiredString: fmt.Sprintf("Required filtered %d", i), - RequiredInt: int32(i * 1000), + containers = append(containers, &productv1.TestContainer{ + Id: fmt.Sprintf("container-%d", i), + Name: fmt.Sprintf("TestContainer %d", i), + Description: &wrapperspb.StringValue{Value: fmt.Sprintf("Description for container %d", i)}, }) } - return &productv1.QueryNullableFieldsTypeWithFilterResponse{ - NullableFieldsTypeWithFilter: results, + return &productv1.QueryTestContainersResponse{ + TestContainers: containers, }, nil } @@ -812,40 +206,6 @@ func (s *MockService) QuerySearch(ctx context.Context, in *productv1.QuerySearch }, nil } -func (s *MockService) LookupProductById(ctx context.Context, in *productv1.LookupProductByIdRequest) (*productv1.LookupProductByIdResponse, error) { - var results []*productv1.Product - - for _, input := range in.GetKeys() { - productId := input.GetId() - results = append(results, &productv1.Product{ - Id: productId, - Name: fmt.Sprintf("Product %s", productId), - Price: 99.99, - }) - } - - return &productv1.LookupProductByIdResponse{ - Result: results, - }, nil -} - -func (s *MockService) LookupStorageById(ctx context.Context, in *productv1.LookupStorageByIdRequest) (*productv1.LookupStorageByIdResponse, error) { - var results []*productv1.Storage - - for _, input := range in.GetKeys() { - storageId := input.GetId() - results = append(results, &productv1.Storage{ - Id: storageId, - Name: fmt.Sprintf("Storage %s", storageId), - Location: fmt.Sprintf("Location %d", rand.Intn(100)), - }) - } - - return &productv1.LookupStorageByIdResponse{ - Result: results, - }, nil -} - func (s *MockService) QueryUsers(ctx context.Context, in *productv1.QueryUsersRequest) (*productv1.QueryUsersResponse, error) { var results []*productv1.User @@ -997,6 +357,30 @@ func (s *MockService) QueryRandomPet(ctx context.Context, in *productv1.QueryRan Name: "Whiskers", Kind: "Siamese", MeowVolume: int32(rand.Intn(10) + 1), // Random volume between 1-10 + Owner: &productv1.Owner{ + Id: "owner-cat-1", + Name: "Alice Johnson", + Contact: &productv1.ContactInfo{ + Email: "alice@example.com", + Phone: "555-100-2000", + Address: &productv1.Address{ + Street: "10 Cat Street", + City: "Catville", + Country: "USA", + ZipCode: "10101", + }, + }, + }, + Breed: &productv1.CatBreed{ + Id: "breed-cat-1", + Name: "Siamese", + Origin: "Thailand", + Characteristics: &productv1.BreedCharacteristics{ + Size: "Medium", + Temperament: "Vocal and Active", + Lifespan: "15-20 years", + }, + }, }, }, } @@ -1009,6 +393,30 @@ func (s *MockService) QueryRandomPet(ctx context.Context, in *productv1.QueryRan Name: "Spot", Kind: "Dalmatian", BarkVolume: int32(rand.Intn(10) + 1), // Random volume between 1-10 + Owner: &productv1.Owner{ + Id: "owner-dog-1", + Name: "Bob Smith", + Contact: &productv1.ContactInfo{ + Email: "bob@example.com", + Phone: "555-200-3000", + Address: &productv1.Address{ + Street: "20 Dog Lane", + City: "Dogtown", + Country: "USA", + ZipCode: "20202", + }, + }, + }, + Breed: &productv1.DogBreed{ + Id: "breed-dog-1", + Name: "Dalmatian", + Origin: "Croatia", + Characteristics: &productv1.BreedCharacteristics{ + Size: "Large", + Temperament: "Outgoing and Friendly", + Lifespan: "10-13 years", + }, + }, }, }, } @@ -1032,6 +440,30 @@ func (s *MockService) QueryAllPets(ctx context.Context, in *productv1.QueryAllPe Name: fmt.Sprintf("Cat %d", i), Kind: fmt.Sprintf("Breed %d", i), MeowVolume: int32(i + 3), // Different volumes + Owner: &productv1.Owner{ + Id: fmt.Sprintf("owner-cat-%d", i), + Name: fmt.Sprintf("Cat Owner %d", i), + Contact: &productv1.ContactInfo{ + Email: fmt.Sprintf("cat-owner-%d@example.com", i), + Phone: fmt.Sprintf("555-%03d-0000", i*100), + Address: &productv1.Address{ + Street: fmt.Sprintf("%d Cat Street", i*100), + City: "Feline City", + Country: "USA", + ZipCode: fmt.Sprintf("%05d", i*10000), + }, + }, + }, + Breed: &productv1.CatBreed{ + Id: fmt.Sprintf("breed-cat-%d", i), + Name: fmt.Sprintf("Cat Breed %d", i), + Origin: "Various", + Characteristics: &productv1.BreedCharacteristics{ + Size: "Medium", + Temperament: "Friendly", + Lifespan: "12-18 years", + }, + }, }, }, }) @@ -1046,6 +478,30 @@ func (s *MockService) QueryAllPets(ctx context.Context, in *productv1.QueryAllPe Name: fmt.Sprintf("Dog %d", i), Kind: fmt.Sprintf("Breed %d", i), BarkVolume: int32(i + 5), // Different volumes + Owner: &productv1.Owner{ + Id: fmt.Sprintf("owner-dog-%d", i), + Name: fmt.Sprintf("Dog Owner %d", i), + Contact: &productv1.ContactInfo{ + Email: fmt.Sprintf("dog-owner-%d@example.com", i), + Phone: fmt.Sprintf("555-%03d-1111", i*100), + Address: &productv1.Address{ + Street: fmt.Sprintf("%d Dog Avenue", i*200), + City: "Canine City", + Country: "USA", + ZipCode: fmt.Sprintf("%05d", i*20000), + }, + }, + }, + Breed: &productv1.DogBreed{ + Id: fmt.Sprintf("breed-dog-%d", i), + Name: fmt.Sprintf("Dog Breed %d", i), + Origin: "Various", + Characteristics: &productv1.BreedCharacteristics{ + Size: "Large", + Temperament: "Loyal", + Lifespan: "10-14 years", + }, + }, }, }, }) @@ -1056,159 +512,25 @@ func (s *MockService) QueryAllPets(ctx context.Context, in *productv1.QueryAllPe }, nil } -// Implementation for QueryCategories -func (s *MockService) QueryCategories(ctx context.Context, in *productv1.QueryCategoriesRequest) (*productv1.QueryCategoriesResponse, error) { - // Generate a list of categories - var categories []*productv1.Category - - // Create sample categories for each CategoryKind - categoryKinds := []productv1.CategoryKind{ - productv1.CategoryKind_CATEGORY_KIND_BOOK, - productv1.CategoryKind_CATEGORY_KIND_ELECTRONICS, - productv1.CategoryKind_CATEGORY_KIND_FURNITURE, - productv1.CategoryKind_CATEGORY_KIND_OTHER, - } +// Implementation for CreateUser mutation +func (s *MockService) MutationCreateUser(ctx context.Context, in *productv1.MutationCreateUserRequest) (*productv1.MutationCreateUserResponse, error) { + input := in.GetInput() - for i, kind := range categoryKinds { - categories = append(categories, &productv1.Category{ - Id: fmt.Sprintf("category-%d", i+1), - Name: fmt.Sprintf("%s Category", kind.String()), - Kind: kind, - Subcategories: createSubcategories(fmt.Sprintf("category-%d", i+1), kind, i+1), - }) + // Create a new user with the input name and a random ID + user := &productv1.User{ + Id: fmt.Sprintf("user-%d", rand.Intn(1000)), + Name: input.GetName(), } - return &productv1.QueryCategoriesResponse{ - Categories: categories, + return &productv1.MutationCreateUserResponse{ + CreateUser: user, }, nil } -// Implementation for QueryCategoriesByKind -func (s *MockService) QueryCategoriesByKind(ctx context.Context, in *productv1.QueryCategoriesByKindRequest) (*productv1.QueryCategoriesByKindResponse, error) { - kind := in.GetKind() - - // Generate categories for the specified kind - var categories []*productv1.Category - - // Create 3 categories of the requested kind - for i := 1; i <= 3; i++ { - - subcategoties := make([]*productv1.Subcategory, 0, i) - for j := 1; j <= i; j++ { - subcategoties = append(subcategoties, &productv1.Subcategory{ - Id: fmt.Sprintf("%s-subcategory-%d", kind.String(), j), - Name: fmt.Sprintf("%s Subcategory %d", kind.String(), j), - Description: &wrapperspb.StringValue{Value: fmt.Sprintf("%s Subcategory %d", kind.String(), j)}, - IsActive: true, - }) - } - - categories = append(categories, &productv1.Category{ - Id: fmt.Sprintf("%s-category-%d", kind.String(), i), - Name: fmt.Sprintf("%s Category %d", kind.String(), i), - Kind: kind, - Subcategories: &productv1.ListOfSubcategory{ - List: &productv1.ListOfSubcategory_List{ - Items: subcategoties, - }, - }, - }) - } - - return &productv1.QueryCategoriesByKindResponse{ - CategoriesByKind: categories, - }, nil -} - -func (s *MockService) QueryCategoriesByKinds(ctx context.Context, in *productv1.QueryCategoriesByKindsRequest) (*productv1.QueryCategoriesByKindsResponse, error) { - kinds := in.GetKinds() - - var categories []*productv1.Category - - for i, kind := range kinds { - categories = append(categories, &productv1.Category{ - Id: fmt.Sprintf("%s-category-%d", kind.String(), i), - Name: fmt.Sprintf("%s Category %d", kind.String(), i), - Kind: kind, - Subcategories: createSubcategories(fmt.Sprintf("%s-category-%d", kind.String(), i), kind, i+1), - }) - } - - return &productv1.QueryCategoriesByKindsResponse{ - CategoriesByKinds: categories, - }, nil -} - -// Implementation for QueryFilterCategories -func (s *MockService) QueryFilterCategories(ctx context.Context, in *productv1.QueryFilterCategoriesRequest) (*productv1.QueryFilterCategoriesResponse, error) { - filter := in.GetFilter() - - if filter == nil { - return &productv1.QueryFilterCategoriesResponse{ - FilterCategories: []*productv1.Category{}, - }, nil - } - - kind := filter.GetCategory() - - // Generate filtered categories - var categories []*productv1.Category - - // Create categories that match the filter - for i := 1; i <= 5; i++ { - categories = append(categories, &productv1.Category{ - Id: fmt.Sprintf("filtered-%s-category-%d", kind.String(), i), - Name: fmt.Sprintf("Filtered %s Category %d", kind.String(), i), - Kind: kind, - Subcategories: createSubcategories(fmt.Sprintf("filtered-%s-category-%d", kind.String(), i), kind, i), - }) - } - - // Apply pagination if provided - pagination := filter.GetPagination() - if pagination != nil { - page := int(pagination.GetPage()) - perPage := int(pagination.GetPerPage()) - - if page > 0 && perPage > 0 && len(categories) > perPage { - startIdx := (page - 1) * perPage - endIdx := startIdx + perPage - - if startIdx < len(categories) { - if endIdx > len(categories) { - endIdx = len(categories) - } - categories = categories[startIdx:endIdx] - } else { - categories = []*productv1.Category{} - } - } - } - - return &productv1.QueryFilterCategoriesResponse{ - FilterCategories: categories, - }, nil -} - -// Implementation for CreateUser mutation -func (s *MockService) MutationCreateUser(ctx context.Context, in *productv1.MutationCreateUserRequest) (*productv1.MutationCreateUserResponse, error) { - input := in.GetInput() - - // Create a new user with the input name and a random ID - user := &productv1.User{ - Id: fmt.Sprintf("user-%d", rand.Intn(1000)), - Name: input.GetName(), - } - - return &productv1.MutationCreateUserResponse{ - CreateUser: user, - }, nil -} - -// Implementation for QueryCalculateTotals -func (s *MockService) QueryCalculateTotals(ctx context.Context, in *productv1.QueryCalculateTotalsRequest) (*productv1.QueryCalculateTotalsResponse, error) { - orders := in.GetOrders() - var calculatedOrders []*productv1.Order +// Implementation for QueryCalculateTotals +func (s *MockService) QueryCalculateTotals(ctx context.Context, in *productv1.QueryCalculateTotalsRequest) (*productv1.QueryCalculateTotalsResponse, error) { + orders := in.GetOrders() + var calculatedOrders []*productv1.Order for _, orderInput := range orders { // Calculate total items by summing up quantities from all order lines @@ -1242,1744 +564,3 @@ func (s *MockService) QueryCalculateTotals(ctx context.Context, in *productv1.Qu CalculateTotals: calculatedOrders, }, nil } - -// BlogPost query implementations -func (s *MockService) QueryBlogPost(ctx context.Context, in *productv1.QueryBlogPostRequest) (*productv1.QueryBlogPostResponse, error) { - // Return a default blog post with comprehensive list examples - result := &productv1.BlogPost{ - Id: "blog-default", - Title: "Default Blog Post", - Content: "This is a sample blog post content for testing nested lists.", - Tags: []string{"tech", "programming", "go"}, - OptionalTags: &productv1.ListOfString{ - List: &productv1.ListOfString_List{ - Items: []string{"optional1", "optional2"}, - }, - }, - Categories: []string{"Technology", "", "Programming"}, // includes null/empty - Keywords: &productv1.ListOfString{ - List: &productv1.ListOfString_List{ - Items: []string{"keyword1", "keyword2"}, - }, - }, - ViewCounts: []int32{100, 150, 200, 250}, - Ratings: &productv1.ListOfFloat{ - List: &productv1.ListOfFloat_List{ - Items: []float64{4.5, 3.8, 5.0}, - }, - }, - IsPublished: &productv1.ListOfBoolean{ - List: &productv1.ListOfBoolean_List{ - Items: []bool{false, true, true}, - }, - }, - TagGroups: &productv1.ListOfListOfString{ - List: &productv1.ListOfListOfString_List{ - Items: []*productv1.ListOfString{ - {List: &productv1.ListOfString_List{ - Items: []string{"tech", "programming"}, - }}, - {List: &productv1.ListOfString_List{ - Items: []string{"golang", "backend"}, - }}, - }, - }, - }, - RelatedTopics: &productv1.ListOfListOfString{ - List: &productv1.ListOfListOfString_List{ - Items: []*productv1.ListOfString{ - {List: &productv1.ListOfString_List{Items: []string{"microservices", "api"}}}, - {List: &productv1.ListOfString_List{Items: []string{"databases", "performance"}}}, - }, - }, - }, - CommentThreads: &productv1.ListOfListOfString{ - List: &productv1.ListOfListOfString_List{ - Items: []*productv1.ListOfString{ - {List: &productv1.ListOfString_List{Items: []string{"Great post!", "Very helpful"}}}, - {List: &productv1.ListOfString_List{Items: []string{"Could use more examples", "Thanks for sharing"}}}, - }, - }, - }, - Suggestions: &productv1.ListOfListOfString{ - List: &productv1.ListOfListOfString_List{ - Items: []*productv1.ListOfString{ - {List: &productv1.ListOfString_List{Items: []string{"Add code examples", "Include diagrams"}}}, - }, - }, - }, - RelatedCategories: []*productv1.Category{ - {Id: "cat-1", Name: "Technology", Kind: productv1.CategoryKind_CATEGORY_KIND_ELECTRONICS}, - {Id: "cat-2", Name: "Programming", Kind: productv1.CategoryKind_CATEGORY_KIND_BOOK}, - }, - Contributors: []*productv1.User{ - {Id: "user-1", Name: "John Doe"}, - {Id: "user-2", Name: "Jane Smith"}, - }, - MentionedProducts: &productv1.ListOfProduct{ - List: &productv1.ListOfProduct_List{ - Items: []*productv1.Product{ - {Id: "prod-1", Name: "Sample Product", Price: 99.99}, - }, - }, - }, - MentionedUsers: &productv1.ListOfUser{ - List: &productv1.ListOfUser_List{ - Items: []*productv1.User{ - {Id: "user-3", Name: "Bob Johnson"}, - }, - }, - }, - CategoryGroups: &productv1.ListOfListOfCategory{ - List: &productv1.ListOfListOfCategory_List{ - Items: []*productv1.ListOfCategory{ - {List: &productv1.ListOfCategory_List{ - Items: []*productv1.Category{ - {Id: "cat-3", Name: "Web Development", Kind: productv1.CategoryKind_CATEGORY_KIND_ELECTRONICS}, - {Id: "cat-4", Name: "Backend", Kind: productv1.CategoryKind_CATEGORY_KIND_ELECTRONICS}, - }, - }}, - }, - }, - }, - ContributorTeams: &productv1.ListOfListOfUser{ - List: &productv1.ListOfListOfUser_List{ - Items: []*productv1.ListOfUser{ - {List: &productv1.ListOfUser_List{ - Items: []*productv1.User{ - {Id: "user-4", Name: "Alice Brown"}, - {Id: "user-5", Name: "Charlie Wilson"}, - }, - }}, - }, - }, - }, - } - - return &productv1.QueryBlogPostResponse{ - BlogPost: result, - }, nil -} - -func (s *MockService) QueryBlogPostById(ctx context.Context, in *productv1.QueryBlogPostByIdRequest) (*productv1.QueryBlogPostByIdResponse, error) { - id := in.GetId() - - // Return null for specific test IDs - if id == "not-found" { - return &productv1.QueryBlogPostByIdResponse{ - BlogPostById: nil, - }, nil - } - - // Create different test data based on ID - var result *productv1.BlogPost - - switch id { - case "simple": - result = &productv1.BlogPost{ - Id: id, - Title: "Simple Post", - Content: "Simple content", - Tags: []string{"simple"}, - Categories: []string{"Basic"}, - ViewCounts: []int32{10}, - // Required nested lists must have data - TagGroups: &productv1.ListOfListOfString{ - List: &productv1.ListOfListOfString_List{ - Items: []*productv1.ListOfString{ - {List: &productv1.ListOfString_List{Items: []string{"simple"}}}, - }, - }, - }, - RelatedTopics: &productv1.ListOfListOfString{ - List: &productv1.ListOfListOfString_List{ - Items: []*productv1.ListOfString{ - {List: &productv1.ListOfString_List{Items: []string{"basic"}}}, - }, - }, - }, - CommentThreads: &productv1.ListOfListOfString{ - List: &productv1.ListOfListOfString_List{ - Items: []*productv1.ListOfString{ - {List: &productv1.ListOfString_List{Items: []string{"Nice post"}}}, - }, - }, - }, - // Required complex lists must have data - RelatedCategories: []*productv1.Category{ - {Id: "cat-simple", Name: "Basic", Kind: productv1.CategoryKind_CATEGORY_KIND_OTHER}, - }, - Contributors: []*productv1.User{ - {Id: "user-simple", Name: "Simple Author"}, - }, - CategoryGroups: &productv1.ListOfListOfCategory{ - List: &productv1.ListOfListOfCategory_List{ - Items: []*productv1.ListOfCategory{ - {List: &productv1.ListOfCategory_List{ - Items: []*productv1.Category{ - {Id: "cat-group-simple", Name: "Simple Category", Kind: productv1.CategoryKind_CATEGORY_KIND_OTHER}, - }, - }}, - }, - }, - }, - } - case "complex": - result = &productv1.BlogPost{ - Id: id, - Title: "Complex Blog Post", - Content: "Complex content with comprehensive lists", - Tags: []string{"complex", "advanced", "detailed"}, - OptionalTags: &productv1.ListOfString{ - List: &productv1.ListOfString_List{ - Items: []string{"deep-dive", "tutorial"}, - }, - }, - Categories: []string{"Advanced", "Tutorial", "Guide"}, - Keywords: &productv1.ListOfString{ - List: &productv1.ListOfString_List{ - Items: []string{"advanced", "complex", "comprehensive"}, - }, - }, - ViewCounts: []int32{500, 600, 750, 800, 950}, - Ratings: &productv1.ListOfFloat{ - List: &productv1.ListOfFloat_List{ - Items: []float64{4.8, 4.9, 4.7, 5.0}, - }, - }, - IsPublished: &productv1.ListOfBoolean{ - List: &productv1.ListOfBoolean_List{ - Items: []bool{false, false, true, true}, - }, - }, - TagGroups: &productv1.ListOfListOfString{ - List: &productv1.ListOfListOfString_List{ - Items: []*productv1.ListOfString{ - {List: &productv1.ListOfString_List{Items: []string{"advanced", "expert"}}}, - {List: &productv1.ListOfString_List{Items: []string{"tutorial", "guide", "comprehensive"}}}, - {List: &productv1.ListOfString_List{Items: []string{"deep-dive", "detailed"}}}, - }, - }, - }, - RelatedTopics: &productv1.ListOfListOfString{ - List: &productv1.ListOfListOfString_List{ - Items: []*productv1.ListOfString{ - {List: &productv1.ListOfString_List{Items: []string{"architecture", "patterns", "design"}}}, - {List: &productv1.ListOfString_List{Items: []string{"optimization", "performance", "scaling"}}}, - }, - }, - }, - CommentThreads: &productv1.ListOfListOfString{ - List: &productv1.ListOfListOfString_List{ - Items: []*productv1.ListOfString{ - {List: &productv1.ListOfString_List{Items: []string{"Excellent deep dive!", "Very thorough"}}}, - {List: &productv1.ListOfString_List{Items: []string{"Could be longer", "More examples please"}}}, - {List: &productv1.ListOfString_List{Items: []string{"Best tutorial I've read", "Thank you!"}}}, - }, - }, - }, - Suggestions: &productv1.ListOfListOfString{ - List: &productv1.ListOfListOfString_List{ - Items: []*productv1.ListOfString{ - {List: &productv1.ListOfString_List{Items: []string{"Add video content", "Include interactive examples"}}}, - {List: &productv1.ListOfString_List{Items: []string{"Create follow-up posts", "Add Q&A section"}}}, - }, - }, - }, - // Complex example includes all new complex list fields - RelatedCategories: []*productv1.Category{ - {Id: "cat-complex-1", Name: "Advanced Programming", Kind: productv1.CategoryKind_CATEGORY_KIND_ELECTRONICS}, - {Id: "cat-complex-2", Name: "Software Architecture", Kind: productv1.CategoryKind_CATEGORY_KIND_BOOK}, - }, - Contributors: []*productv1.User{ - {Id: "user-complex-1", Name: "Expert Author"}, - {Id: "user-complex-2", Name: "Technical Reviewer"}, - }, - MentionedProducts: &productv1.ListOfProduct{ - List: &productv1.ListOfProduct_List{ - Items: []*productv1.Product{ - {Id: "prod-complex-1", Name: "Advanced IDE", Price: 299.99}, - {Id: "prod-complex-2", Name: "Profiling Tool", Price: 149.99}, - }, - }, - }, - MentionedUsers: &productv1.ListOfUser{ - List: &productv1.ListOfUser_List{ - Items: []*productv1.User{ - {Id: "user-complex-3", Name: "Referenced Expert"}, - }, - }, - }, - CategoryGroups: &productv1.ListOfListOfCategory{ - List: &productv1.ListOfListOfCategory_List{ - Items: []*productv1.ListOfCategory{ - {List: &productv1.ListOfCategory_List{ - Items: []*productv1.Category{ - {Id: "cat-group-1", Name: "System Design", Kind: productv1.CategoryKind_CATEGORY_KIND_ELECTRONICS}, - {Id: "cat-group-2", Name: "Architecture Patterns", Kind: productv1.CategoryKind_CATEGORY_KIND_BOOK}, - }, - }}, - {List: &productv1.ListOfCategory_List{ - Items: []*productv1.Category{ - {Id: "cat-group-3", Name: "Performance", Kind: productv1.CategoryKind_CATEGORY_KIND_ELECTRONICS}, - }, - }}, - }, - }, - }, - ContributorTeams: &productv1.ListOfListOfUser{ - List: &productv1.ListOfListOfUser_List{ - Items: []*productv1.ListOfUser{ - {List: &productv1.ListOfUser_List{ - Items: []*productv1.User{ - {Id: "team-complex-1", Name: "Senior Engineer A"}, - {Id: "team-complex-2", Name: "Senior Engineer B"}, - }, - }}, - {List: &productv1.ListOfUser_List{ - Items: []*productv1.User{ - {Id: "team-complex-3", Name: "QA Lead"}, - }, - }}, - }, - }, - }, - } - default: - // Generic response for any other ID - result = &productv1.BlogPost{ - Id: id, - Title: fmt.Sprintf("Blog Post %s", id), - Content: fmt.Sprintf("Content for blog post %s", id), - Tags: []string{fmt.Sprintf("tag-%s", id), "general"}, - Categories: []string{"General", fmt.Sprintf("Category-%s", id)}, - ViewCounts: []int32{int32(len(id) * 10), int32(len(id) * 20)}, - // Required nested lists must have data - TagGroups: &productv1.ListOfListOfString{ - List: &productv1.ListOfListOfString_List{ - Items: []*productv1.ListOfString{ - {List: &productv1.ListOfString_List{ - Items: []string{fmt.Sprintf("tag-%s", id), "group"}, - }}, - }, - }, - }, - RelatedTopics: &productv1.ListOfListOfString{ - List: &productv1.ListOfListOfString_List{ - Items: []*productv1.ListOfString{ - {List: &productv1.ListOfString_List{ - Items: []string{fmt.Sprintf("topic-%s", id)}, - }}, - }, - }, - }, - CommentThreads: &productv1.ListOfListOfString{ - List: &productv1.ListOfListOfString_List{ - Items: []*productv1.ListOfString{ - {List: &productv1.ListOfString_List{ - Items: []string{fmt.Sprintf("Comment on %s", id)}, - }}, - }, - }, - }, - // Required complex lists must have data - RelatedCategories: []*productv1.Category{ - {Id: fmt.Sprintf("cat-%s", id), Name: fmt.Sprintf("Category %s", id), Kind: productv1.CategoryKind_CATEGORY_KIND_OTHER}, - }, - Contributors: []*productv1.User{ - {Id: fmt.Sprintf("user-%s", id), Name: fmt.Sprintf("Author %s", id)}, - }, - CategoryGroups: &productv1.ListOfListOfCategory{ - List: &productv1.ListOfListOfCategory_List{ - Items: []*productv1.ListOfCategory{ - {List: &productv1.ListOfCategory_List{ - Items: []*productv1.Category{ - {Id: fmt.Sprintf("cat-group-%s", id), Name: fmt.Sprintf("Group Category %s", id), Kind: productv1.CategoryKind_CATEGORY_KIND_OTHER}, - }, - }}, - }, - }, - }, - } - } - - return &productv1.QueryBlogPostByIdResponse{ - BlogPostById: result, - }, nil -} - -func (s *MockService) QueryBlogPostsWithFilter(ctx context.Context, in *productv1.QueryBlogPostsWithFilterRequest) (*productv1.QueryBlogPostsWithFilterResponse, error) { - filter := in.GetFilter() - var results []*productv1.BlogPost - - // If no filter provided, return empty results - if filter == nil { - return &productv1.QueryBlogPostsWithFilterResponse{ - BlogPostsWithFilter: results, - }, nil - } - - titleFilter := "" - if filter.Title != nil { - titleFilter = filter.Title.GetValue() - } - - hasCategories := false - if filter.HasCategories != nil { - hasCategories = filter.HasCategories.GetValue() - } - - minTags := int32(0) - if filter.MinTags != nil { - minTags = filter.MinTags.GetValue() - } - - // Generate filtered results - for i := 1; i <= 3; i++ { - title := fmt.Sprintf("Filtered Post %d", i) - if titleFilter != "" { - title = fmt.Sprintf("%s - Post %d", titleFilter, i) - } - - var tags []string - tagsCount := minTags + int32(i) - for j := int32(0); j < tagsCount; j++ { - tags = append(tags, fmt.Sprintf("tag%d", j+1)) - } - - var categories []string - if hasCategories { - categories = []string{fmt.Sprintf("Category%d", i), "Filtered"} - } - - results = append(results, &productv1.BlogPost{ - Id: fmt.Sprintf("filtered-blog-%d", i), - Title: title, - Content: fmt.Sprintf("Filtered content %d", i), - Tags: tags, - Categories: categories, - ViewCounts: []int32{int32(i * 100)}, - // Required nested lists must have data - TagGroups: &productv1.ListOfListOfString{ - List: &productv1.ListOfListOfString_List{ - Items: []*productv1.ListOfString{ - {List: &productv1.ListOfString_List{ - Items: []string{fmt.Sprintf("filtered-tag-%d", i)}, - }}, - }, - }, - }, - RelatedTopics: &productv1.ListOfListOfString{ - List: &productv1.ListOfListOfString_List{ - Items: []*productv1.ListOfString{ - {List: &productv1.ListOfString_List{ - Items: []string{fmt.Sprintf("filtered-topic-%d", i)}, - }}, - }, - }, - }, - CommentThreads: &productv1.ListOfListOfString{ - List: &productv1.ListOfListOfString_List{ - Items: []*productv1.ListOfString{ - {List: &productv1.ListOfString_List{ - Items: []string{fmt.Sprintf("Filtered comment %d", i)}, - }}, - }, - }, - }, - // Required complex lists must have data - RelatedCategories: []*productv1.Category{ - {Id: fmt.Sprintf("cat-filtered-%d", i), Name: fmt.Sprintf("Filtered Category %d", i), Kind: productv1.CategoryKind_CATEGORY_KIND_OTHER}, - }, - Contributors: []*productv1.User{ - {Id: fmt.Sprintf("user-filtered-%d", i), Name: fmt.Sprintf("Filtered Author %d", i)}, - }, - CategoryGroups: &productv1.ListOfListOfCategory{ - List: &productv1.ListOfListOfCategory_List{ - Items: []*productv1.ListOfCategory{ - {List: &productv1.ListOfCategory_List{ - Items: []*productv1.Category{ - {Id: fmt.Sprintf("cat-group-filtered-%d", i), Name: fmt.Sprintf("Filtered Group %d", i), Kind: productv1.CategoryKind_CATEGORY_KIND_OTHER}, - }, - }}, - }, - }, - }, - }) - } - - return &productv1.QueryBlogPostsWithFilterResponse{ - BlogPostsWithFilter: results, - }, nil -} - -func (s *MockService) QueryAllBlogPosts(ctx context.Context, in *productv1.QueryAllBlogPostsRequest) (*productv1.QueryAllBlogPostsResponse, error) { - var results []*productv1.BlogPost - - // Create a variety of blog posts - for i := 1; i <= 4; i++ { - var optionalTags *productv1.ListOfString - var keywords *productv1.ListOfString - var ratings *productv1.ListOfFloat - - // Vary the optional fields - if i%2 == 1 { - optionalTags = &productv1.ListOfString{ - List: &productv1.ListOfString_List{ - Items: []string{fmt.Sprintf("optional%d", i), "common"}, - }, - } - } - - if i%3 == 0 { - keywords = &productv1.ListOfString{ - List: &productv1.ListOfString_List{ - Items: []string{fmt.Sprintf("keyword%d", i)}, - }, - } - } - - if i%2 == 0 { - ratings = &productv1.ListOfFloat{ - List: &productv1.ListOfFloat_List{ - Items: []float64{float64(i) + 0.5, float64(i) + 1.0}, - }, - } - } - - results = append(results, &productv1.BlogPost{ - Id: fmt.Sprintf("blog-%d", i), - Title: fmt.Sprintf("Blog Post %d", i), - Content: fmt.Sprintf("Content for blog post %d", i), - Tags: []string{fmt.Sprintf("tag%d", i), "common"}, - OptionalTags: optionalTags, - Categories: []string{fmt.Sprintf("Category%d", i)}, - Keywords: keywords, - ViewCounts: []int32{int32(i * 100), int32(i * 150)}, - Ratings: ratings, - IsPublished: &productv1.ListOfBoolean{ - List: &productv1.ListOfBoolean_List{ - Items: []bool{i%2 == 0, true}, - }, - }, - TagGroups: &productv1.ListOfListOfString{ - List: &productv1.ListOfListOfString_List{ - Items: []*productv1.ListOfString{ - {List: &productv1.ListOfString_List{ - Items: []string{fmt.Sprintf("group%d", i), "shared"}, - }}, - }, - }, - }, - RelatedTopics: &productv1.ListOfListOfString{ - List: &productv1.ListOfListOfString_List{ - Items: []*productv1.ListOfString{ - {List: &productv1.ListOfString_List{ - Items: []string{fmt.Sprintf("topic%d", i)}, - }}, - }, - }, - }, - CommentThreads: &productv1.ListOfListOfString{ - List: &productv1.ListOfListOfString_List{ - Items: []*productv1.ListOfString{ - {List: &productv1.ListOfString_List{ - Items: []string{fmt.Sprintf("Comment for post %d", i)}, - }}, - }, - }, - }, - // Required complex lists must have data - RelatedCategories: []*productv1.Category{ - {Id: fmt.Sprintf("cat-all-%d", i), Name: fmt.Sprintf("Category %d", i), Kind: productv1.CategoryKind_CATEGORY_KIND_OTHER}, - }, - Contributors: []*productv1.User{ - {Id: fmt.Sprintf("user-all-%d", i), Name: fmt.Sprintf("Author %d", i)}, - }, - CategoryGroups: &productv1.ListOfListOfCategory{ - List: &productv1.ListOfListOfCategory_List{ - Items: []*productv1.ListOfCategory{ - {List: &productv1.ListOfCategory_List{ - Items: []*productv1.Category{ - {Id: fmt.Sprintf("cat-group-all-%d", i), Name: fmt.Sprintf("Group Category %d", i), Kind: productv1.CategoryKind_CATEGORY_KIND_OTHER}, - }, - }}, - }, - }, - }, - // Optional list - can be empty - Suggestions: &productv1.ListOfListOfString{}, - }) - } - - return &productv1.QueryAllBlogPostsResponse{ - AllBlogPosts: results, - }, nil -} - -// Author query implementations -func (s *MockService) QueryAuthor(ctx context.Context, in *productv1.QueryAuthorRequest) (*productv1.QueryAuthorResponse, error) { - result := &productv1.Author{ - Id: "author-default", - Name: "Default Author", - Email: &wrapperspb.StringValue{ - Value: "author@example.com", - }, - Skills: []string{"Go", "GraphQL", "Protocol Buffers"}, - Languages: []string{"English", "Spanish", ""}, - SocialLinks: &productv1.ListOfString{ - List: &productv1.ListOfString_List{ - Items: []string{"https://twitter.com/author", "https://linkedin.com/in/author"}, - }, - }, - TeamsByProject: &productv1.ListOfListOfString{ - List: &productv1.ListOfListOfString_List{ - Items: []*productv1.ListOfString{ - {List: &productv1.ListOfString_List{ - Items: []string{"Alice", "Bob", "Charlie"}, - }}, - {List: &productv1.ListOfString_List{ - Items: []string{"David", "Eve"}, - }}, - }, - }, - }, - Collaborations: &productv1.ListOfListOfString{ - List: &productv1.ListOfListOfString_List{ - Items: []*productv1.ListOfString{ - {List: &productv1.ListOfString_List{ - Items: []string{"Open Source Project A", "Research Paper B"}, - }}, - {List: &productv1.ListOfString_List{ - Items: []string{"Conference Talk C"}, - }}, - }, - }, - }, - WrittenPosts: &productv1.ListOfBlogPost{ - List: &productv1.ListOfBlogPost_List{ - Items: []*productv1.BlogPost{ - {Id: "blog-1", Title: "GraphQL Best Practices", Content: "Content here..."}, - {Id: "blog-2", Title: "gRPC vs REST", Content: "Comparison content..."}, - }, - }, - }, - FavoriteCategories: []*productv1.Category{ - {Id: "cat-fav-1", Name: "Software Engineering", Kind: productv1.CategoryKind_CATEGORY_KIND_ELECTRONICS}, - {Id: "cat-fav-2", Name: "Technical Writing", Kind: productv1.CategoryKind_CATEGORY_KIND_BOOK}, - }, - RelatedAuthors: &productv1.ListOfUser{ - List: &productv1.ListOfUser_List{ - Items: []*productv1.User{ - {Id: "author-rel-1", Name: "Related Author One"}, - {Id: "author-rel-2", Name: "Related Author Two"}, - }, - }, - }, - ProductReviews: &productv1.ListOfProduct{ - List: &productv1.ListOfProduct_List{ - Items: []*productv1.Product{ - {Id: "prod-rev-1", Name: "Code Editor Pro", Price: 199.99}, - }, - }, - }, - AuthorGroups: &productv1.ListOfListOfUser{ - List: &productv1.ListOfListOfUser_List{ - Items: []*productv1.ListOfUser{ - {List: &productv1.ListOfUser_List{ - Items: []*productv1.User{ - {Id: "group-auth-1", Name: "Team Lead Alpha"}, - {Id: "group-auth-2", Name: "Senior Dev Beta"}, - }, - }}, - {List: &productv1.ListOfUser_List{ - Items: []*productv1.User{ - {Id: "group-auth-3", Name: "Junior Dev Gamma"}, - }, - }}, - // empty list - {List: &productv1.ListOfUser_List{}}, - // null item - nil, - }, - }, - }, - CategoryPreferences: &productv1.ListOfListOfCategory{ - List: &productv1.ListOfListOfCategory_List{ - Items: []*productv1.ListOfCategory{ - {List: &productv1.ListOfCategory_List{ - Items: []*productv1.Category{ - {Id: "pref-cat-1", Name: "Microservices", Kind: productv1.CategoryKind_CATEGORY_KIND_ELECTRONICS}, - {Id: "pref-cat-2", Name: "Cloud Computing", Kind: productv1.CategoryKind_CATEGORY_KIND_ELECTRONICS}, - }, - }}, - }, - }, - }, - } - - return &productv1.QueryAuthorResponse{ - Author: result, - }, nil -} - -func (s *MockService) QueryAuthorById(ctx context.Context, in *productv1.QueryAuthorByIdRequest) (*productv1.QueryAuthorByIdResponse, error) { - id := in.GetId() - - // Return null for specific test IDs - if id == "not-found" { - return &productv1.QueryAuthorByIdResponse{ - AuthorById: nil, - }, nil - } - - var result *productv1.Author - - switch id { - case "minimal": - result = &productv1.Author{ - Id: id, - Name: "Minimal Author", - Skills: []string{"Basic"}, - Languages: []string{"English"}, - TeamsByProject: &productv1.ListOfListOfString{ - List: &productv1.ListOfListOfString_List{ - Items: []*productv1.ListOfString{ - {List: &productv1.ListOfString_List{ - Items: []string{"Solo"}, - }}, - }, - }, - }, - // Required complex lists must have data - FavoriteCategories: []*productv1.Category{ - {Id: "cat-minimal", Name: "Basic Category", Kind: productv1.CategoryKind_CATEGORY_KIND_OTHER}, - }, - CategoryPreferences: &productv1.ListOfListOfCategory{ - List: &productv1.ListOfListOfCategory_List{ - Items: []*productv1.ListOfCategory{ - {List: &productv1.ListOfCategory_List{ - Items: []*productv1.Category{ - {Id: "cat-pref-minimal", Name: "Minimal Preference", Kind: productv1.CategoryKind_CATEGORY_KIND_OTHER}, - }, - }}, - }, - }, - }, - // Optional list - can be empty - Collaborations: &productv1.ListOfListOfString{}, - } - case "experienced": - result = &productv1.Author{ - Id: id, - Name: "Experienced Author", - Email: &wrapperspb.StringValue{ - Value: "experienced@example.com", - }, - Skills: []string{"Go", "GraphQL", "gRPC", "Microservices", "Kubernetes"}, - Languages: []string{"English", "French", "German"}, - SocialLinks: &productv1.ListOfString{ - List: &productv1.ListOfString_List{ - Items: []string{ - "https://github.com/experienced", - "https://twitter.com/experienced", - "https://medium.com/@experienced", - }, - }, - }, - TeamsByProject: &productv1.ListOfListOfString{ - List: &productv1.ListOfListOfString_List{ - Items: []*productv1.ListOfString{ - {List: &productv1.ListOfString_List{ - Items: []string{"Senior Dev 1", "Senior Dev 2", "Tech Lead"}, - }}, - {List: &productv1.ListOfString_List{ - Items: []string{"Architect", "Principal Engineer"}, - }}, - {List: &productv1.ListOfString_List{ - Items: []string{"PM", "Designer", "QA Lead"}, - }}, - }, - }, - }, - Collaborations: &productv1.ListOfListOfString{ - List: &productv1.ListOfListOfString_List{ - Items: []*productv1.ListOfString{ - {List: &productv1.ListOfString_List{ - Items: []string{"Major OSS Project", "Industry Standard", "Research Initiative"}, - }}, - {List: &productv1.ListOfString_List{ - Items: []string{"Conference Keynote", "Workshop Series"}, - }}, - }, - }, - }, - // Required complex lists must have data - FavoriteCategories: []*productv1.Category{ - {Id: "cat-experienced-1", Name: "Advanced Programming", Kind: productv1.CategoryKind_CATEGORY_KIND_ELECTRONICS}, - {Id: "cat-experienced-2", Name: "Technical Leadership", Kind: productv1.CategoryKind_CATEGORY_KIND_BOOK}, - }, - CategoryPreferences: &productv1.ListOfListOfCategory{ - List: &productv1.ListOfListOfCategory_List{ - Items: []*productv1.ListOfCategory{ - {List: &productv1.ListOfCategory_List{ - Items: []*productv1.Category{ - {Id: "cat-pref-experienced-1", Name: "System Architecture", Kind: productv1.CategoryKind_CATEGORY_KIND_ELECTRONICS}, - {Id: "cat-pref-experienced-2", Name: "Team Management", Kind: productv1.CategoryKind_CATEGORY_KIND_BOOK}, - }, - }}, - }, - }, - }, - } - default: - result = &productv1.Author{ - Id: id, - Name: fmt.Sprintf("Author %s", id), - Email: &wrapperspb.StringValue{ - Value: fmt.Sprintf("%s@example.com", id), - }, - Skills: []string{fmt.Sprintf("Skill-%s", id), "General"}, - Languages: []string{"English", fmt.Sprintf("Language-%s", id)}, - TeamsByProject: &productv1.ListOfListOfString{ - List: &productv1.ListOfListOfString_List{ - Items: []*productv1.ListOfString{ - {List: &productv1.ListOfString_List{ - Items: []string{fmt.Sprintf("Team-%s", id)}, - }}, - }, - }, - }, - // Required complex lists must have data - FavoriteCategories: []*productv1.Category{ - {Id: fmt.Sprintf("cat-%s", id), Name: fmt.Sprintf("Favorite Category %s", id), Kind: productv1.CategoryKind_CATEGORY_KIND_OTHER}, - }, - CategoryPreferences: &productv1.ListOfListOfCategory{ - List: &productv1.ListOfListOfCategory_List{ - Items: []*productv1.ListOfCategory{ - {List: &productv1.ListOfCategory_List{ - Items: []*productv1.Category{ - {Id: fmt.Sprintf("cat-pref-%s", id), Name: fmt.Sprintf("Preference %s", id), Kind: productv1.CategoryKind_CATEGORY_KIND_OTHER}, - }, - }}, - }, - }, - }, - // Optional list - can be empty - Collaborations: &productv1.ListOfListOfString{}, - } - } - - return &productv1.QueryAuthorByIdResponse{ - AuthorById: result, - }, nil -} - -func (s *MockService) QueryAuthorsWithFilter(ctx context.Context, in *productv1.QueryAuthorsWithFilterRequest) (*productv1.QueryAuthorsWithFilterResponse, error) { - filter := in.GetFilter() - var results []*productv1.Author - - if filter == nil { - return &productv1.QueryAuthorsWithFilterResponse{ - AuthorsWithFilter: results, - }, nil - } - - nameFilter := "" - if filter.Name != nil { - nameFilter = filter.Name.GetValue() - } - - hasTeams := false - if filter.HasTeams != nil { - hasTeams = filter.HasTeams.GetValue() - } - - skillCount := int32(0) - if filter.SkillCount != nil { - skillCount = filter.SkillCount.GetValue() - } - - // Generate filtered results - for i := 1; i <= 3; i++ { - name := fmt.Sprintf("Filtered Author %d", i) - if nameFilter != "" { - name = fmt.Sprintf("%s - Author %d", nameFilter, i) - } - - var skills []string - skillsNeeded := skillCount + int32(i) - for j := int32(0); j < skillsNeeded; j++ { - skills = append(skills, fmt.Sprintf("Skill%d", j+1)) - } - - var teamsByProject *productv1.ListOfListOfString - if hasTeams { - teamsByProject = &productv1.ListOfListOfString{ - List: &productv1.ListOfListOfString_List{ - Items: []*productv1.ListOfString{ - {List: &productv1.ListOfString_List{ - Items: []string{fmt.Sprintf("Team%d", i), "SharedTeam"}, - }}, - }, - }, - } - } else { - teamsByProject = &productv1.ListOfListOfString{List: &productv1.ListOfListOfString_List{}} - } - - results = append(results, &productv1.Author{ - Id: fmt.Sprintf("filtered-author-%d", i), - Name: name, - Skills: skills, - Languages: []string{"English", fmt.Sprintf("Lang%d", i)}, - TeamsByProject: teamsByProject, - // Required complex lists must have data - FavoriteCategories: []*productv1.Category{ - {Id: fmt.Sprintf("cat-filtered-%d", i), Name: fmt.Sprintf("Filtered Category %d", i), Kind: productv1.CategoryKind_CATEGORY_KIND_OTHER}, - }, - CategoryPreferences: &productv1.ListOfListOfCategory{ - List: &productv1.ListOfListOfCategory_List{ - Items: []*productv1.ListOfCategory{ - {List: &productv1.ListOfCategory_List{ - Items: []*productv1.Category{ - {Id: fmt.Sprintf("cat-pref-filtered-%d", i), Name: fmt.Sprintf("Filtered Preference %d", i), Kind: productv1.CategoryKind_CATEGORY_KIND_OTHER}, - }, - }}, - }, - }, - }, - // Optional list - can be empty - Collaborations: &productv1.ListOfListOfString{}, - }) - } - - return &productv1.QueryAuthorsWithFilterResponse{ - AuthorsWithFilter: results, - }, nil -} - -func (s *MockService) QueryAllAuthors(ctx context.Context, in *productv1.QueryAllAuthorsRequest) (*productv1.QueryAllAuthorsResponse, error) { - var results []*productv1.Author - - for i := 1; i <= 3; i++ { - var email *wrapperspb.StringValue - var socialLinks *productv1.ListOfString - var collaborations *productv1.ListOfListOfString - - if i%2 == 1 { - email = &wrapperspb.StringValue{ - Value: fmt.Sprintf("author%d@example.com", i), - } - } - - if i%3 == 0 { - socialLinks = &productv1.ListOfString{ - List: &productv1.ListOfString_List{ - Items: []string{fmt.Sprintf("https://github.com/author%d", i)}, - }, - } - } - - if i == 2 { - collaborations = &productv1.ListOfListOfString{ - List: &productv1.ListOfListOfString_List{ - Items: []*productv1.ListOfString{ - {List: &productv1.ListOfString_List{ - Items: []string{"Collaboration A", "Collaboration B"}, - }}, - }, - }, - } - } else { - collaborations = &productv1.ListOfListOfString{} - } - - results = append(results, &productv1.Author{ - Id: fmt.Sprintf("author-%d", i), - Name: fmt.Sprintf("Author %d", i), - Email: email, - Skills: []string{fmt.Sprintf("Skill%d", i), "Common"}, - Languages: []string{"English", fmt.Sprintf("Language%d", i)}, - SocialLinks: socialLinks, - TeamsByProject: &productv1.ListOfListOfString{ - List: &productv1.ListOfListOfString_List{ - Items: []*productv1.ListOfString{ - {List: &productv1.ListOfString_List{ - Items: []string{fmt.Sprintf("Team%d", i)}, - }}, - }, - }, - }, - // Required complex lists must have data - FavoriteCategories: []*productv1.Category{ - {Id: fmt.Sprintf("cat-all-%d", i), Name: fmt.Sprintf("All Category %d", i), Kind: productv1.CategoryKind_CATEGORY_KIND_OTHER}, - }, - CategoryPreferences: &productv1.ListOfListOfCategory{ - List: &productv1.ListOfListOfCategory_List{ - Items: []*productv1.ListOfCategory{ - {List: &productv1.ListOfCategory_List{ - Items: []*productv1.Category{ - {Id: fmt.Sprintf("cat-pref-all-%d", i), Name: fmt.Sprintf("All Preference %d", i), Kind: productv1.CategoryKind_CATEGORY_KIND_OTHER}, - }, - }}, - }, - }, - }, - // Optional list - can be empty/variable - Collaborations: collaborations, - }) - } - - return &productv1.QueryAllAuthorsResponse{ - AllAuthors: results, - }, nil -} - -// BlogPost mutation implementations -func (s *MockService) MutationCreateBlogPost(ctx context.Context, in *productv1.MutationCreateBlogPostRequest) (*productv1.MutationCreateBlogPostResponse, error) { - input := in.GetInput() - - result := &productv1.BlogPost{ - Id: fmt.Sprintf("blog-%d", rand.Intn(1000)), - Title: input.GetTitle(), - Content: input.GetContent(), - Tags: input.GetTags(), - OptionalTags: input.GetOptionalTags(), - Categories: input.GetCategories(), - Keywords: input.GetKeywords(), - ViewCounts: input.GetViewCounts(), - Ratings: input.GetRatings(), - IsPublished: input.GetIsPublished(), - TagGroups: input.GetTagGroups(), - RelatedTopics: input.GetRelatedTopics(), - CommentThreads: input.GetCommentThreads(), - Suggestions: input.GetSuggestions(), - // Convert input types to output types - RelatedCategories: convertCategoryInputListToCategories(input.GetRelatedCategories()), - Contributors: convertUserInputsToUsers(input.GetContributors()), - CategoryGroups: convertNestedCategoryInputsToCategories(input.GetCategoryGroups()), - MentionedProducts: &productv1.ListOfProduct{ - List: &productv1.ListOfProduct_List{ - Items: []*productv1.Product{ - {Id: "prod-1", Name: "Sample Product", Price: 99.99}, - }, - }, - }, - MentionedUsers: &productv1.ListOfUser{ - List: &productv1.ListOfUser_List{ - Items: []*productv1.User{ - {Id: "user-3", Name: "Bob Johnson"}, - }, - }, - }, - ContributorTeams: &productv1.ListOfListOfUser{ - List: &productv1.ListOfListOfUser_List{ - Items: []*productv1.ListOfUser{ - {List: &productv1.ListOfUser_List{ - Items: []*productv1.User{ - {Id: "user-4", Name: "Alice Brown"}, - }, - }}, - }, - }, - }, - } - - return &productv1.MutationCreateBlogPostResponse{ - CreateBlogPost: result, - }, nil -} - -func (s *MockService) MutationUpdateBlogPost(ctx context.Context, in *productv1.MutationUpdateBlogPostRequest) (*productv1.MutationUpdateBlogPostResponse, error) { - id := in.GetId() - input := in.GetInput() - - if id == "non-existent" { - return &productv1.MutationUpdateBlogPostResponse{ - UpdateBlogPost: nil, - }, nil - } - - result := &productv1.BlogPost{ - Id: id, - Title: input.GetTitle(), - Content: input.GetContent(), - Tags: input.GetTags(), - OptionalTags: input.GetOptionalTags(), - Categories: input.GetCategories(), - Keywords: input.GetKeywords(), - ViewCounts: input.GetViewCounts(), - Ratings: input.GetRatings(), - IsPublished: input.GetIsPublished(), - TagGroups: input.GetTagGroups(), - RelatedTopics: input.GetRelatedTopics(), - CommentThreads: input.GetCommentThreads(), - Suggestions: input.GetSuggestions(), - // Convert input types to output types - RelatedCategories: convertCategoryInputListToCategories(input.GetRelatedCategories()), - Contributors: convertUserInputsToUsers(input.GetContributors()), - CategoryGroups: convertNestedCategoryInputsToCategories(input.GetCategoryGroups()), - MentionedProducts: &productv1.ListOfProduct{ - List: &productv1.ListOfProduct_List{ - Items: []*productv1.Product{ - {Id: "prod-updated", Name: "Updated Product", Price: 149.99}, - }, - }, - }, - MentionedUsers: &productv1.ListOfUser{ - List: &productv1.ListOfUser_List{ - Items: []*productv1.User{ - {Id: "user-updated", Name: "Updated User"}, - }, - }, - }, - ContributorTeams: &productv1.ListOfListOfUser{ - List: &productv1.ListOfListOfUser_List{ - Items: []*productv1.ListOfUser{ - {List: &productv1.ListOfUser_List{ - Items: []*productv1.User{ - {Id: "user-team-updated", Name: "Updated Team Member"}, - }, - }}, - }, - }, - }, - } - - return &productv1.MutationUpdateBlogPostResponse{ - UpdateBlogPost: result, - }, nil -} - -// Author mutation implementations -func (s *MockService) MutationCreateAuthor(ctx context.Context, in *productv1.MutationCreateAuthorRequest) (*productv1.MutationCreateAuthorResponse, error) { - input := in.GetInput() - - result := &productv1.Author{ - Id: fmt.Sprintf("author-%d", rand.Intn(1000)), - Name: input.GetName(), - Email: input.GetEmail(), - Skills: input.GetSkills(), - Languages: input.GetLanguages(), - SocialLinks: input.GetSocialLinks(), - TeamsByProject: input.GetTeamsByProject(), - Collaborations: input.GetCollaborations(), - // Convert input types to output types for complex fields - FavoriteCategories: convertCategoryInputsToCategories(input.GetFavoriteCategories()), - AuthorGroups: convertNestedUserInputsToUsers(input.GetAuthorGroups()), - ProjectTeams: convertNestedUserInputsToUsers(input.GetProjectTeams()), - // Keep other complex fields with mock data since they're not in the simplified input - WrittenPosts: &productv1.ListOfBlogPost{ - List: &productv1.ListOfBlogPost_List{ - Items: []*productv1.BlogPost{ - {Id: "blog-created", Title: "Created Post", Content: "Content..."}, - }, - }, - }, - RelatedAuthors: &productv1.ListOfUser{ - List: &productv1.ListOfUser_List{ - Items: []*productv1.User{ - {Id: "related-author", Name: "Related Author"}, - }, - }, - }, - ProductReviews: &productv1.ListOfProduct{ - List: &productv1.ListOfProduct_List{ - Items: []*productv1.Product{ - {Id: "reviewed-product", Name: "Code Editor", Price: 199.99}, - }, - }, - }, - CategoryPreferences: &productv1.ListOfListOfCategory{ - List: &productv1.ListOfListOfCategory_List{ - Items: []*productv1.ListOfCategory{ - {List: &productv1.ListOfCategory_List{ - Items: []*productv1.Category{ - {Id: "pref-cat", Name: "Backend Development", Kind: productv1.CategoryKind_CATEGORY_KIND_ELECTRONICS}, - }, - }}, - }, - }, - }, - } - - return &productv1.MutationCreateAuthorResponse{ - CreateAuthor: result, - }, nil -} - -func (s *MockService) MutationUpdateAuthor(ctx context.Context, in *productv1.MutationUpdateAuthorRequest) (*productv1.MutationUpdateAuthorResponse, error) { - id := in.GetId() - input := in.GetInput() - - if id == "non-existent" { - return &productv1.MutationUpdateAuthorResponse{ - UpdateAuthor: nil, - }, nil - } - - result := &productv1.Author{ - Id: id, - Name: input.GetName(), - Email: input.GetEmail(), - Skills: input.GetSkills(), - Languages: input.GetLanguages(), - SocialLinks: input.GetSocialLinks(), - TeamsByProject: input.GetTeamsByProject(), - Collaborations: input.GetCollaborations(), - // Convert input types to output types for complex fields - FavoriteCategories: convertCategoryInputsToCategories(input.GetFavoriteCategories()), - AuthorGroups: convertNestedUserInputsToUsers(input.GetAuthorGroups()), - ProjectTeams: convertNestedUserInputsToUsers(input.GetProjectTeams()), - // Keep other complex fields with mock data since they're not in the simplified input - WrittenPosts: &productv1.ListOfBlogPost{ - List: &productv1.ListOfBlogPost_List{ - Items: []*productv1.BlogPost{ - {Id: "blog-updated", Title: "Updated Post", Content: "Updated content..."}, - }, - }, - }, - RelatedAuthors: &productv1.ListOfUser{ - List: &productv1.ListOfUser_List{ - Items: []*productv1.User{ - {Id: "related-author-updated", Name: "Updated Related Author"}, - }, - }, - }, - ProductReviews: &productv1.ListOfProduct{ - List: &productv1.ListOfProduct_List{ - Items: []*productv1.Product{ - {Id: "reviewed-product-updated", Name: "Updated Code Editor", Price: 249.99}, - }, - }, - }, - CategoryPreferences: &productv1.ListOfListOfCategory{ - List: &productv1.ListOfListOfCategory_List{ - Items: []*productv1.ListOfCategory{ - {List: &productv1.ListOfCategory_List{ - Items: []*productv1.Category{ - {Id: "pref-cat-updated", Name: "Updated Backend Development", Kind: productv1.CategoryKind_CATEGORY_KIND_ELECTRONICS}, - }, - }}, - }, - }, - }, - } - - return &productv1.MutationUpdateAuthorResponse{ - UpdateAuthor: result, - }, nil -} - -// Bulk operation implementations -func (s *MockService) QueryBulkSearchAuthors(ctx context.Context, in *productv1.QueryBulkSearchAuthorsRequest) (*productv1.QueryBulkSearchAuthorsResponse, error) { - var allResults []*productv1.Author - - // Handle nullable list - if filters is nil, return empty results - if in.Filters == nil { - return &productv1.QueryBulkSearchAuthorsResponse{ - BulkSearchAuthors: allResults, - }, nil - } - - // Process each filter in the list - if in.Filters.List != nil { - for i, filter := range in.Filters.List.Items { - // Create mock results for each filter - for j := 1; j <= 2; j++ { - name := fmt.Sprintf("Bulk Author %d-%d", i+1, j) - if filter.Name != nil { - name = fmt.Sprintf("%s - Bulk %d-%d", filter.Name.GetValue(), i+1, j) - } - - var skills []string - skillCount := int32(3) - if filter.SkillCount != nil { - skillCount = filter.SkillCount.GetValue() - } - for k := int32(0); k < skillCount; k++ { - skills = append(skills, fmt.Sprintf("BulkSkill%d", k+1)) - } - - var teamsByProject *productv1.ListOfListOfString - if filter.HasTeams != nil && filter.HasTeams.GetValue() { - teamsByProject = &productv1.ListOfListOfString{ - List: &productv1.ListOfListOfString_List{ - Items: []*productv1.ListOfString{ - {List: &productv1.ListOfString_List{ - Items: []string{fmt.Sprintf("BulkTeam%d", j), "SharedBulkTeam"}, - }}, - }, - }, - } - } else { - teamsByProject = &productv1.ListOfListOfString{List: &productv1.ListOfListOfString_List{}} - } - - allResults = append(allResults, &productv1.Author{ - Id: fmt.Sprintf("bulk-author-%d-%d", i+1, j), - Name: name, - Skills: skills, - Languages: []string{"English", fmt.Sprintf("BulkLang%d", j)}, - TeamsByProject: teamsByProject, - FavoriteCategories: []*productv1.Category{ - {Id: fmt.Sprintf("bulk-cat-%d-%d", i+1, j), Name: fmt.Sprintf("Bulk Category %d-%d", i+1, j), Kind: productv1.CategoryKind_CATEGORY_KIND_OTHER}, - }, - CategoryPreferences: &productv1.ListOfListOfCategory{ - List: &productv1.ListOfListOfCategory_List{ - Items: []*productv1.ListOfCategory{ - {List: &productv1.ListOfCategory_List{ - Items: []*productv1.Category{ - {Id: fmt.Sprintf("bulk-pref-%d-%d", i+1, j), Name: fmt.Sprintf("Bulk Preference %d-%d", i+1, j), Kind: productv1.CategoryKind_CATEGORY_KIND_BOOK}, - }, - }}, - }, - }, - }, - }) - } - } - } - - return &productv1.QueryBulkSearchAuthorsResponse{ - BulkSearchAuthors: allResults, - }, nil -} - -func (s *MockService) QueryBulkSearchBlogPosts(ctx context.Context, in *productv1.QueryBulkSearchBlogPostsRequest) (*productv1.QueryBulkSearchBlogPostsResponse, error) { - var allResults []*productv1.BlogPost - - // Handle nullable list - if filters is nil, return empty results - if in.Filters == nil { - return &productv1.QueryBulkSearchBlogPostsResponse{ - BulkSearchBlogPosts: allResults, - }, nil - } - - // Process each filter in the list - if in.Filters.List != nil { - for i, filter := range in.Filters.List.Items { - // Create mock results for each filter - for j := 1; j <= 2; j++ { - title := fmt.Sprintf("Bulk Blog Post %d-%d", i+1, j) - if filter.Title != nil { - title = fmt.Sprintf("%s - Bulk %d-%d", filter.Title.GetValue(), i+1, j) - } - - var categories []string - if filter.HasCategories != nil && filter.HasCategories.GetValue() { - categories = []string{fmt.Sprintf("BulkCategory%d", j), "SharedBulkCategory"} - } else { - categories = []string{} - } - - minTags := int32(2) - if filter.MinTags != nil { - minTags = filter.MinTags.GetValue() - } - var tags []string - for k := int32(0); k < minTags; k++ { - tags = append(tags, fmt.Sprintf("BulkTag%d", k+1)) - } - - allResults = append(allResults, &productv1.BlogPost{ - Id: fmt.Sprintf("bulk-post-%d-%d", i+1, j), - Title: title, - Content: fmt.Sprintf("Bulk content for post %d-%d", i+1, j), - Tags: tags, - Categories: categories, - ViewCounts: []int32{100, 150, 200}, - TagGroups: &productv1.ListOfListOfString{ - List: &productv1.ListOfListOfString_List{ - Items: []*productv1.ListOfString{ - {List: &productv1.ListOfString_List{ - Items: []string{fmt.Sprintf("BulkGroup%d", j)}, - }}, - }, - }, - }, - RelatedTopics: &productv1.ListOfListOfString{ - List: &productv1.ListOfListOfString_List{ - Items: []*productv1.ListOfString{ - {List: &productv1.ListOfString_List{ - Items: []string{fmt.Sprintf("BulkTopic%d", j)}, - }}, - }, - }, - }, - CommentThreads: &productv1.ListOfListOfString{ - List: &productv1.ListOfListOfString_List{ - Items: []*productv1.ListOfString{ - {List: &productv1.ListOfString_List{ - Items: []string{fmt.Sprintf("BulkComment%d", j)}, - }}, - }, - }, - }, - RelatedCategories: []*productv1.Category{ - {Id: fmt.Sprintf("bulk-rel-cat-%d-%d", i+1, j), Name: fmt.Sprintf("Bulk Related %d-%d", i+1, j), Kind: productv1.CategoryKind_CATEGORY_KIND_OTHER}, - }, - Contributors: []*productv1.User{ - {Id: fmt.Sprintf("bulk-contrib-%d-%d", i+1, j), Name: fmt.Sprintf("Bulk Contributor %d-%d", i+1, j)}, - }, - CategoryGroups: &productv1.ListOfListOfCategory{ - List: &productv1.ListOfListOfCategory_List{ - Items: []*productv1.ListOfCategory{ - {List: &productv1.ListOfCategory_List{ - Items: []*productv1.Category{ - {Id: fmt.Sprintf("bulk-grp-cat-%d-%d", i+1, j), Name: fmt.Sprintf("Bulk Group Cat %d-%d", i+1, j), Kind: productv1.CategoryKind_CATEGORY_KIND_BOOK}, - }, - }}, - }, - }, - }, - }) - } - } - } - - return &productv1.QueryBulkSearchBlogPostsResponse{ - BulkSearchBlogPosts: allResults, - }, nil -} - -func (s *MockService) MutationBulkCreateAuthors(ctx context.Context, in *productv1.MutationBulkCreateAuthorsRequest) (*productv1.MutationBulkCreateAuthorsResponse, error) { - var results []*productv1.Author - - // Handle nullable list - if authors is nil, return empty results - if in.Authors == nil { - return &productv1.MutationBulkCreateAuthorsResponse{ - BulkCreateAuthors: results, - }, nil - } - - // Process each author input in the list - if in.Authors.List != nil { - for i, authorInput := range in.Authors.List.Items { - // Convert nested UserInput lists to Users for complex fields - var authorGroups *productv1.ListOfListOfUser - if authorInput.AuthorGroups != nil { - authorGroups = convertNestedUserInputsToUsers(authorInput.AuthorGroups) - } - - var projectTeams *productv1.ListOfListOfUser - if authorInput.ProjectTeams != nil { - projectTeams = convertNestedUserInputsToUsers(authorInput.ProjectTeams) - } - - // Convert CategoryInput list to Categories - var favoriteCategories []*productv1.Category - if authorInput.FavoriteCategories != nil { - favoriteCategories = convertCategoryInputsToCategories(authorInput.FavoriteCategories) - } - - author := &productv1.Author{ - Id: fmt.Sprintf("bulk-created-author-%d", i+1), - Name: authorInput.Name, - Email: authorInput.Email, - Skills: authorInput.Skills, - Languages: authorInput.Languages, - SocialLinks: authorInput.SocialLinks, - TeamsByProject: authorInput.TeamsByProject, - Collaborations: authorInput.Collaborations, - FavoriteCategories: favoriteCategories, - AuthorGroups: authorGroups, - ProjectTeams: projectTeams, - // Add required complex fields with mock data - WrittenPosts: &productv1.ListOfBlogPost{ - List: &productv1.ListOfBlogPost_List{ - Items: []*productv1.BlogPost{ - {Id: fmt.Sprintf("bulk-blog-%d", i+1), Title: fmt.Sprintf("Bulk Created Post %d", i+1), Content: "Bulk created content..."}, - }, - }, - }, - RelatedAuthors: &productv1.ListOfUser{ - List: &productv1.ListOfUser_List{ - Items: []*productv1.User{ - {Id: fmt.Sprintf("bulk-rel-author-%d", i+1), Name: fmt.Sprintf("Bulk Related Author %d", i+1)}, - }, - }, - }, - ProductReviews: &productv1.ListOfProduct{ - List: &productv1.ListOfProduct_List{ - Items: []*productv1.Product{ - {Id: fmt.Sprintf("bulk-prod-%d", i+1), Name: fmt.Sprintf("Bulk Product %d", i+1), Price: 99.99}, - }, - }, - }, - CategoryPreferences: &productv1.ListOfListOfCategory{ - List: &productv1.ListOfListOfCategory_List{ - Items: []*productv1.ListOfCategory{ - {List: &productv1.ListOfCategory_List{ - Items: []*productv1.Category{ - {Id: fmt.Sprintf("bulk-cat-pref-%d", i+1), Name: fmt.Sprintf("Bulk Category Preference %d", i+1), Kind: productv1.CategoryKind_CATEGORY_KIND_ELECTRONICS}, - }, - }}, - }, - }, - }, - } - - results = append(results, author) - } - } - - return &productv1.MutationBulkCreateAuthorsResponse{ - BulkCreateAuthors: results, - }, nil -} - -func (s *MockService) MutationBulkUpdateAuthors(ctx context.Context, in *productv1.MutationBulkUpdateAuthorsRequest) (*productv1.MutationBulkUpdateAuthorsResponse, error) { - var results []*productv1.Author - - // Handle nullable list - if authors is nil, return empty results - if in.Authors == nil { - return &productv1.MutationBulkUpdateAuthorsResponse{ - BulkUpdateAuthors: results, - }, nil - } - - // Process each author input in the list - if in.Authors.List != nil { - for i, authorInput := range in.Authors.List.Items { - // Convert nested UserInput lists to Users for complex fields - var authorGroups *productv1.ListOfListOfUser - if authorInput.AuthorGroups != nil { - authorGroups = convertNestedUserInputsToUsers(authorInput.AuthorGroups) - } - - var projectTeams *productv1.ListOfListOfUser - if authorInput.ProjectTeams != nil { - projectTeams = convertNestedUserInputsToUsers(authorInput.ProjectTeams) - } - - // Convert CategoryInput list to Categories - var favoriteCategories []*productv1.Category - if authorInput.FavoriteCategories != nil { - favoriteCategories = convertCategoryInputsToCategories(authorInput.FavoriteCategories) - } - - author := &productv1.Author{ - Id: fmt.Sprintf("bulk-updated-author-%d", i+1), - Name: authorInput.Name, - Email: authorInput.Email, - Skills: authorInput.Skills, - Languages: authorInput.Languages, - SocialLinks: authorInput.SocialLinks, - TeamsByProject: authorInput.TeamsByProject, - Collaborations: authorInput.Collaborations, - FavoriteCategories: favoriteCategories, - AuthorGroups: authorGroups, - ProjectTeams: projectTeams, - // Add required complex fields with mock data - WrittenPosts: &productv1.ListOfBlogPost{ - List: &productv1.ListOfBlogPost_List{ - Items: []*productv1.BlogPost{ - {Id: fmt.Sprintf("bulk-updated-blog-%d", i+1), Title: fmt.Sprintf("Bulk Updated Post %d", i+1), Content: "Bulk updated content..."}, - }, - }, - }, - RelatedAuthors: &productv1.ListOfUser{ - List: &productv1.ListOfUser_List{ - Items: []*productv1.User{ - {Id: fmt.Sprintf("bulk-updated-rel-author-%d", i+1), Name: fmt.Sprintf("Bulk Updated Related Author %d", i+1)}, - }, - }, - }, - ProductReviews: &productv1.ListOfProduct{ - List: &productv1.ListOfProduct_List{ - Items: []*productv1.Product{ - {Id: fmt.Sprintf("bulk-updated-prod-%d", i+1), Name: fmt.Sprintf("Bulk Updated Product %d", i+1), Price: 149.99}, - }, - }, - }, - CategoryPreferences: &productv1.ListOfListOfCategory{ - List: &productv1.ListOfListOfCategory_List{ - Items: []*productv1.ListOfCategory{ - {List: &productv1.ListOfCategory_List{ - Items: []*productv1.Category{ - {Id: fmt.Sprintf("bulk-updated-cat-pref-%d", i+1), Name: fmt.Sprintf("Bulk Updated Category Preference %d", i+1), Kind: productv1.CategoryKind_CATEGORY_KIND_ELECTRONICS}, - }, - }}, - }, - }, - }, - } - - results = append(results, author) - } - } - - return &productv1.MutationBulkUpdateAuthorsResponse{ - BulkUpdateAuthors: results, - }, nil -} - -func (s *MockService) MutationBulkCreateBlogPosts(ctx context.Context, in *productv1.MutationBulkCreateBlogPostsRequest) (*productv1.MutationBulkCreateBlogPostsResponse, error) { - var results []*productv1.BlogPost - - // Handle nullable list - if blogPosts is nil, return empty results - if in.BlogPosts == nil { - return &productv1.MutationBulkCreateBlogPostsResponse{ - BulkCreateBlogPosts: results, - }, nil - } - - // Process each blog post input in the list - if in.BlogPosts.List != nil { - for i, blogPostInput := range in.BlogPosts.List.Items { - // Convert CategoryInput lists to Categories - var relatedCategories []*productv1.Category - if blogPostInput.RelatedCategories != nil { - relatedCategories = convertCategoryInputListToCategories(blogPostInput.RelatedCategories) - } - - var contributors []*productv1.User - if blogPostInput.Contributors != nil { - contributors = convertUserInputsToUsers(blogPostInput.Contributors) - } - - var categoryGroups *productv1.ListOfListOfCategory - if blogPostInput.CategoryGroups != nil { - categoryGroups = convertNestedCategoryInputsToCategories(blogPostInput.CategoryGroups) - } - - blogPost := &productv1.BlogPost{ - Id: fmt.Sprintf("bulk-created-post-%d", i+1), - Title: blogPostInput.Title, - Content: blogPostInput.Content, - Tags: blogPostInput.Tags, - OptionalTags: blogPostInput.OptionalTags, - Categories: blogPostInput.Categories, - Keywords: blogPostInput.Keywords, - ViewCounts: blogPostInput.ViewCounts, - Ratings: blogPostInput.Ratings, - IsPublished: blogPostInput.IsPublished, - TagGroups: blogPostInput.TagGroups, - RelatedTopics: blogPostInput.RelatedTopics, - CommentThreads: blogPostInput.CommentThreads, - Suggestions: blogPostInput.Suggestions, - RelatedCategories: relatedCategories, - Contributors: contributors, - CategoryGroups: categoryGroups, - // Add required fields with mock data - MentionedProducts: &productv1.ListOfProduct{ - List: &productv1.ListOfProduct_List{ - Items: []*productv1.Product{ - {Id: fmt.Sprintf("bulk-prod-%d", i+1), Name: fmt.Sprintf("Bulk Created Product %d", i+1), Price: 99.99}, - }, - }, - }, - MentionedUsers: &productv1.ListOfUser{ - List: &productv1.ListOfUser_List{ - Items: []*productv1.User{ - {Id: fmt.Sprintf("bulk-user-%d", i+1), Name: fmt.Sprintf("Bulk Created User %d", i+1)}, - }, - }, - }, - ContributorTeams: &productv1.ListOfListOfUser{ - List: &productv1.ListOfListOfUser_List{ - Items: []*productv1.ListOfUser{ - {List: &productv1.ListOfUser_List{ - Items: []*productv1.User{ - {Id: fmt.Sprintf("bulk-team-%d", i+1), Name: fmt.Sprintf("Bulk Created Team Member %d", i+1)}, - }, - }}, - }, - }, - }, - } - - results = append(results, blogPost) - } - } - - return &productv1.MutationBulkCreateBlogPostsResponse{ - BulkCreateBlogPosts: results, - }, nil -} - -func (s *MockService) MutationBulkUpdateBlogPosts(ctx context.Context, in *productv1.MutationBulkUpdateBlogPostsRequest) (*productv1.MutationBulkUpdateBlogPostsResponse, error) { - var results []*productv1.BlogPost - - // Handle nullable list - if blogPosts is nil, return empty results - if in.BlogPosts == nil { - return &productv1.MutationBulkUpdateBlogPostsResponse{ - BulkUpdateBlogPosts: results, - }, nil - } - - // Process each blog post input in the list - if in.BlogPosts.List != nil { - for i, blogPostInput := range in.BlogPosts.List.Items { - // Convert CategoryInput lists to Categories - var relatedCategories []*productv1.Category - if blogPostInput.RelatedCategories != nil { - relatedCategories = convertCategoryInputListToCategories(blogPostInput.RelatedCategories) - } - - var contributors []*productv1.User - if blogPostInput.Contributors != nil { - contributors = convertUserInputsToUsers(blogPostInput.Contributors) - } - - var categoryGroups *productv1.ListOfListOfCategory - if blogPostInput.CategoryGroups != nil { - categoryGroups = convertNestedCategoryInputsToCategories(blogPostInput.CategoryGroups) - } - - blogPost := &productv1.BlogPost{ - Id: fmt.Sprintf("bulk-updated-post-%d", i+1), - Title: blogPostInput.Title, - Content: blogPostInput.Content, - Tags: blogPostInput.Tags, - OptionalTags: blogPostInput.OptionalTags, - Categories: blogPostInput.Categories, - Keywords: blogPostInput.Keywords, - ViewCounts: blogPostInput.ViewCounts, - Ratings: blogPostInput.Ratings, - IsPublished: blogPostInput.IsPublished, - TagGroups: blogPostInput.TagGroups, - RelatedTopics: blogPostInput.RelatedTopics, - CommentThreads: blogPostInput.CommentThreads, - Suggestions: blogPostInput.Suggestions, - RelatedCategories: relatedCategories, - Contributors: contributors, - CategoryGroups: categoryGroups, - // Add required fields with mock data - MentionedProducts: &productv1.ListOfProduct{ - List: &productv1.ListOfProduct_List{ - Items: []*productv1.Product{ - {Id: fmt.Sprintf("bulk-updated-prod-%d", i+1), Name: fmt.Sprintf("Bulk Updated Product %d", i+1), Price: 149.99}, - }, - }, - }, - MentionedUsers: &productv1.ListOfUser{ - List: &productv1.ListOfUser_List{ - Items: []*productv1.User{ - {Id: fmt.Sprintf("bulk-updated-user-%d", i+1), Name: fmt.Sprintf("Bulk Updated User %d", i+1)}, - }, - }, - }, - ContributorTeams: &productv1.ListOfListOfUser{ - List: &productv1.ListOfListOfUser_List{ - Items: []*productv1.ListOfUser{ - {List: &productv1.ListOfUser_List{ - Items: []*productv1.User{ - {Id: fmt.Sprintf("bulk-updated-team-%d", i+1), Name: fmt.Sprintf("Bulk Updated Team Member %d", i+1)}, - }, - }}, - }, - }, - }, - } - - results = append(results, blogPost) - } - } - - return &productv1.MutationBulkUpdateBlogPostsResponse{ - BulkUpdateBlogPosts: results, - }, nil -} diff --git a/v2/pkg/grpctest/mockservice_enums.go b/v2/pkg/grpctest/mockservice_enums.go new file mode 100644 index 000000000..15e590025 --- /dev/null +++ b/v2/pkg/grpctest/mockservice_enums.go @@ -0,0 +1,144 @@ +package grpctest + +import ( + "context" + "fmt" + + "google.golang.org/protobuf/types/known/wrapperspb" + + "github.com/wundergraph/graphql-go-tools/v2/pkg/grpctest/productv1" +) + +// Implementation for QueryCategories +func (s *MockService) QueryCategories(ctx context.Context, in *productv1.QueryCategoriesRequest) (*productv1.QueryCategoriesResponse, error) { + // Generate a list of categories + var categories []*productv1.Category + + // Create sample categories for each CategoryKind + categoryKinds := []productv1.CategoryKind{ + productv1.CategoryKind_CATEGORY_KIND_BOOK, + productv1.CategoryKind_CATEGORY_KIND_ELECTRONICS, + productv1.CategoryKind_CATEGORY_KIND_FURNITURE, + productv1.CategoryKind_CATEGORY_KIND_OTHER, + } + + for i, kind := range categoryKinds { + categories = append(categories, &productv1.Category{ + Id: fmt.Sprintf("category-%d", i+1), + Name: fmt.Sprintf("%s Category", kind.String()), + Kind: kind, + Subcategories: createSubcategories(fmt.Sprintf("category-%d", i+1), kind, i+1), + }) + } + + return &productv1.QueryCategoriesResponse{ + Categories: categories, + }, nil +} + +// Implementation for QueryCategoriesByKind +func (s *MockService) QueryCategoriesByKind(ctx context.Context, in *productv1.QueryCategoriesByKindRequest) (*productv1.QueryCategoriesByKindResponse, error) { + kind := in.GetKind() + + // Generate categories for the specified kind + var categories []*productv1.Category + + // Create 3 categories of the requested kind + for i := 1; i <= 3; i++ { + + subcategories := make([]*productv1.Subcategory, 0, i) + for j := 1; j <= i; j++ { + subcategories = append(subcategories, &productv1.Subcategory{ + Id: fmt.Sprintf("%s-subcategory-%d", kind.String(), j), + Name: fmt.Sprintf("%s Subcategory %d", kind.String(), j), + Description: &wrapperspb.StringValue{Value: fmt.Sprintf("%s Subcategory %d", kind.String(), j)}, + IsActive: true, + }) + } + + categories = append(categories, &productv1.Category{ + Id: fmt.Sprintf("%s-category-%d", kind.String(), i), + Name: fmt.Sprintf("%s Category %d", kind.String(), i), + Kind: kind, + Subcategories: &productv1.ListOfSubcategory{ + List: &productv1.ListOfSubcategory_List{ + Items: subcategories, + }, + }, + }) + } + + return &productv1.QueryCategoriesByKindResponse{ + CategoriesByKind: categories, + }, nil +} + +func (s *MockService) QueryCategoriesByKinds(ctx context.Context, in *productv1.QueryCategoriesByKindsRequest) (*productv1.QueryCategoriesByKindsResponse, error) { + kinds := in.GetKinds() + + var categories []*productv1.Category + + for i, kind := range kinds { + categories = append(categories, &productv1.Category{ + Id: fmt.Sprintf("%s-category-%d", kind.String(), i), + Name: fmt.Sprintf("%s Category %d", kind.String(), i), + Kind: kind, + Subcategories: createSubcategories(fmt.Sprintf("%s-category-%d", kind.String(), i), kind, i+1), + }) + } + + return &productv1.QueryCategoriesByKindsResponse{ + CategoriesByKinds: categories, + }, nil +} + +// Implementation for QueryFilterCategories +func (s *MockService) QueryFilterCategories(ctx context.Context, in *productv1.QueryFilterCategoriesRequest) (*productv1.QueryFilterCategoriesResponse, error) { + filter := in.GetFilter() + + if filter == nil { + return &productv1.QueryFilterCategoriesResponse{ + FilterCategories: []*productv1.Category{}, + }, nil + } + + kind := filter.GetCategory() + + // Generate filtered categories + var categories []*productv1.Category + + // Create categories that match the filter + for i := 1; i <= 5; i++ { + categories = append(categories, &productv1.Category{ + Id: fmt.Sprintf("filtered-%s-category-%d", kind.String(), i), + Name: fmt.Sprintf("Filtered %s Category %d", kind.String(), i), + Kind: kind, + Subcategories: createSubcategories(fmt.Sprintf("filtered-%s-category-%d", kind.String(), i), kind, i), + }) + } + + // Apply pagination if provided + pagination := filter.GetPagination() + if pagination != nil { + page := int(pagination.GetPage()) + perPage := int(pagination.GetPerPage()) + + if page > 0 && perPage > 0 { + startIdx := (page - 1) * perPage + endIdx := startIdx + perPage + + if startIdx < len(categories) { + if endIdx > len(categories) { + endIdx = len(categories) + } + categories = categories[startIdx:endIdx] + } else { + categories = []*productv1.Category{} + } + } + } + + return &productv1.QueryFilterCategoriesResponse{ + FilterCategories: categories, + }, nil +} diff --git a/v2/pkg/grpctest/mockservice_lists.go b/v2/pkg/grpctest/mockservice_lists.go new file mode 100644 index 000000000..9963861f1 --- /dev/null +++ b/v2/pkg/grpctest/mockservice_lists.go @@ -0,0 +1,1752 @@ +package grpctest + +import ( + "context" + "fmt" + "math/rand" + + "google.golang.org/protobuf/types/known/wrapperspb" + + "github.com/wundergraph/graphql-go-tools/v2/pkg/grpctest/productv1" +) + +// BlogPost query implementations +func (s *MockService) QueryBlogPost(ctx context.Context, in *productv1.QueryBlogPostRequest) (*productv1.QueryBlogPostResponse, error) { + // Return a default blog post with comprehensive list examples + result := &productv1.BlogPost{ + Id: "blog-default", + Title: "Default Blog Post", + Content: "This is a sample blog post content for testing nested lists.", + Tags: []string{"tech", "programming", "go"}, + OptionalTags: &productv1.ListOfString{ + List: &productv1.ListOfString_List{ + Items: []string{"optional1", "optional2"}, + }, + }, + Categories: []string{"Technology", "", "Programming"}, // includes null/empty + Keywords: &productv1.ListOfString{ + List: &productv1.ListOfString_List{ + Items: []string{"keyword1", "keyword2"}, + }, + }, + ViewCounts: []int32{100, 150, 200, 250}, + Ratings: &productv1.ListOfFloat{ + List: &productv1.ListOfFloat_List{ + Items: []float64{4.5, 3.8, 5.0}, + }, + }, + IsPublished: &productv1.ListOfBoolean{ + List: &productv1.ListOfBoolean_List{ + Items: []bool{false, true, true}, + }, + }, + TagGroups: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{ + Items: []string{"tech", "programming"}, + }}, + {List: &productv1.ListOfString_List{ + Items: []string{"golang", "backend"}, + }}, + }, + }, + }, + RelatedTopics: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{Items: []string{"microservices", "api"}}}, + {List: &productv1.ListOfString_List{Items: []string{"databases", "performance"}}}, + }, + }, + }, + CommentThreads: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{Items: []string{"Great post!", "Very helpful"}}}, + {List: &productv1.ListOfString_List{Items: []string{"Could use more examples", "Thanks for sharing"}}}, + }, + }, + }, + Suggestions: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{Items: []string{"Add code examples", "Include diagrams"}}}, + }, + }, + }, + RelatedCategories: []*productv1.Category{ + {Id: "cat-1", Name: "Technology", Kind: productv1.CategoryKind_CATEGORY_KIND_ELECTRONICS}, + {Id: "cat-2", Name: "Programming", Kind: productv1.CategoryKind_CATEGORY_KIND_BOOK}, + }, + Contributors: []*productv1.User{ + {Id: "user-1", Name: "John Doe"}, + {Id: "user-2", Name: "Jane Smith"}, + }, + MentionedProducts: &productv1.ListOfProduct{ + List: &productv1.ListOfProduct_List{ + Items: []*productv1.Product{ + {Id: "prod-1", Name: "Sample Product", Price: 99.99}, + }, + }, + }, + MentionedUsers: &productv1.ListOfUser{ + List: &productv1.ListOfUser_List{ + Items: []*productv1.User{ + {Id: "user-3", Name: "Bob Johnson"}, + }, + }, + }, + CategoryGroups: &productv1.ListOfListOfCategory{ + List: &productv1.ListOfListOfCategory_List{ + Items: []*productv1.ListOfCategory{ + {List: &productv1.ListOfCategory_List{ + Items: []*productv1.Category{ + {Id: "cat-3", Name: "Web Development", Kind: productv1.CategoryKind_CATEGORY_KIND_ELECTRONICS}, + {Id: "cat-4", Name: "Backend", Kind: productv1.CategoryKind_CATEGORY_KIND_ELECTRONICS}, + }, + }}, + }, + }, + }, + ContributorTeams: &productv1.ListOfListOfUser{ + List: &productv1.ListOfListOfUser_List{ + Items: []*productv1.ListOfUser{ + {List: &productv1.ListOfUser_List{ + Items: []*productv1.User{ + {Id: "user-4", Name: "Alice Brown"}, + {Id: "user-5", Name: "Charlie Wilson"}, + }, + }}, + }, + }, + }, + } + + return &productv1.QueryBlogPostResponse{ + BlogPost: result, + }, nil +} + +func (s *MockService) QueryBlogPostById(ctx context.Context, in *productv1.QueryBlogPostByIdRequest) (*productv1.QueryBlogPostByIdResponse, error) { + id := in.GetId() + + // Return null for specific test IDs + if id == "not-found" { + return &productv1.QueryBlogPostByIdResponse{ + BlogPostById: nil, + }, nil + } + + // Create different test data based on ID + var result *productv1.BlogPost + + switch id { + case "simple": + result = &productv1.BlogPost{ + Id: id, + Title: "Simple Post", + Content: "Simple content", + Tags: []string{"simple"}, + Categories: []string{"Basic"}, + ViewCounts: []int32{10}, + // Required nested lists must have data + TagGroups: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{Items: []string{"simple"}}}, + }, + }, + }, + RelatedTopics: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{Items: []string{"basic"}}}, + }, + }, + }, + CommentThreads: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{Items: []string{"Nice post"}}}, + }, + }, + }, + // Required complex lists must have data + RelatedCategories: []*productv1.Category{ + {Id: "cat-simple", Name: "Basic", Kind: productv1.CategoryKind_CATEGORY_KIND_OTHER}, + }, + Contributors: []*productv1.User{ + {Id: "user-simple", Name: "Simple Author"}, + }, + CategoryGroups: &productv1.ListOfListOfCategory{ + List: &productv1.ListOfListOfCategory_List{ + Items: []*productv1.ListOfCategory{ + {List: &productv1.ListOfCategory_List{ + Items: []*productv1.Category{ + {Id: "cat-group-simple", Name: "Simple Category", Kind: productv1.CategoryKind_CATEGORY_KIND_OTHER}, + }, + }}, + }, + }, + }, + } + case "complex": + result = &productv1.BlogPost{ + Id: id, + Title: "Complex Blog Post", + Content: "Complex content with comprehensive lists", + Tags: []string{"complex", "advanced", "detailed"}, + OptionalTags: &productv1.ListOfString{ + List: &productv1.ListOfString_List{ + Items: []string{"deep-dive", "tutorial"}, + }, + }, + Categories: []string{"Advanced", "Tutorial", "Guide"}, + Keywords: &productv1.ListOfString{ + List: &productv1.ListOfString_List{ + Items: []string{"advanced", "complex", "comprehensive"}, + }, + }, + ViewCounts: []int32{500, 600, 750, 800, 950}, + Ratings: &productv1.ListOfFloat{ + List: &productv1.ListOfFloat_List{ + Items: []float64{4.8, 4.9, 4.7, 5.0}, + }, + }, + IsPublished: &productv1.ListOfBoolean{ + List: &productv1.ListOfBoolean_List{ + Items: []bool{false, false, true, true}, + }, + }, + TagGroups: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{Items: []string{"advanced", "expert"}}}, + {List: &productv1.ListOfString_List{Items: []string{"tutorial", "guide", "comprehensive"}}}, + {List: &productv1.ListOfString_List{Items: []string{"deep-dive", "detailed"}}}, + }, + }, + }, + RelatedTopics: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{Items: []string{"architecture", "patterns", "design"}}}, + {List: &productv1.ListOfString_List{Items: []string{"optimization", "performance", "scaling"}}}, + }, + }, + }, + CommentThreads: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{Items: []string{"Excellent deep dive!", "Very thorough"}}}, + {List: &productv1.ListOfString_List{Items: []string{"Could be longer", "More examples please"}}}, + {List: &productv1.ListOfString_List{Items: []string{"Best tutorial I've read", "Thank you!"}}}, + }, + }, + }, + Suggestions: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{Items: []string{"Add video content", "Include interactive examples"}}}, + {List: &productv1.ListOfString_List{Items: []string{"Create follow-up posts", "Add Q&A section"}}}, + }, + }, + }, + // Complex example includes all new complex list fields + RelatedCategories: []*productv1.Category{ + {Id: "cat-complex-1", Name: "Advanced Programming", Kind: productv1.CategoryKind_CATEGORY_KIND_ELECTRONICS}, + {Id: "cat-complex-2", Name: "Software Architecture", Kind: productv1.CategoryKind_CATEGORY_KIND_BOOK}, + }, + Contributors: []*productv1.User{ + {Id: "user-complex-1", Name: "Expert Author"}, + {Id: "user-complex-2", Name: "Technical Reviewer"}, + }, + MentionedProducts: &productv1.ListOfProduct{ + List: &productv1.ListOfProduct_List{ + Items: []*productv1.Product{ + {Id: "prod-complex-1", Name: "Advanced IDE", Price: 299.99}, + {Id: "prod-complex-2", Name: "Profiling Tool", Price: 149.99}, + }, + }, + }, + MentionedUsers: &productv1.ListOfUser{ + List: &productv1.ListOfUser_List{ + Items: []*productv1.User{ + {Id: "user-complex-3", Name: "Referenced Expert"}, + }, + }, + }, + CategoryGroups: &productv1.ListOfListOfCategory{ + List: &productv1.ListOfListOfCategory_List{ + Items: []*productv1.ListOfCategory{ + {List: &productv1.ListOfCategory_List{ + Items: []*productv1.Category{ + {Id: "cat-group-1", Name: "System Design", Kind: productv1.CategoryKind_CATEGORY_KIND_ELECTRONICS}, + {Id: "cat-group-2", Name: "Architecture Patterns", Kind: productv1.CategoryKind_CATEGORY_KIND_BOOK}, + }, + }}, + {List: &productv1.ListOfCategory_List{ + Items: []*productv1.Category{ + {Id: "cat-group-3", Name: "Performance", Kind: productv1.CategoryKind_CATEGORY_KIND_ELECTRONICS}, + }, + }}, + }, + }, + }, + ContributorTeams: &productv1.ListOfListOfUser{ + List: &productv1.ListOfListOfUser_List{ + Items: []*productv1.ListOfUser{ + {List: &productv1.ListOfUser_List{ + Items: []*productv1.User{ + {Id: "team-complex-1", Name: "Senior Engineer A"}, + {Id: "team-complex-2", Name: "Senior Engineer B"}, + }, + }}, + {List: &productv1.ListOfUser_List{ + Items: []*productv1.User{ + {Id: "team-complex-3", Name: "QA Lead"}, + }, + }}, + }, + }, + }, + } + default: + // Generic response for any other ID + result = &productv1.BlogPost{ + Id: id, + Title: fmt.Sprintf("Blog Post %s", id), + Content: fmt.Sprintf("Content for blog post %s", id), + Tags: []string{fmt.Sprintf("tag-%s", id), "general"}, + Categories: []string{"General", fmt.Sprintf("Category-%s", id)}, + ViewCounts: []int32{int32(len(id) * 10), int32(len(id) * 20)}, + // Required nested lists must have data + TagGroups: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{ + Items: []string{fmt.Sprintf("tag-%s", id), "group"}, + }}, + }, + }, + }, + RelatedTopics: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{ + Items: []string{fmt.Sprintf("topic-%s", id)}, + }}, + }, + }, + }, + CommentThreads: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{ + Items: []string{fmt.Sprintf("Comment on %s", id)}, + }}, + }, + }, + }, + // Required complex lists must have data + RelatedCategories: []*productv1.Category{ + {Id: fmt.Sprintf("cat-%s", id), Name: fmt.Sprintf("Category %s", id), Kind: productv1.CategoryKind_CATEGORY_KIND_OTHER}, + }, + Contributors: []*productv1.User{ + {Id: fmt.Sprintf("user-%s", id), Name: fmt.Sprintf("Author %s", id)}, + }, + CategoryGroups: &productv1.ListOfListOfCategory{ + List: &productv1.ListOfListOfCategory_List{ + Items: []*productv1.ListOfCategory{ + {List: &productv1.ListOfCategory_List{ + Items: []*productv1.Category{ + {Id: fmt.Sprintf("cat-group-%s", id), Name: fmt.Sprintf("Group Category %s", id), Kind: productv1.CategoryKind_CATEGORY_KIND_OTHER}, + }, + }}, + }, + }, + }, + } + } + + return &productv1.QueryBlogPostByIdResponse{ + BlogPostById: result, + }, nil +} + +func (s *MockService) QueryBlogPostsWithFilter(ctx context.Context, in *productv1.QueryBlogPostsWithFilterRequest) (*productv1.QueryBlogPostsWithFilterResponse, error) { + filter := in.GetFilter() + var results []*productv1.BlogPost + + // If no filter provided, return empty results + if filter == nil { + return &productv1.QueryBlogPostsWithFilterResponse{ + BlogPostsWithFilter: results, + }, nil + } + + titleFilter := "" + if filter.Title != nil { + titleFilter = filter.Title.GetValue() + } + + hasCategories := false + if filter.HasCategories != nil { + hasCategories = filter.HasCategories.GetValue() + } + + minTags := int32(0) + if filter.MinTags != nil { + minTags = filter.MinTags.GetValue() + } + + // Generate filtered results + for i := 1; i <= 3; i++ { + title := fmt.Sprintf("Filtered Post %d", i) + if titleFilter != "" { + title = fmt.Sprintf("%s - Post %d", titleFilter, i) + } + + var tags []string + tagsCount := minTags + int32(i) + for j := int32(0); j < tagsCount; j++ { + tags = append(tags, fmt.Sprintf("tag%d", j+1)) + } + + var categories []string + if hasCategories { + categories = []string{fmt.Sprintf("Category%d", i), "Filtered"} + } + + results = append(results, &productv1.BlogPost{ + Id: fmt.Sprintf("filtered-blog-%d", i), + Title: title, + Content: fmt.Sprintf("Filtered content %d", i), + Tags: tags, + Categories: categories, + ViewCounts: []int32{int32(i * 100)}, + // Required nested lists must have data + TagGroups: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{ + Items: []string{fmt.Sprintf("filtered-tag-%d", i)}, + }}, + }, + }, + }, + RelatedTopics: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{ + Items: []string{fmt.Sprintf("filtered-topic-%d", i)}, + }}, + }, + }, + }, + CommentThreads: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{ + Items: []string{fmt.Sprintf("Filtered comment %d", i)}, + }}, + }, + }, + }, + // Required complex lists must have data + RelatedCategories: []*productv1.Category{ + {Id: fmt.Sprintf("cat-filtered-%d", i), Name: fmt.Sprintf("Filtered Category %d", i), Kind: productv1.CategoryKind_CATEGORY_KIND_OTHER}, + }, + Contributors: []*productv1.User{ + {Id: fmt.Sprintf("user-filtered-%d", i), Name: fmt.Sprintf("Filtered Author %d", i)}, + }, + CategoryGroups: &productv1.ListOfListOfCategory{ + List: &productv1.ListOfListOfCategory_List{ + Items: []*productv1.ListOfCategory{ + {List: &productv1.ListOfCategory_List{ + Items: []*productv1.Category{ + {Id: fmt.Sprintf("cat-group-filtered-%d", i), Name: fmt.Sprintf("Filtered Group %d", i), Kind: productv1.CategoryKind_CATEGORY_KIND_OTHER}, + }, + }}, + }, + }, + }, + }) + } + + return &productv1.QueryBlogPostsWithFilterResponse{ + BlogPostsWithFilter: results, + }, nil +} + +func (s *MockService) QueryAllBlogPosts(ctx context.Context, in *productv1.QueryAllBlogPostsRequest) (*productv1.QueryAllBlogPostsResponse, error) { + var results []*productv1.BlogPost + + // Create a variety of blog posts + for i := 1; i <= 4; i++ { + var optionalTags *productv1.ListOfString + var keywords *productv1.ListOfString + var ratings *productv1.ListOfFloat + + // Vary the optional fields + if i%2 == 1 { + optionalTags = &productv1.ListOfString{ + List: &productv1.ListOfString_List{ + Items: []string{fmt.Sprintf("optional%d", i), "common"}, + }, + } + } + + if i%3 == 0 { + keywords = &productv1.ListOfString{ + List: &productv1.ListOfString_List{ + Items: []string{fmt.Sprintf("keyword%d", i)}, + }, + } + } + + if i%2 == 0 { + ratings = &productv1.ListOfFloat{ + List: &productv1.ListOfFloat_List{ + Items: []float64{float64(i) + 0.5, float64(i) + 1.0}, + }, + } + } + + results = append(results, &productv1.BlogPost{ + Id: fmt.Sprintf("blog-%d", i), + Title: fmt.Sprintf("Blog Post %d", i), + Content: fmt.Sprintf("Content for blog post %d", i), + Tags: []string{fmt.Sprintf("tag%d", i), "common"}, + OptionalTags: optionalTags, + Categories: []string{fmt.Sprintf("Category%d", i)}, + Keywords: keywords, + ViewCounts: []int32{int32(i * 100), int32(i * 150)}, + Ratings: ratings, + IsPublished: &productv1.ListOfBoolean{ + List: &productv1.ListOfBoolean_List{ + Items: []bool{i%2 == 0, true}, + }, + }, + TagGroups: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{ + Items: []string{fmt.Sprintf("group%d", i), "shared"}, + }}, + }, + }, + }, + RelatedTopics: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{ + Items: []string{fmt.Sprintf("topic%d", i)}, + }}, + }, + }, + }, + CommentThreads: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{ + Items: []string{fmt.Sprintf("Comment for post %d", i)}, + }}, + }, + }, + }, + // Required complex lists must have data + RelatedCategories: []*productv1.Category{ + {Id: fmt.Sprintf("cat-all-%d", i), Name: fmt.Sprintf("Category %d", i), Kind: productv1.CategoryKind_CATEGORY_KIND_OTHER}, + }, + Contributors: []*productv1.User{ + {Id: fmt.Sprintf("user-all-%d", i), Name: fmt.Sprintf("Author %d", i)}, + }, + CategoryGroups: &productv1.ListOfListOfCategory{ + List: &productv1.ListOfListOfCategory_List{ + Items: []*productv1.ListOfCategory{ + {List: &productv1.ListOfCategory_List{ + Items: []*productv1.Category{ + {Id: fmt.Sprintf("cat-group-all-%d", i), Name: fmt.Sprintf("Group Category %d", i), Kind: productv1.CategoryKind_CATEGORY_KIND_OTHER}, + }, + }}, + }, + }, + }, + // Optional list - can be empty + Suggestions: &productv1.ListOfListOfString{}, + }) + } + + return &productv1.QueryAllBlogPostsResponse{ + AllBlogPosts: results, + }, nil +} + +// Author query implementations +func (s *MockService) QueryAuthor(ctx context.Context, in *productv1.QueryAuthorRequest) (*productv1.QueryAuthorResponse, error) { + result := &productv1.Author{ + Id: "author-default", + Name: "Default Author", + Email: &wrapperspb.StringValue{ + Value: "author@example.com", + }, + Skills: []string{"Go", "GraphQL", "Protocol Buffers"}, + Languages: []string{"English", "Spanish", ""}, + SocialLinks: &productv1.ListOfString{ + List: &productv1.ListOfString_List{ + Items: []string{"https://twitter.com/author", "https://linkedin.com/in/author"}, + }, + }, + TeamsByProject: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{ + Items: []string{"Alice", "Bob", "Charlie"}, + }}, + {List: &productv1.ListOfString_List{ + Items: []string{"David", "Eve"}, + }}, + }, + }, + }, + Collaborations: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{ + Items: []string{"Open Source Project A", "Research Paper B"}, + }}, + {List: &productv1.ListOfString_List{ + Items: []string{"Conference Talk C"}, + }}, + }, + }, + }, + WrittenPosts: &productv1.ListOfBlogPost{ + List: &productv1.ListOfBlogPost_List{ + Items: []*productv1.BlogPost{ + {Id: "blog-1", Title: "GraphQL Best Practices", Content: "Content here..."}, + {Id: "blog-2", Title: "gRPC vs REST", Content: "Comparison content..."}, + }, + }, + }, + FavoriteCategories: []*productv1.Category{ + {Id: "cat-fav-1", Name: "Software Engineering", Kind: productv1.CategoryKind_CATEGORY_KIND_ELECTRONICS}, + {Id: "cat-fav-2", Name: "Technical Writing", Kind: productv1.CategoryKind_CATEGORY_KIND_BOOK}, + }, + RelatedAuthors: &productv1.ListOfUser{ + List: &productv1.ListOfUser_List{ + Items: []*productv1.User{ + {Id: "author-rel-1", Name: "Related Author One"}, + {Id: "author-rel-2", Name: "Related Author Two"}, + }, + }, + }, + ProductReviews: &productv1.ListOfProduct{ + List: &productv1.ListOfProduct_List{ + Items: []*productv1.Product{ + {Id: "prod-rev-1", Name: "Code Editor Pro", Price: 199.99}, + }, + }, + }, + AuthorGroups: &productv1.ListOfListOfUser{ + List: &productv1.ListOfListOfUser_List{ + Items: []*productv1.ListOfUser{ + {List: &productv1.ListOfUser_List{ + Items: []*productv1.User{ + {Id: "group-auth-1", Name: "Team Lead Alpha"}, + {Id: "group-auth-2", Name: "Senior Dev Beta"}, + }, + }}, + {List: &productv1.ListOfUser_List{ + Items: []*productv1.User{ + {Id: "group-auth-3", Name: "Junior Dev Gamma"}, + }, + }}, + // empty list + {List: &productv1.ListOfUser_List{}}, + // null item + nil, + }, + }, + }, + CategoryPreferences: &productv1.ListOfListOfCategory{ + List: &productv1.ListOfListOfCategory_List{ + Items: []*productv1.ListOfCategory{ + {List: &productv1.ListOfCategory_List{ + Items: []*productv1.Category{ + {Id: "pref-cat-1", Name: "Microservices", Kind: productv1.CategoryKind_CATEGORY_KIND_ELECTRONICS}, + {Id: "pref-cat-2", Name: "Cloud Computing", Kind: productv1.CategoryKind_CATEGORY_KIND_ELECTRONICS}, + }, + }}, + }, + }, + }, + } + + return &productv1.QueryAuthorResponse{ + Author: result, + }, nil +} + +func (s *MockService) QueryAuthorById(ctx context.Context, in *productv1.QueryAuthorByIdRequest) (*productv1.QueryAuthorByIdResponse, error) { + id := in.GetId() + + // Return null for specific test IDs + if id == "not-found" { + return &productv1.QueryAuthorByIdResponse{ + AuthorById: nil, + }, nil + } + + var result *productv1.Author + + switch id { + case "minimal": + result = &productv1.Author{ + Id: id, + Name: "Minimal Author", + Skills: []string{"Basic"}, + Languages: []string{"English"}, + TeamsByProject: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{ + Items: []string{"Solo"}, + }}, + }, + }, + }, + // Required complex lists must have data + FavoriteCategories: []*productv1.Category{ + {Id: "cat-minimal", Name: "Basic Category", Kind: productv1.CategoryKind_CATEGORY_KIND_OTHER}, + }, + CategoryPreferences: &productv1.ListOfListOfCategory{ + List: &productv1.ListOfListOfCategory_List{ + Items: []*productv1.ListOfCategory{ + {List: &productv1.ListOfCategory_List{ + Items: []*productv1.Category{ + {Id: "cat-pref-minimal", Name: "Minimal Preference", Kind: productv1.CategoryKind_CATEGORY_KIND_OTHER}, + }, + }}, + }, + }, + }, + // Optional list - can be empty + Collaborations: &productv1.ListOfListOfString{}, + } + case "experienced": + result = &productv1.Author{ + Id: id, + Name: "Experienced Author", + Email: &wrapperspb.StringValue{ + Value: "experienced@example.com", + }, + Skills: []string{"Go", "GraphQL", "gRPC", "Microservices", "Kubernetes"}, + Languages: []string{"English", "French", "German"}, + SocialLinks: &productv1.ListOfString{ + List: &productv1.ListOfString_List{ + Items: []string{ + "https://github.com/experienced", + "https://twitter.com/experienced", + "https://medium.com/@experienced", + }, + }, + }, + TeamsByProject: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{ + Items: []string{"Senior Dev 1", "Senior Dev 2", "Tech Lead"}, + }}, + {List: &productv1.ListOfString_List{ + Items: []string{"Architect", "Principal Engineer"}, + }}, + {List: &productv1.ListOfString_List{ + Items: []string{"PM", "Designer", "QA Lead"}, + }}, + }, + }, + }, + Collaborations: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{ + Items: []string{"Major OSS Project", "Industry Standard", "Research Initiative"}, + }}, + {List: &productv1.ListOfString_List{ + Items: []string{"Conference Keynote", "Workshop Series"}, + }}, + }, + }, + }, + // Required complex lists must have data + FavoriteCategories: []*productv1.Category{ + {Id: "cat-experienced-1", Name: "Advanced Programming", Kind: productv1.CategoryKind_CATEGORY_KIND_ELECTRONICS}, + {Id: "cat-experienced-2", Name: "Technical Leadership", Kind: productv1.CategoryKind_CATEGORY_KIND_BOOK}, + }, + CategoryPreferences: &productv1.ListOfListOfCategory{ + List: &productv1.ListOfListOfCategory_List{ + Items: []*productv1.ListOfCategory{ + {List: &productv1.ListOfCategory_List{ + Items: []*productv1.Category{ + {Id: "cat-pref-experienced-1", Name: "System Architecture", Kind: productv1.CategoryKind_CATEGORY_KIND_ELECTRONICS}, + {Id: "cat-pref-experienced-2", Name: "Team Management", Kind: productv1.CategoryKind_CATEGORY_KIND_BOOK}, + }, + }}, + }, + }, + }, + } + default: + result = &productv1.Author{ + Id: id, + Name: fmt.Sprintf("Author %s", id), + Email: &wrapperspb.StringValue{ + Value: fmt.Sprintf("%s@example.com", id), + }, + Skills: []string{fmt.Sprintf("Skill-%s", id), "General"}, + Languages: []string{"English", fmt.Sprintf("Language-%s", id)}, + TeamsByProject: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{ + Items: []string{fmt.Sprintf("Team-%s", id)}, + }}, + }, + }, + }, + // Required complex lists must have data + FavoriteCategories: []*productv1.Category{ + {Id: fmt.Sprintf("cat-%s", id), Name: fmt.Sprintf("Favorite Category %s", id), Kind: productv1.CategoryKind_CATEGORY_KIND_OTHER}, + }, + CategoryPreferences: &productv1.ListOfListOfCategory{ + List: &productv1.ListOfListOfCategory_List{ + Items: []*productv1.ListOfCategory{ + {List: &productv1.ListOfCategory_List{ + Items: []*productv1.Category{ + {Id: fmt.Sprintf("cat-pref-%s", id), Name: fmt.Sprintf("Preference %s", id), Kind: productv1.CategoryKind_CATEGORY_KIND_OTHER}, + }, + }}, + }, + }, + }, + // Optional list - can be empty + Collaborations: &productv1.ListOfListOfString{}, + } + } + + return &productv1.QueryAuthorByIdResponse{ + AuthorById: result, + }, nil +} + +func (s *MockService) QueryAuthorsWithFilter(ctx context.Context, in *productv1.QueryAuthorsWithFilterRequest) (*productv1.QueryAuthorsWithFilterResponse, error) { + filter := in.GetFilter() + var results []*productv1.Author + + if filter == nil { + return &productv1.QueryAuthorsWithFilterResponse{ + AuthorsWithFilter: results, + }, nil + } + + nameFilter := "" + if filter.Name != nil { + nameFilter = filter.Name.GetValue() + } + + hasTeams := false + if filter.HasTeams != nil { + hasTeams = filter.HasTeams.GetValue() + } + + skillCount := int32(0) + if filter.SkillCount != nil { + skillCount = filter.SkillCount.GetValue() + } + + // Generate filtered results + for i := 1; i <= 3; i++ { + name := fmt.Sprintf("Filtered Author %d", i) + if nameFilter != "" { + name = fmt.Sprintf("%s - Author %d", nameFilter, i) + } + + var skills []string + skillsNeeded := skillCount + int32(i) + for j := int32(0); j < skillsNeeded; j++ { + skills = append(skills, fmt.Sprintf("Skill%d", j+1)) + } + + var teamsByProject *productv1.ListOfListOfString + if hasTeams { + teamsByProject = &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{ + Items: []string{fmt.Sprintf("Team%d", i), "SharedTeam"}, + }}, + }, + }, + } + } else { + teamsByProject = &productv1.ListOfListOfString{List: &productv1.ListOfListOfString_List{}} + } + + results = append(results, &productv1.Author{ + Id: fmt.Sprintf("filtered-author-%d", i), + Name: name, + Skills: skills, + Languages: []string{"English", fmt.Sprintf("Lang%d", i)}, + TeamsByProject: teamsByProject, + // Required complex lists must have data + FavoriteCategories: []*productv1.Category{ + {Id: fmt.Sprintf("cat-filtered-%d", i), Name: fmt.Sprintf("Filtered Category %d", i), Kind: productv1.CategoryKind_CATEGORY_KIND_OTHER}, + }, + CategoryPreferences: &productv1.ListOfListOfCategory{ + List: &productv1.ListOfListOfCategory_List{ + Items: []*productv1.ListOfCategory{ + {List: &productv1.ListOfCategory_List{ + Items: []*productv1.Category{ + {Id: fmt.Sprintf("cat-pref-filtered-%d", i), Name: fmt.Sprintf("Filtered Preference %d", i), Kind: productv1.CategoryKind_CATEGORY_KIND_OTHER}, + }, + }}, + }, + }, + }, + // Optional list - can be empty + Collaborations: &productv1.ListOfListOfString{}, + }) + } + + return &productv1.QueryAuthorsWithFilterResponse{ + AuthorsWithFilter: results, + }, nil +} + +func (s *MockService) QueryAllAuthors(ctx context.Context, in *productv1.QueryAllAuthorsRequest) (*productv1.QueryAllAuthorsResponse, error) { + var results []*productv1.Author + + for i := 1; i <= 3; i++ { + var email *wrapperspb.StringValue + var socialLinks *productv1.ListOfString + var collaborations *productv1.ListOfListOfString + + if i%2 == 1 { + email = &wrapperspb.StringValue{ + Value: fmt.Sprintf("author%d@example.com", i), + } + } + + if i%3 == 0 { + socialLinks = &productv1.ListOfString{ + List: &productv1.ListOfString_List{ + Items: []string{fmt.Sprintf("https://github.com/author%d", i)}, + }, + } + } + + if i == 2 { + collaborations = &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{ + Items: []string{"Collaboration A", "Collaboration B"}, + }}, + }, + }, + } + } else { + collaborations = &productv1.ListOfListOfString{} + } + + results = append(results, &productv1.Author{ + Id: fmt.Sprintf("author-%d", i), + Name: fmt.Sprintf("Author %d", i), + Email: email, + Skills: []string{fmt.Sprintf("Skill%d", i), "Common"}, + Languages: []string{"English", fmt.Sprintf("Language%d", i)}, + SocialLinks: socialLinks, + TeamsByProject: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{ + Items: []string{fmt.Sprintf("Team%d", i)}, + }}, + }, + }, + }, + // Required complex lists must have data + FavoriteCategories: []*productv1.Category{ + {Id: fmt.Sprintf("cat-all-%d", i), Name: fmt.Sprintf("All Category %d", i), Kind: productv1.CategoryKind_CATEGORY_KIND_OTHER}, + }, + CategoryPreferences: &productv1.ListOfListOfCategory{ + List: &productv1.ListOfListOfCategory_List{ + Items: []*productv1.ListOfCategory{ + {List: &productv1.ListOfCategory_List{ + Items: []*productv1.Category{ + {Id: fmt.Sprintf("cat-pref-all-%d", i), Name: fmt.Sprintf("All Preference %d", i), Kind: productv1.CategoryKind_CATEGORY_KIND_OTHER}, + }, + }}, + }, + }, + }, + // Optional list - can be empty/variable + Collaborations: collaborations, + }) + } + + return &productv1.QueryAllAuthorsResponse{ + AllAuthors: results, + }, nil +} + +// BlogPost mutation implementations +func (s *MockService) MutationCreateBlogPost(ctx context.Context, in *productv1.MutationCreateBlogPostRequest) (*productv1.MutationCreateBlogPostResponse, error) { + input := in.GetInput() + + result := &productv1.BlogPost{ + Id: fmt.Sprintf("blog-%d", rand.Intn(1000)), + Title: input.GetTitle(), + Content: input.GetContent(), + Tags: input.GetTags(), + OptionalTags: input.GetOptionalTags(), + Categories: input.GetCategories(), + Keywords: input.GetKeywords(), + ViewCounts: input.GetViewCounts(), + Ratings: input.GetRatings(), + IsPublished: input.GetIsPublished(), + TagGroups: input.GetTagGroups(), + RelatedTopics: input.GetRelatedTopics(), + CommentThreads: input.GetCommentThreads(), + Suggestions: input.GetSuggestions(), + // Convert input types to output types + RelatedCategories: convertCategoryInputListToCategories(input.GetRelatedCategories()), + Contributors: convertUserInputsToUsers(input.GetContributors()), + CategoryGroups: convertNestedCategoryInputsToCategories(input.GetCategoryGroups()), + MentionedProducts: &productv1.ListOfProduct{ + List: &productv1.ListOfProduct_List{ + Items: []*productv1.Product{ + {Id: "prod-1", Name: "Sample Product", Price: 99.99}, + }, + }, + }, + MentionedUsers: &productv1.ListOfUser{ + List: &productv1.ListOfUser_List{ + Items: []*productv1.User{ + {Id: "user-3", Name: "Bob Johnson"}, + }, + }, + }, + ContributorTeams: &productv1.ListOfListOfUser{ + List: &productv1.ListOfListOfUser_List{ + Items: []*productv1.ListOfUser{ + {List: &productv1.ListOfUser_List{ + Items: []*productv1.User{ + {Id: "user-4", Name: "Alice Brown"}, + }, + }}, + }, + }, + }, + } + + return &productv1.MutationCreateBlogPostResponse{ + CreateBlogPost: result, + }, nil +} + +func (s *MockService) MutationUpdateBlogPost(ctx context.Context, in *productv1.MutationUpdateBlogPostRequest) (*productv1.MutationUpdateBlogPostResponse, error) { + id := in.GetId() + input := in.GetInput() + + if id == "non-existent" { + return &productv1.MutationUpdateBlogPostResponse{ + UpdateBlogPost: nil, + }, nil + } + + result := &productv1.BlogPost{ + Id: id, + Title: input.GetTitle(), + Content: input.GetContent(), + Tags: input.GetTags(), + OptionalTags: input.GetOptionalTags(), + Categories: input.GetCategories(), + Keywords: input.GetKeywords(), + ViewCounts: input.GetViewCounts(), + Ratings: input.GetRatings(), + IsPublished: input.GetIsPublished(), + TagGroups: input.GetTagGroups(), + RelatedTopics: input.GetRelatedTopics(), + CommentThreads: input.GetCommentThreads(), + Suggestions: input.GetSuggestions(), + // Convert input types to output types + RelatedCategories: convertCategoryInputListToCategories(input.GetRelatedCategories()), + Contributors: convertUserInputsToUsers(input.GetContributors()), + CategoryGroups: convertNestedCategoryInputsToCategories(input.GetCategoryGroups()), + MentionedProducts: &productv1.ListOfProduct{ + List: &productv1.ListOfProduct_List{ + Items: []*productv1.Product{ + {Id: "prod-updated", Name: "Updated Product", Price: 149.99}, + }, + }, + }, + MentionedUsers: &productv1.ListOfUser{ + List: &productv1.ListOfUser_List{ + Items: []*productv1.User{ + {Id: "user-updated", Name: "Updated User"}, + }, + }, + }, + ContributorTeams: &productv1.ListOfListOfUser{ + List: &productv1.ListOfListOfUser_List{ + Items: []*productv1.ListOfUser{ + {List: &productv1.ListOfUser_List{ + Items: []*productv1.User{ + {Id: "user-team-updated", Name: "Updated Team Member"}, + }, + }}, + }, + }, + }, + } + + return &productv1.MutationUpdateBlogPostResponse{ + UpdateBlogPost: result, + }, nil +} + +// Author mutation implementations +func (s *MockService) MutationCreateAuthor(ctx context.Context, in *productv1.MutationCreateAuthorRequest) (*productv1.MutationCreateAuthorResponse, error) { + input := in.GetInput() + + result := &productv1.Author{ + Id: fmt.Sprintf("author-%d", rand.Intn(1000)), + Name: input.GetName(), + Email: input.GetEmail(), + Skills: input.GetSkills(), + Languages: input.GetLanguages(), + SocialLinks: input.GetSocialLinks(), + TeamsByProject: input.GetTeamsByProject(), + Collaborations: input.GetCollaborations(), + // Convert input types to output types for complex fields + FavoriteCategories: convertCategoryInputsToCategories(input.GetFavoriteCategories()), + AuthorGroups: convertNestedUserInputsToUsers(input.GetAuthorGroups()), + ProjectTeams: convertNestedUserInputsToUsers(input.GetProjectTeams()), + // Keep other complex fields with mock data since they're not in the simplified input + WrittenPosts: &productv1.ListOfBlogPost{ + List: &productv1.ListOfBlogPost_List{ + Items: []*productv1.BlogPost{ + {Id: "blog-created", Title: "Created Post", Content: "Content..."}, + }, + }, + }, + RelatedAuthors: &productv1.ListOfUser{ + List: &productv1.ListOfUser_List{ + Items: []*productv1.User{ + {Id: "related-author", Name: "Related Author"}, + }, + }, + }, + ProductReviews: &productv1.ListOfProduct{ + List: &productv1.ListOfProduct_List{ + Items: []*productv1.Product{ + {Id: "reviewed-product", Name: "Code Editor", Price: 199.99}, + }, + }, + }, + CategoryPreferences: &productv1.ListOfListOfCategory{ + List: &productv1.ListOfListOfCategory_List{ + Items: []*productv1.ListOfCategory{ + {List: &productv1.ListOfCategory_List{ + Items: []*productv1.Category{ + {Id: "pref-cat", Name: "Backend Development", Kind: productv1.CategoryKind_CATEGORY_KIND_ELECTRONICS}, + }, + }}, + }, + }, + }, + } + + return &productv1.MutationCreateAuthorResponse{ + CreateAuthor: result, + }, nil +} + +func (s *MockService) MutationUpdateAuthor(ctx context.Context, in *productv1.MutationUpdateAuthorRequest) (*productv1.MutationUpdateAuthorResponse, error) { + id := in.GetId() + input := in.GetInput() + + if id == "non-existent" { + return &productv1.MutationUpdateAuthorResponse{ + UpdateAuthor: nil, + }, nil + } + + result := &productv1.Author{ + Id: id, + Name: input.GetName(), + Email: input.GetEmail(), + Skills: input.GetSkills(), + Languages: input.GetLanguages(), + SocialLinks: input.GetSocialLinks(), + TeamsByProject: input.GetTeamsByProject(), + Collaborations: input.GetCollaborations(), + // Convert input types to output types for complex fields + FavoriteCategories: convertCategoryInputsToCategories(input.GetFavoriteCategories()), + AuthorGroups: convertNestedUserInputsToUsers(input.GetAuthorGroups()), + ProjectTeams: convertNestedUserInputsToUsers(input.GetProjectTeams()), + // Keep other complex fields with mock data since they're not in the simplified input + WrittenPosts: &productv1.ListOfBlogPost{ + List: &productv1.ListOfBlogPost_List{ + Items: []*productv1.BlogPost{ + {Id: "blog-updated", Title: "Updated Post", Content: "Updated content..."}, + }, + }, + }, + RelatedAuthors: &productv1.ListOfUser{ + List: &productv1.ListOfUser_List{ + Items: []*productv1.User{ + {Id: "related-author-updated", Name: "Updated Related Author"}, + }, + }, + }, + ProductReviews: &productv1.ListOfProduct{ + List: &productv1.ListOfProduct_List{ + Items: []*productv1.Product{ + {Id: "reviewed-product-updated", Name: "Updated Code Editor", Price: 249.99}, + }, + }, + }, + CategoryPreferences: &productv1.ListOfListOfCategory{ + List: &productv1.ListOfListOfCategory_List{ + Items: []*productv1.ListOfCategory{ + {List: &productv1.ListOfCategory_List{ + Items: []*productv1.Category{ + {Id: "pref-cat-updated", Name: "Updated Backend Development", Kind: productv1.CategoryKind_CATEGORY_KIND_ELECTRONICS}, + }, + }}, + }, + }, + }, + } + + return &productv1.MutationUpdateAuthorResponse{ + UpdateAuthor: result, + }, nil +} + +// Bulk operation implementations +func (s *MockService) QueryBulkSearchAuthors(ctx context.Context, in *productv1.QueryBulkSearchAuthorsRequest) (*productv1.QueryBulkSearchAuthorsResponse, error) { + var allResults []*productv1.Author + + // Handle nullable list - if filters is nil, return empty results + if in.Filters == nil { + return &productv1.QueryBulkSearchAuthorsResponse{ + BulkSearchAuthors: allResults, + }, nil + } + + // Process each filter in the list + if in.Filters.List != nil { + for i, filter := range in.Filters.List.Items { + // Create mock results for each filter + for j := 1; j <= 2; j++ { + name := fmt.Sprintf("Bulk Author %d-%d", i+1, j) + if filter.Name != nil { + name = fmt.Sprintf("%s - Bulk %d-%d", filter.Name.GetValue(), i+1, j) + } + + var skills []string + skillCount := int32(3) + if filter.SkillCount != nil { + skillCount = filter.SkillCount.GetValue() + } + for k := int32(0); k < skillCount; k++ { + skills = append(skills, fmt.Sprintf("BulkSkill%d", k+1)) + } + + var teamsByProject *productv1.ListOfListOfString + if filter.HasTeams != nil && filter.HasTeams.GetValue() { + teamsByProject = &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{ + Items: []string{fmt.Sprintf("BulkTeam%d", j), "SharedBulkTeam"}, + }}, + }, + }, + } + } else { + teamsByProject = &productv1.ListOfListOfString{List: &productv1.ListOfListOfString_List{}} + } + + allResults = append(allResults, &productv1.Author{ + Id: fmt.Sprintf("bulk-author-%d-%d", i+1, j), + Name: name, + Skills: skills, + Languages: []string{"English", fmt.Sprintf("BulkLang%d", j)}, + TeamsByProject: teamsByProject, + FavoriteCategories: []*productv1.Category{ + {Id: fmt.Sprintf("bulk-cat-%d-%d", i+1, j), Name: fmt.Sprintf("Bulk Category %d-%d", i+1, j), Kind: productv1.CategoryKind_CATEGORY_KIND_OTHER}, + }, + CategoryPreferences: &productv1.ListOfListOfCategory{ + List: &productv1.ListOfListOfCategory_List{ + Items: []*productv1.ListOfCategory{ + {List: &productv1.ListOfCategory_List{ + Items: []*productv1.Category{ + {Id: fmt.Sprintf("bulk-pref-%d-%d", i+1, j), Name: fmt.Sprintf("Bulk Preference %d-%d", i+1, j), Kind: productv1.CategoryKind_CATEGORY_KIND_BOOK}, + }, + }}, + }, + }, + }, + }) + } + } + } + + return &productv1.QueryBulkSearchAuthorsResponse{ + BulkSearchAuthors: allResults, + }, nil +} + +func (s *MockService) QueryBulkSearchBlogPosts(ctx context.Context, in *productv1.QueryBulkSearchBlogPostsRequest) (*productv1.QueryBulkSearchBlogPostsResponse, error) { + var allResults []*productv1.BlogPost + + // Handle nullable list - if filters is nil, return empty results + if in.Filters == nil { + return &productv1.QueryBulkSearchBlogPostsResponse{ + BulkSearchBlogPosts: allResults, + }, nil + } + + // Process each filter in the list + if in.Filters.List != nil { + for i, filter := range in.Filters.List.Items { + // Create mock results for each filter + for j := 1; j <= 2; j++ { + title := fmt.Sprintf("Bulk Blog Post %d-%d", i+1, j) + if filter.Title != nil { + title = fmt.Sprintf("%s - Bulk %d-%d", filter.Title.GetValue(), i+1, j) + } + + var categories []string + if filter.HasCategories != nil && filter.HasCategories.GetValue() { + categories = []string{fmt.Sprintf("BulkCategory%d", j), "SharedBulkCategory"} + } else { + categories = []string{} + } + + minTags := int32(2) + if filter.MinTags != nil { + minTags = filter.MinTags.GetValue() + } + var tags []string + for k := int32(0); k < minTags; k++ { + tags = append(tags, fmt.Sprintf("BulkTag%d", k+1)) + } + + allResults = append(allResults, &productv1.BlogPost{ + Id: fmt.Sprintf("bulk-post-%d-%d", i+1, j), + Title: title, + Content: fmt.Sprintf("Bulk content for post %d-%d", i+1, j), + Tags: tags, + Categories: categories, + ViewCounts: []int32{100, 150, 200}, + TagGroups: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{ + Items: []string{fmt.Sprintf("BulkGroup%d", j)}, + }}, + }, + }, + }, + RelatedTopics: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{ + Items: []string{fmt.Sprintf("BulkTopic%d", j)}, + }}, + }, + }, + }, + CommentThreads: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{ + Items: []string{fmt.Sprintf("BulkComment%d", j)}, + }}, + }, + }, + }, + RelatedCategories: []*productv1.Category{ + {Id: fmt.Sprintf("bulk-rel-cat-%d-%d", i+1, j), Name: fmt.Sprintf("Bulk Related %d-%d", i+1, j), Kind: productv1.CategoryKind_CATEGORY_KIND_OTHER}, + }, + Contributors: []*productv1.User{ + {Id: fmt.Sprintf("bulk-contrib-%d-%d", i+1, j), Name: fmt.Sprintf("Bulk Contributor %d-%d", i+1, j)}, + }, + CategoryGroups: &productv1.ListOfListOfCategory{ + List: &productv1.ListOfListOfCategory_List{ + Items: []*productv1.ListOfCategory{ + {List: &productv1.ListOfCategory_List{ + Items: []*productv1.Category{ + {Id: fmt.Sprintf("bulk-grp-cat-%d-%d", i+1, j), Name: fmt.Sprintf("Bulk Group Cat %d-%d", i+1, j), Kind: productv1.CategoryKind_CATEGORY_KIND_BOOK}, + }, + }}, + }, + }, + }, + }) + } + } + } + + return &productv1.QueryBulkSearchBlogPostsResponse{ + BulkSearchBlogPosts: allResults, + }, nil +} + +func (s *MockService) MutationBulkCreateAuthors(ctx context.Context, in *productv1.MutationBulkCreateAuthorsRequest) (*productv1.MutationBulkCreateAuthorsResponse, error) { + var results []*productv1.Author + + // Handle nullable list - if authors is nil, return empty results + if in.Authors == nil { + return &productv1.MutationBulkCreateAuthorsResponse{ + BulkCreateAuthors: results, + }, nil + } + + // Process each author input in the list + if in.Authors.List != nil { + for i, authorInput := range in.Authors.List.Items { + // Convert nested UserInput lists to Users for complex fields + var authorGroups *productv1.ListOfListOfUser + if authorInput.AuthorGroups != nil { + authorGroups = convertNestedUserInputsToUsers(authorInput.AuthorGroups) + } + + var projectTeams *productv1.ListOfListOfUser + if authorInput.ProjectTeams != nil { + projectTeams = convertNestedUserInputsToUsers(authorInput.ProjectTeams) + } + + // Convert CategoryInput list to Categories + var favoriteCategories []*productv1.Category + if authorInput.FavoriteCategories != nil { + favoriteCategories = convertCategoryInputsToCategories(authorInput.FavoriteCategories) + } + + author := &productv1.Author{ + Id: fmt.Sprintf("bulk-created-author-%d", i+1), + Name: authorInput.Name, + Email: authorInput.Email, + Skills: authorInput.Skills, + Languages: authorInput.Languages, + SocialLinks: authorInput.SocialLinks, + TeamsByProject: authorInput.TeamsByProject, + Collaborations: authorInput.Collaborations, + FavoriteCategories: favoriteCategories, + AuthorGroups: authorGroups, + ProjectTeams: projectTeams, + // Add required complex fields with mock data + WrittenPosts: &productv1.ListOfBlogPost{ + List: &productv1.ListOfBlogPost_List{ + Items: []*productv1.BlogPost{ + {Id: fmt.Sprintf("bulk-blog-%d", i+1), Title: fmt.Sprintf("Bulk Created Post %d", i+1), Content: "Bulk created content..."}, + }, + }, + }, + RelatedAuthors: &productv1.ListOfUser{ + List: &productv1.ListOfUser_List{ + Items: []*productv1.User{ + {Id: fmt.Sprintf("bulk-rel-author-%d", i+1), Name: fmt.Sprintf("Bulk Related Author %d", i+1)}, + }, + }, + }, + ProductReviews: &productv1.ListOfProduct{ + List: &productv1.ListOfProduct_List{ + Items: []*productv1.Product{ + {Id: fmt.Sprintf("bulk-prod-%d", i+1), Name: fmt.Sprintf("Bulk Product %d", i+1), Price: 99.99}, + }, + }, + }, + CategoryPreferences: &productv1.ListOfListOfCategory{ + List: &productv1.ListOfListOfCategory_List{ + Items: []*productv1.ListOfCategory{ + {List: &productv1.ListOfCategory_List{ + Items: []*productv1.Category{ + {Id: fmt.Sprintf("bulk-cat-pref-%d", i+1), Name: fmt.Sprintf("Bulk Category Preference %d", i+1), Kind: productv1.CategoryKind_CATEGORY_KIND_ELECTRONICS}, + }, + }}, + }, + }, + }, + } + + results = append(results, author) + } + } + + return &productv1.MutationBulkCreateAuthorsResponse{ + BulkCreateAuthors: results, + }, nil +} + +func (s *MockService) MutationBulkUpdateAuthors(ctx context.Context, in *productv1.MutationBulkUpdateAuthorsRequest) (*productv1.MutationBulkUpdateAuthorsResponse, error) { + var results []*productv1.Author + + // Handle nullable list - if authors is nil, return empty results + if in.Authors == nil { + return &productv1.MutationBulkUpdateAuthorsResponse{ + BulkUpdateAuthors: results, + }, nil + } + + // Process each author input in the list + if in.Authors.List != nil { + for i, authorInput := range in.Authors.List.Items { + // Convert nested UserInput lists to Users for complex fields + var authorGroups *productv1.ListOfListOfUser + if authorInput.AuthorGroups != nil { + authorGroups = convertNestedUserInputsToUsers(authorInput.AuthorGroups) + } + + var projectTeams *productv1.ListOfListOfUser + if authorInput.ProjectTeams != nil { + projectTeams = convertNestedUserInputsToUsers(authorInput.ProjectTeams) + } + + // Convert CategoryInput list to Categories + var favoriteCategories []*productv1.Category + if authorInput.FavoriteCategories != nil { + favoriteCategories = convertCategoryInputsToCategories(authorInput.FavoriteCategories) + } + + author := &productv1.Author{ + Id: fmt.Sprintf("bulk-updated-author-%d", i+1), + Name: authorInput.Name, + Email: authorInput.Email, + Skills: authorInput.Skills, + Languages: authorInput.Languages, + SocialLinks: authorInput.SocialLinks, + TeamsByProject: authorInput.TeamsByProject, + Collaborations: authorInput.Collaborations, + FavoriteCategories: favoriteCategories, + AuthorGroups: authorGroups, + ProjectTeams: projectTeams, + // Add required complex fields with mock data + WrittenPosts: &productv1.ListOfBlogPost{ + List: &productv1.ListOfBlogPost_List{ + Items: []*productv1.BlogPost{ + {Id: fmt.Sprintf("bulk-updated-blog-%d", i+1), Title: fmt.Sprintf("Bulk Updated Post %d", i+1), Content: "Bulk updated content..."}, + }, + }, + }, + RelatedAuthors: &productv1.ListOfUser{ + List: &productv1.ListOfUser_List{ + Items: []*productv1.User{ + {Id: fmt.Sprintf("bulk-updated-rel-author-%d", i+1), Name: fmt.Sprintf("Bulk Updated Related Author %d", i+1)}, + }, + }, + }, + ProductReviews: &productv1.ListOfProduct{ + List: &productv1.ListOfProduct_List{ + Items: []*productv1.Product{ + {Id: fmt.Sprintf("bulk-updated-prod-%d", i+1), Name: fmt.Sprintf("Bulk Updated Product %d", i+1), Price: 149.99}, + }, + }, + }, + CategoryPreferences: &productv1.ListOfListOfCategory{ + List: &productv1.ListOfListOfCategory_List{ + Items: []*productv1.ListOfCategory{ + {List: &productv1.ListOfCategory_List{ + Items: []*productv1.Category{ + {Id: fmt.Sprintf("bulk-updated-cat-pref-%d", i+1), Name: fmt.Sprintf("Bulk Updated Category Preference %d", i+1), Kind: productv1.CategoryKind_CATEGORY_KIND_ELECTRONICS}, + }, + }}, + }, + }, + }, + } + + results = append(results, author) + } + } + + return &productv1.MutationBulkUpdateAuthorsResponse{ + BulkUpdateAuthors: results, + }, nil +} + +func (s *MockService) MutationBulkCreateBlogPosts(ctx context.Context, in *productv1.MutationBulkCreateBlogPostsRequest) (*productv1.MutationBulkCreateBlogPostsResponse, error) { + var results []*productv1.BlogPost + + // Handle nullable list - if blogPosts is nil, return empty results + if in.BlogPosts == nil { + return &productv1.MutationBulkCreateBlogPostsResponse{ + BulkCreateBlogPosts: results, + }, nil + } + + // Process each blog post input in the list + if in.BlogPosts.List != nil { + for i, blogPostInput := range in.BlogPosts.List.Items { + // Convert CategoryInput lists to Categories + var relatedCategories []*productv1.Category + if blogPostInput.RelatedCategories != nil { + relatedCategories = convertCategoryInputListToCategories(blogPostInput.RelatedCategories) + } + + var contributors []*productv1.User + if blogPostInput.Contributors != nil { + contributors = convertUserInputsToUsers(blogPostInput.Contributors) + } + + var categoryGroups *productv1.ListOfListOfCategory + if blogPostInput.CategoryGroups != nil { + categoryGroups = convertNestedCategoryInputsToCategories(blogPostInput.CategoryGroups) + } + + blogPost := &productv1.BlogPost{ + Id: fmt.Sprintf("bulk-created-post-%d", i+1), + Title: blogPostInput.Title, + Content: blogPostInput.Content, + Tags: blogPostInput.Tags, + OptionalTags: blogPostInput.OptionalTags, + Categories: blogPostInput.Categories, + Keywords: blogPostInput.Keywords, + ViewCounts: blogPostInput.ViewCounts, + Ratings: blogPostInput.Ratings, + IsPublished: blogPostInput.IsPublished, + TagGroups: blogPostInput.TagGroups, + RelatedTopics: blogPostInput.RelatedTopics, + CommentThreads: blogPostInput.CommentThreads, + Suggestions: blogPostInput.Suggestions, + RelatedCategories: relatedCategories, + Contributors: contributors, + CategoryGroups: categoryGroups, + // Add required fields with mock data + MentionedProducts: &productv1.ListOfProduct{ + List: &productv1.ListOfProduct_List{ + Items: []*productv1.Product{ + {Id: fmt.Sprintf("bulk-prod-%d", i+1), Name: fmt.Sprintf("Bulk Created Product %d", i+1), Price: 99.99}, + }, + }, + }, + MentionedUsers: &productv1.ListOfUser{ + List: &productv1.ListOfUser_List{ + Items: []*productv1.User{ + {Id: fmt.Sprintf("bulk-user-%d", i+1), Name: fmt.Sprintf("Bulk Created User %d", i+1)}, + }, + }, + }, + ContributorTeams: &productv1.ListOfListOfUser{ + List: &productv1.ListOfListOfUser_List{ + Items: []*productv1.ListOfUser{ + {List: &productv1.ListOfUser_List{ + Items: []*productv1.User{ + {Id: fmt.Sprintf("bulk-team-%d", i+1), Name: fmt.Sprintf("Bulk Created Team Member %d", i+1)}, + }, + }}, + }, + }, + }, + } + + results = append(results, blogPost) + } + } + + return &productv1.MutationBulkCreateBlogPostsResponse{ + BulkCreateBlogPosts: results, + }, nil +} + +func (s *MockService) MutationBulkUpdateBlogPosts(ctx context.Context, in *productv1.MutationBulkUpdateBlogPostsRequest) (*productv1.MutationBulkUpdateBlogPostsResponse, error) { + var results []*productv1.BlogPost + + // Handle nullable list - if blogPosts is nil, return empty results + if in.BlogPosts == nil { + return &productv1.MutationBulkUpdateBlogPostsResponse{ + BulkUpdateBlogPosts: results, + }, nil + } + + // Process each blog post input in the list + if in.BlogPosts.List != nil { + for i, blogPostInput := range in.BlogPosts.List.Items { + // Convert CategoryInput lists to Categories + var relatedCategories []*productv1.Category + if blogPostInput.RelatedCategories != nil { + relatedCategories = convertCategoryInputListToCategories(blogPostInput.RelatedCategories) + } + + var contributors []*productv1.User + if blogPostInput.Contributors != nil { + contributors = convertUserInputsToUsers(blogPostInput.Contributors) + } + + var categoryGroups *productv1.ListOfListOfCategory + if blogPostInput.CategoryGroups != nil { + categoryGroups = convertNestedCategoryInputsToCategories(blogPostInput.CategoryGroups) + } + + blogPost := &productv1.BlogPost{ + Id: fmt.Sprintf("bulk-updated-post-%d", i+1), + Title: blogPostInput.Title, + Content: blogPostInput.Content, + Tags: blogPostInput.Tags, + OptionalTags: blogPostInput.OptionalTags, + Categories: blogPostInput.Categories, + Keywords: blogPostInput.Keywords, + ViewCounts: blogPostInput.ViewCounts, + Ratings: blogPostInput.Ratings, + IsPublished: blogPostInput.IsPublished, + TagGroups: blogPostInput.TagGroups, + RelatedTopics: blogPostInput.RelatedTopics, + CommentThreads: blogPostInput.CommentThreads, + Suggestions: blogPostInput.Suggestions, + RelatedCategories: relatedCategories, + Contributors: contributors, + CategoryGroups: categoryGroups, + // Add required fields with mock data + MentionedProducts: &productv1.ListOfProduct{ + List: &productv1.ListOfProduct_List{ + Items: []*productv1.Product{ + {Id: fmt.Sprintf("bulk-updated-prod-%d", i+1), Name: fmt.Sprintf("Bulk Updated Product %d", i+1), Price: 149.99}, + }, + }, + }, + MentionedUsers: &productv1.ListOfUser{ + List: &productv1.ListOfUser_List{ + Items: []*productv1.User{ + {Id: fmt.Sprintf("bulk-updated-user-%d", i+1), Name: fmt.Sprintf("Bulk Updated User %d", i+1)}, + }, + }, + }, + ContributorTeams: &productv1.ListOfListOfUser{ + List: &productv1.ListOfListOfUser_List{ + Items: []*productv1.ListOfUser{ + {List: &productv1.ListOfUser_List{ + Items: []*productv1.User{ + {Id: fmt.Sprintf("bulk-updated-team-%d", i+1), Name: fmt.Sprintf("Bulk Updated Team Member %d", i+1)}, + }, + }}, + }, + }, + }, + } + + results = append(results, blogPost) + } + } + + return &productv1.MutationBulkUpdateBlogPostsResponse{ + BulkUpdateBlogPosts: results, + }, nil +} diff --git a/v2/pkg/grpctest/mockservice_lookup.go b/v2/pkg/grpctest/mockservice_lookup.go new file mode 100644 index 000000000..afebcbcb6 --- /dev/null +++ b/v2/pkg/grpctest/mockservice_lookup.go @@ -0,0 +1,76 @@ +package grpctest + +import ( + "context" + "fmt" + "math/rand" + + "github.com/wundergraph/graphql-go-tools/v2/pkg/grpctest/productv1" +) + +// LookupWarehouseById implements productv1.ProductServiceServer. +func (s *MockService) LookupWarehouseById(ctx context.Context, in *productv1.LookupWarehouseByIdRequest) (*productv1.LookupWarehouseByIdResponse, error) { + var results []*productv1.Warehouse + + // Special requirement: return one less item than requested to test error handling + // This deliberately breaks the normal pattern of returning the same number of items as keys + keys := in.GetKeys() + if len(keys) == 0 { + return &productv1.LookupWarehouseByIdResponse{ + Result: results, + }, nil + } + + // Return all items except the last one to test error scenarios + for i, input := range keys { + // Skip the last item to create an intentional mismatch + if i == len(keys)-1 { + break + } + + warehouseId := input.GetId() + results = append(results, &productv1.Warehouse{ + Id: warehouseId, + Name: fmt.Sprintf("Warehouse %s", warehouseId), + Location: fmt.Sprintf("Location %d", rand.Intn(100)), + }) + } + + return &productv1.LookupWarehouseByIdResponse{ + Result: results, + }, nil +} + +func (s *MockService) LookupProductById(ctx context.Context, in *productv1.LookupProductByIdRequest) (*productv1.LookupProductByIdResponse, error) { + var results []*productv1.Product + + for _, input := range in.GetKeys() { + productId := input.GetId() + results = append(results, &productv1.Product{ + Id: productId, + Name: fmt.Sprintf("Product %s", productId), + Price: 99.99, + }) + } + + return &productv1.LookupProductByIdResponse{ + Result: results, + }, nil +} + +func (s *MockService) LookupStorageById(ctx context.Context, in *productv1.LookupStorageByIdRequest) (*productv1.LookupStorageByIdResponse, error) { + var results []*productv1.Storage + + for _, input := range in.GetKeys() { + storageId := input.GetId() + results = append(results, &productv1.Storage{ + Id: storageId, + Name: fmt.Sprintf("Storage %s", storageId), + Location: fmt.Sprintf("Location %d", rand.Intn(100)), + }) + } + + return &productv1.LookupStorageByIdResponse{ + Result: results, + }, nil +} diff --git a/v2/pkg/grpctest/mockservice_nullable_fields.go b/v2/pkg/grpctest/mockservice_nullable_fields.go new file mode 100644 index 000000000..e112e5ca4 --- /dev/null +++ b/v2/pkg/grpctest/mockservice_nullable_fields.go @@ -0,0 +1,293 @@ +package grpctest + +import ( + "context" + "fmt" + "math" + "math/rand" + + "google.golang.org/protobuf/types/known/wrapperspb" + + "github.com/wundergraph/graphql-go-tools/v2/pkg/grpctest/productv1" +) + +// MutationCreateNullableFieldsType implements productv1.ProductServiceServer. +func (s *MockService) MutationCreateNullableFieldsType(ctx context.Context, in *productv1.MutationCreateNullableFieldsTypeRequest) (*productv1.MutationCreateNullableFieldsTypeResponse, error) { + input := in.GetInput() + + // Create a new NullableFieldsType from the input + result := &productv1.NullableFieldsType{ + Id: fmt.Sprintf("nullable-%d", rand.Intn(1000)), + Name: input.GetName(), + RequiredString: input.GetRequiredString(), + RequiredInt: input.GetRequiredInt(), + } + + // Handle optional fields - copy from input if they exist + if input.OptionalString != nil { + result.OptionalString = &wrapperspb.StringValue{Value: input.OptionalString.GetValue()} + } + if input.OptionalInt != nil { + result.OptionalInt = &wrapperspb.Int32Value{Value: input.OptionalInt.GetValue()} + } + if input.OptionalFloat != nil { + result.OptionalFloat = &wrapperspb.DoubleValue{Value: input.OptionalFloat.GetValue()} + } + if input.OptionalBoolean != nil { + result.OptionalBoolean = &wrapperspb.BoolValue{Value: input.OptionalBoolean.GetValue()} + } + + return &productv1.MutationCreateNullableFieldsTypeResponse{ + CreateNullableFieldsType: result, + }, nil +} + +// MutationUpdateNullableFieldsType implements productv1.ProductServiceServer. +func (s *MockService) MutationUpdateNullableFieldsType(ctx context.Context, in *productv1.MutationUpdateNullableFieldsTypeRequest) (*productv1.MutationUpdateNullableFieldsTypeResponse, error) { + id := in.GetId() + input := in.GetInput() + + // Return nil if trying to update a non-existent ID + if id == "non-existent" { + return &productv1.MutationUpdateNullableFieldsTypeResponse{ + UpdateNullableFieldsType: nil, + }, nil + } + + // Create updated NullableFieldsType + result := &productv1.NullableFieldsType{ + Id: id, + Name: input.GetName(), + RequiredString: input.GetRequiredString(), + RequiredInt: input.GetRequiredInt(), + } + + // Handle optional fields - copy from input if they exist + if input.OptionalString != nil { + result.OptionalString = &wrapperspb.StringValue{Value: input.OptionalString.GetValue()} + } + if input.OptionalInt != nil { + result.OptionalInt = &wrapperspb.Int32Value{Value: input.OptionalInt.GetValue()} + } + if input.OptionalFloat != nil { + result.OptionalFloat = &wrapperspb.DoubleValue{Value: input.OptionalFloat.GetValue()} + } + if input.OptionalBoolean != nil { + result.OptionalBoolean = &wrapperspb.BoolValue{Value: input.OptionalBoolean.GetValue()} + } + + return &productv1.MutationUpdateNullableFieldsTypeResponse{ + UpdateNullableFieldsType: result, + }, nil +} + +// QueryAllNullableFieldsTypes implements productv1.ProductServiceServer. +func (s *MockService) QueryAllNullableFieldsTypes(ctx context.Context, in *productv1.QueryAllNullableFieldsTypesRequest) (*productv1.QueryAllNullableFieldsTypesResponse, error) { + var results []*productv1.NullableFieldsType + + // Create a variety of test data with different nullable field combinations + + // Entry 1: All fields populated + results = append(results, &productv1.NullableFieldsType{ + Id: "nullable-1", + Name: "Full Data Entry", + OptionalString: &wrapperspb.StringValue{Value: "Optional String Value"}, + OptionalInt: &wrapperspb.Int32Value{Value: 42}, + OptionalFloat: &wrapperspb.DoubleValue{Value: math.MaxFloat64}, + OptionalBoolean: &wrapperspb.BoolValue{Value: true}, + RequiredString: "Required String 1", + RequiredInt: 100, + }) + + // Entry 2: Some nullable fields are null + results = append(results, &productv1.NullableFieldsType{ + Id: "nullable-2", + Name: "Partial Data Entry", + OptionalString: &wrapperspb.StringValue{Value: "Only string is set"}, + OptionalInt: nil, // null + OptionalFloat: nil, // null + OptionalBoolean: &wrapperspb.BoolValue{Value: false}, + RequiredString: "Required String 2", + RequiredInt: 200, + }) + + // Entry 3: All nullable fields are null + results = append(results, &productv1.NullableFieldsType{ + Id: "nullable-3", + Name: "Minimal Data Entry", + OptionalString: nil, // null + OptionalInt: nil, // null + OptionalFloat: nil, // null + OptionalBoolean: nil, // null + RequiredString: "Required String 3", + RequiredInt: 300, + }) + + return &productv1.QueryAllNullableFieldsTypesResponse{ + AllNullableFieldsTypes: results, + }, nil +} + +// QueryNullableFieldsType implements productv1.ProductServiceServer. +func (s *MockService) QueryNullableFieldsType(ctx context.Context, in *productv1.QueryNullableFieldsTypeRequest) (*productv1.QueryNullableFieldsTypeResponse, error) { + // Return a single NullableFieldsType with mixed null/non-null values + result := &productv1.NullableFieldsType{ + Id: "nullable-default", + Name: "Default Nullable Fields Type", + OptionalString: &wrapperspb.StringValue{Value: "Default optional string"}, + OptionalInt: &wrapperspb.Int32Value{Value: 777}, + OptionalFloat: nil, // null + OptionalBoolean: &wrapperspb.BoolValue{Value: true}, + RequiredString: "Default required string", + RequiredInt: 999, + } + + return &productv1.QueryNullableFieldsTypeResponse{ + NullableFieldsType: result, + }, nil +} + +// QueryNullableFieldsTypeById implements productv1.ProductServiceServer. +func (s *MockService) QueryNullableFieldsTypeById(ctx context.Context, in *productv1.QueryNullableFieldsTypeByIdRequest) (*productv1.QueryNullableFieldsTypeByIdResponse, error) { + id := in.GetId() + + // Return null for specific test IDs + if id == "not-found" || id == "null-test" { + return &productv1.QueryNullableFieldsTypeByIdResponse{ + NullableFieldsTypeById: nil, + }, nil + } + + // Create different test data based on ID + var result *productv1.NullableFieldsType + + switch id { + case "full-data": + result = &productv1.NullableFieldsType{ + Id: id, + Name: "Full Data by ID", + OptionalString: &wrapperspb.StringValue{Value: "All fields populated"}, + OptionalInt: &wrapperspb.Int32Value{Value: 123}, + OptionalFloat: &wrapperspb.DoubleValue{Value: 12.34}, + OptionalBoolean: &wrapperspb.BoolValue{Value: false}, + RequiredString: "Required by ID", + RequiredInt: 456, + } + case "partial-data": + result = &productv1.NullableFieldsType{ + Id: id, + Name: "Partial Data by ID", + OptionalString: nil, // null + OptionalInt: &wrapperspb.Int32Value{Value: 789}, + OptionalFloat: nil, // null + OptionalBoolean: &wrapperspb.BoolValue{Value: true}, + RequiredString: "Partial required by ID", + RequiredInt: 321, + } + case "minimal-data": + result = &productv1.NullableFieldsType{ + Id: id, + Name: "Minimal Data by ID", + OptionalString: nil, // null + OptionalInt: nil, // null + OptionalFloat: nil, // null + OptionalBoolean: nil, // null + RequiredString: "Only required fields", + RequiredInt: 111, + } + default: + // Generic response for any other ID + result = &productv1.NullableFieldsType{ + Id: id, + Name: fmt.Sprintf("Nullable Type %s", id), + OptionalString: &wrapperspb.StringValue{Value: fmt.Sprintf("Optional for %s", id)}, + OptionalInt: &wrapperspb.Int32Value{Value: int32(len(id) * 10)}, + OptionalFloat: &wrapperspb.DoubleValue{Value: float64(len(id)) * 1.5}, + OptionalBoolean: &wrapperspb.BoolValue{Value: len(id)%2 == 0}, + RequiredString: fmt.Sprintf("Required for %s", id), + RequiredInt: int32(len(id) * 100), + } + } + + return &productv1.QueryNullableFieldsTypeByIdResponse{ + NullableFieldsTypeById: result, + }, nil +} + +// QueryNullableFieldsTypeWithFilter implements productv1.ProductServiceServer. +func (s *MockService) QueryNullableFieldsTypeWithFilter(ctx context.Context, in *productv1.QueryNullableFieldsTypeWithFilterRequest) (*productv1.QueryNullableFieldsTypeWithFilterResponse, error) { + filter := in.GetFilter() + var results []*productv1.NullableFieldsType + + // If no filter provided, return empty results + if filter == nil { + return &productv1.QueryNullableFieldsTypeWithFilterResponse{ + NullableFieldsTypeWithFilter: results, + }, nil + } + + // Create test data based on filter criteria + nameFilter := "" + if filter.Name != nil { + nameFilter = filter.Name.GetValue() + } + + optionalStringFilter := "" + if filter.OptionalString != nil { + optionalStringFilter = filter.OptionalString.GetValue() + } + + includeNulls := false + if filter.IncludeNulls != nil { + includeNulls = filter.IncludeNulls.GetValue() + } + + // Generate filtered results + for i := 1; i <= 3; i++ { + var optionalString *wrapperspb.StringValue + var optionalInt *wrapperspb.Int32Value + var optionalFloat *wrapperspb.DoubleValue + var optionalBoolean *wrapperspb.BoolValue + + // Vary the nullable fields based on includeNulls and index + if includeNulls || i%2 == 1 { + if optionalStringFilter != "" { + optionalString = &wrapperspb.StringValue{Value: optionalStringFilter} + } else { + optionalString = &wrapperspb.StringValue{Value: fmt.Sprintf("Filtered string %d", i)} + } + } + + if includeNulls || i%3 != 0 { + optionalInt = &wrapperspb.Int32Value{Value: int32(i * 100)} + } + + if includeNulls || i%2 == 0 { + optionalFloat = &wrapperspb.DoubleValue{Value: float64(i) * 10.5} + } + + if includeNulls || i%4 != 0 { + optionalBoolean = &wrapperspb.BoolValue{Value: i%2 == 0} + } + + name := fmt.Sprintf("Filtered Item %d", i) + if nameFilter != "" { + name = fmt.Sprintf("%s - %d", nameFilter, i) + } + + results = append(results, &productv1.NullableFieldsType{ + Id: fmt.Sprintf("filtered-%d", i), + Name: name, + OptionalString: optionalString, + OptionalInt: optionalInt, + OptionalFloat: optionalFloat, + OptionalBoolean: optionalBoolean, + RequiredString: fmt.Sprintf("Required filtered %d", i), + RequiredInt: int32(i * 1000), + }) + } + + return &productv1.QueryNullableFieldsTypeWithFilterResponse{ + NullableFieldsTypeWithFilter: results, + }, nil +} diff --git a/v2/pkg/grpctest/mockservice_resolve.go b/v2/pkg/grpctest/mockservice_resolve.go new file mode 100644 index 000000000..107364ffe --- /dev/null +++ b/v2/pkg/grpctest/mockservice_resolve.go @@ -0,0 +1,773 @@ +package grpctest + +import ( + "context" + "fmt" + + "google.golang.org/protobuf/types/known/wrapperspb" + + "github.com/wundergraph/graphql-go-tools/v2/pkg/grpctest/productv1" +) + +// ResolveProductMascotRecommendation implements productv1.ProductServiceServer. +func (s *MockService) ResolveProductMascotRecommendation(_ context.Context, req *productv1.ResolveProductMascotRecommendationRequest) (*productv1.ResolveProductMascotRecommendationResponse, error) { + results := make([]*productv1.ResolveProductMascotRecommendationResult, 0, len(req.GetContext())) + + includeDetails := false + if req.GetFieldArgs() != nil { + includeDetails = req.GetFieldArgs().GetIncludeDetails() + } + + for i, ctx := range req.GetContext() { + // Alternate between Cat and Dog based on index + var animal *productv1.Animal + if i%2 == 0 { + volume := int32(5) + if includeDetails { + volume = int32((i + 1) * 8) + } + animal = &productv1.Animal{ + Instance: &productv1.Animal_Cat{ + Cat: &productv1.Cat{ + Id: fmt.Sprintf("mascot-cat-%s", ctx.GetId()), + Name: fmt.Sprintf("MascotCat for %s", ctx.GetName()), + Kind: "Cat", + MeowVolume: volume, + Owner: &productv1.Owner{ + Id: fmt.Sprintf("owner-cat-%s", ctx.GetId()), + Name: fmt.Sprintf("OwnerCat for %s", ctx.GetName()), + Contact: &productv1.ContactInfo{ + Email: "owner-cat@example.com", + Phone: "123-456-7890", + Address: &productv1.Address{ + Street: "123 Main St", + City: "Anytown", + Country: "USA", + ZipCode: "12345", + }, + }, + }, + Breed: &productv1.CatBreed{ + Id: fmt.Sprintf("breed-cat-%s", ctx.GetId()), + Name: fmt.Sprintf("BreedCat for %s", ctx.GetName()), + Origin: "USA", + Characteristics: &productv1.BreedCharacteristics{ + Size: "Small", + Temperament: "Curious", + Lifespan: "14-16 years", + }, + }, + }, + }, + } + } else { + volume := int32(7) + if includeDetails { + volume = int32((i + 1) * 10) + } + animal = &productv1.Animal{ + Instance: &productv1.Animal_Dog{ + Dog: &productv1.Dog{ + Id: fmt.Sprintf("mascot-dog-%s", ctx.GetId()), + Name: fmt.Sprintf("MascotDog for %s", ctx.GetName()), + Kind: "Dog", + BarkVolume: volume, + Owner: &productv1.Owner{ + Id: fmt.Sprintf("owner-dog-%s", ctx.GetId()), + Name: fmt.Sprintf("OwnerDog for %s", ctx.GetName()), + Contact: &productv1.ContactInfo{ + Email: "owner-dog@example.com", + Phone: "123-456-7890", + Address: &productv1.Address{ + Street: "123 Main St", + City: "Anytown", + Country: "USA", + ZipCode: "12345", + }, + }, + }, + Breed: &productv1.DogBreed{ + Id: fmt.Sprintf("breed-dog-%s", ctx.GetId()), + Name: fmt.Sprintf("BreedDog for %s", ctx.GetName()), + Origin: "USA", + Characteristics: &productv1.BreedCharacteristics{ + Size: "Medium", + Temperament: "Loyal", + Lifespan: "10-12 years", + }, + }, + }, + }, + } + } + + results = append(results, &productv1.ResolveProductMascotRecommendationResult{ + MascotRecommendation: animal, + }) + } + + return &productv1.ResolveProductMascotRecommendationResponse{ + Result: results, + }, nil +} + +// ResolveProductProductDetails implements productv1.ProductServiceServer. +func (s *MockService) ResolveProductProductDetails(_ context.Context, req *productv1.ResolveProductProductDetailsRequest) (*productv1.ResolveProductProductDetailsResponse, error) { + results := make([]*productv1.ResolveProductProductDetailsResult, 0, len(req.GetContext())) + + includeExtended := false + if req.GetFieldArgs() != nil { + includeExtended = req.GetFieldArgs().GetIncludeExtended() + } + + for i, ctx := range req.GetContext() { + // Create recommended pet (alternate between Cat and Dog) + var pet *productv1.Animal + if i%2 == 0 { + pet = &productv1.Animal{ + Instance: &productv1.Animal_Cat{ + Cat: &productv1.Cat{ + Id: fmt.Sprintf("details-cat-%s", ctx.GetId()), + Name: fmt.Sprintf("RecommendedCat for %s", ctx.GetName()), + Kind: "Cat", + MeowVolume: int32((i + 1) * 6), + Owner: &productv1.Owner{ + Id: fmt.Sprintf("owner-details-cat-%s", ctx.GetId()), + Name: fmt.Sprintf("OwnerDetailsCat for %s", ctx.GetName()), + Contact: &productv1.ContactInfo{ + Email: "owner-details-cat@example.com", + Phone: "555-111-2222", + Address: &productv1.Address{ + Street: "456 Oak Ave", + City: "Springfield", + Country: "USA", + ZipCode: "54321", + }, + }, + }, + Breed: &productv1.CatBreed{ + Id: fmt.Sprintf("breed-details-cat-%s", ctx.GetId()), + Name: fmt.Sprintf("BreedDetailsCat for %s", ctx.GetName()), + Origin: "France", + Characteristics: &productv1.BreedCharacteristics{ + Size: "Medium", + Temperament: "Friendly", + Lifespan: "12-15 years", + }, + }, + }, + }, + } + } else { + pet = &productv1.Animal{ + Instance: &productv1.Animal_Dog{ + Dog: &productv1.Dog{ + Id: fmt.Sprintf("details-dog-%s", ctx.GetId()), + Name: fmt.Sprintf("RecommendedDog for %s", ctx.GetName()), + Kind: "Dog", + BarkVolume: int32((i + 1) * 9), + Owner: &productv1.Owner{ + Id: fmt.Sprintf("owner-details-dog-%s", ctx.GetId()), + Name: fmt.Sprintf("OwnerDetailsDog for %s", ctx.GetName()), + Contact: &productv1.ContactInfo{ + Email: "owner-details-dog@example.com", + Phone: "555-333-4444", + Address: &productv1.Address{ + Street: "789 Elm St", + City: "Riverside", + Country: "USA", + ZipCode: "67890", + }, + }, + }, + Breed: &productv1.DogBreed{ + Id: fmt.Sprintf("breed-details-dog-%s", ctx.GetId()), + Name: fmt.Sprintf("BreedDetailsDog for %s", ctx.GetName()), + Origin: "Germany", + Characteristics: &productv1.BreedCharacteristics{ + Size: "Large", + Temperament: "Loyal", + Lifespan: "10-12 years", + }, + }, + }, + }, + } + } + + // Create review summary (alternate between success and error based on price and extended flag) + var reviewSummary *productv1.ActionResult + if includeExtended && ctx.GetPrice() > 500 { + reviewSummary = &productv1.ActionResult{ + Value: &productv1.ActionResult_ActionError{ + ActionError: &productv1.ActionError{ + Message: fmt.Sprintf("Product %s has negative reviews", ctx.GetName()), + Code: "NEGATIVE_REVIEWS", + }, + }, + } + } else { + reviewSummary = &productv1.ActionResult{ + Value: &productv1.ActionResult_ActionSuccess{ + ActionSuccess: &productv1.ActionSuccess{ + Message: fmt.Sprintf("Product %s has positive reviews", ctx.GetName()), + Timestamp: "2024-01-01T15:00:00Z", + }, + }, + } + } + + description := fmt.Sprintf("Standard details for %s", ctx.GetName()) + if includeExtended { + description = fmt.Sprintf("Extended details for %s with comprehensive information", ctx.GetName()) + } + + results = append(results, &productv1.ResolveProductProductDetailsResult{ + ProductDetails: &productv1.ProductDetails{ + Id: fmt.Sprintf("details-%s-%d", ctx.GetId(), i), + Description: description, + ReviewSummary: reviewSummary, + RecommendedPet: pet, + }, + }) + } + + return &productv1.ResolveProductProductDetailsResponse{ + Result: results, + }, nil +} + +// ResolveProductStockStatus implements productv1.ProductServiceServer. +func (s *MockService) ResolveProductStockStatus(_ context.Context, req *productv1.ResolveProductStockStatusRequest) (*productv1.ResolveProductStockStatusResponse, error) { + results := make([]*productv1.ResolveProductStockStatusResult, 0, len(req.GetContext())) + + checkAvailability := false + if req.GetFieldArgs() != nil { + checkAvailability = req.GetFieldArgs().GetCheckAvailability() + } + + for i, ctx := range req.GetContext() { + var stockStatus *productv1.ActionResult + + // If checking availability and price is high, return out of stock error + if checkAvailability && ctx.GetPrice() > 300 && i%2 == 0 { + stockStatus = &productv1.ActionResult{ + Value: &productv1.ActionResult_ActionError{ + ActionError: &productv1.ActionError{ + Message: fmt.Sprintf("Product %s is currently out of stock", ctx.GetName()), + Code: "OUT_OF_STOCK", + }, + }, + } + } else { + stockStatus = &productv1.ActionResult{ + Value: &productv1.ActionResult_ActionSuccess{ + ActionSuccess: &productv1.ActionSuccess{ + Message: fmt.Sprintf("Product %s is in stock and available", ctx.GetName()), + Timestamp: "2024-01-01T10:00:00Z", + }, + }, + } + } + + results = append(results, &productv1.ResolveProductStockStatusResult{ + StockStatus: stockStatus, + }) + } + + return &productv1.ResolveProductStockStatusResponse{ + Result: results, + }, nil +} + +// ResolveTestContainerDetails implements productv1.ProductServiceServer. +func (s *MockService) ResolveTestContainerDetails(_ context.Context, req *productv1.ResolveTestContainerDetailsRequest) (*productv1.ResolveTestContainerDetailsResponse, error) { + results := make([]*productv1.ResolveTestContainerDetailsResult, 0, len(req.GetContext())) + + includeExtended := false + if req.GetFieldArgs() != nil { + includeExtended = req.GetFieldArgs().GetIncludeExtended() + } + + for i, ctx := range req.GetContext() { + // Alternate between Cat and Dog for the pet field (Animal interface) + var pet *productv1.Animal + if i%2 == 0 { + pet = &productv1.Animal{ + Instance: &productv1.Animal_Cat{ + Cat: &productv1.Cat{ + Id: fmt.Sprintf("test-cat-%s", ctx.GetId()), + Name: fmt.Sprintf("TestCat-%s", ctx.GetName()), + Kind: "Cat", + MeowVolume: int32((i + 1) * 5), + Owner: &productv1.Owner{ + Id: fmt.Sprintf("owner-test-cat-%s", ctx.GetId()), + Name: fmt.Sprintf("OwnerTestCat for %s", ctx.GetName()), + Contact: &productv1.ContactInfo{ + Email: "owner-test-cat@example.com", + Phone: "555-555-5555", + Address: &productv1.Address{ + Street: "321 Pine Rd", + City: "Lakeside", + Country: "Canada", + ZipCode: "A1B2C3", + }, + }, + }, + Breed: &productv1.CatBreed{ + Id: fmt.Sprintf("breed-test-cat-%s", ctx.GetId()), + Name: fmt.Sprintf("BreedTestCat for %s", ctx.GetName()), + Origin: "Egypt", + Characteristics: &productv1.BreedCharacteristics{ + Size: "Small", + Temperament: "Curious", + Lifespan: "14-16 years", + }, + }, + }, + }, + } + } else { + pet = &productv1.Animal{ + Instance: &productv1.Animal_Dog{ + Dog: &productv1.Dog{ + Id: fmt.Sprintf("test-dog-%s", ctx.GetId()), + Name: fmt.Sprintf("TestDog-%s", ctx.GetName()), + Kind: "Dog", + BarkVolume: int32((i + 1) * 7), + Owner: &productv1.Owner{ + Id: fmt.Sprintf("owner-test-dog-%s", ctx.GetId()), + Name: fmt.Sprintf("OwnerTestDog for %s", ctx.GetName()), + Contact: &productv1.ContactInfo{ + Email: "owner-test-dog@example.com", + Phone: "555-666-7777", + Address: &productv1.Address{ + Street: "654 Birch Ln", + City: "Mountain View", + Country: "Canada", + ZipCode: "X9Y8Z7", + }, + }, + }, + Breed: &productv1.DogBreed{ + Id: fmt.Sprintf("breed-test-dog-%s", ctx.GetId()), + Name: fmt.Sprintf("BreedTestDog for %s", ctx.GetName()), + Origin: "England", + Characteristics: &productv1.BreedCharacteristics{ + Size: "Medium", + Temperament: "Energetic", + Lifespan: "11-13 years", + }, + }, + }, + }, + } + } + + // Alternate between ActionSuccess and ActionError for the status field (ActionResult union) + var status *productv1.ActionResult + if includeExtended && i%3 == 0 { + // Return error status for extended mode on certain items + status = &productv1.ActionResult{ + Value: &productv1.ActionResult_ActionError{ + ActionError: &productv1.ActionError{ + Message: fmt.Sprintf("Extended check failed for %s", ctx.GetName()), + Code: "EXTENDED_CHECK_FAILED", + }, + }, + } + } else { + // Return success status + status = &productv1.ActionResult{ + Value: &productv1.ActionResult_ActionSuccess{ + ActionSuccess: &productv1.ActionSuccess{ + Message: fmt.Sprintf("TestContainer %s details loaded successfully", ctx.GetName()), + Timestamp: "2024-01-01T12:00:00Z", + }, + }, + } + } + + summary := fmt.Sprintf("Summary for %s", ctx.GetName()) + if includeExtended { + summary = fmt.Sprintf("Extended summary for %s with additional details", ctx.GetName()) + } + + results = append(results, &productv1.ResolveTestContainerDetailsResult{ + Details: &productv1.TestDetails{ + Id: fmt.Sprintf("details-%s-%d", ctx.GetId(), i), + Summary: summary, + Pet: pet, + Status: status, + }, + }) + } + + return &productv1.ResolveTestContainerDetailsResponse{ + Result: results, + }, nil +} + +// ResolveCategoryMetricsNormalizedScore implements productv1.ProductServiceServer. +func (s *MockService) ResolveCategoryMetricsNormalizedScore(_ context.Context, req *productv1.ResolveCategoryMetricsNormalizedScoreRequest) (*productv1.ResolveCategoryMetricsNormalizedScoreResponse, error) { + results := make([]*productv1.ResolveCategoryMetricsNormalizedScoreResult, 0, len(req.GetContext())) + + baseline := req.GetFieldArgs().GetBaseline() + if baseline == 0 { + baseline = 1.0 // Avoid division by zero + } + + for _, ctx := range req.GetContext() { + // Calculate normalized score: (value / baseline) * 100 + // This gives a percentage relative to the baseline + normalizedScore := (ctx.GetValue() / baseline) * 100.0 + + results = append(results, &productv1.ResolveCategoryMetricsNormalizedScoreResult{ + NormalizedScore: normalizedScore, + }) + } + + resp := &productv1.ResolveCategoryMetricsNormalizedScoreResponse{ + Result: results, + } + + return resp, nil +} + +// ResolveCategoryMascot implements productv1.ProductServiceServer. +func (s *MockService) ResolveCategoryMascot(_ context.Context, req *productv1.ResolveCategoryMascotRequest) (*productv1.ResolveCategoryMascotResponse, error) { + results := make([]*productv1.ResolveCategoryMascotResult, 0, len(req.GetContext())) + + includeVolume := false + if req.GetFieldArgs() != nil { + includeVolume = req.GetFieldArgs().GetIncludeVolume() + } + + for i, ctx := range req.GetContext() { + // Return nil for certain categories to test optional return + if ctx.GetKind() == productv1.CategoryKind_CATEGORY_KIND_OTHER { + results = append(results, &productv1.ResolveCategoryMascotResult{ + Mascot: nil, + }) + } else { + // Alternate between Cat and Dog based on category kind + var animal *productv1.Animal + if ctx.GetKind() == productv1.CategoryKind_CATEGORY_KIND_BOOK || ctx.GetKind() == productv1.CategoryKind_CATEGORY_KIND_ELECTRONICS { + volume := int32(0) + if includeVolume { + volume = int32(i*10 + 5) + } + animal = &productv1.Animal{ + Instance: &productv1.Animal_Cat{ + Cat: &productv1.Cat{ + Id: fmt.Sprintf("cat-mascot-%s", ctx.GetId()), + Name: fmt.Sprintf("Whiskers-%s", ctx.GetId()), + Kind: "Cat", + MeowVolume: volume, + Owner: &productv1.Owner{ + Id: fmt.Sprintf("owner-cat-mascot-%s", ctx.GetId()), + Name: fmt.Sprintf("OwnerCatMascot for %s", ctx.GetId()), + Contact: &productv1.ContactInfo{ + Email: "owner-cat-mascot@example.com", + Phone: "555-777-8888", + Address: &productv1.Address{ + Street: "111 Maple Dr", + City: "Booktown", + Country: "USA", + ZipCode: "11111", + }, + }, + }, + Breed: &productv1.CatBreed{ + Id: fmt.Sprintf("breed-cat-mascot-%s", ctx.GetId()), + Name: fmt.Sprintf("BreedCatMascot for %s", ctx.GetId()), + Origin: "Scotland", + Characteristics: &productv1.BreedCharacteristics{ + Size: "Large", + Temperament: "Gentle", + Lifespan: "13-17 years", + }, + }, + }, + }, + } + } else { + volume := int32(0) + if includeVolume { + volume = int32(i*10 + 10) + } + animal = &productv1.Animal{ + Instance: &productv1.Animal_Dog{ + Dog: &productv1.Dog{ + Id: fmt.Sprintf("dog-mascot-%s", ctx.GetId()), + Name: fmt.Sprintf("Buddy-%s", ctx.GetId()), + Kind: "Dog", + BarkVolume: volume, + Owner: &productv1.Owner{ + Id: fmt.Sprintf("owner-dog-mascot-%s", ctx.GetId()), + Name: fmt.Sprintf("OwnerDogMascot for %s", ctx.GetId()), + Contact: &productv1.ContactInfo{ + Email: "owner-dog-mascot@example.com", + Phone: "555-888-9999", + Address: &productv1.Address{ + Street: "222 Cedar Ct", + City: "Mascotville", + Country: "USA", + ZipCode: "22222", + }, + }, + }, + Breed: &productv1.DogBreed{ + Id: fmt.Sprintf("breed-dog-mascot-%s", ctx.GetId()), + Name: fmt.Sprintf("BreedDogMascot for %s", ctx.GetId()), + Origin: "Australia", + Characteristics: &productv1.BreedCharacteristics{ + Size: "Medium", + Temperament: "Playful", + Lifespan: "10-14 years", + }, + }, + }, + }, + } + } + results = append(results, &productv1.ResolveCategoryMascotResult{ + Mascot: animal, + }) + } + } + + resp := &productv1.ResolveCategoryMascotResponse{ + Result: results, + } + + return resp, nil +} + +// ResolveCategoryCategoryStatus implements productv1.ProductServiceServer. +func (s *MockService) ResolveCategoryCategoryStatus(_ context.Context, req *productv1.ResolveCategoryCategoryStatusRequest) (*productv1.ResolveCategoryCategoryStatusResponse, error) { + results := make([]*productv1.ResolveCategoryCategoryStatusResult, 0, len(req.GetContext())) + + checkHealth := false + if req.GetFieldArgs() != nil { + checkHealth = req.GetFieldArgs().GetCheckHealth() + } + + for i, ctx := range req.GetContext() { + var actionResult *productv1.ActionResult + + if checkHealth && i%3 == 0 { + // Return error status for health check failures + actionResult = &productv1.ActionResult{ + Value: &productv1.ActionResult_ActionError{ + ActionError: &productv1.ActionError{ + Message: fmt.Sprintf("Health check failed for category %s", ctx.GetName()), + Code: "HEALTH_CHECK_FAILED", + }, + }, + } + } else { + // Return success status + actionResult = &productv1.ActionResult{ + Value: &productv1.ActionResult_ActionSuccess{ + ActionSuccess: &productv1.ActionSuccess{ + Message: fmt.Sprintf("Category %s is healthy", ctx.GetName()), + Timestamp: "2024-01-01T00:00:00Z", + }, + }, + } + } + + results = append(results, &productv1.ResolveCategoryCategoryStatusResult{ + CategoryStatus: actionResult, + }) + } + + resp := &productv1.ResolveCategoryCategoryStatusResponse{ + Result: results, + } + + return resp, nil +} + +// ResolveProductRecommendedCategory implements productv1.ProductServiceServer. +func (s *MockService) ResolveProductRecommendedCategory(_ context.Context, req *productv1.ResolveProductRecommendedCategoryRequest) (*productv1.ResolveProductRecommendedCategoryResponse, error) { + results := make([]*productv1.ResolveProductRecommendedCategoryResult, 0, len(req.GetContext())) + + maxPrice := int32(0) + if req.GetFieldArgs() != nil { + maxPrice = req.GetFieldArgs().GetMaxPrice() + } + + for _, ctx := range req.GetContext() { + // Return nil for products with high price to test optional return + if maxPrice > 0 && ctx.GetPrice() > float64(maxPrice) { + results = append(results, &productv1.ResolveProductRecommendedCategoryResult{ + RecommendedCategory: nil, + }) + } else { + // Create a recommended category based on product context + var categoryKind productv1.CategoryKind + if ctx.GetPrice() < 50 { + categoryKind = productv1.CategoryKind_CATEGORY_KIND_BOOK + } else if ctx.GetPrice() < 200 { + categoryKind = productv1.CategoryKind_CATEGORY_KIND_ELECTRONICS + } else { + categoryKind = productv1.CategoryKind_CATEGORY_KIND_FURNITURE + } + + results = append(results, &productv1.ResolveProductRecommendedCategoryResult{ + RecommendedCategory: &productv1.Category{ + Id: fmt.Sprintf("recommended-cat-%s", ctx.GetId()), + Name: fmt.Sprintf("Recommended for %s", ctx.GetName()), + Kind: categoryKind, + Subcategories: createSubcategories(fmt.Sprintf("recommended-cat-%s", ctx.GetId()), categoryKind, 2), + }, + }) + } + } + + resp := &productv1.ResolveProductRecommendedCategoryResponse{ + Result: results, + } + + return resp, nil +} + +// ResolveProductShippingEstimate implements productv1.ProductServiceServer. +func (s *MockService) ResolveProductShippingEstimate(_ context.Context, req *productv1.ResolveProductShippingEstimateRequest) (*productv1.ResolveProductShippingEstimateResponse, error) { + results := make([]*productv1.ResolveProductShippingEstimateResult, 0, len(req.GetContext())) + + for _, ctx := range req.GetContext() { + // Base shipping cost calculation + baseCost := ctx.GetPrice() * 0.1 // 10% of product price + + // Add weight-based cost if input provided + if req.GetFieldArgs() != nil && req.GetFieldArgs().GetInput() != nil { + input := req.GetFieldArgs().GetInput() + + // Add weight cost + weightCost := float64(input.GetWeight()) * 2.5 + baseCost += weightCost + + // Add expedited shipping cost + if input.GetExpedited() != nil && input.GetExpedited().GetValue() { + baseCost *= 1.5 // 50% surcharge for expedited + } + + // Add destination-based cost + destination := input.GetDestination() + switch destination { + case productv1.ShippingDestination_SHIPPING_DESTINATION_INTERNATIONAL: + baseCost += 25.0 + case productv1.ShippingDestination_SHIPPING_DESTINATION_EXPRESS: + baseCost += 10.0 + case productv1.ShippingDestination_SHIPPING_DESTINATION_DOMESTIC: + // No additional cost for domestic shipping + } + } + + results = append(results, &productv1.ResolveProductShippingEstimateResult{ + ShippingEstimate: baseCost, + }) + } + + resp := &productv1.ResolveProductShippingEstimateResponse{ + Result: results, + } + + return resp, nil +} + +// ResolveCategoryCategoryMetrics implements productv1.ProductServiceServer. +func (s *MockService) ResolveCategoryCategoryMetrics(_ context.Context, req *productv1.ResolveCategoryCategoryMetricsRequest) (*productv1.ResolveCategoryCategoryMetricsResponse, error) { + results := make([]*productv1.ResolveCategoryCategoryMetricsResult, 0, len(req.GetContext())) + + metricType := "" + if req.GetFieldArgs() != nil { + metricType = req.GetFieldArgs().GetMetricType() + } + + for i, ctx := range req.GetContext() { + // Return nil for certain metric types to test optional return + if metricType == "unavailable" { + results = append(results, &productv1.ResolveCategoryCategoryMetricsResult{ + CategoryMetrics: nil, + }) + } else { + results = append(results, &productv1.ResolveCategoryCategoryMetricsResult{ + CategoryMetrics: &productv1.CategoryMetrics{ + Id: fmt.Sprintf("metrics-%s-%d", ctx.GetId(), i), + MetricType: metricType, + Value: float64(i*25 + 100), // Different values based on index + Timestamp: "2024-01-01T00:00:00Z", + CategoryId: ctx.GetId(), + }, + }) + } + } + + resp := &productv1.ResolveCategoryCategoryMetricsResponse{ + Result: results, + } + + return resp, nil +} + +// ResolveCategoryPopularityScore implements productv1.ProductServiceServer. +func (s *MockService) ResolveCategoryPopularityScore(_ context.Context, req *productv1.ResolveCategoryPopularityScoreRequest) (*productv1.ResolveCategoryPopularityScoreResponse, error) { + results := make([]*productv1.ResolveCategoryPopularityScoreResult, 0, len(req.GetContext())) + + threshold := req.GetFieldArgs().GetThreshold() + + baseScore := 50 + for range req.GetContext() { + if int(threshold.GetValue()) > baseScore { + results = append(results, &productv1.ResolveCategoryPopularityScoreResult{ + PopularityScore: nil, + }) + } else { + results = append(results, &productv1.ResolveCategoryPopularityScoreResult{ + PopularityScore: &wrapperspb.Int32Value{Value: int32(baseScore)}, + }) + } + } + + resp := &productv1.ResolveCategoryPopularityScoreResponse{ + Result: results, + } + + return resp, nil +} + +// ResolveSubcategoryItemCount implements productv1.ProductServiceServer. +func (s *MockService) ResolveSubcategoryItemCount(_ context.Context, req *productv1.ResolveSubcategoryItemCountRequest) (*productv1.ResolveSubcategoryItemCountResponse, error) { + results := make([]*productv1.ResolveSubcategoryItemCountResult, 0, len(req.GetContext())) + for i := range req.GetContext() { + results = append(results, &productv1.ResolveSubcategoryItemCountResult{ + ItemCount: int32(i * 10), // Different multiplier to distinguish from productCount + }) + } + + resp := &productv1.ResolveSubcategoryItemCountResponse{ + Result: results, + } + + return resp, nil +} + +// ResolveCategoryProductCount implements productv1.ProductServiceServer. +func (s *MockService) ResolveCategoryProductCount(_ context.Context, req *productv1.ResolveCategoryProductCountRequest) (*productv1.ResolveCategoryProductCountResponse, error) { + results := make([]*productv1.ResolveCategoryProductCountResult, 0, len(req.GetContext())) + for i := range req.GetContext() { + results = append(results, &productv1.ResolveCategoryProductCountResult{ + ProductCount: int32(i), + }) + } + + resp := &productv1.ResolveCategoryProductCountResponse{ + Result: results, + } + + return resp, nil +} diff --git a/v2/pkg/grpctest/product.proto b/v2/pkg/grpctest/product.proto index ac6ec65b2..855c1cdde 100644 --- a/v2/pkg/grpctest/product.proto +++ b/v2/pkg/grpctest/product.proto @@ -51,16 +51,25 @@ service ProductService { rpc QueryRandomSearchResult(QueryRandomSearchResultRequest) returns (QueryRandomSearchResultResponse) {} rpc QueryRecursiveType(QueryRecursiveTypeRequest) returns (QueryRecursiveTypeResponse) {} rpc QuerySearch(QuerySearchRequest) returns (QuerySearchResponse) {} + rpc QueryTestContainer(QueryTestContainerRequest) returns (QueryTestContainerResponse) {} + rpc QueryTestContainers(QueryTestContainersRequest) returns (QueryTestContainersResponse) {} rpc QueryTypeFilterWithArguments(QueryTypeFilterWithArgumentsRequest) returns (QueryTypeFilterWithArgumentsResponse) {} rpc QueryTypeWithMultipleFilterFields(QueryTypeWithMultipleFilterFieldsRequest) returns (QueryTypeWithMultipleFilterFieldsResponse) {} rpc QueryUser(QueryUserRequest) returns (QueryUserResponse) {} rpc QueryUsers(QueryUsersRequest) returns (QueryUsersResponse) {} rpc ResolveCategoryCategoryMetrics(ResolveCategoryCategoryMetricsRequest) returns (ResolveCategoryCategoryMetricsResponse) {} + rpc ResolveCategoryCategoryStatus(ResolveCategoryCategoryStatusRequest) returns (ResolveCategoryCategoryStatusResponse) {} + rpc ResolveCategoryMascot(ResolveCategoryMascotRequest) returns (ResolveCategoryMascotResponse) {} + rpc ResolveCategoryMetricsNormalizedScore(ResolveCategoryMetricsNormalizedScoreRequest) returns (ResolveCategoryMetricsNormalizedScoreResponse) {} rpc ResolveCategoryPopularityScore(ResolveCategoryPopularityScoreRequest) returns (ResolveCategoryPopularityScoreResponse) {} rpc ResolveCategoryProductCount(ResolveCategoryProductCountRequest) returns (ResolveCategoryProductCountResponse) {} + rpc ResolveProductMascotRecommendation(ResolveProductMascotRecommendationRequest) returns (ResolveProductMascotRecommendationResponse) {} + rpc ResolveProductProductDetails(ResolveProductProductDetailsRequest) returns (ResolveProductProductDetailsResponse) {} rpc ResolveProductRecommendedCategory(ResolveProductRecommendedCategoryRequest) returns (ResolveProductRecommendedCategoryResponse) {} rpc ResolveProductShippingEstimate(ResolveProductShippingEstimateRequest) returns (ResolveProductShippingEstimateResponse) {} + rpc ResolveProductStockStatus(ResolveProductStockStatusRequest) returns (ResolveProductStockStatusResponse) {} rpc ResolveSubcategoryItemCount(ResolveSubcategoryItemCountRequest) returns (ResolveSubcategoryItemCountResponse) {} + rpc ResolveTestContainerDetails(ResolveTestContainerDetailsRequest) returns (ResolveTestContainerDetailsResponse) {} } // Wrapper message for a list of AuthorFilter. @@ -533,6 +542,21 @@ message QueryBulkSearchBlogPostsRequest { message QueryBulkSearchBlogPostsResponse { repeated BlogPost bulk_search_blog_posts = 1; } +// Request message for testContainer operation. +message QueryTestContainerRequest { + string id = 1; +} +// Response message for testContainer operation. +message QueryTestContainerResponse { + TestContainer test_container = 1; +} +// Request message for testContainers operation. +message QueryTestContainersRequest { +} +// Response message for testContainers operation. +message QueryTestContainersResponse { + repeated TestContainer test_containers = 1; +} // Request message for createUser operation. message MutationCreateUserRequest { UserInput input = 1; @@ -681,6 +705,80 @@ message ResolveProductRecommendedCategoryResponse { repeated ResolveProductRecommendedCategoryResult result = 1; } +message ResolveProductMascotRecommendationArgs { + bool include_details = 1; +} + +message ResolveProductMascotRecommendationContext { + string id = 1; + string name = 2; +} + +message ResolveProductMascotRecommendationRequest { + // context provides the resolver context for the field mascotRecommendation of type Product. + repeated ResolveProductMascotRecommendationContext context = 1; + // field_args provides the arguments for the resolver field mascotRecommendation of type Product. + ResolveProductMascotRecommendationArgs field_args = 2; +} + +message ResolveProductMascotRecommendationResult { + Animal mascot_recommendation = 1; +} + +message ResolveProductMascotRecommendationResponse { + repeated ResolveProductMascotRecommendationResult result = 1; +} + +message ResolveProductStockStatusArgs { + bool check_availability = 1; +} + +message ResolveProductStockStatusContext { + string id = 1; + string name = 2; + double price = 3; +} + +message ResolveProductStockStatusRequest { + // context provides the resolver context for the field stockStatus of type Product. + repeated ResolveProductStockStatusContext context = 1; + // field_args provides the arguments for the resolver field stockStatus of type Product. + ResolveProductStockStatusArgs field_args = 2; +} + +message ResolveProductStockStatusResult { + ActionResult stock_status = 1; +} + +message ResolveProductStockStatusResponse { + repeated ResolveProductStockStatusResult result = 1; +} + +message ResolveProductProductDetailsArgs { + bool include_extended = 1; +} + +message ResolveProductProductDetailsContext { + string id = 1; + string name = 2; + double price = 3; +} + +message ResolveProductProductDetailsRequest { + // context provides the resolver context for the field productDetails of type Product. + repeated ResolveProductProductDetailsContext context = 1; + // field_args provides the arguments for the resolver field productDetails of type Product. + ResolveProductProductDetailsArgs field_args = 2; +} + +message ResolveProductProductDetailsResult { + ProductDetails product_details = 1; +} + +message ResolveProductProductDetailsResponse { + repeated ResolveProductProductDetailsResult result = 1; +} + message ResolveCategoryProductCountArgs { ProductCountFilter filters = 1; } @@ -752,6 +850,54 @@ message ResolveCategoryCategoryMetricsResponse { repeated ResolveCategoryCategoryMetricsResult result = 1; } +message ResolveCategoryMascotArgs { + bool include_volume = 1; +} + +message ResolveCategoryMascotContext { + string id = 1; + CategoryKind kind = 2; +} + +message ResolveCategoryMascotRequest { + // context provides the resolver context for the field mascot of type Category. + repeated ResolveCategoryMascotContext context = 1; + // field_args provides the arguments for the resolver field mascot of type Category. + ResolveCategoryMascotArgs field_args = 2; +} + +message ResolveCategoryMascotResult { + Animal mascot = 1; +} + +message ResolveCategoryMascotResponse { + repeated ResolveCategoryMascotResult result = 1; +} + +message ResolveCategoryCategoryStatusArgs { + bool check_health = 1; +} + +message ResolveCategoryCategoryStatusContext { + string id = 1; + string name = 2; +} + +message ResolveCategoryCategoryStatusRequest { + // context provides the resolver context for the field categoryStatus of type Category. + repeated ResolveCategoryCategoryStatusContext context = 1; + // field_args provides the arguments for the resolver field categoryStatus of type Category. + ResolveCategoryCategoryStatusArgs field_args = 2; +} + +message ResolveCategoryCategoryStatusResult { + ActionResult category_status = 1; +} + +message ResolveCategoryCategoryStatusResponse { + repeated ResolveCategoryCategoryStatusResult result = 1; +} + message ResolveSubcategoryItemCountArgs { SubcategoryItemFilter filters = 1; } @@ -775,6 +921,55 @@ message ResolveSubcategoryItemCountResponse { repeated ResolveSubcategoryItemCountResult result = 1; } +message ResolveCategoryMetricsNormalizedScoreArgs { + double baseline = 1; +} + +message ResolveCategoryMetricsNormalizedScoreContext { + string id = 1; + string metricType = 2; + double value = 3; +} + +message ResolveCategoryMetricsNormalizedScoreRequest { + // context provides the resolver context for the field normalizedScore of type CategoryMetrics. + repeated ResolveCategoryMetricsNormalizedScoreContext context = 1; + // field_args provides the arguments for the resolver field normalizedScore of type CategoryMetrics. + ResolveCategoryMetricsNormalizedScoreArgs field_args = 2; +} + +message ResolveCategoryMetricsNormalizedScoreResult { + double normalized_score = 1; +} + +message ResolveCategoryMetricsNormalizedScoreResponse { + repeated ResolveCategoryMetricsNormalizedScoreResult result = 1; +} + +message ResolveTestContainerDetailsArgs { + bool include_extended = 1; +} + +message ResolveTestContainerDetailsContext { + string id = 1; + string name = 2; +} + +message ResolveTestContainerDetailsRequest { + // context provides the resolver context for the field details of type TestContainer. + repeated ResolveTestContainerDetailsContext context = 1; + // field_args provides the arguments for the resolver field details of type TestContainer. + ResolveTestContainerDetailsArgs field_args = 2; +} + +message ResolveTestContainerDetailsResult { + TestDetails details = 1; +} + +message ResolveTestContainerDetailsResponse { + repeated ResolveTestContainerDetailsResult result = 1; +} + message Product { string id = 1; string name = 2; @@ -946,6 +1141,12 @@ message AuthorFilter { google.protobuf.Int32Value skill_count = 3; } +message TestContainer { + string id = 1; + string name = 2; + google.protobuf.StringValue description = 3; +} + message UserInput { string name = 1; } @@ -1004,6 +1205,13 @@ message AuthorInput { ListOfListOfUserInput project_teams = 10; } +message ProductDetails { + string id = 1; + string description = 2; + ActionResult review_summary = 3; + Animal recommended_pet = 4; +} + message NestedTypeB { string id = 1; string name = 2; @@ -1052,6 +1260,7 @@ message CategoryMetrics { double value = 3; string timestamp = 4; string category_id = 5; + Category related_category = 6; } enum CategoryKind { @@ -1067,6 +1276,8 @@ message Cat { string name = 2; string kind = 3; int32 meow_volume = 4; + Owner owner = 5; + CatBreed breed = 6; } message Dog { @@ -1074,6 +1285,47 @@ message Dog { string name = 2; string kind = 3; int32 bark_volume = 4; + Owner owner = 5; + DogBreed breed = 6; +} + +message Owner { + string id = 1; + string name = 2; + ContactInfo contact = 3; +} + +message ContactInfo { + string email = 1; + string phone = 2; + Address address = 3; +} + +message Address { + string street = 1; + string city = 2; + string country = 3; + string zip_code = 4; +} + +message CatBreed { + string id = 1; + string name = 2; + string origin = 3; + BreedCharacteristics characteristics = 4; +} + +message DogBreed { + string id = 1; + string name = 2; + string origin = 3; + BreedCharacteristics characteristics = 4; +} + +message BreedCharacteristics { + string size = 1; + string temperament = 2; + string lifespan = 3; } message ActionSuccess { @@ -1086,6 +1338,13 @@ message ActionError { string code = 2; } +message TestDetails { + string id = 1; + string summary = 2; + Animal pet = 3; + ActionResult status = 4; +} + message CategoryInput { string name = 1; CategoryKind kind = 2; diff --git a/v2/pkg/grpctest/productv1/product.pb.go b/v2/pkg/grpctest/productv1/product.pb.go index ed265f796..92c0c8187 100644 --- a/v2/pkg/grpctest/productv1/product.pb.go +++ b/v2/pkg/grpctest/productv1/product.pb.go @@ -4086,6 +4086,178 @@ func (x *QueryBulkSearchBlogPostsResponse) GetBulkSearchBlogPosts() []*BlogPost return nil } +// Request message for testContainer operation. +type QueryTestContainerRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *QueryTestContainerRequest) Reset() { + *x = QueryTestContainerRequest{} + mi := &file_product_proto_msgTypes[89] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *QueryTestContainerRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QueryTestContainerRequest) ProtoMessage() {} + +func (x *QueryTestContainerRequest) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[89] + 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 QueryTestContainerRequest.ProtoReflect.Descriptor instead. +func (*QueryTestContainerRequest) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{89} +} + +func (x *QueryTestContainerRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +// Response message for testContainer operation. +type QueryTestContainerResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + TestContainer *TestContainer `protobuf:"bytes,1,opt,name=test_container,json=testContainer,proto3" json:"test_container,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *QueryTestContainerResponse) Reset() { + *x = QueryTestContainerResponse{} + mi := &file_product_proto_msgTypes[90] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *QueryTestContainerResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QueryTestContainerResponse) ProtoMessage() {} + +func (x *QueryTestContainerResponse) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[90] + 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 QueryTestContainerResponse.ProtoReflect.Descriptor instead. +func (*QueryTestContainerResponse) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{90} +} + +func (x *QueryTestContainerResponse) GetTestContainer() *TestContainer { + if x != nil { + return x.TestContainer + } + return nil +} + +// Request message for testContainers operation. +type QueryTestContainersRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *QueryTestContainersRequest) Reset() { + *x = QueryTestContainersRequest{} + mi := &file_product_proto_msgTypes[91] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *QueryTestContainersRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QueryTestContainersRequest) ProtoMessage() {} + +func (x *QueryTestContainersRequest) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[91] + 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 QueryTestContainersRequest.ProtoReflect.Descriptor instead. +func (*QueryTestContainersRequest) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{91} +} + +// Response message for testContainers operation. +type QueryTestContainersResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + TestContainers []*TestContainer `protobuf:"bytes,1,rep,name=test_containers,json=testContainers,proto3" json:"test_containers,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *QueryTestContainersResponse) Reset() { + *x = QueryTestContainersResponse{} + mi := &file_product_proto_msgTypes[92] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *QueryTestContainersResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QueryTestContainersResponse) ProtoMessage() {} + +func (x *QueryTestContainersResponse) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[92] + 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 QueryTestContainersResponse.ProtoReflect.Descriptor instead. +func (*QueryTestContainersResponse) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{92} +} + +func (x *QueryTestContainersResponse) GetTestContainers() []*TestContainer { + if x != nil { + return x.TestContainers + } + return nil +} + // Request message for createUser operation. type MutationCreateUserRequest struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -4096,7 +4268,7 @@ type MutationCreateUserRequest struct { func (x *MutationCreateUserRequest) Reset() { *x = MutationCreateUserRequest{} - mi := &file_product_proto_msgTypes[89] + mi := &file_product_proto_msgTypes[93] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4108,7 +4280,7 @@ func (x *MutationCreateUserRequest) String() string { func (*MutationCreateUserRequest) ProtoMessage() {} func (x *MutationCreateUserRequest) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[89] + mi := &file_product_proto_msgTypes[93] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4121,7 +4293,7 @@ func (x *MutationCreateUserRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MutationCreateUserRequest.ProtoReflect.Descriptor instead. func (*MutationCreateUserRequest) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{89} + return file_product_proto_rawDescGZIP(), []int{93} } func (x *MutationCreateUserRequest) GetInput() *UserInput { @@ -4141,7 +4313,7 @@ type MutationCreateUserResponse struct { func (x *MutationCreateUserResponse) Reset() { *x = MutationCreateUserResponse{} - mi := &file_product_proto_msgTypes[90] + mi := &file_product_proto_msgTypes[94] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4153,7 +4325,7 @@ func (x *MutationCreateUserResponse) String() string { func (*MutationCreateUserResponse) ProtoMessage() {} func (x *MutationCreateUserResponse) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[90] + mi := &file_product_proto_msgTypes[94] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4166,7 +4338,7 @@ func (x *MutationCreateUserResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use MutationCreateUserResponse.ProtoReflect.Descriptor instead. func (*MutationCreateUserResponse) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{90} + return file_product_proto_rawDescGZIP(), []int{94} } func (x *MutationCreateUserResponse) GetCreateUser() *User { @@ -4186,7 +4358,7 @@ type MutationPerformActionRequest struct { func (x *MutationPerformActionRequest) Reset() { *x = MutationPerformActionRequest{} - mi := &file_product_proto_msgTypes[91] + mi := &file_product_proto_msgTypes[95] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4198,7 +4370,7 @@ func (x *MutationPerformActionRequest) String() string { func (*MutationPerformActionRequest) ProtoMessage() {} func (x *MutationPerformActionRequest) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[91] + mi := &file_product_proto_msgTypes[95] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4211,7 +4383,7 @@ func (x *MutationPerformActionRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MutationPerformActionRequest.ProtoReflect.Descriptor instead. func (*MutationPerformActionRequest) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{91} + return file_product_proto_rawDescGZIP(), []int{95} } func (x *MutationPerformActionRequest) GetInput() *ActionInput { @@ -4231,7 +4403,7 @@ type MutationPerformActionResponse struct { func (x *MutationPerformActionResponse) Reset() { *x = MutationPerformActionResponse{} - mi := &file_product_proto_msgTypes[92] + mi := &file_product_proto_msgTypes[96] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4243,7 +4415,7 @@ func (x *MutationPerformActionResponse) String() string { func (*MutationPerformActionResponse) ProtoMessage() {} func (x *MutationPerformActionResponse) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[92] + mi := &file_product_proto_msgTypes[96] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4256,7 +4428,7 @@ func (x *MutationPerformActionResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use MutationPerformActionResponse.ProtoReflect.Descriptor instead. func (*MutationPerformActionResponse) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{92} + return file_product_proto_rawDescGZIP(), []int{96} } func (x *MutationPerformActionResponse) GetPerformAction() *ActionResult { @@ -4276,7 +4448,7 @@ type MutationCreateNullableFieldsTypeRequest struct { func (x *MutationCreateNullableFieldsTypeRequest) Reset() { *x = MutationCreateNullableFieldsTypeRequest{} - mi := &file_product_proto_msgTypes[93] + mi := &file_product_proto_msgTypes[97] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4288,7 +4460,7 @@ func (x *MutationCreateNullableFieldsTypeRequest) String() string { func (*MutationCreateNullableFieldsTypeRequest) ProtoMessage() {} func (x *MutationCreateNullableFieldsTypeRequest) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[93] + mi := &file_product_proto_msgTypes[97] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4301,7 +4473,7 @@ func (x *MutationCreateNullableFieldsTypeRequest) ProtoReflect() protoreflect.Me // Deprecated: Use MutationCreateNullableFieldsTypeRequest.ProtoReflect.Descriptor instead. func (*MutationCreateNullableFieldsTypeRequest) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{93} + return file_product_proto_rawDescGZIP(), []int{97} } func (x *MutationCreateNullableFieldsTypeRequest) GetInput() *NullableFieldsInput { @@ -4321,7 +4493,7 @@ type MutationCreateNullableFieldsTypeResponse struct { func (x *MutationCreateNullableFieldsTypeResponse) Reset() { *x = MutationCreateNullableFieldsTypeResponse{} - mi := &file_product_proto_msgTypes[94] + mi := &file_product_proto_msgTypes[98] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4333,7 +4505,7 @@ func (x *MutationCreateNullableFieldsTypeResponse) String() string { func (*MutationCreateNullableFieldsTypeResponse) ProtoMessage() {} func (x *MutationCreateNullableFieldsTypeResponse) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[94] + mi := &file_product_proto_msgTypes[98] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4346,7 +4518,7 @@ func (x *MutationCreateNullableFieldsTypeResponse) ProtoReflect() protoreflect.M // Deprecated: Use MutationCreateNullableFieldsTypeResponse.ProtoReflect.Descriptor instead. func (*MutationCreateNullableFieldsTypeResponse) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{94} + return file_product_proto_rawDescGZIP(), []int{98} } func (x *MutationCreateNullableFieldsTypeResponse) GetCreateNullableFieldsType() *NullableFieldsType { @@ -4367,7 +4539,7 @@ type MutationUpdateNullableFieldsTypeRequest struct { func (x *MutationUpdateNullableFieldsTypeRequest) Reset() { *x = MutationUpdateNullableFieldsTypeRequest{} - mi := &file_product_proto_msgTypes[95] + mi := &file_product_proto_msgTypes[99] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4379,7 +4551,7 @@ func (x *MutationUpdateNullableFieldsTypeRequest) String() string { func (*MutationUpdateNullableFieldsTypeRequest) ProtoMessage() {} func (x *MutationUpdateNullableFieldsTypeRequest) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[95] + mi := &file_product_proto_msgTypes[99] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4392,7 +4564,7 @@ func (x *MutationUpdateNullableFieldsTypeRequest) ProtoReflect() protoreflect.Me // Deprecated: Use MutationUpdateNullableFieldsTypeRequest.ProtoReflect.Descriptor instead. func (*MutationUpdateNullableFieldsTypeRequest) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{95} + return file_product_proto_rawDescGZIP(), []int{99} } func (x *MutationUpdateNullableFieldsTypeRequest) GetId() string { @@ -4419,7 +4591,7 @@ type MutationUpdateNullableFieldsTypeResponse struct { func (x *MutationUpdateNullableFieldsTypeResponse) Reset() { *x = MutationUpdateNullableFieldsTypeResponse{} - mi := &file_product_proto_msgTypes[96] + mi := &file_product_proto_msgTypes[100] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4431,7 +4603,7 @@ func (x *MutationUpdateNullableFieldsTypeResponse) String() string { func (*MutationUpdateNullableFieldsTypeResponse) ProtoMessage() {} func (x *MutationUpdateNullableFieldsTypeResponse) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[96] + mi := &file_product_proto_msgTypes[100] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4444,7 +4616,7 @@ func (x *MutationUpdateNullableFieldsTypeResponse) ProtoReflect() protoreflect.M // Deprecated: Use MutationUpdateNullableFieldsTypeResponse.ProtoReflect.Descriptor instead. func (*MutationUpdateNullableFieldsTypeResponse) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{96} + return file_product_proto_rawDescGZIP(), []int{100} } func (x *MutationUpdateNullableFieldsTypeResponse) GetUpdateNullableFieldsType() *NullableFieldsType { @@ -4464,7 +4636,7 @@ type MutationCreateBlogPostRequest struct { func (x *MutationCreateBlogPostRequest) Reset() { *x = MutationCreateBlogPostRequest{} - mi := &file_product_proto_msgTypes[97] + mi := &file_product_proto_msgTypes[101] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4476,7 +4648,7 @@ func (x *MutationCreateBlogPostRequest) String() string { func (*MutationCreateBlogPostRequest) ProtoMessage() {} func (x *MutationCreateBlogPostRequest) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[97] + mi := &file_product_proto_msgTypes[101] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4489,7 +4661,7 @@ func (x *MutationCreateBlogPostRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MutationCreateBlogPostRequest.ProtoReflect.Descriptor instead. func (*MutationCreateBlogPostRequest) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{97} + return file_product_proto_rawDescGZIP(), []int{101} } func (x *MutationCreateBlogPostRequest) GetInput() *BlogPostInput { @@ -4509,7 +4681,7 @@ type MutationCreateBlogPostResponse struct { func (x *MutationCreateBlogPostResponse) Reset() { *x = MutationCreateBlogPostResponse{} - mi := &file_product_proto_msgTypes[98] + mi := &file_product_proto_msgTypes[102] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4521,7 +4693,7 @@ func (x *MutationCreateBlogPostResponse) String() string { func (*MutationCreateBlogPostResponse) ProtoMessage() {} func (x *MutationCreateBlogPostResponse) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[98] + mi := &file_product_proto_msgTypes[102] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4534,7 +4706,7 @@ func (x *MutationCreateBlogPostResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use MutationCreateBlogPostResponse.ProtoReflect.Descriptor instead. func (*MutationCreateBlogPostResponse) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{98} + return file_product_proto_rawDescGZIP(), []int{102} } func (x *MutationCreateBlogPostResponse) GetCreateBlogPost() *BlogPost { @@ -4555,7 +4727,7 @@ type MutationUpdateBlogPostRequest struct { func (x *MutationUpdateBlogPostRequest) Reset() { *x = MutationUpdateBlogPostRequest{} - mi := &file_product_proto_msgTypes[99] + mi := &file_product_proto_msgTypes[103] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4567,7 +4739,7 @@ func (x *MutationUpdateBlogPostRequest) String() string { func (*MutationUpdateBlogPostRequest) ProtoMessage() {} func (x *MutationUpdateBlogPostRequest) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[99] + mi := &file_product_proto_msgTypes[103] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4580,7 +4752,7 @@ func (x *MutationUpdateBlogPostRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MutationUpdateBlogPostRequest.ProtoReflect.Descriptor instead. func (*MutationUpdateBlogPostRequest) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{99} + return file_product_proto_rawDescGZIP(), []int{103} } func (x *MutationUpdateBlogPostRequest) GetId() string { @@ -4607,7 +4779,7 @@ type MutationUpdateBlogPostResponse struct { func (x *MutationUpdateBlogPostResponse) Reset() { *x = MutationUpdateBlogPostResponse{} - mi := &file_product_proto_msgTypes[100] + mi := &file_product_proto_msgTypes[104] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4619,7 +4791,7 @@ func (x *MutationUpdateBlogPostResponse) String() string { func (*MutationUpdateBlogPostResponse) ProtoMessage() {} func (x *MutationUpdateBlogPostResponse) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[100] + mi := &file_product_proto_msgTypes[104] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4632,7 +4804,7 @@ func (x *MutationUpdateBlogPostResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use MutationUpdateBlogPostResponse.ProtoReflect.Descriptor instead. func (*MutationUpdateBlogPostResponse) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{100} + return file_product_proto_rawDescGZIP(), []int{104} } func (x *MutationUpdateBlogPostResponse) GetUpdateBlogPost() *BlogPost { @@ -4652,7 +4824,7 @@ type MutationCreateAuthorRequest struct { func (x *MutationCreateAuthorRequest) Reset() { *x = MutationCreateAuthorRequest{} - mi := &file_product_proto_msgTypes[101] + mi := &file_product_proto_msgTypes[105] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4664,7 +4836,7 @@ func (x *MutationCreateAuthorRequest) String() string { func (*MutationCreateAuthorRequest) ProtoMessage() {} func (x *MutationCreateAuthorRequest) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[101] + mi := &file_product_proto_msgTypes[105] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4677,7 +4849,7 @@ func (x *MutationCreateAuthorRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MutationCreateAuthorRequest.ProtoReflect.Descriptor instead. func (*MutationCreateAuthorRequest) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{101} + return file_product_proto_rawDescGZIP(), []int{105} } func (x *MutationCreateAuthorRequest) GetInput() *AuthorInput { @@ -4697,7 +4869,7 @@ type MutationCreateAuthorResponse struct { func (x *MutationCreateAuthorResponse) Reset() { *x = MutationCreateAuthorResponse{} - mi := &file_product_proto_msgTypes[102] + mi := &file_product_proto_msgTypes[106] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4709,7 +4881,7 @@ func (x *MutationCreateAuthorResponse) String() string { func (*MutationCreateAuthorResponse) ProtoMessage() {} func (x *MutationCreateAuthorResponse) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[102] + mi := &file_product_proto_msgTypes[106] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4722,7 +4894,7 @@ func (x *MutationCreateAuthorResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use MutationCreateAuthorResponse.ProtoReflect.Descriptor instead. func (*MutationCreateAuthorResponse) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{102} + return file_product_proto_rawDescGZIP(), []int{106} } func (x *MutationCreateAuthorResponse) GetCreateAuthor() *Author { @@ -4743,7 +4915,7 @@ type MutationUpdateAuthorRequest struct { func (x *MutationUpdateAuthorRequest) Reset() { *x = MutationUpdateAuthorRequest{} - mi := &file_product_proto_msgTypes[103] + mi := &file_product_proto_msgTypes[107] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4755,7 +4927,7 @@ func (x *MutationUpdateAuthorRequest) String() string { func (*MutationUpdateAuthorRequest) ProtoMessage() {} func (x *MutationUpdateAuthorRequest) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[103] + mi := &file_product_proto_msgTypes[107] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4768,7 +4940,7 @@ func (x *MutationUpdateAuthorRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MutationUpdateAuthorRequest.ProtoReflect.Descriptor instead. func (*MutationUpdateAuthorRequest) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{103} + return file_product_proto_rawDescGZIP(), []int{107} } func (x *MutationUpdateAuthorRequest) GetId() string { @@ -4795,7 +4967,7 @@ type MutationUpdateAuthorResponse struct { func (x *MutationUpdateAuthorResponse) Reset() { *x = MutationUpdateAuthorResponse{} - mi := &file_product_proto_msgTypes[104] + mi := &file_product_proto_msgTypes[108] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4807,7 +4979,7 @@ func (x *MutationUpdateAuthorResponse) String() string { func (*MutationUpdateAuthorResponse) ProtoMessage() {} func (x *MutationUpdateAuthorResponse) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[104] + mi := &file_product_proto_msgTypes[108] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4820,7 +4992,7 @@ func (x *MutationUpdateAuthorResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use MutationUpdateAuthorResponse.ProtoReflect.Descriptor instead. func (*MutationUpdateAuthorResponse) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{104} + return file_product_proto_rawDescGZIP(), []int{108} } func (x *MutationUpdateAuthorResponse) GetUpdateAuthor() *Author { @@ -4840,7 +5012,7 @@ type MutationBulkCreateAuthorsRequest struct { func (x *MutationBulkCreateAuthorsRequest) Reset() { *x = MutationBulkCreateAuthorsRequest{} - mi := &file_product_proto_msgTypes[105] + mi := &file_product_proto_msgTypes[109] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4852,7 +5024,7 @@ func (x *MutationBulkCreateAuthorsRequest) String() string { func (*MutationBulkCreateAuthorsRequest) ProtoMessage() {} func (x *MutationBulkCreateAuthorsRequest) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[105] + mi := &file_product_proto_msgTypes[109] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4865,7 +5037,7 @@ func (x *MutationBulkCreateAuthorsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MutationBulkCreateAuthorsRequest.ProtoReflect.Descriptor instead. func (*MutationBulkCreateAuthorsRequest) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{105} + return file_product_proto_rawDescGZIP(), []int{109} } func (x *MutationBulkCreateAuthorsRequest) GetAuthors() *ListOfAuthorInput { @@ -4885,7 +5057,7 @@ type MutationBulkCreateAuthorsResponse struct { func (x *MutationBulkCreateAuthorsResponse) Reset() { *x = MutationBulkCreateAuthorsResponse{} - mi := &file_product_proto_msgTypes[106] + mi := &file_product_proto_msgTypes[110] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4897,7 +5069,7 @@ func (x *MutationBulkCreateAuthorsResponse) String() string { func (*MutationBulkCreateAuthorsResponse) ProtoMessage() {} func (x *MutationBulkCreateAuthorsResponse) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[106] + mi := &file_product_proto_msgTypes[110] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4910,7 +5082,7 @@ func (x *MutationBulkCreateAuthorsResponse) ProtoReflect() protoreflect.Message // Deprecated: Use MutationBulkCreateAuthorsResponse.ProtoReflect.Descriptor instead. func (*MutationBulkCreateAuthorsResponse) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{106} + return file_product_proto_rawDescGZIP(), []int{110} } func (x *MutationBulkCreateAuthorsResponse) GetBulkCreateAuthors() []*Author { @@ -4930,7 +5102,7 @@ type MutationBulkUpdateAuthorsRequest struct { func (x *MutationBulkUpdateAuthorsRequest) Reset() { *x = MutationBulkUpdateAuthorsRequest{} - mi := &file_product_proto_msgTypes[107] + mi := &file_product_proto_msgTypes[111] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4942,7 +5114,7 @@ func (x *MutationBulkUpdateAuthorsRequest) String() string { func (*MutationBulkUpdateAuthorsRequest) ProtoMessage() {} func (x *MutationBulkUpdateAuthorsRequest) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[107] + mi := &file_product_proto_msgTypes[111] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4955,7 +5127,7 @@ func (x *MutationBulkUpdateAuthorsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MutationBulkUpdateAuthorsRequest.ProtoReflect.Descriptor instead. func (*MutationBulkUpdateAuthorsRequest) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{107} + return file_product_proto_rawDescGZIP(), []int{111} } func (x *MutationBulkUpdateAuthorsRequest) GetAuthors() *ListOfAuthorInput { @@ -4975,7 +5147,7 @@ type MutationBulkUpdateAuthorsResponse struct { func (x *MutationBulkUpdateAuthorsResponse) Reset() { *x = MutationBulkUpdateAuthorsResponse{} - mi := &file_product_proto_msgTypes[108] + mi := &file_product_proto_msgTypes[112] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4987,7 +5159,7 @@ func (x *MutationBulkUpdateAuthorsResponse) String() string { func (*MutationBulkUpdateAuthorsResponse) ProtoMessage() {} func (x *MutationBulkUpdateAuthorsResponse) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[108] + mi := &file_product_proto_msgTypes[112] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5000,7 +5172,7 @@ func (x *MutationBulkUpdateAuthorsResponse) ProtoReflect() protoreflect.Message // Deprecated: Use MutationBulkUpdateAuthorsResponse.ProtoReflect.Descriptor instead. func (*MutationBulkUpdateAuthorsResponse) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{108} + return file_product_proto_rawDescGZIP(), []int{112} } func (x *MutationBulkUpdateAuthorsResponse) GetBulkUpdateAuthors() []*Author { @@ -5020,7 +5192,7 @@ type MutationBulkCreateBlogPostsRequest struct { func (x *MutationBulkCreateBlogPostsRequest) Reset() { *x = MutationBulkCreateBlogPostsRequest{} - mi := &file_product_proto_msgTypes[109] + mi := &file_product_proto_msgTypes[113] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5032,7 +5204,7 @@ func (x *MutationBulkCreateBlogPostsRequest) String() string { func (*MutationBulkCreateBlogPostsRequest) ProtoMessage() {} func (x *MutationBulkCreateBlogPostsRequest) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[109] + mi := &file_product_proto_msgTypes[113] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5045,7 +5217,7 @@ func (x *MutationBulkCreateBlogPostsRequest) ProtoReflect() protoreflect.Message // Deprecated: Use MutationBulkCreateBlogPostsRequest.ProtoReflect.Descriptor instead. func (*MutationBulkCreateBlogPostsRequest) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{109} + return file_product_proto_rawDescGZIP(), []int{113} } func (x *MutationBulkCreateBlogPostsRequest) GetBlogPosts() *ListOfBlogPostInput { @@ -5065,7 +5237,7 @@ type MutationBulkCreateBlogPostsResponse struct { func (x *MutationBulkCreateBlogPostsResponse) Reset() { *x = MutationBulkCreateBlogPostsResponse{} - mi := &file_product_proto_msgTypes[110] + mi := &file_product_proto_msgTypes[114] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5077,7 +5249,7 @@ func (x *MutationBulkCreateBlogPostsResponse) String() string { func (*MutationBulkCreateBlogPostsResponse) ProtoMessage() {} func (x *MutationBulkCreateBlogPostsResponse) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[110] + mi := &file_product_proto_msgTypes[114] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5090,7 +5262,7 @@ func (x *MutationBulkCreateBlogPostsResponse) ProtoReflect() protoreflect.Messag // Deprecated: Use MutationBulkCreateBlogPostsResponse.ProtoReflect.Descriptor instead. func (*MutationBulkCreateBlogPostsResponse) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{110} + return file_product_proto_rawDescGZIP(), []int{114} } func (x *MutationBulkCreateBlogPostsResponse) GetBulkCreateBlogPosts() []*BlogPost { @@ -5110,7 +5282,7 @@ type MutationBulkUpdateBlogPostsRequest struct { func (x *MutationBulkUpdateBlogPostsRequest) Reset() { *x = MutationBulkUpdateBlogPostsRequest{} - mi := &file_product_proto_msgTypes[111] + mi := &file_product_proto_msgTypes[115] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5122,7 +5294,7 @@ func (x *MutationBulkUpdateBlogPostsRequest) String() string { func (*MutationBulkUpdateBlogPostsRequest) ProtoMessage() {} func (x *MutationBulkUpdateBlogPostsRequest) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[111] + mi := &file_product_proto_msgTypes[115] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5135,7 +5307,7 @@ func (x *MutationBulkUpdateBlogPostsRequest) ProtoReflect() protoreflect.Message // Deprecated: Use MutationBulkUpdateBlogPostsRequest.ProtoReflect.Descriptor instead. func (*MutationBulkUpdateBlogPostsRequest) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{111} + return file_product_proto_rawDescGZIP(), []int{115} } func (x *MutationBulkUpdateBlogPostsRequest) GetBlogPosts() *ListOfBlogPostInput { @@ -5155,7 +5327,7 @@ type MutationBulkUpdateBlogPostsResponse struct { func (x *MutationBulkUpdateBlogPostsResponse) Reset() { *x = MutationBulkUpdateBlogPostsResponse{} - mi := &file_product_proto_msgTypes[112] + mi := &file_product_proto_msgTypes[116] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5167,7 +5339,7 @@ func (x *MutationBulkUpdateBlogPostsResponse) String() string { func (*MutationBulkUpdateBlogPostsResponse) ProtoMessage() {} func (x *MutationBulkUpdateBlogPostsResponse) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[112] + mi := &file_product_proto_msgTypes[116] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5180,7 +5352,7 @@ func (x *MutationBulkUpdateBlogPostsResponse) ProtoReflect() protoreflect.Messag // Deprecated: Use MutationBulkUpdateBlogPostsResponse.ProtoReflect.Descriptor instead. func (*MutationBulkUpdateBlogPostsResponse) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{112} + return file_product_proto_rawDescGZIP(), []int{116} } func (x *MutationBulkUpdateBlogPostsResponse) GetBulkUpdateBlogPosts() []*BlogPost { @@ -5199,7 +5371,7 @@ type ResolveProductShippingEstimateArgs struct { func (x *ResolveProductShippingEstimateArgs) Reset() { *x = ResolveProductShippingEstimateArgs{} - mi := &file_product_proto_msgTypes[113] + mi := &file_product_proto_msgTypes[117] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5211,7 +5383,7 @@ func (x *ResolveProductShippingEstimateArgs) String() string { func (*ResolveProductShippingEstimateArgs) ProtoMessage() {} func (x *ResolveProductShippingEstimateArgs) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[113] + mi := &file_product_proto_msgTypes[117] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5224,7 +5396,7 @@ func (x *ResolveProductShippingEstimateArgs) ProtoReflect() protoreflect.Message // Deprecated: Use ResolveProductShippingEstimateArgs.ProtoReflect.Descriptor instead. func (*ResolveProductShippingEstimateArgs) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{113} + return file_product_proto_rawDescGZIP(), []int{117} } func (x *ResolveProductShippingEstimateArgs) GetInput() *ShippingEstimateInput { @@ -5244,7 +5416,7 @@ type ResolveProductShippingEstimateContext struct { func (x *ResolveProductShippingEstimateContext) Reset() { *x = ResolveProductShippingEstimateContext{} - mi := &file_product_proto_msgTypes[114] + mi := &file_product_proto_msgTypes[118] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5256,7 +5428,7 @@ func (x *ResolveProductShippingEstimateContext) String() string { func (*ResolveProductShippingEstimateContext) ProtoMessage() {} func (x *ResolveProductShippingEstimateContext) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[114] + mi := &file_product_proto_msgTypes[118] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5269,7 +5441,7 @@ func (x *ResolveProductShippingEstimateContext) ProtoReflect() protoreflect.Mess // Deprecated: Use ResolveProductShippingEstimateContext.ProtoReflect.Descriptor instead. func (*ResolveProductShippingEstimateContext) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{114} + return file_product_proto_rawDescGZIP(), []int{118} } func (x *ResolveProductShippingEstimateContext) GetId() string { @@ -5298,7 +5470,7 @@ type ResolveProductShippingEstimateRequest struct { func (x *ResolveProductShippingEstimateRequest) Reset() { *x = ResolveProductShippingEstimateRequest{} - mi := &file_product_proto_msgTypes[115] + mi := &file_product_proto_msgTypes[119] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5310,7 +5482,7 @@ func (x *ResolveProductShippingEstimateRequest) String() string { func (*ResolveProductShippingEstimateRequest) ProtoMessage() {} func (x *ResolveProductShippingEstimateRequest) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[115] + mi := &file_product_proto_msgTypes[119] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5323,7 +5495,7 @@ func (x *ResolveProductShippingEstimateRequest) ProtoReflect() protoreflect.Mess // Deprecated: Use ResolveProductShippingEstimateRequest.ProtoReflect.Descriptor instead. func (*ResolveProductShippingEstimateRequest) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{115} + return file_product_proto_rawDescGZIP(), []int{119} } func (x *ResolveProductShippingEstimateRequest) GetContext() []*ResolveProductShippingEstimateContext { @@ -5349,7 +5521,7 @@ type ResolveProductShippingEstimateResult struct { func (x *ResolveProductShippingEstimateResult) Reset() { *x = ResolveProductShippingEstimateResult{} - mi := &file_product_proto_msgTypes[116] + mi := &file_product_proto_msgTypes[120] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5361,7 +5533,7 @@ func (x *ResolveProductShippingEstimateResult) String() string { func (*ResolveProductShippingEstimateResult) ProtoMessage() {} func (x *ResolveProductShippingEstimateResult) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[116] + mi := &file_product_proto_msgTypes[120] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5374,7 +5546,7 @@ func (x *ResolveProductShippingEstimateResult) ProtoReflect() protoreflect.Messa // Deprecated: Use ResolveProductShippingEstimateResult.ProtoReflect.Descriptor instead. func (*ResolveProductShippingEstimateResult) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{116} + return file_product_proto_rawDescGZIP(), []int{120} } func (x *ResolveProductShippingEstimateResult) GetShippingEstimate() float64 { @@ -5393,7 +5565,7 @@ type ResolveProductShippingEstimateResponse struct { func (x *ResolveProductShippingEstimateResponse) Reset() { *x = ResolveProductShippingEstimateResponse{} - mi := &file_product_proto_msgTypes[117] + mi := &file_product_proto_msgTypes[121] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5405,7 +5577,7 @@ func (x *ResolveProductShippingEstimateResponse) String() string { func (*ResolveProductShippingEstimateResponse) ProtoMessage() {} func (x *ResolveProductShippingEstimateResponse) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[117] + mi := &file_product_proto_msgTypes[121] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5418,7 +5590,7 @@ func (x *ResolveProductShippingEstimateResponse) ProtoReflect() protoreflect.Mes // Deprecated: Use ResolveProductShippingEstimateResponse.ProtoReflect.Descriptor instead. func (*ResolveProductShippingEstimateResponse) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{117} + return file_product_proto_rawDescGZIP(), []int{121} } func (x *ResolveProductShippingEstimateResponse) GetResult() []*ResolveProductShippingEstimateResult { @@ -5437,7 +5609,7 @@ type ResolveProductRecommendedCategoryArgs struct { func (x *ResolveProductRecommendedCategoryArgs) Reset() { *x = ResolveProductRecommendedCategoryArgs{} - mi := &file_product_proto_msgTypes[118] + mi := &file_product_proto_msgTypes[122] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5449,7 +5621,7 @@ func (x *ResolveProductRecommendedCategoryArgs) String() string { func (*ResolveProductRecommendedCategoryArgs) ProtoMessage() {} func (x *ResolveProductRecommendedCategoryArgs) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[118] + mi := &file_product_proto_msgTypes[122] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5462,7 +5634,7 @@ func (x *ResolveProductRecommendedCategoryArgs) ProtoReflect() protoreflect.Mess // Deprecated: Use ResolveProductRecommendedCategoryArgs.ProtoReflect.Descriptor instead. func (*ResolveProductRecommendedCategoryArgs) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{118} + return file_product_proto_rawDescGZIP(), []int{122} } func (x *ResolveProductRecommendedCategoryArgs) GetMaxPrice() int32 { @@ -5483,7 +5655,7 @@ type ResolveProductRecommendedCategoryContext struct { func (x *ResolveProductRecommendedCategoryContext) Reset() { *x = ResolveProductRecommendedCategoryContext{} - mi := &file_product_proto_msgTypes[119] + mi := &file_product_proto_msgTypes[123] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5495,7 +5667,7 @@ func (x *ResolveProductRecommendedCategoryContext) String() string { func (*ResolveProductRecommendedCategoryContext) ProtoMessage() {} func (x *ResolveProductRecommendedCategoryContext) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[119] + mi := &file_product_proto_msgTypes[123] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5508,7 +5680,7 @@ func (x *ResolveProductRecommendedCategoryContext) ProtoReflect() protoreflect.M // Deprecated: Use ResolveProductRecommendedCategoryContext.ProtoReflect.Descriptor instead. func (*ResolveProductRecommendedCategoryContext) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{119} + return file_product_proto_rawDescGZIP(), []int{123} } func (x *ResolveProductRecommendedCategoryContext) GetId() string { @@ -5544,7 +5716,7 @@ type ResolveProductRecommendedCategoryRequest struct { func (x *ResolveProductRecommendedCategoryRequest) Reset() { *x = ResolveProductRecommendedCategoryRequest{} - mi := &file_product_proto_msgTypes[120] + mi := &file_product_proto_msgTypes[124] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5556,7 +5728,7 @@ func (x *ResolveProductRecommendedCategoryRequest) String() string { func (*ResolveProductRecommendedCategoryRequest) ProtoMessage() {} func (x *ResolveProductRecommendedCategoryRequest) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[120] + mi := &file_product_proto_msgTypes[124] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5569,7 +5741,7 @@ func (x *ResolveProductRecommendedCategoryRequest) ProtoReflect() protoreflect.M // Deprecated: Use ResolveProductRecommendedCategoryRequest.ProtoReflect.Descriptor instead. func (*ResolveProductRecommendedCategoryRequest) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{120} + return file_product_proto_rawDescGZIP(), []int{124} } func (x *ResolveProductRecommendedCategoryRequest) GetContext() []*ResolveProductRecommendedCategoryContext { @@ -5595,7 +5767,7 @@ type ResolveProductRecommendedCategoryResult struct { func (x *ResolveProductRecommendedCategoryResult) Reset() { *x = ResolveProductRecommendedCategoryResult{} - mi := &file_product_proto_msgTypes[121] + mi := &file_product_proto_msgTypes[125] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5607,7 +5779,7 @@ func (x *ResolveProductRecommendedCategoryResult) String() string { func (*ResolveProductRecommendedCategoryResult) ProtoMessage() {} func (x *ResolveProductRecommendedCategoryResult) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[121] + mi := &file_product_proto_msgTypes[125] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5620,7 +5792,7 @@ func (x *ResolveProductRecommendedCategoryResult) ProtoReflect() protoreflect.Me // Deprecated: Use ResolveProductRecommendedCategoryResult.ProtoReflect.Descriptor instead. func (*ResolveProductRecommendedCategoryResult) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{121} + return file_product_proto_rawDescGZIP(), []int{125} } func (x *ResolveProductRecommendedCategoryResult) GetRecommendedCategory() *Category { @@ -5639,7 +5811,7 @@ type ResolveProductRecommendedCategoryResponse struct { func (x *ResolveProductRecommendedCategoryResponse) Reset() { *x = ResolveProductRecommendedCategoryResponse{} - mi := &file_product_proto_msgTypes[122] + mi := &file_product_proto_msgTypes[126] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5651,7 +5823,7 @@ func (x *ResolveProductRecommendedCategoryResponse) String() string { func (*ResolveProductRecommendedCategoryResponse) ProtoMessage() {} func (x *ResolveProductRecommendedCategoryResponse) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[122] + mi := &file_product_proto_msgTypes[126] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5664,7 +5836,7 @@ func (x *ResolveProductRecommendedCategoryResponse) ProtoReflect() protoreflect. // Deprecated: Use ResolveProductRecommendedCategoryResponse.ProtoReflect.Descriptor instead. func (*ResolveProductRecommendedCategoryResponse) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{122} + return file_product_proto_rawDescGZIP(), []int{126} } func (x *ResolveProductRecommendedCategoryResponse) GetResult() []*ResolveProductRecommendedCategoryResult { @@ -5674,28 +5846,28 @@ func (x *ResolveProductRecommendedCategoryResponse) GetResult() []*ResolveProduc return nil } -type ResolveCategoryProductCountArgs struct { - state protoimpl.MessageState `protogen:"open.v1"` - Filters *ProductCountFilter `protobuf:"bytes,1,opt,name=filters,proto3" json:"filters,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +type ResolveProductMascotRecommendationArgs struct { + state protoimpl.MessageState `protogen:"open.v1"` + IncludeDetails bool `protobuf:"varint,1,opt,name=include_details,json=includeDetails,proto3" json:"include_details,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *ResolveCategoryProductCountArgs) Reset() { - *x = ResolveCategoryProductCountArgs{} - mi := &file_product_proto_msgTypes[123] +func (x *ResolveProductMascotRecommendationArgs) Reset() { + *x = ResolveProductMascotRecommendationArgs{} + mi := &file_product_proto_msgTypes[127] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *ResolveCategoryProductCountArgs) String() string { +func (x *ResolveProductMascotRecommendationArgs) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ResolveCategoryProductCountArgs) ProtoMessage() {} +func (*ResolveProductMascotRecommendationArgs) ProtoMessage() {} -func (x *ResolveCategoryProductCountArgs) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[123] +func (x *ResolveProductMascotRecommendationArgs) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[127] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5706,19 +5878,19 @@ func (x *ResolveCategoryProductCountArgs) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ResolveCategoryProductCountArgs.ProtoReflect.Descriptor instead. -func (*ResolveCategoryProductCountArgs) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{123} +// Deprecated: Use ResolveProductMascotRecommendationArgs.ProtoReflect.Descriptor instead. +func (*ResolveProductMascotRecommendationArgs) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{127} } -func (x *ResolveCategoryProductCountArgs) GetFilters() *ProductCountFilter { +func (x *ResolveProductMascotRecommendationArgs) GetIncludeDetails() bool { if x != nil { - return x.Filters + return x.IncludeDetails } - return nil + return false } -type ResolveCategoryProductCountContext struct { +type ResolveProductMascotRecommendationContext struct { state protoimpl.MessageState `protogen:"open.v1"` Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` @@ -5726,21 +5898,21 @@ type ResolveCategoryProductCountContext struct { sizeCache protoimpl.SizeCache } -func (x *ResolveCategoryProductCountContext) Reset() { - *x = ResolveCategoryProductCountContext{} - mi := &file_product_proto_msgTypes[124] +func (x *ResolveProductMascotRecommendationContext) Reset() { + *x = ResolveProductMascotRecommendationContext{} + mi := &file_product_proto_msgTypes[128] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *ResolveCategoryProductCountContext) String() string { +func (x *ResolveProductMascotRecommendationContext) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ResolveCategoryProductCountContext) ProtoMessage() {} +func (*ResolveProductMascotRecommendationContext) ProtoMessage() {} -func (x *ResolveCategoryProductCountContext) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[124] +func (x *ResolveProductMascotRecommendationContext) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[128] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5751,50 +5923,50 @@ func (x *ResolveCategoryProductCountContext) ProtoReflect() protoreflect.Message return mi.MessageOf(x) } -// Deprecated: Use ResolveCategoryProductCountContext.ProtoReflect.Descriptor instead. -func (*ResolveCategoryProductCountContext) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{124} +// Deprecated: Use ResolveProductMascotRecommendationContext.ProtoReflect.Descriptor instead. +func (*ResolveProductMascotRecommendationContext) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{128} } -func (x *ResolveCategoryProductCountContext) GetId() string { +func (x *ResolveProductMascotRecommendationContext) GetId() string { if x != nil { return x.Id } return "" } -func (x *ResolveCategoryProductCountContext) GetName() string { +func (x *ResolveProductMascotRecommendationContext) GetName() string { if x != nil { return x.Name } return "" } -type ResolveCategoryProductCountRequest struct { +type ResolveProductMascotRecommendationRequest struct { state protoimpl.MessageState `protogen:"open.v1"` - // context provides the resolver context for the field productCount of type Category. - Context []*ResolveCategoryProductCountContext `protobuf:"bytes,1,rep,name=context,proto3" json:"context,omitempty"` - // field_args provides the arguments for the resolver field productCount of type Category. - FieldArgs *ResolveCategoryProductCountArgs `protobuf:"bytes,2,opt,name=field_args,json=fieldArgs,proto3" json:"field_args,omitempty"` + // context provides the resolver context for the field mascotRecommendation of type Product. + Context []*ResolveProductMascotRecommendationContext `protobuf:"bytes,1,rep,name=context,proto3" json:"context,omitempty"` + // field_args provides the arguments for the resolver field mascotRecommendation of type Product. + FieldArgs *ResolveProductMascotRecommendationArgs `protobuf:"bytes,2,opt,name=field_args,json=fieldArgs,proto3" json:"field_args,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *ResolveCategoryProductCountRequest) Reset() { - *x = ResolveCategoryProductCountRequest{} - mi := &file_product_proto_msgTypes[125] +func (x *ResolveProductMascotRecommendationRequest) Reset() { + *x = ResolveProductMascotRecommendationRequest{} + mi := &file_product_proto_msgTypes[129] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *ResolveCategoryProductCountRequest) String() string { +func (x *ResolveProductMascotRecommendationRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ResolveCategoryProductCountRequest) ProtoMessage() {} +func (*ResolveProductMascotRecommendationRequest) ProtoMessage() {} -func (x *ResolveCategoryProductCountRequest) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[125] +func (x *ResolveProductMascotRecommendationRequest) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[129] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5805,47 +5977,47 @@ func (x *ResolveCategoryProductCountRequest) ProtoReflect() protoreflect.Message return mi.MessageOf(x) } -// Deprecated: Use ResolveCategoryProductCountRequest.ProtoReflect.Descriptor instead. -func (*ResolveCategoryProductCountRequest) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{125} +// Deprecated: Use ResolveProductMascotRecommendationRequest.ProtoReflect.Descriptor instead. +func (*ResolveProductMascotRecommendationRequest) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{129} } -func (x *ResolveCategoryProductCountRequest) GetContext() []*ResolveCategoryProductCountContext { +func (x *ResolveProductMascotRecommendationRequest) GetContext() []*ResolveProductMascotRecommendationContext { if x != nil { return x.Context } return nil } -func (x *ResolveCategoryProductCountRequest) GetFieldArgs() *ResolveCategoryProductCountArgs { +func (x *ResolveProductMascotRecommendationRequest) GetFieldArgs() *ResolveProductMascotRecommendationArgs { if x != nil { return x.FieldArgs } return nil } -type ResolveCategoryProductCountResult struct { - state protoimpl.MessageState `protogen:"open.v1"` - ProductCount int32 `protobuf:"varint,1,opt,name=product_count,json=productCount,proto3" json:"product_count,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +type ResolveProductMascotRecommendationResult struct { + state protoimpl.MessageState `protogen:"open.v1"` + MascotRecommendation *Animal `protobuf:"bytes,1,opt,name=mascot_recommendation,json=mascotRecommendation,proto3" json:"mascot_recommendation,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *ResolveCategoryProductCountResult) Reset() { - *x = ResolveCategoryProductCountResult{} - mi := &file_product_proto_msgTypes[126] +func (x *ResolveProductMascotRecommendationResult) Reset() { + *x = ResolveProductMascotRecommendationResult{} + mi := &file_product_proto_msgTypes[130] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *ResolveCategoryProductCountResult) String() string { +func (x *ResolveProductMascotRecommendationResult) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ResolveCategoryProductCountResult) ProtoMessage() {} +func (*ResolveProductMascotRecommendationResult) ProtoMessage() {} -func (x *ResolveCategoryProductCountResult) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[126] +func (x *ResolveProductMascotRecommendationResult) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[130] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5856,40 +6028,40 @@ func (x *ResolveCategoryProductCountResult) ProtoReflect() protoreflect.Message return mi.MessageOf(x) } -// Deprecated: Use ResolveCategoryProductCountResult.ProtoReflect.Descriptor instead. -func (*ResolveCategoryProductCountResult) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{126} +// Deprecated: Use ResolveProductMascotRecommendationResult.ProtoReflect.Descriptor instead. +func (*ResolveProductMascotRecommendationResult) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{130} } -func (x *ResolveCategoryProductCountResult) GetProductCount() int32 { +func (x *ResolveProductMascotRecommendationResult) GetMascotRecommendation() *Animal { if x != nil { - return x.ProductCount + return x.MascotRecommendation } - return 0 + return nil } -type ResolveCategoryProductCountResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - Result []*ResolveCategoryProductCountResult `protobuf:"bytes,1,rep,name=result,proto3" json:"result,omitempty"` +type ResolveProductMascotRecommendationResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Result []*ResolveProductMascotRecommendationResult `protobuf:"bytes,1,rep,name=result,proto3" json:"result,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *ResolveCategoryProductCountResponse) Reset() { - *x = ResolveCategoryProductCountResponse{} - mi := &file_product_proto_msgTypes[127] +func (x *ResolveProductMascotRecommendationResponse) Reset() { + *x = ResolveProductMascotRecommendationResponse{} + mi := &file_product_proto_msgTypes[131] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *ResolveCategoryProductCountResponse) String() string { +func (x *ResolveProductMascotRecommendationResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ResolveCategoryProductCountResponse) ProtoMessage() {} +func (*ResolveProductMascotRecommendationResponse) ProtoMessage() {} -func (x *ResolveCategoryProductCountResponse) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[127] +func (x *ResolveProductMascotRecommendationResponse) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[131] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5900,40 +6072,40 @@ func (x *ResolveCategoryProductCountResponse) ProtoReflect() protoreflect.Messag return mi.MessageOf(x) } -// Deprecated: Use ResolveCategoryProductCountResponse.ProtoReflect.Descriptor instead. -func (*ResolveCategoryProductCountResponse) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{127} +// Deprecated: Use ResolveProductMascotRecommendationResponse.ProtoReflect.Descriptor instead. +func (*ResolveProductMascotRecommendationResponse) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{131} } -func (x *ResolveCategoryProductCountResponse) GetResult() []*ResolveCategoryProductCountResult { +func (x *ResolveProductMascotRecommendationResponse) GetResult() []*ResolveProductMascotRecommendationResult { if x != nil { return x.Result } return nil } -type ResolveCategoryPopularityScoreArgs struct { - state protoimpl.MessageState `protogen:"open.v1"` - Threshold *wrapperspb.Int32Value `protobuf:"bytes,1,opt,name=threshold,proto3" json:"threshold,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +type ResolveProductStockStatusArgs struct { + state protoimpl.MessageState `protogen:"open.v1"` + CheckAvailability bool `protobuf:"varint,1,opt,name=check_availability,json=checkAvailability,proto3" json:"check_availability,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *ResolveCategoryPopularityScoreArgs) Reset() { - *x = ResolveCategoryPopularityScoreArgs{} - mi := &file_product_proto_msgTypes[128] +func (x *ResolveProductStockStatusArgs) Reset() { + *x = ResolveProductStockStatusArgs{} + mi := &file_product_proto_msgTypes[132] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *ResolveCategoryPopularityScoreArgs) String() string { +func (x *ResolveProductStockStatusArgs) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ResolveCategoryPopularityScoreArgs) ProtoMessage() {} +func (*ResolveProductStockStatusArgs) ProtoMessage() {} -func (x *ResolveCategoryPopularityScoreArgs) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[128] +func (x *ResolveProductStockStatusArgs) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[132] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5944,40 +6116,42 @@ func (x *ResolveCategoryPopularityScoreArgs) ProtoReflect() protoreflect.Message return mi.MessageOf(x) } -// Deprecated: Use ResolveCategoryPopularityScoreArgs.ProtoReflect.Descriptor instead. -func (*ResolveCategoryPopularityScoreArgs) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{128} +// Deprecated: Use ResolveProductStockStatusArgs.ProtoReflect.Descriptor instead. +func (*ResolveProductStockStatusArgs) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{132} } -func (x *ResolveCategoryPopularityScoreArgs) GetThreshold() *wrapperspb.Int32Value { +func (x *ResolveProductStockStatusArgs) GetCheckAvailability() bool { if x != nil { - return x.Threshold + return x.CheckAvailability } - return nil + return false } -type ResolveCategoryPopularityScoreContext struct { +type ResolveProductStockStatusContext struct { state protoimpl.MessageState `protogen:"open.v1"` Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Price float64 `protobuf:"fixed64,3,opt,name=price,proto3" json:"price,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *ResolveCategoryPopularityScoreContext) Reset() { - *x = ResolveCategoryPopularityScoreContext{} - mi := &file_product_proto_msgTypes[129] +func (x *ResolveProductStockStatusContext) Reset() { + *x = ResolveProductStockStatusContext{} + mi := &file_product_proto_msgTypes[133] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *ResolveCategoryPopularityScoreContext) String() string { +func (x *ResolveProductStockStatusContext) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ResolveCategoryPopularityScoreContext) ProtoMessage() {} +func (*ResolveProductStockStatusContext) ProtoMessage() {} -func (x *ResolveCategoryPopularityScoreContext) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[129] +func (x *ResolveProductStockStatusContext) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[133] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5988,43 +6162,57 @@ func (x *ResolveCategoryPopularityScoreContext) ProtoReflect() protoreflect.Mess return mi.MessageOf(x) } -// Deprecated: Use ResolveCategoryPopularityScoreContext.ProtoReflect.Descriptor instead. -func (*ResolveCategoryPopularityScoreContext) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{129} +// Deprecated: Use ResolveProductStockStatusContext.ProtoReflect.Descriptor instead. +func (*ResolveProductStockStatusContext) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{133} } -func (x *ResolveCategoryPopularityScoreContext) GetId() string { +func (x *ResolveProductStockStatusContext) GetId() string { if x != nil { return x.Id } return "" } -type ResolveCategoryPopularityScoreRequest struct { +func (x *ResolveProductStockStatusContext) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *ResolveProductStockStatusContext) GetPrice() float64 { + if x != nil { + return x.Price + } + return 0 +} + +type ResolveProductStockStatusRequest struct { state protoimpl.MessageState `protogen:"open.v1"` - // context provides the resolver context for the field popularityScore of type Category. - Context []*ResolveCategoryPopularityScoreContext `protobuf:"bytes,1,rep,name=context,proto3" json:"context,omitempty"` - // field_args provides the arguments for the resolver field popularityScore of type Category. - FieldArgs *ResolveCategoryPopularityScoreArgs `protobuf:"bytes,2,opt,name=field_args,json=fieldArgs,proto3" json:"field_args,omitempty"` + // context provides the resolver context for the field stockStatus of type Product. + Context []*ResolveProductStockStatusContext `protobuf:"bytes,1,rep,name=context,proto3" json:"context,omitempty"` + // field_args provides the arguments for the resolver field stockStatus of type Product. + FieldArgs *ResolveProductStockStatusArgs `protobuf:"bytes,2,opt,name=field_args,json=fieldArgs,proto3" json:"field_args,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *ResolveCategoryPopularityScoreRequest) Reset() { - *x = ResolveCategoryPopularityScoreRequest{} - mi := &file_product_proto_msgTypes[130] +func (x *ResolveProductStockStatusRequest) Reset() { + *x = ResolveProductStockStatusRequest{} + mi := &file_product_proto_msgTypes[134] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *ResolveCategoryPopularityScoreRequest) String() string { +func (x *ResolveProductStockStatusRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ResolveCategoryPopularityScoreRequest) ProtoMessage() {} +func (*ResolveProductStockStatusRequest) ProtoMessage() {} -func (x *ResolveCategoryPopularityScoreRequest) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[130] +func (x *ResolveProductStockStatusRequest) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[134] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6035,47 +6223,47 @@ func (x *ResolveCategoryPopularityScoreRequest) ProtoReflect() protoreflect.Mess return mi.MessageOf(x) } -// Deprecated: Use ResolveCategoryPopularityScoreRequest.ProtoReflect.Descriptor instead. -func (*ResolveCategoryPopularityScoreRequest) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{130} +// Deprecated: Use ResolveProductStockStatusRequest.ProtoReflect.Descriptor instead. +func (*ResolveProductStockStatusRequest) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{134} } -func (x *ResolveCategoryPopularityScoreRequest) GetContext() []*ResolveCategoryPopularityScoreContext { +func (x *ResolveProductStockStatusRequest) GetContext() []*ResolveProductStockStatusContext { if x != nil { return x.Context } return nil } -func (x *ResolveCategoryPopularityScoreRequest) GetFieldArgs() *ResolveCategoryPopularityScoreArgs { +func (x *ResolveProductStockStatusRequest) GetFieldArgs() *ResolveProductStockStatusArgs { if x != nil { return x.FieldArgs } return nil } -type ResolveCategoryPopularityScoreResult struct { - state protoimpl.MessageState `protogen:"open.v1"` - PopularityScore *wrapperspb.Int32Value `protobuf:"bytes,1,opt,name=popularity_score,json=popularityScore,proto3" json:"popularity_score,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +type ResolveProductStockStatusResult struct { + state protoimpl.MessageState `protogen:"open.v1"` + StockStatus *ActionResult `protobuf:"bytes,1,opt,name=stock_status,json=stockStatus,proto3" json:"stock_status,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *ResolveCategoryPopularityScoreResult) Reset() { - *x = ResolveCategoryPopularityScoreResult{} - mi := &file_product_proto_msgTypes[131] +func (x *ResolveProductStockStatusResult) Reset() { + *x = ResolveProductStockStatusResult{} + mi := &file_product_proto_msgTypes[135] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *ResolveCategoryPopularityScoreResult) String() string { +func (x *ResolveProductStockStatusResult) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ResolveCategoryPopularityScoreResult) ProtoMessage() {} +func (*ResolveProductStockStatusResult) ProtoMessage() {} -func (x *ResolveCategoryPopularityScoreResult) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[131] +func (x *ResolveProductStockStatusResult) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[135] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6086,40 +6274,40 @@ func (x *ResolveCategoryPopularityScoreResult) ProtoReflect() protoreflect.Messa return mi.MessageOf(x) } -// Deprecated: Use ResolveCategoryPopularityScoreResult.ProtoReflect.Descriptor instead. -func (*ResolveCategoryPopularityScoreResult) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{131} +// Deprecated: Use ResolveProductStockStatusResult.ProtoReflect.Descriptor instead. +func (*ResolveProductStockStatusResult) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{135} } -func (x *ResolveCategoryPopularityScoreResult) GetPopularityScore() *wrapperspb.Int32Value { +func (x *ResolveProductStockStatusResult) GetStockStatus() *ActionResult { if x != nil { - return x.PopularityScore + return x.StockStatus } return nil } -type ResolveCategoryPopularityScoreResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - Result []*ResolveCategoryPopularityScoreResult `protobuf:"bytes,1,rep,name=result,proto3" json:"result,omitempty"` +type ResolveProductStockStatusResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Result []*ResolveProductStockStatusResult `protobuf:"bytes,1,rep,name=result,proto3" json:"result,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *ResolveCategoryPopularityScoreResponse) Reset() { - *x = ResolveCategoryPopularityScoreResponse{} - mi := &file_product_proto_msgTypes[132] +func (x *ResolveProductStockStatusResponse) Reset() { + *x = ResolveProductStockStatusResponse{} + mi := &file_product_proto_msgTypes[136] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *ResolveCategoryPopularityScoreResponse) String() string { +func (x *ResolveProductStockStatusResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ResolveCategoryPopularityScoreResponse) ProtoMessage() {} +func (*ResolveProductStockStatusResponse) ProtoMessage() {} -func (x *ResolveCategoryPopularityScoreResponse) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[132] +func (x *ResolveProductStockStatusResponse) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[136] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6130,40 +6318,40 @@ func (x *ResolveCategoryPopularityScoreResponse) ProtoReflect() protoreflect.Mes return mi.MessageOf(x) } -// Deprecated: Use ResolveCategoryPopularityScoreResponse.ProtoReflect.Descriptor instead. -func (*ResolveCategoryPopularityScoreResponse) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{132} +// Deprecated: Use ResolveProductStockStatusResponse.ProtoReflect.Descriptor instead. +func (*ResolveProductStockStatusResponse) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{136} } -func (x *ResolveCategoryPopularityScoreResponse) GetResult() []*ResolveCategoryPopularityScoreResult { +func (x *ResolveProductStockStatusResponse) GetResult() []*ResolveProductStockStatusResult { if x != nil { return x.Result } return nil } -type ResolveCategoryCategoryMetricsArgs struct { - state protoimpl.MessageState `protogen:"open.v1"` - MetricType string `protobuf:"bytes,1,opt,name=metric_type,json=metricType,proto3" json:"metric_type,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +type ResolveProductProductDetailsArgs struct { + state protoimpl.MessageState `protogen:"open.v1"` + IncludeExtended bool `protobuf:"varint,1,opt,name=include_extended,json=includeExtended,proto3" json:"include_extended,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *ResolveCategoryCategoryMetricsArgs) Reset() { - *x = ResolveCategoryCategoryMetricsArgs{} - mi := &file_product_proto_msgTypes[133] +func (x *ResolveProductProductDetailsArgs) Reset() { + *x = ResolveProductProductDetailsArgs{} + mi := &file_product_proto_msgTypes[137] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *ResolveCategoryCategoryMetricsArgs) String() string { +func (x *ResolveProductProductDetailsArgs) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ResolveCategoryCategoryMetricsArgs) ProtoMessage() {} +func (*ResolveProductProductDetailsArgs) ProtoMessage() {} -func (x *ResolveCategoryCategoryMetricsArgs) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[133] +func (x *ResolveProductProductDetailsArgs) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[137] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6174,41 +6362,42 @@ func (x *ResolveCategoryCategoryMetricsArgs) ProtoReflect() protoreflect.Message return mi.MessageOf(x) } -// Deprecated: Use ResolveCategoryCategoryMetricsArgs.ProtoReflect.Descriptor instead. -func (*ResolveCategoryCategoryMetricsArgs) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{133} +// Deprecated: Use ResolveProductProductDetailsArgs.ProtoReflect.Descriptor instead. +func (*ResolveProductProductDetailsArgs) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{137} } -func (x *ResolveCategoryCategoryMetricsArgs) GetMetricType() string { +func (x *ResolveProductProductDetailsArgs) GetIncludeExtended() bool { if x != nil { - return x.MetricType + return x.IncludeExtended } - return "" + return false } -type ResolveCategoryCategoryMetricsContext struct { +type ResolveProductProductDetailsContext struct { state protoimpl.MessageState `protogen:"open.v1"` Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Price float64 `protobuf:"fixed64,3,opt,name=price,proto3" json:"price,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *ResolveCategoryCategoryMetricsContext) Reset() { - *x = ResolveCategoryCategoryMetricsContext{} - mi := &file_product_proto_msgTypes[134] +func (x *ResolveProductProductDetailsContext) Reset() { + *x = ResolveProductProductDetailsContext{} + mi := &file_product_proto_msgTypes[138] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *ResolveCategoryCategoryMetricsContext) String() string { +func (x *ResolveProductProductDetailsContext) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ResolveCategoryCategoryMetricsContext) ProtoMessage() {} +func (*ResolveProductProductDetailsContext) ProtoMessage() {} -func (x *ResolveCategoryCategoryMetricsContext) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[134] +func (x *ResolveProductProductDetailsContext) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[138] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6219,50 +6408,57 @@ func (x *ResolveCategoryCategoryMetricsContext) ProtoReflect() protoreflect.Mess return mi.MessageOf(x) } -// Deprecated: Use ResolveCategoryCategoryMetricsContext.ProtoReflect.Descriptor instead. -func (*ResolveCategoryCategoryMetricsContext) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{134} +// Deprecated: Use ResolveProductProductDetailsContext.ProtoReflect.Descriptor instead. +func (*ResolveProductProductDetailsContext) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{138} } -func (x *ResolveCategoryCategoryMetricsContext) GetId() string { +func (x *ResolveProductProductDetailsContext) GetId() string { if x != nil { return x.Id } return "" } -func (x *ResolveCategoryCategoryMetricsContext) GetName() string { +func (x *ResolveProductProductDetailsContext) GetName() string { if x != nil { return x.Name } return "" } -type ResolveCategoryCategoryMetricsRequest struct { +func (x *ResolveProductProductDetailsContext) GetPrice() float64 { + if x != nil { + return x.Price + } + return 0 +} + +type ResolveProductProductDetailsRequest struct { state protoimpl.MessageState `protogen:"open.v1"` - // context provides the resolver context for the field categoryMetrics of type Category. - Context []*ResolveCategoryCategoryMetricsContext `protobuf:"bytes,1,rep,name=context,proto3" json:"context,omitempty"` - // field_args provides the arguments for the resolver field categoryMetrics of type Category. - FieldArgs *ResolveCategoryCategoryMetricsArgs `protobuf:"bytes,2,opt,name=field_args,json=fieldArgs,proto3" json:"field_args,omitempty"` + // context provides the resolver context for the field productDetails of type Product. + Context []*ResolveProductProductDetailsContext `protobuf:"bytes,1,rep,name=context,proto3" json:"context,omitempty"` + // field_args provides the arguments for the resolver field productDetails of type Product. + FieldArgs *ResolveProductProductDetailsArgs `protobuf:"bytes,2,opt,name=field_args,json=fieldArgs,proto3" json:"field_args,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *ResolveCategoryCategoryMetricsRequest) Reset() { - *x = ResolveCategoryCategoryMetricsRequest{} - mi := &file_product_proto_msgTypes[135] +func (x *ResolveProductProductDetailsRequest) Reset() { + *x = ResolveProductProductDetailsRequest{} + mi := &file_product_proto_msgTypes[139] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *ResolveCategoryCategoryMetricsRequest) String() string { +func (x *ResolveProductProductDetailsRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ResolveCategoryCategoryMetricsRequest) ProtoMessage() {} +func (*ResolveProductProductDetailsRequest) ProtoMessage() {} -func (x *ResolveCategoryCategoryMetricsRequest) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[135] +func (x *ResolveProductProductDetailsRequest) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[139] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6273,47 +6469,47 @@ func (x *ResolveCategoryCategoryMetricsRequest) ProtoReflect() protoreflect.Mess return mi.MessageOf(x) } -// Deprecated: Use ResolveCategoryCategoryMetricsRequest.ProtoReflect.Descriptor instead. -func (*ResolveCategoryCategoryMetricsRequest) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{135} +// Deprecated: Use ResolveProductProductDetailsRequest.ProtoReflect.Descriptor instead. +func (*ResolveProductProductDetailsRequest) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{139} } -func (x *ResolveCategoryCategoryMetricsRequest) GetContext() []*ResolveCategoryCategoryMetricsContext { +func (x *ResolveProductProductDetailsRequest) GetContext() []*ResolveProductProductDetailsContext { if x != nil { return x.Context } return nil } -func (x *ResolveCategoryCategoryMetricsRequest) GetFieldArgs() *ResolveCategoryCategoryMetricsArgs { +func (x *ResolveProductProductDetailsRequest) GetFieldArgs() *ResolveProductProductDetailsArgs { if x != nil { return x.FieldArgs } return nil } -type ResolveCategoryCategoryMetricsResult struct { - state protoimpl.MessageState `protogen:"open.v1"` - CategoryMetrics *CategoryMetrics `protobuf:"bytes,1,opt,name=category_metrics,json=categoryMetrics,proto3" json:"category_metrics,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +type ResolveProductProductDetailsResult struct { + state protoimpl.MessageState `protogen:"open.v1"` + ProductDetails *ProductDetails `protobuf:"bytes,1,opt,name=product_details,json=productDetails,proto3" json:"product_details,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *ResolveCategoryCategoryMetricsResult) Reset() { - *x = ResolveCategoryCategoryMetricsResult{} - mi := &file_product_proto_msgTypes[136] +func (x *ResolveProductProductDetailsResult) Reset() { + *x = ResolveProductProductDetailsResult{} + mi := &file_product_proto_msgTypes[140] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *ResolveCategoryCategoryMetricsResult) String() string { +func (x *ResolveProductProductDetailsResult) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ResolveCategoryCategoryMetricsResult) ProtoMessage() {} +func (*ResolveProductProductDetailsResult) ProtoMessage() {} -func (x *ResolveCategoryCategoryMetricsResult) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[136] +func (x *ResolveProductProductDetailsResult) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[140] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6324,40 +6520,40 @@ func (x *ResolveCategoryCategoryMetricsResult) ProtoReflect() protoreflect.Messa return mi.MessageOf(x) } -// Deprecated: Use ResolveCategoryCategoryMetricsResult.ProtoReflect.Descriptor instead. -func (*ResolveCategoryCategoryMetricsResult) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{136} +// Deprecated: Use ResolveProductProductDetailsResult.ProtoReflect.Descriptor instead. +func (*ResolveProductProductDetailsResult) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{140} } -func (x *ResolveCategoryCategoryMetricsResult) GetCategoryMetrics() *CategoryMetrics { +func (x *ResolveProductProductDetailsResult) GetProductDetails() *ProductDetails { if x != nil { - return x.CategoryMetrics + return x.ProductDetails } return nil } -type ResolveCategoryCategoryMetricsResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - Result []*ResolveCategoryCategoryMetricsResult `protobuf:"bytes,1,rep,name=result,proto3" json:"result,omitempty"` +type ResolveProductProductDetailsResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Result []*ResolveProductProductDetailsResult `protobuf:"bytes,1,rep,name=result,proto3" json:"result,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *ResolveCategoryCategoryMetricsResponse) Reset() { - *x = ResolveCategoryCategoryMetricsResponse{} - mi := &file_product_proto_msgTypes[137] +func (x *ResolveProductProductDetailsResponse) Reset() { + *x = ResolveProductProductDetailsResponse{} + mi := &file_product_proto_msgTypes[141] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *ResolveCategoryCategoryMetricsResponse) String() string { +func (x *ResolveProductProductDetailsResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ResolveCategoryCategoryMetricsResponse) ProtoMessage() {} +func (*ResolveProductProductDetailsResponse) ProtoMessage() {} -func (x *ResolveCategoryCategoryMetricsResponse) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[137] +func (x *ResolveProductProductDetailsResponse) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[141] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6368,40 +6564,40 @@ func (x *ResolveCategoryCategoryMetricsResponse) ProtoReflect() protoreflect.Mes return mi.MessageOf(x) } -// Deprecated: Use ResolveCategoryCategoryMetricsResponse.ProtoReflect.Descriptor instead. -func (*ResolveCategoryCategoryMetricsResponse) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{137} +// Deprecated: Use ResolveProductProductDetailsResponse.ProtoReflect.Descriptor instead. +func (*ResolveProductProductDetailsResponse) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{141} } -func (x *ResolveCategoryCategoryMetricsResponse) GetResult() []*ResolveCategoryCategoryMetricsResult { +func (x *ResolveProductProductDetailsResponse) GetResult() []*ResolveProductProductDetailsResult { if x != nil { return x.Result } return nil } -type ResolveSubcategoryItemCountArgs struct { +type ResolveCategoryProductCountArgs struct { state protoimpl.MessageState `protogen:"open.v1"` - Filters *SubcategoryItemFilter `protobuf:"bytes,1,opt,name=filters,proto3" json:"filters,omitempty"` + Filters *ProductCountFilter `protobuf:"bytes,1,opt,name=filters,proto3" json:"filters,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *ResolveSubcategoryItemCountArgs) Reset() { - *x = ResolveSubcategoryItemCountArgs{} - mi := &file_product_proto_msgTypes[138] +func (x *ResolveCategoryProductCountArgs) Reset() { + *x = ResolveCategoryProductCountArgs{} + mi := &file_product_proto_msgTypes[142] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *ResolveSubcategoryItemCountArgs) String() string { +func (x *ResolveCategoryProductCountArgs) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ResolveSubcategoryItemCountArgs) ProtoMessage() {} +func (*ResolveCategoryProductCountArgs) ProtoMessage() {} -func (x *ResolveSubcategoryItemCountArgs) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[138] +func (x *ResolveCategoryProductCountArgs) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[142] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6412,40 +6608,41 @@ func (x *ResolveSubcategoryItemCountArgs) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ResolveSubcategoryItemCountArgs.ProtoReflect.Descriptor instead. -func (*ResolveSubcategoryItemCountArgs) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{138} +// Deprecated: Use ResolveCategoryProductCountArgs.ProtoReflect.Descriptor instead. +func (*ResolveCategoryProductCountArgs) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{142} } -func (x *ResolveSubcategoryItemCountArgs) GetFilters() *SubcategoryItemFilter { +func (x *ResolveCategoryProductCountArgs) GetFilters() *ProductCountFilter { if x != nil { return x.Filters } return nil } -type ResolveSubcategoryItemCountContext struct { +type ResolveCategoryProductCountContext struct { state protoimpl.MessageState `protogen:"open.v1"` Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *ResolveSubcategoryItemCountContext) Reset() { - *x = ResolveSubcategoryItemCountContext{} - mi := &file_product_proto_msgTypes[139] +func (x *ResolveCategoryProductCountContext) Reset() { + *x = ResolveCategoryProductCountContext{} + mi := &file_product_proto_msgTypes[143] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *ResolveSubcategoryItemCountContext) String() string { +func (x *ResolveCategoryProductCountContext) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ResolveSubcategoryItemCountContext) ProtoMessage() {} +func (*ResolveCategoryProductCountContext) ProtoMessage() {} -func (x *ResolveSubcategoryItemCountContext) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[139] +func (x *ResolveCategoryProductCountContext) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[143] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6456,43 +6653,50 @@ func (x *ResolveSubcategoryItemCountContext) ProtoReflect() protoreflect.Message return mi.MessageOf(x) } -// Deprecated: Use ResolveSubcategoryItemCountContext.ProtoReflect.Descriptor instead. -func (*ResolveSubcategoryItemCountContext) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{139} +// Deprecated: Use ResolveCategoryProductCountContext.ProtoReflect.Descriptor instead. +func (*ResolveCategoryProductCountContext) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{143} } -func (x *ResolveSubcategoryItemCountContext) GetId() string { +func (x *ResolveCategoryProductCountContext) GetId() string { if x != nil { return x.Id } return "" } -type ResolveSubcategoryItemCountRequest struct { +func (x *ResolveCategoryProductCountContext) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +type ResolveCategoryProductCountRequest struct { state protoimpl.MessageState `protogen:"open.v1"` - // context provides the resolver context for the field itemCount of type Subcategory. - Context []*ResolveSubcategoryItemCountContext `protobuf:"bytes,1,rep,name=context,proto3" json:"context,omitempty"` - // field_args provides the arguments for the resolver field itemCount of type Subcategory. - FieldArgs *ResolveSubcategoryItemCountArgs `protobuf:"bytes,2,opt,name=field_args,json=fieldArgs,proto3" json:"field_args,omitempty"` + // context provides the resolver context for the field productCount of type Category. + Context []*ResolveCategoryProductCountContext `protobuf:"bytes,1,rep,name=context,proto3" json:"context,omitempty"` + // field_args provides the arguments for the resolver field productCount of type Category. + FieldArgs *ResolveCategoryProductCountArgs `protobuf:"bytes,2,opt,name=field_args,json=fieldArgs,proto3" json:"field_args,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *ResolveSubcategoryItemCountRequest) Reset() { - *x = ResolveSubcategoryItemCountRequest{} - mi := &file_product_proto_msgTypes[140] +func (x *ResolveCategoryProductCountRequest) Reset() { + *x = ResolveCategoryProductCountRequest{} + mi := &file_product_proto_msgTypes[144] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *ResolveSubcategoryItemCountRequest) String() string { +func (x *ResolveCategoryProductCountRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ResolveSubcategoryItemCountRequest) ProtoMessage() {} +func (*ResolveCategoryProductCountRequest) ProtoMessage() {} -func (x *ResolveSubcategoryItemCountRequest) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[140] +func (x *ResolveCategoryProductCountRequest) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[144] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6503,47 +6707,47 @@ func (x *ResolveSubcategoryItemCountRequest) ProtoReflect() protoreflect.Message return mi.MessageOf(x) } -// Deprecated: Use ResolveSubcategoryItemCountRequest.ProtoReflect.Descriptor instead. -func (*ResolveSubcategoryItemCountRequest) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{140} +// Deprecated: Use ResolveCategoryProductCountRequest.ProtoReflect.Descriptor instead. +func (*ResolveCategoryProductCountRequest) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{144} } -func (x *ResolveSubcategoryItemCountRequest) GetContext() []*ResolveSubcategoryItemCountContext { +func (x *ResolveCategoryProductCountRequest) GetContext() []*ResolveCategoryProductCountContext { if x != nil { return x.Context } return nil } -func (x *ResolveSubcategoryItemCountRequest) GetFieldArgs() *ResolveSubcategoryItemCountArgs { +func (x *ResolveCategoryProductCountRequest) GetFieldArgs() *ResolveCategoryProductCountArgs { if x != nil { return x.FieldArgs } return nil } -type ResolveSubcategoryItemCountResult struct { +type ResolveCategoryProductCountResult struct { state protoimpl.MessageState `protogen:"open.v1"` - ItemCount int32 `protobuf:"varint,1,opt,name=item_count,json=itemCount,proto3" json:"item_count,omitempty"` + ProductCount int32 `protobuf:"varint,1,opt,name=product_count,json=productCount,proto3" json:"product_count,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *ResolveSubcategoryItemCountResult) Reset() { - *x = ResolveSubcategoryItemCountResult{} - mi := &file_product_proto_msgTypes[141] +func (x *ResolveCategoryProductCountResult) Reset() { + *x = ResolveCategoryProductCountResult{} + mi := &file_product_proto_msgTypes[145] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *ResolveSubcategoryItemCountResult) String() string { +func (x *ResolveCategoryProductCountResult) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ResolveSubcategoryItemCountResult) ProtoMessage() {} +func (*ResolveCategoryProductCountResult) ProtoMessage() {} -func (x *ResolveSubcategoryItemCountResult) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[141] +func (x *ResolveCategoryProductCountResult) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[145] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6554,40 +6758,40 @@ func (x *ResolveSubcategoryItemCountResult) ProtoReflect() protoreflect.Message return mi.MessageOf(x) } -// Deprecated: Use ResolveSubcategoryItemCountResult.ProtoReflect.Descriptor instead. -func (*ResolveSubcategoryItemCountResult) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{141} +// Deprecated: Use ResolveCategoryProductCountResult.ProtoReflect.Descriptor instead. +func (*ResolveCategoryProductCountResult) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{145} } -func (x *ResolveSubcategoryItemCountResult) GetItemCount() int32 { +func (x *ResolveCategoryProductCountResult) GetProductCount() int32 { if x != nil { - return x.ItemCount + return x.ProductCount } return 0 } -type ResolveSubcategoryItemCountResponse struct { +type ResolveCategoryProductCountResponse struct { state protoimpl.MessageState `protogen:"open.v1"` - Result []*ResolveSubcategoryItemCountResult `protobuf:"bytes,1,rep,name=result,proto3" json:"result,omitempty"` + Result []*ResolveCategoryProductCountResult `protobuf:"bytes,1,rep,name=result,proto3" json:"result,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *ResolveSubcategoryItemCountResponse) Reset() { - *x = ResolveSubcategoryItemCountResponse{} - mi := &file_product_proto_msgTypes[142] +func (x *ResolveCategoryProductCountResponse) Reset() { + *x = ResolveCategoryProductCountResponse{} + mi := &file_product_proto_msgTypes[146] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *ResolveSubcategoryItemCountResponse) String() string { +func (x *ResolveCategoryProductCountResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ResolveSubcategoryItemCountResponse) ProtoMessage() {} +func (*ResolveCategoryProductCountResponse) ProtoMessage() {} -func (x *ResolveSubcategoryItemCountResponse) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[142] +func (x *ResolveCategoryProductCountResponse) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[146] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6598,42 +6802,40 @@ func (x *ResolveSubcategoryItemCountResponse) ProtoReflect() protoreflect.Messag return mi.MessageOf(x) } -// Deprecated: Use ResolveSubcategoryItemCountResponse.ProtoReflect.Descriptor instead. -func (*ResolveSubcategoryItemCountResponse) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{142} +// Deprecated: Use ResolveCategoryProductCountResponse.ProtoReflect.Descriptor instead. +func (*ResolveCategoryProductCountResponse) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{146} } -func (x *ResolveSubcategoryItemCountResponse) GetResult() []*ResolveSubcategoryItemCountResult { +func (x *ResolveCategoryProductCountResponse) GetResult() []*ResolveCategoryProductCountResult { if x != nil { return x.Result } return nil } -type Product struct { +type ResolveCategoryPopularityScoreArgs struct { state protoimpl.MessageState `protogen:"open.v1"` - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - Price float64 `protobuf:"fixed64,3,opt,name=price,proto3" json:"price,omitempty"` + Threshold *wrapperspb.Int32Value `protobuf:"bytes,1,opt,name=threshold,proto3" json:"threshold,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *Product) Reset() { - *x = Product{} - mi := &file_product_proto_msgTypes[143] +func (x *ResolveCategoryPopularityScoreArgs) Reset() { + *x = ResolveCategoryPopularityScoreArgs{} + mi := &file_product_proto_msgTypes[147] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *Product) String() string { +func (x *ResolveCategoryPopularityScoreArgs) String() string { return protoimpl.X.MessageStringOf(x) } -func (*Product) ProtoMessage() {} +func (*ResolveCategoryPopularityScoreArgs) ProtoMessage() {} -func (x *Product) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[143] +func (x *ResolveCategoryPopularityScoreArgs) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[147] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6644,56 +6846,40 @@ func (x *Product) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use Product.ProtoReflect.Descriptor instead. -func (*Product) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{143} -} - -func (x *Product) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *Product) GetName() string { - if x != nil { - return x.Name - } - return "" +// Deprecated: Use ResolveCategoryPopularityScoreArgs.ProtoReflect.Descriptor instead. +func (*ResolveCategoryPopularityScoreArgs) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{147} } -func (x *Product) GetPrice() float64 { +func (x *ResolveCategoryPopularityScoreArgs) GetThreshold() *wrapperspb.Int32Value { if x != nil { - return x.Price + return x.Threshold } - return 0 + return nil } -type Storage struct { +type ResolveCategoryPopularityScoreContext struct { state protoimpl.MessageState `protogen:"open.v1"` Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - Location string `protobuf:"bytes,3,opt,name=location,proto3" json:"location,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *Storage) Reset() { - *x = Storage{} - mi := &file_product_proto_msgTypes[144] +func (x *ResolveCategoryPopularityScoreContext) Reset() { + *x = ResolveCategoryPopularityScoreContext{} + mi := &file_product_proto_msgTypes[148] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *Storage) String() string { +func (x *ResolveCategoryPopularityScoreContext) String() string { return protoimpl.X.MessageStringOf(x) } -func (*Storage) ProtoMessage() {} +func (*ResolveCategoryPopularityScoreContext) ProtoMessage() {} -func (x *Storage) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[144] +func (x *ResolveCategoryPopularityScoreContext) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[148] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6704,56 +6890,43 @@ func (x *Storage) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use Storage.ProtoReflect.Descriptor instead. -func (*Storage) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{144} +// Deprecated: Use ResolveCategoryPopularityScoreContext.ProtoReflect.Descriptor instead. +func (*ResolveCategoryPopularityScoreContext) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{148} } -func (x *Storage) GetId() string { +func (x *ResolveCategoryPopularityScoreContext) GetId() string { if x != nil { return x.Id } return "" } -func (x *Storage) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *Storage) GetLocation() string { - if x != nil { - return x.Location - } - return "" -} - -type Warehouse struct { - state protoimpl.MessageState `protogen:"open.v1"` - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - Location string `protobuf:"bytes,3,opt,name=location,proto3" json:"location,omitempty"` +type ResolveCategoryPopularityScoreRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // context provides the resolver context for the field popularityScore of type Category. + Context []*ResolveCategoryPopularityScoreContext `protobuf:"bytes,1,rep,name=context,proto3" json:"context,omitempty"` + // field_args provides the arguments for the resolver field popularityScore of type Category. + FieldArgs *ResolveCategoryPopularityScoreArgs `protobuf:"bytes,2,opt,name=field_args,json=fieldArgs,proto3" json:"field_args,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *Warehouse) Reset() { - *x = Warehouse{} - mi := &file_product_proto_msgTypes[145] +func (x *ResolveCategoryPopularityScoreRequest) Reset() { + *x = ResolveCategoryPopularityScoreRequest{} + mi := &file_product_proto_msgTypes[149] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *Warehouse) String() string { +func (x *ResolveCategoryPopularityScoreRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*Warehouse) ProtoMessage() {} +func (*ResolveCategoryPopularityScoreRequest) ProtoMessage() {} -func (x *Warehouse) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[145] +func (x *ResolveCategoryPopularityScoreRequest) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[149] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6764,55 +6937,47 @@ func (x *Warehouse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use Warehouse.ProtoReflect.Descriptor instead. -func (*Warehouse) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{145} -} - -func (x *Warehouse) GetId() string { - if x != nil { - return x.Id - } - return "" +// Deprecated: Use ResolveCategoryPopularityScoreRequest.ProtoReflect.Descriptor instead. +func (*ResolveCategoryPopularityScoreRequest) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{149} } -func (x *Warehouse) GetName() string { +func (x *ResolveCategoryPopularityScoreRequest) GetContext() []*ResolveCategoryPopularityScoreContext { if x != nil { - return x.Name + return x.Context } - return "" + return nil } -func (x *Warehouse) GetLocation() string { +func (x *ResolveCategoryPopularityScoreRequest) GetFieldArgs() *ResolveCategoryPopularityScoreArgs { if x != nil { - return x.Location + return x.FieldArgs } - return "" + return nil } -type User struct { - state protoimpl.MessageState `protogen:"open.v1"` - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +type ResolveCategoryPopularityScoreResult struct { + state protoimpl.MessageState `protogen:"open.v1"` + PopularityScore *wrapperspb.Int32Value `protobuf:"bytes,1,opt,name=popularity_score,json=popularityScore,proto3" json:"popularity_score,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *User) Reset() { - *x = User{} - mi := &file_product_proto_msgTypes[146] +func (x *ResolveCategoryPopularityScoreResult) Reset() { + *x = ResolveCategoryPopularityScoreResult{} + mi := &file_product_proto_msgTypes[150] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *User) String() string { +func (x *ResolveCategoryPopularityScoreResult) String() string { return protoimpl.X.MessageStringOf(x) } -func (*User) ProtoMessage() {} +func (*ResolveCategoryPopularityScoreResult) ProtoMessage() {} -func (x *User) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[146] +func (x *ResolveCategoryPopularityScoreResult) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[150] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6823,49 +6988,40 @@ func (x *User) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use User.ProtoReflect.Descriptor instead. -func (*User) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{146} -} - -func (x *User) GetId() string { - if x != nil { - return x.Id - } - return "" +// Deprecated: Use ResolveCategoryPopularityScoreResult.ProtoReflect.Descriptor instead. +func (*ResolveCategoryPopularityScoreResult) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{150} } -func (x *User) GetName() string { +func (x *ResolveCategoryPopularityScoreResult) GetPopularityScore() *wrapperspb.Int32Value { if x != nil { - return x.Name + return x.PopularityScore } - return "" + return nil } -type NestedTypeA struct { - state protoimpl.MessageState `protogen:"open.v1"` - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - B *NestedTypeB `protobuf:"bytes,3,opt,name=b,proto3" json:"b,omitempty"` +type ResolveCategoryPopularityScoreResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Result []*ResolveCategoryPopularityScoreResult `protobuf:"bytes,1,rep,name=result,proto3" json:"result,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *NestedTypeA) Reset() { - *x = NestedTypeA{} - mi := &file_product_proto_msgTypes[147] +func (x *ResolveCategoryPopularityScoreResponse) Reset() { + *x = ResolveCategoryPopularityScoreResponse{} + mi := &file_product_proto_msgTypes[151] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *NestedTypeA) String() string { +func (x *ResolveCategoryPopularityScoreResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*NestedTypeA) ProtoMessage() {} +func (*ResolveCategoryPopularityScoreResponse) ProtoMessage() {} -func (x *NestedTypeA) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[147] +func (x *ResolveCategoryPopularityScoreResponse) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[151] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6876,56 +7032,40 @@ func (x *NestedTypeA) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use NestedTypeA.ProtoReflect.Descriptor instead. -func (*NestedTypeA) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{147} -} - -func (x *NestedTypeA) GetId() string { - if x != nil { - return x.Id - } - return "" +// Deprecated: Use ResolveCategoryPopularityScoreResponse.ProtoReflect.Descriptor instead. +func (*ResolveCategoryPopularityScoreResponse) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{151} } -func (x *NestedTypeA) GetName() string { +func (x *ResolveCategoryPopularityScoreResponse) GetResult() []*ResolveCategoryPopularityScoreResult { if x != nil { - return x.Name + return x.Result } - return "" + return nil } -func (x *NestedTypeA) GetB() *NestedTypeB { - if x != nil { - return x.B - } - return nil -} - -type RecursiveType struct { +type ResolveCategoryCategoryMetricsArgs struct { state protoimpl.MessageState `protogen:"open.v1"` - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - RecursiveType *RecursiveType `protobuf:"bytes,3,opt,name=recursive_type,json=recursiveType,proto3" json:"recursive_type,omitempty"` + MetricType string `protobuf:"bytes,1,opt,name=metric_type,json=metricType,proto3" json:"metric_type,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *RecursiveType) Reset() { - *x = RecursiveType{} - mi := &file_product_proto_msgTypes[148] +func (x *ResolveCategoryCategoryMetricsArgs) Reset() { + *x = ResolveCategoryCategoryMetricsArgs{} + mi := &file_product_proto_msgTypes[152] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *RecursiveType) String() string { +func (x *ResolveCategoryCategoryMetricsArgs) String() string { return protoimpl.X.MessageStringOf(x) } -func (*RecursiveType) ProtoMessage() {} +func (*ResolveCategoryCategoryMetricsArgs) ProtoMessage() {} -func (x *RecursiveType) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[148] +func (x *ResolveCategoryCategoryMetricsArgs) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[152] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6936,57 +7076,41 @@ func (x *RecursiveType) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use RecursiveType.ProtoReflect.Descriptor instead. -func (*RecursiveType) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{148} -} - -func (x *RecursiveType) GetId() string { - if x != nil { - return x.Id - } - return "" +// Deprecated: Use ResolveCategoryCategoryMetricsArgs.ProtoReflect.Descriptor instead. +func (*ResolveCategoryCategoryMetricsArgs) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{152} } -func (x *RecursiveType) GetName() string { +func (x *ResolveCategoryCategoryMetricsArgs) GetMetricType() string { if x != nil { - return x.Name + return x.MetricType } return "" } -func (x *RecursiveType) GetRecursiveType() *RecursiveType { - if x != nil { - return x.RecursiveType - } - return nil -} - -type TypeWithMultipleFilterFields struct { +type ResolveCategoryCategoryMetricsContext struct { state protoimpl.MessageState `protogen:"open.v1"` Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - FilterField_1 string `protobuf:"bytes,3,opt,name=filter_field_1,json=filterField1,proto3" json:"filter_field_1,omitempty"` - FilterField_2 string `protobuf:"bytes,4,opt,name=filter_field_2,json=filterField2,proto3" json:"filter_field_2,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *TypeWithMultipleFilterFields) Reset() { - *x = TypeWithMultipleFilterFields{} - mi := &file_product_proto_msgTypes[149] +func (x *ResolveCategoryCategoryMetricsContext) Reset() { + *x = ResolveCategoryCategoryMetricsContext{} + mi := &file_product_proto_msgTypes[153] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *TypeWithMultipleFilterFields) String() string { +func (x *ResolveCategoryCategoryMetricsContext) String() string { return protoimpl.X.MessageStringOf(x) } -func (*TypeWithMultipleFilterFields) ProtoMessage() {} +func (*ResolveCategoryCategoryMetricsContext) ProtoMessage() {} -func (x *TypeWithMultipleFilterFields) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[149] +func (x *ResolveCategoryCategoryMetricsContext) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[153] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6997,62 +7121,50 @@ func (x *TypeWithMultipleFilterFields) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use TypeWithMultipleFilterFields.ProtoReflect.Descriptor instead. -func (*TypeWithMultipleFilterFields) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{149} +// Deprecated: Use ResolveCategoryCategoryMetricsContext.ProtoReflect.Descriptor instead. +func (*ResolveCategoryCategoryMetricsContext) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{153} } -func (x *TypeWithMultipleFilterFields) GetId() string { +func (x *ResolveCategoryCategoryMetricsContext) GetId() string { if x != nil { return x.Id } return "" } -func (x *TypeWithMultipleFilterFields) GetName() string { +func (x *ResolveCategoryCategoryMetricsContext) GetName() string { if x != nil { return x.Name } return "" } -func (x *TypeWithMultipleFilterFields) GetFilterField_1() string { - if x != nil { - return x.FilterField_1 - } - return "" -} - -func (x *TypeWithMultipleFilterFields) GetFilterField_2() string { - if x != nil { - return x.FilterField_2 - } - return "" -} - -type FilterTypeInput struct { - state protoimpl.MessageState `protogen:"open.v1"` - FilterField_1 string `protobuf:"bytes,1,opt,name=filter_field_1,json=filterField1,proto3" json:"filter_field_1,omitempty"` - FilterField_2 string `protobuf:"bytes,2,opt,name=filter_field_2,json=filterField2,proto3" json:"filter_field_2,omitempty"` +type ResolveCategoryCategoryMetricsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // context provides the resolver context for the field categoryMetrics of type Category. + Context []*ResolveCategoryCategoryMetricsContext `protobuf:"bytes,1,rep,name=context,proto3" json:"context,omitempty"` + // field_args provides the arguments for the resolver field categoryMetrics of type Category. + FieldArgs *ResolveCategoryCategoryMetricsArgs `protobuf:"bytes,2,opt,name=field_args,json=fieldArgs,proto3" json:"field_args,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *FilterTypeInput) Reset() { - *x = FilterTypeInput{} - mi := &file_product_proto_msgTypes[150] +func (x *ResolveCategoryCategoryMetricsRequest) Reset() { + *x = ResolveCategoryCategoryMetricsRequest{} + mi := &file_product_proto_msgTypes[154] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *FilterTypeInput) String() string { +func (x *ResolveCategoryCategoryMetricsRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*FilterTypeInput) ProtoMessage() {} +func (*ResolveCategoryCategoryMetricsRequest) ProtoMessage() {} -func (x *FilterTypeInput) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[150] +func (x *ResolveCategoryCategoryMetricsRequest) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[154] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7063,47 +7175,47 @@ func (x *FilterTypeInput) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use FilterTypeInput.ProtoReflect.Descriptor instead. -func (*FilterTypeInput) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{150} +// Deprecated: Use ResolveCategoryCategoryMetricsRequest.ProtoReflect.Descriptor instead. +func (*ResolveCategoryCategoryMetricsRequest) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{154} } -func (x *FilterTypeInput) GetFilterField_1() string { +func (x *ResolveCategoryCategoryMetricsRequest) GetContext() []*ResolveCategoryCategoryMetricsContext { if x != nil { - return x.FilterField_1 + return x.Context } - return "" + return nil } -func (x *FilterTypeInput) GetFilterField_2() string { +func (x *ResolveCategoryCategoryMetricsRequest) GetFieldArgs() *ResolveCategoryCategoryMetricsArgs { if x != nil { - return x.FilterField_2 + return x.FieldArgs } - return "" + return nil } -type ComplexFilterTypeInput struct { - state protoimpl.MessageState `protogen:"open.v1"` - Filter *FilterType `protobuf:"bytes,1,opt,name=filter,proto3" json:"filter,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +type ResolveCategoryCategoryMetricsResult struct { + state protoimpl.MessageState `protogen:"open.v1"` + CategoryMetrics *CategoryMetrics `protobuf:"bytes,1,opt,name=category_metrics,json=categoryMetrics,proto3" json:"category_metrics,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *ComplexFilterTypeInput) Reset() { - *x = ComplexFilterTypeInput{} - mi := &file_product_proto_msgTypes[151] +func (x *ResolveCategoryCategoryMetricsResult) Reset() { + *x = ResolveCategoryCategoryMetricsResult{} + mi := &file_product_proto_msgTypes[155] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *ComplexFilterTypeInput) String() string { +func (x *ResolveCategoryCategoryMetricsResult) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ComplexFilterTypeInput) ProtoMessage() {} +func (*ResolveCategoryCategoryMetricsResult) ProtoMessage() {} -func (x *ComplexFilterTypeInput) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[151] +func (x *ResolveCategoryCategoryMetricsResult) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[155] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7114,41 +7226,40 @@ func (x *ComplexFilterTypeInput) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ComplexFilterTypeInput.ProtoReflect.Descriptor instead. -func (*ComplexFilterTypeInput) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{151} +// Deprecated: Use ResolveCategoryCategoryMetricsResult.ProtoReflect.Descriptor instead. +func (*ResolveCategoryCategoryMetricsResult) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{155} } -func (x *ComplexFilterTypeInput) GetFilter() *FilterType { +func (x *ResolveCategoryCategoryMetricsResult) GetCategoryMetrics() *CategoryMetrics { if x != nil { - return x.Filter + return x.CategoryMetrics } return nil } -type TypeWithComplexFilterInput struct { - state protoimpl.MessageState `protogen:"open.v1"` - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` +type ResolveCategoryCategoryMetricsResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Result []*ResolveCategoryCategoryMetricsResult `protobuf:"bytes,1,rep,name=result,proto3" json:"result,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *TypeWithComplexFilterInput) Reset() { - *x = TypeWithComplexFilterInput{} - mi := &file_product_proto_msgTypes[152] +func (x *ResolveCategoryCategoryMetricsResponse) Reset() { + *x = ResolveCategoryCategoryMetricsResponse{} + mi := &file_product_proto_msgTypes[156] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *TypeWithComplexFilterInput) String() string { +func (x *ResolveCategoryCategoryMetricsResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*TypeWithComplexFilterInput) ProtoMessage() {} +func (*ResolveCategoryCategoryMetricsResponse) ProtoMessage() {} -func (x *TypeWithComplexFilterInput) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[152] +func (x *ResolveCategoryCategoryMetricsResponse) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[156] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7159,49 +7270,40 @@ func (x *TypeWithComplexFilterInput) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use TypeWithComplexFilterInput.ProtoReflect.Descriptor instead. -func (*TypeWithComplexFilterInput) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{152} -} - -func (x *TypeWithComplexFilterInput) GetId() string { - if x != nil { - return x.Id - } - return "" +// Deprecated: Use ResolveCategoryCategoryMetricsResponse.ProtoReflect.Descriptor instead. +func (*ResolveCategoryCategoryMetricsResponse) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{156} } -func (x *TypeWithComplexFilterInput) GetName() string { +func (x *ResolveCategoryCategoryMetricsResponse) GetResult() []*ResolveCategoryCategoryMetricsResult { if x != nil { - return x.Name + return x.Result } - return "" + return nil } -type OrderInput struct { +type ResolveCategoryMascotArgs struct { state protoimpl.MessageState `protogen:"open.v1"` - OrderId string `protobuf:"bytes,1,opt,name=order_id,json=orderId,proto3" json:"order_id,omitempty"` - CustomerName string `protobuf:"bytes,2,opt,name=customer_name,json=customerName,proto3" json:"customer_name,omitempty"` - Lines []*OrderLineInput `protobuf:"bytes,3,rep,name=lines,proto3" json:"lines,omitempty"` + IncludeVolume bool `protobuf:"varint,1,opt,name=include_volume,json=includeVolume,proto3" json:"include_volume,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *OrderInput) Reset() { - *x = OrderInput{} - mi := &file_product_proto_msgTypes[153] +func (x *ResolveCategoryMascotArgs) Reset() { + *x = ResolveCategoryMascotArgs{} + mi := &file_product_proto_msgTypes[157] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *OrderInput) String() string { +func (x *ResolveCategoryMascotArgs) String() string { return protoimpl.X.MessageStringOf(x) } -func (*OrderInput) ProtoMessage() {} +func (*ResolveCategoryMascotArgs) ProtoMessage() {} -func (x *OrderInput) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[153] +func (x *ResolveCategoryMascotArgs) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[157] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7212,57 +7314,41 @@ func (x *OrderInput) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use OrderInput.ProtoReflect.Descriptor instead. -func (*OrderInput) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{153} -} - -func (x *OrderInput) GetOrderId() string { - if x != nil { - return x.OrderId - } - return "" -} - -func (x *OrderInput) GetCustomerName() string { - if x != nil { - return x.CustomerName - } - return "" +// Deprecated: Use ResolveCategoryMascotArgs.ProtoReflect.Descriptor instead. +func (*ResolveCategoryMascotArgs) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{157} } -func (x *OrderInput) GetLines() []*OrderLineInput { +func (x *ResolveCategoryMascotArgs) GetIncludeVolume() bool { if x != nil { - return x.Lines + return x.IncludeVolume } - return nil + return false } -type Order struct { +type ResolveCategoryMascotContext struct { state protoimpl.MessageState `protogen:"open.v1"` - OrderId string `protobuf:"bytes,1,opt,name=order_id,json=orderId,proto3" json:"order_id,omitempty"` - CustomerName string `protobuf:"bytes,2,opt,name=customer_name,json=customerName,proto3" json:"customer_name,omitempty"` - TotalItems int32 `protobuf:"varint,3,opt,name=total_items,json=totalItems,proto3" json:"total_items,omitempty"` - OrderLines *ListOfOrderLine `protobuf:"bytes,4,opt,name=order_lines,json=orderLines,proto3" json:"order_lines,omitempty"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Kind CategoryKind `protobuf:"varint,2,opt,name=kind,proto3,enum=productv1.CategoryKind" json:"kind,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *Order) Reset() { - *x = Order{} - mi := &file_product_proto_msgTypes[154] +func (x *ResolveCategoryMascotContext) Reset() { + *x = ResolveCategoryMascotContext{} + mi := &file_product_proto_msgTypes[158] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *Order) String() string { +func (x *ResolveCategoryMascotContext) String() string { return protoimpl.X.MessageStringOf(x) } -func (*Order) ProtoMessage() {} +func (*ResolveCategoryMascotContext) ProtoMessage() {} -func (x *Order) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[154] +func (x *ResolveCategoryMascotContext) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[158] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7273,64 +7359,50 @@ func (x *Order) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use Order.ProtoReflect.Descriptor instead. -func (*Order) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{154} -} - -func (x *Order) GetOrderId() string { - if x != nil { - return x.OrderId - } - return "" +// Deprecated: Use ResolveCategoryMascotContext.ProtoReflect.Descriptor instead. +func (*ResolveCategoryMascotContext) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{158} } -func (x *Order) GetCustomerName() string { +func (x *ResolveCategoryMascotContext) GetId() string { if x != nil { - return x.CustomerName + return x.Id } return "" } -func (x *Order) GetTotalItems() int32 { - if x != nil { - return x.TotalItems - } - return 0 -} - -func (x *Order) GetOrderLines() *ListOfOrderLine { +func (x *ResolveCategoryMascotContext) GetKind() CategoryKind { if x != nil { - return x.OrderLines + return x.Kind } - return nil + return CategoryKind_CATEGORY_KIND_UNSPECIFIED } -type Category struct { - state protoimpl.MessageState `protogen:"open.v1"` - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - Kind CategoryKind `protobuf:"varint,3,opt,name=kind,proto3,enum=productv1.CategoryKind" json:"kind,omitempty"` - Subcategories *ListOfSubcategory `protobuf:"bytes,5,opt,name=subcategories,proto3" json:"subcategories,omitempty"` +type ResolveCategoryMascotRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // context provides the resolver context for the field mascot of type Category. + Context []*ResolveCategoryMascotContext `protobuf:"bytes,1,rep,name=context,proto3" json:"context,omitempty"` + // field_args provides the arguments for the resolver field mascot of type Category. + FieldArgs *ResolveCategoryMascotArgs `protobuf:"bytes,2,opt,name=field_args,json=fieldArgs,proto3" json:"field_args,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *Category) Reset() { - *x = Category{} - mi := &file_product_proto_msgTypes[155] +func (x *ResolveCategoryMascotRequest) Reset() { + *x = ResolveCategoryMascotRequest{} + mi := &file_product_proto_msgTypes[159] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *Category) String() string { +func (x *ResolveCategoryMascotRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*Category) ProtoMessage() {} +func (*ResolveCategoryMascotRequest) ProtoMessage() {} -func (x *Category) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[155] +func (x *ResolveCategoryMascotRequest) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[159] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7341,62 +7413,47 @@ func (x *Category) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use Category.ProtoReflect.Descriptor instead. -func (*Category) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{155} -} - -func (x *Category) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *Category) GetName() string { - if x != nil { - return x.Name - } - return "" +// Deprecated: Use ResolveCategoryMascotRequest.ProtoReflect.Descriptor instead. +func (*ResolveCategoryMascotRequest) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{159} } -func (x *Category) GetKind() CategoryKind { +func (x *ResolveCategoryMascotRequest) GetContext() []*ResolveCategoryMascotContext { if x != nil { - return x.Kind + return x.Context } - return CategoryKind_CATEGORY_KIND_UNSPECIFIED + return nil } -func (x *Category) GetSubcategories() *ListOfSubcategory { +func (x *ResolveCategoryMascotRequest) GetFieldArgs() *ResolveCategoryMascotArgs { if x != nil { - return x.Subcategories + return x.FieldArgs } return nil } -type CategoryFilter struct { +type ResolveCategoryMascotResult struct { state protoimpl.MessageState `protogen:"open.v1"` - Category CategoryKind `protobuf:"varint,1,opt,name=category,proto3,enum=productv1.CategoryKind" json:"category,omitempty"` - Pagination *Pagination `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` + Mascot *Animal `protobuf:"bytes,1,opt,name=mascot,proto3" json:"mascot,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *CategoryFilter) Reset() { - *x = CategoryFilter{} - mi := &file_product_proto_msgTypes[156] +func (x *ResolveCategoryMascotResult) Reset() { + *x = ResolveCategoryMascotResult{} + mi := &file_product_proto_msgTypes[160] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *CategoryFilter) String() string { +func (x *ResolveCategoryMascotResult) String() string { return protoimpl.X.MessageStringOf(x) } -func (*CategoryFilter) ProtoMessage() {} +func (*ResolveCategoryMascotResult) ProtoMessage() {} -func (x *CategoryFilter) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[156] +func (x *ResolveCategoryMascotResult) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[160] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7407,51 +7464,40 @@ func (x *CategoryFilter) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use CategoryFilter.ProtoReflect.Descriptor instead. -func (*CategoryFilter) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{156} -} - -func (x *CategoryFilter) GetCategory() CategoryKind { - if x != nil { - return x.Category - } - return CategoryKind_CATEGORY_KIND_UNSPECIFIED +// Deprecated: Use ResolveCategoryMascotResult.ProtoReflect.Descriptor instead. +func (*ResolveCategoryMascotResult) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{160} } -func (x *CategoryFilter) GetPagination() *Pagination { +func (x *ResolveCategoryMascotResult) GetMascot() *Animal { if x != nil { - return x.Pagination + return x.Mascot } return nil } -type Animal struct { - state protoimpl.MessageState `protogen:"open.v1"` - // Types that are valid to be assigned to Instance: - // - // *Animal_Cat - // *Animal_Dog - Instance isAnimal_Instance `protobuf_oneof:"instance"` +type ResolveCategoryMascotResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Result []*ResolveCategoryMascotResult `protobuf:"bytes,1,rep,name=result,proto3" json:"result,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *Animal) Reset() { - *x = Animal{} - mi := &file_product_proto_msgTypes[157] +func (x *ResolveCategoryMascotResponse) Reset() { + *x = ResolveCategoryMascotResponse{} + mi := &file_product_proto_msgTypes[161] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *Animal) String() string { +func (x *ResolveCategoryMascotResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*Animal) ProtoMessage() {} +func (*ResolveCategoryMascotResponse) ProtoMessage() {} -func (x *Animal) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[157] +func (x *ResolveCategoryMascotResponse) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[161] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7462,75 +7508,85 @@ func (x *Animal) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use Animal.ProtoReflect.Descriptor instead. -func (*Animal) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{157} +// Deprecated: Use ResolveCategoryMascotResponse.ProtoReflect.Descriptor instead. +func (*ResolveCategoryMascotResponse) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{161} } -func (x *Animal) GetInstance() isAnimal_Instance { +func (x *ResolveCategoryMascotResponse) GetResult() []*ResolveCategoryMascotResult { if x != nil { - return x.Instance + return x.Result } return nil } -func (x *Animal) GetCat() *Cat { - if x != nil { - if x, ok := x.Instance.(*Animal_Cat); ok { - return x.Cat - } - } - return nil +type ResolveCategoryCategoryStatusArgs struct { + state protoimpl.MessageState `protogen:"open.v1"` + CheckHealth bool `protobuf:"varint,1,opt,name=check_health,json=checkHealth,proto3" json:"check_health,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *Animal) GetDog() *Dog { - if x != nil { - if x, ok := x.Instance.(*Animal_Dog); ok { - return x.Dog - } - } - return nil +func (x *ResolveCategoryCategoryStatusArgs) Reset() { + *x = ResolveCategoryCategoryStatusArgs{} + mi := &file_product_proto_msgTypes[162] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } -type isAnimal_Instance interface { - isAnimal_Instance() +func (x *ResolveCategoryCategoryStatusArgs) String() string { + return protoimpl.X.MessageStringOf(x) } -type Animal_Cat struct { - Cat *Cat `protobuf:"bytes,1,opt,name=cat,proto3,oneof"` -} +func (*ResolveCategoryCategoryStatusArgs) ProtoMessage() {} -type Animal_Dog struct { - Dog *Dog `protobuf:"bytes,2,opt,name=dog,proto3,oneof"` +func (x *ResolveCategoryCategoryStatusArgs) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[162] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -func (*Animal_Cat) isAnimal_Instance() {} +// Deprecated: Use ResolveCategoryCategoryStatusArgs.ProtoReflect.Descriptor instead. +func (*ResolveCategoryCategoryStatusArgs) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{162} +} -func (*Animal_Dog) isAnimal_Instance() {} +func (x *ResolveCategoryCategoryStatusArgs) GetCheckHealth() bool { + if x != nil { + return x.CheckHealth + } + return false +} -type SearchInput struct { +type ResolveCategoryCategoryStatusContext struct { state protoimpl.MessageState `protogen:"open.v1"` - Query string `protobuf:"bytes,1,opt,name=query,proto3" json:"query,omitempty"` - Limit *wrapperspb.Int32Value `protobuf:"bytes,2,opt,name=limit,proto3" json:"limit,omitempty"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *SearchInput) Reset() { - *x = SearchInput{} - mi := &file_product_proto_msgTypes[158] +func (x *ResolveCategoryCategoryStatusContext) Reset() { + *x = ResolveCategoryCategoryStatusContext{} + mi := &file_product_proto_msgTypes[163] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *SearchInput) String() string { +func (x *ResolveCategoryCategoryStatusContext) String() string { return protoimpl.X.MessageStringOf(x) } -func (*SearchInput) ProtoMessage() {} +func (*ResolveCategoryCategoryStatusContext) ProtoMessage() {} -func (x *SearchInput) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[158] +func (x *ResolveCategoryCategoryStatusContext) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[163] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7541,52 +7597,50 @@ func (x *SearchInput) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use SearchInput.ProtoReflect.Descriptor instead. -func (*SearchInput) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{158} +// Deprecated: Use ResolveCategoryCategoryStatusContext.ProtoReflect.Descriptor instead. +func (*ResolveCategoryCategoryStatusContext) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{163} } -func (x *SearchInput) GetQuery() string { +func (x *ResolveCategoryCategoryStatusContext) GetId() string { if x != nil { - return x.Query + return x.Id } return "" } -func (x *SearchInput) GetLimit() *wrapperspb.Int32Value { +func (x *ResolveCategoryCategoryStatusContext) GetName() string { if x != nil { - return x.Limit + return x.Name } - return nil + return "" } -type SearchResult struct { +type ResolveCategoryCategoryStatusRequest struct { state protoimpl.MessageState `protogen:"open.v1"` - // Types that are valid to be assigned to Value: - // - // *SearchResult_Product - // *SearchResult_User - // *SearchResult_Category - Value isSearchResult_Value `protobuf_oneof:"value"` + // context provides the resolver context for the field categoryStatus of type Category. + Context []*ResolveCategoryCategoryStatusContext `protobuf:"bytes,1,rep,name=context,proto3" json:"context,omitempty"` + // field_args provides the arguments for the resolver field categoryStatus of type Category. + FieldArgs *ResolveCategoryCategoryStatusArgs `protobuf:"bytes,2,opt,name=field_args,json=fieldArgs,proto3" json:"field_args,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *SearchResult) Reset() { - *x = SearchResult{} - mi := &file_product_proto_msgTypes[159] +func (x *ResolveCategoryCategoryStatusRequest) Reset() { + *x = ResolveCategoryCategoryStatusRequest{} + mi := &file_product_proto_msgTypes[164] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *SearchResult) String() string { +func (x *ResolveCategoryCategoryStatusRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*SearchResult) ProtoMessage() {} +func (*ResolveCategoryCategoryStatusRequest) ProtoMessage() {} -func (x *SearchResult) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[159] +func (x *ResolveCategoryCategoryStatusRequest) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[164] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7597,96 +7651,2255 @@ func (x *SearchResult) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use SearchResult.ProtoReflect.Descriptor instead. -func (*SearchResult) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{159} +// Deprecated: Use ResolveCategoryCategoryStatusRequest.ProtoReflect.Descriptor instead. +func (*ResolveCategoryCategoryStatusRequest) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{164} } -func (x *SearchResult) GetValue() isSearchResult_Value { +func (x *ResolveCategoryCategoryStatusRequest) GetContext() []*ResolveCategoryCategoryStatusContext { if x != nil { - return x.Value + return x.Context } return nil } -func (x *SearchResult) GetProduct() *Product { +func (x *ResolveCategoryCategoryStatusRequest) GetFieldArgs() *ResolveCategoryCategoryStatusArgs { if x != nil { - if x, ok := x.Value.(*SearchResult_Product); ok { - return x.Product - } + return x.FieldArgs } return nil } -func (x *SearchResult) GetUser() *User { +type ResolveCategoryCategoryStatusResult struct { + state protoimpl.MessageState `protogen:"open.v1"` + CategoryStatus *ActionResult `protobuf:"bytes,1,opt,name=category_status,json=categoryStatus,proto3" json:"category_status,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ResolveCategoryCategoryStatusResult) Reset() { + *x = ResolveCategoryCategoryStatusResult{} + mi := &file_product_proto_msgTypes[165] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ResolveCategoryCategoryStatusResult) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResolveCategoryCategoryStatusResult) ProtoMessage() {} + +func (x *ResolveCategoryCategoryStatusResult) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[165] if x != nil { - if x, ok := x.Value.(*SearchResult_User); ok { - return x.User + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) } + return ms } - return nil + return mi.MessageOf(x) } -func (x *SearchResult) GetCategory() *Category { +// Deprecated: Use ResolveCategoryCategoryStatusResult.ProtoReflect.Descriptor instead. +func (*ResolveCategoryCategoryStatusResult) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{165} +} + +func (x *ResolveCategoryCategoryStatusResult) GetCategoryStatus() *ActionResult { if x != nil { - if x, ok := x.Value.(*SearchResult_Category); ok { - return x.Category - } + return x.CategoryStatus } return nil } -type isSearchResult_Value interface { - isSearchResult_Value() -} - -type SearchResult_Product struct { - Product *Product `protobuf:"bytes,1,opt,name=product,proto3,oneof"` +type ResolveCategoryCategoryStatusResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Result []*ResolveCategoryCategoryStatusResult `protobuf:"bytes,1,rep,name=result,proto3" json:"result,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ResolveCategoryCategoryStatusResponse) Reset() { + *x = ResolveCategoryCategoryStatusResponse{} + mi := &file_product_proto_msgTypes[166] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ResolveCategoryCategoryStatusResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResolveCategoryCategoryStatusResponse) ProtoMessage() {} + +func (x *ResolveCategoryCategoryStatusResponse) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[166] + 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 ResolveCategoryCategoryStatusResponse.ProtoReflect.Descriptor instead. +func (*ResolveCategoryCategoryStatusResponse) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{166} +} + +func (x *ResolveCategoryCategoryStatusResponse) GetResult() []*ResolveCategoryCategoryStatusResult { + if x != nil { + return x.Result + } + return nil +} + +type ResolveSubcategoryItemCountArgs struct { + state protoimpl.MessageState `protogen:"open.v1"` + Filters *SubcategoryItemFilter `protobuf:"bytes,1,opt,name=filters,proto3" json:"filters,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ResolveSubcategoryItemCountArgs) Reset() { + *x = ResolveSubcategoryItemCountArgs{} + mi := &file_product_proto_msgTypes[167] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ResolveSubcategoryItemCountArgs) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResolveSubcategoryItemCountArgs) ProtoMessage() {} + +func (x *ResolveSubcategoryItemCountArgs) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[167] + 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 ResolveSubcategoryItemCountArgs.ProtoReflect.Descriptor instead. +func (*ResolveSubcategoryItemCountArgs) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{167} +} + +func (x *ResolveSubcategoryItemCountArgs) GetFilters() *SubcategoryItemFilter { + if x != nil { + return x.Filters + } + return nil +} + +type ResolveSubcategoryItemCountContext struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ResolveSubcategoryItemCountContext) Reset() { + *x = ResolveSubcategoryItemCountContext{} + mi := &file_product_proto_msgTypes[168] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ResolveSubcategoryItemCountContext) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResolveSubcategoryItemCountContext) ProtoMessage() {} + +func (x *ResolveSubcategoryItemCountContext) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[168] + 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 ResolveSubcategoryItemCountContext.ProtoReflect.Descriptor instead. +func (*ResolveSubcategoryItemCountContext) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{168} +} + +func (x *ResolveSubcategoryItemCountContext) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +type ResolveSubcategoryItemCountRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // context provides the resolver context for the field itemCount of type Subcategory. + Context []*ResolveSubcategoryItemCountContext `protobuf:"bytes,1,rep,name=context,proto3" json:"context,omitempty"` + // field_args provides the arguments for the resolver field itemCount of type Subcategory. + FieldArgs *ResolveSubcategoryItemCountArgs `protobuf:"bytes,2,opt,name=field_args,json=fieldArgs,proto3" json:"field_args,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ResolveSubcategoryItemCountRequest) Reset() { + *x = ResolveSubcategoryItemCountRequest{} + mi := &file_product_proto_msgTypes[169] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ResolveSubcategoryItemCountRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResolveSubcategoryItemCountRequest) ProtoMessage() {} + +func (x *ResolveSubcategoryItemCountRequest) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[169] + 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 ResolveSubcategoryItemCountRequest.ProtoReflect.Descriptor instead. +func (*ResolveSubcategoryItemCountRequest) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{169} +} + +func (x *ResolveSubcategoryItemCountRequest) GetContext() []*ResolveSubcategoryItemCountContext { + if x != nil { + return x.Context + } + return nil +} + +func (x *ResolveSubcategoryItemCountRequest) GetFieldArgs() *ResolveSubcategoryItemCountArgs { + if x != nil { + return x.FieldArgs + } + return nil +} + +type ResolveSubcategoryItemCountResult struct { + state protoimpl.MessageState `protogen:"open.v1"` + ItemCount int32 `protobuf:"varint,1,opt,name=item_count,json=itemCount,proto3" json:"item_count,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ResolveSubcategoryItemCountResult) Reset() { + *x = ResolveSubcategoryItemCountResult{} + mi := &file_product_proto_msgTypes[170] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ResolveSubcategoryItemCountResult) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResolveSubcategoryItemCountResult) ProtoMessage() {} + +func (x *ResolveSubcategoryItemCountResult) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[170] + 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 ResolveSubcategoryItemCountResult.ProtoReflect.Descriptor instead. +func (*ResolveSubcategoryItemCountResult) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{170} +} + +func (x *ResolveSubcategoryItemCountResult) GetItemCount() int32 { + if x != nil { + return x.ItemCount + } + return 0 +} + +type ResolveSubcategoryItemCountResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Result []*ResolveSubcategoryItemCountResult `protobuf:"bytes,1,rep,name=result,proto3" json:"result,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ResolveSubcategoryItemCountResponse) Reset() { + *x = ResolveSubcategoryItemCountResponse{} + mi := &file_product_proto_msgTypes[171] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ResolveSubcategoryItemCountResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResolveSubcategoryItemCountResponse) ProtoMessage() {} + +func (x *ResolveSubcategoryItemCountResponse) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[171] + 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 ResolveSubcategoryItemCountResponse.ProtoReflect.Descriptor instead. +func (*ResolveSubcategoryItemCountResponse) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{171} +} + +func (x *ResolveSubcategoryItemCountResponse) GetResult() []*ResolveSubcategoryItemCountResult { + if x != nil { + return x.Result + } + return nil +} + +type ResolveCategoryMetricsNormalizedScoreArgs struct { + state protoimpl.MessageState `protogen:"open.v1"` + Baseline float64 `protobuf:"fixed64,1,opt,name=baseline,proto3" json:"baseline,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ResolveCategoryMetricsNormalizedScoreArgs) Reset() { + *x = ResolveCategoryMetricsNormalizedScoreArgs{} + mi := &file_product_proto_msgTypes[172] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ResolveCategoryMetricsNormalizedScoreArgs) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResolveCategoryMetricsNormalizedScoreArgs) ProtoMessage() {} + +func (x *ResolveCategoryMetricsNormalizedScoreArgs) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[172] + 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 ResolveCategoryMetricsNormalizedScoreArgs.ProtoReflect.Descriptor instead. +func (*ResolveCategoryMetricsNormalizedScoreArgs) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{172} +} + +func (x *ResolveCategoryMetricsNormalizedScoreArgs) GetBaseline() float64 { + if x != nil { + return x.Baseline + } + return 0 +} + +type ResolveCategoryMetricsNormalizedScoreContext struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + MetricType string `protobuf:"bytes,2,opt,name=metricType,proto3" json:"metricType,omitempty"` + Value float64 `protobuf:"fixed64,3,opt,name=value,proto3" json:"value,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ResolveCategoryMetricsNormalizedScoreContext) Reset() { + *x = ResolveCategoryMetricsNormalizedScoreContext{} + mi := &file_product_proto_msgTypes[173] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ResolveCategoryMetricsNormalizedScoreContext) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResolveCategoryMetricsNormalizedScoreContext) ProtoMessage() {} + +func (x *ResolveCategoryMetricsNormalizedScoreContext) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[173] + 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 ResolveCategoryMetricsNormalizedScoreContext.ProtoReflect.Descriptor instead. +func (*ResolveCategoryMetricsNormalizedScoreContext) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{173} +} + +func (x *ResolveCategoryMetricsNormalizedScoreContext) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *ResolveCategoryMetricsNormalizedScoreContext) GetMetricType() string { + if x != nil { + return x.MetricType + } + return "" +} + +func (x *ResolveCategoryMetricsNormalizedScoreContext) GetValue() float64 { + if x != nil { + return x.Value + } + return 0 +} + +type ResolveCategoryMetricsNormalizedScoreRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // context provides the resolver context for the field normalizedScore of type CategoryMetrics. + Context []*ResolveCategoryMetricsNormalizedScoreContext `protobuf:"bytes,1,rep,name=context,proto3" json:"context,omitempty"` + // field_args provides the arguments for the resolver field normalizedScore of type CategoryMetrics. + FieldArgs *ResolveCategoryMetricsNormalizedScoreArgs `protobuf:"bytes,2,opt,name=field_args,json=fieldArgs,proto3" json:"field_args,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ResolveCategoryMetricsNormalizedScoreRequest) Reset() { + *x = ResolveCategoryMetricsNormalizedScoreRequest{} + mi := &file_product_proto_msgTypes[174] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ResolveCategoryMetricsNormalizedScoreRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResolveCategoryMetricsNormalizedScoreRequest) ProtoMessage() {} + +func (x *ResolveCategoryMetricsNormalizedScoreRequest) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[174] + 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 ResolveCategoryMetricsNormalizedScoreRequest.ProtoReflect.Descriptor instead. +func (*ResolveCategoryMetricsNormalizedScoreRequest) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{174} +} + +func (x *ResolveCategoryMetricsNormalizedScoreRequest) GetContext() []*ResolveCategoryMetricsNormalizedScoreContext { + if x != nil { + return x.Context + } + return nil +} + +func (x *ResolveCategoryMetricsNormalizedScoreRequest) GetFieldArgs() *ResolveCategoryMetricsNormalizedScoreArgs { + if x != nil { + return x.FieldArgs + } + return nil +} + +type ResolveCategoryMetricsNormalizedScoreResult struct { + state protoimpl.MessageState `protogen:"open.v1"` + NormalizedScore float64 `protobuf:"fixed64,1,opt,name=normalized_score,json=normalizedScore,proto3" json:"normalized_score,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ResolveCategoryMetricsNormalizedScoreResult) Reset() { + *x = ResolveCategoryMetricsNormalizedScoreResult{} + mi := &file_product_proto_msgTypes[175] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ResolveCategoryMetricsNormalizedScoreResult) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResolveCategoryMetricsNormalizedScoreResult) ProtoMessage() {} + +func (x *ResolveCategoryMetricsNormalizedScoreResult) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[175] + 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 ResolveCategoryMetricsNormalizedScoreResult.ProtoReflect.Descriptor instead. +func (*ResolveCategoryMetricsNormalizedScoreResult) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{175} +} + +func (x *ResolveCategoryMetricsNormalizedScoreResult) GetNormalizedScore() float64 { + if x != nil { + return x.NormalizedScore + } + return 0 +} + +type ResolveCategoryMetricsNormalizedScoreResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Result []*ResolveCategoryMetricsNormalizedScoreResult `protobuf:"bytes,1,rep,name=result,proto3" json:"result,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ResolveCategoryMetricsNormalizedScoreResponse) Reset() { + *x = ResolveCategoryMetricsNormalizedScoreResponse{} + mi := &file_product_proto_msgTypes[176] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ResolveCategoryMetricsNormalizedScoreResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResolveCategoryMetricsNormalizedScoreResponse) ProtoMessage() {} + +func (x *ResolveCategoryMetricsNormalizedScoreResponse) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[176] + 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 ResolveCategoryMetricsNormalizedScoreResponse.ProtoReflect.Descriptor instead. +func (*ResolveCategoryMetricsNormalizedScoreResponse) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{176} +} + +func (x *ResolveCategoryMetricsNormalizedScoreResponse) GetResult() []*ResolveCategoryMetricsNormalizedScoreResult { + if x != nil { + return x.Result + } + return nil +} + +type ResolveTestContainerDetailsArgs struct { + state protoimpl.MessageState `protogen:"open.v1"` + IncludeExtended bool `protobuf:"varint,1,opt,name=include_extended,json=includeExtended,proto3" json:"include_extended,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ResolveTestContainerDetailsArgs) Reset() { + *x = ResolveTestContainerDetailsArgs{} + mi := &file_product_proto_msgTypes[177] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ResolveTestContainerDetailsArgs) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResolveTestContainerDetailsArgs) ProtoMessage() {} + +func (x *ResolveTestContainerDetailsArgs) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[177] + 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 ResolveTestContainerDetailsArgs.ProtoReflect.Descriptor instead. +func (*ResolveTestContainerDetailsArgs) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{177} +} + +func (x *ResolveTestContainerDetailsArgs) GetIncludeExtended() bool { + if x != nil { + return x.IncludeExtended + } + return false +} + +type ResolveTestContainerDetailsContext struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ResolveTestContainerDetailsContext) Reset() { + *x = ResolveTestContainerDetailsContext{} + mi := &file_product_proto_msgTypes[178] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ResolveTestContainerDetailsContext) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResolveTestContainerDetailsContext) ProtoMessage() {} + +func (x *ResolveTestContainerDetailsContext) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[178] + 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 ResolveTestContainerDetailsContext.ProtoReflect.Descriptor instead. +func (*ResolveTestContainerDetailsContext) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{178} +} + +func (x *ResolveTestContainerDetailsContext) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *ResolveTestContainerDetailsContext) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +type ResolveTestContainerDetailsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // context provides the resolver context for the field details of type TestContainer. + Context []*ResolveTestContainerDetailsContext `protobuf:"bytes,1,rep,name=context,proto3" json:"context,omitempty"` + // field_args provides the arguments for the resolver field details of type TestContainer. + FieldArgs *ResolveTestContainerDetailsArgs `protobuf:"bytes,2,opt,name=field_args,json=fieldArgs,proto3" json:"field_args,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ResolveTestContainerDetailsRequest) Reset() { + *x = ResolveTestContainerDetailsRequest{} + mi := &file_product_proto_msgTypes[179] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ResolveTestContainerDetailsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResolveTestContainerDetailsRequest) ProtoMessage() {} + +func (x *ResolveTestContainerDetailsRequest) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[179] + 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 ResolveTestContainerDetailsRequest.ProtoReflect.Descriptor instead. +func (*ResolveTestContainerDetailsRequest) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{179} +} + +func (x *ResolveTestContainerDetailsRequest) GetContext() []*ResolveTestContainerDetailsContext { + if x != nil { + return x.Context + } + return nil +} + +func (x *ResolveTestContainerDetailsRequest) GetFieldArgs() *ResolveTestContainerDetailsArgs { + if x != nil { + return x.FieldArgs + } + return nil +} + +type ResolveTestContainerDetailsResult struct { + state protoimpl.MessageState `protogen:"open.v1"` + Details *TestDetails `protobuf:"bytes,1,opt,name=details,proto3" json:"details,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ResolveTestContainerDetailsResult) Reset() { + *x = ResolveTestContainerDetailsResult{} + mi := &file_product_proto_msgTypes[180] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ResolveTestContainerDetailsResult) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResolveTestContainerDetailsResult) ProtoMessage() {} + +func (x *ResolveTestContainerDetailsResult) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[180] + 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 ResolveTestContainerDetailsResult.ProtoReflect.Descriptor instead. +func (*ResolveTestContainerDetailsResult) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{180} +} + +func (x *ResolveTestContainerDetailsResult) GetDetails() *TestDetails { + if x != nil { + return x.Details + } + return nil +} + +type ResolveTestContainerDetailsResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Result []*ResolveTestContainerDetailsResult `protobuf:"bytes,1,rep,name=result,proto3" json:"result,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ResolveTestContainerDetailsResponse) Reset() { + *x = ResolveTestContainerDetailsResponse{} + mi := &file_product_proto_msgTypes[181] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ResolveTestContainerDetailsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResolveTestContainerDetailsResponse) ProtoMessage() {} + +func (x *ResolveTestContainerDetailsResponse) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[181] + 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 ResolveTestContainerDetailsResponse.ProtoReflect.Descriptor instead. +func (*ResolveTestContainerDetailsResponse) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{181} +} + +func (x *ResolveTestContainerDetailsResponse) GetResult() []*ResolveTestContainerDetailsResult { + if x != nil { + return x.Result + } + return nil +} + +type Product struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Price float64 `protobuf:"fixed64,3,opt,name=price,proto3" json:"price,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Product) Reset() { + *x = Product{} + mi := &file_product_proto_msgTypes[182] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Product) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Product) ProtoMessage() {} + +func (x *Product) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[182] + 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 Product.ProtoReflect.Descriptor instead. +func (*Product) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{182} +} + +func (x *Product) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Product) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Product) GetPrice() float64 { + if x != nil { + return x.Price + } + return 0 +} + +type Storage struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Location string `protobuf:"bytes,3,opt,name=location,proto3" json:"location,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Storage) Reset() { + *x = Storage{} + mi := &file_product_proto_msgTypes[183] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Storage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Storage) ProtoMessage() {} + +func (x *Storage) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[183] + 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 Storage.ProtoReflect.Descriptor instead. +func (*Storage) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{183} +} + +func (x *Storage) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Storage) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Storage) GetLocation() string { + if x != nil { + return x.Location + } + return "" +} + +type Warehouse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Location string `protobuf:"bytes,3,opt,name=location,proto3" json:"location,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Warehouse) Reset() { + *x = Warehouse{} + mi := &file_product_proto_msgTypes[184] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Warehouse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Warehouse) ProtoMessage() {} + +func (x *Warehouse) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[184] + 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 Warehouse.ProtoReflect.Descriptor instead. +func (*Warehouse) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{184} +} + +func (x *Warehouse) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Warehouse) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Warehouse) GetLocation() string { + if x != nil { + return x.Location + } + return "" +} + +type User struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *User) Reset() { + *x = User{} + mi := &file_product_proto_msgTypes[185] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *User) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*User) ProtoMessage() {} + +func (x *User) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[185] + 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 User.ProtoReflect.Descriptor instead. +func (*User) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{185} +} + +func (x *User) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *User) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +type NestedTypeA struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + B *NestedTypeB `protobuf:"bytes,3,opt,name=b,proto3" json:"b,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *NestedTypeA) Reset() { + *x = NestedTypeA{} + mi := &file_product_proto_msgTypes[186] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *NestedTypeA) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NestedTypeA) ProtoMessage() {} + +func (x *NestedTypeA) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[186] + 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 NestedTypeA.ProtoReflect.Descriptor instead. +func (*NestedTypeA) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{186} +} + +func (x *NestedTypeA) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *NestedTypeA) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *NestedTypeA) GetB() *NestedTypeB { + if x != nil { + return x.B + } + return nil +} + +type RecursiveType struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + RecursiveType *RecursiveType `protobuf:"bytes,3,opt,name=recursive_type,json=recursiveType,proto3" json:"recursive_type,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RecursiveType) Reset() { + *x = RecursiveType{} + mi := &file_product_proto_msgTypes[187] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RecursiveType) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RecursiveType) ProtoMessage() {} + +func (x *RecursiveType) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[187] + 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 RecursiveType.ProtoReflect.Descriptor instead. +func (*RecursiveType) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{187} +} + +func (x *RecursiveType) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *RecursiveType) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *RecursiveType) GetRecursiveType() *RecursiveType { + if x != nil { + return x.RecursiveType + } + return nil +} + +type TypeWithMultipleFilterFields struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + FilterField_1 string `protobuf:"bytes,3,opt,name=filter_field_1,json=filterField1,proto3" json:"filter_field_1,omitempty"` + FilterField_2 string `protobuf:"bytes,4,opt,name=filter_field_2,json=filterField2,proto3" json:"filter_field_2,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *TypeWithMultipleFilterFields) Reset() { + *x = TypeWithMultipleFilterFields{} + mi := &file_product_proto_msgTypes[188] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *TypeWithMultipleFilterFields) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TypeWithMultipleFilterFields) ProtoMessage() {} + +func (x *TypeWithMultipleFilterFields) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[188] + 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 TypeWithMultipleFilterFields.ProtoReflect.Descriptor instead. +func (*TypeWithMultipleFilterFields) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{188} +} + +func (x *TypeWithMultipleFilterFields) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *TypeWithMultipleFilterFields) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *TypeWithMultipleFilterFields) GetFilterField_1() string { + if x != nil { + return x.FilterField_1 + } + return "" +} + +func (x *TypeWithMultipleFilterFields) GetFilterField_2() string { + if x != nil { + return x.FilterField_2 + } + return "" +} + +type FilterTypeInput struct { + state protoimpl.MessageState `protogen:"open.v1"` + FilterField_1 string `protobuf:"bytes,1,opt,name=filter_field_1,json=filterField1,proto3" json:"filter_field_1,omitempty"` + FilterField_2 string `protobuf:"bytes,2,opt,name=filter_field_2,json=filterField2,proto3" json:"filter_field_2,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *FilterTypeInput) Reset() { + *x = FilterTypeInput{} + mi := &file_product_proto_msgTypes[189] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *FilterTypeInput) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FilterTypeInput) ProtoMessage() {} + +func (x *FilterTypeInput) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[189] + 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 FilterTypeInput.ProtoReflect.Descriptor instead. +func (*FilterTypeInput) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{189} +} + +func (x *FilterTypeInput) GetFilterField_1() string { + if x != nil { + return x.FilterField_1 + } + return "" +} + +func (x *FilterTypeInput) GetFilterField_2() string { + if x != nil { + return x.FilterField_2 + } + return "" +} + +type ComplexFilterTypeInput struct { + state protoimpl.MessageState `protogen:"open.v1"` + Filter *FilterType `protobuf:"bytes,1,opt,name=filter,proto3" json:"filter,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ComplexFilterTypeInput) Reset() { + *x = ComplexFilterTypeInput{} + mi := &file_product_proto_msgTypes[190] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ComplexFilterTypeInput) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ComplexFilterTypeInput) ProtoMessage() {} + +func (x *ComplexFilterTypeInput) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[190] + 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 ComplexFilterTypeInput.ProtoReflect.Descriptor instead. +func (*ComplexFilterTypeInput) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{190} +} + +func (x *ComplexFilterTypeInput) GetFilter() *FilterType { + if x != nil { + return x.Filter + } + return nil +} + +type TypeWithComplexFilterInput struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *TypeWithComplexFilterInput) Reset() { + *x = TypeWithComplexFilterInput{} + mi := &file_product_proto_msgTypes[191] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *TypeWithComplexFilterInput) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TypeWithComplexFilterInput) ProtoMessage() {} + +func (x *TypeWithComplexFilterInput) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[191] + 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 TypeWithComplexFilterInput.ProtoReflect.Descriptor instead. +func (*TypeWithComplexFilterInput) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{191} +} + +func (x *TypeWithComplexFilterInput) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *TypeWithComplexFilterInput) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +type OrderInput struct { + state protoimpl.MessageState `protogen:"open.v1"` + OrderId string `protobuf:"bytes,1,opt,name=order_id,json=orderId,proto3" json:"order_id,omitempty"` + CustomerName string `protobuf:"bytes,2,opt,name=customer_name,json=customerName,proto3" json:"customer_name,omitempty"` + Lines []*OrderLineInput `protobuf:"bytes,3,rep,name=lines,proto3" json:"lines,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *OrderInput) Reset() { + *x = OrderInput{} + mi := &file_product_proto_msgTypes[192] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *OrderInput) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OrderInput) ProtoMessage() {} + +func (x *OrderInput) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[192] + 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 OrderInput.ProtoReflect.Descriptor instead. +func (*OrderInput) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{192} +} + +func (x *OrderInput) GetOrderId() string { + if x != nil { + return x.OrderId + } + return "" +} + +func (x *OrderInput) GetCustomerName() string { + if x != nil { + return x.CustomerName + } + return "" +} + +func (x *OrderInput) GetLines() []*OrderLineInput { + if x != nil { + return x.Lines + } + return nil +} + +type Order struct { + state protoimpl.MessageState `protogen:"open.v1"` + OrderId string `protobuf:"bytes,1,opt,name=order_id,json=orderId,proto3" json:"order_id,omitempty"` + CustomerName string `protobuf:"bytes,2,opt,name=customer_name,json=customerName,proto3" json:"customer_name,omitempty"` + TotalItems int32 `protobuf:"varint,3,opt,name=total_items,json=totalItems,proto3" json:"total_items,omitempty"` + OrderLines *ListOfOrderLine `protobuf:"bytes,4,opt,name=order_lines,json=orderLines,proto3" json:"order_lines,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Order) Reset() { + *x = Order{} + mi := &file_product_proto_msgTypes[193] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Order) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Order) ProtoMessage() {} + +func (x *Order) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[193] + 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 Order.ProtoReflect.Descriptor instead. +func (*Order) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{193} +} + +func (x *Order) GetOrderId() string { + if x != nil { + return x.OrderId + } + return "" +} + +func (x *Order) GetCustomerName() string { + if x != nil { + return x.CustomerName + } + return "" +} + +func (x *Order) GetTotalItems() int32 { + if x != nil { + return x.TotalItems + } + return 0 +} + +func (x *Order) GetOrderLines() *ListOfOrderLine { + if x != nil { + return x.OrderLines + } + return nil +} + +type Category struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Kind CategoryKind `protobuf:"varint,3,opt,name=kind,proto3,enum=productv1.CategoryKind" json:"kind,omitempty"` + Subcategories *ListOfSubcategory `protobuf:"bytes,5,opt,name=subcategories,proto3" json:"subcategories,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Category) Reset() { + *x = Category{} + mi := &file_product_proto_msgTypes[194] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Category) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Category) ProtoMessage() {} + +func (x *Category) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[194] + 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 Category.ProtoReflect.Descriptor instead. +func (*Category) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{194} +} + +func (x *Category) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Category) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Category) GetKind() CategoryKind { + if x != nil { + return x.Kind + } + return CategoryKind_CATEGORY_KIND_UNSPECIFIED +} + +func (x *Category) GetSubcategories() *ListOfSubcategory { + if x != nil { + return x.Subcategories + } + return nil +} + +type CategoryFilter struct { + state protoimpl.MessageState `protogen:"open.v1"` + Category CategoryKind `protobuf:"varint,1,opt,name=category,proto3,enum=productv1.CategoryKind" json:"category,omitempty"` + Pagination *Pagination `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CategoryFilter) Reset() { + *x = CategoryFilter{} + mi := &file_product_proto_msgTypes[195] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CategoryFilter) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CategoryFilter) ProtoMessage() {} + +func (x *CategoryFilter) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[195] + 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 CategoryFilter.ProtoReflect.Descriptor instead. +func (*CategoryFilter) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{195} +} + +func (x *CategoryFilter) GetCategory() CategoryKind { + if x != nil { + return x.Category + } + return CategoryKind_CATEGORY_KIND_UNSPECIFIED +} + +func (x *CategoryFilter) GetPagination() *Pagination { + if x != nil { + return x.Pagination + } + return nil +} + +type Animal struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Instance: + // + // *Animal_Cat + // *Animal_Dog + Instance isAnimal_Instance `protobuf_oneof:"instance"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Animal) Reset() { + *x = Animal{} + mi := &file_product_proto_msgTypes[196] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Animal) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Animal) ProtoMessage() {} + +func (x *Animal) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[196] + 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 Animal.ProtoReflect.Descriptor instead. +func (*Animal) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{196} +} + +func (x *Animal) GetInstance() isAnimal_Instance { + if x != nil { + return x.Instance + } + return nil +} + +func (x *Animal) GetCat() *Cat { + if x != nil { + if x, ok := x.Instance.(*Animal_Cat); ok { + return x.Cat + } + } + return nil +} + +func (x *Animal) GetDog() *Dog { + if x != nil { + if x, ok := x.Instance.(*Animal_Dog); ok { + return x.Dog + } + } + return nil +} + +type isAnimal_Instance interface { + isAnimal_Instance() +} + +type Animal_Cat struct { + Cat *Cat `protobuf:"bytes,1,opt,name=cat,proto3,oneof"` +} + +type Animal_Dog struct { + Dog *Dog `protobuf:"bytes,2,opt,name=dog,proto3,oneof"` +} + +func (*Animal_Cat) isAnimal_Instance() {} + +func (*Animal_Dog) isAnimal_Instance() {} + +type SearchInput struct { + state protoimpl.MessageState `protogen:"open.v1"` + Query string `protobuf:"bytes,1,opt,name=query,proto3" json:"query,omitempty"` + Limit *wrapperspb.Int32Value `protobuf:"bytes,2,opt,name=limit,proto3" json:"limit,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SearchInput) Reset() { + *x = SearchInput{} + mi := &file_product_proto_msgTypes[197] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SearchInput) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SearchInput) ProtoMessage() {} + +func (x *SearchInput) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[197] + 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 SearchInput.ProtoReflect.Descriptor instead. +func (*SearchInput) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{197} +} + +func (x *SearchInput) GetQuery() string { + if x != nil { + return x.Query + } + return "" +} + +func (x *SearchInput) GetLimit() *wrapperspb.Int32Value { + if x != nil { + return x.Limit + } + return nil +} + +type SearchResult struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Value: + // + // *SearchResult_Product + // *SearchResult_User + // *SearchResult_Category + Value isSearchResult_Value `protobuf_oneof:"value"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SearchResult) Reset() { + *x = SearchResult{} + mi := &file_product_proto_msgTypes[198] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SearchResult) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SearchResult) ProtoMessage() {} + +func (x *SearchResult) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[198] + 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 SearchResult.ProtoReflect.Descriptor instead. +func (*SearchResult) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{198} +} + +func (x *SearchResult) GetValue() isSearchResult_Value { + if x != nil { + return x.Value + } + return nil +} + +func (x *SearchResult) GetProduct() *Product { + if x != nil { + if x, ok := x.Value.(*SearchResult_Product); ok { + return x.Product + } + } + return nil +} + +func (x *SearchResult) GetUser() *User { + if x != nil { + if x, ok := x.Value.(*SearchResult_User); ok { + return x.User + } + } + return nil +} + +func (x *SearchResult) GetCategory() *Category { + if x != nil { + if x, ok := x.Value.(*SearchResult_Category); ok { + return x.Category + } + } + return nil +} + +type isSearchResult_Value interface { + isSearchResult_Value() +} + +type SearchResult_Product struct { + Product *Product `protobuf:"bytes,1,opt,name=product,proto3,oneof"` } type SearchResult_User struct { User *User `protobuf:"bytes,2,opt,name=user,proto3,oneof"` } -type SearchResult_Category struct { - Category *Category `protobuf:"bytes,3,opt,name=category,proto3,oneof"` +type SearchResult_Category struct { + Category *Category `protobuf:"bytes,3,opt,name=category,proto3,oneof"` +} + +func (*SearchResult_Product) isSearchResult_Value() {} + +func (*SearchResult_User) isSearchResult_Value() {} + +func (*SearchResult_Category) isSearchResult_Value() {} + +type NullableFieldsType struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + OptionalString *wrapperspb.StringValue `protobuf:"bytes,3,opt,name=optional_string,json=optionalString,proto3" json:"optional_string,omitempty"` + OptionalInt *wrapperspb.Int32Value `protobuf:"bytes,4,opt,name=optional_int,json=optionalInt,proto3" json:"optional_int,omitempty"` + OptionalFloat *wrapperspb.DoubleValue `protobuf:"bytes,5,opt,name=optional_float,json=optionalFloat,proto3" json:"optional_float,omitempty"` + OptionalBoolean *wrapperspb.BoolValue `protobuf:"bytes,6,opt,name=optional_boolean,json=optionalBoolean,proto3" json:"optional_boolean,omitempty"` + RequiredString string `protobuf:"bytes,7,opt,name=required_string,json=requiredString,proto3" json:"required_string,omitempty"` + RequiredInt int32 `protobuf:"varint,8,opt,name=required_int,json=requiredInt,proto3" json:"required_int,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *NullableFieldsType) Reset() { + *x = NullableFieldsType{} + mi := &file_product_proto_msgTypes[199] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *NullableFieldsType) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NullableFieldsType) ProtoMessage() {} + +func (x *NullableFieldsType) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[199] + 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 NullableFieldsType.ProtoReflect.Descriptor instead. +func (*NullableFieldsType) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{199} +} + +func (x *NullableFieldsType) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *NullableFieldsType) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *NullableFieldsType) GetOptionalString() *wrapperspb.StringValue { + if x != nil { + return x.OptionalString + } + return nil +} + +func (x *NullableFieldsType) GetOptionalInt() *wrapperspb.Int32Value { + if x != nil { + return x.OptionalInt + } + return nil +} + +func (x *NullableFieldsType) GetOptionalFloat() *wrapperspb.DoubleValue { + if x != nil { + return x.OptionalFloat + } + return nil +} + +func (x *NullableFieldsType) GetOptionalBoolean() *wrapperspb.BoolValue { + if x != nil { + return x.OptionalBoolean + } + return nil +} + +func (x *NullableFieldsType) GetRequiredString() string { + if x != nil { + return x.RequiredString + } + return "" +} + +func (x *NullableFieldsType) GetRequiredInt() int32 { + if x != nil { + return x.RequiredInt + } + return 0 +} + +type NullableFieldsFilter struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name *wrapperspb.StringValue `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + OptionalString *wrapperspb.StringValue `protobuf:"bytes,2,opt,name=optional_string,json=optionalString,proto3" json:"optional_string,omitempty"` + IncludeNulls *wrapperspb.BoolValue `protobuf:"bytes,3,opt,name=include_nulls,json=includeNulls,proto3" json:"include_nulls,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *NullableFieldsFilter) Reset() { + *x = NullableFieldsFilter{} + mi := &file_product_proto_msgTypes[200] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *NullableFieldsFilter) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NullableFieldsFilter) ProtoMessage() {} + +func (x *NullableFieldsFilter) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[200] + 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 NullableFieldsFilter.ProtoReflect.Descriptor instead. +func (*NullableFieldsFilter) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{200} +} + +func (x *NullableFieldsFilter) GetName() *wrapperspb.StringValue { + if x != nil { + return x.Name + } + return nil +} + +func (x *NullableFieldsFilter) GetOptionalString() *wrapperspb.StringValue { + if x != nil { + return x.OptionalString + } + return nil +} + +func (x *NullableFieldsFilter) GetIncludeNulls() *wrapperspb.BoolValue { + if x != nil { + return x.IncludeNulls + } + return nil +} + +type BlogPost struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Title string `protobuf:"bytes,2,opt,name=title,proto3" json:"title,omitempty"` + Content string `protobuf:"bytes,3,opt,name=content,proto3" json:"content,omitempty"` + Tags []string `protobuf:"bytes,4,rep,name=tags,proto3" json:"tags,omitempty"` + OptionalTags *ListOfString `protobuf:"bytes,5,opt,name=optional_tags,json=optionalTags,proto3" json:"optional_tags,omitempty"` + Categories []string `protobuf:"bytes,6,rep,name=categories,proto3" json:"categories,omitempty"` + Keywords *ListOfString `protobuf:"bytes,7,opt,name=keywords,proto3" json:"keywords,omitempty"` + ViewCounts []int32 `protobuf:"varint,8,rep,packed,name=view_counts,json=viewCounts,proto3" json:"view_counts,omitempty"` + Ratings *ListOfFloat `protobuf:"bytes,9,opt,name=ratings,proto3" json:"ratings,omitempty"` + IsPublished *ListOfBoolean `protobuf:"bytes,10,opt,name=is_published,json=isPublished,proto3" json:"is_published,omitempty"` + TagGroups *ListOfListOfString `protobuf:"bytes,11,opt,name=tag_groups,json=tagGroups,proto3" json:"tag_groups,omitempty"` + RelatedTopics *ListOfListOfString `protobuf:"bytes,12,opt,name=related_topics,json=relatedTopics,proto3" json:"related_topics,omitempty"` + CommentThreads *ListOfListOfString `protobuf:"bytes,13,opt,name=comment_threads,json=commentThreads,proto3" json:"comment_threads,omitempty"` + Suggestions *ListOfListOfString `protobuf:"bytes,14,opt,name=suggestions,proto3" json:"suggestions,omitempty"` + RelatedCategories []*Category `protobuf:"bytes,15,rep,name=related_categories,json=relatedCategories,proto3" json:"related_categories,omitempty"` + Contributors []*User `protobuf:"bytes,16,rep,name=contributors,proto3" json:"contributors,omitempty"` + MentionedProducts *ListOfProduct `protobuf:"bytes,17,opt,name=mentioned_products,json=mentionedProducts,proto3" json:"mentioned_products,omitempty"` + MentionedUsers *ListOfUser `protobuf:"bytes,18,opt,name=mentioned_users,json=mentionedUsers,proto3" json:"mentioned_users,omitempty"` + CategoryGroups *ListOfListOfCategory `protobuf:"bytes,19,opt,name=category_groups,json=categoryGroups,proto3" json:"category_groups,omitempty"` + ContributorTeams *ListOfListOfUser `protobuf:"bytes,20,opt,name=contributor_teams,json=contributorTeams,proto3" json:"contributor_teams,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *BlogPost) Reset() { + *x = BlogPost{} + mi := &file_product_proto_msgTypes[201] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *BlogPost) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BlogPost) ProtoMessage() {} + +func (x *BlogPost) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[201] + 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 BlogPost.ProtoReflect.Descriptor instead. +func (*BlogPost) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{201} +} + +func (x *BlogPost) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *BlogPost) GetTitle() string { + if x != nil { + return x.Title + } + return "" +} + +func (x *BlogPost) GetContent() string { + if x != nil { + return x.Content + } + return "" +} + +func (x *BlogPost) GetTags() []string { + if x != nil { + return x.Tags + } + return nil +} + +func (x *BlogPost) GetOptionalTags() *ListOfString { + if x != nil { + return x.OptionalTags + } + return nil +} + +func (x *BlogPost) GetCategories() []string { + if x != nil { + return x.Categories + } + return nil +} + +func (x *BlogPost) GetKeywords() *ListOfString { + if x != nil { + return x.Keywords + } + return nil +} + +func (x *BlogPost) GetViewCounts() []int32 { + if x != nil { + return x.ViewCounts + } + return nil +} + +func (x *BlogPost) GetRatings() *ListOfFloat { + if x != nil { + return x.Ratings + } + return nil +} + +func (x *BlogPost) GetIsPublished() *ListOfBoolean { + if x != nil { + return x.IsPublished + } + return nil +} + +func (x *BlogPost) GetTagGroups() *ListOfListOfString { + if x != nil { + return x.TagGroups + } + return nil +} + +func (x *BlogPost) GetRelatedTopics() *ListOfListOfString { + if x != nil { + return x.RelatedTopics + } + return nil +} + +func (x *BlogPost) GetCommentThreads() *ListOfListOfString { + if x != nil { + return x.CommentThreads + } + return nil +} + +func (x *BlogPost) GetSuggestions() *ListOfListOfString { + if x != nil { + return x.Suggestions + } + return nil +} + +func (x *BlogPost) GetRelatedCategories() []*Category { + if x != nil { + return x.RelatedCategories + } + return nil +} + +func (x *BlogPost) GetContributors() []*User { + if x != nil { + return x.Contributors + } + return nil } -func (*SearchResult_Product) isSearchResult_Value() {} +func (x *BlogPost) GetMentionedProducts() *ListOfProduct { + if x != nil { + return x.MentionedProducts + } + return nil +} -func (*SearchResult_User) isSearchResult_Value() {} +func (x *BlogPost) GetMentionedUsers() *ListOfUser { + if x != nil { + return x.MentionedUsers + } + return nil +} -func (*SearchResult_Category) isSearchResult_Value() {} +func (x *BlogPost) GetCategoryGroups() *ListOfListOfCategory { + if x != nil { + return x.CategoryGroups + } + return nil +} -type NullableFieldsType struct { - state protoimpl.MessageState `protogen:"open.v1"` - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - OptionalString *wrapperspb.StringValue `protobuf:"bytes,3,opt,name=optional_string,json=optionalString,proto3" json:"optional_string,omitempty"` - OptionalInt *wrapperspb.Int32Value `protobuf:"bytes,4,opt,name=optional_int,json=optionalInt,proto3" json:"optional_int,omitempty"` - OptionalFloat *wrapperspb.DoubleValue `protobuf:"bytes,5,opt,name=optional_float,json=optionalFloat,proto3" json:"optional_float,omitempty"` - OptionalBoolean *wrapperspb.BoolValue `protobuf:"bytes,6,opt,name=optional_boolean,json=optionalBoolean,proto3" json:"optional_boolean,omitempty"` - RequiredString string `protobuf:"bytes,7,opt,name=required_string,json=requiredString,proto3" json:"required_string,omitempty"` - RequiredInt int32 `protobuf:"varint,8,opt,name=required_int,json=requiredInt,proto3" json:"required_int,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +func (x *BlogPost) GetContributorTeams() *ListOfListOfUser { + if x != nil { + return x.ContributorTeams + } + return nil } -func (x *NullableFieldsType) Reset() { - *x = NullableFieldsType{} - mi := &file_product_proto_msgTypes[160] +type BlogPostFilter struct { + state protoimpl.MessageState `protogen:"open.v1"` + Title *wrapperspb.StringValue `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"` + HasCategories *wrapperspb.BoolValue `protobuf:"bytes,2,opt,name=has_categories,json=hasCategories,proto3" json:"has_categories,omitempty"` + MinTags *wrapperspb.Int32Value `protobuf:"bytes,3,opt,name=min_tags,json=minTags,proto3" json:"min_tags,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *BlogPostFilter) Reset() { + *x = BlogPostFilter{} + mi := &file_product_proto_msgTypes[202] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *NullableFieldsType) String() string { +func (x *BlogPostFilter) String() string { return protoimpl.X.MessageStringOf(x) } -func (*NullableFieldsType) ProtoMessage() {} +func (*BlogPostFilter) ProtoMessage() {} -func (x *NullableFieldsType) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[160] +func (x *BlogPostFilter) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[202] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7697,91 +9910,212 @@ func (x *NullableFieldsType) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use NullableFieldsType.ProtoReflect.Descriptor instead. -func (*NullableFieldsType) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{160} +// Deprecated: Use BlogPostFilter.ProtoReflect.Descriptor instead. +func (*BlogPostFilter) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{202} } -func (x *NullableFieldsType) GetId() string { +func (x *BlogPostFilter) GetTitle() *wrapperspb.StringValue { + if x != nil { + return x.Title + } + return nil +} + +func (x *BlogPostFilter) GetHasCategories() *wrapperspb.BoolValue { + if x != nil { + return x.HasCategories + } + return nil +} + +func (x *BlogPostFilter) GetMinTags() *wrapperspb.Int32Value { + if x != nil { + return x.MinTags + } + return nil +} + +type Author struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Email *wrapperspb.StringValue `protobuf:"bytes,3,opt,name=email,proto3" json:"email,omitempty"` + Skills []string `protobuf:"bytes,4,rep,name=skills,proto3" json:"skills,omitempty"` + Languages []string `protobuf:"bytes,5,rep,name=languages,proto3" json:"languages,omitempty"` + SocialLinks *ListOfString `protobuf:"bytes,6,opt,name=social_links,json=socialLinks,proto3" json:"social_links,omitempty"` + TeamsByProject *ListOfListOfString `protobuf:"bytes,7,opt,name=teams_by_project,json=teamsByProject,proto3" json:"teams_by_project,omitempty"` + Collaborations *ListOfListOfString `protobuf:"bytes,8,opt,name=collaborations,proto3" json:"collaborations,omitempty"` + WrittenPosts *ListOfBlogPost `protobuf:"bytes,9,opt,name=written_posts,json=writtenPosts,proto3" json:"written_posts,omitempty"` + FavoriteCategories []*Category `protobuf:"bytes,10,rep,name=favorite_categories,json=favoriteCategories,proto3" json:"favorite_categories,omitempty"` + RelatedAuthors *ListOfUser `protobuf:"bytes,11,opt,name=related_authors,json=relatedAuthors,proto3" json:"related_authors,omitempty"` + ProductReviews *ListOfProduct `protobuf:"bytes,12,opt,name=product_reviews,json=productReviews,proto3" json:"product_reviews,omitempty"` + AuthorGroups *ListOfListOfUser `protobuf:"bytes,13,opt,name=author_groups,json=authorGroups,proto3" json:"author_groups,omitempty"` + CategoryPreferences *ListOfListOfCategory `protobuf:"bytes,14,opt,name=category_preferences,json=categoryPreferences,proto3" json:"category_preferences,omitempty"` + ProjectTeams *ListOfListOfUser `protobuf:"bytes,15,opt,name=project_teams,json=projectTeams,proto3" json:"project_teams,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Author) Reset() { + *x = Author{} + mi := &file_product_proto_msgTypes[203] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Author) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Author) ProtoMessage() {} + +func (x *Author) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[203] + 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 Author.ProtoReflect.Descriptor instead. +func (*Author) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{203} +} + +func (x *Author) GetId() string { if x != nil { return x.Id } return "" } -func (x *NullableFieldsType) GetName() string { +func (x *Author) GetName() string { if x != nil { return x.Name } return "" } -func (x *NullableFieldsType) GetOptionalString() *wrapperspb.StringValue { +func (x *Author) GetEmail() *wrapperspb.StringValue { if x != nil { - return x.OptionalString + return x.Email } return nil } -func (x *NullableFieldsType) GetOptionalInt() *wrapperspb.Int32Value { +func (x *Author) GetSkills() []string { if x != nil { - return x.OptionalInt + return x.Skills } return nil } -func (x *NullableFieldsType) GetOptionalFloat() *wrapperspb.DoubleValue { +func (x *Author) GetLanguages() []string { if x != nil { - return x.OptionalFloat + return x.Languages } return nil } -func (x *NullableFieldsType) GetOptionalBoolean() *wrapperspb.BoolValue { +func (x *Author) GetSocialLinks() *ListOfString { if x != nil { - return x.OptionalBoolean + return x.SocialLinks } return nil } -func (x *NullableFieldsType) GetRequiredString() string { +func (x *Author) GetTeamsByProject() *ListOfListOfString { if x != nil { - return x.RequiredString + return x.TeamsByProject } - return "" + return nil } -func (x *NullableFieldsType) GetRequiredInt() int32 { +func (x *Author) GetCollaborations() *ListOfListOfString { if x != nil { - return x.RequiredInt + return x.Collaborations } - return 0 + return nil } -type NullableFieldsFilter struct { - state protoimpl.MessageState `protogen:"open.v1"` - Name *wrapperspb.StringValue `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - OptionalString *wrapperspb.StringValue `protobuf:"bytes,2,opt,name=optional_string,json=optionalString,proto3" json:"optional_string,omitempty"` - IncludeNulls *wrapperspb.BoolValue `protobuf:"bytes,3,opt,name=include_nulls,json=includeNulls,proto3" json:"include_nulls,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +func (x *Author) GetWrittenPosts() *ListOfBlogPost { + if x != nil { + return x.WrittenPosts + } + return nil } -func (x *NullableFieldsFilter) Reset() { - *x = NullableFieldsFilter{} - mi := &file_product_proto_msgTypes[161] +func (x *Author) GetFavoriteCategories() []*Category { + if x != nil { + return x.FavoriteCategories + } + return nil +} + +func (x *Author) GetRelatedAuthors() *ListOfUser { + if x != nil { + return x.RelatedAuthors + } + return nil +} + +func (x *Author) GetProductReviews() *ListOfProduct { + if x != nil { + return x.ProductReviews + } + return nil +} + +func (x *Author) GetAuthorGroups() *ListOfListOfUser { + if x != nil { + return x.AuthorGroups + } + return nil +} + +func (x *Author) GetCategoryPreferences() *ListOfListOfCategory { + if x != nil { + return x.CategoryPreferences + } + return nil +} + +func (x *Author) GetProjectTeams() *ListOfListOfUser { + if x != nil { + return x.ProjectTeams + } + return nil +} + +type AuthorFilter struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name *wrapperspb.StringValue `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + HasTeams *wrapperspb.BoolValue `protobuf:"bytes,2,opt,name=has_teams,json=hasTeams,proto3" json:"has_teams,omitempty"` + SkillCount *wrapperspb.Int32Value `protobuf:"bytes,3,opt,name=skill_count,json=skillCount,proto3" json:"skill_count,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AuthorFilter) Reset() { + *x = AuthorFilter{} + mi := &file_product_proto_msgTypes[204] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *NullableFieldsFilter) String() string { +func (x *AuthorFilter) String() string { return protoimpl.X.MessageStringOf(x) } -func (*NullableFieldsFilter) ProtoMessage() {} +func (*AuthorFilter) ProtoMessage() {} -func (x *NullableFieldsFilter) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[161] +func (x *AuthorFilter) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[204] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7792,73 +10126,56 @@ func (x *NullableFieldsFilter) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use NullableFieldsFilter.ProtoReflect.Descriptor instead. -func (*NullableFieldsFilter) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{161} +// Deprecated: Use AuthorFilter.ProtoReflect.Descriptor instead. +func (*AuthorFilter) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{204} } -func (x *NullableFieldsFilter) GetName() *wrapperspb.StringValue { +func (x *AuthorFilter) GetName() *wrapperspb.StringValue { if x != nil { return x.Name } return nil } -func (x *NullableFieldsFilter) GetOptionalString() *wrapperspb.StringValue { +func (x *AuthorFilter) GetHasTeams() *wrapperspb.BoolValue { if x != nil { - return x.OptionalString + return x.HasTeams } return nil } -func (x *NullableFieldsFilter) GetIncludeNulls() *wrapperspb.BoolValue { +func (x *AuthorFilter) GetSkillCount() *wrapperspb.Int32Value { if x != nil { - return x.IncludeNulls + return x.SkillCount } return nil } -type BlogPost struct { - state protoimpl.MessageState `protogen:"open.v1"` - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Title string `protobuf:"bytes,2,opt,name=title,proto3" json:"title,omitempty"` - Content string `protobuf:"bytes,3,opt,name=content,proto3" json:"content,omitempty"` - Tags []string `protobuf:"bytes,4,rep,name=tags,proto3" json:"tags,omitempty"` - OptionalTags *ListOfString `protobuf:"bytes,5,opt,name=optional_tags,json=optionalTags,proto3" json:"optional_tags,omitempty"` - Categories []string `protobuf:"bytes,6,rep,name=categories,proto3" json:"categories,omitempty"` - Keywords *ListOfString `protobuf:"bytes,7,opt,name=keywords,proto3" json:"keywords,omitempty"` - ViewCounts []int32 `protobuf:"varint,8,rep,packed,name=view_counts,json=viewCounts,proto3" json:"view_counts,omitempty"` - Ratings *ListOfFloat `protobuf:"bytes,9,opt,name=ratings,proto3" json:"ratings,omitempty"` - IsPublished *ListOfBoolean `protobuf:"bytes,10,opt,name=is_published,json=isPublished,proto3" json:"is_published,omitempty"` - TagGroups *ListOfListOfString `protobuf:"bytes,11,opt,name=tag_groups,json=tagGroups,proto3" json:"tag_groups,omitempty"` - RelatedTopics *ListOfListOfString `protobuf:"bytes,12,opt,name=related_topics,json=relatedTopics,proto3" json:"related_topics,omitempty"` - CommentThreads *ListOfListOfString `protobuf:"bytes,13,opt,name=comment_threads,json=commentThreads,proto3" json:"comment_threads,omitempty"` - Suggestions *ListOfListOfString `protobuf:"bytes,14,opt,name=suggestions,proto3" json:"suggestions,omitempty"` - RelatedCategories []*Category `protobuf:"bytes,15,rep,name=related_categories,json=relatedCategories,proto3" json:"related_categories,omitempty"` - Contributors []*User `protobuf:"bytes,16,rep,name=contributors,proto3" json:"contributors,omitempty"` - MentionedProducts *ListOfProduct `protobuf:"bytes,17,opt,name=mentioned_products,json=mentionedProducts,proto3" json:"mentioned_products,omitempty"` - MentionedUsers *ListOfUser `protobuf:"bytes,18,opt,name=mentioned_users,json=mentionedUsers,proto3" json:"mentioned_users,omitempty"` - CategoryGroups *ListOfListOfCategory `protobuf:"bytes,19,opt,name=category_groups,json=categoryGroups,proto3" json:"category_groups,omitempty"` - ContributorTeams *ListOfListOfUser `protobuf:"bytes,20,opt,name=contributor_teams,json=contributorTeams,proto3" json:"contributor_teams,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +type TestContainer struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Description *wrapperspb.StringValue `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *BlogPost) Reset() { - *x = BlogPost{} - mi := &file_product_proto_msgTypes[162] +func (x *TestContainer) Reset() { + *x = TestContainer{} + mi := &file_product_proto_msgTypes[205] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *BlogPost) String() string { +func (x *TestContainer) String() string { return protoimpl.X.MessageStringOf(x) } -func (*BlogPost) ProtoMessage() {} +func (*TestContainer) ProtoMessage() {} -func (x *BlogPost) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[162] +func (x *TestContainer) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[205] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7869,175 +10186,238 @@ func (x *BlogPost) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use BlogPost.ProtoReflect.Descriptor instead. -func (*BlogPost) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{162} +// Deprecated: Use TestContainer.ProtoReflect.Descriptor instead. +func (*TestContainer) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{205} } -func (x *BlogPost) GetId() string { +func (x *TestContainer) GetId() string { if x != nil { return x.Id } return "" } -func (x *BlogPost) GetTitle() string { +func (x *TestContainer) GetName() string { if x != nil { - return x.Title + return x.Name } return "" } -func (x *BlogPost) GetContent() string { +func (x *TestContainer) GetDescription() *wrapperspb.StringValue { if x != nil { - return x.Content + return x.Description } - return "" + return nil } -func (x *BlogPost) GetTags() []string { - if x != nil { - return x.Tags - } - return nil +type UserInput struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *BlogPost) GetOptionalTags() *ListOfString { - if x != nil { - return x.OptionalTags - } - return nil +func (x *UserInput) Reset() { + *x = UserInput{} + mi := &file_product_proto_msgTypes[206] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } -func (x *BlogPost) GetCategories() []string { - if x != nil { - return x.Categories - } - return nil +func (x *UserInput) String() string { + return protoimpl.X.MessageStringOf(x) } -func (x *BlogPost) GetKeywords() *ListOfString { +func (*UserInput) ProtoMessage() {} + +func (x *UserInput) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[206] if x != nil { - return x.Keywords + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms } - return nil + return mi.MessageOf(x) } -func (x *BlogPost) GetViewCounts() []int32 { - if x != nil { - return x.ViewCounts - } - return nil +// Deprecated: Use UserInput.ProtoReflect.Descriptor instead. +func (*UserInput) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{206} } -func (x *BlogPost) GetRatings() *ListOfFloat { +func (x *UserInput) GetName() string { if x != nil { - return x.Ratings + return x.Name } - return nil + return "" } -func (x *BlogPost) GetIsPublished() *ListOfBoolean { - if x != nil { - return x.IsPublished - } - return nil +type ActionInput struct { + state protoimpl.MessageState `protogen:"open.v1"` + Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` + Payload string `protobuf:"bytes,2,opt,name=payload,proto3" json:"payload,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *BlogPost) GetTagGroups() *ListOfListOfString { - if x != nil { - return x.TagGroups - } - return nil +func (x *ActionInput) Reset() { + *x = ActionInput{} + mi := &file_product_proto_msgTypes[207] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } -func (x *BlogPost) GetRelatedTopics() *ListOfListOfString { - if x != nil { - return x.RelatedTopics - } - return nil +func (x *ActionInput) String() string { + return protoimpl.X.MessageStringOf(x) } -func (x *BlogPost) GetCommentThreads() *ListOfListOfString { +func (*ActionInput) ProtoMessage() {} + +func (x *ActionInput) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[207] if x != nil { - return x.CommentThreads + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms } - return nil + return mi.MessageOf(x) } -func (x *BlogPost) GetSuggestions() *ListOfListOfString { - if x != nil { - return x.Suggestions - } - return nil +// Deprecated: Use ActionInput.ProtoReflect.Descriptor instead. +func (*ActionInput) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{207} } -func (x *BlogPost) GetRelatedCategories() []*Category { +func (x *ActionInput) GetType() string { if x != nil { - return x.RelatedCategories + return x.Type } - return nil + return "" } -func (x *BlogPost) GetContributors() []*User { +func (x *ActionInput) GetPayload() string { if x != nil { - return x.Contributors + return x.Payload } - return nil + return "" } -func (x *BlogPost) GetMentionedProducts() *ListOfProduct { +type ActionResult struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Value: + // + // *ActionResult_ActionSuccess + // *ActionResult_ActionError + Value isActionResult_Value `protobuf_oneof:"value"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ActionResult) Reset() { + *x = ActionResult{} + mi := &file_product_proto_msgTypes[208] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ActionResult) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ActionResult) ProtoMessage() {} + +func (x *ActionResult) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[208] if x != nil { - return x.MentionedProducts + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms } - return nil + return mi.MessageOf(x) } -func (x *BlogPost) GetMentionedUsers() *ListOfUser { +// Deprecated: Use ActionResult.ProtoReflect.Descriptor instead. +func (*ActionResult) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{208} +} + +func (x *ActionResult) GetValue() isActionResult_Value { if x != nil { - return x.MentionedUsers + return x.Value } return nil } -func (x *BlogPost) GetCategoryGroups() *ListOfListOfCategory { +func (x *ActionResult) GetActionSuccess() *ActionSuccess { if x != nil { - return x.CategoryGroups + if x, ok := x.Value.(*ActionResult_ActionSuccess); ok { + return x.ActionSuccess + } } return nil } -func (x *BlogPost) GetContributorTeams() *ListOfListOfUser { +func (x *ActionResult) GetActionError() *ActionError { if x != nil { - return x.ContributorTeams + if x, ok := x.Value.(*ActionResult_ActionError); ok { + return x.ActionError + } } return nil } -type BlogPostFilter struct { - state protoimpl.MessageState `protogen:"open.v1"` - Title *wrapperspb.StringValue `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"` - HasCategories *wrapperspb.BoolValue `protobuf:"bytes,2,opt,name=has_categories,json=hasCategories,proto3" json:"has_categories,omitempty"` - MinTags *wrapperspb.Int32Value `protobuf:"bytes,3,opt,name=min_tags,json=minTags,proto3" json:"min_tags,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +type isActionResult_Value interface { + isActionResult_Value() +} + +type ActionResult_ActionSuccess struct { + ActionSuccess *ActionSuccess `protobuf:"bytes,1,opt,name=action_success,json=actionSuccess,proto3,oneof"` +} + +type ActionResult_ActionError struct { + ActionError *ActionError `protobuf:"bytes,2,opt,name=action_error,json=actionError,proto3,oneof"` +} + +func (*ActionResult_ActionSuccess) isActionResult_Value() {} + +func (*ActionResult_ActionError) isActionResult_Value() {} + +type NullableFieldsInput struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + OptionalString *wrapperspb.StringValue `protobuf:"bytes,2,opt,name=optional_string,json=optionalString,proto3" json:"optional_string,omitempty"` + OptionalInt *wrapperspb.Int32Value `protobuf:"bytes,3,opt,name=optional_int,json=optionalInt,proto3" json:"optional_int,omitempty"` + OptionalFloat *wrapperspb.DoubleValue `protobuf:"bytes,4,opt,name=optional_float,json=optionalFloat,proto3" json:"optional_float,omitempty"` + OptionalBoolean *wrapperspb.BoolValue `protobuf:"bytes,5,opt,name=optional_boolean,json=optionalBoolean,proto3" json:"optional_boolean,omitempty"` + RequiredString string `protobuf:"bytes,6,opt,name=required_string,json=requiredString,proto3" json:"required_string,omitempty"` + RequiredInt int32 `protobuf:"varint,7,opt,name=required_int,json=requiredInt,proto3" json:"required_int,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *BlogPostFilter) Reset() { - *x = BlogPostFilter{} - mi := &file_product_proto_msgTypes[163] +func (x *NullableFieldsInput) Reset() { + *x = NullableFieldsInput{} + mi := &file_product_proto_msgTypes[209] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *BlogPostFilter) String() string { +func (x *NullableFieldsInput) String() string { return protoimpl.X.MessageStringOf(x) } -func (*BlogPostFilter) ProtoMessage() {} +func (*NullableFieldsInput) ProtoMessage() {} -func (x *BlogPostFilter) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[163] +func (x *NullableFieldsInput) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[209] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8048,68 +10428,97 @@ func (x *BlogPostFilter) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use BlogPostFilter.ProtoReflect.Descriptor instead. -func (*BlogPostFilter) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{163} +// Deprecated: Use NullableFieldsInput.ProtoReflect.Descriptor instead. +func (*NullableFieldsInput) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{209} } -func (x *BlogPostFilter) GetTitle() *wrapperspb.StringValue { +func (x *NullableFieldsInput) GetName() string { if x != nil { - return x.Title + return x.Name + } + return "" +} + +func (x *NullableFieldsInput) GetOptionalString() *wrapperspb.StringValue { + if x != nil { + return x.OptionalString } return nil } -func (x *BlogPostFilter) GetHasCategories() *wrapperspb.BoolValue { +func (x *NullableFieldsInput) GetOptionalInt() *wrapperspb.Int32Value { if x != nil { - return x.HasCategories + return x.OptionalInt } return nil } -func (x *BlogPostFilter) GetMinTags() *wrapperspb.Int32Value { +func (x *NullableFieldsInput) GetOptionalFloat() *wrapperspb.DoubleValue { if x != nil { - return x.MinTags + return x.OptionalFloat } return nil } -type Author struct { - state protoimpl.MessageState `protogen:"open.v1"` - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - Email *wrapperspb.StringValue `protobuf:"bytes,3,opt,name=email,proto3" json:"email,omitempty"` - Skills []string `protobuf:"bytes,4,rep,name=skills,proto3" json:"skills,omitempty"` - Languages []string `protobuf:"bytes,5,rep,name=languages,proto3" json:"languages,omitempty"` - SocialLinks *ListOfString `protobuf:"bytes,6,opt,name=social_links,json=socialLinks,proto3" json:"social_links,omitempty"` - TeamsByProject *ListOfListOfString `protobuf:"bytes,7,opt,name=teams_by_project,json=teamsByProject,proto3" json:"teams_by_project,omitempty"` - Collaborations *ListOfListOfString `protobuf:"bytes,8,opt,name=collaborations,proto3" json:"collaborations,omitempty"` - WrittenPosts *ListOfBlogPost `protobuf:"bytes,9,opt,name=written_posts,json=writtenPosts,proto3" json:"written_posts,omitempty"` - FavoriteCategories []*Category `protobuf:"bytes,10,rep,name=favorite_categories,json=favoriteCategories,proto3" json:"favorite_categories,omitempty"` - RelatedAuthors *ListOfUser `protobuf:"bytes,11,opt,name=related_authors,json=relatedAuthors,proto3" json:"related_authors,omitempty"` - ProductReviews *ListOfProduct `protobuf:"bytes,12,opt,name=product_reviews,json=productReviews,proto3" json:"product_reviews,omitempty"` - AuthorGroups *ListOfListOfUser `protobuf:"bytes,13,opt,name=author_groups,json=authorGroups,proto3" json:"author_groups,omitempty"` - CategoryPreferences *ListOfListOfCategory `protobuf:"bytes,14,opt,name=category_preferences,json=categoryPreferences,proto3" json:"category_preferences,omitempty"` - ProjectTeams *ListOfListOfUser `protobuf:"bytes,15,opt,name=project_teams,json=projectTeams,proto3" json:"project_teams,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +func (x *NullableFieldsInput) GetOptionalBoolean() *wrapperspb.BoolValue { + if x != nil { + return x.OptionalBoolean + } + return nil } -func (x *Author) Reset() { - *x = Author{} - mi := &file_product_proto_msgTypes[164] +func (x *NullableFieldsInput) GetRequiredString() string { + if x != nil { + return x.RequiredString + } + return "" +} + +func (x *NullableFieldsInput) GetRequiredInt() int32 { + if x != nil { + return x.RequiredInt + } + return 0 +} + +type BlogPostInput struct { + state protoimpl.MessageState `protogen:"open.v1"` + Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"` + Content string `protobuf:"bytes,2,opt,name=content,proto3" json:"content,omitempty"` + Tags []string `protobuf:"bytes,3,rep,name=tags,proto3" json:"tags,omitempty"` + OptionalTags *ListOfString `protobuf:"bytes,4,opt,name=optional_tags,json=optionalTags,proto3" json:"optional_tags,omitempty"` + Categories []string `protobuf:"bytes,5,rep,name=categories,proto3" json:"categories,omitempty"` + Keywords *ListOfString `protobuf:"bytes,6,opt,name=keywords,proto3" json:"keywords,omitempty"` + ViewCounts []int32 `protobuf:"varint,7,rep,packed,name=view_counts,json=viewCounts,proto3" json:"view_counts,omitempty"` + Ratings *ListOfFloat `protobuf:"bytes,8,opt,name=ratings,proto3" json:"ratings,omitempty"` + IsPublished *ListOfBoolean `protobuf:"bytes,9,opt,name=is_published,json=isPublished,proto3" json:"is_published,omitempty"` + TagGroups *ListOfListOfString `protobuf:"bytes,10,opt,name=tag_groups,json=tagGroups,proto3" json:"tag_groups,omitempty"` + RelatedTopics *ListOfListOfString `protobuf:"bytes,11,opt,name=related_topics,json=relatedTopics,proto3" json:"related_topics,omitempty"` + CommentThreads *ListOfListOfString `protobuf:"bytes,12,opt,name=comment_threads,json=commentThreads,proto3" json:"comment_threads,omitempty"` + Suggestions *ListOfListOfString `protobuf:"bytes,13,opt,name=suggestions,proto3" json:"suggestions,omitempty"` + RelatedCategories *ListOfCategoryInput `protobuf:"bytes,14,opt,name=related_categories,json=relatedCategories,proto3" json:"related_categories,omitempty"` + Contributors *ListOfUserInput `protobuf:"bytes,15,opt,name=contributors,proto3" json:"contributors,omitempty"` + CategoryGroups *ListOfListOfCategoryInput `protobuf:"bytes,16,opt,name=category_groups,json=categoryGroups,proto3" json:"category_groups,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *BlogPostInput) Reset() { + *x = BlogPostInput{} + mi := &file_product_proto_msgTypes[210] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *Author) String() string { +func (x *BlogPostInput) String() string { return protoimpl.X.MessageStringOf(x) } -func (*Author) ProtoMessage() {} +func (*BlogPostInput) ProtoMessage() {} -func (x *Author) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[164] +func (x *BlogPostInput) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[210] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8120,198 +10529,154 @@ func (x *Author) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use Author.ProtoReflect.Descriptor instead. -func (*Author) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{164} +// Deprecated: Use BlogPostInput.ProtoReflect.Descriptor instead. +func (*BlogPostInput) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{210} } -func (x *Author) GetId() string { +func (x *BlogPostInput) GetTitle() string { if x != nil { - return x.Id + return x.Title } return "" } -func (x *Author) GetName() string { +func (x *BlogPostInput) GetContent() string { if x != nil { - return x.Name + return x.Content } return "" } -func (x *Author) GetEmail() *wrapperspb.StringValue { - if x != nil { - return x.Email - } - return nil -} - -func (x *Author) GetSkills() []string { - if x != nil { - return x.Skills - } - return nil -} - -func (x *Author) GetLanguages() []string { +func (x *BlogPostInput) GetTags() []string { if x != nil { - return x.Languages + return x.Tags } return nil } -func (x *Author) GetSocialLinks() *ListOfString { +func (x *BlogPostInput) GetOptionalTags() *ListOfString { if x != nil { - return x.SocialLinks + return x.OptionalTags } return nil } -func (x *Author) GetTeamsByProject() *ListOfListOfString { +func (x *BlogPostInput) GetCategories() []string { if x != nil { - return x.TeamsByProject + return x.Categories } return nil } -func (x *Author) GetCollaborations() *ListOfListOfString { +func (x *BlogPostInput) GetKeywords() *ListOfString { if x != nil { - return x.Collaborations + return x.Keywords } return nil } -func (x *Author) GetWrittenPosts() *ListOfBlogPost { +func (x *BlogPostInput) GetViewCounts() []int32 { if x != nil { - return x.WrittenPosts + return x.ViewCounts } return nil } -func (x *Author) GetFavoriteCategories() []*Category { +func (x *BlogPostInput) GetRatings() *ListOfFloat { if x != nil { - return x.FavoriteCategories + return x.Ratings } return nil } -func (x *Author) GetRelatedAuthors() *ListOfUser { +func (x *BlogPostInput) GetIsPublished() *ListOfBoolean { if x != nil { - return x.RelatedAuthors + return x.IsPublished } return nil } -func (x *Author) GetProductReviews() *ListOfProduct { +func (x *BlogPostInput) GetTagGroups() *ListOfListOfString { if x != nil { - return x.ProductReviews + return x.TagGroups } return nil } -func (x *Author) GetAuthorGroups() *ListOfListOfUser { +func (x *BlogPostInput) GetRelatedTopics() *ListOfListOfString { if x != nil { - return x.AuthorGroups + return x.RelatedTopics } return nil } -func (x *Author) GetCategoryPreferences() *ListOfListOfCategory { +func (x *BlogPostInput) GetCommentThreads() *ListOfListOfString { if x != nil { - return x.CategoryPreferences + return x.CommentThreads } return nil } -func (x *Author) GetProjectTeams() *ListOfListOfUser { +func (x *BlogPostInput) GetSuggestions() *ListOfListOfString { if x != nil { - return x.ProjectTeams + return x.Suggestions } return nil } -type AuthorFilter struct { - state protoimpl.MessageState `protogen:"open.v1"` - Name *wrapperspb.StringValue `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - HasTeams *wrapperspb.BoolValue `protobuf:"bytes,2,opt,name=has_teams,json=hasTeams,proto3" json:"has_teams,omitempty"` - SkillCount *wrapperspb.Int32Value `protobuf:"bytes,3,opt,name=skill_count,json=skillCount,proto3" json:"skill_count,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *AuthorFilter) Reset() { - *x = AuthorFilter{} - mi := &file_product_proto_msgTypes[165] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *AuthorFilter) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AuthorFilter) ProtoMessage() {} - -func (x *AuthorFilter) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[165] - 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 AuthorFilter.ProtoReflect.Descriptor instead. -func (*AuthorFilter) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{165} -} - -func (x *AuthorFilter) GetName() *wrapperspb.StringValue { +func (x *BlogPostInput) GetRelatedCategories() *ListOfCategoryInput { if x != nil { - return x.Name + return x.RelatedCategories } return nil } -func (x *AuthorFilter) GetHasTeams() *wrapperspb.BoolValue { +func (x *BlogPostInput) GetContributors() *ListOfUserInput { if x != nil { - return x.HasTeams + return x.Contributors } return nil } -func (x *AuthorFilter) GetSkillCount() *wrapperspb.Int32Value { +func (x *BlogPostInput) GetCategoryGroups() *ListOfListOfCategoryInput { if x != nil { - return x.SkillCount + return x.CategoryGroups } return nil } -type UserInput struct { - state protoimpl.MessageState `protogen:"open.v1"` - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +type AuthorInput struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Email *wrapperspb.StringValue `protobuf:"bytes,2,opt,name=email,proto3" json:"email,omitempty"` + Skills []string `protobuf:"bytes,3,rep,name=skills,proto3" json:"skills,omitempty"` + Languages []string `protobuf:"bytes,4,rep,name=languages,proto3" json:"languages,omitempty"` + SocialLinks *ListOfString `protobuf:"bytes,5,opt,name=social_links,json=socialLinks,proto3" json:"social_links,omitempty"` + TeamsByProject *ListOfListOfString `protobuf:"bytes,6,opt,name=teams_by_project,json=teamsByProject,proto3" json:"teams_by_project,omitempty"` + Collaborations *ListOfListOfString `protobuf:"bytes,7,opt,name=collaborations,proto3" json:"collaborations,omitempty"` + FavoriteCategories []*CategoryInput `protobuf:"bytes,8,rep,name=favorite_categories,json=favoriteCategories,proto3" json:"favorite_categories,omitempty"` + AuthorGroups *ListOfListOfUserInput `protobuf:"bytes,9,opt,name=author_groups,json=authorGroups,proto3" json:"author_groups,omitempty"` + ProjectTeams *ListOfListOfUserInput `protobuf:"bytes,10,opt,name=project_teams,json=projectTeams,proto3" json:"project_teams,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *UserInput) Reset() { - *x = UserInput{} - mi := &file_product_proto_msgTypes[166] +func (x *AuthorInput) Reset() { + *x = AuthorInput{} + mi := &file_product_proto_msgTypes[211] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *UserInput) String() string { +func (x *AuthorInput) String() string { return protoimpl.X.MessageStringOf(x) } -func (*UserInput) ProtoMessage() {} +func (*AuthorInput) ProtoMessage() {} -func (x *UserInput) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[166] +func (x *AuthorInput) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[211] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8322,96 +10687,106 @@ func (x *UserInput) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use UserInput.ProtoReflect.Descriptor instead. -func (*UserInput) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{166} +// Deprecated: Use AuthorInput.ProtoReflect.Descriptor instead. +func (*AuthorInput) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{211} } -func (x *UserInput) GetName() string { +func (x *AuthorInput) GetName() string { if x != nil { return x.Name } return "" } -type ActionInput struct { - state protoimpl.MessageState `protogen:"open.v1"` - Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` - Payload string `protobuf:"bytes,2,opt,name=payload,proto3" json:"payload,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +func (x *AuthorInput) GetEmail() *wrapperspb.StringValue { + if x != nil { + return x.Email + } + return nil } -func (x *ActionInput) Reset() { - *x = ActionInput{} - mi := &file_product_proto_msgTypes[167] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) +func (x *AuthorInput) GetSkills() []string { + if x != nil { + return x.Skills + } + return nil } -func (x *ActionInput) String() string { - return protoimpl.X.MessageStringOf(x) +func (x *AuthorInput) GetLanguages() []string { + if x != nil { + return x.Languages + } + return nil } -func (*ActionInput) ProtoMessage() {} +func (x *AuthorInput) GetSocialLinks() *ListOfString { + if x != nil { + return x.SocialLinks + } + return nil +} -func (x *ActionInput) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[167] +func (x *AuthorInput) GetTeamsByProject() *ListOfListOfString { if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms + return x.TeamsByProject } - return mi.MessageOf(x) + return nil } -// Deprecated: Use ActionInput.ProtoReflect.Descriptor instead. -func (*ActionInput) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{167} +func (x *AuthorInput) GetCollaborations() *ListOfListOfString { + if x != nil { + return x.Collaborations + } + return nil } -func (x *ActionInput) GetType() string { +func (x *AuthorInput) GetFavoriteCategories() []*CategoryInput { if x != nil { - return x.Type + return x.FavoriteCategories } - return "" + return nil } -func (x *ActionInput) GetPayload() string { +func (x *AuthorInput) GetAuthorGroups() *ListOfListOfUserInput { if x != nil { - return x.Payload + return x.AuthorGroups } - return "" + return nil } -type ActionResult struct { - state protoimpl.MessageState `protogen:"open.v1"` - // Types that are valid to be assigned to Value: - // - // *ActionResult_ActionSuccess - // *ActionResult_ActionError - Value isActionResult_Value `protobuf_oneof:"value"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +func (x *AuthorInput) GetProjectTeams() *ListOfListOfUserInput { + if x != nil { + return x.ProjectTeams + } + return nil } -func (x *ActionResult) Reset() { - *x = ActionResult{} - mi := &file_product_proto_msgTypes[168] +type ProductDetails struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` + ReviewSummary *ActionResult `protobuf:"bytes,3,opt,name=review_summary,json=reviewSummary,proto3" json:"review_summary,omitempty"` + RecommendedPet *Animal `protobuf:"bytes,4,opt,name=recommended_pet,json=recommendedPet,proto3" json:"recommended_pet,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ProductDetails) Reset() { + *x = ProductDetails{} + mi := &file_product_proto_msgTypes[212] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *ActionResult) String() string { +func (x *ProductDetails) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ActionResult) ProtoMessage() {} +func (*ProductDetails) ProtoMessage() {} -func (x *ActionResult) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[168] +func (x *ProductDetails) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[212] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8422,80 +10797,63 @@ func (x *ActionResult) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ActionResult.ProtoReflect.Descriptor instead. -func (*ActionResult) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{168} +// Deprecated: Use ProductDetails.ProtoReflect.Descriptor instead. +func (*ProductDetails) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{212} } -func (x *ActionResult) GetValue() isActionResult_Value { +func (x *ProductDetails) GetId() string { if x != nil { - return x.Value + return x.Id } - return nil + return "" } -func (x *ActionResult) GetActionSuccess() *ActionSuccess { +func (x *ProductDetails) GetDescription() string { if x != nil { - if x, ok := x.Value.(*ActionResult_ActionSuccess); ok { - return x.ActionSuccess - } + return x.Description } - return nil + return "" } -func (x *ActionResult) GetActionError() *ActionError { +func (x *ProductDetails) GetReviewSummary() *ActionResult { if x != nil { - if x, ok := x.Value.(*ActionResult_ActionError); ok { - return x.ActionError - } + return x.ReviewSummary } return nil } -type isActionResult_Value interface { - isActionResult_Value() -} - -type ActionResult_ActionSuccess struct { - ActionSuccess *ActionSuccess `protobuf:"bytes,1,opt,name=action_success,json=actionSuccess,proto3,oneof"` -} - -type ActionResult_ActionError struct { - ActionError *ActionError `protobuf:"bytes,2,opt,name=action_error,json=actionError,proto3,oneof"` +func (x *ProductDetails) GetRecommendedPet() *Animal { + if x != nil { + return x.RecommendedPet + } + return nil } -func (*ActionResult_ActionSuccess) isActionResult_Value() {} - -func (*ActionResult_ActionError) isActionResult_Value() {} - -type NullableFieldsInput struct { - state protoimpl.MessageState `protogen:"open.v1"` - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - OptionalString *wrapperspb.StringValue `protobuf:"bytes,2,opt,name=optional_string,json=optionalString,proto3" json:"optional_string,omitempty"` - OptionalInt *wrapperspb.Int32Value `protobuf:"bytes,3,opt,name=optional_int,json=optionalInt,proto3" json:"optional_int,omitempty"` - OptionalFloat *wrapperspb.DoubleValue `protobuf:"bytes,4,opt,name=optional_float,json=optionalFloat,proto3" json:"optional_float,omitempty"` - OptionalBoolean *wrapperspb.BoolValue `protobuf:"bytes,5,opt,name=optional_boolean,json=optionalBoolean,proto3" json:"optional_boolean,omitempty"` - RequiredString string `protobuf:"bytes,6,opt,name=required_string,json=requiredString,proto3" json:"required_string,omitempty"` - RequiredInt int32 `protobuf:"varint,7,opt,name=required_int,json=requiredInt,proto3" json:"required_int,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +type NestedTypeB struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + C *NestedTypeC `protobuf:"bytes,3,opt,name=c,proto3" json:"c,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *NullableFieldsInput) Reset() { - *x = NullableFieldsInput{} - mi := &file_product_proto_msgTypes[169] +func (x *NestedTypeB) Reset() { + *x = NestedTypeB{} + mi := &file_product_proto_msgTypes[213] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *NullableFieldsInput) String() string { +func (x *NestedTypeB) String() string { return protoimpl.X.MessageStringOf(x) } -func (*NullableFieldsInput) ProtoMessage() {} +func (*NestedTypeB) ProtoMessage() {} -func (x *NullableFieldsInput) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[169] +func (x *NestedTypeB) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[213] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8506,97 +10864,55 @@ func (x *NullableFieldsInput) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use NullableFieldsInput.ProtoReflect.Descriptor instead. -func (*NullableFieldsInput) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{169} +// Deprecated: Use NestedTypeB.ProtoReflect.Descriptor instead. +func (*NestedTypeB) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{213} } -func (x *NullableFieldsInput) GetName() string { +func (x *NestedTypeB) GetId() string { if x != nil { - return x.Name + return x.Id } return "" } -func (x *NullableFieldsInput) GetOptionalString() *wrapperspb.StringValue { - if x != nil { - return x.OptionalString - } - return nil -} - -func (x *NullableFieldsInput) GetOptionalInt() *wrapperspb.Int32Value { - if x != nil { - return x.OptionalInt - } - return nil -} - -func (x *NullableFieldsInput) GetOptionalFloat() *wrapperspb.DoubleValue { - if x != nil { - return x.OptionalFloat - } - return nil -} - -func (x *NullableFieldsInput) GetOptionalBoolean() *wrapperspb.BoolValue { - if x != nil { - return x.OptionalBoolean - } - return nil -} - -func (x *NullableFieldsInput) GetRequiredString() string { +func (x *NestedTypeB) GetName() string { if x != nil { - return x.RequiredString + return x.Name } return "" } -func (x *NullableFieldsInput) GetRequiredInt() int32 { +func (x *NestedTypeB) GetC() *NestedTypeC { if x != nil { - return x.RequiredInt + return x.C } - return 0 + return nil } -type BlogPostInput struct { - state protoimpl.MessageState `protogen:"open.v1"` - Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"` - Content string `protobuf:"bytes,2,opt,name=content,proto3" json:"content,omitempty"` - Tags []string `protobuf:"bytes,3,rep,name=tags,proto3" json:"tags,omitempty"` - OptionalTags *ListOfString `protobuf:"bytes,4,opt,name=optional_tags,json=optionalTags,proto3" json:"optional_tags,omitempty"` - Categories []string `protobuf:"bytes,5,rep,name=categories,proto3" json:"categories,omitempty"` - Keywords *ListOfString `protobuf:"bytes,6,opt,name=keywords,proto3" json:"keywords,omitempty"` - ViewCounts []int32 `protobuf:"varint,7,rep,packed,name=view_counts,json=viewCounts,proto3" json:"view_counts,omitempty"` - Ratings *ListOfFloat `protobuf:"bytes,8,opt,name=ratings,proto3" json:"ratings,omitempty"` - IsPublished *ListOfBoolean `protobuf:"bytes,9,opt,name=is_published,json=isPublished,proto3" json:"is_published,omitempty"` - TagGroups *ListOfListOfString `protobuf:"bytes,10,opt,name=tag_groups,json=tagGroups,proto3" json:"tag_groups,omitempty"` - RelatedTopics *ListOfListOfString `protobuf:"bytes,11,opt,name=related_topics,json=relatedTopics,proto3" json:"related_topics,omitempty"` - CommentThreads *ListOfListOfString `protobuf:"bytes,12,opt,name=comment_threads,json=commentThreads,proto3" json:"comment_threads,omitempty"` - Suggestions *ListOfListOfString `protobuf:"bytes,13,opt,name=suggestions,proto3" json:"suggestions,omitempty"` - RelatedCategories *ListOfCategoryInput `protobuf:"bytes,14,opt,name=related_categories,json=relatedCategories,proto3" json:"related_categories,omitempty"` - Contributors *ListOfUserInput `protobuf:"bytes,15,opt,name=contributors,proto3" json:"contributors,omitempty"` - CategoryGroups *ListOfListOfCategoryInput `protobuf:"bytes,16,opt,name=category_groups,json=categoryGroups,proto3" json:"category_groups,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +type NestedTypeC struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *BlogPostInput) Reset() { - *x = BlogPostInput{} - mi := &file_product_proto_msgTypes[170] +func (x *NestedTypeC) Reset() { + *x = NestedTypeC{} + mi := &file_product_proto_msgTypes[214] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *BlogPostInput) String() string { +func (x *NestedTypeC) String() string { return protoimpl.X.MessageStringOf(x) } -func (*BlogPostInput) ProtoMessage() {} +func (*NestedTypeC) ProtoMessage() {} -func (x *BlogPostInput) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[170] +func (x *NestedTypeC) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[214] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8607,154 +10923,169 @@ func (x *BlogPostInput) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use BlogPostInput.ProtoReflect.Descriptor instead. -func (*BlogPostInput) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{170} +// Deprecated: Use NestedTypeC.ProtoReflect.Descriptor instead. +func (*NestedTypeC) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{214} } -func (x *BlogPostInput) GetTitle() string { +func (x *NestedTypeC) GetId() string { if x != nil { - return x.Title + return x.Id } return "" } -func (x *BlogPostInput) GetContent() string { +func (x *NestedTypeC) GetName() string { if x != nil { - return x.Content + return x.Name } return "" } -func (x *BlogPostInput) GetTags() []string { - if x != nil { - return x.Tags - } - return nil +type FilterType struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + FilterField_1 string `protobuf:"bytes,2,opt,name=filter_field_1,json=filterField1,proto3" json:"filter_field_1,omitempty"` + FilterField_2 string `protobuf:"bytes,3,opt,name=filter_field_2,json=filterField2,proto3" json:"filter_field_2,omitempty"` + Pagination *Pagination `protobuf:"bytes,4,opt,name=pagination,proto3" json:"pagination,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *BlogPostInput) GetOptionalTags() *ListOfString { - if x != nil { - return x.OptionalTags - } - return nil +func (x *FilterType) Reset() { + *x = FilterType{} + mi := &file_product_proto_msgTypes[215] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } -func (x *BlogPostInput) GetCategories() []string { - if x != nil { - return x.Categories - } - return nil +func (x *FilterType) String() string { + return protoimpl.X.MessageStringOf(x) } -func (x *BlogPostInput) GetKeywords() *ListOfString { +func (*FilterType) ProtoMessage() {} + +func (x *FilterType) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[215] if x != nil { - return x.Keywords + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms } - return nil + return mi.MessageOf(x) } -func (x *BlogPostInput) GetViewCounts() []int32 { - if x != nil { - return x.ViewCounts - } - return nil +// Deprecated: Use FilterType.ProtoReflect.Descriptor instead. +func (*FilterType) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{215} } -func (x *BlogPostInput) GetRatings() *ListOfFloat { +func (x *FilterType) GetName() string { if x != nil { - return x.Ratings + return x.Name } - return nil + return "" } -func (x *BlogPostInput) GetIsPublished() *ListOfBoolean { +func (x *FilterType) GetFilterField_1() string { if x != nil { - return x.IsPublished + return x.FilterField_1 } - return nil + return "" } -func (x *BlogPostInput) GetTagGroups() *ListOfListOfString { +func (x *FilterType) GetFilterField_2() string { if x != nil { - return x.TagGroups + return x.FilterField_2 } - return nil + return "" } -func (x *BlogPostInput) GetRelatedTopics() *ListOfListOfString { +func (x *FilterType) GetPagination() *Pagination { if x != nil { - return x.RelatedTopics + return x.Pagination } return nil } -func (x *BlogPostInput) GetCommentThreads() *ListOfListOfString { - if x != nil { - return x.CommentThreads - } - return nil +type Pagination struct { + state protoimpl.MessageState `protogen:"open.v1"` + Page int32 `protobuf:"varint,1,opt,name=page,proto3" json:"page,omitempty"` + PerPage int32 `protobuf:"varint,2,opt,name=per_page,json=perPage,proto3" json:"per_page,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *BlogPostInput) GetSuggestions() *ListOfListOfString { - if x != nil { - return x.Suggestions - } - return nil +func (x *Pagination) Reset() { + *x = Pagination{} + mi := &file_product_proto_msgTypes[216] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } -func (x *BlogPostInput) GetRelatedCategories() *ListOfCategoryInput { +func (x *Pagination) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Pagination) ProtoMessage() {} + +func (x *Pagination) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[216] if x != nil { - return x.RelatedCategories + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms } - return nil + return mi.MessageOf(x) } -func (x *BlogPostInput) GetContributors() *ListOfUserInput { +// Deprecated: Use Pagination.ProtoReflect.Descriptor instead. +func (*Pagination) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{216} +} + +func (x *Pagination) GetPage() int32 { if x != nil { - return x.Contributors + return x.Page } - return nil + return 0 } -func (x *BlogPostInput) GetCategoryGroups() *ListOfListOfCategoryInput { +func (x *Pagination) GetPerPage() int32 { if x != nil { - return x.CategoryGroups + return x.PerPage } - return nil + return 0 } -type AuthorInput struct { - state protoimpl.MessageState `protogen:"open.v1"` - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Email *wrapperspb.StringValue `protobuf:"bytes,2,opt,name=email,proto3" json:"email,omitempty"` - Skills []string `protobuf:"bytes,3,rep,name=skills,proto3" json:"skills,omitempty"` - Languages []string `protobuf:"bytes,4,rep,name=languages,proto3" json:"languages,omitempty"` - SocialLinks *ListOfString `protobuf:"bytes,5,opt,name=social_links,json=socialLinks,proto3" json:"social_links,omitempty"` - TeamsByProject *ListOfListOfString `protobuf:"bytes,6,opt,name=teams_by_project,json=teamsByProject,proto3" json:"teams_by_project,omitempty"` - Collaborations *ListOfListOfString `protobuf:"bytes,7,opt,name=collaborations,proto3" json:"collaborations,omitempty"` - FavoriteCategories []*CategoryInput `protobuf:"bytes,8,rep,name=favorite_categories,json=favoriteCategories,proto3" json:"favorite_categories,omitempty"` - AuthorGroups *ListOfListOfUserInput `protobuf:"bytes,9,opt,name=author_groups,json=authorGroups,proto3" json:"author_groups,omitempty"` - ProjectTeams *ListOfListOfUserInput `protobuf:"bytes,10,opt,name=project_teams,json=projectTeams,proto3" json:"project_teams,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +type OrderLineInput struct { + state protoimpl.MessageState `protogen:"open.v1"` + ProductId string `protobuf:"bytes,1,opt,name=product_id,json=productId,proto3" json:"product_id,omitempty"` + Quantity int32 `protobuf:"varint,2,opt,name=quantity,proto3" json:"quantity,omitempty"` + Modifiers *ListOfString `protobuf:"bytes,3,opt,name=modifiers,proto3" json:"modifiers,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *AuthorInput) Reset() { - *x = AuthorInput{} - mi := &file_product_proto_msgTypes[171] +func (x *OrderLineInput) Reset() { + *x = OrderLineInput{} + mi := &file_product_proto_msgTypes[217] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *AuthorInput) String() string { +func (x *OrderLineInput) String() string { return protoimpl.X.MessageStringOf(x) } -func (*AuthorInput) ProtoMessage() {} +func (*OrderLineInput) ProtoMessage() {} -func (x *AuthorInput) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[171] +func (x *OrderLineInput) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[217] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8765,105 +11096,117 @@ func (x *AuthorInput) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use AuthorInput.ProtoReflect.Descriptor instead. -func (*AuthorInput) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{171} +// Deprecated: Use OrderLineInput.ProtoReflect.Descriptor instead. +func (*OrderLineInput) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{217} } -func (x *AuthorInput) GetName() string { +func (x *OrderLineInput) GetProductId() string { if x != nil { - return x.Name + return x.ProductId } return "" } -func (x *AuthorInput) GetEmail() *wrapperspb.StringValue { +func (x *OrderLineInput) GetQuantity() int32 { if x != nil { - return x.Email + return x.Quantity } - return nil + return 0 } -func (x *AuthorInput) GetSkills() []string { +func (x *OrderLineInput) GetModifiers() *ListOfString { if x != nil { - return x.Skills + return x.Modifiers } return nil } -func (x *AuthorInput) GetLanguages() []string { - if x != nil { - return x.Languages - } - return nil +type OrderLine struct { + state protoimpl.MessageState `protogen:"open.v1"` + ProductId string `protobuf:"bytes,1,opt,name=product_id,json=productId,proto3" json:"product_id,omitempty"` + Quantity int32 `protobuf:"varint,2,opt,name=quantity,proto3" json:"quantity,omitempty"` + Modifiers *ListOfString `protobuf:"bytes,3,opt,name=modifiers,proto3" json:"modifiers,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *AuthorInput) GetSocialLinks() *ListOfString { - if x != nil { - return x.SocialLinks - } - return nil +func (x *OrderLine) Reset() { + *x = OrderLine{} + mi := &file_product_proto_msgTypes[218] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } -func (x *AuthorInput) GetTeamsByProject() *ListOfListOfString { - if x != nil { - return x.TeamsByProject - } - return nil +func (x *OrderLine) String() string { + return protoimpl.X.MessageStringOf(x) } -func (x *AuthorInput) GetCollaborations() *ListOfListOfString { +func (*OrderLine) ProtoMessage() {} + +func (x *OrderLine) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[218] if x != nil { - return x.Collaborations + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms } - return nil + return mi.MessageOf(x) } -func (x *AuthorInput) GetFavoriteCategories() []*CategoryInput { +// Deprecated: Use OrderLine.ProtoReflect.Descriptor instead. +func (*OrderLine) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{218} +} + +func (x *OrderLine) GetProductId() string { if x != nil { - return x.FavoriteCategories + return x.ProductId } - return nil + return "" } -func (x *AuthorInput) GetAuthorGroups() *ListOfListOfUserInput { +func (x *OrderLine) GetQuantity() int32 { if x != nil { - return x.AuthorGroups + return x.Quantity } - return nil + return 0 } -func (x *AuthorInput) GetProjectTeams() *ListOfListOfUserInput { +func (x *OrderLine) GetModifiers() *ListOfString { if x != nil { - return x.ProjectTeams + return x.Modifiers } return nil } -type NestedTypeB struct { - state protoimpl.MessageState `protogen:"open.v1"` - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - C *NestedTypeC `protobuf:"bytes,3,opt,name=c,proto3" json:"c,omitempty"` +type Subcategory struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Description *wrapperspb.StringValue `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` + IsActive bool `protobuf:"varint,4,opt,name=is_active,json=isActive,proto3" json:"is_active,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *NestedTypeB) Reset() { - *x = NestedTypeB{} - mi := &file_product_proto_msgTypes[172] +func (x *Subcategory) Reset() { + *x = Subcategory{} + mi := &file_product_proto_msgTypes[219] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *NestedTypeB) String() string { +func (x *Subcategory) String() string { return protoimpl.X.MessageStringOf(x) } -func (*NestedTypeB) ProtoMessage() {} +func (*Subcategory) ProtoMessage() {} -func (x *NestedTypeB) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[172] +func (x *Subcategory) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[219] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8874,55 +11217,66 @@ func (x *NestedTypeB) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use NestedTypeB.ProtoReflect.Descriptor instead. -func (*NestedTypeB) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{172} +// Deprecated: Use Subcategory.ProtoReflect.Descriptor instead. +func (*Subcategory) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{219} } -func (x *NestedTypeB) GetId() string { +func (x *Subcategory) GetId() string { if x != nil { return x.Id } return "" } -func (x *NestedTypeB) GetName() string { +func (x *Subcategory) GetName() string { if x != nil { return x.Name } return "" } -func (x *NestedTypeB) GetC() *NestedTypeC { +func (x *Subcategory) GetDescription() *wrapperspb.StringValue { if x != nil { - return x.C + return x.Description } return nil } -type NestedTypeC struct { - state protoimpl.MessageState `protogen:"open.v1"` - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +func (x *Subcategory) GetIsActive() bool { + if x != nil { + return x.IsActive + } + return false } -func (x *NestedTypeC) Reset() { - *x = NestedTypeC{} - mi := &file_product_proto_msgTypes[173] +type CategoryMetrics struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + MetricType string `protobuf:"bytes,2,opt,name=metric_type,json=metricType,proto3" json:"metric_type,omitempty"` + Value float64 `protobuf:"fixed64,3,opt,name=value,proto3" json:"value,omitempty"` + Timestamp string `protobuf:"bytes,4,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + CategoryId string `protobuf:"bytes,5,opt,name=category_id,json=categoryId,proto3" json:"category_id,omitempty"` + RelatedCategory *Category `protobuf:"bytes,6,opt,name=related_category,json=relatedCategory,proto3" json:"related_category,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CategoryMetrics) Reset() { + *x = CategoryMetrics{} + mi := &file_product_proto_msgTypes[220] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *NestedTypeC) String() string { +func (x *CategoryMetrics) String() string { return protoimpl.X.MessageStringOf(x) } -func (*NestedTypeC) ProtoMessage() {} +func (*CategoryMetrics) ProtoMessage() {} -func (x *NestedTypeC) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[173] +func (x *CategoryMetrics) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[220] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8933,50 +11287,80 @@ func (x *NestedTypeC) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use NestedTypeC.ProtoReflect.Descriptor instead. -func (*NestedTypeC) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{173} +// Deprecated: Use CategoryMetrics.ProtoReflect.Descriptor instead. +func (*CategoryMetrics) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{220} } -func (x *NestedTypeC) GetId() string { +func (x *CategoryMetrics) GetId() string { if x != nil { return x.Id } return "" } -func (x *NestedTypeC) GetName() string { +func (x *CategoryMetrics) GetMetricType() string { if x != nil { - return x.Name + return x.MetricType } return "" } -type FilterType struct { +func (x *CategoryMetrics) GetValue() float64 { + if x != nil { + return x.Value + } + return 0 +} + +func (x *CategoryMetrics) GetTimestamp() string { + if x != nil { + return x.Timestamp + } + return "" +} + +func (x *CategoryMetrics) GetCategoryId() string { + if x != nil { + return x.CategoryId + } + return "" +} + +func (x *CategoryMetrics) GetRelatedCategory() *Category { + if x != nil { + return x.RelatedCategory + } + return nil +} + +type Cat struct { state protoimpl.MessageState `protogen:"open.v1"` - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - FilterField_1 string `protobuf:"bytes,2,opt,name=filter_field_1,json=filterField1,proto3" json:"filter_field_1,omitempty"` - FilterField_2 string `protobuf:"bytes,3,opt,name=filter_field_2,json=filterField2,proto3" json:"filter_field_2,omitempty"` - Pagination *Pagination `protobuf:"bytes,4,opt,name=pagination,proto3" json:"pagination,omitempty"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Kind string `protobuf:"bytes,3,opt,name=kind,proto3" json:"kind,omitempty"` + MeowVolume int32 `protobuf:"varint,4,opt,name=meow_volume,json=meowVolume,proto3" json:"meow_volume,omitempty"` + Owner *Owner `protobuf:"bytes,5,opt,name=owner,proto3" json:"owner,omitempty"` + Breed *CatBreed `protobuf:"bytes,6,opt,name=breed,proto3" json:"breed,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *FilterType) Reset() { - *x = FilterType{} - mi := &file_product_proto_msgTypes[174] +func (x *Cat) Reset() { + *x = Cat{} + mi := &file_product_proto_msgTypes[221] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *FilterType) String() string { +func (x *Cat) String() string { return protoimpl.X.MessageStringOf(x) } -func (*FilterType) ProtoMessage() {} +func (*Cat) ProtoMessage() {} -func (x *FilterType) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[174] +func (x *Cat) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[221] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8987,62 +11371,80 @@ func (x *FilterType) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use FilterType.ProtoReflect.Descriptor instead. -func (*FilterType) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{174} +// Deprecated: Use Cat.ProtoReflect.Descriptor instead. +func (*Cat) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{221} } -func (x *FilterType) GetName() string { +func (x *Cat) GetId() string { if x != nil { - return x.Name + return x.Id } return "" } -func (x *FilterType) GetFilterField_1() string { +func (x *Cat) GetName() string { if x != nil { - return x.FilterField_1 + return x.Name } return "" } -func (x *FilterType) GetFilterField_2() string { +func (x *Cat) GetKind() string { if x != nil { - return x.FilterField_2 + return x.Kind } return "" } -func (x *FilterType) GetPagination() *Pagination { +func (x *Cat) GetMeowVolume() int32 { if x != nil { - return x.Pagination + return x.MeowVolume + } + return 0 +} + +func (x *Cat) GetOwner() *Owner { + if x != nil { + return x.Owner } return nil } -type Pagination struct { +func (x *Cat) GetBreed() *CatBreed { + if x != nil { + return x.Breed + } + return nil +} + +type Dog struct { state protoimpl.MessageState `protogen:"open.v1"` - Page int32 `protobuf:"varint,1,opt,name=page,proto3" json:"page,omitempty"` - PerPage int32 `protobuf:"varint,2,opt,name=per_page,json=perPage,proto3" json:"per_page,omitempty"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Kind string `protobuf:"bytes,3,opt,name=kind,proto3" json:"kind,omitempty"` + BarkVolume int32 `protobuf:"varint,4,opt,name=bark_volume,json=barkVolume,proto3" json:"bark_volume,omitempty"` + Owner *Owner `protobuf:"bytes,5,opt,name=owner,proto3" json:"owner,omitempty"` + Breed *DogBreed `protobuf:"bytes,6,opt,name=breed,proto3" json:"breed,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *Pagination) Reset() { - *x = Pagination{} - mi := &file_product_proto_msgTypes[175] +func (x *Dog) Reset() { + *x = Dog{} + mi := &file_product_proto_msgTypes[222] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *Pagination) String() string { +func (x *Dog) String() string { return protoimpl.X.MessageStringOf(x) } -func (*Pagination) ProtoMessage() {} +func (*Dog) ProtoMessage() {} -func (x *Pagination) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[175] +func (x *Dog) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[222] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9053,49 +11455,77 @@ func (x *Pagination) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use Pagination.ProtoReflect.Descriptor instead. -func (*Pagination) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{175} +// Deprecated: Use Dog.ProtoReflect.Descriptor instead. +func (*Dog) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{222} } -func (x *Pagination) GetPage() int32 { +func (x *Dog) GetId() string { if x != nil { - return x.Page + return x.Id } - return 0 + return "" } -func (x *Pagination) GetPerPage() int32 { +func (x *Dog) GetName() string { if x != nil { - return x.PerPage + return x.Name + } + return "" +} + +func (x *Dog) GetKind() string { + if x != nil { + return x.Kind + } + return "" +} + +func (x *Dog) GetBarkVolume() int32 { + if x != nil { + return x.BarkVolume } return 0 } -type OrderLineInput struct { +func (x *Dog) GetOwner() *Owner { + if x != nil { + return x.Owner + } + return nil +} + +func (x *Dog) GetBreed() *DogBreed { + if x != nil { + return x.Breed + } + return nil +} + +type Owner struct { state protoimpl.MessageState `protogen:"open.v1"` - ProductId string `protobuf:"bytes,1,opt,name=product_id,json=productId,proto3" json:"product_id,omitempty"` - Quantity int32 `protobuf:"varint,2,opt,name=quantity,proto3" json:"quantity,omitempty"` - Modifiers *ListOfString `protobuf:"bytes,3,opt,name=modifiers,proto3" json:"modifiers,omitempty"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Contact *ContactInfo `protobuf:"bytes,3,opt,name=contact,proto3" json:"contact,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *OrderLineInput) Reset() { - *x = OrderLineInput{} - mi := &file_product_proto_msgTypes[176] +func (x *Owner) Reset() { + *x = Owner{} + mi := &file_product_proto_msgTypes[223] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *OrderLineInput) String() string { +func (x *Owner) String() string { return protoimpl.X.MessageStringOf(x) } -func (*OrderLineInput) ProtoMessage() {} +func (*Owner) ProtoMessage() {} -func (x *OrderLineInput) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[176] +func (x *Owner) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[223] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9106,56 +11536,56 @@ func (x *OrderLineInput) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use OrderLineInput.ProtoReflect.Descriptor instead. -func (*OrderLineInput) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{176} +// Deprecated: Use Owner.ProtoReflect.Descriptor instead. +func (*Owner) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{223} } -func (x *OrderLineInput) GetProductId() string { +func (x *Owner) GetId() string { if x != nil { - return x.ProductId + return x.Id } return "" } -func (x *OrderLineInput) GetQuantity() int32 { +func (x *Owner) GetName() string { if x != nil { - return x.Quantity + return x.Name } - return 0 + return "" } -func (x *OrderLineInput) GetModifiers() *ListOfString { +func (x *Owner) GetContact() *ContactInfo { if x != nil { - return x.Modifiers + return x.Contact } return nil } -type OrderLine struct { +type ContactInfo struct { state protoimpl.MessageState `protogen:"open.v1"` - ProductId string `protobuf:"bytes,1,opt,name=product_id,json=productId,proto3" json:"product_id,omitempty"` - Quantity int32 `protobuf:"varint,2,opt,name=quantity,proto3" json:"quantity,omitempty"` - Modifiers *ListOfString `protobuf:"bytes,3,opt,name=modifiers,proto3" json:"modifiers,omitempty"` + Email string `protobuf:"bytes,1,opt,name=email,proto3" json:"email,omitempty"` + Phone string `protobuf:"bytes,2,opt,name=phone,proto3" json:"phone,omitempty"` + Address *Address `protobuf:"bytes,3,opt,name=address,proto3" json:"address,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *OrderLine) Reset() { - *x = OrderLine{} - mi := &file_product_proto_msgTypes[177] +func (x *ContactInfo) Reset() { + *x = ContactInfo{} + mi := &file_product_proto_msgTypes[224] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *OrderLine) String() string { +func (x *ContactInfo) String() string { return protoimpl.X.MessageStringOf(x) } -func (*OrderLine) ProtoMessage() {} +func (*ContactInfo) ProtoMessage() {} -func (x *OrderLine) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[177] +func (x *ContactInfo) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[224] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9166,57 +11596,57 @@ func (x *OrderLine) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use OrderLine.ProtoReflect.Descriptor instead. -func (*OrderLine) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{177} +// Deprecated: Use ContactInfo.ProtoReflect.Descriptor instead. +func (*ContactInfo) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{224} } -func (x *OrderLine) GetProductId() string { +func (x *ContactInfo) GetEmail() string { if x != nil { - return x.ProductId + return x.Email } return "" } -func (x *OrderLine) GetQuantity() int32 { +func (x *ContactInfo) GetPhone() string { if x != nil { - return x.Quantity + return x.Phone } - return 0 + return "" } -func (x *OrderLine) GetModifiers() *ListOfString { +func (x *ContactInfo) GetAddress() *Address { if x != nil { - return x.Modifiers + return x.Address } return nil } -type Subcategory struct { - state protoimpl.MessageState `protogen:"open.v1"` - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - Description *wrapperspb.StringValue `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` - IsActive bool `protobuf:"varint,4,opt,name=is_active,json=isActive,proto3" json:"is_active,omitempty"` +type Address struct { + state protoimpl.MessageState `protogen:"open.v1"` + Street string `protobuf:"bytes,1,opt,name=street,proto3" json:"street,omitempty"` + City string `protobuf:"bytes,2,opt,name=city,proto3" json:"city,omitempty"` + Country string `protobuf:"bytes,3,opt,name=country,proto3" json:"country,omitempty"` + ZipCode string `protobuf:"bytes,4,opt,name=zip_code,json=zipCode,proto3" json:"zip_code,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *Subcategory) Reset() { - *x = Subcategory{} - mi := &file_product_proto_msgTypes[178] +func (x *Address) Reset() { + *x = Address{} + mi := &file_product_proto_msgTypes[225] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *Subcategory) String() string { +func (x *Address) String() string { return protoimpl.X.MessageStringOf(x) } -func (*Subcategory) ProtoMessage() {} +func (*Address) ProtoMessage() {} -func (x *Subcategory) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[178] +func (x *Address) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[225] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9227,65 +11657,64 @@ func (x *Subcategory) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use Subcategory.ProtoReflect.Descriptor instead. -func (*Subcategory) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{178} +// Deprecated: Use Address.ProtoReflect.Descriptor instead. +func (*Address) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{225} } -func (x *Subcategory) GetId() string { +func (x *Address) GetStreet() string { if x != nil { - return x.Id + return x.Street } return "" } -func (x *Subcategory) GetName() string { +func (x *Address) GetCity() string { if x != nil { - return x.Name + return x.City } return "" } -func (x *Subcategory) GetDescription() *wrapperspb.StringValue { +func (x *Address) GetCountry() string { if x != nil { - return x.Description + return x.Country } - return nil + return "" } -func (x *Subcategory) GetIsActive() bool { +func (x *Address) GetZipCode() string { if x != nil { - return x.IsActive + return x.ZipCode } - return false + return "" } -type CategoryMetrics struct { - state protoimpl.MessageState `protogen:"open.v1"` - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - MetricType string `protobuf:"bytes,2,opt,name=metric_type,json=metricType,proto3" json:"metric_type,omitempty"` - Value float64 `protobuf:"fixed64,3,opt,name=value,proto3" json:"value,omitempty"` - Timestamp string `protobuf:"bytes,4,opt,name=timestamp,proto3" json:"timestamp,omitempty"` - CategoryId string `protobuf:"bytes,5,opt,name=category_id,json=categoryId,proto3" json:"category_id,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +type CatBreed struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Origin string `protobuf:"bytes,3,opt,name=origin,proto3" json:"origin,omitempty"` + Characteristics *BreedCharacteristics `protobuf:"bytes,4,opt,name=characteristics,proto3" json:"characteristics,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *CategoryMetrics) Reset() { - *x = CategoryMetrics{} - mi := &file_product_proto_msgTypes[179] +func (x *CatBreed) Reset() { + *x = CatBreed{} + mi := &file_product_proto_msgTypes[226] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *CategoryMetrics) String() string { +func (x *CatBreed) String() string { return protoimpl.X.MessageStringOf(x) } -func (*CategoryMetrics) ProtoMessage() {} +func (*CatBreed) ProtoMessage() {} -func (x *CategoryMetrics) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[179] +func (x *CatBreed) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[226] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9296,71 +11725,64 @@ func (x *CategoryMetrics) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use CategoryMetrics.ProtoReflect.Descriptor instead. -func (*CategoryMetrics) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{179} +// Deprecated: Use CatBreed.ProtoReflect.Descriptor instead. +func (*CatBreed) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{226} } -func (x *CategoryMetrics) GetId() string { +func (x *CatBreed) GetId() string { if x != nil { return x.Id } return "" } -func (x *CategoryMetrics) GetMetricType() string { +func (x *CatBreed) GetName() string { if x != nil { - return x.MetricType + return x.Name } return "" } -func (x *CategoryMetrics) GetValue() float64 { - if x != nil { - return x.Value - } - return 0 -} - -func (x *CategoryMetrics) GetTimestamp() string { +func (x *CatBreed) GetOrigin() string { if x != nil { - return x.Timestamp + return x.Origin } return "" } -func (x *CategoryMetrics) GetCategoryId() string { +func (x *CatBreed) GetCharacteristics() *BreedCharacteristics { if x != nil { - return x.CategoryId + return x.Characteristics } - return "" + return nil } -type Cat struct { - state protoimpl.MessageState `protogen:"open.v1"` - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - Kind string `protobuf:"bytes,3,opt,name=kind,proto3" json:"kind,omitempty"` - MeowVolume int32 `protobuf:"varint,4,opt,name=meow_volume,json=meowVolume,proto3" json:"meow_volume,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +type DogBreed struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Origin string `protobuf:"bytes,3,opt,name=origin,proto3" json:"origin,omitempty"` + Characteristics *BreedCharacteristics `protobuf:"bytes,4,opt,name=characteristics,proto3" json:"characteristics,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *Cat) Reset() { - *x = Cat{} - mi := &file_product_proto_msgTypes[180] +func (x *DogBreed) Reset() { + *x = DogBreed{} + mi := &file_product_proto_msgTypes[227] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *Cat) String() string { +func (x *DogBreed) String() string { return protoimpl.X.MessageStringOf(x) } -func (*Cat) ProtoMessage() {} +func (*DogBreed) ProtoMessage() {} -func (x *Cat) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[180] +func (x *DogBreed) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[227] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9371,64 +11793,63 @@ func (x *Cat) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use Cat.ProtoReflect.Descriptor instead. -func (*Cat) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{180} +// Deprecated: Use DogBreed.ProtoReflect.Descriptor instead. +func (*DogBreed) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{227} } -func (x *Cat) GetId() string { +func (x *DogBreed) GetId() string { if x != nil { return x.Id } return "" } -func (x *Cat) GetName() string { +func (x *DogBreed) GetName() string { if x != nil { return x.Name } return "" } -func (x *Cat) GetKind() string { +func (x *DogBreed) GetOrigin() string { if x != nil { - return x.Kind + return x.Origin } return "" } -func (x *Cat) GetMeowVolume() int32 { +func (x *DogBreed) GetCharacteristics() *BreedCharacteristics { if x != nil { - return x.MeowVolume + return x.Characteristics } - return 0 + return nil } -type Dog struct { +type BreedCharacteristics struct { state protoimpl.MessageState `protogen:"open.v1"` - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - Kind string `protobuf:"bytes,3,opt,name=kind,proto3" json:"kind,omitempty"` - BarkVolume int32 `protobuf:"varint,4,opt,name=bark_volume,json=barkVolume,proto3" json:"bark_volume,omitempty"` + Size string `protobuf:"bytes,1,opt,name=size,proto3" json:"size,omitempty"` + Temperament string `protobuf:"bytes,2,opt,name=temperament,proto3" json:"temperament,omitempty"` + Lifespan string `protobuf:"bytes,3,opt,name=lifespan,proto3" json:"lifespan,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *Dog) Reset() { - *x = Dog{} - mi := &file_product_proto_msgTypes[181] +func (x *BreedCharacteristics) Reset() { + *x = BreedCharacteristics{} + mi := &file_product_proto_msgTypes[228] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *Dog) String() string { +func (x *BreedCharacteristics) String() string { return protoimpl.X.MessageStringOf(x) } -func (*Dog) ProtoMessage() {} +func (*BreedCharacteristics) ProtoMessage() {} -func (x *Dog) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[181] +func (x *BreedCharacteristics) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[228] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9439,39 +11860,32 @@ func (x *Dog) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use Dog.ProtoReflect.Descriptor instead. -func (*Dog) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{181} +// Deprecated: Use BreedCharacteristics.ProtoReflect.Descriptor instead. +func (*BreedCharacteristics) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{228} } -func (x *Dog) GetId() string { +func (x *BreedCharacteristics) GetSize() string { if x != nil { - return x.Id + return x.Size } return "" } -func (x *Dog) GetName() string { +func (x *BreedCharacteristics) GetTemperament() string { if x != nil { - return x.Name + return x.Temperament } return "" } -func (x *Dog) GetKind() string { +func (x *BreedCharacteristics) GetLifespan() string { if x != nil { - return x.Kind + return x.Lifespan } return "" } -func (x *Dog) GetBarkVolume() int32 { - if x != nil { - return x.BarkVolume - } - return 0 -} - type ActionSuccess struct { state protoimpl.MessageState `protogen:"open.v1"` Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` @@ -9482,7 +11896,7 @@ type ActionSuccess struct { func (x *ActionSuccess) Reset() { *x = ActionSuccess{} - mi := &file_product_proto_msgTypes[182] + mi := &file_product_proto_msgTypes[229] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9494,7 +11908,7 @@ func (x *ActionSuccess) String() string { func (*ActionSuccess) ProtoMessage() {} func (x *ActionSuccess) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[182] + mi := &file_product_proto_msgTypes[229] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9507,7 +11921,7 @@ func (x *ActionSuccess) ProtoReflect() protoreflect.Message { // Deprecated: Use ActionSuccess.ProtoReflect.Descriptor instead. func (*ActionSuccess) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{182} + return file_product_proto_rawDescGZIP(), []int{229} } func (x *ActionSuccess) GetMessage() string { @@ -9534,7 +11948,7 @@ type ActionError struct { func (x *ActionError) Reset() { *x = ActionError{} - mi := &file_product_proto_msgTypes[183] + mi := &file_product_proto_msgTypes[230] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9546,7 +11960,7 @@ func (x *ActionError) String() string { func (*ActionError) ProtoMessage() {} func (x *ActionError) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[183] + mi := &file_product_proto_msgTypes[230] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9559,7 +11973,7 @@ func (x *ActionError) ProtoReflect() protoreflect.Message { // Deprecated: Use ActionError.ProtoReflect.Descriptor instead. func (*ActionError) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{183} + return file_product_proto_rawDescGZIP(), []int{230} } func (x *ActionError) GetMessage() string { @@ -9576,6 +11990,74 @@ func (x *ActionError) GetCode() string { return "" } +type TestDetails struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Summary string `protobuf:"bytes,2,opt,name=summary,proto3" json:"summary,omitempty"` + Pet *Animal `protobuf:"bytes,3,opt,name=pet,proto3" json:"pet,omitempty"` + Status *ActionResult `protobuf:"bytes,4,opt,name=status,proto3" json:"status,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *TestDetails) Reset() { + *x = TestDetails{} + mi := &file_product_proto_msgTypes[231] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *TestDetails) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TestDetails) ProtoMessage() {} + +func (x *TestDetails) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[231] + 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 TestDetails.ProtoReflect.Descriptor instead. +func (*TestDetails) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{231} +} + +func (x *TestDetails) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *TestDetails) GetSummary() string { + if x != nil { + return x.Summary + } + return "" +} + +func (x *TestDetails) GetPet() *Animal { + if x != nil { + return x.Pet + } + return nil +} + +func (x *TestDetails) GetStatus() *ActionResult { + if x != nil { + return x.Status + } + return nil +} + type CategoryInput struct { state protoimpl.MessageState `protogen:"open.v1"` Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` @@ -9586,7 +12068,7 @@ type CategoryInput struct { func (x *CategoryInput) Reset() { *x = CategoryInput{} - mi := &file_product_proto_msgTypes[184] + mi := &file_product_proto_msgTypes[232] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9598,7 +12080,7 @@ func (x *CategoryInput) String() string { func (*CategoryInput) ProtoMessage() {} func (x *CategoryInput) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[184] + mi := &file_product_proto_msgTypes[232] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9611,7 +12093,7 @@ func (x *CategoryInput) ProtoReflect() protoreflect.Message { // Deprecated: Use CategoryInput.ProtoReflect.Descriptor instead. func (*CategoryInput) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{184} + return file_product_proto_rawDescGZIP(), []int{232} } func (x *CategoryInput) GetName() string { @@ -9640,7 +12122,7 @@ type ProductCountFilter struct { func (x *ProductCountFilter) Reset() { *x = ProductCountFilter{} - mi := &file_product_proto_msgTypes[185] + mi := &file_product_proto_msgTypes[233] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9652,7 +12134,7 @@ func (x *ProductCountFilter) String() string { func (*ProductCountFilter) ProtoMessage() {} func (x *ProductCountFilter) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[185] + mi := &file_product_proto_msgTypes[233] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9665,7 +12147,7 @@ func (x *ProductCountFilter) ProtoReflect() protoreflect.Message { // Deprecated: Use ProductCountFilter.ProtoReflect.Descriptor instead. func (*ProductCountFilter) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{185} + return file_product_proto_rawDescGZIP(), []int{233} } func (x *ProductCountFilter) GetMinPrice() *wrapperspb.DoubleValue { @@ -9709,7 +12191,7 @@ type SubcategoryItemFilter struct { func (x *SubcategoryItemFilter) Reset() { *x = SubcategoryItemFilter{} - mi := &file_product_proto_msgTypes[186] + mi := &file_product_proto_msgTypes[234] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9721,7 +12203,7 @@ func (x *SubcategoryItemFilter) String() string { func (*SubcategoryItemFilter) ProtoMessage() {} func (x *SubcategoryItemFilter) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[186] + mi := &file_product_proto_msgTypes[234] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9734,7 +12216,7 @@ func (x *SubcategoryItemFilter) ProtoReflect() protoreflect.Message { // Deprecated: Use SubcategoryItemFilter.ProtoReflect.Descriptor instead. func (*SubcategoryItemFilter) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{186} + return file_product_proto_rawDescGZIP(), []int{234} } func (x *SubcategoryItemFilter) GetMinPrice() *wrapperspb.DoubleValue { @@ -9783,7 +12265,7 @@ type ShippingEstimateInput struct { func (x *ShippingEstimateInput) Reset() { *x = ShippingEstimateInput{} - mi := &file_product_proto_msgTypes[187] + mi := &file_product_proto_msgTypes[235] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9795,7 +12277,7 @@ func (x *ShippingEstimateInput) String() string { func (*ShippingEstimateInput) ProtoMessage() {} func (x *ShippingEstimateInput) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[187] + mi := &file_product_proto_msgTypes[235] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9808,7 +12290,7 @@ func (x *ShippingEstimateInput) ProtoReflect() protoreflect.Message { // Deprecated: Use ShippingEstimateInput.ProtoReflect.Descriptor instead. func (*ShippingEstimateInput) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{187} + return file_product_proto_rawDescGZIP(), []int{235} } func (x *ShippingEstimateInput) GetDestination() ShippingDestination { @@ -9841,7 +12323,7 @@ type ListOfAuthorFilter_List struct { func (x *ListOfAuthorFilter_List) Reset() { *x = ListOfAuthorFilter_List{} - mi := &file_product_proto_msgTypes[188] + mi := &file_product_proto_msgTypes[236] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9853,7 +12335,7 @@ func (x *ListOfAuthorFilter_List) String() string { func (*ListOfAuthorFilter_List) ProtoMessage() {} func (x *ListOfAuthorFilter_List) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[188] + mi := &file_product_proto_msgTypes[236] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9885,7 +12367,7 @@ type ListOfAuthorInput_List struct { func (x *ListOfAuthorInput_List) Reset() { *x = ListOfAuthorInput_List{} - mi := &file_product_proto_msgTypes[189] + mi := &file_product_proto_msgTypes[237] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9897,7 +12379,7 @@ func (x *ListOfAuthorInput_List) String() string { func (*ListOfAuthorInput_List) ProtoMessage() {} func (x *ListOfAuthorInput_List) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[189] + mi := &file_product_proto_msgTypes[237] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9929,7 +12411,7 @@ type ListOfBlogPost_List struct { func (x *ListOfBlogPost_List) Reset() { *x = ListOfBlogPost_List{} - mi := &file_product_proto_msgTypes[190] + mi := &file_product_proto_msgTypes[238] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9941,7 +12423,7 @@ func (x *ListOfBlogPost_List) String() string { func (*ListOfBlogPost_List) ProtoMessage() {} func (x *ListOfBlogPost_List) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[190] + mi := &file_product_proto_msgTypes[238] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9973,7 +12455,7 @@ type ListOfBlogPostFilter_List struct { func (x *ListOfBlogPostFilter_List) Reset() { *x = ListOfBlogPostFilter_List{} - mi := &file_product_proto_msgTypes[191] + mi := &file_product_proto_msgTypes[239] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9985,7 +12467,7 @@ func (x *ListOfBlogPostFilter_List) String() string { func (*ListOfBlogPostFilter_List) ProtoMessage() {} func (x *ListOfBlogPostFilter_List) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[191] + mi := &file_product_proto_msgTypes[239] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10017,7 +12499,7 @@ type ListOfBlogPostInput_List struct { func (x *ListOfBlogPostInput_List) Reset() { *x = ListOfBlogPostInput_List{} - mi := &file_product_proto_msgTypes[192] + mi := &file_product_proto_msgTypes[240] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10029,7 +12511,7 @@ func (x *ListOfBlogPostInput_List) String() string { func (*ListOfBlogPostInput_List) ProtoMessage() {} func (x *ListOfBlogPostInput_List) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[192] + mi := &file_product_proto_msgTypes[240] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10061,7 +12543,7 @@ type ListOfBoolean_List struct { func (x *ListOfBoolean_List) Reset() { *x = ListOfBoolean_List{} - mi := &file_product_proto_msgTypes[193] + mi := &file_product_proto_msgTypes[241] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10073,7 +12555,7 @@ func (x *ListOfBoolean_List) String() string { func (*ListOfBoolean_List) ProtoMessage() {} func (x *ListOfBoolean_List) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[193] + mi := &file_product_proto_msgTypes[241] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10105,7 +12587,7 @@ type ListOfCategory_List struct { func (x *ListOfCategory_List) Reset() { *x = ListOfCategory_List{} - mi := &file_product_proto_msgTypes[194] + mi := &file_product_proto_msgTypes[242] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10117,7 +12599,7 @@ func (x *ListOfCategory_List) String() string { func (*ListOfCategory_List) ProtoMessage() {} func (x *ListOfCategory_List) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[194] + mi := &file_product_proto_msgTypes[242] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10149,7 +12631,7 @@ type ListOfCategoryInput_List struct { func (x *ListOfCategoryInput_List) Reset() { *x = ListOfCategoryInput_List{} - mi := &file_product_proto_msgTypes[195] + mi := &file_product_proto_msgTypes[243] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10161,7 +12643,7 @@ func (x *ListOfCategoryInput_List) String() string { func (*ListOfCategoryInput_List) ProtoMessage() {} func (x *ListOfCategoryInput_List) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[195] + mi := &file_product_proto_msgTypes[243] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10193,7 +12675,7 @@ type ListOfFloat_List struct { func (x *ListOfFloat_List) Reset() { *x = ListOfFloat_List{} - mi := &file_product_proto_msgTypes[196] + mi := &file_product_proto_msgTypes[244] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10205,7 +12687,7 @@ func (x *ListOfFloat_List) String() string { func (*ListOfFloat_List) ProtoMessage() {} func (x *ListOfFloat_List) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[196] + mi := &file_product_proto_msgTypes[244] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10237,7 +12719,7 @@ type ListOfListOfCategory_List struct { func (x *ListOfListOfCategory_List) Reset() { *x = ListOfListOfCategory_List{} - mi := &file_product_proto_msgTypes[197] + mi := &file_product_proto_msgTypes[245] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10249,7 +12731,7 @@ func (x *ListOfListOfCategory_List) String() string { func (*ListOfListOfCategory_List) ProtoMessage() {} func (x *ListOfListOfCategory_List) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[197] + mi := &file_product_proto_msgTypes[245] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10281,7 +12763,7 @@ type ListOfListOfCategoryInput_List struct { func (x *ListOfListOfCategoryInput_List) Reset() { *x = ListOfListOfCategoryInput_List{} - mi := &file_product_proto_msgTypes[198] + mi := &file_product_proto_msgTypes[246] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10293,7 +12775,7 @@ func (x *ListOfListOfCategoryInput_List) String() string { func (*ListOfListOfCategoryInput_List) ProtoMessage() {} func (x *ListOfListOfCategoryInput_List) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[198] + mi := &file_product_proto_msgTypes[246] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10325,7 +12807,7 @@ type ListOfListOfString_List struct { func (x *ListOfListOfString_List) Reset() { *x = ListOfListOfString_List{} - mi := &file_product_proto_msgTypes[199] + mi := &file_product_proto_msgTypes[247] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10337,7 +12819,7 @@ func (x *ListOfListOfString_List) String() string { func (*ListOfListOfString_List) ProtoMessage() {} func (x *ListOfListOfString_List) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[199] + mi := &file_product_proto_msgTypes[247] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10369,7 +12851,7 @@ type ListOfListOfUser_List struct { func (x *ListOfListOfUser_List) Reset() { *x = ListOfListOfUser_List{} - mi := &file_product_proto_msgTypes[200] + mi := &file_product_proto_msgTypes[248] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10381,7 +12863,7 @@ func (x *ListOfListOfUser_List) String() string { func (*ListOfListOfUser_List) ProtoMessage() {} func (x *ListOfListOfUser_List) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[200] + mi := &file_product_proto_msgTypes[248] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10413,7 +12895,7 @@ type ListOfListOfUserInput_List struct { func (x *ListOfListOfUserInput_List) Reset() { *x = ListOfListOfUserInput_List{} - mi := &file_product_proto_msgTypes[201] + mi := &file_product_proto_msgTypes[249] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10425,7 +12907,7 @@ func (x *ListOfListOfUserInput_List) String() string { func (*ListOfListOfUserInput_List) ProtoMessage() {} func (x *ListOfListOfUserInput_List) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[201] + mi := &file_product_proto_msgTypes[249] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10457,7 +12939,7 @@ type ListOfOrderLine_List struct { func (x *ListOfOrderLine_List) Reset() { *x = ListOfOrderLine_List{} - mi := &file_product_proto_msgTypes[202] + mi := &file_product_proto_msgTypes[250] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10469,7 +12951,7 @@ func (x *ListOfOrderLine_List) String() string { func (*ListOfOrderLine_List) ProtoMessage() {} func (x *ListOfOrderLine_List) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[202] + mi := &file_product_proto_msgTypes[250] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10501,7 +12983,7 @@ type ListOfProduct_List struct { func (x *ListOfProduct_List) Reset() { *x = ListOfProduct_List{} - mi := &file_product_proto_msgTypes[203] + mi := &file_product_proto_msgTypes[251] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10513,7 +12995,7 @@ func (x *ListOfProduct_List) String() string { func (*ListOfProduct_List) ProtoMessage() {} func (x *ListOfProduct_List) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[203] + mi := &file_product_proto_msgTypes[251] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10545,7 +13027,7 @@ type ListOfString_List struct { func (x *ListOfString_List) Reset() { *x = ListOfString_List{} - mi := &file_product_proto_msgTypes[204] + mi := &file_product_proto_msgTypes[252] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10557,7 +13039,7 @@ func (x *ListOfString_List) String() string { func (*ListOfString_List) ProtoMessage() {} func (x *ListOfString_List) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[204] + mi := &file_product_proto_msgTypes[252] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10589,7 +13071,7 @@ type ListOfSubcategory_List struct { func (x *ListOfSubcategory_List) Reset() { *x = ListOfSubcategory_List{} - mi := &file_product_proto_msgTypes[205] + mi := &file_product_proto_msgTypes[253] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10601,7 +13083,7 @@ func (x *ListOfSubcategory_List) String() string { func (*ListOfSubcategory_List) ProtoMessage() {} func (x *ListOfSubcategory_List) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[205] + mi := &file_product_proto_msgTypes[253] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10633,7 +13115,7 @@ type ListOfUser_List struct { func (x *ListOfUser_List) Reset() { *x = ListOfUser_List{} - mi := &file_product_proto_msgTypes[206] + mi := &file_product_proto_msgTypes[254] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10645,7 +13127,7 @@ func (x *ListOfUser_List) String() string { func (*ListOfUser_List) ProtoMessage() {} func (x *ListOfUser_List) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[206] + mi := &file_product_proto_msgTypes[254] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10677,7 +13159,7 @@ type ListOfUserInput_List struct { func (x *ListOfUserInput_List) Reset() { *x = ListOfUserInput_List{} - mi := &file_product_proto_msgTypes[207] + mi := &file_product_proto_msgTypes[255] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10689,7 +13171,7 @@ func (x *ListOfUserInput_List) String() string { func (*ListOfUserInput_List) ProtoMessage() {} func (x *ListOfUserInput_List) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[207] + mi := &file_product_proto_msgTypes[255] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10929,7 +13411,14 @@ const file_product_proto_rawDesc = "" + "\x1fQueryBulkSearchBlogPostsRequest\x129\n" + "\afilters\x18\x01 \x01(\v2\x1f.productv1.ListOfBlogPostFilterR\afilters\"l\n" + " QueryBulkSearchBlogPostsResponse\x12H\n" + - "\x16bulk_search_blog_posts\x18\x01 \x03(\v2\x13.productv1.BlogPostR\x13bulkSearchBlogPosts\"G\n" + + "\x16bulk_search_blog_posts\x18\x01 \x03(\v2\x13.productv1.BlogPostR\x13bulkSearchBlogPosts\"+\n" + + "\x19QueryTestContainerRequest\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\"]\n" + + "\x1aQueryTestContainerResponse\x12?\n" + + "\x0etest_container\x18\x01 \x01(\v2\x18.productv1.TestContainerR\rtestContainer\"\x1c\n" + + "\x1aQueryTestContainersRequest\"`\n" + + "\x1bQueryTestContainersResponse\x12A\n" + + "\x0ftest_containers\x18\x01 \x03(\v2\x18.productv1.TestContainerR\x0etestContainers\"G\n" + "\x19MutationCreateUserRequest\x12*\n" + "\x05input\x18\x01 \x01(\v2\x14.productv1.UserInputR\x05input\"N\n" + "\x1aMutationCreateUserResponse\x120\n" + @@ -11010,7 +13499,48 @@ const file_product_proto_rawDesc = "" + "'ResolveProductRecommendedCategoryResult\x12F\n" + "\x14recommended_category\x18\x01 \x01(\v2\x13.productv1.CategoryR\x13recommendedCategory\"w\n" + ")ResolveProductRecommendedCategoryResponse\x12J\n" + - "\x06result\x18\x01 \x03(\v22.productv1.ResolveProductRecommendedCategoryResultR\x06result\"Z\n" + + "\x06result\x18\x01 \x03(\v22.productv1.ResolveProductRecommendedCategoryResultR\x06result\"Q\n" + + "&ResolveProductMascotRecommendationArgs\x12'\n" + + "\x0finclude_details\x18\x01 \x01(\bR\x0eincludeDetails\"O\n" + + ")ResolveProductMascotRecommendationContext\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n" + + "\x04name\x18\x02 \x01(\tR\x04name\"\xcd\x01\n" + + ")ResolveProductMascotRecommendationRequest\x12N\n" + + "\acontext\x18\x01 \x03(\v24.productv1.ResolveProductMascotRecommendationContextR\acontext\x12P\n" + + "\n" + + "field_args\x18\x02 \x01(\v21.productv1.ResolveProductMascotRecommendationArgsR\tfieldArgs\"r\n" + + "(ResolveProductMascotRecommendationResult\x12F\n" + + "\x15mascot_recommendation\x18\x01 \x01(\v2\x11.productv1.AnimalR\x14mascotRecommendation\"y\n" + + "*ResolveProductMascotRecommendationResponse\x12K\n" + + "\x06result\x18\x01 \x03(\v23.productv1.ResolveProductMascotRecommendationResultR\x06result\"N\n" + + "\x1dResolveProductStockStatusArgs\x12-\n" + + "\x12check_availability\x18\x01 \x01(\bR\x11checkAvailability\"\\\n" + + " ResolveProductStockStatusContext\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n" + + "\x04name\x18\x02 \x01(\tR\x04name\x12\x14\n" + + "\x05price\x18\x03 \x01(\x01R\x05price\"\xb2\x01\n" + + " ResolveProductStockStatusRequest\x12E\n" + + "\acontext\x18\x01 \x03(\v2+.productv1.ResolveProductStockStatusContextR\acontext\x12G\n" + + "\n" + + "field_args\x18\x02 \x01(\v2(.productv1.ResolveProductStockStatusArgsR\tfieldArgs\"]\n" + + "\x1fResolveProductStockStatusResult\x12:\n" + + "\fstock_status\x18\x01 \x01(\v2\x17.productv1.ActionResultR\vstockStatus\"g\n" + + "!ResolveProductStockStatusResponse\x12B\n" + + "\x06result\x18\x01 \x03(\v2*.productv1.ResolveProductStockStatusResultR\x06result\"M\n" + + " ResolveProductProductDetailsArgs\x12)\n" + + "\x10include_extended\x18\x01 \x01(\bR\x0fincludeExtended\"_\n" + + "#ResolveProductProductDetailsContext\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n" + + "\x04name\x18\x02 \x01(\tR\x04name\x12\x14\n" + + "\x05price\x18\x03 \x01(\x01R\x05price\"\xbb\x01\n" + + "#ResolveProductProductDetailsRequest\x12H\n" + + "\acontext\x18\x01 \x03(\v2..productv1.ResolveProductProductDetailsContextR\acontext\x12J\n" + + "\n" + + "field_args\x18\x02 \x01(\v2+.productv1.ResolveProductProductDetailsArgsR\tfieldArgs\"h\n" + + "\"ResolveProductProductDetailsResult\x12B\n" + + "\x0fproduct_details\x18\x01 \x01(\v2\x19.productv1.ProductDetailsR\x0eproductDetails\"m\n" + + "$ResolveProductProductDetailsResponse\x12E\n" + + "\x06result\x18\x01 \x03(\v2-.productv1.ResolveProductProductDetailsResultR\x06result\"Z\n" + "\x1fResolveCategoryProductCountArgs\x127\n" + "\afilters\x18\x01 \x01(\v2\x1d.productv1.ProductCountFilterR\afilters\"H\n" + "\"ResolveCategoryProductCountContext\x12\x0e\n" + @@ -11049,7 +13579,33 @@ const file_product_proto_rawDesc = "" + "$ResolveCategoryCategoryMetricsResult\x12E\n" + "\x10category_metrics\x18\x01 \x01(\v2\x1a.productv1.CategoryMetricsR\x0fcategoryMetrics\"q\n" + "&ResolveCategoryCategoryMetricsResponse\x12G\n" + - "\x06result\x18\x01 \x03(\v2/.productv1.ResolveCategoryCategoryMetricsResultR\x06result\"]\n" + + "\x06result\x18\x01 \x03(\v2/.productv1.ResolveCategoryCategoryMetricsResultR\x06result\"B\n" + + "\x19ResolveCategoryMascotArgs\x12%\n" + + "\x0einclude_volume\x18\x01 \x01(\bR\rincludeVolume\"[\n" + + "\x1cResolveCategoryMascotContext\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12+\n" + + "\x04kind\x18\x02 \x01(\x0e2\x17.productv1.CategoryKindR\x04kind\"\xa6\x01\n" + + "\x1cResolveCategoryMascotRequest\x12A\n" + + "\acontext\x18\x01 \x03(\v2'.productv1.ResolveCategoryMascotContextR\acontext\x12C\n" + + "\n" + + "field_args\x18\x02 \x01(\v2$.productv1.ResolveCategoryMascotArgsR\tfieldArgs\"H\n" + + "\x1bResolveCategoryMascotResult\x12)\n" + + "\x06mascot\x18\x01 \x01(\v2\x11.productv1.AnimalR\x06mascot\"_\n" + + "\x1dResolveCategoryMascotResponse\x12>\n" + + "\x06result\x18\x01 \x03(\v2&.productv1.ResolveCategoryMascotResultR\x06result\"F\n" + + "!ResolveCategoryCategoryStatusArgs\x12!\n" + + "\fcheck_health\x18\x01 \x01(\bR\vcheckHealth\"J\n" + + "$ResolveCategoryCategoryStatusContext\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n" + + "\x04name\x18\x02 \x01(\tR\x04name\"\xbe\x01\n" + + "$ResolveCategoryCategoryStatusRequest\x12I\n" + + "\acontext\x18\x01 \x03(\v2/.productv1.ResolveCategoryCategoryStatusContextR\acontext\x12K\n" + + "\n" + + "field_args\x18\x02 \x01(\v2,.productv1.ResolveCategoryCategoryStatusArgsR\tfieldArgs\"g\n" + + "#ResolveCategoryCategoryStatusResult\x12@\n" + + "\x0fcategory_status\x18\x01 \x01(\v2\x17.productv1.ActionResultR\x0ecategoryStatus\"o\n" + + "%ResolveCategoryCategoryStatusResponse\x12F\n" + + "\x06result\x18\x01 \x03(\v2..productv1.ResolveCategoryCategoryStatusResultR\x06result\"]\n" + "\x1fResolveSubcategoryItemCountArgs\x12:\n" + "\afilters\x18\x01 \x01(\v2 .productv1.SubcategoryItemFilterR\afilters\"4\n" + "\"ResolveSubcategoryItemCountContext\x12\x0e\n" + @@ -11062,7 +13618,36 @@ const file_product_proto_rawDesc = "" + "\n" + "item_count\x18\x01 \x01(\x05R\titemCount\"k\n" + "#ResolveSubcategoryItemCountResponse\x12D\n" + - "\x06result\x18\x01 \x03(\v2,.productv1.ResolveSubcategoryItemCountResultR\x06result\"C\n" + + "\x06result\x18\x01 \x03(\v2,.productv1.ResolveSubcategoryItemCountResultR\x06result\"G\n" + + ")ResolveCategoryMetricsNormalizedScoreArgs\x12\x1a\n" + + "\bbaseline\x18\x01 \x01(\x01R\bbaseline\"t\n" + + ",ResolveCategoryMetricsNormalizedScoreContext\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12\x1e\n" + + "\n" + + "metricType\x18\x02 \x01(\tR\n" + + "metricType\x12\x14\n" + + "\x05value\x18\x03 \x01(\x01R\x05value\"\xd6\x01\n" + + ",ResolveCategoryMetricsNormalizedScoreRequest\x12Q\n" + + "\acontext\x18\x01 \x03(\v27.productv1.ResolveCategoryMetricsNormalizedScoreContextR\acontext\x12S\n" + + "\n" + + "field_args\x18\x02 \x01(\v24.productv1.ResolveCategoryMetricsNormalizedScoreArgsR\tfieldArgs\"X\n" + + "+ResolveCategoryMetricsNormalizedScoreResult\x12)\n" + + "\x10normalized_score\x18\x01 \x01(\x01R\x0fnormalizedScore\"\x7f\n" + + "-ResolveCategoryMetricsNormalizedScoreResponse\x12N\n" + + "\x06result\x18\x01 \x03(\v26.productv1.ResolveCategoryMetricsNormalizedScoreResultR\x06result\"L\n" + + "\x1fResolveTestContainerDetailsArgs\x12)\n" + + "\x10include_extended\x18\x01 \x01(\bR\x0fincludeExtended\"H\n" + + "\"ResolveTestContainerDetailsContext\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n" + + "\x04name\x18\x02 \x01(\tR\x04name\"\xb8\x01\n" + + "\"ResolveTestContainerDetailsRequest\x12G\n" + + "\acontext\x18\x01 \x03(\v2-.productv1.ResolveTestContainerDetailsContextR\acontext\x12I\n" + + "\n" + + "field_args\x18\x02 \x01(\v2*.productv1.ResolveTestContainerDetailsArgsR\tfieldArgs\"U\n" + + "!ResolveTestContainerDetailsResult\x120\n" + + "\adetails\x18\x01 \x01(\v2\x16.productv1.TestDetailsR\adetails\"k\n" + + "#ResolveTestContainerDetailsResponse\x12D\n" + + "\x06result\x18\x01 \x03(\v2,.productv1.ResolveTestContainerDetailsResultR\x06result\"C\n" + "\aProduct\x12\x0e\n" + "\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n" + "\x04name\x18\x02 \x01(\tR\x04name\x12\x14\n" + @@ -11198,7 +13783,11 @@ const file_product_proto_rawDesc = "" + "\x04name\x18\x01 \x01(\v2\x1c.google.protobuf.StringValueR\x04name\x127\n" + "\thas_teams\x18\x02 \x01(\v2\x1a.google.protobuf.BoolValueR\bhasTeams\x12<\n" + "\vskill_count\x18\x03 \x01(\v2\x1b.google.protobuf.Int32ValueR\n" + - "skillCount\"\x1f\n" + + "skillCount\"s\n" + + "\rTestContainer\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n" + + "\x04name\x18\x02 \x01(\tR\x04name\x12>\n" + + "\vdescription\x18\x03 \x01(\v2\x1c.google.protobuf.StringValueR\vdescription\"\x1f\n" + "\tUserInput\x12\x12\n" + "\x04name\x18\x01 \x01(\tR\x04name\";\n" + "\vActionInput\x12\x12\n" + @@ -11249,7 +13838,12 @@ const file_product_proto_rawDesc = "" + "\x13favorite_categories\x18\b \x03(\v2\x18.productv1.CategoryInputR\x12favoriteCategories\x12E\n" + "\rauthor_groups\x18\t \x01(\v2 .productv1.ListOfListOfUserInputR\fauthorGroups\x12E\n" + "\rproject_teams\x18\n" + - " \x01(\v2 .productv1.ListOfListOfUserInputR\fprojectTeams\"W\n" + + " \x01(\v2 .productv1.ListOfListOfUserInputR\fprojectTeams\"\xbe\x01\n" + + "\x0eProductDetails\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12 \n" + + "\vdescription\x18\x02 \x01(\tR\vdescription\x12>\n" + + "\x0ereview_summary\x18\x03 \x01(\v2\x17.productv1.ActionResultR\rreviewSummary\x12:\n" + + "\x0frecommended_pet\x18\x04 \x01(\v2\x11.productv1.AnimalR\x0erecommendedPet\"W\n" + "\vNestedTypeB\x12\x0e\n" + "\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n" + "\x04name\x18\x02 \x01(\tR\x04name\x12$\n" + @@ -11283,7 +13877,7 @@ const file_product_proto_rawDesc = "" + "\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n" + "\x04name\x18\x02 \x01(\tR\x04name\x12>\n" + "\vdescription\x18\x03 \x01(\v2\x1c.google.protobuf.StringValueR\vdescription\x12\x1b\n" + - "\tis_active\x18\x04 \x01(\bR\bisActive\"\x97\x01\n" + + "\tis_active\x18\x04 \x01(\bR\bisActive\"\xd7\x01\n" + "\x0fCategoryMetrics\x12\x0e\n" + "\x02id\x18\x01 \x01(\tR\x02id\x12\x1f\n" + "\vmetric_type\x18\x02 \x01(\tR\n" + @@ -11291,25 +13885,62 @@ const file_product_proto_rawDesc = "" + "\x05value\x18\x03 \x01(\x01R\x05value\x12\x1c\n" + "\ttimestamp\x18\x04 \x01(\tR\ttimestamp\x12\x1f\n" + "\vcategory_id\x18\x05 \x01(\tR\n" + - "categoryId\"^\n" + + "categoryId\x12>\n" + + "\x10related_category\x18\x06 \x01(\v2\x13.productv1.CategoryR\x0frelatedCategory\"\xb1\x01\n" + "\x03Cat\x12\x0e\n" + "\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n" + "\x04name\x18\x02 \x01(\tR\x04name\x12\x12\n" + "\x04kind\x18\x03 \x01(\tR\x04kind\x12\x1f\n" + "\vmeow_volume\x18\x04 \x01(\x05R\n" + - "meowVolume\"^\n" + + "meowVolume\x12&\n" + + "\x05owner\x18\x05 \x01(\v2\x10.productv1.OwnerR\x05owner\x12)\n" + + "\x05breed\x18\x06 \x01(\v2\x13.productv1.CatBreedR\x05breed\"\xb1\x01\n" + "\x03Dog\x12\x0e\n" + "\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n" + "\x04name\x18\x02 \x01(\tR\x04name\x12\x12\n" + "\x04kind\x18\x03 \x01(\tR\x04kind\x12\x1f\n" + "\vbark_volume\x18\x04 \x01(\x05R\n" + - "barkVolume\"G\n" + + "barkVolume\x12&\n" + + "\x05owner\x18\x05 \x01(\v2\x10.productv1.OwnerR\x05owner\x12)\n" + + "\x05breed\x18\x06 \x01(\v2\x13.productv1.DogBreedR\x05breed\"]\n" + + "\x05Owner\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n" + + "\x04name\x18\x02 \x01(\tR\x04name\x120\n" + + "\acontact\x18\x03 \x01(\v2\x16.productv1.ContactInfoR\acontact\"g\n" + + "\vContactInfo\x12\x14\n" + + "\x05email\x18\x01 \x01(\tR\x05email\x12\x14\n" + + "\x05phone\x18\x02 \x01(\tR\x05phone\x12,\n" + + "\aaddress\x18\x03 \x01(\v2\x12.productv1.AddressR\aaddress\"j\n" + + "\aAddress\x12\x16\n" + + "\x06street\x18\x01 \x01(\tR\x06street\x12\x12\n" + + "\x04city\x18\x02 \x01(\tR\x04city\x12\x18\n" + + "\acountry\x18\x03 \x01(\tR\acountry\x12\x19\n" + + "\bzip_code\x18\x04 \x01(\tR\azipCode\"\x91\x01\n" + + "\bCatBreed\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n" + + "\x04name\x18\x02 \x01(\tR\x04name\x12\x16\n" + + "\x06origin\x18\x03 \x01(\tR\x06origin\x12I\n" + + "\x0fcharacteristics\x18\x04 \x01(\v2\x1f.productv1.BreedCharacteristicsR\x0fcharacteristics\"\x91\x01\n" + + "\bDogBreed\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n" + + "\x04name\x18\x02 \x01(\tR\x04name\x12\x16\n" + + "\x06origin\x18\x03 \x01(\tR\x06origin\x12I\n" + + "\x0fcharacteristics\x18\x04 \x01(\v2\x1f.productv1.BreedCharacteristicsR\x0fcharacteristics\"h\n" + + "\x14BreedCharacteristics\x12\x12\n" + + "\x04size\x18\x01 \x01(\tR\x04size\x12 \n" + + "\vtemperament\x18\x02 \x01(\tR\vtemperament\x12\x1a\n" + + "\blifespan\x18\x03 \x01(\tR\blifespan\"G\n" + "\rActionSuccess\x12\x18\n" + "\amessage\x18\x01 \x01(\tR\amessage\x12\x1c\n" + "\ttimestamp\x18\x02 \x01(\tR\ttimestamp\";\n" + "\vActionError\x12\x18\n" + "\amessage\x18\x01 \x01(\tR\amessage\x12\x12\n" + - "\x04code\x18\x02 \x01(\tR\x04code\"P\n" + + "\x04code\x18\x02 \x01(\tR\x04code\"\x8d\x01\n" + + "\vTestDetails\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12\x18\n" + + "\asummary\x18\x02 \x01(\tR\asummary\x12#\n" + + "\x03pet\x18\x03 \x01(\v2\x11.productv1.AnimalR\x03pet\x12/\n" + + "\x06status\x18\x04 \x01(\v2\x17.productv1.ActionResultR\x06status\"P\n" + "\rCategoryInput\x12\x12\n" + "\x04name\x18\x01 \x01(\tR\x04name\x12+\n" + "\x04kind\x18\x02 \x01(\x0e2\x17.productv1.CategoryKindR\x04kind\"\x80\x02\n" + @@ -11340,7 +13971,7 @@ const file_product_proto_rawDesc = "" + " SHIPPING_DESTINATION_UNSPECIFIED\x10\x00\x12!\n" + "\x1dSHIPPING_DESTINATION_DOMESTIC\x10\x01\x12 \n" + "\x1cSHIPPING_DESTINATION_EXPRESS\x10\x02\x12&\n" + - "\"SHIPPING_DESTINATION_INTERNATIONAL\x10\x032\xe9,\n" + + "\"SHIPPING_DESTINATION_INTERNATIONAL\x10\x032\xde5\n" + "\x0eProductService\x12`\n" + "\x11LookupProductById\x12#.productv1.LookupProductByIdRequest\x1a$.productv1.LookupProductByIdResponse\"\x00\x12`\n" + "\x11LookupStorageById\x12#.productv1.LookupStorageByIdRequest\x1a$.productv1.LookupStorageByIdResponse\"\x00\x12f\n" + @@ -11382,18 +14013,27 @@ const file_product_proto_rawDesc = "" + "\x0eQueryRandomPet\x12 .productv1.QueryRandomPetRequest\x1a!.productv1.QueryRandomPetResponse\"\x00\x12r\n" + "\x17QueryRandomSearchResult\x12).productv1.QueryRandomSearchResultRequest\x1a*.productv1.QueryRandomSearchResultResponse\"\x00\x12c\n" + "\x12QueryRecursiveType\x12$.productv1.QueryRecursiveTypeRequest\x1a%.productv1.QueryRecursiveTypeResponse\"\x00\x12N\n" + - "\vQuerySearch\x12\x1d.productv1.QuerySearchRequest\x1a\x1e.productv1.QuerySearchResponse\"\x00\x12\x81\x01\n" + + "\vQuerySearch\x12\x1d.productv1.QuerySearchRequest\x1a\x1e.productv1.QuerySearchResponse\"\x00\x12c\n" + + "\x12QueryTestContainer\x12$.productv1.QueryTestContainerRequest\x1a%.productv1.QueryTestContainerResponse\"\x00\x12f\n" + + "\x13QueryTestContainers\x12%.productv1.QueryTestContainersRequest\x1a&.productv1.QueryTestContainersResponse\"\x00\x12\x81\x01\n" + "\x1cQueryTypeFilterWithArguments\x12..productv1.QueryTypeFilterWithArgumentsRequest\x1a/.productv1.QueryTypeFilterWithArgumentsResponse\"\x00\x12\x90\x01\n" + "!QueryTypeWithMultipleFilterFields\x123.productv1.QueryTypeWithMultipleFilterFieldsRequest\x1a4.productv1.QueryTypeWithMultipleFilterFieldsResponse\"\x00\x12H\n" + "\tQueryUser\x12\x1b.productv1.QueryUserRequest\x1a\x1c.productv1.QueryUserResponse\"\x00\x12K\n" + "\n" + "QueryUsers\x12\x1c.productv1.QueryUsersRequest\x1a\x1d.productv1.QueryUsersResponse\"\x00\x12\x87\x01\n" + - "\x1eResolveCategoryCategoryMetrics\x120.productv1.ResolveCategoryCategoryMetricsRequest\x1a1.productv1.ResolveCategoryCategoryMetricsResponse\"\x00\x12\x87\x01\n" + + "\x1eResolveCategoryCategoryMetrics\x120.productv1.ResolveCategoryCategoryMetricsRequest\x1a1.productv1.ResolveCategoryCategoryMetricsResponse\"\x00\x12\x84\x01\n" + + "\x1dResolveCategoryCategoryStatus\x12/.productv1.ResolveCategoryCategoryStatusRequest\x1a0.productv1.ResolveCategoryCategoryStatusResponse\"\x00\x12l\n" + + "\x15ResolveCategoryMascot\x12'.productv1.ResolveCategoryMascotRequest\x1a(.productv1.ResolveCategoryMascotResponse\"\x00\x12\x9c\x01\n" + + "%ResolveCategoryMetricsNormalizedScore\x127.productv1.ResolveCategoryMetricsNormalizedScoreRequest\x1a8.productv1.ResolveCategoryMetricsNormalizedScoreResponse\"\x00\x12\x87\x01\n" + "\x1eResolveCategoryPopularityScore\x120.productv1.ResolveCategoryPopularityScoreRequest\x1a1.productv1.ResolveCategoryPopularityScoreResponse\"\x00\x12~\n" + - "\x1bResolveCategoryProductCount\x12-.productv1.ResolveCategoryProductCountRequest\x1a..productv1.ResolveCategoryProductCountResponse\"\x00\x12\x90\x01\n" + + "\x1bResolveCategoryProductCount\x12-.productv1.ResolveCategoryProductCountRequest\x1a..productv1.ResolveCategoryProductCountResponse\"\x00\x12\x93\x01\n" + + "\"ResolveProductMascotRecommendation\x124.productv1.ResolveProductMascotRecommendationRequest\x1a5.productv1.ResolveProductMascotRecommendationResponse\"\x00\x12\x81\x01\n" + + "\x1cResolveProductProductDetails\x12..productv1.ResolveProductProductDetailsRequest\x1a/.productv1.ResolveProductProductDetailsResponse\"\x00\x12\x90\x01\n" + "!ResolveProductRecommendedCategory\x123.productv1.ResolveProductRecommendedCategoryRequest\x1a4.productv1.ResolveProductRecommendedCategoryResponse\"\x00\x12\x87\x01\n" + - "\x1eResolveProductShippingEstimate\x120.productv1.ResolveProductShippingEstimateRequest\x1a1.productv1.ResolveProductShippingEstimateResponse\"\x00\x12~\n" + - "\x1bResolveSubcategoryItemCount\x12-.productv1.ResolveSubcategoryItemCountRequest\x1a..productv1.ResolveSubcategoryItemCountResponse\"\x00B%Z#cosmo/pkg/proto/productv1;productv1b\x06proto3" + "\x1eResolveProductShippingEstimate\x120.productv1.ResolveProductShippingEstimateRequest\x1a1.productv1.ResolveProductShippingEstimateResponse\"\x00\x12x\n" + + "\x19ResolveProductStockStatus\x12+.productv1.ResolveProductStockStatusRequest\x1a,.productv1.ResolveProductStockStatusResponse\"\x00\x12~\n" + + "\x1bResolveSubcategoryItemCount\x12-.productv1.ResolveSubcategoryItemCountRequest\x1a..productv1.ResolveSubcategoryItemCountResponse\"\x00\x12~\n" + + "\x1bResolveTestContainerDetails\x12-.productv1.ResolveTestContainerDetailsRequest\x1a..productv1.ResolveTestContainerDetailsResponse\"\x00B%Z#cosmo/pkg/proto/productv1;productv1b\x06proto3" var ( file_product_proto_rawDescOnce sync.Once @@ -11408,559 +14048,669 @@ func file_product_proto_rawDescGZIP() []byte { } var file_product_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_product_proto_msgTypes = make([]protoimpl.MessageInfo, 208) +var file_product_proto_msgTypes = make([]protoimpl.MessageInfo, 256) var file_product_proto_goTypes = []any{ - (CategoryKind)(0), // 0: productv1.CategoryKind - (ShippingDestination)(0), // 1: productv1.ShippingDestination - (*ListOfAuthorFilter)(nil), // 2: productv1.ListOfAuthorFilter - (*ListOfAuthorInput)(nil), // 3: productv1.ListOfAuthorInput - (*ListOfBlogPost)(nil), // 4: productv1.ListOfBlogPost - (*ListOfBlogPostFilter)(nil), // 5: productv1.ListOfBlogPostFilter - (*ListOfBlogPostInput)(nil), // 6: productv1.ListOfBlogPostInput - (*ListOfBoolean)(nil), // 7: productv1.ListOfBoolean - (*ListOfCategory)(nil), // 8: productv1.ListOfCategory - (*ListOfCategoryInput)(nil), // 9: productv1.ListOfCategoryInput - (*ListOfFloat)(nil), // 10: productv1.ListOfFloat - (*ListOfListOfCategory)(nil), // 11: productv1.ListOfListOfCategory - (*ListOfListOfCategoryInput)(nil), // 12: productv1.ListOfListOfCategoryInput - (*ListOfListOfString)(nil), // 13: productv1.ListOfListOfString - (*ListOfListOfUser)(nil), // 14: productv1.ListOfListOfUser - (*ListOfListOfUserInput)(nil), // 15: productv1.ListOfListOfUserInput - (*ListOfOrderLine)(nil), // 16: productv1.ListOfOrderLine - (*ListOfProduct)(nil), // 17: productv1.ListOfProduct - (*ListOfString)(nil), // 18: productv1.ListOfString - (*ListOfSubcategory)(nil), // 19: productv1.ListOfSubcategory - (*ListOfUser)(nil), // 20: productv1.ListOfUser - (*ListOfUserInput)(nil), // 21: productv1.ListOfUserInput - (*LookupProductByIdRequestKey)(nil), // 22: productv1.LookupProductByIdRequestKey - (*LookupProductByIdRequest)(nil), // 23: productv1.LookupProductByIdRequest - (*LookupProductByIdResponse)(nil), // 24: productv1.LookupProductByIdResponse - (*LookupStorageByIdRequestKey)(nil), // 25: productv1.LookupStorageByIdRequestKey - (*LookupStorageByIdRequest)(nil), // 26: productv1.LookupStorageByIdRequest - (*LookupStorageByIdResponse)(nil), // 27: productv1.LookupStorageByIdResponse - (*LookupWarehouseByIdRequestKey)(nil), // 28: productv1.LookupWarehouseByIdRequestKey - (*LookupWarehouseByIdRequest)(nil), // 29: productv1.LookupWarehouseByIdRequest - (*LookupWarehouseByIdResponse)(nil), // 30: productv1.LookupWarehouseByIdResponse - (*QueryUsersRequest)(nil), // 31: productv1.QueryUsersRequest - (*QueryUsersResponse)(nil), // 32: productv1.QueryUsersResponse - (*QueryUserRequest)(nil), // 33: productv1.QueryUserRequest - (*QueryUserResponse)(nil), // 34: productv1.QueryUserResponse - (*QueryNestedTypeRequest)(nil), // 35: productv1.QueryNestedTypeRequest - (*QueryNestedTypeResponse)(nil), // 36: productv1.QueryNestedTypeResponse - (*QueryRecursiveTypeRequest)(nil), // 37: productv1.QueryRecursiveTypeRequest - (*QueryRecursiveTypeResponse)(nil), // 38: productv1.QueryRecursiveTypeResponse - (*QueryTypeFilterWithArgumentsRequest)(nil), // 39: productv1.QueryTypeFilterWithArgumentsRequest - (*QueryTypeFilterWithArgumentsResponse)(nil), // 40: productv1.QueryTypeFilterWithArgumentsResponse - (*QueryTypeWithMultipleFilterFieldsRequest)(nil), // 41: productv1.QueryTypeWithMultipleFilterFieldsRequest - (*QueryTypeWithMultipleFilterFieldsResponse)(nil), // 42: productv1.QueryTypeWithMultipleFilterFieldsResponse - (*QueryComplexFilterTypeRequest)(nil), // 43: productv1.QueryComplexFilterTypeRequest - (*QueryComplexFilterTypeResponse)(nil), // 44: productv1.QueryComplexFilterTypeResponse - (*QueryCalculateTotalsRequest)(nil), // 45: productv1.QueryCalculateTotalsRequest - (*QueryCalculateTotalsResponse)(nil), // 46: productv1.QueryCalculateTotalsResponse - (*QueryCategoriesRequest)(nil), // 47: productv1.QueryCategoriesRequest - (*QueryCategoriesResponse)(nil), // 48: productv1.QueryCategoriesResponse - (*QueryCategoriesByKindRequest)(nil), // 49: productv1.QueryCategoriesByKindRequest - (*QueryCategoriesByKindResponse)(nil), // 50: productv1.QueryCategoriesByKindResponse - (*QueryCategoriesByKindsRequest)(nil), // 51: productv1.QueryCategoriesByKindsRequest - (*QueryCategoriesByKindsResponse)(nil), // 52: productv1.QueryCategoriesByKindsResponse - (*QueryFilterCategoriesRequest)(nil), // 53: productv1.QueryFilterCategoriesRequest - (*QueryFilterCategoriesResponse)(nil), // 54: productv1.QueryFilterCategoriesResponse - (*QueryRandomPetRequest)(nil), // 55: productv1.QueryRandomPetRequest - (*QueryRandomPetResponse)(nil), // 56: productv1.QueryRandomPetResponse - (*QueryAllPetsRequest)(nil), // 57: productv1.QueryAllPetsRequest - (*QueryAllPetsResponse)(nil), // 58: productv1.QueryAllPetsResponse - (*QuerySearchRequest)(nil), // 59: productv1.QuerySearchRequest - (*QuerySearchResponse)(nil), // 60: productv1.QuerySearchResponse - (*QueryRandomSearchResultRequest)(nil), // 61: productv1.QueryRandomSearchResultRequest - (*QueryRandomSearchResultResponse)(nil), // 62: productv1.QueryRandomSearchResultResponse - (*QueryNullableFieldsTypeRequest)(nil), // 63: productv1.QueryNullableFieldsTypeRequest - (*QueryNullableFieldsTypeResponse)(nil), // 64: productv1.QueryNullableFieldsTypeResponse - (*QueryNullableFieldsTypeByIdRequest)(nil), // 65: productv1.QueryNullableFieldsTypeByIdRequest - (*QueryNullableFieldsTypeByIdResponse)(nil), // 66: productv1.QueryNullableFieldsTypeByIdResponse - (*QueryNullableFieldsTypeWithFilterRequest)(nil), // 67: productv1.QueryNullableFieldsTypeWithFilterRequest - (*QueryNullableFieldsTypeWithFilterResponse)(nil), // 68: productv1.QueryNullableFieldsTypeWithFilterResponse - (*QueryAllNullableFieldsTypesRequest)(nil), // 69: productv1.QueryAllNullableFieldsTypesRequest - (*QueryAllNullableFieldsTypesResponse)(nil), // 70: productv1.QueryAllNullableFieldsTypesResponse - (*QueryBlogPostRequest)(nil), // 71: productv1.QueryBlogPostRequest - (*QueryBlogPostResponse)(nil), // 72: productv1.QueryBlogPostResponse - (*QueryBlogPostByIdRequest)(nil), // 73: productv1.QueryBlogPostByIdRequest - (*QueryBlogPostByIdResponse)(nil), // 74: productv1.QueryBlogPostByIdResponse - (*QueryBlogPostsWithFilterRequest)(nil), // 75: productv1.QueryBlogPostsWithFilterRequest - (*QueryBlogPostsWithFilterResponse)(nil), // 76: productv1.QueryBlogPostsWithFilterResponse - (*QueryAllBlogPostsRequest)(nil), // 77: productv1.QueryAllBlogPostsRequest - (*QueryAllBlogPostsResponse)(nil), // 78: productv1.QueryAllBlogPostsResponse - (*QueryAuthorRequest)(nil), // 79: productv1.QueryAuthorRequest - (*QueryAuthorResponse)(nil), // 80: productv1.QueryAuthorResponse - (*QueryAuthorByIdRequest)(nil), // 81: productv1.QueryAuthorByIdRequest - (*QueryAuthorByIdResponse)(nil), // 82: productv1.QueryAuthorByIdResponse - (*QueryAuthorsWithFilterRequest)(nil), // 83: productv1.QueryAuthorsWithFilterRequest - (*QueryAuthorsWithFilterResponse)(nil), // 84: productv1.QueryAuthorsWithFilterResponse - (*QueryAllAuthorsRequest)(nil), // 85: productv1.QueryAllAuthorsRequest - (*QueryAllAuthorsResponse)(nil), // 86: productv1.QueryAllAuthorsResponse - (*QueryBulkSearchAuthorsRequest)(nil), // 87: productv1.QueryBulkSearchAuthorsRequest - (*QueryBulkSearchAuthorsResponse)(nil), // 88: productv1.QueryBulkSearchAuthorsResponse - (*QueryBulkSearchBlogPostsRequest)(nil), // 89: productv1.QueryBulkSearchBlogPostsRequest - (*QueryBulkSearchBlogPostsResponse)(nil), // 90: productv1.QueryBulkSearchBlogPostsResponse - (*MutationCreateUserRequest)(nil), // 91: productv1.MutationCreateUserRequest - (*MutationCreateUserResponse)(nil), // 92: productv1.MutationCreateUserResponse - (*MutationPerformActionRequest)(nil), // 93: productv1.MutationPerformActionRequest - (*MutationPerformActionResponse)(nil), // 94: productv1.MutationPerformActionResponse - (*MutationCreateNullableFieldsTypeRequest)(nil), // 95: productv1.MutationCreateNullableFieldsTypeRequest - (*MutationCreateNullableFieldsTypeResponse)(nil), // 96: productv1.MutationCreateNullableFieldsTypeResponse - (*MutationUpdateNullableFieldsTypeRequest)(nil), // 97: productv1.MutationUpdateNullableFieldsTypeRequest - (*MutationUpdateNullableFieldsTypeResponse)(nil), // 98: productv1.MutationUpdateNullableFieldsTypeResponse - (*MutationCreateBlogPostRequest)(nil), // 99: productv1.MutationCreateBlogPostRequest - (*MutationCreateBlogPostResponse)(nil), // 100: productv1.MutationCreateBlogPostResponse - (*MutationUpdateBlogPostRequest)(nil), // 101: productv1.MutationUpdateBlogPostRequest - (*MutationUpdateBlogPostResponse)(nil), // 102: productv1.MutationUpdateBlogPostResponse - (*MutationCreateAuthorRequest)(nil), // 103: productv1.MutationCreateAuthorRequest - (*MutationCreateAuthorResponse)(nil), // 104: productv1.MutationCreateAuthorResponse - (*MutationUpdateAuthorRequest)(nil), // 105: productv1.MutationUpdateAuthorRequest - (*MutationUpdateAuthorResponse)(nil), // 106: productv1.MutationUpdateAuthorResponse - (*MutationBulkCreateAuthorsRequest)(nil), // 107: productv1.MutationBulkCreateAuthorsRequest - (*MutationBulkCreateAuthorsResponse)(nil), // 108: productv1.MutationBulkCreateAuthorsResponse - (*MutationBulkUpdateAuthorsRequest)(nil), // 109: productv1.MutationBulkUpdateAuthorsRequest - (*MutationBulkUpdateAuthorsResponse)(nil), // 110: productv1.MutationBulkUpdateAuthorsResponse - (*MutationBulkCreateBlogPostsRequest)(nil), // 111: productv1.MutationBulkCreateBlogPostsRequest - (*MutationBulkCreateBlogPostsResponse)(nil), // 112: productv1.MutationBulkCreateBlogPostsResponse - (*MutationBulkUpdateBlogPostsRequest)(nil), // 113: productv1.MutationBulkUpdateBlogPostsRequest - (*MutationBulkUpdateBlogPostsResponse)(nil), // 114: productv1.MutationBulkUpdateBlogPostsResponse - (*ResolveProductShippingEstimateArgs)(nil), // 115: productv1.ResolveProductShippingEstimateArgs - (*ResolveProductShippingEstimateContext)(nil), // 116: productv1.ResolveProductShippingEstimateContext - (*ResolveProductShippingEstimateRequest)(nil), // 117: productv1.ResolveProductShippingEstimateRequest - (*ResolveProductShippingEstimateResult)(nil), // 118: productv1.ResolveProductShippingEstimateResult - (*ResolveProductShippingEstimateResponse)(nil), // 119: productv1.ResolveProductShippingEstimateResponse - (*ResolveProductRecommendedCategoryArgs)(nil), // 120: productv1.ResolveProductRecommendedCategoryArgs - (*ResolveProductRecommendedCategoryContext)(nil), // 121: productv1.ResolveProductRecommendedCategoryContext - (*ResolveProductRecommendedCategoryRequest)(nil), // 122: productv1.ResolveProductRecommendedCategoryRequest - (*ResolveProductRecommendedCategoryResult)(nil), // 123: productv1.ResolveProductRecommendedCategoryResult - (*ResolveProductRecommendedCategoryResponse)(nil), // 124: productv1.ResolveProductRecommendedCategoryResponse - (*ResolveCategoryProductCountArgs)(nil), // 125: productv1.ResolveCategoryProductCountArgs - (*ResolveCategoryProductCountContext)(nil), // 126: productv1.ResolveCategoryProductCountContext - (*ResolveCategoryProductCountRequest)(nil), // 127: productv1.ResolveCategoryProductCountRequest - (*ResolveCategoryProductCountResult)(nil), // 128: productv1.ResolveCategoryProductCountResult - (*ResolveCategoryProductCountResponse)(nil), // 129: productv1.ResolveCategoryProductCountResponse - (*ResolveCategoryPopularityScoreArgs)(nil), // 130: productv1.ResolveCategoryPopularityScoreArgs - (*ResolveCategoryPopularityScoreContext)(nil), // 131: productv1.ResolveCategoryPopularityScoreContext - (*ResolveCategoryPopularityScoreRequest)(nil), // 132: productv1.ResolveCategoryPopularityScoreRequest - (*ResolveCategoryPopularityScoreResult)(nil), // 133: productv1.ResolveCategoryPopularityScoreResult - (*ResolveCategoryPopularityScoreResponse)(nil), // 134: productv1.ResolveCategoryPopularityScoreResponse - (*ResolveCategoryCategoryMetricsArgs)(nil), // 135: productv1.ResolveCategoryCategoryMetricsArgs - (*ResolveCategoryCategoryMetricsContext)(nil), // 136: productv1.ResolveCategoryCategoryMetricsContext - (*ResolveCategoryCategoryMetricsRequest)(nil), // 137: productv1.ResolveCategoryCategoryMetricsRequest - (*ResolveCategoryCategoryMetricsResult)(nil), // 138: productv1.ResolveCategoryCategoryMetricsResult - (*ResolveCategoryCategoryMetricsResponse)(nil), // 139: productv1.ResolveCategoryCategoryMetricsResponse - (*ResolveSubcategoryItemCountArgs)(nil), // 140: productv1.ResolveSubcategoryItemCountArgs - (*ResolveSubcategoryItemCountContext)(nil), // 141: productv1.ResolveSubcategoryItemCountContext - (*ResolveSubcategoryItemCountRequest)(nil), // 142: productv1.ResolveSubcategoryItemCountRequest - (*ResolveSubcategoryItemCountResult)(nil), // 143: productv1.ResolveSubcategoryItemCountResult - (*ResolveSubcategoryItemCountResponse)(nil), // 144: productv1.ResolveSubcategoryItemCountResponse - (*Product)(nil), // 145: productv1.Product - (*Storage)(nil), // 146: productv1.Storage - (*Warehouse)(nil), // 147: productv1.Warehouse - (*User)(nil), // 148: productv1.User - (*NestedTypeA)(nil), // 149: productv1.NestedTypeA - (*RecursiveType)(nil), // 150: productv1.RecursiveType - (*TypeWithMultipleFilterFields)(nil), // 151: productv1.TypeWithMultipleFilterFields - (*FilterTypeInput)(nil), // 152: productv1.FilterTypeInput - (*ComplexFilterTypeInput)(nil), // 153: productv1.ComplexFilterTypeInput - (*TypeWithComplexFilterInput)(nil), // 154: productv1.TypeWithComplexFilterInput - (*OrderInput)(nil), // 155: productv1.OrderInput - (*Order)(nil), // 156: productv1.Order - (*Category)(nil), // 157: productv1.Category - (*CategoryFilter)(nil), // 158: productv1.CategoryFilter - (*Animal)(nil), // 159: productv1.Animal - (*SearchInput)(nil), // 160: productv1.SearchInput - (*SearchResult)(nil), // 161: productv1.SearchResult - (*NullableFieldsType)(nil), // 162: productv1.NullableFieldsType - (*NullableFieldsFilter)(nil), // 163: productv1.NullableFieldsFilter - (*BlogPost)(nil), // 164: productv1.BlogPost - (*BlogPostFilter)(nil), // 165: productv1.BlogPostFilter - (*Author)(nil), // 166: productv1.Author - (*AuthorFilter)(nil), // 167: productv1.AuthorFilter - (*UserInput)(nil), // 168: productv1.UserInput - (*ActionInput)(nil), // 169: productv1.ActionInput - (*ActionResult)(nil), // 170: productv1.ActionResult - (*NullableFieldsInput)(nil), // 171: productv1.NullableFieldsInput - (*BlogPostInput)(nil), // 172: productv1.BlogPostInput - (*AuthorInput)(nil), // 173: productv1.AuthorInput - (*NestedTypeB)(nil), // 174: productv1.NestedTypeB - (*NestedTypeC)(nil), // 175: productv1.NestedTypeC - (*FilterType)(nil), // 176: productv1.FilterType - (*Pagination)(nil), // 177: productv1.Pagination - (*OrderLineInput)(nil), // 178: productv1.OrderLineInput - (*OrderLine)(nil), // 179: productv1.OrderLine - (*Subcategory)(nil), // 180: productv1.Subcategory - (*CategoryMetrics)(nil), // 181: productv1.CategoryMetrics - (*Cat)(nil), // 182: productv1.Cat - (*Dog)(nil), // 183: productv1.Dog - (*ActionSuccess)(nil), // 184: productv1.ActionSuccess - (*ActionError)(nil), // 185: productv1.ActionError - (*CategoryInput)(nil), // 186: productv1.CategoryInput - (*ProductCountFilter)(nil), // 187: productv1.ProductCountFilter - (*SubcategoryItemFilter)(nil), // 188: productv1.SubcategoryItemFilter - (*ShippingEstimateInput)(nil), // 189: productv1.ShippingEstimateInput - (*ListOfAuthorFilter_List)(nil), // 190: productv1.ListOfAuthorFilter.List - (*ListOfAuthorInput_List)(nil), // 191: productv1.ListOfAuthorInput.List - (*ListOfBlogPost_List)(nil), // 192: productv1.ListOfBlogPost.List - (*ListOfBlogPostFilter_List)(nil), // 193: productv1.ListOfBlogPostFilter.List - (*ListOfBlogPostInput_List)(nil), // 194: productv1.ListOfBlogPostInput.List - (*ListOfBoolean_List)(nil), // 195: productv1.ListOfBoolean.List - (*ListOfCategory_List)(nil), // 196: productv1.ListOfCategory.List - (*ListOfCategoryInput_List)(nil), // 197: productv1.ListOfCategoryInput.List - (*ListOfFloat_List)(nil), // 198: productv1.ListOfFloat.List - (*ListOfListOfCategory_List)(nil), // 199: productv1.ListOfListOfCategory.List - (*ListOfListOfCategoryInput_List)(nil), // 200: productv1.ListOfListOfCategoryInput.List - (*ListOfListOfString_List)(nil), // 201: productv1.ListOfListOfString.List - (*ListOfListOfUser_List)(nil), // 202: productv1.ListOfListOfUser.List - (*ListOfListOfUserInput_List)(nil), // 203: productv1.ListOfListOfUserInput.List - (*ListOfOrderLine_List)(nil), // 204: productv1.ListOfOrderLine.List - (*ListOfProduct_List)(nil), // 205: productv1.ListOfProduct.List - (*ListOfString_List)(nil), // 206: productv1.ListOfString.List - (*ListOfSubcategory_List)(nil), // 207: productv1.ListOfSubcategory.List - (*ListOfUser_List)(nil), // 208: productv1.ListOfUser.List - (*ListOfUserInput_List)(nil), // 209: productv1.ListOfUserInput.List - (*wrapperspb.Int32Value)(nil), // 210: google.protobuf.Int32Value - (*wrapperspb.StringValue)(nil), // 211: google.protobuf.StringValue - (*wrapperspb.DoubleValue)(nil), // 212: google.protobuf.DoubleValue - (*wrapperspb.BoolValue)(nil), // 213: google.protobuf.BoolValue + (CategoryKind)(0), // 0: productv1.CategoryKind + (ShippingDestination)(0), // 1: productv1.ShippingDestination + (*ListOfAuthorFilter)(nil), // 2: productv1.ListOfAuthorFilter + (*ListOfAuthorInput)(nil), // 3: productv1.ListOfAuthorInput + (*ListOfBlogPost)(nil), // 4: productv1.ListOfBlogPost + (*ListOfBlogPostFilter)(nil), // 5: productv1.ListOfBlogPostFilter + (*ListOfBlogPostInput)(nil), // 6: productv1.ListOfBlogPostInput + (*ListOfBoolean)(nil), // 7: productv1.ListOfBoolean + (*ListOfCategory)(nil), // 8: productv1.ListOfCategory + (*ListOfCategoryInput)(nil), // 9: productv1.ListOfCategoryInput + (*ListOfFloat)(nil), // 10: productv1.ListOfFloat + (*ListOfListOfCategory)(nil), // 11: productv1.ListOfListOfCategory + (*ListOfListOfCategoryInput)(nil), // 12: productv1.ListOfListOfCategoryInput + (*ListOfListOfString)(nil), // 13: productv1.ListOfListOfString + (*ListOfListOfUser)(nil), // 14: productv1.ListOfListOfUser + (*ListOfListOfUserInput)(nil), // 15: productv1.ListOfListOfUserInput + (*ListOfOrderLine)(nil), // 16: productv1.ListOfOrderLine + (*ListOfProduct)(nil), // 17: productv1.ListOfProduct + (*ListOfString)(nil), // 18: productv1.ListOfString + (*ListOfSubcategory)(nil), // 19: productv1.ListOfSubcategory + (*ListOfUser)(nil), // 20: productv1.ListOfUser + (*ListOfUserInput)(nil), // 21: productv1.ListOfUserInput + (*LookupProductByIdRequestKey)(nil), // 22: productv1.LookupProductByIdRequestKey + (*LookupProductByIdRequest)(nil), // 23: productv1.LookupProductByIdRequest + (*LookupProductByIdResponse)(nil), // 24: productv1.LookupProductByIdResponse + (*LookupStorageByIdRequestKey)(nil), // 25: productv1.LookupStorageByIdRequestKey + (*LookupStorageByIdRequest)(nil), // 26: productv1.LookupStorageByIdRequest + (*LookupStorageByIdResponse)(nil), // 27: productv1.LookupStorageByIdResponse + (*LookupWarehouseByIdRequestKey)(nil), // 28: productv1.LookupWarehouseByIdRequestKey + (*LookupWarehouseByIdRequest)(nil), // 29: productv1.LookupWarehouseByIdRequest + (*LookupWarehouseByIdResponse)(nil), // 30: productv1.LookupWarehouseByIdResponse + (*QueryUsersRequest)(nil), // 31: productv1.QueryUsersRequest + (*QueryUsersResponse)(nil), // 32: productv1.QueryUsersResponse + (*QueryUserRequest)(nil), // 33: productv1.QueryUserRequest + (*QueryUserResponse)(nil), // 34: productv1.QueryUserResponse + (*QueryNestedTypeRequest)(nil), // 35: productv1.QueryNestedTypeRequest + (*QueryNestedTypeResponse)(nil), // 36: productv1.QueryNestedTypeResponse + (*QueryRecursiveTypeRequest)(nil), // 37: productv1.QueryRecursiveTypeRequest + (*QueryRecursiveTypeResponse)(nil), // 38: productv1.QueryRecursiveTypeResponse + (*QueryTypeFilterWithArgumentsRequest)(nil), // 39: productv1.QueryTypeFilterWithArgumentsRequest + (*QueryTypeFilterWithArgumentsResponse)(nil), // 40: productv1.QueryTypeFilterWithArgumentsResponse + (*QueryTypeWithMultipleFilterFieldsRequest)(nil), // 41: productv1.QueryTypeWithMultipleFilterFieldsRequest + (*QueryTypeWithMultipleFilterFieldsResponse)(nil), // 42: productv1.QueryTypeWithMultipleFilterFieldsResponse + (*QueryComplexFilterTypeRequest)(nil), // 43: productv1.QueryComplexFilterTypeRequest + (*QueryComplexFilterTypeResponse)(nil), // 44: productv1.QueryComplexFilterTypeResponse + (*QueryCalculateTotalsRequest)(nil), // 45: productv1.QueryCalculateTotalsRequest + (*QueryCalculateTotalsResponse)(nil), // 46: productv1.QueryCalculateTotalsResponse + (*QueryCategoriesRequest)(nil), // 47: productv1.QueryCategoriesRequest + (*QueryCategoriesResponse)(nil), // 48: productv1.QueryCategoriesResponse + (*QueryCategoriesByKindRequest)(nil), // 49: productv1.QueryCategoriesByKindRequest + (*QueryCategoriesByKindResponse)(nil), // 50: productv1.QueryCategoriesByKindResponse + (*QueryCategoriesByKindsRequest)(nil), // 51: productv1.QueryCategoriesByKindsRequest + (*QueryCategoriesByKindsResponse)(nil), // 52: productv1.QueryCategoriesByKindsResponse + (*QueryFilterCategoriesRequest)(nil), // 53: productv1.QueryFilterCategoriesRequest + (*QueryFilterCategoriesResponse)(nil), // 54: productv1.QueryFilterCategoriesResponse + (*QueryRandomPetRequest)(nil), // 55: productv1.QueryRandomPetRequest + (*QueryRandomPetResponse)(nil), // 56: productv1.QueryRandomPetResponse + (*QueryAllPetsRequest)(nil), // 57: productv1.QueryAllPetsRequest + (*QueryAllPetsResponse)(nil), // 58: productv1.QueryAllPetsResponse + (*QuerySearchRequest)(nil), // 59: productv1.QuerySearchRequest + (*QuerySearchResponse)(nil), // 60: productv1.QuerySearchResponse + (*QueryRandomSearchResultRequest)(nil), // 61: productv1.QueryRandomSearchResultRequest + (*QueryRandomSearchResultResponse)(nil), // 62: productv1.QueryRandomSearchResultResponse + (*QueryNullableFieldsTypeRequest)(nil), // 63: productv1.QueryNullableFieldsTypeRequest + (*QueryNullableFieldsTypeResponse)(nil), // 64: productv1.QueryNullableFieldsTypeResponse + (*QueryNullableFieldsTypeByIdRequest)(nil), // 65: productv1.QueryNullableFieldsTypeByIdRequest + (*QueryNullableFieldsTypeByIdResponse)(nil), // 66: productv1.QueryNullableFieldsTypeByIdResponse + (*QueryNullableFieldsTypeWithFilterRequest)(nil), // 67: productv1.QueryNullableFieldsTypeWithFilterRequest + (*QueryNullableFieldsTypeWithFilterResponse)(nil), // 68: productv1.QueryNullableFieldsTypeWithFilterResponse + (*QueryAllNullableFieldsTypesRequest)(nil), // 69: productv1.QueryAllNullableFieldsTypesRequest + (*QueryAllNullableFieldsTypesResponse)(nil), // 70: productv1.QueryAllNullableFieldsTypesResponse + (*QueryBlogPostRequest)(nil), // 71: productv1.QueryBlogPostRequest + (*QueryBlogPostResponse)(nil), // 72: productv1.QueryBlogPostResponse + (*QueryBlogPostByIdRequest)(nil), // 73: productv1.QueryBlogPostByIdRequest + (*QueryBlogPostByIdResponse)(nil), // 74: productv1.QueryBlogPostByIdResponse + (*QueryBlogPostsWithFilterRequest)(nil), // 75: productv1.QueryBlogPostsWithFilterRequest + (*QueryBlogPostsWithFilterResponse)(nil), // 76: productv1.QueryBlogPostsWithFilterResponse + (*QueryAllBlogPostsRequest)(nil), // 77: productv1.QueryAllBlogPostsRequest + (*QueryAllBlogPostsResponse)(nil), // 78: productv1.QueryAllBlogPostsResponse + (*QueryAuthorRequest)(nil), // 79: productv1.QueryAuthorRequest + (*QueryAuthorResponse)(nil), // 80: productv1.QueryAuthorResponse + (*QueryAuthorByIdRequest)(nil), // 81: productv1.QueryAuthorByIdRequest + (*QueryAuthorByIdResponse)(nil), // 82: productv1.QueryAuthorByIdResponse + (*QueryAuthorsWithFilterRequest)(nil), // 83: productv1.QueryAuthorsWithFilterRequest + (*QueryAuthorsWithFilterResponse)(nil), // 84: productv1.QueryAuthorsWithFilterResponse + (*QueryAllAuthorsRequest)(nil), // 85: productv1.QueryAllAuthorsRequest + (*QueryAllAuthorsResponse)(nil), // 86: productv1.QueryAllAuthorsResponse + (*QueryBulkSearchAuthorsRequest)(nil), // 87: productv1.QueryBulkSearchAuthorsRequest + (*QueryBulkSearchAuthorsResponse)(nil), // 88: productv1.QueryBulkSearchAuthorsResponse + (*QueryBulkSearchBlogPostsRequest)(nil), // 89: productv1.QueryBulkSearchBlogPostsRequest + (*QueryBulkSearchBlogPostsResponse)(nil), // 90: productv1.QueryBulkSearchBlogPostsResponse + (*QueryTestContainerRequest)(nil), // 91: productv1.QueryTestContainerRequest + (*QueryTestContainerResponse)(nil), // 92: productv1.QueryTestContainerResponse + (*QueryTestContainersRequest)(nil), // 93: productv1.QueryTestContainersRequest + (*QueryTestContainersResponse)(nil), // 94: productv1.QueryTestContainersResponse + (*MutationCreateUserRequest)(nil), // 95: productv1.MutationCreateUserRequest + (*MutationCreateUserResponse)(nil), // 96: productv1.MutationCreateUserResponse + (*MutationPerformActionRequest)(nil), // 97: productv1.MutationPerformActionRequest + (*MutationPerformActionResponse)(nil), // 98: productv1.MutationPerformActionResponse + (*MutationCreateNullableFieldsTypeRequest)(nil), // 99: productv1.MutationCreateNullableFieldsTypeRequest + (*MutationCreateNullableFieldsTypeResponse)(nil), // 100: productv1.MutationCreateNullableFieldsTypeResponse + (*MutationUpdateNullableFieldsTypeRequest)(nil), // 101: productv1.MutationUpdateNullableFieldsTypeRequest + (*MutationUpdateNullableFieldsTypeResponse)(nil), // 102: productv1.MutationUpdateNullableFieldsTypeResponse + (*MutationCreateBlogPostRequest)(nil), // 103: productv1.MutationCreateBlogPostRequest + (*MutationCreateBlogPostResponse)(nil), // 104: productv1.MutationCreateBlogPostResponse + (*MutationUpdateBlogPostRequest)(nil), // 105: productv1.MutationUpdateBlogPostRequest + (*MutationUpdateBlogPostResponse)(nil), // 106: productv1.MutationUpdateBlogPostResponse + (*MutationCreateAuthorRequest)(nil), // 107: productv1.MutationCreateAuthorRequest + (*MutationCreateAuthorResponse)(nil), // 108: productv1.MutationCreateAuthorResponse + (*MutationUpdateAuthorRequest)(nil), // 109: productv1.MutationUpdateAuthorRequest + (*MutationUpdateAuthorResponse)(nil), // 110: productv1.MutationUpdateAuthorResponse + (*MutationBulkCreateAuthorsRequest)(nil), // 111: productv1.MutationBulkCreateAuthorsRequest + (*MutationBulkCreateAuthorsResponse)(nil), // 112: productv1.MutationBulkCreateAuthorsResponse + (*MutationBulkUpdateAuthorsRequest)(nil), // 113: productv1.MutationBulkUpdateAuthorsRequest + (*MutationBulkUpdateAuthorsResponse)(nil), // 114: productv1.MutationBulkUpdateAuthorsResponse + (*MutationBulkCreateBlogPostsRequest)(nil), // 115: productv1.MutationBulkCreateBlogPostsRequest + (*MutationBulkCreateBlogPostsResponse)(nil), // 116: productv1.MutationBulkCreateBlogPostsResponse + (*MutationBulkUpdateBlogPostsRequest)(nil), // 117: productv1.MutationBulkUpdateBlogPostsRequest + (*MutationBulkUpdateBlogPostsResponse)(nil), // 118: productv1.MutationBulkUpdateBlogPostsResponse + (*ResolveProductShippingEstimateArgs)(nil), // 119: productv1.ResolveProductShippingEstimateArgs + (*ResolveProductShippingEstimateContext)(nil), // 120: productv1.ResolveProductShippingEstimateContext + (*ResolveProductShippingEstimateRequest)(nil), // 121: productv1.ResolveProductShippingEstimateRequest + (*ResolveProductShippingEstimateResult)(nil), // 122: productv1.ResolveProductShippingEstimateResult + (*ResolveProductShippingEstimateResponse)(nil), // 123: productv1.ResolveProductShippingEstimateResponse + (*ResolveProductRecommendedCategoryArgs)(nil), // 124: productv1.ResolveProductRecommendedCategoryArgs + (*ResolveProductRecommendedCategoryContext)(nil), // 125: productv1.ResolveProductRecommendedCategoryContext + (*ResolveProductRecommendedCategoryRequest)(nil), // 126: productv1.ResolveProductRecommendedCategoryRequest + (*ResolveProductRecommendedCategoryResult)(nil), // 127: productv1.ResolveProductRecommendedCategoryResult + (*ResolveProductRecommendedCategoryResponse)(nil), // 128: productv1.ResolveProductRecommendedCategoryResponse + (*ResolveProductMascotRecommendationArgs)(nil), // 129: productv1.ResolveProductMascotRecommendationArgs + (*ResolveProductMascotRecommendationContext)(nil), // 130: productv1.ResolveProductMascotRecommendationContext + (*ResolveProductMascotRecommendationRequest)(nil), // 131: productv1.ResolveProductMascotRecommendationRequest + (*ResolveProductMascotRecommendationResult)(nil), // 132: productv1.ResolveProductMascotRecommendationResult + (*ResolveProductMascotRecommendationResponse)(nil), // 133: productv1.ResolveProductMascotRecommendationResponse + (*ResolveProductStockStatusArgs)(nil), // 134: productv1.ResolveProductStockStatusArgs + (*ResolveProductStockStatusContext)(nil), // 135: productv1.ResolveProductStockStatusContext + (*ResolveProductStockStatusRequest)(nil), // 136: productv1.ResolveProductStockStatusRequest + (*ResolveProductStockStatusResult)(nil), // 137: productv1.ResolveProductStockStatusResult + (*ResolveProductStockStatusResponse)(nil), // 138: productv1.ResolveProductStockStatusResponse + (*ResolveProductProductDetailsArgs)(nil), // 139: productv1.ResolveProductProductDetailsArgs + (*ResolveProductProductDetailsContext)(nil), // 140: productv1.ResolveProductProductDetailsContext + (*ResolveProductProductDetailsRequest)(nil), // 141: productv1.ResolveProductProductDetailsRequest + (*ResolveProductProductDetailsResult)(nil), // 142: productv1.ResolveProductProductDetailsResult + (*ResolveProductProductDetailsResponse)(nil), // 143: productv1.ResolveProductProductDetailsResponse + (*ResolveCategoryProductCountArgs)(nil), // 144: productv1.ResolveCategoryProductCountArgs + (*ResolveCategoryProductCountContext)(nil), // 145: productv1.ResolveCategoryProductCountContext + (*ResolveCategoryProductCountRequest)(nil), // 146: productv1.ResolveCategoryProductCountRequest + (*ResolveCategoryProductCountResult)(nil), // 147: productv1.ResolveCategoryProductCountResult + (*ResolveCategoryProductCountResponse)(nil), // 148: productv1.ResolveCategoryProductCountResponse + (*ResolveCategoryPopularityScoreArgs)(nil), // 149: productv1.ResolveCategoryPopularityScoreArgs + (*ResolveCategoryPopularityScoreContext)(nil), // 150: productv1.ResolveCategoryPopularityScoreContext + (*ResolveCategoryPopularityScoreRequest)(nil), // 151: productv1.ResolveCategoryPopularityScoreRequest + (*ResolveCategoryPopularityScoreResult)(nil), // 152: productv1.ResolveCategoryPopularityScoreResult + (*ResolveCategoryPopularityScoreResponse)(nil), // 153: productv1.ResolveCategoryPopularityScoreResponse + (*ResolveCategoryCategoryMetricsArgs)(nil), // 154: productv1.ResolveCategoryCategoryMetricsArgs + (*ResolveCategoryCategoryMetricsContext)(nil), // 155: productv1.ResolveCategoryCategoryMetricsContext + (*ResolveCategoryCategoryMetricsRequest)(nil), // 156: productv1.ResolveCategoryCategoryMetricsRequest + (*ResolveCategoryCategoryMetricsResult)(nil), // 157: productv1.ResolveCategoryCategoryMetricsResult + (*ResolveCategoryCategoryMetricsResponse)(nil), // 158: productv1.ResolveCategoryCategoryMetricsResponse + (*ResolveCategoryMascotArgs)(nil), // 159: productv1.ResolveCategoryMascotArgs + (*ResolveCategoryMascotContext)(nil), // 160: productv1.ResolveCategoryMascotContext + (*ResolveCategoryMascotRequest)(nil), // 161: productv1.ResolveCategoryMascotRequest + (*ResolveCategoryMascotResult)(nil), // 162: productv1.ResolveCategoryMascotResult + (*ResolveCategoryMascotResponse)(nil), // 163: productv1.ResolveCategoryMascotResponse + (*ResolveCategoryCategoryStatusArgs)(nil), // 164: productv1.ResolveCategoryCategoryStatusArgs + (*ResolveCategoryCategoryStatusContext)(nil), // 165: productv1.ResolveCategoryCategoryStatusContext + (*ResolveCategoryCategoryStatusRequest)(nil), // 166: productv1.ResolveCategoryCategoryStatusRequest + (*ResolveCategoryCategoryStatusResult)(nil), // 167: productv1.ResolveCategoryCategoryStatusResult + (*ResolveCategoryCategoryStatusResponse)(nil), // 168: productv1.ResolveCategoryCategoryStatusResponse + (*ResolveSubcategoryItemCountArgs)(nil), // 169: productv1.ResolveSubcategoryItemCountArgs + (*ResolveSubcategoryItemCountContext)(nil), // 170: productv1.ResolveSubcategoryItemCountContext + (*ResolveSubcategoryItemCountRequest)(nil), // 171: productv1.ResolveSubcategoryItemCountRequest + (*ResolveSubcategoryItemCountResult)(nil), // 172: productv1.ResolveSubcategoryItemCountResult + (*ResolveSubcategoryItemCountResponse)(nil), // 173: productv1.ResolveSubcategoryItemCountResponse + (*ResolveCategoryMetricsNormalizedScoreArgs)(nil), // 174: productv1.ResolveCategoryMetricsNormalizedScoreArgs + (*ResolveCategoryMetricsNormalizedScoreContext)(nil), // 175: productv1.ResolveCategoryMetricsNormalizedScoreContext + (*ResolveCategoryMetricsNormalizedScoreRequest)(nil), // 176: productv1.ResolveCategoryMetricsNormalizedScoreRequest + (*ResolveCategoryMetricsNormalizedScoreResult)(nil), // 177: productv1.ResolveCategoryMetricsNormalizedScoreResult + (*ResolveCategoryMetricsNormalizedScoreResponse)(nil), // 178: productv1.ResolveCategoryMetricsNormalizedScoreResponse + (*ResolveTestContainerDetailsArgs)(nil), // 179: productv1.ResolveTestContainerDetailsArgs + (*ResolveTestContainerDetailsContext)(nil), // 180: productv1.ResolveTestContainerDetailsContext + (*ResolveTestContainerDetailsRequest)(nil), // 181: productv1.ResolveTestContainerDetailsRequest + (*ResolveTestContainerDetailsResult)(nil), // 182: productv1.ResolveTestContainerDetailsResult + (*ResolveTestContainerDetailsResponse)(nil), // 183: productv1.ResolveTestContainerDetailsResponse + (*Product)(nil), // 184: productv1.Product + (*Storage)(nil), // 185: productv1.Storage + (*Warehouse)(nil), // 186: productv1.Warehouse + (*User)(nil), // 187: productv1.User + (*NestedTypeA)(nil), // 188: productv1.NestedTypeA + (*RecursiveType)(nil), // 189: productv1.RecursiveType + (*TypeWithMultipleFilterFields)(nil), // 190: productv1.TypeWithMultipleFilterFields + (*FilterTypeInput)(nil), // 191: productv1.FilterTypeInput + (*ComplexFilterTypeInput)(nil), // 192: productv1.ComplexFilterTypeInput + (*TypeWithComplexFilterInput)(nil), // 193: productv1.TypeWithComplexFilterInput + (*OrderInput)(nil), // 194: productv1.OrderInput + (*Order)(nil), // 195: productv1.Order + (*Category)(nil), // 196: productv1.Category + (*CategoryFilter)(nil), // 197: productv1.CategoryFilter + (*Animal)(nil), // 198: productv1.Animal + (*SearchInput)(nil), // 199: productv1.SearchInput + (*SearchResult)(nil), // 200: productv1.SearchResult + (*NullableFieldsType)(nil), // 201: productv1.NullableFieldsType + (*NullableFieldsFilter)(nil), // 202: productv1.NullableFieldsFilter + (*BlogPost)(nil), // 203: productv1.BlogPost + (*BlogPostFilter)(nil), // 204: productv1.BlogPostFilter + (*Author)(nil), // 205: productv1.Author + (*AuthorFilter)(nil), // 206: productv1.AuthorFilter + (*TestContainer)(nil), // 207: productv1.TestContainer + (*UserInput)(nil), // 208: productv1.UserInput + (*ActionInput)(nil), // 209: productv1.ActionInput + (*ActionResult)(nil), // 210: productv1.ActionResult + (*NullableFieldsInput)(nil), // 211: productv1.NullableFieldsInput + (*BlogPostInput)(nil), // 212: productv1.BlogPostInput + (*AuthorInput)(nil), // 213: productv1.AuthorInput + (*ProductDetails)(nil), // 214: productv1.ProductDetails + (*NestedTypeB)(nil), // 215: productv1.NestedTypeB + (*NestedTypeC)(nil), // 216: productv1.NestedTypeC + (*FilterType)(nil), // 217: productv1.FilterType + (*Pagination)(nil), // 218: productv1.Pagination + (*OrderLineInput)(nil), // 219: productv1.OrderLineInput + (*OrderLine)(nil), // 220: productv1.OrderLine + (*Subcategory)(nil), // 221: productv1.Subcategory + (*CategoryMetrics)(nil), // 222: productv1.CategoryMetrics + (*Cat)(nil), // 223: productv1.Cat + (*Dog)(nil), // 224: productv1.Dog + (*Owner)(nil), // 225: productv1.Owner + (*ContactInfo)(nil), // 226: productv1.ContactInfo + (*Address)(nil), // 227: productv1.Address + (*CatBreed)(nil), // 228: productv1.CatBreed + (*DogBreed)(nil), // 229: productv1.DogBreed + (*BreedCharacteristics)(nil), // 230: productv1.BreedCharacteristics + (*ActionSuccess)(nil), // 231: productv1.ActionSuccess + (*ActionError)(nil), // 232: productv1.ActionError + (*TestDetails)(nil), // 233: productv1.TestDetails + (*CategoryInput)(nil), // 234: productv1.CategoryInput + (*ProductCountFilter)(nil), // 235: productv1.ProductCountFilter + (*SubcategoryItemFilter)(nil), // 236: productv1.SubcategoryItemFilter + (*ShippingEstimateInput)(nil), // 237: productv1.ShippingEstimateInput + (*ListOfAuthorFilter_List)(nil), // 238: productv1.ListOfAuthorFilter.List + (*ListOfAuthorInput_List)(nil), // 239: productv1.ListOfAuthorInput.List + (*ListOfBlogPost_List)(nil), // 240: productv1.ListOfBlogPost.List + (*ListOfBlogPostFilter_List)(nil), // 241: productv1.ListOfBlogPostFilter.List + (*ListOfBlogPostInput_List)(nil), // 242: productv1.ListOfBlogPostInput.List + (*ListOfBoolean_List)(nil), // 243: productv1.ListOfBoolean.List + (*ListOfCategory_List)(nil), // 244: productv1.ListOfCategory.List + (*ListOfCategoryInput_List)(nil), // 245: productv1.ListOfCategoryInput.List + (*ListOfFloat_List)(nil), // 246: productv1.ListOfFloat.List + (*ListOfListOfCategory_List)(nil), // 247: productv1.ListOfListOfCategory.List + (*ListOfListOfCategoryInput_List)(nil), // 248: productv1.ListOfListOfCategoryInput.List + (*ListOfListOfString_List)(nil), // 249: productv1.ListOfListOfString.List + (*ListOfListOfUser_List)(nil), // 250: productv1.ListOfListOfUser.List + (*ListOfListOfUserInput_List)(nil), // 251: productv1.ListOfListOfUserInput.List + (*ListOfOrderLine_List)(nil), // 252: productv1.ListOfOrderLine.List + (*ListOfProduct_List)(nil), // 253: productv1.ListOfProduct.List + (*ListOfString_List)(nil), // 254: productv1.ListOfString.List + (*ListOfSubcategory_List)(nil), // 255: productv1.ListOfSubcategory.List + (*ListOfUser_List)(nil), // 256: productv1.ListOfUser.List + (*ListOfUserInput_List)(nil), // 257: productv1.ListOfUserInput.List + (*wrapperspb.Int32Value)(nil), // 258: google.protobuf.Int32Value + (*wrapperspb.StringValue)(nil), // 259: google.protobuf.StringValue + (*wrapperspb.DoubleValue)(nil), // 260: google.protobuf.DoubleValue + (*wrapperspb.BoolValue)(nil), // 261: google.protobuf.BoolValue } var file_product_proto_depIdxs = []int32{ - 190, // 0: productv1.ListOfAuthorFilter.list:type_name -> productv1.ListOfAuthorFilter.List - 191, // 1: productv1.ListOfAuthorInput.list:type_name -> productv1.ListOfAuthorInput.List - 192, // 2: productv1.ListOfBlogPost.list:type_name -> productv1.ListOfBlogPost.List - 193, // 3: productv1.ListOfBlogPostFilter.list:type_name -> productv1.ListOfBlogPostFilter.List - 194, // 4: productv1.ListOfBlogPostInput.list:type_name -> productv1.ListOfBlogPostInput.List - 195, // 5: productv1.ListOfBoolean.list:type_name -> productv1.ListOfBoolean.List - 196, // 6: productv1.ListOfCategory.list:type_name -> productv1.ListOfCategory.List - 197, // 7: productv1.ListOfCategoryInput.list:type_name -> productv1.ListOfCategoryInput.List - 198, // 8: productv1.ListOfFloat.list:type_name -> productv1.ListOfFloat.List - 199, // 9: productv1.ListOfListOfCategory.list:type_name -> productv1.ListOfListOfCategory.List - 200, // 10: productv1.ListOfListOfCategoryInput.list:type_name -> productv1.ListOfListOfCategoryInput.List - 201, // 11: productv1.ListOfListOfString.list:type_name -> productv1.ListOfListOfString.List - 202, // 12: productv1.ListOfListOfUser.list:type_name -> productv1.ListOfListOfUser.List - 203, // 13: productv1.ListOfListOfUserInput.list:type_name -> productv1.ListOfListOfUserInput.List - 204, // 14: productv1.ListOfOrderLine.list:type_name -> productv1.ListOfOrderLine.List - 205, // 15: productv1.ListOfProduct.list:type_name -> productv1.ListOfProduct.List - 206, // 16: productv1.ListOfString.list:type_name -> productv1.ListOfString.List - 207, // 17: productv1.ListOfSubcategory.list:type_name -> productv1.ListOfSubcategory.List - 208, // 18: productv1.ListOfUser.list:type_name -> productv1.ListOfUser.List - 209, // 19: productv1.ListOfUserInput.list:type_name -> productv1.ListOfUserInput.List + 238, // 0: productv1.ListOfAuthorFilter.list:type_name -> productv1.ListOfAuthorFilter.List + 239, // 1: productv1.ListOfAuthorInput.list:type_name -> productv1.ListOfAuthorInput.List + 240, // 2: productv1.ListOfBlogPost.list:type_name -> productv1.ListOfBlogPost.List + 241, // 3: productv1.ListOfBlogPostFilter.list:type_name -> productv1.ListOfBlogPostFilter.List + 242, // 4: productv1.ListOfBlogPostInput.list:type_name -> productv1.ListOfBlogPostInput.List + 243, // 5: productv1.ListOfBoolean.list:type_name -> productv1.ListOfBoolean.List + 244, // 6: productv1.ListOfCategory.list:type_name -> productv1.ListOfCategory.List + 245, // 7: productv1.ListOfCategoryInput.list:type_name -> productv1.ListOfCategoryInput.List + 246, // 8: productv1.ListOfFloat.list:type_name -> productv1.ListOfFloat.List + 247, // 9: productv1.ListOfListOfCategory.list:type_name -> productv1.ListOfListOfCategory.List + 248, // 10: productv1.ListOfListOfCategoryInput.list:type_name -> productv1.ListOfListOfCategoryInput.List + 249, // 11: productv1.ListOfListOfString.list:type_name -> productv1.ListOfListOfString.List + 250, // 12: productv1.ListOfListOfUser.list:type_name -> productv1.ListOfListOfUser.List + 251, // 13: productv1.ListOfListOfUserInput.list:type_name -> productv1.ListOfListOfUserInput.List + 252, // 14: productv1.ListOfOrderLine.list:type_name -> productv1.ListOfOrderLine.List + 253, // 15: productv1.ListOfProduct.list:type_name -> productv1.ListOfProduct.List + 254, // 16: productv1.ListOfString.list:type_name -> productv1.ListOfString.List + 255, // 17: productv1.ListOfSubcategory.list:type_name -> productv1.ListOfSubcategory.List + 256, // 18: productv1.ListOfUser.list:type_name -> productv1.ListOfUser.List + 257, // 19: productv1.ListOfUserInput.list:type_name -> productv1.ListOfUserInput.List 22, // 20: productv1.LookupProductByIdRequest.keys:type_name -> productv1.LookupProductByIdRequestKey - 145, // 21: productv1.LookupProductByIdResponse.result:type_name -> productv1.Product + 184, // 21: productv1.LookupProductByIdResponse.result:type_name -> productv1.Product 25, // 22: productv1.LookupStorageByIdRequest.keys:type_name -> productv1.LookupStorageByIdRequestKey - 146, // 23: productv1.LookupStorageByIdResponse.result:type_name -> productv1.Storage + 185, // 23: productv1.LookupStorageByIdResponse.result:type_name -> productv1.Storage 28, // 24: productv1.LookupWarehouseByIdRequest.keys:type_name -> productv1.LookupWarehouseByIdRequestKey - 147, // 25: productv1.LookupWarehouseByIdResponse.result:type_name -> productv1.Warehouse - 148, // 26: productv1.QueryUsersResponse.users:type_name -> productv1.User - 148, // 27: productv1.QueryUserResponse.user:type_name -> productv1.User - 149, // 28: productv1.QueryNestedTypeResponse.nested_type:type_name -> productv1.NestedTypeA - 150, // 29: productv1.QueryRecursiveTypeResponse.recursive_type:type_name -> productv1.RecursiveType - 151, // 30: productv1.QueryTypeFilterWithArgumentsResponse.type_filter_with_arguments:type_name -> productv1.TypeWithMultipleFilterFields - 152, // 31: productv1.QueryTypeWithMultipleFilterFieldsRequest.filter:type_name -> productv1.FilterTypeInput - 151, // 32: productv1.QueryTypeWithMultipleFilterFieldsResponse.type_with_multiple_filter_fields:type_name -> productv1.TypeWithMultipleFilterFields - 153, // 33: productv1.QueryComplexFilterTypeRequest.filter:type_name -> productv1.ComplexFilterTypeInput - 154, // 34: productv1.QueryComplexFilterTypeResponse.complex_filter_type:type_name -> productv1.TypeWithComplexFilterInput - 155, // 35: productv1.QueryCalculateTotalsRequest.orders:type_name -> productv1.OrderInput - 156, // 36: productv1.QueryCalculateTotalsResponse.calculate_totals:type_name -> productv1.Order - 157, // 37: productv1.QueryCategoriesResponse.categories:type_name -> productv1.Category + 186, // 25: productv1.LookupWarehouseByIdResponse.result:type_name -> productv1.Warehouse + 187, // 26: productv1.QueryUsersResponse.users:type_name -> productv1.User + 187, // 27: productv1.QueryUserResponse.user:type_name -> productv1.User + 188, // 28: productv1.QueryNestedTypeResponse.nested_type:type_name -> productv1.NestedTypeA + 189, // 29: productv1.QueryRecursiveTypeResponse.recursive_type:type_name -> productv1.RecursiveType + 190, // 30: productv1.QueryTypeFilterWithArgumentsResponse.type_filter_with_arguments:type_name -> productv1.TypeWithMultipleFilterFields + 191, // 31: productv1.QueryTypeWithMultipleFilterFieldsRequest.filter:type_name -> productv1.FilterTypeInput + 190, // 32: productv1.QueryTypeWithMultipleFilterFieldsResponse.type_with_multiple_filter_fields:type_name -> productv1.TypeWithMultipleFilterFields + 192, // 33: productv1.QueryComplexFilterTypeRequest.filter:type_name -> productv1.ComplexFilterTypeInput + 193, // 34: productv1.QueryComplexFilterTypeResponse.complex_filter_type:type_name -> productv1.TypeWithComplexFilterInput + 194, // 35: productv1.QueryCalculateTotalsRequest.orders:type_name -> productv1.OrderInput + 195, // 36: productv1.QueryCalculateTotalsResponse.calculate_totals:type_name -> productv1.Order + 196, // 37: productv1.QueryCategoriesResponse.categories:type_name -> productv1.Category 0, // 38: productv1.QueryCategoriesByKindRequest.kind:type_name -> productv1.CategoryKind - 157, // 39: productv1.QueryCategoriesByKindResponse.categories_by_kind:type_name -> productv1.Category + 196, // 39: productv1.QueryCategoriesByKindResponse.categories_by_kind:type_name -> productv1.Category 0, // 40: productv1.QueryCategoriesByKindsRequest.kinds:type_name -> productv1.CategoryKind - 157, // 41: productv1.QueryCategoriesByKindsResponse.categories_by_kinds:type_name -> productv1.Category - 158, // 42: productv1.QueryFilterCategoriesRequest.filter:type_name -> productv1.CategoryFilter - 157, // 43: productv1.QueryFilterCategoriesResponse.filter_categories:type_name -> productv1.Category - 159, // 44: productv1.QueryRandomPetResponse.random_pet:type_name -> productv1.Animal - 159, // 45: productv1.QueryAllPetsResponse.all_pets:type_name -> productv1.Animal - 160, // 46: productv1.QuerySearchRequest.input:type_name -> productv1.SearchInput - 161, // 47: productv1.QuerySearchResponse.search:type_name -> productv1.SearchResult - 161, // 48: productv1.QueryRandomSearchResultResponse.random_search_result:type_name -> productv1.SearchResult - 162, // 49: productv1.QueryNullableFieldsTypeResponse.nullable_fields_type:type_name -> productv1.NullableFieldsType - 162, // 50: productv1.QueryNullableFieldsTypeByIdResponse.nullable_fields_type_by_id:type_name -> productv1.NullableFieldsType - 163, // 51: productv1.QueryNullableFieldsTypeWithFilterRequest.filter:type_name -> productv1.NullableFieldsFilter - 162, // 52: productv1.QueryNullableFieldsTypeWithFilterResponse.nullable_fields_type_with_filter:type_name -> productv1.NullableFieldsType - 162, // 53: productv1.QueryAllNullableFieldsTypesResponse.all_nullable_fields_types:type_name -> productv1.NullableFieldsType - 164, // 54: productv1.QueryBlogPostResponse.blog_post:type_name -> productv1.BlogPost - 164, // 55: productv1.QueryBlogPostByIdResponse.blog_post_by_id:type_name -> productv1.BlogPost - 165, // 56: productv1.QueryBlogPostsWithFilterRequest.filter:type_name -> productv1.BlogPostFilter - 164, // 57: productv1.QueryBlogPostsWithFilterResponse.blog_posts_with_filter:type_name -> productv1.BlogPost - 164, // 58: productv1.QueryAllBlogPostsResponse.all_blog_posts:type_name -> productv1.BlogPost - 166, // 59: productv1.QueryAuthorResponse.author:type_name -> productv1.Author - 166, // 60: productv1.QueryAuthorByIdResponse.author_by_id:type_name -> productv1.Author - 167, // 61: productv1.QueryAuthorsWithFilterRequest.filter:type_name -> productv1.AuthorFilter - 166, // 62: productv1.QueryAuthorsWithFilterResponse.authors_with_filter:type_name -> productv1.Author - 166, // 63: productv1.QueryAllAuthorsResponse.all_authors:type_name -> productv1.Author + 196, // 41: productv1.QueryCategoriesByKindsResponse.categories_by_kinds:type_name -> productv1.Category + 197, // 42: productv1.QueryFilterCategoriesRequest.filter:type_name -> productv1.CategoryFilter + 196, // 43: productv1.QueryFilterCategoriesResponse.filter_categories:type_name -> productv1.Category + 198, // 44: productv1.QueryRandomPetResponse.random_pet:type_name -> productv1.Animal + 198, // 45: productv1.QueryAllPetsResponse.all_pets:type_name -> productv1.Animal + 199, // 46: productv1.QuerySearchRequest.input:type_name -> productv1.SearchInput + 200, // 47: productv1.QuerySearchResponse.search:type_name -> productv1.SearchResult + 200, // 48: productv1.QueryRandomSearchResultResponse.random_search_result:type_name -> productv1.SearchResult + 201, // 49: productv1.QueryNullableFieldsTypeResponse.nullable_fields_type:type_name -> productv1.NullableFieldsType + 201, // 50: productv1.QueryNullableFieldsTypeByIdResponse.nullable_fields_type_by_id:type_name -> productv1.NullableFieldsType + 202, // 51: productv1.QueryNullableFieldsTypeWithFilterRequest.filter:type_name -> productv1.NullableFieldsFilter + 201, // 52: productv1.QueryNullableFieldsTypeWithFilterResponse.nullable_fields_type_with_filter:type_name -> productv1.NullableFieldsType + 201, // 53: productv1.QueryAllNullableFieldsTypesResponse.all_nullable_fields_types:type_name -> productv1.NullableFieldsType + 203, // 54: productv1.QueryBlogPostResponse.blog_post:type_name -> productv1.BlogPost + 203, // 55: productv1.QueryBlogPostByIdResponse.blog_post_by_id:type_name -> productv1.BlogPost + 204, // 56: productv1.QueryBlogPostsWithFilterRequest.filter:type_name -> productv1.BlogPostFilter + 203, // 57: productv1.QueryBlogPostsWithFilterResponse.blog_posts_with_filter:type_name -> productv1.BlogPost + 203, // 58: productv1.QueryAllBlogPostsResponse.all_blog_posts:type_name -> productv1.BlogPost + 205, // 59: productv1.QueryAuthorResponse.author:type_name -> productv1.Author + 205, // 60: productv1.QueryAuthorByIdResponse.author_by_id:type_name -> productv1.Author + 206, // 61: productv1.QueryAuthorsWithFilterRequest.filter:type_name -> productv1.AuthorFilter + 205, // 62: productv1.QueryAuthorsWithFilterResponse.authors_with_filter:type_name -> productv1.Author + 205, // 63: productv1.QueryAllAuthorsResponse.all_authors:type_name -> productv1.Author 2, // 64: productv1.QueryBulkSearchAuthorsRequest.filters:type_name -> productv1.ListOfAuthorFilter - 166, // 65: productv1.QueryBulkSearchAuthorsResponse.bulk_search_authors:type_name -> productv1.Author + 205, // 65: productv1.QueryBulkSearchAuthorsResponse.bulk_search_authors:type_name -> productv1.Author 5, // 66: productv1.QueryBulkSearchBlogPostsRequest.filters:type_name -> productv1.ListOfBlogPostFilter - 164, // 67: productv1.QueryBulkSearchBlogPostsResponse.bulk_search_blog_posts:type_name -> productv1.BlogPost - 168, // 68: productv1.MutationCreateUserRequest.input:type_name -> productv1.UserInput - 148, // 69: productv1.MutationCreateUserResponse.create_user:type_name -> productv1.User - 169, // 70: productv1.MutationPerformActionRequest.input:type_name -> productv1.ActionInput - 170, // 71: productv1.MutationPerformActionResponse.perform_action:type_name -> productv1.ActionResult - 171, // 72: productv1.MutationCreateNullableFieldsTypeRequest.input:type_name -> productv1.NullableFieldsInput - 162, // 73: productv1.MutationCreateNullableFieldsTypeResponse.create_nullable_fields_type:type_name -> productv1.NullableFieldsType - 171, // 74: productv1.MutationUpdateNullableFieldsTypeRequest.input:type_name -> productv1.NullableFieldsInput - 162, // 75: productv1.MutationUpdateNullableFieldsTypeResponse.update_nullable_fields_type:type_name -> productv1.NullableFieldsType - 172, // 76: productv1.MutationCreateBlogPostRequest.input:type_name -> productv1.BlogPostInput - 164, // 77: productv1.MutationCreateBlogPostResponse.create_blog_post:type_name -> productv1.BlogPost - 172, // 78: productv1.MutationUpdateBlogPostRequest.input:type_name -> productv1.BlogPostInput - 164, // 79: productv1.MutationUpdateBlogPostResponse.update_blog_post:type_name -> productv1.BlogPost - 173, // 80: productv1.MutationCreateAuthorRequest.input:type_name -> productv1.AuthorInput - 166, // 81: productv1.MutationCreateAuthorResponse.create_author:type_name -> productv1.Author - 173, // 82: productv1.MutationUpdateAuthorRequest.input:type_name -> productv1.AuthorInput - 166, // 83: productv1.MutationUpdateAuthorResponse.update_author:type_name -> productv1.Author - 3, // 84: productv1.MutationBulkCreateAuthorsRequest.authors:type_name -> productv1.ListOfAuthorInput - 166, // 85: productv1.MutationBulkCreateAuthorsResponse.bulk_create_authors:type_name -> productv1.Author - 3, // 86: productv1.MutationBulkUpdateAuthorsRequest.authors:type_name -> productv1.ListOfAuthorInput - 166, // 87: productv1.MutationBulkUpdateAuthorsResponse.bulk_update_authors:type_name -> productv1.Author - 6, // 88: productv1.MutationBulkCreateBlogPostsRequest.blog_posts:type_name -> productv1.ListOfBlogPostInput - 164, // 89: productv1.MutationBulkCreateBlogPostsResponse.bulk_create_blog_posts:type_name -> productv1.BlogPost - 6, // 90: productv1.MutationBulkUpdateBlogPostsRequest.blog_posts:type_name -> productv1.ListOfBlogPostInput - 164, // 91: productv1.MutationBulkUpdateBlogPostsResponse.bulk_update_blog_posts:type_name -> productv1.BlogPost - 189, // 92: productv1.ResolveProductShippingEstimateArgs.input:type_name -> productv1.ShippingEstimateInput - 116, // 93: productv1.ResolveProductShippingEstimateRequest.context:type_name -> productv1.ResolveProductShippingEstimateContext - 115, // 94: productv1.ResolveProductShippingEstimateRequest.field_args:type_name -> productv1.ResolveProductShippingEstimateArgs - 118, // 95: productv1.ResolveProductShippingEstimateResponse.result:type_name -> productv1.ResolveProductShippingEstimateResult - 121, // 96: productv1.ResolveProductRecommendedCategoryRequest.context:type_name -> productv1.ResolveProductRecommendedCategoryContext - 120, // 97: productv1.ResolveProductRecommendedCategoryRequest.field_args:type_name -> productv1.ResolveProductRecommendedCategoryArgs - 157, // 98: productv1.ResolveProductRecommendedCategoryResult.recommended_category:type_name -> productv1.Category - 123, // 99: productv1.ResolveProductRecommendedCategoryResponse.result:type_name -> productv1.ResolveProductRecommendedCategoryResult - 187, // 100: productv1.ResolveCategoryProductCountArgs.filters:type_name -> productv1.ProductCountFilter - 126, // 101: productv1.ResolveCategoryProductCountRequest.context:type_name -> productv1.ResolveCategoryProductCountContext - 125, // 102: productv1.ResolveCategoryProductCountRequest.field_args:type_name -> productv1.ResolveCategoryProductCountArgs - 128, // 103: productv1.ResolveCategoryProductCountResponse.result:type_name -> productv1.ResolveCategoryProductCountResult - 210, // 104: productv1.ResolveCategoryPopularityScoreArgs.threshold:type_name -> google.protobuf.Int32Value - 131, // 105: productv1.ResolveCategoryPopularityScoreRequest.context:type_name -> productv1.ResolveCategoryPopularityScoreContext - 130, // 106: productv1.ResolveCategoryPopularityScoreRequest.field_args:type_name -> productv1.ResolveCategoryPopularityScoreArgs - 210, // 107: productv1.ResolveCategoryPopularityScoreResult.popularity_score:type_name -> google.protobuf.Int32Value - 133, // 108: productv1.ResolveCategoryPopularityScoreResponse.result:type_name -> productv1.ResolveCategoryPopularityScoreResult - 136, // 109: productv1.ResolveCategoryCategoryMetricsRequest.context:type_name -> productv1.ResolveCategoryCategoryMetricsContext - 135, // 110: productv1.ResolveCategoryCategoryMetricsRequest.field_args:type_name -> productv1.ResolveCategoryCategoryMetricsArgs - 181, // 111: productv1.ResolveCategoryCategoryMetricsResult.category_metrics:type_name -> productv1.CategoryMetrics - 138, // 112: productv1.ResolveCategoryCategoryMetricsResponse.result:type_name -> productv1.ResolveCategoryCategoryMetricsResult - 188, // 113: productv1.ResolveSubcategoryItemCountArgs.filters:type_name -> productv1.SubcategoryItemFilter - 141, // 114: productv1.ResolveSubcategoryItemCountRequest.context:type_name -> productv1.ResolveSubcategoryItemCountContext - 140, // 115: productv1.ResolveSubcategoryItemCountRequest.field_args:type_name -> productv1.ResolveSubcategoryItemCountArgs - 143, // 116: productv1.ResolveSubcategoryItemCountResponse.result:type_name -> productv1.ResolveSubcategoryItemCountResult - 174, // 117: productv1.NestedTypeA.b:type_name -> productv1.NestedTypeB - 150, // 118: productv1.RecursiveType.recursive_type:type_name -> productv1.RecursiveType - 176, // 119: productv1.ComplexFilterTypeInput.filter:type_name -> productv1.FilterType - 178, // 120: productv1.OrderInput.lines:type_name -> productv1.OrderLineInput - 16, // 121: productv1.Order.order_lines:type_name -> productv1.ListOfOrderLine - 0, // 122: productv1.Category.kind:type_name -> productv1.CategoryKind - 19, // 123: productv1.Category.subcategories:type_name -> productv1.ListOfSubcategory - 0, // 124: productv1.CategoryFilter.category:type_name -> productv1.CategoryKind - 177, // 125: productv1.CategoryFilter.pagination:type_name -> productv1.Pagination - 182, // 126: productv1.Animal.cat:type_name -> productv1.Cat - 183, // 127: productv1.Animal.dog:type_name -> productv1.Dog - 210, // 128: productv1.SearchInput.limit:type_name -> google.protobuf.Int32Value - 145, // 129: productv1.SearchResult.product:type_name -> productv1.Product - 148, // 130: productv1.SearchResult.user:type_name -> productv1.User - 157, // 131: productv1.SearchResult.category:type_name -> productv1.Category - 211, // 132: productv1.NullableFieldsType.optional_string:type_name -> google.protobuf.StringValue - 210, // 133: productv1.NullableFieldsType.optional_int:type_name -> google.protobuf.Int32Value - 212, // 134: productv1.NullableFieldsType.optional_float:type_name -> google.protobuf.DoubleValue - 213, // 135: productv1.NullableFieldsType.optional_boolean:type_name -> google.protobuf.BoolValue - 211, // 136: productv1.NullableFieldsFilter.name:type_name -> google.protobuf.StringValue - 211, // 137: productv1.NullableFieldsFilter.optional_string:type_name -> google.protobuf.StringValue - 213, // 138: productv1.NullableFieldsFilter.include_nulls:type_name -> google.protobuf.BoolValue - 18, // 139: productv1.BlogPost.optional_tags:type_name -> productv1.ListOfString - 18, // 140: productv1.BlogPost.keywords:type_name -> productv1.ListOfString - 10, // 141: productv1.BlogPost.ratings:type_name -> productv1.ListOfFloat - 7, // 142: productv1.BlogPost.is_published:type_name -> productv1.ListOfBoolean - 13, // 143: productv1.BlogPost.tag_groups:type_name -> productv1.ListOfListOfString - 13, // 144: productv1.BlogPost.related_topics:type_name -> productv1.ListOfListOfString - 13, // 145: productv1.BlogPost.comment_threads:type_name -> productv1.ListOfListOfString - 13, // 146: productv1.BlogPost.suggestions:type_name -> productv1.ListOfListOfString - 157, // 147: productv1.BlogPost.related_categories:type_name -> productv1.Category - 148, // 148: productv1.BlogPost.contributors:type_name -> productv1.User - 17, // 149: productv1.BlogPost.mentioned_products:type_name -> productv1.ListOfProduct - 20, // 150: productv1.BlogPost.mentioned_users:type_name -> productv1.ListOfUser - 11, // 151: productv1.BlogPost.category_groups:type_name -> productv1.ListOfListOfCategory - 14, // 152: productv1.BlogPost.contributor_teams:type_name -> productv1.ListOfListOfUser - 211, // 153: productv1.BlogPostFilter.title:type_name -> google.protobuf.StringValue - 213, // 154: productv1.BlogPostFilter.has_categories:type_name -> google.protobuf.BoolValue - 210, // 155: productv1.BlogPostFilter.min_tags:type_name -> google.protobuf.Int32Value - 211, // 156: productv1.Author.email:type_name -> google.protobuf.StringValue - 18, // 157: productv1.Author.social_links:type_name -> productv1.ListOfString - 13, // 158: productv1.Author.teams_by_project:type_name -> productv1.ListOfListOfString - 13, // 159: productv1.Author.collaborations:type_name -> productv1.ListOfListOfString - 4, // 160: productv1.Author.written_posts:type_name -> productv1.ListOfBlogPost - 157, // 161: productv1.Author.favorite_categories:type_name -> productv1.Category - 20, // 162: productv1.Author.related_authors:type_name -> productv1.ListOfUser - 17, // 163: productv1.Author.product_reviews:type_name -> productv1.ListOfProduct - 14, // 164: productv1.Author.author_groups:type_name -> productv1.ListOfListOfUser - 11, // 165: productv1.Author.category_preferences:type_name -> productv1.ListOfListOfCategory - 14, // 166: productv1.Author.project_teams:type_name -> productv1.ListOfListOfUser - 211, // 167: productv1.AuthorFilter.name:type_name -> google.protobuf.StringValue - 213, // 168: productv1.AuthorFilter.has_teams:type_name -> google.protobuf.BoolValue - 210, // 169: productv1.AuthorFilter.skill_count:type_name -> google.protobuf.Int32Value - 184, // 170: productv1.ActionResult.action_success:type_name -> productv1.ActionSuccess - 185, // 171: productv1.ActionResult.action_error:type_name -> productv1.ActionError - 211, // 172: productv1.NullableFieldsInput.optional_string:type_name -> google.protobuf.StringValue - 210, // 173: productv1.NullableFieldsInput.optional_int:type_name -> google.protobuf.Int32Value - 212, // 174: productv1.NullableFieldsInput.optional_float:type_name -> google.protobuf.DoubleValue - 213, // 175: productv1.NullableFieldsInput.optional_boolean:type_name -> google.protobuf.BoolValue - 18, // 176: productv1.BlogPostInput.optional_tags:type_name -> productv1.ListOfString - 18, // 177: productv1.BlogPostInput.keywords:type_name -> productv1.ListOfString - 10, // 178: productv1.BlogPostInput.ratings:type_name -> productv1.ListOfFloat - 7, // 179: productv1.BlogPostInput.is_published:type_name -> productv1.ListOfBoolean - 13, // 180: productv1.BlogPostInput.tag_groups:type_name -> productv1.ListOfListOfString - 13, // 181: productv1.BlogPostInput.related_topics:type_name -> productv1.ListOfListOfString - 13, // 182: productv1.BlogPostInput.comment_threads:type_name -> productv1.ListOfListOfString - 13, // 183: productv1.BlogPostInput.suggestions:type_name -> productv1.ListOfListOfString - 9, // 184: productv1.BlogPostInput.related_categories:type_name -> productv1.ListOfCategoryInput - 21, // 185: productv1.BlogPostInput.contributors:type_name -> productv1.ListOfUserInput - 12, // 186: productv1.BlogPostInput.category_groups:type_name -> productv1.ListOfListOfCategoryInput - 211, // 187: productv1.AuthorInput.email:type_name -> google.protobuf.StringValue - 18, // 188: productv1.AuthorInput.social_links:type_name -> productv1.ListOfString - 13, // 189: productv1.AuthorInput.teams_by_project:type_name -> productv1.ListOfListOfString - 13, // 190: productv1.AuthorInput.collaborations:type_name -> productv1.ListOfListOfString - 186, // 191: productv1.AuthorInput.favorite_categories:type_name -> productv1.CategoryInput - 15, // 192: productv1.AuthorInput.author_groups:type_name -> productv1.ListOfListOfUserInput - 15, // 193: productv1.AuthorInput.project_teams:type_name -> productv1.ListOfListOfUserInput - 175, // 194: productv1.NestedTypeB.c:type_name -> productv1.NestedTypeC - 177, // 195: productv1.FilterType.pagination:type_name -> productv1.Pagination - 18, // 196: productv1.OrderLineInput.modifiers:type_name -> productv1.ListOfString - 18, // 197: productv1.OrderLine.modifiers:type_name -> productv1.ListOfString - 211, // 198: productv1.Subcategory.description:type_name -> google.protobuf.StringValue - 0, // 199: productv1.CategoryInput.kind:type_name -> productv1.CategoryKind - 212, // 200: productv1.ProductCountFilter.min_price:type_name -> google.protobuf.DoubleValue - 212, // 201: productv1.ProductCountFilter.max_price:type_name -> google.protobuf.DoubleValue - 213, // 202: productv1.ProductCountFilter.in_stock:type_name -> google.protobuf.BoolValue - 211, // 203: productv1.ProductCountFilter.search_term:type_name -> google.protobuf.StringValue - 212, // 204: productv1.SubcategoryItemFilter.min_price:type_name -> google.protobuf.DoubleValue - 212, // 205: productv1.SubcategoryItemFilter.max_price:type_name -> google.protobuf.DoubleValue - 213, // 206: productv1.SubcategoryItemFilter.in_stock:type_name -> google.protobuf.BoolValue - 213, // 207: productv1.SubcategoryItemFilter.is_active:type_name -> google.protobuf.BoolValue - 211, // 208: productv1.SubcategoryItemFilter.search_term:type_name -> google.protobuf.StringValue - 1, // 209: productv1.ShippingEstimateInput.destination:type_name -> productv1.ShippingDestination - 213, // 210: productv1.ShippingEstimateInput.expedited:type_name -> google.protobuf.BoolValue - 167, // 211: productv1.ListOfAuthorFilter.List.items:type_name -> productv1.AuthorFilter - 173, // 212: productv1.ListOfAuthorInput.List.items:type_name -> productv1.AuthorInput - 164, // 213: productv1.ListOfBlogPost.List.items:type_name -> productv1.BlogPost - 165, // 214: productv1.ListOfBlogPostFilter.List.items:type_name -> productv1.BlogPostFilter - 172, // 215: productv1.ListOfBlogPostInput.List.items:type_name -> productv1.BlogPostInput - 157, // 216: productv1.ListOfCategory.List.items:type_name -> productv1.Category - 186, // 217: productv1.ListOfCategoryInput.List.items:type_name -> productv1.CategoryInput - 8, // 218: productv1.ListOfListOfCategory.List.items:type_name -> productv1.ListOfCategory - 9, // 219: productv1.ListOfListOfCategoryInput.List.items:type_name -> productv1.ListOfCategoryInput - 18, // 220: productv1.ListOfListOfString.List.items:type_name -> productv1.ListOfString - 20, // 221: productv1.ListOfListOfUser.List.items:type_name -> productv1.ListOfUser - 21, // 222: productv1.ListOfListOfUserInput.List.items:type_name -> productv1.ListOfUserInput - 179, // 223: productv1.ListOfOrderLine.List.items:type_name -> productv1.OrderLine - 145, // 224: productv1.ListOfProduct.List.items:type_name -> productv1.Product - 180, // 225: productv1.ListOfSubcategory.List.items:type_name -> productv1.Subcategory - 148, // 226: productv1.ListOfUser.List.items:type_name -> productv1.User - 168, // 227: productv1.ListOfUserInput.List.items:type_name -> productv1.UserInput - 23, // 228: productv1.ProductService.LookupProductById:input_type -> productv1.LookupProductByIdRequest - 26, // 229: productv1.ProductService.LookupStorageById:input_type -> productv1.LookupStorageByIdRequest - 29, // 230: productv1.ProductService.LookupWarehouseById:input_type -> productv1.LookupWarehouseByIdRequest - 107, // 231: productv1.ProductService.MutationBulkCreateAuthors:input_type -> productv1.MutationBulkCreateAuthorsRequest - 111, // 232: productv1.ProductService.MutationBulkCreateBlogPosts:input_type -> productv1.MutationBulkCreateBlogPostsRequest - 109, // 233: productv1.ProductService.MutationBulkUpdateAuthors:input_type -> productv1.MutationBulkUpdateAuthorsRequest - 113, // 234: productv1.ProductService.MutationBulkUpdateBlogPosts:input_type -> productv1.MutationBulkUpdateBlogPostsRequest - 103, // 235: productv1.ProductService.MutationCreateAuthor:input_type -> productv1.MutationCreateAuthorRequest - 99, // 236: productv1.ProductService.MutationCreateBlogPost:input_type -> productv1.MutationCreateBlogPostRequest - 95, // 237: productv1.ProductService.MutationCreateNullableFieldsType:input_type -> productv1.MutationCreateNullableFieldsTypeRequest - 91, // 238: productv1.ProductService.MutationCreateUser:input_type -> productv1.MutationCreateUserRequest - 93, // 239: productv1.ProductService.MutationPerformAction:input_type -> productv1.MutationPerformActionRequest - 105, // 240: productv1.ProductService.MutationUpdateAuthor:input_type -> productv1.MutationUpdateAuthorRequest - 101, // 241: productv1.ProductService.MutationUpdateBlogPost:input_type -> productv1.MutationUpdateBlogPostRequest - 97, // 242: productv1.ProductService.MutationUpdateNullableFieldsType:input_type -> productv1.MutationUpdateNullableFieldsTypeRequest - 85, // 243: productv1.ProductService.QueryAllAuthors:input_type -> productv1.QueryAllAuthorsRequest - 77, // 244: productv1.ProductService.QueryAllBlogPosts:input_type -> productv1.QueryAllBlogPostsRequest - 69, // 245: productv1.ProductService.QueryAllNullableFieldsTypes:input_type -> productv1.QueryAllNullableFieldsTypesRequest - 57, // 246: productv1.ProductService.QueryAllPets:input_type -> productv1.QueryAllPetsRequest - 79, // 247: productv1.ProductService.QueryAuthor:input_type -> productv1.QueryAuthorRequest - 81, // 248: productv1.ProductService.QueryAuthorById:input_type -> productv1.QueryAuthorByIdRequest - 83, // 249: productv1.ProductService.QueryAuthorsWithFilter:input_type -> productv1.QueryAuthorsWithFilterRequest - 71, // 250: productv1.ProductService.QueryBlogPost:input_type -> productv1.QueryBlogPostRequest - 73, // 251: productv1.ProductService.QueryBlogPostById:input_type -> productv1.QueryBlogPostByIdRequest - 75, // 252: productv1.ProductService.QueryBlogPostsWithFilter:input_type -> productv1.QueryBlogPostsWithFilterRequest - 87, // 253: productv1.ProductService.QueryBulkSearchAuthors:input_type -> productv1.QueryBulkSearchAuthorsRequest - 89, // 254: productv1.ProductService.QueryBulkSearchBlogPosts:input_type -> productv1.QueryBulkSearchBlogPostsRequest - 45, // 255: productv1.ProductService.QueryCalculateTotals:input_type -> productv1.QueryCalculateTotalsRequest - 47, // 256: productv1.ProductService.QueryCategories:input_type -> productv1.QueryCategoriesRequest - 49, // 257: productv1.ProductService.QueryCategoriesByKind:input_type -> productv1.QueryCategoriesByKindRequest - 51, // 258: productv1.ProductService.QueryCategoriesByKinds:input_type -> productv1.QueryCategoriesByKindsRequest - 43, // 259: productv1.ProductService.QueryComplexFilterType:input_type -> productv1.QueryComplexFilterTypeRequest - 53, // 260: productv1.ProductService.QueryFilterCategories:input_type -> productv1.QueryFilterCategoriesRequest - 35, // 261: productv1.ProductService.QueryNestedType:input_type -> productv1.QueryNestedTypeRequest - 63, // 262: productv1.ProductService.QueryNullableFieldsType:input_type -> productv1.QueryNullableFieldsTypeRequest - 65, // 263: productv1.ProductService.QueryNullableFieldsTypeById:input_type -> productv1.QueryNullableFieldsTypeByIdRequest - 67, // 264: productv1.ProductService.QueryNullableFieldsTypeWithFilter:input_type -> productv1.QueryNullableFieldsTypeWithFilterRequest - 55, // 265: productv1.ProductService.QueryRandomPet:input_type -> productv1.QueryRandomPetRequest - 61, // 266: productv1.ProductService.QueryRandomSearchResult:input_type -> productv1.QueryRandomSearchResultRequest - 37, // 267: productv1.ProductService.QueryRecursiveType:input_type -> productv1.QueryRecursiveTypeRequest - 59, // 268: productv1.ProductService.QuerySearch:input_type -> productv1.QuerySearchRequest - 39, // 269: productv1.ProductService.QueryTypeFilterWithArguments:input_type -> productv1.QueryTypeFilterWithArgumentsRequest - 41, // 270: productv1.ProductService.QueryTypeWithMultipleFilterFields:input_type -> productv1.QueryTypeWithMultipleFilterFieldsRequest - 33, // 271: productv1.ProductService.QueryUser:input_type -> productv1.QueryUserRequest - 31, // 272: productv1.ProductService.QueryUsers:input_type -> productv1.QueryUsersRequest - 137, // 273: productv1.ProductService.ResolveCategoryCategoryMetrics:input_type -> productv1.ResolveCategoryCategoryMetricsRequest - 132, // 274: productv1.ProductService.ResolveCategoryPopularityScore:input_type -> productv1.ResolveCategoryPopularityScoreRequest - 127, // 275: productv1.ProductService.ResolveCategoryProductCount:input_type -> productv1.ResolveCategoryProductCountRequest - 122, // 276: productv1.ProductService.ResolveProductRecommendedCategory:input_type -> productv1.ResolveProductRecommendedCategoryRequest - 117, // 277: productv1.ProductService.ResolveProductShippingEstimate:input_type -> productv1.ResolveProductShippingEstimateRequest - 142, // 278: productv1.ProductService.ResolveSubcategoryItemCount:input_type -> productv1.ResolveSubcategoryItemCountRequest - 24, // 279: productv1.ProductService.LookupProductById:output_type -> productv1.LookupProductByIdResponse - 27, // 280: productv1.ProductService.LookupStorageById:output_type -> productv1.LookupStorageByIdResponse - 30, // 281: productv1.ProductService.LookupWarehouseById:output_type -> productv1.LookupWarehouseByIdResponse - 108, // 282: productv1.ProductService.MutationBulkCreateAuthors:output_type -> productv1.MutationBulkCreateAuthorsResponse - 112, // 283: productv1.ProductService.MutationBulkCreateBlogPosts:output_type -> productv1.MutationBulkCreateBlogPostsResponse - 110, // 284: productv1.ProductService.MutationBulkUpdateAuthors:output_type -> productv1.MutationBulkUpdateAuthorsResponse - 114, // 285: productv1.ProductService.MutationBulkUpdateBlogPosts:output_type -> productv1.MutationBulkUpdateBlogPostsResponse - 104, // 286: productv1.ProductService.MutationCreateAuthor:output_type -> productv1.MutationCreateAuthorResponse - 100, // 287: productv1.ProductService.MutationCreateBlogPost:output_type -> productv1.MutationCreateBlogPostResponse - 96, // 288: productv1.ProductService.MutationCreateNullableFieldsType:output_type -> productv1.MutationCreateNullableFieldsTypeResponse - 92, // 289: productv1.ProductService.MutationCreateUser:output_type -> productv1.MutationCreateUserResponse - 94, // 290: productv1.ProductService.MutationPerformAction:output_type -> productv1.MutationPerformActionResponse - 106, // 291: productv1.ProductService.MutationUpdateAuthor:output_type -> productv1.MutationUpdateAuthorResponse - 102, // 292: productv1.ProductService.MutationUpdateBlogPost:output_type -> productv1.MutationUpdateBlogPostResponse - 98, // 293: productv1.ProductService.MutationUpdateNullableFieldsType:output_type -> productv1.MutationUpdateNullableFieldsTypeResponse - 86, // 294: productv1.ProductService.QueryAllAuthors:output_type -> productv1.QueryAllAuthorsResponse - 78, // 295: productv1.ProductService.QueryAllBlogPosts:output_type -> productv1.QueryAllBlogPostsResponse - 70, // 296: productv1.ProductService.QueryAllNullableFieldsTypes:output_type -> productv1.QueryAllNullableFieldsTypesResponse - 58, // 297: productv1.ProductService.QueryAllPets:output_type -> productv1.QueryAllPetsResponse - 80, // 298: productv1.ProductService.QueryAuthor:output_type -> productv1.QueryAuthorResponse - 82, // 299: productv1.ProductService.QueryAuthorById:output_type -> productv1.QueryAuthorByIdResponse - 84, // 300: productv1.ProductService.QueryAuthorsWithFilter:output_type -> productv1.QueryAuthorsWithFilterResponse - 72, // 301: productv1.ProductService.QueryBlogPost:output_type -> productv1.QueryBlogPostResponse - 74, // 302: productv1.ProductService.QueryBlogPostById:output_type -> productv1.QueryBlogPostByIdResponse - 76, // 303: productv1.ProductService.QueryBlogPostsWithFilter:output_type -> productv1.QueryBlogPostsWithFilterResponse - 88, // 304: productv1.ProductService.QueryBulkSearchAuthors:output_type -> productv1.QueryBulkSearchAuthorsResponse - 90, // 305: productv1.ProductService.QueryBulkSearchBlogPosts:output_type -> productv1.QueryBulkSearchBlogPostsResponse - 46, // 306: productv1.ProductService.QueryCalculateTotals:output_type -> productv1.QueryCalculateTotalsResponse - 48, // 307: productv1.ProductService.QueryCategories:output_type -> productv1.QueryCategoriesResponse - 50, // 308: productv1.ProductService.QueryCategoriesByKind:output_type -> productv1.QueryCategoriesByKindResponse - 52, // 309: productv1.ProductService.QueryCategoriesByKinds:output_type -> productv1.QueryCategoriesByKindsResponse - 44, // 310: productv1.ProductService.QueryComplexFilterType:output_type -> productv1.QueryComplexFilterTypeResponse - 54, // 311: productv1.ProductService.QueryFilterCategories:output_type -> productv1.QueryFilterCategoriesResponse - 36, // 312: productv1.ProductService.QueryNestedType:output_type -> productv1.QueryNestedTypeResponse - 64, // 313: productv1.ProductService.QueryNullableFieldsType:output_type -> productv1.QueryNullableFieldsTypeResponse - 66, // 314: productv1.ProductService.QueryNullableFieldsTypeById:output_type -> productv1.QueryNullableFieldsTypeByIdResponse - 68, // 315: productv1.ProductService.QueryNullableFieldsTypeWithFilter:output_type -> productv1.QueryNullableFieldsTypeWithFilterResponse - 56, // 316: productv1.ProductService.QueryRandomPet:output_type -> productv1.QueryRandomPetResponse - 62, // 317: productv1.ProductService.QueryRandomSearchResult:output_type -> productv1.QueryRandomSearchResultResponse - 38, // 318: productv1.ProductService.QueryRecursiveType:output_type -> productv1.QueryRecursiveTypeResponse - 60, // 319: productv1.ProductService.QuerySearch:output_type -> productv1.QuerySearchResponse - 40, // 320: productv1.ProductService.QueryTypeFilterWithArguments:output_type -> productv1.QueryTypeFilterWithArgumentsResponse - 42, // 321: productv1.ProductService.QueryTypeWithMultipleFilterFields:output_type -> productv1.QueryTypeWithMultipleFilterFieldsResponse - 34, // 322: productv1.ProductService.QueryUser:output_type -> productv1.QueryUserResponse - 32, // 323: productv1.ProductService.QueryUsers:output_type -> productv1.QueryUsersResponse - 139, // 324: productv1.ProductService.ResolveCategoryCategoryMetrics:output_type -> productv1.ResolveCategoryCategoryMetricsResponse - 134, // 325: productv1.ProductService.ResolveCategoryPopularityScore:output_type -> productv1.ResolveCategoryPopularityScoreResponse - 129, // 326: productv1.ProductService.ResolveCategoryProductCount:output_type -> productv1.ResolveCategoryProductCountResponse - 124, // 327: productv1.ProductService.ResolveProductRecommendedCategory:output_type -> productv1.ResolveProductRecommendedCategoryResponse - 119, // 328: productv1.ProductService.ResolveProductShippingEstimate:output_type -> productv1.ResolveProductShippingEstimateResponse - 144, // 329: productv1.ProductService.ResolveSubcategoryItemCount:output_type -> productv1.ResolveSubcategoryItemCountResponse - 279, // [279:330] is the sub-list for method output_type - 228, // [228:279] is the sub-list for method input_type - 228, // [228:228] is the sub-list for extension type_name - 228, // [228:228] is the sub-list for extension extendee - 0, // [0:228] is the sub-list for field type_name + 203, // 67: productv1.QueryBulkSearchBlogPostsResponse.bulk_search_blog_posts:type_name -> productv1.BlogPost + 207, // 68: productv1.QueryTestContainerResponse.test_container:type_name -> productv1.TestContainer + 207, // 69: productv1.QueryTestContainersResponse.test_containers:type_name -> productv1.TestContainer + 208, // 70: productv1.MutationCreateUserRequest.input:type_name -> productv1.UserInput + 187, // 71: productv1.MutationCreateUserResponse.create_user:type_name -> productv1.User + 209, // 72: productv1.MutationPerformActionRequest.input:type_name -> productv1.ActionInput + 210, // 73: productv1.MutationPerformActionResponse.perform_action:type_name -> productv1.ActionResult + 211, // 74: productv1.MutationCreateNullableFieldsTypeRequest.input:type_name -> productv1.NullableFieldsInput + 201, // 75: productv1.MutationCreateNullableFieldsTypeResponse.create_nullable_fields_type:type_name -> productv1.NullableFieldsType + 211, // 76: productv1.MutationUpdateNullableFieldsTypeRequest.input:type_name -> productv1.NullableFieldsInput + 201, // 77: productv1.MutationUpdateNullableFieldsTypeResponse.update_nullable_fields_type:type_name -> productv1.NullableFieldsType + 212, // 78: productv1.MutationCreateBlogPostRequest.input:type_name -> productv1.BlogPostInput + 203, // 79: productv1.MutationCreateBlogPostResponse.create_blog_post:type_name -> productv1.BlogPost + 212, // 80: productv1.MutationUpdateBlogPostRequest.input:type_name -> productv1.BlogPostInput + 203, // 81: productv1.MutationUpdateBlogPostResponse.update_blog_post:type_name -> productv1.BlogPost + 213, // 82: productv1.MutationCreateAuthorRequest.input:type_name -> productv1.AuthorInput + 205, // 83: productv1.MutationCreateAuthorResponse.create_author:type_name -> productv1.Author + 213, // 84: productv1.MutationUpdateAuthorRequest.input:type_name -> productv1.AuthorInput + 205, // 85: productv1.MutationUpdateAuthorResponse.update_author:type_name -> productv1.Author + 3, // 86: productv1.MutationBulkCreateAuthorsRequest.authors:type_name -> productv1.ListOfAuthorInput + 205, // 87: productv1.MutationBulkCreateAuthorsResponse.bulk_create_authors:type_name -> productv1.Author + 3, // 88: productv1.MutationBulkUpdateAuthorsRequest.authors:type_name -> productv1.ListOfAuthorInput + 205, // 89: productv1.MutationBulkUpdateAuthorsResponse.bulk_update_authors:type_name -> productv1.Author + 6, // 90: productv1.MutationBulkCreateBlogPostsRequest.blog_posts:type_name -> productv1.ListOfBlogPostInput + 203, // 91: productv1.MutationBulkCreateBlogPostsResponse.bulk_create_blog_posts:type_name -> productv1.BlogPost + 6, // 92: productv1.MutationBulkUpdateBlogPostsRequest.blog_posts:type_name -> productv1.ListOfBlogPostInput + 203, // 93: productv1.MutationBulkUpdateBlogPostsResponse.bulk_update_blog_posts:type_name -> productv1.BlogPost + 237, // 94: productv1.ResolveProductShippingEstimateArgs.input:type_name -> productv1.ShippingEstimateInput + 120, // 95: productv1.ResolveProductShippingEstimateRequest.context:type_name -> productv1.ResolveProductShippingEstimateContext + 119, // 96: productv1.ResolveProductShippingEstimateRequest.field_args:type_name -> productv1.ResolveProductShippingEstimateArgs + 122, // 97: productv1.ResolveProductShippingEstimateResponse.result:type_name -> productv1.ResolveProductShippingEstimateResult + 125, // 98: productv1.ResolveProductRecommendedCategoryRequest.context:type_name -> productv1.ResolveProductRecommendedCategoryContext + 124, // 99: productv1.ResolveProductRecommendedCategoryRequest.field_args:type_name -> productv1.ResolveProductRecommendedCategoryArgs + 196, // 100: productv1.ResolveProductRecommendedCategoryResult.recommended_category:type_name -> productv1.Category + 127, // 101: productv1.ResolveProductRecommendedCategoryResponse.result:type_name -> productv1.ResolveProductRecommendedCategoryResult + 130, // 102: productv1.ResolveProductMascotRecommendationRequest.context:type_name -> productv1.ResolveProductMascotRecommendationContext + 129, // 103: productv1.ResolveProductMascotRecommendationRequest.field_args:type_name -> productv1.ResolveProductMascotRecommendationArgs + 198, // 104: productv1.ResolveProductMascotRecommendationResult.mascot_recommendation:type_name -> productv1.Animal + 132, // 105: productv1.ResolveProductMascotRecommendationResponse.result:type_name -> productv1.ResolveProductMascotRecommendationResult + 135, // 106: productv1.ResolveProductStockStatusRequest.context:type_name -> productv1.ResolveProductStockStatusContext + 134, // 107: productv1.ResolveProductStockStatusRequest.field_args:type_name -> productv1.ResolveProductStockStatusArgs + 210, // 108: productv1.ResolveProductStockStatusResult.stock_status:type_name -> productv1.ActionResult + 137, // 109: productv1.ResolveProductStockStatusResponse.result:type_name -> productv1.ResolveProductStockStatusResult + 140, // 110: productv1.ResolveProductProductDetailsRequest.context:type_name -> productv1.ResolveProductProductDetailsContext + 139, // 111: productv1.ResolveProductProductDetailsRequest.field_args:type_name -> productv1.ResolveProductProductDetailsArgs + 214, // 112: productv1.ResolveProductProductDetailsResult.product_details:type_name -> productv1.ProductDetails + 142, // 113: productv1.ResolveProductProductDetailsResponse.result:type_name -> productv1.ResolveProductProductDetailsResult + 235, // 114: productv1.ResolveCategoryProductCountArgs.filters:type_name -> productv1.ProductCountFilter + 145, // 115: productv1.ResolveCategoryProductCountRequest.context:type_name -> productv1.ResolveCategoryProductCountContext + 144, // 116: productv1.ResolveCategoryProductCountRequest.field_args:type_name -> productv1.ResolveCategoryProductCountArgs + 147, // 117: productv1.ResolveCategoryProductCountResponse.result:type_name -> productv1.ResolveCategoryProductCountResult + 258, // 118: productv1.ResolveCategoryPopularityScoreArgs.threshold:type_name -> google.protobuf.Int32Value + 150, // 119: productv1.ResolveCategoryPopularityScoreRequest.context:type_name -> productv1.ResolveCategoryPopularityScoreContext + 149, // 120: productv1.ResolveCategoryPopularityScoreRequest.field_args:type_name -> productv1.ResolveCategoryPopularityScoreArgs + 258, // 121: productv1.ResolveCategoryPopularityScoreResult.popularity_score:type_name -> google.protobuf.Int32Value + 152, // 122: productv1.ResolveCategoryPopularityScoreResponse.result:type_name -> productv1.ResolveCategoryPopularityScoreResult + 155, // 123: productv1.ResolveCategoryCategoryMetricsRequest.context:type_name -> productv1.ResolveCategoryCategoryMetricsContext + 154, // 124: productv1.ResolveCategoryCategoryMetricsRequest.field_args:type_name -> productv1.ResolveCategoryCategoryMetricsArgs + 222, // 125: productv1.ResolveCategoryCategoryMetricsResult.category_metrics:type_name -> productv1.CategoryMetrics + 157, // 126: productv1.ResolveCategoryCategoryMetricsResponse.result:type_name -> productv1.ResolveCategoryCategoryMetricsResult + 0, // 127: productv1.ResolveCategoryMascotContext.kind:type_name -> productv1.CategoryKind + 160, // 128: productv1.ResolveCategoryMascotRequest.context:type_name -> productv1.ResolveCategoryMascotContext + 159, // 129: productv1.ResolveCategoryMascotRequest.field_args:type_name -> productv1.ResolveCategoryMascotArgs + 198, // 130: productv1.ResolveCategoryMascotResult.mascot:type_name -> productv1.Animal + 162, // 131: productv1.ResolveCategoryMascotResponse.result:type_name -> productv1.ResolveCategoryMascotResult + 165, // 132: productv1.ResolveCategoryCategoryStatusRequest.context:type_name -> productv1.ResolveCategoryCategoryStatusContext + 164, // 133: productv1.ResolveCategoryCategoryStatusRequest.field_args:type_name -> productv1.ResolveCategoryCategoryStatusArgs + 210, // 134: productv1.ResolveCategoryCategoryStatusResult.category_status:type_name -> productv1.ActionResult + 167, // 135: productv1.ResolveCategoryCategoryStatusResponse.result:type_name -> productv1.ResolveCategoryCategoryStatusResult + 236, // 136: productv1.ResolveSubcategoryItemCountArgs.filters:type_name -> productv1.SubcategoryItemFilter + 170, // 137: productv1.ResolveSubcategoryItemCountRequest.context:type_name -> productv1.ResolveSubcategoryItemCountContext + 169, // 138: productv1.ResolveSubcategoryItemCountRequest.field_args:type_name -> productv1.ResolveSubcategoryItemCountArgs + 172, // 139: productv1.ResolveSubcategoryItemCountResponse.result:type_name -> productv1.ResolveSubcategoryItemCountResult + 175, // 140: productv1.ResolveCategoryMetricsNormalizedScoreRequest.context:type_name -> productv1.ResolveCategoryMetricsNormalizedScoreContext + 174, // 141: productv1.ResolveCategoryMetricsNormalizedScoreRequest.field_args:type_name -> productv1.ResolveCategoryMetricsNormalizedScoreArgs + 177, // 142: productv1.ResolveCategoryMetricsNormalizedScoreResponse.result:type_name -> productv1.ResolveCategoryMetricsNormalizedScoreResult + 180, // 143: productv1.ResolveTestContainerDetailsRequest.context:type_name -> productv1.ResolveTestContainerDetailsContext + 179, // 144: productv1.ResolveTestContainerDetailsRequest.field_args:type_name -> productv1.ResolveTestContainerDetailsArgs + 233, // 145: productv1.ResolveTestContainerDetailsResult.details:type_name -> productv1.TestDetails + 182, // 146: productv1.ResolveTestContainerDetailsResponse.result:type_name -> productv1.ResolveTestContainerDetailsResult + 215, // 147: productv1.NestedTypeA.b:type_name -> productv1.NestedTypeB + 189, // 148: productv1.RecursiveType.recursive_type:type_name -> productv1.RecursiveType + 217, // 149: productv1.ComplexFilterTypeInput.filter:type_name -> productv1.FilterType + 219, // 150: productv1.OrderInput.lines:type_name -> productv1.OrderLineInput + 16, // 151: productv1.Order.order_lines:type_name -> productv1.ListOfOrderLine + 0, // 152: productv1.Category.kind:type_name -> productv1.CategoryKind + 19, // 153: productv1.Category.subcategories:type_name -> productv1.ListOfSubcategory + 0, // 154: productv1.CategoryFilter.category:type_name -> productv1.CategoryKind + 218, // 155: productv1.CategoryFilter.pagination:type_name -> productv1.Pagination + 223, // 156: productv1.Animal.cat:type_name -> productv1.Cat + 224, // 157: productv1.Animal.dog:type_name -> productv1.Dog + 258, // 158: productv1.SearchInput.limit:type_name -> google.protobuf.Int32Value + 184, // 159: productv1.SearchResult.product:type_name -> productv1.Product + 187, // 160: productv1.SearchResult.user:type_name -> productv1.User + 196, // 161: productv1.SearchResult.category:type_name -> productv1.Category + 259, // 162: productv1.NullableFieldsType.optional_string:type_name -> google.protobuf.StringValue + 258, // 163: productv1.NullableFieldsType.optional_int:type_name -> google.protobuf.Int32Value + 260, // 164: productv1.NullableFieldsType.optional_float:type_name -> google.protobuf.DoubleValue + 261, // 165: productv1.NullableFieldsType.optional_boolean:type_name -> google.protobuf.BoolValue + 259, // 166: productv1.NullableFieldsFilter.name:type_name -> google.protobuf.StringValue + 259, // 167: productv1.NullableFieldsFilter.optional_string:type_name -> google.protobuf.StringValue + 261, // 168: productv1.NullableFieldsFilter.include_nulls:type_name -> google.protobuf.BoolValue + 18, // 169: productv1.BlogPost.optional_tags:type_name -> productv1.ListOfString + 18, // 170: productv1.BlogPost.keywords:type_name -> productv1.ListOfString + 10, // 171: productv1.BlogPost.ratings:type_name -> productv1.ListOfFloat + 7, // 172: productv1.BlogPost.is_published:type_name -> productv1.ListOfBoolean + 13, // 173: productv1.BlogPost.tag_groups:type_name -> productv1.ListOfListOfString + 13, // 174: productv1.BlogPost.related_topics:type_name -> productv1.ListOfListOfString + 13, // 175: productv1.BlogPost.comment_threads:type_name -> productv1.ListOfListOfString + 13, // 176: productv1.BlogPost.suggestions:type_name -> productv1.ListOfListOfString + 196, // 177: productv1.BlogPost.related_categories:type_name -> productv1.Category + 187, // 178: productv1.BlogPost.contributors:type_name -> productv1.User + 17, // 179: productv1.BlogPost.mentioned_products:type_name -> productv1.ListOfProduct + 20, // 180: productv1.BlogPost.mentioned_users:type_name -> productv1.ListOfUser + 11, // 181: productv1.BlogPost.category_groups:type_name -> productv1.ListOfListOfCategory + 14, // 182: productv1.BlogPost.contributor_teams:type_name -> productv1.ListOfListOfUser + 259, // 183: productv1.BlogPostFilter.title:type_name -> google.protobuf.StringValue + 261, // 184: productv1.BlogPostFilter.has_categories:type_name -> google.protobuf.BoolValue + 258, // 185: productv1.BlogPostFilter.min_tags:type_name -> google.protobuf.Int32Value + 259, // 186: productv1.Author.email:type_name -> google.protobuf.StringValue + 18, // 187: productv1.Author.social_links:type_name -> productv1.ListOfString + 13, // 188: productv1.Author.teams_by_project:type_name -> productv1.ListOfListOfString + 13, // 189: productv1.Author.collaborations:type_name -> productv1.ListOfListOfString + 4, // 190: productv1.Author.written_posts:type_name -> productv1.ListOfBlogPost + 196, // 191: productv1.Author.favorite_categories:type_name -> productv1.Category + 20, // 192: productv1.Author.related_authors:type_name -> productv1.ListOfUser + 17, // 193: productv1.Author.product_reviews:type_name -> productv1.ListOfProduct + 14, // 194: productv1.Author.author_groups:type_name -> productv1.ListOfListOfUser + 11, // 195: productv1.Author.category_preferences:type_name -> productv1.ListOfListOfCategory + 14, // 196: productv1.Author.project_teams:type_name -> productv1.ListOfListOfUser + 259, // 197: productv1.AuthorFilter.name:type_name -> google.protobuf.StringValue + 261, // 198: productv1.AuthorFilter.has_teams:type_name -> google.protobuf.BoolValue + 258, // 199: productv1.AuthorFilter.skill_count:type_name -> google.protobuf.Int32Value + 259, // 200: productv1.TestContainer.description:type_name -> google.protobuf.StringValue + 231, // 201: productv1.ActionResult.action_success:type_name -> productv1.ActionSuccess + 232, // 202: productv1.ActionResult.action_error:type_name -> productv1.ActionError + 259, // 203: productv1.NullableFieldsInput.optional_string:type_name -> google.protobuf.StringValue + 258, // 204: productv1.NullableFieldsInput.optional_int:type_name -> google.protobuf.Int32Value + 260, // 205: productv1.NullableFieldsInput.optional_float:type_name -> google.protobuf.DoubleValue + 261, // 206: productv1.NullableFieldsInput.optional_boolean:type_name -> google.protobuf.BoolValue + 18, // 207: productv1.BlogPostInput.optional_tags:type_name -> productv1.ListOfString + 18, // 208: productv1.BlogPostInput.keywords:type_name -> productv1.ListOfString + 10, // 209: productv1.BlogPostInput.ratings:type_name -> productv1.ListOfFloat + 7, // 210: productv1.BlogPostInput.is_published:type_name -> productv1.ListOfBoolean + 13, // 211: productv1.BlogPostInput.tag_groups:type_name -> productv1.ListOfListOfString + 13, // 212: productv1.BlogPostInput.related_topics:type_name -> productv1.ListOfListOfString + 13, // 213: productv1.BlogPostInput.comment_threads:type_name -> productv1.ListOfListOfString + 13, // 214: productv1.BlogPostInput.suggestions:type_name -> productv1.ListOfListOfString + 9, // 215: productv1.BlogPostInput.related_categories:type_name -> productv1.ListOfCategoryInput + 21, // 216: productv1.BlogPostInput.contributors:type_name -> productv1.ListOfUserInput + 12, // 217: productv1.BlogPostInput.category_groups:type_name -> productv1.ListOfListOfCategoryInput + 259, // 218: productv1.AuthorInput.email:type_name -> google.protobuf.StringValue + 18, // 219: productv1.AuthorInput.social_links:type_name -> productv1.ListOfString + 13, // 220: productv1.AuthorInput.teams_by_project:type_name -> productv1.ListOfListOfString + 13, // 221: productv1.AuthorInput.collaborations:type_name -> productv1.ListOfListOfString + 234, // 222: productv1.AuthorInput.favorite_categories:type_name -> productv1.CategoryInput + 15, // 223: productv1.AuthorInput.author_groups:type_name -> productv1.ListOfListOfUserInput + 15, // 224: productv1.AuthorInput.project_teams:type_name -> productv1.ListOfListOfUserInput + 210, // 225: productv1.ProductDetails.review_summary:type_name -> productv1.ActionResult + 198, // 226: productv1.ProductDetails.recommended_pet:type_name -> productv1.Animal + 216, // 227: productv1.NestedTypeB.c:type_name -> productv1.NestedTypeC + 218, // 228: productv1.FilterType.pagination:type_name -> productv1.Pagination + 18, // 229: productv1.OrderLineInput.modifiers:type_name -> productv1.ListOfString + 18, // 230: productv1.OrderLine.modifiers:type_name -> productv1.ListOfString + 259, // 231: productv1.Subcategory.description:type_name -> google.protobuf.StringValue + 196, // 232: productv1.CategoryMetrics.related_category:type_name -> productv1.Category + 225, // 233: productv1.Cat.owner:type_name -> productv1.Owner + 228, // 234: productv1.Cat.breed:type_name -> productv1.CatBreed + 225, // 235: productv1.Dog.owner:type_name -> productv1.Owner + 229, // 236: productv1.Dog.breed:type_name -> productv1.DogBreed + 226, // 237: productv1.Owner.contact:type_name -> productv1.ContactInfo + 227, // 238: productv1.ContactInfo.address:type_name -> productv1.Address + 230, // 239: productv1.CatBreed.characteristics:type_name -> productv1.BreedCharacteristics + 230, // 240: productv1.DogBreed.characteristics:type_name -> productv1.BreedCharacteristics + 198, // 241: productv1.TestDetails.pet:type_name -> productv1.Animal + 210, // 242: productv1.TestDetails.status:type_name -> productv1.ActionResult + 0, // 243: productv1.CategoryInput.kind:type_name -> productv1.CategoryKind + 260, // 244: productv1.ProductCountFilter.min_price:type_name -> google.protobuf.DoubleValue + 260, // 245: productv1.ProductCountFilter.max_price:type_name -> google.protobuf.DoubleValue + 261, // 246: productv1.ProductCountFilter.in_stock:type_name -> google.protobuf.BoolValue + 259, // 247: productv1.ProductCountFilter.search_term:type_name -> google.protobuf.StringValue + 260, // 248: productv1.SubcategoryItemFilter.min_price:type_name -> google.protobuf.DoubleValue + 260, // 249: productv1.SubcategoryItemFilter.max_price:type_name -> google.protobuf.DoubleValue + 261, // 250: productv1.SubcategoryItemFilter.in_stock:type_name -> google.protobuf.BoolValue + 261, // 251: productv1.SubcategoryItemFilter.is_active:type_name -> google.protobuf.BoolValue + 259, // 252: productv1.SubcategoryItemFilter.search_term:type_name -> google.protobuf.StringValue + 1, // 253: productv1.ShippingEstimateInput.destination:type_name -> productv1.ShippingDestination + 261, // 254: productv1.ShippingEstimateInput.expedited:type_name -> google.protobuf.BoolValue + 206, // 255: productv1.ListOfAuthorFilter.List.items:type_name -> productv1.AuthorFilter + 213, // 256: productv1.ListOfAuthorInput.List.items:type_name -> productv1.AuthorInput + 203, // 257: productv1.ListOfBlogPost.List.items:type_name -> productv1.BlogPost + 204, // 258: productv1.ListOfBlogPostFilter.List.items:type_name -> productv1.BlogPostFilter + 212, // 259: productv1.ListOfBlogPostInput.List.items:type_name -> productv1.BlogPostInput + 196, // 260: productv1.ListOfCategory.List.items:type_name -> productv1.Category + 234, // 261: productv1.ListOfCategoryInput.List.items:type_name -> productv1.CategoryInput + 8, // 262: productv1.ListOfListOfCategory.List.items:type_name -> productv1.ListOfCategory + 9, // 263: productv1.ListOfListOfCategoryInput.List.items:type_name -> productv1.ListOfCategoryInput + 18, // 264: productv1.ListOfListOfString.List.items:type_name -> productv1.ListOfString + 20, // 265: productv1.ListOfListOfUser.List.items:type_name -> productv1.ListOfUser + 21, // 266: productv1.ListOfListOfUserInput.List.items:type_name -> productv1.ListOfUserInput + 220, // 267: productv1.ListOfOrderLine.List.items:type_name -> productv1.OrderLine + 184, // 268: productv1.ListOfProduct.List.items:type_name -> productv1.Product + 221, // 269: productv1.ListOfSubcategory.List.items:type_name -> productv1.Subcategory + 187, // 270: productv1.ListOfUser.List.items:type_name -> productv1.User + 208, // 271: productv1.ListOfUserInput.List.items:type_name -> productv1.UserInput + 23, // 272: productv1.ProductService.LookupProductById:input_type -> productv1.LookupProductByIdRequest + 26, // 273: productv1.ProductService.LookupStorageById:input_type -> productv1.LookupStorageByIdRequest + 29, // 274: productv1.ProductService.LookupWarehouseById:input_type -> productv1.LookupWarehouseByIdRequest + 111, // 275: productv1.ProductService.MutationBulkCreateAuthors:input_type -> productv1.MutationBulkCreateAuthorsRequest + 115, // 276: productv1.ProductService.MutationBulkCreateBlogPosts:input_type -> productv1.MutationBulkCreateBlogPostsRequest + 113, // 277: productv1.ProductService.MutationBulkUpdateAuthors:input_type -> productv1.MutationBulkUpdateAuthorsRequest + 117, // 278: productv1.ProductService.MutationBulkUpdateBlogPosts:input_type -> productv1.MutationBulkUpdateBlogPostsRequest + 107, // 279: productv1.ProductService.MutationCreateAuthor:input_type -> productv1.MutationCreateAuthorRequest + 103, // 280: productv1.ProductService.MutationCreateBlogPost:input_type -> productv1.MutationCreateBlogPostRequest + 99, // 281: productv1.ProductService.MutationCreateNullableFieldsType:input_type -> productv1.MutationCreateNullableFieldsTypeRequest + 95, // 282: productv1.ProductService.MutationCreateUser:input_type -> productv1.MutationCreateUserRequest + 97, // 283: productv1.ProductService.MutationPerformAction:input_type -> productv1.MutationPerformActionRequest + 109, // 284: productv1.ProductService.MutationUpdateAuthor:input_type -> productv1.MutationUpdateAuthorRequest + 105, // 285: productv1.ProductService.MutationUpdateBlogPost:input_type -> productv1.MutationUpdateBlogPostRequest + 101, // 286: productv1.ProductService.MutationUpdateNullableFieldsType:input_type -> productv1.MutationUpdateNullableFieldsTypeRequest + 85, // 287: productv1.ProductService.QueryAllAuthors:input_type -> productv1.QueryAllAuthorsRequest + 77, // 288: productv1.ProductService.QueryAllBlogPosts:input_type -> productv1.QueryAllBlogPostsRequest + 69, // 289: productv1.ProductService.QueryAllNullableFieldsTypes:input_type -> productv1.QueryAllNullableFieldsTypesRequest + 57, // 290: productv1.ProductService.QueryAllPets:input_type -> productv1.QueryAllPetsRequest + 79, // 291: productv1.ProductService.QueryAuthor:input_type -> productv1.QueryAuthorRequest + 81, // 292: productv1.ProductService.QueryAuthorById:input_type -> productv1.QueryAuthorByIdRequest + 83, // 293: productv1.ProductService.QueryAuthorsWithFilter:input_type -> productv1.QueryAuthorsWithFilterRequest + 71, // 294: productv1.ProductService.QueryBlogPost:input_type -> productv1.QueryBlogPostRequest + 73, // 295: productv1.ProductService.QueryBlogPostById:input_type -> productv1.QueryBlogPostByIdRequest + 75, // 296: productv1.ProductService.QueryBlogPostsWithFilter:input_type -> productv1.QueryBlogPostsWithFilterRequest + 87, // 297: productv1.ProductService.QueryBulkSearchAuthors:input_type -> productv1.QueryBulkSearchAuthorsRequest + 89, // 298: productv1.ProductService.QueryBulkSearchBlogPosts:input_type -> productv1.QueryBulkSearchBlogPostsRequest + 45, // 299: productv1.ProductService.QueryCalculateTotals:input_type -> productv1.QueryCalculateTotalsRequest + 47, // 300: productv1.ProductService.QueryCategories:input_type -> productv1.QueryCategoriesRequest + 49, // 301: productv1.ProductService.QueryCategoriesByKind:input_type -> productv1.QueryCategoriesByKindRequest + 51, // 302: productv1.ProductService.QueryCategoriesByKinds:input_type -> productv1.QueryCategoriesByKindsRequest + 43, // 303: productv1.ProductService.QueryComplexFilterType:input_type -> productv1.QueryComplexFilterTypeRequest + 53, // 304: productv1.ProductService.QueryFilterCategories:input_type -> productv1.QueryFilterCategoriesRequest + 35, // 305: productv1.ProductService.QueryNestedType:input_type -> productv1.QueryNestedTypeRequest + 63, // 306: productv1.ProductService.QueryNullableFieldsType:input_type -> productv1.QueryNullableFieldsTypeRequest + 65, // 307: productv1.ProductService.QueryNullableFieldsTypeById:input_type -> productv1.QueryNullableFieldsTypeByIdRequest + 67, // 308: productv1.ProductService.QueryNullableFieldsTypeWithFilter:input_type -> productv1.QueryNullableFieldsTypeWithFilterRequest + 55, // 309: productv1.ProductService.QueryRandomPet:input_type -> productv1.QueryRandomPetRequest + 61, // 310: productv1.ProductService.QueryRandomSearchResult:input_type -> productv1.QueryRandomSearchResultRequest + 37, // 311: productv1.ProductService.QueryRecursiveType:input_type -> productv1.QueryRecursiveTypeRequest + 59, // 312: productv1.ProductService.QuerySearch:input_type -> productv1.QuerySearchRequest + 91, // 313: productv1.ProductService.QueryTestContainer:input_type -> productv1.QueryTestContainerRequest + 93, // 314: productv1.ProductService.QueryTestContainers:input_type -> productv1.QueryTestContainersRequest + 39, // 315: productv1.ProductService.QueryTypeFilterWithArguments:input_type -> productv1.QueryTypeFilterWithArgumentsRequest + 41, // 316: productv1.ProductService.QueryTypeWithMultipleFilterFields:input_type -> productv1.QueryTypeWithMultipleFilterFieldsRequest + 33, // 317: productv1.ProductService.QueryUser:input_type -> productv1.QueryUserRequest + 31, // 318: productv1.ProductService.QueryUsers:input_type -> productv1.QueryUsersRequest + 156, // 319: productv1.ProductService.ResolveCategoryCategoryMetrics:input_type -> productv1.ResolveCategoryCategoryMetricsRequest + 166, // 320: productv1.ProductService.ResolveCategoryCategoryStatus:input_type -> productv1.ResolveCategoryCategoryStatusRequest + 161, // 321: productv1.ProductService.ResolveCategoryMascot:input_type -> productv1.ResolveCategoryMascotRequest + 176, // 322: productv1.ProductService.ResolveCategoryMetricsNormalizedScore:input_type -> productv1.ResolveCategoryMetricsNormalizedScoreRequest + 151, // 323: productv1.ProductService.ResolveCategoryPopularityScore:input_type -> productv1.ResolveCategoryPopularityScoreRequest + 146, // 324: productv1.ProductService.ResolveCategoryProductCount:input_type -> productv1.ResolveCategoryProductCountRequest + 131, // 325: productv1.ProductService.ResolveProductMascotRecommendation:input_type -> productv1.ResolveProductMascotRecommendationRequest + 141, // 326: productv1.ProductService.ResolveProductProductDetails:input_type -> productv1.ResolveProductProductDetailsRequest + 126, // 327: productv1.ProductService.ResolveProductRecommendedCategory:input_type -> productv1.ResolveProductRecommendedCategoryRequest + 121, // 328: productv1.ProductService.ResolveProductShippingEstimate:input_type -> productv1.ResolveProductShippingEstimateRequest + 136, // 329: productv1.ProductService.ResolveProductStockStatus:input_type -> productv1.ResolveProductStockStatusRequest + 171, // 330: productv1.ProductService.ResolveSubcategoryItemCount:input_type -> productv1.ResolveSubcategoryItemCountRequest + 181, // 331: productv1.ProductService.ResolveTestContainerDetails:input_type -> productv1.ResolveTestContainerDetailsRequest + 24, // 332: productv1.ProductService.LookupProductById:output_type -> productv1.LookupProductByIdResponse + 27, // 333: productv1.ProductService.LookupStorageById:output_type -> productv1.LookupStorageByIdResponse + 30, // 334: productv1.ProductService.LookupWarehouseById:output_type -> productv1.LookupWarehouseByIdResponse + 112, // 335: productv1.ProductService.MutationBulkCreateAuthors:output_type -> productv1.MutationBulkCreateAuthorsResponse + 116, // 336: productv1.ProductService.MutationBulkCreateBlogPosts:output_type -> productv1.MutationBulkCreateBlogPostsResponse + 114, // 337: productv1.ProductService.MutationBulkUpdateAuthors:output_type -> productv1.MutationBulkUpdateAuthorsResponse + 118, // 338: productv1.ProductService.MutationBulkUpdateBlogPosts:output_type -> productv1.MutationBulkUpdateBlogPostsResponse + 108, // 339: productv1.ProductService.MutationCreateAuthor:output_type -> productv1.MutationCreateAuthorResponse + 104, // 340: productv1.ProductService.MutationCreateBlogPost:output_type -> productv1.MutationCreateBlogPostResponse + 100, // 341: productv1.ProductService.MutationCreateNullableFieldsType:output_type -> productv1.MutationCreateNullableFieldsTypeResponse + 96, // 342: productv1.ProductService.MutationCreateUser:output_type -> productv1.MutationCreateUserResponse + 98, // 343: productv1.ProductService.MutationPerformAction:output_type -> productv1.MutationPerformActionResponse + 110, // 344: productv1.ProductService.MutationUpdateAuthor:output_type -> productv1.MutationUpdateAuthorResponse + 106, // 345: productv1.ProductService.MutationUpdateBlogPost:output_type -> productv1.MutationUpdateBlogPostResponse + 102, // 346: productv1.ProductService.MutationUpdateNullableFieldsType:output_type -> productv1.MutationUpdateNullableFieldsTypeResponse + 86, // 347: productv1.ProductService.QueryAllAuthors:output_type -> productv1.QueryAllAuthorsResponse + 78, // 348: productv1.ProductService.QueryAllBlogPosts:output_type -> productv1.QueryAllBlogPostsResponse + 70, // 349: productv1.ProductService.QueryAllNullableFieldsTypes:output_type -> productv1.QueryAllNullableFieldsTypesResponse + 58, // 350: productv1.ProductService.QueryAllPets:output_type -> productv1.QueryAllPetsResponse + 80, // 351: productv1.ProductService.QueryAuthor:output_type -> productv1.QueryAuthorResponse + 82, // 352: productv1.ProductService.QueryAuthorById:output_type -> productv1.QueryAuthorByIdResponse + 84, // 353: productv1.ProductService.QueryAuthorsWithFilter:output_type -> productv1.QueryAuthorsWithFilterResponse + 72, // 354: productv1.ProductService.QueryBlogPost:output_type -> productv1.QueryBlogPostResponse + 74, // 355: productv1.ProductService.QueryBlogPostById:output_type -> productv1.QueryBlogPostByIdResponse + 76, // 356: productv1.ProductService.QueryBlogPostsWithFilter:output_type -> productv1.QueryBlogPostsWithFilterResponse + 88, // 357: productv1.ProductService.QueryBulkSearchAuthors:output_type -> productv1.QueryBulkSearchAuthorsResponse + 90, // 358: productv1.ProductService.QueryBulkSearchBlogPosts:output_type -> productv1.QueryBulkSearchBlogPostsResponse + 46, // 359: productv1.ProductService.QueryCalculateTotals:output_type -> productv1.QueryCalculateTotalsResponse + 48, // 360: productv1.ProductService.QueryCategories:output_type -> productv1.QueryCategoriesResponse + 50, // 361: productv1.ProductService.QueryCategoriesByKind:output_type -> productv1.QueryCategoriesByKindResponse + 52, // 362: productv1.ProductService.QueryCategoriesByKinds:output_type -> productv1.QueryCategoriesByKindsResponse + 44, // 363: productv1.ProductService.QueryComplexFilterType:output_type -> productv1.QueryComplexFilterTypeResponse + 54, // 364: productv1.ProductService.QueryFilterCategories:output_type -> productv1.QueryFilterCategoriesResponse + 36, // 365: productv1.ProductService.QueryNestedType:output_type -> productv1.QueryNestedTypeResponse + 64, // 366: productv1.ProductService.QueryNullableFieldsType:output_type -> productv1.QueryNullableFieldsTypeResponse + 66, // 367: productv1.ProductService.QueryNullableFieldsTypeById:output_type -> productv1.QueryNullableFieldsTypeByIdResponse + 68, // 368: productv1.ProductService.QueryNullableFieldsTypeWithFilter:output_type -> productv1.QueryNullableFieldsTypeWithFilterResponse + 56, // 369: productv1.ProductService.QueryRandomPet:output_type -> productv1.QueryRandomPetResponse + 62, // 370: productv1.ProductService.QueryRandomSearchResult:output_type -> productv1.QueryRandomSearchResultResponse + 38, // 371: productv1.ProductService.QueryRecursiveType:output_type -> productv1.QueryRecursiveTypeResponse + 60, // 372: productv1.ProductService.QuerySearch:output_type -> productv1.QuerySearchResponse + 92, // 373: productv1.ProductService.QueryTestContainer:output_type -> productv1.QueryTestContainerResponse + 94, // 374: productv1.ProductService.QueryTestContainers:output_type -> productv1.QueryTestContainersResponse + 40, // 375: productv1.ProductService.QueryTypeFilterWithArguments:output_type -> productv1.QueryTypeFilterWithArgumentsResponse + 42, // 376: productv1.ProductService.QueryTypeWithMultipleFilterFields:output_type -> productv1.QueryTypeWithMultipleFilterFieldsResponse + 34, // 377: productv1.ProductService.QueryUser:output_type -> productv1.QueryUserResponse + 32, // 378: productv1.ProductService.QueryUsers:output_type -> productv1.QueryUsersResponse + 158, // 379: productv1.ProductService.ResolveCategoryCategoryMetrics:output_type -> productv1.ResolveCategoryCategoryMetricsResponse + 168, // 380: productv1.ProductService.ResolveCategoryCategoryStatus:output_type -> productv1.ResolveCategoryCategoryStatusResponse + 163, // 381: productv1.ProductService.ResolveCategoryMascot:output_type -> productv1.ResolveCategoryMascotResponse + 178, // 382: productv1.ProductService.ResolveCategoryMetricsNormalizedScore:output_type -> productv1.ResolveCategoryMetricsNormalizedScoreResponse + 153, // 383: productv1.ProductService.ResolveCategoryPopularityScore:output_type -> productv1.ResolveCategoryPopularityScoreResponse + 148, // 384: productv1.ProductService.ResolveCategoryProductCount:output_type -> productv1.ResolveCategoryProductCountResponse + 133, // 385: productv1.ProductService.ResolveProductMascotRecommendation:output_type -> productv1.ResolveProductMascotRecommendationResponse + 143, // 386: productv1.ProductService.ResolveProductProductDetails:output_type -> productv1.ResolveProductProductDetailsResponse + 128, // 387: productv1.ProductService.ResolveProductRecommendedCategory:output_type -> productv1.ResolveProductRecommendedCategoryResponse + 123, // 388: productv1.ProductService.ResolveProductShippingEstimate:output_type -> productv1.ResolveProductShippingEstimateResponse + 138, // 389: productv1.ProductService.ResolveProductStockStatus:output_type -> productv1.ResolveProductStockStatusResponse + 173, // 390: productv1.ProductService.ResolveSubcategoryItemCount:output_type -> productv1.ResolveSubcategoryItemCountResponse + 183, // 391: productv1.ProductService.ResolveTestContainerDetails:output_type -> productv1.ResolveTestContainerDetailsResponse + 332, // [332:392] is the sub-list for method output_type + 272, // [272:332] is the sub-list for method input_type + 272, // [272:272] is the sub-list for extension type_name + 272, // [272:272] is the sub-list for extension extendee + 0, // [0:272] is the sub-list for field type_name } func init() { file_product_proto_init() } @@ -11968,16 +14718,16 @@ func file_product_proto_init() { if File_product_proto != nil { return } - file_product_proto_msgTypes[157].OneofWrappers = []any{ + file_product_proto_msgTypes[196].OneofWrappers = []any{ (*Animal_Cat)(nil), (*Animal_Dog)(nil), } - file_product_proto_msgTypes[159].OneofWrappers = []any{ + file_product_proto_msgTypes[198].OneofWrappers = []any{ (*SearchResult_Product)(nil), (*SearchResult_User)(nil), (*SearchResult_Category)(nil), } - file_product_proto_msgTypes[168].OneofWrappers = []any{ + file_product_proto_msgTypes[208].OneofWrappers = []any{ (*ActionResult_ActionSuccess)(nil), (*ActionResult_ActionError)(nil), } @@ -11987,7 +14737,7 @@ func file_product_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_product_proto_rawDesc), len(file_product_proto_rawDesc)), NumEnums: 2, - NumMessages: 208, + NumMessages: 256, NumExtensions: 0, NumServices: 1, }, diff --git a/v2/pkg/grpctest/productv1/product_grpc.pb.go b/v2/pkg/grpctest/productv1/product_grpc.pb.go index 9f856d858..3439376c1 100644 --- a/v2/pkg/grpctest/productv1/product_grpc.pb.go +++ b/v2/pkg/grpctest/productv1/product_grpc.pb.go @@ -19,57 +19,66 @@ import ( const _ = grpc.SupportPackageIsVersion9 const ( - ProductService_LookupProductById_FullMethodName = "/productv1.ProductService/LookupProductById" - ProductService_LookupStorageById_FullMethodName = "/productv1.ProductService/LookupStorageById" - ProductService_LookupWarehouseById_FullMethodName = "/productv1.ProductService/LookupWarehouseById" - ProductService_MutationBulkCreateAuthors_FullMethodName = "/productv1.ProductService/MutationBulkCreateAuthors" - ProductService_MutationBulkCreateBlogPosts_FullMethodName = "/productv1.ProductService/MutationBulkCreateBlogPosts" - ProductService_MutationBulkUpdateAuthors_FullMethodName = "/productv1.ProductService/MutationBulkUpdateAuthors" - ProductService_MutationBulkUpdateBlogPosts_FullMethodName = "/productv1.ProductService/MutationBulkUpdateBlogPosts" - ProductService_MutationCreateAuthor_FullMethodName = "/productv1.ProductService/MutationCreateAuthor" - ProductService_MutationCreateBlogPost_FullMethodName = "/productv1.ProductService/MutationCreateBlogPost" - ProductService_MutationCreateNullableFieldsType_FullMethodName = "/productv1.ProductService/MutationCreateNullableFieldsType" - ProductService_MutationCreateUser_FullMethodName = "/productv1.ProductService/MutationCreateUser" - ProductService_MutationPerformAction_FullMethodName = "/productv1.ProductService/MutationPerformAction" - ProductService_MutationUpdateAuthor_FullMethodName = "/productv1.ProductService/MutationUpdateAuthor" - ProductService_MutationUpdateBlogPost_FullMethodName = "/productv1.ProductService/MutationUpdateBlogPost" - ProductService_MutationUpdateNullableFieldsType_FullMethodName = "/productv1.ProductService/MutationUpdateNullableFieldsType" - ProductService_QueryAllAuthors_FullMethodName = "/productv1.ProductService/QueryAllAuthors" - ProductService_QueryAllBlogPosts_FullMethodName = "/productv1.ProductService/QueryAllBlogPosts" - ProductService_QueryAllNullableFieldsTypes_FullMethodName = "/productv1.ProductService/QueryAllNullableFieldsTypes" - ProductService_QueryAllPets_FullMethodName = "/productv1.ProductService/QueryAllPets" - ProductService_QueryAuthor_FullMethodName = "/productv1.ProductService/QueryAuthor" - ProductService_QueryAuthorById_FullMethodName = "/productv1.ProductService/QueryAuthorById" - ProductService_QueryAuthorsWithFilter_FullMethodName = "/productv1.ProductService/QueryAuthorsWithFilter" - ProductService_QueryBlogPost_FullMethodName = "/productv1.ProductService/QueryBlogPost" - ProductService_QueryBlogPostById_FullMethodName = "/productv1.ProductService/QueryBlogPostById" - ProductService_QueryBlogPostsWithFilter_FullMethodName = "/productv1.ProductService/QueryBlogPostsWithFilter" - ProductService_QueryBulkSearchAuthors_FullMethodName = "/productv1.ProductService/QueryBulkSearchAuthors" - ProductService_QueryBulkSearchBlogPosts_FullMethodName = "/productv1.ProductService/QueryBulkSearchBlogPosts" - ProductService_QueryCalculateTotals_FullMethodName = "/productv1.ProductService/QueryCalculateTotals" - ProductService_QueryCategories_FullMethodName = "/productv1.ProductService/QueryCategories" - ProductService_QueryCategoriesByKind_FullMethodName = "/productv1.ProductService/QueryCategoriesByKind" - ProductService_QueryCategoriesByKinds_FullMethodName = "/productv1.ProductService/QueryCategoriesByKinds" - ProductService_QueryComplexFilterType_FullMethodName = "/productv1.ProductService/QueryComplexFilterType" - ProductService_QueryFilterCategories_FullMethodName = "/productv1.ProductService/QueryFilterCategories" - ProductService_QueryNestedType_FullMethodName = "/productv1.ProductService/QueryNestedType" - ProductService_QueryNullableFieldsType_FullMethodName = "/productv1.ProductService/QueryNullableFieldsType" - ProductService_QueryNullableFieldsTypeById_FullMethodName = "/productv1.ProductService/QueryNullableFieldsTypeById" - ProductService_QueryNullableFieldsTypeWithFilter_FullMethodName = "/productv1.ProductService/QueryNullableFieldsTypeWithFilter" - ProductService_QueryRandomPet_FullMethodName = "/productv1.ProductService/QueryRandomPet" - ProductService_QueryRandomSearchResult_FullMethodName = "/productv1.ProductService/QueryRandomSearchResult" - ProductService_QueryRecursiveType_FullMethodName = "/productv1.ProductService/QueryRecursiveType" - ProductService_QuerySearch_FullMethodName = "/productv1.ProductService/QuerySearch" - ProductService_QueryTypeFilterWithArguments_FullMethodName = "/productv1.ProductService/QueryTypeFilterWithArguments" - ProductService_QueryTypeWithMultipleFilterFields_FullMethodName = "/productv1.ProductService/QueryTypeWithMultipleFilterFields" - ProductService_QueryUser_FullMethodName = "/productv1.ProductService/QueryUser" - ProductService_QueryUsers_FullMethodName = "/productv1.ProductService/QueryUsers" - ProductService_ResolveCategoryCategoryMetrics_FullMethodName = "/productv1.ProductService/ResolveCategoryCategoryMetrics" - ProductService_ResolveCategoryPopularityScore_FullMethodName = "/productv1.ProductService/ResolveCategoryPopularityScore" - ProductService_ResolveCategoryProductCount_FullMethodName = "/productv1.ProductService/ResolveCategoryProductCount" - ProductService_ResolveProductRecommendedCategory_FullMethodName = "/productv1.ProductService/ResolveProductRecommendedCategory" - ProductService_ResolveProductShippingEstimate_FullMethodName = "/productv1.ProductService/ResolveProductShippingEstimate" - ProductService_ResolveSubcategoryItemCount_FullMethodName = "/productv1.ProductService/ResolveSubcategoryItemCount" + ProductService_LookupProductById_FullMethodName = "/productv1.ProductService/LookupProductById" + ProductService_LookupStorageById_FullMethodName = "/productv1.ProductService/LookupStorageById" + ProductService_LookupWarehouseById_FullMethodName = "/productv1.ProductService/LookupWarehouseById" + ProductService_MutationBulkCreateAuthors_FullMethodName = "/productv1.ProductService/MutationBulkCreateAuthors" + ProductService_MutationBulkCreateBlogPosts_FullMethodName = "/productv1.ProductService/MutationBulkCreateBlogPosts" + ProductService_MutationBulkUpdateAuthors_FullMethodName = "/productv1.ProductService/MutationBulkUpdateAuthors" + ProductService_MutationBulkUpdateBlogPosts_FullMethodName = "/productv1.ProductService/MutationBulkUpdateBlogPosts" + ProductService_MutationCreateAuthor_FullMethodName = "/productv1.ProductService/MutationCreateAuthor" + ProductService_MutationCreateBlogPost_FullMethodName = "/productv1.ProductService/MutationCreateBlogPost" + ProductService_MutationCreateNullableFieldsType_FullMethodName = "/productv1.ProductService/MutationCreateNullableFieldsType" + ProductService_MutationCreateUser_FullMethodName = "/productv1.ProductService/MutationCreateUser" + ProductService_MutationPerformAction_FullMethodName = "/productv1.ProductService/MutationPerformAction" + ProductService_MutationUpdateAuthor_FullMethodName = "/productv1.ProductService/MutationUpdateAuthor" + ProductService_MutationUpdateBlogPost_FullMethodName = "/productv1.ProductService/MutationUpdateBlogPost" + ProductService_MutationUpdateNullableFieldsType_FullMethodName = "/productv1.ProductService/MutationUpdateNullableFieldsType" + ProductService_QueryAllAuthors_FullMethodName = "/productv1.ProductService/QueryAllAuthors" + ProductService_QueryAllBlogPosts_FullMethodName = "/productv1.ProductService/QueryAllBlogPosts" + ProductService_QueryAllNullableFieldsTypes_FullMethodName = "/productv1.ProductService/QueryAllNullableFieldsTypes" + ProductService_QueryAllPets_FullMethodName = "/productv1.ProductService/QueryAllPets" + ProductService_QueryAuthor_FullMethodName = "/productv1.ProductService/QueryAuthor" + ProductService_QueryAuthorById_FullMethodName = "/productv1.ProductService/QueryAuthorById" + ProductService_QueryAuthorsWithFilter_FullMethodName = "/productv1.ProductService/QueryAuthorsWithFilter" + ProductService_QueryBlogPost_FullMethodName = "/productv1.ProductService/QueryBlogPost" + ProductService_QueryBlogPostById_FullMethodName = "/productv1.ProductService/QueryBlogPostById" + ProductService_QueryBlogPostsWithFilter_FullMethodName = "/productv1.ProductService/QueryBlogPostsWithFilter" + ProductService_QueryBulkSearchAuthors_FullMethodName = "/productv1.ProductService/QueryBulkSearchAuthors" + ProductService_QueryBulkSearchBlogPosts_FullMethodName = "/productv1.ProductService/QueryBulkSearchBlogPosts" + ProductService_QueryCalculateTotals_FullMethodName = "/productv1.ProductService/QueryCalculateTotals" + ProductService_QueryCategories_FullMethodName = "/productv1.ProductService/QueryCategories" + ProductService_QueryCategoriesByKind_FullMethodName = "/productv1.ProductService/QueryCategoriesByKind" + ProductService_QueryCategoriesByKinds_FullMethodName = "/productv1.ProductService/QueryCategoriesByKinds" + ProductService_QueryComplexFilterType_FullMethodName = "/productv1.ProductService/QueryComplexFilterType" + ProductService_QueryFilterCategories_FullMethodName = "/productv1.ProductService/QueryFilterCategories" + ProductService_QueryNestedType_FullMethodName = "/productv1.ProductService/QueryNestedType" + ProductService_QueryNullableFieldsType_FullMethodName = "/productv1.ProductService/QueryNullableFieldsType" + ProductService_QueryNullableFieldsTypeById_FullMethodName = "/productv1.ProductService/QueryNullableFieldsTypeById" + ProductService_QueryNullableFieldsTypeWithFilter_FullMethodName = "/productv1.ProductService/QueryNullableFieldsTypeWithFilter" + ProductService_QueryRandomPet_FullMethodName = "/productv1.ProductService/QueryRandomPet" + ProductService_QueryRandomSearchResult_FullMethodName = "/productv1.ProductService/QueryRandomSearchResult" + ProductService_QueryRecursiveType_FullMethodName = "/productv1.ProductService/QueryRecursiveType" + ProductService_QuerySearch_FullMethodName = "/productv1.ProductService/QuerySearch" + ProductService_QueryTestContainer_FullMethodName = "/productv1.ProductService/QueryTestContainer" + ProductService_QueryTestContainers_FullMethodName = "/productv1.ProductService/QueryTestContainers" + ProductService_QueryTypeFilterWithArguments_FullMethodName = "/productv1.ProductService/QueryTypeFilterWithArguments" + ProductService_QueryTypeWithMultipleFilterFields_FullMethodName = "/productv1.ProductService/QueryTypeWithMultipleFilterFields" + ProductService_QueryUser_FullMethodName = "/productv1.ProductService/QueryUser" + ProductService_QueryUsers_FullMethodName = "/productv1.ProductService/QueryUsers" + ProductService_ResolveCategoryCategoryMetrics_FullMethodName = "/productv1.ProductService/ResolveCategoryCategoryMetrics" + ProductService_ResolveCategoryCategoryStatus_FullMethodName = "/productv1.ProductService/ResolveCategoryCategoryStatus" + ProductService_ResolveCategoryMascot_FullMethodName = "/productv1.ProductService/ResolveCategoryMascot" + ProductService_ResolveCategoryMetricsNormalizedScore_FullMethodName = "/productv1.ProductService/ResolveCategoryMetricsNormalizedScore" + ProductService_ResolveCategoryPopularityScore_FullMethodName = "/productv1.ProductService/ResolveCategoryPopularityScore" + ProductService_ResolveCategoryProductCount_FullMethodName = "/productv1.ProductService/ResolveCategoryProductCount" + ProductService_ResolveProductMascotRecommendation_FullMethodName = "/productv1.ProductService/ResolveProductMascotRecommendation" + ProductService_ResolveProductProductDetails_FullMethodName = "/productv1.ProductService/ResolveProductProductDetails" + ProductService_ResolveProductRecommendedCategory_FullMethodName = "/productv1.ProductService/ResolveProductRecommendedCategory" + ProductService_ResolveProductShippingEstimate_FullMethodName = "/productv1.ProductService/ResolveProductShippingEstimate" + ProductService_ResolveProductStockStatus_FullMethodName = "/productv1.ProductService/ResolveProductStockStatus" + ProductService_ResolveSubcategoryItemCount_FullMethodName = "/productv1.ProductService/ResolveSubcategoryItemCount" + ProductService_ResolveTestContainerDetails_FullMethodName = "/productv1.ProductService/ResolveTestContainerDetails" ) // ProductServiceClient is the client API for ProductService service. @@ -122,16 +131,25 @@ type ProductServiceClient interface { QueryRandomSearchResult(ctx context.Context, in *QueryRandomSearchResultRequest, opts ...grpc.CallOption) (*QueryRandomSearchResultResponse, error) QueryRecursiveType(ctx context.Context, in *QueryRecursiveTypeRequest, opts ...grpc.CallOption) (*QueryRecursiveTypeResponse, error) QuerySearch(ctx context.Context, in *QuerySearchRequest, opts ...grpc.CallOption) (*QuerySearchResponse, error) + QueryTestContainer(ctx context.Context, in *QueryTestContainerRequest, opts ...grpc.CallOption) (*QueryTestContainerResponse, error) + QueryTestContainers(ctx context.Context, in *QueryTestContainersRequest, opts ...grpc.CallOption) (*QueryTestContainersResponse, error) QueryTypeFilterWithArguments(ctx context.Context, in *QueryTypeFilterWithArgumentsRequest, opts ...grpc.CallOption) (*QueryTypeFilterWithArgumentsResponse, error) QueryTypeWithMultipleFilterFields(ctx context.Context, in *QueryTypeWithMultipleFilterFieldsRequest, opts ...grpc.CallOption) (*QueryTypeWithMultipleFilterFieldsResponse, error) QueryUser(ctx context.Context, in *QueryUserRequest, opts ...grpc.CallOption) (*QueryUserResponse, error) QueryUsers(ctx context.Context, in *QueryUsersRequest, opts ...grpc.CallOption) (*QueryUsersResponse, error) ResolveCategoryCategoryMetrics(ctx context.Context, in *ResolveCategoryCategoryMetricsRequest, opts ...grpc.CallOption) (*ResolveCategoryCategoryMetricsResponse, error) + ResolveCategoryCategoryStatus(ctx context.Context, in *ResolveCategoryCategoryStatusRequest, opts ...grpc.CallOption) (*ResolveCategoryCategoryStatusResponse, error) + ResolveCategoryMascot(ctx context.Context, in *ResolveCategoryMascotRequest, opts ...grpc.CallOption) (*ResolveCategoryMascotResponse, error) + ResolveCategoryMetricsNormalizedScore(ctx context.Context, in *ResolveCategoryMetricsNormalizedScoreRequest, opts ...grpc.CallOption) (*ResolveCategoryMetricsNormalizedScoreResponse, error) ResolveCategoryPopularityScore(ctx context.Context, in *ResolveCategoryPopularityScoreRequest, opts ...grpc.CallOption) (*ResolveCategoryPopularityScoreResponse, error) ResolveCategoryProductCount(ctx context.Context, in *ResolveCategoryProductCountRequest, opts ...grpc.CallOption) (*ResolveCategoryProductCountResponse, error) + ResolveProductMascotRecommendation(ctx context.Context, in *ResolveProductMascotRecommendationRequest, opts ...grpc.CallOption) (*ResolveProductMascotRecommendationResponse, error) + ResolveProductProductDetails(ctx context.Context, in *ResolveProductProductDetailsRequest, opts ...grpc.CallOption) (*ResolveProductProductDetailsResponse, error) ResolveProductRecommendedCategory(ctx context.Context, in *ResolveProductRecommendedCategoryRequest, opts ...grpc.CallOption) (*ResolveProductRecommendedCategoryResponse, error) ResolveProductShippingEstimate(ctx context.Context, in *ResolveProductShippingEstimateRequest, opts ...grpc.CallOption) (*ResolveProductShippingEstimateResponse, error) + ResolveProductStockStatus(ctx context.Context, in *ResolveProductStockStatusRequest, opts ...grpc.CallOption) (*ResolveProductStockStatusResponse, error) ResolveSubcategoryItemCount(ctx context.Context, in *ResolveSubcategoryItemCountRequest, opts ...grpc.CallOption) (*ResolveSubcategoryItemCountResponse, error) + ResolveTestContainerDetails(ctx context.Context, in *ResolveTestContainerDetailsRequest, opts ...grpc.CallOption) (*ResolveTestContainerDetailsResponse, error) } type productServiceClient struct { @@ -552,6 +570,26 @@ func (c *productServiceClient) QuerySearch(ctx context.Context, in *QuerySearchR return out, nil } +func (c *productServiceClient) QueryTestContainer(ctx context.Context, in *QueryTestContainerRequest, opts ...grpc.CallOption) (*QueryTestContainerResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(QueryTestContainerResponse) + err := c.cc.Invoke(ctx, ProductService_QueryTestContainer_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *productServiceClient) QueryTestContainers(ctx context.Context, in *QueryTestContainersRequest, opts ...grpc.CallOption) (*QueryTestContainersResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(QueryTestContainersResponse) + err := c.cc.Invoke(ctx, ProductService_QueryTestContainers_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *productServiceClient) QueryTypeFilterWithArguments(ctx context.Context, in *QueryTypeFilterWithArgumentsRequest, opts ...grpc.CallOption) (*QueryTypeFilterWithArgumentsResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(QueryTypeFilterWithArgumentsResponse) @@ -602,6 +640,36 @@ func (c *productServiceClient) ResolveCategoryCategoryMetrics(ctx context.Contex return out, nil } +func (c *productServiceClient) ResolveCategoryCategoryStatus(ctx context.Context, in *ResolveCategoryCategoryStatusRequest, opts ...grpc.CallOption) (*ResolveCategoryCategoryStatusResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ResolveCategoryCategoryStatusResponse) + err := c.cc.Invoke(ctx, ProductService_ResolveCategoryCategoryStatus_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *productServiceClient) ResolveCategoryMascot(ctx context.Context, in *ResolveCategoryMascotRequest, opts ...grpc.CallOption) (*ResolveCategoryMascotResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ResolveCategoryMascotResponse) + err := c.cc.Invoke(ctx, ProductService_ResolveCategoryMascot_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *productServiceClient) ResolveCategoryMetricsNormalizedScore(ctx context.Context, in *ResolveCategoryMetricsNormalizedScoreRequest, opts ...grpc.CallOption) (*ResolveCategoryMetricsNormalizedScoreResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ResolveCategoryMetricsNormalizedScoreResponse) + err := c.cc.Invoke(ctx, ProductService_ResolveCategoryMetricsNormalizedScore_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *productServiceClient) ResolveCategoryPopularityScore(ctx context.Context, in *ResolveCategoryPopularityScoreRequest, opts ...grpc.CallOption) (*ResolveCategoryPopularityScoreResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(ResolveCategoryPopularityScoreResponse) @@ -622,6 +690,26 @@ func (c *productServiceClient) ResolveCategoryProductCount(ctx context.Context, return out, nil } +func (c *productServiceClient) ResolveProductMascotRecommendation(ctx context.Context, in *ResolveProductMascotRecommendationRequest, opts ...grpc.CallOption) (*ResolveProductMascotRecommendationResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ResolveProductMascotRecommendationResponse) + err := c.cc.Invoke(ctx, ProductService_ResolveProductMascotRecommendation_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *productServiceClient) ResolveProductProductDetails(ctx context.Context, in *ResolveProductProductDetailsRequest, opts ...grpc.CallOption) (*ResolveProductProductDetailsResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ResolveProductProductDetailsResponse) + err := c.cc.Invoke(ctx, ProductService_ResolveProductProductDetails_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *productServiceClient) ResolveProductRecommendedCategory(ctx context.Context, in *ResolveProductRecommendedCategoryRequest, opts ...grpc.CallOption) (*ResolveProductRecommendedCategoryResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(ResolveProductRecommendedCategoryResponse) @@ -642,6 +730,16 @@ func (c *productServiceClient) ResolveProductShippingEstimate(ctx context.Contex return out, nil } +func (c *productServiceClient) ResolveProductStockStatus(ctx context.Context, in *ResolveProductStockStatusRequest, opts ...grpc.CallOption) (*ResolveProductStockStatusResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ResolveProductStockStatusResponse) + err := c.cc.Invoke(ctx, ProductService_ResolveProductStockStatus_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *productServiceClient) ResolveSubcategoryItemCount(ctx context.Context, in *ResolveSubcategoryItemCountRequest, opts ...grpc.CallOption) (*ResolveSubcategoryItemCountResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(ResolveSubcategoryItemCountResponse) @@ -652,6 +750,16 @@ func (c *productServiceClient) ResolveSubcategoryItemCount(ctx context.Context, return out, nil } +func (c *productServiceClient) ResolveTestContainerDetails(ctx context.Context, in *ResolveTestContainerDetailsRequest, opts ...grpc.CallOption) (*ResolveTestContainerDetailsResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ResolveTestContainerDetailsResponse) + err := c.cc.Invoke(ctx, ProductService_ResolveTestContainerDetails_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + // ProductServiceServer is the server API for ProductService service. // All implementations must embed UnimplementedProductServiceServer // for forward compatibility. @@ -702,16 +810,25 @@ type ProductServiceServer interface { QueryRandomSearchResult(context.Context, *QueryRandomSearchResultRequest) (*QueryRandomSearchResultResponse, error) QueryRecursiveType(context.Context, *QueryRecursiveTypeRequest) (*QueryRecursiveTypeResponse, error) QuerySearch(context.Context, *QuerySearchRequest) (*QuerySearchResponse, error) + QueryTestContainer(context.Context, *QueryTestContainerRequest) (*QueryTestContainerResponse, error) + QueryTestContainers(context.Context, *QueryTestContainersRequest) (*QueryTestContainersResponse, error) QueryTypeFilterWithArguments(context.Context, *QueryTypeFilterWithArgumentsRequest) (*QueryTypeFilterWithArgumentsResponse, error) QueryTypeWithMultipleFilterFields(context.Context, *QueryTypeWithMultipleFilterFieldsRequest) (*QueryTypeWithMultipleFilterFieldsResponse, error) QueryUser(context.Context, *QueryUserRequest) (*QueryUserResponse, error) QueryUsers(context.Context, *QueryUsersRequest) (*QueryUsersResponse, error) ResolveCategoryCategoryMetrics(context.Context, *ResolveCategoryCategoryMetricsRequest) (*ResolveCategoryCategoryMetricsResponse, error) + ResolveCategoryCategoryStatus(context.Context, *ResolveCategoryCategoryStatusRequest) (*ResolveCategoryCategoryStatusResponse, error) + ResolveCategoryMascot(context.Context, *ResolveCategoryMascotRequest) (*ResolveCategoryMascotResponse, error) + ResolveCategoryMetricsNormalizedScore(context.Context, *ResolveCategoryMetricsNormalizedScoreRequest) (*ResolveCategoryMetricsNormalizedScoreResponse, error) ResolveCategoryPopularityScore(context.Context, *ResolveCategoryPopularityScoreRequest) (*ResolveCategoryPopularityScoreResponse, error) ResolveCategoryProductCount(context.Context, *ResolveCategoryProductCountRequest) (*ResolveCategoryProductCountResponse, error) + ResolveProductMascotRecommendation(context.Context, *ResolveProductMascotRecommendationRequest) (*ResolveProductMascotRecommendationResponse, error) + ResolveProductProductDetails(context.Context, *ResolveProductProductDetailsRequest) (*ResolveProductProductDetailsResponse, error) ResolveProductRecommendedCategory(context.Context, *ResolveProductRecommendedCategoryRequest) (*ResolveProductRecommendedCategoryResponse, error) ResolveProductShippingEstimate(context.Context, *ResolveProductShippingEstimateRequest) (*ResolveProductShippingEstimateResponse, error) + ResolveProductStockStatus(context.Context, *ResolveProductStockStatusRequest) (*ResolveProductStockStatusResponse, error) ResolveSubcategoryItemCount(context.Context, *ResolveSubcategoryItemCountRequest) (*ResolveSubcategoryItemCountResponse, error) + ResolveTestContainerDetails(context.Context, *ResolveTestContainerDetailsRequest) (*ResolveTestContainerDetailsResponse, error) mustEmbedUnimplementedProductServiceServer() } @@ -845,6 +962,12 @@ func (UnimplementedProductServiceServer) QueryRecursiveType(context.Context, *Qu func (UnimplementedProductServiceServer) QuerySearch(context.Context, *QuerySearchRequest) (*QuerySearchResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method QuerySearch not implemented") } +func (UnimplementedProductServiceServer) QueryTestContainer(context.Context, *QueryTestContainerRequest) (*QueryTestContainerResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method QueryTestContainer not implemented") +} +func (UnimplementedProductServiceServer) QueryTestContainers(context.Context, *QueryTestContainersRequest) (*QueryTestContainersResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method QueryTestContainers not implemented") +} func (UnimplementedProductServiceServer) QueryTypeFilterWithArguments(context.Context, *QueryTypeFilterWithArgumentsRequest) (*QueryTypeFilterWithArgumentsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method QueryTypeFilterWithArguments not implemented") } @@ -860,21 +983,42 @@ func (UnimplementedProductServiceServer) QueryUsers(context.Context, *QueryUsers func (UnimplementedProductServiceServer) ResolveCategoryCategoryMetrics(context.Context, *ResolveCategoryCategoryMetricsRequest) (*ResolveCategoryCategoryMetricsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ResolveCategoryCategoryMetrics not implemented") } +func (UnimplementedProductServiceServer) ResolveCategoryCategoryStatus(context.Context, *ResolveCategoryCategoryStatusRequest) (*ResolveCategoryCategoryStatusResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ResolveCategoryCategoryStatus not implemented") +} +func (UnimplementedProductServiceServer) ResolveCategoryMascot(context.Context, *ResolveCategoryMascotRequest) (*ResolveCategoryMascotResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ResolveCategoryMascot not implemented") +} +func (UnimplementedProductServiceServer) ResolveCategoryMetricsNormalizedScore(context.Context, *ResolveCategoryMetricsNormalizedScoreRequest) (*ResolveCategoryMetricsNormalizedScoreResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ResolveCategoryMetricsNormalizedScore not implemented") +} func (UnimplementedProductServiceServer) ResolveCategoryPopularityScore(context.Context, *ResolveCategoryPopularityScoreRequest) (*ResolveCategoryPopularityScoreResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ResolveCategoryPopularityScore not implemented") } func (UnimplementedProductServiceServer) ResolveCategoryProductCount(context.Context, *ResolveCategoryProductCountRequest) (*ResolveCategoryProductCountResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ResolveCategoryProductCount not implemented") } +func (UnimplementedProductServiceServer) ResolveProductMascotRecommendation(context.Context, *ResolveProductMascotRecommendationRequest) (*ResolveProductMascotRecommendationResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ResolveProductMascotRecommendation not implemented") +} +func (UnimplementedProductServiceServer) ResolveProductProductDetails(context.Context, *ResolveProductProductDetailsRequest) (*ResolveProductProductDetailsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ResolveProductProductDetails not implemented") +} func (UnimplementedProductServiceServer) ResolveProductRecommendedCategory(context.Context, *ResolveProductRecommendedCategoryRequest) (*ResolveProductRecommendedCategoryResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ResolveProductRecommendedCategory not implemented") } func (UnimplementedProductServiceServer) ResolveProductShippingEstimate(context.Context, *ResolveProductShippingEstimateRequest) (*ResolveProductShippingEstimateResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ResolveProductShippingEstimate not implemented") } +func (UnimplementedProductServiceServer) ResolveProductStockStatus(context.Context, *ResolveProductStockStatusRequest) (*ResolveProductStockStatusResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ResolveProductStockStatus not implemented") +} func (UnimplementedProductServiceServer) ResolveSubcategoryItemCount(context.Context, *ResolveSubcategoryItemCountRequest) (*ResolveSubcategoryItemCountResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ResolveSubcategoryItemCount not implemented") } +func (UnimplementedProductServiceServer) ResolveTestContainerDetails(context.Context, *ResolveTestContainerDetailsRequest) (*ResolveTestContainerDetailsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ResolveTestContainerDetails not implemented") +} func (UnimplementedProductServiceServer) mustEmbedUnimplementedProductServiceServer() {} func (UnimplementedProductServiceServer) testEmbeddedByValue() {} @@ -1634,6 +1778,42 @@ func _ProductService_QuerySearch_Handler(srv interface{}, ctx context.Context, d return interceptor(ctx, in, info, handler) } +func _ProductService_QueryTestContainer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryTestContainerRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProductServiceServer).QueryTestContainer(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ProductService_QueryTestContainer_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProductServiceServer).QueryTestContainer(ctx, req.(*QueryTestContainerRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ProductService_QueryTestContainers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryTestContainersRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProductServiceServer).QueryTestContainers(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ProductService_QueryTestContainers_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProductServiceServer).QueryTestContainers(ctx, req.(*QueryTestContainersRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _ProductService_QueryTypeFilterWithArguments_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(QueryTypeFilterWithArgumentsRequest) if err := dec(in); err != nil { @@ -1724,6 +1904,60 @@ func _ProductService_ResolveCategoryCategoryMetrics_Handler(srv interface{}, ctx return interceptor(ctx, in, info, handler) } +func _ProductService_ResolveCategoryCategoryStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ResolveCategoryCategoryStatusRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProductServiceServer).ResolveCategoryCategoryStatus(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ProductService_ResolveCategoryCategoryStatus_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProductServiceServer).ResolveCategoryCategoryStatus(ctx, req.(*ResolveCategoryCategoryStatusRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ProductService_ResolveCategoryMascot_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ResolveCategoryMascotRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProductServiceServer).ResolveCategoryMascot(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ProductService_ResolveCategoryMascot_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProductServiceServer).ResolveCategoryMascot(ctx, req.(*ResolveCategoryMascotRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ProductService_ResolveCategoryMetricsNormalizedScore_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ResolveCategoryMetricsNormalizedScoreRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProductServiceServer).ResolveCategoryMetricsNormalizedScore(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ProductService_ResolveCategoryMetricsNormalizedScore_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProductServiceServer).ResolveCategoryMetricsNormalizedScore(ctx, req.(*ResolveCategoryMetricsNormalizedScoreRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _ProductService_ResolveCategoryPopularityScore_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ResolveCategoryPopularityScoreRequest) if err := dec(in); err != nil { @@ -1760,6 +1994,42 @@ func _ProductService_ResolveCategoryProductCount_Handler(srv interface{}, ctx co return interceptor(ctx, in, info, handler) } +func _ProductService_ResolveProductMascotRecommendation_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ResolveProductMascotRecommendationRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProductServiceServer).ResolveProductMascotRecommendation(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ProductService_ResolveProductMascotRecommendation_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProductServiceServer).ResolveProductMascotRecommendation(ctx, req.(*ResolveProductMascotRecommendationRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ProductService_ResolveProductProductDetails_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ResolveProductProductDetailsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProductServiceServer).ResolveProductProductDetails(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ProductService_ResolveProductProductDetails_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProductServiceServer).ResolveProductProductDetails(ctx, req.(*ResolveProductProductDetailsRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _ProductService_ResolveProductRecommendedCategory_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ResolveProductRecommendedCategoryRequest) if err := dec(in); err != nil { @@ -1796,6 +2066,24 @@ func _ProductService_ResolveProductShippingEstimate_Handler(srv interface{}, ctx return interceptor(ctx, in, info, handler) } +func _ProductService_ResolveProductStockStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ResolveProductStockStatusRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProductServiceServer).ResolveProductStockStatus(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ProductService_ResolveProductStockStatus_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProductServiceServer).ResolveProductStockStatus(ctx, req.(*ResolveProductStockStatusRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _ProductService_ResolveSubcategoryItemCount_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ResolveSubcategoryItemCountRequest) if err := dec(in); err != nil { @@ -1814,6 +2102,24 @@ func _ProductService_ResolveSubcategoryItemCount_Handler(srv interface{}, ctx co return interceptor(ctx, in, info, handler) } +func _ProductService_ResolveTestContainerDetails_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ResolveTestContainerDetailsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProductServiceServer).ResolveTestContainerDetails(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ProductService_ResolveTestContainerDetails_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProductServiceServer).ResolveTestContainerDetails(ctx, req.(*ResolveTestContainerDetailsRequest)) + } + return interceptor(ctx, in, info, handler) +} + // ProductService_ServiceDesc is the grpc.ServiceDesc for ProductService service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -1985,6 +2291,14 @@ var ProductService_ServiceDesc = grpc.ServiceDesc{ MethodName: "QuerySearch", Handler: _ProductService_QuerySearch_Handler, }, + { + MethodName: "QueryTestContainer", + Handler: _ProductService_QueryTestContainer_Handler, + }, + { + MethodName: "QueryTestContainers", + Handler: _ProductService_QueryTestContainers_Handler, + }, { MethodName: "QueryTypeFilterWithArguments", Handler: _ProductService_QueryTypeFilterWithArguments_Handler, @@ -2005,6 +2319,18 @@ var ProductService_ServiceDesc = grpc.ServiceDesc{ MethodName: "ResolveCategoryCategoryMetrics", Handler: _ProductService_ResolveCategoryCategoryMetrics_Handler, }, + { + MethodName: "ResolveCategoryCategoryStatus", + Handler: _ProductService_ResolveCategoryCategoryStatus_Handler, + }, + { + MethodName: "ResolveCategoryMascot", + Handler: _ProductService_ResolveCategoryMascot_Handler, + }, + { + MethodName: "ResolveCategoryMetricsNormalizedScore", + Handler: _ProductService_ResolveCategoryMetricsNormalizedScore_Handler, + }, { MethodName: "ResolveCategoryPopularityScore", Handler: _ProductService_ResolveCategoryPopularityScore_Handler, @@ -2013,6 +2339,14 @@ var ProductService_ServiceDesc = grpc.ServiceDesc{ MethodName: "ResolveCategoryProductCount", Handler: _ProductService_ResolveCategoryProductCount_Handler, }, + { + MethodName: "ResolveProductMascotRecommendation", + Handler: _ProductService_ResolveProductMascotRecommendation_Handler, + }, + { + MethodName: "ResolveProductProductDetails", + Handler: _ProductService_ResolveProductProductDetails_Handler, + }, { MethodName: "ResolveProductRecommendedCategory", Handler: _ProductService_ResolveProductRecommendedCategory_Handler, @@ -2021,10 +2355,18 @@ var ProductService_ServiceDesc = grpc.ServiceDesc{ MethodName: "ResolveProductShippingEstimate", Handler: _ProductService_ResolveProductShippingEstimate_Handler, }, + { + MethodName: "ResolveProductStockStatus", + Handler: _ProductService_ResolveProductStockStatus_Handler, + }, { MethodName: "ResolveSubcategoryItemCount", Handler: _ProductService_ResolveSubcategoryItemCount_Handler, }, + { + MethodName: "ResolveTestContainerDetails", + Handler: _ProductService_ResolveTestContainerDetails_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "product.proto", diff --git a/v2/pkg/grpctest/testdata/products.graphqls b/v2/pkg/grpctest/testdata/products.graphqls index d2b6007d5..47662bfed 100644 --- a/v2/pkg/grpctest/testdata/products.graphqls +++ b/v2/pkg/grpctest/testdata/products.graphqls @@ -5,6 +5,16 @@ type Product @key(fields: "id") { price: Float! shippingEstimate(input: ShippingEstimateInput!): Float! @connect__fieldResolver(context: "id price") recommendedCategory(maxPrice: Int!): Category @connect__fieldResolver(context: "id name price") + mascotRecommendation(includeDetails: Boolean!): Animal @connect__fieldResolver(context: "id name") + stockStatus(checkAvailability: Boolean!): ActionResult! @connect__fieldResolver(context: "id name price") + productDetails(includeExtended: Boolean!): ProductDetails @connect__fieldResolver(context: "id name price") +} + +type ProductDetails { + id: ID! + description: String! + reviewSummary: ActionResult! + recommendedPet: Animal! } type Storage @key(fields: "id") { @@ -118,6 +128,8 @@ type Category { subcategories: [Subcategory!] popularityScore(threshold: Int): Int @connect__fieldResolver(context: "id") categoryMetrics(metricType: String!): CategoryMetrics @connect__fieldResolver(context: "id name") + mascot(includeVolume: Boolean!): Animal @connect__fieldResolver(context: "id kind") + categoryStatus(checkHealth: Boolean!): ActionResult! @connect__fieldResolver(context: "id name") } type Subcategory { @@ -134,6 +146,9 @@ type CategoryMetrics { value: Float! timestamp: String! categoryId: ID! + normalizedScore(baseline: Float!): Float! @connect__fieldResolver(context: "id value metricType") + # This will currently not generate a resolver as it is missing arguments. + relatedCategory: Category @connect__fieldResolver(context: "categoryId") } enum CategoryKind { @@ -154,6 +169,8 @@ type Cat implements Animal { name: String! kind: String! meowVolume: Int! + owner: Owner! + breed: CatBreed! } type Dog implements Animal { @@ -161,6 +178,47 @@ type Dog implements Animal { name: String! kind: String! barkVolume: Int! + owner: Owner! + breed: DogBreed! +} + +type Owner { + id: ID! + name: String! + contact: ContactInfo! +} + +type ContactInfo { + email: String! + phone: String! + address: Address +} + +type Address { + street: String! + city: String! + country: String! + zipCode: String! +} + +type CatBreed { + id: ID! + name: String! + origin: String! + characteristics: BreedCharacteristics! +} + +type DogBreed { + id: ID! + name: String! + origin: String! + characteristics: BreedCharacteristics! +} + +type BreedCharacteristics { + size: String! + temperament: String! + lifespan: String! } # Union Types for Testing @@ -181,6 +239,21 @@ type ActionError { code: String! } +# Test container type for testing field resolvers with interface and union returns +type TestContainer { + id: ID! + name: String! + description: String + details(includeExtended: Boolean!): TestDetails @connect__fieldResolver(context: "id name") +} + +type TestDetails { + id: ID! + summary: String! + pet: Animal! + status: ActionResult! +} + # Input types for union operations input SearchInput { query: String! @@ -413,6 +486,10 @@ type Query { # Bulk search operations for blog posts bulkSearchBlogPosts(filters: [BlogPostFilter!]): [BlogPost!]! + + # Test container queries (testing field resolvers with interface and union returns) + testContainer(id: ID!): TestContainer! + testContainers: [TestContainer!]! } input UserInput { diff --git a/v2/pkg/grpctest/util.go b/v2/pkg/grpctest/util.go new file mode 100644 index 000000000..849112a00 --- /dev/null +++ b/v2/pkg/grpctest/util.go @@ -0,0 +1,151 @@ +package grpctest + +import ( + "fmt" + + "google.golang.org/protobuf/types/known/wrapperspb" + + "github.com/wundergraph/graphql-go-tools/v2/pkg/grpctest/productv1" +) + +// Helper function to create subcategories for a category +func createSubcategories(categoryId string, kind productv1.CategoryKind, count int) *productv1.ListOfSubcategory { + if count <= 0 { + return &productv1.ListOfSubcategory{ + List: &productv1.ListOfSubcategory_List{ + Items: []*productv1.Subcategory{}, + }, + } + } + + subcategories := make([]*productv1.Subcategory, 0, count) + for j := 1; j <= count; j++ { + subcategories = append(subcategories, &productv1.Subcategory{ + Id: fmt.Sprintf("%s-subcategory-%d", categoryId, j), + Name: fmt.Sprintf("%s Subcategory %d", kind.String(), j), + Description: &wrapperspb.StringValue{Value: fmt.Sprintf("Subcategory %d for %s", j, categoryId)}, + IsActive: true, + }) + } + + return &productv1.ListOfSubcategory{ + List: &productv1.ListOfSubcategory_List{ + Items: subcategories, + }, + } +} + +// Helper functions to convert input types to output types +func convertCategoryInputsToCategories(inputs []*productv1.CategoryInput) []*productv1.Category { + if inputs == nil { + return nil + } + results := make([]*productv1.Category, len(inputs)) + for i, input := range inputs { + results[i] = &productv1.Category{ + Id: fmt.Sprintf("cat-input-%d", i), + Name: input.GetName(), + Kind: input.GetKind(), + Subcategories: createSubcategories(fmt.Sprintf("cat-input-%d", i), input.GetKind(), i+1), + } + } + return results +} + +func convertCategoryInputListToCategories(inputs *productv1.ListOfCategoryInput) []*productv1.Category { + if inputs == nil || inputs.List == nil || inputs.List.Items == nil { + return nil + } + results := make([]*productv1.Category, len(inputs.List.Items)) + for i, input := range inputs.List.Items { + results[i] = &productv1.Category{ + Id: fmt.Sprintf("cat-list-input-%d", i), + Name: input.GetName(), + Kind: input.GetKind(), + Subcategories: createSubcategories(fmt.Sprintf("cat-list-input-%d", i), input.GetKind(), i+1), + } + } + return results +} + +func convertUserInputsToUsers(inputs *productv1.ListOfUserInput) []*productv1.User { + if inputs == nil || inputs.List == nil || inputs.List.Items == nil { + return nil + } + results := make([]*productv1.User, len(inputs.List.Items)) + for i, input := range inputs.List.Items { + results[i] = &productv1.User{ + Id: fmt.Sprintf("user-input-%d", i), + Name: input.GetName(), + } + } + return results +} + +func convertNestedUserInputsToUsers(nestedInputs *productv1.ListOfListOfUserInput) *productv1.ListOfListOfUser { + if nestedInputs == nil || nestedInputs.List == nil { + return &productv1.ListOfListOfUser{ + List: &productv1.ListOfListOfUser_List{ + Items: []*productv1.ListOfUser{}, + }, + } + } + + results := make([]*productv1.ListOfUser, len(nestedInputs.GetList().GetItems())) + for i, userList := range nestedInputs.GetList().GetItems() { + userListItems := userList.GetList().GetItems() + users := make([]*productv1.User, len(userListItems)) + for j, userInput := range userListItems { + users[j] = &productv1.User{ + Id: fmt.Sprintf("nested-user-%d-%d", i, j), + Name: userInput.GetName(), + } + } + results[i] = &productv1.ListOfUser{ + List: &productv1.ListOfUser_List{ + Items: users, + }, + } + } + + return &productv1.ListOfListOfUser{ + List: &productv1.ListOfListOfUser_List{ + Items: results, + }, + } +} + +func convertNestedCategoryInputsToCategories(nestedInputs *productv1.ListOfListOfCategoryInput) *productv1.ListOfListOfCategory { + if nestedInputs == nil || nestedInputs.List == nil { + return &productv1.ListOfListOfCategory{ + List: &productv1.ListOfListOfCategory_List{ + Items: []*productv1.ListOfCategory{}, + }, + } + } + + results := make([]*productv1.ListOfCategory, len(nestedInputs.List.Items)) + for i, categoryList := range nestedInputs.GetList().GetItems() { + categoryListItems := categoryList.GetList().GetItems() + categories := make([]*productv1.Category, len(categoryListItems)) + for j, categoryInput := range categoryListItems { + categories[j] = &productv1.Category{ + Id: fmt.Sprintf("nested-cat-%d-%d", i, j), + Name: categoryInput.GetName(), + Kind: categoryInput.GetKind(), + Subcategories: createSubcategories(fmt.Sprintf("nested-cat-%d-%d", i, j), categoryInput.GetKind(), j+1), + } + } + results[i] = &productv1.ListOfCategory{ + List: &productv1.ListOfCategory_List{ + Items: categories, + }, + } + } + + return &productv1.ListOfListOfCategory{ + List: &productv1.ListOfListOfCategory_List{ + Items: results, + }, + } +}