* Parse shorthand format (without provider prefix)
(source: string)
| 94 | * Parse shorthand format (without provider prefix) |
| 95 | */ |
| 96 | function parseShorthand(source: string): Omit<ParsedSource, "provider"> { |
| 97 | // Pattern: owner/repo[@ref][:path] |
| 98 | let remaining = source; |
| 99 | let path: string | undefined; |
| 100 | let ref: string | undefined; |
| 101 | |
| 102 | // Extract path first (after :) |
| 103 | const colonIndex = remaining.indexOf(":"); |
| 104 | if (colonIndex !== -1) { |
| 105 | path = remaining.substring(colonIndex + 1); |
| 106 | if (!path) { |
| 107 | throw new Error(`Invalid source: ${source}. Path cannot be empty after ":".`); |
| 108 | } |
| 109 | remaining = remaining.substring(0, colonIndex); |
| 110 | } |
| 111 | |
| 112 | // Extract ref (after @) |
| 113 | const atIndex = remaining.indexOf("@"); |
| 114 | if (atIndex !== -1) { |
| 115 | ref = remaining.substring(atIndex + 1); |
| 116 | if (!ref) { |
| 117 | throw new Error(`Invalid source: ${source}. Ref cannot be empty after "@".`); |
| 118 | } |
| 119 | remaining = remaining.substring(0, atIndex); |
| 120 | } |
| 121 | |
| 122 | // Parse owner/repo |
| 123 | const slashIndex = remaining.indexOf("/"); |
| 124 | if (slashIndex === -1) { |
| 125 | throw new Error( |
| 126 | `Invalid source: ${source}. Expected format: owner/repo, owner/repo@ref, or owner/repo:path`, |
| 127 | ); |
| 128 | } |
| 129 | |
| 130 | const owner = remaining.substring(0, slashIndex); |
| 131 | const repo = remaining.substring(slashIndex + 1); |
| 132 | |
| 133 | if (!owner || !repo) { |
| 134 | throw new Error(`Invalid source: ${source}. Both owner and repo are required.`); |
| 135 | } |
| 136 | |
| 137 | return { |
| 138 | owner, |
| 139 | repo, |
| 140 | ref, |
| 141 | path, |
| 142 | }; |
| 143 | } |
no outgoing calls
no test coverage detected
searching dependent graphs…