import { isNonEmptyString } from '@sindresorhus/is';
import * as hostRules from '../../../util/host-rules.ts';
import { regEx } from '../../../util/regex.ts';
import { parseRegistryUrl } from '../../datasource/nuget/common.ts';
import { NugetDatasource } from '../../datasource/nuget/index.ts';
import type { ParsedRegistryUrl } from '../../datasource/nuget/types.ts';
import type {
PackageSourceCredential,
PackageSourceMap,
Registry,
} from './types.ts';
export function createNuGetConfigXml(registries: Registry[]): string {
let contents = `\n\n\n`;
let unnamedRegistryCount = 0;
const credentials: PackageSourceCredential[] = [];
const packageSourceMaps: PackageSourceMap[] = [];
const seenUrls = new Set();
for (const registry of registries) {
// Skip if we've already seen this URL
if (seenUrls.has(registry.url)) {
continue;
}
seenUrls.add(registry.url);
const registryName =
registry.name ?? `Package source ${++unnamedRegistryCount}`;
const registryInfo = parseRegistryUrl(registry.url);
contents += formatPackageSourceElement(registryInfo, registryName);
const { password, username } = hostRules.find({
hostType: NugetDatasource.id,
url: registry.url,
});
if (isNonEmptyString(password) || isNonEmptyString(username)) {
credentials.push({
name: registryName,
password,
username,
});
}
if (registry.sourceMappedPackagePatterns) {
packageSourceMaps.push({
name: registryName,
patterns: registry.sourceMappedPackagePatterns,
});
}
}
contents += '\n';
if (credentials.length > 0) {
contents += '\n';
for (const credential of credentials) {
contents += formatPackageSourceCredentialElement(credential);
}
contents += '\n';
}
if (packageSourceMaps.length > 0) {
contents += '\n';
for (const packageSourceMap of packageSourceMaps) {
contents += formatPackageSource(packageSourceMap);
}
contents += '';
}
contents += '\n';
return contents;
}
function formatPackageSourceElement(
registryInfo: ParsedRegistryUrl,
name: string,
): string {
let element = `\n`;
}
function formatPackageSourceCredentialElement(
credential: PackageSourceCredential,
): string {
const escapedName = escapeName(credential.name);
let packageSourceCredential = `<${escapedName}>\n`;
if (credential.username) {
packageSourceCredential += `\n`;
}
if (credential.password) {
packageSourceCredential += `\n`;
}
packageSourceCredential += ``;
packageSourceCredential += `${escapedName}>\n`;
return packageSourceCredential;
}
function formatPackageSource(packageSourceMap: PackageSourceMap): string {
let packageSource = `\n`;
for (const pattern of packageSourceMap.patterns) {
packageSource += `\n`;
}
return `${packageSource}\n`;
}
const charactersToEscape = regEx(/[^A-Za-z0-9\-_.]/);
function escapeName(name: string): string {
let escapedName = '';
for (const char of name) {
if (char.match(charactersToEscape)) {
escapedName += `_x${char.codePointAt(0)!.toString(16).padStart(4, '0')}_`;
} else {
escapedName += char;
}
}
return escapedName;
}