(
name: string,
source: { source: string; repo?: string; url?: string },
)
| 117 | * @returns An error message if validation fails, or null if valid |
| 118 | */ |
| 119 | export function validateOfficialNameSource( |
| 120 | name: string, |
| 121 | source: { source: string; repo?: string; url?: string }, |
| 122 | ): string | null { |
| 123 | const normalizedName = name.toLowerCase() |
| 124 | |
| 125 | // Only validate reserved names |
| 126 | if (!ALLOWED_OFFICIAL_MARKETPLACE_NAMES.has(normalizedName)) { |
| 127 | return null // Not a reserved name, no source validation needed |
| 128 | } |
| 129 | |
| 130 | // Check for GitHub source type |
| 131 | if (source.source === 'github') { |
| 132 | // Verify the repo is from the official org |
| 133 | const repo = source.repo || '' |
| 134 | if (!repo.toLowerCase().startsWith(`${OFFICIAL_GITHUB_ORG}/`)) { |
| 135 | return `The name '${name}' is reserved for official Anthropic marketplaces. Only repositories from 'github.com/${OFFICIAL_GITHUB_ORG}/' can use this name.` |
| 136 | } |
| 137 | return null // Valid: reserved name from official GitHub source |
| 138 | } |
| 139 | |
| 140 | // Check for git URL source type |
| 141 | if (source.source === 'git' && source.url) { |
| 142 | const url = source.url.toLowerCase() |
| 143 | // Check for HTTPS URL format: https://github.com/anthropics/... |
| 144 | // or SSH format: git@github.com:anthropics/... |
| 145 | const isHttpsAnthropics = url.includes('github.com/anthropics/') |
| 146 | const isSshAnthropics = url.includes('git@github.com:anthropics/') |
| 147 | |
| 148 | if (isHttpsAnthropics || isSshAnthropics) { |
| 149 | return null // Valid: reserved name from official git URL |
| 150 | } |
| 151 | |
| 152 | return `The name '${name}' is reserved for official Anthropic marketplaces. Only repositories from 'github.com/${OFFICIAL_GITHUB_ORG}/' can use this name.` |
| 153 | } |
| 154 | |
| 155 | // Reserved names must come from GitHub (either 'github' or 'git' source) |
| 156 | return `The name '${name}' is reserved for official Anthropic marketplaces and can only be used with GitHub sources from the '${OFFICIAL_GITHUB_ORG}' organization.` |
| 157 | } |
| 158 | |
| 159 | /** |
| 160 | * Schema for relative file paths that must start with './' |
no test coverage detected