@hyperframes/aws-lambda 0.8.181 → 0.8.184

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,77 +0,0 @@
1
- import { describe, expect, it } from "bun:test";
2
- import { spawnSync } from "node:child_process";
3
- import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
4
- import { tmpdir } from "node:os";
5
- import { join } from "node:path";
6
- import { pathToFileURL } from "node:url";
7
- import * as esbuild from "esbuild";
8
- import { HANDLER_BANNER } from "./_handlerBanner.js";
9
-
10
- // The handler ships as ESM (.mjs) but inlines CJS deps that assume Node's CJS
11
- // globals exist at module scope: postcss et al. call top-level `require(...)`,
12
- // and wawoff2's emscripten build reads `__dirname`. A freshly deployed stack
13
- // crashed on every render (#1932) with "__dirname is not defined in ES module
14
- // scope"; the fix is the require/__filename/__dirname shim in HANDLER_BANNER.
15
- //
16
- // This bundles a fixture touching all three globals with the REAL banner and
17
- // imports the output, so it catches a dropped/renamed shim behaviourally
18
- // rather than by grepping for literals (which survives a broken refactor).
19
- //
20
- // The import MUST run under Node, not the `bun test` runtime: Bun defines
21
- // `__dirname`/`__filename` even in ESM, which would mask a missing shim and
22
- // green-light a broken bundle. Lambda runs Node, so we spawn `node` (guaranteed
23
- // present in CI alongside bun) to reproduce the deploy target faithfully.
24
- describe("build-zip handler banner", () => {
25
- it("shims require/__filename/__dirname so inlined CJS deps import under Node", () => {
26
- const dir = mkdtempSync(join(tmpdir(), "hf-banner-test-"));
27
- try {
28
- const entry = join(dir, "fixture.ts");
29
- const outfile = join(dir, "out.mjs");
30
- // Reference each CJS global at module top level, the way inlined deps do.
31
- // If any shim is missing, importing `out.mjs` throws at eval time.
32
- writeFileSync(
33
- entry,
34
- [
35
- "const cjsDir = __dirname;",
36
- "const cjsFile = __filename;",
37
- "const path = require('node:path');",
38
- "if (typeof cjsDir !== 'string') throw new Error('__dirname missing');",
39
- "if (typeof cjsFile !== 'string') throw new Error('__filename missing');",
40
- "if (typeof path.join !== 'function') throw new Error('require missing');",
41
- "console.log('BANNER_OK');",
42
- ].join("\n"),
43
- );
44
-
45
- esbuild.buildSync({
46
- bundle: true,
47
- platform: "node",
48
- target: "node22",
49
- format: "esm",
50
- entryPoints: [entry],
51
- outfile,
52
- banner: { js: HANDLER_BANNER },
53
- });
54
-
55
- // Import under real Node — Lambda's runtime — not the bun test runtime.
56
- const res = spawnSync(
57
- "node",
58
- [
59
- "--input-type=module",
60
- "-e",
61
- `await import(${JSON.stringify(pathToFileURL(outfile).href)});`,
62
- ],
63
- { encoding: "utf8" },
64
- );
65
-
66
- // A missing shim surfaces as a non-zero exit + ReferenceError on stderr.
67
- // Guard against a silent skip if `node` isn't on PATH (it is in CI).
68
- expect(res.error).toBeUndefined();
69
- expect(res.stderr).not.toContain("is not defined in ES module scope");
70
- expect(res.stderr).not.toContain("Dynamic require");
71
- expect(res.status).toBe(0);
72
- expect(res.stdout).toContain("BANNER_OK");
73
- } finally {
74
- rmSync(dir, { recursive: true, force: true });
75
- }
76
- });
77
- });
@@ -1,101 +0,0 @@
1
- import { afterEach, describe, expect, it } from "bun:test";
2
- import { createHash } from "node:crypto";
3
- import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
4
- import { tmpdir } from "node:os";
5
- import { join } from "node:path";
6
- import { adapterPackageRoot, prebuiltHandler } from "../src/sdk/prebuiltHandler.js";
7
- import { pinHandlerZip } from "./pin-handler-zip.js";
8
-
9
- const realTemplate = readFileSync(
10
- join(import.meta.dir, "..", "..", "..", "examples", "aws-lambda", "template.yaml"),
11
- "utf-8",
12
- );
13
- const dirs: string[] = [];
14
-
15
- function fixtureRepo(): { root: string; pkgDir: string } {
16
- const root = mkdtempSync(join(tmpdir(), "hf-pin-zip-"));
17
- dirs.push(root);
18
- const pkgDir = join(root, "packages", "aws-lambda");
19
- mkdirSync(join(pkgDir, "dist"), { recursive: true });
20
- writeFileSync(
21
- join(pkgDir, "package.json"),
22
- JSON.stringify({
23
- name: "@hyperframes/aws-lambda",
24
- version: "9.8.7",
25
- repository: { url: "https://github.com/heygen-com/hyperframes" },
26
- }),
27
- );
28
- mkdirSync(join(root, "examples", "aws-lambda"), { recursive: true });
29
- writeFileSync(join(root, "examples", "aws-lambda", "template.yaml"), realTemplate);
30
- return { root, pkgDir };
31
- }
32
-
33
- afterEach(() => {
34
- for (const dir of dirs.splice(0)) rmSync(dir, { recursive: true, force: true });
35
- });
36
-
37
- describe("pinHandlerZip", () => {
38
- it("moves the built zip out of the package and pins its URL and sha256 for this version", () => {
39
- const { root, pkgDir } = fixtureRepo();
40
- const zip = Buffer.from("zip bytes");
41
- writeFileSync(join(pkgDir, "dist", "handler.zip"), zip);
42
- writeFileSync(join(pkgDir, "dist", "handler.zip.manifest.json"), "{}");
43
- const sha256 = createHash("sha256").update(zip).digest("hex");
44
-
45
- const manifest = pinHandlerZip(root);
46
-
47
- expect(manifest).toEqual({
48
- version: "9.8.7",
49
- url: "https://github.com/heygen-com/hyperframes/releases/download/v9.8.7/hyperframes-lambda-handler.zip",
50
- sha256,
51
- bytes: zip.length,
52
- });
53
- // Nothing large is left for npm to pack.
54
- expect(existsSync(join(pkgDir, "dist", "handler.zip"))).toBe(false);
55
- expect(existsSync(join(pkgDir, "dist", "handler.zip.manifest.json"))).toBe(false);
56
- expect(readFileSync(join(root, "dist", "hyperframes-lambda-handler.zip"))).toEqual(zip);
57
- expect(readFileSync(join(root, "dist", "hyperframes-lambda-handler.sha256"), "utf-8")).toBe(
58
- `${sha256} hyperframes-lambda-handler.zip\n`,
59
- );
60
-
61
- const pinned = prebuiltHandler(pkgDir);
62
- expect(pinned).toEqual({
63
- ...manifest,
64
- templatePath: join(pkgDir, "prebuilt", "template.yaml"),
65
- });
66
- const template = readFileSync(pinned!.templatePath, "utf-8");
67
- expect(template).toContain(" CodeUri: handler.zip\n");
68
- expect(template).not.toContain("packages/aws-lambda/dist/handler.zip\n");
69
- });
70
-
71
- it("pins a zip a previous run already attached to the release", () => {
72
- const { root, pkgDir } = fixtureRepo();
73
- mkdirSync(join(root, "dist"));
74
- writeFileSync(join(root, "dist", "hyperframes-lambda-handler.zip"), "attached");
75
-
76
- expect(pinHandlerZip(root).sha256).toBe(createHash("sha256").update("attached").digest("hex"));
77
- expect(prebuiltHandler(pkgDir)?.sha256).toBe(pinHandlerZip(root).sha256);
78
- });
79
-
80
- it("refuses a template whose CodeUri it cannot rewrite", () => {
81
- const { root, pkgDir } = fixtureRepo();
82
- writeFileSync(join(pkgDir, "dist", "handler.zip"), "zip");
83
- writeFileSync(
84
- join(root, "examples", "aws-lambda", "template.yaml"),
85
- "CodeUri: elsewhere.zip\n",
86
- );
87
-
88
- expect(() => pinHandlerZip(root)).toThrow(/expected exactly one/);
89
- });
90
- });
91
-
92
- describe("prebuiltHandler", () => {
93
- it("reads from its own package root", () => {
94
- expect(adapterPackageRoot()).toBe(join(import.meta.dir, ".."));
95
- });
96
-
97
- it("is undefined when the package carries no pinned zip", () => {
98
- const { pkgDir } = fixtureRepo();
99
- expect(prebuiltHandler(pkgDir)).toBeUndefined();
100
- });
101
- });
@@ -1,80 +0,0 @@
1
- import { describe, expect, it } from "bun:test";
2
- import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
3
- import { tmpdir } from "node:os";
4
- import { join, resolve } from "node:path";
5
- import {
6
- _awaitBeforeDeadlineForTests,
7
- _closeBrowserForProbeTests,
8
- parseProbeArgs,
9
- } from "./probe-beginframe.js";
10
-
11
- describe("parseProbeArgs", () => {
12
- it("defaults to the @sparticuz/chromium source", () => {
13
- expect(parseProbeArgs([])).toEqual({});
14
- });
15
-
16
- it("accepts a standalone executable path", () => {
17
- expect(parseProbeArgs(["--executable-path", "/opt/chrome/chrome-headless-shell"])).toEqual({
18
- executablePath: "/opt/chrome/chrome-headless-shell",
19
- });
20
- });
21
-
22
- it("accepts the equals form and resolves relative paths", () => {
23
- expect(parseProbeArgs(["--executable-path=./chrome"])).toEqual({
24
- executablePath: resolve("./chrome"),
25
- });
26
- });
27
-
28
- it("loads exact production launch arguments from JSON", () => {
29
- const dir = mkdtempSync(join(tmpdir(), "hf-probe-args-"));
30
- const argsPath = join(dir, "args.json");
31
- writeFileSync(argsPath, JSON.stringify(["--enable-begin-frame-control", "--no-sandbox"]));
32
- try {
33
- expect(parseProbeArgs(["--launch-args-json", argsPath])).toEqual({
34
- launchArgs: ["--enable-begin-frame-control", "--no-sandbox"],
35
- });
36
- } finally {
37
- rmSync(dir, { recursive: true, force: true });
38
- }
39
- });
40
-
41
- it("rejects missing values and unknown arguments", () => {
42
- expect(() => parseProbeArgs(["--executable-path"])).toThrow(
43
- "--executable-path requires a path",
44
- );
45
- expect(() => parseProbeArgs(["--source", "chrome"])).toThrow("Unknown argument: --source");
46
- expect(() => parseProbeArgs(["--launch-args-json"])).toThrow(
47
- "--launch-args-json requires a path",
48
- );
49
- });
50
-
51
- it("bounds a CDP operation that never resolves", async () => {
52
- const never = new Promise<never>(() => {});
53
- await expect(
54
- _awaitBeforeDeadlineForTests(never, Date.now() + 25, "screenshot beginFrame"),
55
- ).rejects.toThrow("timeout during screenshot beginFrame");
56
- });
57
-
58
- it("force-kills and disconnects when graceful cleanup never resolves", async () => {
59
- let killedWith: NodeJS.Signals | number | undefined;
60
- let disconnected = false;
61
- await _closeBrowserForProbeTests(
62
- {
63
- close: () => new Promise<never>(() => {}),
64
- process: () => ({
65
- kill: (signal) => {
66
- killedWith = signal;
67
- return true;
68
- },
69
- }),
70
- disconnect: async () => {
71
- disconnected = true;
72
- },
73
- },
74
- 25,
75
- );
76
-
77
- expect(killedWith).toBe("SIGKILL");
78
- expect(disconnected).toBe(true);
79
- });
80
- });