(content: string)
| 38 | }; |
| 39 | |
| 40 | export function parseCredentials(content: string): CredentialsFile { |
| 41 | const result: CredentialsFile = {}; |
| 42 | let currentEntry: ProfileEntry | null = null; |
| 43 | for (const rawLine of content.split('\n')) { |
| 44 | const line = rawLine.trim(); |
| 45 | if (line === '' || line.startsWith('#') || line.startsWith(';')) continue; |
| 46 | const sectionMatch = /^\[([^\]]+)\]$/.exec(line); |
| 47 | if (sectionMatch) { |
| 48 | const sectionName = sectionMatch[1]!.trim(); |
| 49 | const existing = result[sectionName]; |
| 50 | if (existing) { |
| 51 | currentEntry = existing; |
| 52 | } else { |
| 53 | const newEntry: ProfileEntry = {}; |
| 54 | result[sectionName] = newEntry; |
| 55 | currentEntry = newEntry; |
| 56 | } |
| 57 | continue; |
| 58 | } |
| 59 | if (currentEntry === null) continue; |
| 60 | const eqIndex = line.indexOf('='); |
| 61 | if (eqIndex < 0) continue; |
| 62 | const rawKey = line.slice(0, eqIndex).trim(); |
| 63 | const rawValue = line.slice(eqIndex + 1).trim(); |
| 64 | const field = FILE_KEY_TO_FIELD[rawKey]; |
| 65 | if (field) currentEntry[field] = rawValue; |
| 66 | } |
| 67 | return result; |
| 68 | } |
| 69 | |
| 70 | export function serializeCredentials(file: CredentialsFile): string { |
| 71 | const orderedSections = Object.keys(file).sort((a, b) => { |
no outgoing calls
no test coverage detected