pantry/scripts/upload-sync.ts
2022-09-08 16:40:35 -04:00

60 lines
No EOL
1.8 KiB
TypeScript
Executable file
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env -S tea -E
/*---
args:
- deno
- run
- --allow-net
- --allow-read={{ tea.prefix }}/tea.xyz/var/www
- --allow-env=AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY,S3_BUCKET
- --import-map={{ srcroot }}/import-map.json
---*/
import { S3 } from "s3";
import { crypto } from "deno/crypto/mod.ts";
import useCache from "hooks/useCache.ts";
import { encodeToString } from "encodeToString";
import { readAll, readerFromStreamReader } from "deno/streams/mod.ts";
const s3 = new S3({
accessKeyID: Deno.env.get("AWS_ACCESS_KEY_ID")!,
secretKey: Deno.env.get("AWS_SECRET_ACCESS_KEY")!,
region: "us-east-1",
});
const bucket = s3.getBucket(Deno.env.get("S3_BUCKET")!);
for (const pkg of await useCache().ls()) {
const key = useCache().s3Key(pkg)
const bottle = useCache().bottle(pkg)
console.log({ checking: key });
const inRepo = await bucket.headObject(key)
const repoChecksum = inRepo ? await checksum(`https://dist.tea.xyz/${key}.sha256sum`) : undefined
// path.read() returns a string; this is easier to get a UInt8Array
const contents = await Deno.readFile(bottle.string);
const sha256sum = encodeToString(new Uint8Array(await crypto.subtle.digest("SHA-256", contents)))
if (!inRepo || repoChecksum !== sha256sum) {
const basename = key.split("/").pop()
const body = new TextEncoder().encode(`${sha256sum} ${basename}`)
console.log({ uploading: key });
await bucket.putObject(key, contents);
await bucket.putObject(`${key}.sha256sum`, body);
console.log({ uploaded: key });
}
}
async function checksum(url: string) {
const rsp = await fetch(url)
if (!rsp.ok) throw new Error(`404-not-found: ${url}`)
const rdr = rsp.body?.getReader()
if (!rdr) throw new Error(`Couldnt read: ${url}`)
const r = await readAll(readerFromStreamReader(rdr))
return new TextDecoder().decode(r).split(' ')[0]
}