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

chadtmiller.com/pds.js

An atproto PDS in JavaScript, for Cloudflare Workers and Node

0
0
main
63 lines · 2.2 KB Raw History
/**
 * Naming a repository. The command line names one by handle, the firehose
 * names the same one by DID, and the state file keys off the DID form.
 */

/**
 * Repository names may contain no slash, so the last one separates the
 * authority from the name.
 * @param {string} spec - "<handle-or-did>/<repo>"
 * @returns {{authority: string, repoName: string}}
 */
export function parseSpec(spec) {
  const slash = spec.lastIndexOf('/');
  if (slash <= 0 || slash === spec.length - 1) {
    throw new Error(`expected <handle-or-did>/<repo>, got "${spec}"`);
  }
  return { authority: spec.slice(0, slash), repoName: spec.slice(slash + 1) };
}

/**
 * @param {string} did
 * @param {string} repoName
 * @returns {string}
 */
export function repoKey(did, repoName) {
  return `${did}/${repoName}`;
}

/** Characters an atproto record key permits. */
const RKEY_SAFE = /[^A-Za-z0-9._~:-]/g;

/**
 * The record key holding the latest check for one ref of one repository. A
 * reader computes this from the repository record it already has, so the
 * check costs one getRecord and no listing.
 *
 * The repository's own key names it, so a rename leaves every check where it
 * is. Ref names carry slashes, which record keys do not permit, so every
 * character outside the key charset becomes an underscore. Two refs that
 * differ only in those characters therefore share a key.
 * @param {string} did - repository owner
 * @param {string} repoRkey - the repository's record key
 * @param {string} ref - full ref name, e.g. refs/heads/main
 * @returns {string}
 */
export function latestCheckKey(did, repoRkey, ref) {
  return `${did}:${repoRkey}:${ref}`.replace(RKEY_SAFE, '_');
}

/**
 * The record key of a check request for one ref of one repository. The
 * request is in the owner's own repo, so the owner DID is implied and only
 * the repository and the ref name the key.
 *
 * The key is derived rather than a TID, so asking twice replaces the record
 * instead of leaving a request per click in the owner's repo.
 * @param {string} repoRkey - the repository's record key
 * @param {string} ref - full ref name, e.g. refs/heads/main
 * @returns {string}
 */
export function checkRequestKey(repoRkey, ref) {
  return `${repoRkey}:${ref}`.replace(RKEY_SAFE, '_');
}