Skip to content

Instantly share code, notes, and snippets.

@tatemz
Created December 29, 2021 16:31
Show Gist options
  • Save tatemz/239be89051d557e33f23174dc42c1fce to your computer and use it in GitHub Desktop.
Save tatemz/239be89051d557e33f23174dc42c1fce to your computer and use it in GitHub Desktop.
Sample of isomorphic git in Deno
import { encode } from "https://deno.land/[email protected]/encoding/base64url.ts";
import { join } from "https://deno.land/[email protected]/path/mod.ts";
import fs from "https://deno.land/[email protected]/node/fs.ts";
import git from "http://esm.sh/[email protected]";
import http from "http://esm.sh/[email protected]/http/web";
import { QueryHandler } from "./QueryHandler.ts";
const throwFSError = (e: Error) => {
if (e instanceof Deno.errors.AlreadyExists) {
throw { ...e, code: "EEXIST" };
}
if (e instanceof Deno.errors.NotFound) {
throw { ...e, code: "ENOENT" };
}
if (e.message.startsWith("Not a directory")) {
console.log(typeof e);
throw { ...e, code: "ENOTDIR" };
}
throw e;
};
const denoFS = {
...fs,
promises: {
...fs.promises,
readFile: async (
...args: Parameters<typeof fs.promises.readFile>
) => {
try {
return await fs.promises.readFile(...args);
} catch (e) {
throwFSError(e);
}
},
writeFile: async (
...args: Parameters<typeof fs.promises.writeFile>
) => {
try {
return await fs.promises.writeFile(...args);
} catch (e) {
throwFSError(e);
}
},
mkdir: async (...args: Parameters<typeof fs.promises.mkdir>) => {
try {
return await fs.promises.mkdir(...args);
} catch (e) {
throwFSError(e);
}
},
rmdir: async (...args: Parameters<typeof fs.promises.rmdir>) => {
try {
return await fs.promises.rmdir(...args);
} catch (e) {
throwFSError(e);
}
},
unlink: async (...args: Parameters<typeof fs.promises.unlink>) => {
try {
return await fs.promises.unlink(...args);
} catch (e) {
throwFSError(e);
}
},
stat: async (...args: Parameters<typeof fs.promises.stat>) => {
try {
return await fs.promises.stat(...args);
} catch (e) {
throwFSError(e);
}
},
lstat: async (...args: Parameters<typeof fs.promises.lstat>) => {
try {
return await fs.promises.lstat(...args);
} catch (e) {
throwFSError(e);
}
},
readdir: async (...args: Parameters<typeof fs.promises.readdir>) => {
try {
return await fs.promises.readdir(...args);
} catch (e) {
throwFSError(e);
}
},
readlink: async (
...args: Parameters<typeof fs.promises.readlink>
) => {
try {
return await fs.promises.readlink(...args);
} catch (e) {
throwFSError(e);
}
},
symlink: async (...args: Parameters<typeof fs.promises.symlink>) => {
try {
return await fs.promises.symlink(...args);
} catch (e) {
throwFSError(e);
}
},
},
};
export const makeQueryHandler = (): QueryHandler => {
const cache = {};
const tmpDir = Deno.makeTempDirSync();
const textEncoder = new TextEncoder();
return async (query) => {
const { params: { remote, ref } } = query;
const dir = join(tmpDir, encode(textEncoder.encode(`${remote}:${ref}`)));
const refsWithPrefix = await git.listServerRefs({
http,
url: remote,
prefix: ref,
protocolVersion: 2,
});
const matchingRefs = refsWithPrefix.filter((refWithPrefix) =>
refWithPrefix.ref === ref
);
if (!matchingRefs || matchingRefs.length !== 1) {
throw new Error("ref invalid");
}
const refSHA = matchingRefs[0].oid;
await git.init({
fs: denoFS,
dir,
});
await git.addRemote({
fs: denoFS,
dir,
remote: "origin",
url: remote,
});
await git.fetch({
fs: denoFS,
http,
dir,
url: remote,
singleBranch: true,
ref: refSHA,
tags: ref.startsWith("refs/tags"),
cache,
});
return {
type: "GitLog",
data: await git.log({
fs: denoFS,
dir,
ref: refSHA,
cache,
}) || [],
};
};
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment