chadtmiller.com/pds.js
An atproto PDS in JavaScript, for Cloudflare Workers and Node
0
0
// Merging a pull request, which is the one act in this model that moves the
// repository's canonical branch.
//
// Everything else the page writes goes into the visitor's own repo. This
// writes the repository record, so it runs as the owner, on the owner's own
// PDS, under the owner's OAuth session. The server accepts it only from a
// token whose account is the repository's, so nobody else's session merges,
// and the grant reaches no repository but the owner's own.
import { XrpcError } from '@pdsjs/git/client';
import { account } from '#/lib/git.js';
import { authedFetch } from '#/lib/oauth.js';
/**
* Put a pull request's work on the canonical branch.
*
* A squash is the change, so it takes the change's title. A merge is a record
* of taking the change rather than the change itself, so it names the branch
* the way `git merge` does and the title is not its subject.
* @param {import('#/lib/oauth.js').Session} session - the owner's own
* @param {string} repo - repository name on this site
* @param {{author: {did: string, handle: string}, branch: string, title: string}} pull
* @param {'merge'|'squash'} mode
* @returns {Promise<{sha: string, ref: string, objects: number}>}
*/
export async function mergePull(session, repo, pull, mode) {
const response = await authedFetch(
session,
`${account.pds}/xrpc/dev.pdsjs.git.mergePull`,
{
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({
name: repo,
did: pull.author.did,
ref: `refs/heads/${pull.branch}`,
mode,
handle: pull.author.handle,
...(mode === 'squash' && pull.title ? { subject: pull.title } : {}),
}),
},
);
const body = await response.json().catch(() => ({}));
if (!response.ok) {
// A grant made before the scope named the repository record cannot
// merge; the session provider sends such a session back through consent,
// so this reports only what a fresh grant still could not do.
throw new XrpcError(
response.status,
body.error ?? 'Unknown',
body.message ?? `The merge failed (${response.status}).`,
);
}
return body;
}