-
Notifications
You must be signed in to change notification settings - Fork 213
Add formatting and validation for free-form fields #272
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
+484
−12
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package validators | ||
|
||
import "errors" | ||
|
||
// Error messages for validation | ||
var ( | ||
// Repository validation errors | ||
ErrInvalidRepositoryURL = errors.New("invalid repository URL") | ||
|
||
// Package validation errors | ||
ErrPackageNameHasSpaces = errors.New("package name cannot contain spaces") | ||
|
||
// Remote validation errors | ||
ErrInvalidRemoteURL = errors.New("invalid remote URL") | ||
) | ||
|
||
// RepositorySource represents valid repository sources | ||
type RepositorySource string | ||
|
||
const ( | ||
SourceGitHub RepositorySource = "github" | ||
SourceGitLab RepositorySource = "gitlab" | ||
) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package validators | ||
|
||
import ( | ||
"net/url" | ||
"regexp" | ||
"strings" | ||
) | ||
|
||
var ( | ||
// Regular expressions for validating repository URLs | ||
// These regex patterns ensure the URL is in the format of a valid GitHub or GitLab repository | ||
// For example: // - GitHub: https://github.com/user/repo | ||
githubURLRegex = regexp.MustCompile(`^https?://(www\.)?github\.com/[\w.-]+/[\w.-]+/?$`) | ||
gitlabURLRegex = regexp.MustCompile(`^https?://(www\.)?gitlab\.com/[\w.-]+/[\w.-]+/?$`) | ||
) | ||
|
||
// IsValidRepositoryURL checks if the given URL is valid for the specified repository source | ||
func IsValidRepositoryURL(source RepositorySource, url string) bool { | ||
switch source { | ||
case SourceGitHub: | ||
return githubURLRegex.MatchString(url) | ||
case SourceGitLab: | ||
return gitlabURLRegex.MatchString(url) | ||
} | ||
return false | ||
} | ||
|
||
// HasNoSpaces checks if a string contains no spaces | ||
func HasNoSpaces(s string) bool { | ||
return !strings.Contains(s, " ") | ||
} | ||
|
||
// IsValidURL checks if a URL is in valid format | ||
func IsValidURL(rawURL string) bool { | ||
// Parse the URL | ||
u, err := url.Parse(rawURL) | ||
if err != nil { | ||
return false | ||
} | ||
|
||
// Check if scheme is present (http or https) | ||
if u.Scheme != "http" && u.Scheme != "https" { | ||
return false | ||
} | ||
|
||
if u.Host == "" { | ||
return false | ||
} | ||
return true | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
package validators | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/modelcontextprotocol/registry/internal/model" | ||
) | ||
|
||
// ServerValidator validates server details | ||
type ServerValidator struct { | ||
*RepositoryValidator // Embedded RepositoryValidator for repository validation | ||
} | ||
|
||
// Validate checks if the server details are valid | ||
func (v *ServerValidator) Validate(obj *model.ServerDetail) error { | ||
if err := v.RepositoryValidator.Validate(&obj.Repository); err != nil { | ||
return err | ||
} | ||
return nil | ||
} | ||
|
||
// NewServerValidator creates a new ServerValidator instance | ||
func NewServerValidator() *ServerValidator { | ||
return &ServerValidator{ | ||
RepositoryValidator: NewRepositoryValidator(), | ||
} | ||
} | ||
|
||
// RepositoryValidator validates repository details | ||
type RepositoryValidator struct { | ||
validSources map[RepositorySource]bool | ||
} | ||
|
||
// Validate checks if the repository details are valid | ||
func (rv *RepositoryValidator) Validate(obj *model.Repository) error { | ||
// Skip validation for empty repository (optional field) | ||
if obj.URL == "" && obj.Source == "" { | ||
return nil | ||
} | ||
|
||
// validate the repository source | ||
repoSource := RepositorySource(obj.Source) | ||
if !IsValidRepositoryURL(repoSource, obj.URL) { | ||
return fmt.Errorf("%w: %s", ErrInvalidRepositoryURL, obj.URL) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// NewRepositoryValidator creates a new RepositoryValidator instance | ||
func NewRepositoryValidator() *RepositoryValidator { | ||
return &RepositoryValidator{ | ||
validSources: map[RepositorySource]bool{SourceGitHub: true, SourceGitLab: true}, | ||
} | ||
} | ||
|
||
// PackageValidator validates package details | ||
type PackageValidator struct{} | ||
|
||
// Validate checks if the package details are valid | ||
func (pv *PackageValidator) Validate(obj *model.Package) error { | ||
domdomegg marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if !HasNoSpaces(obj.Name) { | ||
return ErrPackageNameHasSpaces | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// NewPackageValidator creates a new PackageValidator instance | ||
func NewPackageValidator() *PackageValidator { | ||
return &PackageValidator{} | ||
} | ||
|
||
// RemoteValidator validates remote connection details | ||
type RemoteValidator struct{} | ||
|
||
// Validate checks if the remote connection details are valid | ||
func (rv *RemoteValidator) Validate(obj *model.Remote) error { | ||
if !IsValidURL(obj.URL) { | ||
Avish34 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return fmt.Errorf("%w: %s", ErrInvalidRemoteURL, obj.URL) | ||
} | ||
return nil | ||
} | ||
|
||
// NewRemoteValidator creates a new RemoteValidator instance | ||
func NewRemoteValidator() *RemoteValidator { | ||
return &RemoteValidator{} | ||
} | ||
|
||
// ObjectValidator aggregates multiple validators for different object types | ||
// This allows for a single entry point to validate complex objects that may contain multiple fields | ||
// that need validation. | ||
type ObjectValidator struct { | ||
ServerValidator *ServerValidator | ||
PackageValidator *PackageValidator | ||
RemoteValidator *RemoteValidator | ||
} | ||
|
||
func NewObjectValidator() *ObjectValidator { | ||
return &ObjectValidator{ | ||
ServerValidator: NewServerValidator(), | ||
PackageValidator: NewPackageValidator(), | ||
RemoteValidator: NewRemoteValidator(), | ||
} | ||
} | ||
|
||
func (ov *ObjectValidator) Validate(obj *model.ServerDetail) error { | ||
if err := ov.ServerValidator.Validate(obj); err != nil { | ||
return err | ||
} | ||
|
||
for _, pkg := range obj.Packages { | ||
if err := ov.PackageValidator.Validate(&pkg); err != nil { | ||
return err | ||
} | ||
} | ||
|
||
for _, remote := range obj.Remotes { | ||
if err := ov.RemoteValidator.Validate(&remote); err != nil { | ||
return err | ||
} | ||
} | ||
return nil | ||
} |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.