Skip to content

Commit

Permalink
chore: cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
devsergiy committed Dec 30, 2024
1 parent 3edd88b commit 4cfa27e
Show file tree
Hide file tree
Showing 2 changed files with 202 additions and 422 deletions.
212 changes: 48 additions & 164 deletions v2/pkg/variablesvalidation/variablesvalidation.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,35 @@ func (e *InvalidVariableError) Error() string {
return e.Message
}

func newInvalidVariableError(message string, isApolloCompatibilityMode bool) *InvalidVariableError {
func (v *variablesVisitor) invalidValueIfAllowed(variableContent string) string {
if v.opts.DisableExposingVariablesContent {
return ""
}

return fmt.Sprintf(": %s", variableContent)
}

func (v *variablesVisitor) invalidEnumValueIfAllowed(variableContent string) string {
if v.opts.DisableExposingVariablesContent {
return ""
}

return fmt.Sprintf("\"%s\" ", variableContent)
}

func (v *variablesVisitor) invalidValueMessage(variableName, variableContent string) string {
if v.opts.DisableExposingVariablesContent {
return fmt.Sprintf(`Variable "$%s" got invalid value`, variableName)
}

return fmt.Sprintf(`Variable "$%s" got invalid value %s`, variableName, variableContent)
}

func (v *variablesVisitor) newInvalidVariableError(message string) *InvalidVariableError {
err := &InvalidVariableError{
Message: message,
}
if isApolloCompatibilityMode {
if v.opts.ApolloCompatibilityFlags.ReplaceInvalidVarError {
err.ExtensionCode = errorcodes.BadUserInput
}
return err
Expand All @@ -40,16 +64,16 @@ type VariablesValidator struct {
}

type VariablesValidatorOptions struct {
ApolloCompatibilityFlags apollocompatibility.Flags
ApolloCompatibilityFlags apollocompatibility.Flags
DisableExposingVariablesContent bool
}

func NewVariablesValidator(options VariablesValidatorOptions) *VariablesValidator {
walker := astvisitor.NewWalker(8)
visitor := &variablesVisitor{
variables: &astjson.JSON{},
walker: &walker,
apolloCompatibilityFlags: options.ApolloCompatibilityFlags,
dev_mode: false,
variables: &astjson.JSON{},
walker: &walker,
opts: options,
}
walker.RegisterEnterVariableDefinitionVisitor(visitor)
return &VariablesValidator{
Expand All @@ -58,11 +82,8 @@ func NewVariablesValidator(options VariablesValidatorOptions) *VariablesValidato
}
}

func (v *VariablesValidator) Validate(operation, definition *ast.Document, variables []byte, devMode bool) error {
func (v *VariablesValidator) Validate(operation, definition *ast.Document, variables []byte) error {
v.visitor.err = nil
if devMode {
v.visitor.dev_mode = devMode
}
v.visitor.definition = definition
v.visitor.operation = operation
err := v.visitor.variables.ParseObject(variables)
Expand All @@ -86,8 +107,7 @@ type variablesVisitor struct {
currentVariableName []byte
currentVariableJsonNodeRef int
path []pathItem
dev_mode bool
apolloCompatibilityFlags apollocompatibility.Flags
opts VariablesValidatorOptions
}

func (v *variablesVisitor) renderPath() string {
Expand Down Expand Up @@ -195,10 +215,7 @@ func (v *variablesVisitor) renderVariableRequiredError(variableName []byte, type
v.err = err
return
}
v.err = newInvalidVariableError(
fmt.Sprintf(`Variable "$%s" of required type "%s" was not provided.`, string(variableName), out.String()),
v.apolloCompatibilityFlags.ReplaceInvalidVarError,
)
v.err = v.newInvalidVariableError(fmt.Sprintf(`Variable "$%s" of required type "%s" was not provided.`, string(variableName), out.String()))
}

func (v *variablesVisitor) renderVariableInvalidObjectTypeError(typeName []byte, variablesNode astjson.Node) {
Expand All @@ -209,17 +226,7 @@ func (v *variablesVisitor) renderVariableInvalidObjectTypeError(typeName []byte,
return
}
variableContent := out.String()
if v.dev_mode {
v.err = newInvalidVariableError(
fmt.Sprintf(`Variable "$%s" got invalid value %s; Expected type "%s" to be an object.`, string(v.currentVariableName), variableContent, string(typeName)),
v.apolloCompatibilityFlags.ReplaceInvalidVarError,
)
} else {
v.err = newInvalidVariableError(
fmt.Sprintf(`Variable "$%s" got invalid value; Expected type "%s" to be an object.`, string(v.currentVariableName), string(typeName)),
v.apolloCompatibilityFlags.ReplaceInvalidVarError,
)
}
v.err = v.newInvalidVariableError(fmt.Sprintf(`%s; Expected type "%s" to be an object.`, v.invalidValueMessage(string(v.currentVariableName), variableContent), string(typeName)))
}

func (v *variablesVisitor) renderVariableRequiredNotProvidedError(fieldName []byte, typeRef int) {
Expand All @@ -236,17 +243,7 @@ func (v *variablesVisitor) renderVariableRequiredNotProvidedError(fieldName []by
v.err = err
return
}
if v.dev_mode {
v.err = newInvalidVariableError(
fmt.Sprintf(`Variable "$%s" got invalid value %s; Field "%s" of required type "%s" was not provided.`, string(v.currentVariableName), variableContent, string(fieldName), out.String()),
v.apolloCompatibilityFlags.ReplaceInvalidVarError,
)
} else {
v.err = newInvalidVariableError(
fmt.Sprintf(`Variable "$%s" got invalid value; Field "%s" of required type "%s" was not provided.`, string(v.currentVariableName), string(fieldName), out.String()),
v.apolloCompatibilityFlags.ReplaceInvalidVarError,
)
}
v.err = v.newInvalidVariableError(fmt.Sprintf(`%s; Field "%s" of required type "%s" was not provided.`, v.invalidValueMessage(string(v.currentVariableName), variableContent), string(fieldName), out.String()))
}

func (v *variablesVisitor) renderVariableInvalidNestedTypeError(actualJsonNodeRef int, expectedType ast.NodeKind, expectedTypeName []byte, expectedList bool) {
Expand All @@ -267,116 +264,26 @@ func (v *variablesVisitor) renderVariableInvalidNestedTypeError(actualJsonNodeRe
case ast.NodeKindScalarTypeDefinition:
switch typeName {
case "String":
if v.dev_mode {
v.err = newInvalidVariableError(
fmt.Sprintf(`Variable "$%s" got invalid value %s%s; String cannot represent a non string value: %s`, variableName, invalidValue, path, invalidValue),
v.apolloCompatibilityFlags.ReplaceInvalidVarError,
)
} else {
v.err = newInvalidVariableError(
fmt.Sprintf(`Variable "$%s" got invalid value%s; String cannot represent a non string value`, variableName, path),
v.apolloCompatibilityFlags.ReplaceInvalidVarError,
)
}
v.err = v.newInvalidVariableError(fmt.Sprintf(`%s%s; String cannot represent a non string value%s`, v.invalidValueMessage(variableName, invalidValue), path, v.invalidValueIfAllowed(invalidValue)))
case "Int":
if v.dev_mode {
v.err = newInvalidVariableError(
fmt.Sprintf(`Variable "$%s" got invalid value %s%s; Int cannot represent non-integer value: %s`, variableName, invalidValue, path, invalidValue),
v.apolloCompatibilityFlags.ReplaceInvalidVarError,
)
} else {
v.err = newInvalidVariableError(
fmt.Sprintf(`Variable "$%s" got invalid value%s; Int cannot represent non-integer value`, variableName, path),
v.apolloCompatibilityFlags.ReplaceInvalidVarError,
)
}
v.err = v.newInvalidVariableError(fmt.Sprintf(`%s%s; Int cannot represent non-integer value%s`, v.invalidValueMessage(variableName, invalidValue), path, v.invalidValueIfAllowed(invalidValue)))
case "Float":
if v.dev_mode {
v.err = newInvalidVariableError(
fmt.Sprintf(`Variable "$%s" got invalid value %s%s; Float cannot represent non numeric value: %s`, variableName, invalidValue, path, invalidValue),
v.apolloCompatibilityFlags.ReplaceInvalidVarError,
)
} else {
v.err = newInvalidVariableError(
fmt.Sprintf(`Variable "$%s" got invalid value%s; Float cannot represent non numeric value`, variableName, path),
v.apolloCompatibilityFlags.ReplaceInvalidVarError,
)
}
v.err = v.newInvalidVariableError(fmt.Sprintf(`%s%s; Float cannot represent non numeric value%s`, v.invalidValueMessage(variableName, invalidValue), path, v.invalidValueIfAllowed(invalidValue)))
case "Boolean":
if v.dev_mode {
v.err = newInvalidVariableError(
fmt.Sprintf(`Variable "$%s" got invalid value %s%s; Boolean cannot represent a non boolean value: %s`, variableName, invalidValue, path, invalidValue),
v.apolloCompatibilityFlags.ReplaceInvalidVarError,
)
} else {
v.err = newInvalidVariableError(
fmt.Sprintf(`Variable "$%s" got invalid value%s; Boolean cannot represent a non boolean value`, variableName, path),
v.apolloCompatibilityFlags.ReplaceInvalidVarError,
)
}
v.err = v.newInvalidVariableError(fmt.Sprintf(`%s%s; Boolean cannot represent a non boolean value%s`, v.invalidValueMessage(variableName, invalidValue), path, v.invalidValueIfAllowed(invalidValue)))
case "ID":
if v.dev_mode {
v.err = newInvalidVariableError(
fmt.Sprintf(`Variable "$%s" got invalid value %s%s; ID cannot represent value: %s`, variableName, invalidValue, path, invalidValue),
v.apolloCompatibilityFlags.ReplaceInvalidVarError,
)
} else {
v.err = newInvalidVariableError(
fmt.Sprintf(`Variable "$%s" got invalid value%s; ID cannot represent value`, variableName, path),
v.apolloCompatibilityFlags.ReplaceInvalidVarError,
)
}
v.err = v.newInvalidVariableError(fmt.Sprintf(`%s%s; ID cannot represent a non-string and non-integer value%s`, v.invalidValueMessage(variableName, invalidValue), path, v.invalidValueIfAllowed(invalidValue)))
default:
if v.dev_mode {
v.err = newInvalidVariableError(
fmt.Sprintf(`Variable "$%s" got invalid value %s%s; Expected type "%s" to be a scalar.`, variableName, invalidValue, path, typeName),
v.apolloCompatibilityFlags.ReplaceInvalidVarError,
)
} else {
v.err = newInvalidVariableError(
fmt.Sprintf(`Variable "$%s" got invalid value%s; Expected type "%s" to be a scalar.`, variableName, path, typeName),
v.apolloCompatibilityFlags.ReplaceInvalidVarError,
)
}
v.err = v.newInvalidVariableError(fmt.Sprintf(`%s%s; Expected type "%s" to be a scalar.`, v.invalidValueMessage(variableName, invalidValue), path, typeName))
}
case ast.NodeKindInputObjectTypeDefinition:
if expectedList {
if v.dev_mode {
v.err = newInvalidVariableError(
fmt.Sprintf(`Variable "$%s" got invalid value %s%s; Got input type "%s", want: "[%s]"`, variableName, invalidValue, path, typeName, typeName),
v.apolloCompatibilityFlags.ReplaceInvalidVarError,
)
} else {
v.err = newInvalidVariableError(
fmt.Sprintf(`Variable "$%s" got invalid value%s; Got input type "%s", want: "[%s]"`, variableName, path, typeName, typeName),
v.apolloCompatibilityFlags.ReplaceInvalidVarError,
)
}
v.err = v.newInvalidVariableError(fmt.Sprintf(`%s%s; Got input type "%s", want: "[%s]"`, v.invalidValueMessage(variableName, invalidValue), path, typeName, typeName))
} else {
if v.dev_mode {
v.err = newInvalidVariableError(
fmt.Sprintf(`Variable "$%s" got invalid value %s%s; Expected type "%s" to be an input object.`, variableName, invalidValue, path, typeName),
v.apolloCompatibilityFlags.ReplaceInvalidVarError,
)
} else {
v.err = newInvalidVariableError(
fmt.Sprintf(`Variable "$%s" got invalid value%s; Expected type "%s" to be an input object.`, variableName, path, typeName),
v.apolloCompatibilityFlags.ReplaceInvalidVarError,
)
}
v.err = v.newInvalidVariableError(fmt.Sprintf(`%s%s; Expected type "%s" to be an input object.`, v.invalidValueMessage(variableName, invalidValue), path, typeName))
}
case ast.NodeKindEnumTypeDefinition:
if v.dev_mode {
v.err = newInvalidVariableError(
fmt.Sprintf(`Variable "$%s" got invalid value %s%s; Enum "%s" cannot represent non-string value: %s.`, variableName, invalidValue, path, typeName, invalidValue),
v.apolloCompatibilityFlags.ReplaceInvalidVarError,
)
} else {
v.err = newInvalidVariableError(
fmt.Sprintf(`Variable "$%s" got invalid value%s; Enum "%s" cannot represent non-string value.`, variableName, path, typeName),
v.apolloCompatibilityFlags.ReplaceInvalidVarError,
)
}
v.err = v.newInvalidVariableError(fmt.Sprintf(`%s%s; Enum "%s" cannot represent non-string value%s.`, v.invalidValueMessage(variableName, invalidValue), path, typeName, v.invalidValueIfAllowed(invalidValue)))
}
}

Expand All @@ -390,17 +297,7 @@ func (v *variablesVisitor) renderVariableFieldNotDefinedError(fieldName []byte,
}
invalidValue := buf.String()
path := v.renderPath()
if v.dev_mode {
v.err = newInvalidVariableError(
fmt.Sprintf(`Variable "$%s" got invalid value %s at "%s"; Field "%s" is not defined by type "%s".`, variableName, invalidValue, path, string(fieldName), string(typeName)),
v.apolloCompatibilityFlags.ReplaceInvalidVarError,
)
} else {
v.err = newInvalidVariableError(
fmt.Sprintf(`Variable "$%s" got invalid value at "%s"; Field "%s" is not defined by type "%s".`, variableName, path, string(fieldName), string(typeName)),
v.apolloCompatibilityFlags.ReplaceInvalidVarError,
)
}
v.err = v.newInvalidVariableError(fmt.Sprintf(`%s at "%s"; Field "%s" is not defined by type "%s".`, v.invalidValueMessage(variableName, invalidValue), path, string(fieldName), string(typeName)))
}

func (v *variablesVisitor) renderVariableEnumValueDoesNotExistError(typeName []byte, enumValue []byte) {
Expand All @@ -416,17 +313,7 @@ func (v *variablesVisitor) renderVariableEnumValueDoesNotExistError(typeName []b
if len(v.path) > 1 {
path = fmt.Sprintf(` at "%s"`, v.renderPath())
}
if v.dev_mode {
v.err = newInvalidVariableError(
fmt.Sprintf(`Variable "$%s" got invalid value %s%s; Value "%s" does not exist in "%s" enum.`, variableName, invalidValue, path, string(enumValue), string(typeName)),
v.apolloCompatibilityFlags.ReplaceInvalidVarError,
)
} else {
v.err = newInvalidVariableError(
fmt.Sprintf(`Variable "$%s" got invalid value%s; Value does not exist in "%s" enum.`, variableName, path, string(typeName)),
v.apolloCompatibilityFlags.ReplaceInvalidVarError,
)
}
v.err = v.newInvalidVariableError(fmt.Sprintf(`%s%s; Value %sdoes not exist in "%s" enum.`, v.invalidValueMessage(variableName, invalidValue), path, v.invalidEnumValueIfAllowed(string(enumValue)), string(typeName)))
}

func (v *variablesVisitor) renderVariableInvalidNullError(variableName []byte, typeRef int) {
Expand All @@ -437,10 +324,7 @@ func (v *variablesVisitor) renderVariableInvalidNullError(variableName []byte, t
return
}
typeName := buf.String()
v.err = newInvalidVariableError(
fmt.Sprintf(`Variable "$%s" got invalid value null; Expected non-nullable type "%s" not to be null.`, string(variableName), typeName),
v.apolloCompatibilityFlags.ReplaceInvalidVarError,
)
v.err = v.newInvalidVariableError(fmt.Sprintf(`Variable "$%s" got invalid value null; Expected non-nullable type "%s" not to be null.`, string(variableName), typeName))
}

func (v *variablesVisitor) traverseFieldDefinitionType(fieldTypeDefinitionNodeKind ast.NodeKind, fieldName ast.ByteSlice, typeRef int, fieldVariablesJsonNodeRef int, inputFieldRef int) {
Expand Down
Loading

0 comments on commit 4cfa27e

Please sign in to comment.