~ knotless Search/
↑↓ move↵ open⇧↵ all results

chadtmiller.com/pds.js

An atproto PDS in JavaScript, for Cloudflare Workers and Node

0
0
main
43 lines · 1.4 KB Raw History
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://<handle-or-did>/<repo-name>
 *
 * 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://<handle-or-did>/<repo-name>`,
    );
  }
  const segments = url.slice('atproto://'.length).replace(/\/$/, '').split('/');
  if (segments.length !== 2 || !segments.every(Boolean)) {
    throw new Error(
      `invalid remote URL "${url}", expected atproto://<handle-or-did>/<repo-name>`,
    );
  }
  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 };
}