| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768 |
- package autocomplete
- import (
- "fmt"
- "github.com/opencost/opencost/core/pkg/filter/ast"
- "github.com/opencost/opencost/core/pkg/opencost"
- )
- // FieldValidator normalizes and validates an autocomplete field name.
- type FieldValidator func(field string) (string, error)
- // WindowValidator validates a parsed autocomplete window.
- type WindowValidator func(window opencost.Window) error
- // DefaultWindowValidator rejects open-ended windows.
- func DefaultWindowValidator(window opencost.Window) error {
- if window.IsOpen() {
- return fmt.Errorf("%w: invalid window: %s", ErrBadRequest, window.String())
- }
- return nil
- }
- // NormalizeOptions configures shared request normalization.
- type NormalizeOptions struct {
- RequireTenantID bool
- EnsureLabelConfig bool
- WindowValidator WindowValidator
- }
- // NormalizeRequest validates and normalizes an autocomplete request in place.
- func NormalizeRequest(req *Request, validateField FieldValidator, opts NormalizeOptions) (string, error) {
- if req == nil {
- return "", fmt.Errorf("%w: request is nil", ErrBadRequest)
- }
- if opts.RequireTenantID && req.TenantID == "" {
- return "", fmt.Errorf("%w: tenant ID is required", ErrBadRequest)
- }
- windowValidator := opts.WindowValidator
- if windowValidator == nil {
- windowValidator = DefaultWindowValidator
- }
- if err := windowValidator(req.Window); err != nil {
- return "", err
- }
- field, err := validateField(req.Field)
- if err != nil {
- return "", fmt.Errorf("%w: invalid field: %w", ErrBadRequest, err)
- }
- limit, err := NormalizeLimit(req.Limit)
- if err != nil {
- return "", err
- }
- req.Field = field
- req.Search = SanitizeSearch(req.Search)
- req.Limit = limit
- if req.Filter == nil {
- req.Filter = &ast.VoidOp{}
- }
- if opts.EnsureLabelConfig && req.LabelConfig == nil {
- req.LabelConfig = opencost.NewLabelConfig()
- }
- return field, nil
- }
|