summaryrefslogtreecommitdiff
path: root/Homework/cs5260/widgetrequesthandler/scripts/build-layer.ts
diff options
context:
space:
mode:
authorElizabeth Alexander Hunt <me@liz.coffee>2026-07-02 11:55:17 -0700
committerElizabeth Alexander Hunt <me@liz.coffee>2026-07-02 11:55:17 -0700
commit6bf4b90c90f15f4ab60833bddf5b5756d1a6b1f6 (patch)
treeed97e39ec77c5231ffd2c394493e68d00ddac5a4 /Homework/cs5260/widgetrequesthandler/scripts/build-layer.ts
downloadmisc-undergrad-6bf4b90c90f15f4ab60833bddf5b5756d1a6b1f6.tar.gz
misc-undergrad-6bf4b90c90f15f4ab60833bddf5b5756d1a6b1f6.zip
Diffstat (limited to 'Homework/cs5260/widgetrequesthandler/scripts/build-layer.ts')
-rw-r--r--Homework/cs5260/widgetrequesthandler/scripts/build-layer.ts105
1 files changed, 105 insertions, 0 deletions
diff --git a/Homework/cs5260/widgetrequesthandler/scripts/build-layer.ts b/Homework/cs5260/widgetrequesthandler/scripts/build-layer.ts
new file mode 100644
index 0000000..408e015
--- /dev/null
+++ b/Homework/cs5260/widgetrequesthandler/scripts/build-layer.ts
@@ -0,0 +1,105 @@
+// HACK: https://github.com/oven-sh/bun/issues/2081
+process.stdout.getWindowSize = () => [80, 80];
+process.stderr.getWindowSize = () => [80, 80];
+
+import { createReadStream, createWriteStream } from "node:fs";
+import { join } from "node:path";
+import { Command, Flags } from "@oclif/core";
+import JSZip from "jszip";
+
+export class BuildCommand extends Command {
+ static summary = "Build a custom Lambda layer for Bun.";
+
+ static flags = {
+ arch: Flags.string({
+ description: "The architecture type to support.",
+ options: ["x64", "aarch64"],
+ default: "aarch64",
+ }),
+ release: Flags.string({
+ description: "The release of Bun to install.",
+ default: "latest",
+ }),
+ url: Flags.string({
+ description: "A custom URL to download Bun.",
+ exclusive: ["release"],
+ }),
+ output: Flags.file({
+ exists: false,
+ default: async () => "bun-lambda-layer.zip",
+ }),
+ layer: Flags.string({
+ description: "The name of the Lambda layer.",
+ multiple: true,
+ default: ["bun"],
+ }),
+ region: Flags.string({
+ description: "The region to publish the layer.",
+ multiple: true,
+ default: [],
+ }),
+ public: Flags.boolean({
+ description: "If the layer should be public.",
+ default: false,
+ }),
+ };
+
+ async run() {
+ const result = await this.parse(BuildCommand);
+ const { flags } = result;
+ this.debug("Options:", flags);
+ const { arch, release, url, output } = flags;
+ const { href } = new URL(
+ url ?? `https://bun.sh/download/${release}/linux/${arch}?avx2=true`,
+ );
+ this.log("Downloading...", href);
+ const response = await fetch(href, {
+ headers: {
+ "User-Agent": "bun-lambda",
+ },
+ });
+ if (response.url !== href) {
+ this.debug("Redirected URL:", response.url);
+ }
+ this.debug("Response:", response.status, response.statusText);
+ if (!response.ok) {
+ const reason = await response.text();
+ this.error(reason, { exit: 1 });
+ }
+ this.log("Extracting...");
+ const buffer = await response.arrayBuffer();
+ let archive;
+ try {
+ archive = await JSZip.loadAsync(buffer);
+ } catch (cause) {
+ this.debug(cause);
+ this.error("Failed to unzip file:", { exit: 1 });
+ }
+ this.debug("Extracted archive:", Object.keys(archive.files));
+ const bun = archive.filter(
+ (_, { dir, name }) => !dir && name.endsWith("bun"),
+ )[0];
+ if (!bun) {
+ this.error("Failed to find executable in zip", { exit: 1 });
+ }
+ const cwd = bun.name.split("/")[0];
+ archive = archive.folder(cwd) ?? archive;
+ for (const filename of ["bootstrap", "runtime.ts"]) {
+ const path = join(__dirname, "..", filename);
+ archive.file(filename, createReadStream(path));
+ }
+ this.log("Saving...", output);
+ archive
+ .generateNodeStream({
+ streamFiles: true,
+ compression: "DEFLATE",
+ compressionOptions: {
+ level: 9,
+ },
+ })
+ .pipe(createWriteStream(output));
+ this.log("Saved");
+ }
+}
+
+await BuildCommand.run(process.argv.slice(2));