@hyperframes/aws-lambda 0.7.36 → 0.7.37
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.
- package/package.json +2 -2
- package/scripts/_handlerBanner.ts +30 -0
- package/scripts/build-zip.test.ts +71 -8
- package/scripts/build-zip.ts +4 -17
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hyperframes/aws-lambda",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.37",
|
|
4
4
|
"description": "AWS Lambda adapter for HyperFrames distributed rendering — handler, client-side SDK, and CDK construct.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"ffprobe-static": "^3.1.0",
|
|
46
46
|
"puppeteer-core": "^24.39.1",
|
|
47
47
|
"tar": "^7.4.3",
|
|
48
|
-
"@hyperframes/producer": "^0.7.
|
|
48
|
+
"@hyperframes/producer": "^0.7.37"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@types/aws-lambda": "^8.10.146",
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CJS-interop banner prepended to the ESM handler bundle.
|
|
3
|
+
*
|
|
4
|
+
* Lambda's Node 22 runtime treats `.mjs` as ESM, which has no `require`,
|
|
5
|
+
* `__filename`, or `__dirname`. The handler bundle inlines CJS deps that
|
|
6
|
+
* assume all three exist at module scope:
|
|
7
|
+
* - postcss et al. call top-level `require(...)`
|
|
8
|
+
* - wawoff2's emscripten build (pulled in unconditionally via
|
|
9
|
+
* producer → fontCompression) reads `__dirname` at module scope
|
|
10
|
+
* Without the shims the handler throws "Dynamic require of <X> is not
|
|
11
|
+
* supported" / "__dirname is not defined in ES module scope" at import time,
|
|
12
|
+
* before it can run — which is exactly how a freshly deployed stack crashed
|
|
13
|
+
* on every render (#1932).
|
|
14
|
+
*
|
|
15
|
+
* This mirrors the producer's own CJS banner (packages/producer/build.mjs);
|
|
16
|
+
* the handler bundle inlines producer source, so it needs the same shim.
|
|
17
|
+
*
|
|
18
|
+
* Kept in its own module (not inline in build-zip.ts, which self-executes on
|
|
19
|
+
* import) so build-zip.test.ts can import the exact banner, bundle a fixture
|
|
20
|
+
* with it, and assert the globals actually resolve.
|
|
21
|
+
*/
|
|
22
|
+
export const HANDLER_BANNER = [
|
|
23
|
+
"// hyperframes-aws-lambda handler bundle",
|
|
24
|
+
'import { createRequire as __hf_createRequire } from "module";',
|
|
25
|
+
'import { fileURLToPath as __hf_fileURLToPath } from "url";',
|
|
26
|
+
'import { dirname as __hf_dirname } from "path";',
|
|
27
|
+
"const require = __hf_createRequire(import.meta.url);",
|
|
28
|
+
"const __filename = __hf_fileURLToPath(import.meta.url);",
|
|
29
|
+
"const __dirname = __hf_dirname(__filename);",
|
|
30
|
+
].join("\n");
|
|
@@ -1,14 +1,77 @@
|
|
|
1
1
|
import { describe, expect, it } from "bun:test";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
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";
|
|
4
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.
|
|
5
24
|
describe("build-zip handler banner", () => {
|
|
6
|
-
it("
|
|
7
|
-
const
|
|
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
|
+
);
|
|
8
44
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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
|
+
}
|
|
13
76
|
});
|
|
14
77
|
});
|
package/scripts/build-zip.ts
CHANGED
|
@@ -48,6 +48,7 @@ import { dirname, join, resolve } from "node:path";
|
|
|
48
48
|
import { fileURLToPath } from "node:url";
|
|
49
49
|
import * as esbuild from "esbuild";
|
|
50
50
|
import { formatBytes } from "./_formatBytes.js";
|
|
51
|
+
import { HANDLER_BANNER } from "./_handlerBanner.js";
|
|
51
52
|
|
|
52
53
|
const scriptDir = dirname(fileURLToPath(import.meta.url));
|
|
53
54
|
const packageRoot = resolve(scriptDir, "..");
|
|
@@ -239,24 +240,10 @@ async function bundleHandler(stagingDir: string): Promise<void> {
|
|
|
239
240
|
sourcemap: false,
|
|
240
241
|
entryPoints: [entry],
|
|
241
242
|
outfile,
|
|
242
|
-
//
|
|
243
|
-
//
|
|
244
|
-
// instead of throwing "Dynamic require of <X> is not supported" on
|
|
245
|
-
// CommonJS modules in the dependency graph (postcss, etc. that ship
|
|
246
|
-
// top-level `require('path')` calls). The shim does
|
|
247
|
-
// `typeof require !== "undefined" ? require : <throwing-proxy>`, so
|
|
248
|
-
// making `require` a real value in module scope flips it onto the
|
|
249
|
-
// happy path.
|
|
243
|
+
// See HANDLER_BANNER (_handlerBanner.ts) for why the ESM bundle needs the
|
|
244
|
+
// CJS require/__filename/__dirname shims.
|
|
250
245
|
banner: {
|
|
251
|
-
js:
|
|
252
|
-
"// hyperframes-aws-lambda handler bundle",
|
|
253
|
-
'import { createRequire as __hf_createRequire } from "module";',
|
|
254
|
-
"const require = __hf_createRequire(import.meta.url);",
|
|
255
|
-
'import { fileURLToPath as __hf_fileURLToPath } from "url";',
|
|
256
|
-
'import { dirname as __hf_dirname } from "path";',
|
|
257
|
-
"const __filename = __hf_fileURLToPath(import.meta.url);",
|
|
258
|
-
"const __dirname = __hf_dirname(__filename);",
|
|
259
|
-
].join("\n"),
|
|
246
|
+
js: HANDLER_BANNER,
|
|
260
247
|
},
|
|
261
248
|
});
|
|
262
249
|
console.log(`[build-zip] bundled handler → ${outfile}`);
|