( starterSpecifier: string, preferredFramework?: string, )
| 140 | } |
| 141 | |
| 142 | export async function resolveStarterSpecifier( |
| 143 | starterSpecifier: string, |
| 144 | preferredFramework?: string, |
| 145 | ) { |
| 146 | const normalized = starterSpecifier.trim() |
| 147 | |
| 148 | if (!normalized || isLikelyStarterUrlOrPath(normalized)) { |
| 149 | return normalized |
| 150 | } |
| 151 | |
| 152 | const registry = await getRawRegistry() |
| 153 | if (registry && registry.starters?.length) { |
| 154 | const lookup = normalized.toLowerCase() |
| 155 | const matches = registry.starters.filter((starter) => { |
| 156 | const candidateIds = new Set<string>() |
| 157 | candidateIds.add(starter.name.toLowerCase()) |
| 158 | candidateIds.add(slugifyStarterName(starter.name)) |
| 159 | |
| 160 | for (const id of getStarterIdsFromUrl(starter.url)) { |
| 161 | candidateIds.add(id) |
| 162 | } |
| 163 | |
| 164 | return candidateIds.has(lookup) |
| 165 | }) |
| 166 | |
| 167 | const frameworkMatch = preferredFramework |
| 168 | ? matches.find( |
| 169 | (starter) => starter.framework.toLowerCase() === preferredFramework, |
| 170 | ) |
| 171 | : undefined |
| 172 | |
| 173 | if (frameworkMatch) { |
| 174 | return frameworkMatch.url |
| 175 | } |
| 176 | |
| 177 | if (matches.length > 0) { |
| 178 | return matches[0].url |
| 179 | } |
| 180 | } |
| 181 | |
| 182 | const monorepoStarterPath = resolveMonorepoStarterById( |
| 183 | normalized, |
| 184 | preferredFramework, |
| 185 | ) |
| 186 | if (monorepoStarterPath) { |
| 187 | return monorepoStarterPath |
| 188 | } |
| 189 | |
| 190 | if (!registry || !registry.starters?.length) { |
| 191 | throw new Error( |
| 192 | `Could not resolve template id "${normalized}" because no template registry is configured. Pass a template URL (or set CTA_REGISTRY).`, |
| 193 | ) |
| 194 | } |
| 195 | |
| 196 | const availableIds = Array.from( |
| 197 | new Set( |
| 198 | registry.starters.flatMap((starter) => { |
| 199 | const ids = [slugifyStarterName(starter.name)] |
no test coverage detected