import { isValidRepoName } from './record.js'; /** * @typedef {Object} AtprotoGitUrl * @property {string} authority - Handle or DID that owns the repository. * @property {string} repoName - Record key of the git repo record. */ /** * Parse an atproto:// remote URL. Parsed by hand because DIDs contain colons * that confuse the WHATWG URL host parser. * * One form, for a public and a private repository alike: * * atproto:/// * * Whether the name is a public record or a private one is the helper's to * find out: a private repository keeps a space of its own under the same * name, so the address never has to say. * * @param {string} url * @returns {AtprotoGitUrl} */ export function parseAtprotoUrl(url) { if (!url.startsWith('atproto://')) { throw new Error( `invalid remote URL "${url}", expected atproto:///`, ); } const segments = url.slice('atproto://'.length).replace(/\/$/, '').split('/'); if (segments.length !== 2 || !segments.every(Boolean)) { throw new Error( `invalid remote URL "${url}", expected atproto:///`, ); } const [authority, repoName] = segments; if (!isValidRepoName(repoName)) { throw new Error( `invalid repository name "${repoName}", allowed characters are A-Z a-z 0-9 . _ ~ -`, ); } return { authority, repoName }; }