isogit-lfs/src/pointers.ts

83 lines
1.9 KiB
TypeScript
Raw Normal View History

2021-11-25 12:27:33 +00:00
import path from 'path';
import { Sha256 } from '@aws-crypto/sha256-universal';
import { SPEC_URL, toHex } from './util';
2021-11-25 12:27:33 +00:00
2021-11-30 21:18:47 +00:00
export interface PointerInfo {
/** OID (currently, SHA256 hash) of actual blob contents. */
2021-11-25 12:27:33 +00:00
oid: string;
/** Actual blob size in bytes. */
size: number;
2021-11-25 12:27:33 +00:00
}
export interface Pointer {
info: PointerInfo;
/** Absolute path to actual blob in LFS cache. */
2021-11-25 12:27:33 +00:00
objectPath: string;
}
function isValidPointerInfo(val: Record<string, any>): val is PointerInfo {
return val.oid.trim !== undefined && typeof val.size === 'number';
2021-11-25 12:27:33 +00:00
}
export function readPointerInfo(content: Buffer): PointerInfo {
2021-11-25 12:27:33 +00:00
const info = content.toString().trim().split('\n').reduce((accum, line) => {
const [k, v] = line.split(' ', 2);
if (k === 'oid') {
accum[k] = v.split(':', 2)[1];
} else if (k === 'size') {
accum[k] = parseInt(v, 10);
2021-11-25 12:27:33 +00:00
}
return accum;
}, {} as Record<string, any>);
if (isValidPointerInfo(info)) {
return info;
2021-11-25 12:27:33 +00:00
} else {
throw new Error("LFS pointer is incomplete or cannot be read");
}
}
interface PointerRequest {
dir: string;
gitdir?: string;
content: Buffer;
}
export function readPointer({ dir, gitdir = path.join(dir, '.git'), content }: PointerRequest): Pointer {
const info = readPointerInfo(content);
const objectPath = path.join(
gitdir,
'lfs',
'objects',
info.oid.substr(0, 2),
info.oid.substr(2, 2),
info.oid);
return { info, objectPath };
}
/** Formats given PointerInfo for writing in Git tree. */
export function formatPointerInfo(info: PointerInfo): Buffer {
const lines = [
`version ${SPEC_URL}`,
`oid sha256:${info.oid}`,
`size ${info.size}`,
];
return Buffer.from(lines.join('\n'));
}
export async function buildPointerInfo(content: Buffer): Promise<PointerInfo> {
const size = Buffer.byteLength(content);
const hash = new Sha256();
hash.update(content);
const oid = toHex(await hash.digest());
return { oid, size };
}