normalize.go 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. package autocomplete
  2. import (
  3. "fmt"
  4. "github.com/opencost/opencost/core/pkg/opencost"
  5. )
  6. // FieldValidator normalizes and validates an autocomplete field name.
  7. type FieldValidator func(field string) (string, error)
  8. // WindowValidator validates a parsed autocomplete window.
  9. type WindowValidator func(window opencost.Window) error
  10. // DefaultWindowValidator rejects open-ended windows.
  11. func DefaultWindowValidator(window opencost.Window) error {
  12. if window.IsOpen() {
  13. return fmt.Errorf("%w: invalid window: %s", ErrBadRequest, window.String())
  14. }
  15. return nil
  16. }
  17. // NormalizeOptions configures shared request normalization.
  18. type NormalizeOptions struct {
  19. RequireTenantID bool
  20. EnsureLabelConfig bool
  21. WindowValidator WindowValidator
  22. }
  23. // NormalizeRequest validates and normalizes an autocomplete request in place.
  24. func NormalizeRequest(req *Request, validateField FieldValidator, opts NormalizeOptions) (string, error) {
  25. if req == nil {
  26. return "", fmt.Errorf("%w: request is nil", ErrBadRequest)
  27. }
  28. if opts.RequireTenantID && req.TenantID == "" {
  29. return "", fmt.Errorf("%w: tenant ID is required", ErrBadRequest)
  30. }
  31. windowValidator := opts.WindowValidator
  32. if windowValidator == nil {
  33. windowValidator = DefaultWindowValidator
  34. }
  35. if err := windowValidator(req.Window); err != nil {
  36. return "", err
  37. }
  38. field, err := validateField(req.Field)
  39. if err != nil {
  40. return "", fmt.Errorf("%w: invalid field: %w", ErrBadRequest, err)
  41. }
  42. limit, err := NormalizeLimit(req.Limit)
  43. if err != nil {
  44. return "", err
  45. }
  46. req.Field = field
  47. req.Search = SanitizeSearch(req.Search)
  48. req.Limit = limit
  49. if opts.EnsureLabelConfig && req.LabelConfig == nil {
  50. req.LabelConfig = opencost.NewLabelConfig()
  51. }
  52. return field, nil
  53. }