- Replace chained array transforms with explicit loops across mobile and server paths - Tighten provider, git, and orchestration parsing while preserving behavior - Improve remote-connect UI data shaping and thread activity filtering
Showing the changes to apps/server/src/sourceControl (4 of 54 files). Show all
Unified · Split
| @@ -208,10 +208,13 @@ function parseRepositorySpecifier(repository: string): { · 207 unmodified lines | |||
| 208 | readonly project: string | null; | 208 | readonly project: string | null; |
| 209 | readonly name: string; | 209 | readonly name: string; |
| 210 | } { | 210 | } { |
| 211 | const parts = repository | 211 | const parts: Array<string> = []; |
| 212 | .split("/") | 212 | for (const part of repository.split("/")) { |
| 213 | .map((part) => part.trim()) | 213 | const trimmed = part.trim(); |
| 214 | .filter((part) => part.length > 0); | 214 | if (trimmed.length > 0) { |
| 215 | parts.push(trimmed); | ||
| 216 | } | ||
| 217 | } | ||
| 215 | return { | 218 | return { |
| 216 | project: parts.length > 1 ? (parts.at(-2) ?? null) : null, | 219 | project: parts.length > 1 ? (parts.at(-2) ?? null) : null, |
| 217 | name: parts.at(-1) ?? repository.trim(), | 220 | name: parts.at(-1) ?? repository.trim(), |
| @@ -247,10 +247,13 @@ function parseRepositoryPath(repository: string): { · 246 unmodified lines | |||
| 247 | readonly namespacePath: string | null; | 247 | readonly namespacePath: string | null; |
| 248 | readonly projectPath: string; | 248 | readonly projectPath: string; |
| 249 | } { | 249 | } { |
| 250 | const parts = repository | 250 | const parts: Array<string> = []; |
| 251 | .split("/") | 251 | for (const part of repository.split("/")) { |
| 252 | .map((part) => part.trim()) | 252 | const trimmed = part.trim(); |
| 253 | .filter((part) => part.length > 0); | 253 | if (trimmed.length > 0) { |
| 254 | parts.push(trimmed); | ||
| 255 | } | ||
| 256 | } | ||
| 254 | const projectPath = parts.at(-1) ?? repository.trim(); | 257 | const projectPath = parts.at(-1) ?? repository.trim(); |
| 255 | const namespacePath = parts.length > 1 ? parts.slice(0, -1).join("/") : null; | 258 | const namespacePath = parts.length > 1 ? parts.slice(0, -1).join("/") : null; |
| 256 | return { namespacePath, projectPath }; | 259 | return { namespacePath, projectPath }; |
| @@ -96,15 +96,24 @@ export function unknownAuth(detail?: string): SourceControlProviderAuth { · 95 unmodified lines | |||
| 96 | } | 96 | } |
| 97 | 97 | ||
| 98 | export function combinedAuthOutput(input: SourceControlAuthProbeInput): string { | 98 | export function combinedAuthOutput(input: SourceControlAuthProbeInput): string { |
| 99 | return [input.stdout, input.stderr].filter((entry) => entry.trim().length > 0).join("\n"); | 99 | const parts: string[] = []; |
| 100 | for (const entry of [input.stdout, input.stderr]) { | ||
| 101 | if (entry.trim().length > 0) { | ||
| 102 | parts.push(entry); | ||
| 103 | } | ||
| 104 | } | ||
| 105 | return parts.join("\n"); | ||
| 100 | } | 106 | } |
| 101 | 107 | ||
| 102 | function sanitizedAuthLines(text: string): ReadonlyArray<string> { | 108 | function sanitizedAuthLines(text: string): ReadonlyArray<string> { |
| 103 | return text | 109 | const lines: string[] = []; |
| 104 | .split(/\r?\n/) | 110 | for (const entry of text.split(/\r?\n/)) { |
| 105 | .map((entry) => entry.trim()) | 111 | const line = entry.trim(); |
| 106 | .filter((entry) => entry.length > 0) | 112 | if (line.length === 0) continue; |
| 107 | .filter((entry) => !/^[-\s]*token(?:\s+scopes?)?:/iu.test(entry)); | 113 | if (/^[-\s]*token(?:\s+scopes?)?:/iu.test(line)) continue; |
| 114 | lines.push(line); | ||
| 115 | } | ||
| 116 | return lines; | ||
| 108 | } | 117 | } |
| 109 | 118 | ||
| 110 | export function firstSafeAuthLine(text: string): string | undefined { | 119 | export function firstSafeAuthLine(text: string): string | undefined { |
| @@ -92,18 +92,17 @@ function selectProviderContext( · 91 unmodified lines | |||
| 92 | readonly url: string; | 92 | readonly url: string; |
| 93 | }>, | 93 | }>, |
| 94 | ): SourceControlProvider.SourceControlProviderContext | null { | 94 | ): SourceControlProvider.SourceControlProviderContext | null { |
| 95 | const candidates = remotes | 95 | const candidates: Array<SourceControlProvider.SourceControlProviderContext> = []; |
| 96 | .map((remote) => { | 96 | for (const remote of remotes) { |
| 97 | const provider = detectSourceControlProviderFromRemoteUrl(remote.url); | 97 | const provider = detectSourceControlProviderFromRemoteUrl(remote.url); |
| 98 | return provider | 98 | if (provider) { |
| 99 | ? { | 99 | candidates.push({ |
| 100 | provider, | 100 | provider, |
| 101 | remoteName: remote.name, | 101 | remoteName: remote.name, |
| 102 | remoteUrl: remote.url, | 102 | remoteUrl: remote.url, |
| 103 | } | 103 | }); |
| 104 | : null; | 104 | } |
| 105 | }) | 105 | } |
| 106 | .filter((value): value is SourceControlProvider.SourceControlProviderContext => value !== null); | ||
| 107 | 106 | ||
| 108 | return ( | 107 | return ( |
| 109 | candidates.find((candidate) => candidate.remoteName === "origin") ?? | 108 | candidates.find((candidate) => candidate.remoteName === "origin") ?? |