ValidateServerJSON performs exhaustive validation and returns all issues found opts specifies which types of validation to perform. ValidateSchema implies ValidateSchemaVersion. Empty schema is always checked and always produces an error when schema validation is performed.
(serverJSON *apiv0.ServerJSON, opts ValidationOptions)
| 55 | // opts specifies which types of validation to perform. ValidateSchema implies ValidateSchemaVersion. |
| 56 | // Empty schema is always checked and always produces an error when schema validation is performed. |
| 57 | func ValidateServerJSON(serverJSON *apiv0.ServerJSON, opts ValidationOptions) *ValidationResult { |
| 58 | result := &ValidationResult{Valid: true, Issues: []ValidationIssue{}} |
| 59 | ctx := &ValidationContext{} |
| 60 | |
| 61 | // Schema validation (version check and/or full validation) |
| 62 | if opts.ValidateSchemaVersion || opts.ValidateSchema { |
| 63 | schemaResult := validateServerJSONSchema(serverJSON, opts.ValidateSchema, opts.NonCurrentSchemaPolicy) |
| 64 | result.Merge(schemaResult) |
| 65 | } |
| 66 | |
| 67 | // Semantic validation (only if requested) |
| 68 | if !opts.ValidateSemantic { |
| 69 | return result |
| 70 | } |
| 71 | |
| 72 | // Validate server name exists and format |
| 73 | if _, err := parseServerName(*serverJSON); err != nil { |
| 74 | issue := NewValidationIssueFromError( |
| 75 | ValidationIssueTypeSemantic, |
| 76 | ctx.Field("name").String(), |
| 77 | err, |
| 78 | "invalid-server-name", |
| 79 | ) |
| 80 | result.AddIssue(issue) |
| 81 | } |
| 82 | |
| 83 | // Validate top-level server version is a specific version (not a range) & not "latest" |
| 84 | versionResult := validateVersion(ctx.Field("version"), serverJSON.Version) |
| 85 | result.Merge(versionResult) |
| 86 | |
| 87 | // Validate repository |
| 88 | repoResult := validateRepository(ctx.Field("repository"), serverJSON.Repository) |
| 89 | result.Merge(repoResult) |
| 90 | |
| 91 | // Validate website URL if provided |
| 92 | websiteResult := validateWebsiteURL(ctx.Field("websiteUrl"), serverJSON.WebsiteURL) |
| 93 | result.Merge(websiteResult) |
| 94 | |
| 95 | // Validate title if provided |
| 96 | titleResult := validateTitle(ctx.Field("title"), serverJSON.Title) |
| 97 | result.Merge(titleResult) |
| 98 | |
| 99 | // Validate icons if provided |
| 100 | iconsResult := validateIcons(ctx.Field("icons"), serverJSON.Icons) |
| 101 | result.Merge(iconsResult) |
| 102 | |
| 103 | // Validate all packages (basic field validation) |
| 104 | // Detailed package validation (including registry checks) is done during publish |
| 105 | for i, pkg := range serverJSON.Packages { |
| 106 | pkgResult := validatePackageField(ctx.Field("packages").Index(i), &pkg) |
| 107 | result.Merge(pkgResult) |
| 108 | } |
| 109 | |
| 110 | // Validate all remotes |
| 111 | for i, remote := range serverJSON.Remotes { |
| 112 | remoteResult := validateRemoteTransport(ctx.Field("remotes").Index(i), &remote) |
| 113 | result.Merge(remoteResult) |
| 114 | } |
searching dependent graphs…